@fgv/ts-extras 5.1.0-52 → 5.1.0-54

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.
Files changed (47) hide show
  1. package/dist/packlets/ai-assist/completionClient.js +147 -19
  2. package/dist/packlets/ai-assist/completionClient.js.map +1 -1
  3. package/dist/packlets/ai-assist/index.js +2 -1
  4. package/dist/packlets/ai-assist/index.js.map +1 -1
  5. package/dist/packlets/ai-assist/jsonCompletion.js +20 -2
  6. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -1
  7. package/dist/packlets/ai-assist/model.js.map +1 -1
  8. package/dist/packlets/ai-assist/registry.js +39 -1
  9. package/dist/packlets/ai-assist/registry.js.map +1 -1
  10. package/dist/packlets/ai-assist/structuredOutput.js +315 -0
  11. package/dist/packlets/ai-assist/structuredOutput.js.map +1 -0
  12. package/dist/packlets/ai-assist/structuredOutputTypes.js +21 -0
  13. package/dist/packlets/ai-assist/structuredOutputTypes.js.map +1 -0
  14. package/dist/packlets/ai-assist/toolFormats.js +36 -0
  15. package/dist/packlets/ai-assist/toolFormats.js.map +1 -1
  16. package/dist/ts-extras.d.ts +229 -2
  17. package/lib/packlets/ai-assist/completionClient.d.ts +13 -0
  18. package/lib/packlets/ai-assist/completionClient.d.ts.map +1 -1
  19. package/lib/packlets/ai-assist/completionClient.js +146 -18
  20. package/lib/packlets/ai-assist/completionClient.js.map +1 -1
  21. package/lib/packlets/ai-assist/index.d.ts +3 -1
  22. package/lib/packlets/ai-assist/index.d.ts.map +1 -1
  23. package/lib/packlets/ai-assist/index.js +6 -2
  24. package/lib/packlets/ai-assist/index.js.map +1 -1
  25. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -1
  26. package/lib/packlets/ai-assist/jsonCompletion.js +20 -2
  27. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -1
  28. package/lib/packlets/ai-assist/model.d.ts +38 -2
  29. package/lib/packlets/ai-assist/model.d.ts.map +1 -1
  30. package/lib/packlets/ai-assist/model.js.map +1 -1
  31. package/lib/packlets/ai-assist/registry.d.ts +20 -0
  32. package/lib/packlets/ai-assist/registry.d.ts.map +1 -1
  33. package/lib/packlets/ai-assist/registry.js +41 -1
  34. package/lib/packlets/ai-assist/registry.js.map +1 -1
  35. package/lib/packlets/ai-assist/structuredOutput.d.ts +88 -0
  36. package/lib/packlets/ai-assist/structuredOutput.d.ts.map +1 -0
  37. package/lib/packlets/ai-assist/structuredOutput.js +321 -0
  38. package/lib/packlets/ai-assist/structuredOutput.js.map +1 -0
  39. package/lib/packlets/ai-assist/structuredOutputTypes.d.ts +142 -0
  40. package/lib/packlets/ai-assist/structuredOutputTypes.d.ts.map +1 -0
  41. package/lib/packlets/ai-assist/structuredOutputTypes.js +22 -0
  42. package/lib/packlets/ai-assist/structuredOutputTypes.js.map +1 -0
  43. package/lib/packlets/ai-assist/toolFormats.d.ts +0 -23
  44. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -1
  45. package/lib/packlets/ai-assist/toolFormats.js +36 -0
  46. package/lib/packlets/ai-assist/toolFormats.js.map +1 -1
  47. package/package.json +7 -7
