Skip to content

feat(opencode): turn lifecycle events (Turn.Started, Turn.Ended) - #81

Merged
filipeforattini merged 2 commits into
mainfrom
feat/turn-lifecycle-events
Aug 21, 2026
Merged

feat(opencode): turn lifecycle events (Turn.Started, Turn.Ended)#81
filipeforattini merged 2 commits into
mainfrom
feat/turn-lifecycle-events

Conversation

@filipeforattini

@filipeforattini filipeforattini commented Aug 21, 2026

Copy link
Copy Markdown

First two events of the agent-loop decomposition. Adds SessionEvent.Turn.Started and SessionEvent.Turn.Ended (live events) and fires them around the runLoop in packages/opencode/src/session/prompt.ts.

What this PR does

  • Adds Turn.Started / Turn.Ended to the schema (live, non-durable).
  • Turn.Started fires once at the top of runLoop, before any step runs.
  • Turn.Ended fires once when the loop exits (after the final break), before the prune fork.

Why this matters

A turn is the natural boundary of agent work (one user prompt may span multiple steps). Marking it explicitly gives V2 plugins / telemetry a clean entry/exit point without depending on the internal while (true) structure. dsh uses turn/start and turn/ending for the same reason.

Pattern

Same as the rest: V2 surface alongside the existing V1 flow, no breaking change. V2 plugins can subscribe via events.subscribe/events.subscribeAll without registering a V1 plugin.

Out of scope (next steps in the decomposition)

  • Step.Started/Step.Ended per-step events (already in schema, just need wiring)
  • LLM.Stream event around the AI-SDK call
  • Tools.Execute event wrapping the per-tool pipeline
  • Replaceable per-step services via the plugin runtime

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Adds `SessionEvent.Turn.Started` and `SessionEvent.Turn.Ended` (live events, types `session.next.turn.started`/`session.next.turn.ended`) carrying `{ sessionID, timestamp }` (+ `finished` on Ended). Fires `Turn.Started` once per turn at the top of `runLoop` and `Turn.Ended` once when the loop exits.

First two events of the agent-loop decomposition. They mark the natural lifecycle boundary of a turn (a user prompt may span multiple steps) and give V2 plugins / telemetry a clean entry/exit point without depending on the internal `while (true)` structure. Same shim pattern as the rest: V2 surface alongside the existing V1 flow, no breaking change.

Next decomposition steps (separate PRs): `Step.Started`/`Step.Ended` per-step events, `LLM.Stream` already wired in schema, `Tools.Execute` event around the per-tool pipeline, and finally the per-step services replaceable via the plugin runtime.
@filipeforattini
filipeforattini merged commit 3f7128c into main Aug 21, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant