feat(opencode): expose native task agents - #1
Closed
pekth wants to merge 15 commits into
Closed
Conversation
Thread transfer impact
This comment will update automatically after the next completed run. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Implement captain-approved bounded V1 OpenCode native Task visibility in the T3 Agents panel. Expose OpenCode child Task agents through the existing lifecycle, persistence, fold, and panel without schema, UI/client/mobile/desktop/relay changes, process scanning, a generic orchestration framework, an SDK bump, or the PR pingdotgg#4664 backport. Keep the implementation limited to OpenCodeAdapter.ts and focused adapter tests, with only an ingestion assertion if source evidence requires it. Preserve isolated safe child dispatch, explicit resumed-running activation, one-call status-map handling with resumable idle, provider-truth terminal and child-stop semantics, and bounded ordering-safe hydration/deduplication. Validate the locked SDK and focused tests/typecheck, then real OpenCode v1.18.15 foreground/background/resume/stop behavior with Agents-panel and disposable SQLite proof, and deliver through review, exact validation, normal push, branch CI, non-draft PR, and green PR checks without merging.
What Changed
Risk Assessment
Testing
Focused tests passed. Real disposable T3 verification showed OpenCode child rows working, completion, resume hydration, and stopped-child behavior. Typecheck not run because static-analysis commands were prohibited.
/var/folders/jh/pqhqm3rd1lb4vxnlrb806j140000gn/T/no-mistakes-evidence/01KZHMQ3ZCSNCXANME81SAS2DJ/agents-opencode-running.png)Evidence: Disposable SQLite OpenCode lifecycle evidence
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed (11) ✅
AGENTS.md:150- Intent requires: “Keep implementation limited to OpenCodeAdapter.ts and focused adapter tests...” Diff adds unrelated AGENTS.md guidance at lines 150–155. Remove this out-of-scope change or obtain approval.🔧 Fix: Removed out-of-scope AGENTS guidance
3 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:303- Childmessage.part.updatedevents without envelope IDs are deduplicated bypart.id, so later running→completed/error updates for the same tool part are dropped beforeemitChildToolProgresscan process them. Include state/time in the key or deduplicate exact snapshots.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1121-emitChildToolProgressdoes not guardchild.terminalStatus; late child events after stop/failure/completion can emittool.progressfor a terminal Agents-panel row.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1297- Hydration infers foreground completion from any latest completed assistant message in the child session. During explicit reactivation, prior-run history plus an idle status snapshot can falsely terminalize the new activation instead of preserving resumable idle behavior required by the intent.🔧 Fix: Fix OpenCode child lifecycle deduplication and reactivation
4 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1216- Child status map is cached for the whole session. A later child linked after the snapshot reuses a missing entry, which is treated as idle and can falsely terminalize a foreground child. Invalidate or refresh status coverage for newly appearing children.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1373- First-link hydration still infers completion from prior child history. After adapter restart or resume, a reused child with completed history plus an idle snapshot can be marked terminal before its new activation becomes busy; later status events cannot reopen it.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1372- Hydration runs before applying the current Task part's explicit completed/error state. Hydration can set terminalStatus first, causing the current provider terminal state at lines 1377-1380 to be suppressed and report the wrong result.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1061- emitChildStarted lacks the aborting guard used by other child emitters. A stop or interrupt racing with first linkage can emit task.started after child abort has begun, producing stale lifecycle ordering.🔧 Fix: Fix OpenCode child lifecycle hydration and status races
2 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:308- Fallback deduplication keysmessage.updatedonly byinfo.id; a later update carrying assistant error/completion fields is dropped, so child failure may never emittask.completed. Include relevant state in the key or deduplicate exact snapshots.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1259- Reactivation clearslastToolFingerprint, then hydration scans all child history and emits the latest tool as current progress, even when it belongs to the prior activation. Agents panel can show stale work for the newly running child.🔧 Fix: Fix OpenCode child deduplication and reactivation hydration
2 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1271- First-link hydration emits the latest historical tool part even when it is completed/error, producing stale tool.progress for an already-idle child. Hydrate only active tool states or gate on provider busy status.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1217- A failed session.status request caches undefined while marking the map loaded, so later children never retry status hydration and can remain stuck running instead of becoming idle/waiting. Do not cache failed loads.🔧 Fix: Fix stale OpenCode hydration and retry failed status loads
3 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:683- Child abort requests have no timeout or cancellation; one hung child blocksinterruptTurn/stopSessionbefore the parent abort runs.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1180- Child permission/question events only mark the task waiting. They are not stored or emitted as requests, so approval-required children cannot be resumed through existing response methods.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1291- Current status hydration runs before replaying buffered events; an older buffered busy/idle event can overwrite current provider truth and leave a child permanently shown in the wrong state.🔧 Fix: Fix OpenCode child lifecycle timeout, routing, and hydration
3 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1345- Buffered child error events replay before current status hydration can set terminalStatus; a newer busy status is then ignored, leaving reactivated child permanently failed. Apply current provider status before replay or prevent stale buffered terminals from closing a newer activation.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1365- First-link hydration emits the latest historical completed/error tool as current progress whenever child status is busy, so a newly active child can show stale prior work. Hydrate only pending/running tool states.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1065- A root task event already inside the handler can link a new child after stop snapshots tracked children; the guard checks only abortingChildIds, allowing task.started and hydration after session shutdown. Re-check stopped state across async boundaries before linking/emitting.🔧 Fix: Fix buffered hydration and shutdown race handling
3 warnings still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:309- Deduplication omits permission/question request IDs (properties.id), so multiple child permission.asked or question.asked events collapse to the same<type>:eventkey and later requests are dropped. Include event request IDs in the fallback key.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1174- Child request handling does not reject terminal children. Late or buffered permission.asked/question.asked events can open new requests after task.completed, even though status/tool events are terminal-guarded.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1046- Child status checks occur before an await in buildEventBase; stop can set stopped or terminal state during that await, after which task.updated is still emitted. Recheck lifecycle state immediately before queueing child status, tool, and completion events.🔧 Fix: Hardened OpenCode child lifecycle event handling
5 issues (1 error, 4 warnings) still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1503- Intent requires “explicit resumed-running activation,” but child linkage only occurs from live root task events; resumed sessions never hydrate root history, so existing active child Tasks can remain undiscovered after restart/resume.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1291- Child question requests omitquestion.rejected; rejected requests remain pending and the Agents panel never receivesuser-input.resolved, unlike root handling at line 1755.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1503-hydrateChildawaits unboundedsession.messagesandsession.statuscalls inside serialStream.runForEach, so one slow child hydration blocks all root events and can stall turn completion/status updates.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1021- The 64-event pre-link cap silently drops control events such aspermission.askedorquestion.asked; a delayed task link can leave a child blocked without any request reaching T3.apps/server/src/provider/Layers/OpenCodeAdapter.ts:722- After a successful child abort with a still-busy status snapshot,abortingChildIdsis cleared and later idle events emit onlytask.updated; notask.completedstopped event is ever produced, leaving interrupted child rows resumable instead of stopped.🔧 Fix: Fix resumed child lifecycle and shutdown handling
2 issues (1 error, 1 warning) still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1646- Resume hydration only rediscovers task parts stillpendingorrunning. Background tasks intentionally becomecompletedin the parent while their child continues running, so resumed background children are never linked or shown, violating explicit resumed-running activation.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1249- After abort succeeds while a child remains busy, it is placed inchildStopPendingIds, but all subsequent child events are rejected byabortingChildIds. The later idle status can never reachemitChildStopped, leaving interrupted child rows without stopped completion.🔧 Fix: Fixed resumed background visibility and pending child stops
1 warning still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1509- Hydration applies current status before replayingpostHydrationBufferedEvents, but replays those events with the same stalestatusType. A newer buffered error can be suppressed when snapshot status was busy, and buffered status events can overwrite current provider truth, violating the required ordering-safe hydration behavior.🔧 Fix: Fix OpenCode hydration replay ordering
✅ Re-checked - no issues remain.
🔧 **Test** - 4 issues found → auto-fixed (4) ✅
apps/server/src/provider/Layers/OpenCodeAdapter.test.ts:2072- Reactivation test fails: expected two status-map calls, received zero.apps/server/src/provider/Layers/OpenCodeAdapter.test.ts:2167- Reactivation hydration emits current tool progress before prior progress; related hydration tests hang for 60 seconds.apps/server/src/provider/Layers/OpenCodeAdapter.test.ts:2339- Terminal failure ordering assertion fails during late success and idle events.apps/server/src/provider/Layers/OpenCodeAdapter.ts:1- No Agents-panel screenshot or real OpenCode foreground/background/resume/stop SQLite evidence produced; browser verification requires permission and focused tests currently fail.opencode --version(1.18.15)./node_modules/.bin/vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.tsFocused reactivation/status and tool-hydration testsFocused terminal-failure ordering testgit diff --check c0a7cc31d664171be523fc1fcb92df3c508d5c72 5b4691cd58f158555143ab16353455f91df41fd5🔧 Fix: Fix OpenCode hydration ordering and test isolation
1 warning still open:
./node_modules/.bin/vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.ts./node_modules/.bin/vp run devwithcurl http://localhost:5954/opencode --version🔧 Fix: Guard OpenCode message error narrowing in hydration
1 warning still open:
apps/server/src/provider/Layers/OpenCodeAdapter.ts:1- Required T3 end-to-end foreground/background/resume/stop SQLite evidence and Agents-panel screenshot were not produced; only direct OpenCode child-task evidence and initial shell screenshot were captured../node_modules/.bin/vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.ts./node_modules/.bin/vp run --filter t3 typecheckopencode --versionReal OpenCode 1.18.15 task delegation in disposable projectDisposable T3 dev server startup and pairing flowChrome headless screenshot capture of T3 shell🔧 Fix: OpenCode tests pass; full suite blocked by Electron setup
1 warning still open:
pnpm exec vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.ts apps/server/src/provider/Layers/OpenCodeProvider.test.ts apps/server/src/textGeneration/OpenCodeTextGeneration.test.tsDisposable T3 server with isolated.t3-e2e-opencodestateBrowser inspection of Providers, model picker, and Agents panelSQLite lifecycle query🔧 Fix: Focused OpenCode tests pass; full-suite failure was flaky
✅ Re-checked - no issues remain.
pnpm exec vp test run apps/server/src/provider/Layers/OpenCodeAdapter.test.ts apps/server/src/provider/Layers/OpenCodeProvider.test.ts apps/server/src/textGeneration/OpenCodeTextGeneration.test.tsDisposable T3/OpenCode thread: foreground child completion, resumed thread hydration, running child, stop generation, persisted stopped state.Read-only SQLite lifecycle query and Agents-panel screenshot capture.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.