Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ Tasks with no open blockers - ready to work on. Use `/ready` to refresh this lis
- Notes: CANCELLED: Reconciled: queued in DB but TODO.md has no #auto-dispatch tag or Dispatch Queue entry (t1180)
- [x] t1303 Soft TTSR rule engine — define rules in `.agents/rules/` with `ttsr_trigger` regex in frontmatter (following oh-my-pi's pattern). Implement rule loader that discovers and parses rule files. Rules specify: trigger regex, rule content (correction instructions), repeat policy (once/after-gap). This is the foundation for both soft TTSR (Phase 1) and future real TTSR when OpenCode adds stream hooks. ~1h #feature #harness #auto-dispatch model:sonnet ref:GH#2127 status:deployed pr:#2136 completed:2026-02-22
- [x] t1304 Soft TTSR: wire rules into OpenCode plugin hooks — use three currently-unused plugin hooks: (1) `experimental.chat.system.transform` to inject active rules into system prompt preventatively, (2) `experimental.chat.messages.transform` to scan previous assistant outputs for rule violations and inject correction context into message history, (3) `experimental.text.complete` to detect violations post-hoc and flag them. This gives us preventative enforcement without stream-level interception. ~2h #feature #harness #opencode #auto-dispatch model:sonnet ref:GH#2128 assignee:marcusquinn started:2026-02-22T05:02:07Z status:deployed pr:#2139 completed:2026-02-22
- [ ] t1305 OpenCode upstream: open issue proposing stream.delta + stream.aborted plugin hooks — research existing OpenCode issues for overlap. Draft issue citing oh-my-pi benchmark data (hashline improved 15 models, 5-68% success rate gains, 20-61% token reduction). Propose two new hooks: `stream.delta` (observe individual streaming tokens, return `{abort?: boolean}`) and `stream.aborted` (handle abort with `{retry?: boolean, injectMessage?: string}`). Reference the streaming loop where hooks would be inserted. Include code sketch showing the modest change needed. NOTE: v1.2.7 did massive Bun→Filesystem migration and v1.2.1 added PartDelta SDK events — re-check processor.ts location and streaming architecture before starting. ~2h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2129 status:deployed
- [ ] t1306 OpenCode upstream: proof-of-concept PR for stream hooks — fork anomalyco/opencode, implement `stream.delta` and `stream.aborted` hooks in streaming loop. Add plugin trigger calls at `text-delta`, `reasoning-delta`, and `tool-input-delta` cases. Implement abort mechanism via AbortController exposure. Add tests. Reference the issue from t1305. NOTE: v1.2.7 migrated from Bun.file() to Filesystem module across entire codebase — fork from latest main, not our stale clone. ~4h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2130 [proposed:auto-dispatch model:opus] status:deployed
- Notes: CANCELLED: cancelled by supervisor
- [x] t1305 OpenCode upstream: open issue proposing stream.delta + stream.aborted plugin hooks — research existing OpenCode issues for overlap. Draft issue citing oh-my-pi benchmark data (hashline improved 15 models, 5-68% success rate gains, 20-61% token reduction). Propose two new hooks: `stream.delta` (observe individual streaming tokens, return `{abort?: boolean}`) and `stream.aborted` (handle abort with `{retry?: boolean, injectMessage?: string}`). Reference the streaming loop where hooks would be inserted. Include code sketch showing the modest change needed. ~2h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2129 pr:#2152 completed:2026-02-22 upstream-issue:anomalyco/opencode#14740
- [x] t1306 OpenCode upstream: proof-of-concept PR for stream hooks — fork anomalyco/opencode, implement `stream.delta` and `stream.aborted` hooks in streaming loop. Add plugin trigger calls at `text-delta`, `reasoning-delta`, and `tool-input-delta` cases. Implement abort mechanism via AbortController exposure. Add tests. Reference the issue from t1305. ~4h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2130 completed:2026-02-25 upstream-pr:anomalyco/opencode#14741
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The task description for t1306 mentions implementing the abort mechanism using AbortController exposure. However, the newly added task brief (todo/tasks/t1306-brief.md) states that a StreamAbortedError custom error class was used instead. To maintain consistency and accurately reflect the work done, it would be best to update the task description in this file.

Suggested change
- [x] t1306 OpenCode upstream: proof-of-concept PR for stream hooks — fork anomalyco/opencode, implement `stream.delta` and `stream.aborted` hooks in streaming loop. Add plugin trigger calls at `text-delta`, `reasoning-delta`, and `tool-input-delta` cases. Implement abort mechanism via AbortController exposure. Add tests. Reference the issue from t1305. ~4h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2130 completed:2026-02-25 upstream-pr:anomalyco/opencode#14741
- [x] t1306 OpenCode upstream: proof-of-concept PR for stream hooks — fork anomalyco/opencode, implement `stream.delta` and `stream.aborted` hooks in streaming loop. Add plugin trigger calls at `text-delta`, `reasoning-delta`, and `tool-input-delta` cases. Implement abort mechanism via a custom StreamAbortedError. Add tests. Reference the issue from t1305. ~4h #feature #auto-dispatch #harness #opencode #upstream model:opus ref:GH#2130 completed:2026-02-25 upstream-pr:anomalyco/opencode#14741

- Notes: Upstream PR anomalyco/opencode#14741 — all 9/9 CI checks pass, MERGEABLE, 267 additions (processor.ts stream hooks + plugin type definitions + 11 tests). Awaiting upstream maintainer review.
- [x] t1307 LLM observability: SQLite-based request tracking — create `observability-helper.sh` with SQLite WAL-mode database tracking all LLM requests: model, provider, tokens (input/output/cache read/write), costs (per-category), duration, TTFT (time to first token), stop reason, error messages. Inspired by oh-my-pi's `packages/stats/` system. Incremental parsing with offset tracking. CLI: `aidevops stats [summary|models|projects|costs|trend]`. Wire into existing budget enforcement (t1100). ~3h #feature #observability #auto-dispatch model:sonnet ref:GH#2176 pr:#2137 completed:2026-02-22
- [x] t1308 LLM observability: data collection from OpenCode plugin — extend OpenCode plugin to capture LLM request metadata via `event` hook and `tool.execute.after`. Record: model used, token counts, cost, duration, tool call counts, success/failure. Write to the SQLite DB from t1307. Incremental — each session appends, no full reparse needed. ~1h #feature #observability #opencode #auto-dispatch model:sonnet ref:GH#2177 assignee:marcusquinn started:2026-02-22T05:02:44Z status:deployed pr:#2138 completed:2026-02-22
- [x] t1309 Intent tracing in OpenCode plugin — add intent field to tool call logging. Inspired by oh-my-pi's `agent__intent` pattern where a hidden field is injected into every tool's JSON Schema requiring the LLM to describe its intent in present participle form. In our case, log the intent alongside tool calls in the observability DB (t1307) for debugging and audit trails. v1.2.7 now passes sessionID and callID to shell.env hook — more context available. Evaluate whether `tool.execute.before` hook provides enough context. ~1h #feature #auto-dispatch #observability #opencode model:sonnet ref:GH#2190 assignee:marcusquinn started:2026-02-22T16:37:42Z status:deployed pr:#2153 completed:2026-02-22
Expand Down
120 changes: 120 additions & 0 deletions todo/tasks/t1306-brief.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
mode: subagent
---
# t1306: OpenCode upstream — proof-of-concept PR for stream hooks

## Origin

- **Created:** 2026-02-22
- **Session:** claude-code (interactive)
- **Created by:** ai-supervisor (auto-dispatch from p030 harness plan)
- **Parent task:** t1302 (Harness engineering: oh-my-pi learnings)
- **Conversation context:** Analysis of oh-my-pi's TTSR (Time-To-Stream Rules) pattern revealed OpenCode lacks plugin hooks for real-time stream observation. t1305 opened the upstream issue; this task implements the proof-of-concept PR.

## What

Fork anomalyco/opencode and submit a PR implementing two new plugin hooks:

1. **`stream.delta`** — fires on `text-delta`, `reasoning-delta`, and `tool-input-delta` events during streaming. Plugins can set `output.abort = true` to cancel the stream.
2. **`stream.aborted`** — fires after abort. Plugins can set `output.retry = true` with optional `injectMessage` to retry with corrective context.

The PR must include type definitions in the plugin package, implementation in `processor.ts`, and tests.

## Why

Full TTSR (real-time stream policy enforcement) is blocked without stream-level plugin hooks. The existing `experimental.text.complete` hook only fires after generation completes — too late for real-time content filtering, pattern detection, or cost control. This is the highest-leverage upstream contribution from the p030 harness plan.

## How (Approach)

1. Fork from latest `anomalyco/opencode` dev branch (not stale clone — v1.2.7+ migrated from Bun.file() to Filesystem module)
2. Add `Plugin.trigger("stream.delta", ...)` calls in the three delta cases in `packages/opencode/src/session/processor.ts`
3. Add `StreamAbortedError` class for clean abort signaling
4. Add catch-block handling with retry logic (max 3 attempts) and optional message injection
5. Add type definitions to `packages/plugin/src/index.ts` (Hooks interface)
6. Add tests in `packages/opencode/test/session/stream-hooks.test.ts`

Key files:
- `packages/opencode/src/session/processor.ts` — streaming loop (two locations: reasoning and text delta handlers)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The brief mentions that stream.delta hooks are triggered for text-delta, reasoning-delta, and tool-input-delta. However, this line only lists "reasoning and text delta handlers" as key locations. For clarity and consistency, it would be good to include tool-input-delta here as well.

Suggested change
- `packages/opencode/src/session/processor.ts` — streaming loop (two locations: reasoning and text delta handlers)
- `packages/opencode/src/session/processor.ts` — streaming loop (handlers for text-delta, reasoning-delta, and tool-input-delta)
References
  1. Ensuring all relevant operational details, such as delta handlers, are explicitly listed for clarity and consistency, especially when presented in a bulleted format.

- `packages/plugin/src/index.ts:231` — Hooks interface extension
- `packages/opencode/test/session/stream-hooks.test.ts` — new test file

## Acceptance Criteria

- [x] `stream.delta` hook fires on text-delta, reasoning-delta, and tool-input-delta

```yaml
verify:
method: manual
prompt: "Check upstream PR anomalyco/opencode#14741 diff for Plugin.trigger calls in all three delta cases"
```

- [x] `stream.aborted` hook fires after abort with retry capability

```yaml
verify:
method: manual
prompt: "Check upstream PR anomalyco/opencode#14741 diff for StreamAbortedError catch block with retry logic"
```

- [x] Plugin type definitions added to Hooks interface

```yaml
verify:
method: manual
prompt: "Check packages/plugin/src/index.ts diff for stream.delta and stream.aborted type definitions"
```

- [x] Tests pass (11 tests covering StreamAbortedError, hook shapes, retry loop)

```yaml
verify:
method: manual
prompt: "Check upstream CI — all 9/9 checks pass including unit (linux) with stream-hooks tests"
```

- [x] All upstream CI checks pass

```yaml
verify:
method: manual
prompt: "gh pr checks 14741 --repo anomalyco/opencode — all 9 checks SUCCESS"
```

- [x] PR references upstream issue from t1305

## Context & Decisions

- **v2 branch**: First attempt (`feature/stream-hooks`, PR #14701/#14727) was closed due to stale base. Rebased onto latest dev as `feature/stream-hooks-v2` (PR #14741).
- **AbortController vs custom error**: Chose `StreamAbortedError` custom error class over AbortController exposure — simpler, doesn't require plumbing AbortController through the plugin API.
- **Max retries = 3**: Hardcoded constant `STREAM_ABORT_MAX_RETRIES = 3` to prevent infinite retry loops.
- **Type assertions for tool-input-delta**: Used `(value as any).id` and `(value as any).delta` because the upstream SDK types don't expose these fields on tool-input-delta events yet.
- **Accumulated text tracking**: Added `toolInputAccumulated` record to track accumulated tool input per tool call ID, matching the pattern used for text and reasoning deltas.

## Relevant Files

- `packages/opencode/src/session/processor.ts` — main implementation (stream hooks + abort handling)
- `packages/plugin/src/index.ts` — type definitions for new hooks
- `packages/opencode/test/session/stream-hooks.test.ts` — 11 tests (new file)

## Dependencies

- **Blocked by:** t1305 (upstream issue — completed, anomalyco/opencode#14740)
- **Blocks:** Full TTSR implementation (real-time stream policy enforcement in aidevops OpenCode plugin)
- **External:** Upstream maintainer review and merge of anomalyco/opencode#14741

## Estimate Breakdown

| Phase | Time | Notes |
|-------|------|-------|
| Research/read | 1h | Study processor.ts streaming architecture, v1.2.7 migration |
| Implementation | 2h | Hook calls, error class, retry logic, type definitions |
| Testing | 30m | 11 unit tests + CI verification |
| PR iteration | 30m | Rebase onto latest dev, address CI flakiness |
| **Total** | **4h** | |

## Completion Evidence

- **Upstream PR:** [anomalyco/opencode#14741](https://github.com/anomalyco/opencode/pull/14741) — OPEN, MERGEABLE, 9/9 CI checks pass
- **Upstream issue:** [anomalyco/opencode#14740](https://github.com/anomalyco/opencode/issues/14740) — OPEN
- **Changes:** 267 additions, 2 deletions across 3 files
- **Tests:** 11 new tests in `stream-hooks.test.ts` + all 120 existing session tests pass
Comment on lines +115 to +120
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Completion evidence references an OPEN PR — clarify the task completion boundary.

The brief marks all checkboxes [x] and the task is listed as done, but the upstream PR is still OPEN and awaiting maintainer review. "Delivery complete" ≠ "merged and shipped." If the upstream maintainer requests significant rework or closes the PR, this task needs to be re-engaged.

Recommend rephrasing the section header from ## Completion Evidence to ## Delivery Evidence and adding an explicit note:

+> ⚠️ Merge is pending upstream maintainer review. Task status reflects delivery of the PoC PR, not upstream adoption.
 - **Upstream PR:** [anomalyco/opencode#14741](https://github.com/anomalyco/opencode/pull/14741) — OPEN, MERGEABLE, 9/9 CI checks pass

Also consider adding a follow-up task (e.g., t1315: track upstream merge of anomalyco/opencode#14741) to close the loop.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Completion Evidence
- **Upstream PR:** [anomalyco/opencode#14741](https://github.com/anomalyco/opencode/pull/14741) — OPEN, MERGEABLE, 9/9 CI checks pass
- **Upstream issue:** [anomalyco/opencode#14740](https://github.com/anomalyco/opencode/issues/14740) — OPEN
- **Changes:** 267 additions, 2 deletions across 3 files
- **Tests:** 11 new tests in `stream-hooks.test.ts` + all 120 existing session tests pass
## Completion Evidence
> ⚠️ Merge is pending upstream maintainer review. Task status reflects delivery of the PoC PR, not upstream adoption.
- **Upstream PR:** [anomalyco/opencode#14741](https://github.com/anomalyco/opencode/pull/14741) — OPEN, MERGEABLE, 9/9 CI checks pass
- **Upstream issue:** [anomalyco/opencode#14740](https://github.com/anomalyco/opencode/issues/14740) — OPEN
- **Changes:** 267 additions, 2 deletions across 3 files
- **Tests:** 11 new tests in `stream-hooks.test.ts` + all 120 existing session tests pass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@todo/tasks/t1306-brief.md` around lines 115 - 120, Rename the "## Completion
Evidence" header to "## Delivery Evidence" in todo/tasks/t1306-brief.md, update
the paragraph that lists the upstream PR anomalyco/opencode#14741 to explicitly
state that the PR is OPEN and that delivery is pending upstream merge (e.g.,
"Upstream PR is open; delivery is pending maintainer merge — re-engage if PR is
closed or requests rework"), and add a follow-up task entry (suggested id:
t1315) that tracks the upstream merge of anomalyco/opencode#14741 so the task
can be closed only after the PR is merged.

Loading