@agentex/agent 0.0.36 → 0.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +460 -0
- package/README.md +32 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/claude/parse.d.ts +3 -0
- package/dist/providers/claude/parse.d.ts.map +1 -1
- package/dist/providers/claude/parse.js +23 -1
- package/dist/providers/claude/parse.js.map +1 -1
- package/dist/providers/claude/session.d.ts +174 -4
- package/dist/providers/claude/session.d.ts.map +1 -1
- package/dist/providers/claude/session.js +541 -29
- package/dist/providers/claude/session.js.map +1 -1
- package/dist/providers/codex/execute.d.ts.map +1 -1
- package/dist/providers/codex/execute.js +3 -0
- package/dist/providers/codex/execute.js.map +1 -1
- package/dist/providers/codex/parse.d.ts +12 -1
- package/dist/providers/codex/parse.d.ts.map +1 -1
- package/dist/providers/codex/parse.js +21 -0
- package/dist/providers/codex/parse.js.map +1 -1
- package/dist/providers/codex/session.d.ts.map +1 -1
- package/dist/providers/codex/session.js +21 -1
- package/dist/providers/codex/session.js.map +1 -1
- package/dist/types.d.ts +95 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/instructions.d.ts +36 -12
- package/dist/utils/instructions.d.ts.map +1 -1
- package/dist/utils/instructions.js +104 -53
- package/dist/utils/instructions.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/providers/claude/parse.ts +23 -1
- package/src/providers/claude/session.ts +556 -30
- package/src/providers/codex/execute.ts +3 -0
- package/src/providers/codex/parse.ts +25 -0
- package/src/providers/codex/session.ts +24 -1
- package/src/types.ts +97 -0
- package/src/utils/instructions.ts +152 -64
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,195 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.38 — AGENTS.md is the workspace instruction file for every runtime
|
|
4
|
+
|
|
5
|
+
Claude Code reads `AGENTS.md` since 2.1.277, loaded exactly where `CLAUDE.md` would be, but only in a folder with no `CLAUDE.md`. A `CLAUDE.md`, a `CLAUDE.local.md`, or one in a parent folder hides `AGENTS.md` completely (verified against 2.1.281). Not yet on Bedrock, Vertex or Foundry.
|
|
6
|
+
|
|
7
|
+
### Changed (breaking)
|
|
8
|
+
|
|
9
|
+
- **`installInstructions` writes `AGENTS.md` only by default.** Claude's workspace file is now `AGENTS.md`, like every other runtime. `CLAUDE.md` is Claude's native file, written only with `includeNativeFiles: true`, and then as a one-line `@AGENTS.md` pointer in the managed region instead of a second copy of the brief. A copy would have made anything the user writes in `AGENTS.md` invisible to Claude. Opt in for Claude Code before 2.1.277 or on a third-party API provider. `includeNativeFiles` still writes Gemini's `GEMINI.md` as a copy.
|
|
10
|
+
- **An existing workspace `CLAUDE.md` is reconciled** whenever `claude` is among the runtimes and the opt-in is off, because it would hide `AGENTS.md`: one holding nothing but this installer's managed region (for example the full brief 0.0.37 and earlier wrote) is deleted, and one the user wrote keeps their content and gains `@AGENTS.md` in the managed region. `managed: false` leaves it alone.
|
|
11
|
+
- **`removeInstructions` always checks native files** (`CLAUDE.md`, `GEMINI.md`), so an opt-in install is fully removable. It still only strips the managed region.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `InstructionStatus` gains `"removed"`, and `InstructionInstallResult` a `removed` count.
|
|
16
|
+
- `InstructionTarget.importsFile` marks a pointer file (`"AGENTS.md"` on an opt-in `CLAUDE.md`).
|
|
17
|
+
|
|
18
|
+
### Migration
|
|
19
|
+
|
|
20
|
+
A host that relied on the default `CLAUDE.md` gets `AGENTS.md` only. Nothing else is needed on Claude Code 2.1.277+ with first-party auth: the next install deletes the old managed-only `CLAUDE.md`. Elsewhere, pass `includeNativeFiles: true`.
|
|
21
|
+
|
|
22
|
+
## 0.0.37 — Turn liveness and background-task identity (Claude)
|
|
23
|
+
|
|
24
|
+
Claude Code starts turns by itself. When a background task finishes, the CLI
|
|
25
|
+
enqueues the notification as user input, which opens a fresh turn with no host
|
|
26
|
+
involvement. A host that tracks "is the agent working" from its own `send()`
|
|
27
|
+
cannot see those turns — `send()` already resolved — so the session reads as
|
|
28
|
+
finished while the agent is visibly working. Verified against Claude Code
|
|
29
|
+
2.1.241, where one user message produced two `result` events with a
|
|
30
|
+
self-started turn between them.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **`turn_start` StreamEvent.** Pairs with `result`, which closes a turn.
|
|
35
|
+
Carries `trigger: "send" | "resume"` — `resume` meaning the provider opened
|
|
36
|
+
the turn on its own. Emitted for host-initiated turns too, so `turn_start` →
|
|
37
|
+
`result` describes turn liveness straight off the stream rather than by
|
|
38
|
+
inference from dispatch.
|
|
39
|
+
|
|
40
|
+
It deliberately does not name the background task behind a `resume`. Claude
|
|
41
|
+
delivers a task's result and opens the turn as two unlinked records, and with
|
|
42
|
+
several tasks in flight the pairing is not recoverable from the wire; every
|
|
43
|
+
attempt to infer it produced a plausible id that was sometimes wrong.
|
|
44
|
+
Correlate through `background_task.report` and `toolUseId`, which the
|
|
45
|
+
provider does state.
|
|
46
|
+
|
|
47
|
+
Attribution is exact, not inferred. A host message carries a uuid and a
|
|
48
|
+
provider-initiated continuation does not: every dequeued input with a uuid
|
|
49
|
+
emits `command_lifecycle` naming it, while the task-notification continuation
|
|
50
|
+
is enqueued without one. So a turn opened by a `started` naming an
|
|
51
|
+
outstanding message *is* that message's turn. A build that has never emitted
|
|
52
|
+
`command_lifecycle` falls back to the oldest unclaimed send; once one has
|
|
53
|
+
been seen, the fallback is disabled, because guessing there would mislabel
|
|
54
|
+
twice.
|
|
55
|
+
|
|
56
|
+
- **`turn_end` StreamEvent.** Every `turn_start` is followed by exactly one,
|
|
57
|
+
carrying the same `turnId` and a `reason`. `result` cannot serve as the close
|
|
58
|
+
signal on its own: a message the CLI cancels, discards, or refuses opens a
|
|
59
|
+
turn and produces no result, so a host pairing `turn_start` with `result`
|
|
60
|
+
would stay busy forever on those paths. `result` remains the outcome payload
|
|
61
|
+
and is ordered before the `turn_end` that follows it.
|
|
62
|
+
|
|
63
|
+
- **`background_task.report`.** The task's delivered output (`summary`,
|
|
64
|
+
`outputFile`, `usage`), present only on the event that hands the result
|
|
65
|
+
back. Claude emits *both* `task_updated` and `task_notification` for a single
|
|
66
|
+
completion; they are different records, not duplicates, and only the
|
|
67
|
+
notification carries the result. Collapsing them into one indistinguishable
|
|
68
|
+
`phase: "completed"` event made hosts render every finished task twice, once
|
|
69
|
+
with its report and once empty. A task that was stopped or killed delivered
|
|
70
|
+
nothing and carries no report. Codex applies the identical rule at every
|
|
71
|
+
emitter, so "one row per delivered result" holds across providers.
|
|
72
|
+
|
|
73
|
+
- **`background_task.toolUseId`.** The tool call that launched the task — the
|
|
74
|
+
same id Claude writes into a subagent's `meta.json`, and the only structured
|
|
75
|
+
task-to-tool_call link the wire provides. It was being discarded.
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
80
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
81
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
82
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
83
|
+
have its sends resolved by that handler — the failure that made two
|
|
84
|
+
back-to-back results resolve both callers with the first result.
|
|
85
|
+
|
|
86
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
87
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
88
|
+
Modelling one command per turn left every coalesced message permanently
|
|
89
|
+
unsettled.
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- A background task's `taskType` and `description` survive its whole lifetime.
|
|
94
|
+
`task_started` is the only record that names them; the patches and the
|
|
95
|
+
completion notification that follow identify the task by id alone, so every
|
|
96
|
+
finished subagent normalized to `taskType: "unknown"` and hosts rendered
|
|
97
|
+
"Background task completed" for what was plainly a subagent. A completion for
|
|
98
|
+
a task the session never saw start still reports `unknown` rather than
|
|
99
|
+
guessing. The cache is bounded at 512 entries, oldest evicted.
|
|
100
|
+
|
|
101
|
+
- A detached subagent's own output no longer drives the parent session. Claude
|
|
102
|
+
streams a child's assistant text, thinking, and tool calls onto the parent
|
|
103
|
+
stream while the root turn is already over. Anything carrying
|
|
104
|
+
`parent_tool_use_id` is the child working, not the session: it does not open
|
|
105
|
+
a turn, does not move `session.state`, and a child's permission prompt no
|
|
106
|
+
longer parks the parent in `waiting_for_approval` with nothing able to clear
|
|
107
|
+
it.
|
|
108
|
+
|
|
109
|
+
- `session.state` and `turn_start`/`result` agree. A host turn took `thinking`
|
|
110
|
+
from `send()`; a provider-initiated one had nothing to set it, so `state`
|
|
111
|
+
read `idle` for the whole head of every resume turn while `turn_start` had
|
|
112
|
+
already fired.
|
|
113
|
+
|
|
114
|
+
- Turn settling is synchronous with the `result` line. The CLI can flush a
|
|
115
|
+
result and the next turn's opening line in one chunk; deferring the close
|
|
116
|
+
until the event chain drained swallowed the following `turn_start`, and
|
|
117
|
+
deferring the turn's send-resolvers with it let the next turn mistake them
|
|
118
|
+
for its own. The resolvers are appended to a settling list, never assigned
|
|
119
|
+
over — overwriting discarded the earlier turn's resolvers outright, hanging
|
|
120
|
+
that caller's `send()` and deadlocking `drain()` behind it.
|
|
121
|
+
|
|
122
|
+
- Background-task state is tracked from the wire, not from the delivery path.
|
|
123
|
+
It was maintained inside event dispatch, which only runs when a host
|
|
124
|
+
subscribed, so `session.state`, `drain()`, and turn attribution silently
|
|
125
|
+
degraded for a host that reads the session without an `onEvent` handler.
|
|
126
|
+
|
|
127
|
+
- A send resolves with its own turn. `_pendingResults` was a flat queue drained
|
|
128
|
+
by whatever `result` landed next, so a follow-up the CLI had merely queued
|
|
129
|
+
resolved against a turn that never contained it — the host then read
|
|
130
|
+
"finished" for a message still waiting to run. Each entry now carries its
|
|
131
|
+
command uuid and settles only when the turn that claimed it completes. A
|
|
132
|
+
terminal `command_lifecycle` settles a message the CLI retires without
|
|
133
|
+
running, which previously had nothing to settle it at all.
|
|
134
|
+
|
|
135
|
+
- `drain()` waits for provider-initiated turns and for running subagents.
|
|
136
|
+
`_inFlight` only tracks turns the host dispatched, so draining during the gap
|
|
137
|
+
between a root result and the resume turn that follows it — measured at 8-11
|
|
138
|
+
seconds live — SIGTERM'd the CLI and killed the child outright. Background
|
|
139
|
+
*processes* are deliberately excluded: a dev server started with
|
|
140
|
+
`run_in_background` may never exit, and the contract is "let the agent's work
|
|
141
|
+
settle", not "outlive whatever it launched". Bounded by a deadline so a
|
|
142
|
+
wedged turn cannot hang the drain.
|
|
143
|
+
|
|
144
|
+
It also holds across the gap between a task's result being delivered and the
|
|
145
|
+
resume turn it triggers — 24ms for a subagent, 71ms for a background process.
|
|
146
|
+
The task is no longer live by then, so waiting on live tasks alone left
|
|
147
|
+
`drain()` landing in that window and killing the very turn it was extended to
|
|
148
|
+
protect. The delivery record is the provider stating a turn is coming, so it
|
|
149
|
+
is used as one; the wait is released by the next turn to open or close.
|
|
150
|
+
|
|
151
|
+
- Turns opened by a command that ends in `refused`, `discarded`, or `cancelled`
|
|
152
|
+
are closed by that record. Those states never produce a `result`, so nothing
|
|
153
|
+
else would ever close them and the session pinned as working with no path
|
|
154
|
+
back.
|
|
155
|
+
|
|
156
|
+
- Wire lines arriving after `close()` are ignored, and `close()` rejects sends
|
|
157
|
+
still waiting on a turn instead of stranding the caller forever.
|
|
158
|
+
|
|
159
|
+
- `turn_start` carries the `eventId` of the line that opened it, and a minimal
|
|
160
|
+
`raw`. A resume turn is headed by `system/init`, whose payload runs to ~5KB
|
|
161
|
+
of tools, skills, plugins, and MCP config; echoing it whole made hosts that
|
|
162
|
+
persist `raw` pay that for every resume, twice.
|
|
163
|
+
|
|
164
|
+
### Compatibility
|
|
165
|
+
|
|
166
|
+
- Additive at the type level. `turn_start` is a new event type — consumers with
|
|
167
|
+
exhaustive `switch` statements over `StreamEvent` will need a case or a
|
|
168
|
+
default. `report` and `toolUseId` are new required fields on
|
|
169
|
+
`background_task`; every in-tree provider sets them, and both are `null`
|
|
170
|
+
where the provider reports nothing.
|
|
171
|
+
- No behavior change for OpenCode, Cursor, or any other provider. Codex gains
|
|
172
|
+
`report`/`toolUseId` and is otherwise untouched; only the Claude provider
|
|
173
|
+
emits `turn_start`.
|
|
174
|
+
|
|
3
175
|
## 0.0.36 — OpenCode empty-turn follow-ups
|
|
4
176
|
|
|
5
177
|
Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
6
178
|
|
|
179
|
+
### Changed
|
|
180
|
+
|
|
181
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
182
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
183
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
184
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
185
|
+
have its sends resolved by that handler — the failure that made two
|
|
186
|
+
back-to-back results resolve both callers with the first result.
|
|
187
|
+
|
|
188
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
189
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
190
|
+
Modelling one command per turn left every coalesced message permanently
|
|
191
|
+
unsettled.
|
|
192
|
+
|
|
7
193
|
### Fixed
|
|
8
194
|
|
|
9
195
|
- The empty-turn classifier's "finished" guard now lives in `terminalOutcome`,
|
|
@@ -28,6 +214,26 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
28
214
|
Codex's handling of the same action, rather than `agent_error` with a
|
|
29
215
|
JSON-stringified error object.
|
|
30
216
|
|
|
217
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
218
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
219
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
220
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
221
|
+
killed.
|
|
222
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
223
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
224
|
+
bug one layer down: output visible while the session still read as finished.
|
|
225
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
226
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
227
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
228
|
+
moved off it the moment its `result` is read.
|
|
229
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
230
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
231
|
+
delivery and its resume turn wiped the attribution.
|
|
232
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
233
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
234
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
235
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
236
|
+
|
|
31
237
|
### Compatibility
|
|
32
238
|
|
|
33
239
|
- The incomplete-turn note is emitted as `type: "assistant"` (the only surface a
|
|
@@ -39,6 +245,20 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
39
245
|
|
|
40
246
|
## 0.0.35 — Codex turn-boundary correctness and model discovery
|
|
41
247
|
|
|
248
|
+
### Changed
|
|
249
|
+
|
|
250
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
251
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
252
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
253
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
254
|
+
have its sends resolved by that handler — the failure that made two
|
|
255
|
+
back-to-back results resolve both callers with the first result.
|
|
256
|
+
|
|
257
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
258
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
259
|
+
Modelling one command per turn left every coalesced message permanently
|
|
260
|
+
unsettled.
|
|
261
|
+
|
|
42
262
|
### Fixed
|
|
43
263
|
|
|
44
264
|
- A Codex `send()` issued while the previous turn's result was still being
|
|
@@ -183,6 +403,26 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
183
403
|
contract test now checks both directions so a provider cannot declare
|
|
184
404
|
discovery it does not implement, or implement discovery it does not declare.
|
|
185
405
|
|
|
406
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
407
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
408
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
409
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
410
|
+
killed.
|
|
411
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
412
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
413
|
+
bug one layer down: output visible while the session still read as finished.
|
|
414
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
415
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
416
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
417
|
+
moved off it the moment its `result` is read.
|
|
418
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
419
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
420
|
+
delivery and its resume turn wiped the attribution.
|
|
421
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
422
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
423
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
424
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
425
|
+
|
|
186
426
|
### Compatibility
|
|
187
427
|
|
|
188
428
|
- Discovery is curated-list-plus-validation for Claude, not enumeration. A tier
|
|
@@ -229,6 +469,20 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
229
469
|
|
|
230
470
|
## 0.0.34 - Codex collaboration task lifecycle
|
|
231
471
|
|
|
472
|
+
### Changed
|
|
473
|
+
|
|
474
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
475
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
476
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
477
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
478
|
+
have its sends resolved by that handler — the failure that made two
|
|
479
|
+
back-to-back results resolve both callers with the first result.
|
|
480
|
+
|
|
481
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
482
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
483
|
+
Modelling one command per turn left every coalesced message permanently
|
|
484
|
+
unsettled.
|
|
485
|
+
|
|
232
486
|
### Fixed
|
|
233
487
|
|
|
234
488
|
- Codex 0.144 collaboration tool calls now register spawned child threads as
|
|
@@ -241,6 +495,26 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
241
495
|
child-thread, and reconciliation signals. Session shutdown also closes any
|
|
242
496
|
still-active child lifecycle instead of leaving a permanent running state.
|
|
243
497
|
|
|
498
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
499
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
500
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
501
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
502
|
+
killed.
|
|
503
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
504
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
505
|
+
bug one layer down: output visible while the session still read as finished.
|
|
506
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
507
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
508
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
509
|
+
moved off it the moment its `result` is read.
|
|
510
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
511
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
512
|
+
delivery and its resume turn wiped the attribution.
|
|
513
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
514
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
515
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
516
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
517
|
+
|
|
244
518
|
### Compatibility
|
|
245
519
|
|
|
246
520
|
- The change is isolated to Codex collaboration events. Claude and the other
|
|
@@ -264,6 +538,20 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
264
538
|
`getClaudeTaskDetails()` remains available for Claude-native fields and
|
|
265
539
|
accepts legacy `unknown` task events from older agentex versions.
|
|
266
540
|
|
|
541
|
+
### Changed
|
|
542
|
+
|
|
543
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
544
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
545
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
546
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
547
|
+
have its sends resolved by that handler — the failure that made two
|
|
548
|
+
back-to-back results resolve both callers with the first result.
|
|
549
|
+
|
|
550
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
551
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
552
|
+
Modelling one command per turn left every coalesced message permanently
|
|
553
|
+
unsettled.
|
|
554
|
+
|
|
267
555
|
### Fixed
|
|
268
556
|
|
|
269
557
|
- Codex live sessions now track the active root turn and interrupt it with the
|
|
@@ -277,6 +565,26 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
277
565
|
as `aborted`. Interrupt RPC errors propagate to the caller so hosts can show a
|
|
278
566
|
failed Stop action instead of reporting false success.
|
|
279
567
|
|
|
568
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
569
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
570
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
571
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
572
|
+
killed.
|
|
573
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
574
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
575
|
+
bug one layer down: output visible while the session still read as finished.
|
|
576
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
577
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
578
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
579
|
+
moved off it the moment its `result` is read.
|
|
580
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
581
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
582
|
+
delivery and its resume turn wiped the attribution.
|
|
583
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
584
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
585
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
586
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
587
|
+
|
|
280
588
|
### Compatibility
|
|
281
589
|
|
|
282
590
|
- Timeout and AbortSignal cancellation remain best-effort and preserve their
|
|
@@ -286,6 +594,20 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
286
594
|
|
|
287
595
|
## 0.0.32 — Codex root-thread completion isolation
|
|
288
596
|
|
|
597
|
+
### Changed
|
|
598
|
+
|
|
599
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
600
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
601
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
602
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
603
|
+
have its sends resolved by that handler — the failure that made two
|
|
604
|
+
back-to-back results resolve both callers with the first result.
|
|
605
|
+
|
|
606
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
607
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
608
|
+
Modelling one command per turn left every coalesced message permanently
|
|
609
|
+
unsettled.
|
|
610
|
+
|
|
289
611
|
### Fixed
|
|
290
612
|
|
|
291
613
|
- Codex live sessions now pin their root thread and ignore notifications from
|
|
@@ -302,6 +624,26 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
302
624
|
- Live Codex event identity prefers the event's own thread scope while retaining
|
|
303
625
|
the pinned root id as a compatibility fallback for older unscoped events.
|
|
304
626
|
|
|
627
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
628
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
629
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
630
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
631
|
+
killed.
|
|
632
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
633
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
634
|
+
bug one layer down: output visible while the session still read as finished.
|
|
635
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
636
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
637
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
638
|
+
moved off it the moment its `result` is read.
|
|
639
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
640
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
641
|
+
delivery and its resume turn wiped the attribution.
|
|
642
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
643
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
644
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
645
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
646
|
+
|
|
305
647
|
### Compatibility
|
|
306
648
|
|
|
307
649
|
- Unscoped global Codex notifications continue to flow through. The documented
|
|
@@ -355,6 +697,20 @@ Follow-ups to the OpenCode empty-turn handling in 0.0.35.
|
|
|
355
697
|
|
|
356
698
|
## 0.0.30 — Complete Claude and Codex host capabilities
|
|
357
699
|
|
|
700
|
+
### Changed
|
|
701
|
+
|
|
702
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
703
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
704
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
705
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
706
|
+
have its sends resolved by that handler — the failure that made two
|
|
707
|
+
back-to-back results resolve both callers with the first result.
|
|
708
|
+
|
|
709
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
710
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
711
|
+
Modelling one command per turn left every coalesced message permanently
|
|
712
|
+
unsettled.
|
|
713
|
+
|
|
358
714
|
### Fixed
|
|
359
715
|
|
|
360
716
|
- Claude and Codex now declare the resumability, permission, question, and
|
|
@@ -489,6 +845,26 @@ remain source-compatible.
|
|
|
489
845
|
- Codex endpoint header names are emitted as quoted TOML path segments, so
|
|
490
846
|
valid names containing dots cannot become nested configuration keys.
|
|
491
847
|
|
|
848
|
+
- `session.state` no longer follows a detached child. The state machine set
|
|
849
|
+
`thinking` on any assistant line, including a subagent's, so `state` and
|
|
850
|
+
`turn_start`/`result` contradicted each other for the child's entire run —
|
|
851
|
+
measured at 7.6s live — with nothing to clear it if the child was stopped or
|
|
852
|
+
killed.
|
|
853
|
+
- `stream_event` opens a turn. Under `includePartialMessages` the whole
|
|
854
|
+
streamed reply arrived before `turn_start`, which reintroduced the reported
|
|
855
|
+
bug one layer down: output visible while the session still read as finished.
|
|
856
|
+
- A `send()` issued while a turn is settling is no longer classified as
|
|
857
|
+
`resume`. The trigger reads a counter of host messages still awaiting a
|
|
858
|
+
turn; the resolver list cannot answer that, because a turn's resolvers are
|
|
859
|
+
moved off it the moment its `result` is read.
|
|
860
|
+
- `_pendingResumeTaskId` is consumed only by the resume turn it explains. It
|
|
861
|
+
was cleared on every turn open, so a host send landing between a task's
|
|
862
|
+
delivery and its resume turn wiped the attribution.
|
|
863
|
+
- Turn state, the task-fact cache, and the unclaimed-send counter are all
|
|
864
|
+
reset when a session's pending work is rejected (exit, crash, close). A
|
|
865
|
+
`_turnOpen` left set would also suppress the `idle` fallback in
|
|
866
|
+
`handleResult` and pin a dead session as working with no path back.
|
|
867
|
+
|
|
492
868
|
### Compatibility and limits
|
|
493
869
|
|
|
494
870
|
- OpenCode 1.3.2 is the release-tested server schema. Safe disconnect uses
|
|
@@ -505,6 +881,20 @@ remain source-compatible.
|
|
|
505
881
|
|
|
506
882
|
## 0.0.27 — Codex session reasoning effort
|
|
507
883
|
|
|
884
|
+
### Changed
|
|
885
|
+
|
|
886
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
887
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
888
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
889
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
890
|
+
have its sends resolved by that handler — the failure that made two
|
|
891
|
+
back-to-back results resolve both callers with the first result.
|
|
892
|
+
|
|
893
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
894
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
895
|
+
Modelling one command per turn left every coalesced message permanently
|
|
896
|
+
unsettled.
|
|
897
|
+
|
|
508
898
|
### Fixed
|
|
509
899
|
|
|
510
900
|
- **Codex session reasoning effort.** Multi-turn Codex sessions now forward
|
|
@@ -630,6 +1020,20 @@ invisible to callers. `getProvider` stays synchronous; only heavy modules
|
|
|
630
1020
|
The loader defaults to the built-in `acpProvider`; `registerAcpFactory` stays
|
|
631
1021
|
exported and honored as an override hook.
|
|
632
1022
|
|
|
1023
|
+
### Changed
|
|
1024
|
+
|
|
1025
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
1026
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
1027
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
1028
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
1029
|
+
have its sends resolved by that handler — the failure that made two
|
|
1030
|
+
back-to-back results resolve both callers with the first result.
|
|
1031
|
+
|
|
1032
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
1033
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
1034
|
+
Modelling one command per turn left every coalesced message permanently
|
|
1035
|
+
unsettled.
|
|
1036
|
+
|
|
633
1037
|
### Fixed
|
|
634
1038
|
|
|
635
1039
|
- **TDZ crash on direct provider import.** `import("@agentex/agent/providers/gemini")`
|
|
@@ -693,6 +1097,20 @@ A session-scoped **goal** primitive. Attach a durable objective and the library
|
|
|
693
1097
|
- **`GoalController` + reconstruction helpers**, exported for hosts: `goalStateFromEvent`, `latestGoalFromEvents`, `normalizeClaudeGoalAttachment`, `normalizeCodexGoalStatus`, `normalizeCodexGoalRecord`, `createDefaultSentinel`, `parseAssessment`, `isTerminalGoalStatus`, `EMULATED_GOAL_CAPABILITY`, `GOAL_OBJECTIVE_MAX`, `CODEX_GOAL_TOOLS`, plus the `GoalState` / `GoalStatus` / `GoalOptions` / `GoalSentinel` / `SetGoalResult` / `ClearGoalResult` types.
|
|
694
1098
|
- **Native observability + resume.** Claude writes `goal_status` only to the on-disk transcript (never live stdout), so a native goal session tails its transcript to surface `active`→`met` and restores an unmet goal on `--resume`. Codex rehydrates a durable goal on resume via `thread/goal/get`. Both confirmed live.
|
|
695
1099
|
|
|
1100
|
+
### Changed
|
|
1101
|
+
|
|
1102
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
1103
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
1104
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
1105
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
1106
|
+
have its sends resolved by that handler — the failure that made two
|
|
1107
|
+
back-to-back results resolve both callers with the first result.
|
|
1108
|
+
|
|
1109
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
1110
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
1111
|
+
Modelling one command per turn left every coalesced message permanently
|
|
1112
|
+
unsettled.
|
|
1113
|
+
|
|
696
1114
|
### Fixed
|
|
697
1115
|
|
|
698
1116
|
- **Codex failed turns are no longer reported as success.** codex 0.130 signals failure via `turn/completed` with `turn.status: "failed"` (carrying `turn.error.message`), not only `turn/failed` — agentex hardcoded `isError:false`, so a failed turn (e.g. a 4xx from the model API) looked `completed`. The parser + session now detect the failed status and the trailing `error` notification, reporting `status:"failed"` with the error text. Verified live.
|
|
@@ -724,6 +1142,20 @@ Additive. The instruction-file twin of `installSkills`: install an orientation b
|
|
|
724
1142
|
|
|
725
1143
|
Driven by consumer feedback from an embedding host wiring an orchestrator onto agentex sessions. All additive — except the MCP fix, which replaces behavior that never worked in any published version.
|
|
726
1144
|
|
|
1145
|
+
### Changed
|
|
1146
|
+
|
|
1147
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
1148
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
1149
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
1150
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
1151
|
+
have its sends resolved by that handler — the failure that made two
|
|
1152
|
+
back-to-back results resolve both callers with the first result.
|
|
1153
|
+
|
|
1154
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
1155
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
1156
|
+
Modelling one command per turn left every coalesced message permanently
|
|
1157
|
+
unsettled.
|
|
1158
|
+
|
|
727
1159
|
### Fixed
|
|
728
1160
|
|
|
729
1161
|
- **`config.mcpServers` actually attaches MCP servers now.** It previously emitted `--mcp-server <name> -- <command>…` — a flag that does not exist in Claude Code 2.x — so any run/session setting the field died instantly with `error: unknown option '--mcp-server'` (verified against claude 2.1.165; the field has never worked in any published version, so there is no behavior to migrate from). The config is now staged as a **mode-0600 JSON file** in a temp dir and passed via the real `--mcp-config <path>`, cleaned up with the run/session (including spawn-failure paths). Secrets never touch argv — http `headers` (bearer tokens) live only in the 0600 file; argv is world-readable via `ps`.
|
|
@@ -759,6 +1191,20 @@ A three-tier provider architecture (deep-native · ACP · bespoke). The ACP tier
|
|
|
759
1191
|
- **Codex collaboration modes.** `codexProvider.listModes()` discovers Codex's collaboration modes via `collaborationMode/list`; `config.modeId` applies a chosen mode to a fresh `thread/start` (a resumed thread keeps its original mode). `capabilities.modes` is now `true` for Codex.
|
|
760
1192
|
- **Codex structured questions.** The app-server `requestUserInput` (and legacy `tool/requestUserInput`) server→client request is now bridged to `onUserInputRequest` as an `AskUserQuestion`, with answers mapped back into Codex's `{ answers: { [id]: { answers: [] } } }` shape — Codex sessions can answer questions headlessly.
|
|
761
1193
|
|
|
1194
|
+
### Changed
|
|
1195
|
+
|
|
1196
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
1197
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
1198
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
1199
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
1200
|
+
have its sends resolved by that handler — the failure that made two
|
|
1201
|
+
back-to-back results resolve both callers with the first result.
|
|
1202
|
+
|
|
1203
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
1204
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
1205
|
+
Modelling one command per turn left every coalesced message permanently
|
|
1206
|
+
unsettled.
|
|
1207
|
+
|
|
762
1208
|
### Fixed
|
|
763
1209
|
|
|
764
1210
|
- **Codex tool-approval response shape.** Command/file approval requests are now answered with `{ decision: "accept" | "decline" }` (Codex's actual app-server contract) instead of `{ approved: boolean }`, which the app-server did not honor. Tool-permission gating in Codex sessions now works headlessly.
|
|
@@ -796,6 +1242,20 @@ Scheduled / fire-and-forget session runs needed three things the SDK pushed onto
|
|
|
796
1242
|
|
|
797
1243
|
- **`SendHandle`, `SendOptions`, `CancelResult`** are now exported from the package entry point (previously only the `AgentSession` interface was).
|
|
798
1244
|
|
|
1245
|
+
### Changed
|
|
1246
|
+
|
|
1247
|
+
- Turn, command, and task state is now reduced from the ordered wire in one
|
|
1248
|
+
place, rather than held in mutable fields updated across `await` boundaries.
|
|
1249
|
+
Each turn's settlement batch is captured synchronously before any suspension
|
|
1250
|
+
point, so a turn that opens while an earlier handler is still draining cannot
|
|
1251
|
+
have its sends resolved by that handler — the failure that made two
|
|
1252
|
+
back-to-back results resolve both callers with the first result.
|
|
1253
|
+
|
|
1254
|
+
- A turn owns a *set* of command uuids. The CLI coalesces: a host message
|
|
1255
|
+
dequeued while a turn is running joins that turn instead of starting its own.
|
|
1256
|
+
Modelling one command per turn left every coalesced message permanently
|
|
1257
|
+
unsettled.
|
|
1258
|
+
|
|
799
1259
|
### Fixed
|
|
800
1260
|
|
|
801
1261
|
- **Session `close()` now honors `ProviderConfig.graceSec`** for the SIGTERM → SIGKILL window (was hardcoded to 5s, ignoring the config field that `execute()` already respected). `drain()` uses the same configurable grace.
|