@fgv/ts-extras 5.1.0-35 → 5.1.0-36

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.
@@ -1711,18 +1711,40 @@ declare interface IAiClientToolConfig<TParams = unknown> {
1711
1711
  */
1712
1712
  declare interface IAiClientToolContinuation {
1713
1713
  /**
1714
- * Provider-native wire-format message objects to supply back on the next
1715
- * streaming call via `IExecuteClientToolTurnParams.continuationMessages`
1716
- * (which is forwarded as `rawTail` to the underlying call). The exact
1717
- * shape depends on the provider format and may contain provider-specific
1718
- * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use). These are
1719
- * NOT `IChatMessage[]` and must not be prepended via `messagesBefore`
1720
- * the normalized-message path would strip the provider-native fields
1721
- * (signatures, redacted thinking) that the server requires for
1722
- * continuation validation.
1714
+ * **Cumulative** provider-native wire-format message objects covering all
1715
+ * tool rounds so far. On each turn, `executeClientToolTurn` prepends the
1716
+ * inbound `continuationMessages` so that this array always contains the
1717
+ * complete wire tail from round 1 through the current round.
1718
+ *
1719
+ * To drive a multi-round loop, simply **replace** `continuationMessages`
1720
+ * with this value do not manually concatenate:
1721
+ *
1722
+ * ```ts
1723
+ * let tail: JsonObject[] | undefined;
1724
+ * while (true) {
1725
+ * const { events, nextTurn } = executeClientToolTurn({
1726
+ * ..., continuationMessages: tail
1727
+ * }).orThrow();
1728
+ * for await (const e of events) { /* observe *\/ }
1729
+ * const outcome = (await nextTurn).orThrow();
1730
+ * if (!outcome.continuation) break;
1731
+ * tail = [...outcome.continuation.messages]; // replace — already cumulative
1732
+ * }
1733
+ * ```
1734
+ *
1735
+ * The exact shape is provider-native and may include provider-specific
1736
+ * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use, OpenAI
1737
+ * function_call/function_call_output items, Gemini functionCall/functionResponse
1738
+ * parts). These are NOT `IChatMessage[]` and must NOT be placed in the
1739
+ * `messages` parameter — the normalized-message path strips provider-native
1740
+ * fields (thinking signatures, redacted_thinking data) that the server
1741
+ * requires for continuation validation.
1742
+ *
1743
+ * `toolCallsSummary` is per-round only (the calls executed in the current
1744
+ * turn). Only `messages` is cumulative.
1723
1745
  */
1724
1746
  readonly messages: ReadonlyArray<JsonObject>;
1725
- /** Summary of each tool call that was executed in this turn. */
1747
+ /** Summary of each tool call executed in this turn (per-round, not cumulative). */
1726
1748
  readonly toolCallsSummary: ReadonlyArray<IAiClientToolCallSummary>;
1727
1749
  }
1728
1750
 
@@ -2984,19 +3006,28 @@ declare interface IExecuteClientToolTurnParams extends IChatRequest {
2984
3006
  /** API key for authentication. */
2985
3007
  readonly apiKey: string;
2986
3008
  /**
2987
- * Provider-specific continuation messages to append after the current user
2988
- * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s
2989
- * `messages` field from a prior turn back to the provider in the follow-up request.
3009
+ * The cumulative provider-native wire tail from the previous turn's
3010
+ * {@link AiAssist.IAiClientToolContinuation.messages}. Supply this as-is
3011
+ * each round — `messages` is already cumulative, so **replace** rather
3012
+ * than manually concatenate:
3013
+ *
3014
+ * ```ts
3015
+ * tail = outcome.continuation.messages; // replace — already cumulative
3016
+ * ```
3017
+ *
3018
+ * On the first turn this should be `undefined` (or omitted).
2990
3019
  *
2991
3020
  * Each provider applies its own shape guard to the supplied wire objects:
2992
3021
  * - Anthropic: projects each entry to `{ role, content }` (sufficient for
2993
3022
  * thinking blocks and `tool_result` arrays).
2994
3023
  * - OpenAI / xAI Responses: passes each item verbatim (`function_call` /
2995
- * `function_call_output` items carry distinct fields per `type`); only guards
2996
- * that each entry is a JSON object.
3024
+ * `function_call_output` items carry distinct fields per `type`); only
3025
+ * guards that each entry is a JSON object.
2997
3026
  * - Gemini: projects each entry to `{ role, parts }`.
2998
3027
  *
2999
3028
  * Entries that fail their provider's shape check are silently skipped.
3029
+ * Do NOT place these objects in the `messages` parameter — the
3030
+ * normalized-message path strips provider-native fields.
3000
3031
  */
3001
3032
  readonly continuationMessages?: ReadonlyArray<JsonObject>;
3002
3033
  /** Temperature (default: 0.7). */
@@ -299,18 +299,40 @@ export interface IAiClientToolCallSummary {
299
299
  */
300
300
  export interface IAiClientToolContinuation {
301
301
  /**
302
- * Provider-native wire-format message objects to supply back on the next
303
- * streaming call via `IExecuteClientToolTurnParams.continuationMessages`
304
- * (which is forwarded as `rawTail` to the underlying call). The exact
305
- * shape depends on the provider format and may contain provider-specific
306
- * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use). These are
307
- * NOT `IChatMessage[]` and must not be prepended via `messagesBefore`
308
- * the normalized-message path would strip the provider-native fields
309
- * (signatures, redacted thinking) that the server requires for
310
- * continuation validation.
302
+ * **Cumulative** provider-native wire-format message objects covering all
303
+ * tool rounds so far. On each turn, `executeClientToolTurn` prepends the
304
+ * inbound `continuationMessages` so that this array always contains the
305
+ * complete wire tail from round 1 through the current round.
306
+ *
307
+ * To drive a multi-round loop, simply **replace** `continuationMessages`
308
+ * with this value do not manually concatenate:
309
+ *
310
+ * ```ts
311
+ * let tail: JsonObject[] | undefined;
312
+ * while (true) {
313
+ * const { events, nextTurn } = executeClientToolTurn({
314
+ * ..., continuationMessages: tail
315
+ * }).orThrow();
316
+ * for await (const e of events) { /* observe *\/ }
317
+ * const outcome = (await nextTurn).orThrow();
318
+ * if (!outcome.continuation) break;
319
+ * tail = [...outcome.continuation.messages]; // replace — already cumulative
320
+ * }
321
+ * ```
322
+ *
323
+ * The exact shape is provider-native and may include provider-specific
324
+ * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use, OpenAI
325
+ * function_call/function_call_output items, Gemini functionCall/functionResponse
326
+ * parts). These are NOT `IChatMessage[]` and must NOT be placed in the
327
+ * `messages` parameter — the normalized-message path strips provider-native
328
+ * fields (thinking signatures, redacted_thinking data) that the server
329
+ * requires for continuation validation.
330
+ *
331
+ * `toolCallsSummary` is per-round only (the calls executed in the current
332
+ * turn). Only `messages` is cumulative.
311
333
  */
312
334
  readonly messages: ReadonlyArray<JsonObject>;
313
- /** Summary of each tool call that was executed in this turn. */
335
+ /** Summary of each tool call executed in this turn (per-round, not cumulative). */
314
336
  readonly toolCallsSummary: ReadonlyArray<IAiClientToolCallSummary>;
315
337
  }
316
338
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Core types for AI assist: prompt class, provider descriptors, settings, and chat messages.\n * @packageDocumentation\n */\n\nimport { type Result } from '@fgv/ts-utils';\nimport { type JsonObject, type JsonSchema } from '@fgv/ts-json-base';\n\n// ============================================================================\n// Image Data\n// ============================================================================\n\n/**\n * Universal image representation used for both image input (vision prompts)\n * and image output (generation responses).\n *\n * @remarks\n * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to\n * format it for browser-display contexts.\n *\n * @public\n */\nexport interface IAiImageData {\n /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */\n readonly mimeType: string;\n /** Base64-encoded image bytes (no `data:` prefix). */\n readonly base64: string;\n}\n\n/**\n * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.\n * @param image - The image to format\n * @returns A `data:<mime>;base64,<data>` URL string\n * @public\n */\nexport function toDataUrl(image: IAiImageData): string {\n return `data:${image.mimeType};base64,${image.base64}`;\n}\n\n/**\n * Image attachment for a vision (image-input) prompt.\n *\n * @remarks\n * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is\n * silently ignored by Anthropic, Gemini, and other providers.\n *\n * @public\n */\nexport interface IAiImageAttachment extends IAiImageData {\n /**\n * OpenAI vision detail hint:\n * - `'low'`: faster, cheaper, lower fidelity\n * - `'high'`: slower, more expensive, higher fidelity\n * - `'auto'` (default): provider chooses\n *\n * Ignored by providers other than OpenAI.\n */\n readonly detail?: 'low' | 'high' | 'auto';\n}\n\n// ============================================================================\n// AiPrompt\n// ============================================================================\n\n/**\n * A structured AI prompt with system/user split for direct API calls,\n * and a lazily-constructed combined version for copy/paste workflows.\n * @public\n */\nexport class AiPrompt {\n /** System instructions: schema documentation, format rules, general guidance. */\n public readonly system: string;\n /** User request: the specific entity generation request. */\n public readonly user: string;\n /**\n * Optional image attachments. When present, vision-capable providers will\n * include them in the user message; non-vision providers will reject the\n * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).\n */\n public readonly attachments: ReadonlyArray<IAiImageAttachment>;\n\n public constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>) {\n this.system = system;\n this.user = user;\n this.attachments = attachments ?? [];\n }\n\n /**\n * Combined single-string version (user + system joined) for copy/paste.\n * When attachments are present, includes a sentinel noting they aren't\n * part of the copied text.\n */\n public get combined(): string {\n const sentinel =\n this.attachments.length > 0\n ? `\\n\\n[${this.attachments.length} image attachment(s) — not included in copied text]`\n : '';\n return `${this.user}${sentinel}\\n\\n${this.system}`;\n }\n\n /**\n * Lowers this prompt to the unified {@link AiAssist.IChatRequest} shape consumed\n * by the turn entry points (`callProviderCompletion`,\n * `callProviderCompletionStream`, `generateJsonCompletion`,\n * `executeClientToolTurn`). The prompt becomes a single current `user` turn\n * (carrying any attachments) with the system instructions in the distinct\n * `system` field.\n */\n public toRequest(): IChatRequest {\n return {\n system: this.system,\n messages: [\n {\n role: 'user',\n content: this.user,\n ...(this.attachments.length > 0 ? { attachments: this.attachments } : {})\n }\n ]\n };\n }\n}\n\n// ============================================================================\n// Chat Message\n// ============================================================================\n\n/**\n * A single chat message in OpenAI format.\n * @public\n */\nexport interface IChatMessage {\n /** Message role */\n readonly role: 'system' | 'user' | 'assistant';\n /** Message content */\n readonly content: string;\n /**\n * Optional image attachments. Only honoured on the **current turn** (the last\n * message of an {@link AiAssist.IChatRequest}); vision-capable providers include\n * them in that user message, non-vision providers reject the call up front (see\n * {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}). Attachments on\n * history (non-final) messages are ignored.\n */\n readonly attachments?: ReadonlyArray<IAiImageAttachment>;\n}\n\n// ============================================================================\n// Chat Request\n// ============================================================================\n\n/**\n * An ordered chat request: optional system instructions plus the conversation\n * turns. The **last** entry in `messages` is the current turn (always a `user`\n * turn); everything before it is prior conversation history.\n *\n * @remarks\n * This is the unified shape accepted by every turn entry point. Both the\n * completion path and the client-tool turn path linearize it identically:\n * `[system, ...history, current user turn, ...continuation]`. Keeping `system`\n * as a distinct field (rather than a `system`-role message) matches how the\n * per-provider request builders already separate system from the turn list\n * (Anthropic top-level `system`, Gemini `systemInstruction`, OpenAI a leading\n * `system`-role message). `messages` should therefore carry only `user` /\n * `assistant` turns.\n *\n * @public\n */\nexport interface IChatRequest {\n /** System instructions (schema docs, format rules, general guidance). */\n readonly system?: string;\n /**\n * The ordered conversation turns. Must be non-empty; the last entry is the\n * current `user` turn and the preceding entries are history.\n */\n readonly messages: ReadonlyArray<IChatMessage>;\n}\n\n// ============================================================================\n// Server-Side Tools\n// ============================================================================\n\n/**\n * Built-in server-side tool types supported across providers.\n * @public\n */\nexport type AiServerToolType = 'web_search';\n\n/**\n * Configuration specific to web search tools.\n * @public\n */\nexport interface IAiWebSearchToolConfig {\n readonly type: 'web_search';\n /** Optional: restrict search to these domains. */\n readonly allowedDomains?: ReadonlyArray<string>;\n /** Optional: exclude these domains from search. */\n readonly blockedDomains?: ReadonlyArray<string>;\n /** Optional: max number of searches per request. */\n readonly maxUses?: number;\n /**\n * Optional: enable image understanding during web search.\n * When true, the model can view and analyze images found during search.\n * Currently supported by xAI only; ignored by other providers.\n */\n readonly enableImageUnderstanding?: boolean;\n}\n\n/**\n * Union of all server-side tool configurations. Discriminated on `type`.\n * @public\n */\nexport type AiServerToolConfig = IAiWebSearchToolConfig;\n\n/**\n * Declares a tool as enabled/disabled in provider settings.\n * Tools are disabled by default — consuming apps must opt in explicitly.\n * @public\n */\nexport interface IAiToolEnablement {\n /** Which tool type. */\n readonly type: AiServerToolType;\n /** Whether this tool is enabled by default for this provider. */\n readonly enabled: boolean;\n /** Optional tool-specific configuration. */\n readonly config?: AiServerToolConfig;\n}\n\n// ============================================================================\n// Client-Defined Tools\n// ============================================================================\n\n/**\n * Configuration for a client-defined (harness-supplied) tool.\n *\n * @remarks\n * The `parametersSchema` is the single source of truth for both the wire-format\n * JSON Schema sent to the provider (via `.toJson()`) and the runtime argument\n * validation (via `.validate(rawArgs)`). Use `JsonSchema.object(...)` from\n * `@fgv/ts-json-base` to author the schema as a const (e.g. `const mySchema = JsonSchema.object({...})`);\n * the static type `TParams` is then derived via `JsonSchema.Static<typeof mySchema>` —\n * no drift between wire schema and runtime validation.\n *\n * @public\n */\nexport interface IAiClientToolConfig<TParams = unknown> {\n /** Discriminator — always `'client_tool'`. */\n readonly type: 'client_tool';\n /** Tool name sent to the model (must be unique within a call). */\n readonly name: string;\n /** Human-readable description of what the tool does, shown to the model. */\n readonly description: string;\n /**\n * JSON Schema validator for the tool's parameters. Emits wire format via\n * `.toJson()` and validates model-returned args via `.validate(rawArgs)`.\n */\n readonly parametersSchema: JsonSchema.ISchemaValidator<TParams>;\n}\n\n/**\n * A client-defined tool: configuration + execution callback pair.\n *\n * @remarks\n * The `execute` callback receives typed `TParams` (already validated by\n * `config.parametersSchema.validate()`) and returns a `Promise<Result<unknown>>`.\n * Thrown errors are caught via `captureAsyncResult` in the round-trip helper.\n *\n * @public\n */\nexport interface IAiClientTool<TParams = unknown> {\n /** The tool's configuration (name, description, parameters schema). */\n readonly config: IAiClientToolConfig<TParams>;\n /**\n * Execute the tool with validated parameters.\n * @param args - Typed arguments, already validated against `config.parametersSchema`.\n * @returns A `Promise<Result<unknown>>` — the result is stringified and sent back to the model.\n */\n readonly execute: (args: TParams) => Promise<Result<unknown>>;\n}\n\n/**\n * Union of all tool configurations: server-side or client-defined.\n * Discriminated on `type`.\n * @public\n */\nexport type AiToolConfig = AiServerToolConfig | IAiClientToolConfig;\n\n// ============================================================================\n// Client Tool Streaming Events\n// ============================================================================\n\n/**\n * Emitted when a client-defined tool call begins streaming. Carries the tool name\n * and optional provider-assigned call ID (Anthropic / OpenAI Responses API; absent\n * for Gemini which does not assign call IDs).\n * @public\n */\nexport interface IAiStreamToolUseStart {\n readonly type: 'client-tool-call-start';\n /** The name of the client tool being called. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier (Anthropic: `toolu_*`; OpenAI: `call_*`).\n * Absent for Gemini (correlation by name).\n */\n readonly callId?: string;\n}\n\n/**\n * Emitted when a client-defined tool call is complete and its arguments are fully\n * accumulated. The `args` object is the fully parsed JSON object — no further\n * streaming deltas follow for this call.\n * @public\n */\nexport interface IAiStreamToolUseDelta {\n readonly type: 'client-tool-call-done';\n /** The name of the client tool being called. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier. Absent for Gemini.\n */\n readonly callId?: string;\n /** The fully accumulated and parsed tool arguments. */\n readonly args: JsonObject;\n}\n\n/**\n * Emitted after a client-defined tool has been executed and the result is ready\n * to be fed back to the model in the round-trip continuation.\n * @public\n */\nexport interface IAiStreamToolUseComplete {\n readonly type: 'client-tool-result';\n /** The name of the client tool that was executed. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier. Absent for Gemini.\n */\n readonly callId?: string;\n /** The stringified result returned by the tool's execute callback. */\n readonly result: string;\n /** Whether the tool execution failed (schema validation failure, execute error, or unknown tool). */\n readonly isError: boolean;\n}\n\n// ============================================================================\n// Client Tool Round-Trip Types\n// ============================================================================\n\n/**\n * Summary of a single client tool call within a turn: the tool name, call ID,\n * raw arguments, execution result, and whether the execution was an error.\n * @public\n */\nexport interface IAiClientToolCallSummary {\n /** The name of the tool that was called. */\n readonly toolName: string;\n /** Provider-assigned call identifier (absent for Gemini). */\n readonly callId?: string;\n /** The fully accumulated raw arguments object as parsed JSON. */\n readonly args: JsonObject;\n /** The stringified result (success value or error message). */\n readonly result: string;\n /** Whether execution failed (schema validation failure, execute error, or unknown tool). */\n readonly isError: boolean;\n}\n\n/**\n * The provider-specific continuation data needed to build the follow-up request\n * for the next round of the conversation.\n *\n * @remarks\n * `messages` are provider-native request objects (Anthropic: content-block arrays,\n * OpenAI Responses API: input items, Gemini: content parts). The continuation\n * builder in `clientToolContinuationBuilder.ts` populates this.\n *\n * @public\n */\nexport interface IAiClientToolContinuation {\n /**\n * Provider-native wire-format message objects to supply back on the next\n * streaming call via `IExecuteClientToolTurnParams.continuationMessages`\n * (which is forwarded as `rawTail` to the underlying call). The exact\n * shape depends on the provider format and may contain provider-specific\n * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use). These are\n * NOT `IChatMessage[]` and must not be prepended via `messagesBefore` —\n * the normalized-message path would strip the provider-native fields\n * (signatures, redacted thinking) that the server requires for\n * continuation validation.\n */\n readonly messages: ReadonlyArray<JsonObject>;\n /** Summary of each tool call that was executed in this turn. */\n readonly toolCallsSummary: ReadonlyArray<IAiClientToolCallSummary>;\n}\n\n/**\n * The result of a single client-tool turn: the optional continuation for the next\n * call (absent when no tool calls occurred) and whether the stream was truncated.\n * @public\n */\nexport interface IAiClientToolTurnResult {\n /**\n * The continuation data for the next round-trip. `undefined` when the model\n * completed without invoking any client tools.\n */\n readonly continuation: IAiClientToolContinuation | undefined;\n /** Whether the stream was truncated (token limit or stop reason). */\n readonly truncated: boolean;\n /** The full concatenated text from all `text-delta` events in this turn. */\n readonly fullText: string;\n}\n\n// ============================================================================\n// Model Specification\n// ============================================================================\n\n/**\n * Known context keys for model specification maps.\n * @public\n */\nexport type ModelSpecKey = 'base' | 'tools' | 'image' | 'thinking' | 'embedding';\n\n/**\n * All valid {@link ModelSpecKey} values.\n * @public\n */\nexport const allModelSpecKeys: ReadonlyArray<ModelSpecKey> = [\n 'base',\n 'tools',\n 'image',\n 'thinking',\n 'embedding'\n];\n\n/**\n * Default context key used as fallback when resolving a {@link ModelSpec}.\n * @public\n */\nexport const MODEL_SPEC_BASE_KEY: ModelSpecKey = 'base';\n\n/**\n * A model specification: either a simple model string or a record mapping\n * context keys to nested model specs.\n *\n * @remarks\n * A bare string is equivalent to `{ base: string }`. This keeps the simple\n * case simple while allowing context-aware model selection (e.g. different\n * models for tool-augmented vs. base completions).\n *\n * @example\n * ```typescript\n * // Simple — same model for all contexts:\n * const simple: ModelSpec = 'grok-4.3';\n *\n * // Context-aware — different model for tools and thinking:\n * const split: ModelSpec = { base: 'grok-4.3', tools: 'grok-4.3', thinking: 'grok-4.3' };\n *\n * // Future nested — per-tool model selection:\n * const nested: ModelSpec = { base: 'grok-fast', tools: { base: 'grok-r', image: 'grok-v' } };\n * ```\n * @public\n */\nexport interface IModelSpecMap {\n readonly [key: string]: ModelSpec;\n}\n\n/**\n * @public\n */\nexport type ModelSpec = string | IModelSpecMap;\n\n/**\n * Resolves a {@link ModelSpec} to a concrete model string given an optional context key.\n *\n * @remarks\n * Resolution rules:\n * 1. If the spec is a string, return it directly (context is irrelevant).\n * 2. If the spec is an object and the context key exists, recurse into that branch.\n * 3. Otherwise, fall back to the {@link MODEL_SPEC_BASE_KEY | 'base'} key.\n * 4. If neither context nor `'base'` exists, use the first available value.\n *\n * @param spec - The model specification to resolve\n * @param context - Optional context key (e.g. `'tools'`)\n * @returns The resolved model string\n * @public\n */\nexport function resolveModel(spec: ModelSpec, context?: string): string {\n if (typeof spec === 'string') {\n return spec;\n }\n\n // Try the requested context key first\n if (context !== undefined && context in spec) {\n return resolveModel(spec[context]);\n }\n\n // Fall back to 'base'\n if (MODEL_SPEC_BASE_KEY in spec) {\n return resolveModel(spec[MODEL_SPEC_BASE_KEY]);\n }\n\n // Last resort: first value in the record\n const first = Object.values(spec)[0];\n /* c8 ignore next 3 - defensive: only reachable with empty object (prevented by converter) */\n if (first === undefined) {\n return '';\n }\n return resolveModel(first);\n}\n\n// ============================================================================\n// Provider Descriptor\n// ============================================================================\n\n/**\n * All known AI provider identifiers.\n * @public\n */\nexport type AiProviderId =\n | 'copy-paste'\n | 'xai-grok'\n | 'openai'\n | 'openai-compat'\n | 'anthropic'\n | 'google-gemini'\n | 'groq'\n | 'mistral'\n | 'ollama';\n\n/**\n * API format categories for provider routing.\n * @public\n */\nexport type AiApiFormat = 'openai' | 'anthropic' | 'gemini';\n\n/**\n * API format categories for image-generation provider routing.\n *\n * @remarks\n * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`\n * (text-only) or `/images/edits` (when reference images are present).\n * - `'xai-images'` — xAI Images API. Text-only JSON generation request.\n * - `'xai-images-edits'` — xAI Images API for Grok Imagine models. Uses JSON\n * body with `{ type: \"image_url\" }` objects (not multipart).\n * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.\n * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`\n * endpoint that returns image parts (Gemini 2.5 Flash Image / \"Nano\n * Banana\"). Accepts reference images.\n *\n * @public\n */\nexport type AiImageApiFormat =\n | 'openai-images'\n | 'gemini-imagen'\n | 'xai-images'\n | 'xai-images-edits'\n | 'gemini-image-out';\n\n/**\n * API format categories for embedding provider routing.\n *\n * @remarks\n * - `'openai-embeddings'` — OpenAI `/v1/embeddings` shape. Serves OpenAI,\n * Ollama (via `/v1`), openai-compat self-hosted servers (vLLM, LM Studio,\n * llama.cpp's openai-server), and Mistral (`mistral-embed`) — all of which\n * speak the same request/response shape.\n * - `'gemini-embeddings'` — Google Gemini `:batchEmbedContents` endpoint. A\n * genuinely divergent shape (different route, auth header, request body, and\n * the `taskType` retrieval-asymmetry knob that has no OpenAI analog).\n *\n * Named with the `ApiFormat` suffix for symmetry with `AiApiFormat` and\n * `AiImageApiFormat`.\n *\n * @public\n */\nexport type AiEmbeddingApiFormat = 'openai-embeddings' | 'gemini-embeddings';\n\n// ============================================================================\n// Completion Response\n// ============================================================================\n\n/**\n * Result of an AI provider completion call.\n * @public\n */\nexport interface IAiCompletionResponse {\n /** The generated text content */\n readonly content: string;\n /** Whether the response was truncated due to token limits */\n readonly truncated: boolean;\n}\n\n// ============================================================================\n// Streaming Events\n// ============================================================================\n\n/**\n * A text-content delta arriving during a streaming completion.\n * @public\n */\nexport interface IAiStreamTextDelta {\n readonly type: 'text-delta';\n /** The newly arrived text fragment. */\n readonly delta: string;\n}\n\n/**\n * A server-side tool progress event arriving during a streaming completion.\n * Surfaced for providers that emit explicit tool-progress markers (OpenAI\n * Responses API, Anthropic). Gemini's grounding doesn't emit these.\n * @public\n */\nexport interface IAiStreamToolEvent {\n readonly type: 'tool-event';\n /** Which server-side tool this event describes. */\n readonly toolType: AiServerToolType;\n /** Tool lifecycle phase. */\n readonly phase: 'started' | 'completed';\n /**\n * Optional provider-specific detail. For web_search this is typically the\n * search query when available; format varies by provider.\n */\n readonly detail?: string;\n}\n\n/**\n * Terminal success event for a streaming completion. Carries the aggregated\n * full text and truncation status for callers that want both the progressive\n * UI and the complete result.\n * @public\n */\nexport interface IAiStreamDone {\n readonly type: 'done';\n /** Whether the response was truncated due to token limits. */\n readonly truncated: boolean;\n /** The full concatenated text from all `text-delta` events. */\n readonly fullText: string;\n /**\n * Provider-reported reason a truncated response was cut short (e.g.\n * `'max_output_tokens'`, `'content_filter'`), when the provider supplies one.\n * Currently populated only by the OpenAI / xAI Responses adapter, from the\n * completed payload's `incomplete_details.reason`. Meaningful only when\n * `truncated === true`; `undefined` otherwise (and whenever the provider\n * reports truncation without a reason).\n */\n readonly incompleteReason?: string;\n}\n\n/**\n * Terminal failure event for a streaming completion. After this event no\n * further events are emitted.\n *\n * @remarks\n * Connection-time failures (auth, network, pre-flight CORS rejection) are\n * surfaced via the outer `Result.fail` returned by\n * `callProviderCompletionStream` rather than as an `error` event, so callers\n * can distinguish \"didn't start\" from \"started but errored mid-stream.\"\n *\n * @public\n */\nexport interface IAiStreamError {\n readonly type: 'error';\n readonly message: string;\n}\n\n/**\n * Discriminated union of events emitted by a streaming completion.\n *\n * @remarks\n * **Exhaustive-switch consumers must handle all variants.** The three\n * `client-tool-*` variants were added when client-tool support shipped;\n * update every exhaustive switch over this union in lockstep.\n *\n * @public\n */\nexport type IAiStreamEvent =\n | IAiStreamTextDelta\n | IAiStreamToolEvent\n | IAiStreamToolUseStart\n | IAiStreamToolUseDelta\n | IAiStreamToolUseComplete\n | IAiStreamDone\n | IAiStreamError;\n\n/**\n * Thinking/reasoning mode support for a provider.\n * @public\n */\nexport type AiThinkingMode = 'optional' | 'required' | 'unsupported';\n\n/**\n * Describes a single AI provider — single source of truth for all metadata.\n * @public\n */\nexport interface IAiProviderDescriptor {\n /** Provider identifier (e.g. 'xai-grok', 'anthropic') */\n readonly id: AiProviderId;\n /** Human-readable label (e.g. \"xAI Grok\") */\n readonly label: string;\n /** Button label for action buttons (e.g. \"AI Assist | Grok\") */\n readonly buttonLabel: string;\n /** Whether this provider requires an API key secret */\n readonly needsSecret: boolean;\n /** Which API adapter format to use */\n readonly apiFormat: AiApiFormat;\n /** Base URL for the API (e.g. 'https://api.x.ai/v1') */\n readonly baseUrl: string;\n /** Default model specification — string or context-aware map. */\n readonly defaultModel: ModelSpec;\n /** Which server-side tools this provider supports (empty = none). */\n readonly supportedTools: ReadonlyArray<AiServerToolType>;\n /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */\n readonly corsRestricted: boolean;\n /**\n * Whether this provider's streaming completion endpoint requires a proxy\n * for direct browser calls. Some providers gate streaming separately from\n * non-streaming (rare), so this is tracked independently from\n * {@link IAiProviderDescriptor.corsRestricted}.\n *\n * @remarks\n * When `true`, `callProviderCompletionStream` rejects up front unless the\n * call is being routed through a proxy.\n */\n readonly streamingCorsRestricted: boolean;\n /**\n * Whether this provider's chat completions API accepts image input\n * (i.e. supports vision prompts). When false, calls with\n * `prompt.attachments` are rejected up front.\n */\n readonly acceptsImageInput: boolean;\n /**\n * Whether this provider supports thinking/reasoning mode.\n * - 'optional': thinking can be enabled but is not required\n * - 'required': thinking is always active (e.g. o-series models)\n * - 'unsupported': thinking is not supported\n */\n readonly thinkingMode: AiThinkingMode;\n /**\n * Image-generation capabilities, scoped to model id prefixes. Empty or\n * undefined means the provider does not support image generation.\n *\n * @remarks\n * The dispatcher matches the resolved model id against each rule's\n * `modelPrefix` and selects the longest match (see\n * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the\n * catch-all and matches every model id.\n *\n * Multiple entries support providers that host more than one image-API\n * surface under one baseUrl. Google Gemini is the canonical case: the\n * `imagen-*` family is predict-only via `:predict`, while\n * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts\n * reference images. Listing both lets callers pick the right model and the\n * dispatcher routes accordingly.\n *\n * Image-model selection reuses the existing `image` {@link ModelSpecKey}.\n * Providers that declare `imageGeneration` should declare a model in\n * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.\n */\n readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;\n /**\n * Embedding capabilities, scoped to model id prefixes. Empty or undefined\n * means the provider does not support embeddings.\n *\n * @remarks\n * The dispatcher matches the resolved embedding model id against each rule's\n * `modelPrefix` and selects the longest match (see\n * {@link AiAssist.resolveEmbeddingCapability}). An empty `modelPrefix` is the\n * catch-all and matches every model id.\n *\n * Embedding-model selection uses the `embedding` {@link ModelSpecKey}.\n * Providers that declare `embedding` should declare a model in\n * `defaultModel.embedding`, e.g. `{ base: 'gpt-4o', embedding: 'text-embedding-3-small' }`.\n * Self-hosted providers (`ollama`, `openai-compat`) leave it unset — the\n * caller supplies the embedding model via `modelOverride`.\n */\n readonly embedding?: ReadonlyArray<IAiEmbeddingModelCapability>;\n}\n\n/**\n * Image-generation capability for a model family within a provider. Used as\n * an entry in {@link IAiProviderDescriptor.imageGeneration}.\n *\n * @public\n */\nexport interface IAiImageModelCapability {\n /**\n * Prefix matched against the resolved image model id. The empty string is\n * the catch-all and matches every model. When multiple rules' prefixes\n * match a model id, the longest prefix wins; ties are broken by\n * first-encountered.\n */\n readonly modelPrefix: string;\n /** API format used to dispatch requests for matching models. */\n readonly format: AiImageApiFormat;\n /**\n * Whether matching models accept reference images via\n * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or\n * undefined, calls that include reference images are rejected up front.\n */\n readonly acceptsImageReferenceInput?: boolean;\n /** Accepted size strings. When present, dispatcher pre-validates. */\n readonly acceptedSizes?: ReadonlyArray<string>;\n /** When true, quality param is sent. When false/undefined, don't send quality. */\n readonly supportsQualityParam?: boolean;\n /** Accepted quality values when supportsQualityParam is true. */\n readonly acceptedQualities?: ReadonlyArray<string>;\n /** Maximum count (n). When present, dispatcher pre-validates. */\n readonly maxCount?: number;\n /**\n * How to encode the output format on the wire:\n * - 'response-format': send response_format: 'b64_json' (dall-e-2, dall-e-3)\n * - 'output-format': send output_format (gpt-image-1)\n * - 'none': send neither (Imagen, Gemini Flash)\n */\n readonly outputParamStyle?: 'response-format' | 'output-format' | 'none';\n /** Default MIME type for response images. */\n readonly defaultOutputMimeType?: string;\n}\n\n// ============================================================================\n// Embedding — capability + request/result types\n// ============================================================================\n\n/**\n * Embedding capability for a model family within a provider. Used as an entry\n * in {@link IAiProviderDescriptor.embedding}.\n *\n * @public\n */\nexport interface IAiEmbeddingModelCapability {\n /**\n * Prefix matched against the resolved embedding model id. The empty string is\n * the catch-all and matches every model. When multiple rules' prefixes match\n * a model id, the longest prefix wins; ties are broken by first-encountered.\n */\n readonly modelPrefix: string;\n /** API format used to dispatch requests for matching models. */\n readonly format: AiEmbeddingApiFormat;\n /**\n * Whether matching models honor a requested output `dimensions`\n * (OpenAI `text-embedding-3-*`, Gemini `gemini-embedding-001` via MRL\n * truncation). When false/undefined, a caller-supplied `dimensions` is a\n * no-op (logged, not failed — see {@link AiAssist.IAiEmbeddingParams}).\n */\n readonly supportsDimensions?: boolean;\n /**\n * Whether matching models honor a `taskType` hint (Gemini only today). When\n * false/undefined, a caller-supplied `taskType` is a no-op (logged, not\n * failed).\n */\n readonly supportsTaskType?: boolean;\n /** Native fixed output dimension, when the model has one (metadata only). */\n readonly defaultDimensions?: number;\n /**\n * Maximum number of inputs accepted per request. When present, the dispatcher\n * rejects batches larger than this up front (no auto-chunking in v1).\n */\n readonly maxBatchSize?: number;\n}\n\n/**\n * A single embedding task-type hint (Gemini-style). Cross-provider; providers\n * that don't support task typing ignore it (logged, not failed). Open string\n * union so new Gemini task types don't force a churn, with the known set\n * enumerated for ergonomics.\n *\n * @remarks\n * Values are the kebab-case cross-provider form; the Gemini adapter maps them to\n * `SCREAMING_SNAKE_CASE` on the wire (e.g. `'retrieval-document'` →\n * `RETRIEVAL_DOCUMENT`).\n *\n * @public\n */\nexport type AiEmbeddingTaskType =\n | 'retrieval-query'\n | 'retrieval-document'\n | 'semantic-similarity'\n | 'classification'\n | 'clustering'\n | 'code-retrieval-query'\n | 'question-answering'\n | 'fact-verification'\n | (string & {});\n\n/**\n * Parameters for an embedding request. Batch is the norm: `input` accepts a\n * single string or an array; the result always exposes a vector array aligned\n * by index to the input.\n *\n * @public\n */\nexport interface IAiEmbeddingParams {\n /** One or more input strings. A bare string is treated as a single-element batch. */\n readonly input: string | ReadonlyArray<string>;\n /**\n * Requested output dimensionality. Honored only by models whose capability\n * declares `supportsDimensions` (OpenAI `text-embedding-3-*`, Gemini\n * `gemini-embedding-001` via MRL truncation). Ignored — with a `logger.info`\n * note — by models that don't.\n */\n readonly dimensions?: number;\n /**\n * Task-type hint. Mapped to Gemini `taskType`; a no-op (with a `logger.info`\n * note) on OpenAI/Ollama/compat/Mistral. Preserves Gemini's\n * query-vs-document retrieval asymmetry.\n */\n readonly taskType?: AiEmbeddingTaskType;\n}\n\n/**\n * Token-usage accounting for an embedding call, when the provider reports it.\n * @public\n */\nexport interface IAiEmbeddingUsage {\n /** Tokens consumed by the input(s). */\n readonly promptTokens?: number;\n /** Total tokens billed. */\n readonly totalTokens?: number;\n}\n\n/**\n * Result of an embedding call. `vectors[i]` is the embedding for `input[i]`,\n * in request order.\n *\n * @remarks\n * Vectors are plain `number[]` (not `Float32Array`) for JSON-wire fidelity and\n * validator-friendliness — consumers who want a typed array call\n * `Float32Array.from(vector)` at the vector-store / WebGPU boundary. The\n * library does not L2-normalize; Gemini's MRL truncation (when\n * `dimensions < native`) returns un-normalized vectors that the consumer should\n * normalize if their similarity metric requires it.\n *\n * @public\n */\nexport interface IAiEmbeddingResult {\n /** One vector per input, aligned by index to the request order. */\n readonly vectors: ReadonlyArray<ReadonlyArray<number>>;\n /** The resolved provider-native model id that produced the vectors. */\n readonly model: string;\n /** Dimensionality of each returned vector (`vectors[0].length`; `0` for empty input). */\n readonly dimensions: number;\n /** Token usage, when the provider reports it (OpenAI-format; absent for Gemini). */\n readonly usage?: IAiEmbeddingUsage;\n}\n\n// ============================================================================\n// Image Generation — Layered Options Types\n// ============================================================================\n\n/** Pixel dimension sizes accepted by dall-e-2. @public */\nexport type DallE2Size = '256x256' | '512x512' | '1024x1024';\n\n/** Pixel dimension sizes accepted by dall-e-3. @public */\nexport type DallE3Size = '1024x1024' | '1792x1024' | '1024x1792';\n\n/** Pixel dimension sizes accepted by gpt-image-1. @public */\nexport type GptImageSize = '1024x1024' | '1536x1024' | '1024x1536' | 'auto';\n\n/** All accepted image size strings across all providers. @public */\nexport type AiImageSize = DallE2Size | DallE3Size | GptImageSize;\n\n/** Quality values for dall-e-3. @public */\nexport type DallE3Quality = 'standard' | 'hd';\n\n/** Quality values for gpt-image-1. @public */\nexport type GptImageQuality = 'low' | 'medium' | 'high' | 'auto';\n\n/** All accepted quality strings across all providers. @public */\nexport type AiImageQuality = DallE3Quality | GptImageQuality;\n\n/** Model names in the DALL-E family. @public */\nexport type DallEModelNames = 'dall-e-2' | 'dall-e-3';\n\n/** Model names in the GPT Image family. @public */\nexport type GptImageModelNames = 'gpt-image-1';\n\n/** Model names in the xAI Grok Imagine family. @public */\nexport type GrokImagineModelNames = 'grok-imagine-image' | 'grok-imagine-image-quality';\n\n/** Model names in the Imagen 4 family. @public */\nexport type Imagen4ModelNames =\n | 'imagen-4.0-generate-001'\n | 'imagen-4.0-ultra-generate-001'\n | 'imagen-4.0-fast-generate-001';\n\n/** Model names in the Gemini Flash Image family. @public */\nexport type GeminiFlashImageModelNames = 'gemini-2.5-flash-image';\n\n// ---- Family-level config shapes ----\n\n/**\n * Provider-specific config for DALL-E models (dall-e-2, dall-e-3).\n * @remarks\n * style is only valid for dall-e-3; the runtime validator rejects it for dall-e-2.\n * @public\n */\nexport interface IDallEImageGenerationConfig {\n /** Image dimensions (dall-e-2: 256x256|512x512|1024x1024; dall-e-3: 1024x1024|1792x1024|1024x1792). */\n readonly size?: DallE2Size | DallE3Size;\n /** dall-e-3 only. Quality tier. */\n readonly quality?: DallE3Quality;\n /** dall-e-3 only. Visual style. */\n readonly style?: 'vivid' | 'natural';\n}\n\n/**\n * Provider-specific config for gpt-image-1.\n * @public\n */\nexport interface IGptImageGenerationConfig {\n /** Image dimensions. */\n readonly size?: GptImageSize;\n /** Quality tier. */\n readonly quality?: GptImageQuality;\n /** Output format (replaces response_format for this model). */\n readonly outputFormat?: 'png' | 'jpeg' | 'webp';\n /** JPEG/WebP compression level 0–100. */\n readonly outputCompression?: number;\n /** Background transparency control. */\n readonly background?: 'transparent' | 'opaque' | 'auto';\n /** Content moderation strictness. */\n readonly moderation?: 'low' | 'auto';\n}\n\n/**\n * Provider-specific config for xAI Grok Imagine models.\n * @public\n */\nexport interface IGrokImagineImageGenerationConfig {\n /** Aspect ratio string (xAI uses aspect ratios, not pixel dimensions). */\n readonly aspectRatio?: string;\n /** Resolution hint. */\n readonly resolution?: string;\n}\n\n/**\n * Provider-specific config for Google Imagen 4 models.\n * @public\n */\nexport interface IImagen4GenerationConfig {\n /** Aspect ratio string. */\n readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';\n /** Output resolution. */\n readonly imageSize?: '1K' | '2K';\n /** Whether to add SynthID watermark. Must be false to use seed. */\n readonly addWatermark?: boolean;\n /** LLM-based prompt rewriting. */\n readonly enhancePrompt?: boolean;\n /** Output MIME type. */\n readonly outputMimeType?: 'image/jpeg' | 'image/png';\n /** JPEG compression quality. */\n readonly outputCompressionQuality?: number;\n /** Person generation policy. */\n readonly personGeneration?: 'allow_all' | 'allow_adult' | 'dont_allow';\n}\n\n/**\n * Provider-specific config for Gemini Flash Image.\n * @public\n */\nexport interface IGeminiFlashImageGenerationConfig {\n /** Aspect ratio string. */\n readonly aspectRatio?: string;\n}\n\n// ---- Model-family option blocks ----\n\n/**\n * Base shape shared by all named family option blocks.\n * Provides a typed `models` field for applicability filtering without unsafe casts.\n * @internal\n */\nexport interface INamedModelFamilyConfig {\n readonly models?: readonly string[];\n}\n\n/**\n * Options block scoped to DALL-E family models.\n * @public\n */\nexport interface IDallEModelOptions extends INamedModelFamilyConfig {\n /** Discriminator: openai provider lineage. */\n readonly provider: 'openai';\n /** Family identifier. */\n readonly family: 'dall-e';\n /** Optional model names this block applies to. Omit = applies to all DALL-E models. */\n readonly models?: DallEModelNames[];\n /** Family-specific config. */\n readonly config: IDallEImageGenerationConfig;\n}\n\n/**\n * Options block scoped to GPT Image family models.\n * @public\n */\nexport interface IGptImageModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'openai';\n readonly family: 'gpt-image';\n readonly models?: GptImageModelNames[];\n readonly config: IGptImageGenerationConfig;\n}\n\n/**\n * Options block scoped to xAI Grok Imagine family models.\n * @public\n */\nexport interface IGrokImagineModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'xai';\n readonly family: 'grok-imagine';\n readonly models?: GrokImagineModelNames[];\n readonly config: IGrokImagineImageGenerationConfig;\n}\n\n/**\n * Options block scoped to Google Imagen 4 models.\n * @public\n */\nexport interface IImagen4ModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'google';\n readonly family: 'imagen-4';\n readonly models?: Imagen4ModelNames[];\n readonly config: IImagen4GenerationConfig;\n}\n\n/**\n * Options block scoped to Gemini Flash Image models.\n * @public\n */\nexport interface IGeminiFlashImageModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'google';\n readonly family: 'gemini-flash-image';\n readonly models?: GeminiFlashImageModelNames[];\n readonly config: IGeminiFlashImageGenerationConfig;\n}\n\n/**\n * Escape-hatch options block for models not covered by a named family.\n * @remarks\n * `models` is required — there is no implicit \"all\" for unknown model families.\n * `config` is `JsonObject` — passed verbatim to the wire request with no validation.\n * This is the \"trust me, I know what I'm doing\" path for callers who need to send\n * wire params our typed configs don't yet expose.\n * @public\n */\nexport interface IOtherModelOptions {\n readonly provider: 'other';\n readonly models: string[];\n readonly config: JsonObject;\n}\n\n/**\n * Discriminated union of all model-family option blocks.\n * Discriminated on `provider` + `family` fields.\n * @public\n */\nexport type IModelFamilyConfig =\n | IDallEModelOptions\n | IGptImageModelOptions\n | IGrokImagineModelOptions\n | IImagen4ModelOptions\n | IGeminiFlashImageModelOptions\n | IOtherModelOptions;\n\n// ============================================================================\n// Image Generation\n// ============================================================================\n\n/**\n * Options for image generation requests.\n *\n * @remarks\n * Uses a layered architecture:\n * 1. Generic top-level options (size, count, quality, seed) apply across providers\n * via the resolved model's registry mapping.\n * 2. Optional `models` array contains model-family-scoped blocks; the resolver\n * picks applicable blocks based on the resolved model and applies them in\n * declaration order.\n *\n * **Merge precedence (later wins):**\n * 1. Generic top-level options (lowest precedence)\n * 2. Family-generic blocks (matching family, models field omitted)\n * 3. Model-specific blocks (models array includes resolved model name)\n * 4. Other blocks (provider: 'other', models array includes resolved model name)\n *\n * Provider-mismatch: blocks whose provider doesn't match the dispatcher's\n * provider lineage are silently skipped.\n *\n * @public\n */\nexport interface IAiImageGenerationOptions {\n /**\n * Image dimensions for OpenAI models (mapped to `size` field).\n * For xAI aspect ratio or Imagen aspect ratio, use the corresponding `models` family block.\n */\n readonly size?: AiImageSize;\n /** Number of images. Default 1. Some models enforce a maximum. */\n readonly count?: number;\n /**\n * Quality tier. Accepted values differ per model:\n * - dall-e-3: 'standard' | 'hd'\n * - gpt-image-1: 'low' | 'medium' | 'high' | 'auto'\n * Other models ignore this field.\n */\n readonly quality?: AiImageQuality;\n /** Reproducibility seed, where supported. */\n readonly seed?: number;\n /**\n * Optional precision via model-family-scoped blocks. The resolver picks\n * applicable blocks dynamically based on the resolved model.\n */\n readonly models?: ReadonlyArray<IModelFamilyConfig>;\n}\n\n/**\n * Parameters for an image-generation request.\n * @public\n */\nexport interface IAiImageGenerationParams {\n /** The text prompt describing the desired image. */\n readonly prompt: string;\n /** Optional generation options. */\n readonly options?: IAiImageGenerationOptions;\n /**\n * Optional reference images. When present, the provider will use them as\n * visual context (e.g. to preserve a character's appearance across multiple\n * generations). The dispatcher resolves the\n * {@link AiAssist.IAiImageModelCapability} for the requested model and\n * rejects the call up front if `acceptsImageReferenceInput` is not set on\n * the matching capability. An empty array is treated identically to\n * `undefined`.\n */\n readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;\n}\n\n/**\n * A single generated image.\n * @public\n */\nexport interface IAiGeneratedImage extends IAiImageData {\n /**\n * The prompt as rewritten by the provider, if any. OpenAI's image models\n * commonly rewrite prompts; other providers do not.\n */\n readonly revisedPrompt?: string;\n}\n\n// ============================================================================\n// Model Catalog (listModels)\n// ============================================================================\n\n/**\n * Capability vocabulary used to describe what a model can do. Used as both\n * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.\n *\n * @remarks\n * Adding a new capability is cheap; adding the *first* one after consumers\n * already exist forces churn. The initial vocabulary is intentionally broad\n * even though only `image-generation` is fully exercised today.\n *\n * @public\n */\nexport type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation' | 'thinking' | 'embedding';\n\n/**\n * All valid `AiModelCapability` values — the single source of truth for\n * the capability vocabulary (used by validators and capability filters).\n * @public\n */\nexport const allModelCapabilities: ReadonlyArray<AiModelCapability> = [\n 'chat',\n 'tools',\n 'vision',\n 'image-generation',\n 'thinking',\n 'embedding'\n];\n\n/**\n * Information about a single model returned by a provider's list endpoint,\n * with capabilities already resolved (native + config rules).\n * @public\n */\nexport interface IAiModelInfo {\n /** Provider-native model identifier. */\n readonly id: string;\n /** Resolved capability set — union of native declarations and config rules. */\n readonly capabilities: ReadonlySet<AiModelCapability>;\n /** Friendly name for display, when known. */\n readonly displayName?: string;\n}\n\n/**\n * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match\n * a single model — their capability arrays are unioned.\n * @public\n */\nexport interface IAiModelCapabilityRule {\n /** RegExp tested against the model id (using `.test`). */\n readonly idPattern: RegExp;\n /** Capabilities this rule attributes to matching models. */\n readonly capabilities: ReadonlyArray<AiModelCapability>;\n /**\n * Friendly display-name override for matching models. The function form\n * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).\n * If multiple matching rules supply `displayName`, the first match wins.\n */\n readonly displayName?: string | ((id: string) => string);\n}\n\n/**\n * Configuration that maps model id patterns to capabilities. Used to\n * augment (or, where the provider supplies no capability info, fully\n * derive) the capability set for each listed model.\n * @public\n */\nexport interface IAiModelCapabilityConfig {\n /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */\n readonly perProvider?: { readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule> };\n /** Cross-provider fallback rules. */\n readonly global?: ReadonlyArray<IAiModelCapabilityRule>;\n}\n\n/**\n * Result of an image-generation call.\n * @public\n */\nexport interface IAiImageGenerationResponse {\n /** The generated images, in provider-returned order. */\n readonly images: ReadonlyArray<IAiGeneratedImage>;\n}\n\n// ============================================================================\n// Thinking / Reasoning Config — Layered Options Types\n// ============================================================================\n\n/**\n * Model IDs for Anthropic thinking-capable models.\n * @public\n */\nexport type AnthropicThinkingModelNames =\n | 'claude-sonnet-4-5'\n | 'claude-sonnet-4-6'\n | 'claude-opus-4-6'\n | 'claude-opus-4-7';\n\n/**\n * Model IDs for OpenAI thinking-capable models.\n * @public\n */\nexport type OpenAiThinkingModelNames =\n | 'o3'\n | 'o4-mini'\n | 'o3-deep-research'\n | 'o4-mini-deep-research'\n | 'gpt-5'\n | 'gpt-5.1'\n | 'gpt-5.2'\n | 'gpt-5.5'\n | 'gpt-5-pro';\n\n/**\n * Model IDs for Google Gemini thinking-capable models.\n * @public\n */\nexport type GeminiThinkingModelNames = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite';\n\n/**\n * Model IDs for xAI thinking-capable models.\n * @public\n */\nexport type XAiThinkingModelNames = 'grok-3-mini' | 'grok-4.3' | 'grok-4';\n\n/**\n * Anthropic-specific thinking configuration.\n * @public\n */\nexport interface IAnthropicThinkingConfig {\n /**\n * Anthropic effort level. The emit-site converts to `thinking.budget_tokens`\n * (the integer budget the Anthropic API requires). Mapping policy: low = 2048,\n * medium = 8192, high = 24000, max = 32000.\n * - 'low' | 'medium' | 'high': all thinking-capable models\n * - 'max': Opus 4.6 only\n */\n readonly effort?: 'low' | 'medium' | 'high' | 'max';\n}\n\n/**\n * OpenAI-specific thinking configuration.\n * @remarks\n * Maps to `reasoning_effort` (Chat Completions path) or `reasoning.effort`\n * (Responses API path) on the wire. The adapter selects the correct field.\n * @public\n */\nexport interface IOpenAiThinkingConfig {\n /**\n * OpenAI reasoning effort. Maps 1:1 to the wire field.\n * - 'none': disables reasoning (gpt-5.x only; rejected by o-series)\n * - 'minimal': fastest (gpt-5.x)\n * - 'low' | 'medium' | 'high': standard tiers\n * - 'xhigh': highest (select gpt-5.x models only)\n *\n * @remarks\n * When effective effort is 'none', reasoning is disabled and temperature is\n * accepted by gpt-5.x models. This is the only case where temperature and\n * thinking config co-exist without a Result.fail.\n */\n readonly effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n}\n\n/**\n * Google Gemini-specific thinking configuration.\n * @public\n */\nexport interface IGeminiThinkingConfig {\n /**\n * Token budget for thinking. Maps 1:1 to `thinkingBudget` on the wire.\n * - 0: disable thinking (Flash and Flash-Lite only; error on Pro)\n * - positive integer: soft token cap\n * - -1: dynamic\n * - omitted: model default\n */\n readonly thinkingBudget?: number;\n /**\n * Whether to include thought summaries in the response.\n * @remarks\n * INERT in phase B. Adapters never send `includeThoughts: true`.\n * Wired up by the followup stream `ai-assist-thinking-events`.\n */\n readonly includeThoughts?: boolean;\n}\n\n/**\n * xAI-specific thinking configuration.\n * @public\n */\nexport interface IXAiThinkingConfig {\n /**\n * xAI reasoning effort. Maps 1:1 to `reasoning_effort` on the wire.\n * For grok-4, the adapter omits this field (grok-4 always reasons and\n * rejects the parameter).\n */\n readonly effort?: 'none' | 'low' | 'medium' | 'high';\n}\n\n/**\n * Anthropic-specific thinking options block.\n * @public\n */\nexport interface IAnthropicThinkingOptions {\n readonly provider: 'anthropic';\n readonly models?: ReadonlyArray<AnthropicThinkingModelNames>;\n readonly config: IAnthropicThinkingConfig;\n}\n\n/**\n * OpenAI-specific thinking options block.\n * @public\n */\nexport interface IOpenAiThinkingOptions {\n readonly provider: 'openai';\n readonly models?: ReadonlyArray<OpenAiThinkingModelNames>;\n readonly config: IOpenAiThinkingConfig;\n}\n\n/**\n * Google Gemini-specific thinking options block.\n * @public\n */\nexport interface IGeminiThinkingOptions {\n readonly provider: 'google';\n readonly models?: ReadonlyArray<GeminiThinkingModelNames>;\n readonly config: IGeminiThinkingConfig;\n}\n\n/**\n * xAI-specific thinking options block.\n * @public\n */\nexport interface IXAiThinkingOptions {\n readonly provider: 'xai';\n readonly models?: ReadonlyArray<XAiThinkingModelNames>;\n readonly config: IXAiThinkingConfig;\n}\n\n/**\n * Escape-hatch options block for providers not covered by typed configs.\n * @remarks\n * `models` is required — no implicit \"all\" for unknown providers.\n * `config` fields are merged verbatim into the wire request.\n * @public\n */\nexport interface IOtherThinkingOptions {\n readonly provider: 'other';\n readonly models: ReadonlyArray<string>;\n readonly config: JsonObject;\n}\n\n/**\n * Discriminated union of per-provider thinking config blocks.\n * @public\n */\nexport type IThinkingProviderConfig =\n | IAnthropicThinkingOptions\n | IOpenAiThinkingOptions\n | IGeminiThinkingOptions\n | IXAiThinkingOptions\n | IOtherThinkingOptions;\n\n/**\n * Thinking/reasoning mode configuration for a completion request.\n *\n * @remarks\n * The generic `effort` field covers the common-subset cross-provider vocabulary.\n * For provider-specific precision (Anthropic 'max', OpenAI 'xhigh', Gemini token\n * budgets, xAI effort-level tuning), use the `providers` array.\n *\n * Absence (or undefined) means \"no thinking mode\" — existing callers are unaffected.\n *\n * @public\n */\nexport interface IThinkingConfig {\n /**\n * Cross-provider effort level. Common-subset mapping:\n * - 'low': Anthropic effort:low | OpenAI effort:low | Gemini thinkingBudget:1024 | xAI reasoning_effort:low\n * - 'medium': effort:medium | effort:medium | thinkingBudget:4096 | reasoning_effort:medium\n * - 'high': effort:high | effort:high | thinkingBudget:8192 | reasoning_effort:high\n */\n readonly effort?: 'low' | 'medium' | 'high';\n /**\n * Optional per-provider precision blocks. Blocks for providers that don't\n * match the resolved model's provider are silently skipped.\n */\n readonly providers?: ReadonlyArray<IThinkingProviderConfig>;\n}\n\n// ============================================================================\n// Settings\n// ============================================================================\n\n/**\n * Configuration for a single AI assist provider.\n * @public\n */\nexport interface IAiAssistProviderConfig {\n /** Which provider this configures */\n readonly provider: AiProviderId;\n /** For API-based providers: the keystore secret name holding the API key */\n readonly secretName?: string;\n /** Optional model override — string or context-aware map. */\n readonly model?: ModelSpec;\n /** Tool enablement/configuration. Tools are disabled unless explicitly enabled. */\n readonly tools?: ReadonlyArray<IAiToolEnablement>;\n /**\n * Optional caller-supplied endpoint URL (http/https). Overrides\n * `descriptor.baseUrl` for this provider. Used to point a provider at a\n * self-hosted server (Ollama, LM Studio, llama.cpp's openai-server) or a\n * local proxy. Validation lives in `@fgv/ts-extras` — query strings,\n * fragments, and userinfo are rejected.\n */\n readonly endpoint?: string;\n}\n\n/**\n * AI assist settings — which providers are enabled and their configuration.\n * @public\n */\nexport interface IAiAssistSettings {\n /** Enabled providers and their configuration. */\n readonly providers: ReadonlyArray<IAiAssistProviderConfig>;\n /** Which enabled provider is the default for the main button. Falls back to first in list. */\n readonly defaultProvider?: AiProviderId;\n /** Optional proxy URL for routing API requests through a backend server (e.g. `http://localhost:3002`). */\n readonly proxyUrl?: string;\n /** When true, route all providers through the proxy. When false (default), only CORS-restricted providers use the proxy. */\n readonly proxyAllProviders?: boolean;\n}\n\n/**\n * Default AI assist settings (copy-paste only).\n * @public\n */\nexport const DEFAULT_AI_ASSIST: IAiAssistSettings = {\n providers: [{ provider: 'copy-paste' }]\n};\n\n// ============================================================================\n// Keystore Interface\n// ============================================================================\n\n/**\n * Minimal keystore interface for AI assist API key resolution.\n * Satisfied structurally by the concrete `KeyStore` class from `@fgv/ts-extras`.\n * @public\n */\nexport interface IAiAssistKeyStore {\n /** Whether the keystore is currently unlocked */\n readonly isUnlocked: boolean;\n /** Check if a named secret exists */\n hasSecret(name: string): Result<boolean>;\n /** Get an API key by secret name */\n getApiKey(name: string): Result<string>;\n}\n"]}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/model.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Core types for AI assist: prompt class, provider descriptors, settings, and chat messages.\n * @packageDocumentation\n */\n\nimport { type Result } from '@fgv/ts-utils';\nimport { type JsonObject, type JsonSchema } from '@fgv/ts-json-base';\n\n// ============================================================================\n// Image Data\n// ============================================================================\n\n/**\n * Universal image representation used for both image input (vision prompts)\n * and image output (generation responses).\n *\n * @remarks\n * The base64 string is raw — no `data:` URL prefix. Use {@link AiAssist.toDataUrl} to\n * format it for browser-display contexts.\n *\n * @public\n */\nexport interface IAiImageData {\n /** MIME type, e.g. `'image/png'`, `'image/jpeg'`, `'image/webp'`. */\n readonly mimeType: string;\n /** Base64-encoded image bytes (no `data:` prefix). */\n readonly base64: string;\n}\n\n/**\n * Formats an {@link IAiImageData} as a `data:` URL suitable for browser display.\n * @param image - The image to format\n * @returns A `data:<mime>;base64,<data>` URL string\n * @public\n */\nexport function toDataUrl(image: IAiImageData): string {\n return `data:${image.mimeType};base64,${image.base64}`;\n}\n\n/**\n * Image attachment for a vision (image-input) prompt.\n *\n * @remarks\n * Extends {@link IAiImageData} with an OpenAI-specific `detail` hint that is\n * silently ignored by Anthropic, Gemini, and other providers.\n *\n * @public\n */\nexport interface IAiImageAttachment extends IAiImageData {\n /**\n * OpenAI vision detail hint:\n * - `'low'`: faster, cheaper, lower fidelity\n * - `'high'`: slower, more expensive, higher fidelity\n * - `'auto'` (default): provider chooses\n *\n * Ignored by providers other than OpenAI.\n */\n readonly detail?: 'low' | 'high' | 'auto';\n}\n\n// ============================================================================\n// AiPrompt\n// ============================================================================\n\n/**\n * A structured AI prompt with system/user split for direct API calls,\n * and a lazily-constructed combined version for copy/paste workflows.\n * @public\n */\nexport class AiPrompt {\n /** System instructions: schema documentation, format rules, general guidance. */\n public readonly system: string;\n /** User request: the specific entity generation request. */\n public readonly user: string;\n /**\n * Optional image attachments. When present, vision-capable providers will\n * include them in the user message; non-vision providers will reject the\n * call up front (see {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}).\n */\n public readonly attachments: ReadonlyArray<IAiImageAttachment>;\n\n public constructor(user: string, system: string, attachments?: ReadonlyArray<IAiImageAttachment>) {\n this.system = system;\n this.user = user;\n this.attachments = attachments ?? [];\n }\n\n /**\n * Combined single-string version (user + system joined) for copy/paste.\n * When attachments are present, includes a sentinel noting they aren't\n * part of the copied text.\n */\n public get combined(): string {\n const sentinel =\n this.attachments.length > 0\n ? `\\n\\n[${this.attachments.length} image attachment(s) — not included in copied text]`\n : '';\n return `${this.user}${sentinel}\\n\\n${this.system}`;\n }\n\n /**\n * Lowers this prompt to the unified {@link AiAssist.IChatRequest} shape consumed\n * by the turn entry points (`callProviderCompletion`,\n * `callProviderCompletionStream`, `generateJsonCompletion`,\n * `executeClientToolTurn`). The prompt becomes a single current `user` turn\n * (carrying any attachments) with the system instructions in the distinct\n * `system` field.\n */\n public toRequest(): IChatRequest {\n return {\n system: this.system,\n messages: [\n {\n role: 'user',\n content: this.user,\n ...(this.attachments.length > 0 ? { attachments: this.attachments } : {})\n }\n ]\n };\n }\n}\n\n// ============================================================================\n// Chat Message\n// ============================================================================\n\n/**\n * A single chat message in OpenAI format.\n * @public\n */\nexport interface IChatMessage {\n /** Message role */\n readonly role: 'system' | 'user' | 'assistant';\n /** Message content */\n readonly content: string;\n /**\n * Optional image attachments. Only honoured on the **current turn** (the last\n * message of an {@link AiAssist.IChatRequest}); vision-capable providers include\n * them in that user message, non-vision providers reject the call up front (see\n * {@link AiAssist.IAiProviderDescriptor.acceptsImageInput}). Attachments on\n * history (non-final) messages are ignored.\n */\n readonly attachments?: ReadonlyArray<IAiImageAttachment>;\n}\n\n// ============================================================================\n// Chat Request\n// ============================================================================\n\n/**\n * An ordered chat request: optional system instructions plus the conversation\n * turns. The **last** entry in `messages` is the current turn (always a `user`\n * turn); everything before it is prior conversation history.\n *\n * @remarks\n * This is the unified shape accepted by every turn entry point. Both the\n * completion path and the client-tool turn path linearize it identically:\n * `[system, ...history, current user turn, ...continuation]`. Keeping `system`\n * as a distinct field (rather than a `system`-role message) matches how the\n * per-provider request builders already separate system from the turn list\n * (Anthropic top-level `system`, Gemini `systemInstruction`, OpenAI a leading\n * `system`-role message). `messages` should therefore carry only `user` /\n * `assistant` turns.\n *\n * @public\n */\nexport interface IChatRequest {\n /** System instructions (schema docs, format rules, general guidance). */\n readonly system?: string;\n /**\n * The ordered conversation turns. Must be non-empty; the last entry is the\n * current `user` turn and the preceding entries are history.\n */\n readonly messages: ReadonlyArray<IChatMessage>;\n}\n\n// ============================================================================\n// Server-Side Tools\n// ============================================================================\n\n/**\n * Built-in server-side tool types supported across providers.\n * @public\n */\nexport type AiServerToolType = 'web_search';\n\n/**\n * Configuration specific to web search tools.\n * @public\n */\nexport interface IAiWebSearchToolConfig {\n readonly type: 'web_search';\n /** Optional: restrict search to these domains. */\n readonly allowedDomains?: ReadonlyArray<string>;\n /** Optional: exclude these domains from search. */\n readonly blockedDomains?: ReadonlyArray<string>;\n /** Optional: max number of searches per request. */\n readonly maxUses?: number;\n /**\n * Optional: enable image understanding during web search.\n * When true, the model can view and analyze images found during search.\n * Currently supported by xAI only; ignored by other providers.\n */\n readonly enableImageUnderstanding?: boolean;\n}\n\n/**\n * Union of all server-side tool configurations. Discriminated on `type`.\n * @public\n */\nexport type AiServerToolConfig = IAiWebSearchToolConfig;\n\n/**\n * Declares a tool as enabled/disabled in provider settings.\n * Tools are disabled by default — consuming apps must opt in explicitly.\n * @public\n */\nexport interface IAiToolEnablement {\n /** Which tool type. */\n readonly type: AiServerToolType;\n /** Whether this tool is enabled by default for this provider. */\n readonly enabled: boolean;\n /** Optional tool-specific configuration. */\n readonly config?: AiServerToolConfig;\n}\n\n// ============================================================================\n// Client-Defined Tools\n// ============================================================================\n\n/**\n * Configuration for a client-defined (harness-supplied) tool.\n *\n * @remarks\n * The `parametersSchema` is the single source of truth for both the wire-format\n * JSON Schema sent to the provider (via `.toJson()`) and the runtime argument\n * validation (via `.validate(rawArgs)`). Use `JsonSchema.object(...)` from\n * `@fgv/ts-json-base` to author the schema as a const (e.g. `const mySchema = JsonSchema.object({...})`);\n * the static type `TParams` is then derived via `JsonSchema.Static<typeof mySchema>` —\n * no drift between wire schema and runtime validation.\n *\n * @public\n */\nexport interface IAiClientToolConfig<TParams = unknown> {\n /** Discriminator — always `'client_tool'`. */\n readonly type: 'client_tool';\n /** Tool name sent to the model (must be unique within a call). */\n readonly name: string;\n /** Human-readable description of what the tool does, shown to the model. */\n readonly description: string;\n /**\n * JSON Schema validator for the tool's parameters. Emits wire format via\n * `.toJson()` and validates model-returned args via `.validate(rawArgs)`.\n */\n readonly parametersSchema: JsonSchema.ISchemaValidator<TParams>;\n}\n\n/**\n * A client-defined tool: configuration + execution callback pair.\n *\n * @remarks\n * The `execute` callback receives typed `TParams` (already validated by\n * `config.parametersSchema.validate()`) and returns a `Promise<Result<unknown>>`.\n * Thrown errors are caught via `captureAsyncResult` in the round-trip helper.\n *\n * @public\n */\nexport interface IAiClientTool<TParams = unknown> {\n /** The tool's configuration (name, description, parameters schema). */\n readonly config: IAiClientToolConfig<TParams>;\n /**\n * Execute the tool with validated parameters.\n * @param args - Typed arguments, already validated against `config.parametersSchema`.\n * @returns A `Promise<Result<unknown>>` — the result is stringified and sent back to the model.\n */\n readonly execute: (args: TParams) => Promise<Result<unknown>>;\n}\n\n/**\n * Union of all tool configurations: server-side or client-defined.\n * Discriminated on `type`.\n * @public\n */\nexport type AiToolConfig = AiServerToolConfig | IAiClientToolConfig;\n\n// ============================================================================\n// Client Tool Streaming Events\n// ============================================================================\n\n/**\n * Emitted when a client-defined tool call begins streaming. Carries the tool name\n * and optional provider-assigned call ID (Anthropic / OpenAI Responses API; absent\n * for Gemini which does not assign call IDs).\n * @public\n */\nexport interface IAiStreamToolUseStart {\n readonly type: 'client-tool-call-start';\n /** The name of the client tool being called. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier (Anthropic: `toolu_*`; OpenAI: `call_*`).\n * Absent for Gemini (correlation by name).\n */\n readonly callId?: string;\n}\n\n/**\n * Emitted when a client-defined tool call is complete and its arguments are fully\n * accumulated. The `args` object is the fully parsed JSON object — no further\n * streaming deltas follow for this call.\n * @public\n */\nexport interface IAiStreamToolUseDelta {\n readonly type: 'client-tool-call-done';\n /** The name of the client tool being called. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier. Absent for Gemini.\n */\n readonly callId?: string;\n /** The fully accumulated and parsed tool arguments. */\n readonly args: JsonObject;\n}\n\n/**\n * Emitted after a client-defined tool has been executed and the result is ready\n * to be fed back to the model in the round-trip continuation.\n * @public\n */\nexport interface IAiStreamToolUseComplete {\n readonly type: 'client-tool-result';\n /** The name of the client tool that was executed. */\n readonly toolName: string;\n /**\n * Provider-assigned call identifier. Absent for Gemini.\n */\n readonly callId?: string;\n /** The stringified result returned by the tool's execute callback. */\n readonly result: string;\n /** Whether the tool execution failed (schema validation failure, execute error, or unknown tool). */\n readonly isError: boolean;\n}\n\n// ============================================================================\n// Client Tool Round-Trip Types\n// ============================================================================\n\n/**\n * Summary of a single client tool call within a turn: the tool name, call ID,\n * raw arguments, execution result, and whether the execution was an error.\n * @public\n */\nexport interface IAiClientToolCallSummary {\n /** The name of the tool that was called. */\n readonly toolName: string;\n /** Provider-assigned call identifier (absent for Gemini). */\n readonly callId?: string;\n /** The fully accumulated raw arguments object as parsed JSON. */\n readonly args: JsonObject;\n /** The stringified result (success value or error message). */\n readonly result: string;\n /** Whether execution failed (schema validation failure, execute error, or unknown tool). */\n readonly isError: boolean;\n}\n\n/**\n * The provider-specific continuation data needed to build the follow-up request\n * for the next round of the conversation.\n *\n * @remarks\n * `messages` are provider-native request objects (Anthropic: content-block arrays,\n * OpenAI Responses API: input items, Gemini: content parts). The continuation\n * builder in `clientToolContinuationBuilder.ts` populates this.\n *\n * @public\n */\nexport interface IAiClientToolContinuation {\n /**\n * **Cumulative** provider-native wire-format message objects covering all\n * tool rounds so far. On each turn, `executeClientToolTurn` prepends the\n * inbound `continuationMessages` so that this array always contains the\n * complete wire tail from round 1 through the current round.\n *\n * To drive a multi-round loop, simply **replace** `continuationMessages`\n * with this value — do not manually concatenate:\n *\n * ```ts\n * let tail: JsonObject[] | undefined;\n * while (true) {\n * const { events, nextTurn } = executeClientToolTurn({\n * ..., continuationMessages: tail\n * }).orThrow();\n * for await (const e of events) { /* observe *\\/ }\n * const outcome = (await nextTurn).orThrow();\n * if (!outcome.continuation) break;\n * tail = [...outcome.continuation.messages]; // replace — already cumulative\n * }\n * ```\n *\n * The exact shape is provider-native and may include provider-specific\n * blocks (e.g. Anthropic thinking/redacted_thinking/tool_use, OpenAI\n * function_call/function_call_output items, Gemini functionCall/functionResponse\n * parts). These are NOT `IChatMessage[]` and must NOT be placed in the\n * `messages` parameter — the normalized-message path strips provider-native\n * fields (thinking signatures, redacted_thinking data) that the server\n * requires for continuation validation.\n *\n * `toolCallsSummary` is per-round only (the calls executed in the current\n * turn). Only `messages` is cumulative.\n */\n readonly messages: ReadonlyArray<JsonObject>;\n /** Summary of each tool call executed in this turn (per-round, not cumulative). */\n readonly toolCallsSummary: ReadonlyArray<IAiClientToolCallSummary>;\n}\n\n/**\n * The result of a single client-tool turn: the optional continuation for the next\n * call (absent when no tool calls occurred) and whether the stream was truncated.\n * @public\n */\nexport interface IAiClientToolTurnResult {\n /**\n * The continuation data for the next round-trip. `undefined` when the model\n * completed without invoking any client tools.\n */\n readonly continuation: IAiClientToolContinuation | undefined;\n /** Whether the stream was truncated (token limit or stop reason). */\n readonly truncated: boolean;\n /** The full concatenated text from all `text-delta` events in this turn. */\n readonly fullText: string;\n}\n\n// ============================================================================\n// Model Specification\n// ============================================================================\n\n/**\n * Known context keys for model specification maps.\n * @public\n */\nexport type ModelSpecKey = 'base' | 'tools' | 'image' | 'thinking' | 'embedding';\n\n/**\n * All valid {@link ModelSpecKey} values.\n * @public\n */\nexport const allModelSpecKeys: ReadonlyArray<ModelSpecKey> = [\n 'base',\n 'tools',\n 'image',\n 'thinking',\n 'embedding'\n];\n\n/**\n * Default context key used as fallback when resolving a {@link ModelSpec}.\n * @public\n */\nexport const MODEL_SPEC_BASE_KEY: ModelSpecKey = 'base';\n\n/**\n * A model specification: either a simple model string or a record mapping\n * context keys to nested model specs.\n *\n * @remarks\n * A bare string is equivalent to `{ base: string }`. This keeps the simple\n * case simple while allowing context-aware model selection (e.g. different\n * models for tool-augmented vs. base completions).\n *\n * @example\n * ```typescript\n * // Simple — same model for all contexts:\n * const simple: ModelSpec = 'grok-4.3';\n *\n * // Context-aware — different model for tools and thinking:\n * const split: ModelSpec = { base: 'grok-4.3', tools: 'grok-4.3', thinking: 'grok-4.3' };\n *\n * // Future nested — per-tool model selection:\n * const nested: ModelSpec = { base: 'grok-fast', tools: { base: 'grok-r', image: 'grok-v' } };\n * ```\n * @public\n */\nexport interface IModelSpecMap {\n readonly [key: string]: ModelSpec;\n}\n\n/**\n * @public\n */\nexport type ModelSpec = string | IModelSpecMap;\n\n/**\n * Resolves a {@link ModelSpec} to a concrete model string given an optional context key.\n *\n * @remarks\n * Resolution rules:\n * 1. If the spec is a string, return it directly (context is irrelevant).\n * 2. If the spec is an object and the context key exists, recurse into that branch.\n * 3. Otherwise, fall back to the {@link MODEL_SPEC_BASE_KEY | 'base'} key.\n * 4. If neither context nor `'base'` exists, use the first available value.\n *\n * @param spec - The model specification to resolve\n * @param context - Optional context key (e.g. `'tools'`)\n * @returns The resolved model string\n * @public\n */\nexport function resolveModel(spec: ModelSpec, context?: string): string {\n if (typeof spec === 'string') {\n return spec;\n }\n\n // Try the requested context key first\n if (context !== undefined && context in spec) {\n return resolveModel(spec[context]);\n }\n\n // Fall back to 'base'\n if (MODEL_SPEC_BASE_KEY in spec) {\n return resolveModel(spec[MODEL_SPEC_BASE_KEY]);\n }\n\n // Last resort: first value in the record\n const first = Object.values(spec)[0];\n /* c8 ignore next 3 - defensive: only reachable with empty object (prevented by converter) */\n if (first === undefined) {\n return '';\n }\n return resolveModel(first);\n}\n\n// ============================================================================\n// Provider Descriptor\n// ============================================================================\n\n/**\n * All known AI provider identifiers.\n * @public\n */\nexport type AiProviderId =\n | 'copy-paste'\n | 'xai-grok'\n | 'openai'\n | 'openai-compat'\n | 'anthropic'\n | 'google-gemini'\n | 'groq'\n | 'mistral'\n | 'ollama';\n\n/**\n * API format categories for provider routing.\n * @public\n */\nexport type AiApiFormat = 'openai' | 'anthropic' | 'gemini';\n\n/**\n * API format categories for image-generation provider routing.\n *\n * @remarks\n * - `'openai-images'` — OpenAI Images API. Routes to `/images/generations`\n * (text-only) or `/images/edits` (when reference images are present).\n * - `'xai-images'` — xAI Images API. Text-only JSON generation request.\n * - `'xai-images-edits'` — xAI Images API for Grok Imagine models. Uses JSON\n * body with `{ type: \"image_url\" }` objects (not multipart).\n * - `'gemini-imagen'` — Google Imagen `:predict` endpoint. Text-only.\n * - `'gemini-image-out'` — Google Gemini chat-style `:generateContent`\n * endpoint that returns image parts (Gemini 2.5 Flash Image / \"Nano\n * Banana\"). Accepts reference images.\n *\n * @public\n */\nexport type AiImageApiFormat =\n | 'openai-images'\n | 'gemini-imagen'\n | 'xai-images'\n | 'xai-images-edits'\n | 'gemini-image-out';\n\n/**\n * API format categories for embedding provider routing.\n *\n * @remarks\n * - `'openai-embeddings'` — OpenAI `/v1/embeddings` shape. Serves OpenAI,\n * Ollama (via `/v1`), openai-compat self-hosted servers (vLLM, LM Studio,\n * llama.cpp's openai-server), and Mistral (`mistral-embed`) — all of which\n * speak the same request/response shape.\n * - `'gemini-embeddings'` — Google Gemini `:batchEmbedContents` endpoint. A\n * genuinely divergent shape (different route, auth header, request body, and\n * the `taskType` retrieval-asymmetry knob that has no OpenAI analog).\n *\n * Named with the `ApiFormat` suffix for symmetry with `AiApiFormat` and\n * `AiImageApiFormat`.\n *\n * @public\n */\nexport type AiEmbeddingApiFormat = 'openai-embeddings' | 'gemini-embeddings';\n\n// ============================================================================\n// Completion Response\n// ============================================================================\n\n/**\n * Result of an AI provider completion call.\n * @public\n */\nexport interface IAiCompletionResponse {\n /** The generated text content */\n readonly content: string;\n /** Whether the response was truncated due to token limits */\n readonly truncated: boolean;\n}\n\n// ============================================================================\n// Streaming Events\n// ============================================================================\n\n/**\n * A text-content delta arriving during a streaming completion.\n * @public\n */\nexport interface IAiStreamTextDelta {\n readonly type: 'text-delta';\n /** The newly arrived text fragment. */\n readonly delta: string;\n}\n\n/**\n * A server-side tool progress event arriving during a streaming completion.\n * Surfaced for providers that emit explicit tool-progress markers (OpenAI\n * Responses API, Anthropic). Gemini's grounding doesn't emit these.\n * @public\n */\nexport interface IAiStreamToolEvent {\n readonly type: 'tool-event';\n /** Which server-side tool this event describes. */\n readonly toolType: AiServerToolType;\n /** Tool lifecycle phase. */\n readonly phase: 'started' | 'completed';\n /**\n * Optional provider-specific detail. For web_search this is typically the\n * search query when available; format varies by provider.\n */\n readonly detail?: string;\n}\n\n/**\n * Terminal success event for a streaming completion. Carries the aggregated\n * full text and truncation status for callers that want both the progressive\n * UI and the complete result.\n * @public\n */\nexport interface IAiStreamDone {\n readonly type: 'done';\n /** Whether the response was truncated due to token limits. */\n readonly truncated: boolean;\n /** The full concatenated text from all `text-delta` events. */\n readonly fullText: string;\n /**\n * Provider-reported reason a truncated response was cut short (e.g.\n * `'max_output_tokens'`, `'content_filter'`), when the provider supplies one.\n * Currently populated only by the OpenAI / xAI Responses adapter, from the\n * completed payload's `incomplete_details.reason`. Meaningful only when\n * `truncated === true`; `undefined` otherwise (and whenever the provider\n * reports truncation without a reason).\n */\n readonly incompleteReason?: string;\n}\n\n/**\n * Terminal failure event for a streaming completion. After this event no\n * further events are emitted.\n *\n * @remarks\n * Connection-time failures (auth, network, pre-flight CORS rejection) are\n * surfaced via the outer `Result.fail` returned by\n * `callProviderCompletionStream` rather than as an `error` event, so callers\n * can distinguish \"didn't start\" from \"started but errored mid-stream.\"\n *\n * @public\n */\nexport interface IAiStreamError {\n readonly type: 'error';\n readonly message: string;\n}\n\n/**\n * Discriminated union of events emitted by a streaming completion.\n *\n * @remarks\n * **Exhaustive-switch consumers must handle all variants.** The three\n * `client-tool-*` variants were added when client-tool support shipped;\n * update every exhaustive switch over this union in lockstep.\n *\n * @public\n */\nexport type IAiStreamEvent =\n | IAiStreamTextDelta\n | IAiStreamToolEvent\n | IAiStreamToolUseStart\n | IAiStreamToolUseDelta\n | IAiStreamToolUseComplete\n | IAiStreamDone\n | IAiStreamError;\n\n/**\n * Thinking/reasoning mode support for a provider.\n * @public\n */\nexport type AiThinkingMode = 'optional' | 'required' | 'unsupported';\n\n/**\n * Describes a single AI provider — single source of truth for all metadata.\n * @public\n */\nexport interface IAiProviderDescriptor {\n /** Provider identifier (e.g. 'xai-grok', 'anthropic') */\n readonly id: AiProviderId;\n /** Human-readable label (e.g. \"xAI Grok\") */\n readonly label: string;\n /** Button label for action buttons (e.g. \"AI Assist | Grok\") */\n readonly buttonLabel: string;\n /** Whether this provider requires an API key secret */\n readonly needsSecret: boolean;\n /** Which API adapter format to use */\n readonly apiFormat: AiApiFormat;\n /** Base URL for the API (e.g. 'https://api.x.ai/v1') */\n readonly baseUrl: string;\n /** Default model specification — string or context-aware map. */\n readonly defaultModel: ModelSpec;\n /** Which server-side tools this provider supports (empty = none). */\n readonly supportedTools: ReadonlyArray<AiServerToolType>;\n /** Whether this provider's API enforces CORS restrictions that prevent direct browser calls. */\n readonly corsRestricted: boolean;\n /**\n * Whether this provider's streaming completion endpoint requires a proxy\n * for direct browser calls. Some providers gate streaming separately from\n * non-streaming (rare), so this is tracked independently from\n * {@link IAiProviderDescriptor.corsRestricted}.\n *\n * @remarks\n * When `true`, `callProviderCompletionStream` rejects up front unless the\n * call is being routed through a proxy.\n */\n readonly streamingCorsRestricted: boolean;\n /**\n * Whether this provider's chat completions API accepts image input\n * (i.e. supports vision prompts). When false, calls with\n * `prompt.attachments` are rejected up front.\n */\n readonly acceptsImageInput: boolean;\n /**\n * Whether this provider supports thinking/reasoning mode.\n * - 'optional': thinking can be enabled but is not required\n * - 'required': thinking is always active (e.g. o-series models)\n * - 'unsupported': thinking is not supported\n */\n readonly thinkingMode: AiThinkingMode;\n /**\n * Image-generation capabilities, scoped to model id prefixes. Empty or\n * undefined means the provider does not support image generation.\n *\n * @remarks\n * The dispatcher matches the resolved model id against each rule's\n * `modelPrefix` and selects the longest match (see\n * {@link AiAssist.resolveImageCapability}). An empty `modelPrefix` is the\n * catch-all and matches every model id.\n *\n * Multiple entries support providers that host more than one image-API\n * surface under one baseUrl. Google Gemini is the canonical case: the\n * `imagen-*` family is predict-only via `:predict`, while\n * `gemini-2.5-flash-image` uses chat-style `:generateContent` and accepts\n * reference images. Listing both lets callers pick the right model and the\n * dispatcher routes accordingly.\n *\n * Image-model selection reuses the existing `image` {@link ModelSpecKey}.\n * Providers that declare `imageGeneration` should declare a model in\n * `defaultModel.image`, e.g. `{ base: 'gpt-4o', image: 'dall-e-3' }`.\n */\n readonly imageGeneration?: ReadonlyArray<IAiImageModelCapability>;\n /**\n * Embedding capabilities, scoped to model id prefixes. Empty or undefined\n * means the provider does not support embeddings.\n *\n * @remarks\n * The dispatcher matches the resolved embedding model id against each rule's\n * `modelPrefix` and selects the longest match (see\n * {@link AiAssist.resolveEmbeddingCapability}). An empty `modelPrefix` is the\n * catch-all and matches every model id.\n *\n * Embedding-model selection uses the `embedding` {@link ModelSpecKey}.\n * Providers that declare `embedding` should declare a model in\n * `defaultModel.embedding`, e.g. `{ base: 'gpt-4o', embedding: 'text-embedding-3-small' }`.\n * Self-hosted providers (`ollama`, `openai-compat`) leave it unset — the\n * caller supplies the embedding model via `modelOverride`.\n */\n readonly embedding?: ReadonlyArray<IAiEmbeddingModelCapability>;\n}\n\n/**\n * Image-generation capability for a model family within a provider. Used as\n * an entry in {@link IAiProviderDescriptor.imageGeneration}.\n *\n * @public\n */\nexport interface IAiImageModelCapability {\n /**\n * Prefix matched against the resolved image model id. The empty string is\n * the catch-all and matches every model. When multiple rules' prefixes\n * match a model id, the longest prefix wins; ties are broken by\n * first-encountered.\n */\n readonly modelPrefix: string;\n /** API format used to dispatch requests for matching models. */\n readonly format: AiImageApiFormat;\n /**\n * Whether matching models accept reference images via\n * {@link AiAssist.IAiImageGenerationParams.referenceImages}. When false or\n * undefined, calls that include reference images are rejected up front.\n */\n readonly acceptsImageReferenceInput?: boolean;\n /** Accepted size strings. When present, dispatcher pre-validates. */\n readonly acceptedSizes?: ReadonlyArray<string>;\n /** When true, quality param is sent. When false/undefined, don't send quality. */\n readonly supportsQualityParam?: boolean;\n /** Accepted quality values when supportsQualityParam is true. */\n readonly acceptedQualities?: ReadonlyArray<string>;\n /** Maximum count (n). When present, dispatcher pre-validates. */\n readonly maxCount?: number;\n /**\n * How to encode the output format on the wire:\n * - 'response-format': send response_format: 'b64_json' (dall-e-2, dall-e-3)\n * - 'output-format': send output_format (gpt-image-1)\n * - 'none': send neither (Imagen, Gemini Flash)\n */\n readonly outputParamStyle?: 'response-format' | 'output-format' | 'none';\n /** Default MIME type for response images. */\n readonly defaultOutputMimeType?: string;\n}\n\n// ============================================================================\n// Embedding — capability + request/result types\n// ============================================================================\n\n/**\n * Embedding capability for a model family within a provider. Used as an entry\n * in {@link IAiProviderDescriptor.embedding}.\n *\n * @public\n */\nexport interface IAiEmbeddingModelCapability {\n /**\n * Prefix matched against the resolved embedding model id. The empty string is\n * the catch-all and matches every model. When multiple rules' prefixes match\n * a model id, the longest prefix wins; ties are broken by first-encountered.\n */\n readonly modelPrefix: string;\n /** API format used to dispatch requests for matching models. */\n readonly format: AiEmbeddingApiFormat;\n /**\n * Whether matching models honor a requested output `dimensions`\n * (OpenAI `text-embedding-3-*`, Gemini `gemini-embedding-001` via MRL\n * truncation). When false/undefined, a caller-supplied `dimensions` is a\n * no-op (logged, not failed — see {@link AiAssist.IAiEmbeddingParams}).\n */\n readonly supportsDimensions?: boolean;\n /**\n * Whether matching models honor a `taskType` hint (Gemini only today). When\n * false/undefined, a caller-supplied `taskType` is a no-op (logged, not\n * failed).\n */\n readonly supportsTaskType?: boolean;\n /** Native fixed output dimension, when the model has one (metadata only). */\n readonly defaultDimensions?: number;\n /**\n * Maximum number of inputs accepted per request. When present, the dispatcher\n * rejects batches larger than this up front (no auto-chunking in v1).\n */\n readonly maxBatchSize?: number;\n}\n\n/**\n * A single embedding task-type hint (Gemini-style). Cross-provider; providers\n * that don't support task typing ignore it (logged, not failed). Open string\n * union so new Gemini task types don't force a churn, with the known set\n * enumerated for ergonomics.\n *\n * @remarks\n * Values are the kebab-case cross-provider form; the Gemini adapter maps them to\n * `SCREAMING_SNAKE_CASE` on the wire (e.g. `'retrieval-document'` →\n * `RETRIEVAL_DOCUMENT`).\n *\n * @public\n */\nexport type AiEmbeddingTaskType =\n | 'retrieval-query'\n | 'retrieval-document'\n | 'semantic-similarity'\n | 'classification'\n | 'clustering'\n | 'code-retrieval-query'\n | 'question-answering'\n | 'fact-verification'\n | (string & {});\n\n/**\n * Parameters for an embedding request. Batch is the norm: `input` accepts a\n * single string or an array; the result always exposes a vector array aligned\n * by index to the input.\n *\n * @public\n */\nexport interface IAiEmbeddingParams {\n /** One or more input strings. A bare string is treated as a single-element batch. */\n readonly input: string | ReadonlyArray<string>;\n /**\n * Requested output dimensionality. Honored only by models whose capability\n * declares `supportsDimensions` (OpenAI `text-embedding-3-*`, Gemini\n * `gemini-embedding-001` via MRL truncation). Ignored — with a `logger.info`\n * note — by models that don't.\n */\n readonly dimensions?: number;\n /**\n * Task-type hint. Mapped to Gemini `taskType`; a no-op (with a `logger.info`\n * note) on OpenAI/Ollama/compat/Mistral. Preserves Gemini's\n * query-vs-document retrieval asymmetry.\n */\n readonly taskType?: AiEmbeddingTaskType;\n}\n\n/**\n * Token-usage accounting for an embedding call, when the provider reports it.\n * @public\n */\nexport interface IAiEmbeddingUsage {\n /** Tokens consumed by the input(s). */\n readonly promptTokens?: number;\n /** Total tokens billed. */\n readonly totalTokens?: number;\n}\n\n/**\n * Result of an embedding call. `vectors[i]` is the embedding for `input[i]`,\n * in request order.\n *\n * @remarks\n * Vectors are plain `number[]` (not `Float32Array`) for JSON-wire fidelity and\n * validator-friendliness — consumers who want a typed array call\n * `Float32Array.from(vector)` at the vector-store / WebGPU boundary. The\n * library does not L2-normalize; Gemini's MRL truncation (when\n * `dimensions < native`) returns un-normalized vectors that the consumer should\n * normalize if their similarity metric requires it.\n *\n * @public\n */\nexport interface IAiEmbeddingResult {\n /** One vector per input, aligned by index to the request order. */\n readonly vectors: ReadonlyArray<ReadonlyArray<number>>;\n /** The resolved provider-native model id that produced the vectors. */\n readonly model: string;\n /** Dimensionality of each returned vector (`vectors[0].length`; `0` for empty input). */\n readonly dimensions: number;\n /** Token usage, when the provider reports it (OpenAI-format; absent for Gemini). */\n readonly usage?: IAiEmbeddingUsage;\n}\n\n// ============================================================================\n// Image Generation — Layered Options Types\n// ============================================================================\n\n/** Pixel dimension sizes accepted by dall-e-2. @public */\nexport type DallE2Size = '256x256' | '512x512' | '1024x1024';\n\n/** Pixel dimension sizes accepted by dall-e-3. @public */\nexport type DallE3Size = '1024x1024' | '1792x1024' | '1024x1792';\n\n/** Pixel dimension sizes accepted by gpt-image-1. @public */\nexport type GptImageSize = '1024x1024' | '1536x1024' | '1024x1536' | 'auto';\n\n/** All accepted image size strings across all providers. @public */\nexport type AiImageSize = DallE2Size | DallE3Size | GptImageSize;\n\n/** Quality values for dall-e-3. @public */\nexport type DallE3Quality = 'standard' | 'hd';\n\n/** Quality values for gpt-image-1. @public */\nexport type GptImageQuality = 'low' | 'medium' | 'high' | 'auto';\n\n/** All accepted quality strings across all providers. @public */\nexport type AiImageQuality = DallE3Quality | GptImageQuality;\n\n/** Model names in the DALL-E family. @public */\nexport type DallEModelNames = 'dall-e-2' | 'dall-e-3';\n\n/** Model names in the GPT Image family. @public */\nexport type GptImageModelNames = 'gpt-image-1';\n\n/** Model names in the xAI Grok Imagine family. @public */\nexport type GrokImagineModelNames = 'grok-imagine-image' | 'grok-imagine-image-quality';\n\n/** Model names in the Imagen 4 family. @public */\nexport type Imagen4ModelNames =\n | 'imagen-4.0-generate-001'\n | 'imagen-4.0-ultra-generate-001'\n | 'imagen-4.0-fast-generate-001';\n\n/** Model names in the Gemini Flash Image family. @public */\nexport type GeminiFlashImageModelNames = 'gemini-2.5-flash-image';\n\n// ---- Family-level config shapes ----\n\n/**\n * Provider-specific config for DALL-E models (dall-e-2, dall-e-3).\n * @remarks\n * style is only valid for dall-e-3; the runtime validator rejects it for dall-e-2.\n * @public\n */\nexport interface IDallEImageGenerationConfig {\n /** Image dimensions (dall-e-2: 256x256|512x512|1024x1024; dall-e-3: 1024x1024|1792x1024|1024x1792). */\n readonly size?: DallE2Size | DallE3Size;\n /** dall-e-3 only. Quality tier. */\n readonly quality?: DallE3Quality;\n /** dall-e-3 only. Visual style. */\n readonly style?: 'vivid' | 'natural';\n}\n\n/**\n * Provider-specific config for gpt-image-1.\n * @public\n */\nexport interface IGptImageGenerationConfig {\n /** Image dimensions. */\n readonly size?: GptImageSize;\n /** Quality tier. */\n readonly quality?: GptImageQuality;\n /** Output format (replaces response_format for this model). */\n readonly outputFormat?: 'png' | 'jpeg' | 'webp';\n /** JPEG/WebP compression level 0–100. */\n readonly outputCompression?: number;\n /** Background transparency control. */\n readonly background?: 'transparent' | 'opaque' | 'auto';\n /** Content moderation strictness. */\n readonly moderation?: 'low' | 'auto';\n}\n\n/**\n * Provider-specific config for xAI Grok Imagine models.\n * @public\n */\nexport interface IGrokImagineImageGenerationConfig {\n /** Aspect ratio string (xAI uses aspect ratios, not pixel dimensions). */\n readonly aspectRatio?: string;\n /** Resolution hint. */\n readonly resolution?: string;\n}\n\n/**\n * Provider-specific config for Google Imagen 4 models.\n * @public\n */\nexport interface IImagen4GenerationConfig {\n /** Aspect ratio string. */\n readonly aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';\n /** Output resolution. */\n readonly imageSize?: '1K' | '2K';\n /** Whether to add SynthID watermark. Must be false to use seed. */\n readonly addWatermark?: boolean;\n /** LLM-based prompt rewriting. */\n readonly enhancePrompt?: boolean;\n /** Output MIME type. */\n readonly outputMimeType?: 'image/jpeg' | 'image/png';\n /** JPEG compression quality. */\n readonly outputCompressionQuality?: number;\n /** Person generation policy. */\n readonly personGeneration?: 'allow_all' | 'allow_adult' | 'dont_allow';\n}\n\n/**\n * Provider-specific config for Gemini Flash Image.\n * @public\n */\nexport interface IGeminiFlashImageGenerationConfig {\n /** Aspect ratio string. */\n readonly aspectRatio?: string;\n}\n\n// ---- Model-family option blocks ----\n\n/**\n * Base shape shared by all named family option blocks.\n * Provides a typed `models` field for applicability filtering without unsafe casts.\n * @internal\n */\nexport interface INamedModelFamilyConfig {\n readonly models?: readonly string[];\n}\n\n/**\n * Options block scoped to DALL-E family models.\n * @public\n */\nexport interface IDallEModelOptions extends INamedModelFamilyConfig {\n /** Discriminator: openai provider lineage. */\n readonly provider: 'openai';\n /** Family identifier. */\n readonly family: 'dall-e';\n /** Optional model names this block applies to. Omit = applies to all DALL-E models. */\n readonly models?: DallEModelNames[];\n /** Family-specific config. */\n readonly config: IDallEImageGenerationConfig;\n}\n\n/**\n * Options block scoped to GPT Image family models.\n * @public\n */\nexport interface IGptImageModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'openai';\n readonly family: 'gpt-image';\n readonly models?: GptImageModelNames[];\n readonly config: IGptImageGenerationConfig;\n}\n\n/**\n * Options block scoped to xAI Grok Imagine family models.\n * @public\n */\nexport interface IGrokImagineModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'xai';\n readonly family: 'grok-imagine';\n readonly models?: GrokImagineModelNames[];\n readonly config: IGrokImagineImageGenerationConfig;\n}\n\n/**\n * Options block scoped to Google Imagen 4 models.\n * @public\n */\nexport interface IImagen4ModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'google';\n readonly family: 'imagen-4';\n readonly models?: Imagen4ModelNames[];\n readonly config: IImagen4GenerationConfig;\n}\n\n/**\n * Options block scoped to Gemini Flash Image models.\n * @public\n */\nexport interface IGeminiFlashImageModelOptions extends INamedModelFamilyConfig {\n readonly provider: 'google';\n readonly family: 'gemini-flash-image';\n readonly models?: GeminiFlashImageModelNames[];\n readonly config: IGeminiFlashImageGenerationConfig;\n}\n\n/**\n * Escape-hatch options block for models not covered by a named family.\n * @remarks\n * `models` is required — there is no implicit \"all\" for unknown model families.\n * `config` is `JsonObject` — passed verbatim to the wire request with no validation.\n * This is the \"trust me, I know what I'm doing\" path for callers who need to send\n * wire params our typed configs don't yet expose.\n * @public\n */\nexport interface IOtherModelOptions {\n readonly provider: 'other';\n readonly models: string[];\n readonly config: JsonObject;\n}\n\n/**\n * Discriminated union of all model-family option blocks.\n * Discriminated on `provider` + `family` fields.\n * @public\n */\nexport type IModelFamilyConfig =\n | IDallEModelOptions\n | IGptImageModelOptions\n | IGrokImagineModelOptions\n | IImagen4ModelOptions\n | IGeminiFlashImageModelOptions\n | IOtherModelOptions;\n\n// ============================================================================\n// Image Generation\n// ============================================================================\n\n/**\n * Options for image generation requests.\n *\n * @remarks\n * Uses a layered architecture:\n * 1. Generic top-level options (size, count, quality, seed) apply across providers\n * via the resolved model's registry mapping.\n * 2. Optional `models` array contains model-family-scoped blocks; the resolver\n * picks applicable blocks based on the resolved model and applies them in\n * declaration order.\n *\n * **Merge precedence (later wins):**\n * 1. Generic top-level options (lowest precedence)\n * 2. Family-generic blocks (matching family, models field omitted)\n * 3. Model-specific blocks (models array includes resolved model name)\n * 4. Other blocks (provider: 'other', models array includes resolved model name)\n *\n * Provider-mismatch: blocks whose provider doesn't match the dispatcher's\n * provider lineage are silently skipped.\n *\n * @public\n */\nexport interface IAiImageGenerationOptions {\n /**\n * Image dimensions for OpenAI models (mapped to `size` field).\n * For xAI aspect ratio or Imagen aspect ratio, use the corresponding `models` family block.\n */\n readonly size?: AiImageSize;\n /** Number of images. Default 1. Some models enforce a maximum. */\n readonly count?: number;\n /**\n * Quality tier. Accepted values differ per model:\n * - dall-e-3: 'standard' | 'hd'\n * - gpt-image-1: 'low' | 'medium' | 'high' | 'auto'\n * Other models ignore this field.\n */\n readonly quality?: AiImageQuality;\n /** Reproducibility seed, where supported. */\n readonly seed?: number;\n /**\n * Optional precision via model-family-scoped blocks. The resolver picks\n * applicable blocks dynamically based on the resolved model.\n */\n readonly models?: ReadonlyArray<IModelFamilyConfig>;\n}\n\n/**\n * Parameters for an image-generation request.\n * @public\n */\nexport interface IAiImageGenerationParams {\n /** The text prompt describing the desired image. */\n readonly prompt: string;\n /** Optional generation options. */\n readonly options?: IAiImageGenerationOptions;\n /**\n * Optional reference images. When present, the provider will use them as\n * visual context (e.g. to preserve a character's appearance across multiple\n * generations). The dispatcher resolves the\n * {@link AiAssist.IAiImageModelCapability} for the requested model and\n * rejects the call up front if `acceptsImageReferenceInput` is not set on\n * the matching capability. An empty array is treated identically to\n * `undefined`.\n */\n readonly referenceImages?: ReadonlyArray<IAiImageAttachment>;\n}\n\n/**\n * A single generated image.\n * @public\n */\nexport interface IAiGeneratedImage extends IAiImageData {\n /**\n * The prompt as rewritten by the provider, if any. OpenAI's image models\n * commonly rewrite prompts; other providers do not.\n */\n readonly revisedPrompt?: string;\n}\n\n// ============================================================================\n// Model Catalog (listModels)\n// ============================================================================\n\n/**\n * Capability vocabulary used to describe what a model can do. Used as both\n * a filter and as a tag in {@link AiAssist.IAiModelInfo.capabilities}.\n *\n * @remarks\n * Adding a new capability is cheap; adding the *first* one after consumers\n * already exist forces churn. The initial vocabulary is intentionally broad\n * even though only `image-generation` is fully exercised today.\n *\n * @public\n */\nexport type AiModelCapability = 'chat' | 'tools' | 'vision' | 'image-generation' | 'thinking' | 'embedding';\n\n/**\n * All valid `AiModelCapability` values — the single source of truth for\n * the capability vocabulary (used by validators and capability filters).\n * @public\n */\nexport const allModelCapabilities: ReadonlyArray<AiModelCapability> = [\n 'chat',\n 'tools',\n 'vision',\n 'image-generation',\n 'thinking',\n 'embedding'\n];\n\n/**\n * Information about a single model returned by a provider's list endpoint,\n * with capabilities already resolved (native + config rules).\n * @public\n */\nexport interface IAiModelInfo {\n /** Provider-native model identifier. */\n readonly id: string;\n /** Resolved capability set — union of native declarations and config rules. */\n readonly capabilities: ReadonlySet<AiModelCapability>;\n /** Friendly name for display, when known. */\n readonly displayName?: string;\n}\n\n/**\n * One rule in an {@link IAiModelCapabilityConfig}. Multiple rules can match\n * a single model — their capability arrays are unioned.\n * @public\n */\nexport interface IAiModelCapabilityRule {\n /** RegExp tested against the model id (using `.test`). */\n readonly idPattern: RegExp;\n /** Capabilities this rule attributes to matching models. */\n readonly capabilities: ReadonlyArray<AiModelCapability>;\n /**\n * Friendly display-name override for matching models. The function form\n * lets one rule format many ids (e.g. `(id) => id.toUpperCase()`).\n * If multiple matching rules supply `displayName`, the first match wins.\n */\n readonly displayName?: string | ((id: string) => string);\n}\n\n/**\n * Configuration that maps model id patterns to capabilities. Used to\n * augment (or, where the provider supplies no capability info, fully\n * derive) the capability set for each listed model.\n * @public\n */\nexport interface IAiModelCapabilityConfig {\n /** Per-provider rules. Tried before {@link AiAssist.IAiModelCapabilityConfig.global}. */\n readonly perProvider?: { readonly [P in AiProviderId]?: ReadonlyArray<IAiModelCapabilityRule> };\n /** Cross-provider fallback rules. */\n readonly global?: ReadonlyArray<IAiModelCapabilityRule>;\n}\n\n/**\n * Result of an image-generation call.\n * @public\n */\nexport interface IAiImageGenerationResponse {\n /** The generated images, in provider-returned order. */\n readonly images: ReadonlyArray<IAiGeneratedImage>;\n}\n\n// ============================================================================\n// Thinking / Reasoning Config — Layered Options Types\n// ============================================================================\n\n/**\n * Model IDs for Anthropic thinking-capable models.\n * @public\n */\nexport type AnthropicThinkingModelNames =\n | 'claude-sonnet-4-5'\n | 'claude-sonnet-4-6'\n | 'claude-opus-4-6'\n | 'claude-opus-4-7';\n\n/**\n * Model IDs for OpenAI thinking-capable models.\n * @public\n */\nexport type OpenAiThinkingModelNames =\n | 'o3'\n | 'o4-mini'\n | 'o3-deep-research'\n | 'o4-mini-deep-research'\n | 'gpt-5'\n | 'gpt-5.1'\n | 'gpt-5.2'\n | 'gpt-5.5'\n | 'gpt-5-pro';\n\n/**\n * Model IDs for Google Gemini thinking-capable models.\n * @public\n */\nexport type GeminiThinkingModelNames = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite';\n\n/**\n * Model IDs for xAI thinking-capable models.\n * @public\n */\nexport type XAiThinkingModelNames = 'grok-3-mini' | 'grok-4.3' | 'grok-4';\n\n/**\n * Anthropic-specific thinking configuration.\n * @public\n */\nexport interface IAnthropicThinkingConfig {\n /**\n * Anthropic effort level. The emit-site converts to `thinking.budget_tokens`\n * (the integer budget the Anthropic API requires). Mapping policy: low = 2048,\n * medium = 8192, high = 24000, max = 32000.\n * - 'low' | 'medium' | 'high': all thinking-capable models\n * - 'max': Opus 4.6 only\n */\n readonly effort?: 'low' | 'medium' | 'high' | 'max';\n}\n\n/**\n * OpenAI-specific thinking configuration.\n * @remarks\n * Maps to `reasoning_effort` (Chat Completions path) or `reasoning.effort`\n * (Responses API path) on the wire. The adapter selects the correct field.\n * @public\n */\nexport interface IOpenAiThinkingConfig {\n /**\n * OpenAI reasoning effort. Maps 1:1 to the wire field.\n * - 'none': disables reasoning (gpt-5.x only; rejected by o-series)\n * - 'minimal': fastest (gpt-5.x)\n * - 'low' | 'medium' | 'high': standard tiers\n * - 'xhigh': highest (select gpt-5.x models only)\n *\n * @remarks\n * When effective effort is 'none', reasoning is disabled and temperature is\n * accepted by gpt-5.x models. This is the only case where temperature and\n * thinking config co-exist without a Result.fail.\n */\n readonly effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n}\n\n/**\n * Google Gemini-specific thinking configuration.\n * @public\n */\nexport interface IGeminiThinkingConfig {\n /**\n * Token budget for thinking. Maps 1:1 to `thinkingBudget` on the wire.\n * - 0: disable thinking (Flash and Flash-Lite only; error on Pro)\n * - positive integer: soft token cap\n * - -1: dynamic\n * - omitted: model default\n */\n readonly thinkingBudget?: number;\n /**\n * Whether to include thought summaries in the response.\n * @remarks\n * INERT in phase B. Adapters never send `includeThoughts: true`.\n * Wired up by the followup stream `ai-assist-thinking-events`.\n */\n readonly includeThoughts?: boolean;\n}\n\n/**\n * xAI-specific thinking configuration.\n * @public\n */\nexport interface IXAiThinkingConfig {\n /**\n * xAI reasoning effort. Maps 1:1 to `reasoning_effort` on the wire.\n * For grok-4, the adapter omits this field (grok-4 always reasons and\n * rejects the parameter).\n */\n readonly effort?: 'none' | 'low' | 'medium' | 'high';\n}\n\n/**\n * Anthropic-specific thinking options block.\n * @public\n */\nexport interface IAnthropicThinkingOptions {\n readonly provider: 'anthropic';\n readonly models?: ReadonlyArray<AnthropicThinkingModelNames>;\n readonly config: IAnthropicThinkingConfig;\n}\n\n/**\n * OpenAI-specific thinking options block.\n * @public\n */\nexport interface IOpenAiThinkingOptions {\n readonly provider: 'openai';\n readonly models?: ReadonlyArray<OpenAiThinkingModelNames>;\n readonly config: IOpenAiThinkingConfig;\n}\n\n/**\n * Google Gemini-specific thinking options block.\n * @public\n */\nexport interface IGeminiThinkingOptions {\n readonly provider: 'google';\n readonly models?: ReadonlyArray<GeminiThinkingModelNames>;\n readonly config: IGeminiThinkingConfig;\n}\n\n/**\n * xAI-specific thinking options block.\n * @public\n */\nexport interface IXAiThinkingOptions {\n readonly provider: 'xai';\n readonly models?: ReadonlyArray<XAiThinkingModelNames>;\n readonly config: IXAiThinkingConfig;\n}\n\n/**\n * Escape-hatch options block for providers not covered by typed configs.\n * @remarks\n * `models` is required — no implicit \"all\" for unknown providers.\n * `config` fields are merged verbatim into the wire request.\n * @public\n */\nexport interface IOtherThinkingOptions {\n readonly provider: 'other';\n readonly models: ReadonlyArray<string>;\n readonly config: JsonObject;\n}\n\n/**\n * Discriminated union of per-provider thinking config blocks.\n * @public\n */\nexport type IThinkingProviderConfig =\n | IAnthropicThinkingOptions\n | IOpenAiThinkingOptions\n | IGeminiThinkingOptions\n | IXAiThinkingOptions\n | IOtherThinkingOptions;\n\n/**\n * Thinking/reasoning mode configuration for a completion request.\n *\n * @remarks\n * The generic `effort` field covers the common-subset cross-provider vocabulary.\n * For provider-specific precision (Anthropic 'max', OpenAI 'xhigh', Gemini token\n * budgets, xAI effort-level tuning), use the `providers` array.\n *\n * Absence (or undefined) means \"no thinking mode\" — existing callers are unaffected.\n *\n * @public\n */\nexport interface IThinkingConfig {\n /**\n * Cross-provider effort level. Common-subset mapping:\n * - 'low': Anthropic effort:low | OpenAI effort:low | Gemini thinkingBudget:1024 | xAI reasoning_effort:low\n * - 'medium': effort:medium | effort:medium | thinkingBudget:4096 | reasoning_effort:medium\n * - 'high': effort:high | effort:high | thinkingBudget:8192 | reasoning_effort:high\n */\n readonly effort?: 'low' | 'medium' | 'high';\n /**\n * Optional per-provider precision blocks. Blocks for providers that don't\n * match the resolved model's provider are silently skipped.\n */\n readonly providers?: ReadonlyArray<IThinkingProviderConfig>;\n}\n\n// ============================================================================\n// Settings\n// ============================================================================\n\n/**\n * Configuration for a single AI assist provider.\n * @public\n */\nexport interface IAiAssistProviderConfig {\n /** Which provider this configures */\n readonly provider: AiProviderId;\n /** For API-based providers: the keystore secret name holding the API key */\n readonly secretName?: string;\n /** Optional model override — string or context-aware map. */\n readonly model?: ModelSpec;\n /** Tool enablement/configuration. Tools are disabled unless explicitly enabled. */\n readonly tools?: ReadonlyArray<IAiToolEnablement>;\n /**\n * Optional caller-supplied endpoint URL (http/https). Overrides\n * `descriptor.baseUrl` for this provider. Used to point a provider at a\n * self-hosted server (Ollama, LM Studio, llama.cpp's openai-server) or a\n * local proxy. Validation lives in `@fgv/ts-extras` — query strings,\n * fragments, and userinfo are rejected.\n */\n readonly endpoint?: string;\n}\n\n/**\n * AI assist settings — which providers are enabled and their configuration.\n * @public\n */\nexport interface IAiAssistSettings {\n /** Enabled providers and their configuration. */\n readonly providers: ReadonlyArray<IAiAssistProviderConfig>;\n /** Which enabled provider is the default for the main button. Falls back to first in list. */\n readonly defaultProvider?: AiProviderId;\n /** Optional proxy URL for routing API requests through a backend server (e.g. `http://localhost:3002`). */\n readonly proxyUrl?: string;\n /** When true, route all providers through the proxy. When false (default), only CORS-restricted providers use the proxy. */\n readonly proxyAllProviders?: boolean;\n}\n\n/**\n * Default AI assist settings (copy-paste only).\n * @public\n */\nexport const DEFAULT_AI_ASSIST: IAiAssistSettings = {\n providers: [{ provider: 'copy-paste' }]\n};\n\n// ============================================================================\n// Keystore Interface\n// ============================================================================\n\n/**\n * Minimal keystore interface for AI assist API key resolution.\n * Satisfied structurally by the concrete `KeyStore` class from `@fgv/ts-extras`.\n * @public\n */\nexport interface IAiAssistKeyStore {\n /** Whether the keystore is currently unlocked */\n readonly isUnlocked: boolean;\n /** Check if a named secret exists */\n hasSecret(name: string): Result<boolean>;\n /** Get an API key by secret name */\n getApiKey(name: string): Result<string>;\n}\n"]}
@@ -88,19 +88,28 @@ export interface IExecuteClientToolTurnParams extends IChatRequest {
88
88
  /** API key for authentication. */
89
89
  readonly apiKey: string;
90
90
  /**
91
- * Provider-specific continuation messages to append after the current user
92
- * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s
93
- * `messages` field from a prior turn back to the provider in the follow-up request.
91
+ * The cumulative provider-native wire tail from the previous turn's
92
+ * {@link AiAssist.IAiClientToolContinuation.messages}. Supply this as-is
93
+ * each round — `messages` is already cumulative, so **replace** rather
94
+ * than manually concatenate:
95
+ *
96
+ * ```ts
97
+ * tail = outcome.continuation.messages; // replace — already cumulative
98
+ * ```
99
+ *
100
+ * On the first turn this should be `undefined` (or omitted).
94
101
  *
95
102
  * Each provider applies its own shape guard to the supplied wire objects:
96
103
  * - Anthropic: projects each entry to `{ role, content }` (sufficient for
97
104
  * thinking blocks and `tool_result` arrays).
98
105
  * - OpenAI / xAI Responses: passes each item verbatim (`function_call` /
99
- * `function_call_output` items carry distinct fields per `type`); only guards
100
- * that each entry is a JSON object.
106
+ * `function_call_output` items carry distinct fields per `type`); only
107
+ * guards that each entry is a JSON object.
101
108
  * - Gemini: projects each entry to `{ role, parts }`.
102
109
  *
103
110
  * Entries that fail their provider's shape check are silently skipped.
111
+ * Do NOT place these objects in the `messages` parameter — the
112
+ * normalized-message path strips provider-native fields.
104
113
  */
105
114
  readonly continuationMessages?: ReadonlyArray<JsonObject>;
106
115
  /** Temperature (default: 0.7). */
@@ -1 +1 @@
1
- {"version":3,"file":"clientToolContinuationBuilder.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clientToolContinuationBuilder.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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"}
@@ -523,6 +523,14 @@ function executeClientToolTurn(params) {
523
523
  return yield __await(void 0);
524
524
  }
525
525
  }
526
+ // Prepend inbound continuationMessages so the returned continuation is cumulative.
527
+ // A consumer that does `tail = outcome.continuation.messages` (replace) is then
528
+ // correct for all N rounds — messages always contains the full wire tail from
529
+ // round 1 through the current round. toolCallsSummary stays per-round (this
530
+ // round's calls only); messages is the accumulated tail to re-send.
531
+ if (continuationMessages && continuationMessages.length > 0) {
532
+ continuation = Object.assign(Object.assign({}, continuation), { messages: [...continuationMessages, ...continuation.messages] });
533
+ }
526
534
  resolveNextTurn((0, ts_utils_1.succeed)({ continuation, truncated, fullText }));
527
535
  });
528
536
  }