Skip to content

Commit 72f7aa7

Browse files
committed
docs: changelog entries for OpenAI Responses toolCalls, Gemini Live, AG-UI usage, CLI signal fixes
1 parent e152680 commit 72f7aa7

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- **AG-UI `RUN_FINISHED` and `RUN_ERROR` events now carry an optional `usage` field.** AG-UI's canonical `events.ts` declares an optional `usage: TokenUsage[]` on both terminal event schemas, but aimock's event interfaces carried neither. A new exported `AGUITokenUsage` type — numeric-only, mirroring `@ag-ui/core`'s `TokenUsageSchema` field for field (`provider` / `model` labels plus non-negative-integer `inputTokens`, `outputTokens`, `totalTokens`, `reasoningTokens`, `cachedInputTokens`, and no content-bearing or identifying fields) — is added as `usage?: AGUITokenUsage[]` on `AGUIRunFinishedEvent` and `AGUIRunErrorEvent`, and exported from both the package root and the `agui-stub` entrypoint. The field is reachable, not merely declarative: `AGUIBuildOpts` gains a `usage` option that is threaded to the terminal `RUN_FINISHED` of every builder and to `RUN_ERROR` in `buildErrorResponse`. Following the repo's existing usage policy (Bedrock / Cohere / Gemini), token counts are never synthesized from fixture content — `usage` is emitted only when a caller supplies it explicitly, so existing callers see byte-identical events. It is an array so a run that invokes multiple models keeps their counts separate (#378)
8+
59
### Changed
610

711
- `POST /__aimock/reset` is now the canonical full reset and returns a plain `{ "reset": true }` with no deprecation header or body fields. `POST /__aimock/reset/journal` is unaffected.
@@ -15,6 +19,12 @@
1519
- `POST /__aimock/reset/fixtures` — now a deprecated alias for `POST /__aimock/reset`. The name promised a fixtures-only reset while it always performed the full reset, so `/reset` is the honest route and the deprecation moves onto the alias: it still performs the same full reset but emits a `Deprecation: true` response header, `deprecated` / `deprecation` fields in the body, and a log warning. Use `POST /__aimock/reset` for a full reset, `POST /__aimock/reset/journal` for a journal-only one, or `DELETE /__aimock/fixtures` to clear fixtures and nothing else.
1620
- The alias's **reset semantics are unchanged** — it clears exactly what it always did, so existing callers keep working. Its **response body is additively extended**: it now carries `deprecated` and `deprecation` alongside `reset`, plus the `Deprecation: true` header. A caller asserting strict equality on the old `{ "reset": true }` body will need to relax that assertion; a caller reading `body.reset` is unaffected.
1721

22+
### Fixed
23+
24+
- **Recording a tool-call turn over the OpenAI Responses API now collapses to `toolCalls` instead of an empty assistant turn.** `collapseOpenAISSE` handled Responses-API text, reasoning and web-search output items but let a catch-all (`if (parsed.type?.startsWith("response.")) continue;`) silently skip the entire function-call sequence — `response.output_item.added` for a `function_call` item, `response.function_call_arguments.delta` / `.done`, and `response.output_item.done` for a `function_call`. A tool-call-only turn therefore collapsed to empty `content` with no `toolCalls` (logged `Stream collapse produced empty content — fixture may be incomplete`), and replaying that fixture yielded an empty assistant turn with no tool invocation. Only fresh Responses-API recordings broke, because the older Chat-Completions path already accumulated `choices[0].delta.tool_calls`. aimock now accumulates the function-call events into the existing tool-call map keyed by `output_index`, capturing the Responses `call_id` (the id a tool result references — **not** the internal `fc_…` item id) as the tool-call `id`, and emits `{ id, name, arguments }` with arguments normalized to valid JSON — identical to the Chat-Completions shape and the checked-in fixtures. Scope: this fixes the stream collapser only; it does not address the fixture-capture race in which a post-tool-result turn can still be draining when the capture probe exits (#380)
25+
- **A Gemini Live turn that both speaks and calls a function is now expressible over the Live protocol, and an audio turn keeps its companions.** The Live handler's audio branch emitted a single `serverContent` frame (audio `inlineData` + `turnComplete: true`) and returned, silently dropping the `toolCalls` and text `content` that `AudioResponse` documents as preserved. Because `serverContent` and `toolCall` are alternatives of one `LiveServerMessage` union (not sibling parts of a single list as on HTTP `generateContent`), a speak-and-call turn is now emitted as separate messages in the order the live provider was observed to use: a `serverContent` (`modelTurn.parts` = audio first, then the text companion) strictly **before** the `toolCall` (`functionCalls`), then a final `serverContent{ turnComplete: true }`. The assistant entry pushed to conversation history now records the recorded text `content` (instead of the literal `"[audio]"`) and the tool calls, with tool-call ids resolved once so the wire message and history agree. An audio-only turn (no `toolCalls`) is unchanged except that it now includes its text companion part when the fixture carries one. Not handled: `AudioResponse.reasoning` — this handler emits no thought channel in any branch, so replaying reasoning from the audio branch alone is deliberately left out as a separate gap (#378)
26+
- **The CLI installs its `SIGINT` / `SIGTERM` handlers before announcing readiness, so a supervisor that shuts the server down the instant it starts no longer kills it ungracefully.** Previously the CLI logged `aimock server listening on <url>` and only then registered the signal handlers. Pipe writes are synchronous on Linux, so a supervisor reacting to that readiness line could deliver `SIGTERM` while the process was still mid-statement, in the window before the handler existed; the signal reached Node's default disposition, which re-raises it, and the process died with a null exit code without running its own shutdown (closing the file watcher and the server) — most visible under container / process supervisors. Both entrypoints (`cli.ts` and `aimock-cli.ts`) now register the handlers first and log readiness last, closing that race (observed on linux/node20 by freezing the child at the announcement: 55/60 iterations died with `code=null signal=SIGTERM` before the change, 0/60 after). The handlers are installed once the server is already listening, so a signal delivered during earlier startup — strictly before readiness — remains outside their scope (#374)
27+
1828
## [1.38.0] - 2026-08-03
1929

2030
### Added

0 commit comments

Comments
 (0)