You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/ARCHITECTURE.md
+15-1Lines changed: 15 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,8 +18,22 @@ This repeats until the director emits `capabilities.done()`.
18
18
19
19
| Event | When it fires |
20
20
|---|---|
21
-
|`inference.done`| The LLM finished one assistant turn. Carries the full turn content. |
21
+
|`inference.done`| The LLM finished one assistant turn. Carries the full turn content. Fires once per turn, every turn — this is the **turn boundary**. |
22
22
|`tool.done`| One tool call completed. Carries the result and the original `callId`. |
23
+
|`reactor.done`| The reactor loop shut down. Fires once, at the end of the run — not between turns. |
24
+
25
+
`inference.done` and `reactor.done` read as near-synonyms at a call site but
26
+
answer different questions: "did a turn end" versus "did the reactor shut
27
+
down." Three shipped defects came from code that needed a turn boundary but
28
+
keyed off `reactor.done` instead: queued messages never dispatched because
29
+
the send-queue drain waited for shutdown; `run.json`'s `turnsUsed` froze for
30
+
an entire session because the mid-run snapshot only re-fired on shutdown;
31
+
and the shell run state didn't return to idle between turns. Documentation
32
+
didn't prevent the second and third instances, so code that needs to ask
33
+
"did a turn end" or "did the reactor shut down" should go through the
34
+
`onTurnBoundary` / `onReactorShutdown` guards in `src/agent/reactor-events.ts`
35
+
rather than comparing `event.type` to a string directly — the guards can't be
36
+
handed the wrong event by mistake the way a bare string comparison can.
0 commit comments