Skip to content

chore(deps): update dependency @copilotkit/aimock to v1.35.0#820

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/copilotkit-aimock-1.x
Open

chore(deps): update dependency @copilotkit/aimock to v1.35.0#820
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/copilotkit-aimock-1.x

Conversation

@renovate

@renovate renovate Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@copilotkit/aimock (source) 1.15.11.35.0 age confidence

Release Notes

CopilotKit/aimock (@​copilotkit/aimock)

v1.35.0

Compare Source

Added
  • Native Google Veo async video lifecycle mock — POST /v1beta/models/{model}:predictLongRunning submit, GET /v1beta/operations/{name} poll through done:false → done:true, poll-count progression via veoVideo; the Files-API uri is served as-is (aimock never proxies or downloads video bytes) (#​278)
  • Record-mode live proxying for the Veo surface (record.providers.veo) — submit and poll forwarded 1:1, eager fixture capture of the Files-API uri on done:true; captured operations replay later (#​278)
  • Native xAI Grok Imagine async video lifecycle mock — POST /v1/videos/generations submit (JSON-only; multipart rejected with 400), GET /v1/videos/{request_id} poll through pending → done | failed | expired with synthesized progress, grokVideo progression, cost_in_usd_ticks units, and a Sora-safe /v1/videos/{id} dispatch that leaves the OpenAI video surface unchanged (#​278)
  • Record-mode live proxying for the Grok surface (record.providers.grok) — submit and poll forwarded 1:1, eager fixture capture of url/duration/cost on done, failed persisted, expired passed through; captured jobs replay later (#​278)
  • Optional blocks array on the combined content + toolCalls fixture shape lets a fixture express ordered text/tool-call blocks ({type:"text",text} | {type:"toolCall",name,arguments,id?}); when present it takes precedence over {content, toolCalls} for stream order, enabling tool-first and interleaved ordering. Legacy {content, toolCalls} fixtures are unchanged (#​274)
  • All five providers stream combined responses in fixture block order: Anthropic, OpenAI Responses, and Gemini are fully observable; Ollama is best-effort (clients may reassemble positionally); OpenAI chat-completions emits in order but is degenerate (delta.content/delta.tool_calls are separate channels the client merges) (#​274)
  • Recorder captures block order and persists blocks only when the recorded upstream stream was genuinely tool-first or interleaved; text-first streams keep the legacy {content, toolCalls} shape so golden recordings round-trip byte-identically (#​274)
  • Blocks-only fixtures are first-class: a non-empty blocks array is a complete response shape on its own, with no content/toolCalls required — builders derive the aggregate from the blocks and validateFixtures() accepts the shape (#​274)
  • Block ordering is now honored on replay across the remaining providers — Cohere (streaming), Bedrock invoke, Bedrock Converse, and Gemini Interactions — so a tool-first or interleaved fixture streams its tool call ahead of its text wherever the wire protocol can express it (#​274)
  • Record-side block capture extends to the Cohere and Bedrock collapsers; Gemini Interactions normalizes tool-call arguments only and does not reorder blocks on capture (its step-index protocol can't reconcile arrival-order blocks at record time), while replay still honors a hand-authored blocks array (#​274)
  • validateBlocks rejects a malformed blocks array at load time — non-array, non-object entries, a type other than text/toolCall, a non-string or empty-string text block, or a toolCall block missing a name or carrying non-JSON arguments — and warns when a fixture carries both blocks and divergent content/toolCalls, so a bad array never reaches a builder mid-dispatch (#​274)

v1.34.0

Compare Source

Changed
  • Replay matching is content-anchored: turnIndex disambiguates, no longer a hard reject gate (#​276)
  • Empirical over 9769 real requests: 3213 false-miss fixes, 0 new misses, 0 wrong-fixture (#​276)
  • Diverges only on off-by-N assistant count in either direction (behind OR ahead of turn) (#​276)
  • New turnIndexRelaxed match diagnostic + one-shot logger warn on a divergent relaxed serve (#​276)
  • AIMOCK_STRICT_TURN_INDEX=1 restores the legacy strict turnIndex gate for replay (#​276)
Fixed
  • Gemini Interactions mock now emits the SDK 2.x event protocol on both paths — streamed SSE (step.*, interaction.created/completed, tool args via arguments_delta) and non-streaming responses (steps/output_text); legacy 1.x recorded fixtures still parse (#​279)

v1.33.0

Compare Source

Added
  • --max-proxy-buffer-bytes / --max-proxy-buffer-frames flags to cap proxy buffering (#​275)
Fixed
  • Proxy path no longer leaks memory on long-lived upstream streams (#​275)
  • Oversized proxied responses no longer crash with Invalid string length (#​275)
  • Sanitize X-AIMock-Context to prevent fixture path traversal (#​272)
  • Scope one-shot error injection, improve recorder fixture fidelity, fix matchesPattern lastIndex (#​272)

v1.32.0

Compare Source

Added
  • fal queue status/result responses now emit x-fal-request-id, and a billableUnits fixture field (e.g. onFalQueue(model, json, { billableUnits })) emits x-fal-billable-units on the completed result so adapters like @tanstack/ai-fal can surface usage.unitsBilled on replay. Record mode captures the upstream x-fal-billable-units header automatically, so recorded fixtures round-trip billing with no hand-editing (#​269)

v1.31.0

Compare Source

Added
  • OpenRouter async video job lifecycle mock — submit, poll, content download, model listing (#​262)
  • Record-mode live proxying for the OpenRouter video surface; captured videos replay later (#​265)
Changed
  • Recording proxies now strip aimock-internal control headers on every provider path (#​265)
Fixed
  • Recorder and fal record paths hardened — timeouts, threshold sanitizing, persist errors (#​265)
  • attw ^0.18 fixes the test:exports crash (#​263); OpenAI /v1/videos docs corrected (#​264)

v1.30.0

Compare Source

Added
  • Extended-thinking request invariants — aimock now validates Anthropic extended-thinking continuations on the tool-use loop. When extended thinking is enabled, a continuation whose prior assistant turn drops the leading thinking block (or its signature, or a redacted_thinking block's data) is rejected with the real Anthropic 400, instead of producing a false-green replay — under strict mode; otherwise the violation warns and replay proceeds. Emitted thinking blocks now carry a non-empty placeholder signature so record→replay round-trips stay green across text, content+tool, and tool-only response shapes.
  • Faithful reasoning capture + replay — the recorder now preserves provider reasoning artifacts that recording previously dropped. Anthropic thinking-block signatures (the signature_delta wire event on the streaming paths; each thinking block's signature field non-streaming) and redacted_thinking block data are captured across all three Anthropic capture paths — the SSE stream collapser, the Anthropic-native binary frames on Bedrock invoke-with-response-stream (thinking_delta/signature_delta/redacted_thinking), and the non-streaming JSON recording path. Bedrock Converse reasoningContent deltas and Cohere thinking content-deltas are captured into reasoning, and a recorded Anthropic reasoningSignature plus any redactedThinking payloads are written into the saved fixture (TextResponse / ToolCallResponse / ContentWithToolCallsResponse). On replay, Anthropic emits the recorded signature when one was captured and otherwise falls back to the round-trip-safe placeholder, and recorded redactedThinking payloads are replayed as faithful leading redacted_thinking content blocks (streaming content_block_start/content_block_stop with the opaque data, non-streaming content-array blocks), across both streaming and non-streaming text, content+tool, and tool-only response shapes. The encrypted reasoning artifacts (reasoningSignature and redactedThinking) are gated on the same model-capability resolution as the plaintext reasoning channel, so replaying a reasoning-model fixture against a non-reasoning model under strict mode suppresses the thinking, signature, and redacted_thinking channels together rather than leaving the encrypted blocks half-gated. Fidelity caveat: the interleaving of thinking and redacted_thinking blocks and per-block signatures are not preserved — all recorded redacted_thinking blocks replay as a leading group, and the merged thinking block carries the signature of the last thinking block that actually emitted one (a signature-less block does not clobber an earlier signature).
Changed
  • Reasoning emission — replaying a reasoning channel is now gated on the requested model's capability. aimock no longer synthesizes a reasoning channel (chat reasoning_content / Responses reasoning_summary_text / Anthropic thinking / etc.) for models that would not emit reasoning against the real provider. A new isReasoningModel classifier and resolveReasoningForModel gate are applied across OpenAI chat + Responses, Anthropic, Ollama, Gemini, Cohere, Bedrock (invoke + Converse), and WebSocket Responses: a non-reasoning model paired with a reasoning fixture has its reasoning suppressed under strict mode, or warns-and-emits otherwise. The AIMOCK_REASONING_MODELS and AIMOCK_NONREASONING_MODELS env vars override the classifier.
  • Tool-only reasoning emission — the capability gate now also covers the tool-call-only response path of every provider (OpenAI chat + Responses, Cohere, Bedrock invoke + Converse, Ollama, WebSocket Responses, and the Gemini chat tool-only path). Previously a tool-only fixture carrying reasoning dropped the reasoning channel entirely; it now emits the provider-native reasoning channel for reasoning-capable models and is suppressed under strict mode (or warns-and-emits otherwise), matching the text and content+tool paths, with leading reasoning blocks shifting streaming tool/output indices by one where applicable. The Gemini audio companion's reasoning is now capability-gated as well.
  • Strict-mode 503 now distinguishes sequence/turn exhaustion from a true no-match: when candidate fixtures matched the request shape but were skipped by sequenceIndex/turnIndex count state, the 503 message and error log read N candidate fixture(s) skipped by sequence/turn state instead of the generic no fixture matched. HTTP status (503) and error envelope shape are unchanged. Applied across all strict-mode emission sites via a shared helper. Design notes: the skip diagnostic is captured from the same single matcher pass that performs the match — stateful match.predicate functions fire exactly once per request — and the hasToolResult shape predicate is evaluated before the sequenceIndex/turnIndex state gates, so the skip count only includes fixtures whose request shape actually matched.
Fixed
  • Recorder — pathological-but-real Anthropic turns (thinking-only with empty text, redacted-only, redacted blocks with empty data) now record as normal empty-content fixtures instead of "Could not detect response format" error fixtures, with streaming/non-streaming parity.
  • redacted_thinking blocks with empty data are filtered at every capture site via one shared predicate, matching the strict replay validator — a recorded fixture can no longer 400 on replay for data the validator rejects (record-green ⇒ replay-green).

v1.29.0

Compare Source

Added
  • POST /__aimock/reset/fixtures — full reset (clears fixtures, generation state, and journal).
  • POST /__aimock/reset/journal — clears only the request journal, leaving fixtures intact.
  • aimock-pytest: reset_fixtures() and reset_journal() client methods.
  • Control API reference documentation.
Changed
  • engines.node lowered to >=20.15.0. The runtime supports Node 20 (the published CLI runs on Node 20/22/24); the previous >=24.0.0 floor reflected an OIDC publish-time requirement, which is a CI concern handled by the publish workflow, not a runtime constraint for consumers.
Deprecated
  • POST /__aimock/reset — now a deprecated alias for /__aimock/reset/fixtures; it still performs a full reset but emits a Deprecation response header and a deprecated field in the body. Use the explicit /reset/fixtures or /reset/journal routes instead.
Fixed
  • VideoPOST /v1/videos (videos.create) now parses multipart/form-data bodies. The OpenAI SDK (>=6.28.0) sends video-create requests as multipart instead of JSON (even for File-less bodies), which previously returned a 400 invalid_json. The handler reuses the existing transcription multipart field parser and preserves the JSON path for older SDKs.
  • aimock-pytest: per-fixture options passed via add_fixture/on_message/etc. (latency, chunkSize, sequenceIndex, chaos, …) are now forwarded in the correct wire shape. They were previously nested under an opts key the server ignored, so they were silently dropped.
  • aimock-pytest: _wait_for_ready now honors its startup timeout (a background reader thread drains the child's stdout, so a no-output child can no longer hang past the deadline or deadlock on a full pipe buffer), tears down the subprocess on a startup failure, and surfaces the child's captured output (the health-check failure path also reports accurate elapsed time).
  • DELETE /v1/_requests now clears only the request-journal entries, preserving fixture match-counts (so sequenced fixtures are not rewound) — consistent with POST /__aimock/reset/journal.

v1.28.0

Compare Source

Added
  • Harmony channel format — parse OpenAI "harmony" channel tokens (<|channel|>… <|message|>… <|call|>) emitted by local gpt-oss models (Ollama / vLLM / OpenRouter) so their tool calls, reasoning, and content are captured when recording (hosted OpenAI pre-parses harmony, so only local runtimes pass it through raw). Implemented as a lexer + state-machine parser with a uniform all-or-nothing verbatim fail-safe, wired as fallback-only so it never produces phantom tool calls.
Fixed
  • Recorder — decode streamed response chunks incrementally to prevent multibyte UTF-8 corruption; CRLF-tolerant frame-timing splitter; propagate webSearches and audio-companion fields (tool calls / content / reasoning) into recorded fixtures; log firstDroppedSample alongside dropped-chunk warnings.
  • Stream collapsers — multi-line and CRLF SSE handling; missing/uncorrelated tool-call index guards with symmetric dropped-chunk accounting across OpenAI / Anthropic / Bedrock / Cohere; bound Bedrock EventStream header parsing against malformed frames.
  • Gemini — replay audio-companion tool calls / content / reasoning on audio turns instead of dropping them.

v1.27.3

Compare Source

Fixed
  • correct OpenAI images endpoint path from /v1/images/edit to /v1/images/edits (closes #​221)
  • add Ollama /api/embed route as alias for /api/embeddings; /api/embed is the current documented endpoint (ollama/ollama docs/api.md) used by modern Ollama SDKs, while /api/embeddings is retained for backwards-compatibility. Both routes dispatch to the same handler.

v1.27.2

Compare Source

Fixed
  • Fixture loader — full recursive directory traversal replaces 2-level cap; supports per-integration showcase layouts like d6/<integration>/<feature>.json.
Changed
  • Docker image — added git binary to production stage for sparse-checkout fixture fetching at boot.

v1.27.1

Compare Source

Fixed
  • Router — systemMessage array exact-match logic was unsatisfiable for 2+ needles; collapsed to substring matching. Added elevenlabs-tts and translation to endpoint compatibility filter.
  • Recorder — Content-Type empty-string fallback (??||), derived EndpointType from FixtureMatch instead of duplicate union, negative guards on Gemini Interactions outputs detection, scoped turnIndex/hasToolResult to chat endpoints only.
  • WS-Realtime — session.update rollback now captures full snapshot instead of just model/type. Added Beta flat fields for noise reduction, transcription, and turn_detection. Joined all text content parts in realtimeItemsToMessages. Added try-catch with debug logging around sendEvent for WebSocket close race safety.
  • WS-Gemini-Live — replaced deterministic call_gemini_${name}_${i} tool call IDs with random generateToolCallId() to prevent cross-turn collisions. Pre-computed resolvedToolCalls for wire/history ID consistency. Added unrecognized-role warning and ws.send try-catch with debug logging.
  • Gemini InteractionsinteractionsUsage honors Gemini-native field names (promptTokenCount/candidatesTokenCount/totalTokenCount). truncateAfterChunks only counts content.delta events. Added webSearches warning on tool-call branch.
  • fal-audio + ElevenLabs — all journal entries now use flattenHeaders(req.headers) instead of {}. handleSyncRun accepts RawJSONResponse fixtures from queue-walk recordings.
  • Helpers — extended resolveUsage with Gemini-native token fields. Preserved error cause in resolveResponse factory rethrow. buildEmbeddingResponse accepts optional usage. extractFormField escapes regex metacharacters.
  • Drift test infra — retry logging with body consumption, broadened redactUrl to cover api_key/apikey/token/access_token patterns, URL threaded into error messages with redaction, parseDataOnlySSE [DONE] filter fix, parseTypedSSE multi-line data handling with null guards.
  • Drift collector — invoke vitest directly via npx to avoid pnpm stdout prefix breaking JSON parse; classify raw stack traces as infrastructure errors instead of crashing.
  • AG-UI config loader — removed /.*/ catch-all regex fallback when match.message is absent; fixtures without a message pattern no longer shadow other fixtures.
  • AG-UI input validation — runtime check that input.messages is an array after JSON parse; returns 400 instead of confusing downstream 404.
  • AG-UI SSE writerwriteAGUIEventStream uses logger abstraction instead of console.warn; handles non-Error throws.
  • Drift test helpersparseDataOnlySSE handles multi-line data blocks, aligned with providers.ts implementation.

v1.27.0

Compare Source

Added
  • HITL continuation recording/replay supporttoolCallId matching for continuation fixtures. New toolCallId field on AGUIFixtureMatch and AGUIConfigFixture. getLastMessageIfToolResult helper and onToolResult fluent API. Recorder uses tool-result-first priority for continuation fixtures. (#​233, closes #​232)
Fixed
  • Walk structured content arrays in extractLastUserMessage — handle multimodal user content (AGUIMessageContentPart[]) by joining text parts and skipping non-text. Export NO_USER_MESSAGE_SENTINEL constant and AGUIMessageContentPart type. (#​231)
  • Harden recorder against error responses, double-settle, and broken sentinel persistence — guard against recording fixtures from non-2xx upstream responses, add settled flag to prevent error+end race, skip disk write for predicate fixtures (sentinel was semantically broken on reload), include parse error reason in SSE warning log

v1.26.1

Compare Source

Added
  • Context-based fixture routingX-AIMock-Context header scopes fixtures per integration. Fixtures with match.context only match requests carrying that context; fixtures without context remain shared. Recorder auto-captures context and routes recorded fixtures into context subdirectories.

v1.26.0

Compare Source

Added
  • Timing-aware recording and replay — proxy recording captures per-frame
    arrival timestamps as recordedTimings on fixtures. Replay uses recorded
    timings for approximate timing reproduction based on recorded TTFT and
    inter-frame cadence instead of the synthetic model. Replay chunk count may
    differ from recording chunk count — TTFT and average pace are preserved,
    not per-token fidelity. --replay-speed N multiplier applies to all delay
    sources (recorded timings, streaming profiles, global latency). Per-fixture
    replaySpeed override. Covers SSE, NDJSON, Bedrock EventStream, and
    WebSocket protocols.

v1.25.0

Compare Source

Added
  • Gemini embedContent endpointPOST /v1beta/models/{model}:embedContent
    with deterministic fallback embeddings and fixture matching
  • /v1/images/edit and /v1/images/variations endpoints — multipart
    form-data, same response format as generations. Closes #​221
  • /v1/audio/translations endpoint — reuses transcription handler with
    endpoint: "translation" and task: "translate" in verbose mode
  • Ollama /api/embeddings endpoint — single-embedding response, supports
    both prompt and input (string or array) fields
  • Cohere /v2/embed endpoint — multi-text embedding with configurable
    embedding_types (float, int8, etc.)
  • ElevenLabs /v1/text-to-speech/{voice_id} endpoint — binary audio
    response with voice routing and onElevenLabsTTS helper
  • Streaming usage chunks — when stream_options.include_usage is set,
    emits a final SSE chunk with token usage before [DONE]
  • Automatic token usage estimation — responses without explicit fixture
    usage overrides now return estimated token counts (~4 chars/token)
    instead of zeros
  • Rate limiting headers on 429 responsesRetry-After,
    x-ratelimit-limit-*, x-ratelimit-remaining-*,
    x-ratelimit-reset-* headers on all error fixtures with status 429.
    Custom retryAfter override via fixture field
  • onTranslation convenience method — register translation fixtures
    with endpoint discrimination
  • onElevenLabsTTS convenience method — register ElevenLabs TTS
    fixtures
  • Configurable proxy timeoutsRecordConfig now accepts upstreamTimeoutMs (default 30s) and bodyTimeoutMs (default 30s). The body-idle timeout is the Node socket inactivity timer that fires req.destroy() mid-stream; under concurrent load against reasoning models (e.g. Grok 4.3 + structured output), token-emission gaps can routinely exceed 30s during the thinking phase, causing record-mode runs to truncate SSE responses mid-stream with no [DONE] and no finish_reason. Lift to e.g. bodyTimeoutMs: 180_000 to record cleanly under that workload.

v1.24.1

Compare Source

Fixed
  • Gemini tool-call response serializer dropped fixture-pinned tool_call.idparseToolCallPart emitted { functionCall: { name, args } } and omitted the id even when the fixture pinned one. Pairs with v1.23.1's INGEST-direction fix (#​196) which preserves functionCall.id when aimock parses an incoming Gemini request — that fix only helps when the id is already in the response body. Without this EGRESS-direction fix, aimock never emits one for clients to preserve in the first place, so the round-trip silently breaks for any client that depends on functionCall.id to correlate follow-up functionResponse parts back to the originating call

v1.24.0

Compare Source

Added
  • onFalImage(pattern, ImageResponse) — typed helper that wraps ImageResponse into fal's image envelope
  • onFalVideo(pattern, VideoResponse) — typed helper that wraps VideoResponse into fal's video envelope
  • MockServerOptions.falQueue — opt into realistic IN_QUEUE → IN_PROGRESS → COMPLETED polling progression with configurable thresholds
  • Queue status responses include logs[] (state-transition entries) and metrics.inference_time (once COMPLETED)
  • Cancel-before-completion returns 200 { status: "CANCELLED" }; cancel-after returns 400 { status: "ALREADY_COMPLETED" }
  • Result fetch before completion returns 202 with current status body
  • Queue-walk recording: recorder now walks the upstream fal queue (submit → poll → result) and persists the FINAL job body, not the submit envelope
  • RecordConfig.fal.pollIntervalMs / fal.timeoutMs for tuning upstream queue-walk recording cadence
  • Malformed JSON request bodies now return 400 invalid_json (consistent with all other handlers)
Fixed
  • pollsBeforeCompleted auto-defaults to pollsBeforeInProgress + 1 when only the in-progress threshold is set
  • URL extension extraction no longer produces invalid MIME types for URLs with query strings, fragments, or no extension
  • Double-cancel no longer pushes duplicate log entries
  • Legacy fal audio queue recording now uses the same queue-walk approach
Changed
  • Default fal queue-walk timeout bumped from 2 min to 15 min (video generations routinely take 5–10 min)
  • persistFixture and buildFixtureMatch extracted from recorder internals and exported for reuse

v1.23.1

Compare Source

Fixed
  • Gemini functionCall.id preservation — the Gemini conversation history converter generated new tool call IDs (call_gemini_*) instead of preserving the original IDs from functionCall.id. This broke toolCallId-based fixture matching on follow-up turns: the follow-up fixture couldn't match because the ID was overwritten, so the request fell through to userMessage fixtures which returned another tool call — creating an infinite loop for all Gemini/ADK showcase integrations. LangGraph-python (OpenAI format) was unaffected because it preserves IDs natively. (#​196)

v1.23.0

Compare Source

Added
  • Model-aware fixture recording — recorded fixtures now include the model name in match criteria, preventing collisions when an app makes multiple LLM calls with the same user message but different models. Model names are normalized by stripping date/version suffixes (e.g., claude-opus-4-20250514claude-opus-4) so fixtures survive version bumps. Disable with recordFullModelVersion: true. (#​185)
  • Drift detection metadata — recorded fixtures include systemHash and toolsHash in a metadata block for detecting system prompt or tool definition changes since recording.
  • Prefix model matching — fixture router uses startsWith for string model matching, so model: "claude-opus-4" matches any claude-opus-4-* version.
  • GA Realtime protocol migration with Beta compatibility shim — handler emits GA event names natively; sendEvent() wrapper translates back for Beta clients detected via OpenAI-Beta header. Default model changed to gpt-realtime-2.
  • GA Realtime modelsgpt-realtime, gpt-realtime-2, gpt-realtime-1.5, gpt-realtime-mini (and dated snapshots). Transcription/translation sessions use gpt-4o-transcribe, gpt-4o-mini-transcribe, or whisper-1.
  • Transcription and translation session types — dedicated session configurations for translation and transcription workloads on the Realtime API.
  • Image input support — Realtime sessions accept image content parts alongside text and audio.
  • Commentary phase — Realtime handler supports the GA commentary phase for model-generated annotations.
  • conversation.item.done and response.cancel events — new GA Realtime event types for item completion tracking and response cancellation.
  • Endpoint type routing for Realtime — router distinguishes GA vs Beta Realtime endpoints for fixture matching.
  • Drift detection for GA Realtime — drift test suite extended with GA protocol shapes, Beta conformance shapes, and three-way triangulation.
Tests
  • 73 GA Realtime integration tests — comprehensive test coverage for all GA event types, Beta compatibility, session management, model routing, image input, translate/whisper, commentary, and cancellation.
  • GA and Beta Realtime conformance suites — API conformance tests validating event shapes against both GA and Beta protocol specs.
  • GA Realtime drift detection — SDK shape tests and provider triangulation for the GA Realtime protocol.

v1.22.1

Compare Source

Fixed
  • Strict mode checked before proxy attempt — in --proxy-only mode, the X-AIMock-Strict header had no effect because proxyAndRecord() returned before the strict check. Now all 17 handlers check strict mode first: when strict + no fixture → 503 immediately, no proxy attempt
  • Helper utilities and error serialization — hardened helper functions and error serialization paths for correctness and robustness
  • Journal and fixture-loader correctness — fixed journal entry handling and fixture-loader edge cases
  • WebSocket handler consistency and strict-mode journal — aligned WebSocket handler behavior and ensured strict-mode journal entries are recorded correctly
  • Provider handler consistency and proxy outcomes — unified provider handler error paths and proxy outcome reporting
  • Media handler hardening and chaos injection — strengthened media handler validation and chaos injection reliability
Tests
  • Bedrock mock consistency and CLI help text — corrected Bedrock mock test assertions and CLI --help output coverage

v1.22.0

Compare Source

Added
  • Per-request strict mode via X-AIMock-Strict header — overrides the server-wide --strict flag per request (true/1 = strict, false/0 = lenient). When strict: fixture miss returns 503; when lenient: fixture miss proxies to real provider. Follows the X-AIMock-Chaos-* precedence pattern. Journal entries record strictOverride when the header overrides the server default. Enables the same aimock instance to serve both deterministic test probes and live demo traffic simultaneously.
Fixed
  • Progressive relay for NDJSON and Bedrock binary event streams — Ollama NDJSON and Bedrock binary event streams were fully buffered before relay, triggering downstream idle timeouts; now relayed progressively as chunks arrive
  • JSON.parse error detail in bare catch blocks — capture and surface parse-error detail in all bare catch blocks across 25+ provider/WebSocket/stream-collapse handlers instead of swallowing context
  • Unguarded stream write/end calls — wrap stream write/end in try/catch (recorder.ts, agui-recorder.ts) to prevent unhandled exceptions on client disconnect
  • Response termination for headers-already-sent paths — add response termination in error paths where headers were already sent (server.ts, a2a-mock.ts, mcp-mock.ts), preventing connection hangs
  • Vector-mock double body consumption — fix route passthrough consuming the request body twice, causing empty-body forwarding
  • Drift detection compared only first event per typecompareSSESequences now compares ALL events per type, not just the first, catching previously invisible divergences
  • Ollama drift tests used broken async describe.skipIf — replaced with synchronous env-var gate so tests are correctly skipped or executed
  • 12 unrestored spy/mock leaks and misleading assertions — fix spy/mock leaks across test files and correct assertions that passed for the wrong reasons
  • Proxy relay hardcoded POST method — now forwards the original HTTP method
  • Response timeout timer leak — cleared after successful upstream completion
  • Client disconnect handler race — checks writableFinished before destroying upstream request
  • onHookBypassed and beforeWriteResponse callbacks not wrapped in try/catch
  • Audio error relay sent non-2xx responses with audio content-type instead of application/json
  • Snapshot-mode fixture writes not atomic — concurrent requests could corrupt the file
  • Undefined toolCall name/arguments silently dropped during fixture save
  • Video detection heuristic false-positives on LLM provider responses with {id, status} shape
  • One-shot error fixture splice during iteration (deferred via microtask)
  • Azure model injection catch swallowed non-SyntaxError exceptions
  • fal request body lost on passthrough (double readBody consumption)
  • fal queue handler dropped PUT request body
  • Recorder test: tmpDir leak on strict-mode reassignment, global fetch dependency, fragile fixturePath cleanup, duplicate helpers, spy leak on assertion failure
Added
  • Fixture-level chaos evaluation for non-completions endpoints (ElevenLabs, fal)
Changed
  • Anti-buffering headers on all progressive stream relay paths — standard headers (Cache-Control, Connection, X-Accel-Buffering) added to all progressive stream relay paths to prevent intermediate proxy buffering
  • Stream-collapse returns firstDroppedSample — stream-collapse functions now return the first dropped sample for forensic debugging of collapsed streams

v1.21.0

Compare Source

Added
  • match.systemMessage accepts string[] — array form requires ALL substrings to be present in the joined system-message text (AND semantics). Use this when the gate must combine multiple non-adjacent tokens that may appear in any order — e.g., a host that serialises agent-context entries into a system message whose entry order is not stable, but where a fixture should only match when every default value is present (["\"value\": \"Atai\"", "[\"Viewed the pricing page\",\"Watched the product demo video\"]"]). Single-string and RegExp forms continue to work unchanged. JSON form accepts string | string[]; programmatic form accepts string | string[] | RegExp.

v1.20.0

Compare Source

Fixed
  • Drift tests passed vacuously with zero assertions — the shouldFail guard silently skipped all expect calls when no critical diffs were found, so broken extraction logic or warning-level drift went completely undetected. Replaced every guarded assertion across all 21 drift test files (89 instances) with unconditional expect(diffs.filter(...)).toEqual([])
  • Proxy relay leaked raw upstream HTTP status codes — 5 recorder relay paths in recorder.ts and agui-recorder.ts forwarded raw upstream codes (429, 503, 401, 201, etc.) to aimock clients, exposing provider implementation details. Normalized to 200 for success and 502 for errors; fixture recording preserves the original status for fidelity
Added
  • match.systemMessage fixture matcher — gate a fixture on a substring (or regexp) found inside the concatenated text of every system role message in the request. Hosts that plumb dynamic context (persona, agent-context entries, dynamic config) through system messages can now narrow a fixture to a specific context state; when the caller changes that state the fixture stops matching and the request falls through to the next fixture or upstream proxy instead of silently returning a stale baked response. JSON form: "match": { "userMessage": "Who am I?", "systemMessage": "name=Atai" }. Programmatic form accepts string | RegExp.
  • Status code normalization tests — 5 tests verifying proxy relay normalization (201→200, 429→502, 503→502, 401→502, SSE 429→502) with fixture preservation assertions; 2 existing tests updated to expect normalized 502

v1.19.5

Compare Source

Fixed
  • Responses API request conversion — forward max_output_tokens and response_format from Responses requests to the underlying Chat Completions call
  • Gemini request conversion — forward maxOutputTokens, topP, topK from generationConfig; remove synthetic functionCall.id that real Gemini does not produce
  • Cohere request conversion — structured content (images, documents), native tool definitions, temperature, max_tokens, and stop_sequences now forwarded
  • Ollama request conversiontool_calls on assistant messages, base64 images on user messages, system parameter on /api/generate
  • Chat Completions error responses — add param field per OpenAI error spec
  • Moderation response shape — correct categories and category_scores to match the real OpenAI moderation object (boolean flags + float scores)
  • Transcription verbose response — add task, duration, segments, words fields for verbose_json format
  • Search response shape — add status field to search results
  • Rerank response shape — wrap results in { results: [...] } with relevance_score per result
  • Realtime WebSocket — add previous_item_id to conversation items, correct event ID prefixes, add missing fields on session and response events
  • Gemini Live WebSocketgenerationConfig alias for generation_config, turnComplete server event, correct gRPC status codes in error events, complete httpToGrpc mapper
  • Anthropic thinking blocks — add signature field to thinking content blocks and signature_delta event type for extended thinking with signatures
Added
  • Drift tests for 9 multimedia/auxiliary providers — images, speech/TTS, transcription/STT, moderation, ElevenLabs audio, fal.ai, fal.ai queue lifecycle, video, rerank
  • Error shape drift tests — OpenAI Chat, Anthropic Claude, Gemini, Cohere error response shapes validated against SDK types
  • Reasoning/thinking drift tests — OpenAI Chat reasoning_effort, OpenAI Responses reasoning, Anthropic thinking content blocks, Gemini thinking_config

v1.19.4

Compare Source

Fixed
  • Converse stream: spurious type field in contentBlockDelta and contentBlockStartdelta objects contained a Claude Messages API type field (text_delta, thinking_delta) that is not a member of the Converse API's tagged union. botocore's single-member union parser rejected the extra field with ResponseParserError. Also fixed reasoning deltas to use reasoningContent (Converse format) instead of thinking (Claude format). (Issue #​165, reported by @​KMiya84377)
  • Converse: inferenceConfig.maxTokens silently droppedconverseToCompletionRequest now forwards maxTokens to max_tokens
  • Converse: non-streaming responses missing metrics — Added metrics: { latencyMs: 0 } to all 3 non-streaming converse response builders, matching the streaming path and AWS ConverseResponse spec
Added
  • Bedrock drift test expansion — invoke-with-response-stream drift test with binary frame parsing and Anthropic-native event shape comparison. Converse-stream SDK shapes for tool call (toolUse start/delta) and reasoning (reasoningContent start/delta) variants. Three-way triangulate comparisons for all variants.

v1.19.3

Compare Source

Fixed
  • Recorder: multi-turn runs collapsed to a single fixture. --record mode wrote only userMessage to the saved fixture's match block, so two LLM calls in the same agent run that share the user message (the canonical tool-call → tool-result → follow-up shape) collided in the in-memory fixture cache: as soon as turn 0 was recorded, turn 1 matched it on the same userMessage substring, the recorder was skipped, and the follow-up text turn was silently lost. Replaying the resulting single fixture against the same run looped on the tool call until the framework's recursion limit fired. Recorder now also writes turnIndex (count of assistant messages) and hasToolResult (any role:"tool" present) — the matcher in 1.16.0 already accepts both — so each call in a run produces a distinct, deterministic match key. Existing single-userMessage fixtures continue to match unchanged. Surfaced as: CopilotKit's beautiful-chat showcase having to hot-patch dist/recorder.js inside its running aimock container to make --record produce usable multi-turn recordings.

v1.19.2

Compare Source

Fixed
  • Converse stream: double-wrapped Event Stream payloadsbuildBedrockStreamTextEvents, buildBedrockStreamToolCallEvents, and buildBedrockStreamContentWithToolCallsEvents emitted payloads wrapped with the event type name (e.g. { messageStart: { role: "assistant" } }). The :event-type header already carries the event name, so AWS SDK (botocore) expected flat payloads (e.g. { role: "assistant" }). The redundant wrapping caused botocore's BaseEventStreamParser to silently return empty dicts, producing KeyError: 'role' in downstream frameworks like Strands Agents. (Issue #​162, reported by @​KMiya84377)
  • Responses API: missing item_id on 3 SSE event types — Added item_id to response.output_text.done, response.content_part.added, and response.content_part.done events, matching the real OpenAI Responses API shape. SDK drift shapes updated.
  • Chat Completions: missing logprobs on choices — Added logprobs: null to all streaming chunks and non-streaming choices. Removed logprobs from drift allowlist so future omissions are caught.
  • Ollama: missing created_at on /api/chat — Added created_at to all 6 /api/chat builder functions (text, tool call, content+tools, and their streaming variants). The /api/generate path already had it.
  • Gemini: error fixtures used Anthropic-style error codes — Test fixtures and the Gemini Live WebSocket handler now use Google canonical gRPC status codes (RESOURCE_EXHAUSTED, INTERNAL) instead of rate_limit_error / ERROR.

v1.19.1

Compare Source

Fixed
  • Fixture loader: snapshot-style subdirectories skipped on bootloadFixturesFromDir now recurses one level into subdirectories to load <testId>/<provider>.json files written by the snapshot recorder. Previously the loader skipped all subdirectories with a warning, so recorded fixtures could never be replayed. (Issue #​161, reported by @​jantimon)
  • CLI: immediate exit on npx/bunx — Entry-point guard now matches the aimock bin name (not just aimock-cli.js), fixing silent exit when invoked via npx aimock or bunx aimock. (Issue #​160)

v1.19.0

Compare Source

Added
  • Async fixture responses — Fixture responses can now be sync or async functions that receive the request and return the response dynamically. Enables awaiting side effects (database writes, API calls) before constructing the response — eliminating race conditions in complex multi-turn E2E tests. Works with all providers, streaming, and convenience methods (on(), onMessage(), onTurn(), onToolCall(), onToolResult()). (Feature request by @​5ebastianMeier, issue #​154)
  • Snapshot-style recording — When X-Test-Id is present, recorded fixtures are saved to <fixturePath>/<slugified-testId>/<provider>.json instead of timestamp-based filenames. Multiple fixtures for the same test+provider merge into one file. Stable paths enable meaningful PR diffs and easy test-to-fixture mapping. (Feature request by @​jantimon, issue #​155)
Fixed
  • CORS: Firefox preflight blocked by restricted Allow-Headers — Changed Access-Control-Allow-Headers from Content-Type, Authorization to wildcard *, fixing Firefox's strict CORS enforcement when the OpenAI SDK sends User-Agent in the preflight. (Issue #​158)
  • GitHub Action: cosmetic binary renameaction.yml fixtures branch referenced the legacy llmock binary (still functional); updated to aimock for consistency
  • GitHub Action: hardcoded URLs in docs examples — All workflow examples now use steps.<id>.outputs.url instead of hardcoded http://127.0.0.1:4010

v1.18.0

Compare Source

Added
  • Chaos testing in proxy mode — Pre-flight chaos (drop/disconnect) prevents upstream contact; post-response chaos (malformed) corrupts relay body after recording the real upstream response. SSE bypass tracked via aimock_chaos_bypassed_total metric. Explicit source label (fixture/proxy/internal) on all chaos Prometheus counters and journal entries.
  • fal.ai as first-class provider — General fal.ai handler (src/fal.ts) supporting arbitrary JSON request/response payloads (image, video, motion, music, etc.) alongside the existing audio-only fal-audio.ts. Routes by x-fal-target-host header. Queue lifecycle (submit→status→result→cancel), sync run, storage upload stub. RawJSONResponse type for verbatim JSON fixture preservation. Convenience methods onFalQueue() and onFalRun(). Record and replay support. (PR #​153, tombeckenham)
Fixed
  • Fixture validation for RawJSONResponsevalidateFixtures() now recognizes RawJSONResponse, fixing the record→restart→replay cycle for fal.ai fixtures loaded from disk

v1.17.0

Compare Source

Added
  • Gemini Interactions API — 12th LLM provider. Full record/replay support for Google's Gemini Interactions streaming API (/v1beta/models/{model}:streamGenerateContent), including multi-turn conversations, function calling, streaming text, and safety metadata. Drift tests, integration tests, and documentation included. (PR #​139)
  • AG-UI interrupt-aware typesAGUIInterrupt, AGUIResumeEntry, and AGUIRunFinishedOutcome (discriminated union: success | interrupt) from ag-ui PR #​1569. outcome field on AGUIRunFinishedEvent, resume field on AGUIRunAgentInput.
  • AG-UI convenience buildersbuildActivityDelta, buildToolCallChunk, buildRawEvent, buildCustomEvent, buildReasoningChunk, buildReasoningEncryptedValue.
  • ./agui subpath exportagui-stub.ts wired into tsdown.config.ts and package.json exports, matching ./a2a, ./mcp, ./vector pattern.
  • Complete AG-UI type exports — All event types (reasoning, step, thinking, raw, custom, chunk), AGUIBuildOpts, matchesAGUIFixture, AGUIReasoningEncryptedValueSubtype, AGUIMessageRole now exported from package root.
  • "warn" log level — New log level between "silent" and "info" with proper hierarchy. AGUIMockOptions.logLevel option added; AG-UI mock defaults to "warn" instead of "silent".
  • Non-speech audio generation — Mock support for ElevenLabs sound effects (/v1/sound-generation) and music (/v1/music/*), fal.ai queue-based audio (/fal/queue/submit/*, /fal/queue/requests/*, /fal/run/*), Gemini HTTP audio via generateContent/streamGenerateContent with inlineData audio parts, and Gemini Live WebSocket audio. Convenience methods: onAudio(), onSoundEffect(), onMusic(), onFalAudio(). (PR #​140, closes #​118)
  • AudioResponse broadenedaudio field now supports both string (base64) and { b64Json, contentType } object form
  • Gemini audio recording — Record and replay Gemini audio responses (both streaming SSE and non-streaming JSON)
  • Router audio-gen filtering — Bidirectional endpoint filtering for audio-gen and fal-audio endpoint types
Fixed
  • AG-UI type alignmentAGUIMessage.id and AGUIRunAgentInput.threadId/runId now required (was optional). AGUIToolDefinition.description now required, metadata field added. encryptedValue and error fields added to AGUIMessage. AGUIMessageRole union covers all 7 protocol roles.
  • AG-UI handler hardeningwriteAGUIEventStream logs all caught errors (was silently swallowing non-TypeError/RangeError), preserves user-supplied timestamps (was always overwriting with Date.now()). buildCompositeResponse omits RUN_FINISHED when inner events contain RUN_ERROR (protocol compliance). matchesFixture resets lastIndex on regex before test().
  • AG-UI recorder SSE parsing — Handle data: lines without space after colon per SSE spec. Serialize predicate-match fixtures as __NO_USER_MESSAGE__ sentinel on disk instead of producing catch-all {}. Return actual HTTP status from proxy (was always boolean/200). Forward upstream content-type on non-2xx responses instead of SSE headers.
  • AG-UI mock error handlingreadBody wrapped in try/catch (was unguarded await producing opaque 500s). JSON parse errors now include detail in 400 response. Proxy status correctly journale

Note

PR body was truncated to here.


Configuration

📅 Schedule: (in timezone America/Los_Angeles)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

0 participants