@@ -185,16 +185,52 @@ export function toAnthropicTools(tools) {
185
185
  *
186
186
  * @internal
187
187
  */
188
+ /**
189
+ * The non-`null` member of a draft-07 nullable `type` union, or `undefined` when `type` is
190
+ * not one.
191
+ *
192
+ * @remarks
193
+ * Deliberately narrow: only the two-member `[<type>, 'null']` shape `JsonSchema` emits is
194
+ * recognised. A general union has no OpenAPI equivalent, so translating one would be
195
+ * inventing a meaning — it is passed through unchanged and Gemini refuses it, which is the
196
+ * honest outcome.
197
+ * @internal
198
+ */
199
+ function _nullableUnionMember(type) {
200
+ if (!Array.isArray(type) || type.length !== 2 || !type.includes('null')) {
201
+ return undefined;
202
+ }
203
+ const other = type.find((member) => member !== 'null');
204
+ return typeof other === 'string' ? other : undefined;
205
+ }
188
206
  export function toGeminiParameterSchema(schema) {
189
207
  if (Array.isArray(schema)) {
190
208
  return schema.map(toGeminiParameterSchema);
191
209
  }
192
210
  if (schema !== null && typeof schema === 'object') {
193
211
  const out = {};
212
+ // Nullability is spelled differently in the two dialects and they are mutually
213
+ // exclusive: draft-07 (and OpenAI strict mode) wants `type: ['string', 'null']`,
214
+ // OpenAPI 3.0 (and Gemini) wants `type: 'string'` + `nullable: true` and rejects the
215
+ // union array. This is the same class of translation as the `additionalProperties`
216
+ // strip above — a dialect difference the consumer should not have to know about.
217
+ const nullableType = _nullableUnionMember(schema.type);
194
218
  for (const [key, value] of Object.entries(schema)) {
195
219
  if (key === 'additionalProperties' || key === '$schema') {
196
220
  continue;
197
221
  }
222
+ if (nullableType !== undefined && key === 'type') {
223
+ out.type = nullableType;
224
+ out.nullable = true;
225
+ continue;
226
+ }
227
+ if (nullableType !== undefined && key === 'enum' && Array.isArray(value)) {
228
+ // A nullable enum carries `null` among its values in draft-07. OpenAPI expresses
229
+ // that with `nullable` alone, so the member is dropped rather than sent as a value
230
+ // Gemini would reject.
231
+ out.enum = value.filter((member) => member !== null);
232
+ continue;
233
+ }
198
234
  if (key === 'properties' && value !== null && typeof value === 'object' && !Array.isArray(value)) {
199
235
  // `properties` maps user-defined parameter names to subschemas: recurse each
200
236
  // subschema value but never treat a parameter name as a strippable keyword.
@@ -1 +1 @@
1
- {"version":3,"file":"toolFormats.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/toolFormats.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 * Provider-specific tool format translation and tool resolution logic.\n * @packageDocumentation\n */\n\nimport { type JsonObject, type JsonValue } from '@fgv/ts-json-base';\n\nimport {\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiClientToolConfig,\n type IAiProviderDescriptor,\n type IAiToolEnablement,\n type IAiWebSearchToolConfig\n} from './model';\n\n// ============================================================================\n// Tool resolution\n// ============================================================================\n\n/**\n * Resolves the effective tools for a completion call.\n *\n * - If per-call tools are provided, they override settings-level tools entirely.\n * - Otherwise, settings-level enabled tools are used.\n * - Only tools supported by the provider are included.\n * - Returns an empty array if no tools are enabled (= no tools sent).\n *\n * @param descriptor - The provider descriptor (used to filter by supported tools)\n * @param settingsTools - Tool enablement from provider settings (optional)\n * @param perCallTools - Per-call tool override (optional)\n * @returns The resolved list of tool configs to include in the request\n * @public\n */\nexport function resolveEffectiveTools(\n descriptor: IAiProviderDescriptor,\n settingsTools?: ReadonlyArray<IAiToolEnablement>,\n perCallTools?: ReadonlyArray<AiServerToolConfig>\n): ReadonlyArray<AiServerToolConfig> {\n const supported = new Set(descriptor.supportedTools);\n\n if (perCallTools !== undefined) {\n return perCallTools.filter((t) => supported.has(t.type));\n }\n\n if (settingsTools === undefined) {\n return [];\n }\n\n return settingsTools\n .filter((e) => e.enabled && supported.has(e.type))\n .map((e): AiServerToolConfig => e.config ?? { type: e.type });\n}\n\n// ============================================================================\n// OpenAI / xAI Responses API format\n// ============================================================================\n\n/**\n * Formats a web search tool config for the xAI/OpenAI Responses API.\n * @internal\n */\nfunction webSearchToResponsesApi(config: IAiWebSearchToolConfig): JsonObject {\n const tool: Record<string, unknown> = { type: 'web_search' };\n\n if (config.allowedDomains || config.blockedDomains) {\n const filters: Record<string, unknown> = {};\n if (config.allowedDomains) {\n filters.allowed_domains = [...config.allowedDomains];\n }\n if (config.blockedDomains) {\n filters.excluded_domains = [...config.blockedDomains];\n }\n tool.filters = filters;\n }\n\n if (config.enableImageUnderstanding) {\n tool.enable_image_understanding = true;\n }\n\n return tool as JsonObject;\n}\n\n/**\n * Formats a client tool config for the xAI/OpenAI Responses API.\n * @internal\n */\nfunction clientToolToResponsesApi(config: IAiClientToolConfig): JsonObject {\n return {\n type: 'function',\n name: config.name,\n description: config.description,\n parameters: config.parametersSchema.toJson()\n } as JsonObject;\n}\n\n/**\n * Formats tool configs for the xAI/OpenAI Responses API.\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toResponsesApiTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n return tools.map((t) => {\n switch (t.type) {\n case 'web_search':\n return webSearchToResponsesApi(t);\n case 'client_tool':\n return clientToolToResponsesApi(t);\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n return { type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject;\n }\n }\n });\n}\n\n// ============================================================================\n// Anthropic Messages API format\n// ============================================================================\n\n/**\n * Formats a web search tool config for the Anthropic Messages API.\n * @internal\n */\nfunction webSearchToAnthropic(config: IAiWebSearchToolConfig): JsonObject {\n const tool: Record<string, unknown> = {\n type: 'web_search_20250305',\n name: 'web_search'\n };\n\n if (config.maxUses !== undefined) {\n tool.max_uses = config.maxUses;\n }\n if (config.allowedDomains) {\n tool.allowed_domains = [...config.allowedDomains];\n }\n if (config.blockedDomains) {\n tool.blocked_domains = [...config.blockedDomains];\n }\n\n return tool as JsonObject;\n}\n\n/**\n * Formats a client tool config for the Anthropic Messages API.\n * Note: Anthropic client tools have no `type` field (unlike server tools).\n * @internal\n */\nfunction clientToolToAnthropic(config: IAiClientToolConfig): JsonObject {\n return {\n name: config.name,\n description: config.description,\n input_schema: config.parametersSchema.toJson()\n } as JsonObject;\n}\n\n/**\n * Formats tool configs for the Anthropic Messages API.\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toAnthropicTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n return tools.map((t) => {\n switch (t.type) {\n case 'web_search':\n return webSearchToAnthropic(t);\n case 'client_tool':\n return clientToolToAnthropic(t);\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n return { type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject;\n }\n }\n });\n}\n\n// ============================================================================\n// Gemini generateContent API format\n// ============================================================================\n\n/**\n * Sanitizes a draft-07 JSON Schema (as emitted by `JsonSchema.object(...).toJson()`)\n * into the OpenAPI 3.0 Schema Object subset that Gemini's `function_declarations[].parameters`\n * accepts.\n *\n * @remarks\n * Gemini's function-declaration schema is **not** full JSON Schema — it is a subset of\n * the OpenAPI 3.0 Schema Object and **rejects** (rather than ignores) draft-07-only\n * keywords. `JsonSchema` objects are strict-by-default, so `.toJson()` emits\n * `additionalProperties: false` on every object node, which 400s the whole request on\n * Gemini. This helper recursively strips the unsupported keywords so any\n * `JsonSchema`-authored client tool works on Gemini without consumer awareness of the\n * dialect difference. Stripping is infallible, so it returns a plain value rather than a\n * `Result`.\n *\n * `additionalProperties` and `$schema` are stripped only where they appear as schema\n * *keywords* (siblings of `type`/`properties`/etc.). Inside a `properties` map the keys\n * are user-defined parameter names, not keywords, so they are preserved verbatim while\n * each property's subschema value is still recursively sanitized — a tool parameter\n * legitimately named `additionalProperties` survives.\n *\n * @internal\n */\nexport function toGeminiParameterSchema(schema: JsonValue): JsonValue {\n if (Array.isArray(schema)) {\n return schema.map(toGeminiParameterSchema);\n }\n if (schema !== null && typeof schema === 'object') {\n const out: JsonObject = {};\n for (const [key, value] of Object.entries(schema)) {\n if (key === 'additionalProperties' || key === '$schema') {\n continue;\n }\n if (key === 'properties' && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n // `properties` maps user-defined parameter names to subschemas: recurse each\n // subschema value but never treat a parameter name as a strippable keyword.\n const properties: JsonObject = {};\n for (const [name, propSchema] of Object.entries(value)) {\n properties[name] = toGeminiParameterSchema(propSchema);\n }\n out[key] = properties;\n } else {\n out[key] = toGeminiParameterSchema(value);\n }\n }\n return out;\n }\n return schema;\n}\n\n/**\n * Formats tool configs for the Gemini generateContent API.\n *\n * @remarks\n * Gemini uses `google_search` for search grounding (no per-tool config).\n * Client-defined tools are accumulated into a single `function_declarations` entry.\n * Each client tool's parameters schema is sanitized to Gemini's OpenAPI-subset\n * dialect via {@link toGeminiParameterSchema} (the raw draft-07 `.toJson()` output\n * carries `additionalProperties`, which Gemini rejects).\n *\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toGeminiTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n const result: JsonObject[] = [];\n const functionDeclarations: JsonObject[] = [];\n\n for (const t of tools) {\n switch (t.type) {\n case 'web_search':\n result.push({ google_search: {} } as JsonObject);\n break;\n case 'client_tool':\n functionDeclarations.push({\n name: t.name,\n description: t.description,\n parameters: toGeminiParameterSchema(t.parametersSchema.toJson())\n } as JsonObject);\n break;\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n result.push({ type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject);\n }\n }\n }\n\n if (functionDeclarations.length > 0) {\n result.push({ function_declarations: functionDeclarations } as JsonObject);\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"toolFormats.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/toolFormats.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 * Provider-specific tool format translation and tool resolution logic.\n * @packageDocumentation\n */\n\nimport { type JsonObject, type JsonValue } from '@fgv/ts-json-base';\n\nimport {\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiClientToolConfig,\n type IAiProviderDescriptor,\n type IAiToolEnablement,\n type IAiWebSearchToolConfig\n} from './model';\n\n// ============================================================================\n// Tool resolution\n// ============================================================================\n\n/**\n * Resolves the effective tools for a completion call.\n *\n * - If per-call tools are provided, they override settings-level tools entirely.\n * - Otherwise, settings-level enabled tools are used.\n * - Only tools supported by the provider are included.\n * - Returns an empty array if no tools are enabled (= no tools sent).\n *\n * @param descriptor - The provider descriptor (used to filter by supported tools)\n * @param settingsTools - Tool enablement from provider settings (optional)\n * @param perCallTools - Per-call tool override (optional)\n * @returns The resolved list of tool configs to include in the request\n * @public\n */\nexport function resolveEffectiveTools(\n descriptor: IAiProviderDescriptor,\n settingsTools?: ReadonlyArray<IAiToolEnablement>,\n perCallTools?: ReadonlyArray<AiServerToolConfig>\n): ReadonlyArray<AiServerToolConfig> {\n const supported = new Set(descriptor.supportedTools);\n\n if (perCallTools !== undefined) {\n return perCallTools.filter((t) => supported.has(t.type));\n }\n\n if (settingsTools === undefined) {\n return [];\n }\n\n return settingsTools\n .filter((e) => e.enabled && supported.has(e.type))\n .map((e): AiServerToolConfig => e.config ?? { type: e.type });\n}\n\n// ============================================================================\n// OpenAI / xAI Responses API format\n// ============================================================================\n\n/**\n * Formats a web search tool config for the xAI/OpenAI Responses API.\n * @internal\n */\nfunction webSearchToResponsesApi(config: IAiWebSearchToolConfig): JsonObject {\n const tool: Record<string, unknown> = { type: 'web_search' };\n\n if (config.allowedDomains || config.blockedDomains) {\n const filters: Record<string, unknown> = {};\n if (config.allowedDomains) {\n filters.allowed_domains = [...config.allowedDomains];\n }\n if (config.blockedDomains) {\n filters.excluded_domains = [...config.blockedDomains];\n }\n tool.filters = filters;\n }\n\n if (config.enableImageUnderstanding) {\n tool.enable_image_understanding = true;\n }\n\n return tool as JsonObject;\n}\n\n/**\n * Formats a client tool config for the xAI/OpenAI Responses API.\n * @internal\n */\nfunction clientToolToResponsesApi(config: IAiClientToolConfig): JsonObject {\n return {\n type: 'function',\n name: config.name,\n description: config.description,\n parameters: config.parametersSchema.toJson()\n } as JsonObject;\n}\n\n/**\n * Formats tool configs for the xAI/OpenAI Responses API.\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toResponsesApiTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n return tools.map((t) => {\n switch (t.type) {\n case 'web_search':\n return webSearchToResponsesApi(t);\n case 'client_tool':\n return clientToolToResponsesApi(t);\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n return { type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject;\n }\n }\n });\n}\n\n// ============================================================================\n// Anthropic Messages API format\n// ============================================================================\n\n/**\n * Formats a web search tool config for the Anthropic Messages API.\n * @internal\n */\nfunction webSearchToAnthropic(config: IAiWebSearchToolConfig): JsonObject {\n const tool: Record<string, unknown> = {\n type: 'web_search_20250305',\n name: 'web_search'\n };\n\n if (config.maxUses !== undefined) {\n tool.max_uses = config.maxUses;\n }\n if (config.allowedDomains) {\n tool.allowed_domains = [...config.allowedDomains];\n }\n if (config.blockedDomains) {\n tool.blocked_domains = [...config.blockedDomains];\n }\n\n return tool as JsonObject;\n}\n\n/**\n * Formats a client tool config for the Anthropic Messages API.\n * Note: Anthropic client tools have no `type` field (unlike server tools).\n * @internal\n */\nfunction clientToolToAnthropic(config: IAiClientToolConfig): JsonObject {\n return {\n name: config.name,\n description: config.description,\n input_schema: config.parametersSchema.toJson()\n } as JsonObject;\n}\n\n/**\n * Formats tool configs for the Anthropic Messages API.\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toAnthropicTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n return tools.map((t) => {\n switch (t.type) {\n case 'web_search':\n return webSearchToAnthropic(t);\n case 'client_tool':\n return clientToolToAnthropic(t);\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n return { type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject;\n }\n }\n });\n}\n\n// ============================================================================\n// Gemini generateContent API format\n// ============================================================================\n\n/**\n * Sanitizes a draft-07 JSON Schema (as emitted by `JsonSchema.object(...).toJson()`)\n * into the OpenAPI 3.0 Schema Object subset that Gemini's `function_declarations[].parameters`\n * accepts.\n *\n * @remarks\n * Gemini's function-declaration schema is **not** full JSON Schema — it is a subset of\n * the OpenAPI 3.0 Schema Object and **rejects** (rather than ignores) draft-07-only\n * keywords. `JsonSchema` objects are strict-by-default, so `.toJson()` emits\n * `additionalProperties: false` on every object node, which 400s the whole request on\n * Gemini. This helper recursively strips the unsupported keywords so any\n * `JsonSchema`-authored client tool works on Gemini without consumer awareness of the\n * dialect difference. Stripping is infallible, so it returns a plain value rather than a\n * `Result`.\n *\n * `additionalProperties` and `$schema` are stripped only where they appear as schema\n * *keywords* (siblings of `type`/`properties`/etc.). Inside a `properties` map the keys\n * are user-defined parameter names, not keywords, so they are preserved verbatim while\n * each property's subschema value is still recursively sanitized — a tool parameter\n * legitimately named `additionalProperties` survives.\n *\n * @internal\n */\n/**\n * The non-`null` member of a draft-07 nullable `type` union, or `undefined` when `type` is\n * not one.\n *\n * @remarks\n * Deliberately narrow: only the two-member `[<type>, 'null']` shape `JsonSchema` emits is\n * recognised. A general union has no OpenAPI equivalent, so translating one would be\n * inventing a meaning — it is passed through unchanged and Gemini refuses it, which is the\n * honest outcome.\n * @internal\n */\nfunction _nullableUnionMember(type: JsonValue | undefined): string | undefined {\n if (!Array.isArray(type) || type.length !== 2 || !type.includes('null')) {\n return undefined;\n }\n const other: JsonValue | undefined = type.find((member) => member !== 'null');\n return typeof other === 'string' ? other : undefined;\n}\n\nexport function toGeminiParameterSchema(schema: JsonValue): JsonValue {\n if (Array.isArray(schema)) {\n return schema.map(toGeminiParameterSchema);\n }\n if (schema !== null && typeof schema === 'object') {\n const out: JsonObject = {};\n // Nullability is spelled differently in the two dialects and they are mutually\n // exclusive: draft-07 (and OpenAI strict mode) wants `type: ['string', 'null']`,\n // OpenAPI 3.0 (and Gemini) wants `type: 'string'` + `nullable: true` and rejects the\n // union array. This is the same class of translation as the `additionalProperties`\n // strip above — a dialect difference the consumer should not have to know about.\n const nullableType: string | undefined = _nullableUnionMember(schema.type);\n for (const [key, value] of Object.entries(schema)) {\n if (key === 'additionalProperties' || key === '$schema') {\n continue;\n }\n if (nullableType !== undefined && key === 'type') {\n out.type = nullableType;\n out.nullable = true;\n continue;\n }\n if (nullableType !== undefined && key === 'enum' && Array.isArray(value)) {\n // A nullable enum carries `null` among its values in draft-07. OpenAPI expresses\n // that with `nullable` alone, so the member is dropped rather than sent as a value\n // Gemini would reject.\n out.enum = value.filter((member) => member !== null);\n continue;\n }\n if (key === 'properties' && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n // `properties` maps user-defined parameter names to subschemas: recurse each\n // subschema value but never treat a parameter name as a strippable keyword.\n const properties: JsonObject = {};\n for (const [name, propSchema] of Object.entries(value)) {\n properties[name] = toGeminiParameterSchema(propSchema);\n }\n out[key] = properties;\n } else {\n out[key] = toGeminiParameterSchema(value);\n }\n }\n return out;\n }\n return schema;\n}\n\n/**\n * Formats tool configs for the Gemini generateContent API.\n *\n * @remarks\n * Gemini uses `google_search` for search grounding (no per-tool config).\n * Client-defined tools are accumulated into a single `function_declarations` entry.\n * Each client tool's parameters schema is sanitized to Gemini's OpenAPI-subset\n * dialect via {@link toGeminiParameterSchema} (the raw draft-07 `.toJson()` output\n * carries `additionalProperties`, which Gemini rejects).\n *\n * @param tools - The resolved tool configs (server-side and/or client-defined)\n * @returns Provider-native tool objects for the `tools` request field\n * @public\n */\nexport function toGeminiTools(tools: ReadonlyArray<AiToolConfig>): ReadonlyArray<JsonObject> {\n const result: JsonObject[] = [];\n const functionDeclarations: JsonObject[] = [];\n\n for (const t of tools) {\n switch (t.type) {\n case 'web_search':\n result.push({ google_search: {} } as JsonObject);\n break;\n case 'client_tool':\n functionDeclarations.push({\n name: t.name,\n description: t.description,\n parameters: toGeminiParameterSchema(t.parametersSchema.toJson())\n } as JsonObject);\n break;\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = t;\n result.push({ type: `unknown:${JSON.stringify(_exhaustive)}` } as JsonObject);\n }\n }\n }\n\n if (functionDeclarations.length > 0) {\n result.push({ function_declarations: functionDeclarations } as JsonObject);\n }\n\n return result;\n}\n"]}
@@ -181,6 +181,8 @@ declare namespace AiAssist {
181
181
  supportsImageGeneration,
182
182
  resolveEmbeddingCapability,
183
183
  supportsEmbedding,
184
+ resolveStructuredOutputCapability,
185
+ supportsStructuredOutput,
184
186
  DEFAULT_MODEL_CAPABILITY_CONFIG,
185
187
  callProviderCompletion,
186
188
  callProxiedCompletion,
@@ -213,6 +215,14 @@ declare namespace AiAssist {
213
215
  modelSpecKey,
214
216
  modelSpec,
215
217
  resolveEffectiveTools,
218
+ ANTHROPIC_STRUCTURED_OUTPUT_TOOL_NAME,
219
+ AiStructuredOutputFormat,
220
+ IAiStructuredOutputCapability,
221
+ IJsonObjectStructuredOutputRequest,
222
+ ISchemaStructuredOutputRequest,
223
+ StructuredOutputEnforcement,
224
+ StructuredOutputFallback,
225
+ StructuredOutputRequest,
216
226
  classifyJsonParseFailure,
217
227
  extractJsonText,
218
228
  fencedStringifiedJson,
@@ -393,6 +403,20 @@ declare type AiServerToolType = 'web_search';
393
403
  */
394
404
  declare const aiServerToolType: Converter<AiServerToolType>;
395
405
 
406
+ /**
407
+ * Wire format a provider uses to express a structured-output constraint.
408
+ *
409
+ * @remarks
410
+ * Four shapes, not one, and they differ in more than field names: the OpenAI
411
+ * pair carry the schema in the request body, Gemini carries it inside
412
+ * `generationConfig`, and Anthropic has no response-format field at all —
413
+ * its mechanism is forced tool use, which is why `'tool-forced'` is a distinct
414
+ * {@link AiAssist.StructuredOutputEnforcement} value rather than a spelling of
415
+ * `'schema'`.
416
+ * @public
417
+ */
418
+ declare type AiStructuredOutputFormat = 'openai-json-schema' | 'openai-responses-format' | 'gemini-response-schema' | 'anthropic-tool-forced';
419
+
396
420
  /**
397
421
  * Thinking/reasoning mode support for a provider.
398
422
  * @public
@@ -550,6 +574,19 @@ declare const allProviderIds: ReadonlyArray<AiProviderId>;
550
574
  */
551
575
  declare const ALWAYS_STRIPPED_HEADERS: ReadonlyArray<string>;
552
576
 
577
+ /**
578
+ * The name the Anthropic forced-tool path gives its synthetic tool.
579
+ *
580
+ * @remarks
581
+ * Anthropic has no `response_format`; its structured-output mechanism is forced
582
+ * tool use, so a tool must exist to be forced. The name is fgv-owned and never
583
+ * reaches the caller — the structured-output resolver re-serializes the tool's
584
+ * `input` back into `IAiCompletionResponse.content`, so a caller's converter sees
585
+ * a JSON string exactly as it does on every other provider.
586
+ * @public
587
+ */
588
+ declare const ANTHROPIC_STRUCTURED_OUTPUT_TOOL_NAME: string;
589
+
553
590
  /**
554
591
  * Maps Anthropic effort level to the `thinking.budget_tokens` integer that the
555
592
  * Anthropic API requires when `thinking.type === 'enabled'`.
@@ -2596,11 +2633,29 @@ declare interface IAiCompletionResponse {
2596
2633
  readonly content: string;
2597
2634
  /** Whether the response was truncated due to token limits */
2598
2635
  readonly truncated: boolean;
2636
+ /**
2637
+ * Which structured-output constraint the provider was **asked** to apply.
2638
+ *
2639
+ * @remarks
2640
+ * **Required, not optional, and that is the point.** An optional field would
2641
+ * make absence three-ways ambiguous — no capability / not requested / a build
2642
+ * predating the feature — and disambiguating exactly that is what this field
2643
+ * exists for. `'none'` already expresses *"no constraint sent"*, so
2644
+ * always-present costs nothing and removes the ambiguity by construction. The
2645
+ * same remedy as `MemoryEmbedOutcome` in `@fgv/ts-agent-memory`, applied to the
2646
+ * same defect.
2647
+ *
2648
+ * It reports what was *sent*, never whether **this** response conforms — that
2649
+ * is the caller's converter's answer and re-deriving it here would be a second
2650
+ * source of truth. See `StructuredOutputEnforcement` for the three-question
2651
+ * split.
2652
+ */
2653
+ readonly structuredOutput: StructuredOutputEnforcement;
2599
2654
  }
2600
2655
 
2601
2656
  /**
2602
2657
  * Embedding capability for a model family within a provider. Used as an entry
2603
- * in {@link IAiProviderDescriptor.embedding}.
2658
+ * in `embedding`.
2604
2659
  *
2605
2660
  * @public
2606
2661
  */
@@ -2823,7 +2878,7 @@ declare interface IAiImageGenerationResponse {
2823
2878
 
2824
2879
  /**
2825
2880
  * Image-generation capability for a model family within a provider. Used as
2826
- * an entry in {@link IAiProviderDescriptor.imageGeneration}.
2881
+ * an entry in `imageGeneration`.
2827
2882
  *
2828
2883
  * @public
2829
2884
  */
@@ -3006,6 +3061,23 @@ declare interface IAiProviderDescriptor {
3006
3061
  * caller supplies the embedding model via `modelOverride`.
3007
3062
  */
3008
3063
  readonly embedding?: ReadonlyArray<IAiEmbeddingModelCapability>;
3064
+ /**
3065
+ * Per-model-family structured-output capability, longest-prefix matched against
3066
+ * the **resolved** completion model id. Absent (or no matching entry) means the
3067
+ * model can enforce nothing, and a request against it reports `'none'`.
3068
+ *
3069
+ * @remarks
3070
+ * Same declaration idiom as `imageGeneration` and
3071
+ * `embedding`, resolved through the same
3072
+ * alias-first helper — a capability lookup on an unresolved alias is the defect
3073
+ * `resolveImageCapability` once had, where a catch-all `modelPrefix: ''` turned
3074
+ * an unknown alias into a confidently wrong answer.
3075
+ *
3076
+ * Note this declares which wire format a model *family* supports, not which
3077
+ * OpenAI endpoint a given call will take — that also depends on whether the
3078
+ * call carries server tools, so the dispatcher supplies it.
3079
+ */
3080
+ readonly structuredOutput?: ReadonlyArray<IAiStructuredOutputCapability>;
3009
3081
  /**
3010
3082
  * Concrete model ids (prefix-matched) that must be invoked via the OpenAI
3011
3083
  * Responses API rather than chat completions — e.g. `gpt-5.5-pro`. Non-OpenAI
@@ -3180,6 +3252,28 @@ declare interface IAiStreamToolUseStart {
3180
3252
  readonly callId?: string;
3181
3253
  }
3182
3254
 
3255
+ /**
3256
+ * Structured-output capability for a model family within a provider. Used as an
3257
+ * entry in `IAiProviderDescriptor.structuredOutput`.
3258
+ *
3259
+ * @remarks
3260
+ * Deliberately thinner than its `imageGeneration` / `embedding` siblings: it
3261
+ * carries no `supportsX` flags, because what each format can enforce is a
3262
+ * property of the provider's **API surface** rather than of any one model, and a
3263
+ * per-entry declaration of it could only ever disagree with the one in code.
3264
+ * @public
3265
+ */
3266
+ declare interface IAiStructuredOutputCapability {
3267
+ /**
3268
+ * Prefix matched against the resolved completion model id. The empty string is
3269
+ * the catch-all and matches every model. When multiple rules' prefixes match a
3270
+ * model id, the longest prefix wins; ties are broken by first-encountered.
3271
+ */
3272
+ readonly modelPrefix: string;
3273
+ /** Wire format used to express the constraint for matching models. */
3274
+ readonly format: AiStructuredOutputFormat;
3275
+ }
3276
+
3183
3277
  /**
3184
3278
  * Behavior annotations for a client-defined tool.
3185
3279
  *
@@ -4543,6 +4637,22 @@ declare interface IImportSecretOptions extends IAddSecretOptions {
4543
4637
  readonly replace?: boolean;
4544
4638
  }
4545
4639
 
4640
+ /**
4641
+ * Ask the provider for syntactically valid JSON of arbitrary shape.
4642
+ *
4643
+ * @remarks
4644
+ * The weaker floor, and worth having on its own: the failure that motivated this
4645
+ * surface (`Expected ',' or '}' after property value` — an unescaped quote closing
4646
+ * a string early) is **syntactic**, so a JSON-mode guarantee removes it. Schema
4647
+ * constraint is what additionally buys shape. It is also the only mode some
4648
+ * model/provider pairs support.
4649
+ * @public
4650
+ */
4651
+ declare interface IJsonObjectStructuredOutputRequest {
4652
+ readonly mode: 'json-object';
4653
+ readonly onUnsupported?: StructuredOutputFallback;
4654
+ }
4655
+
4546
4656
  /**
4547
4657
  * Key derivation parameters stored in encrypted files.
4548
4658
  * Discriminated union on `kdf` field: `'pbkdf2'` or `'argon2id'`.
@@ -5239,6 +5349,18 @@ declare interface IProviderCompletionParams extends IChatRequest {
5239
5349
  * Messages API requires the field, so it falls back to `DEFAULT_ANTHROPIC_MAX_TOKENS`.
5240
5350
  */
5241
5351
  readonly maxTokens?: number;
5352
+ /**
5353
+ * Ask the provider to constrain its output — to a schema, or to syntactically
5354
+ * valid JSON of arbitrary shape.
5355
+ *
5356
+ * @remarks
5357
+ * **The caller supplies intent; the response reports outcome.** A caller cannot
5358
+ * know up front which concrete model will serve the request (a `tier` request
5359
+ * cascades, and aliases resolve at call time), so it never has to: whatever was
5360
+ * actually enforced comes back on
5361
+ * `IAiCompletionResponse.structuredOutput`.
5362
+ */
5363
+ readonly structuredOutput?: StructuredOutputRequest;
5242
5364
  }
5243
5365
 
5244
5366
  /**
@@ -5820,6 +5942,25 @@ declare interface ISaferFetchResponseHead {
5820
5942
  readonly contentLength?: number;
5821
5943
  }
5822
5944
 
5945
+ /**
5946
+ * Ask the provider for JSON constrained to a schema.
5947
+ * @public
5948
+ */
5949
+ declare interface ISchemaStructuredOutputRequest {
5950
+ readonly mode: 'schema';
5951
+ /**
5952
+ * The schema to constrain generation to — **the same object you validate the
5953
+ * reply with**, so the wire schema and the check cannot drift.
5954
+ *
5955
+ * @remarks
5956
+ * Author it with `JsonSchema.object({...})` from `@fgv/ts-json-base`. This is
5957
+ * the property `@fgv/ts-extras-ollama`'s `chatStructured` already has; this
5958
+ * surface is its cloud sibling.
5959
+ */
5960
+ readonly schema: JsonSchema.ISchemaValidator<unknown>;
5961
+ readonly onUnsupported?: StructuredOutputFallback;
5962
+ }
5963
+
5823
5964
  /**
5824
5965
  * Checks if a JSON object appears to be an encrypted file.
5825
5966
  * Uses the format field as a discriminator.
@@ -7897,6 +8038,21 @@ declare function resolveModelAlias(descriptor: IAiProviderDescriptor, model: str
7897
8038
  */
7898
8039
  declare function resolveProviderModel(descriptor: IAiProviderDescriptor, modelOverride: ModelSpec | undefined, context?: ModelSpecKey): Result<string>;
7899
8040
 
8041
+ /**
8042
+ * The structured-output capability for `modelId` under `descriptor`, or
8043
+ * `undefined` when the model can enforce nothing.
8044
+ *
8045
+ * @remarks
8046
+ * Alias-first, exactly like its `imageGeneration` / `embedding` siblings — an
8047
+ * unresolved alias returns `undefined` rather than prefix-matching a catch-all
8048
+ * `modelPrefix: ''`, which is the defect this helper was written to prevent.
8049
+ *
8050
+ * @param descriptor - The provider descriptor.
8051
+ * @param modelId - A concrete model id or an `@provider:role` alias.
8052
+ * @public
8053
+ */
8054
+ declare function resolveStructuredOutputCapability(descriptor: IAiProviderDescriptor, modelId: string): IAiStructuredOutputCapability | undefined;
8055
+
7900
8056
  /**
7901
8057
  * Statuses whose `Retry-After` header is honored.
7902
8058
  *
@@ -8163,6 +8319,71 @@ declare const SMART_JSON_PROMPT_HINT: string;
8163
8319
  */
8164
8320
  declare function spkiToRawX25519(spki: Uint8Array): Result<Uint8Array>;
8165
8321
 
8322
+ /**
8323
+ * Which constraint the provider was **asked** to apply to this response.
8324
+ *
8325
+ * @remarks
8326
+ * Three questions hide inside *"did it honour my schema"*, and they have different
8327
+ * owners:
8328
+ *
8329
+ * | question | answerable by |
8330
+ * |---|---|
8331
+ * | did we send a constraint? | this client, at request-build time |
8332
+ * | which constraint did the provider apply? | this client, from the resolved model's capability |
8333
+ * | does *this response* conform to my shape? | the caller's converter, and nothing else |
8334
+ *
8335
+ * This type answers the first two and deliberately not the third. Reporting
8336
+ * conformance would mean re-validating against the caller's own schema to
8337
+ * re-derive an answer the caller already holds.
8338
+ *
8339
+ * - `'none'` — nothing was sent; the resolved model declares no capability.
8340
+ * - `'json-mode'` — syntactically valid JSON is guaranteed; the shape is not.
8341
+ * - `'schema'` — generation was constrained to the supplied schema.
8342
+ * - `'tool-forced'` — Anthropic-style forced tool use; the shape comes from the
8343
+ * forced tool's input schema, and `content` is the re-serialized tool input.
8344
+ * @public
8345
+ */
8346
+ declare type StructuredOutputEnforcement = 'none' | 'json-mode' | 'schema' | 'tool-forced';
8347
+
8348
+ /**
8349
+ * What to do when the resolved model cannot apply the requested constraint.
8350
+ *
8351
+ * @remarks
8352
+ * `'degrade'` is the default, and it is only safe **because
8353
+ * `IAiCompletionResponse.structuredOutput` is required** rather than
8354
+ * optional. Degrade-and-tell-me is safe; degrade-silently is the failure this
8355
+ * whole surface exists to remove — so the two decisions are one decision, not
8356
+ * two independent ones.
8357
+ *
8358
+ * Reach for `'fail'` when the output is persisted or put on a wire, where an
8359
+ * unconstrained generation that happens to parse is worse than an error because
8360
+ * it is wrong quietly. Leave it at `'degrade'` on paths that are *designed* to
8361
+ * degrade — an extractor that may return nothing, a segmenter that floors to a
8362
+ * mechanical chunker — where a hard failure would make this library less safe
8363
+ * than the code it replaces.
8364
+ * @public
8365
+ */
8366
+ declare type StructuredOutputFallback = 'degrade' | 'fail';
8367
+
8368
+ /**
8369
+ * A caller's structured-output intent.
8370
+ *
8371
+ * @remarks
8372
+ * A discriminated union rather than an optional `schema` whose absence means
8373
+ * *"json-object please"* — an absence that means something is the shape this repo
8374
+ * has been burned by (see `MemoryEmbedOutcome` in `@fgv/ts-agent-memory`, which
8375
+ * exists because a three-ways-ambiguous absence could not be read).
8376
+ *
8377
+ * **The caller supplies intent; the response reports outcome.** A request never
8378
+ * needs to know whether the constraint will be honoured, because
8379
+ * `resolveProviderModel` resolves aliases and tiers at *call* time — a `tier`
8380
+ * request can cascade — so the concrete model that will serve a request is not
8381
+ * knowable to the caller up front. Requiring it to know would be unsound, which
8382
+ * is why the report rides on the response rather than being a lookup.
8383
+ * @public
8384
+ */
8385
+ declare type StructuredOutputRequest = ISchemaStructuredOutputRequest | IJsonObjectStructuredOutputRequest;
8386
+
8166
8387
  /**
8167
8388
  * URL schemes this primitive will ever request.
8168
8389
  *
@@ -8195,6 +8416,12 @@ declare function supportsEmbedding(descriptor: IAiProviderDescriptor): boolean;
8195
8416
  */
8196
8417
  declare function supportsImageGeneration(descriptor: IAiProviderDescriptor): boolean;
8197
8418
 
8419
+ /**
8420
+ * Whether `descriptor` declares any structured-output capability at all.
8421
+ * @public
8422
+ */
8423
+ declare function supportsStructuredOutput(descriptor: IAiProviderDescriptor): boolean;
8424
+
8198
8425
  /**
8199
8426
  * Helper function to create a `StringConverter` which converts
8200
8427
  * `unknown` to `string`, applying template conversions supplied at construction time or at
@@ -1,5 +1,6 @@
1
1
  import { type Logging, Result } from '@fgv/ts-utils';
2
2
  import { type AiServerToolConfig, type IAiCompletionResponse, type IAiProviderDescriptor, type IChatRequest, type IThinkingConfig, type ModelSpec } from './model';
3
+ import type { StructuredOutputRequest } from './structuredOutputTypes';
3
4
  /**
4
5
  * Parameters for a provider completion request. Carries the unified
5
6
  * {@link AiAssist.IChatRequest} shape (`system?` + ordered `messages`, last =
@@ -52,6 +53,18 @@ export interface IProviderCompletionParams extends IChatRequest {
52
53
  * Messages API requires the field, so it falls back to `DEFAULT_ANTHROPIC_MAX_TOKENS`.
53
54
  */
54
55
  readonly maxTokens?: number;
56
+ /**
57
+ * Ask the provider to constrain its output — to a schema, or to syntactically
58
+ * valid JSON of arbitrary shape.
59
+ *
60
+ * @remarks
61
+ * **The caller supplies intent; the response reports outcome.** A caller cannot
62
+ * know up front which concrete model will serve the request (a `tier` request
63
+ * cascades, and aliases resolve at call time), so it never has to: whatever was
64
+ * actually enforced comes back on
65
+ * `IAiCompletionResponse.structuredOutput`.
66
+ */
67
+ readonly structuredOutput?: StructuredOutputRequest;
55
68
  }
56
69
  /**
57
70
  * Calls the appropriate chat completion API for a given provider. Routes by
@@ -1 +1 @@
1
- {"version":3,"file":"completionClient.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/completionClient.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAEhG,OAAO,EAEL,KAAK,kBAAkB,EAEvB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAE1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,SAAS,EAMf,MAAM,SAAS,CAAC;AA8BjB;;;;;GAKG;AACH,MAAM,WAAW,yBAA0B,SAAQ,YAAY;IAC7D,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAClC,uGAAuG;IACvG,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACnD,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AA0aD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAqIxC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAwExC"}
1
+ {"version":3,"file":"completionClient.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/completionClient.ts"],"names":[],"mappings":"AA8BA,OAAO,EAGL,KAAK,OAAO,EACZ,MAAM,EAIP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,KAAK,kBAAkB,EAEvB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAE1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,SAAS,EAMf,MAAM,SAAS,CAAC;AAiCjB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAMvE;;;;;GAKG;AACH,MAAM,WAAW,yBAA0B,SAAQ,YAAY;IAC7D,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAClC,uGAAuG;IACvG,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACnD,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,uBAAuB,CAAC;CACrD;AAigBD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAiLxC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAiHxC"}