@vedmalex/ai-connect 0.7.0 → 0.9.0

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 (39) hide show
  1. package/README.md +37 -4
  2. package/dist/browser/index.js +717 -284
  3. package/dist/browser/index.js.map +3 -3
  4. package/dist/bun/index.js +1248 -450
  5. package/dist/bun/index.js.map +4 -4
  6. package/dist/bun/local.js +1194 -444
  7. package/dist/bun/local.js.map +4 -4
  8. package/dist/node/index.js +1248 -450
  9. package/dist/node/index.js.map +4 -4
  10. package/dist/node/local.js +1194 -444
  11. package/dist/node/local.js.map +4 -4
  12. package/dist/types/acp.d.ts +14 -0
  13. package/dist/types/acp.d.ts.map +1 -1
  14. package/dist/types/cli-presets.d.ts.map +1 -1
  15. package/dist/types/cli.d.ts.map +1 -1
  16. package/dist/types/client.d.ts.map +1 -1
  17. package/dist/types/config.d.ts.map +1 -1
  18. package/dist/types/default-handlers.d.ts.map +1 -1
  19. package/dist/types/errors.d.ts +11 -0
  20. package/dist/types/errors.d.ts.map +1 -1
  21. package/dist/types/fanout.d.ts.map +1 -1
  22. package/dist/types/files.d.ts +47 -1
  23. package/dist/types/files.d.ts.map +1 -1
  24. package/dist/types/local-handlers.d.ts.map +1 -1
  25. package/dist/types/logging.d.ts +18 -1
  26. package/dist/types/logging.d.ts.map +1 -1
  27. package/dist/types/mock-gateway.d.ts +20 -0
  28. package/dist/types/mock-gateway.d.ts.map +1 -1
  29. package/dist/types/model-reference.d.ts +5 -2
  30. package/dist/types/model-reference.d.ts.map +1 -1
  31. package/dist/types/router.d.ts.map +1 -1
  32. package/dist/types/server-presets.d.ts +1 -1
  33. package/dist/types/server-presets.d.ts.map +1 -1
  34. package/dist/types/server.d.ts.map +1 -1
  35. package/dist/types/transport-runtime.d.ts +75 -0
  36. package/dist/types/transport-runtime.d.ts.map +1 -0
  37. package/dist/types/types.d.ts +44 -0
  38. package/dist/types/types.d.ts.map +1 -1
  39. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/cli-presets.ts", "../../src/errors.ts", "../../src/config.ts", "../../src/fanout.ts", "../../src/files.ts", "../../src/logging.ts", "../../src/router.ts", "../../src/model-reference.ts", "../../src/probe.ts", "../../src/runtime.ts", "../../src/client.ts", "../../src/image.ts", "../../src/default-handlers.ts", "../../src/acp-presets.ts", "../../src/server-presets.ts", "../../src/catalog.ts", "../../src/browser.ts", "../../src/local.ts", "../../src/acp.ts", "../../src/cli.ts", "../../src/server.ts", "../../src/local-handlers.ts"],
4
- "sourcesContent": ["import type {\n CliTransportOptions,\n CliTransportPresetId,\n} from \"./types.js\";\n\nexport type CliTransportPreset = {\n id: CliTransportPresetId;\n label: string;\n command: string;\n transportId: string;\n options: CliTransportOptions;\n};\n\nexport const AI_CONNECT_DEFAULT_CLI_PRESETS: Record<\n CliTransportPresetId,\n CliTransportPreset\n> =\n {\n pi: {\n id: \"pi\",\n label: \"pi (coding agent)\",\n command: \"pi\",\n transportId: \"pi-cli\",\n options: {\n preset: \"pi\",\n // pi print mode emits the answer as plain text on stdout (no JSON wrapper),\n // and has no ACP mode \u2014 so it uses the raw `text` parser and no discovery sidecar.\n // pi takes file/image attachments as separate `@<path>` argv tokens (REQ-024);\n // {files} expands one `@<staged-path>` token per attachment. pi stages all\n // categories (PDFs as-is, no extraction guarantee).\n argsTemplate: [\"--print\", \"--model\", \"{model}\", \"{files}\", \"{prompt}\"],\n discovery: {\n via: \"none\",\n },\n parser: {\n kind: \"text\",\n },\n fileInput: {\n placement: \"args\",\n perFileArgs: [\"@{path}\"],\n },\n },\n },\n claude: {\n id: \"claude\",\n label: \"Claude CLI\",\n command: \"claude\",\n transportId: \"claude-cli\",\n options: {\n preset: \"claude\",\n argsTemplate: [\"--print\", \"--output-format\", \"json\", \"--model\", \"{model}\", \"{prompt}\"],\n discovery: {\n via: \"acp\",\n acp: {\n transportId: \"claude-code-acp\",\n },\n },\n parser: {\n kind: \"json\",\n textPath: \"__preset__:claude.result\",\n usagePath: \"usage\",\n errorPath: \"__preset__:claude.error\",\n },\n },\n },\n openclaude: {\n id: \"openclaude\",\n label: \"OpenClaude CLI\",\n command: \"openclaude\",\n transportId: \"openclaude-cli\",\n options: {\n preset: \"openclaude\",\n argsTemplate: [\"--print\", \"--output-format\", \"json\", \"--model\", \"{model}\", \"{prompt}\"],\n parser: {\n kind: \"json\",\n textPath: \"__preset__:claude.result\",\n usagePath: \"usage\",\n errorPath: \"__preset__:claude.error\",\n },\n },\n },\n codex: {\n id: \"codex\",\n label: \"Codex CLI\",\n command: \"codex\",\n transportId: \"codex-cli\",\n options: {\n preset: \"codex\",\n // codex exec takes image attachments via `-i/--image <FILE>` flags\n // (REQ-024); {files} expands a `--image <staged-path>` pair per image.\n // Images only \u2014 a non-image attachment cleanly rejects pre-spawn.\n argsTemplate: [\n \"exec\",\n \"--json\",\n \"--output-last-message\",\n \"{output_file}\",\n \"--model\",\n \"{model}\",\n \"{files}\",\n \"{prompt}\",\n ],\n discovery: {\n via: \"acp\",\n acp: {\n transportId: \"codex-acp\",\n },\n },\n fileInput: {\n placement: \"args\",\n perFileArgs: [\"--image\", \"{path}\"],\n categories: [\"image\"],\n },\n parser: {\n kind: \"jsonl\",\n text: {\n path: \"__preset__:codex.text\",\n },\n usage: {\n path: \"__preset__:codex.usage\",\n },\n error: {\n path: \"__preset__:codex.error\",\n },\n },\n },\n },\n };\n\nexport const AI_CONNECT_DEFAULT_CLI_COMMANDS: Record<string, string> = {\n \"anthropic:claude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.claude.command,\n \"anthropic:openclaude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.openclaude.command,\n \"openclaude:openclaude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.openclaude.command,\n \"openai:codex-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.codex.command,\n \"pi:pi-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.pi.command,\n};\n\nexport function getCliTransportPreset(\n presetId: CliTransportPresetId,\n): CliTransportPreset {\n return AI_CONNECT_DEFAULT_CLI_PRESETS[presetId];\n}\n", "import type { AbortReason, AiConnectErrorCode } from \"./types.js\";\n\nexport class AiConnectError extends Error {\n readonly code: AiConnectErrorCode;\n readonly details: Record<string, unknown> | undefined;\n\n constructor(\n code: AiConnectErrorCode,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"AiConnectError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function isAiConnectError(error: unknown): error is AiConnectError {\n return error instanceof AiConnectError;\n}\n\n/**\n * Map a derived-abort `reason` to the canonical terminal error. `timeout` \u2192 `\"timeout\"`\n * (deadline elapsed), anything else (including `undefined`/`\"caller\"`) \u2192 `\"aborted\"`\n * (caller cancellation). Both codes are hard-terminal: they never rotate/retry/fall back.\n */\nexport function mapAbortError(\n reason: AbortReason | undefined,\n message?: string,\n): AiConnectError {\n return reason === \"timeout\"\n ? new AiConnectError(\"timeout\", message ?? \"Operation timed out.\")\n : new AiConnectError(\"aborted\", message ?? \"Operation aborted.\");\n}\n\nexport function toAiConnectError(\n error: unknown,\n fallbackCode: AiConnectErrorCode = \"temporary_unavailable\",\n): AiConnectError {\n if (error instanceof AiConnectError) {\n return error;\n }\n\n // Duck-typed DOMException/abort recognition (reliable across node/bun/browser where\n // `instanceof DOMException` is not): an aborted fetch throws `AbortError`, a timed-out\n // one throws `TimeoutError`. The authoritative reason still comes from the client's\n // AbortContext.reason; this is the transport-edge fallback.\n if (typeof (error as { name?: unknown })?.name === \"string\") {\n const name = (error as { name: string }).name;\n const message =\n error instanceof Error ? error.message : \"Operation aborted.\";\n if (name === \"AbortError\") {\n return new AiConnectError(\"aborted\", message);\n }\n if (name === \"TimeoutError\") {\n return new AiConnectError(\"timeout\", message);\n }\n }\n\n if (error instanceof Error) {\n return new AiConnectError(fallbackCode, error.message);\n }\n\n return new AiConnectError(fallbackCode, \"Unknown route failure.\");\n}\n", "import { AI_CONNECT_DEFAULT_CLI_PRESETS } from \"./cli-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport type {\n AccountConfigInput,\n AiConnectConfig,\n AiConnectConfigInput,\n AiConnectErrorCode,\n CliFileInputCategory,\n CliFileInputOptions,\n CliTransportPresetId,\n ContextMode,\n CredentialConfigInput,\n FallbackAction,\n FanoutPolicy,\n NormalizedFanoutPolicy,\n ModelAllowlistMode,\n ModelInput,\n NormalizedAccountConfig,\n NormalizedCredentialConfig,\n NormalizedModelConfig,\n NormalizedOperationRouting,\n NormalizedProviderConfig,\n NormalizedRoute,\n NormalizedRouteResolutionConfig,\n OperationKind,\n OperationRoutingInput,\n PublicRouteCapabilities,\n RouteCapabilities,\n RouteRuntime,\n RoutingStrategy,\n UnknownSelectorPolicy,\n CliTransportOptions,\n CliTransportOptionsInput,\n CliTransportParser,\n TransportDescriptor,\n TransportDescriptorInput,\n} from \"./types.js\";\n\nconst DEFAULT_OPERATIONS: OperationKind[] = [\"text\", \"image\", \"file\"];\nconst DEFAULT_STRATEGY: RoutingStrategy = \"priority\";\n\nconst DEFAULT_FALLBACK_ACTIONS: Record<\n AiConnectErrorCode,\n FallbackAction[]\n> = {\n rate_limit: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n quota_exhausted: [\n \"rotate-account\",\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n invalid_credentials: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-provider\",\n ],\n auth_error: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-provider\",\n ],\n unsupported_capability: [\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n temporary_unavailable: [\n \"retry\",\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n local_harness_unavailable: [\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n validation_error: [],\n not_supported: [\"fallback-model\", \"fallback-transport\", \"fallback-provider\"],\n // Hard-terminal: caller cancellation, deadline, and client-side fanout limit never\n // rotate/retry/fall back (they are not provider/route-health signals).\n aborted: [],\n timeout: [],\n fanout_limit: [],\n};\n\nconst DEFAULT_COOLDOWN_MS: Record<AiConnectErrorCode, number> = {\n rate_limit: 30_000,\n quota_exhausted: 120_000,\n invalid_credentials: 300_000,\n auth_error: 300_000,\n unsupported_capability: 0,\n temporary_unavailable: 10_000,\n local_harness_unavailable: 60_000,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 10_000,\n fanout_limit: 0,\n};\n\nconst DEFAULT_RETRY_MAX_ATTEMPTS: Record<AiConnectErrorCode, number> = {\n rate_limit: 0,\n quota_exhausted: 0,\n invalid_credentials: 0,\n auth_error: 0,\n unsupported_capability: 0,\n temporary_unavailable: 1,\n local_harness_unavailable: 0,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 0,\n fanout_limit: 0,\n};\n\nconst DEFAULT_RETRY_DELAY_MS: Record<AiConnectErrorCode, number> = {\n rate_limit: 0,\n quota_exhausted: 0,\n invalid_credentials: 0,\n auth_error: 0,\n unsupported_capability: 0,\n temporary_unavailable: 1_000,\n local_harness_unavailable: 0,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 1_000,\n fanout_limit: 0,\n};\n\nfunction slugify(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/**\n * Project the secret-free, client-safe capability subset (INV-PROJ-1). The SINGLE\n * source of truth shared by `toPublicRoute` (PublicRoute) and the router's\n * `candidateModels()` (CandidateModel) projections, so internal routing flags\n * (localOnly, requiresFilesystem, the requires-/profile-verification/rotation\n * flags) can never leak onto a public/ModelSelector surface. Built by an EXPLICIT\n * field-by-field copy keyed on the {@link PublicRouteCapabilities} `Pick` \u2014 never\n * by spreading the full {@link RouteCapabilities}.\n */\nexport function toPublicCapabilities(\n capabilities: RouteCapabilities,\n): PublicRouteCapabilities {\n return {\n browserSafe: capabilities.browserSafe,\n supportsStreaming: capabilities.supportsStreaming,\n supportsToolSchema: capabilities.supportsToolSchema,\n supportsToolExecution: capabilities.supportsToolExecution,\n supportsClientToolExecution: capabilities.supportsClientToolExecution,\n supportsFileUpload: capabilities.supportsFileUpload,\n supportsFileOutput: capabilities.supportsFileOutput,\n supportsImageInput: capabilities.supportsImageInput,\n supportsImageOutput: capabilities.supportsImageOutput,\n };\n}\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new AiConnectError(\"validation_error\", message);\n }\n}\n\nfunction asPositiveInteger(value: unknown, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return fallback;\n }\n\n return Math.floor(value);\n}\n\nfunction asNonNegativeInteger(value: unknown, fallback: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return fallback;\n }\n\n return Math.floor(value);\n}\n\nfunction asOptionalContextWindow(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n\n return Math.floor(value);\n}\n\n/**\n * Normalize a single account `models` entry (C4). A bare string inherits the account-level\n * `accountContextWindow` (when set). A `{ id, contextWindow }` object overrides it for that\n * model only; a string with no account-level default leaves `contextWindow` UNDEFINED (never\n * coerced to 0). The `id` is trimmed; empty ids are dropped by the caller.\n */\nfunction normalizeModelInput(\n input: ModelInput,\n accountContextWindow: number | undefined,\n): NormalizedModelConfig {\n if (typeof input === \"string\") {\n return {\n id: input.trim(),\n ...(accountContextWindow !== undefined\n ? { contextWindow: accountContextWindow }\n : {}),\n };\n }\n\n const id = input.id.trim();\n const override = asOptionalContextWindow(input.contextWindow);\n const contextWindow = override ?? accountContextWindow;\n return {\n id,\n ...(contextWindow !== undefined ? { contextWindow } : {}),\n };\n}\n\n/**\n * Resolve one optional fan-out bound (C9). A finite positive number is kept (floored); anything\n * else (unset / non-finite / `<= 0` / `Infinity`) means UNBOUNDED \u2192 {@link Number.POSITIVE_INFINITY}.\n */\nfunction asFanoutBound(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return Number.POSITIVE_INFINITY;\n }\n return Math.floor(value);\n}\n\n/**\n * Normalize a {@link FanoutPolicy} into a {@link NormalizedFanoutPolicy} (C9). Every unset/invalid\n * field resolves to `POSITIVE_INFINITY` (unbounded). Pure; no client/runtime dependency.\n */\nexport function normalizeFanoutPolicy(\n policy: FanoutPolicy | undefined,\n): NormalizedFanoutPolicy {\n return {\n maxConcurrency: asFanoutBound(policy?.maxConcurrency),\n requestsPerSecond: asFanoutBound(policy?.requestsPerSecond),\n maxCalls: asFanoutBound(policy?.maxCalls),\n };\n}\n\n/**\n * Merge a per-request {@link FanoutPolicy} OVER a client-level default, per-field (C9 / R15). A\n * field present (non-`undefined`) on `request` wins; otherwise the `base` field is kept. Returns a\n * plain {@link FanoutPolicy} (still to be normalized) so an unset field on BOTH stays unset. The\n * result is fresh \u2014 neither input is mutated; the per-request limiter is built request-scoped.\n */\nexport function mergeFanoutPolicy(\n base: FanoutPolicy | undefined,\n request: FanoutPolicy | undefined,\n): FanoutPolicy {\n return {\n ...(request?.maxConcurrency !== undefined\n ? { maxConcurrency: request.maxConcurrency }\n : base?.maxConcurrency !== undefined\n ? { maxConcurrency: base.maxConcurrency }\n : {}),\n ...(request?.requestsPerSecond !== undefined\n ? { requestsPerSecond: request.requestsPerSecond }\n : base?.requestsPerSecond !== undefined\n ? { requestsPerSecond: base.requestsPerSecond }\n : {}),\n ...(request?.maxCalls !== undefined\n ? { maxCalls: request.maxCalls }\n : base?.maxCalls !== undefined\n ? { maxCalls: base.maxCalls }\n : {}),\n };\n}\n\nfunction normalizeTransport(\n providerId: string,\n input: AccountConfigInput[\"transport\"],\n): TransportDescriptor {\n const descriptor: TransportDescriptorInput =\n typeof input === \"string\" ? { kind: input } : input;\n const normalizedCli = (() => {\n if (!descriptor.cli) {\n return undefined;\n }\n\n const normalizeSelector = (\n selector: {\n path: string;\n wherePath?: string;\n whereEquals?: string | number | boolean;\n },\n selectorName: string,\n ) => {\n assert(\n selector.path.trim().length > 0,\n `CLI parser ${selectorName}.path must be a non-empty string for provider \"${providerId}\".`,\n );\n\n return {\n path: selector.path.trim(),\n ...(selector.wherePath?.trim()\n ? { wherePath: selector.wherePath.trim() }\n : {}),\n ...(selector.whereEquals !== undefined\n ? { whereEquals: selector.whereEquals }\n : {}),\n };\n };\n\n const normalizeCliParser = (\n cliParser: NonNullable<CliTransportOptionsInput[\"parser\"]>,\n ): CliTransportParser => {\n if (cliParser.kind === \"json\") {\n assert(\n cliParser.textPath.trim().length > 0,\n `CLI json parser textPath must be a non-empty string for provider \"${providerId}\".`,\n );\n\n return {\n kind: \"json\",\n textPath: cliParser.textPath.trim(),\n ...(cliParser.errorPath?.trim()\n ? { errorPath: cliParser.errorPath.trim() }\n : {}),\n ...(cliParser.usagePath?.trim()\n ? { usagePath: cliParser.usagePath.trim() }\n : {}),\n } satisfies CliTransportParser;\n }\n\n if (cliParser.kind === \"text\") {\n return {\n kind: \"text\",\n // Default trim=true, stripAnsi=false; only persist explicit overrides.\n ...(cliParser.trim === false ? { trim: false } : {}),\n ...(cliParser.stripAnsi === true ? { stripAnsi: true } : {}),\n } satisfies CliTransportParser;\n }\n\n return {\n kind: \"jsonl\",\n text: normalizeSelector(cliParser.text, \"text\"),\n ...(cliParser.error\n ? { error: normalizeSelector(cliParser.error, \"error\") }\n : {}),\n ...(cliParser.usage\n ? { usage: normalizeSelector(cliParser.usage, \"usage\") }\n : {}),\n } satisfies CliTransportParser;\n };\n\n const parser = descriptor.cli?.parser\n ? normalizeCliParser(descriptor.cli.parser)\n : undefined;\n\n const normalized = {\n ...(descriptor.cli.preset ? { preset: descriptor.cli.preset } : {}),\n ...(descriptor.cli.argsTemplate\n ? {\n argsTemplate: descriptor.cli.argsTemplate.map((part) => String(part)),\n }\n : {}),\n ...(parser ? { parser } : {}),\n } satisfies CliTransportOptions;\n\n const discovery = (() => {\n if (!descriptor.cli?.discovery) {\n return undefined;\n }\n\n const explicitVia = descriptor.cli.discovery.via;\n if (explicitVia !== undefined) {\n assert(\n explicitVia === \"none\" ||\n explicitVia === \"acp\" ||\n explicitVia === \"command\" ||\n explicitVia === \"static\",\n `Unsupported CLI discovery mode \"${String(explicitVia)}\" for provider \"${providerId}\".`,\n );\n }\n\n const launch = descriptor.cli.discovery.acp?.launch\n ? (() => {\n const contextMode =\n descriptor.cli.discovery?.acp?.launch?.contextMode ??\n \"workspace\";\n const skillsMode =\n descriptor.cli.discovery?.acp?.launch?.skillsMode ??\n \"default\";\n\n assert(\n contextMode === \"workspace\" || contextMode === \"clean\",\n `Unsupported CLI discovery ACP contextMode \"${String(contextMode)}\" for provider \"${providerId}\".`,\n );\n assert(\n skillsMode === \"default\" || skillsMode === \"disabled\",\n `Unsupported CLI discovery ACP skillsMode \"${String(skillsMode)}\" for provider \"${providerId}\".`,\n );\n\n return {\n contextMode,\n skillsMode,\n };\n })()\n : undefined;\n\n const auth =\n descriptor.cli.discovery.acp?.auth?.methodId?.trim()\n ? {\n methodId: descriptor.cli.discovery.acp.auth.methodId.trim(),\n params: descriptor.cli.discovery.acp.auth.params ?? {},\n }\n : undefined;\n\n // Normalize the acp block whenever present (presets set via:\"acp\" + acp;\n // a custom route may also predeclare acp overrides the chain can use).\n const acp = descriptor.cli.discovery.acp\n ? {\n ...(descriptor.cli.discovery.acp?.providerId?.trim()\n ? { providerId: descriptor.cli.discovery.acp.providerId.trim() }\n : {}),\n ...(descriptor.cli.discovery.acp?.transportId?.trim()\n ? {\n transportId:\n descriptor.cli.discovery.acp.transportId.trim(),\n }\n : {}),\n ...(auth ? { auth } : {}),\n ...(launch ? { launch } : {}),\n }\n : undefined;\n\n // Normalize the `command` (list-models) source.\n const commandInput = descriptor.cli.discovery.command;\n const command = commandInput\n ? (() => {\n assert(\n Array.isArray(commandInput.argsTemplate) &&\n commandInput.argsTemplate.length > 0,\n `CLI discovery command.argsTemplate must be a non-empty array for provider \"${providerId}\".`,\n );\n const cmdParserInput = commandInput.parser ?? { kind: \"text\" };\n const cmdParser =\n cmdParserInput.kind === \"text\"\n ? {\n kind: \"text\" as const,\n ...(cmdParserInput.trim === false ? { trim: false } : {}),\n ...(cmdParserInput.stripAnsi === true\n ? { stripAnsi: true }\n : {}),\n }\n : { kind: cmdParserInput.kind };\n if (cmdParser.kind !== \"text\") {\n assert(\n Boolean(commandInput.models?.idPath?.trim()),\n `CLI discovery command.models.idPath is required for a ${cmdParser.kind} parser for provider \"${providerId}\".`,\n );\n }\n const m = commandInput.models;\n const models =\n m?.idPath?.trim()\n ? {\n ...(m.path?.trim() ? { path: m.path.trim() } : {}),\n idPath: m.idPath.trim(),\n ...(m.namePath?.trim() ? { namePath: m.namePath.trim() } : {}),\n ...(m.descriptionPath?.trim()\n ? { descriptionPath: m.descriptionPath.trim() }\n : {}),\n ...(m.contextLengthPath?.trim()\n ? { contextLengthPath: m.contextLengthPath.trim() }\n : {}),\n }\n : undefined;\n return {\n ...(commandInput.command?.trim()\n ? { command: commandInput.command.trim() }\n : {}),\n argsTemplate: commandInput.argsTemplate.map((part) => String(part)),\n parser: cmdParser,\n ...(models ? { models } : {}),\n } satisfies NonNullable<CliTransportOptions[\"discovery\"]>[\"command\"];\n })()\n : undefined;\n\n assert(\n explicitVia !== \"command\" || command !== undefined,\n `CLI discovery via:\"command\" requires a discovery.command block for provider \"${providerId}\".`,\n );\n\n const fallback = descriptor.cli.discovery.fallback;\n if (fallback !== undefined) {\n assert(\n fallback === \"static\" || fallback === \"none\",\n `Unsupported CLI discovery fallback \"${String(fallback)}\" for provider \"${providerId}\".`,\n );\n }\n\n return {\n ...(explicitVia !== undefined ? { via: explicitVia } : {}),\n ...(acp ? { acp } : {}),\n ...(command ? { command } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n } satisfies NonNullable<CliTransportOptions[\"discovery\"]>;\n })();\n\n const fileInput = (() => {\n const fi = descriptor.cli?.fileInput;\n if (!fi) {\n return undefined;\n }\n const validCategories = [\"image\", \"document\", \"text\", \"other\"] as const;\n if (fi.categories) {\n for (const c of fi.categories) {\n assert(\n (validCategories as readonly string[]).includes(c),\n `Unsupported CLI fileInput category \"${String(c)}\" for provider \"${providerId}\".`,\n );\n }\n }\n const placement = fi.placement ?? \"args\";\n assert(\n placement === \"args\" || placement === \"prompt\",\n `Unsupported CLI fileInput placement \"${String(placement)}\" for provider \"${providerId}\".`,\n );\n return {\n placement,\n ...(fi.perFileArgs\n ? { perFileArgs: fi.perFileArgs.map((part) => String(part)) }\n : {}),\n ...(fi.mentionTemplate?.trim()\n ? { mentionTemplate: fi.mentionTemplate.trim() }\n : {}),\n ...(fi.separator !== undefined ? { separator: fi.separator } : {}),\n ...(fi.categories ? { categories: [...fi.categories] } : {}),\n ...(fi.stagingDir?.trim() ? { stagingDir: fi.stagingDir.trim() } : {}),\n } satisfies CliFileInputOptions;\n })();\n\n return {\n ...normalized,\n ...(discovery ? { discovery } : {}),\n ...(fileInput ? { fileInput } : {}),\n } satisfies CliTransportOptions;\n })();\n const normalizedAuth =\n descriptor.auth?.methodId?.trim()\n ? {\n methodId: descriptor.auth.methodId.trim(),\n params: descriptor.auth.params ?? {},\n }\n : undefined;\n\n assert(\n descriptor.kind === \"api\" ||\n descriptor.kind === \"acp\" ||\n descriptor.kind === \"cli\" ||\n descriptor.kind === \"server\",\n `Unsupported transport kind for provider \"${providerId}\".`,\n );\n if (descriptor.kind !== \"acp\") {\n assert(\n !normalizedAuth,\n `Transport auth is only supported for ACP routes. Provider \"${providerId}\" declared auth on a non-ACP transport.`,\n );\n assert(\n !descriptor.launch,\n `Transport launch options are only supported for ACP routes. Provider \"${providerId}\" declared launch settings on a non-ACP transport.`,\n );\n }\n if (descriptor.kind !== \"cli\") {\n assert(\n !normalizedCli,\n `CLI transport options are only supported for CLI routes. Provider \"${providerId}\" declared cli settings on a non-CLI transport.`,\n );\n }\n\n if (descriptor.kind === \"api\") {\n return {\n kind: \"api\",\n id: descriptor.id?.trim() || \"api\",\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n };\n }\n\n if (descriptor.kind === \"cli\") {\n const inferredId =\n providerId === \"anthropic\"\n ? \"claude-cli\"\n : providerId === \"openclaude\"\n ? \"openclaude-cli\"\n : providerId === \"openai\"\n ? \"codex-cli\"\n : providerId === \"pi\"\n ? \"pi-cli\"\n : \"cli\";\n\n return {\n kind: \"cli\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(normalizedCli ? { cli: normalizedCli } : {}),\n };\n }\n\n if (descriptor.kind === \"server\") {\n const inferredId = providerId === \"opencode\" ? \"opencode-server\" : \"server\";\n\n return {\n kind: \"server\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n };\n }\n\n const inferredId =\n providerId === \"anthropic\"\n ? \"claude-code-acp\"\n : providerId === \"openai\"\n ? \"codex-acp\"\n : \"acp\";\n const normalizedLaunch = descriptor.launch\n ? (() => {\n const contextMode = descriptor.launch?.contextMode ?? \"workspace\";\n const skillsMode = descriptor.launch?.skillsMode ?? \"default\";\n\n assert(\n contextMode === \"workspace\" || contextMode === \"clean\",\n `Unsupported ACP contextMode \"${String(contextMode)}\" for provider \"${providerId}\".`,\n );\n assert(\n skillsMode === \"default\" || skillsMode === \"disabled\",\n `Unsupported ACP skillsMode \"${String(skillsMode)}\" for provider \"${providerId}\".`,\n );\n\n return {\n contextMode,\n skillsMode,\n };\n })()\n : undefined;\n\n return {\n kind: \"acp\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n ...(normalizedAuth ? { auth: normalizedAuth } : {}),\n ...(normalizedLaunch ? { launch: normalizedLaunch } : {}),\n };\n}\n\nfunction normalizeRuntime(\n transport: TransportDescriptor,\n runtime: RouteRuntime | undefined,\n): RouteRuntime {\n if (\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\"\n ) {\n return \"local\";\n }\n\n if (runtime === \"browser\" || runtime === \"local\" || runtime === \"universal\") {\n return runtime;\n }\n\n return \"universal\";\n}\n\n// Map a cli transport id to its built-in preset id (mirror cli.ts\n// defaultCliPresetIdForRoute) so capability derivation can see a preset's\n// default fileInput before runtime preset-merging happens.\nfunction cliPresetIdForTransportId(\n transportId: string,\n): CliTransportPresetId | undefined {\n switch (transportId) {\n case \"pi-cli\":\n return \"pi\";\n case \"claude-cli\":\n return \"claude\";\n case \"openclaude-cli\":\n return \"openclaude\";\n case \"codex-cli\":\n return \"codex\";\n default:\n return undefined;\n }\n}\n\n// Resolve the effective fileInput for a cli route at capability-derivation time:\n// the route-level fileInput merged over the resolved preset's default fileInput\n// (REQ-024, F-CR-1). Returns the staged categories, or an empty set when the\n// route has no file input at all.\nfunction cliFileInputCategories(\n transport: TransportDescriptor,\n): Set<CliFileInputCategory> {\n if (transport.kind !== \"cli\") {\n return new Set();\n }\n const presetId =\n transport.cli?.preset ?? cliPresetIdForTransportId(transport.id);\n const presetFileInput = presetId\n ? AI_CONNECT_DEFAULT_CLI_PRESETS[presetId]?.options.fileInput\n : undefined;\n const routeFileInput = transport.cli?.fileInput;\n if (!presetFileInput && !routeFileInput) {\n return new Set();\n }\n const merged: CliFileInputOptions = {\n ...(presetFileInput ?? {}),\n ...(routeFileInput ?? {}),\n };\n return new Set(\n merged.categories ?? [\"image\", \"document\", \"text\", \"other\"],\n );\n}\n\nfunction defaultCapabilities(\n transport: TransportDescriptor,\n runtime: RouteRuntime,\n): RouteCapabilities {\n const cliFileCategories = cliFileInputCategories(transport);\n const localOnly =\n runtime === \"local\" ||\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\";\n const browserSafe = !localOnly;\n\n return {\n browserSafe,\n localOnly,\n requiresFilesystem:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n requiresInstalledBinary:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n requiresAuthenticatedSession:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n supportsStreaming:\n transport.kind === \"api\" || transport.kind === \"acp\",\n supportsToolSchema: transport.kind === \"api\",\n supportsToolExecution: transport.kind === \"acp\",\n supportsClientToolExecution: transport.kind === \"api\",\n // C6 / F-P-4: api routes now advertise document + image input parity with acp.\n // The per-account `capabilities` override remains the escape hatch for\n // text-only api proxies that must opt out. REQ-024: a cli route advertises\n // document/image input ONLY for the categories its fileInput actually stages\n // (category-aware so e.g. an image-only cli cleanly rejects a PDF pre-spawn).\n supportsFileUpload:\n transport.kind === \"acp\" ||\n transport.kind === \"api\" ||\n cliFileCategories.has(\"document\"),\n supportsFileOutput: transport.kind === \"acp\",\n supportsImageInput:\n transport.kind === \"acp\" ||\n transport.kind === \"api\" ||\n cliFileCategories.has(\"image\"),\n supportsImageOutput: transport.kind === \"acp\",\n supportsProfileVerification: true,\n supportsCredentialRotation: false,\n supportsAccountRotation: false,\n };\n}\n\nfunction normalizeCredential(\n providerId: string,\n accountId: string,\n transport: TransportDescriptor,\n input: CredentialConfigInput,\n index: number,\n): NormalizedCredentialConfig {\n const id = input.id?.trim() || `${accountId}-credential-${index + 1}`;\n const source =\n input.source?.trim() ||\n (input.apiKey\n ? \"literal\"\n : input.apiKeyEnv\n ? \"env\"\n : transport.kind === \"api\"\n ? \"env\"\n : \"session\");\n\n if (transport.kind === \"api\") {\n assert(\n Boolean(input.apiKey?.trim()) || Boolean(input.apiKeyEnv?.trim()),\n `API account \"${accountId}\" for provider \"${providerId}\" requires apiKey or apiKeyEnv credentials.`,\n );\n }\n\n return {\n id,\n source,\n weight: asPositiveInteger(input.weight, 1),\n metadata: input.metadata ?? {},\n ...(input.apiKey?.trim() ? { apiKey: input.apiKey.trim() } : {}),\n ...(input.apiKeyEnv?.trim() ? { apiKeyEnv: input.apiKeyEnv.trim() } : {}),\n ...(input.apiKeyDelimiter ? { apiKeyDelimiter: input.apiKeyDelimiter } : {}),\n };\n}\n\nfunction normalizeCredentials(\n providerId: string,\n accountId: string,\n transport: TransportDescriptor,\n credentials: CredentialConfigInput[] | undefined,\n): NormalizedCredentialConfig[] {\n if (credentials && credentials.length > 0) {\n return credentials.map((input, index) =>\n normalizeCredential(providerId, accountId, transport, input, index),\n );\n }\n\n if (\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\"\n ) {\n return [\n {\n id: `${accountId}-session-default`,\n source: \"session\",\n weight: 1,\n metadata: {},\n },\n ];\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `API account \"${accountId}\" for provider \"${providerId}\" must define at least one credential.`,\n );\n}\n\nfunction buildRouteId(route: {\n provider: string;\n transport: TransportDescriptor;\n accountId: string;\n credentialId: string;\n model: string;\n}): string {\n return [\n route.provider,\n route.transport.id,\n route.accountId,\n route.credentialId,\n slugify(route.model),\n ].join(\":\");\n}\n\nfunction routeAliases(route: NormalizedRoute): string[] {\n return [\n route.provider,\n route.id,\n `${route.provider}:${route.accountId}`,\n `${route.provider}:${route.accountId}:${route.model}`,\n `${route.provider}:${route.transport.id}:${route.accountId}`,\n `${route.provider}:${route.transport.id}:${route.accountId}:${route.model}`,\n ];\n}\n\n/**\n * Selector-resolution policy for an unmatched selector (C7 / OQ-8). OPTIONAL on every call site:\n * when omitted the policy defaults to `error`, which is byte-identical to the pre-C7 behaviour, so\n * existing positional callers (`resolveRouteRefs(selectors, routes)`) are unaffected.\n */\ninterface ResolveRouteRefsPolicy {\n unknownSelector?: UnknownSelectorPolicy;\n /** Single resolved route id substituted for each unmatched selector when policy is `default`. */\n defaultRouteId?: string;\n}\n\nfunction resolveRouteRefs(\n selectors: string[] | undefined,\n routes: NormalizedRoute[],\n policy?: ResolveRouteRefsPolicy,\n): string[] {\n if (!selectors || selectors.length === 0) {\n return routes.map((route) => route.id);\n }\n\n const unknownSelector = policy?.unknownSelector ?? \"error\";\n const seen = new Set<string>();\n const resolved: string[] = [];\n\n const push = (routeId: string): void => {\n if (!seen.has(routeId)) {\n seen.add(routeId);\n resolved.push(routeId);\n }\n };\n\n for (const selector of selectors) {\n const matches = routes.filter((route) =>\n routeAliases(route).includes(selector),\n );\n\n if (matches.length === 0) {\n // OQ-8 per-unmatched substitution: each unmatched selector independently triggers the\n // policy. `error` (default) throws; `default` substitutes the configured default route for\n // THIS selector; `off` silently drops it (degrade).\n if (unknownSelector === \"default\" && policy?.defaultRouteId) {\n push(policy.defaultRouteId);\n continue;\n }\n if (unknownSelector === \"off\") {\n continue;\n }\n assert(\n false,\n `Route selector \"${selector}\" did not match any normalized routes.`,\n );\n }\n\n for (const match of matches) {\n push(match.id);\n }\n }\n\n return resolved;\n}\n\nfunction normalizeOperationRouting(\n input: string[] | OperationRoutingInput | undefined,\n routes: NormalizedRoute[],\n defaultStrategy: RoutingStrategy,\n resolution: NormalizedRouteResolutionConfig,\n): NormalizedOperationRouting {\n const policy: ResolveRouteRefsPolicy = {\n unknownSelector: resolution.unknownSelector,\n ...(resolution.defaultRouteId !== undefined\n ? { defaultRouteId: resolution.defaultRouteId }\n : {}),\n };\n\n if (Array.isArray(input)) {\n return {\n strategy: defaultStrategy,\n pool: resolveRouteRefs(input, routes, policy),\n };\n }\n\n return {\n strategy: input?.strategy ?? defaultStrategy,\n pool: resolveRouteRefs(input?.pool, routes, policy),\n };\n}\n\nfunction finalizeRotationCapabilities(routes: NormalizedRoute[]): void {\n const credentialGroups = new Map<string, Set<string>>();\n const accountGroups = new Map<string, Set<string>>();\n\n for (const route of routes) {\n const credentialKey = [\n route.provider,\n route.transport.id,\n route.accountId,\n route.model,\n ].join(\"|\");\n const accountKey = [\n route.provider,\n route.transport.id,\n route.model,\n ].join(\"|\");\n\n const credentialSet =\n credentialGroups.get(credentialKey) ?? new Set<string>();\n credentialSet.add(route.credentialId);\n credentialGroups.set(credentialKey, credentialSet);\n\n const accountSet = accountGroups.get(accountKey) ?? new Set<string>();\n accountSet.add(route.accountId);\n accountGroups.set(accountKey, accountSet);\n }\n\n for (const route of routes) {\n const credentialKey = [\n route.provider,\n route.transport.id,\n route.accountId,\n route.model,\n ].join(\"|\");\n const accountKey = [\n route.provider,\n route.transport.id,\n route.model,\n ].join(\"|\");\n\n route.capabilities.supportsCredentialRotation =\n (credentialGroups.get(credentialKey)?.size ?? 0) > 1;\n route.capabilities.supportsAccountRotation =\n (accountGroups.get(accountKey)?.size ?? 0) > 1;\n }\n}\n\nexport function defineConfig(input: AiConnectConfigInput): AiConnectConfig {\n assert(\n typeof input === \"object\" && input !== null,\n \"ai-connect config must be an object.\",\n );\n\n const providerEntries = Object.entries(input.providers ?? {});\n assert(providerEntries.length > 0, \"At least one provider must be configured.\");\n\n const providers: Record<string, NormalizedProviderConfig> = {};\n const routes: NormalizedRoute[] = [];\n\n for (const [providerId, providerInput] of providerEntries) {\n assert(\n providerId !== \"google\",\n 'Provider \"google\" is not supported. Use provider \"gemini\" for the Google Gemini stack.',\n );\n\n assert(\n Array.isArray(providerInput.accounts) && providerInput.accounts.length > 0,\n `Provider \"${providerId}\" must define at least one account.`,\n );\n\n const accounts: NormalizedAccountConfig[] = [];\n\n providerInput.accounts.forEach((accountInput, accountIndex) => {\n const accountId =\n accountInput.id?.trim() || `${providerId}-account-${accountIndex + 1}`;\n const transport = normalizeTransport(providerId, accountInput.transport);\n const runtime = normalizeRuntime(transport, accountInput.runtime);\n const accountContextWindow = asOptionalContextWindow(\n accountInput.contextWindow,\n );\n // C7: per-route policy fields seeded from the account input (defaults preserve pre-C7\n // behaviour \u2014 strict allowlist, workspace context).\n const accountModelAllowlistMode: ModelAllowlistMode =\n accountInput.modelAllowlistMode ?? \"strict\";\n const accountContextMode: ContextMode =\n accountInput.contextMode ?? \"workspace\";\n const accountSystemPrompt = accountInput.systemPrompt?.trim()\n ? accountInput.systemPrompt.trim()\n : undefined;\n const accountLabel = accountInput.id?.trim()\n ? accountInput.id.trim()\n : undefined;\n // #15: guard the array shape BEFORE `.map` so omitting `models` raises a\n // clean validation_error rather than an opaque \"Cannot read properties of\n // undefined (reading 'map')\" TypeError.\n assert(\n Array.isArray(accountInput.models) && accountInput.models.length > 0,\n `Account \"${accountId}\" for provider \"${providerId}\" must declare at least one model.`,\n );\n\n const models = accountInput.models\n .map((model) => normalizeModelInput(model, accountContextWindow))\n .filter((model) => model.id.length > 0);\n\n assert(\n models.length > 0,\n `Account \"${accountId}\" for provider \"${providerId}\" must declare at least one model.`,\n );\n\n const credentials = normalizeCredentials(\n providerId,\n accountId,\n transport,\n accountInput.credentials,\n );\n const capabilities = {\n ...defaultCapabilities(transport, runtime),\n ...(accountInput.capabilities ?? {}),\n };\n const profile =\n accountInput.profile?.trim() || `${providerId}-${transport.id}`;\n const verify = {\n env: accountInput.verify?.env ?? [],\n ...(accountInput.verify?.command?.trim()\n ? { command: accountInput.verify.command.trim() }\n : {}),\n ...(accountInput.verify?.session?.trim()\n ? { session: accountInput.verify.session.trim() }\n : {}),\n };\n const normalizedAccount: NormalizedAccountConfig = {\n id: accountId,\n profile,\n runtime,\n transport,\n models: models.map((model) => model.id),\n credentials,\n capabilities,\n verify,\n weight: asPositiveInteger(accountInput.weight, 1),\n priority: asNonNegativeInteger(accountInput.priority, accountIndex),\n enabled: accountInput.enabled ?? true,\n };\n\n accounts.push(normalizedAccount);\n\n if (!normalizedAccount.enabled) {\n return;\n }\n\n for (const model of models) {\n for (const credential of credentials) {\n routes.push({\n id: buildRouteId({\n provider: providerId,\n transport,\n accountId,\n credentialId: credential.id,\n model: model.id,\n }),\n provider: providerId,\n transport,\n profileId: profile,\n accountId,\n credentialId: credential.id,\n model: model.id,\n runtime,\n weight: credential.weight,\n priority: normalizedAccount.priority,\n handlerKey: `${providerId}:${transport.id}`,\n capabilities: { ...capabilities },\n verify,\n credential,\n ...(model.contextWindow !== undefined\n ? { contextWindow: model.contextWindow }\n : {}),\n modelAllowlistMode: accountModelAllowlistMode,\n advertisedModels: [model.id],\n contextMode: accountContextMode,\n ...(accountInput.defaultResponseFormat !== undefined\n ? { defaultResponseFormat: accountInput.defaultResponseFormat }\n : {}),\n ...(accountSystemPrompt !== undefined\n ? { systemPrompt: accountSystemPrompt }\n : {}),\n ...(accountLabel !== undefined ? { label: accountLabel } : {}),\n });\n }\n }\n });\n\n providers[providerId] = {\n id: providerId,\n accounts,\n };\n }\n\n assert(routes.length > 0, \"At least one enabled route must be produced.\");\n finalizeRotationCapabilities(routes);\n\n const strategy = input.routing?.strategy ?? DEFAULT_STRATEGY;\n\n // C7 / OQ-8: normalize the selector-resolution policy. Default is `error` (byte-identical to\n // pre-C7). For the `default` policy, fail fast at config time unless the configured\n // `defaultRouteId` resolves to EXACTLY one route (an ambiguous/missing default is unrecoverable).\n const resolutionInput = input.routing?.resolution;\n const unknownSelector: UnknownSelectorPolicy =\n resolutionInput?.unknownSelector ?? \"error\";\n let resolvedDefaultRouteId: string | undefined;\n if (unknownSelector === \"default\") {\n assert(\n typeof resolutionInput?.defaultRouteId === \"string\" &&\n resolutionInput.defaultRouteId.trim().length > 0,\n 'Routing resolution policy \"default\" requires a non-empty \"defaultRouteId\".',\n );\n const matchedDefaults = routes.filter((route) =>\n routeAliases(route).includes(resolutionInput!.defaultRouteId!),\n );\n assert(\n matchedDefaults.length === 1,\n `Routing resolution \"defaultRouteId\" must resolve to exactly one route; \"${resolutionInput!.defaultRouteId}\" matched ${matchedDefaults.length}.`,\n );\n resolvedDefaultRouteId = matchedDefaults[0]!.id;\n }\n const resolution: NormalizedRouteResolutionConfig = {\n unknownSelector,\n ...(resolvedDefaultRouteId !== undefined\n ? { defaultRouteId: resolvedDefaultRouteId }\n : {}),\n };\n\n const operations = DEFAULT_OPERATIONS.reduce<\n Record<OperationKind, NormalizedOperationRouting>\n >((accumulator, operation) => {\n accumulator[operation] = normalizeOperationRouting(\n input.routing?.operations?.[operation],\n routes,\n strategy,\n resolution,\n );\n return accumulator;\n }, {} as Record<OperationKind, NormalizedOperationRouting>);\n\n const fallback = {\n on: {\n ...DEFAULT_FALLBACK_ACTIONS,\n ...(input.routing?.fallback?.on ?? {}),\n },\n cooldownMs: {\n ...DEFAULT_COOLDOWN_MS,\n ...(input.routing?.fallback?.cooldownMs ?? {}),\n },\n };\n\n const retry = {\n maxAttempts: {\n ...DEFAULT_RETRY_MAX_ATTEMPTS,\n ...(input.routing?.retry?.maxAttempts ?? {}),\n },\n delayMs: {\n ...DEFAULT_RETRY_DELAY_MS,\n ...(input.routing?.retry?.delayMs ?? {}),\n },\n };\n\n return {\n providers,\n routes,\n routing: {\n strategy,\n operations,\n fallback,\n retry,\n shuffleOnInit: input.routing?.shuffleOnInit ?? false,\n resolution,\n },\n };\n}\n\nexport function isNormalizedConfig(\n value: AiConnectConfig | AiConnectConfigInput,\n): value is AiConnectConfig {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"routes\" in value &&\n Array.isArray(value.routes) &&\n \"routing\" in value\n );\n}\n\nexport function resolveRouteSelectors(\n selectors: string[] | undefined,\n routes: NormalizedRoute[],\n policy?: {\n unknownSelector?: UnknownSelectorPolicy;\n defaultRouteId?: string;\n },\n): string[] {\n return resolveRouteRefs(selectors, routes, policy);\n}\n", "// C9 \u2014 client-side fan-out throttle (UR-013 / UR-015 / F-4).\n//\n// CLIENT-FREE by construction: this module has TYPE-ONLY imports (plus the AiConnectError value),\n// ZERO Node builtins, no import from the client / transport modules, and NO provider-vendor\n// symbol. It is a browser-safe, reusable primitive (INV-REUSE-1) \u2014\n// `createFanoutLimiter(policy, runtime)` works standalone with NO client instance.\n//\n// Determinism (D6 / INV-DET-1): the rate limit is a token bucket recomputed off `runtime.now()`\n// ON EACH `acquire` \u2014 NEVER a wall-clock `setTimeout` \u2014 so `rate-limit-shapes-call-start-times`\n// replays bit-identically under a seeded fake clock.\n\nimport { AiConnectError } from \"./errors.js\";\nimport type {\n FanoutLimiter,\n NormalizedFanoutPolicy,\n RuntimeEnvironment,\n} from \"./types.js\";\n\ninterface Waiter {\n resolve: () => void;\n reject: (error: unknown) => void;\n signal?: AbortSignal;\n onAbort?: () => void;\n}\n\n/**\n * Create a fan-out limiter from a normalized policy + a runtime clock seam.\n *\n * Three independent gates, all checked on `acquire`:\n * - **lifetime `maxCalls`** \u2014 a hard ceiling. The `(callsStarted)`-th acquire past the ceiling\n * REJECTS synchronously-derived with `AiConnectError('fanout_limit')`; it consumes no slot and\n * starts no transport (the client raises this BEFORE route selection, R16).\n * - **rate `requestsPerSecond`** \u2014 a token bucket of capacity `requestsPerSecond`, refilled at\n * `requestsPerSecond` tokens/sec computed from `runtime.now()` deltas (recompute-on-acquire).\n * When empty, the waiter is parked until enough wall-time (per `runtime.now()`) has elapsed \u2014\n * the client advances the seeded clock to release it deterministically.\n * - **concurrency `maxConcurrency`** \u2014 a semaphore; over-cap acquires queue FIFO (fairness, R15).\n *\n * The returned `acquire` resolves to a single-use `release` fn. `release` frees the concurrency\n * slot and pumps the FIFO queue. `maxCalls` is charged at acquire time (a started call counts even\n * if it later fails) and is NEVER refunded by `release`.\n */\nexport function createFanoutLimiter(\n policy: NormalizedFanoutPolicy,\n runtime: RuntimeEnvironment,\n): FanoutLimiter {\n const now = (): number => runtime.now?.() ?? Date.now();\n\n const { maxConcurrency, requestsPerSecond, maxCalls } = policy;\n const rateLimited = Number.isFinite(requestsPerSecond);\n const concurrencyLimited = Number.isFinite(maxConcurrency);\n\n let inFlight = 0;\n let callsStarted = 0;\n\n // Token bucket (only meaningful when rateLimited). Capacity = requestsPerSecond.\n let tokens = rateLimited ? requestsPerSecond : Number.POSITIVE_INFINITY;\n let lastRefill = now();\n\n // FIFO concurrency queue (R15 fairness) \u2014 waiters released in arrival order.\n const concurrencyQueue: Waiter[] = [];\n\n function refill(): void {\n if (!rateLimited) {\n return;\n }\n const current = now();\n const elapsedMs = current - lastRefill;\n if (elapsedMs <= 0) {\n return;\n }\n lastRefill = current;\n tokens = Math.min(requestsPerSecond, tokens + (elapsedMs / 1000) * requestsPerSecond);\n }\n\n /** Ms until the bucket holds at least one token (used to schedule a rate-gated retry). */\n function msUntilToken(): number {\n if (!rateLimited || tokens >= 1) {\n return 0;\n }\n const deficit = 1 - tokens;\n return Math.ceil((deficit / requestsPerSecond) * 1000);\n }\n\n function rejectWaiter(waiter: Waiter, error: unknown): void {\n detachAbort(waiter);\n waiter.reject(error);\n }\n\n function detachAbort(waiter: Waiter): void {\n if (waiter.signal && waiter.onAbort) {\n waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n }\n }\n\n function release(): void {\n inFlight = Math.max(0, inFlight - 1);\n pumpConcurrency();\n }\n\n function pumpConcurrency(): void {\n while (\n concurrencyQueue.length > 0 &&\n (!concurrencyLimited || inFlight < maxConcurrency)\n ) {\n const waiter = concurrencyQueue.shift()!;\n detachAbort(waiter);\n inFlight += 1;\n waiter.resolve();\n }\n }\n\n async function awaitConcurrencySlot(signal?: AbortSignal): Promise<void> {\n if (!concurrencyLimited || inFlight < maxConcurrency) {\n inFlight += 1;\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const waiter: Waiter = { resolve, reject };\n if (signal) {\n const onAbort = (): void => {\n const index = concurrencyQueue.indexOf(waiter);\n if (index >= 0) {\n concurrencyQueue.splice(index, 1);\n }\n rejectWaiter(waiter, new AiConnectError(\"aborted\", \"Operation aborted.\"));\n };\n if (signal.aborted) {\n reject(new AiConnectError(\"aborted\", \"Operation aborted.\"));\n return;\n }\n waiter.signal = signal;\n waiter.onAbort = onAbort;\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n concurrencyQueue.push(waiter);\n });\n }\n\n /**\n * Wait until the token bucket has \u22651 token, consuming it. Parks on the runtime timer seam so a\n * seeded fake clock releases the waiter when the harness advances time (deterministic). Without\n * `runtime.setTimer` (real environments) this falls back to real `setTimeout`.\n */\n async function awaitRateToken(signal?: AbortSignal): Promise<void> {\n if (!rateLimited) {\n return;\n }\n // Loop: refill, take a token if available, else wait the computed deficit.\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (signal?.aborted) {\n throw new AiConnectError(\"aborted\", \"Operation aborted.\");\n }\n refill();\n if (tokens >= 1) {\n tokens -= 1;\n return;\n }\n const waitMs = msUntilToken();\n await delay(waitMs, signal);\n }\n }\n\n function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let cancelTimer: (() => void) | undefined;\n const onAbort = (): void => {\n cancelTimer?.();\n if (signal) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n reject(new AiConnectError(\"aborted\", \"Operation aborted.\"));\n };\n if (signal) {\n if (signal.aborted) {\n reject(new AiConnectError(\"aborted\", \"Operation aborted.\"));\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n const done = (): void => {\n if (signal) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n resolve();\n };\n if (runtime.setTimer) {\n cancelTimer = runtime.setTimer(ms, done);\n } else {\n const handle = setTimeout(done, ms);\n cancelTimer = () => clearTimeout(handle);\n }\n });\n }\n\n return {\n async acquire(signal?: AbortSignal): Promise<() => void> {\n // Lifetime ceiling FIRST (R16): a hard, unrefundable cap \u2014 exhausting it never touches a\n // slot, a token, or route health. The client raises this before route selection.\n if (callsStarted >= maxCalls) {\n throw new AiConnectError(\n \"fanout_limit\",\n `Fan-out lifetime call ceiling (maxCalls=${maxCalls}) exhausted.`,\n );\n }\n callsStarted += 1;\n\n // Rate gate (deterministic token bucket). May park on the clock seam.\n await awaitRateToken(signal);\n\n // Concurrency gate (FIFO semaphore). May park behind earlier waiters.\n await awaitConcurrencySlot(signal);\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n release();\n };\n },\n stats() {\n return {\n inFlight,\n queued: concurrencyQueue.length,\n callsStarted,\n maxConcurrency,\n requestsPerSecond,\n maxCalls,\n };\n },\n };\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport type {\n PortableFile,\n PortableFileCategory,\n PortableFilePayload,\n PortableFileInput,\n RemoteFileReferenceInput,\n} from \"./types.js\";\n\n/**\n * MIME types treated as `document` (UR-003: PDF input). A Set keeps membership\n * checks O(1) and the surface explicit \u2014 extend here when a new document format\n * gains provider parity. Currently application/pdf only; the document content\n * blocks of all default API providers accept it.\n */\nexport const SUPPORTED_DOCUMENT_MIME_TYPES: ReadonlySet<string> = new Set([\n \"application/pdf\",\n]);\n\nconst DOCUMENT_EXTENSION_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n};\n\nconst IMAGE_EXTENSION_MIME_TYPES: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n};\n\nconst TEXT_EXTENSIONS = new Set([\n \"txt\",\n \"md\",\n \"markdown\",\n \"json\",\n \"jsonl\",\n \"yaml\",\n \"yml\",\n \"xml\",\n \"csv\",\n \"ts\",\n \"tsx\",\n \"js\",\n \"jsx\",\n \"mjs\",\n \"cjs\",\n \"css\",\n \"html\",\n]);\n\nfunction isPortableFile(input: PortableFileInput): input is PortableFile {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"kind\" in input &&\n \"name\" in input &&\n \"id\" in input\n );\n}\n\nfunction isRemoteReference(\n input: PortableFileInput,\n): input is RemoteFileReferenceInput {\n return (\n typeof input === \"object\" &&\n input !== null &&\n (\"providerFileId\" in input || \"uri\" in input)\n );\n}\n\nfunction basename(value: string): string {\n const normalized = value.replaceAll(\"\\\\\", \"/\");\n const tail = normalized.split(\"/\").pop();\n return tail && tail.length > 0 ? tail : \"file\";\n}\n\nfunction extension(value: string): string {\n const name = basename(value);\n const index = name.lastIndexOf(\".\");\n if (index === -1 || index === name.length - 1) {\n return \"\";\n }\n return name.slice(index + 1).toLowerCase();\n}\n\n/**\n * Best-effort file extension for a MIME type, for naming a staged file when the\n * source attachment has no usable name (REQ-024). Cosmetic \u2014 the target CLI\n * receives the staged path verbatim and does not key off the extension.\n */\nexport function extensionForMime(mimeType: string): string {\n const subtype = mimeType.split(\"/\")[1]?.toLowerCase().replace(/[^a-z0-9.+-]/g, \"\");\n return subtype && subtype.length > 0 ? subtype : \"bin\";\n}\n\nfunction isRemoteUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nfunction parseDataUrl(value: string): {\n mimeType: string;\n extension: string;\n data: string;\n} | null {\n // Allow intermediate `;param=value` segments between the media type and the\n // `;base64` marker, e.g. `data:text/plain;charset=utf-8;base64,...` (#14). The\n // media type is everything up to the first `;`; params are accepted but dropped.\n const match = /^data:([^,]*?);base64,(.*)$/i.exec(value);\n if (!match) {\n return null;\n }\n\n const mediaTypeAndParams = match[1] ?? \"\";\n const mimeType =\n mediaTypeAndParams.split(\";\")[0]?.trim() || \"application/octet-stream\";\n const extension = mimeType.split(\"/\")[1] ?? \"bin\";\n return {\n mimeType,\n extension,\n data: match[2] ?? \"\",\n };\n}\n\nfunction mimeTypeFromName(name: string): string | undefined {\n const ext = extension(name);\n if (!ext) {\n return undefined;\n }\n\n if (ext === \"json\") {\n return \"application/json\";\n }\n\n if (ext === \"xml\") {\n return \"application/xml\";\n }\n\n if (TEXT_EXTENSIONS.has(ext)) {\n return \"text/plain\";\n }\n\n return IMAGE_EXTENSION_MIME_TYPES[ext] ?? DOCUMENT_EXTENSION_MIME_TYPES[ext];\n}\n\nfunction isTextMimeType(mimeType: string | undefined): boolean {\n return (\n typeof mimeType === \"string\" &&\n (mimeType.startsWith(\"text/\") ||\n mimeType === \"application/json\" ||\n mimeType === \"application/xml\")\n );\n}\n\nfunction encodeBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\");\n }\n\n let binary = \"\";\n for (let index = 0; index < bytes.length; index += 1) {\n binary += String.fromCharCode(bytes[index]!);\n }\n\n if (typeof btoa === \"function\") {\n return btoa(binary);\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No base64 encoder is available for portable file serialization.\",\n );\n}\n\nfunction decodeBase64(base64: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\").toString(\"utf8\");\n }\n\n // Browser branch: `atob` yields one Latin-1 byte per char, so decoding the\n // RAW atob string mangles any multi-byte UTF-8 text ('caf\u00E9' \u2192 mojibake).\n // Reuse the correct byte decode (atob + charCodeAt) and run it through a\n // UTF-8 TextDecoder so multi-byte text round-trips exactly.\n return new TextDecoder().decode(decodeBase64Bytes(base64));\n}\n\nfunction decodeBase64Bytes(base64: string): Uint8Array {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\");\n }\n\n if (typeof atob === \"function\") {\n const binary = atob(base64);\n return Uint8Array.from(binary, (char) => char.charCodeAt(0));\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No base64 decoder is available for portable file upload serialization.\",\n );\n}\n\nexport function inferPortableFileMimeType(file: PortableFile): string | undefined {\n if (file.mimeType) {\n return file.mimeType;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n return parseDataUrl(file.source)?.mimeType;\n }\n\n if (file.kind === \"path\") {\n return mimeTypeFromName(file.name);\n }\n\n if (file.kind === \"remote\") {\n const source = file.source as RemoteFileReferenceInput;\n return source.mimeType ?? (source.uri ? mimeTypeFromName(source.uri) : undefined);\n }\n\n return mimeTypeFromName(file.name);\n}\n\nexport function isPortableImageFile(file: PortableFile): boolean {\n return inferPortableFileMimeType(file)?.startsWith(\"image/\") ?? false;\n}\n\nexport function isPortableTextFile(file: PortableFile): boolean {\n const mimeType = inferPortableFileMimeType(file);\n if (isTextMimeType(mimeType)) {\n return true;\n }\n\n return TEXT_EXTENSIONS.has(extension(file.name));\n}\n\nexport function portableFileRemoteUri(file: PortableFile): string | undefined {\n if (file.kind !== \"remote\") {\n return undefined;\n }\n\n const source = file.source as RemoteFileReferenceInput;\n return source.uri;\n}\n\n/**\n * Coarse multimodal classification (C6). MIME type wins; document membership is\n * gated by `SUPPORTED_DOCUMENT_MIME_TYPES` so only known-supported document\n * formats route to a provider document block. Order: image \u2192 document \u2192 text \u2192\n * other (stable; `mixed-attachments-ordering` relies on it not reordering).\n */\nexport function portableFileCategory(file: PortableFile): PortableFileCategory {\n const mimeType = inferPortableFileMimeType(file);\n if (mimeType?.startsWith(\"image/\")) {\n return \"image\";\n }\n if (mimeType && SUPPORTED_DOCUMENT_MIME_TYPES.has(mimeType)) {\n return \"document\";\n }\n if (isPortableTextFile(file)) {\n return \"text\";\n }\n return \"other\";\n}\n\nexport function isPortableDocumentFile(file: PortableFile): boolean {\n return portableFileCategory(file) === \"document\";\n}\n\nfunction remoteReferenceProviderFileId(file: PortableFile): string | undefined {\n if (file.kind !== \"remote\") {\n return undefined;\n }\n const source = file.source as RemoteFileReferenceInput;\n return source.providerFileId;\n}\n\n/**\n * Raw base64 of a portable file's bytes (NO data-url prefix). Returns undefined\n * when no decodable byte source is available (e.g. a remote reference carrying\n * only a URI / providerFileId). Used by the Anthropic document base64 block and\n * the Gemini inlineData path. All node:* access stays behind `loadFsPromises`.\n */\nexport async function portableFileToBase64(\n file: PortableFile,\n): Promise<string | undefined> {\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed?.data;\n }\n\n const bytes = await portableFileToBytes(file);\n return bytes ? encodeBase64(bytes) : undefined;\n}\n\nasync function readPathBytes(filePath: string): Promise<Uint8Array> {\n const { readFile } = await loadFsPromises();\n return await readFile(filePath);\n}\n\nasync function readPathText(filePath: string): Promise<string> {\n const { readFile } = await loadFsPromises();\n return await readFile(filePath, \"utf8\");\n}\n\ntype FsPromisesModule = typeof import(\"node:fs/promises\");\n\nasync function loadFsPromises(): Promise<FsPromisesModule> {\n if (typeof process === \"undefined\" || !process.versions?.node) {\n throw new AiConnectError(\n \"not_supported\",\n \"Path-based file access is only available in local runtimes.\",\n );\n }\n\n const dynamicImport = new Function(\n \"specifier\",\n \"return import(specifier);\",\n ) as (specifier: string) => Promise<FsPromisesModule>;\n\n return await dynamicImport(\"node:fs/promises\");\n}\n\nexport async function portableFileToDataUrl(\n file: PortableFile,\n): Promise<string | undefined> {\n if (!isPortableImageFile(file)) {\n return undefined;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n return file.source;\n }\n\n const mimeType = inferPortableFileMimeType(file) ?? \"image/png\";\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n const bytes = new Uint8Array(await file.source.arrayBuffer());\n return `data:${mimeType};base64,${encodeBase64(bytes)}`;\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n const bytes = await readPathBytes(file.source);\n return `data:${mimeType};base64,${encodeBase64(bytes)}`;\n }\n\n return undefined;\n}\n\nexport async function portableFileToBytes(\n file: PortableFile,\n): Promise<Uint8Array | undefined> {\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed ? decodeBase64Bytes(parsed.data) : undefined;\n }\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n return new Uint8Array(await file.source.arrayBuffer());\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return await readPathBytes(file.source);\n }\n\n return undefined;\n}\n\nexport async function portableFileToText(\n file: PortableFile,\n): Promise<string | undefined> {\n if (!isPortableTextFile(file)) {\n return undefined;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed ? decodeBase64(parsed.data) : undefined;\n }\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n return await file.source.text();\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return await readPathText(file.source);\n }\n\n return undefined;\n}\n\n/**\n * SINGLE decode path (C6 \u2014 INV the design calls \"materializePortableFile\"). One\n * pass resolves the category + MIME type and reads the byte/text/uri source\n * exactly once, populating only the carriers a downstream provider builder can\n * use. Every consumer (api document/image builders, acp PDF path) reads from the\n * payload rather than re-decoding the file. All filesystem access flows through\n * `portableFileToBytes`/`portableFileToText`, which sit behind the lazy\n * `loadFsPromises` guard (F-A2: browser-reachable, node:*-free).\n */\nexport async function materializePortableFile(\n file: PortableFile,\n): Promise<PortableFilePayload> {\n const category = portableFileCategory(file);\n const mimeType =\n inferPortableFileMimeType(file) ??\n (category === \"image\"\n ? \"image/png\"\n : category === \"document\"\n ? \"application/pdf\"\n : \"application/octet-stream\");\n\n const uri = portableFileRemoteUri(file);\n const providerFileId = remoteReferenceProviderFileId(file);\n\n const payload: PortableFilePayload = {\n category,\n mimeType,\n name: file.name,\n ...(uri ? { uri } : {}),\n ...(providerFileId ? { providerFileId } : {}),\n };\n\n if (category === \"text\") {\n const text = await portableFileToText(file);\n if (text !== undefined) {\n payload.text = text;\n }\n return payload;\n }\n\n if (category === \"image\" || category === \"document\") {\n // Prefer raw bytes (path/blob/data-url). A remote reference with no bytes\n // keeps only its uri/providerFileId \u2014 builders fall back to the URL/file-id\n // wire shape and never emit an empty base64 block.\n const base64 = await portableFileToBase64(file);\n if (base64 !== undefined) {\n payload.base64 = base64;\n payload.dataUrl = `data:${mimeType};base64,${base64}`;\n }\n }\n\n return payload;\n}\n\nexport function preparePortableFile(input: PortableFileInput): PortableFile {\n if (isPortableFile(input)) {\n return input;\n }\n\n if (typeof input === \"string\") {\n const dataUrl = parseDataUrl(input);\n if (dataUrl) {\n return {\n id: `data-url:${input.length}`,\n kind: \"data-url\",\n name: `generated.${dataUrl.extension}`,\n mimeType: dataUrl.mimeType,\n source: input,\n };\n }\n\n if (isRemoteUrl(input)) {\n return {\n id: `remote:${input}`,\n kind: \"remote\",\n name: basename(input),\n source: {\n uri: input,\n name: basename(input),\n },\n };\n }\n\n return {\n id: `path:${input}`,\n kind: \"path\",\n name: basename(input),\n source: input,\n };\n }\n\n if (isRemoteReference(input)) {\n const name = input.name ?? input.providerFileId ?? input.uri ?? \"remote\";\n return {\n id: input.id ?? `remote:${name}`,\n kind: \"remote\",\n name,\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n ...(input.size !== undefined ? { size: input.size } : {}),\n source: input,\n };\n }\n\n if (typeof File !== \"undefined\" && input instanceof File) {\n return {\n id: `file:${input.name}:${input.size}`,\n kind: \"browser-file\",\n name: input.name,\n ...(input.type ? { mimeType: input.type } : {}),\n size: input.size,\n source: input,\n };\n }\n\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n return {\n id: `blob:${input.size}:${input.type || \"application/octet-stream\"}`,\n kind: \"browser-blob\",\n name: \"blob\",\n ...(input.type ? { mimeType: input.type } : {}),\n size: input.size,\n source: input,\n };\n }\n\n throw new AiConnectError(\n \"validation_error\",\n \"Unsupported file input. Expected a path, browser File/Blob, or remote file reference.\",\n );\n}\n", "import type {\n WideEvent,\n WideEventLogger,\n WideEventSamplingOptions,\n} from \"./types.js\";\n\nexport interface ConsoleWideEventLoggerOptions {\n pretty?: boolean;\n write?: (line: string) => void;\n}\n\nexport function createConsoleWideEventLogger(\n options: ConsoleWideEventLoggerOptions = {},\n): WideEventLogger {\n const write =\n options.write ??\n ((line: string) => {\n console.info(line);\n });\n\n return (event) => {\n write(\n options.pretty\n ? JSON.stringify(event, null, 2)\n : JSON.stringify(event),\n );\n };\n}\n\nexport async function shouldEmitWideEvent(\n event: WideEvent,\n options: WideEventSamplingOptions = {},\n): Promise<boolean> {\n const sampleRate = options.sampleRate ?? 1;\n\n if ((options.keepErrors ?? true) && event.outcome === \"error\") {\n return true;\n }\n\n const slowOperationMs = options.slowOperationMs ?? 2_000;\n if (event.durationMs >= slowOperationMs) {\n return true;\n }\n\n if (\n (options.keepWarnings ?? false) &&\n (event.result?.warningsCount ?? 0) > 0\n ) {\n return true;\n }\n\n if (options.keepOperations?.includes(event.operationName)) {\n return true;\n }\n\n if (\n options.keepRoutes?.some((routeId) =>\n event.candidates.some((candidate) => candidate.id === routeId),\n )\n ) {\n return true;\n }\n\n if (\n options.keepProviders?.some((providerId) =>\n event.candidates.some((candidate) => candidate.provider === providerId),\n )\n ) {\n return true;\n }\n\n if (options.predicate && (await options.predicate(event))) {\n return true;\n }\n\n if (sampleRate <= 0) {\n return false;\n }\n\n if (sampleRate >= 1) {\n return true;\n }\n\n return Math.random() < sampleRate;\n}\n", "import { resolveRouteSelectors, toPublicCapabilities } from \"./config.js\";\nimport type {\n AiConnectConfig,\n AiConnectErrorCode,\n CandidateModel,\n GenerateRequest,\n NormalizedRoute,\n OperationKind,\n ProviderId,\n RouteHealthSnapshot,\n RouteHints,\n RoutingStrategy,\n RuntimeEnvironment,\n} from \"./types.js\";\n\ntype RouteHealthStateInternal = RouteHealthSnapshot;\n\nfunction runtimeEligible(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n): boolean {\n if (route.transport.kind === \"acp\" && runtime.kind !== \"local\") {\n return false;\n }\n\n if (route.runtime === \"universal\") {\n return true;\n }\n\n return route.runtime === runtime.kind;\n}\n\nfunction capabilityMatch(\n route: NormalizedRoute,\n hints: RouteHints | undefined,\n): boolean {\n if (!hints?.requiredCapabilities) {\n return true;\n }\n\n return Object.entries(hints.requiredCapabilities).every(([key, value]) => {\n if (value === undefined) {\n return true;\n }\n\n return route.capabilities[key as keyof typeof route.capabilities] === value;\n });\n}\n\nfunction preferredProviderScore(\n route: NormalizedRoute,\n preferredProviders: string[] | undefined,\n): number {\n if (!preferredProviders || preferredProviders.length === 0) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const index = preferredProviders.indexOf(route.provider);\n return index === -1 ? Number.MAX_SAFE_INTEGER : index;\n}\n\nfunction baseSort(\n routes: NormalizedRoute[],\n preferredProviders: string[] | undefined,\n): NormalizedRoute[] {\n return [...routes].sort((left, right) => {\n const preferredDelta =\n preferredProviderScore(left, preferredProviders) -\n preferredProviderScore(right, preferredProviders);\n\n if (preferredDelta !== 0) {\n return preferredDelta;\n }\n\n if (left.priority !== right.priority) {\n return left.priority - right.priority;\n }\n\n if (left.weight !== right.weight) {\n return right.weight - left.weight;\n }\n\n return left.id.localeCompare(right.id);\n });\n}\n\nfunction rotate<T>(items: T[], index: number): T[] {\n if (items.length === 0) {\n return [];\n }\n\n const start = index % items.length;\n return [...items.slice(start), ...items.slice(0, start)];\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)];\n}\n\nfunction buildWeightedOrder(routes: NormalizedRoute[]): NormalizedRoute[] {\n const expanded: NormalizedRoute[] = [];\n\n for (const route of routes) {\n for (let index = 0; index < route.weight; index += 1) {\n expanded.push(route);\n }\n }\n\n return expanded;\n}\n\nexport class RouteRegistry {\n readonly config: AiConnectConfig;\n readonly runtime: RuntimeEnvironment;\n\n #health = new Map<string, RouteHealthStateInternal>();\n #cursors = new Map<string, number>();\n #routeMap = new Map<string, NormalizedRoute>();\n #shuffles = new Map<string, NormalizedRoute[]>();\n\n constructor(config: AiConnectConfig, runtime: RuntimeEnvironment) {\n this.config = config;\n this.runtime = runtime;\n\n for (const route of config.routes) {\n this.#routeMap.set(route.id, route);\n }\n }\n\n getHealth(route: NormalizedRoute): RouteHealthSnapshot {\n const current = this.#health.get(route.id);\n\n if (!current) {\n return {\n state: \"ready\",\n failureCount: 0,\n };\n }\n\n if (\n current.state === \"cooling_down\" &&\n current.cooldownUntil !== undefined &&\n current.cooldownUntil <= this.#now()\n ) {\n const readyState = {\n state: \"ready\" as const,\n failureCount: current.failureCount,\n };\n this.#health.set(route.id, readyState);\n return readyState;\n }\n\n return current;\n }\n\n listRoutes(filter?: {\n operation?: GenerateRequest[\"operation\"];\n }): NormalizedRoute[] {\n if (!filter?.operation) {\n return [...this.config.routes];\n }\n\n const routeIds = this.config.routing.operations[filter.operation].pool;\n return routeIds\n .map((routeId) => this.#routeMap.get(routeId))\n .filter((route): route is NormalizedRoute => Boolean(route));\n }\n\n /**\n * Project the currently-eligible routes into secret-free {@link CandidateModel}s (C9 / UR-014).\n * Deferred from C7 (needs the C9-owned `CandidateModel` type). Reuses the runtime-eligibility +\n * health filters (a `cooling_down`/`unavailable` route is excluded), then narrows by optional\n * `operation` (router pool) and `provider`. Carries ONLY the secret-free fields \u2014 never a\n * credential/baseUrl/handler key (mirrors INV-PROJ-1 for the candidate list).\n */\n candidateModels(filter?: {\n operation?: OperationKind;\n provider?: ProviderId;\n }): CandidateModel[] {\n const operationFilter = filter?.operation\n ? { operation: filter.operation }\n : undefined;\n return this.listRoutes(operationFilter)\n .filter((route) =>\n filter?.provider ? route.provider === filter.provider : true,\n )\n .filter((route) => runtimeEligible(route, this.runtime))\n .filter((route) => {\n const state = this.getHealth(route).state;\n return state !== \"cooling_down\" && state !== \"unavailable\";\n })\n .map((route) => ({\n model: route.model,\n provider: route.provider,\n routeId: route.id,\n transportKind: route.transport.kind,\n // INV-PROJ-1: project the secret-free subset (never the full\n // RouteCapabilities) so internal routing flags do not leak to the\n // ModelSelector / listCandidateModels surface (#12).\n capabilities: toPublicCapabilities(route.capabilities),\n }));\n }\n\n resolveCandidates(request: GenerateRequest & { operation: NonNullable<GenerateRequest[\"operation\"]> }): NormalizedRoute[] {\n const operation = request.operation;\n const operationRouting = this.config.routing.operations[operation];\n const routeIds = request.routeHints?.pool?.length\n ? resolveRouteSelectors(request.routeHints.pool, this.config.routes)\n : operationRouting.pool;\n\n const excludedIds = new Set(request.routeHints?.excludeRouteIds ?? []);\n const requestedModel = request.routeHints?.model;\n const available = routeIds\n .map((routeId) => this.#routeMap.get(routeId))\n .filter((route): route is NormalizedRoute => Boolean(route))\n .filter((route) => !excludedIds.has(route.id))\n .filter((route) => runtimeEligible(route, this.runtime))\n .filter((route) => capabilityMatch(route, request.routeHints))\n .filter((route) => {\n const state = this.getHealth(route).state;\n return state !== \"cooling_down\" && state !== \"unavailable\";\n })\n // C7 / INV-ROUTE-1: apply a request-level model override (CD-8). On a `strict` route an\n // undeclared model DROPS the route (never billed); on a `shortlist` route it is passed\n // through verbatim on a synthetic copy preserving `route.id` (R12). Runs AFTER the health\n // filter so a dropped strict route never pollutes ordering.\n .map((route) => applyRequestedModel(route, requestedModel))\n .filter((route): route is NormalizedRoute => Boolean(route));\n\n return this.#order(\n request.routeHints?.strategy ?? operationRouting.strategy,\n available,\n request.routeHints?.preferredProviders,\n );\n }\n\n recordSuccess(route: NormalizedRoute): void {\n this.#health.set(route.id, {\n state: \"ready\",\n failureCount: 0,\n });\n }\n\n recordFailure(route: NormalizedRoute, code: AiConnectErrorCode): void {\n const previous = this.getHealth(route);\n const failureCount = previous.failureCount + 1;\n const cooldownMs = this.config.routing.fallback.cooldownMs[code] ?? 0;\n\n if (\n code === \"rate_limit\" ||\n code === \"quota_exhausted\" ||\n code === \"temporary_unavailable\" ||\n code === \"local_harness_unavailable\"\n ) {\n this.#health.set(route.id, {\n state: cooldownMs > 0 ? \"cooling_down\" : \"degraded\",\n failureCount,\n ...(cooldownMs > 0 ? { cooldownUntil: this.#now() + cooldownMs } : {}),\n });\n return;\n }\n\n if (\n code === \"invalid_credentials\" ||\n code === \"auth_error\" ||\n code === \"validation_error\"\n ) {\n this.#health.set(route.id, {\n state: \"unavailable\",\n failureCount,\n });\n return;\n }\n\n this.#health.set(route.id, {\n state: \"degraded\",\n failureCount,\n });\n }\n\n #order(\n strategy: RoutingStrategy,\n routes: NormalizedRoute[],\n preferredProviders: string[] | undefined,\n ): NormalizedRoute[] {\n const sorted = baseSort(routes, preferredProviders);\n const cursorKey = `${strategy}:${sorted.map((route) => route.id).join(\"|\")}`;\n const ordered = this.config.routing.shuffleOnInit\n ? this.#shuffle(cursorKey, sorted)\n : sorted;\n\n if (strategy === \"priority\" || strategy === \"failover\") {\n return ordered;\n }\n\n if (strategy === \"round-robin\") {\n const index = this.#cursor(cursorKey, ordered.length);\n return rotate(ordered, index);\n }\n\n const weighted = buildWeightedOrder(ordered);\n const index = this.#cursor(cursorKey, weighted.length);\n return unique(rotate(weighted, index));\n }\n\n #shuffle(key: string, routes: NormalizedRoute[]): NormalizedRoute[] {\n const cached = this.#shuffles.get(key);\n if (cached) {\n return cached;\n }\n\n const items = [...routes];\n for (let index = items.length - 1; index > 0; index -= 1) {\n const nextIndex = Math.floor(Math.random() * (index + 1));\n const current = items[index]!;\n const next = items[nextIndex]!;\n items[index] = next;\n items[nextIndex] = current;\n }\n\n this.#shuffles.set(key, items);\n return items;\n }\n\n #cursor(key: string, length: number): number {\n if (length === 0) {\n return 0;\n }\n\n const current = this.#cursors.get(key) ?? 0;\n this.#cursors.set(key, current + 1);\n return current;\n }\n\n #now(): number {\n return this.runtime.now?.() ?? Date.now();\n }\n}\n\nexport function canFallbackBetween(\n failed: NormalizedRoute,\n next: NormalizedRoute,\n actions: string[],\n): boolean {\n for (const action of actions) {\n if (\n action === \"rotate-credential\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.accountId === next.accountId &&\n failed.model === next.model &&\n failed.credentialId !== next.credentialId\n ) {\n return true;\n }\n\n if (\n action === \"rotate-account\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.model === next.model &&\n failed.accountId !== next.accountId\n ) {\n return true;\n }\n\n if (\n action === \"fallback-model\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.model !== next.model\n ) {\n return true;\n }\n\n if (\n action === \"fallback-transport\" &&\n failed.provider === next.provider &&\n failed.transport.id !== next.transport.id\n ) {\n return true;\n }\n\n if (action === \"fallback-provider\" && failed.provider !== next.provider) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Apply a request-level model override to a candidate route (C7 / CD-8 / INV-ROUTE-1).\n *\n * - No `requestedModel` \u2192 the route is returned unchanged.\n * - `requestedModel` already equals `route.model` \u2192 returned unchanged (no synthetic copy).\n * - `strict` route + undeclared model \u2192 returns `undefined` (DROP \u2014 never silently billed; OQ-6).\n * - `shortlist` route + undeclared model \u2192 returns a synthetic copy with `model: requestedModel`\n * while PRESERVING the original `route.id` (R12 \u2014 health/cursors keyed on `id` never fragment).\n *\n * Pure and route-local: the input route object is never mutated.\n */\nexport function applyRequestedModel(\n route: NormalizedRoute,\n requestedModel: string | undefined,\n): NormalizedRoute | undefined {\n if (!requestedModel || requestedModel === route.model) {\n return route;\n }\n\n if (route.advertisedModels.includes(requestedModel)) {\n // Declared model \u2014 verbatim passthrough on a synthetic copy (id preserved).\n return { ...route, model: requestedModel };\n }\n\n if (route.modelAllowlistMode === \"strict\") {\n // Undeclared on a strict route \u2014 DROP so it can never be billed.\n return undefined;\n }\n\n // shortlist: advisory allowlist \u2014 pass the undeclared model through verbatim, id preserved.\n return { ...route, model: requestedModel };\n}\n", "import type {\n AcpModelInfo,\n ModelContextResolution,\n ModelPricing,\n ModelReferenceEntry,\n ResolveModelContextInput,\n} from \"./types.js\";\n\n/**\n * Browser-safe model-reference primitive (C4 / UR-007, UR-009, UR-015).\n *\n * This module is a PURE data + functions reuse primitive: it has ZERO `node:*` imports,\n * needs no client instance, and references no provider/transport/bs-search symbol except\n * inside the curated `MODEL_REFERENCE` id-string literals (INV-REUSE-1). Everything here is\n * synchronous and side-effect-free \u2014 safe to run in a browser bundle.\n *\n * The fallback default context window when nothing else is known.\n */\nexport const DEFAULT_CONTEXT_WINDOW = 8192;\n\n/**\n * Curated reference table of model context windows / pricing / free-tier flags.\n *\n * Keys are NORMALIZED model keys (see {@link normalizeModelKey}): lowercase, provider prefix\n * dropped, `:free`/`:beta` suffixes dropped. Covers every model id that appears in\n * `src/catalog.ts` plus the common public model families so the flat-8192 default rarely\n * fires (R-OQ3). The provider/model NAMES that appear here are inert string DATA, not symbol\n * references \u2014 the reusability gate (INV-REUSE-1) explicitly allows them inside these literals.\n */\nexport const MODEL_REFERENCE: Record<string, ModelReferenceEntry> = {\n // --- OpenAI (gpt / codex families; catalog: gpt-4.1, gpt-5.4/xhigh) ---\n \"gpt-4.1\": { key: \"gpt-4.1\", contextLength: 1_047_576 },\n \"gpt-4.1-mini\": { key: \"gpt-4.1-mini\", contextLength: 1_047_576 },\n \"gpt-4.1-nano\": { key: \"gpt-4.1-nano\", contextLength: 1_047_576 },\n \"gpt-4o\": { key: \"gpt-4o\", contextLength: 128_000 },\n \"gpt-4o-mini\": { key: \"gpt-4o-mini\", contextLength: 128_000 },\n \"gpt-4-turbo\": { key: \"gpt-4-turbo\", contextLength: 128_000 },\n \"gpt-4\": { key: \"gpt-4\", contextLength: 8_192 },\n \"gpt-3.5-turbo\": { key: \"gpt-3.5-turbo\", contextLength: 16_385 },\n \"gpt-5\": { key: \"gpt-5\", contextLength: 400_000 },\n \"gpt-5.4\": { key: \"gpt-5.4\", contextLength: 400_000 },\n o1: { key: \"o1\", contextLength: 200_000 },\n \"o1-mini\": { key: \"o1-mini\", contextLength: 128_000 },\n \"o3-mini\": { key: \"o3-mini\", contextLength: 200_000 },\n\n // --- Anthropic (claude families; catalog: claude-sonnet-4-6, claude-sonnet-4) ---\n \"claude-sonnet-4-6\": { key: \"claude-sonnet-4-6\", contextLength: 200_000 },\n \"claude-sonnet-4\": { key: \"claude-sonnet-4\", contextLength: 200_000 },\n \"claude-opus-4\": { key: \"claude-opus-4\", contextLength: 200_000 },\n \"claude-haiku-4\": { key: \"claude-haiku-4\", contextLength: 200_000 },\n \"claude-3-5-sonnet\": { key: \"claude-3-5-sonnet\", contextLength: 200_000 },\n \"claude-3-5-haiku\": { key: \"claude-3-5-haiku\", contextLength: 200_000 },\n \"claude-3-opus\": { key: \"claude-3-opus\", contextLength: 200_000 },\n \"claude-3-sonnet\": { key: \"claude-3-sonnet\", contextLength: 200_000 },\n \"claude-3-haiku\": { key: \"claude-3-haiku\", contextLength: 200_000 },\n\n // --- Gemini (catalog: gemini-3.1-flash-lite, gemini-2.5-flash, auto-gemini-3) ---\n \"gemini-3.1-flash-lite\": {\n key: \"gemini-3.1-flash-lite\",\n contextLength: 1_048_576,\n },\n \"gemini-3.1-pro\": { key: \"gemini-3.1-pro\", contextLength: 1_048_576 },\n \"gemini-3-pro\": { key: \"gemini-3-pro\", contextLength: 2_097_152 },\n \"auto-gemini-3\": { key: \"auto-gemini-3\", contextLength: 1_048_576 },\n \"gemini-2.5-flash\": { key: \"gemini-2.5-flash\", contextLength: 1_048_576 },\n \"gemini-2.5-pro\": { key: \"gemini-2.5-pro\", contextLength: 2_097_152 },\n \"gemini-2.0-flash\": { key: \"gemini-2.0-flash\", contextLength: 1_048_576 },\n \"gemini-1.5-flash\": { key: \"gemini-1.5-flash\", contextLength: 1_048_576 },\n \"gemini-1.5-pro\": { key: \"gemini-1.5-pro\", contextLength: 2_097_152 },\n};\n\n/**\n * Normalize a model id into a {@link MODEL_REFERENCE} lookup key:\n * 1. lowercase\n * 2. drop a leading `provider/` segment (e.g. `openai/gpt-4.1` \u2192 `gpt-4.1`)\n * 3. drop a trailing `:free` / `:beta` modifier (e.g. `gpt-4.1:free` \u2192 `gpt-4.1`)\n *\n * Pure string transform \u2014 provider/transport-blind.\n */\nexport function normalizeModelKey(model: string): string {\n let key = model.trim().toLowerCase();\n // Drop provider prefix: only the FIRST `/`-delimited segment is treated as a provider.\n const slashIndex = key.indexOf(\"/\");\n if (slashIndex > 0) {\n key = key.slice(slashIndex + 1);\n }\n // Drop a trailing free/beta modifier.\n key = key.replace(/:(?:free|beta)$/i, \"\");\n return key.trim();\n}\n\n/**\n * Look up a curated {@link ModelReferenceEntry} for a model id. Normalizes the id first\n * (see {@link normalizeModelKey}) then matches by, in order: EXACT key, longest PREFIX key,\n * longest SUBSTRING key. When several keys tie, the LONGEST key wins (R18 \u2014 avoids a short\n * key shadowing a more specific one). Returns `undefined` when nothing matches.\n */\nexport function lookupModelRef(model: string): ModelReferenceEntry | undefined {\n const normalized = normalizeModelKey(model);\n if (!normalized) {\n return undefined;\n }\n\n // 1. Exact match.\n const exact = MODEL_REFERENCE[normalized];\n if (exact) {\n return exact;\n }\n\n // 2. Prefix match \u2014 the normalized id starts with a reference key.\n let prefixWinner: ModelReferenceEntry | undefined;\n for (const [key, entry] of Object.entries(MODEL_REFERENCE)) {\n if (normalized.startsWith(key)) {\n if (!prefixWinner || key.length > prefixWinner.key.length) {\n prefixWinner = entry;\n }\n }\n }\n if (prefixWinner) {\n return prefixWinner;\n }\n\n // 3. Substring match \u2014 a reference key appears anywhere in the normalized id.\n let substringWinner: ModelReferenceEntry | undefined;\n for (const [key, entry] of Object.entries(MODEL_REFERENCE)) {\n if (normalized.includes(key)) {\n if (!substringWinner || key.length > substringWinner.key.length) {\n substringWinner = entry;\n }\n }\n }\n return substringWinner;\n}\n\nfunction isUsableContextLength(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Extract a context-window length from a raw provider model record. Probes a FIXED key order\n * (first usable value wins): `context_length` \u2192 `max_model_len` \u2192 `context_window` \u2192\n * `top_provider.context_length`. Zero, negative, NaN, and non-number values are ignored.\n * Returns `undefined` when no usable value is present.\n */\nexport function extractModelContextLength(raw: unknown): number | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined;\n }\n const record = raw as Record<string, unknown>;\n\n if (isUsableContextLength(record.context_length)) {\n return record.context_length;\n }\n if (isUsableContextLength(record.max_model_len)) {\n return record.max_model_len;\n }\n if (isUsableContextLength(record.context_window)) {\n return record.context_window;\n }\n const topProvider = record.top_provider;\n if (topProvider && typeof topProvider === \"object\") {\n const nested = (topProvider as Record<string, unknown>).context_length;\n if (isUsableContextLength(nested)) {\n return nested;\n }\n }\n return undefined;\n}\n\nfunction asPricingNumber(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n // Provider pricing tables frequently encode amounts as decimal strings.\n if (typeof value === \"string\" && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return undefined;\n}\n\n/**\n * Parse a {@link ModelPricing} block from a raw provider model record's `pricing` object.\n * Numbers and numeric strings are accepted; other shapes are dropped. Returns `undefined`\n * when no pricing components are present.\n */\nexport function parseModelPricing(raw: unknown): ModelPricing | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined;\n }\n const pricing = (raw as Record<string, unknown>).pricing;\n if (!pricing || typeof pricing !== \"object\") {\n return undefined;\n }\n const record = pricing as Record<string, unknown>;\n\n const prompt = asPricingNumber(record.prompt);\n const completion = asPricingNumber(record.completion);\n const request = asPricingNumber(record.request);\n const image = asPricingNumber(record.image);\n const currency =\n typeof record.currency === \"string\" ? record.currency : undefined;\n\n const result: ModelPricing = {\n ...(prompt !== undefined ? { prompt } : {}),\n ...(completion !== undefined ? { completion } : {}),\n ...(request !== undefined ? { request } : {}),\n ...(image !== undefined ? { image } : {}),\n ...(currency !== undefined ? { currency } : {}),\n };\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Determine whether a model is free. Two independent signals (INV \u2014 dual-free-detection):\n * 1. the model id carries a `:free` suffix, OR\n * 2. every DEFINED pricing component (prompt/completion/request/image) is exactly 0.\n *\n * A PARTIAL zero (some components 0, others positive) is NOT free. When no pricing is supplied\n * and there is no `:free` suffix, returns `false`.\n */\nexport function detectModelFree(\n modelId: string,\n pricing?: ModelPricing,\n raw?: unknown,\n): boolean {\n if (/:free$/i.test(modelId.trim())) {\n return true;\n }\n\n const effectivePricing = pricing ?? parseModelPricing(raw);\n if (!effectivePricing) {\n return false;\n }\n\n const components = [\n effectivePricing.prompt,\n effectivePricing.completion,\n effectivePricing.request,\n effectivePricing.image,\n ].filter((value): value is number => typeof value === \"number\");\n\n if (components.length === 0) {\n return false;\n }\n\n return components.every((value) => value === 0);\n}\n\n/**\n * Standalone context-window resolver (no client instance required \u2014 INV-REUSE-1). Precedence\n * is FIXED: discovered > reference > configured > default. Each candidate must be a usable\n * positive finite number to participate; otherwise the next source is consulted. When nothing\n * is usable, falls back to `defaultContextWindow` (default {@link DEFAULT_CONTEXT_WINDOW}).\n */\nexport function resolveModelContextWindow(input: {\n discovered?: number;\n reference?: number;\n configured?: number;\n defaultContextWindow?: number;\n}): { contextWindow: number; source: ModelContextResolution[\"source\"] } {\n if (isUsableContextLength(input.discovered)) {\n return { contextWindow: input.discovered, source: \"discovered\" };\n }\n if (isUsableContextLength(input.reference)) {\n return { contextWindow: input.reference, source: \"reference\" };\n }\n if (isUsableContextLength(input.configured)) {\n return { contextWindow: input.configured, source: \"configured\" };\n }\n const fallback = isUsableContextLength(input.defaultContextWindow)\n ? input.defaultContextWindow\n : DEFAULT_CONTEXT_WINDOW;\n return { contextWindow: fallback, source: \"default\" };\n}\n\n/**\n * GAP-A: surface a route's CONFIGURED context window into a discovery catalog's\n * `ModelInfo.contextLength` (TASK-028 / UR-002).\n *\n * Monotonic + configured-only: writes `contextLength` ONLY when the entry has no\n * usable value yet AND `route.contextWindow` is usable (>0). Live/discovered\n * values (e.g. from an OpenAI/Anthropic /models response) are therefore never\n * overwritten. Only the route's own model (`route.model`) is filled so a static\n * catalog with one entry per route stays correct. A `metadata.contextWindowSource:\n * \"configured\"` tag marks the provenance so external consumers that map\n * `contextLength` into {@link resolveModelContextWindow}'s `discovered` slot can\n * gate on it (a configured value must feed `configured`, not `discovered`, to keep\n * the discovered>reference>configured>default precedence honest).\n */\nexport function fillConfiguredContextLength(\n route: { model?: string; contextWindow?: number },\n models: AcpModelInfo[],\n): AcpModelInfo[] {\n if (!isUsableContextLength(route.contextWindow)) {\n return models;\n }\n const configured = route.contextWindow;\n return models.map((entry) => {\n if (isUsableContextLength(entry.contextLength)) {\n return entry;\n }\n if (route.model !== undefined && entry.modelId !== route.model) {\n return entry;\n }\n return {\n ...entry,\n contextLength: configured,\n // FT-002: typed provenance (canonical) + metadata alias (back-compat).\n contextWindowSource: \"configured\",\n metadata: { ...(entry.metadata ?? {}), contextWindowSource: \"configured\" },\n };\n });\n}\n\n/**\n * Compute the cache key + model id for a {@link ResolveModelContextInput}. Cache scope is\n * per-(baseUrl|transportId)::model so two routes pointing at different gateways do not share a\n * cached window.\n */\nexport function modelContextCacheKey(input: ResolveModelContextInput): {\n key: string;\n model: string;\n} {\n if (typeof input === \"string\") {\n return { key: `::${input}`, model: input };\n }\n const scope = input.baseUrl ?? input.transportId ?? \"\";\n return { key: `${scope}::${input.model}`, model: input.model };\n}\n", "// C8 \u2014 health/probe pure primitives (UR-008 / UR-015 / CD-7 / CD-9).\n//\n// CLIENT-FREE by construction: this module has TYPE-ONLY imports, ZERO Node builtins, no import\n// from the client / transport modules, and no provider-vendor symbol. It is\n// a browser-safe, reusable primitive (INV-REUSE-1) \u2014 there is NO module-level mutable state: the\n// probe cache map is OWNED by the caller (the client) and passed in, and `now` is always a param\n// (fake-clock friendly, D6/INV-DET-1). Per CD-4 there is NO probe-local `withTimeout`; the per-\n// probe timeout is scheduled by the client via the `deriveAbort` / `runtime.setTimer` seam.\n\nimport type { AiConnectError } from \"./errors.js\";\nimport type { AiConnectErrorCode, ProbeModelResult } from \"./types.js\";\n\n/** Default per-probe timeout (ms). The probe ping aborts independently after this elapses. */\nexport const PROBE_DEFAULT_TIMEOUT_MS = 8000;\n/** Default TTL (ms) for the per-(route::sorted-models) probe cache. */\nexport const PROBE_DEFAULT_TTL_MS = 300000;\n/** Default bounded fan-out concurrency for `probeModels`. */\nexport const PROBE_DEFAULT_CONCURRENCY = 4;\n\n/**\n * Outcome of classifying a single probe ping. `ok` is true ONLY when the ping produced usable\n * output (non-empty `text` OR at least one `toolCall`). `broken` flags a route-side fault that a\n * retry will NOT fix: `400 \u2264 httpStatus < 500 \u2227 httpStatus \u2260 429` (INV-PROBE-1). Everything else\n * (429 / 5xx / status-less transport errors) is transient (`broken:false`).\n */\nexport interface ProbeOutcomeClassification {\n ok: boolean;\n broken: boolean;\n detail: string;\n code?: AiConnectErrorCode | \"not_supported\";\n httpStatus?: number;\n}\n\n/** Internal cache entry \u2014 exported as a type only so the client can own a typed `Map`. */\nexport interface ProbeCacheEntry {\n expiresAt: number;\n results: ProbeModelResult[];\n}\n\n/** The probe cache shape. The client owns one of these per-client; this module never mutates a global. */\nexport type ProbeCache = Map<string, ProbeCacheEntry>;\n\n/**\n * Extract the raw HTTP status carried on an {@link AiConnectError} via `details.httpStatus`\n * (CD-7 \u2014 attached by `classifyApiError` for every api error). Returns `undefined` for non-HTTP\n * transports (acp/cli/server) or when the carrier is absent.\n */\nfunction extractHttpStatus(error: AiConnectError | undefined): number | undefined {\n const raw = error?.details?.[\"httpStatus\"];\n return typeof raw === \"number\" && Number.isFinite(raw) ? raw : undefined;\n}\n\n/**\n * Classify a probe ping into {ok, broken, detail, code?, httpStatus?} (INV-PROBE-1).\n *\n * - On error: `ok=false`; `broken` is true exactly when `400 \u2264 httpStatus < 500 \u2227 httpStatus \u2260 429`\n * (the route-side, retry-won't-fix band). 429 / 5xx / status-less are transient (`broken=false`).\n * - On success: `ok=true` ONLY when `text` is non-empty OR `toolCalls` is present; an empty/blank\n * response is treated as a model-side failure (`ok=false`, `broken=false`).\n *\n * Pure and provider-blind \u2014 keys off `httpStatus` + output presence only, never a provider symbol.\n */\nexport function classifyProbeOutcome(input: {\n error?: AiConnectError;\n text?: string;\n toolCalls?: unknown[];\n}): ProbeOutcomeClassification {\n if (input.error) {\n const httpStatus = extractHttpStatus(input.error);\n const broken =\n httpStatus !== undefined &&\n httpStatus >= 400 &&\n httpStatus < 500 &&\n httpStatus !== 429;\n return {\n ok: false,\n broken,\n detail: input.error.message,\n code: input.error.code,\n ...(httpStatus !== undefined ? { httpStatus } : {}),\n };\n }\n\n const hasText = typeof input.text === \"string\" && input.text.trim().length > 0;\n const hasToolCalls = Array.isArray(input.toolCalls) && input.toolCalls.length > 0;\n if (hasText || hasToolCalls) {\n return { ok: true, broken: false, detail: \"ok\" };\n }\n\n return {\n ok: false,\n broken: false,\n detail: \"model returned an empty response\",\n };\n}\n\n/**\n * Stable, order-independent cache key for a route::model-set probe. Models are sorted+deduped so\n * `['a','b']` and `['b','a']` collide (scenario #47). The `routeId` is the namespace; the joined\n * sorted model list is the discriminant.\n */\nexport function probeCacheKey(routeId: string, models: readonly string[]): string {\n const sorted = [...new Set(models)].sort();\n return `${routeId}::${sorted.join(\",\")}`;\n}\n\n/**\n * Read a non-expired cache entry. A hit requires `now < entry.expiresAt` (so `now = expiresAt - 1`\n * hits and `now = expiresAt` / `+1` misses \u2014 scenario #47). Returns `undefined` on miss/absence.\n * Pure read; never mutates the cache or reads wall-clock (`now` is injected).\n */\nexport function readProbeCache(\n cache: ProbeCache,\n key: string,\n now: number,\n): ProbeModelResult[] | undefined {\n const entry = cache.get(key);\n if (!entry || now >= entry.expiresAt) {\n return undefined;\n }\n // Return shallow copies flagged `cached:true` so callers never mutate the stored results.\n return entry.results.map((result) => ({ ...result, cached: true }));\n}\n\n/**\n * Write a cache entry expiring at `now + ttlMs`. Stored results are normalized to `cached:false`\n * (the stored copy represents a freshly-probed result; `readProbeCache` re-flags hits). Mutates\n * only the caller-owned `cache` \u2014 no module-level state.\n */\nexport function writeProbeCache(\n cache: ProbeCache,\n key: string,\n results: ProbeModelResult[],\n now: number,\n ttlMs: number,\n): void {\n cache.set(key, {\n expiresAt: now + ttlMs,\n results: results.map((result) => ({ ...result, cached: false })),\n });\n}\n\n/**\n * Bounded-concurrency runner (INV: max in-flight \u2264 `limit` at all times). Runs `fn` over every\n * item with at most `limit` concurrent in-flight, preserving input order in the resolved array.\n * `fn` receives the item index so callers can correlate results. Rejections propagate (the first\n * rejection rejects the whole run) \u2014 probe callers therefore make `fn` total (it never rejects).\n *\n * Pure scheduling primitive: no timers, no clock, no provider/transport symbol (UR-015).\n */\nexport async function runBounded<T, R>(\n items: readonly T[],\n limit: number,\n fn: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const total = items.length;\n const results = new Array<R>(total);\n if (total === 0) {\n return results;\n }\n const effectiveLimit = Math.max(1, Math.min(limit, total));\n let cursor = 0;\n\n async function worker(): Promise<void> {\n while (true) {\n const index = cursor;\n cursor += 1;\n if (index >= total) {\n return;\n }\n results[index] = await fn(items[index]!, index);\n }\n }\n\n const workers: Promise<void>[] = [];\n for (let i = 0; i < effectiveLimit; i += 1) {\n workers.push(worker());\n }\n await Promise.all(workers);\n return results;\n}\n", "import type {\n RuntimeEnvironment,\n RuntimeKind,\n} from \"./types.js\";\n\nexport function inferRuntimeKind(): RuntimeKind {\n if (\n typeof window !== \"undefined\" &&\n typeof document !== \"undefined\"\n ) {\n return \"browser\";\n }\n\n return \"local\";\n}\n\nexport function createRuntimeEnvironment(\n kind: RuntimeKind,\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return {\n kind,\n now: overrides.now ?? (() => Date.now()),\n ...(overrides.getEnv ? { getEnv: overrides.getEnv } : {}),\n ...(overrides.hasCommand ? { hasCommand: overrides.hasCommand } : {}),\n // Forward the optional timer seam (F-P-3) so a seeded fake-clock `setTimer`\n // injected via factory overrides actually reaches `deriveAbort`. When omitted,\n // `deriveAbort` falls back to real `setTimeout`+`unref`.\n ...(overrides.setTimer ? { setTimer: overrides.setTimer } : {}),\n };\n}\n\nexport function createBrowserRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createRuntimeEnvironment(\"browser\", overrides);\n}\n\nexport function createLocalRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createRuntimeEnvironment(\"local\", overrides);\n}\n", "import {\n defineConfig,\n isNormalizedConfig,\n mergeFanoutPolicy,\n normalizeFanoutPolicy,\n resolveRouteSelectors,\n toPublicCapabilities,\n} from \"./config.js\";\nimport { AiConnectError, mapAbortError, toAiConnectError } from \"./errors.js\";\nimport { createFanoutLimiter } from \"./fanout.js\";\nimport {\n isPortableDocumentFile,\n isPortableImageFile,\n preparePortableFile,\n} from \"./files.js\";\nimport { shouldEmitWideEvent } from \"./logging.js\";\nimport { RouteRegistry, canFallbackBetween } from \"./router.js\";\nimport {\n lookupModelRef,\n modelContextCacheKey,\n resolveModelContextWindow,\n} from \"./model-reference.js\";\nimport {\n PROBE_DEFAULT_CONCURRENCY,\n PROBE_DEFAULT_TIMEOUT_MS,\n PROBE_DEFAULT_TTL_MS,\n classifyProbeOutcome,\n probeCacheKey,\n readProbeCache,\n runBounded,\n writeProbeCache,\n} from \"./probe.js\";\nimport type { ProbeCache } from \"./probe.js\";\nimport { createRuntimeEnvironment, inferRuntimeKind } from \"./runtime.js\";\nimport type {\n AbortContext,\n AbortReason,\n AcpModelDiscoveryReport,\n AcpModelDiscoveryRouteReport,\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CandidateModel,\n CheckHealthTarget,\n ClientToolDefinition,\n ClientToolExecutionResult,\n ClientOperationName,\n CreateClientOptions,\n DiscoverModelsTarget,\n DiscoverAcpModelsTarget,\n FanoutLimiter,\n FanoutPolicy,\n GenerateCallOptions,\n GenerateParameters,\n GenerateRequest,\n GenerateResult,\n GenerateStreamEvent,\n GenerateToolDefinition,\n ModelSelector,\n HealthModelStageResult,\n HealthReport,\n HealthStageResult,\n OperationKind,\n OperationTimeoutDefaults,\n ListedRoute,\n MessageInput,\n ModelContextResolution,\n ProbeModelResult,\n ProbeModelsOptions,\n ProbeModelsTarget,\n PublicRoute,\n RouteHealthReport,\n ResolveModelContextInput,\n ResolveModelContextOptions,\n NormalizedGenerateRequest,\n NormalizedRoute,\n PortableFile,\n RouteAttempt,\n RouteHandler,\n RouteHandlerGenerateResult,\n RouteHealthState,\n ToolCallInput,\n VerificationIssue,\n VerificationReport,\n VerificationRouteReport,\n TransportKind,\n WideEventAcpModelDiscoverySummary,\n WideEvent,\n WideEventAttempt,\n WideEventHealthRouteSummary,\n WideEventHealthSummary,\n WideEventParameterSummary,\n WideEventProbeRouteSummary,\n WideEventProbeSummary,\n WideEventRequestSummary,\n WideEventResultSummary,\n WideEventRouteSummary,\n WideEventTransportSummary,\n WideEventVerificationSummary,\n} from \"./types.js\";\n\nconst DEFAULT_LOGGING_SERVICE = \"ai-connect\";\n\nfunction splitCredentialValues(value: string, delimiter: string): string[] {\n return value\n .split(delimiter)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction materializeRuntimeConfig(config: AiConnectConfig, runtime: NonNullable<CreateClientOptions[\"runtime\"]>): AiConnectConfig {\n const routeExpansion = new Map<string, string[]>();\n const routes: NormalizedRoute[] = [];\n\n for (const route of config.routes) {\n const delimiter = route.credential.apiKeyDelimiter;\n const envName = route.credential.apiKeyEnv;\n const envValue = delimiter && envName ? runtime.getEnv?.(envName)?.trim() : undefined;\n const values = delimiter && envValue ? splitCredentialValues(envValue, delimiter) : undefined;\n\n if (!values || values.length <= 1) {\n routeExpansion.set(route.id, [route.id]);\n routes.push(route);\n continue;\n }\n\n const expandedIds: string[] = [];\n values.forEach((apiKey, index) => {\n const credentialId = `${route.credentialId}#${index + 1}`;\n const expandedRoute: NormalizedRoute = {\n ...route,\n id: `${route.id}#${index + 1}`,\n credentialId,\n weight: 1,\n credential: {\n ...route.credential,\n id: credentialId,\n apiKey,\n ...(route.credential.apiKeyEnv ? { apiKeyEnv: route.credential.apiKeyEnv } : {}),\n },\n };\n expandedIds.push(expandedRoute.id);\n routes.push(expandedRoute);\n });\n routeExpansion.set(route.id, expandedIds);\n }\n\n return {\n ...config,\n routes,\n routing: {\n ...config.routing,\n operations: {\n text: {\n ...config.routing.operations.text,\n pool: config.routing.operations.text.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n image: {\n ...config.routing.operations.image,\n pool: config.routing.operations.image.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n file: {\n ...config.routing.operations.file,\n pool: config.routing.operations.file.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n },\n },\n };\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n if (delayMs <= 0) {\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n}\n\nfunction normalizeWorkingDirectory(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n throw new AiConnectError(\n \"validation_error\",\n \"Generate request workingDirectory must be a non-empty string when provided.\",\n );\n }\n\n return trimmed;\n}\n\nfunction normalizeClientToolDefinition(\n input: ClientToolDefinition,\n): ClientToolDefinition {\n const name = input.function.name.trim();\n if (!name) {\n throw new AiConnectError(\n \"validation_error\",\n \"Client tool function.name must be a non-empty string.\",\n );\n }\n\n if (typeof input.execute !== \"function\") {\n throw new AiConnectError(\n \"validation_error\",\n `Client tool \"${name}\" must provide an execute handler.`,\n );\n }\n\n return {\n ...input,\n function: {\n ...input.function,\n name,\n ...(input.function.description !== undefined\n ? { description: input.function.description }\n : {}),\n ...(input.function.parameters !== undefined\n ? { parameters: input.function.parameters }\n : {}),\n },\n };\n}\n\nfunction normalizeClientToolRegistry(\n tools: ClientToolDefinition[] | undefined,\n): Map<string, ClientToolDefinition> {\n const registry = new Map<string, ClientToolDefinition>();\n\n for (const tool of tools ?? []) {\n const normalized = normalizeClientToolDefinition(tool);\n registry.set(normalized.function.name, normalized);\n }\n\n return registry;\n}\n\nfunction resolveClientToolSelections(\n selections: GenerateRequest[\"clientTools\"] | undefined,\n registry: Map<string, ClientToolDefinition>,\n): ClientToolDefinition[] {\n if (!selections || selections.length === 0) {\n return [];\n }\n\n const resolved = new Map<string, ClientToolDefinition>();\n\n for (const selection of selections) {\n if (typeof selection === \"string\") {\n const name = selection.trim();\n if (!name) {\n throw new AiConnectError(\n \"validation_error\",\n \"Client tool references must be non-empty strings.\",\n );\n }\n\n const registered = registry.get(name);\n if (!registered) {\n throw new AiConnectError(\n \"validation_error\",\n `No client tool named \"${name}\" is registered on this client.`,\n );\n }\n\n resolved.set(name, registered);\n continue;\n }\n\n const normalized = normalizeClientToolDefinition(selection);\n resolved.set(normalized.function.name, normalized);\n }\n\n return Array.from(resolved.values());\n}\n\nfunction mergeToolDefinitions(\n existing: GenerateParameters[\"tools\"] | undefined,\n clientTools: ClientToolDefinition[],\n): GenerateToolDefinition[] | undefined {\n if (!existing?.length && clientTools.length === 0) {\n return existing;\n }\n\n const merged = new Map<string, GenerateToolDefinition>();\n for (const tool of existing ?? []) {\n merged.set(tool.function.name, tool);\n }\n for (const tool of clientTools) {\n merged.set(tool.function.name, {\n type: \"function\",\n function: {\n ...tool.function,\n },\n });\n }\n\n return Array.from(merged.values());\n}\n\nfunction requiresClientToolExecution(\n request: NormalizedGenerateRequest,\n): boolean {\n return Boolean(request.clientTools?.length);\n}\n\nfunction normalizeToolResult(\n result: ClientToolExecutionResult,\n): Pick<MessageInput, \"content\" | \"data\" | \"isError\"> {\n if (typeof result === \"string\") {\n return {\n content: result,\n };\n }\n\n const content =\n result.content !== undefined\n ? result.content\n : result.data !== undefined\n ? JSON.stringify(result.data)\n : \"\";\n\n return {\n content,\n ...(result.data !== undefined ? { data: result.data } : {}),\n ...(result.isError !== undefined ? { isError: result.isError } : {}),\n };\n}\n\nfunction sumOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number | undefined {\n if (left === undefined) {\n return right;\n }\n if (right === undefined) {\n return left;\n }\n\n return left + right;\n}\n\nfunction mergeUsage(\n current: GenerateResult[\"usage\"] | undefined,\n next: GenerateResult[\"usage\"] | undefined,\n): GenerateResult[\"usage\"] | undefined {\n if (!current) {\n return next;\n }\n if (!next) {\n return current;\n }\n\n const inputTokens = sumOptionalNumbers(current.inputTokens, next.inputTokens);\n const outputTokens = sumOptionalNumbers(current.outputTokens, next.outputTokens);\n const reasoningTokens = sumOptionalNumbers(\n current.reasoningTokens,\n next.reasoningTokens,\n );\n const totalTokens = sumOptionalNumbers(current.totalTokens, next.totalTokens);\n const cachedReadTokens = sumOptionalNumbers(\n current.cachedReadTokens,\n next.cachedReadTokens,\n );\n const contextWindowUsed =\n next.contextWindowUsed ?? current.contextWindowUsed;\n const contextWindowSize =\n next.contextWindowSize ?? current.contextWindowSize;\n const durationMs = sumOptionalNumbers(current.durationMs, next.durationMs);\n const calls = sumOptionalNumbers(current.calls, next.calls);\n const costAmount = sumOptionalNumbers(current.cost?.amount, next.cost?.amount);\n const costCurrency = next.cost?.currency ?? current.cost?.currency;\n const modelUsage = next.modelUsage ?? current.modelUsage;\n\n const merged = {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n ...(contextWindowUsed !== undefined ? { contextWindowUsed } : {}),\n ...(contextWindowSize !== undefined ? { contextWindowSize } : {}),\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(calls !== undefined ? { calls } : {}),\n ...(current.cost || next.cost\n ? {\n cost: {\n amount: costAmount ?? 0,\n ...(costCurrency !== undefined ? { currency: costCurrency } : {}),\n },\n }\n : {}),\n ...(modelUsage !== undefined ? { modelUsage } : {}),\n };\n\n return merged;\n}\n\nfunction requiresToolSchema(\n request: NormalizedGenerateRequest,\n): boolean {\n return Boolean(\n request.parameters?.tools?.length ||\n request.parameters?.toolChoice !== undefined ||\n request.parameters?.parallelToolCalls !== undefined,\n );\n}\n\n/**\n * True when any attachment (or the image-operation source/reference inputs) is an\n * image \u2014 the request can only be served by a route advertising\n * `supportsImageInput`. (C6 \u2014 UR-012.)\n */\nfunction requiresImageInput(\n request: NormalizedGenerateRequest,\n): boolean {\n if (request.attachments.some((file) => isPortableImageFile(file))) {\n return true;\n }\n const image = request.image;\n if (!image) {\n return false;\n }\n return Boolean(\n image.sourceImage ||\n image.mask ||\n (image.referenceImages && image.referenceImages.length > 0),\n );\n}\n\n/**\n * True when any attachment is a supported document (PDF) \u2014 the request can only\n * be served by a route advertising `supportsFileUpload`. (C6 \u2014 UR-003.)\n */\nfunction requiresFileUpload(\n request: NormalizedGenerateRequest,\n): boolean {\n return request.attachments.some((file) => isPortableDocumentFile(file));\n}\n\nfunction normalizeRequestBase(request: GenerateRequest): NormalizedGenerateRequest {\n if (request.messages.length === 0) {\n throw new AiConnectError(\"validation_error\", \"Unified generate/stream requests must include at least one message.\");\n }\n\n const workingDirectory = normalizeWorkingDirectory(request.workingDirectory);\n const rest = {\n messages: request.messages,\n ...(request.parameters ? { parameters: request.parameters } : {}),\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n ...(request.logContext ? { logContext: request.logContext } : {}),\n ...(workingDirectory !== undefined ? { workingDirectory } : {}),\n };\n const normalizedImage: NormalizedGenerateRequest[\"image\"] = request.image\n ? {\n ...(request.image.size !== undefined ? { size: request.image.size } : {}),\n ...(request.image.rawPrompt !== undefined ? { rawPrompt: request.image.rawPrompt } : {}),\n ...(request.image.aspectRatio ? { aspectRatio: request.image.aspectRatio } : {}),\n ...(request.image.quality ? { quality: request.image.quality } : {}),\n ...(request.image.imageSize ? { imageSize: request.image.imageSize } : {}),\n ...(request.image.style ? { style: request.image.style } : {}),\n ...(request.image.sourceImage ? { sourceImage: preparePortableFile(request.image.sourceImage) } : {}),\n ...(request.image.mask ? { mask: preparePortableFile(request.image.mask) } : {}),\n ...(request.image.referenceImages\n ? {\n referenceImages: request.image.referenceImages.map((input) => preparePortableFile(input)),\n }\n : {}),\n }\n : undefined;\n\n return {\n ...rest,\n operation: request.operation ?? \"text\",\n attachments: [...(request.attachments ?? []), ...(normalizedImage?.referenceImages ?? [])].map((input) => preparePortableFile(input)),\n ...(normalizedImage ? { image: normalizedImage } : {}),\n };\n}\n\nfunction resolveHandler(route: NormalizedRoute, handlers: Record<string, RouteHandler>): RouteHandler | undefined {\n return handlers[route.handlerKey] ?? handlers[`${route.provider}:${route.transport.kind}`] ?? handlers[`*:${route.transport.kind}`];\n}\n\n/**\n * Inject the selected route's explicit per-route config (C7 / R14) onto a request just before it\n * reaches the handler:\n *\n * - `route.defaultResponseFormat` \u2192 `parameters.responseFormat`, ONLY when the caller supplied\n * none (caller override always wins).\n * - `route.systemPrompt` \u2192 a leading `{role:\"system\"}` message, ONLY when the caller authored no\n * system message.\n *\n * Always derived from the ORIGINAL normalized request, so it is idempotent across retry/fallback\n * (a second route's defaults never stack on a first route's injection). This is explicit\n * consumer-config-authored content, NOT ai-connect ambient \u2014 so it is applied in BOTH `workspace`\n * and `clean` context modes (OQ-15 / INV-CLEAN-1: clean suppresses ambient, not explicit config).\n */\nfunction applyRouteDefaults(\n route: NormalizedRoute,\n request: NormalizedGenerateRequest,\n): NormalizedGenerateRequest {\n const callerHasSystemMessage = request.messages.some(\n (message) => message.role === \"system\",\n );\n const injectSystemPrompt =\n route.systemPrompt !== undefined && !callerHasSystemMessage;\n\n const callerHasResponseFormat =\n request.parameters?.responseFormat !== undefined;\n const injectResponseFormat =\n route.defaultResponseFormat !== undefined && !callerHasResponseFormat;\n\n if (!injectSystemPrompt && !injectResponseFormat) {\n return request;\n }\n\n const messages: MessageInput[] = injectSystemPrompt\n ? [{ role: \"system\", content: route.systemPrompt! }, ...request.messages]\n : request.messages;\n\n const parameters: GenerateParameters | undefined = injectResponseFormat\n ? {\n ...(request.parameters ?? {}),\n responseFormat: route.defaultResponseFormat!,\n }\n : request.parameters;\n\n return {\n ...request,\n messages,\n ...(parameters !== undefined ? { parameters } : {}),\n };\n}\n\n/**\n * Secret-free projection of a normalized route (C7 / INV-PROJ-1). Built by EXPLICIT construction \u2014\n * the {@link NormalizedRoute} is NEVER spread, so credential/baseUrl/apiKeyEnv/accountId/\n * handlerKey/credentialId can never leak into a public surface. Each capability flag is copied\n * field-by-field from the safe {@link PublicRouteCapabilities} `Pick`.\n */\nfunction toPublicRoute(\n route: NormalizedRoute,\n health: RouteHealthState,\n): PublicRoute {\n // INV-PROJ-1: the shared secret-free projector (also used by the router's\n // candidateModels) \u2014 never spread the full RouteCapabilities (#12).\n const capabilities = toPublicCapabilities(route.capabilities);\n\n return {\n id: route.id,\n label: route.label ?? route.id,\n provider: route.provider,\n transportKind: route.transport.kind,\n models: [...route.advertisedModels],\n defaultModel: route.model,\n ...(route.contextWindow !== undefined\n ? { contextWindow: route.contextWindow }\n : {}),\n modelAllowlistMode: route.modelAllowlistMode,\n ...(route.defaultResponseFormat !== undefined\n ? { defaultResponseFormat: route.defaultResponseFormat }\n : {}),\n ...(route.systemPrompt !== undefined\n ? { systemPrompt: route.systemPrompt }\n : {}),\n capabilities,\n health,\n };\n}\n\n/**\n * Build the minimal chat ping for Stage-2 health-checks and model probes (C8). A single user\n * message + `maxTokens: 1` keeps the billable cost as low as possible; the goal is liveness, not\n * content. The request is already normalized (no attachments, no client tools, no image).\n */\nfunction buildPingRequest(): NormalizedGenerateRequest {\n return {\n operation: \"text\",\n messages: [{ role: \"user\", content: \"ping\" }],\n attachments: [],\n parameters: { maxTokens: 1 },\n };\n}\n\nfunction normalizeResult(route: NormalizedRoute, output: Awaited<ReturnType<NonNullable<RouteHandler[\"generate\"]>>>, attempts: RouteAttempt[]): GenerateResult {\n return {\n route,\n attachments: (output.attachments ?? []).map((item) => preparePortableFile(item)),\n warnings: output.warnings ?? [],\n attempts,\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.reasoning !== undefined ? { reasoning: output.reasoning } : {}),\n ...(output.data !== undefined ? { data: output.data } : {}),\n ...(output.usage !== undefined ? { usage: output.usage } : {}),\n };\n}\n\nfunction runtimeIssue(route: NormalizedRoute): VerificationIssue | undefined {\n if (route.transport.kind === \"acp\") {\n return {\n code: \"runtime_mismatch\",\n message: \"ACP routes are local-only and cannot run in a browser runtime.\",\n };\n }\n\n return route.runtime === \"local\"\n ? {\n code: \"runtime_mismatch\",\n message: \"This route is marked local-only and cannot run in a browser runtime.\",\n }\n : undefined;\n}\n\nfunction nowMs(runtime: NonNullable<CreateClientOptions[\"runtime\"]>): number {\n return runtime.now?.() ?? Date.now();\n}\n\n/** Per-operation timeout tier (CD-6). */\ntype OperationTimeoutTier = \"generateMs\" | \"probeMs\";\n\nconst OPERATION_TIMEOUT_DEFAULTS: Record<OperationTimeoutTier, number> = {\n generateMs: 120_000,\n probeMs: 12_000,\n};\n\n/**\n * Resolve the effective per-operation timeout (CD-6). Precedence: explicit caller\n * `opts.timeoutMs` \u2192 client tier default \u2192 built-in tier default. A value `<= 0` or\n * non-finite (`Infinity`) DISABLES the timer (returns `undefined`). This is policy data\n * only; it is provider/transport-blind.\n */\nfunction resolveOpTimeout(\n opts: Pick<GenerateCallOptions, \"timeoutMs\"> | undefined,\n tier: OperationTimeoutTier,\n timeouts: OperationTimeoutDefaults | undefined,\n): number | undefined {\n const explicit = opts?.timeoutMs;\n const candidate =\n explicit !== undefined\n ? explicit\n : timeouts?.[tier] ?? OPERATION_TIMEOUT_DEFAULTS[tier];\n\n if (candidate === undefined || !Number.isFinite(candidate) || candidate <= 0) {\n return undefined;\n }\n\n return candidate;\n}\n\n/**\n * The SINGLE abort/timeout merge point (CD-4). Merges the caller `signal` \u2295 an op timeout\n * into ONE derived `AbortController`; the `reason` is first-writer-wins ('caller' vs\n * 'timeout') so the thrown code is deterministic (INV-ABORT-2). The timeout is scheduled\n * via `runtime.setTimer?` (default real `setTimeout`+`unref`) so a seeded DST fake-clock\n * controls it (F-P-3). `pauseSignal` is passed THROUGH untouched. `dispose()` clears the\n * timer and removes listeners \u2014 callers MUST invoke it in a `finally`.\n *\n * Provider-blind by construction: this function references no provider/transport symbol\n * (UR-015 INV-REUSE).\n */\nfunction deriveAbort(\n opts: Pick<GenerateCallOptions, \"signal\" | \"pauseSignal\" | \"timeoutMs\"> | undefined,\n timeoutMs: number | undefined,\n runtime: NonNullable<CreateClientOptions[\"runtime\"]>,\n config: { pauseAsAbort?: boolean } = {},\n): { abort: AbortContext; dispose: () => void } {\n const controller = new AbortController();\n const callerSignal = opts?.signal;\n // `pauseAsAbort` is set by generate(): a non-streamed call cannot retain a partial, so a\n // mid-call pause degenerates to a caller abort. stream() leaves it false and instead reads\n // `abort.pauseSignal` to emit a terminal {type:'paused'}.\n const pauseAbortSignal = config.pauseAsAbort ? opts?.pauseSignal : undefined;\n\n let reason: AbortReason | undefined;\n let cancelTimer: (() => void) | undefined;\n let callerListener: (() => void) | undefined;\n let pauseListener: (() => void) | undefined;\n\n const abortWith = (next: AbortReason): void => {\n if (reason !== undefined) {\n return; // first-writer-wins (INV-ABORT-2)\n }\n reason = next;\n abortContext.reason = next;\n if (!controller.signal.aborted) {\n controller.abort();\n }\n };\n\n const abortContext: AbortContext = {\n signal: controller.signal,\n ...(opts?.pauseSignal ? { pauseSignal: opts.pauseSignal } : {}),\n };\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n abortWith(\"caller\");\n } else {\n callerListener = () => abortWith(\"caller\");\n callerSignal.addEventListener(\"abort\", callerListener, { once: true });\n }\n }\n\n if (reason === undefined && pauseAbortSignal) {\n if (pauseAbortSignal.aborted) {\n abortWith(\"caller\");\n } else {\n pauseListener = () => abortWith(\"caller\");\n pauseAbortSignal.addEventListener(\"abort\", pauseListener, { once: true });\n }\n }\n\n if (reason === undefined && timeoutMs !== undefined) {\n const fire = () => abortWith(\"timeout\");\n if (typeof runtime.setTimer === \"function\") {\n cancelTimer = runtime.setTimer(timeoutMs, fire);\n } else {\n const handle = setTimeout(fire, timeoutMs);\n (handle as { unref?: () => void }).unref?.();\n cancelTimer = () => clearTimeout(handle);\n }\n }\n\n const dispose = (): void => {\n cancelTimer?.();\n cancelTimer = undefined;\n if (callerSignal && callerListener) {\n callerSignal.removeEventListener(\"abort\", callerListener);\n callerListener = undefined;\n }\n if (pauseAbortSignal && pauseListener) {\n pauseAbortSignal.removeEventListener(\"abort\", pauseListener);\n pauseListener = undefined;\n }\n };\n\n return { abort: abortContext, dispose };\n}\n\nfunction isoTimestamp(value: number): string {\n return new Date(value).toISOString();\n}\n\nfunction createRequestId(): string {\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction resolveEventRequestId(context: Record<string, unknown> | undefined): string {\n const requestId = typeof context?.request_id === \"string\" ? context.request_id : typeof context?.requestId === \"string\" ? context.requestId : undefined;\n\n return requestId?.trim() || createRequestId();\n}\n\nfunction summarizeRoute(route: NormalizedRoute): WideEventRouteSummary {\n return {\n id: route.id,\n provider: route.provider,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n runtime: route.runtime,\n accountId: route.accountId,\n credentialId: route.credentialId,\n model: route.model,\n handlerKey: route.handlerKey,\n profileId: route.profileId,\n ...(route.transport.baseUrl ? { baseUrl: route.transport.baseUrl } : {}),\n };\n}\n\nfunction summarizeFiles(files: PortableFile[]): {\n count: number;\n kinds: PortableFile[\"kind\"][];\n names: string[];\n} {\n return {\n count: files.length,\n kinds: files.map((file) => file.kind),\n names: files.map((file) => file.name),\n };\n}\n\nfunction summarizeToolChoice(choice: GenerateParameters[\"toolChoice\"]): string | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (typeof choice === \"string\") {\n return choice;\n }\n\n if (choice.type === \"function\" && choice.name.trim().length > 0) {\n return `function:${choice.name}`;\n }\n\n return undefined;\n}\n\nfunction summarizeParameters(parameters: GenerateParameters | undefined): WideEventParameterSummary | undefined {\n if (!parameters) {\n return undefined;\n }\n\n const keys = Object.keys(parameters).sort();\n const stopCount = Array.isArray(parameters.stop) ? parameters.stop.length : typeof parameters.stop === \"string\" ? 1 : undefined;\n const thinkingMode = parameters.thinking?.mode ?? (parameters.thinking?.enabled === true ? \"enabled\" : parameters.thinking?.enabled === false ? \"disabled\" : undefined);\n const providerOptionKeys = Object.fromEntries(\n Object.entries(parameters.providerOptions ?? {})\n .filter((entry): entry is [string, Record<string, unknown>] => Boolean(entry[1]))\n .map(([providerId, value]) => [providerId, Object.keys(value).sort()]),\n );\n const toolChoice = summarizeToolChoice(parameters.toolChoice);\n\n return {\n keys,\n ...(parameters.maxTokens !== undefined ? { maxTokens: parameters.maxTokens } : {}),\n ...(parameters.temperature !== undefined ? { temperature: parameters.temperature } : {}),\n ...(parameters.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopCount !== undefined ? { stopCount } : {}),\n ...(parameters.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters.candidateCount !== undefined ? { candidateCount: parameters.candidateCount } : {}),\n ...(parameters.presencePenalty !== undefined ? { presencePenalty: parameters.presencePenalty } : {}),\n ...(parameters.frequencyPenalty !== undefined ? { frequencyPenalty: parameters.frequencyPenalty } : {}),\n ...(parameters.responseFormat ? { responseFormatType: parameters.responseFormat.type } : {}),\n ...(parameters.tools ? { toolCount: parameters.tools.length } : {}),\n ...(toolChoice ? { toolChoice } : {}),\n ...(parameters.parallelToolCalls !== undefined ? { parallelToolCalls: parameters.parallelToolCalls } : {}),\n ...(thinkingMode ? { thinkingMode } : {}),\n ...(parameters.thinking?.budgetTokens !== undefined ? { thinkingBudgetTokens: parameters.thinking.budgetTokens } : {}),\n ...(parameters.thinking?.effort ? { thinkingEffort: parameters.thinking.effort } : {}),\n ...(parameters.thinking?.includeThoughts !== undefined ? { includeThoughts: parameters.thinking.includeThoughts } : {}),\n ...(parameters.safetySettings ? { safetySettingsCount: parameters.safetySettings.length } : {}),\n ...(parameters.metadata ? { metadataKeys: Object.keys(parameters.metadata).sort() } : {}),\n ...(parameters.extra ? { extraKeys: Object.keys(parameters.extra).sort() } : {}),\n ...(Object.keys(providerOptionKeys).length > 0 ? { providerOptionKeys } : {}),\n };\n}\n\nfunction summarizeRequest(request: NormalizedGenerateRequest, candidates: WideEventRouteSummary[]): WideEventRequestSummary {\n const attachments = summarizeFiles(request.attachments);\n const parameters = summarizeParameters(request.parameters);\n\n return {\n messageCount: request.messages.length,\n messageRoles: request.messages.map((message) => message.role),\n inputChars: request.messages.reduce((sum, message) => sum + message.content.length, 0),\n attachmentCount: attachments.count,\n attachmentKinds: attachments.kinds,\n attachmentNames: attachments.names,\n candidateRouteIds: candidates.map((route) => route.id),\n ...(request.clientTools?.length\n ? {\n clientToolCount: request.clientTools.length,\n clientToolNames: request.clientTools.map((tool) => tool.function.name),\n }\n : {}),\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n ...(request.workingDirectory\n ? { workingDirectory: request.workingDirectory }\n : {}),\n ...(request.image?.size ? { imageSize: String(request.image.size) } : {}),\n ...(request.image?.aspectRatio ? { imageAspectRatio: request.image.aspectRatio } : {}),\n ...(request.image?.quality ? { imageQuality: request.image.quality } : {}),\n ...(request.image?.imageSize ? { imageOutputSize: request.image.imageSize } : {}),\n ...(request.image?.style ? { imageStyle: request.image.style } : {}),\n ...(request.image?.rawPrompt !== undefined ? { rawImagePrompt: request.image.rawPrompt } : {}),\n ...(request.image?.referenceImages?.length ? { imageReferenceCount: request.image.referenceImages.length } : {}),\n ...(request.image?.sourceImage ? { imageHasSourceImage: true } : {}),\n ...(request.image?.mask ? { imageHasMask: true } : {}),\n ...(parameters ? { parameters } : {}),\n };\n}\n\nfunction summarizeResult(result: GenerateResult): WideEventResultSummary {\n const attachments = summarizeFiles(result.attachments);\n\n return {\n warningsCount: result.warnings.length,\n warnings: result.warnings,\n attachmentCount: attachments.count,\n attachmentKinds: attachments.kinds,\n attachmentNames: attachments.names,\n ...(result.text !== undefined ? { outputTextChars: result.text.length } : {}),\n ...(result.toolCalls?.length ? { toolCallCount: result.toolCalls.length } : {}),\n ...(result.usage !== undefined ? { usage: result.usage } : {}),\n };\n}\n\nfunction summarizeVerification(report: VerificationReport, targetIds: Set<string> | undefined): WideEventVerificationSummary {\n const issueCodes = report.routes.flatMap((route) => route.issues.map((issue) => issue.code));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n issueCount: issueCodes.length,\n issueCodes,\n routeReports: report.routes.map((route) => ({\n routeId: route.routeId,\n ok: route.ok,\n issueCodes: route.issues.map((issue) => issue.code),\n })),\n };\n}\n\nfunction summarizeAcpModelDiscovery(report: AcpModelDiscoveryReport, targetIds: Set<string> | undefined): WideEventAcpModelDiscoverySummary {\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n routeReports: report.routes.map((route) => ({\n routeId: route.routeId,\n provider: route.provider,\n ok: route.ok,\n transportKind: route.transportKind,\n transportId: route.transportId,\n ...(route.requestedModelId ? { requestedModelId: route.requestedModelId } : {}),\n ...(route.requestedModelAdvertised !== undefined ? { requestedModelAdvertised: route.requestedModelAdvertised } : {}),\n ...(route.canonicalModelId ? { canonicalModelId: route.canonicalModelId } : {}),\n ...(route.resolvedModelId ? { resolvedModelId: route.resolvedModelId } : {}),\n ...(route.currentModelId ? { currentModelId: route.currentModelId } : {}),\n availableModelCount: route.availableModels.length,\n availableModelIds: route.availableModels.map((model) => model.modelId),\n ...(route.error\n ? {\n errorCode: route.error.code,\n message: route.error.message,\n }\n : {}),\n })),\n };\n}\n\nfunction summarizeHealth(\n report: HealthReport,\n reachabilityOnly: boolean,\n targetIds: Set<string> | undefined,\n): WideEventHealthSummary {\n const routeReports: WideEventHealthRouteSummary[] = report.routes.map((route) => ({\n routeId: route.routeId,\n provider: route.provider,\n transportKind: route.transportKind,\n ok: route.ok,\n endpointOk: route.endpoint.ok,\n modelOk: route.model.ok,\n ...(route.endpoint.code ? { endpointCode: route.endpoint.code } : {}),\n ...(route.model.code ? { modelCode: route.model.code } : {}),\n ...(route.model.latencyMs !== undefined\n ? { modelLatencyMs: route.model.latencyMs }\n : {}),\n }));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n reachabilityOnly,\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n routeReports,\n };\n}\n\nfunction summarizeProbe(\n results: ProbeModelResult[],\n targetIds: Set<string> | undefined,\n): WideEventProbeSummary {\n const routeReports: WideEventProbeRouteSummary[] = results.map((result) => ({\n routeId: result.routeId,\n modelId: result.modelId,\n ok: result.ok,\n broken: result.broken,\n cached: result.cached === true,\n ...(result.code ? { code: result.code } : {}),\n ...(result.httpStatus !== undefined ? { httpStatus: result.httpStatus } : {}),\n ...(result.latencyMs !== undefined ? { latencyMs: result.latencyMs } : {}),\n }));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n probesIssued: results.length,\n probesOk: results.filter((result) => result.ok).length,\n probesBroken: results.filter((result) => result.broken).length,\n probesCached: results.filter((result) => result.cached === true).length,\n routeReports,\n };\n}\n\nexport function createClient(configOrInput: AiConnectConfig | AiConnectConfigInput, options: CreateClientOptions = {}): AiConnectClient {\n const baseConfig = isNormalizedConfig(configOrInput) ? configOrInput : defineConfig(configOrInput);\n const runtime = options.runtime ?? createRuntimeEnvironment(inferRuntimeKind());\n const config = materializeRuntimeConfig(baseConfig, runtime);\n const handlers = options.handlers ?? {};\n const clientToolRegistry = normalizeClientToolRegistry(options.clientTools);\n const router = new RouteRegistry(config, runtime);\n // C4 \u2014 per-(baseUrl|transportId)::model context-window cache. A hit returns the cached\n // value+source with cached:true and IGNORES options.discovered (OQ-4 / INV-CTX-1).\n const modelContextCache = new Map<string, ModelContextResolution>();\n // C8 \u2014 per-client probe cache keyed by `routeId::sorted-models` (probeCacheKey). Owned HERE,\n // never inside probe.ts (which is a stateless reusable primitive). TTL default 5min.\n const probeCache: ProbeCache = new Map();\n const logging = options.logging;\n const dispose = options.dispose ?? (async () => {});\n\n // C9 \u2014 fan-out throttle. The CLIENT-level limiter is built once from `options.fanout` and shared\n // across requests that don't override it (lifetime `maxCalls` is a per-client ceiling). A request\n // with its own `request.fanout` gets a request-SCOPED limiter (merged per-field over the client\n // default) so it NEVER mutates the shared client limiter (R15).\n const clientFanoutPolicy: FanoutPolicy | undefined = options.fanout;\n const clientFanoutLimiter: FanoutLimiter = createFanoutLimiter(\n normalizeFanoutPolicy(clientFanoutPolicy),\n runtime,\n );\n // C9 \u2014 the client-scoped ModelSelector hook (OQ-11). `failOpen` (default false) flips a throwing\n // selector from fail-closed `validation_error` to a silent fall-through to normal routing.\n const modelSelector: ModelSelector | undefined =\n options.routeHints?.modelSelector;\n const modelSelectorFailOpen = options.routeHints?.failOpen === true;\n\n /**\n * Pick the fan-out limiter for one request (R15). When the request carries its own `fanout`, a\n * fresh request-scoped limiter is built from the per-field merge over the client default \u2014 the\n * shared `clientFanoutLimiter` is never touched. Otherwise the shared client limiter is used.\n */\n function limiterForRequest(request: GenerateRequest): FanoutLimiter {\n if (request.fanout === undefined) {\n return clientFanoutLimiter;\n }\n return createFanoutLimiter(\n normalizeFanoutPolicy(mergeFanoutPolicy(clientFanoutPolicy, request.fanout)),\n runtime,\n );\n }\n\n /**\n * Resolve the effective request-level model (C9 / UR-014 / OQ-11). Precedence:\n * 1. explicit `routeHints.model` \u2014 wins outright; the selector is NOT invoked\n * (explicit-routeHints.model-beats-selector).\n * 2. the consumer `modelSelector` hook \u2014 invoked with the neutral input + eligible candidates;\n * an eligible returned id is applied; an undefined/ineligible id falls through (normal\n * routing). A throwing/rejecting selector FAILS CLOSED to `validation_error` unless `failOpen`.\n * 3. neither \u2014 undefined (normal routing).\n * Returns the model id to thread into `routeHints.model`, or undefined to leave routing untouched.\n */\n async function resolveSelectedModel(\n request: NormalizedGenerateRequest,\n ): Promise<string | undefined> {\n const explicit = request.routeHints?.model;\n if (explicit !== undefined) {\n return explicit;\n }\n if (!modelSelector) {\n return undefined;\n }\n const candidates = router.candidateModels({ operation: request.operation });\n let picked: string | undefined;\n try {\n picked = await modelSelector(\n {\n text: request.messages.map((message) => message.content).join(\"\\n\"),\n messages: request.messages,\n operation: request.operation,\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n },\n candidates,\n );\n } catch {\n // OQ-11: fail-closed by default \u2014 a throwing/rejecting selector yields a single deterministic\n // validation_error without consuming a fan-out slot or corrupting candidate ordering.\n if (modelSelectorFailOpen) {\n return undefined;\n }\n throw new AiConnectError(\n \"validation_error\",\n \"The configured modelSelector hook threw or rejected.\",\n );\n }\n if (picked === undefined) {\n return undefined;\n }\n // Only apply an eligible candidate; an ineligible id falls through so the strict-route DROP in\n // applyRequestedModel can surface a deterministic not_supported on empty candidates.\n return candidates.some((candidate) => candidate.model === picked)\n ? picked\n : undefined;\n }\n\n /**\n * Inject the selector-chosen model into the request's `routeHints.model` (when one was chosen and\n * the caller did not set an explicit one). Pure \u2014 returns a fresh request; never mutates input.\n */\n function withSelectedModel(\n request: NormalizedGenerateRequest,\n selectedModel: string | undefined,\n ): NormalizedGenerateRequest {\n if (selectedModel === undefined || request.routeHints?.model !== undefined) {\n return request;\n }\n return {\n ...request,\n routeHints: { ...(request.routeHints ?? {}), model: selectedModel },\n };\n }\n\n function prepareRequest(request: GenerateRequest): NormalizedGenerateRequest {\n const normalized = normalizeRequestBase(request);\n const clientTools = resolveClientToolSelections(\n request.clientTools,\n clientToolRegistry,\n );\n\n if (\n clientTools.length > 0 &&\n (normalized.operation !== \"text\" ||\n normalized.attachments.length > 0 ||\n normalized.image !== undefined)\n ) {\n throw new AiConnectError(\n \"validation_error\",\n \"clientTools are currently supported only for text requests without attachments or image options.\",\n );\n }\n\n const mergedTools = clientTools.length\n ? mergeToolDefinitions(normalized.parameters?.tools, clientTools)\n : undefined;\n\n return {\n ...normalized,\n ...(clientTools.length > 0 ? { clientTools } : {}),\n ...(mergedTools\n ? {\n parameters: {\n ...(normalized.parameters ?? {}),\n tools: mergedTools,\n },\n }\n : {}),\n };\n }\n\n async function executeClientToolLoop(\n route: NormalizedRoute,\n handler: NonNullable<RouteHandler[\"generate\"]>,\n request: NormalizedGenerateRequest,\n initialOutput: RouteHandlerGenerateResult,\n baseAttempt: number,\n abort: AbortContext,\n ): Promise<{\n output: RouteHandlerGenerateResult;\n transportSummary?: WideEventTransportSummary;\n }> {\n if (!request.clientTools?.length || !initialOutput.toolCalls?.length) {\n return { output: initialOutput };\n }\n\n const registry = new Map(\n request.clientTools.map((tool) => [tool.function.name, tool] as const),\n );\n const warnings = [...(initialOutput.warnings ?? [])];\n let usage = initialOutput.usage;\n let output = initialOutput;\n let messages = [...request.messages];\n let transportSummary: WideEventTransportSummary | undefined;\n\n for (let round = 0; round < 8; round += 1) {\n const toolCalls = output.toolCalls ?? [];\n if (toolCalls.length === 0) {\n return {\n output: {\n ...output,\n warnings,\n ...(usage ? { usage } : {}),\n },\n ...(transportSummary ? { transportSummary } : {}),\n };\n }\n\n const assistantMessage: MessageInput = {\n role: \"assistant\",\n content: output.text ?? \"\",\n toolCalls,\n };\n const toolMessages: MessageInput[] = [];\n\n for (const toolCall of toolCalls) {\n const tool = registry.get(toolCall.name);\n if (!tool) {\n throw new AiConnectError(\n \"validation_error\",\n `No client tool handler is registered for \"${toolCall.name}\".`,\n );\n }\n\n const execution = normalizeToolResult(\n await tool.execute(toolCall.arguments, {\n route,\n request,\n runtime,\n toolCall,\n messages,\n ...(request.workingDirectory\n ? { workingDirectory: request.workingDirectory }\n : {}),\n }),\n );\n\n toolMessages.push({\n role: \"tool\",\n content: execution.content,\n toolName: tool.function.name,\n toolCallId: toolCall.id,\n ...(execution.data !== undefined ? { data: execution.data } : {}),\n ...(execution.isError !== undefined\n ? { isError: execution.isError }\n : {}),\n });\n }\n\n messages = [...messages, assistantMessage, ...toolMessages];\n\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n output = await handler({\n route,\n request: {\n ...request,\n messages,\n attachments: [],\n },\n runtime,\n attempt: baseAttempt,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n });\n warnings.push(...(output.warnings ?? []));\n usage = mergeUsage(usage, output.usage);\n }\n\n throw new AiConnectError(\n \"validation_error\",\n \"clientTools exceeded the maximum tool-call loop depth of 8.\",\n );\n }\n\n async function emitWideEvent(event: Omit<WideEvent, \"service\" | \"library\">): Promise<void> {\n if (!logging?.logger) {\n return;\n }\n\n const mergedContext = {\n ...(logging.baseContext ?? {}),\n ...(event.context ?? {}),\n };\n const finalEvent: WideEvent = {\n ...event,\n service: logging.service ?? DEFAULT_LOGGING_SERVICE,\n library: \"ai-connect\",\n ...(Object.keys(mergedContext).length > 0 ? { context: mergedContext } : {}),\n ...(logging.version ? { version: logging.version } : {}),\n ...(logging.deploymentId ? { deploymentId: logging.deploymentId } : {}),\n ...(logging.region ? { region: logging.region } : {}),\n };\n\n if (!(await shouldEmitWideEvent(finalEvent, logging.sampling))) {\n return;\n }\n\n try {\n await logging.logger(finalEvent);\n } catch {\n // Logging should never break request handling.\n }\n }\n\n async function executeGenerateOperation(\n normalizedRequest: NormalizedGenerateRequest,\n operationName: ClientOperationName,\n abort: AbortContext,\n seed: {\n startMs?: number;\n requestId?: string;\n candidates?: WideEventRouteSummary[];\n attempts?: RouteAttempt[];\n wideAttempts?: WideEventAttempt[];\n } = {},\n ): Promise<GenerateResult> {\n const startedAt = seed.startMs ?? nowMs(runtime);\n const requestId = seed.requestId ?? resolveEventRequestId(normalizedRequest.logContext);\n const requiresSchema = requiresToolSchema(normalizedRequest);\n const requiresClientTools = requiresClientToolExecution(normalizedRequest);\n // C6: inject multimodal capability requirements so a PDF/image request only\n // routes to a candidate that advertises it; an empty candidate set then maps\n // to a clean `unsupported_capability` (no spawn/fetch \u2014 INV the design calls\n // pdf-on-unsupported-route-clean-error).\n const requiresImage = requiresImageInput(normalizedRequest);\n const requiresFile = requiresFileUpload(normalizedRequest);\n const requiresAnyCapability =\n requiresSchema || requiresClientTools || requiresImage || requiresFile;\n const resolvedCandidates = router.resolveCandidates(\n requiresAnyCapability\n ? {\n ...normalizedRequest,\n routeHints: {\n ...(normalizedRequest.routeHints ?? {}),\n requiredCapabilities: {\n ...(normalizedRequest.routeHints?.requiredCapabilities ?? {}),\n ...(requiresSchema ? { supportsToolSchema: true } : {}),\n ...(requiresClientTools\n ? { supportsClientToolExecution: true }\n : {}),\n ...(requiresImage ? { supportsImageInput: true } : {}),\n ...(requiresFile ? { supportsFileUpload: true } : {}),\n },\n },\n }\n : normalizedRequest,\n );\n const candidates = seed.candidates ?? resolvedCandidates.map(summarizeRoute);\n const requestSummary = summarizeRequest(normalizedRequest, candidates);\n\n if (resolvedCandidates.length === 0) {\n const error =\n requiresImage || requiresFile\n ? new AiConnectError(\n \"unsupported_capability\",\n `No eligible route supports the required ${\n requiresFile ? \"document/file\" : \"image\"\n } input for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`,\n )\n : new AiConnectError(\"not_supported\", `No eligible routes are available for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: seed.wideAttempts ?? [],\n request: requestSummary,\n error: {\n code: error.code,\n message: error.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw error;\n }\n\n const attempts = [...(seed.attempts ?? [])];\n const wideAttempts = [...(seed.wideAttempts ?? [])];\n let failedRoute: NormalizedRoute | undefined;\n let allowedFallbacks: string[] | undefined;\n\n for (const route of resolvedCandidates) {\n // INV-ABORT-1 / R2: a caller abort or fired timeout MUST short-circuit the fallback\n // loop BEFORE selecting/retrying any route \u2014 a cancel must never rotate credentials.\n if (abort.signal.aborted) {\n const abortError = mapAbortError(abort.reason);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: abortError.code,\n message: abortError.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw abortError;\n }\n\n if (failedRoute && allowedFallbacks && !canFallbackBetween(failedRoute, route, allowedFallbacks)) {\n continue;\n }\n\n const routeSummary = summarizeRoute(route);\n const handler = resolveHandler(route, handlers);\n if (!handler?.generate) {\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: \"not_supported\",\n message: `No generate handler is registered for ${route.handlerKey}.`,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: 0,\n outcome: \"error\",\n retryCount: 0,\n errorCode: \"not_supported\",\n message: `No generate handler is registered for ${route.handlerKey}.`,\n fallbackActions: config.routing.fallback.on.not_supported,\n });\n failedRoute = route;\n allowedFallbacks = config.routing.fallback.on.not_supported;\n router.recordFailure(route, \"not_supported\");\n continue;\n }\n\n let retryCount = 0;\n\n // C7 / R14: inject this route's explicit per-route defaults (systemPrompt /\n // defaultResponseFormat) when the caller omitted them. Derived from the ORIGINAL request so\n // it stays idempotent across retries and fallback to another route.\n const routeRequest = applyRouteDefaults(route, normalizedRequest);\n\n while (true) {\n const attemptStartedAt = nowMs(runtime);\n let transportSummary: WideEventTransportSummary | undefined;\n\n try {\n let output = await handler.generate({\n route,\n request: routeRequest,\n runtime,\n attempt: attempts.length + 1,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n });\n\n if (routeRequest.clientTools?.length && output.toolCalls?.length) {\n const loopResult = await executeClientToolLoop(\n route,\n handler.generate,\n routeRequest,\n output,\n attempts.length + 1,\n abort,\n );\n output = loopResult.output;\n if (loopResult.transportSummary) {\n transportSummary = loopResult.transportSummary;\n }\n }\n\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n router.recordSuccess(route);\n\n const result = normalizeResult(route, output, attempts);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n result: summarizeResult(result),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n return result;\n } catch (error) {\n // INV-ABORT-1 / R2: if the derived signal aborted, normalize to the canonical\n // abort/timeout code from `abort.reason` (NOT post-hoc DOMException sniffing) and\n // throw immediately \u2014 BEFORE consulting fallback policy, recording route health,\n // or rotating credentials. The handler's thrown error (an AbortError from the\n // underlying fetch/child) is discarded in favour of the authoritative reason.\n if (abort.signal.aborted) {\n const abortError = mapAbortError(abort.reason);\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: abortError.code,\n message: abortError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount,\n errorCode: abortError.code,\n message: abortError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: abortError.code,\n message: abortError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw new AiConnectError(abortError.code, abortError.message, {\n attempts,\n routeId: route.id,\n });\n }\n\n const normalizedError = toAiConnectError(error);\n const actions = config.routing.fallback.on[normalizedError.code] ?? [];\n\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n ...(actions.length ? { fallbackActions: actions } : {}),\n });\n\n const maxRetries = config.routing.retry.maxAttempts[normalizedError.code] ?? 0;\n if (actions.includes(\"retry\") && retryCount < maxRetries) {\n retryCount += 1;\n await sleep(config.routing.retry.delayMs[normalizedError.code] ?? 0);\n continue;\n }\n\n router.recordFailure(route, normalizedError.code);\n if (actions.length === 0) {\n const finalError = new AiConnectError(normalizedError.code, normalizedError.message, {\n // Preserve original error details (e.g. httpStatus from classifyApiError,\n // CD-7) through the terminal re-wrap \u2014 F-PF-1. `...undefined` is a no-op.\n ...normalizedError.details,\n attempts,\n routeId: route.id,\n });\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: finalError.code,\n message: finalError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw finalError;\n }\n\n failedRoute = route;\n allowedFallbacks = actions;\n break;\n }\n }\n }\n\n const finalError = new AiConnectError(\"temporary_unavailable\", \"No eligible fallback routes remained after route failures.\", { attempts });\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: finalError.code,\n message: finalError.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw finalError;\n }\n\n async function executeModelDiscoveryOperation(\n target:\n | {\n routes?: string[];\n logContext?: Record<string, unknown>;\n transports?: TransportKind[];\n }\n | undefined,\n options: {\n operationName: \"discoverModels\" | \"discoverAcpModels\";\n acpOnly?: boolean;\n abort: AbortContext;\n },\n ): Promise<AcpModelDiscoveryReport> {\n const startedAt = nowMs(runtime);\n const abort = options.abort;\n const targetIds = target?.routes?.length ? new Set(resolveRouteSelectors(target.routes, config.routes)) : undefined;\n const transportFilter = target?.transports && target.transports.length > 0 ? new Set(target.transports) : undefined;\n const reports: AcpModelDiscoveryRouteReport[] = [];\n const wideAttempts: WideEventAttempt[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n\n if (options.acpOnly && route.transport.kind !== \"acp\") {\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: \"not_supported\",\n message: `Route \"${route.id}\" is not an ACP route.`,\n },\n });\n continue;\n }\n\n const routeSummary = summarizeRoute(route);\n const handler = resolveHandler(route, handlers);\n if (!handler?.discoverModels) {\n const message = options.acpOnly\n ? `No ACP model discovery handler is registered for ${route.handlerKey}.`\n : `No model discovery handler is registered for ${route.handlerKey}.`;\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: \"not_supported\",\n message,\n },\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: 0,\n outcome: \"error\",\n retryCount: 0,\n errorCode: \"not_supported\",\n message,\n });\n continue;\n }\n\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const attemptStartedAt = nowMs(runtime);\n let transportSummary: WideEventTransportSummary | undefined;\n\n try {\n const catalog = await handler.discoverModels({\n route,\n runtime,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n });\n\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: true,\n ...(catalog.requestedModelId ? { requestedModelId: catalog.requestedModelId } : {}),\n ...(catalog.requestedModelAdvertised !== undefined ? { requestedModelAdvertised: catalog.requestedModelAdvertised } : {}),\n ...(catalog.canonicalModelId ? { canonicalModelId: catalog.canonicalModelId } : {}),\n ...(catalog.resolvedModelId ? { resolvedModelId: catalog.resolvedModelId } : {}),\n ...(catalog.currentModelId ? { currentModelId: catalog.currentModelId } : {}),\n availableModels: catalog.availableModels,\n ...(catalog.warnings?.length ? { warnings: catalog.warnings } : {}),\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n } catch (error) {\n // A caller abort / fired timeout terminates the whole probe-tier sweep (it is\n // hard-terminal, never per-route health) \u2014 surface the canonical reason.\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalizedError = toAiConnectError(error);\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: normalizedError.code,\n message: normalizedError.message,\n },\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount: 0,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n }\n }\n\n const report = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n const candidates = config.routes\n .filter((route) => {\n if (targetIds && !targetIds.has(route.id)) {\n return false;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n return false;\n }\n return true;\n })\n .map(summarizeRoute);\n const discoverySummary = summarizeAcpModelDiscovery(report, targetIds);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: options.operationName,\n operation: \"discover_models\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n modelDiscovery: discoverySummary,\n ...(options.acpOnly ? { acpModelDiscovery: discoverySummary } : {}),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n }\n\n // \u2500\u2500 C8 \u2014 live health-check + model probe (UR-008 / INV-PROBE-1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // READ-ONLY re router health: NEITHER checkHealth NOR probeModels (NOR their helpers below)\n // ever calls `router.recordFailure`/`router.recordSuccess`. A probe is diagnostic, not a live\n // request \u2014 letting it mutate route-health would let a cheap liveness ping cool down a route\n // (R16-adjacent). The only router call here is the READ-ONLY `router.getHealth(...)` used for\n // candidate selection / projection elsewhere. (INV-PROBE-1; enforced by discipline + DST #52.)\n\n /**\n * Await `handler.generate` BUT lose the race to a derived-abort: if `abort.signal` fires (caller\n * cancel mid-fan-out OR the per-probe timeout) before the handler settles, this rejects with the\n * canonical abort/timeout error EVEN IF the handler never resolves (DST #50 \u2014 a hung tuple yields\n * a timeout while siblings complete). The handler is also passed `abort` so a compliant handler\n * can cancel its own fetch; the race guarantees liveness regardless.\n */\n async function runPingWithAbort(\n route: NormalizedRoute,\n handler: NonNullable<RouteHandler[\"generate\"]>,\n abort: AbortContext,\n ): Promise<RouteHandlerGenerateResult> {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const handlerPromise = handler({\n route,\n request: buildPingRequest(),\n runtime,\n attempt: 1,\n abort,\n });\n let onAbort: (() => void) | undefined;\n const abortPromise = new Promise<never>((_, reject) => {\n onAbort = () => reject(mapAbortError(abort.reason));\n abort.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n return await Promise.race([handlerPromise, abortPromise]);\n } finally {\n if (onAbort) {\n abort.signal.removeEventListener(\"abort\", onAbort);\n }\n // Swallow a late handler rejection so an aborted/timed-out probe never surfaces an unhandled\n // rejection after we have already resolved the race (DST #49/#50).\n void Promise.resolve(handlerPromise).catch(() => {});\n }\n }\n\n /**\n * Stage-1 reachability probe. For api routes this is the GET /models discovery (`discoverModels`);\n * for acp/cli/server it is the session/availability `verify`. Returns a {@link HealthStageResult}\n * \u2014 `ok=false` carries the normalized error code + (CD-7) httpStatus when available. READ-ONLY.\n */\n async function checkEndpointReachable(\n route: NormalizedRoute,\n handler: RouteHandler | undefined,\n abort: AbortContext,\n ): Promise<HealthStageResult> {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n if (!handler) {\n return {\n ok: false,\n detail: `No handler is registered for ${route.handlerKey}.`,\n code: \"not_supported\",\n };\n }\n\n try {\n if (route.transport.kind === \"api\" && handler.discoverModels) {\n await handler.discoverModels({ route, runtime, abort });\n return { ok: true, detail: \"reachable\" };\n }\n if (handler.verify) {\n const issues = await handler.verify({ route, runtime });\n if (issues.length === 0) {\n return { ok: true, detail: \"reachable\" };\n }\n return {\n ok: false,\n detail: issues.map((issue) => issue.message).join(\"; \"),\n code: \"local_harness_unavailable\",\n };\n }\n // No reachability primitive available \u2014 treat as a soft pass so Stage-2 can still attempt.\n return { ok: true, detail: \"reachability check not supported; assuming reachable\" };\n } catch (error) {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalized = toAiConnectError(error);\n const httpStatus = normalized.details?.[\"httpStatus\"];\n return {\n ok: false,\n detail: normalized.message,\n code: normalized.code,\n ...(typeof httpStatus === \"number\" ? { httpStatus } : {}),\n };\n }\n }\n\n /**\n * Stage-2 minimal chat ping. Issues a max-1-token ping via `handler.generate` and classifies the\n * outcome with `classifyProbeOutcome` (empty response \u21D2 model fail). Captures `latencyMs` off the\n * injected clock (fake-clock deterministic). READ-ONLY re router health.\n */\n async function pingModel(\n route: NormalizedRoute,\n handler: RouteHandler | undefined,\n abort: AbortContext,\n ): Promise<HealthModelStageResult> {\n if (!handler?.generate) {\n return {\n ok: false,\n detail: `No generate handler is registered for ${route.handlerKey}.`,\n code: \"not_supported\",\n };\n }\n const startedAt = nowMs(runtime);\n try {\n const output = await runPingWithAbort(route, handler.generate, abort);\n const classification = classifyProbeOutcome({\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n });\n return {\n ok: classification.ok,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - startedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n };\n } catch (error) {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalized = toAiConnectError(error);\n const classification = classifyProbeOutcome({ error: normalized });\n return {\n ok: classification.ok,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - startedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n };\n }\n }\n\n async function executeCheckHealth(target?: CheckHealthTarget): Promise<HealthReport> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length\n ? new Set(resolveRouteSelectors(target.routes, config.routes))\n : undefined;\n const transportFilter =\n target?.transports && target.transports.length > 0\n ? new Set(target.transports)\n : undefined;\n const reachabilityOnly = target?.reachabilityOnly === true;\n const { abort, dispose: disposeAbort } = deriveAbort(\n target?.signal ? { signal: target.signal } : undefined,\n resolveOpTimeout(target, \"probeMs\", options.timeouts),\n runtime,\n );\n\n try {\n const reports: RouteHealthReport[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const handler = resolveHandler(route, handlers);\n const endpoint = await checkEndpointReachable(route, handler, abort);\n\n let model: HealthModelStageResult;\n if (!endpoint.ok) {\n // Stage-1 short-circuit (DST #51): never invoke handler.generate when unreachable.\n model = { ok: false, detail: \"skipped: endpoint unreachable\" };\n } else if (reachabilityOnly) {\n model = { ok: true, detail: \"skipped: reachabilityOnly\" };\n } else {\n model = await pingModel(route, handler, abort);\n }\n\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n modelId: route.model,\n ok: endpoint.ok && model.ok,\n endpoint,\n model,\n });\n }\n\n const report: HealthReport = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"checkHealth\",\n operation: \"check_health\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: config.routes\n .filter((route) => {\n if (targetIds && !targetIds.has(route.id)) {\n return false;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n return false;\n }\n return true;\n })\n .map(summarizeRoute),\n attempts: [],\n health: summarizeHealth(report, reachabilityOnly, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n } finally {\n disposeAbort();\n }\n }\n\n /**\n * Shared engine for `probeModels` / `probeModelsStream`. Yields each {@link ProbeModelResult} as\n * it settles (the streaming surface) while the array form simply drains the generator. Uses a\n * per-(route::sorted-models) TTL cache, bounded concurrency, a per-probe timeout via the\n * `deriveAbort` seam, and honors the fan-out-level `opts.signal` mid-flight. READ-ONLY re router.\n */\n async function* runProbeModels(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): AsyncGenerator<ProbeModelResult, void, void> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length\n ? new Set(resolveRouteSelectors(target.routes, config.routes))\n : undefined;\n const transportFilter =\n target?.transports && target.transports.length > 0\n ? new Set(target.transports)\n : undefined;\n const modelFilter =\n target?.models && target.models.length > 0\n ? new Set(target.models)\n : undefined;\n const concurrency =\n opts?.concurrency && opts.concurrency > 0\n ? opts.concurrency\n : PROBE_DEFAULT_CONCURRENCY;\n const perProbeTimeoutMs =\n opts?.timeoutMs !== undefined ? opts.timeoutMs : PROBE_DEFAULT_TIMEOUT_MS;\n const ttlMs =\n opts?.cacheTtlMs !== undefined ? opts.cacheTtlMs : PROBE_DEFAULT_TTL_MS;\n const fanoutSignal = opts?.signal;\n\n // The route::model tuples to probe (the route advertises its own models; `modelFilter` narrows).\n const tuples: { route: NormalizedRoute; modelId: string }[] = [];\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n const models = route.advertisedModels.length\n ? route.advertisedModels\n : [route.model];\n for (const modelId of models) {\n if (modelFilter && !modelFilter.has(modelId)) {\n continue;\n }\n tuples.push({ route, modelId });\n }\n }\n\n // TTL cache is keyed per-route over its (sorted) probed model set (#47). Group tuples by route\n // so a route's whole probe set shares one cache entry.\n const byRoute = new Map<string, { route: NormalizedRoute; models: string[] }>();\n for (const tuple of tuples) {\n const existing = byRoute.get(tuple.route.id);\n if (existing) {\n existing.models.push(tuple.modelId);\n } else {\n byRoute.set(tuple.route.id, { route: tuple.route, models: [tuple.modelId] });\n }\n }\n\n const emitted: ProbeModelResult[] = [];\n const cachedRouteResults = new Map<string, ProbeModelResult[]>();\n const liveGroups: { route: NormalizedRoute; models: string[] }[] = [];\n\n for (const group of byRoute.values()) {\n const key = probeCacheKey(group.route.id, group.models);\n if (!opts?.forceRefresh) {\n const hit = readProbeCache(probeCache, key, nowMs(runtime));\n if (hit) {\n cachedRouteResults.set(group.route.id, hit);\n continue;\n }\n }\n liveGroups.push(group);\n }\n\n // Pre-abort short-circuit (DST #49): a pre-aborted fan-out signal does zero handler work.\n if (fanoutSignal?.aborted) {\n throw mapAbortError(\"caller\");\n }\n\n // Flatten live tuples for bounded fan-out; cached tuples are emitted without any handler call.\n const liveTuples: { route: NormalizedRoute; modelId: string }[] = [];\n for (const group of liveGroups) {\n for (const modelId of group.models) {\n liveTuples.push({ route: group.route, modelId });\n }\n }\n\n const liveResults = await runBounded(\n liveTuples,\n concurrency,\n async (tuple): Promise<ProbeModelResult> => {\n // A fan-out abort that already fired means later tuples must not start (#49).\n if (fanoutSignal?.aborted) {\n throw mapAbortError(\"caller\");\n }\n // Per-probe derived abort: fan-out signal \u2295 this probe's own timeout, scheduled on the\n // `runtime.setTimer` seam so a fake clock fires it (#50). NO probe-local withTimeout (CD-4).\n const { abort, dispose: disposeAbort } = deriveAbort(\n {\n ...(fanoutSignal ? { signal: fanoutSignal } : {}),\n ...(perProbeTimeoutMs !== undefined ? { timeoutMs: perProbeTimeoutMs } : {}),\n },\n resolveOpTimeout({ timeoutMs: perProbeTimeoutMs }, \"probeMs\", options.timeouts),\n runtime,\n );\n const probeStartedAt = nowMs(runtime);\n const handler = resolveHandler(tuple.route, handlers);\n const probeRoute: NormalizedRoute = { ...tuple.route, model: tuple.modelId };\n try {\n if (!handler?.generate) {\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: false,\n broken: false,\n detail: `No generate handler is registered for ${tuple.route.handlerKey}.`,\n code: \"not_supported\",\n cached: false,\n };\n }\n const output = await runPingWithAbort(probeRoute, handler.generate, abort);\n const classification = classifyProbeOutcome({\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n });\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: classification.ok,\n broken: classification.broken,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - probeStartedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n cached: false,\n };\n } catch (error) {\n const normalized = toAiConnectError(error);\n // A per-probe timeout/abort: ok=false, broken=false (transient), detail ~ timeout (#50).\n if (\n normalized.code === \"timeout\" ||\n normalized.code === \"aborted\"\n ) {\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: false,\n broken: false,\n detail:\n normalized.code === \"timeout\"\n ? `probe timed out after ${perProbeTimeoutMs}ms`\n : normalized.message,\n latencyMs: nowMs(runtime) - probeStartedAt,\n code: normalized.code,\n cached: false,\n };\n }\n const classification = classifyProbeOutcome({ error: normalized });\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: classification.ok,\n broken: classification.broken,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - probeStartedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n cached: false,\n };\n } finally {\n disposeAbort();\n }\n },\n );\n\n // Write fresh per-route results back to the TTL cache, then assemble final emission order:\n // iterate the original `byRoute` order, emitting cached hits verbatim and fresh results once.\n const liveByRoute = new Map<string, ProbeModelResult[]>();\n for (const result of liveResults) {\n const bucket = liveByRoute.get(result.routeId);\n if (bucket) {\n bucket.push(result);\n } else {\n liveByRoute.set(result.routeId, [result]);\n }\n }\n for (const group of liveGroups) {\n const results = liveByRoute.get(group.route.id) ?? [];\n writeProbeCache(\n probeCache,\n probeCacheKey(group.route.id, group.models),\n results,\n nowMs(runtime),\n ttlMs,\n );\n }\n\n for (const group of byRoute.values()) {\n const cached = cachedRouteResults.get(group.route.id);\n const results = cached ?? liveByRoute.get(group.route.id) ?? [];\n for (const result of results) {\n emitted.push(result);\n yield result;\n }\n }\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"probeModels\",\n operation: \"probe_models\",\n runtime: runtime.kind,\n outcome: emitted.every((result) => result.ok) ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: liveGroups.map((group) => summarizeRoute(group.route)),\n attempts: [],\n probe: summarizeProbe(emitted, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n }\n\n return {\n config,\n runtime,\n listRoutes(filter): ListedRoute[] {\n return router.listRoutes(filter).map((route) => ({\n ...route,\n health: router.getHealth(route),\n }));\n },\n listPublicRoutes(filter): PublicRoute[] {\n // C7 / INV-PROJ-1: project each route through the explicit secret-free `toPublicRoute`.\n // `operation` reuses the existing router pool filter; `provider` narrows further. The\n // projection is stable under health changes \u2014 only the `health` field tracks live state.\n const operationFilter: { operation?: OperationKind } | undefined =\n filter?.operation ? { operation: filter.operation } : undefined;\n return router\n .listRoutes(operationFilter)\n .filter((route) =>\n filter?.provider ? route.provider === filter.provider : true,\n )\n .map((route) => toPublicRoute(route, router.getHealth(route).state));\n },\n listCandidateModels(filter): CandidateModel[] {\n // C9 / UR-014: the same secret-free candidate projection offered to a ModelSelector.\n return router.candidateModels(filter);\n },\n prepareFile(input) {\n return preparePortableFile(input);\n },\n resolveModelContext(\n input: ResolveModelContextInput,\n options?: ResolveModelContextOptions,\n ): ModelContextResolution {\n const { key, model } = modelContextCacheKey(input);\n const cached = modelContextCache.get(key);\n if (cached) {\n return { ...cached, cached: true };\n }\n const reference = lookupModelRef(model)?.contextLength;\n const { contextWindow, source } = resolveModelContextWindow({\n ...(options?.discovered !== undefined\n ? { discovered: options.discovered }\n : {}),\n ...(reference !== undefined ? { reference } : {}),\n ...(options?.configured !== undefined\n ? { configured: options.configured }\n : {}),\n ...(options?.defaultContextWindow !== undefined\n ? { defaultContextWindow: options.defaultContextWindow }\n : {}),\n });\n const result: ModelContextResolution = {\n contextWindow,\n source,\n model,\n cached: false,\n };\n modelContextCache.set(key, result);\n return result;\n },\n async verify(target, opts): Promise<VerificationReport> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length ? new Set(resolveRouteSelectors(target.routes, config.routes)) : undefined;\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n\n try {\n const reports: VerificationRouteReport[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const issues: VerificationIssue[] = [];\n\n if (runtime.kind === \"browser\") {\n const issue = runtimeIssue(route);\n if (issue) {\n issues.push(issue);\n }\n }\n\n for (const envName of route.verify.env) {\n const value = runtime.getEnv?.(envName);\n if (!value) {\n issues.push({\n code: \"missing_env\",\n message: `Missing required environment variable \"${envName}\" for route \"${route.id}\".`,\n });\n }\n }\n\n if (route.verify.command) {\n const hasCommand = await runtime.hasCommand?.(route.verify.command);\n if (!hasCommand) {\n issues.push({\n code: \"missing_command\",\n message: `Required command \"${route.verify.command}\" is unavailable for route \"${route.id}\".`,\n });\n }\n }\n\n if (route.verify.session && route.transport.kind === \"acp\") {\n const sessionValue = runtime.getEnv?.(route.verify.session);\n if (!sessionValue) {\n issues.push({\n code: \"missing_session\",\n message: `Missing required local session reference \"${route.verify.session}\" for route \"${route.id}\".`,\n });\n }\n }\n\n const handler = resolveHandler(route, handlers);\n if (!handler) {\n issues.push({\n code: \"handler_issue\",\n message: `No handler is registered for ${route.handlerKey}.`,\n });\n }\n const handlerIssues = await handler?.verify?.({\n route,\n runtime,\n });\n if (handlerIssues?.length) {\n issues.push(...handlerIssues);\n }\n\n reports.push({\n routeId: route.id,\n ok: issues.length === 0,\n issues,\n });\n }\n\n const report = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"verify\",\n operation: \"verify\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: config.routes.map(summarizeRoute),\n attempts: [],\n verification: summarizeVerification(report, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n } finally {\n disposeAbort();\n }\n },\n async discoverModels(target?: DiscoverModelsTarget, opts?): Promise<AcpModelDiscoveryReport> {\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n try {\n return await executeModelDiscoveryOperation(target, {\n operationName: \"discoverModels\",\n abort,\n });\n } finally {\n disposeAbort();\n }\n },\n async discoverAcpModels(target?: DiscoverAcpModelsTarget, opts?): Promise<AcpModelDiscoveryReport> {\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n try {\n return await executeModelDiscoveryOperation(target, {\n operationName: \"discoverAcpModels\",\n acpOnly: true,\n abort,\n });\n } finally {\n disposeAbort();\n }\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1): checkHealth NEVER calls\n // router.recordFailure/recordSuccess; a diagnostic ping must not cool down a route.\n async checkHealth(target?: CheckHealthTarget): Promise<HealthReport> {\n return executeCheckHealth(target);\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1): probeModels NEVER calls\n // router.recordFailure/recordSuccess.\n async probeModels(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): Promise<ProbeModelResult[]> {\n const results: ProbeModelResult[] = [];\n for await (const result of runProbeModels(target, opts)) {\n results.push(result);\n }\n return results;\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1).\n probeModelsStream(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): AsyncIterable<ProbeModelResult> {\n return runProbeModels(target, opts);\n },\n async generate(request, opts): Promise<GenerateResult> {\n // pauseAsAbort: a non-streamed call cannot retain a partial, so a mid-call pause\n // degenerates to a caller abort (CD-3 / pause-degenerates-on-generate).\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"generateMs\", options.timeouts),\n runtime,\n { pauseAsAbort: true },\n );\n // C9 / R16: acquire a fan-out slot BEFORE any route/selector/health work, so a maxCalls\n // exhaustion raises `fanout_limit` ahead of route selection and never becomes route-health\n // (INV-FANOUT-1). Released in the finally regardless of outcome (never mutates the client\n // limiter for a per-request override \u2014 limiterForRequest returns a request-scoped instance).\n const limiter = limiterForRequest(request);\n // R16 leak-safety: `deriveAbort` ABOVE already registered a caller-signal\n // listener + scheduled the timeout timer, so `disposeAbort()` MUST run even\n // when `limiter.acquire()` rejects (fanout_limit / pre-aborted signal /\n // abort-while-parked). Hence acquire is INSIDE the try and `release` is\n // guarded in the finally \u2014 otherwise the listener+timer leak per call on a\n // reused caller signal.\n let release: (() => void) | undefined;\n try {\n release = await limiter.acquire(abort.signal);\n const normalizedRequest = prepareRequest(request);\n const selectedModel = await resolveSelectedModel(normalizedRequest);\n return await executeGenerateOperation(\n withSelectedModel(normalizedRequest, selectedModel),\n \"generate\",\n abort,\n );\n } finally {\n release?.();\n disposeAbort();\n }\n },\n async *stream(request, opts): AsyncIterable<GenerateStreamEvent> {\n const preparedRequest = prepareRequest(request);\n if (preparedRequest.clientTools?.length) {\n throw new AiConnectError(\n \"not_supported\",\n \"clientTools are currently supported only by generate(), not stream().\",\n );\n }\n // stream() keeps pause SEPARATE from abort: caller/timeout abort discards partials and\n // throws; a pauseSignal stops reading and yields a terminal {type:'paused'} KEEPING the\n // accumulated partial (INV-ABORT-3). So deriveAbort is built WITHOUT pauseAsAbort.\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"generateMs\", options.timeouts),\n runtime,\n );\n const pauseSignal = abort.pauseSignal;\n // C9 / R16: acquire a fan-out slot BEFORE route selection (so fanout_limit precedes any\n // route-health work); R15: a per-request override uses a request-scoped limiter.\n const limiter = limiterForRequest(request);\n // R16 leak-safety (mirrors generate()): acquire INSIDE the try so a rejected\n // `limiter.acquire()` (fanout_limit / pre-aborted signal / abort-while-parked)\n // still reaches `disposeAbort()` in the finally and never leaks the\n // caller-signal listener + timeout timer that `deriveAbort` registered above.\n let release: (() => void) | undefined;\n let released = false;\n const releaseOnce = (): void => {\n if (!released && release) {\n released = true;\n release();\n }\n };\n try {\n release = await limiter.acquire(abort.signal);\n // C9 / OQ-11: apply the ModelSelector (explicit routeHints.model still wins) BEFORE routing.\n const selectedModel = await resolveSelectedModel(preparedRequest);\n const normalizedRequest = withSelectedModel(preparedRequest, selectedModel);\n const requiresSchema = requiresToolSchema(normalizedRequest);\n const candidates = router.resolveCandidates(\n requiresSchema\n ? {\n ...normalizedRequest,\n routeHints: {\n ...(normalizedRequest.routeHints ?? {}),\n requiredCapabilities: {\n ...(normalizedRequest.routeHints?.requiredCapabilities ?? {}),\n supportsToolSchema: true,\n },\n },\n }\n : normalizedRequest,\n );\n const startedAt = nowMs(runtime);\n const requestId = resolveEventRequestId(normalizedRequest.logContext);\n const candidateSummaries = candidates.map(summarizeRoute);\n const requestSummary = summarizeRequest(normalizedRequest, candidateSummaries);\n const attempts: RouteAttempt[] = [];\n const wideAttempts: WideEventAttempt[] = [];\n\n if (candidates.length === 0) {\n const error = new AiConnectError(\"not_supported\", `No eligible routes are available for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: error.code,\n message: error.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw error;\n }\n\n for (const route of candidates) {\n const handler = resolveHandler(route, handlers);\n if (!handler) {\n continue;\n }\n\n if (handler.stream) {\n const routeSummary = summarizeRoute(route);\n const attemptStartedAt = nowMs(runtime);\n let lastResult: GenerateResult | undefined;\n // Accumulate the partial so a pause can yield a terminal {type:'paused'} carrying\n // everything received so far, even if the producer only emitted deltas.\n let accumulatedText = \"\";\n\n // C7 / R14: inject this route's explicit per-route defaults before streaming.\n const routeRequest = applyRouteDefaults(route, normalizedRequest);\n\n const iterable = handler.stream({\n route,\n request: routeRequest,\n runtime,\n attempt: 1,\n abort,\n });\n const iterator = iterable[Symbol.asyncIterator]();\n let iteratorReturned = false;\n const returnIterator = async (): Promise<void> => {\n if (iteratorReturned) {\n return;\n }\n iteratorReturned = true;\n try {\n await iterator.return?.();\n } catch {\n // A producer that throws on return() must not mask the abort/pause outcome.\n }\n };\n\n try {\n while (true) {\n // Caller/timeout abort: discard partials, throw, close the producer exactly once.\n if (abort.signal.aborted) {\n await returnIterator();\n throw mapAbortError(abort.reason);\n }\n // Pause: stop reading, keep the accumulated partial, emit ONE terminal\n // {type:'paused'} and return without throwing.\n if (pauseSignal?.aborted) {\n await returnIterator();\n const pausedResult: GenerateResult =\n lastResult ?? {\n route,\n text: accumulatedText,\n attachments: [],\n warnings: [],\n attempts,\n };\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n });\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n result: summarizeResult(pausedResult),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n yield { type: \"paused\", result: pausedResult };\n return;\n }\n\n const next = await iterator.next();\n if (next.done) {\n break;\n }\n const event = next.value;\n if (event.type === \"delta\") {\n accumulatedText += event.text;\n yield event;\n continue;\n }\n // A producer-emitted terminal (`result` | `paused`) ends this stream:\n // yield it ONCE, then break so the post-loop success path emits the\n // wide event exactly once. Continuing the loop here would let a\n // misbehaving producer emit a SECOND terminal (double-terminal).\n lastResult = event.result;\n yield event;\n break;\n }\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n });\n router.recordSuccess(route);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n ...(lastResult ? { result: summarizeResult(lastResult) } : {}),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n return;\n } catch (error) {\n await returnIterator();\n const normalizedError = abort.signal.aborted\n ? mapAbortError(abort.reason)\n : toAiConnectError(error);\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount: 0,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n // A caller/timeout abort is hard-terminal: it never rotates credentials or falls\n // back (R2). Surface it immediately rather than trying the next route.\n if (abort.signal.aborted) {\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: normalizedError.code,\n message: normalizedError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw normalizedError;\n }\n router.recordFailure(route, normalizedError.code);\n continue;\n }\n }\n\n if (handler.generate) {\n break;\n }\n }\n\n const result = await executeGenerateOperation(normalizedRequest, \"stream\", abort, {\n startMs: startedAt,\n requestId,\n candidates: candidateSummaries,\n attempts,\n wideAttempts,\n });\n yield {\n type: \"result\",\n result,\n };\n } finally {\n releaseOnce();\n disposeAbort();\n }\n },\n async dispose(): Promise<void> {\n await dispose();\n },\n };\n}\n", "import type {\n GenerateRequest,\n ImageSizePreset,\n MessageInput,\n PortableFile,\n} from \"./types.js\";\n\nexport const IMAGE_PROMPT_PROTOCOL = \"ai_connect_image_json_v1\";\nexport const DEFAULT_IMAGE_SIZE: ImageSizePreset = \"1024x1024\";\n\nexport const IMAGE_SIZE_PRESETS: Record<string, string> = {\n \"1024x1024\": \"Square (1:1) - general use\",\n \"1280x720\": \"Landscape (16:9) - presentations and video\",\n \"720x1280\": \"Portrait (9:16) - mobile and stories\",\n \"1216x896\": \"Wide (4:3) - documents and slides\",\n \"1200x1696\": \"A3 portrait print\",\n \"848x1200\": \"A4 portrait print\",\n \"600x848\": \"A5 portrait print\",\n \"424x600\": \"A6 portrait print\",\n \"597x822\": \"Mini card\",\n \"747x1122\": \"Bridge card\",\n \"822x1122\": \"Poker card\",\n \"897x1479\": \"Tarot card\",\n \"1122x1797\": \"Large card\",\n \"1536x1024\": \"Landscape high-detail\",\n \"1024x1536\": \"Portrait high-detail\",\n auto: \"Let the provider choose the canvas size\",\n};\n\nconst SYSTEM_TEMPLATE = {\n protocol: IMAGE_PROMPT_PROTOCOL,\n kind: \"system_preference\",\n generation_goal: \"image_generation\",\n policies: {\n render_only_user_content: true,\n do_not_render_structural_markers: true,\n treat_parenthetical_text_as_visual_hints: true,\n },\n};\n\nconst DEFAULT_VISUAL_RULES = [\n \"Render only semantic content, never structural labels.\",\n \"Treat parenthetical text as visual hint metadata.\",\n \"Use strong visual hierarchy and legible typography when text is required.\",\n];\n\nconst STRUCTURAL_MARKERS = new Set([\n \"\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\",\n \"\u043F\u043E\u0434\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\",\n \"\u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u044B\u0439 \u043E\u0431\u0440\u0430\u0437\",\n \"\u0431\u043B\u043E\u043A\",\n \"\u0441\u0435\u043A\u0446\u0438\u044F\",\n \"\u0440\u0430\u0437\u0434\u0435\u043B\",\n \"\u0444\u0443\u0442\u0435\u0440\",\n \"\u043F\u043E\u0434\u0432\u0430\u043B\",\n \"header\",\n \"title\",\n \"subtitle\",\n \"central image\",\n \"block\",\n \"section\",\n \"footer\",\n]);\n\nconst STRUCTURAL_PATTERNS = [\n /^\u0431\u043B\u043E\u043A\\s+\\d+:/i,\n /^\u0441\u0435\u043A\u0446\u0438\u044F\\s+\\d+:/i,\n /^\u0440\u0430\u0437\u0434\u0435\u043B\\s+\\d+:/i,\n /^block\\s+\\d+:/i,\n /^section\\s+\\d+:/i,\n];\n\nfunction tryParseJsonPayload(content: string): unknown | null {\n const stripped = content.trim();\n if (!stripped.startsWith(\"{\") && !stripped.startsWith(\"[\")) {\n return null;\n }\n\n try {\n return JSON.parse(stripped);\n } catch {\n return null;\n }\n}\n\nexport function normalizeImageSource(messages: MessageInput[]): string {\n return messages\n .map((message) => `${message.role.toUpperCase()}:\\n${message.content}`)\n .join(\"\\n\\n\");\n}\n\nexport function filterStructuralMarkers(content: string): {\n cleanContent: string;\n structure: Record<string, unknown>;\n hasStructure: boolean;\n} {\n const lines = content.split(\"\\n\");\n const cleanLines: string[] = [];\n const blocks: Array<{ name?: string; content: string[] }> = [];\n let currentBlock: { name?: string; content: string[] } | undefined;\n\n for (const originalLine of lines) {\n const trimmed = originalLine.trim();\n const lowered = trimmed.toLowerCase();\n\n if (trimmed.length === 0) {\n continue;\n }\n\n if (STRUCTURAL_MARKERS.has(lowered.replace(/:$/, \"\"))) {\n continue;\n }\n\n const matchedPattern = STRUCTURAL_PATTERNS.find((pattern) =>\n pattern.test(trimmed),\n );\n if (matchedPattern) {\n const [, blockName] = trimmed.split(\":\", 2);\n currentBlock = {\n ...(blockName?.trim() ? { name: blockName.trim() } : {}),\n content: [],\n };\n blocks.push(currentBlock);\n if (blockName?.trim()) {\n cleanLines.push(blockName.trim());\n }\n continue;\n }\n\n const cleanedLine = originalLine.replace(\n /^(\u0431\u043B\u043E\u043A|block|\u0441\u0435\u043A\u0446\u0438\u044F|section|\u0440\u0430\u0437\u0434\u0435\u043B)\\s*\\d*:\\s*/i,\n \"\",\n ).trim();\n\n if (cleanedLine.length === 0) {\n continue;\n }\n\n cleanLines.push(cleanedLine);\n currentBlock?.content.push(cleanedLine);\n }\n\n return {\n cleanContent: cleanLines.join(\"\\n\"),\n structure: {\n blocks,\n },\n hasStructure: blocks.length > 0,\n };\n}\n\nexport function buildImageSystemPreferencePayload(input: {\n size: string;\n model: string;\n rawPrompt: boolean;\n aspectRatio?: string;\n quality?: string;\n imageSize?: string;\n style?: string;\n}): Record<string, unknown> {\n return {\n ...SYSTEM_TEMPLATE,\n runtime: {\n model: input.model,\n size: input.size,\n raw_prompt_mode: input.rawPrompt,\n ...(input.aspectRatio\n ? { requested_aspect_ratio: input.aspectRatio }\n : {}),\n ...(input.quality ? { requested_quality: input.quality } : {}),\n ...(input.imageSize ? { requested_image_size: input.imageSize } : {}),\n ...(input.style ? { requested_style: input.style } : {}),\n },\n };\n}\n\nexport function buildImageUserPromptPayload(input: {\n content: string;\n size: string;\n rawPrompt: boolean;\n referenceImages: PortableFile[];\n hasSourceImage: boolean;\n hasMask: boolean;\n}): Record<string, unknown> {\n const parsed = tryParseJsonPayload(input.content);\n if (parsed !== null) {\n return {\n protocol: IMAGE_PROMPT_PROTOCOL,\n input_format: \"json\",\n task: \"generate_image\",\n canvas: { size: input.size },\n source_prompt_json: parsed,\n raw_prompt_mode: input.rawPrompt,\n reference_images_present: input.referenceImages.length > 0,\n source_image_present: input.hasSourceImage,\n mask_present: input.hasMask,\n };\n }\n\n const filtered = filterStructuralMarkers(input.content);\n return {\n protocol: IMAGE_PROMPT_PROTOCOL,\n input_format: \"text\",\n task: \"generate_image\",\n canvas: { size: input.size },\n raw_prompt_mode: input.rawPrompt,\n reference_images_present: input.referenceImages.length > 0,\n source_image_present: input.hasSourceImage,\n mask_present: input.hasMask,\n visual_rules: DEFAULT_VISUAL_RULES,\n content: {\n original_text: input.content,\n normalized_text: filtered.cleanContent,\n has_structure: filtered.hasStructure,\n structure: filtered.structure,\n },\n };\n}\n\nexport function serializeImagePayload(\n payload: Record<string, unknown>,\n): string {\n return JSON.stringify(payload, ensure_ascii_false_replacer, 0);\n}\n\nfunction ensure_ascii_false_replacer(_key: string, value: unknown): unknown {\n return value;\n}\n\nexport function buildImagePromptBundle(input: {\n request: GenerateRequest;\n model: string;\n referenceImages: PortableFile[];\n}): {\n size: string;\n systemPreference: Record<string, unknown>;\n userPrompt: Record<string, unknown>;\n prompt: string;\n} {\n const size =\n input.request.image?.size ??\n input.request.image?.aspectRatio ??\n DEFAULT_IMAGE_SIZE;\n const rawPrompt = input.request.image?.rawPrompt ?? false;\n const content = normalizeImageSource(input.request.messages);\n const systemPreference = buildImageSystemPreferencePayload({\n size,\n model: input.model,\n rawPrompt,\n ...(input.request.image?.aspectRatio\n ? { aspectRatio: input.request.image.aspectRatio }\n : {}),\n ...(input.request.image?.quality\n ? { quality: input.request.image.quality }\n : {}),\n ...(input.request.image?.imageSize\n ? { imageSize: input.request.image.imageSize }\n : {}),\n ...(input.request.image?.style ? { style: input.request.image.style } : {}),\n });\n const userPrompt = buildImageUserPromptPayload({\n content,\n size,\n rawPrompt,\n referenceImages: input.referenceImages,\n hasSourceImage: Boolean(input.request.image?.sourceImage),\n hasMask: Boolean(input.request.image?.mask),\n });\n\n return {\n size,\n systemPreference,\n userPrompt,\n prompt: JSON.stringify(\n {\n system_preference: systemPreference,\n user_prompt: userPrompt,\n },\n null,\n 0,\n ),\n };\n}\n\nfunction toPlainData(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => toPlainData(item));\n }\n\n if (typeof value === \"object\") {\n const modelDump = (value as { model_dump?: () => unknown }).model_dump;\n if (typeof modelDump === \"function\") {\n return toPlainData(modelDump());\n }\n\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n toPlainData(entry),\n ]),\n );\n }\n\n return String(value);\n}\n\nfunction normalizeImagePayloadString(payload: string): string {\n if (payload.startsWith(\"data:image/\")) {\n return payload;\n }\n\n return `data:image/png;base64,${payload}`;\n}\n\nfunction collectImagePayloads(node: unknown, out: string[]): void {\n const plain = toPlainData(node);\n\n if (Array.isArray(plain)) {\n for (const item of plain) {\n collectImagePayloads(item, out);\n }\n return;\n }\n\n if (plain && typeof plain === \"object\") {\n for (const [key, value] of Object.entries(plain as Record<string, unknown>)) {\n const lowerKey = key.toLowerCase();\n if (typeof value === \"string\") {\n if (value.startsWith(\"data:image/\")) {\n out.push(value);\n } else if (\n lowerKey === \"b64_json\" ||\n lowerKey === \"base64\" ||\n lowerKey === \"image_base64\"\n ) {\n out.push(normalizeImagePayloadString(value));\n } else if (lowerKey === \"url\" && value.startsWith(\"http\")) {\n out.push(value);\n }\n }\n\n collectImagePayloads(value, out);\n }\n }\n}\n\nexport function extractImagePayloads(...nodes: unknown[]): string[] {\n const items: string[] = [];\n for (const node of nodes) {\n collectImagePayloads(node, items);\n }\n\n return [...new Set(items)];\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport {\n inferPortableFileMimeType,\n isPortableDocumentFile,\n isPortableImageFile,\n materializePortableFile,\n portableFileRemoteUri,\n portableFileToBytes,\n portableFileToDataUrl,\n portableFileToText,\n preparePortableFile,\n} from \"./files.js\";\nimport {\n buildImagePromptBundle,\n extractImagePayloads,\n} from \"./image.js\";\nimport {\n detectModelFree,\n extractModelContextLength,\n fillConfiguredContextLength,\n parseModelPricing,\n} from \"./model-reference.js\";\nimport type {\n AcpModelCatalog,\n AcpModelInfo,\n CreateClientOptions,\n DiscoverAcpModelsContext,\n FetchLike,\n GenerateParameters,\n GenerateResponseFormat,\n GenerateContext,\n GenerateResult,\n GenerateStreamEvent,\n GenerateThinkingOptions,\n GenerateToolChoice,\n GenerateToolDefinition,\n MessageInput,\n NormalizedRoute,\n PortableFile,\n PortableFilePayload,\n RouteHandlerRegistry,\n RuntimeEnvironment,\n ToolCallInput,\n WideEventParameterSummary,\n WideEventTransportSummary,\n} from \"./types.js\";\n\nconst INLINE_ATTACHMENT_TEXT_LIMIT = 16_000;\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction appendPath(baseUrl: string, suffix: string): string {\n return `${trimTrailingSlash(baseUrl)}/${suffix.replace(/^\\/+/, \"\")}`;\n}\n\nfunction resolveOpenAiEndpoint(\n route: NormalizedRoute,\n operation: \"text\" | \"image\",\n): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return operation === \"image\"\n ? \"https://api.openai.com/v1/images/generations\"\n : \"https://api.openai.com/v1/chat/completions\";\n }\n\n if (\n configured.endsWith(\"/chat/completions\") ||\n configured.endsWith(\"/images/generations\")\n ) {\n return configured;\n }\n\n return appendPath(\n configured,\n operation === \"image\" ? \"/images/generations\" : \"/chat/completions\",\n );\n}\n\nfunction resolveOpenAiImageEditEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.openai.com/v1/images/edits\";\n }\n\n if (configured.endsWith(\"/images/edits\")) {\n return configured;\n }\n if (configured.endsWith(\"/images/generations\")) {\n return `${configured.slice(0, -\"/images/generations\".length)}/images/edits`;\n }\n\n return appendPath(configured, \"/images/edits\");\n}\n\nfunction resolveOpenAiModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.openai.com/v1/models\";\n }\n\n if (configured.endsWith(\"/models\")) {\n return configured;\n }\n if (configured.endsWith(\"/chat/completions\")) {\n return `${configured.slice(0, -\"/chat/completions\".length)}/models`;\n }\n if (configured.endsWith(\"/images/generations\")) {\n return `${configured.slice(0, -\"/images/generations\".length)}/models`;\n }\n\n return appendPath(configured, \"/models\");\n}\n\nfunction resolveAnthropicEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.anthropic.com/v1/messages\";\n }\n\n if (configured.endsWith(\"/messages\")) {\n return configured;\n }\n\n return appendPath(configured, \"/messages\");\n}\n\nfunction resolveAnthropicModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.anthropic.com/v1/models\";\n }\n\n if (configured.endsWith(\"/models\")) {\n return configured;\n }\n if (configured.endsWith(\"/messages\")) {\n return `${configured.slice(0, -\"/messages\".length)}/models`;\n }\n\n return appendPath(configured, \"/models\");\n}\n\n/**\n * Header used to authenticate Gemini REST calls WITHOUT placing the API key in\n * the URL (SEC: Gemini key leak). The endpoint string flows unredacted into the\n * wide-event `transportSummary.endpoint`; carrying the key in the URL `?key=`\n * query param would emit it to the logger. The `x-goog-api-key` request header\n * is the Google-supported alternative that keeps the secret out of telemetry.\n */\nconst GEMINI_API_KEY_HEADER = \"x-goog-api-key\";\n\n/**\n * Build the `x-goog-api-key` header bag for Gemini REST transports. The key is\n * delivered out-of-band of the URL so it never reaches the wide-event endpoint.\n */\nfunction geminiApiKeyHeaders(apiKey: string): Record<string, string> {\n return { [GEMINI_API_KEY_HEADER]: apiKey };\n}\n\nfunction resolveGeminiTextEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return `https://generativelanguage.googleapis.com/v1beta/models/${route.model}:generateContent`;\n }\n\n if (configured.includes(\"{model}\")) {\n return configured.replaceAll(\"{model}\", route.model);\n }\n if (!configured.endsWith(\":generateContent\")) {\n return appendPath(configured, `${route.model}:generateContent`);\n }\n\n return configured;\n}\n\nfunction resolveGeminiModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/models\";\n }\n\n let url = trimTrailingSlash(configured);\n const modelPlaceholderIndex = url.indexOf(\"{model}\");\n if (modelPlaceholderIndex >= 0) {\n url = trimTrailingSlash(url.slice(0, modelPlaceholderIndex));\n } else if (url.endsWith(\":generateContent\")) {\n url = url.replace(/\\/[^/?#]+:generateContent$/, \"\");\n }\n\n return url.endsWith(\"/models\") ? url : appendPath(url, \"/models\");\n}\n\nfunction resolveGeminiImageEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/openai/images/generations\";\n }\n\n if (configured.endsWith(\"/openai/images/generations\")) {\n return configured;\n }\n\n const normalized = trimTrailingSlash(configured);\n if (normalized.endsWith(\"/v1beta/models\")) {\n return `${normalized.slice(0, -\"/v1beta/models\".length)}/v1/images/generations`;\n }\n if (normalized.endsWith(\"/models\")) {\n return `${normalized.slice(0, -\"/models\".length)}/images/generations`;\n }\n\n return appendPath(normalized, \"/openai/images/generations\");\n}\n\nfunction resolveGeminiImageEditEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/openai/images/edits\";\n }\n\n if (configured.endsWith(\"/openai/images/edits\")) {\n return configured;\n }\n if (configured.endsWith(\"/openai/images/generations\")) {\n return `${configured.slice(0, -\"/openai/images/generations\".length)}/openai/images/edits`;\n }\n\n const normalized = trimTrailingSlash(configured);\n if (normalized.endsWith(\"/v1beta/models\")) {\n return `${normalized.slice(0, -\"/v1beta/models\".length)}/v1/images/edits`;\n }\n if (normalized.endsWith(\"/models\")) {\n return `${normalized.slice(0, -\"/models\".length)}/images/edits`;\n }\n\n return appendPath(normalized, \"/openai/images/edits\");\n}\n\nfunction getFetch(fetchImpl?: FetchLike): FetchLike {\n if (fetchImpl) {\n return fetchImpl;\n }\n\n if (typeof fetch === \"function\") {\n return fetch;\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No fetch implementation is available for API transports.\",\n );\n}\n\nfunction resolveApiKey(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n): string {\n if (route.credential.apiKey) {\n return route.credential.apiKey;\n }\n\n if (route.credential.apiKeyEnv) {\n const value = runtime.getEnv?.(route.credential.apiKeyEnv);\n if (value) {\n return value;\n }\n }\n\n throw new AiConnectError(\n \"auth_error\",\n `No API key is available for route \"${route.id}\".`,\n );\n}\n\nasync function readPayload(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n}\n\n/** Max levels of nested `.error` / `.message` unwrap (R20 / INV-ROBUST-1). */\nconst PAYLOAD_MESSAGE_MAX_DEPTH = 3;\n\n/**\n * Parse a message string ONE level deeper iff it is itself JSON encoding an\n * object that carries `error`/`message` (the \"double-JSON-decode\" of an error\n * string, R20). Primitives, arrays, and plain objects WITHOUT error/message are\n * left verbatim \u2014 the caller keeps the original string. Never throws.\n */\nfunction decodeErrorMessageString(value: string): unknown {\n const trimmed = value.trim();\n // Cheap pre-filter: only attempt JSON.parse on something object-shaped.\n if (!trimmed.startsWith(\"{\")) {\n return undefined;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n return undefined;\n }\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const record = parsed as Record<string, unknown>;\n if (\"error\" in record || \"message\" in record) {\n return parsed;\n }\n }\n return undefined;\n}\n\n/**\n * Depth-bounded (\u22643 levels), cycle-safe recursive unwrap of a provider error\n * payload to its most specific human-readable message (R20 / INV-ROBUST-1).\n *\n * - Strings are returned verbatim UNLESS they are themselves JSON carrying\n * `.error`/`.message`, in which case they are decoded ONCE (the single\n * double-JSON-decode) and the unwrap continues on the decoded object.\n * - Objects are unwrapped via `.message` then `.error` (string or nested\n * object), recursing with a decremented depth budget.\n * - Bounded by `depth` and a `seen` set, so cyclic / pathological inputs\n * terminate; never throws. Returns `undefined` so the caller can fall back\n * to the status-text message.\n */\nfunction unwrapPayloadMessage(\n value: unknown,\n depth: number,\n seen: Set<object>,\n decodeBudget: { value: number },\n): string | undefined {\n // A string is a terminal leaf \u2014 evaluable at ANY remaining depth (depth\n // counts OBJECT-nesting levels, not string leaves).\n if (typeof value === \"string\") {\n if (value.trim().length === 0) {\n return undefined;\n }\n // Single double-JSON-decode: if the string is itself JSON carrying\n // error/message, decode it ONCE (consuming the shared budget) and recurse\n // into the decoded object. The decode does not consume an object-depth\n // level; it is bounded independently by `decodeBudget`.\n if (decodeBudget.value > 0) {\n const decoded = decodeErrorMessageString(value);\n if (decoded !== undefined) {\n decodeBudget.value -= 1;\n const fromDecoded = unwrapPayloadMessage(\n decoded,\n depth,\n seen,\n decodeBudget,\n );\n if (fromDecoded !== undefined) {\n return fromDecoded;\n }\n }\n }\n return value;\n }\n\n // Object-nesting budget exhausted \u21D2 stop (status-text fallback).\n if (depth < 0) {\n return undefined;\n }\n\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n // Cycle guard: a value already on the current unwrap path is not revisited.\n if (seen.has(value as object)) {\n return undefined;\n }\n seen.add(value as object);\n\n const record = value as Record<string, unknown>;\n\n const directMessage = record.message;\n if (directMessage !== undefined) {\n const message = unwrapPayloadMessage(\n directMessage,\n depth - 1,\n seen,\n decodeBudget,\n );\n if (message !== undefined) {\n return message;\n }\n }\n\n const errorValue = record.error;\n if (errorValue !== undefined) {\n const message = unwrapPayloadMessage(\n errorValue,\n depth - 1,\n seen,\n decodeBudget,\n );\n if (message !== undefined) {\n return message;\n }\n }\n }\n\n return undefined;\n}\n\nfunction payloadMessage(payload: unknown): string | undefined {\n return unwrapPayloadMessage(payload, PAYLOAD_MESSAGE_MAX_DEPTH, new Set(), {\n value: 1,\n });\n}\n\nfunction classifyApiError(\n provider: string,\n response: Response,\n payload: unknown,\n): AiConnectError {\n const message =\n payloadMessage(payload) ??\n `${provider} API request failed with status ${response.status}.`;\n const normalized = message.toLowerCase();\n // CD-7: carry the raw HTTP status on EVERY constructed error so Health's `classifyProbeOutcome`\n // can derive `broken` (400\u2264s<500\u2227\u2260429). Harmless to other consumers \u2014 Robustness keys off the\n // message, never the status, so the two never conflict.\n const details = { httpStatus: response.status };\n\n if (response.status === 429) {\n if (normalized.includes(\"quota\")) {\n return new AiConnectError(\"quota_exhausted\", message, details);\n }\n return new AiConnectError(\"rate_limit\", message, details);\n }\n\n if (response.status === 401 || response.status === 403) {\n if (normalized.includes(\"quota\")) {\n return new AiConnectError(\"quota_exhausted\", message, details);\n }\n return new AiConnectError(\"auth_error\", message, details);\n }\n\n if (response.status === 404) {\n return new AiConnectError(\"not_supported\", message, details);\n }\n\n if (response.status >= 500) {\n return new AiConnectError(\"temporary_unavailable\", message, details);\n }\n\n return new AiConnectError(\"validation_error\", message, details);\n}\n\n/** Tokens that mark a 400 as a response_format / structured-output rejection. */\nconst RESPONSE_FORMAT_REJECTION_TOKENS = [\n \"response_format\",\n \"response format\",\n \"json_schema\",\n \"json schema\",\n \"schema\",\n \"strict\",\n] as const;\n\n/**\n * True ONLY when `response` is a 400 whose `message` references one of the\n * response_format / json_schema / schema / strict tokens (R21 / INV-ROBUST-1).\n *\n * R21 also requires the request to have actually carried `response_format`; the\n * caller (`runOpenAi`) enforces that precondition by only consulting this gate\n * when it added `response_format` to the request body \u2014 so this predicate is\n * narrow (400 + specific token) and never mis-fires on unrelated validation\n * errors that merely contain the generic word \"schema\" on a non-400 status.\n */\nfunction isResponseFormatRejection(\n response: Response,\n message: string,\n): boolean {\n if (response.status !== 400) {\n return false;\n }\n const normalized = message.toLowerCase();\n return RESPONSE_FORMAT_REJECTION_TOKENS.some((token) =>\n normalized.includes(token),\n );\n}\n\nfunction truncateInlineText(content: string): string {\n if (content.length <= INLINE_ATTACHMENT_TEXT_LIMIT) {\n return content;\n }\n\n return `${content.slice(0, INLINE_ATTACHMENT_TEXT_LIMIT)}\\n...[truncated]`;\n}\n\nfunction attachmentDescriptor(file: PortableFile): string {\n const uri = portableFileRemoteUri(file);\n if (uri) {\n return uri;\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return file.source;\n }\n\n return file.name;\n}\n\ntype OpenAiContentPart =\n | { type: \"text\"; text: string }\n | { type: \"image_url\"; image_url: { url: string } }\n // C6: OpenAI file input \u2014 base64 (file_data + filename) for inline, or an\n // uploaded Files-API id (file_id). Used for PDF documents.\n | {\n type: \"file\";\n file: { file_id?: string; file_data?: string; filename?: string };\n };\n\ntype AnthropicContentPart =\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: Record<string, unknown> }\n | { type: \"tool_result\"; tool_use_id: string; content: string; is_error?: boolean }\n | {\n type: \"image\";\n source: {\n type: \"base64\";\n media_type: string;\n data: string;\n };\n }\n // C6: Anthropic document block \u2014 base64 (inline), file (Files-API id), or url\n // (remote). media_type is application/pdf for PDFs.\n | {\n type: \"document\";\n source:\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | { type: \"url\"; url: string };\n };\n\ntype GeminiPart =\n | { text: string }\n | { functionCall: { name: string; args: Record<string, unknown> } }\n | { functionResponse: { name: string; response: Record<string, unknown> } }\n | {\n inlineData: {\n mimeType: string;\n data: string;\n };\n }\n // C6: Gemini File API reference \u2014 used for documents/images uploaded to the\n // File API (or remote references with a fileUri).\n | {\n fileData: {\n mimeType: string;\n fileUri: string;\n };\n };\n\nconst TRANSPORT_CONTENT_KEYS = new Set([\n \"messages\",\n \"contents\",\n \"systemInstruction\",\n \"prompt\",\n \"input\",\n]);\n\nfunction hasAssistantToolCalls(\n message: MessageInput,\n): message is MessageInput & { role: \"assistant\"; toolCalls: ToolCallInput[] } {\n return (\n message.role === \"assistant\" &&\n Array.isArray(message.toolCalls) &&\n message.toolCalls.length > 0\n );\n}\n\nfunction isToolMessage(\n message: MessageInput,\n): message is MessageInput & {\n role: \"tool\";\n toolCallId: string;\n toolName?: string;\n} {\n return message.role === \"tool\" && typeof message.toolCallId === \"string\";\n}\n\nfunction parseToolArguments(\n value: unknown,\n provider: string,\n toolName: string,\n): Record<string, unknown> {\n if (isRecord(value)) {\n return value;\n }\n\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (!trimmed) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(trimmed);\n if (isRecord(parsed)) {\n return parsed;\n }\n } catch {\n // fall through\n }\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `${provider} returned invalid tool arguments for \"${toolName}\".`,\n );\n}\n\nfunction openAiToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const calls =\n (payload as {\n choices?: Array<{\n message?: {\n tool_calls?: Array<{\n id?: unknown;\n function?: {\n name?: unknown;\n arguments?: unknown;\n };\n }>;\n };\n }>;\n })?.choices?.[0]?.message?.tool_calls ?? [];\n\n return calls.flatMap((call, index) => {\n const name =\n typeof call?.function?.name === \"string\" ? call.function.name.trim() : \"\";\n if (!name) {\n return [];\n }\n\n return [\n {\n id:\n typeof call.id === \"string\" && call.id.trim().length > 0\n ? call.id\n : `openai-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(\n call.function?.arguments,\n \"OpenAI-compatible API\",\n name,\n ),\n },\n ];\n });\n}\n\nfunction anthropicToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const parts =\n (payload as {\n content?: Array<{\n type?: unknown;\n id?: unknown;\n name?: unknown;\n input?: unknown;\n }>;\n })?.content ?? [];\n\n return parts.flatMap((part, index) => {\n if (part?.type !== \"tool_use\" || typeof part.name !== \"string\") {\n return [];\n }\n\n const name = part.name.trim();\n if (!name) {\n return [];\n }\n\n return [\n {\n id:\n typeof part.id === \"string\" && part.id.trim().length > 0\n ? part.id\n : `anthropic-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(part.input, \"Anthropic API\", name),\n },\n ];\n });\n}\n\nfunction geminiToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const parts =\n (payload as {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n functionCall?: {\n name?: unknown;\n args?: unknown;\n };\n }>;\n };\n }>;\n })?.candidates?.[0]?.content?.parts ?? [];\n\n return parts.flatMap((part, index) => {\n const name =\n typeof part?.functionCall?.name === \"string\"\n ? part.functionCall.name.trim()\n : \"\";\n if (!name) {\n return [];\n }\n\n return [\n {\n id: `gemini-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(part.functionCall?.args, \"Gemini API\", name),\n },\n ];\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction sortedKeys(value: unknown): string[] {\n return isRecord(value) ? Object.keys(value).sort() : [];\n}\n\nfunction metadataFromRecord(\n value: Record<string, unknown>,\n omittedKeys: string[],\n): Record<string, unknown> | undefined {\n const metadata = Object.fromEntries(\n Object.entries(value).filter(\n ([key, entryValue]) =>\n !omittedKeys.includes(key) && entryValue !== undefined,\n ),\n );\n\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction summarizeToolChoice(\n choice: GenerateToolChoice | undefined,\n): string | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (typeof choice === \"string\") {\n return choice;\n }\n\n return choice.type === \"function\" ? `function:${choice.name}` : undefined;\n}\n\nfunction summarizeParameters(\n parameters: GenerateParameters | undefined,\n): WideEventParameterSummary | undefined {\n if (!parameters) {\n return undefined;\n }\n\n const stopCount = Array.isArray(parameters.stop)\n ? parameters.stop.length\n : typeof parameters.stop === \"string\"\n ? 1\n : undefined;\n const thinkingMode =\n parameters.thinking?.mode ??\n (parameters.thinking?.enabled === true\n ? \"enabled\"\n : parameters.thinking?.enabled === false\n ? \"disabled\"\n : undefined);\n const providerOptionKeys = Object.fromEntries(\n Object.entries(parameters.providerOptions ?? {})\n .filter((entry): entry is [string, Record<string, unknown>] =>\n Boolean(entry[1]),\n )\n .map(([providerId, value]) => [providerId, Object.keys(value).sort()]),\n );\n const toolChoice = summarizeToolChoice(parameters.toolChoice);\n\n return {\n keys: Object.keys(parameters).sort(),\n ...(parameters.maxTokens !== undefined\n ? { maxTokens: parameters.maxTokens }\n : {}),\n ...(parameters.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopCount !== undefined ? { stopCount } : {}),\n ...(parameters.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters.candidateCount !== undefined\n ? { candidateCount: parameters.candidateCount }\n : {}),\n ...(parameters.presencePenalty !== undefined\n ? { presencePenalty: parameters.presencePenalty }\n : {}),\n ...(parameters.frequencyPenalty !== undefined\n ? { frequencyPenalty: parameters.frequencyPenalty }\n : {}),\n ...(parameters.responseFormat\n ? { responseFormatType: parameters.responseFormat.type }\n : {}),\n ...(parameters.tools ? { toolCount: parameters.tools.length } : {}),\n ...(toolChoice ? { toolChoice } : {}),\n ...(parameters.parallelToolCalls !== undefined\n ? { parallelToolCalls: parameters.parallelToolCalls }\n : {}),\n ...(thinkingMode ? { thinkingMode } : {}),\n ...(parameters.thinking?.budgetTokens !== undefined\n ? { thinkingBudgetTokens: parameters.thinking.budgetTokens }\n : {}),\n ...(parameters.thinking?.effort\n ? { thinkingEffort: parameters.thinking.effort }\n : {}),\n ...(parameters.thinking?.includeThoughts !== undefined\n ? { includeThoughts: parameters.thinking.includeThoughts }\n : {}),\n ...(parameters.safetySettings\n ? { safetySettingsCount: parameters.safetySettings.length }\n : {}),\n ...(parameters.metadata\n ? { metadataKeys: Object.keys(parameters.metadata).sort() }\n : {}),\n ...(parameters.extra\n ? { extraKeys: Object.keys(parameters.extra).sort() }\n : {}),\n ...(Object.keys(providerOptionKeys).length > 0\n ? { providerOptionKeys }\n : {}),\n };\n}\n\nfunction providerExtra(\n context: GenerateContext,\n): Record<string, unknown> | undefined {\n const extra = context.request.parameters?.extra;\n const providerOptions =\n context.request.parameters?.providerOptions?.[context.route.provider];\n\n if (!extra && !providerOptions) {\n return undefined;\n }\n\n return {\n ...(extra ?? {}),\n ...(providerOptions ?? {}),\n };\n}\n\nfunction captureTransport(\n context: GenerateContext,\n summary: Omit<WideEventTransportSummary, \"parameters\">,\n): void {\n const parameters = summarizeParameters(context.request.parameters);\n context.telemetry?.captureTransport({\n ...summary,\n ...(parameters ? { parameters } : {}),\n });\n}\n\nfunction captureDiscoveryTransport(\n context: DiscoverAcpModelsContext,\n summary: Omit<WideEventTransportSummary, \"parameters\">,\n): void {\n context.telemetry?.captureTransport(summary);\n}\n\nfunction transportSummary(\n context: GenerateContext,\n protocol: string,\n endpoint: string,\n method: string,\n stream: boolean,\n body: Record<string, unknown>,\n): void {\n const bodyKeys = Object.keys(body).sort();\n captureTransport(context, {\n protocol,\n endpoint,\n method,\n stream,\n bodyKeys,\n parameterKeys: bodyKeys.filter((key) => !TRANSPORT_CONTENT_KEYS.has(key)),\n });\n}\n\nfunction discoveryTransportSummary(\n context: DiscoverAcpModelsContext,\n protocol: string,\n endpoint: string,\n method: string,\n): void {\n captureDiscoveryTransport(context, {\n protocol,\n endpoint,\n method,\n stream: false,\n bodyKeys: [],\n parameterKeys: [],\n });\n}\n\nexport function currentModelIdForRoute(\n route: NormalizedRoute,\n modelIds: string[],\n): string | undefined {\n return modelIds.includes(route.model) ? route.model : undefined;\n}\n\nfunction canonicalGeminiImageModelId(modelId: string | undefined): string | undefined {\n if (!modelId) {\n return undefined;\n }\n\n return modelId.toLowerCase().includes(\"image\")\n ? \"gemini-3-pro-image\"\n : undefined;\n}\n\nexport function buildModelCatalog(\n route: NormalizedRoute,\n availableModels: AcpModelInfo[],\n currentModelId?: string,\n): AcpModelCatalog {\n const requestedModelId = route.model;\n // GAP-A (TASK-028 / UR-002): surface the route's configured contextWindow onto\n // entries that have no discovered contextLength. Monotonic + configured-only,\n // so live values are never overwritten. This single call covers the API\n // providers AND the cli static/command discovery paths, which both route\n // through buildModelCatalog.\n const filledModels = fillConfiguredContextLength(route, availableModels);\n const requestedModelAdvertised = filledModels.some(\n (model) => model.modelId === requestedModelId,\n );\n const canonicalModelId =\n route.provider === \"gemini\"\n ? canonicalGeminiImageModelId(requestedModelId)\n : undefined;\n const resolvedModelId = requestedModelAdvertised\n ? requestedModelId\n : canonicalModelId &&\n filledModels.some((model) => model.modelId === canonicalModelId)\n ? canonicalModelId\n : undefined;\n\n return {\n requestedModelId,\n requestedModelAdvertised,\n ...(canonicalModelId ? { canonicalModelId } : {}),\n ...(resolvedModelId ? { resolvedModelId } : {}),\n ...(currentModelId ? { currentModelId } : {}),\n availableModels: filledModels,\n };\n}\n\nfunction parseOpenAiModelCatalog(\n route: NormalizedRoute,\n payload: unknown,\n): AcpModelCatalog {\n const data = isRecord(payload) && Array.isArray(payload.data) ? payload.data : [];\n const availableModels = data.flatMap((entry) => {\n if (!isRecord(entry) || typeof entry.id !== \"string\") {\n return [];\n }\n\n const metadata = metadataFromRecord(entry, [\n \"id\",\n \"name\",\n \"display_name\",\n \"description\",\n ]);\n\n const contextLength = extractModelContextLength(entry);\n const pricing = parseModelPricing(entry);\n const free = detectModelFree(entry.id, pricing, entry);\n\n return [\n {\n modelId: entry.id,\n name:\n typeof entry.display_name === \"string\"\n ? entry.display_name\n : typeof entry.name === \"string\"\n ? entry.name\n : entry.id,\n ...(typeof entry.description === \"string\"\n ? { description: entry.description }\n : {}),\n ...(contextLength !== undefined\n ? { contextLength, contextWindowSource: \"discovered\" as const }\n : {}),\n ...(pricing ? { pricing } : {}),\n ...(free ? { free } : {}),\n ...(metadata\n ? {\n metadata,\n }\n : {}),\n },\n ];\n });\n const currentModelId = currentModelIdForRoute(\n route,\n availableModels.map((model) => model.modelId),\n );\n\n return buildModelCatalog(route, availableModels, currentModelId);\n}\n\nfunction parseGeminiModelId(value: string): string {\n return value.startsWith(\"models/\") ? value.slice(\"models/\".length) : value;\n}\n\nfunction parseGeminiModelCatalog(\n route: NormalizedRoute,\n payload: unknown,\n): AcpModelCatalog {\n const models =\n isRecord(payload) && Array.isArray(payload.models) ? payload.models : [];\n const availableModels = models.flatMap((entry) => {\n if (!isRecord(entry) || typeof entry.name !== \"string\") {\n return [];\n }\n\n const modelId = parseGeminiModelId(entry.name);\n const canonicalModelId = canonicalGeminiImageModelId(modelId);\n const metadata = metadataFromRecord(entry, [\n \"name\",\n \"displayName\",\n \"description\",\n ]);\n return [\n {\n modelId,\n name:\n typeof entry.displayName === \"string\"\n ? entry.displayName\n : modelId,\n ...(typeof entry.description === \"string\"\n ? { description: entry.description }\n : {}),\n ...(canonicalModelId && canonicalModelId !== modelId\n ? { canonicalModelId }\n : {}),\n ...(metadata\n ? {\n metadata,\n }\n : {}),\n },\n ];\n });\n const currentModelId = currentModelIdForRoute(\n route,\n availableModels.map((model) => model.modelId),\n );\n\n return buildModelCatalog(route, availableModels, currentModelId);\n}\n\nasync function discoverOpenAiModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveOpenAiModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"openai-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n },\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"openai\", response, payload);\n }\n\n return parseOpenAiModelCatalog(context.route, payload);\n}\n\nasync function discoverAnthropicModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveAnthropicModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"anthropic-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: {\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"anthropic\", response, payload);\n }\n\n return parseOpenAiModelCatalog(context.route, payload);\n}\n\nasync function discoverGeminiModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveGeminiModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"gemini-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: geminiApiKeyHeaders(apiKey),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(context.route.provider, response, payload);\n }\n\n return parseGeminiModelCatalog(context.route, payload);\n}\n\nfunction openAiToolChoice(\n choice: GenerateToolChoice | undefined,\n): GenerateToolChoice | undefined {\n return choice;\n}\n\nfunction anthropicToolChoice(\n choice: GenerateToolChoice | undefined,\n): Record<string, unknown> | undefined {\n if (!choice || choice === \"none\") {\n return undefined;\n }\n\n if (choice === \"auto\") {\n return { type: \"auto\" };\n }\n\n if (choice === \"required\") {\n return { type: \"any\" };\n }\n\n if (choice.type === \"function\") {\n return { type: \"tool\", name: choice.name };\n }\n\n return undefined;\n}\n\nfunction geminiToolConfig(\n choice: GenerateToolChoice | undefined,\n): Record<string, unknown> | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (choice === \"auto\") {\n return { functionCallingConfig: { mode: \"AUTO\" } };\n }\n\n if (choice === \"required\") {\n return { functionCallingConfig: { mode: \"ANY\" } };\n }\n\n if (choice === \"none\") {\n return { functionCallingConfig: { mode: \"NONE\" } };\n }\n\n if (choice.type === \"function\") {\n return {\n functionCallingConfig: {\n mode: \"ANY\",\n allowedFunctionNames: [choice.name],\n },\n };\n }\n\n return undefined;\n}\n\nfunction openAiTools(\n tools: GenerateToolDefinition[] | undefined,\n): GenerateToolDefinition[] | undefined {\n return tools;\n}\n\nfunction anthropicTools(\n tools: GenerateToolDefinition[] | undefined,\n): Array<Record<string, unknown>> | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n\n return tools.map((tool) => ({\n name: tool.function.name,\n ...(tool.function.description\n ? { description: tool.function.description }\n : {}),\n input_schema: tool.function.parameters ?? {\n type: \"object\",\n properties: {},\n },\n }));\n}\n\nfunction geminiTools(\n tools: GenerateToolDefinition[] | undefined,\n): Array<Record<string, unknown>> | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n\n return [\n {\n functionDeclarations: tools.map((tool) => ({\n name: tool.function.name,\n ...(tool.function.description\n ? { description: tool.function.description }\n : {}),\n parameters: tool.function.parameters ?? {\n type: \"object\",\n properties: {},\n },\n })),\n },\n ];\n}\n\nfunction openAiResponseFormat(\n format: GenerateResponseFormat | undefined,\n): unknown {\n if (!format || format.type === \"text\") {\n return undefined;\n }\n\n if (format.type === \"json_object\") {\n return { type: \"json_object\" };\n }\n\n if (format.type === \"json_schema\") {\n return {\n type: \"json_schema\",\n json_schema: {\n name: format.name ?? \"response\",\n schema: format.schema,\n // Conditional spread: forward `strict` ONLY when the caller set it, so\n // the wire body omits the field entirely when undefined (INV-ROBUST-1).\n ...(format.strict !== undefined ? { strict: format.strict } : {}),\n },\n };\n }\n\n return format.value;\n}\n\nfunction geminiResponseFormat(\n format: GenerateResponseFormat | undefined,\n): Record<string, unknown> | undefined {\n if (!format || format.type === \"text\") {\n return undefined;\n }\n\n if (format.type === \"json_object\") {\n return {\n responseMimeType: \"application/json\",\n };\n }\n\n if (format.type === \"json_schema\") {\n return {\n responseMimeType: \"application/json\",\n responseSchema: format.schema,\n };\n }\n\n return isRecord(format.value) ? format.value : undefined;\n}\n\nfunction normalizeThinkingMode(\n thinking: GenerateThinkingOptions | undefined,\n): \"enabled\" | \"disabled\" | \"adaptive\" | undefined {\n if (!thinking) {\n return undefined;\n }\n\n if (thinking.mode) {\n return thinking.mode;\n }\n\n if (thinking.enabled === true) {\n return \"enabled\";\n }\n\n if (thinking.enabled === false) {\n return \"disabled\";\n }\n\n return undefined;\n}\n\nfunction openAiThinking(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n const mode = normalizeThinkingMode(thinking);\n if (!thinking || !mode) {\n return undefined;\n }\n\n return {\n type: mode,\n ...(thinking.budgetTokens !== undefined\n ? { budget_tokens: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n ...(thinking.includeThoughts !== undefined\n ? { includeThoughts: thinking.includeThoughts }\n : {}),\n };\n}\n\nfunction anthropicThinking(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n const mode = normalizeThinkingMode(thinking);\n if (!thinking || !mode || mode === \"disabled\") {\n return undefined;\n }\n\n return {\n type: mode,\n ...(thinking.budgetTokens !== undefined\n ? { budget_tokens: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n };\n}\n\nfunction geminiThinkingConfig(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n if (!thinking) {\n return undefined;\n }\n\n const mode = normalizeThinkingMode(thinking);\n const config: Record<string, unknown> = {\n ...(thinking.includeThoughts !== undefined\n ? { includeThoughts: thinking.includeThoughts }\n : {}),\n ...(thinking.budgetTokens !== undefined\n ? { thinkingBudget: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n };\n\n if (mode === \"disabled\") {\n config.includeThoughts = false;\n } else if (mode && mode !== \"enabled\") {\n config.thinkingType = mode;\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\nfunction stopSequences(\n stop: GenerateParameters[\"stop\"],\n): string[] | undefined {\n if (!stop) {\n return undefined;\n }\n\n return Array.isArray(stop) ? stop : [stop];\n}\n\n/**\n * Optional uploader threaded into the attachment builders (C6 / OQ-9). When\n * present, oversize documents are uploaded to the provider Files API and\n * referenced by id; when absent (or for small documents), the inline base64 path\n * is used. Kept OPTIONAL so existing handler call sites stay source-compatible.\n */\ninterface AttachmentUploader {\n fetchImpl: FetchLike;\n context: GenerateContext;\n apiKey: string;\n /** Sink for size-guard / upload-failure warnings surfaced on the result. */\n warnings: string[];\n}\n\n/**\n * Inline-base64 size guard (OQ-9). Documents whose decoded base64 length is at or\n * below this threshold ride inline; larger ones attempt a Files-API upload (when\n * an uploader is threaded). base64 length \u2248 4/3 of byte length, so ~5MB of base64\n * \u2248 ~3.75MB of bytes \u2014 comfortably under every provider's inline cap while\n * keeping the inline request small. Anthropic inline PDF cap is 32MB, OpenAI ~?,\n * Gemini ~20MB; the guard is conservative and identical across providers for\n * deterministic routing (the upload path is purely additive).\n */\nconst INLINE_DOCUMENT_BASE64_LIMIT = 4_500_000;\n\nfunction isOversizeDocument(payload: PortableFilePayload): boolean {\n return (\n payload.base64 !== undefined &&\n payload.base64.length > INLINE_DOCUMENT_BASE64_LIMIT\n );\n}\n\nfunction base64ToBlob(base64: string, mimeType: string): Blob {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return new Blob([bytes], { type: mimeType });\n}\n\nfunction recordOf(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n}\n\n/**\n * Upload a materialized document to the Anthropic Files API (beta\n * `files-api-2025-04-14`) and return the `file_id`, or `undefined` on any\n * failure (the caller falls back to inline base64 + a size warning). Threads the\n * abort signal (C2b parity). Verified shape: `POST /v1/files` multipart `file`\n * field \u2192 response `.id`.\n */\nasync function uploadAnthropicFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n const root = base\n ? base.replace(/\\/(messages|models)$/, \"\")\n : \"https://api.anthropic.com/v1\";\n const endpoint = appendPath(root, \"/files\");\n const form = new FormData();\n form.append(\n \"file\",\n base64ToBlob(payload.base64, payload.mimeType),\n payload.name,\n );\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"x-api-key\": uploader.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"anthropic-beta\": \"files-api-2025-04-14\",\n },\n body: form,\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const id = recordOf(data).id;\n return typeof id === \"string\" ? id : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Upload a materialized document to the OpenAI Files API and return the `file_id`\n * (purpose `user_data` for chat file inputs), or `undefined` on failure. Verified\n * shape: `POST /v1/files` multipart `file` + `purpose` \u2192 response `.id`.\n */\nasync function uploadOpenAiFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n const root = base\n ? base.replace(/\\/(chat\\/completions|images\\/generations|models)$/, \"\")\n : \"https://api.openai.com/v1\";\n const endpoint = appendPath(root, \"/files\");\n const form = new FormData();\n form.append(\n \"file\",\n base64ToBlob(payload.base64, payload.mimeType),\n payload.name,\n );\n form.append(\"purpose\", \"user_data\");\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${uploader.apiKey}`,\n },\n body: form,\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const id = recordOf(data).id;\n return typeof id === \"string\" ? id : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Upload a materialized document to the Gemini File API and return the `fileUri`,\n * or `undefined` on failure. Verified shape: simple media upload to\n * `POST /upload/v1beta/files` with `X-Goog-Upload-Protocol: raw` \u2192\n * response `.file.uri`. The API key rides the `x-goog-api-key` header (NOT a\n * `?key=` query param) so it stays out of any captured endpoint string (SEC).\n */\nasync function uploadGeminiFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n const endpoint = base\n ? appendPath(\n base.replace(/\\/v1beta\\/models.*$/, \"/v1beta\").replace(/\\/+$/, \"\"),\n \"/files\",\n ).replace(\"/v1beta/files\", \"/upload/v1beta/files\")\n : \"https://generativelanguage.googleapis.com/upload/v1beta/files\";\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n ...geminiApiKeyHeaders(uploader.apiKey),\n \"X-Goog-Upload-Protocol\": \"raw\",\n \"X-Goog-Upload-Header-Content-Type\": payload.mimeType,\n \"content-type\": payload.mimeType,\n },\n body: base64ToBlob(payload.base64, payload.mimeType),\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const file = recordOf(recordOf(data).file);\n const uri = file.uri ?? recordOf(data).uri;\n return typeof uri === \"string\" ? uri : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function openAiAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<OpenAiContentPart[]> {\n const parts: OpenAiContentPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const imageUrl =\n (await portableFileToDataUrl(file)) ?? portableFileRemoteUri(file);\n if (imageUrl) {\n parts.push({\n type: \"image_url\",\n image_url: { url: imageUrl },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n // Already-uploaded providerFileId (remote reference) wins.\n if (payload.providerFileId) {\n parts.push({ type: \"file\", file: { file_id: payload.providerFileId } });\n continue;\n }\n // Oversize \u2192 Files-API upload (file_id); fall back to inline + warning.\n if (uploader && isOversizeDocument(payload)) {\n const fileId = await uploadOpenAiFile(payload, uploader);\n if (fileId) {\n parts.push({ type: \"file\", file: { file_id: fileId } });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the OpenAI Files API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n type: \"file\",\n file: {\n filename: file.name,\n file_data: `data:${payload.mimeType};base64,${payload.base64}`,\n },\n });\n continue;\n }\n // Remote document with only a uri \u2192 descriptor (OpenAI has no url source).\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n type: \"text\",\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n type: \"text\",\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nasync function anthropicAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<AnthropicContentPart[]> {\n const parts: AnthropicContentPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const dataUrl = await portableFileToDataUrl(file);\n const mimeType = inferPortableFileMimeType(file);\n if (dataUrl && mimeType) {\n const [, base64Data = \"\"] = dataUrl.split(\",\", 2);\n parts.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: mimeType,\n data: base64Data,\n },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.providerFileId) {\n parts.push({\n type: \"document\",\n source: { type: \"file\", file_id: payload.providerFileId },\n });\n continue;\n }\n // Remote PDF with only a URL \u2192 Anthropic url source (no bytes; never empty\n // base64 \u2014 INV remote-pdf-url-prefers-url-source).\n if (!payload.base64 && payload.uri) {\n parts.push({\n type: \"document\",\n source: { type: \"url\", url: payload.uri },\n });\n continue;\n }\n if (uploader && isOversizeDocument(payload)) {\n const fileId = await uploadAnthropicFile(payload, uploader);\n if (fileId) {\n parts.push({\n type: \"document\",\n source: { type: \"file\", file_id: fileId },\n });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the Anthropic Files API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n type: \"document\",\n source: {\n type: \"base64\",\n media_type: payload.mimeType,\n data: payload.base64,\n },\n });\n continue;\n }\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n type: \"text\",\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n type: \"text\",\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nasync function geminiAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<GeminiPart[]> {\n const parts: GeminiPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const dataUrl = await portableFileToDataUrl(file);\n const mimeType = inferPortableFileMimeType(file);\n if (dataUrl && mimeType) {\n const [, base64Data = \"\"] = dataUrl.split(\",\", 2);\n parts.push({\n inlineData: {\n mimeType,\n data: base64Data,\n },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.uri && !payload.base64) {\n parts.push({\n fileData: { mimeType: payload.mimeType, fileUri: payload.uri },\n });\n continue;\n }\n if (uploader && isOversizeDocument(payload)) {\n const fileUri = await uploadGeminiFile(payload, uploader);\n if (fileUri) {\n parts.push({\n fileData: { mimeType: payload.mimeType, fileUri },\n });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the Gemini File API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n inlineData: { mimeType: payload.mimeType, data: payload.base64 },\n });\n continue;\n }\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nfunction attachOpenAiParts(\n conversation: Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n }>,\n parts: OpenAiContentPart[],\n): Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}> {\n if (parts.length === 0) {\n return conversation;\n }\n\n let targetIndex = -1;\n for (let index = conversation.length - 1; index >= 0; index -= 1) {\n if (conversation[index]?.role === \"user\") {\n targetIndex = index;\n break;\n }\n }\n\n if (targetIndex === -1) {\n conversation.push({\n role: \"user\",\n content: \"\",\n });\n targetIndex = conversation.length - 1;\n }\n\n const target = conversation[targetIndex]!;\n const baseParts =\n typeof target.content === \"string\" && target.content.trim().length > 0\n ? [{ type: \"text\", text: target.content } satisfies OpenAiContentPart]\n : Array.isArray(target.content)\n ? target.content\n : [];\n target.content = [...baseParts, ...parts];\n return conversation;\n}\n\nasync function openAiMessages(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}>> {\n const conversation: Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n }> = messages.map((message) => {\n if (isToolMessage(message)) {\n return {\n role: \"tool\",\n content: message.content,\n tool_call_id: message.toolCallId,\n };\n }\n\n if (hasAssistantToolCalls(message)) {\n return {\n role: \"assistant\",\n content: message.content,\n tool_calls: message.toolCalls.map((call) => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: JSON.stringify(call.arguments),\n },\n })),\n };\n }\n\n return {\n role:\n message.role === \"assistant\"\n ? \"assistant\"\n : message.role === \"system\"\n ? \"system\"\n : \"user\",\n content: message.content,\n };\n });\n\n return attachOpenAiParts(\n conversation,\n await openAiAttachmentParts(attachments, uploader),\n );\n}\n\nasync function anthropicRequest(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<{\n system?: string;\n messages: Array<{\n role: \"user\" | \"assistant\";\n content: string | AnthropicContentPart[];\n }>;\n}> {\n const system = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\");\n\n const conversation: Array<{\n role: \"user\" | \"assistant\";\n content: string | AnthropicContentPart[];\n }> = [];\n\n for (const message of messages.filter((item) => item.role !== \"system\")) {\n if (isToolMessage(message)) {\n const toolResult: AnthropicContentPart = {\n type: \"tool_result\",\n tool_use_id: message.toolCallId,\n content: message.content,\n ...(message.isError !== undefined ? { is_error: message.isError } : {}),\n };\n const last = conversation[conversation.length - 1];\n if (last?.role === \"user\" && Array.isArray(last.content)) {\n last.content.push(toolResult);\n } else {\n conversation.push({\n role: \"user\",\n content: [toolResult],\n });\n }\n continue;\n }\n\n if (hasAssistantToolCalls(message)) {\n const content: AnthropicContentPart[] = [];\n if (message.content.trim().length > 0) {\n content.push({ type: \"text\", text: message.content });\n }\n content.push(\n ...message.toolCalls.map((call) => ({\n type: \"tool_use\" as const,\n id: call.id,\n name: call.name,\n input: call.arguments,\n })),\n );\n conversation.push({\n role: \"assistant\",\n content,\n });\n continue;\n }\n\n conversation.push({\n role: (message.role === \"assistant\" ? \"assistant\" : \"user\") as\n | \"user\"\n | \"assistant\",\n content: message.content,\n });\n }\n\n const attachmentParts = await anthropicAttachmentParts(attachments, uploader);\n if (attachmentParts.length > 0) {\n let targetIndex = -1;\n for (let index = conversation.length - 1; index >= 0; index -= 1) {\n if (conversation[index]?.role === \"user\") {\n targetIndex = index;\n break;\n }\n }\n if (targetIndex === -1) {\n conversation.push({\n role: \"user\",\n content: \"\",\n });\n targetIndex = conversation.length - 1;\n }\n\n const target = conversation[targetIndex]!;\n const baseParts =\n typeof target.content === \"string\" && target.content.trim().length > 0\n ? [{ type: \"text\", text: target.content } satisfies AnthropicContentPart]\n : Array.isArray(target.content)\n ? target.content\n : [];\n target.content = [...baseParts, ...attachmentParts];\n }\n\n return {\n ...(system ? { system } : {}),\n messages:\n conversation.length > 0\n ? conversation\n : [{ role: \"user\", content: \"\" }],\n };\n}\n\nasync function geminiRequest(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<{\n systemInstruction?: { parts: Array<{ text: string }> };\n contents: Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }>;\n}> {\n const system = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\");\n const contents: Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }> = messages\n .filter((message) => message.role !== \"system\")\n .reduce<Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }>>(\n (conversation, message) => {\n if (isToolMessage(message)) {\n const response: GeminiPart = {\n functionResponse: {\n name: message.toolName ?? \"tool\",\n response:\n isRecord(message.data)\n ? message.data\n : {\n content: message.content,\n ...(message.isError !== undefined\n ? { isError: message.isError }\n : {}),\n },\n },\n };\n const last = conversation[conversation.length - 1];\n if (last?.role === \"user\") {\n last.parts.push(response);\n } else {\n conversation.push({\n role: \"user\",\n parts: [response],\n });\n }\n return conversation;\n }\n\n if (hasAssistantToolCalls(message)) {\n const parts: GeminiPart[] = [];\n if (message.content.trim().length > 0) {\n parts.push({ text: message.content });\n }\n parts.push(\n ...message.toolCalls.map((call) => ({\n functionCall: {\n name: call.name,\n args: call.arguments,\n },\n })),\n );\n conversation.push({\n role: \"model\",\n parts,\n });\n return conversation;\n }\n\n conversation.push({\n role: (message.role === \"assistant\" ? \"model\" : \"user\") as\n | \"user\"\n | \"model\",\n parts: [{ text: message.content } satisfies GeminiPart],\n });\n return conversation;\n },\n [],\n );\n\n const attachmentParts = await geminiAttachmentParts(attachments, uploader);\n if (attachmentParts.length > 0) {\n let targetIndex = -1;\n for (let index = contents.length - 1; index >= 0; index -= 1) {\n if (contents[index]?.role === \"user\") {\n targetIndex = index;\n break;\n }\n }\n if (targetIndex === -1) {\n contents.push({\n role: \"user\",\n parts: [],\n });\n targetIndex = contents.length - 1;\n }\n\n contents[targetIndex]!.parts.push(...attachmentParts);\n }\n\n return {\n ...(system\n ? {\n systemInstruction: {\n parts: [{ text: system }],\n },\n }\n : {}),\n contents,\n };\n}\n\nfunction extractText(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value\n .flatMap((part) => {\n if (typeof part === \"string\") {\n return [part];\n }\n if (part && typeof part === \"object\") {\n // Skip the model's REASONING parts (Gemini marks them `{ thought: true, text }`) \u2014 they are the\n // internal chain-of-thought, NOT the answer; without this they leak into the answer text.\n // extractThoughts() collects them separately into GenerateResult.reasoning. Other providers'\n // parts never carry `thought`, so this is a no-op for them.\n if ((part as Record<string, unknown>).thought === true) {\n return [];\n }\n const candidate = (part as Record<string, unknown>).text;\n if (typeof candidate === \"string\") {\n return [candidate];\n }\n }\n return [];\n })\n .join(\"\\n\")\n .trim();\n }\n\n return \"\";\n}\n\n// Collect the model's REASONING (\"thought\") parts' text (Gemini `{ thought: true, text }`), separately from\n// the answer. Returns undefined when there are none so a non-thinking response carries no reasoning field.\nfunction extractThoughts(value: unknown): string | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const thoughts = value.flatMap((part) => {\n if (part && typeof part === \"object\" && (part as Record<string, unknown>).thought === true) {\n const candidate = (part as Record<string, unknown>).text;\n if (typeof candidate === \"string\") {\n return [candidate];\n }\n }\n return [];\n });\n const joined = thoughts.join(\"\\n\").trim();\n return joined.length > 0 ? joined : undefined;\n}\n\nfunction imageAttachmentsFromPayload(\n payload: unknown,\n ...sources: unknown[]\n) {\n return extractImagePayloads(payload, ...sources).map((item) =>\n preparePortableFile(item),\n );\n}\n\nfunction imageReferenceFiles(context: GenerateContext): PortableFile[] {\n if (context.request.image?.referenceImages?.length) {\n return context.request.image.referenceImages;\n }\n\n return context.request.attachments.filter((file) => isPortableImageFile(file));\n}\n\nfunction shouldUseImageEditEndpoint(context: GenerateContext): boolean {\n return Boolean(\n context.request.image?.sourceImage ||\n context.request.image?.mask ||\n imageReferenceFiles(context).length > 0,\n );\n}\n\nfunction shouldUseProxyImageExtensions(route: NormalizedRoute): boolean {\n return route.provider === \"gemini\" || Boolean(route.transport.baseUrl?.trim());\n}\n\nfunction resolveImageRequestSize(context: GenerateContext, fallbackSize: string): string {\n return String(\n context.request.image?.size ??\n context.request.image?.aspectRatio ??\n fallbackSize,\n );\n}\n\nfunction buildImageRequestFields(\n context: GenerateContext,\n bundle: ReturnType<typeof buildImagePromptBundle>,\n): Record<string, unknown> {\n const image = context.request.image;\n return {\n model: context.route.model,\n prompt: bundle.prompt,\n size: resolveImageRequestSize(context, bundle.size),\n response_format: \"b64_json\",\n n: context.request.parameters?.candidateCount ?? 1,\n ...(image?.quality ? { quality: image.quality } : {}),\n ...(image?.style ? { style: image.style } : {}),\n ...(shouldUseProxyImageExtensions(context.route) && image?.aspectRatio\n ? { aspect_ratio: image.aspectRatio }\n : {}),\n ...(shouldUseProxyImageExtensions(context.route) && image?.imageSize\n ? { image_size: image.imageSize }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n}\n\nasync function appendMultipartPortableFile(\n formData: FormData,\n fieldName: string,\n file: PortableFile,\n): Promise<void> {\n const bytes = await portableFileToBytes(file);\n if (!bytes) {\n throw new AiConnectError(\n \"validation_error\",\n `Multipart image uploads require local, browser, or data-url sources for \"${fieldName}\".`,\n );\n }\n\n const mimeType = inferPortableFileMimeType(file) ?? \"application/octet-stream\";\n const arrayBuffer = bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength,\n ) as ArrayBuffer;\n formData.append(\n fieldName,\n new Blob([arrayBuffer], { type: mimeType }),\n file.name,\n );\n}\n\nasync function buildImageEditFormData(\n context: GenerateContext,\n fields: Record<string, unknown>,\n): Promise<FormData> {\n const formData = new FormData();\n for (const [key, value] of Object.entries(fields)) {\n if (value === undefined || value === null) {\n continue;\n }\n formData.append(key, String(value));\n }\n\n if (context.request.image?.sourceImage) {\n await appendMultipartPortableFile(\n formData,\n \"image\",\n context.request.image.sourceImage,\n );\n }\n\n if (context.request.image?.mask) {\n await appendMultipartPortableFile(formData, \"mask\", context.request.image.mask);\n }\n\n const referenceImages = imageReferenceFiles(context);\n for (const [index, file] of referenceImages.entries()) {\n await appendMultipartPortableFile(formData, `image${index + 1}`, file);\n }\n\n return formData;\n}\n\n/**\n * SHARED OpenAI-compatible chat-completions body builder (C3 + C9). Both the `generate` path's\n * one-shot `response_format`-drop retry AND the new `runOpenAiStream` SSE producer build their body\n * through THIS single function \u2014 there is no duplicated body assembly (LEVER / plan \u00A72). The only\n * per-caller deltas are `stream` (false for generate, true for SSE) and `dropResponseFormat` (the\n * C3 fallback omits `response_format`). `messages`/`responseFormat` are precomputed by the caller\n * (the stream producer reuses the same `openAiMessages` + `openAiResponseFormat` upstream).\n */\nfunction buildOpenAiChatBody(\n context: GenerateContext,\n messages: unknown,\n parameters: GenerateContext[\"request\"][\"parameters\"],\n responseFormat: ReturnType<typeof openAiResponseFormat>,\n opts: { stream: boolean; dropResponseFormat: boolean },\n): Record<string, unknown> {\n return {\n model: context.route.model,\n messages,\n stream: opts.stream,\n ...(parameters?.maxTokens !== undefined\n ? { max_tokens: parameters.maxTokens }\n : {}),\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { top_p: parameters.topP } : {}),\n ...(parameters?.stop ? { stop: parameters.stop } : {}),\n ...(parameters?.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters?.candidateCount !== undefined\n ? { n: parameters.candidateCount }\n : {}),\n ...(parameters?.presencePenalty !== undefined\n ? { presence_penalty: parameters.presencePenalty }\n : {}),\n ...(parameters?.frequencyPenalty !== undefined\n ? { frequency_penalty: parameters.frequencyPenalty }\n : {}),\n ...(openAiTools(parameters?.tools)\n ? { tools: openAiTools(parameters?.tools) }\n : {}),\n ...(openAiToolChoice(parameters?.toolChoice)\n ? { tool_choice: openAiToolChoice(parameters?.toolChoice) }\n : {}),\n ...(parameters?.parallelToolCalls !== undefined\n ? { parallel_tool_calls: parameters.parallelToolCalls }\n : {}),\n ...(!opts.dropResponseFormat && responseFormat\n ? { response_format: responseFormat }\n : {}),\n ...(openAiThinking(parameters?.thinking)\n ? { thinking: openAiThinking(parameters?.thinking) }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n}\n\nasync function runOpenAi(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n if (context.request.operation === \"image\") {\n return runOpenAiImage(fetchImpl, context);\n }\n\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const messages = await openAiMessages(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const responseFormat = openAiResponseFormat(parameters?.responseFormat);\n const endpoint = resolveOpenAiEndpoint(context.route, \"text\");\n\n /**\n * Build the chat-completions body via the SHARED `buildOpenAiChatBody`. When\n * `dropResponseFormat` is true the `response_format` field is omitted (the\n * one-shot fallback body). `stream:false` for the generate path.\n */\n const buildBody = (dropResponseFormat: boolean): Record<string, unknown> =>\n buildOpenAiChatBody(context, messages, parameters, responseFormat, {\n stream: false,\n dropResponseFormat,\n });\n\n /**\n * One POST + classify. On a non-ok response it throws the classified error\n * EXCEPT it returns `{ rejection: true }` when this is the first (non-dropped)\n * attempt, `response_format` was actually sent, the failure is a\n * response_format-rejection 400, and the operation is NOT aborted \u2014 so the\n * caller can re-issue exactly once without `response_format` (INV-ROBUST-1).\n * The abort guard ensures a deadline that fired during the call surfaces the\n * canonical abort/timeout error (via the client) rather than a schema retry.\n */\n const attempt = async (\n dropResponseFormat: boolean,\n ): Promise<\n | { rejection: true }\n | {\n rejection: false;\n data: {\n choices?: Array<{ message?: { content?: unknown } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n };\n };\n }\n > => {\n const body = buildBody(dropResponseFormat);\n transportSummary(context, \"openai-chat\", endpoint, \"POST\", false, body);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n const error = classifyApiError(\"openai\", response, payload);\n // R21 precondition: only the FIRST attempt that actually sent\n // `response_format` is eligible for the one-shot drop fallback, and only\n // when the operation has not been aborted/timed-out (C2 dep).\n if (\n !dropResponseFormat &&\n responseFormat !== undefined &&\n !context.abort.signal.aborted &&\n isResponseFormatRejection(response, error.message)\n ) {\n return { rejection: true };\n }\n throw error;\n }\n\n return {\n rejection: false,\n data: payload as {\n choices?: Array<{ message?: { content?: unknown } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n };\n },\n };\n };\n\n let outcome = await attempt(false);\n let droppedResponseFormat = false;\n if (outcome.rejection) {\n // One-shot fallback: re-issue exactly once WITHOUT `response_format`.\n droppedResponseFormat = true;\n const retried = await attempt(true);\n if (retried.rejection) {\n // attempt(true) never returns a rejection sentinel (dropResponseFormat\n // disables the gate), but narrow the type defensively.\n throw classifyApiError(\n \"openai\",\n new Response(null, { status: 400 }),\n undefined,\n );\n }\n outcome = retried;\n }\n\n const data = outcome.data;\n\n const baseWarnings: string[] = [...uploaderWarnings];\n if (parameters?.candidateCount && parameters.candidateCount > 1) {\n baseWarnings.push(\n \"candidateCount > 1 is forwarded to OpenAI-compatible text routes, but the normalized result returns only the first choice.\",\n );\n }\n if (droppedResponseFormat) {\n baseWarnings.push(\n \"response_format was rejected by the OpenAI-compatible route (HTTP 400); the request was retried once without response_format and structured-output formatting was NOT enforced.\",\n );\n }\n\n return {\n text: extractText(data.choices?.[0]?.message?.content),\n data,\n ...(openAiToolCallsFromPayload(data).length > 0\n ? { toolCalls: openAiToolCallsFromPayload(data) }\n : {}),\n ...(baseWarnings.length > 0 ? { warnings: baseWarnings } : {}),\n ...(data.usage?.prompt_tokens !== undefined ||\n data.usage?.completion_tokens !== undefined ||\n data.usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usage?.prompt_tokens !== undefined\n ? { inputTokens: data.usage.prompt_tokens }\n : {}),\n ...(data.usage?.completion_tokens !== undefined\n ? { outputTokens: data.usage.completion_tokens }\n : {}),\n ...(data.usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n reasoningTokens:\n data.usage.completion_tokens_details.reasoning_tokens,\n }\n : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * REAL OpenAI-compatible SSE streaming producer (C9 / OQ-13 / UR-013). The first default `stream`\n * handler that emits genuine incremental `{type:'delta', text}` events parsed from the\n * chat-completions SSE wire, then exactly one terminal `{type:'result', result}` (INV-ABORT-3 /\n * stream-emits-deltas-then-exactly-one-terminal-result).\n *\n * Shares the body builder with the `generate` path (`buildOpenAiChatBody`, `stream:true`) \u2014 no\n * duplication. Honors `context.abort.signal`: passed into `fetch` init AND, on mid-stream abort,\n * the reader is `cancel()`ed so the underlying connection is released even if the `FetchLike`\n * ignored `init.signal` (R17 \u2014 `reader.cancel()` releases our side). Usage is captured ONLY when\n * the stream actually reports a `usage` block (stream_options) \u2014 never fabricated (R17).\n */\nasync function* runOpenAiStream(\n fetchImpl: FetchLike,\n context: GenerateContext,\n): AsyncIterable<GenerateStreamEvent> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const messages = await openAiMessages(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const responseFormat = openAiResponseFormat(parameters?.responseFormat);\n const endpoint = resolveOpenAiEndpoint(context.route, \"text\");\n\n /**\n * Issue ONE streaming POST. On a non-ok response it returns the\n * `{ rejection: true }` sentinel ONLY for the first (non-dropped) attempt that\n * actually sent `response_format`, the failure is a response_format-rejection\n * 400, and the operation is not aborted \u2014 so the caller can re-issue exactly\n * once WITHOUT `response_format` (R21 parity with `runOpenAi`). Otherwise it\n * throws the classified error or returns the streaming `response`.\n */\n const attempt = async (\n dropResponseFormat: boolean,\n ): Promise<{ rejection: true } | { rejection: false; response: Response }> => {\n const body = buildOpenAiChatBody(context, messages, parameters, responseFormat, {\n stream: true,\n dropResponseFormat,\n });\n transportSummary(context, \"openai-chat\", endpoint, \"POST\", true, body);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: context.abort.signal,\n });\n\n if (!response.ok) {\n const payload = await readPayload(response);\n const error = classifyApiError(\"openai\", response, payload);\n if (\n !dropResponseFormat &&\n responseFormat !== undefined &&\n !context.abort.signal.aborted &&\n isResponseFormatRejection(response, error.message)\n ) {\n return { rejection: true };\n }\n throw error;\n }\n\n return { rejection: false, response };\n };\n\n let outcome = await attempt(false);\n let droppedResponseFormat = false;\n if (outcome.rejection) {\n // One-shot fallback: re-issue exactly once WITHOUT `response_format`.\n droppedResponseFormat = true;\n const retried = await attempt(true);\n if (retried.rejection) {\n // attempt(true) never returns a rejection sentinel (dropResponseFormat\n // disables the gate); narrow defensively.\n throw classifyApiError(\n \"openai\",\n new Response(null, { status: 400 }),\n undefined,\n );\n }\n outcome = retried;\n }\n const response = outcome.response;\n\n const streamWarnings = [...uploaderWarnings];\n if (droppedResponseFormat) {\n streamWarnings.push(\n \"response_format was rejected by the OpenAI-compatible route (HTTP 400); the request was retried once without response_format and structured-output formatting was NOT enforced.\",\n );\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n // No streaming body \u2014 fall back to a single terminal result from the parsed payload.\n const payload = (await readPayload(response)) as {\n choices?: Array<{ message?: { content?: unknown } }>;\n };\n yield {\n type: \"result\",\n result: buildOpenAiStreamResult(\n context,\n extractText(payload.choices?.[0]?.message?.content),\n [],\n undefined,\n streamWarnings,\n ),\n };\n return;\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let accumulatedText = \"\";\n // Tool-call fragments are BUFFERED by `index` and never JSON.parsed per chunk:\n // OpenAI streams a tool call's `function.name` on the first fragment and the\n // `function.arguments` JSON across N later fragments. Parsing a partial args\n // string would throw out of this generator and abort the whole stream with no\n // terminal result; instead we concatenate by index and parse ONCE at the end.\n const toolCallFragments = new Map<\n number,\n { id?: string; name?: string; argsString: string }\n >();\n let usage: OpenAiStreamUsage | undefined;\n let drained = false;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (context.abort.signal.aborted) {\n // Mid-stream abort: rethrow so the client surfaces the canonical aborted/timeout code (it\n // never reaches a terminal event). The connection is released in the `finally` via\n // `reader.cancel()` (R17 \u2014 fires whether we throw here OR the consumer calls return()).\n throw new AiConnectError(\"aborted\", \"Operation aborted.\");\n }\n const { done, value } = await reader.read();\n if (done) {\n drained = true;\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n let newlineIndex = buffer.indexOf(\"\\n\");\n while (newlineIndex !== -1) {\n const line = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n newlineIndex = buffer.indexOf(\"\\n\");\n if (!line.startsWith(\"data:\")) {\n continue;\n }\n const payloadText = line.slice(\"data:\".length).trim();\n if (payloadText === \"[DONE]\") {\n continue;\n }\n let chunk: OpenAiStreamChunk;\n try {\n chunk = JSON.parse(payloadText) as OpenAiStreamChunk;\n } catch {\n continue;\n }\n const delta = chunk.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : \"\";\n if (text.length > 0) {\n accumulatedText += text;\n yield { type: \"delta\", text };\n }\n if (Array.isArray(delta?.tool_calls)) {\n for (const fragment of delta.tool_calls) {\n accumulateOpenAiToolCallFragment(toolCallFragments, fragment);\n }\n }\n if (chunk.usage) {\n usage = chunk.usage;\n }\n }\n }\n } finally {\n // R17: if the stream was NOT fully drained (mid-stream abort, OR the consumer called\n // iterator.return() to stop early), cancel the reader so the underlying connection is released\n // from our side even when a non-compliant FetchLike ignored init.signal.\n if (!drained) {\n await reader.cancel().catch(() => {});\n }\n reader.releaseLock?.();\n }\n\n // Assemble + parse the buffered tool-call fragments ONCE, at stream end.\n const toolCalls = assembleOpenAiToolCalls(toolCallFragments);\n\n yield {\n type: \"result\",\n result: buildOpenAiStreamResult(\n context,\n accumulatedText,\n toolCalls,\n usage,\n streamWarnings,\n ),\n };\n}\n\n/** One OpenAI streaming `tool_calls` delta fragment (R17). */\ninterface OpenAiToolCallFragment {\n index?: unknown;\n id?: unknown;\n function?: { name?: unknown; arguments?: unknown };\n}\n\n/**\n * Fold one streamed `tool_calls` delta fragment into the by-`index` buffer.\n * Appends the `function.arguments` string delta verbatim (NO per-chunk parse)\n * and latches the first non-empty `id`/`function.name` seen for that index. A\n * fragment whose `index` is absent falls back to the current map size so a\n * single un-indexed call still accumulates coherently.\n */\nfunction accumulateOpenAiToolCallFragment(\n fragments: Map<number, { id?: string; name?: string; argsString: string }>,\n fragment: OpenAiToolCallFragment,\n): void {\n if (!fragment || typeof fragment !== \"object\") {\n return;\n }\n const index =\n typeof fragment.index === \"number\" ? fragment.index : fragments.size;\n const existing = fragments.get(index) ?? { argsString: \"\" };\n if (\n existing.id === undefined &&\n typeof fragment.id === \"string\" &&\n fragment.id.trim().length > 0\n ) {\n existing.id = fragment.id;\n }\n const name = fragment.function?.name;\n if (\n existing.name === undefined &&\n typeof name === \"string\" &&\n name.trim().length > 0\n ) {\n existing.name = name;\n }\n const args = fragment.function?.arguments;\n if (typeof args === \"string\") {\n existing.argsString += args;\n }\n fragments.set(index, existing);\n}\n\n/**\n * Assemble the buffered fragments into a synthetic non-streaming `tool_calls`\n * payload and parse it ONCE through the shared `openAiToolCallsFromPayload`\n * (which runs `parseToolArguments` on the fully-concatenated args string).\n * Fragments are emitted in ascending index order so the call ordering matches\n * the wire. A fragment that never received a `name` is dropped (same contract\n * as the non-streaming path).\n */\nfunction assembleOpenAiToolCalls(\n fragments: Map<number, { id?: string; name?: string; argsString: string }>,\n): ToolCallInput[] {\n if (fragments.size === 0) {\n return [];\n }\n const ordered = [...fragments.entries()]\n .sort((a, b) => a[0] - b[0])\n .map(([, fragment]) => ({\n ...(fragment.id !== undefined ? { id: fragment.id } : {}),\n function: {\n ...(fragment.name !== undefined ? { name: fragment.name } : {}),\n arguments: fragment.argsString,\n },\n }));\n return openAiToolCallsFromPayload({\n choices: [{ message: { tool_calls: ordered } }],\n });\n}\n\ninterface OpenAiStreamUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n}\n\ninterface OpenAiStreamChunk {\n choices?: Array<{\n delta?: { content?: unknown; tool_calls?: OpenAiToolCallFragment[] };\n }>;\n usage?: OpenAiStreamUsage;\n}\n\n/**\n * Build the terminal {@link GenerateResult} for the SSE producer from the accumulated text/usage.\n * Usage seeds `calls:1` ONLY when the stream reported a usage block (never fabricated, R17).\n */\nfunction buildOpenAiStreamResult(\n context: GenerateContext,\n text: string,\n toolCalls: ToolCallInput[],\n usage: OpenAiStreamUsage | undefined,\n warnings: string[],\n): GenerateResult {\n const hasUsage =\n usage?.prompt_tokens !== undefined ||\n usage?.completion_tokens !== undefined ||\n usage?.completion_tokens_details?.reasoning_tokens !== undefined;\n return {\n route: context.route,\n text,\n attachments: [],\n warnings: [...warnings],\n attempts: [],\n ...(toolCalls.length > 0 ? { toolCalls } : {}),\n ...(hasUsage\n ? {\n usage: {\n calls: 1,\n ...(usage?.prompt_tokens !== undefined\n ? { inputTokens: usage.prompt_tokens }\n : {}),\n ...(usage?.completion_tokens !== undefined\n ? { outputTokens: usage.completion_tokens }\n : {}),\n ...(usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n reasoningTokens:\n usage.completion_tokens_details.reasoning_tokens,\n }\n : {}),\n },\n }\n : {}),\n };\n}\n\nasync function runOpenAiImage(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const referenceImages = imageReferenceFiles(context);\n const bundle = buildImagePromptBundle({\n request: context.request,\n model: context.route.model,\n referenceImages,\n });\n const baseFields = buildImageRequestFields(context, bundle);\n const useEditEndpoint = shouldUseImageEditEndpoint(context);\n const endpoint = useEditEndpoint\n ? resolveOpenAiImageEditEndpoint(context.route)\n : resolveOpenAiEndpoint(context.route, \"image\");\n transportSummary(\n context,\n useEditEndpoint ? \"openai-image-edit\" : \"openai-image\",\n endpoint,\n \"POST\",\n false,\n {\n ...baseFields,\n source_image: Boolean(context.request.image?.sourceImage),\n mask: Boolean(context.request.image?.mask),\n reference_image_count: referenceImages.length,\n },\n );\n const response = await fetchImpl(endpoint, useEditEndpoint\n ? {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n },\n body: await buildImageEditFormData(context, baseFields),\n signal: context.abort.signal,\n }\n : {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(baseFields),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"openai\", response, payload);\n }\n\n return {\n data: {\n request: bundle,\n response: payload,\n },\n attachments: imageAttachmentsFromPayload(payload),\n };\n}\n\nasync function runAnthropic(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const body = await anthropicRequest(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const requestBody = {\n model: context.route.model,\n max_tokens: parameters?.maxTokens ?? 4096,\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { top_p: parameters.topP } : {}),\n ...(parameters?.topK !== undefined ? { top_k: parameters.topK } : {}),\n ...(stopSequences(parameters?.stop)\n ? { stop_sequences: stopSequences(parameters?.stop) }\n : {}),\n ...body,\n ...(anthropicTools(parameters?.tools)\n ? { tools: anthropicTools(parameters?.tools) }\n : {}),\n ...(anthropicToolChoice(parameters?.toolChoice)\n ? { tool_choice: anthropicToolChoice(parameters?.toolChoice) }\n : {}),\n ...(anthropicThinking(parameters?.thinking)\n ? { thinking: anthropicThinking(parameters?.thinking) }\n : {}),\n ...(parameters?.metadata ? { metadata: parameters.metadata } : {}),\n ...(providerExtra(context) ?? {}),\n };\n const endpoint = resolveAnthropicEndpoint(context.route);\n transportSummary(context, \"anthropic-messages\", endpoint, \"POST\", false, requestBody);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(requestBody),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"anthropic\", response, payload);\n }\n\n const data = payload as {\n content?: Array<{ text?: string }>;\n usage?: { input_tokens?: number; output_tokens?: number };\n };\n\n return {\n text: extractText(data.content),\n data,\n ...(anthropicToolCallsFromPayload(data).length > 0\n ? { toolCalls: anthropicToolCallsFromPayload(data) }\n : {}),\n ...(uploaderWarnings.length > 0 ? { warnings: uploaderWarnings } : {}),\n ...(data.usage?.input_tokens !== undefined ||\n data.usage?.output_tokens !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usage?.input_tokens !== undefined\n ? { inputTokens: data.usage.input_tokens }\n : {}),\n ...(data.usage?.output_tokens !== undefined\n ? { outputTokens: data.usage.output_tokens }\n : {}),\n },\n }\n : {}),\n };\n}\n\nasync function runGemini(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n if (context.request.operation === \"image\") {\n return runGeminiImage(fetchImpl, context);\n }\n\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const body = await geminiRequest(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const generationConfig = {\n ...(parameters?.maxTokens !== undefined\n ? { maxOutputTokens: parameters.maxTokens }\n : {}),\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters?.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopSequences(parameters?.stop)\n ? { stopSequences: stopSequences(parameters?.stop) }\n : {}),\n ...(parameters?.candidateCount !== undefined\n ? { candidateCount: parameters.candidateCount }\n : {}),\n ...(parameters?.presencePenalty !== undefined\n ? { presencePenalty: parameters.presencePenalty }\n : {}),\n ...(parameters?.frequencyPenalty !== undefined\n ? { frequencyPenalty: parameters.frequencyPenalty }\n : {}),\n ...(parameters?.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(geminiResponseFormat(parameters?.responseFormat) ?? {}),\n ...(geminiThinkingConfig(parameters?.thinking)\n ? { thinkingConfig: geminiThinkingConfig(parameters?.thinking) }\n : {}),\n };\n const provider = context.route.provider;\n const endpoint = resolveGeminiTextEndpoint(context.route);\n const requestBody = {\n ...body,\n ...(Object.keys(generationConfig).length > 0\n ? { generationConfig }\n : {}),\n ...(geminiTools(parameters?.tools)\n ? { tools: geminiTools(parameters?.tools) }\n : {}),\n ...(geminiToolConfig(parameters?.toolChoice)\n ? { toolConfig: geminiToolConfig(parameters?.toolChoice) }\n : {}),\n ...(parameters?.safetySettings\n ? { safetySettings: parameters.safetySettings }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n transportSummary(context, \"gemini-generate-content\", endpoint, \"POST\", false, requestBody);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n ...geminiApiKeyHeaders(apiKey),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(provider, response, payload);\n }\n\n const data = payload as {\n candidates?: Array<{\n content?: {\n parts?: Array<{ text?: string; thought?: boolean }>;\n };\n }>;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n thoughtsTokenCount?: number;\n };\n };\n\n const geminiThoughts = extractThoughts(data.candidates?.[0]?.content?.parts);\n return {\n text: extractText(data.candidates?.[0]?.content?.parts),\n // The model's `{ thought: true }` parts, separated from the answer (consumers route this to a thinking UI).\n ...(geminiThoughts ? { reasoning: geminiThoughts } : {}),\n data,\n ...(geminiToolCallsFromPayload(data).length > 0\n ? { toolCalls: geminiToolCallsFromPayload(data) }\n : {}),\n ...((() => {\n const warnings = [...uploaderWarnings];\n if (parameters?.candidateCount && parameters.candidateCount > 1) {\n warnings.push(\n \"candidateCount > 1 is forwarded to Gemini text routes, but the normalized result returns only the first candidate.\",\n );\n }\n return warnings.length > 0 ? { warnings } : {};\n })()),\n // INV-USAGE-1: gate on the PRESENCE of an actual token field (mirrors\n // OpenAI/Anthropic), never on `usageMetadata` truthiness. A present-but-empty\n // `usageMetadata:{}` carries no tokens, so fabricating `usage:{calls:1}` would\n // invent a billed call that never happened.\n ...(data.usageMetadata?.promptTokenCount !== undefined ||\n data.usageMetadata?.candidatesTokenCount !== undefined ||\n data.usageMetadata?.thoughtsTokenCount !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usageMetadata?.promptTokenCount !== undefined\n ? { inputTokens: data.usageMetadata.promptTokenCount }\n : {}),\n ...(data.usageMetadata?.candidatesTokenCount !== undefined\n ? { outputTokens: data.usageMetadata.candidatesTokenCount }\n : {}),\n ...(data.usageMetadata?.thoughtsTokenCount !== undefined\n ? { reasoningTokens: data.usageMetadata.thoughtsTokenCount }\n : {}),\n },\n }\n : {}),\n };\n}\n\nasync function runGeminiImage(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const referenceImages = imageReferenceFiles(context);\n const bundle = buildImagePromptBundle({\n request: context.request,\n model: context.route.model,\n referenceImages,\n });\n const baseFields = buildImageRequestFields(context, bundle);\n const useEditEndpoint = shouldUseImageEditEndpoint(context);\n const endpoint = useEditEndpoint\n ? resolveGeminiImageEditEndpoint(context.route)\n : resolveGeminiImageEndpoint(context.route);\n transportSummary(\n context,\n useEditEndpoint ? \"gemini-image-edit\" : \"gemini-image\",\n endpoint,\n \"POST\",\n false,\n {\n ...baseFields,\n source_image: Boolean(context.request.image?.sourceImage),\n mask: Boolean(context.request.image?.mask),\n reference_image_count: referenceImages.length,\n },\n );\n const response = await fetchImpl(endpoint, useEditEndpoint\n ? {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n },\n body: await buildImageEditFormData(context, baseFields),\n signal: context.abort.signal,\n }\n : {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(baseFields),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(context.route.provider, response, payload);\n }\n\n return {\n data: {\n request: bundle,\n response: payload,\n },\n attachments: imageAttachmentsFromPayload(payload),\n };\n}\n\nfunction verifyApiRoute(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n) {\n resolveApiKey(route, runtime);\n return [];\n}\n\nexport function createDefaultRouteHandlers(\n options: {\n fetch?: FetchLike;\n } = {},\n): RouteHandlerRegistry {\n const fetchImpl = getFetch(options.fetch);\n\n return {\n \"openai:api\": {\n async generate(context) {\n return runOpenAi(fetchImpl, context);\n },\n stream(context) {\n return runOpenAiStream(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverOpenAiModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"OpenAI API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n \"anthropic:api\": {\n async generate(context) {\n return runAnthropic(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverAnthropicModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"Anthropic API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n \"gemini:api\": {\n async generate(context) {\n return runGemini(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverGeminiModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"Gemini API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n };\n}\n", "export const AI_CONNECT_DEFAULT_ACP_COMMANDS: Record<string, string> = {\n \"anthropic:claude-code-acp\": \"npx -y @agentclientprotocol/claude-agent-acp@^0.25.0\",\n \"openai:codex-acp\": \"npx @zed-industries/codex-acp@^0.11.1\",\n \"opencode:opencode-acp\": \"opencode acp\",\n};\n", "export type ServerTransportPreset = {\n id: string;\n label: string;\n command: string;\n transportId: string;\n};\n\nexport const AI_CONNECT_DEFAULT_SERVER_PRESETS: Record<\n \"opencode\",\n ServerTransportPreset\n> =\n {\n opencode: {\n id: \"opencode\",\n label: \"OpenCode Server\",\n command: \"opencode serve\",\n transportId: \"opencode-server\",\n },\n };\n\nexport const AI_CONNECT_DEFAULT_SERVER_COMMANDS: Record<string, string> = {\n \"opencode:opencode-server\": AI_CONNECT_DEFAULT_SERVER_PRESETS.opencode.command,\n};\n", "import { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport { AI_CONNECT_DEFAULT_CLI_COMMANDS } from \"./cli-presets.js\";\nimport { AI_CONNECT_DEFAULT_SERVER_COMMANDS } from \"./server-presets.js\";\nimport type { RuntimeKind, TransportKind } from \"./types.js\";\n\nexport type TextTransportCatalogEntry = {\n providerId: string;\n providerLabel: string;\n transportKind: TransportKind;\n transportId: string;\n transportLabel: string;\n runtime: RuntimeKind | \"universal\";\n defaultModel: string;\n defaultBaseUrl?: string;\n defaultCommand?: string;\n};\n\nexport type TextProviderCatalogEntry = {\n providerId: string;\n label: string;\n transports: TextTransportCatalogEntry[];\n};\n\nconst TEXT_PROVIDER_CATALOG: TextProviderCatalogEntry[] = [\n {\n providerId: \"openai\",\n label: \"OpenAI\",\n transports: [\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"OpenAI API\",\n runtime: \"universal\",\n defaultModel: \"gpt-4.1\",\n defaultBaseUrl: \"\",\n },\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"cli\",\n transportId: \"codex-cli\",\n transportLabel: \"Codex CLI\",\n runtime: \"local\",\n defaultModel: \"gpt-5.4/xhigh\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"openai:codex-cli\"]!,\n },\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"acp\",\n transportId: \"codex-acp\",\n transportLabel: \"Codex ACP\",\n runtime: \"local\",\n defaultModel: \"gpt-5.4/xhigh\",\n defaultCommand: AI_CONNECT_DEFAULT_ACP_COMMANDS[\"openai:codex-acp\"]!,\n },\n ],\n },\n {\n providerId: \"anthropic\",\n label: \"Anthropic\",\n transports: [\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"Anthropic API\",\n runtime: \"universal\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultBaseUrl: \"\",\n },\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"cli\",\n transportId: \"claude-cli\",\n transportLabel: \"Claude CLI\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"anthropic:claude-cli\"]!,\n },\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"acp\",\n transportId: \"claude-code-acp\",\n transportLabel: \"Claude Code ACP\",\n runtime: \"local\",\n defaultModel: \"default\",\n defaultCommand:\n AI_CONNECT_DEFAULT_ACP_COMMANDS[\"anthropic:claude-code-acp\"]!,\n },\n ],\n },\n {\n providerId: \"openclaude\",\n label: \"OpenClaude\",\n transports: [\n {\n providerId: \"openclaude\",\n providerLabel: \"OpenClaude\",\n transportKind: \"cli\",\n transportId: \"openclaude-cli\",\n transportLabel: \"OpenClaude CLI\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultCommand:\n AI_CONNECT_DEFAULT_CLI_COMMANDS[\"openclaude:openclaude-cli\"]!,\n },\n ],\n },\n {\n providerId: \"gemini\",\n label: \"Gemini\",\n transports: [\n {\n providerId: \"gemini\",\n providerLabel: \"Gemini\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"Gemini API\",\n runtime: \"universal\",\n defaultModel: \"gemini-3.1-flash-lite\",\n defaultBaseUrl: \"\",\n },\n ],\n },\n {\n providerId: \"pi\",\n label: \"pi\",\n transports: [\n {\n providerId: \"pi\",\n providerLabel: \"pi\",\n transportKind: \"cli\",\n transportId: \"pi-cli\",\n transportLabel: \"pi CLI\",\n runtime: \"local\",\n defaultModel: \"gemini-3.1-pro-low\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"pi:pi-cli\"]!,\n },\n ],\n },\n {\n providerId: \"opencode\",\n label: \"OpenCode\",\n transports: [\n {\n providerId: \"opencode\",\n providerLabel: \"OpenCode\",\n transportKind: \"server\",\n transportId: \"opencode-server\",\n transportLabel: \"OpenCode Server\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4\",\n defaultCommand:\n AI_CONNECT_DEFAULT_SERVER_COMMANDS[\"opencode:opencode-server\"]!,\n },\n {\n providerId: \"opencode\",\n providerLabel: \"OpenCode\",\n transportKind: \"acp\",\n transportId: \"opencode-acp\",\n transportLabel: \"OpenCode ACP\",\n runtime: \"local\",\n defaultModel: \"default\",\n defaultCommand: AI_CONNECT_DEFAULT_ACP_COMMANDS[\"opencode:opencode-acp\"]!,\n },\n ],\n },\n];\n\nfunction matchesRuntime(\n transport: TextTransportCatalogEntry,\n runtime: RuntimeKind | undefined,\n): boolean {\n if (!runtime) {\n return true;\n }\n if (transport.runtime === \"universal\") {\n return true;\n }\n return transport.runtime === runtime;\n}\n\nexport function listTextProviderCatalog(options: {\n runtime?: RuntimeKind;\n} = {}): TextProviderCatalogEntry[] {\n const runtime = options.runtime;\n return TEXT_PROVIDER_CATALOG.map((provider) => ({\n ...provider,\n transports: provider.transports.filter((transport) =>\n matchesRuntime(transport, runtime),\n ),\n })).filter((provider) => provider.transports.length > 0);\n}\n\nexport function getTextProviderCatalogEntry(\n providerId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextProviderCatalogEntry | undefined {\n return listTextProviderCatalog(options).find(\n (provider) => provider.providerId === providerId,\n );\n}\n\nexport function getTextTransportPreset(\n providerId: string,\n transportKind: TransportKind,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n return getTextProviderCatalogEntry(providerId, options)?.transports.find(\n (transport) => transport.transportKind === transportKind,\n );\n}\n\nexport function getTextTransportPresetById(\n providerId: string,\n transportId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n return getTextProviderCatalogEntry(providerId, options)?.transports.find(\n (transport) => transport.transportId === transportId,\n );\n}\n\nexport function getDefaultTextTransportPreset(\n providerId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n const provider = getTextProviderCatalogEntry(providerId, options);\n if (!provider) {\n return undefined;\n }\n return (\n provider.transports.find((transport) => transport.transportKind === \"api\") ||\n provider.transports[0]\n );\n}\n", "import { createClient } from \"./client.js\";\nimport { defineConfig, isNormalizedConfig } from \"./config.js\";\nimport { createDefaultRouteHandlers } from \"./default-handlers.js\";\nimport { createBrowserRuntimeEnvironment } from \"./runtime.js\";\nimport type {\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CreateClientOptions,\n RuntimeEnvironment,\n} from \"./types.js\";\n\nexport function createBrowserClient(\n configOrInput: AiConnectConfig | AiConnectConfigInput,\n options: Omit<CreateClientOptions, \"runtime\"> & {\n runtime?: Partial<RuntimeEnvironment>;\n } = {},\n): AiConnectClient {\n const config = isNormalizedConfig(configOrInput)\n ? configOrInput\n : defineConfig(configOrInput);\n\n return createClient(config, {\n ...options,\n handlers: {\n ...createDefaultRouteHandlers(\n options.fetch ? { fetch: options.fetch } : {},\n ),\n ...(options.handlers ?? {}),\n },\n runtime: createBrowserRuntimeEnvironment(options.runtime),\n });\n}\n", "import { accessSync, constants } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\n\nimport { createClient } from \"./client.js\";\nimport { defineConfig, isNormalizedConfig } from \"./config.js\";\nimport { createDefaultRouteHandlers } from \"./default-handlers.js\";\nimport { createLocalRouteHandlers } from \"./local-handlers.js\";\nimport { createLocalRuntimeEnvironment } from \"./runtime.js\";\nimport type {\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CreateClientOptions,\n RuntimeEnvironment,\n} from \"./types.js\";\n\nfunction executableExists(pathValue: string): boolean {\n try {\n accessSync(pathValue, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findCommand(command: string): boolean {\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n return executableExists(command);\n }\n\n const pathValue = process.env.PATH ?? \"\";\n const segments = pathValue.split(delimiter).filter(Boolean);\n const extensions =\n process.platform === \"win32\" ? [\"\", \".exe\", \".cmd\", \".bat\"] : [\"\"];\n\n for (const segment of segments) {\n for (const extension of extensions) {\n if (executableExists(join(segment, `${command}${extension}`))) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function createDefaultLocalRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createLocalRuntimeEnvironment({\n ...overrides,\n getEnv: overrides.getEnv ?? ((name) => process.env[name]),\n hasCommand: overrides.hasCommand ?? ((command) => findCommand(command)),\n });\n}\n\nexport function createLocalClient(\n configOrInput: AiConnectConfig | AiConnectConfigInput,\n options: Omit<CreateClientOptions, \"runtime\"> & {\n runtime?: Partial<RuntimeEnvironment>;\n } = {},\n): AiConnectClient {\n const config = isNormalizedConfig(configOrInput)\n ? configOrInput\n : defineConfig(configOrInput);\n const localHandlers = createLocalRouteHandlers({\n ...(options.acp ? { acp: options.acp } : {}),\n ...(options.cli ? { cli: options.cli } : {}),\n ...(options.server || options.fetch\n ? {\n server: {\n ...(options.server ?? {}),\n ...(options.fetch && !options.server?.fetch\n ? { fetch: options.fetch }\n : {}),\n },\n }\n : {}),\n });\n\n return createClient(config, {\n ...options,\n handlers: {\n ...createDefaultRouteHandlers(\n options.fetch ? { fetch: options.fetch } : {},\n ),\n ...localHandlers.handlers,\n ...(options.handlers ?? {}),\n },\n runtime: createDefaultLocalRuntimeEnvironment(options.runtime),\n dispose: async () => {\n await localHandlers.dispose();\n await options.dispose?.();\n },\n });\n}\n", "import { Buffer } from \"node:buffer\";\nimport { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport {\n isPortableDocumentFile,\n materializePortableFile,\n preparePortableFile,\n} from \"./files.js\";\nimport { fillConfiguredContextLength } from \"./model-reference.js\";\nimport type {\n AcpLaunchOptions,\n AcpModelCatalog,\n AcpModelInfo,\n AcpClientOptions,\n AcpPermissionMode,\n AcpSessionCacheOptions,\n DiscoverAcpModelsContext,\n GenerateContext,\n GenerateResult,\n GenerateStreamEvent,\n NormalizedRoute,\n PortableFile,\n PortableFileInput,\n RuntimeEnvironment,\n UsageInfo,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype JsonRpcId = number | string | null;\n\ntype JsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: Record<string, unknown>;\n};\n\ntype JsonRpcResponse = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n};\n\ntype JsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n};\n\ntype JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\ntype PromptBlock =\n | {\n type: \"text\";\n text: string;\n }\n | {\n type: \"image\";\n mimeType: string;\n data: string;\n }\n | {\n type: \"resource_link\";\n uri: string;\n title?: string;\n name?: string;\n }\n | {\n type: \"resource\";\n resource: {\n uri: string;\n text?: string;\n // ACP/MCP EmbeddedResource blob shape (C6): base64 contents for binary\n // resources such as PDFs that have no text representation.\n blob?: string;\n mimeType?: string;\n };\n };\n\ntype PendingRequest = {\n resolve: (value: unknown) => void;\n reject: (error: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n};\n\ntype AcpLaunchRuntime = {\n commandLine: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n};\n\ntype PreparedAcpLaunchRuntime = AcpLaunchRuntime & {\n launch: AcpLaunchOptions;\n cleanup?: () => Promise<void>;\n};\n\ntype AcpSandboxPaths = {\n root: string;\n home: string;\n config: string;\n cache: string;\n data: string;\n};\n\ntype AcpPromptOutput = {\n text: string;\n attachments: PortableFileInput[];\n usage?: UsageInfo;\n warnings: string[];\n data: {\n command: string;\n sessionId: string;\n stopReason?: string;\n };\n};\n\ntype AcpAuthRequest = {\n methodId: string;\n params: Record<string, unknown>;\n lifecycleKeys: string[];\n};\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_SESSION_CACHE_IDLE_TTL_MS = 60_000;\nconst IMAGE_EXTENSIONS = new Map<string, string>([\n [\".png\", \"image/png\"],\n [\".jpg\", \"image/jpeg\"],\n [\".jpeg\", \"image/jpeg\"],\n [\".webp\", \"image/webp\"],\n [\".gif\", \"image/gif\"],\n [\".svg\", \"image/svg+xml\"],\n]);\n\nconst TEXT_EXTENSIONS = new Set([\n \".txt\",\n \".md\",\n \".json\",\n \".jsonl\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".ts\",\n \".tsx\",\n \".css\",\n \".html\",\n \".xml\",\n \".yaml\",\n \".yml\",\n \".toml\",\n \".ini\",\n \".env\",\n \".csv\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\n \"validation_error\",\n \"ACP command line is empty.\",\n );\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction normalizeLaunchOptions(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): AcpLaunchOptions {\n return {\n contextMode:\n route.transport.launch?.contextMode ??\n options?.launch?.contextMode ??\n \"workspace\",\n skillsMode:\n route.transport.launch?.skillsMode ??\n options?.launch?.skillsMode ??\n \"default\",\n };\n}\n\nfunction appendCommandArg(\n commandLine: string,\n argument: string,\n): string {\n const { args } = splitCommandLine(commandLine);\n if (args.includes(argument)) {\n return commandLine;\n }\n\n return `${commandLine} ${argument}`;\n}\n\nfunction appendCommandSnippet(\n commandLine: string,\n snippet: string,\n): string {\n return `${commandLine} ${snippet}`;\n}\n\nfunction resolveHomeDir(env: NodeJS.ProcessEnv): string {\n return env.HOME ?? os.homedir();\n}\n\nfunction resolveXdgConfigHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_CONFIG_HOME ?? path.join(resolveHomeDir(env), \".config\");\n}\n\nfunction resolveXdgCacheHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_CACHE_HOME ?? path.join(resolveHomeDir(env), \".cache\");\n}\n\nfunction resolveXdgDataHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_DATA_HOME ?? path.join(resolveHomeDir(env), \".local\", \"share\");\n}\n\nfunction resolveCodexHome(env: NodeJS.ProcessEnv): string {\n return env.CODEX_HOME ?? path.join(resolveHomeDir(env), \".codex\");\n}\n\nfunction resolveCodexSqliteHome(env: NodeJS.ProcessEnv): string {\n return env.CODEX_SQLITE_HOME ?? resolveCodexHome(env);\n}\n\nfunction resolveOpencodeConfigDir(env: NodeJS.ProcessEnv): string {\n return (\n env.OPENCODE_CONFIG_DIR ??\n path.join(resolveXdgConfigHome(env), \"opencode\")\n );\n}\n\nasync function createSandboxPaths(\n prefix: string,\n): Promise<AcpSandboxPaths> {\n const root = await fs.mkdtemp(path.join(os.tmpdir(), prefix));\n const home = path.join(root, \"home\");\n const config = path.join(root, \"config\");\n const cache = path.join(root, \"cache\");\n const data = path.join(root, \"data\");\n\n await Promise.all(\n [home, config, cache, data].map((directory) =>\n fs.mkdir(directory, { recursive: true }),\n ),\n );\n\n return {\n root,\n home,\n config,\n cache,\n data,\n };\n}\n\nasync function maybeCopyFile(\n sourcePath: string,\n destinationPath: string,\n): Promise<void> {\n try {\n await fs.mkdir(path.dirname(destinationPath), { recursive: true });\n await fs.copyFile(sourcePath, destinationPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\nasync function maybeCopyDirectory(\n sourcePath: string,\n destinationPath: string,\n): Promise<void> {\n try {\n await fs.cp(sourcePath, destinationPath, { recursive: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\nasync function removeIfExists(targetPath: string): Promise<void> {\n await fs.rm(targetPath, { recursive: true, force: true }).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n}\n\nasync function readJsonFile(\n filePath: string,\n): Promise<Record<string, unknown> | undefined> {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(raw);\n return isRecord(parsed) ? parsed : undefined;\n } catch (error) {\n if (\n error instanceof SyntaxError ||\n (error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction mergeRecordValues(\n current: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...current };\n\n for (const [key, value] of Object.entries(next)) {\n const existing = merged[key];\n if (isRecord(existing) && isRecord(value)) {\n merged[key] = mergeRecordValues(existing, value);\n continue;\n }\n merged[key] = value;\n }\n\n return merged;\n}\n\nasync function writeJsonFile(\n filePath: string,\n value: Record<string, unknown>,\n): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nasync function writeTextFile(\n filePath: string,\n value: string,\n): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, value, \"utf8\");\n}\n\nasync function prepareOpenCodeLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): Promise<PreparedAcpLaunchRuntime> {\n if (\n launch.contextMode === \"workspace\" &&\n launch.skillsMode === \"default\"\n ) {\n return {\n ...base,\n launch,\n };\n }\n\n const sandbox = await createSandboxPaths(\"ai-connect-opencode-acp-\");\n const originalConfigDir = resolveOpencodeConfigDir(base.env);\n const sandboxConfigDir = path.join(sandbox.config, \"opencode\");\n await fs.mkdir(sandboxConfigDir, { recursive: true });\n await Promise.all(\n [\n \"config.json\",\n \"config.jsonc\",\n \"opencode.json\",\n \"opencode.jsonc\",\n \"tui.json\",\n \"tui.jsonc\",\n ].map((fileName) =>\n maybeCopyFile(\n path.join(originalConfigDir, fileName),\n path.join(sandboxConfigDir, fileName),\n ),\n ),\n );\n\n return {\n commandLine: base.commandLine,\n cwd: base.cwd,\n env: {\n ...base.env,\n OPENCODE_CONFIG_DIR: sandboxConfigDir,\n ...(launch.contextMode === \"clean\"\n ? {\n OPENCODE_DISABLE_PROJECT_CONFIG: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE_PROMPT: \"1\",\n }\n : {}),\n ...(launch.skillsMode === \"disabled\"\n ? {\n OPENCODE_DISABLE_EXTERNAL_SKILLS: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE_SKILLS: \"1\",\n }\n : {}),\n },\n launch,\n cleanup: async () => {\n await removeIfExists(sandbox.root);\n },\n };\n}\n\nasync function prepareCodexLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): Promise<PreparedAcpLaunchRuntime> {\n if (\n launch.contextMode === \"workspace\" &&\n launch.skillsMode === \"default\"\n ) {\n return {\n ...base,\n launch,\n };\n }\n\n const sandbox = await createSandboxPaths(\"ai-connect-codex-acp-\");\n const originalCodexHome = resolveCodexHome(base.env);\n const originalCodexSqliteHome = resolveCodexSqliteHome(base.env);\n const sandboxCodexHome = path.join(sandbox.home, \".codex\");\n const isolatedCwd =\n launch.contextMode === \"clean\" || launch.skillsMode === \"disabled\"\n ? sandbox.root\n : base.cwd;\n\n await Promise.all([\n maybeCopyFile(\n path.join(originalCodexHome, \"config.toml\"),\n path.join(sandboxCodexHome, \"config.toml\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"auth.json\"),\n path.join(sandboxCodexHome, \"auth.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \".credentials.json\"),\n path.join(sandboxCodexHome, \".credentials.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"models_cache.json\"),\n path.join(sandboxCodexHome, \"models_cache.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"version.json\"),\n path.join(sandboxCodexHome, \"version.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \".codex-global-state.json\"),\n path.join(sandboxCodexHome, \".codex-global-state.json\"),\n ),\n ]);\n\n let commandLine = base.commandLine;\n const cleanOverrides = [\n \"project_doc_max_bytes=0\",\n \"project_doc_fallback_filenames=[]\",\n \"history.persistence=\\\"none\\\"\",\n \"memories.use_memories=false\",\n \"memories.generate_memories=false\",\n \"features.plugins=false\",\n \"features.apps=false\",\n \"features.shell_snapshot=false\",\n \"mcp_servers={}\",\n ];\n\n for (const override of cleanOverrides) {\n commandLine = appendCommandSnippet(commandLine, `-c ${override}`);\n }\n\n if (launch.skillsMode === \"disabled\") {\n commandLine = appendCommandSnippet(\n commandLine,\n \"-c skills.bundled.enabled=false\",\n );\n }\n\n if (launch.contextMode === \"clean\" || launch.skillsMode === \"disabled\") {\n commandLine = appendCommandSnippet(\n commandLine,\n `-c projects.\"${isolatedCwd}\".trust_level=\"trusted\"`,\n );\n }\n\n const env: NodeJS.ProcessEnv = {\n ...base.env,\n HOME: sandbox.home,\n XDG_CONFIG_HOME: sandbox.config,\n XDG_CACHE_HOME: sandbox.cache,\n XDG_DATA_HOME: sandbox.data,\n CODEX_HOME: sandboxCodexHome,\n CODEX_SQLITE_HOME: originalCodexSqliteHome,\n };\n\n for (const key of [\n \"CODEX_THREAD_ID\",\n \"CODEX_INTERNAL_ORIGINATOR_OVERRIDE\",\n \"CODEX_SHELL\",\n \"CODEX_CI\",\n ]) {\n delete env[key];\n }\n\n return {\n commandLine,\n cwd: isolatedCwd,\n env,\n launch,\n cleanup: async () => {\n await removeIfExists(sandbox.root);\n },\n };\n}\n\nfunction prepareClaudeLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): PreparedAcpLaunchRuntime {\n let commandLine = base.commandLine;\n\n if (launch.contextMode === \"clean\") {\n commandLine = appendCommandArg(commandLine, \"--bare\");\n }\n if (launch.skillsMode === \"disabled\") {\n commandLine = appendCommandArg(commandLine, \"--disable-slash-commands\");\n }\n\n return {\n commandLine,\n cwd: base.cwd,\n env: base.env,\n launch,\n };\n}\n\nasync function prepareAcpLaunchRuntime(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n commandLine: string,\n cwdOverride?: string,\n): Promise<PreparedAcpLaunchRuntime> {\n const launch = normalizeLaunchOptions(route, options);\n const base: AcpLaunchRuntime = {\n commandLine,\n cwd: path.resolve(cwdOverride ?? options?.cwd ?? process.cwd()),\n env: {\n ...process.env,\n ...(options?.env ?? {}),\n },\n };\n\n if (route.transport.id === \"opencode-acp\") {\n return prepareOpenCodeLaunchRuntime(base, launch);\n }\n\n if (route.transport.id === \"codex-acp\") {\n return prepareCodexLaunchRuntime(base, launch);\n }\n\n if (route.transport.id === \"claude-code-acp\") {\n return prepareClaudeLaunchRuntime(base, launch);\n }\n\n return {\n ...base,\n launch,\n };\n}\n\nfunction promptTimeout(options: AcpClientOptions | undefined): number {\n return options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n}\n\nfunction basename(value: string): string {\n const normalized = value.replaceAll(\"\\\\\", \"/\");\n const tail = normalized.split(\"/\").pop();\n return tail && tail.length > 0 ? tail : \"file\";\n}\n\nfunction parseDataUrl(value: string): {\n mimeType: string;\n data: string;\n} | null {\n // Tolerate intermediate media-type params before `;base64`, e.g.\n // `data:text/plain;charset=utf-8;base64,...` (F-S1-1, mirrors src/files.ts #14).\n const match = /^data:([^,]*?);base64,(.*)$/i.exec(value);\n if (!match) {\n return null;\n }\n\n const mediaType = (match[1] ?? \"\").split(\";\")[0]?.trim() ?? \"\";\n return {\n mimeType: mediaType.length > 0 ? mediaType : \"application/octet-stream\",\n data: match[2] ?? \"\",\n };\n}\n\nfunction mimeTypeFromPath(filePath: string): string | undefined {\n return IMAGE_EXTENSIONS.get(path.extname(filePath).toLowerCase());\n}\n\nfunction isTextPath(filePath: string): boolean {\n return TEXT_EXTENSIONS.has(path.extname(filePath).toLowerCase());\n}\n\nfunction isWithinRoot(rootDir: string, targetPath: string): boolean {\n const relative = path.relative(rootDir, targetPath);\n return relative.length === 0 || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction buildMessageTranscript(context: GenerateContext): string {\n return context.request.messages\n .map((message) => `${message.role.toUpperCase()}:\\n${message.content}`)\n .join(\"\\n\\n\")\n .trim();\n}\n\nasync function fileToPromptBlocks(file: PortableFile): Promise<PromptBlock[]> {\n // C6: PDF (and any SUPPORTED_DOCUMENT_MIME_TYPES) \u2192 an ACP EmbeddedResource\n // blob via the single decode path. A remote document with only a uri degrades\n // to a resource_link; never an empty blob.\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.base64) {\n return [\n {\n type: \"resource\",\n resource: {\n uri:\n payload.uri ??\n (file.kind === \"path\" && typeof file.source === \"string\"\n ? pathToFileURL(file.source).href\n : `attachment:${file.name}`),\n blob: payload.base64,\n mimeType: payload.mimeType,\n },\n },\n ];\n }\n if (payload.uri) {\n return [\n {\n type: \"resource_link\",\n uri: payload.uri,\n name: file.name,\n title: file.name,\n },\n ];\n }\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n if (parsed && parsed.mimeType.startsWith(\"image/\")) {\n return [\n {\n type: \"image\",\n mimeType: parsed.mimeType,\n data: parsed.data,\n },\n ];\n }\n }\n\n if (file.kind === \"remote\") {\n const source = isRecord(file.source) ? file.source : {};\n const uri = typeof source.uri === \"string\" ? source.uri : undefined;\n if (uri) {\n return [\n {\n type: \"resource_link\",\n uri,\n name: file.name,\n title: file.name,\n },\n ];\n }\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n const imageMimeType = mimeTypeFromPath(file.source);\n if (imageMimeType) {\n const data = await fs.readFile(file.source);\n return [\n {\n type: \"image\",\n mimeType: imageMimeType,\n data: data.toString(\"base64\"),\n },\n ];\n }\n\n if (isTextPath(file.source)) {\n const content = await fs.readFile(file.source, \"utf8\");\n return [\n {\n type: \"resource\",\n resource: {\n uri: pathToFileURL(file.source).href,\n text: content,\n },\n },\n ];\n }\n\n return [\n {\n type: \"resource_link\",\n uri: pathToFileURL(file.source).href,\n name: basename(file.source),\n title: basename(file.source),\n },\n ];\n }\n\n return [\n {\n type: \"text\",\n text: `[attachment] ${file.name}`,\n },\n ];\n}\n\nasync function toPromptBlocks(context: GenerateContext): Promise<PromptBlock[]> {\n const blocks: PromptBlock[] = [];\n const transcript = buildMessageTranscript(context);\n\n if (transcript) {\n blocks.push({\n type: \"text\",\n text: transcript,\n });\n }\n\n for (const attachment of context.request.attachments) {\n const next = await fileToPromptBlocks(attachment);\n blocks.push(...next);\n }\n\n return blocks;\n}\n\nfunction inferPermissionKind(request: Record<string, unknown>): string | undefined {\n const toolCall = isRecord(request.toolCall) ? request.toolCall : undefined;\n const explicitKind =\n toolCall && typeof toolCall.kind === \"string\" ? toolCall.kind : undefined;\n if (explicitKind) {\n return explicitKind;\n }\n\n const title =\n toolCall && typeof toolCall.title === \"string\"\n ? toolCall.title.trim().toLowerCase()\n : \"\";\n if (!title) {\n return undefined;\n }\n\n if (title.includes(\"read\") || title.includes(\"cat\")) {\n return \"read\";\n }\n if (title.includes(\"search\") || title.includes(\"find\") || title.includes(\"grep\")) {\n return \"search\";\n }\n if (title.includes(\"write\") || title.includes(\"edit\") || title.includes(\"patch\")) {\n return \"edit\";\n }\n if (title.includes(\"delete\") || title.includes(\"remove\")) {\n return \"delete\";\n }\n if (title.includes(\"run\") || title.includes(\"execute\") || title.includes(\"bash\")) {\n return \"execute\";\n }\n\n return \"other\";\n}\n\nfunction selectPermissionResponse(\n params: Record<string, unknown>,\n mode: AcpPermissionMode,\n): Record<string, unknown> {\n const options = Array.isArray(params.options)\n ? params.options.filter((value): value is Record<string, unknown> => isRecord(value))\n : [];\n\n const allowOption = options.find((option) => {\n const kind = option.kind;\n return kind === \"allow_once\" || kind === \"allow_always\";\n });\n const rejectOption = options.find((option) => {\n const kind = option.kind;\n return kind === \"reject_once\" || kind === \"reject_always\";\n });\n\n const selected = (optionId: unknown) => ({\n outcome: {\n outcome: \"selected\",\n optionId,\n },\n });\n\n if (mode === \"approve-all\") {\n return selected(\n allowOption?.optionId ?? options[0]?.optionId ?? \"allow-once\",\n );\n }\n\n if (mode === \"approve-reads\") {\n const kind = inferPermissionKind(params);\n if ((kind === \"read\" || kind === \"search\") && allowOption?.optionId) {\n return selected(allowOption.optionId);\n }\n }\n\n if (rejectOption?.optionId) {\n return selected(rejectOption.optionId);\n }\n\n return {\n outcome: {\n outcome: \"cancelled\",\n },\n };\n}\n\nfunction readNumberField(\n record: Record<string, unknown>,\n keys: string[],\n): number | undefined {\n for (const key of keys) {\n if (typeof record[key] === \"number\") {\n return record[key] as number;\n }\n }\n\n return undefined;\n}\n\nfunction normalizeUsageModel(\n value: unknown,\n): UsageInfo[\"modelUsage\"] extends Array<infer T> ? T | undefined : never {\n if (!isRecord(value)) {\n return undefined as never;\n }\n\n const modelId =\n typeof value.modelId === \"string\"\n ? value.modelId\n : typeof value.model === \"string\"\n ? value.model\n : typeof value.id === \"string\"\n ? value.id\n : undefined;\n if (!modelId?.trim()) {\n return undefined as never;\n }\n\n const tokenCount = isRecord(value.token_count) ? value.token_count : undefined;\n const inputTokens =\n readNumberField(value, [\"inputTokens\", \"input_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"input_tokens\", \"inputTokens\"]) : undefined);\n const outputTokens =\n readNumberField(value, [\"outputTokens\", \"output_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"output_tokens\", \"outputTokens\"]) : undefined);\n const totalTokens =\n readNumberField(value, [\"totalTokens\", \"total_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"total_tokens\", \"totalTokens\"]) : undefined);\n const reasoningTokens =\n readNumberField(value, [\"reasoningTokens\", \"reasoning_tokens\", \"thoughtTokens\", \"thought_tokens\"]) ??\n (tokenCount\n ? readNumberField(tokenCount, [\n \"reasoning_tokens\",\n \"reasoningTokens\",\n \"thought_tokens\",\n \"thoughtTokens\",\n ])\n : undefined);\n const cachedReadTokens =\n readNumberField(value, [\"cachedReadTokens\", \"cached_read_tokens\"]) ??\n (tokenCount\n ? readNumberField(tokenCount, [\"cached_read_tokens\", \"cachedReadTokens\"])\n : undefined);\n const name =\n typeof value.name === \"string\" && value.name.trim().length > 0\n ? value.name\n : undefined;\n\n return {\n modelId,\n ...(name ? { name } : {}),\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n } as never;\n}\n\nfunction mergeModelUsage(\n current: UsageInfo[\"modelUsage\"] | undefined,\n next: UsageInfo[\"modelUsage\"] | undefined,\n): UsageInfo[\"modelUsage\"] | undefined {\n if (!current?.length) {\n return next?.length ? [...next] : undefined;\n }\n if (!next?.length) {\n return [...current];\n }\n\n const merged = new Map(current.map((entry) => [entry.modelId, { ...entry }]));\n\n for (const entry of next) {\n const existing = merged.get(entry.modelId);\n if (!existing) {\n merged.set(entry.modelId, { ...entry });\n continue;\n }\n\n merged.set(entry.modelId, {\n ...existing,\n ...(entry.name ? { name: entry.name } : {}),\n ...(entry.inputTokens !== undefined\n ? { inputTokens: (existing.inputTokens ?? 0) + entry.inputTokens }\n : {}),\n ...(entry.outputTokens !== undefined\n ? { outputTokens: (existing.outputTokens ?? 0) + entry.outputTokens }\n : {}),\n ...(entry.totalTokens !== undefined\n ? { totalTokens: (existing.totalTokens ?? 0) + entry.totalTokens }\n : {}),\n ...(entry.reasoningTokens !== undefined\n ? {\n reasoningTokens:\n (existing.reasoningTokens ?? 0) + entry.reasoningTokens,\n }\n : {}),\n ...(entry.cachedReadTokens !== undefined\n ? {\n cachedReadTokens:\n (existing.cachedReadTokens ?? 0) + entry.cachedReadTokens,\n }\n : {}),\n });\n }\n\n return [...merged.values()];\n}\n\nfunction sumOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number | undefined {\n if (left === undefined) {\n return right;\n }\n if (right === undefined) {\n return left;\n }\n\n return left + right;\n}\n\nfunction mergeUsageInfo(\n current: UsageInfo | undefined,\n next: UsageInfo | undefined,\n): UsageInfo | undefined {\n if (!current) {\n return next ? { ...next } : undefined;\n }\n if (!next) {\n return { ...current };\n }\n\n const modelUsage = mergeModelUsage(\n current.modelUsage,\n next.modelUsage,\n );\n\n // INV-USAGE-1: the shallow `...next` spread CLOBBERS `calls`; sum it back so\n // two prompt results yield calls:2 not 1. Must come AFTER `...next`.\n const calls = sumOptionalNumbers(current.calls, next.calls);\n\n return {\n ...current,\n ...next,\n ...(modelUsage ? { modelUsage } : {}),\n ...(calls !== undefined ? { calls } : {}),\n };\n}\n\nfunction usageFromGenericUsageRecord(\n usage: Record<string, unknown>,\n): UsageInfo | undefined {\n const inputTokens = readNumberField(usage, [\"inputTokens\", \"input_tokens\"]);\n const outputTokens = readNumberField(usage, [\"outputTokens\", \"output_tokens\"]);\n const totalTokens = readNumberField(usage, [\"totalTokens\", \"total_tokens\"]);\n const reasoningTokens = readNumberField(usage, [\n \"reasoningTokens\",\n \"reasoning_tokens\",\n \"thoughtTokens\",\n \"thought_tokens\",\n ]);\n const cachedReadTokens = readNumberField(usage, [\n \"cachedReadTokens\",\n \"cached_read_tokens\",\n ]);\n\n const hasAny =\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n totalTokens !== undefined ||\n reasoningTokens !== undefined ||\n cachedReadTokens !== undefined;\n\n return hasAny\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n }\n : undefined;\n}\n\nfunction usageFromMeta(meta: Record<string, unknown>): UsageInfo | undefined {\n const usage = isRecord(meta.usage) ? usageFromGenericUsageRecord(meta.usage) : undefined;\n const durationMs = readNumberField(meta, [\"durationMs\", \"duration_ms\"]);\n\n return mergeUsageInfo(\n usage,\n durationMs !== undefined\n ? {\n durationMs,\n }\n : undefined,\n );\n}\n\nfunction usageFromUpdate(update: Record<string, unknown>): UsageInfo | undefined {\n const generic = usageFromGenericUsageRecord(update);\n const contextWindowUsed = readNumberField(update, [\"used\"]);\n const contextWindowSize = readNumberField(update, [\"size\"]);\n const costRecord = isRecord(update.cost) ? update.cost : undefined;\n const costAmount = costRecord ? readNumberField(costRecord, [\"amount\"]) : undefined;\n const costCurrency =\n costRecord && typeof costRecord.currency === \"string\"\n ? costRecord.currency\n : undefined;\n\n return mergeUsageInfo(\n generic,\n contextWindowUsed !== undefined ||\n contextWindowSize !== undefined ||\n costAmount !== undefined\n ? {\n ...(contextWindowUsed !== undefined ? { contextWindowUsed } : {}),\n ...(contextWindowSize !== undefined ? { contextWindowSize } : {}),\n ...(costAmount !== undefined\n ? {\n cost: {\n amount: costAmount,\n ...(costCurrency ? { currency: costCurrency } : {}),\n },\n }\n : {}),\n }\n : undefined,\n );\n}\n\n/**\n * True iff `usage` carries an ACTUAL token measurement \u2014 input/output/reasoning/\n * total/cached token counts or a per-model token breakdown. Timing-only or\n * context-window-only metadata (`durationMs`, `contextWindowUsed/Size`) is NOT\n * token usage: stamping `calls:1` on it (INV-USAGE-1) would fabricate a billed\n * call with zero tokens. Used to gate the call counter in usageFromPromptResult.\n */\nfunction hasTokenUsage(usage: UsageInfo): boolean {\n return (\n usage.inputTokens !== undefined ||\n usage.outputTokens !== undefined ||\n usage.reasoningTokens !== undefined ||\n usage.totalTokens !== undefined ||\n usage.cachedReadTokens !== undefined ||\n (usage.modelUsage?.length ?? 0) > 0\n );\n}\n\nfunction usageFromPromptResult(result: unknown): UsageInfo | undefined {\n if (!isRecord(result)) {\n return undefined;\n }\n\n const meta = isRecord(result._meta) ? result._meta : undefined;\n const quota = meta && isRecord(meta.quota) ? meta.quota : undefined;\n if (!quota) {\n const metaUsage = meta ? usageFromMeta(meta) : undefined;\n // INV-USAGE-1: a TOKEN-bearing prompt result counts as exactly one call.\n // Forced ONLY here (never in usageFromMeta/usageFromUpdate/...) so streaming\n // chunks do not inflate the counter. Gate on actual token usage so a\n // timing-only `_meta:{durationMs}` does NOT fabricate `calls:1` (zero tokens).\n if (!metaUsage) {\n return undefined;\n }\n return hasTokenUsage(metaUsage) ? { ...metaUsage, calls: 1 } : metaUsage;\n }\n\n const tokenCount = isRecord(quota.token_count) ? quota.token_count : undefined;\n const inputTokens = tokenCount\n ? readNumberField(tokenCount, [\"input_tokens\", \"inputTokens\"])\n : undefined;\n const outputTokens = tokenCount\n ? readNumberField(tokenCount, [\"output_tokens\", \"outputTokens\"])\n : undefined;\n const modelUsage = Array.isArray(quota.model_usage)\n ? quota.model_usage\n .map((entry) => normalizeUsageModel(entry))\n .filter((entry) => entry !== undefined)\n : undefined;\n\n const merged = mergeUsageInfo(\n meta ? usageFromMeta(meta) : undefined,\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n modelUsage?.length\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(modelUsage?.length ? { modelUsage } : {}),\n }\n : undefined,\n );\n\n // INV-USAGE-1: force a single call count at the tail of usageFromPromptResult\n // only (never in usageFromMeta/usageFromUpdate/usageFromGenericUsageRecord), and\n // ONLY when actual token usage is present \u2014 timing-only metadata must not\n // fabricate a billed call with zero tokens.\n if (!merged) {\n return undefined;\n }\n return hasTokenUsage(merged) ? { ...merged, calls: 1 } : merged;\n}\n\nfunction normalizeAcpModel(value: unknown): AcpModelInfo | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n const modelId =\n typeof value.modelId === \"string\"\n ? value.modelId\n : typeof value.id === \"string\"\n ? value.id\n : undefined;\n if (!modelId?.trim()) {\n return undefined;\n }\n\n const name =\n typeof value.name === \"string\" && value.name.trim().length > 0\n ? value.name\n : modelId;\n const description =\n typeof value.description === \"string\" && value.description.trim().length > 0\n ? value.description\n : undefined;\n const metadata = Object.fromEntries(\n Object.entries(value).filter(([key]) =>\n ![\"modelId\", \"id\", \"name\", \"description\"].includes(key),\n ),\n );\n\n return {\n modelId,\n name,\n ...(description ? { description } : {}),\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n };\n}\n\nfunction modelCatalogFromSession(result: unknown): AcpModelCatalog | undefined {\n if (!isRecord(result)) {\n return undefined;\n }\n\n const models = result.models;\n const modelState = isRecord(models)\n ? models\n : Array.isArray(models)\n ? { availableModels: models }\n : undefined;\n if (!modelState) {\n return undefined;\n }\n\n const availableModels = Array.isArray(modelState.availableModels)\n ? modelState.availableModels\n .map((entry) => normalizeAcpModel(entry))\n .filter((entry) => entry !== undefined)\n : [];\n const currentModelId =\n typeof modelState.currentModelId === \"string\" &&\n modelState.currentModelId.trim().length > 0\n ? modelState.currentModelId\n : availableModels[0]?.modelId;\n\n if (!currentModelId && availableModels.length === 0) {\n return undefined;\n }\n\n return {\n ...(currentModelId ? { currentModelId } : {}),\n availableModels,\n };\n}\n\nfunction attachmentFromContent(\n content: Record<string, unknown>,\n): PortableFileInput | undefined {\n if (content.type === \"image\") {\n const mimeType =\n typeof content.mimeType === \"string\"\n ? content.mimeType\n : \"image/png\";\n const data = typeof content.data === \"string\" ? content.data : undefined;\n if (data) {\n return `data:${mimeType};base64,${data}`;\n }\n }\n\n if (content.type === \"resource_link\" && typeof content.uri === \"string\") {\n return {\n uri: content.uri,\n name:\n typeof content.name === \"string\"\n ? content.name\n : typeof content.title === \"string\"\n ? content.title\n : basename(content.uri),\n };\n }\n\n return undefined;\n}\n\nfunction extractTextChunk(update: Record<string, unknown>): string | undefined {\n if (typeof update.text === \"string\" && update.text.length > 0) {\n return update.text;\n }\n\n const content = isRecord(update.content) ? update.content : undefined;\n if (content?.type !== \"text\") {\n return undefined;\n }\n\n return typeof content.text === \"string\" && content.text.length > 0\n ? content.text\n : undefined;\n}\n\nfunction normalizeAcpError(error: unknown): AiConnectError {\n if (error instanceof AiConnectError) {\n return error;\n }\n\n if (isRecord(error)) {\n const code = typeof error.code === \"number\" ? error.code : undefined;\n const message =\n typeof error.message === \"string\"\n ? error.message\n : \"ACP transport failed.\";\n\n if (code === -32601 || code === -32602) {\n return new AiConnectError(\"not_supported\", message);\n }\n\n if (message.toLowerCase().includes(\"auth\")) {\n return new AiConnectError(\"auth_error\", message);\n }\n\n return new AiConnectError(\"temporary_unavailable\", message);\n }\n\n if (error instanceof Error) {\n const message = error.message;\n if (\"code\" in error && error.code === \"ENOENT\") {\n return new AiConnectError(\"local_harness_unavailable\", message);\n }\n\n if (message.toLowerCase().includes(\"timed out\")) {\n return new AiConnectError(\"local_harness_unavailable\", message);\n }\n\n return new AiConnectError(\"temporary_unavailable\", message);\n }\n\n return new AiConnectError(\n \"temporary_unavailable\",\n \"ACP transport failed.\",\n );\n}\n\nexport function resolveAcpCommand(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): string {\n const override =\n options?.commands?.[`${route.provider}:${route.transport.id}`] ??\n options?.commands?.[route.transport.id] ??\n options?.commands?.[route.provider];\n\n const resolved =\n override ??\n route.transport.command ??\n AI_CONNECT_DEFAULT_ACP_COMMANDS[`${route.provider}:${route.transport.id}`];\n\n if (!resolved) {\n throw new AiConnectError(\n \"validation_error\",\n `No ACP command is configured for route \"${route.id}\".`,\n );\n }\n\n return resolved;\n}\n\nexport function resolveAcpExecutable(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): string {\n return splitCommandLine(resolveAcpCommand(route, options)).command;\n}\n\nfunction initializePayload(\n mode: AcpPermissionMode,\n): Record<string, unknown> {\n return {\n protocolVersion: 1,\n clientCapabilities: {\n fs: {\n readTextFile: true,\n writeTextFile: mode === \"approve-all\",\n },\n terminal: false,\n },\n clientInfo: {\n name: \"ai-connect\",\n version: \"0.1.0\",\n },\n };\n}\n\nfunction buildAcpAuthRequest(\n route: NormalizedRoute,\n _runtime: RuntimeEnvironment,\n): AcpAuthRequest | undefined {\n const auth = route.transport.auth;\n if (!auth?.methodId) {\n return undefined;\n }\n\n const params = {\n ...(auth.params ?? {}),\n methodId: auth.methodId,\n };\n\n return {\n methodId: auth.methodId,\n params,\n lifecycleKeys: [\n \"authenticate.methodId\",\n ...Object.keys(auth.params ?? {})\n .sort()\n .map((key) => `authenticate.${key}`),\n ],\n };\n}\n\nfunction advertisedAuthMethods(\n result: unknown,\n): Set<string> | undefined {\n if (!isRecord(result) || !Array.isArray(result.authMethods)) {\n return undefined;\n }\n\n return new Set(\n result.authMethods.flatMap((method) => {\n if (!isRecord(method) || typeof method.id !== \"string\") {\n return [];\n }\n return [method.id];\n }),\n );\n}\n\nfunction resolveSessionCacheOptions(\n options: AcpClientOptions | undefined,\n): Required<AcpSessionCacheOptions> & { enabled: boolean } {\n if (options?.sessionCache === false) {\n return {\n enabled: false,\n idleTtlMs: 0,\n };\n }\n\n if (options?.sessionCache === true || options?.sessionCache === undefined) {\n return {\n enabled: true,\n idleTtlMs: DEFAULT_SESSION_CACHE_IDLE_TTL_MS,\n };\n }\n\n return {\n enabled: options.sessionCache.enabled ?? true,\n idleTtlMs:\n options.sessionCache.idleTtlMs ??\n DEFAULT_SESSION_CACHE_IDLE_TTL_MS,\n };\n}\n\nfunction buildAcpLifecycle(\n route: NormalizedRoute,\n authRequest: AcpAuthRequest | undefined,\n mode: \"prompt\" | \"discover\",\n): {\n steps: string[];\n keys: string[];\n} {\n const steps = [\"initialize\"];\n const keys = [...(authRequest?.lifecycleKeys ?? [])];\n if (authRequest) {\n steps.push(\"authenticate\");\n }\n steps.push(\"session/new\");\n if (mode === \"prompt\") {\n steps.push(\"session/prompt\");\n }\n\n return { steps, keys };\n}\n\nfunction createAcpTransportSummary(\n commandLine: string,\n parameterKeys: string[],\n lifecycleSteps: string[],\n lifecycleKeys: string[],\n method: string,\n stream: boolean,\n cache: {\n enabled: boolean;\n hit: boolean;\n },\n): WideEventTransportSummary {\n return {\n protocol: \"acp\",\n endpoint: commandLine,\n method,\n stream,\n bodyKeys: lifecycleSteps,\n parameterKeys: [\n ...new Set([\n ...lifecycleKeys,\n ...parameterKeys,\n ]),\n ].sort(),\n phases: [],\n cache,\n };\n}\n\nfunction recordPhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\nasync function measurePhase<T>(\n phases: WideEventTransportPhase[],\n name: string,\n task: () => Promise<T>,\n): Promise<T> {\n const startedAt = Date.now();\n try {\n return await task();\n } finally {\n recordPhase(phases, name, startedAt);\n }\n}\n\nasync function closeChild(\n child: ReturnType<typeof spawn>,\n): Promise<void> {\n if (child.exitCode !== null || child.killed) {\n return;\n }\n\n child.stdin?.end();\n const closed = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), 250);\n child.once(\"close\", () => {\n clearTimeout(timer);\n resolve(true);\n });\n });\n\n if (closed) {\n return;\n }\n\n killAcpProcess(child, \"SIGTERM\");\n await new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n killAcpProcess(child, \"SIGKILL\");\n resolve();\n }, 1_000);\n child.once(\"close\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\nasync function settleClosePromise(\n closePromise: Promise<void>,\n timeoutMs = 1_500,\n): Promise<void> {\n await Promise.race([\n closePromise.catch(() => {}),\n new Promise<void>((resolve) => {\n setTimeout(resolve, timeoutMs);\n }),\n ]);\n}\n\nfunction killAcpProcess(\n child: ReturnType<typeof spawn>,\n signal: NodeJS.Signals,\n): void {\n if (process.platform !== \"win32\" && typeof child.pid === \"number\") {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n // Fall back to killing only the direct child.\n }\n }\n\n child.kill(signal);\n}\n\ntype AcpPromptState = {\n sessionId: string;\n text: string;\n usage: UsageInfo | undefined;\n attachments: PortableFileInput[];\n warnings: string[];\n /**\n * Streaming sink (C9). When `streamPrompt` drives the prompt, every `agent_message_chunk`\n * incremental text fires this BEFORE it is accumulated, so the ACP `stream` handler can emit a\n * `{type:'delta'}` per chunk. Undefined for the plain `runPrompt` (generate) path.\n */\n onDelta?: (text: string) => void;\n};\n\ntype AcpConnectionOptions = {\n commandLine: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeoutMs: number;\n permissionMode: AcpPermissionMode;\n};\n\nclass AcpConnection {\n private readonly commandLine: string;\n private readonly cwd: string;\n private readonly env: NodeJS.ProcessEnv;\n private readonly timeoutMs: number;\n private readonly permissionMode: AcpPermissionMode;\n private readonly command: string;\n private readonly args: string[];\n\n private child: ReturnType<typeof spawn> | undefined;\n private closePromise: Promise<void> | undefined;\n private nextId = 1;\n private buffer = \"\";\n private stderr = \"\";\n private pending = new Map<JsonRpcId, PendingRequest>();\n private messageQueue = Promise.resolve();\n private initializeResult: unknown;\n private authMethodId: string | undefined;\n private activePrompt: AcpPromptState | undefined;\n private opQueue = Promise.resolve();\n private idleTimer: ReturnType<typeof setTimeout> | undefined;\n private disposed = false;\n\n constructor(options: AcpConnectionOptions) {\n this.commandLine = options.commandLine;\n this.cwd = options.cwd;\n this.env = options.env;\n this.timeoutMs = options.timeoutMs;\n this.permissionMode = options.permissionMode;\n const resolved = splitCommandLine(options.commandLine);\n this.command = resolved.command;\n this.args = resolved.args;\n }\n\n async runPrompt(\n context: GenerateContext,\n transport: WideEventTransportSummary,\n onDelta?: (text: string) => void,\n /**\n * Returns true iff THIS prompt is the sole in-flight user of the (possibly\n * pooled+shared) connection. When the pool is saturated the same child is\n * shared across concurrent prompts (`inFlight > 1`); aborting one MUST NOT\n * SIGKILL the child out from under the others. Absent \u21D2 treated as sole owner\n * (the non-pooled fallback gives every call its own connection).\n */\n isSoleInFlight?: () => boolean,\n ): Promise<AcpPromptOutput> {\n return this.withLock(async () => {\n this.clearIdleTimer();\n const prompt = await toPromptBlocks(context);\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const stderrOffset = this.stderr.length;\n\n await this.ensureReady(context.route, authRequest, transport.phases ?? []);\n\n const session = await measurePhase(\n transport.phases ?? [],\n \"session/new\",\n async () =>\n this.request(\"session/new\", {\n cwd: this.cwd,\n mcpServers: [],\n }),\n );\n if (!isRecord(session) || typeof session.sessionId !== \"string\") {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"ACP session/new did not return a sessionId.\",\n );\n }\n\n const sessionId = session.sessionId;\n\n this.activePrompt = {\n sessionId,\n text: \"\",\n usage: undefined,\n attachments: [],\n warnings: [],\n ...(onDelta ? { onDelta } : {}),\n };\n\n let stopReason: string | undefined;\n\n // On the merged abort signal (caller cancel OR op timeout, CD-4): ask the agent to\n // cancel cooperatively via the `session/cancel` notification, then process-group kill\n // (killAcpProcess) so the local harness cannot outlive the cancellation. The pending\n // session/prompt request rejects; the client maps it to the canonical reason.\n const abortSignal = context.abort.signal;\n let abortListener: (() => void) | undefined;\n const onAbort = (): void => {\n // ALWAYS ask the agent to cancel THIS session cooperatively.\n this.notify(\"session/cancel\", { sessionId });\n // Only SIGKILL the child when this prompt is the SOLE in-flight user of a\n // (possibly shared) pooled connection. With `inFlight > 1` the child is\n // shared with concurrent prompts, so a hard kill would tear those down too\n // (SEC/correctness). In that case the cooperative session/cancel is enough;\n // the connection is reclaimed when the last in-flight user releases it.\n const soleOwner = isSoleInFlight ? isSoleInFlight() : true;\n if (!soleOwner) {\n return;\n }\n const child = this.child;\n if (child) {\n killAcpProcess(child, \"SIGKILL\");\n }\n };\n if (abortSignal.aborted) {\n onAbort();\n } else {\n abortListener = onAbort;\n abortSignal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n try {\n const promptResult = await measurePhase(\n transport.phases ?? [],\n \"session/prompt\",\n async () =>\n this.request(\"session/prompt\", {\n sessionId,\n prompt,\n }),\n );\n if (\n isRecord(promptResult) &&\n typeof promptResult.stopReason === \"string\"\n ) {\n stopReason = promptResult.stopReason;\n }\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n usageFromPromptResult(promptResult),\n );\n } finally {\n if (abortListener) {\n abortSignal.removeEventListener(\"abort\", abortListener);\n }\n this.bumpIdleTimer();\n }\n\n const stderrSlice = this.stderr.slice(stderrOffset).trim();\n const warnings = [...this.activePrompt.warnings];\n if (stderrSlice.length > 0) {\n warnings.push(stderrSlice);\n }\n\n const result: AcpPromptOutput = {\n text: this.activePrompt.text.trim(),\n attachments: [...this.activePrompt.attachments],\n warnings,\n ...(this.activePrompt.usage ? { usage: this.activePrompt.usage } : {}),\n data: {\n command: this.commandLine,\n sessionId,\n ...(stopReason ? { stopReason } : {}),\n },\n };\n this.activePrompt = undefined;\n return result;\n });\n }\n\n async discoverModels(\n context: DiscoverAcpModelsContext,\n transport: WideEventTransportSummary,\n ): Promise<AcpModelCatalog> {\n return this.withLock(async () => {\n this.clearIdleTimer();\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n\n try {\n await this.ensureReady(context.route, authRequest, transport.phases ?? []);\n const session = await measurePhase(\n transport.phases ?? [],\n \"session/new\",\n async () =>\n this.request(\"session/new\", {\n cwd: this.cwd,\n mcpServers: [],\n }),\n );\n const catalog = modelCatalogFromSession(session);\n if (!catalog) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `ACP route \"${context.route.id}\" did not return an ACP model catalog in session/new.`,\n );\n }\n // GAP-A (TASK-028 / UR-002): the acp path builds its catalog via\n // modelCatalogFromSession, bypassing buildModelCatalog, so surface the\n // configured contextWindow here too (covers cli-via-acp + direct acp).\n catalog.availableModels = fillConfiguredContextLength(\n context.route,\n catalog.availableModels,\n );\n return catalog;\n } finally {\n this.bumpIdleTimer();\n }\n });\n }\n\n isWarm(): boolean {\n return !this.disposed && Boolean(this.child) && this.initializeResult !== undefined;\n }\n\n scheduleIdleDispose(\n idleTtlMs: number,\n /**\n * Re-checked WHEN the idle timer fires (not when it was scheduled). Returns\n * true iff the connection is still idle and should actually be torn down; a\n * false return means the slot was re-acquired/queued in the meantime, so the\n * dispose is skipped (#10 \u2014 never tear down a re-acquired connection\n * mid-prompt). The pool removal is also done by this callback.\n */\n onIdleFire: () => boolean,\n ): void {\n this.clearIdleTimer();\n if (idleTtlMs <= 0 || this.disposed) {\n return;\n }\n\n this.idleTimer = setTimeout(() => {\n if (!onIdleFire()) {\n return;\n }\n void this.dispose();\n }, idleTtlMs);\n this.idleTimer.unref?.();\n }\n\n async dispose(): Promise<void> {\n this.disposed = true;\n this.clearIdleTimer();\n\n const child = this.child;\n const closePromise = this.closePromise;\n this.child = undefined;\n this.closePromise = undefined;\n this.initializeResult = undefined;\n this.authMethodId = undefined;\n this.activePrompt = undefined;\n\n if (!child) {\n return;\n }\n\n try {\n await closeChild(child);\n } catch {\n killAcpProcess(child, \"SIGKILL\");\n }\n\n if (closePromise) {\n await settleClosePromise(closePromise);\n }\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer);\n this.idleTimer = undefined;\n }\n }\n\n private bumpIdleTimer(): void {\n this.clearIdleTimer();\n }\n\n private async withLock<T>(task: () => Promise<T>): Promise<T> {\n const previous = this.opQueue.catch(() => {});\n let release!: () => void;\n this.opQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await previous;\n try {\n return await task();\n } finally {\n release();\n }\n }\n\n private async ensureReady(\n route: NormalizedRoute,\n authRequest: AcpAuthRequest | undefined,\n phases: WideEventTransportPhase[],\n ): Promise<void> {\n if (this.disposed) {\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" has already been disposed.`,\n );\n }\n\n await this.spawnChild(phases);\n\n if (this.initializeResult === undefined) {\n this.initializeResult = await measurePhase(\n phases,\n \"initialize\",\n async () =>\n this.request(\n \"initialize\",\n initializePayload(this.permissionMode),\n ),\n );\n }\n\n if (!authRequest) {\n return;\n }\n\n const methods = advertisedAuthMethods(this.initializeResult);\n if (methods && !methods.has(authRequest.methodId)) {\n throw new AiConnectError(\n \"not_supported\",\n `ACP agent \"${route.id}\" does not advertise auth method \"${authRequest.methodId}\".`,\n );\n }\n\n if (this.authMethodId === authRequest.methodId) {\n return;\n }\n\n await measurePhase(phases, \"authenticate\", async () =>\n this.request(\"authenticate\", authRequest.params),\n );\n this.authMethodId = authRequest.methodId;\n }\n\n private async spawnChild(\n phases: WideEventTransportPhase[],\n ): Promise<void> {\n if (this.child) {\n return;\n }\n\n await measurePhase(phases, \"spawn\", async () => {\n const child = spawn(this.command, this.args, {\n cwd: this.cwd,\n env: this.env,\n stdio: \"pipe\",\n detached: process.platform !== \"win32\",\n });\n\n this.child = child;\n this.buffer = \"\";\n this.stderr = \"\";\n this.pending.clear();\n this.messageQueue = Promise.resolve();\n\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n this.buffer += chunk;\n const lines = this.buffer.split(/\\r?\\n/);\n this.buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n this.messageQueue = this.messageQueue\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP message handler error: ${message}\\n`;\n })\n .then(() => this.handleMessage(line))\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP message handler error: ${message}\\n`;\n });\n }\n });\n\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n this.stderr += chunk;\n });\n\n this.closePromise = new Promise<void>((resolve, reject) => {\n child.once(\"error\", (error) => {\n const normalized = normalizeAcpError(error);\n this.failPending(normalized);\n this.resetConnectionState();\n reject(normalized);\n });\n child.once(\"close\", (code) => {\n const hadPending = this.pending.size > 0;\n const normalized = new AiConnectError(\n \"local_harness_unavailable\",\n this.stderr.trim() ||\n `ACP command \"${this.commandLine}\" exited before completing the prompt (code ${code ?? \"null\"}).`,\n );\n if (hadPending) {\n this.failPending(normalized);\n }\n this.resetConnectionState();\n if (hadPending) {\n reject(normalized);\n return;\n }\n resolve();\n });\n });\n // The close rejection is authoritatively surfaced through the pending\n // session/prompt await (and via settleClosePromise on dispose). A process-group\n // kill on abort (C2b) can reject closePromise before any awaiter attaches, so\n // attach a no-op catch to keep that rejection from becoming \"unhandled\".\n this.closePromise.catch(() => {});\n });\n }\n\n private resetConnectionState(): void {\n this.child = undefined;\n this.closePromise = undefined;\n this.initializeResult = undefined;\n this.authMethodId = undefined;\n this.activePrompt = undefined;\n this.nextId = 1;\n this.clearIdleTimer();\n }\n\n private reply(message: JsonRpcResponse): void {\n const stdin = this.child?.stdin;\n if (!stdin) {\n return;\n }\n\n stdin.write(`${JSON.stringify(message)}\\n`);\n }\n\n private failPending(error: unknown): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timer);\n entry.reject(error);\n }\n this.pending.clear();\n }\n\n private async handleAgentRequest(\n message: JsonRpcRequest,\n ): Promise<void> {\n const params = isRecord(message.params) ? message.params : {};\n\n if (message.method === \"requestPermission\") {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: selectPermissionResponse(params, this.permissionMode),\n });\n return;\n }\n\n if (message.method === \"readTextFile\") {\n const filePath =\n typeof params.path === \"string\"\n ? path.resolve(params.path)\n : undefined;\n if (!filePath || !isWithinRoot(this.cwd, filePath)) {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32000,\n message: \"Path is outside the allowed ACP cwd.\",\n },\n });\n return;\n }\n\n const content = await fs.readFile(filePath, \"utf8\");\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: { content },\n });\n return;\n }\n\n if (message.method === \"writeTextFile\") {\n if (this.permissionMode !== \"approve-all\") {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32001,\n message: \"ACP write access is disabled.\",\n },\n });\n return;\n }\n\n const filePath =\n typeof params.path === \"string\"\n ? path.resolve(params.path)\n : undefined;\n const content =\n typeof params.content === \"string\"\n ? params.content\n : undefined;\n if (\n !filePath ||\n content === undefined ||\n !isWithinRoot(this.cwd, filePath)\n ) {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32000,\n message: \"Invalid ACP write request.\",\n },\n });\n return;\n }\n\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf8\");\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: {},\n });\n return;\n }\n\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32601,\n message: `Unsupported ACP client method \"${message.method}\".`,\n },\n });\n }\n\n private handleNotification(message: JsonRpcNotification): void {\n if (message.method !== \"session/update\" || !this.activePrompt) {\n return;\n }\n\n const params = isRecord(message.params) ? message.params : {};\n if (\n typeof params.sessionId === \"string\" &&\n params.sessionId !== this.activePrompt.sessionId\n ) {\n return;\n }\n\n const update = isRecord(params.update) ? params.update : undefined;\n if (!update || typeof update.sessionUpdate !== \"string\") {\n return;\n }\n\n const chunk = extractTextChunk(update);\n if (update.sessionUpdate === \"agent_message_chunk\" && chunk) {\n // C9: fire the streaming sink (when streamPrompt is driving) BEFORE accumulating, so the\n // ACP `stream` handler emits one `{type:'delta'}` per incremental chunk in arrival order.\n this.activePrompt.onDelta?.(chunk);\n this.activePrompt.text += chunk;\n }\n\n if (update.sessionUpdate === \"agent_thought_chunk\" && chunk) {\n this.activePrompt.warnings.push(chunk);\n }\n\n const meta = isRecord(update._meta) ? update._meta : undefined;\n if (meta) {\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n usageFromMeta(meta),\n );\n }\n\n if (update.sessionUpdate === \"agent_message_chunk\") {\n const content = isRecord(update.content) ? update.content : undefined;\n if (content) {\n const attachment = attachmentFromContent(content);\n if (attachment) {\n this.activePrompt.attachments.push(attachment);\n }\n }\n }\n\n if (update.sessionUpdate === \"usage_update\") {\n const nextUsage = usageFromUpdate(update);\n if (nextUsage) {\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n nextUsage,\n );\n }\n }\n }\n\n private async handleMessage(raw: string): Promise<void> {\n const trimmed = raw.trim();\n if (!trimmed) {\n return;\n }\n\n let message: JsonRpcMessage;\n try {\n message = JSON.parse(trimmed) as JsonRpcMessage;\n } catch {\n return;\n }\n\n if (\n isRecord(message) &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n Object.hasOwn(message, \"id\")\n ) {\n await this.handleAgentRequest(message as JsonRpcRequest);\n return;\n }\n\n if (\n isRecord(message) &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n !Object.hasOwn(message, \"id\")\n ) {\n this.handleNotification(message as JsonRpcNotification);\n return;\n }\n\n if (isRecord(message) && Object.hasOwn(message, \"id\")) {\n const response = message as JsonRpcResponse;\n const pendingRequest = this.pending.get(response.id);\n if (!pendingRequest) {\n return;\n }\n\n clearTimeout(pendingRequest.timer);\n this.pending.delete(response.id);\n\n if (response.error) {\n pendingRequest.reject(response.error);\n return;\n }\n\n pendingRequest.resolve(response.result);\n }\n }\n\n /**\n * Send a fire-and-forget JSON-RPC notification (no `id`, no response awaited). Used for\n * `session/cancel` on abort (CD-4): the agent is asked to cancel cooperatively before we\n * fall back to a process-group kill. Best-effort \u2014 a missing stdin is silently ignored.\n */\n private notify(method: string, params: Record<string, unknown>): void {\n const stdin = this.child?.stdin;\n if (!stdin) {\n return;\n }\n const payload: JsonRpcNotification = {\n jsonrpc: \"2.0\",\n method,\n params,\n };\n try {\n stdin.write(`${JSON.stringify(payload)}\\n`);\n } catch {\n // Best-effort: a broken pipe on cancel is non-fatal (we kill the process next).\n }\n }\n\n private request(\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const child = this.child;\n if (!child) {\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" is not running.`,\n );\n }\n\n const id = this.nextId;\n this.nextId += 1;\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(\n new Error(\n `ACP request \"${method}\" timed out after ${this.timeoutMs}ms.`,\n ),\n );\n }, this.timeoutMs);\n // Match the idle timer: do not keep the event loop alive on this per-request\n // deadline so a hung agent cannot block process exit.\n (timer as { unref?: () => void }).unref?.();\n\n this.pending.set(id, {\n resolve,\n reject,\n timer,\n });\n\n const payload: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id,\n method,\n params,\n };\n const stdin = child.stdin;\n if (!stdin) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(\n new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" does not expose stdin.`,\n ),\n );\n return;\n }\n\n stdin.write(`${JSON.stringify(payload)}\\n`);\n });\n }\n}\n\nfunction cacheKeyForConnection(\n route: NormalizedRoute,\n runtime: PreparedAcpLaunchRuntime,\n options: AcpConnectionOptions,\n): string {\n const envEntries = Object.entries(options.env)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\u0001\");\n\n return [\n route.id,\n runtime.commandLine,\n options.cwd,\n options.permissionMode,\n String(options.timeoutMs),\n runtime.launch.contextMode,\n runtime.launch.skillsMode,\n envEntries,\n ].join(\"\\u0002\");\n}\n\nexport function createAcpTransportManager(\n options?: AcpClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<AcpPromptOutput>;\n streamPrompt: (\n context: GenerateContext,\n ) => AsyncIterable<GenerateStreamEvent>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n dispose: () => Promise<void>;\n} {\n type ManagedAcpConnection = {\n connection: AcpConnection;\n inFlight: number;\n };\n\n const connectionPools = new Map<string, ManagedAcpConnection[]>();\n const preparedLaunches = new Map<string, PreparedAcpLaunchRuntime>();\n const cacheOptions = resolveSessionCacheOptions(options);\n const maxConcurrentConnections = Math.max(\n 1,\n Math.floor(options?.maxConcurrentConnections ?? 1),\n );\n\n function launchCacheKey(\n route: NormalizedRoute,\n commandLine: string,\n cwdOverride?: string,\n ): string {\n const launch = normalizeLaunchOptions(route, options);\n return [\n route.id,\n commandLine,\n path.resolve(cwdOverride ?? options?.cwd ?? process.cwd()),\n launch.contextMode,\n launch.skillsMode,\n JSON.stringify(options?.env ?? {}),\n ].join(\"\\u0002\");\n }\n\n async function getPreparedLaunchRuntime(\n route: NormalizedRoute,\n commandLine: string,\n cwdOverride?: string,\n ): Promise<PreparedAcpLaunchRuntime> {\n const key = launchCacheKey(route, commandLine, cwdOverride);\n const existing = preparedLaunches.get(key);\n if (existing) {\n return existing;\n }\n\n const prepared = await prepareAcpLaunchRuntime(\n route,\n options,\n commandLine,\n cwdOverride,\n );\n preparedLaunches.set(key, prepared);\n return prepared;\n }\n\n function buildConnectionOptions(\n runtime: PreparedAcpLaunchRuntime,\n ): AcpConnectionOptions {\n return {\n commandLine: runtime.commandLine,\n cwd: runtime.cwd,\n env: runtime.env,\n timeoutMs: promptTimeout(options),\n permissionMode: options?.permissionMode ?? \"deny-all\",\n };\n }\n\n function getPool(key: string): ManagedAcpConnection[] {\n const existing = connectionPools.get(key);\n if (existing) {\n return existing;\n }\n\n const created: ManagedAcpConnection[] = [];\n connectionPools.set(key, created);\n return created;\n }\n\n function removeManagedConnection(\n key: string,\n entry: ManagedAcpConnection,\n ): void {\n const pool = connectionPools.get(key);\n if (!pool) {\n return;\n }\n\n const nextPool = pool.filter((item) => item !== entry);\n if (nextPool.length === 0) {\n connectionPools.delete(key);\n return;\n }\n\n connectionPools.set(key, nextPool);\n }\n\n function acquireManagedConnection(\n key: string,\n connectionOptions: AcpConnectionOptions,\n ): ManagedAcpConnection {\n const pool = getPool(key);\n const idleWarm = pool.find(\n (entry) => entry.inFlight === 0 && entry.connection.isWarm(),\n );\n if (idleWarm) {\n idleWarm.inFlight += 1;\n return idleWarm;\n }\n\n const idleCold = pool.find((entry) => entry.inFlight === 0);\n if (idleCold) {\n idleCold.inFlight += 1;\n return idleCold;\n }\n\n if (pool.length < maxConcurrentConnections) {\n const created: ManagedAcpConnection = {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n pool.push(created);\n return created;\n }\n\n const fallback =\n pool.reduce((selected, entry) =>\n entry.inFlight < selected.inFlight ? entry : selected,\n );\n fallback.inFlight += 1;\n return fallback;\n }\n\n async function runWithCommand(\n context: GenerateContext,\n commandLine: string,\n onDelta?: (text: string) => void,\n ): Promise<AcpPromptOutput> {\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const lifecycle = buildAcpLifecycle(\n context.route,\n authRequest,\n \"prompt\",\n );\n const preparedRuntime = await getPreparedLaunchRuntime(\n context.route,\n commandLine,\n context.request.workingDirectory,\n );\n const connectionOptions = buildConnectionOptions(preparedRuntime);\n const key = cacheKeyForConnection(\n context.route,\n preparedRuntime,\n connectionOptions,\n );\n\n const entry = cacheOptions.enabled\n ? acquireManagedConnection(key, connectionOptions)\n : {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n const connection = entry.connection;\n const cacheHit = connection.isWarm();\n\n const transport = createAcpTransportSummary(\n preparedRuntime.commandLine,\n [\n \"prompt\",\n `launch.contextMode:${preparedRuntime.launch.contextMode}`,\n `launch.skillsMode:${preparedRuntime.launch.skillsMode}`,\n ...Object.keys(context.request.parameters ?? {}),\n ],\n lifecycle.steps,\n lifecycle.keys,\n \"session/prompt\",\n true,\n {\n enabled: cacheOptions.enabled,\n hit: cacheHit,\n },\n );\n context.telemetry?.captureTransport(transport);\n\n try {\n // Sole-owner predicate (#4): a SIGKILL on abort is only safe when this prompt\n // is the last in-flight user of the shared pooled connection.\n return await connection.runPrompt(\n context,\n transport,\n onDelta,\n () => entry.inFlight <= 1,\n );\n } catch (error) {\n // #4: only tear down the connection when THIS prompt is the sole in-flight\n // user (inFlight not yet decremented here). With a SHARED pooled connection\n // (inFlight > 1) a failed/aborted prompt must NOT evict the entry or dispose\n // the child out from under the concurrent prompt(s) still using it.\n if (entry.inFlight <= 1) {\n if (cacheOptions.enabled) {\n removeManagedConnection(key, entry);\n }\n await connection.dispose();\n }\n throw normalizeAcpError(error);\n } finally {\n entry.inFlight = Math.max(0, entry.inFlight - 1);\n if (!cacheOptions.enabled) {\n await connection.dispose();\n } else {\n if (entry.inFlight === 0) {\n connection.scheduleIdleDispose(cacheOptions.idleTtlMs, () => {\n // Re-checked at fire time: a slot re-acquired (or a prompt queued)\n // since scheduling \u21D2 skip the dispose (#10).\n if (entry.inFlight !== 0) {\n return false;\n }\n\n removeManagedConnection(key, entry);\n return true;\n });\n }\n }\n }\n }\n\n async function discoverWithCommand(\n context: DiscoverAcpModelsContext,\n commandLine: string,\n ): Promise<AcpModelCatalog> {\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const lifecycle = buildAcpLifecycle(\n context.route,\n authRequest,\n \"discover\",\n );\n const preparedRuntime = await getPreparedLaunchRuntime(\n context.route,\n commandLine,\n );\n const connectionOptions = buildConnectionOptions(preparedRuntime);\n const key = cacheKeyForConnection(\n context.route,\n preparedRuntime,\n connectionOptions,\n );\n\n const entry = cacheOptions.enabled\n ? acquireManagedConnection(key, connectionOptions)\n : {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n const connection = entry.connection;\n const cacheHit = connection.isWarm();\n\n const transport = createAcpTransportSummary(\n preparedRuntime.commandLine,\n [\n `launch.contextMode:${preparedRuntime.launch.contextMode}`,\n `launch.skillsMode:${preparedRuntime.launch.skillsMode}`,\n ...lifecycle.keys,\n ],\n lifecycle.steps,\n lifecycle.keys,\n \"session/new\",\n false,\n {\n enabled: cacheOptions.enabled,\n hit: cacheHit,\n },\n );\n context.telemetry?.captureTransport(transport);\n\n try {\n return await connection.discoverModels(context, transport);\n } catch (error) {\n if (cacheOptions.enabled) {\n removeManagedConnection(key, entry);\n }\n await connection.dispose();\n throw normalizeAcpError(error);\n } finally {\n entry.inFlight = Math.max(0, entry.inFlight - 1);\n if (!cacheOptions.enabled) {\n await connection.dispose();\n } else {\n if (entry.inFlight === 0) {\n connection.scheduleIdleDispose(cacheOptions.idleTtlMs, () => {\n // Re-checked at fire time: a slot re-acquired (or a prompt queued)\n // since scheduling \u21D2 skip the dispose (#10).\n if (entry.inFlight !== 0) {\n return false;\n }\n\n removeManagedConnection(key, entry);\n return true;\n });\n }\n }\n }\n }\n\n async function drivePrompt(\n context: GenerateContext,\n onDelta?: (text: string) => void,\n ): Promise<AcpPromptOutput> {\n const commandLine = resolveAcpCommand(context.route, options);\n return await runWithCommand(context, commandLine, onDelta);\n }\n\n return {\n async runPrompt(context): Promise<AcpPromptOutput> {\n return drivePrompt(context);\n },\n /**\n * Streaming ACP prompt (C9 / OQ-13). Drives `runPrompt` with an `onDelta` sink that pushes each\n * `agent_message_chunk` into a bounded async queue; this generator yields one `{type:'delta'}`\n * per chunk IN ORDER, then exactly one terminal `{type:'result'}` from the resolved prompt\n * output (INV-ABORT-3). Abort is handled upstream by the client + `runPrompt`'s `session/cancel`\n * + process-kill on `context.abort.signal`.\n */\n async *streamPrompt(\n context: GenerateContext,\n ): AsyncIterable<GenerateStreamEvent> {\n const deltas: string[] = [];\n let notify: (() => void) | undefined;\n const onDelta = (text: string): void => {\n deltas.push(text);\n notify?.();\n };\n let settled = false;\n let promptError: unknown;\n let output: AcpPromptOutput | undefined;\n const promptPromise = drivePrompt(context, onDelta).then(\n (result) => {\n output = result;\n settled = true;\n notify?.();\n },\n (error) => {\n promptError = error;\n settled = true;\n notify?.();\n },\n );\n\n while (true) {\n while (deltas.length > 0) {\n const text = deltas.shift()!;\n if (text.length > 0) {\n yield { type: \"delta\", text };\n }\n }\n if (settled) {\n break;\n }\n await new Promise<void>((resolve) => {\n notify = resolve;\n });\n notify = undefined;\n }\n await promptPromise;\n if (promptError !== undefined) {\n throw promptError;\n }\n\n const result: GenerateResult = {\n route: context.route,\n text: output?.text ?? \"\",\n attachments: (output?.attachments ?? []).map((item) =>\n preparePortableFile(item),\n ),\n warnings: output?.warnings ?? [],\n attempts: [],\n ...(output?.usage ? { usage: output.usage } : {}),\n ...(output?.data !== undefined ? { data: output.data } : {}),\n };\n yield { type: \"result\", result };\n },\n async discoverModels(context): Promise<AcpModelCatalog> {\n const commandLine = resolveAcpCommand(context.route, options);\n return await discoverWithCommand(context, commandLine);\n },\n async dispose(): Promise<void> {\n const values = [...connectionPools.values()].flat();\n connectionPools.clear();\n await Promise.all(\n values.map(async (entry) => entry.connection.dispose()),\n );\n const launchValues = [...preparedLaunches.values()];\n preparedLaunches.clear();\n await Promise.all(\n launchValues.map(async (runtime) => {\n await runtime.cleanup?.();\n }),\n );\n },\n };\n}\n\nexport async function runAcpPrompt(\n context: GenerateContext,\n options?: AcpClientOptions,\n): Promise<AcpPromptOutput> {\n const manager = createAcpTransportManager({\n ...options,\n sessionCache: false,\n });\n\n try {\n return await manager.runPrompt(context);\n } finally {\n await manager.dispose();\n }\n}\n\n/**\n * Internal usage-merge primitives surfaced for deterministic unit tests\n * (C5/INV-USAGE-1). NOT re-exported from `src/index*.ts`, so the public package\n * surface is unchanged.\n * @internal\n */\nexport const __acpUsageInternals = {\n mergeUsageInfo,\n usageFromPromptResult,\n usageFromUpdate,\n usageFromMeta,\n} as const;\n", "import { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport {\n AI_CONNECT_DEFAULT_CLI_COMMANDS,\n getCliTransportPreset,\n} from \"./cli-presets.js\";\nimport {\n buildModelCatalog,\n currentModelIdForRoute,\n} from \"./default-handlers.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport {\n extensionForMime,\n materializePortableFile,\n portableFileCategory,\n portableFileToBytes,\n preparePortableFile,\n} from \"./files.js\";\nimport type {\n AcpLaunchOptions,\n AcpModelCatalog,\n AcpModelInfo,\n CliClientOptions,\n CliDiscoveryAcpOptions,\n CliDiscoveryCommandModelsSelector,\n CliDiscoveryCommandParser,\n CliFileInputOptions,\n CliJsonLineSelector,\n CliTransportOptions,\n CliTransportParser,\n CliTransportPresetId,\n CliDiscoveryVia,\n DiscoverAcpModelsContext,\n GenerateContext,\n NormalizedCliDiscoveryCommand,\n NormalizedRoute,\n PortableFileInput,\n RouteHandlerGenerateResult,\n UsageInfo,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype CliExecutionResult = {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n};\n\ntype CliInvocation = {\n command: string;\n args: string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n tempDir?: string;\n outputFile?: string;\n parameterKeys: string[];\n /** When true, the per-invocation tempDir (output + staged attachments) is retained (debug). */\n keepStaging?: boolean;\n};\n\nexport type CliResolvedDiscoverySource =\n | {\n via: \"none\";\n }\n | {\n via: \"static\";\n }\n | {\n via: \"command\";\n command: NormalizedCliDiscoveryCommand;\n fallback: \"static\" | \"none\";\n }\n | {\n via: \"acp\";\n providerId: string;\n transportId: string;\n auth?: {\n methodId: string;\n params: Record<string, unknown>;\n };\n launch?: AcpLaunchOptions;\n };\n\nconst CLI_PRESET_ACP_DISCOVERY_DEFAULTS: Partial<\n Record<\n CliTransportPresetId,\n {\n transportId: string;\n providerId: string;\n }\n >\n> = {\n claude: {\n transportId: \"claude-code-acp\",\n providerId: \"anthropic\",\n },\n codex: {\n transportId: \"codex-acp\",\n providerId: \"openai\",\n },\n};\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\"validation_error\", \"CLI command line is empty.\");\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction quoteArg(value: string): string {\n return /\\s/.test(value) ? JSON.stringify(value) : value;\n}\n\nfunction buildCliPrompt(\n context: GenerateContext,\n fileInputEnabled: boolean,\n): string {\n if (context.request.operation !== \"text\") {\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${context.route.transport.id}\" only supports text requests.`,\n );\n }\n\n // Image *operations* (generation) have no CLI channel regardless of fileInput.\n if (context.request.image) {\n throw new AiConnectError(\n \"unsupported_capability\",\n `CLI transport \"${context.route.transport.id}\" does not support image output.`,\n );\n }\n\n // Attachments: when the route has NO resolved fileInput, a CLI text preset has\n // no binary input channel \u2192 reject (defense-in-depth; the client capability\n // gate normally rejects image/document before reaching here). When fileInput\n // IS enabled (REQ-024) the attachments are staged in buildCliInvocation, so\n // they are allowed through here.\n if (!fileInputEnabled && context.request.attachments.length > 0) {\n const hasBinary = context.request.attachments.some(\n (file) =>\n portableFileCategory(file) === \"image\" ||\n portableFileCategory(file) === \"document\",\n );\n throw new AiConnectError(\n hasBinary ? \"unsupported_capability\" : \"not_supported\",\n hasBinary\n ? `CLI transport \"${context.route.transport.id}\" does not support image or document inputs.`\n : `CLI transport \"${context.route.transport.id}\" does not support attachments.`,\n );\n }\n\n return context.request.messages\n .map((message) => {\n if (message.role === \"user\") {\n return message.content;\n }\n\n const roleLabel = message.role.toUpperCase();\n return `${roleLabel}:\\n${message.content}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction resolveCliCommand(\n route: NormalizedRoute,\n options?: CliClientOptions,\n): string {\n if (route.transport.command?.trim()) {\n return route.transport.command.trim();\n }\n\n const candidates = [\n `${route.provider}:${route.transport.id}`,\n route.transport.id,\n route.provider,\n ];\n\n for (const candidate of candidates) {\n const override = options?.commands?.[candidate]?.trim();\n if (override) {\n return override;\n }\n }\n\n const presetId =\n route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n if (presetId) {\n const presetCommand = getCliTransportPreset(presetId).command.trim();\n if (presetCommand) {\n return presetCommand;\n }\n }\n\n const preset = AI_CONNECT_DEFAULT_CLI_COMMANDS[`${route.provider}:${route.transport.id}`];\n if (preset) {\n return preset;\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `No CLI command preset is registered for route \"${route.id}\". Provide transport.command or cli.commands.`,\n );\n}\n\nexport function resolveCliExecutable(\n route: NormalizedRoute,\n options?: CliClientOptions,\n): string {\n return splitCommandLine(resolveCliCommand(route, options)).command;\n}\n\nfunction buildCliEnvironment(options?: CliClientOptions): NodeJS.ProcessEnv {\n return {\n ...process.env,\n ...(options?.env ?? {}),\n };\n}\n\nfunction buildCliCwd(\n context: GenerateContext,\n options?: CliClientOptions,\n): string {\n return path.resolve(\n context.request.workingDirectory ?? options?.cwd ?? process.cwd(),\n );\n}\n\nfunction defaultCliPresetIdForRoute(\n route: NormalizedRoute,\n): CliTransportPresetId | undefined {\n switch (route.transport.id) {\n case \"pi-cli\":\n return \"pi\";\n case \"claude-cli\":\n return \"claude\";\n case \"openclaude-cli\":\n return \"openclaude\";\n case \"codex-cli\":\n return \"codex\";\n default:\n return undefined;\n }\n}\n\nfunction defaultCliDiscoveryPresetForRoute(\n route: NormalizedRoute,\n): CliTransportPresetId | undefined {\n return route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n}\n\nfunction defaultCliDiscoveryTransportIdForRoute(\n route: NormalizedRoute,\n): string | undefined {\n const presetId = defaultCliDiscoveryPresetForRoute(route);\n return presetId\n ? CLI_PRESET_ACP_DISCOVERY_DEFAULTS[presetId]?.transportId\n : undefined;\n}\n\nfunction defaultCliDiscoveryProviderForRoute(\n route: NormalizedRoute,\n transportId: string,\n): string | undefined {\n if (AI_CONNECT_DEFAULT_ACP_COMMANDS[`${route.provider}:${transportId}`]) {\n return route.provider;\n }\n\n const presetId = defaultCliDiscoveryPresetForRoute(route);\n return presetId\n ? CLI_PRESET_ACP_DISCOVERY_DEFAULTS[presetId]?.providerId\n : undefined;\n}\n\nfunction normalizeCliDiscoveryAcpSource(\n route: NormalizedRoute,\n discovery: CliDiscoveryAcpOptions | undefined,\n): CliResolvedDiscoverySource {\n const transportId =\n discovery?.transportId?.trim() ??\n defaultCliDiscoveryTransportIdForRoute(route);\n if (!transportId) {\n return { via: \"none\" };\n }\n\n const providerId =\n discovery?.providerId?.trim() ??\n defaultCliDiscoveryProviderForRoute(route, transportId);\n if (!providerId) {\n return { via: \"none\" };\n }\n\n return {\n via: \"acp\",\n providerId,\n transportId,\n ...(discovery?.auth ? { auth: discovery.auth } : {}),\n ...(discovery?.launch ? { launch: discovery.launch } : {}),\n };\n}\n\nexport function resolveCliDiscoverySource(\n route: NormalizedRoute,\n): CliResolvedDiscoverySource {\n const discovery = route.transport.cli?.discovery;\n const hasModels = (route.advertisedModels?.length ?? 0) > 0;\n const hasAcpDefault = Boolean(defaultCliDiscoveryTransportIdForRoute(route));\n\n // Resolution chain (when `via` is unset): command > acp > static > none.\n // An explicit `via` short-circuits the chain.\n const via: CliDiscoveryVia =\n discovery?.via ??\n (discovery?.command\n ? \"command\"\n : hasAcpDefault\n ? \"acp\"\n : hasModels\n ? \"static\"\n : \"none\");\n\n switch (via) {\n case \"none\":\n return { via: \"none\" };\n case \"static\":\n return { via: \"static\" };\n case \"command\": {\n const command = discovery?.command;\n if (!command) {\n // Misconfiguration (explicit via:\"command\" without a command block).\n // config normalization rejects this; treat defensively as no discovery.\n return { via: \"none\" };\n }\n const fallback = discovery?.fallback ?? (hasModels ? \"static\" : \"none\");\n return { via: \"command\", command, fallback };\n }\n default:\n return normalizeCliDiscoveryAcpSource(route, discovery?.acp);\n }\n}\n\nexport function createCliDiscoveryAcpRoute(\n route: NormalizedRoute,\n): NormalizedRoute | undefined {\n const discovery = resolveCliDiscoverySource(route);\n if (discovery.via !== \"acp\") {\n return undefined;\n }\n\n return {\n ...route,\n id: `${route.id}::cli-discovery::${discovery.providerId}:${discovery.transportId}`,\n provider: discovery.providerId,\n handlerKey: `${discovery.providerId}:${discovery.transportId}`,\n transport: {\n kind: \"acp\",\n id: discovery.transportId,\n ...(discovery.auth ? { auth: discovery.auth } : {}),\n ...(discovery.launch ? { launch: discovery.launch } : {}),\n },\n };\n}\n\nfunction resolveCliTransportOptions(\n route: NormalizedRoute,\n): CliTransportOptions & { argsTemplate: string[] } {\n const presetId =\n route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n const preset = presetId ? getCliTransportPreset(presetId) : undefined;\n\n // Deep-merge fileInput per-field (preset default under route override) so a\n // route overriding one field (e.g. mentionTemplate) keeps the preset's other\n // defaults (e.g. perFileArgs) instead of wiping them via the shallow spread.\n const mergedFileInput: CliFileInputOptions | undefined =\n preset?.options.fileInput || route.transport.cli?.fileInput\n ? {\n ...(preset?.options.fileInput ?? {}),\n ...(route.transport.cli?.fileInput ?? {}),\n }\n : undefined;\n\n const merged: CliTransportOptions = {\n ...(preset?.options ?? {}),\n ...(route.transport.cli ?? {}),\n ...(route.transport.cli?.argsTemplate\n ? { argsTemplate: route.transport.cli.argsTemplate }\n : {}),\n ...(route.transport.cli?.parser\n ? { parser: route.transport.cli.parser }\n : {}),\n ...(mergedFileInput ? { fileInput: mergedFileInput } : {}),\n ...(presetId ? { preset: presetId } : {}),\n };\n\n if (!merged.argsTemplate?.length) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI route \"${route.id}\" does not define argsTemplate and has no matching built-in preset.`,\n );\n }\n\n return merged as CliTransportOptions & { argsTemplate: string[] };\n}\n\nasync function createCliTempDir(\n baseDir?: string,\n prefix?: string,\n): Promise<{\n tempDir: string;\n outputFile: string;\n}> {\n const tempDir = await fs.mkdtemp(\n path.join(baseDir ?? os.tmpdir(), prefix ?? \"ai-connect-cli-\"),\n );\n\n return {\n tempDir,\n outputFile: path.join(tempDir, \"last-message.txt\"),\n };\n}\n\n// Sanitize an attachment name to a safe basename inside the staging dir: strip\n// any directory / traversal / absolute prefix; fall back to attachment-${i}.<ext>\n// when the result is empty or all-dots (REQ-024, F-CR-4).\nfunction safeStagedBasename(name: string, index: number, mimeType: string): string {\n const base = path.basename(name.replace(/\\\\/g, \"/\"));\n if (base === \"\" || base === \".\" || base === \"..\") {\n return `attachment-${index}.${extensionForMime(mimeType)}`;\n }\n return base;\n}\n\n// Materialize attachments to disk under attachDir and return the ordered list of\n// staged references (absolute paths, or a remote uri when the source has no\n// bytes). Only categories in `categories` are staged; others are skipped.\nasync function stageCliAttachments(\n attachments: PortableFileInput[],\n attachDir: string,\n fileInput: CliFileInputOptions,\n): Promise<string[]> {\n const categories = new Set(\n fileInput.categories ?? [\"image\", \"document\", \"text\", \"other\"],\n );\n await fs.mkdir(attachDir, { recursive: true });\n\n const refs: string[] = [];\n const usedNames = new Map<string, number>();\n for (let i = 0; i < attachments.length; i += 1) {\n const file = preparePortableFile(attachments[i]!);\n const payload = await materializePortableFile(file);\n if (!categories.has(payload.category)) {\n continue;\n }\n\n // De-dup names within the batch (index-prefix on collision).\n let destName = safeStagedBasename(payload.name, i, payload.mimeType);\n const seen = usedNames.get(destName);\n if (seen !== undefined) {\n destName = `${i}-${destName}`;\n }\n usedNames.set(destName, i);\n const dest = path.join(attachDir, destName);\n\n if (payload.category === \"text\") {\n if (payload.text !== undefined) {\n await fs.writeFile(dest, payload.text, \"utf8\");\n refs.push(dest);\n continue;\n }\n } else {\n const bytes = payload.base64\n ? Buffer.from(payload.base64, \"base64\")\n : await portableFileToBytes(file);\n if (bytes !== undefined) {\n await fs.writeFile(dest, bytes);\n refs.push(dest);\n continue;\n }\n }\n\n // No local bytes/text: degrade to the remote uri reference (no disk write),\n // mirroring the acp resource_link path.\n if (payload.uri) {\n refs.push(payload.uri);\n }\n }\n return refs;\n}\n\n// Expand the {files} placeholder to argv tokens, one group per staged file via\n// the route's perFileArgs ({path}/{name}). Returns [] for prompt placement\n// (files go into the prompt text instead). The staged absolute paths are values,\n// not telemetry keys (F-P1-3 \u2014 the caller registers a single synthetic '{files}').\nfunction expandFileArgs(\n staged: string[],\n fileInput: CliFileInputOptions | undefined,\n): string[] {\n const perFileArgs = fileInput?.perFileArgs ?? [\"@{path}\"];\n if (fileInput?.placement === \"prompt\") {\n return [];\n }\n return staged.flatMap((ref) =>\n perFileArgs.map((tpl) =>\n tpl.replace(\"{path}\", ref).replace(\"{name}\", path.basename(ref)),\n ),\n );\n}\n\nfunction materializeTemplateArg(\n templateArg: string,\n values: {\n prompt: string;\n model: string;\n outputFile?: string;\n },\n parameterKeys: string[],\n): string {\n switch (templateArg) {\n case \"{prompt}\":\n parameterKeys.push(\"prompt\");\n return values.prompt;\n case \"{model}\":\n parameterKeys.push(\"model\");\n return values.model;\n case \"{output_file}\":\n parameterKeys.push(\"output_file\");\n if (!values.outputFile) {\n throw new AiConnectError(\n \"validation_error\",\n \"CLI argsTemplate references {output_file} but no output file was prepared.\",\n );\n }\n return values.outputFile;\n default:\n if (templateArg.startsWith(\"--\")) {\n parameterKeys.push(templateArg);\n }\n return templateArg;\n }\n}\n\nasync function buildCliInvocation(\n context: GenerateContext,\n options?: CliClientOptions,\n): Promise<CliInvocation> {\n const route = context.route;\n // Resolve options BEFORE building the prompt so buildCliPrompt knows whether\n // the route can accept attachments (F-TS-1) \u2014 single resolution point.\n const cliOptions = resolveCliTransportOptions(route);\n const fileInput = cliOptions.fileInput;\n const attachments = context.request.attachments;\n const hasStageable = Boolean(fileInput) && attachments.length > 0;\n\n let prompt = buildCliPrompt(context, Boolean(fileInput));\n const commandLine = resolveCliCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const parameterKeys: string[] = [];\n let tempDir: string | undefined;\n let outputFile: string | undefined;\n\n const needsOutputFile = cliOptions.argsTemplate.includes(\"{output_file}\");\n if (needsOutputFile || hasStageable) {\n const created = await createCliTempDir(\n fileInput?.stagingDir ?? options?.staging?.dir,\n options?.staging?.prefix,\n );\n tempDir = created.tempDir;\n outputFile = created.outputFile;\n }\n\n // Stage attachments to disk (REQ-024) and resolve their references.\n let staged: string[] = [];\n if (hasStageable && tempDir && fileInput) {\n staged = await stageCliAttachments(\n attachments,\n path.join(tempDir, \"attachments\"),\n fileInput,\n );\n // prompt placement: append the staged references to the prompt text.\n if (fileInput.placement === \"prompt\" && staged.length > 0) {\n const separator = fileInput.separator ?? \" \";\n const mentionTemplate = fileInput.mentionTemplate ?? \"@{path}\";\n const mentions = staged\n .map((ref) =>\n mentionTemplate\n .replace(\"{path}\", ref)\n .replace(\"{name}\", path.basename(ref)),\n )\n .join(separator);\n prompt = `${prompt}${separator}${mentions}`;\n }\n }\n\n const args = [\n ...resolved.args,\n ...cliOptions.argsTemplate.flatMap((part) => {\n if (part === \"{files}\") {\n // Single synthetic telemetry key \u2014 never the expanded paths (F-P1-3).\n if (staged.length > 0) {\n parameterKeys.push(\"{files}\");\n }\n return expandFileArgs(staged, fileInput);\n }\n return [\n materializeTemplateArg(\n part,\n {\n prompt,\n model: route.model,\n ...(outputFile ? { outputFile } : {}),\n },\n parameterKeys,\n ),\n ];\n }),\n ];\n\n return {\n command: resolved.command,\n args,\n cwd: buildCliCwd(context, options),\n env: buildCliEnvironment(options),\n ...(tempDir ? { tempDir } : {}),\n ...(outputFile ? { outputFile } : {}),\n ...(options?.staging?.keep ? { keepStaging: true } : {}),\n parameterKeys,\n };\n}\n\n// Build a CliInvocation for a discovery \"list models\" command. Unlike\n// buildCliInvocation it has no GenerateContext (DiscoverAcpModelsContext carries\n// no request), so cwd falls back to options.cwd ?? process.cwd(), and there is no\n// {prompt}/{output_file} (the discovery argsTemplate is a plain list command;\n// {model} substitution is still honored for CLIs that need a model to list).\nfunction buildCliDiscoveryInvocation(\n route: NormalizedRoute,\n command: NormalizedCliDiscoveryCommand,\n options?: CliClientOptions,\n): CliInvocation {\n const commandLine = command.command?.trim()\n ? command.command\n : resolveCliCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const parameterKeys: string[] = [];\n // Discovery substitutes ONLY {model}; {prompt}/{output_file} are left literal\n // (a list command takes neither).\n const args = [\n ...resolved.args,\n ...command.argsTemplate.map((part) => {\n if (part === \"{model}\") {\n parameterKeys.push(\"model\");\n return route.model;\n }\n if (part.startsWith(\"--\")) {\n parameterKeys.push(part);\n }\n return part;\n }),\n ];\n\n return {\n command: resolved.command,\n args,\n cwd: path.resolve(options?.cwd ?? process.cwd()),\n env: buildCliEnvironment(options),\n parameterKeys,\n };\n}\n\n// Build a discovery catalog from the route's configured static model list\n// (advertisedModels + contextWindow). Reuses buildModelCatalog so the entry\n// shape (name id-fallback, requestedModelAdvertised, resolvedModelId) and the\n// GAP-A configured-contextWindow fill match every other provider's catalog.\nfunction buildStaticCliCatalog(\n route: NormalizedRoute,\n warning?: string,\n): AcpModelCatalog {\n const models: AcpModelInfo[] = route.advertisedModels.map((id) => ({\n modelId: id,\n name: id,\n }));\n const catalog = buildModelCatalog(\n route,\n models,\n currentModelIdForRoute(route, route.advertisedModels),\n );\n // FT-001: a static catalog produced as a FALLBACK from a failed/empty command\n // discovery carries a warning so it is distinguishable from a healthy static\n // catalog; a pure via:static route passes no warning.\n if (warning) {\n catalog.warnings = [...(catalog.warnings ?? []), warning];\n }\n return catalog;\n}\n\nfunction statsToUsage(stats: unknown): UsageInfo | undefined {\n if (!stats || typeof stats !== \"object\") {\n return undefined;\n }\n\n const record = stats as Record<string, unknown>;\n const inputTokens =\n typeof record.inputTokens === \"number\"\n ? record.inputTokens\n : typeof record.promptTokens === \"number\"\n ? record.promptTokens\n : typeof record.prompt_tokens === \"number\"\n ? record.prompt_tokens\n : undefined;\n const outputTokens =\n typeof record.outputTokens === \"number\"\n ? record.outputTokens\n : typeof record.completionTokens === \"number\"\n ? record.completionTokens\n : typeof record.output_tokens === \"number\"\n ? record.output_tokens\n : undefined;\n const totalTokens =\n typeof record.totalTokens === \"number\"\n ? record.totalTokens\n : inputTokens !== undefined || outputTokens !== undefined\n ? (inputTokens ?? 0) + (outputTokens ?? 0)\n : undefined;\n\n if (\n inputTokens === undefined &&\n outputTokens === undefined &&\n totalTokens === undefined\n ) {\n return undefined;\n }\n\n return {\n calls: 1,\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n };\n}\n\nfunction getValueByPath(\n value: unknown,\n dotPath: string,\n): unknown {\n const segments = dotPath.split(\".\").filter(Boolean);\n let current: unknown = value;\n\n for (const segment of segments) {\n if (Array.isArray(current)) {\n const index = Number(segment);\n if (!Number.isInteger(index)) {\n return undefined;\n }\n current = current[index];\n continue;\n }\n\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\n// Split newline-delimited JSON (one object per non-empty line) into parsed\n// records. Shared by parseGenericJsonlCli, parseCodexCli, and parseCliModelList.\nfunction splitJsonlLines(stdout: string): unknown[] {\n return stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => JSON.parse(line));\n}\n\nfunction normalizeErrorMessage(\n value: unknown,\n): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n\n if (\n value &&\n typeof value === \"object\" &&\n \"message\" in value &&\n typeof (value as Record<string, unknown>).message === \"string\"\n ) {\n return ((value as Record<string, unknown>).message as string).trim();\n }\n\n return undefined;\n}\n\nfunction findJsonlSelection(\n entries: unknown[],\n selector: CliJsonLineSelector,\n): unknown {\n for (const entry of entries) {\n if (selector.wherePath) {\n const whereValue = getValueByPath(entry, selector.wherePath);\n if (whereValue !== selector.whereEquals) {\n continue;\n }\n }\n\n const value = getValueByPath(entry, selector.path);\n if (value !== undefined) {\n return value;\n }\n }\n\n return undefined;\n}\n\nfunction parseGenericJsonCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"json\" }>,\n): RouteHandlerGenerateResult {\n const payload = JSON.parse(stdout);\n const errorValue = parser.errorPath\n ? getValueByPath(payload, parser.errorPath)\n : undefined;\n const errorMessage = normalizeErrorMessage(errorValue);\n if (errorMessage) {\n throw new AiConnectError(\"temporary_unavailable\", errorMessage);\n }\n\n const text = getValueByPath(payload, parser.textPath);\n if (typeof text !== \"string\" || !text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI json parser did not find text at path \"${parser.textPath}\".`,\n );\n }\n\n const usageValue = parser.usagePath\n ? getValueByPath(payload, parser.usagePath)\n : undefined;\n const usage = statsToUsage(usageValue);\n\n return {\n text: text.trim(),\n ...(usage ? { usage } : {}),\n data: payload,\n };\n}\n\nfunction parseGenericJsonlCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"jsonl\" }>,\n): RouteHandlerGenerateResult {\n const entries = splitJsonlLines(stdout);\n const errorValue = parser.error\n ? findJsonlSelection(entries, parser.error)\n : undefined;\n const errorMessage = normalizeErrorMessage(errorValue);\n if (errorMessage) {\n throw new AiConnectError(\"temporary_unavailable\", errorMessage);\n }\n\n const text = findJsonlSelection(entries, parser.text);\n if (typeof text !== \"string\" || !text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI jsonl parser did not resolve text using selector \"${parser.text.path}\".`,\n );\n }\n\n const usageValue = parser.usage\n ? findJsonlSelection(entries, parser.usage)\n : undefined;\n const usage = statsToUsage(usageValue);\n\n return {\n text: text.trim(),\n ...(usage ? { usage } : {}),\n data: entries,\n };\n}\n\n// Matches ANSI/VT100 escape sequences (CSI color/cursor codes, spinner noise)\n// emitted by interactive print-mode CLIs. Used only by the raw `text` parser.\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escapes are control chars by definition.\nconst ANSI_ESCAPE_PATTERN = /\u001B\\[[0-?]*[ -/]*[@-~]/g;\n\nfunction parseTextCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"text\" }>,\n): RouteHandlerGenerateResult {\n let text = stdout;\n if (parser.stripAnsi) {\n text = text.replace(ANSI_ESCAPE_PATTERN, \"\");\n }\n if (parser.trim !== false) {\n text = text.trim();\n }\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"CLI text parser produced no output.\",\n );\n }\n\n // Print-mode plain text carries no usage/token information; none is fabricated.\n return { text, data: stdout };\n}\n\nfunction modelInfoFromRecord(\n record: unknown,\n selector: CliDiscoveryCommandModelsSelector,\n): AcpModelInfo | undefined {\n const rawId = getValueByPath(record, selector.idPath);\n const modelId = typeof rawId === \"string\" ? rawId.trim() : \"\";\n if (!modelId) {\n return undefined;\n }\n // name id-fallback mirrors parseOpenAiModelCatalog / normalizeAcpModel so cli\n // entries match every other provider's catalog shape (AcpModelInfo.name is required).\n const rawName = selector.namePath\n ? getValueByPath(record, selector.namePath)\n : undefined;\n const name =\n typeof rawName === \"string\" && rawName.trim().length > 0 ? rawName : modelId;\n const rawDescription = selector.descriptionPath\n ? getValueByPath(record, selector.descriptionPath)\n : undefined;\n const description =\n typeof rawDescription === \"string\" && rawDescription.trim().length > 0\n ? rawDescription\n : undefined;\n const rawContext = selector.contextLengthPath\n ? getValueByPath(record, selector.contextLengthPath)\n : undefined;\n const contextLength =\n typeof rawContext === \"number\" && Number.isFinite(rawContext) && rawContext > 0\n ? Math.floor(rawContext)\n : undefined;\n\n return {\n modelId,\n name,\n ...(description ? { description } : {}),\n // FT-002: a contextLength read from the list-command output is a discovered\n // value (consistent with the API parsers), so tag its provenance.\n ...(contextLength !== undefined\n ? { contextLength, contextWindowSource: \"discovered\" as const }\n : {}),\n };\n}\n\n/**\n * Parse the stdout of a CLI \"list models\" command into AcpModelInfo[].\n * Reuses the json|jsonl|text parser enum (no generation-parser overlap):\n * - text: one trimmed non-empty line per model id (name = id).\n * - jsonl: one model record per line, mapped via the selector.\n * - json: a model array at selector.path (or the payload root), mapped via the selector.\n */\nfunction parseCliModelList(\n stdout: string,\n parser: CliDiscoveryCommandParser,\n selector?: CliDiscoveryCommandModelsSelector,\n): AcpModelInfo[] {\n if (parser.kind === \"text\") {\n let text = stdout;\n if (parser.stripAnsi) {\n text = text.replace(ANSI_ESCAPE_PATTERN, \"\");\n }\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => ({ modelId: line, name: line }));\n }\n\n if (!selector) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI ${parser.kind} discovery parser requires a models selector with idPath.`,\n );\n }\n\n const records: unknown[] =\n parser.kind === \"jsonl\"\n ? splitJsonlLines(stdout)\n : (() => {\n const payload = JSON.parse(stdout);\n const arr = selector.path\n ? getValueByPath(payload, selector.path)\n : payload;\n return Array.isArray(arr) ? arr : [];\n })();\n\n const models: AcpModelInfo[] = [];\n for (const record of records) {\n const info = modelInfoFromRecord(record, selector);\n if (info) {\n models.push(info);\n }\n }\n return models;\n}\n\nfunction parseClaudeCli(stdout: string): RouteHandlerGenerateResult {\n const payload = JSON.parse(stdout) as Record<string, unknown>;\n const text =\n typeof payload.result === \"string\"\n ? payload.result\n : typeof payload.response === \"string\"\n ? payload.response\n : typeof payload.text === \"string\"\n ? payload.text\n : undefined;\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Claude/OpenClaude CLI JSON output did not contain result text.\",\n );\n }\n const usage = payload.usage ? statsToUsage(payload.usage) : undefined;\n\n return {\n text,\n ...(usage ? { usage } : {}),\n data: payload,\n };\n}\n\nfunction parseCodexCli(\n stdout: string,\n outputFileContent: string | undefined,\n): RouteHandlerGenerateResult {\n const events = splitJsonlLines(stdout) as Record<string, unknown>[];\n let text = outputFileContent?.trim() || undefined;\n let usage: UsageInfo | undefined;\n\n for (const event of events) {\n if (event.type === \"turn.completed\" && event.usage) {\n const rawUsage = event.usage as Record<string, unknown>;\n // ACCUMULATE across turns (#7): a multi-turn Codex run emits one\n // `turn.completed` per turn. ASSIGNING here would discard every turn but\n // the last and pin `calls` to 1; instead sum the token fields and count one\n // call per usage-bearing turn.\n const base = usage ?? { calls: 0 };\n const turnInput =\n typeof rawUsage.input_tokens === \"number\"\n ? rawUsage.input_tokens\n : undefined;\n const turnCached =\n typeof rawUsage.cached_input_tokens === \"number\"\n ? rawUsage.cached_input_tokens\n : undefined;\n const turnOutput =\n typeof rawUsage.output_tokens === \"number\"\n ? rawUsage.output_tokens\n : undefined;\n const inputTokens =\n turnInput !== undefined\n ? (base.inputTokens ?? 0) + turnInput\n : base.inputTokens;\n const cachedReadTokens =\n turnCached !== undefined\n ? (base.cachedReadTokens ?? 0) + turnCached\n : base.cachedReadTokens;\n const outputTokens =\n turnOutput !== undefined\n ? (base.outputTokens ?? 0) + turnOutput\n : base.outputTokens;\n usage = {\n calls: (base.calls ?? 0) + 1,\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n };\n if (\n usage.inputTokens !== undefined ||\n usage.outputTokens !== undefined\n ) {\n usage.totalTokens =\n (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);\n }\n }\n\n const item =\n event.item && typeof event.item === \"object\"\n ? (event.item as Record<string, unknown>)\n : undefined;\n const details =\n item?.details && typeof item.details === \"object\"\n ? (item.details as Record<string, unknown>)\n : undefined;\n if (\n !text &&\n details?.type === \"agent_message\" &&\n typeof details.text === \"string\"\n ) {\n text = details.text;\n }\n }\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Codex CLI JSON output did not contain final text output.\",\n );\n }\n\n return {\n text,\n ...(usage ? { usage } : {}),\n data: events,\n };\n}\n\nfunction parseCliResult(\n route: NormalizedRoute,\n result: CliExecutionResult,\n outputFileContent: string | undefined,\n): RouteHandlerGenerateResult {\n const stdout = result.stdout.trim();\n if (!stdout && !outputFileContent?.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n result.stderr.trim() ||\n `CLI transport \"${route.transport.id}\" produced no output.`,\n );\n }\n const cliOptions = resolveCliTransportOptions(route);\n if (route.transport.cli?.parser) {\n const parser = cliOptions.parser;\n if (!parser) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI route \"${route.id}\" declared a parser override but normalization did not preserve it.`,\n );\n }\n\n switch (parser.kind) {\n case \"text\":\n // Pass the RAW stdout (not the upstream-trimmed copy) so the parser's\n // own `trim` option fully controls leading/trailing whitespace.\n return parseTextCli(result.stdout, parser);\n case \"json\":\n return parseGenericJsonCli(stdout, parser);\n default:\n return parseGenericJsonlCli(stdout, parser);\n }\n }\n\n switch (cliOptions.preset) {\n case \"pi\":\n // pi print mode emits the answer as plain text on stdout.\n return parseTextCli(stdout, { kind: \"text\" });\n case \"claude\":\n case \"openclaude\":\n return parseClaudeCli(stdout);\n case \"codex\":\n return parseCodexCli(stdout, outputFileContent);\n default:\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${route.transport.id}\" does not define a parser and has no matching built-in preset.`,\n );\n }\n}\n\nfunction capturePhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\nasync function executeCliInvocation(\n invocation: CliInvocation,\n timeoutMs: number,\n phases: WideEventTransportPhase[],\n signal?: AbortSignal,\n): Promise<CliExecutionResult> {\n const spawnStartedAt = Date.now();\n const child = spawn(invocation.command, invocation.args, {\n cwd: invocation.cwd,\n env: invocation.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n capturePhase(phases, \"spawn\", spawnStartedAt);\n\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n\n const executeStartedAt = Date.now();\n return await new Promise((resolve, reject) => {\n let abortListener: (() => void) | undefined;\n\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(\n new AiConnectError(\n \"temporary_unavailable\",\n `CLI transport \"${quoteArg(invocation.command)}\" timed out after ${timeoutMs}ms.`,\n ),\n );\n }, timeoutMs);\n\n const cleanup = (): void => {\n clearTimeout(timer);\n if (signal && abortListener) {\n signal.removeEventListener(\"abort\", abortListener);\n abortListener = undefined;\n }\n };\n\n // On the merged abort signal (caller cancel OR op timeout, CD-4) SIGKILL the child so a\n // cancellation propagates to the spawned process. The reject reason is normalized to the\n // canonical abort/timeout code by the client via abort.reason.\n if (signal) {\n if (signal.aborted) {\n child.kill(\"SIGKILL\");\n cleanup();\n reject(new AiConnectError(\"aborted\", \"CLI transport aborted before execution.\"));\n return;\n }\n abortListener = () => {\n child.kill(\"SIGKILL\");\n cleanup();\n reject(new AiConnectError(\"aborted\", \"CLI transport aborted.\"));\n };\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n child.once(\"error\", (error) => {\n cleanup();\n reject(\n new AiConnectError(\n \"local_harness_unavailable\",\n error instanceof Error ? error.message : String(error),\n ),\n );\n });\n\n child.once(\"close\", (exitCode) => {\n cleanup();\n capturePhase(phases, \"execute\", executeStartedAt);\n resolve({\n stdout,\n stderr,\n exitCode,\n });\n });\n });\n}\n\nasync function cleanupCliInvocation(invocation: CliInvocation): Promise<void> {\n // keepStaging retains the ENTIRE per-invocation temp dir (output + staged\n // attachments) for debugging (REQ-024, F-CR-3).\n if (invocation.tempDir && !invocation.keepStaging) {\n await fs.rm(invocation.tempDir, { recursive: true, force: true });\n }\n}\n\nexport function createCliTransportManager(\n options?: CliClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<RouteHandlerGenerateResult>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n} {\n return {\n async discoverModels(context): Promise<AcpModelCatalog> {\n const source = resolveCliDiscoverySource(context.route);\n\n if (source.via === \"none\") {\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${context.route.transport.id}\" does not support model discovery (no list command, no ACP sidecar, and no configured models[]).`,\n );\n }\n if (source.via === \"acp\") {\n // The dispatch layer handles acp by delegating to a synthetic ACP route\n // (createCliDiscoveryAcpRoute); the cli manager should not be reached.\n throw new AiConnectError(\n \"not_supported\",\n `CLI route \"${context.route.id}\" resolves discovery via acp; dispatch to the acp discovery route instead.`,\n );\n }\n if (source.via === \"static\") {\n return buildStaticCliCatalog(context.route);\n }\n\n // via === \"command\": run the configured list command and parse its stdout.\n const phases: WideEventTransportPhase[] = [];\n const invocation = buildCliDiscoveryInvocation(\n context.route,\n source.command,\n options,\n );\n context.telemetry?.captureTransport({\n protocol: \"cli\",\n endpoint: invocation.command,\n method: \"process\",\n bodyKeys: [\"argv\"],\n parameterKeys: invocation.parameterKeys,\n phases,\n stream: false,\n });\n\n try {\n let models: AcpModelInfo[];\n try {\n const execution = await executeCliInvocation(\n invocation,\n options?.timeoutMs ?? 60_000,\n phases,\n context.abort.signal,\n );\n if (execution.exitCode !== 0 || !execution.stdout.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n execution.stderr.trim() ||\n `CLI discovery command for \"${context.route.transport.id}\" exited with code ${execution.exitCode ?? \"null\"}.`,\n );\n }\n models = parseCliModelList(\n execution.stdout,\n source.command.parser,\n source.command.models,\n );\n } catch (error) {\n // Never swallow a caller cancellation; propagate it.\n if (error instanceof AiConnectError && error.code === \"aborted\") {\n throw error;\n }\n if (source.fallback === \"static\") {\n const detail =\n error instanceof Error ? error.message : String(error);\n return buildStaticCliCatalog(\n context.route,\n `CLI discovery command for \"${context.route.transport.id}\" failed (${detail}); fell back to the static models[] catalog.`,\n );\n }\n throw error;\n }\n\n if (models.length === 0) {\n // Zero parseable models: fall back to static only when configured;\n // otherwise fail loud (fallback:'none' is a deliberate no-safety-net).\n if (source.fallback === \"static\") {\n return buildStaticCliCatalog(\n context.route,\n `CLI discovery command for \"${context.route.transport.id}\" returned no models; fell back to the static models[] catalog.`,\n );\n }\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI discovery command for \"${context.route.transport.id}\" returned no models.`,\n );\n }\n\n return buildModelCatalog(\n context.route,\n models,\n currentModelIdForRoute(\n context.route,\n models.map((model) => model.modelId),\n ),\n );\n } finally {\n await cleanupCliInvocation(invocation);\n }\n },\n\n async runPrompt(context): Promise<RouteHandlerGenerateResult> {\n const invocation = await buildCliInvocation(context, options);\n const phases: WideEventTransportPhase[] = [];\n const transport: WideEventTransportSummary = {\n protocol: \"cli\",\n endpoint: invocation.command,\n method: \"process\",\n bodyKeys: [\"argv\"],\n parameterKeys: invocation.parameterKeys,\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n try {\n const execution = await executeCliInvocation(\n invocation,\n options?.timeoutMs ?? 60_000,\n phases,\n context.abort.signal,\n );\n\n const outputFileContent = invocation.outputFile\n ? await fs.readFile(invocation.outputFile, \"utf8\").catch(() => \"\")\n : undefined;\n\n if (execution.exitCode !== 0) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n execution.stderr.trim() ||\n `CLI transport \"${context.route.transport.id}\" exited with code ${execution.exitCode ?? \"null\"}.`,\n );\n }\n\n const result = parseCliResult(\n context.route,\n execution,\n outputFileContent,\n );\n if (execution.stderr.trim()) {\n result.warnings = [...(result.warnings ?? []), execution.stderr.trim()];\n }\n return result;\n } finally {\n await cleanupCliInvocation(invocation);\n }\n },\n };\n}\n", "import { spawn } from \"node:child_process\";\nimport net from \"node:net\";\n\nimport { AI_CONNECT_DEFAULT_SERVER_COMMANDS } from \"./server-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport type {\n AcpModelCatalog,\n AcpModelInfo,\n DiscoverAcpModelsContext,\n FetchLike,\n GenerateContext,\n NormalizedRoute,\n RouteHandlerGenerateResult,\n ServerClientOptions,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype ServerInstance = {\n origin: string;\n dispose: () => Promise<void>;\n};\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\"validation_error\", \"Server command line is empty.\");\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction resolveServerCommand(\n route: NormalizedRoute,\n options?: ServerClientOptions,\n): string {\n if (route.transport.command?.trim()) {\n return route.transport.command.trim();\n }\n\n const candidates = [\n `${route.provider}:${route.transport.id}`,\n route.transport.id,\n route.provider,\n ];\n\n for (const candidate of candidates) {\n const override = options?.commands?.[candidate]?.trim();\n if (override) {\n return override;\n }\n }\n\n const preset =\n AI_CONNECT_DEFAULT_SERVER_COMMANDS[`${route.provider}:${route.transport.id}`];\n if (preset) {\n return preset;\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `No server command preset is registered for route \"${route.id}\". Provide transport.command or server.commands.`,\n );\n}\n\nexport function resolveServerExecutable(\n route: NormalizedRoute,\n options?: ServerClientOptions,\n): string {\n return splitCommandLine(resolveServerCommand(route, options)).command;\n}\n\nfunction resolveFetch(fetchLike: FetchLike | undefined): FetchLike {\n if (fetchLike) {\n return fetchLike;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new AiConnectError(\n \"validation_error\",\n \"No fetch implementation is available for server transport.\",\n );\n}\n\nfunction joinUrl(baseUrl: string, pathname: string): string {\n const normalizedBase = baseUrl.endsWith(\"/\")\n ? baseUrl.slice(0, -1)\n : baseUrl;\n\n return `${normalizedBase}${pathname.startsWith(\"/\") ? pathname : `/${pathname}`}`;\n}\n\nfunction buildServerPrompt(context: GenerateContext): string {\n if (context.request.operation !== \"text\") {\n throw new AiConnectError(\n \"not_supported\",\n `Server transport \"${context.route.transport.id}\" only supports text requests.`,\n );\n }\n\n if (context.request.attachments.length > 0 || context.request.image) {\n throw new AiConnectError(\n \"not_supported\",\n `Server transport \"${context.route.transport.id}\" does not support attachments or image inputs.`,\n );\n }\n\n return context.request.messages\n .map((message) => {\n if (message.role === \"user\") {\n return message.content;\n }\n\n return `${message.role.toUpperCase()}:\\n${message.content}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction capturePhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\nasync function findAvailablePort(host = \"127.0.0.1\"): Promise<number> {\n return await new Promise((resolve, reject) => {\n const server = net.createServer();\n server.once(\"error\", reject);\n server.listen(0, host, () => {\n const address = server.address();\n const port =\n address && typeof address === \"object\" ? address.port : undefined;\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n\n if (!port) {\n reject(new Error(\"Failed to allocate an ephemeral port.\"));\n return;\n }\n\n resolve(port);\n });\n });\n });\n}\n\nasync function waitForServerHealth(\n fetchLike: FetchLike,\n origin: string,\n timeoutMs: number,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastError: unknown;\n\n while (Date.now() < deadline) {\n try {\n const response = await fetchLike(joinUrl(origin, \"/global/health\"));\n if (response.ok) {\n return;\n }\n lastError = new Error(\n `Server health probe failed with status ${response.status}.`,\n );\n } catch (error) {\n lastError = error;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n const message =\n lastError instanceof Error ? lastError.message : \"Unknown server startup failure.\";\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `Server transport did not become healthy within ${timeoutMs}ms. ${message}`,\n );\n}\n\nasync function spawnServerInstance(\n route: NormalizedRoute,\n options: ServerClientOptions | undefined,\n phases: WideEventTransportPhase[],\n cwdOverride?: string,\n): Promise<ServerInstance> {\n const commandLine = resolveServerCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const port = await findAvailablePort();\n const host = \"127.0.0.1\";\n const origin = `http://${host}:${port}`;\n const args = [...resolved.args];\n if (!args.includes(\"serve\")) {\n args.push(\"serve\");\n }\n args.push(\"--hostname\", host, \"--port\", String(port));\n\n const spawnStartedAt = Date.now();\n const child = spawn(resolved.command, args, {\n cwd: cwdOverride ?? options?.cwd ?? process.cwd(),\n env: {\n ...process.env,\n ...(options?.env ?? {}),\n },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n capturePhase(phases, \"spawn\", spawnStartedAt);\n\n const healthStartedAt = Date.now();\n try {\n await waitForServerHealth(\n resolveFetch(options?.fetch),\n origin,\n options?.startupTimeoutMs ?? 15_000,\n );\n capturePhase(phases, \"health\", healthStartedAt);\n } catch (error) {\n child.kill(\"SIGKILL\");\n throw new AiConnectError(\n \"local_harness_unavailable\",\n stderr.trim() ||\n (error instanceof Error\n ? error.message\n : \"Failed to start local server transport.\"),\n );\n }\n\n return {\n origin,\n dispose: async () => {\n if (child.killed) {\n return;\n }\n\n child.kill(\"SIGTERM\");\n await new Promise<void>((resolve) => {\n child.once(\"close\", () => resolve());\n setTimeout(() => {\n child.kill(\"SIGKILL\");\n resolve();\n }, 1_000).unref?.();\n });\n },\n };\n}\n\nfunction providerIdsForRoute(\n route: NormalizedRoute,\n providers: Record<string, unknown>[],\n): string[] {\n if (route.provider === \"opencode\") {\n return providers\n .map((provider) =>\n typeof provider.id === \"string\" ? provider.id : undefined,\n )\n .filter((value): value is string => Boolean(value));\n }\n\n return [route.provider];\n}\n\nfunction modelsFromServerPayload(\n route: NormalizedRoute,\n payload: Record<string, unknown>,\n): AcpModelCatalog {\n const providers = Array.isArray(payload.providers)\n ? payload.providers.filter(\n (provider): provider is Record<string, unknown> =>\n Boolean(provider) && typeof provider === \"object\",\n )\n : [];\n const selectedProviders = new Set(providerIdsForRoute(route, providers));\n const availableModels: AcpModelInfo[] = [];\n\n for (const provider of providers) {\n if (\n typeof provider.id !== \"string\" ||\n !selectedProviders.has(provider.id) ||\n !provider.models ||\n typeof provider.models !== \"object\"\n ) {\n continue;\n }\n\n for (const [modelId, value] of Object.entries(\n provider.models as Record<string, unknown>,\n )) {\n const model =\n value && typeof value === \"object\"\n ? (value as Record<string, unknown>)\n : {};\n availableModels.push({\n modelId,\n name: typeof model.name === \"string\" ? model.name : modelId,\n ...(typeof model.family === \"string\"\n ? { description: model.family }\n : {}),\n metadata: {\n providerId: provider.id,\n },\n });\n }\n }\n\n const defaults =\n payload.default && typeof payload.default === \"object\"\n ? (payload.default as Record<string, unknown>)\n : undefined;\n const currentModelId = (() => {\n for (const providerId of selectedProviders) {\n const candidate = defaults?.[providerId];\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate;\n }\n }\n\n return undefined;\n })();\n const requestedModelAdvertised = availableModels.some(\n (model) => model.modelId === route.model,\n );\n\n return {\n requestedModelId: route.model,\n requestedModelAdvertised,\n ...(requestedModelAdvertised ? { resolvedModelId: route.model } : {}),\n ...(currentModelId ? { currentModelId } : {}),\n availableModels,\n };\n}\n\nfunction parseServerGenerateResult(\n payload: Record<string, unknown>,\n): RouteHandlerGenerateResult {\n const parts = Array.isArray(payload.parts)\n ? payload.parts.filter(\n (part): part is Record<string, unknown> =>\n Boolean(part) && typeof part === \"object\",\n )\n : [];\n const text = parts\n .map((part) => (typeof part.text === \"string\" ? part.text : \"\"))\n .filter(Boolean)\n .join(\"\");\n\n if (!text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Server transport response did not contain text parts.\",\n );\n }\n\n return {\n text: text.trim(),\n data: payload,\n };\n}\n\nexport function createServerTransportManager(\n options?: ServerClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<RouteHandlerGenerateResult>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n verifyRoute: (\n route: NormalizedRoute,\n ) => Promise<{\n ok: boolean;\n message?: string;\n }>;\n dispose: () => Promise<void>;\n} {\n const fetchLike = resolveFetch(options?.fetch);\n const instances = new Map<string, Promise<ServerInstance>>();\n\n async function getInstance(\n route: NormalizedRoute,\n phases: WideEventTransportPhase[],\n cwdOverride?: string,\n ): Promise<ServerInstance> {\n const baseUrl = route.transport.baseUrl?.trim();\n if (baseUrl) {\n return {\n origin: baseUrl,\n dispose: async () => {},\n };\n }\n\n const key = [\n route.id,\n cwdOverride ?? options?.cwd ?? process.cwd(),\n JSON.stringify(options?.env ?? {}),\n ].join(\"\\u0002\");\n const existing = instances.get(key);\n if (existing) {\n return await existing;\n }\n\n const pending = spawnServerInstance(route, options, phases, cwdOverride);\n instances.set(key, pending);\n try {\n return await pending;\n } catch (error) {\n instances.delete(key);\n throw error;\n }\n }\n\n return {\n async runPrompt(context): Promise<RouteHandlerGenerateResult> {\n const phases: WideEventTransportPhase[] = [];\n const instance = await getInstance(\n context.route,\n phases,\n context.request.workingDirectory,\n );\n const transport: WideEventTransportSummary = {\n protocol: \"http\",\n endpoint: joinUrl(instance.origin, \"/session/:id/message\"),\n method: \"POST\",\n bodyKeys: [\"model\", \"parts\"],\n parameterKeys: [\"model\", \"parts[0].text\"],\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n const sessionStartedAt = Date.now();\n const sessionResponse = await fetchLike(joinUrl(instance.origin, \"/session\"), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n });\n capturePhase(phases, \"session/create\", sessionStartedAt);\n if (!sessionResponse.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport failed to create session (${sessionResponse.status}).`,\n );\n }\n\n const sessionPayload = (await sessionResponse.json()) as Record<string, unknown>;\n const sessionId =\n typeof sessionPayload.id === \"string\"\n ? sessionPayload.id\n : typeof sessionPayload.sessionID === \"string\"\n ? sessionPayload.sessionID\n : undefined;\n if (!sessionId) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Server transport did not return a session id.\",\n );\n }\n\n try {\n const promptStartedAt = Date.now();\n const response = await fetchLike(\n joinUrl(instance.origin, `/session/${sessionId}/message`),\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: context.route.model,\n parts: [\n {\n type: \"text\",\n text: buildServerPrompt(context),\n },\n ],\n }),\n signal: context.abort.signal,\n },\n );\n capturePhase(phases, \"session/prompt\", promptStartedAt);\n if (!response.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport prompt failed (${response.status}).`,\n );\n }\n\n return parseServerGenerateResult(\n (await response.json()) as Record<string, unknown>,\n );\n } finally {\n void fetchLike(joinUrl(instance.origin, `/session/${sessionId}`), {\n method: \"DELETE\",\n }).catch(() => {});\n }\n },\n async discoverModels(context): Promise<AcpModelCatalog> {\n const phases: WideEventTransportPhase[] = [];\n const instance = await getInstance(context.route, phases);\n const transport: WideEventTransportSummary = {\n protocol: \"http\",\n endpoint: joinUrl(instance.origin, \"/config/providers\"),\n method: \"GET\",\n bodyKeys: [],\n parameterKeys: [],\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n const startedAt = Date.now();\n const response = await fetchLike(joinUrl(instance.origin, \"/config/providers\"));\n capturePhase(phases, \"config/providers\", startedAt);\n if (!response.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport model discovery failed (${response.status}).`,\n );\n }\n\n return modelsFromServerPayload(\n context.route,\n (await response.json()) as Record<string, unknown>,\n );\n },\n async verifyRoute(route): Promise<{ ok: boolean; message?: string }> {\n if (route.transport.baseUrl?.trim()) {\n try {\n const response = await fetchLike(\n joinUrl(route.transport.baseUrl, \"/global/health\"),\n );\n if (response.ok) {\n return { ok: true };\n }\n\n return {\n ok: false,\n message: `Server health endpoint returned ${response.status}.`,\n };\n } catch (error) {\n return {\n ok: false,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n return { ok: true };\n },\n async dispose(): Promise<void> {\n const values = await Promise.all([...instances.values()]);\n instances.clear();\n await Promise.all(values.map((instance) => instance.dispose()));\n },\n };\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport {\n createAcpTransportManager,\n resolveAcpExecutable,\n} from \"./acp.js\";\nimport {\n createCliDiscoveryAcpRoute,\n createCliTransportManager,\n resolveCliDiscoverySource,\n resolveCliExecutable,\n} from \"./cli.js\";\nimport {\n createServerTransportManager,\n resolveServerExecutable,\n} from \"./server.js\";\nimport type {\n AcpClientOptions,\n CliClientOptions,\n RouteHandlerRegistry,\n ServerClientOptions,\n} from \"./types.js\";\n\ntype LocalRouteHandlers = {\n handlers: RouteHandlerRegistry;\n dispose: () => Promise<void>;\n};\n\nexport function createLocalRouteHandlers(\n options: {\n acp?: AcpClientOptions;\n cli?: CliClientOptions;\n server?: ServerClientOptions;\n } = {},\n): LocalRouteHandlers {\n const acpTransport = createAcpTransportManager(options.acp);\n const cliTransport = createCliTransportManager(options.cli);\n const serverTransport = createServerTransportManager(options.server);\n\n return {\n handlers: {\n \"*:acp\": {\n async generate(context) {\n return acpTransport.runPrompt(context);\n },\n stream(context) {\n // C9 / OQ-13: the first real ACP delta producer \u2014 emits {type:'delta'} per\n // agent_message_chunk then exactly one terminal {type:'result'}.\n return acpTransport.streamPrompt(context);\n },\n async discoverModels(context) {\n return acpTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n const executable = resolveAcpExecutable(route, options.acp);\n const available = await runtime.hasCommand?.(executable);\n if (available) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message: `Required ACP executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\n \"validation_error\",\n \"ACP route verification failed.\",\n );\n\n return [\n {\n code: \"handler_issue\",\n message: normalized.message,\n },\n ];\n }\n },\n },\n \"*:cli\": {\n async generate(context) {\n return cliTransport.runPrompt(context);\n },\n async discoverModels(context) {\n const source = resolveCliDiscoverySource(context.route);\n // acp source: delegate to a synthetic ACP discovery route (unchanged).\n if (source.via === \"acp\") {\n const discoveryRoute = createCliDiscoveryAcpRoute(context.route);\n if (!discoveryRoute) {\n throw new AiConnectError(\n \"not_supported\",\n `CLI route \"${context.route.id}\" does not define a model discovery backend.`,\n );\n }\n return acpTransport.discoverModels({\n ...context,\n route: discoveryRoute,\n });\n }\n // command / static / none: handled by the cli transport manager\n // (none throws not_supported there).\n return cliTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n const executable = resolveCliExecutable(route, options.cli);\n const available = await runtime.hasCommand?.(executable);\n if (available) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message: `Required CLI executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\n \"validation_error\",\n \"CLI route verification failed.\",\n );\n\n return [\n {\n code: \"handler_issue\",\n message: normalized.message,\n },\n ];\n }\n },\n },\n \"*:server\": {\n async generate(context) {\n return serverTransport.runPrompt(context);\n },\n async discoverModels(context) {\n return serverTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n if (!route.transport.baseUrl) {\n const executable = resolveServerExecutable(route, options.server);\n const available = await runtime.hasCommand?.(executable);\n if (!available) {\n return [\n {\n code: \"handler_issue\",\n message: `Required server executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n }\n }\n\n const result = await serverTransport.verifyRoute(route);\n if (result.ok) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message:\n result.message ??\n `Server route \"${route.id}\" did not pass verification.`,\n },\n ];\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\n \"validation_error\",\n \"Server route verification failed.\",\n );\n\n return [\n {\n code: \"handler_issue\",\n message: normalized.message,\n },\n ];\n }\n },\n },\n },\n dispose: async () => {\n await acpTransport.dispose();\n await serverTransport.dispose();\n },\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["inferredId", "extension", "index", "delimiter", "transportSummary", "finalError", "options", "summarizeToolChoice", "summarizeParameters", "response", "TEXT_EXTENSIONS", "isRecord", "basename", "parseDataUrl", "TEXT_EXTENSIONS", "isRecord", "sumOptionalNumbers", "result", "spawn", "fs", "os", "path", "splitCommandLine", "path", "fs", "os", "spawn", "spawn", "splitCommandLine", "capturePhase", "spawn", "extension"]
3
+ "sources": ["../../src/cli-presets.ts", "../../src/errors.ts", "../../src/config.ts", "../../src/fanout.ts", "../../src/files.ts", "../../src/logging.ts", "../../src/router.ts", "../../src/model-reference.ts", "../../src/probe.ts", "../../src/runtime.ts", "../../src/client.ts", "../../src/image.ts", "../../src/default-handlers.ts", "../../src/acp-presets.ts", "../../src/server-presets.ts", "../../src/catalog.ts", "../../src/browser.ts", "../../src/local.ts", "../../src/acp.ts", "../../src/transport-runtime.ts", "../../src/cli.ts", "../../src/server.ts", "../../src/local-handlers.ts"],
4
+ "sourcesContent": ["import type {\n CliTransportOptions,\n CliTransportPresetId,\n} from \"./types.js\";\n\nexport type CliTransportPreset = {\n id: CliTransportPresetId;\n label: string;\n command: string;\n transportId: string;\n options: CliTransportOptions;\n};\n\nexport const AI_CONNECT_DEFAULT_CLI_PRESETS: Record<\n CliTransportPresetId,\n CliTransportPreset\n> =\n {\n pi: {\n id: \"pi\",\n label: \"pi (coding agent)\",\n command: \"pi\",\n transportId: \"pi-cli\",\n options: {\n preset: \"pi\",\n // pi print mode emits the answer as plain text on stdout (no JSON wrapper),\n // and has no ACP mode \u2014 so it uses the raw `text` parser and no discovery sidecar.\n // pi takes file/image attachments as separate `@<path>` argv tokens (REQ-024);\n // {files} expands one `@<staged-path>` token per attachment. pi stages all\n // categories (PDFs as-is, no extraction guarantee).\n // H10 (flag injection): the `--` end-of-options token precedes {files}/{prompt}\n // \u2014 both are BARE positionals here \u2014 so an `@<path>` reference or a prompt that\n // starts with `-` is parsed by pi as a positional, never as a flag.\n argsTemplate: [\"--print\", \"--model\", \"{model}\", \"--\", \"{files}\", \"{prompt}\"],\n discovery: {\n via: \"none\",\n },\n parser: {\n kind: \"text\",\n },\n fileInput: {\n placement: \"args\",\n perFileArgs: [\"@{path}\"],\n },\n },\n },\n claude: {\n id: \"claude\",\n label: \"Claude CLI\",\n command: \"claude\",\n transportId: \"claude-cli\",\n options: {\n preset: \"claude\",\n // H10 (flag injection): `--` precedes the trailing {prompt} positional so a\n // prompt starting with `-` (e.g. \"--dangerously-skip-permissions\") is parsed\n // by the claude CLI as a positional, not a flag.\n argsTemplate: [\"--print\", \"--output-format\", \"json\", \"--model\", \"{model}\", \"--\", \"{prompt}\"],\n discovery: {\n via: \"acp\",\n acp: {\n transportId: \"claude-code-acp\",\n },\n },\n // SENTINEL (documentation-only): the `__preset__:*` textPath/errorPath values\n // are NOT resolved as live JSON paths. This `parser` block records which\n // dedicated parser a built-in preset maps to (parseClaudeCli); dispatch for a\n // preset route goes through the `cliOptions.preset` switch in cli.ts\n // (parseCliResult), which only reads a parser config when a ROUTE sets its own\n // `cli.parser`. See the mirrored note in cli.ts::parseCliResult.\n parser: {\n kind: \"json\",\n textPath: \"__preset__:claude.result\",\n usagePath: \"usage\",\n errorPath: \"__preset__:claude.error\",\n },\n },\n },\n openclaude: {\n id: \"openclaude\",\n label: \"OpenClaude CLI\",\n command: \"openclaude\",\n transportId: \"openclaude-cli\",\n options: {\n preset: \"openclaude\",\n // H10 (flag injection): `--` precedes the trailing {prompt} positional (see\n // the claude preset above for rationale).\n argsTemplate: [\"--print\", \"--output-format\", \"json\", \"--model\", \"{model}\", \"--\", \"{prompt}\"],\n // SENTINEL (documentation-only): see the claude preset note \u2014 `__preset__:*`\n // paths are markers, not live JSON paths; dispatch is via the preset switch.\n parser: {\n kind: \"json\",\n textPath: \"__preset__:claude.result\",\n usagePath: \"usage\",\n errorPath: \"__preset__:claude.error\",\n },\n },\n },\n codex: {\n id: \"codex\",\n label: \"Codex CLI\",\n command: \"codex\",\n transportId: \"codex-cli\",\n options: {\n preset: \"codex\",\n // codex exec takes image attachments via `-i/--image <FILE>` flags\n // (REQ-024); {files} expands a `--image <staged-path>` pair per image.\n // Images only \u2014 a non-image attachment cleanly rejects pre-spawn.\n // H10 (flag injection): `--` sits AFTER {files} and before the trailing\n // {prompt} positional. Unlike pi, codex files are passed via the explicit\n // `--image <path>` flag (the path is that flag's VALUE, not a positional), so\n // `--` must NOT precede {files} or it would neutralize `--image`. It guards\n // only the {prompt} positional against being parsed as a flag.\n argsTemplate: [\n \"exec\",\n \"--json\",\n \"--output-last-message\",\n \"{output_file}\",\n \"--model\",\n \"{model}\",\n \"{files}\",\n \"--\",\n \"{prompt}\",\n ],\n discovery: {\n via: \"acp\",\n acp: {\n transportId: \"codex-acp\",\n },\n },\n fileInput: {\n placement: \"args\",\n perFileArgs: [\"--image\", \"{path}\"],\n categories: [\"image\"],\n },\n // SENTINEL (documentation-only): the `__preset__:*` path values below are\n // markers naming the dedicated parser this preset maps to (parseCodexCli), NOT\n // live JSONL selectors. Dispatch for a preset route runs through the\n // `cliOptions.preset` switch in cli.ts::parseCliResult; this block is only ever\n // read as a live parser when a ROUTE overrides `cli.parser`.\n parser: {\n kind: \"jsonl\",\n text: {\n path: \"__preset__:codex.text\",\n },\n usage: {\n path: \"__preset__:codex.usage\",\n },\n error: {\n path: \"__preset__:codex.error\",\n },\n },\n },\n },\n };\n\nexport const AI_CONNECT_DEFAULT_CLI_COMMANDS: Record<string, string> = {\n \"anthropic:claude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.claude.command,\n \"anthropic:openclaude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.openclaude.command,\n \"openclaude:openclaude-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.openclaude.command,\n \"openai:codex-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.codex.command,\n \"pi:pi-cli\": AI_CONNECT_DEFAULT_CLI_PRESETS.pi.command,\n};\n\nexport function getCliTransportPreset(\n presetId: CliTransportPresetId,\n): CliTransportPreset {\n return AI_CONNECT_DEFAULT_CLI_PRESETS[presetId];\n}\n", "import type { AbortReason, AiConnectErrorCode } from \"./types.js\";\n\nexport class AiConnectError extends Error {\n readonly code: AiConnectErrorCode;\n readonly details: Record<string, unknown> | undefined;\n\n constructor(\n code: AiConnectErrorCode,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"AiConnectError\";\n this.code = code;\n this.details = details;\n }\n\n /**\n * `Error.prototype.message` is non-enumerable, so a bare `JSON.stringify(err)` silently drops\n * it (LOW, review-report-seed.md). Provide an explicit projection so serializing an\n * `AiConnectError` (logs, wide events, error-response bodies) always carries the message.\n */\n toJSON(): { name: string; code: AiConnectErrorCode; message: string; details: Record<string, unknown> | undefined } {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n };\n }\n}\n\nexport function isAiConnectError(error: unknown): error is AiConnectError {\n return error instanceof AiConnectError;\n}\n\n/**\n * Map a derived-abort `reason` to the canonical terminal error. `timeout` \u2192 `\"timeout\"`\n * (deadline elapsed), anything else (including `undefined`/`\"caller\"`) \u2192 `\"aborted\"`\n * (caller cancellation). Both codes are hard-terminal: they never rotate/retry/fall back.\n */\nexport function mapAbortError(\n reason: AbortReason | undefined,\n message?: string,\n): AiConnectError {\n return reason === \"timeout\"\n ? new AiConnectError(\"timeout\", message ?? \"Operation timed out.\")\n : new AiConnectError(\"aborted\", message ?? \"Operation aborted.\");\n}\n\nexport function toAiConnectError(\n error: unknown,\n fallbackCode: AiConnectErrorCode = \"temporary_unavailable\",\n): AiConnectError {\n if (error instanceof AiConnectError) {\n return error;\n }\n\n // Duck-typed DOMException/abort recognition (reliable across node/bun/browser where\n // `instanceof DOMException` is not): an aborted fetch throws `AbortError`, a timed-out\n // one throws `TimeoutError`. The authoritative reason still comes from the client's\n // AbortContext.reason; this is the transport-edge fallback.\n if (typeof (error as { name?: unknown })?.name === \"string\") {\n const name = (error as { name: string }).name;\n const message =\n error instanceof Error ? error.message : \"Operation aborted.\";\n if (name === \"AbortError\") {\n return new AiConnectError(\"aborted\", message);\n }\n if (name === \"TimeoutError\") {\n return new AiConnectError(\"timeout\", message);\n }\n }\n\n if (error instanceof Error) {\n return new AiConnectError(fallbackCode, error.message);\n }\n\n return new AiConnectError(fallbackCode, \"Unknown route failure.\");\n}\n", "import { AI_CONNECT_DEFAULT_CLI_PRESETS } from \"./cli-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport type {\n AccountConfigInput,\n AiConnectConfig,\n AiConnectConfigInput,\n AiConnectErrorCode,\n CliFileInputCategory,\n CliFileInputOptions,\n CliTransportPresetId,\n ContextMode,\n CredentialConfigInput,\n FallbackAction,\n FanoutPolicy,\n NormalizedFanoutPolicy,\n ModelAllowlistMode,\n ModelInput,\n NormalizedAccountConfig,\n NormalizedCredentialConfig,\n NormalizedModelConfig,\n NormalizedOperationRouting,\n NormalizedProviderConfig,\n NormalizedRoute,\n NormalizedRouteResolutionConfig,\n OperationKind,\n OperationRoutingInput,\n PublicRouteCapabilities,\n RouteCapabilities,\n RouteRuntime,\n RoutingStrategy,\n UnknownSelectorPolicy,\n CliTransportOptions,\n CliTransportOptionsInput,\n CliTransportParser,\n TransportDescriptor,\n TransportDescriptorInput,\n} from \"./types.js\";\n\nconst DEFAULT_OPERATIONS: OperationKind[] = [\"text\", \"image\", \"file\"];\nconst DEFAULT_STRATEGY: RoutingStrategy = \"priority\";\n\n// D4 (LOW, extensibility): provider \u2192 default transport-id lookup tables, extracted out of the\n// nested-ternary inference in `normalizeTransport` so a new provider's default id is one new\n// entry instead of another `? :` branch. Falls back to the generic per-kind id below when the\n// provider has no dedicated default.\nconst CLI_TRANSPORT_ID_BY_PROVIDER: Readonly<Record<string, string>> = {\n anthropic: \"claude-cli\",\n openclaude: \"openclaude-cli\",\n openai: \"codex-cli\",\n pi: \"pi-cli\",\n};\n\nconst ACP_TRANSPORT_ID_BY_PROVIDER: Readonly<Record<string, string>> = {\n anthropic: \"claude-code-acp\",\n openai: \"codex-acp\",\n};\n\nconst DEFAULT_FALLBACK_ACTIONS: Record<\n AiConnectErrorCode,\n FallbackAction[]\n> = {\n rate_limit: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n quota_exhausted: [\n \"rotate-account\",\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n invalid_credentials: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-provider\",\n ],\n auth_error: [\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-provider\",\n ],\n unsupported_capability: [\n \"fallback-model\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n temporary_unavailable: [\n \"retry\",\n \"rotate-credential\",\n \"rotate-account\",\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n local_harness_unavailable: [\n \"fallback-transport\",\n \"fallback-provider\",\n ],\n validation_error: [],\n not_supported: [\"fallback-model\", \"fallback-transport\", \"fallback-provider\"],\n // Hard-terminal: caller cancellation, deadline, and client-side fanout limit never\n // rotate/retry/fall back (they are not provider/route-health signals).\n aborted: [],\n timeout: [],\n fanout_limit: [],\n};\n\nconst DEFAULT_COOLDOWN_MS: Record<AiConnectErrorCode, number> = {\n rate_limit: 30_000,\n quota_exhausted: 120_000,\n invalid_credentials: 300_000,\n auth_error: 300_000,\n unsupported_capability: 0,\n temporary_unavailable: 10_000,\n local_harness_unavailable: 60_000,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 10_000,\n fanout_limit: 0,\n};\n\nconst DEFAULT_RETRY_MAX_ATTEMPTS: Record<AiConnectErrorCode, number> = {\n rate_limit: 0,\n quota_exhausted: 0,\n invalid_credentials: 0,\n auth_error: 0,\n unsupported_capability: 0,\n temporary_unavailable: 1,\n local_harness_unavailable: 0,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 0,\n fanout_limit: 0,\n};\n\nconst DEFAULT_RETRY_DELAY_MS: Record<AiConnectErrorCode, number> = {\n rate_limit: 0,\n quota_exhausted: 0,\n invalid_credentials: 0,\n auth_error: 0,\n unsupported_capability: 0,\n temporary_unavailable: 1_000,\n local_harness_unavailable: 0,\n validation_error: 0,\n not_supported: 0,\n aborted: 0,\n timeout: 1_000,\n fanout_limit: 0,\n};\n\nfunction slugify(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/**\n * Project the secret-free, client-safe capability subset (INV-PROJ-1). The SINGLE\n * source of truth shared by `toPublicRoute` (PublicRoute) and the router's\n * `candidateModels()` (CandidateModel) projections, so internal routing flags\n * (localOnly, requiresFilesystem, the requires-/profile-verification/rotation\n * flags) can never leak onto a public/ModelSelector surface. Built by an EXPLICIT\n * field-by-field copy keyed on the {@link PublicRouteCapabilities} `Pick` \u2014 never\n * by spreading the full {@link RouteCapabilities}.\n */\nexport function toPublicCapabilities(\n capabilities: RouteCapabilities,\n): PublicRouteCapabilities {\n return {\n browserSafe: capabilities.browserSafe,\n supportsStreaming: capabilities.supportsStreaming,\n supportsToolSchema: capabilities.supportsToolSchema,\n supportsToolExecution: capabilities.supportsToolExecution,\n supportsClientToolExecution: capabilities.supportsClientToolExecution,\n supportsFileUpload: capabilities.supportsFileUpload,\n supportsFileOutput: capabilities.supportsFileOutput,\n supportsImageInput: capabilities.supportsImageInput,\n supportsImageOutput: capabilities.supportsImageOutput,\n };\n}\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new AiConnectError(\"validation_error\", message);\n }\n}\n\n/**\n * `undefined` (omitted) silently resolves to `fallback` \u2014 the caller never set the field. A\n * value that IS present but fails the positive-finite-number check is a distinct, likely\n * misconfiguration signal (wrong type / NaN / non-positive) rather than an intentional omission;\n * when `fieldLabel` is supplied that case is surfaced via `console.warn` instead of silently\n * defaulting (LOW \u2014 kept a warning rather than a hard `validation_error` throw to avoid a broad,\n * hard-to-audit behavior change across every call site).\n */\nfunction asPositiveInteger(\n value: unknown,\n fallback: number,\n fieldLabel?: string,\n): number {\n if (value === undefined) {\n return fallback;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n if (fieldLabel) {\n console.warn(\n `[ai-connect] ${fieldLabel} must be a positive finite number when provided; received ${JSON.stringify(value)}. Falling back to ${fallback}.`,\n );\n }\n return fallback;\n }\n\n return Math.floor(value);\n}\n\n/** See {@link asPositiveInteger} \u2014 same omitted-vs-invalid distinction, non-negative bound. */\nfunction asNonNegativeInteger(\n value: unknown,\n fallback: number,\n fieldLabel?: string,\n): number {\n if (value === undefined) {\n return fallback;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n if (fieldLabel) {\n console.warn(\n `[ai-connect] ${fieldLabel} must be a non-negative finite number when provided; received ${JSON.stringify(value)}. Falling back to ${fallback}.`,\n );\n }\n return fallback;\n }\n\n return Math.floor(value);\n}\n\n/** See {@link asPositiveInteger} \u2014 same omitted-vs-invalid distinction; omitted/invalid both resolve to `undefined`. */\nfunction asOptionalContextWindow(\n value: unknown,\n fieldLabel?: string,\n): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n if (fieldLabel) {\n console.warn(\n `[ai-connect] ${fieldLabel} must be a positive finite number when provided; received ${JSON.stringify(value)}. Ignoring.`,\n );\n }\n return undefined;\n }\n\n return Math.floor(value);\n}\n\n/**\n * Normalize a single account `models` entry (C4). A bare string inherits the account-level\n * `accountContextWindow` (when set). A `{ id, contextWindow }` object overrides it for that\n * model only; a string with no account-level default leaves `contextWindow` UNDEFINED (never\n * coerced to 0). The `id` is trimmed; empty ids are dropped by the caller.\n *\n * The object form's `id` is validated (non-empty string) BEFORE `.trim()` \u2014 mirrors the #15\n * array-shape guard pattern so a missing/malformed `id` raises a clean `validation_error`\n * instead of an opaque `Cannot read properties of undefined (reading 'trim')` TypeError.\n */\nfunction normalizeModelInput(\n input: ModelInput,\n accountContextWindow: number | undefined,\n accountId: string,\n providerId: string,\n): NormalizedModelConfig {\n if (typeof input === \"string\") {\n return {\n id: input.trim(),\n ...(accountContextWindow !== undefined\n ? { contextWindow: accountContextWindow }\n : {}),\n };\n }\n\n assert(\n typeof input.id === \"string\" && input.id.trim().length > 0,\n `Account \"${accountId}\" for provider \"${providerId}\" declared a model entry with a missing or empty \"id\".`,\n );\n\n const id = input.id.trim();\n const override = asOptionalContextWindow(\n input.contextWindow,\n `Model \"${id}\" (account \"${accountId}\", provider \"${providerId}\") contextWindow`,\n );\n const contextWindow = override ?? accountContextWindow;\n return {\n id,\n ...(contextWindow !== undefined ? { contextWindow } : {}),\n };\n}\n\n/**\n * Resolve one optional fan-out bound (C9). A finite positive number is kept (floored); anything\n * else (unset / non-finite / `<= 0` / `Infinity`) means UNBOUNDED \u2192 {@link Number.POSITIVE_INFINITY}.\n * A fractional value in `(0, 1)` floors to `0` \u2014 treated as UNBOUNDED rather than a zero-capacity\n * bound, since a `0` bound (e.g. a token-bucket `requestsPerSecond`) never refills and livelocks\n * every caller forever (H8).\n */\nfunction asFanoutBound(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return Number.POSITIVE_INFINITY;\n }\n const floored = Math.floor(value);\n return floored <= 0 ? Number.POSITIVE_INFINITY : floored;\n}\n\n/**\n * Normalize a {@link FanoutPolicy} into a {@link NormalizedFanoutPolicy} (C9). Every unset/invalid\n * field resolves to `POSITIVE_INFINITY` (unbounded). Pure; no client/runtime dependency.\n */\nexport function normalizeFanoutPolicy(\n policy: FanoutPolicy | undefined,\n): NormalizedFanoutPolicy {\n return {\n maxConcurrency: asFanoutBound(policy?.maxConcurrency),\n requestsPerSecond: asFanoutBound(policy?.requestsPerSecond),\n maxCalls: asFanoutBound(policy?.maxCalls),\n };\n}\n\n/**\n * Merge a per-request {@link FanoutPolicy} OVER a client-level default, per-field (C9 / R15). A\n * field present (non-`undefined`) on `request` wins; otherwise the `base` field is kept. Returns a\n * plain {@link FanoutPolicy} (still to be normalized) so an unset field on BOTH stays unset. The\n * result is fresh \u2014 neither input is mutated; the per-request limiter is built request-scoped.\n */\nexport function mergeFanoutPolicy(\n base: FanoutPolicy | undefined,\n request: FanoutPolicy | undefined,\n): FanoutPolicy {\n return {\n ...(request?.maxConcurrency !== undefined\n ? { maxConcurrency: request.maxConcurrency }\n : base?.maxConcurrency !== undefined\n ? { maxConcurrency: base.maxConcurrency }\n : {}),\n ...(request?.requestsPerSecond !== undefined\n ? { requestsPerSecond: request.requestsPerSecond }\n : base?.requestsPerSecond !== undefined\n ? { requestsPerSecond: base.requestsPerSecond }\n : {}),\n ...(request?.maxCalls !== undefined\n ? { maxCalls: request.maxCalls }\n : base?.maxCalls !== undefined\n ? { maxCalls: base.maxCalls }\n : {}),\n };\n}\n\nfunction normalizeTransport(\n providerId: string,\n input: AccountConfigInput[\"transport\"],\n): TransportDescriptor {\n const descriptor: TransportDescriptorInput =\n typeof input === \"string\" ? { kind: input } : input;\n const normalizedCli = (() => {\n if (!descriptor.cli) {\n return undefined;\n }\n\n const normalizeSelector = (\n selector: {\n path: string;\n wherePath?: string;\n whereEquals?: string | number | boolean;\n },\n selectorName: string,\n ) => {\n assert(\n selector.path.trim().length > 0,\n `CLI parser ${selectorName}.path must be a non-empty string for provider \"${providerId}\".`,\n );\n\n return {\n path: selector.path.trim(),\n ...(selector.wherePath?.trim()\n ? { wherePath: selector.wherePath.trim() }\n : {}),\n ...(selector.whereEquals !== undefined\n ? { whereEquals: selector.whereEquals }\n : {}),\n };\n };\n\n const normalizeCliParser = (\n cliParser: NonNullable<CliTransportOptionsInput[\"parser\"]>,\n ): CliTransportParser => {\n if (cliParser.kind === \"json\") {\n assert(\n cliParser.textPath.trim().length > 0,\n `CLI json parser textPath must be a non-empty string for provider \"${providerId}\".`,\n );\n\n return {\n kind: \"json\",\n textPath: cliParser.textPath.trim(),\n ...(cliParser.errorPath?.trim()\n ? { errorPath: cliParser.errorPath.trim() }\n : {}),\n ...(cliParser.usagePath?.trim()\n ? { usagePath: cliParser.usagePath.trim() }\n : {}),\n } satisfies CliTransportParser;\n }\n\n if (cliParser.kind === \"text\") {\n return {\n kind: \"text\",\n // Default trim=true, stripAnsi=false; only persist explicit overrides.\n ...(cliParser.trim === false ? { trim: false } : {}),\n ...(cliParser.stripAnsi === true ? { stripAnsi: true } : {}),\n } satisfies CliTransportParser;\n }\n\n return {\n kind: \"jsonl\",\n text: normalizeSelector(cliParser.text, \"text\"),\n ...(cliParser.error\n ? { error: normalizeSelector(cliParser.error, \"error\") }\n : {}),\n ...(cliParser.usage\n ? { usage: normalizeSelector(cliParser.usage, \"usage\") }\n : {}),\n } satisfies CliTransportParser;\n };\n\n const parser = descriptor.cli?.parser\n ? normalizeCliParser(descriptor.cli.parser)\n : undefined;\n\n const normalized = {\n ...(descriptor.cli.preset ? { preset: descriptor.cli.preset } : {}),\n ...(descriptor.cli.argsTemplate\n ? {\n argsTemplate: descriptor.cli.argsTemplate.map((part) => String(part)),\n }\n : {}),\n ...(parser ? { parser } : {}),\n } satisfies CliTransportOptions;\n\n const discovery = (() => {\n if (!descriptor.cli?.discovery) {\n return undefined;\n }\n\n const explicitVia = descriptor.cli.discovery.via;\n if (explicitVia !== undefined) {\n assert(\n explicitVia === \"none\" ||\n explicitVia === \"acp\" ||\n explicitVia === \"command\" ||\n explicitVia === \"static\",\n `Unsupported CLI discovery mode \"${String(explicitVia)}\" for provider \"${providerId}\".`,\n );\n }\n\n const launch = descriptor.cli.discovery.acp?.launch\n ? (() => {\n const contextMode =\n descriptor.cli.discovery?.acp?.launch?.contextMode ??\n \"workspace\";\n const skillsMode =\n descriptor.cli.discovery?.acp?.launch?.skillsMode ??\n \"default\";\n\n assert(\n contextMode === \"workspace\" || contextMode === \"clean\",\n `Unsupported CLI discovery ACP contextMode \"${String(contextMode)}\" for provider \"${providerId}\".`,\n );\n assert(\n skillsMode === \"default\" || skillsMode === \"disabled\",\n `Unsupported CLI discovery ACP skillsMode \"${String(skillsMode)}\" for provider \"${providerId}\".`,\n );\n\n return {\n contextMode,\n skillsMode,\n };\n })()\n : undefined;\n\n const auth =\n descriptor.cli.discovery.acp?.auth?.methodId?.trim()\n ? {\n methodId: descriptor.cli.discovery.acp.auth.methodId.trim(),\n params: descriptor.cli.discovery.acp.auth.params ?? {},\n }\n : undefined;\n\n // Normalize the acp block whenever present (presets set via:\"acp\" + acp;\n // a custom route may also predeclare acp overrides the chain can use).\n const acp = descriptor.cli.discovery.acp\n ? {\n ...(descriptor.cli.discovery.acp?.providerId?.trim()\n ? { providerId: descriptor.cli.discovery.acp.providerId.trim() }\n : {}),\n ...(descriptor.cli.discovery.acp?.transportId?.trim()\n ? {\n transportId:\n descriptor.cli.discovery.acp.transportId.trim(),\n }\n : {}),\n ...(auth ? { auth } : {}),\n ...(launch ? { launch } : {}),\n }\n : undefined;\n\n // Normalize the `command` (list-models) source.\n const commandInput = descriptor.cli.discovery.command;\n const command = commandInput\n ? (() => {\n assert(\n Array.isArray(commandInput.argsTemplate) &&\n commandInput.argsTemplate.length > 0,\n `CLI discovery command.argsTemplate must be a non-empty array for provider \"${providerId}\".`,\n );\n const cmdParserInput = commandInput.parser ?? { kind: \"text\" };\n const cmdParser =\n cmdParserInput.kind === \"text\"\n ? {\n kind: \"text\" as const,\n ...(cmdParserInput.trim === false ? { trim: false } : {}),\n ...(cmdParserInput.stripAnsi === true\n ? { stripAnsi: true }\n : {}),\n }\n : { kind: cmdParserInput.kind };\n if (cmdParser.kind !== \"text\") {\n assert(\n Boolean(commandInput.models?.idPath?.trim()),\n `CLI discovery command.models.idPath is required for a ${cmdParser.kind} parser for provider \"${providerId}\".`,\n );\n }\n const m = commandInput.models;\n const models =\n m?.idPath?.trim()\n ? {\n ...(m.path?.trim() ? { path: m.path.trim() } : {}),\n idPath: m.idPath.trim(),\n ...(m.namePath?.trim() ? { namePath: m.namePath.trim() } : {}),\n ...(m.descriptionPath?.trim()\n ? { descriptionPath: m.descriptionPath.trim() }\n : {}),\n ...(m.contextLengthPath?.trim()\n ? { contextLengthPath: m.contextLengthPath.trim() }\n : {}),\n }\n : undefined;\n return {\n ...(commandInput.command?.trim()\n ? { command: commandInput.command.trim() }\n : {}),\n argsTemplate: commandInput.argsTemplate.map((part) => String(part)),\n parser: cmdParser,\n ...(models ? { models } : {}),\n } satisfies NonNullable<CliTransportOptions[\"discovery\"]>[\"command\"];\n })()\n : undefined;\n\n assert(\n explicitVia !== \"command\" || command !== undefined,\n `CLI discovery via:\"command\" requires a discovery.command block for provider \"${providerId}\".`,\n );\n\n const fallback = descriptor.cli.discovery.fallback;\n if (fallback !== undefined) {\n assert(\n fallback === \"static\" || fallback === \"none\",\n `Unsupported CLI discovery fallback \"${String(fallback)}\" for provider \"${providerId}\".`,\n );\n }\n\n return {\n ...(explicitVia !== undefined ? { via: explicitVia } : {}),\n ...(acp ? { acp } : {}),\n ...(command ? { command } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n } satisfies NonNullable<CliTransportOptions[\"discovery\"]>;\n })();\n\n const fileInput = (() => {\n const fi = descriptor.cli?.fileInput;\n if (!fi) {\n return undefined;\n }\n const validCategories = [\"image\", \"document\", \"text\", \"other\"] as const;\n if (fi.categories) {\n for (const c of fi.categories) {\n assert(\n (validCategories as readonly string[]).includes(c),\n `Unsupported CLI fileInput category \"${String(c)}\" for provider \"${providerId}\".`,\n );\n }\n }\n const placement = fi.placement ?? \"args\";\n assert(\n placement === \"args\" || placement === \"prompt\",\n `Unsupported CLI fileInput placement \"${String(placement)}\" for provider \"${providerId}\".`,\n );\n return {\n placement,\n ...(fi.perFileArgs\n ? { perFileArgs: fi.perFileArgs.map((part) => String(part)) }\n : {}),\n ...(fi.mentionTemplate?.trim()\n ? { mentionTemplate: fi.mentionTemplate.trim() }\n : {}),\n ...(fi.separator !== undefined ? { separator: fi.separator } : {}),\n ...(fi.categories ? { categories: [...fi.categories] } : {}),\n ...(fi.stagingDir?.trim() ? { stagingDir: fi.stagingDir.trim() } : {}),\n } satisfies CliFileInputOptions;\n })();\n\n return {\n ...normalized,\n ...(discovery ? { discovery } : {}),\n ...(fileInput ? { fileInput } : {}),\n } satisfies CliTransportOptions;\n })();\n const normalizedAuth =\n descriptor.auth?.methodId?.trim()\n ? {\n methodId: descriptor.auth.methodId.trim(),\n params: descriptor.auth.params ?? {},\n }\n : undefined;\n\n assert(\n descriptor.kind === \"api\" ||\n descriptor.kind === \"acp\" ||\n descriptor.kind === \"cli\" ||\n descriptor.kind === \"server\",\n `Unsupported transport kind for provider \"${providerId}\".`,\n );\n if (descriptor.kind !== \"acp\") {\n assert(\n !normalizedAuth,\n `Transport auth is only supported for ACP routes. Provider \"${providerId}\" declared auth on a non-ACP transport.`,\n );\n assert(\n !descriptor.launch,\n `Transport launch options are only supported for ACP routes. Provider \"${providerId}\" declared launch settings on a non-ACP transport.`,\n );\n }\n if (descriptor.kind !== \"cli\") {\n assert(\n !normalizedCli,\n `CLI transport options are only supported for CLI routes. Provider \"${providerId}\" declared cli settings on a non-CLI transport.`,\n );\n }\n\n if (descriptor.kind === \"api\") {\n return {\n kind: \"api\",\n id: descriptor.id?.trim() || \"api\",\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n };\n }\n\n if (descriptor.kind === \"cli\") {\n const inferredId = CLI_TRANSPORT_ID_BY_PROVIDER[providerId] ?? \"cli\";\n\n return {\n kind: \"cli\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(normalizedCli ? { cli: normalizedCli } : {}),\n };\n }\n\n if (descriptor.kind === \"server\") {\n const inferredId = providerId === \"opencode\" ? \"opencode-server\" : \"server\";\n\n return {\n kind: \"server\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n };\n }\n\n const inferredId = ACP_TRANSPORT_ID_BY_PROVIDER[providerId] ?? \"acp\";\n const normalizedLaunch = descriptor.launch\n ? (() => {\n const contextMode = descriptor.launch?.contextMode ?? \"workspace\";\n const skillsMode = descriptor.launch?.skillsMode ?? \"default\";\n\n assert(\n contextMode === \"workspace\" || contextMode === \"clean\",\n `Unsupported ACP contextMode \"${String(contextMode)}\" for provider \"${providerId}\".`,\n );\n assert(\n skillsMode === \"default\" || skillsMode === \"disabled\",\n `Unsupported ACP skillsMode \"${String(skillsMode)}\" for provider \"${providerId}\".`,\n );\n\n return {\n contextMode,\n skillsMode,\n };\n })()\n : undefined;\n\n return {\n kind: \"acp\",\n id: descriptor.id?.trim() || inferredId,\n ...(descriptor.command?.trim()\n ? { command: descriptor.command.trim() }\n : {}),\n ...(descriptor.baseUrl?.trim()\n ? { baseUrl: descriptor.baseUrl.trim() }\n : {}),\n ...(normalizedAuth ? { auth: normalizedAuth } : {}),\n ...(normalizedLaunch ? { launch: normalizedLaunch } : {}),\n };\n}\n\nfunction normalizeRuntime(\n transport: TransportDescriptor,\n runtime: RouteRuntime | undefined,\n): RouteRuntime {\n if (\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\"\n ) {\n return \"local\";\n }\n\n if (runtime === \"browser\" || runtime === \"local\" || runtime === \"universal\") {\n return runtime;\n }\n\n return \"universal\";\n}\n\n// Map a cli transport id to its built-in preset id (mirror cli.ts\n// defaultCliPresetIdForRoute) so capability derivation can see a preset's\n// default fileInput before runtime preset-merging happens.\nfunction cliPresetIdForTransportId(\n transportId: string,\n): CliTransportPresetId | undefined {\n switch (transportId) {\n case \"pi-cli\":\n return \"pi\";\n case \"claude-cli\":\n return \"claude\";\n case \"openclaude-cli\":\n return \"openclaude\";\n case \"codex-cli\":\n return \"codex\";\n default:\n return undefined;\n }\n}\n\n// Resolve the effective fileInput for a cli route at capability-derivation time:\n// the route-level fileInput merged over the resolved preset's default fileInput\n// (REQ-024, F-CR-1). Returns the staged categories, or an empty set when the\n// route has no file input at all.\nfunction cliFileInputCategories(\n transport: TransportDescriptor,\n): Set<CliFileInputCategory> {\n if (transport.kind !== \"cli\") {\n return new Set();\n }\n const presetId =\n transport.cli?.preset ?? cliPresetIdForTransportId(transport.id);\n const presetFileInput = presetId\n ? AI_CONNECT_DEFAULT_CLI_PRESETS[presetId]?.options.fileInput\n : undefined;\n const routeFileInput = transport.cli?.fileInput;\n if (!presetFileInput && !routeFileInput) {\n return new Set();\n }\n const merged: CliFileInputOptions = {\n ...(presetFileInput ?? {}),\n ...(routeFileInput ?? {}),\n };\n return new Set(\n merged.categories ?? [\"image\", \"document\", \"text\", \"other\"],\n );\n}\n\nfunction defaultCapabilities(\n transport: TransportDescriptor,\n runtime: RouteRuntime,\n): RouteCapabilities {\n const cliFileCategories = cliFileInputCategories(transport);\n const localOnly =\n runtime === \"local\" ||\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\";\n const browserSafe = !localOnly;\n\n return {\n browserSafe,\n localOnly,\n requiresFilesystem:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n requiresInstalledBinary:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n requiresAuthenticatedSession:\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\",\n supportsStreaming:\n transport.kind === \"api\" || transport.kind === \"acp\",\n supportsToolSchema: transport.kind === \"api\",\n supportsToolExecution: transport.kind === \"acp\",\n supportsClientToolExecution: transport.kind === \"api\",\n // C6 / F-P-4: api routes now advertise document + image input parity with acp.\n // The per-account `capabilities` override remains the escape hatch for\n // text-only api proxies that must opt out. REQ-024: a cli route advertises\n // document/image input ONLY for the categories its fileInput actually stages\n // (category-aware so e.g. an image-only cli cleanly rejects a PDF pre-spawn).\n supportsFileUpload:\n transport.kind === \"acp\" ||\n transport.kind === \"api\" ||\n cliFileCategories.has(\"document\"),\n supportsFileOutput: transport.kind === \"acp\",\n supportsImageInput:\n transport.kind === \"acp\" ||\n transport.kind === \"api\" ||\n cliFileCategories.has(\"image\"),\n supportsImageOutput: transport.kind === \"acp\",\n supportsProfileVerification: true,\n supportsCredentialRotation: false,\n supportsAccountRotation: false,\n };\n}\n\nfunction normalizeCredential(\n providerId: string,\n accountId: string,\n transport: TransportDescriptor,\n input: CredentialConfigInput,\n index: number,\n): NormalizedCredentialConfig {\n const id = input.id?.trim() || `${accountId}-credential-${index + 1}`;\n // Compute the trimmed apiKey/apiKeyEnv ONCE and reuse for both `source` inference and the\n // emitted field presence checks below. Previously `source` was inferred from the raw\n // (untrimmed) `input.apiKey`/`input.apiKeyEnv` while the emitted fields used the trimmed\n // value \u2014 a whitespace-only `apiKey` was truthy pre-trim, so `source` resolved to `\"literal\"`\n // even though no `apiKey` field was ever emitted (trimmed to empty string, dropped).\n const trimmedApiKey = input.apiKey?.trim();\n const trimmedApiKeyEnv = input.apiKeyEnv?.trim();\n const source =\n input.source?.trim() ||\n (trimmedApiKey\n ? \"literal\"\n : trimmedApiKeyEnv\n ? \"env\"\n : transport.kind === \"api\"\n ? \"env\"\n : \"session\");\n\n if (transport.kind === \"api\") {\n assert(\n Boolean(trimmedApiKey) || Boolean(trimmedApiKeyEnv),\n `API account \"${accountId}\" for provider \"${providerId}\" requires apiKey or apiKeyEnv credentials.`,\n );\n }\n\n return {\n id,\n source,\n weight: asPositiveInteger(\n input.weight,\n 1,\n `Credential \"${id}\" (account \"${accountId}\", provider \"${providerId}\") weight`,\n ),\n metadata: input.metadata ?? {},\n ...(trimmedApiKey ? { apiKey: trimmedApiKey } : {}),\n ...(trimmedApiKeyEnv ? { apiKeyEnv: trimmedApiKeyEnv } : {}),\n ...(input.apiKeyDelimiter ? { apiKeyDelimiter: input.apiKeyDelimiter } : {}),\n };\n}\n\nfunction normalizeCredentials(\n providerId: string,\n accountId: string,\n transport: TransportDescriptor,\n credentials: CredentialConfigInput[] | undefined,\n): NormalizedCredentialConfig[] {\n if (credentials && credentials.length > 0) {\n return credentials.map((input, index) =>\n normalizeCredential(providerId, accountId, transport, input, index),\n );\n }\n\n if (\n transport.kind === \"acp\" ||\n transport.kind === \"cli\" ||\n transport.kind === \"server\"\n ) {\n return [\n {\n id: `${accountId}-session-default`,\n source: \"session\",\n weight: 1,\n metadata: {},\n },\n ];\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `API account \"${accountId}\" for provider \"${providerId}\" must define at least one credential.`,\n );\n}\n\nfunction buildRouteId(route: {\n provider: string;\n transport: TransportDescriptor;\n accountId: string;\n credentialId: string;\n model: string;\n}): string {\n return [\n route.provider,\n route.transport.id,\n route.accountId,\n route.credentialId,\n slugify(route.model),\n ].join(\":\");\n}\n\n/**\n * H2: `buildRouteId` derives its final id segment from `slugify(model)`, which is lossy \u2014 e.g.\n * `\"GPT 4\"` and `\"gpt-4\"` both slugify to `\"gpt-4\"`. Two DISTINCT model ids on the same\n * provider/transport/account/credential therefore collide onto the same route id, and every\n * id-keyed lookup (route-alias resolution, rotation grouping) silently conflates two different\n * models into \"one\" route. Called once after `routes[]` is fully built; throws a\n * `validation_error` naming every colliding model and its owning account/provider instead of\n * letting the collision surface later as silent misrouting.\n */\nfunction assertRouteIdUniqueness(routes: NormalizedRoute[]): void {\n const byId = new Map<string, NormalizedRoute[]>();\n for (const route of routes) {\n const group = byId.get(route.id);\n if (group) {\n group.push(route);\n } else {\n byId.set(route.id, [route]);\n }\n }\n\n for (const [id, group] of byId) {\n if (group.length <= 1) {\n continue;\n }\n const distinctModels = [...new Set(group.map((route) => route.model))];\n if (distinctModels.length <= 1) {\n // Same model repeated verbatim (e.g. duplicate `models` entry) \u2014 not a slugify collision;\n // leave as-is (harmless redundant route, not the H2 failure mode).\n continue;\n }\n const first = group[0]!;\n assert(\n false,\n `Route id \"${id}\" is ambiguous: model(s) ${distinctModels\n .map((model) => `\"${model}\"`)\n .join(\", \")} on account \"${first.accountId}\" (provider \"${first.provider}\") slugify to the same route id. Rename one of the models so they no longer collide after slugification.`,\n );\n }\n}\n\nfunction routeAliases(route: NormalizedRoute): string[] {\n return [\n route.provider,\n route.id,\n `${route.provider}:${route.accountId}`,\n `${route.provider}:${route.accountId}:${route.model}`,\n `${route.provider}:${route.transport.id}:${route.accountId}`,\n `${route.provider}:${route.transport.id}:${route.accountId}:${route.model}`,\n ];\n}\n\n/**\n * Selector-resolution policy for an unmatched selector (C7 / OQ-8). OPTIONAL on every call site:\n * when omitted the policy defaults to `error`, which is byte-identical to the pre-C7 behaviour, so\n * existing positional callers (`resolveRouteRefs(selectors, routes)`) are unaffected.\n */\ninterface ResolveRouteRefsPolicy {\n unknownSelector?: UnknownSelectorPolicy;\n /** Single resolved route id substituted for each unmatched selector when policy is `default`. */\n defaultRouteId?: string;\n}\n\nfunction resolveRouteRefs(\n selectors: string[] | undefined,\n routes: NormalizedRoute[],\n policy?: ResolveRouteRefsPolicy,\n): string[] {\n if (!selectors || selectors.length === 0) {\n return routes.map((route) => route.id);\n }\n\n const unknownSelector = policy?.unknownSelector ?? \"error\";\n const seen = new Set<string>();\n const resolved: string[] = [];\n\n const push = (routeId: string): void => {\n if (!seen.has(routeId)) {\n seen.add(routeId);\n resolved.push(routeId);\n }\n };\n\n for (const selector of selectors) {\n const matches = routes.filter((route) =>\n routeAliases(route).includes(selector),\n );\n\n if (matches.length === 0) {\n // OQ-8 per-unmatched substitution: each unmatched selector independently triggers the\n // policy. `error` (default) throws; `default` substitutes the configured default route for\n // THIS selector; `off` silently drops it (degrade).\n if (unknownSelector === \"default\" && policy?.defaultRouteId) {\n push(policy.defaultRouteId);\n continue;\n }\n if (unknownSelector === \"off\") {\n continue;\n }\n assert(\n false,\n `Route selector \"${selector}\" did not match any normalized routes.`,\n );\n }\n\n for (const match of matches) {\n push(match.id);\n }\n }\n\n return resolved;\n}\n\nfunction normalizeOperationRouting(\n input: string[] | OperationRoutingInput | undefined,\n routes: NormalizedRoute[],\n defaultStrategy: RoutingStrategy,\n resolution: NormalizedRouteResolutionConfig,\n): NormalizedOperationRouting {\n const policy: ResolveRouteRefsPolicy = {\n unknownSelector: resolution.unknownSelector,\n ...(resolution.defaultRouteId !== undefined\n ? { defaultRouteId: resolution.defaultRouteId }\n : {}),\n };\n\n if (Array.isArray(input)) {\n return {\n strategy: defaultStrategy,\n pool: resolveRouteRefs(input, routes, policy),\n };\n }\n\n return {\n strategy: input?.strategy ?? defaultStrategy,\n pool: resolveRouteRefs(input?.pool, routes, policy),\n };\n}\n\nfunction finalizeRotationCapabilities(routes: NormalizedRoute[]): void {\n const credentialGroups = new Map<string, Set<string>>();\n const accountGroups = new Map<string, Set<string>>();\n\n for (const route of routes) {\n const credentialKey = [\n route.provider,\n route.transport.id,\n route.accountId,\n route.model,\n ].join(\"|\");\n const accountKey = [\n route.provider,\n route.transport.id,\n route.model,\n ].join(\"|\");\n\n const credentialSet =\n credentialGroups.get(credentialKey) ?? new Set<string>();\n credentialSet.add(route.credentialId);\n credentialGroups.set(credentialKey, credentialSet);\n\n const accountSet = accountGroups.get(accountKey) ?? new Set<string>();\n accountSet.add(route.accountId);\n accountGroups.set(accountKey, accountSet);\n }\n\n for (const route of routes) {\n const credentialKey = [\n route.provider,\n route.transport.id,\n route.accountId,\n route.model,\n ].join(\"|\");\n const accountKey = [\n route.provider,\n route.transport.id,\n route.model,\n ].join(\"|\");\n\n route.capabilities.supportsCredentialRotation =\n (credentialGroups.get(credentialKey)?.size ?? 0) > 1;\n route.capabilities.supportsAccountRotation =\n (accountGroups.get(accountKey)?.size ?? 0) > 1;\n }\n}\n\nexport function defineConfig(input: AiConnectConfigInput): AiConnectConfig {\n assert(\n typeof input === \"object\" && input !== null,\n \"ai-connect config must be an object.\",\n );\n\n const providerEntries = Object.entries(input.providers ?? {});\n assert(providerEntries.length > 0, \"At least one provider must be configured.\");\n\n const providers: Record<string, NormalizedProviderConfig> = {};\n const routes: NormalizedRoute[] = [];\n\n for (const [providerId, providerInput] of providerEntries) {\n assert(\n providerId !== \"google\",\n 'Provider \"google\" is not supported. Use provider \"gemini\" for the Google Gemini stack.',\n );\n\n assert(\n Array.isArray(providerInput.accounts) && providerInput.accounts.length > 0,\n `Provider \"${providerId}\" must define at least one account.`,\n );\n\n const accounts: NormalizedAccountConfig[] = [];\n\n providerInput.accounts.forEach((accountInput, accountIndex) => {\n const accountId =\n accountInput.id?.trim() || `${providerId}-account-${accountIndex + 1}`;\n const transport = normalizeTransport(providerId, accountInput.transport);\n const runtime = normalizeRuntime(transport, accountInput.runtime);\n const accountContextWindow = asOptionalContextWindow(\n accountInput.contextWindow,\n `Account \"${accountId}\" (provider \"${providerId}\") contextWindow`,\n );\n // C7: per-route policy fields seeded from the account input (defaults preserve pre-C7\n // behaviour \u2014 strict allowlist, workspace context).\n const accountModelAllowlistMode: ModelAllowlistMode =\n accountInput.modelAllowlistMode ?? \"strict\";\n const accountContextMode: ContextMode =\n accountInput.contextMode ?? \"workspace\";\n const accountSystemPrompt = accountInput.systemPrompt?.trim()\n ? accountInput.systemPrompt.trim()\n : undefined;\n const accountLabel = accountInput.id?.trim()\n ? accountInput.id.trim()\n : undefined;\n // #15: guard the array shape BEFORE `.map` so omitting `models` raises a\n // clean validation_error rather than an opaque \"Cannot read properties of\n // undefined (reading 'map')\" TypeError.\n assert(\n Array.isArray(accountInput.models) && accountInput.models.length > 0,\n `Account \"${accountId}\" for provider \"${providerId}\" must declare at least one model.`,\n );\n\n const models = accountInput.models\n .map((model) =>\n normalizeModelInput(model, accountContextWindow, accountId, providerId),\n )\n .filter((model) => model.id.length > 0);\n\n assert(\n models.length > 0,\n `Account \"${accountId}\" for provider \"${providerId}\" must declare at least one model.`,\n );\n\n const credentials = normalizeCredentials(\n providerId,\n accountId,\n transport,\n accountInput.credentials,\n );\n const capabilities = {\n ...defaultCapabilities(transport, runtime),\n ...(accountInput.capabilities ?? {}),\n };\n const profile =\n accountInput.profile?.trim() || `${providerId}-${transport.id}`;\n const verify = {\n env: accountInput.verify?.env ?? [],\n ...(accountInput.verify?.command?.trim()\n ? { command: accountInput.verify.command.trim() }\n : {}),\n ...(accountInput.verify?.session?.trim()\n ? { session: accountInput.verify.session.trim() }\n : {}),\n };\n const normalizedAccount: NormalizedAccountConfig = {\n id: accountId,\n profile,\n runtime,\n transport,\n models: models.map((model) => model.id),\n credentials,\n capabilities,\n verify,\n weight: asPositiveInteger(\n accountInput.weight,\n 1,\n `Account \"${accountId}\" (provider \"${providerId}\") weight`,\n ),\n priority: asNonNegativeInteger(\n accountInput.priority,\n accountIndex,\n `Account \"${accountId}\" (provider \"${providerId}\") priority`,\n ),\n enabled: accountInput.enabled ?? true,\n };\n\n accounts.push(normalizedAccount);\n\n if (!normalizedAccount.enabled) {\n return;\n }\n\n for (const model of models) {\n for (const credential of credentials) {\n routes.push({\n id: buildRouteId({\n provider: providerId,\n transport,\n accountId,\n credentialId: credential.id,\n model: model.id,\n }),\n provider: providerId,\n transport,\n profileId: profile,\n accountId,\n credentialId: credential.id,\n model: model.id,\n runtime,\n weight: credential.weight,\n priority: normalizedAccount.priority,\n handlerKey: `${providerId}:${transport.id}`,\n capabilities: { ...capabilities },\n verify,\n credential,\n ...(model.contextWindow !== undefined\n ? { contextWindow: model.contextWindow }\n : {}),\n modelAllowlistMode: accountModelAllowlistMode,\n advertisedModels: [model.id],\n contextMode: accountContextMode,\n ...(accountInput.defaultResponseFormat !== undefined\n ? { defaultResponseFormat: accountInput.defaultResponseFormat }\n : {}),\n ...(accountSystemPrompt !== undefined\n ? { systemPrompt: accountSystemPrompt }\n : {}),\n ...(accountLabel !== undefined ? { label: accountLabel } : {}),\n });\n }\n }\n });\n\n providers[providerId] = {\n id: providerId,\n accounts,\n };\n }\n\n assert(routes.length > 0, \"At least one enabled route must be produced.\");\n assertRouteIdUniqueness(routes);\n finalizeRotationCapabilities(routes);\n\n const strategy = input.routing?.strategy ?? DEFAULT_STRATEGY;\n\n // C7 / OQ-8: normalize the selector-resolution policy. Default is `error` (byte-identical to\n // pre-C7). For the `default` policy, fail fast at config time unless the configured\n // `defaultRouteId` resolves to EXACTLY one route (an ambiguous/missing default is unrecoverable).\n const resolutionInput = input.routing?.resolution;\n const unknownSelector: UnknownSelectorPolicy =\n resolutionInput?.unknownSelector ?? \"error\";\n let resolvedDefaultRouteId: string | undefined;\n if (unknownSelector === \"default\") {\n assert(\n typeof resolutionInput?.defaultRouteId === \"string\" &&\n resolutionInput.defaultRouteId.trim().length > 0,\n 'Routing resolution policy \"default\" requires a non-empty \"defaultRouteId\".',\n );\n const matchedDefaults = routes.filter((route) =>\n routeAliases(route).includes(resolutionInput!.defaultRouteId!),\n );\n assert(\n matchedDefaults.length === 1,\n `Routing resolution \"defaultRouteId\" must resolve to exactly one route; \"${resolutionInput!.defaultRouteId}\" matched ${matchedDefaults.length}.`,\n );\n resolvedDefaultRouteId = matchedDefaults[0]!.id;\n }\n const resolution: NormalizedRouteResolutionConfig = {\n unknownSelector,\n ...(resolvedDefaultRouteId !== undefined\n ? { defaultRouteId: resolvedDefaultRouteId }\n : {}),\n };\n\n const operations = DEFAULT_OPERATIONS.reduce<\n Record<OperationKind, NormalizedOperationRouting>\n >((accumulator, operation) => {\n accumulator[operation] = normalizeOperationRouting(\n input.routing?.operations?.[operation],\n routes,\n strategy,\n resolution,\n );\n return accumulator;\n }, {} as Record<OperationKind, NormalizedOperationRouting>);\n\n const fallback = {\n on: {\n ...DEFAULT_FALLBACK_ACTIONS,\n ...(input.routing?.fallback?.on ?? {}),\n },\n cooldownMs: {\n ...DEFAULT_COOLDOWN_MS,\n ...(input.routing?.fallback?.cooldownMs ?? {}),\n },\n };\n\n const retry = {\n maxAttempts: {\n ...DEFAULT_RETRY_MAX_ATTEMPTS,\n ...(input.routing?.retry?.maxAttempts ?? {}),\n },\n delayMs: {\n ...DEFAULT_RETRY_DELAY_MS,\n ...(input.routing?.retry?.delayMs ?? {}),\n },\n };\n\n return {\n providers,\n routes,\n routing: {\n strategy,\n operations,\n fallback,\n retry,\n shuffleOnInit: input.routing?.shuffleOnInit ?? false,\n resolution,\n },\n };\n}\n\nexport function isNormalizedConfig(\n value: AiConnectConfig | AiConnectConfigInput,\n): value is AiConnectConfig {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"routes\" in value &&\n Array.isArray(value.routes) &&\n \"routing\" in value\n );\n}\n\nexport function resolveRouteSelectors(\n selectors: string[] | undefined,\n routes: NormalizedRoute[],\n policy?: {\n unknownSelector?: UnknownSelectorPolicy;\n defaultRouteId?: string;\n },\n): string[] {\n return resolveRouteRefs(selectors, routes, policy);\n}\n", "// C9 \u2014 client-side fan-out throttle (UR-013 / UR-015 / F-4).\n//\n// CLIENT-FREE by construction: this module has TYPE-ONLY imports (plus the AiConnectError value),\n// ZERO Node builtins, no import from the client / transport modules, and NO provider-vendor\n// symbol. It is a browser-safe, reusable primitive (INV-REUSE-1) \u2014\n// `createFanoutLimiter(policy, runtime)` works standalone with NO client instance.\n//\n// Determinism (D6 / INV-DET-1): the rate limit is a token bucket recomputed off `runtime.now()`\n// ON EACH `acquire` \u2014 NEVER a wall-clock `setTimeout` \u2014 so `rate-limit-shapes-call-start-times`\n// replays bit-identically under a seeded fake clock.\n\nimport { AiConnectError } from \"./errors.js\";\nimport type {\n FanoutLimiter,\n NormalizedFanoutPolicy,\n RuntimeEnvironment,\n} from \"./types.js\";\n\ninterface Waiter {\n resolve: () => void;\n reject: (error: unknown) => void;\n signal?: AbortSignal;\n onAbort?: () => void;\n}\n\n/**\n * Canonical \"aborted\" error for every fan-out wait point (rate-gate, concurrency-gate, delay).\n * SYS-7 dedup: previously each call site constructed its own\n * `new AiConnectError(\"aborted\", \"Operation aborted.\")` inline (review-report-seed.md).\n */\nfunction abortedError(): AiConnectError {\n return new AiConnectError(\"aborted\", \"Operation aborted.\");\n}\n\n/**\n * Defensive upper bound on a single scheduled `delay()` wait (belt-and-suspenders for the\n * fractional-rate livelock class, SYS/H8 in review-report-seed.md). The root cause \u2014 a\n * `requestsPerSecond` in `(0,1)` flooring to `0` and never refilling \u2014 is fixed at the source in\n * `config.ts` (`asFanoutBound`); this cap only prevents `msUntilToken()` from ever parking a\n * waiter on a non-finite (`Infinity`/`NaN`) delay if that invariant is ever violated upstream.\n */\nconst MAX_DELAY_MS = 24 * 60 * 60 * 1000; // 1 day\n\n/**\n * Create a fan-out limiter from a normalized policy + a runtime clock seam.\n *\n * Three independent gates, all checked on `acquire`:\n * - **lifetime `maxCalls`** \u2014 a hard ceiling. The `(callsStarted)`-th acquire past the ceiling\n * REJECTS synchronously-derived with `AiConnectError('fanout_limit')`; it consumes no slot and\n * starts no transport (the client raises this BEFORE route selection, R16).\n * - **rate `requestsPerSecond`** \u2014 a token bucket of capacity `requestsPerSecond`, refilled at\n * `requestsPerSecond` tokens/sec computed from `runtime.now()` deltas (recompute-on-acquire).\n * When empty, the waiter is parked until enough wall-time (per `runtime.now()`) has elapsed \u2014\n * the client advances the seeded clock to release it deterministically.\n * - **concurrency `maxConcurrency`** \u2014 a semaphore; over-cap acquires queue FIFO (fairness, R15).\n *\n * The returned `acquire` resolves to a single-use `release` fn. `release` frees the concurrency\n * slot and pumps the FIFO queue. `maxCalls` is charged at acquire time (a started call counts even\n * if it later fails) and is NEVER refunded by `release`.\n */\nexport function createFanoutLimiter(\n policy: NormalizedFanoutPolicy,\n runtime: RuntimeEnvironment,\n): FanoutLimiter {\n const now = (): number => runtime.now?.() ?? Date.now();\n\n const { maxConcurrency, requestsPerSecond, maxCalls } = policy;\n const rateLimited = Number.isFinite(requestsPerSecond);\n const concurrencyLimited = Number.isFinite(maxConcurrency);\n\n let inFlight = 0;\n let callsStarted = 0;\n\n // Token bucket (only meaningful when rateLimited). Capacity = requestsPerSecond.\n let tokens = rateLimited ? requestsPerSecond : Number.POSITIVE_INFINITY;\n let lastRefill = now();\n\n // FIFO concurrency queue (R15 fairness) \u2014 waiters released in arrival order.\n const concurrencyQueue: Waiter[] = [];\n\n function refill(): void {\n if (!rateLimited) {\n return;\n }\n const current = now();\n const elapsedMs = current - lastRefill;\n if (elapsedMs <= 0) {\n return;\n }\n lastRefill = current;\n tokens = Math.min(requestsPerSecond, tokens + (elapsedMs / 1000) * requestsPerSecond);\n }\n\n /** Ms until the bucket holds at least one token (used to schedule a rate-gated retry). */\n function msUntilToken(): number {\n if (!rateLimited || tokens >= 1) {\n return 0;\n }\n const deficit = 1 - tokens;\n return Math.ceil((deficit / requestsPerSecond) * 1000);\n }\n\n function rejectWaiter(waiter: Waiter, error: unknown): void {\n detachAbort(waiter);\n waiter.reject(error);\n }\n\n function detachAbort(waiter: Waiter): void {\n if (waiter.signal && waiter.onAbort) {\n waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n }\n }\n\n function release(): void {\n inFlight = Math.max(0, inFlight - 1);\n pumpConcurrency();\n }\n\n function pumpConcurrency(): void {\n while (\n concurrencyQueue.length > 0 &&\n (!concurrencyLimited || inFlight < maxConcurrency)\n ) {\n const waiter = concurrencyQueue.shift()!;\n detachAbort(waiter);\n inFlight += 1;\n waiter.resolve();\n }\n }\n\n async function awaitConcurrencySlot(signal?: AbortSignal): Promise<void> {\n if (!concurrencyLimited || inFlight < maxConcurrency) {\n inFlight += 1;\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const waiter: Waiter = { resolve, reject };\n if (signal) {\n const onAbort = (): void => {\n const index = concurrencyQueue.indexOf(waiter);\n if (index >= 0) {\n concurrencyQueue.splice(index, 1);\n }\n rejectWaiter(waiter, abortedError());\n };\n if (signal.aborted) {\n reject(abortedError());\n return;\n }\n waiter.signal = signal;\n waiter.onAbort = onAbort;\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n concurrencyQueue.push(waiter);\n });\n }\n\n /**\n * Wait until the token bucket has \u22651 token, consuming it. Parks on the runtime timer seam so a\n * seeded fake clock releases the waiter when the harness advances time (deterministic). Without\n * `runtime.setTimer` (real environments) this falls back to real `setTimeout`.\n */\n async function awaitRateToken(signal?: AbortSignal): Promise<void> {\n if (!rateLimited) {\n return;\n }\n // Loop: refill, take a token if available, else wait the computed deficit.\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (signal?.aborted) {\n throw abortedError();\n }\n refill();\n if (tokens >= 1) {\n tokens -= 1;\n return;\n }\n const waitMs = msUntilToken();\n await delay(waitMs, signal);\n }\n }\n\n function delay(ms: number, signal?: AbortSignal): Promise<void> {\n // Defensive finite cap (belt-and-suspenders, see MAX_DELAY_MS doc comment): a non-finite or\n // negative `ms` (e.g. Infinity from a would-be zero-rate token bucket) is clamped instead of\n // parking the waiter forever.\n const safeMs =\n Number.isFinite(ms) && ms >= 0 ? Math.min(ms, MAX_DELAY_MS) : MAX_DELAY_MS;\n return new Promise<void>((resolve, reject) => {\n let cancelTimer: (() => void) | undefined;\n const onAbort = (): void => {\n cancelTimer?.();\n if (signal) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n reject(abortedError());\n };\n if (signal) {\n if (signal.aborted) {\n reject(abortedError());\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n const done = (): void => {\n if (signal) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n resolve();\n };\n if (runtime.setTimer) {\n cancelTimer = runtime.setTimer(safeMs, done);\n } else {\n const handle = setTimeout(done, safeMs);\n cancelTimer = () => clearTimeout(handle);\n }\n });\n }\n\n return {\n async acquire(signal?: AbortSignal): Promise<() => void> {\n // Lifetime ceiling FIRST (R16): a hard, unrefundable cap \u2014 exhausting it never touches a\n // slot, a token, or route health. The client raises this before route selection.\n if (callsStarted >= maxCalls) {\n throw new AiConnectError(\n \"fanout_limit\",\n `Fan-out lifetime call ceiling (maxCalls=${maxCalls}) exhausted.`,\n );\n }\n callsStarted += 1;\n\n try {\n // Rate gate (deterministic token bucket). May park on the clock seam.\n await awaitRateToken(signal);\n\n // Concurrency gate (FIFO semaphore). May park behind earlier waiters.\n await awaitConcurrencySlot(signal);\n } catch (error) {\n // Refund-on-abort-before-start (LOW, review-report-seed.md): callsStarted is charged\n // above BEFORE either gate is awaited. If the caller aborts while still queued here \u2014\n // i.e. no slot was ever handed out and no work ever started \u2014 the lifetime maxCalls\n // budget must not be permanently consumed by a call that never ran. Both gates only\n // ever reject via abort (never a non-abort failure), so any rejection here means\n // \"queued, never started\" and is unconditionally refunded.\n callsStarted -= 1;\n throw error;\n }\n\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n release();\n };\n },\n stats() {\n return {\n inFlight,\n queued: concurrencyQueue.length,\n callsStarted,\n maxConcurrency,\n requestsPerSecond,\n maxCalls,\n };\n },\n };\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport type {\n PortableFile,\n PortableFileCategory,\n PortableFilePayload,\n PortableFileInput,\n RemoteFileReferenceInput,\n} from \"./types.js\";\n\n/**\n * MIME types treated as `document` (UR-003: PDF input). A Set keeps membership\n * checks O(1) and the surface explicit \u2014 extend here when a new document format\n * gains provider parity. Currently application/pdf only; the document content\n * blocks of all default API providers accept it.\n */\nexport const SUPPORTED_DOCUMENT_MIME_TYPES: ReadonlySet<string> = new Set([\n \"application/pdf\",\n]);\n\nconst DOCUMENT_EXTENSION_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n};\n\nconst IMAGE_EXTENSION_MIME_TYPES: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n};\n\nconst TEXT_EXTENSIONS = new Set([\n \"txt\",\n \"md\",\n \"markdown\",\n \"json\",\n \"jsonl\",\n \"yaml\",\n \"yml\",\n \"xml\",\n \"csv\",\n \"ts\",\n \"tsx\",\n \"js\",\n \"jsx\",\n \"mjs\",\n \"cjs\",\n \"css\",\n \"html\",\n]);\n\nfunction isPortableFile(input: PortableFileInput): input is PortableFile {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"kind\" in input &&\n \"name\" in input &&\n \"id\" in input\n );\n}\n\nfunction isRemoteReference(\n input: PortableFileInput,\n): input is RemoteFileReferenceInput {\n return (\n typeof input === \"object\" &&\n input !== null &&\n (\"providerFileId\" in input || \"uri\" in input)\n );\n}\n\nfunction basename(value: string): string {\n const normalized = value.replaceAll(\"\\\\\", \"/\");\n const tail = normalized.split(\"/\").pop();\n return tail && tail.length > 0 ? tail : \"file\";\n}\n\nfunction extension(value: string): string {\n const name = basename(value);\n const index = name.lastIndexOf(\".\");\n if (index === -1 || index === name.length - 1) {\n return \"\";\n }\n return name.slice(index + 1).toLowerCase();\n}\n\n/**\n * Best-effort file extension for a MIME type, for naming a staged file when the\n * source attachment has no usable name (REQ-024). Cosmetic \u2014 the target CLI\n * receives the staged path verbatim and does not key off the extension.\n */\nexport function extensionForMime(mimeType: string): string {\n const subtype = mimeType.split(\"/\")[1]?.toLowerCase().replace(/[^a-z0-9.+-]/g, \"\");\n return subtype && subtype.length > 0 ? subtype : \"bin\";\n}\n\nfunction isRemoteUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nfunction mimeTypeAndExtensionFromMediaType(\n mediaTypeAndParams: string,\n fallbackMimeType: string,\n fallbackExtension: string,\n): { mimeType: string; extension: string } {\n const mimeType = mediaTypeAndParams.split(\";\")[0]?.trim() || fallbackMimeType;\n const extension = mimeType.split(\"/\")[1] ?? fallbackExtension;\n return { mimeType, extension };\n}\n\n/**\n * Parses a `data:` URL into `{mimeType, extension, data}` where `data` is\n * ALWAYS base64 (callers \u2014 `portableFileToBytes`/`portableFileToText`/\n * `portableFileToBase64` \u2014 decode it as such). Two RFC 2397 shapes are\n * supported:\n * - base64: `data:<mediaType>;base64,<base64-payload>`.\n * - plain/percent-encoded: `data:<mediaType>,<percent-encoded-payload>`\n * (e.g. `data:text/plain,Hello%20World`). Previously this shape fell\n * through to `null` and the caller misclassified it as a filesystem\n * PATH (MEDIUM, review-report-seed.md files.ts:107-129) \u2014 a `data:` URI\n * would be `fs.readFile`'d verbatim. It is now percent-decoded and\n * re-encoded to base64 so every downstream consumer keeps working off one\n * encoding. Any other `data:` shape (malformed percent-encoding, etc.) is\n * a hard `validation_error` rather than a silent path fallback.\n */\nfunction parseDataUrl(value: string): {\n mimeType: string;\n extension: string;\n data: string;\n} | null {\n // Allow intermediate `;param=value` segments between the media type and the\n // `;base64` marker, e.g. `data:text/plain;charset=utf-8;base64,...` (#14). The\n // media type is everything up to the first `;`; params are accepted but dropped.\n const base64Match = /^data:([^,]*?);base64,(.*)$/i.exec(value);\n if (base64Match) {\n const { mimeType, extension } = mimeTypeAndExtensionFromMediaType(\n base64Match[1] ?? \"\",\n \"application/octet-stream\",\n \"bin\",\n );\n return {\n mimeType,\n extension,\n data: base64Match[2] ?? \"\",\n };\n }\n\n const plainMatch = /^data:([^,]*?),(.*)$/i.exec(value);\n if (plainMatch) {\n const { mimeType, extension } = mimeTypeAndExtensionFromMediaType(\n plainMatch[1] ?? \"\",\n \"text/plain\",\n \"txt\",\n );\n\n let decoded: string;\n try {\n decoded = decodeURIComponent(plainMatch[2] ?? \"\");\n } catch {\n throw new AiConnectError(\n \"validation_error\",\n \"unsupported data URL encoding\",\n );\n }\n\n return {\n mimeType,\n extension,\n data: encodeBase64(new TextEncoder().encode(decoded)),\n };\n }\n\n if (/^data:/i.test(value)) {\n throw new AiConnectError(\n \"validation_error\",\n \"unsupported data URL encoding\",\n );\n }\n\n return null;\n}\n\nfunction mimeTypeFromName(name: string): string | undefined {\n const ext = extension(name);\n if (!ext) {\n return undefined;\n }\n\n if (ext === \"json\") {\n return \"application/json\";\n }\n\n if (ext === \"xml\") {\n return \"application/xml\";\n }\n\n if (TEXT_EXTENSIONS.has(ext)) {\n return \"text/plain\";\n }\n\n return IMAGE_EXTENSION_MIME_TYPES[ext] ?? DOCUMENT_EXTENSION_MIME_TYPES[ext];\n}\n\nfunction isTextMimeType(mimeType: string | undefined): boolean {\n return (\n typeof mimeType === \"string\" &&\n (mimeType.startsWith(\"text/\") ||\n mimeType === \"application/json\" ||\n mimeType === \"application/xml\")\n );\n}\n\nfunction encodeBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\");\n }\n\n let binary = \"\";\n for (let index = 0; index < bytes.length; index += 1) {\n binary += String.fromCharCode(bytes[index]!);\n }\n\n if (typeof btoa === \"function\") {\n return btoa(binary);\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No base64 encoder is available for portable file serialization.\",\n );\n}\n\nfunction decodeBase64(base64: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\").toString(\"utf8\");\n }\n\n // Browser branch: `atob` yields one Latin-1 byte per char, so decoding the\n // RAW atob string mangles any multi-byte UTF-8 text ('caf\u00E9' \u2192 mojibake).\n // Reuse the correct byte decode (atob + charCodeAt) and run it through a\n // UTF-8 TextDecoder so multi-byte text round-trips exactly.\n return new TextDecoder().decode(decodeBase64Bytes(base64));\n}\n\nfunction decodeBase64Bytes(base64: string): Uint8Array {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\");\n }\n\n if (typeof atob === \"function\") {\n const binary = atob(base64);\n return Uint8Array.from(binary, (char) => char.charCodeAt(0));\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No base64 decoder is available for portable file upload serialization.\",\n );\n}\n\nexport function inferPortableFileMimeType(file: PortableFile): string | undefined {\n if (file.mimeType) {\n return file.mimeType;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n return parseDataUrl(file.source)?.mimeType;\n }\n\n if (file.kind === \"path\") {\n return mimeTypeFromName(file.name);\n }\n\n if (file.kind === \"remote\") {\n const source = file.source as RemoteFileReferenceInput;\n return source.mimeType ?? (source.uri ? mimeTypeFromName(source.uri) : undefined);\n }\n\n return mimeTypeFromName(file.name);\n}\n\nexport function isPortableImageFile(file: PortableFile): boolean {\n return inferPortableFileMimeType(file)?.startsWith(\"image/\") ?? false;\n}\n\nexport function isPortableTextFile(file: PortableFile): boolean {\n const mimeType = inferPortableFileMimeType(file);\n if (isTextMimeType(mimeType)) {\n return true;\n }\n\n return TEXT_EXTENSIONS.has(extension(file.name));\n}\n\nexport function portableFileRemoteUri(file: PortableFile): string | undefined {\n if (file.kind !== \"remote\") {\n return undefined;\n }\n\n const source = file.source as RemoteFileReferenceInput;\n return source.uri;\n}\n\n/**\n * Coarse multimodal classification (C6). MIME type wins; document membership is\n * gated by `SUPPORTED_DOCUMENT_MIME_TYPES` so only known-supported document\n * formats route to a provider document block. Order: image \u2192 document \u2192 text \u2192\n * other (stable; `mixed-attachments-ordering` relies on it not reordering).\n */\nexport function portableFileCategory(file: PortableFile): PortableFileCategory {\n const mimeType = inferPortableFileMimeType(file);\n if (mimeType?.startsWith(\"image/\")) {\n return \"image\";\n }\n if (mimeType && SUPPORTED_DOCUMENT_MIME_TYPES.has(mimeType)) {\n return \"document\";\n }\n if (isPortableTextFile(file)) {\n return \"text\";\n }\n return \"other\";\n}\n\nexport function isPortableDocumentFile(file: PortableFile): boolean {\n return portableFileCategory(file) === \"document\";\n}\n\nfunction remoteReferenceProviderFileId(file: PortableFile): string | undefined {\n if (file.kind !== \"remote\") {\n return undefined;\n }\n const source = file.source as RemoteFileReferenceInput;\n return source.providerFileId;\n}\n\n/**\n * Raw base64 of a portable file's bytes (NO data-url prefix). Returns undefined\n * when no decodable byte source is available (e.g. a remote reference carrying\n * only a URI / providerFileId). Used by the Anthropic document base64 block and\n * the Gemini inlineData path. All node:* access stays behind `loadFsPromises`.\n */\nexport async function portableFileToBase64(\n file: PortableFile,\n): Promise<string | undefined> {\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed?.data;\n }\n\n const bytes = await portableFileToBytes(file);\n return bytes ? encodeBase64(bytes) : undefined;\n}\n\n// TRUST BOUNDARY: `filePath` is read VERBATIM via `fs.readFile` with no\n// sandboxing/allow-listing here. It normally originates from a `PortableFile`\n// of `kind:'path'` produced by `preparePortableFile` (see that function's doc\n// comment) \u2014 reachable from the PUBLIC `GenerateRequest.attachments` API.\n// Callers exposed to untrusted input should either not reach this path at\n// all (reject `kind:'path'` upstream) or ensure `preparePortableFile` was\n// called with a restrictive `options.pathGuard`.\nasync function readPathBytes(filePath: string): Promise<Uint8Array> {\n const { readFile } = await loadFsPromises();\n return await readFile(filePath);\n}\n\n// See the TRUST BOUNDARY note on `readPathBytes` above \u2014 identical concern.\nasync function readPathText(filePath: string): Promise<string> {\n const { readFile } = await loadFsPromises();\n return await readFile(filePath, \"utf8\");\n}\n\ntype FsPromisesModule = typeof import(\"node:fs/promises\");\n\nasync function loadFsPromises(): Promise<FsPromisesModule> {\n if (typeof process === \"undefined\" || !process.versions?.node) {\n throw new AiConnectError(\n \"not_supported\",\n \"Path-based file access is only available in local runtimes.\",\n );\n }\n\n const dynamicImport = new Function(\n \"specifier\",\n \"return import(specifier);\",\n ) as (specifier: string) => Promise<FsPromisesModule>;\n\n return await dynamicImport(\"node:fs/promises\");\n}\n\nexport async function portableFileToDataUrl(\n file: PortableFile,\n): Promise<string | undefined> {\n if (!isPortableImageFile(file)) {\n return undefined;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n return file.source;\n }\n\n const mimeType = inferPortableFileMimeType(file) ?? \"image/png\";\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n const bytes = new Uint8Array(await file.source.arrayBuffer());\n return `data:${mimeType};base64,${encodeBase64(bytes)}`;\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n const bytes = await readPathBytes(file.source);\n return `data:${mimeType};base64,${encodeBase64(bytes)}`;\n }\n\n return undefined;\n}\n\nexport async function portableFileToBytes(\n file: PortableFile,\n): Promise<Uint8Array | undefined> {\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed ? decodeBase64Bytes(parsed.data) : undefined;\n }\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n return new Uint8Array(await file.source.arrayBuffer());\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return await readPathBytes(file.source);\n }\n\n return undefined;\n}\n\nexport async function portableFileToText(\n file: PortableFile,\n): Promise<string | undefined> {\n if (!isPortableTextFile(file)) {\n return undefined;\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n return parsed ? decodeBase64(parsed.data) : undefined;\n }\n\n if (\n (file.kind === \"browser-file\" || file.kind === \"browser-blob\") &&\n file.source instanceof Blob\n ) {\n return await file.source.text();\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return await readPathText(file.source);\n }\n\n return undefined;\n}\n\n/**\n * SINGLE decode path (C6 \u2014 INV the design calls \"materializePortableFile\"). One\n * pass resolves the category + MIME type and reads the byte/text/uri source\n * exactly once, populating only the carriers a downstream provider builder can\n * use. Every consumer (api document/image builders, acp PDF path) reads from the\n * payload rather than re-decoding the file. All filesystem access flows through\n * `portableFileToBytes`/`portableFileToText`, which sit behind the lazy\n * `loadFsPromises` guard (F-A2: browser-reachable, node:*-free).\n */\nexport async function materializePortableFile(\n file: PortableFile,\n): Promise<PortableFilePayload> {\n const category = portableFileCategory(file);\n const mimeType =\n inferPortableFileMimeType(file) ??\n (category === \"image\"\n ? \"image/png\"\n : category === \"document\"\n ? \"application/pdf\"\n : \"application/octet-stream\");\n\n const uri = portableFileRemoteUri(file);\n const providerFileId = remoteReferenceProviderFileId(file);\n\n const payload: PortableFilePayload = {\n category,\n mimeType,\n name: file.name,\n ...(uri ? { uri } : {}),\n ...(providerFileId ? { providerFileId } : {}),\n };\n\n if (category === \"text\") {\n const text = await portableFileToText(file);\n if (text !== undefined) {\n payload.text = text;\n }\n return payload;\n }\n\n if (category === \"image\" || category === \"document\") {\n // Prefer raw bytes (path/blob/data-url). A remote reference with no bytes\n // keeps only its uri/providerFileId \u2014 builders fall back to the URL/file-id\n // wire shape and never emit an empty base64 block.\n const base64 = await portableFileToBase64(file);\n if (base64 !== undefined) {\n payload.base64 = base64;\n payload.dataUrl = `data:${mimeType};base64,${base64}`;\n }\n }\n\n if (category === \"other\") {\n // SYS-6/MEDIUM (review-report-seed.md files.ts:416-459): an \"other\"\n // (neither image/document/text) file previously yielded a payload with no\n // bytes and no signal that anything was dropped \u2014 silent data loss for\n // local/blob files that DO have decodable bytes. Mirror the image/document\n // path so path/blob/data-url \"other\" files still carry their content.\n const base64 = await portableFileToBase64(file);\n if (base64 !== undefined) {\n payload.base64 = base64;\n payload.dataUrl = `data:${mimeType};base64,${base64}`;\n } else if (!uri && !providerFileId) {\n // No decodable byte source AND no remote uri/providerFileId fallback \u2014\n // the payload genuinely carries no content. Surface it instead of\n // returning a metadata-only payload indistinguishable from \"empty file\".\n const droppedReason =\n `Portable file \"${file.name}\" (category \"other\", kind \"${file.kind}\") has ` +\n \"no decodable byte source and no remote uri/providerFileId; its content \" +\n \"was dropped and this payload carries metadata only.\";\n payload.droppedReason = droppedReason;\n payload.warnings = [...(payload.warnings ?? []), droppedReason];\n }\n }\n\n return payload;\n}\n\n/**\n * Opt-in guard for the plain-string `{kind:'path'}` branch of\n * {@link preparePortableFile} (see the trust-boundary doc comment there).\n * Omitted (default) \u2192 unrestricted, byte-identical to pre-existing behavior.\n * - `\"basename\"`: strip any directory component; only the bare filename is\n * kept as the path source (no `/`, no `\\`, no `..` \u2014 traversal is\n * structurally impossible because there is no directory left to escape\n * with). The caller is expected to resolve the basename against its own\n * trusted base directory downstream.\n * - `{ allowedRoots: string[] }`: the input path must resolve (after\n * collapsing `.`/`..` segments, WITHOUT touching the filesystem \u2014 this is\n * a lightweight, dependency-free check, not a substitute for\n * `fs.realpath`-based canonicalization when symlinks are a concern) inside\n * one of the given root directories, or `preparePortableFile` throws\n * `AiConnectError('validation_error', ...)`.\n */\nexport type PreparePortableFilePathGuard =\n | \"basename\"\n | { allowedRoots: string[] };\n\nexport interface PreparePortableFileOptions {\n pathGuard?: PreparePortableFilePathGuard;\n}\n\nfunction collapsePathSegments(value: string): string {\n const normalized = value.replaceAll(\"\\\\\", \"/\");\n const isAbsolute = normalized.startsWith(\"/\");\n const segments = normalized.split(\"/\");\n const resolved: string[] = [];\n\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\") {\n continue;\n }\n if (segment === \"..\") {\n if (resolved.length > 0 && resolved[resolved.length - 1] !== \"..\") {\n resolved.pop();\n } else if (!isAbsolute) {\n resolved.push(\"..\");\n }\n continue;\n }\n resolved.push(segment);\n }\n\n return (isAbsolute ? \"/\" : \"\") + resolved.join(\"/\");\n}\n\nfunction applyPathGuard(\n rawPath: string,\n guard: PreparePortableFilePathGuard | undefined,\n): string {\n if (!guard) {\n return rawPath;\n }\n\n if (guard === \"basename\") {\n return basename(rawPath);\n }\n\n const resolved = collapsePathSegments(rawPath);\n const withinAllowedRoot = guard.allowedRoots.some((root) => {\n const resolvedRoot = collapsePathSegments(root);\n return resolved === resolvedRoot || resolved.startsWith(`${resolvedRoot}/`);\n });\n\n if (!withinAllowedRoot) {\n throw new AiConnectError(\n \"validation_error\",\n `Path \"${rawPath}\" is outside the configured allowedRoots for portable file attachments.`,\n );\n }\n\n return rawPath;\n}\n\n/**\n * Normalizes a `PortableFileInput` (path string / remote URL / data URL /\n * browser File|Blob / remote reference / already-normalized `PortableFile`)\n * into a `PortableFile`.\n *\n * TRUST BOUNDARY (MEDIUM, review-report-seed.md files.ts:302-310): any plain\n * string that is neither a `data:` URL nor an `http(s):` URL is treated as a\n * filesystem PATH (`{kind:'path'}`) and later read VERBATIM via\n * `fs.readFile` (`readPathBytes`/`readPathText`, below) with NO sandboxing \u2014\n * whatever string reaches this function is eligible to read any file the\n * host process can access. This function is reachable from the PUBLIC\n * `GenerateRequest.attachments` API (and `image.sourceImage`/`mask`/\n * `referenceImages`), so any caller that forwards attacker-controlled strings\n * from an untrusted source (e.g. a server request body) into `attachments`\n * effectively grants that caller read access to the host filesystem.\n *\n * Callers that accept `PortableFileInput`/`attachments` from an untrusted or\n * public caller MUST NOT pass raw strings through unchecked \u2014 either\n * pre-validate/allow-list the path themselves, or pass `options.pathGuard`\n * (`\"basename\"` or `{allowedRoots}`) to restrict what `{kind:'path'}` values\n * this function will produce. Default (no `options`/no `pathGuard`) is\n * UNRESTRICTED for backward compatibility with existing local/CLI callers\n * that intentionally pass trusted local paths.\n */\nexport function preparePortableFile(\n input: PortableFileInput,\n options?: PreparePortableFileOptions,\n): PortableFile {\n if (isPortableFile(input)) {\n return input;\n }\n\n if (typeof input === \"string\") {\n const dataUrl = parseDataUrl(input);\n if (dataUrl) {\n return {\n id: `data-url:${input.length}`,\n kind: \"data-url\",\n name: `generated.${dataUrl.extension}`,\n mimeType: dataUrl.mimeType,\n source: input,\n };\n }\n\n if (isRemoteUrl(input)) {\n return {\n id: `remote:${input}`,\n kind: \"remote\",\n name: basename(input),\n source: {\n uri: input,\n name: basename(input),\n },\n };\n }\n\n const guardedPath = applyPathGuard(input, options?.pathGuard);\n return {\n id: `path:${guardedPath}`,\n kind: \"path\",\n name: basename(guardedPath),\n source: guardedPath,\n };\n }\n\n if (isRemoteReference(input)) {\n const name = input.name ?? input.providerFileId ?? input.uri ?? \"remote\";\n return {\n id: input.id ?? `remote:${name}`,\n kind: \"remote\",\n name,\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n ...(input.size !== undefined ? { size: input.size } : {}),\n source: input,\n };\n }\n\n if (typeof File !== \"undefined\" && input instanceof File) {\n return {\n id: `file:${input.name}:${input.size}`,\n kind: \"browser-file\",\n name: input.name,\n ...(input.type ? { mimeType: input.type } : {}),\n size: input.size,\n source: input,\n };\n }\n\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n return {\n id: `blob:${input.size}:${input.type || \"application/octet-stream\"}`,\n kind: \"browser-blob\",\n name: \"blob\",\n ...(input.type ? { mimeType: input.type } : {}),\n size: input.size,\n source: input,\n };\n }\n\n throw new AiConnectError(\n \"validation_error\",\n \"Unsupported file input. Expected a path, browser File/Blob, or remote file reference.\",\n );\n}\n", "import type {\n WideEvent,\n WideEventLogger,\n WideEventSamplingOptions,\n} from \"./types.js\";\n\nexport interface ConsoleWideEventLoggerOptions {\n pretty?: boolean;\n write?: (line: string) => void;\n}\n\n/**\n * Secret redaction (SYS-3, F-C1-6). Keys whose name (case-insensitive) is one of\n * these are replaced wholesale with `[REDACTED]` \u2014 defense-in-depth so a custom\n * sink cannot accidentally serialize a credential.\n */\nconst REDACT_KEYS = new Set([\n \"apikey\",\n \"authorization\",\n \"password\",\n \"token\",\n \"x-api-key\",\n \"x-goog-api-key\",\n]);\n\nconst REDACTED = \"[REDACTED]\";\n\n/**\n * A canonical UUID (8-4-4-4-12 hex). Request ids default to `crypto.randomUUID()`\n * and trace/span ids are frequently UUIDs \u2014 these are correlation keys, NOT\n * secrets, and must survive redaction or wide-event logging becomes useless\n * (every event would share `requestId: \"[REDACTED]\"`). TASK-035 CODE_REVIEW.\n */\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Known provider credential prefixes \u2014 these ARE secrets regardless of length. */\nconst SECRET_PREFIX_RE = /^(sk-|sk-ant-|xox[baprs]-|ghp_|gho_|AIza)/;\n\n/**\n * Value-heuristic redaction (F-C1-6 / F-C2-2): even under a non-secret key, a\n * value that *looks* like a credential is redacted \u2014 a `Bearer \u2026` token, a known\n * provider key prefix, or a high-entropy base64 blob of length \u2265 40. The\n * character class deliberately EXCLUDES `-` so hyphenated correlation ids\n * (UUIDs, `req-\u2026`) are not matched, and UUIDs are explicitly spared; the length\n * floor is 40 (real API keys/tokens) to avoid nuking 32-hex trace ids and other\n * medium-length non-secret identifiers. `:` `.` `/` whitespace still excluded so\n * URLs/route-ids/command-lines pass through. (TASK-035 CODE_REVIEW: the prior\n * `\u226532` + `-`-inclusive rule redacted `crypto.randomUUID()` request ids.)\n */\nfunction looksLikeSecretValue(value: string): boolean {\n if (UUID_RE.test(value)) {\n return false;\n }\n if (/^Bearer\\s+/i.test(value)) {\n return true;\n }\n if (SECRET_PREFIX_RE.test(value)) {\n return true;\n }\n return /^[A-Za-z0-9+/=_]{40,}$/.test(value);\n}\n\nfunction redactNode(node: unknown): unknown {\n if (node === null || node === undefined) {\n return node;\n }\n if (typeof node === \"string\") {\n return looksLikeSecretValue(node) ? REDACTED : node;\n }\n if (typeof node !== \"object\") {\n return node;\n }\n if (Array.isArray(node)) {\n return node.map((item) => redactNode(item));\n }\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n result[key] = REDACT_KEYS.has(key.toLowerCase())\n ? REDACTED\n : redactNode(value);\n }\n return result;\n}\n\n/**\n * Deep, immutable-copy redaction of a wide event (SYS-3). Never mutates the\n * input. Applied at the logging choke-point so every sink \u2014 including custom\n * ones \u2014 inherits credential-safe output.\n */\nexport function redactEvent<T>(event: T): T {\n return redactNode(event) as T;\n}\n\n/**\n * Strip credentials from a base URL before it reaches telemetry (SYS-3):\n * removes userinfo (`user:pass@`) and the query string / fragment, keeping only\n * scheme + host + path.\n */\nexport function redactBaseUrl(url: string): string {\n try {\n const parsed = new URL(url);\n parsed.username = \"\";\n parsed.password = \"\";\n parsed.search = \"\";\n parsed.hash = \"\";\n return parsed.toString();\n } catch {\n const withoutHash = url.split(\"#\")[0] ?? url;\n return withoutHash.split(\"?\")[0] ?? withoutHash;\n }\n}\n\nexport function createConsoleWideEventLogger(\n options: ConsoleWideEventLoggerOptions = {},\n): WideEventLogger {\n const write =\n options.write ??\n ((line: string) => {\n console.info(line);\n });\n\n return (event) => {\n const redacted = redactEvent(event);\n write(\n options.pretty\n ? JSON.stringify(redacted, null, 2)\n : JSON.stringify(redacted),\n );\n };\n}\n\nexport async function shouldEmitWideEvent(\n event: WideEvent,\n options: WideEventSamplingOptions = {},\n /**\n * Injectable RNG seam (C5 LOW) \u2014 defaults to `Math.random`. Lets deterministic\n * tests pin the sampling decision without touching global state.\n */\n random: () => number = Math.random,\n): Promise<boolean> {\n const sampleRate = options.sampleRate ?? 1;\n\n if ((options.keepErrors ?? true) && event.outcome === \"error\") {\n return true;\n }\n\n const slowOperationMs = options.slowOperationMs ?? 2_000;\n if (event.durationMs >= slowOperationMs) {\n return true;\n }\n\n if (\n (options.keepWarnings ?? false) &&\n (event.result?.warningsCount ?? 0) > 0\n ) {\n return true;\n }\n\n if (options.keepOperations?.includes(event.operationName)) {\n return true;\n }\n\n if (\n options.keepRoutes?.some((routeId) =>\n event.candidates.some((candidate) => candidate.id === routeId),\n )\n ) {\n return true;\n }\n\n if (\n options.keepProviders?.some((providerId) =>\n event.candidates.some((candidate) => candidate.provider === providerId),\n )\n ) {\n return true;\n }\n\n if (options.predicate && (await options.predicate(event))) {\n return true;\n }\n\n if (sampleRate <= 0) {\n return false;\n }\n\n if (sampleRate >= 1) {\n return true;\n }\n\n return random() < sampleRate;\n}\n", "import { resolveRouteSelectors, toPublicCapabilities } from \"./config.js\";\nimport type {\n AiConnectConfig,\n AiConnectErrorCode,\n CandidateModel,\n GenerateRequest,\n NormalizedRoute,\n OperationKind,\n ProviderId,\n RouteHealthSnapshot,\n RouteHints,\n RoutingStrategy,\n RuntimeEnvironment,\n} from \"./types.js\";\n\ntype RouteHealthStateInternal = RouteHealthSnapshot;\n\nfunction runtimeEligible(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n): boolean {\n if (route.transport.kind === \"acp\" && runtime.kind !== \"local\") {\n return false;\n }\n\n if (route.runtime === \"universal\") {\n return true;\n }\n\n return route.runtime === runtime.kind;\n}\n\nfunction capabilityMatch(\n route: NormalizedRoute,\n hints: RouteHints | undefined,\n): boolean {\n if (!hints?.requiredCapabilities) {\n return true;\n }\n\n return Object.entries(hints.requiredCapabilities).every(([key, value]) => {\n if (value === undefined) {\n return true;\n }\n\n return route.capabilities[key as keyof typeof route.capabilities] === value;\n });\n}\n\nfunction preferredProviderScore(\n route: NormalizedRoute,\n preferredProviders: string[] | undefined,\n): number {\n if (!preferredProviders || preferredProviders.length === 0) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const index = preferredProviders.indexOf(route.provider);\n return index === -1 ? Number.MAX_SAFE_INTEGER : index;\n}\n\nfunction baseSort(\n routes: NormalizedRoute[],\n preferredProviders: string[] | undefined,\n): NormalizedRoute[] {\n return [...routes].sort((left, right) => {\n const preferredDelta =\n preferredProviderScore(left, preferredProviders) -\n preferredProviderScore(right, preferredProviders);\n\n if (preferredDelta !== 0) {\n return preferredDelta;\n }\n\n if (left.priority !== right.priority) {\n return left.priority - right.priority;\n }\n\n if (left.weight !== right.weight) {\n return right.weight - left.weight;\n }\n\n return left.id.localeCompare(right.id);\n });\n}\n\nfunction rotate<T>(items: T[], index: number): T[] {\n if (items.length === 0) {\n return [];\n }\n\n const start = index % items.length;\n return [...items.slice(start), ...items.slice(0, start)];\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)];\n}\n\nfunction buildWeightedOrder(routes: NormalizedRoute[]): NormalizedRoute[] {\n const expanded: NormalizedRoute[] = [];\n\n for (const route of routes) {\n for (let index = 0; index < route.weight; index += 1) {\n expanded.push(route);\n }\n }\n\n return expanded;\n}\n\n/**\n * D4 / SYS-4 (extensibility): strategy dispatch as a `Record<RoutingStrategy, ...>` registry\n * instead of if/else branching, so the union type forces exhaustiveness \u2014 adding a new\n * `RoutingStrategy` member without a matching entry here is a compile-time error.\n *\n * Each entry receives the already sorted/shuffled/health-filtered candidate list (`ordered`),\n * a bound cursor accessor, and the cursor key it should advance under. Behavior is byte-for-byte\n * identical to the previous if/else chain.\n */\ntype RoutingStrategyFn = (\n ordered: NormalizedRoute[],\n cursor: (key: string, length: number) => number,\n cursorKey: string,\n) => NormalizedRoute[];\n\nconst ROUTING_STRATEGIES: Record<RoutingStrategy, RoutingStrategyFn> = {\n priority: (ordered) => ordered,\n failover: (ordered) => ordered,\n \"round-robin\": (ordered, cursor, cursorKey) => {\n const index = cursor(cursorKey, ordered.length);\n return rotate(ordered, index);\n },\n \"weighted-round-robin\": (ordered, cursor, cursorKey) => {\n const weighted = buildWeightedOrder(ordered);\n const index = cursor(cursorKey, weighted.length);\n return unique(rotate(weighted, index));\n },\n};\n\nexport class RouteRegistry {\n readonly config: AiConnectConfig;\n readonly runtime: RuntimeEnvironment;\n\n #health = new Map<string, RouteHealthStateInternal>();\n #cursors = new Map<string, number>();\n #routeMap = new Map<string, NormalizedRoute>();\n #shuffles = new Map<string, NormalizedRoute[]>();\n\n constructor(config: AiConnectConfig, runtime: RuntimeEnvironment) {\n this.config = config;\n this.runtime = runtime;\n\n for (const route of config.routes) {\n this.#routeMap.set(route.id, route);\n }\n }\n\n getHealth(route: NormalizedRoute): RouteHealthSnapshot {\n const current = this.#health.get(route.id);\n\n if (!current) {\n return {\n state: \"ready\",\n failureCount: 0,\n };\n }\n\n if (\n current.state === \"cooling_down\" &&\n current.cooldownUntil !== undefined &&\n current.cooldownUntil <= this.#now()\n ) {\n const readyState = {\n state: \"ready\" as const,\n failureCount: current.failureCount,\n };\n this.#health.set(route.id, readyState);\n return readyState;\n }\n\n return current;\n }\n\n listRoutes(filter?: {\n operation?: GenerateRequest[\"operation\"];\n }): NormalizedRoute[] {\n if (!filter?.operation) {\n return [...this.config.routes];\n }\n\n const routeIds = this.config.routing.operations[filter.operation].pool;\n return routeIds\n .map((routeId) => this.#routeMap.get(routeId))\n .filter((route): route is NormalizedRoute => Boolean(route));\n }\n\n /**\n * Project the currently-eligible routes into secret-free {@link CandidateModel}s (C9 / UR-014).\n * Deferred from C7 (needs the C9-owned `CandidateModel` type). Reuses the runtime-eligibility +\n * health filters (a `cooling_down`/`unavailable` route is excluded), then narrows by optional\n * `operation` (router pool) and `provider`. Carries ONLY the secret-free fields \u2014 never a\n * credential/baseUrl/handler key (mirrors INV-PROJ-1 for the candidate list).\n */\n candidateModels(filter?: {\n operation?: OperationKind;\n provider?: ProviderId;\n }): CandidateModel[] {\n const operationFilter = filter?.operation\n ? { operation: filter.operation }\n : undefined;\n return this.listRoutes(operationFilter)\n .filter((route) =>\n filter?.provider ? route.provider === filter.provider : true,\n )\n .filter((route) => runtimeEligible(route, this.runtime))\n .filter((route) => {\n const state = this.getHealth(route).state;\n return state !== \"cooling_down\" && state !== \"unavailable\";\n })\n .map((route) => ({\n model: route.model,\n provider: route.provider,\n routeId: route.id,\n transportKind: route.transport.kind,\n // INV-PROJ-1: project the secret-free subset (never the full\n // RouteCapabilities) so internal routing flags do not leak to the\n // ModelSelector / listCandidateModels surface (#12).\n capabilities: toPublicCapabilities(route.capabilities),\n }));\n }\n\n resolveCandidates(request: GenerateRequest & { operation: NonNullable<GenerateRequest[\"operation\"]> }): NormalizedRoute[] {\n const operation = request.operation;\n const operationRouting = this.config.routing.operations[operation];\n const routeIds = request.routeHints?.pool?.length\n ? resolveRouteSelectors(request.routeHints.pool, this.config.routes)\n : operationRouting.pool;\n\n const excludedIds = new Set(request.routeHints?.excludeRouteIds ?? []);\n const requestedModel = request.routeHints?.model;\n\n // The STABLE pool for this request shape \u2014 everything except transient route-health\n // state (cooling_down/unavailable). Feeds the cursor/shuffle key below so a health flap\n // (route cools down then recovers) never changes the key and resets round-robin rotation\n // fairness (MEDIUM finding, C6b). Health is applied afterwards, as a rotation-time filter\n // in #order, which simply skips currently-unhealthy members instead of re-deriving the key.\n const eligible = routeIds\n .map((routeId) => this.#routeMap.get(routeId))\n .filter((route): route is NormalizedRoute => Boolean(route))\n .filter((route) => !excludedIds.has(route.id))\n .filter((route) => runtimeEligible(route, this.runtime))\n .filter((route) => capabilityMatch(route, request.routeHints))\n // C7 / INV-ROUTE-1: apply a request-level model override (CD-8). On a `strict` route an\n // undeclared model DROPS the route (never billed); on a `shortlist` route it is passed\n // through verbatim on a synthetic copy preserving `route.id` (R12). Independent of health\n // state, so it stays part of the stable eligible set (order vs. the old health-filter\n // position doesn't change the final membership \u2014 both predicates are commutative).\n .map((route) => applyRequestedModel(route, requestedModel))\n .filter((route): route is NormalizedRoute => Boolean(route));\n\n const strategy = request.routeHints?.strategy ?? operationRouting.strategy;\n // Stable identifier: operation + strategy + the full configured/resolved pool id list\n // (pre-health). Deliberately NOT derived from the health-filtered candidate set.\n const cursorKey = `${operation}:${strategy}:${eligible.map((route) => route.id).join(\"|\")}`;\n\n const healthyIds = new Set(\n eligible\n .filter((route) => {\n const state = this.getHealth(route).state;\n // `degraded` routes remain selectable (unlike cooling_down/unavailable) \u2014 a route\n // stays a candidate even after a non-cooldown failure until it either recovers via\n // recordSuccess or escalates to unavailable/cooling_down.\n return state !== \"cooling_down\" && state !== \"unavailable\";\n })\n .map((route) => route.id),\n );\n\n return this.#order(\n strategy,\n eligible,\n healthyIds,\n request.routeHints?.preferredProviders,\n cursorKey,\n );\n }\n\n recordSuccess(route: NormalizedRoute): void {\n this.#health.set(route.id, {\n state: \"ready\",\n failureCount: 0,\n });\n }\n\n recordFailure(route: NormalizedRoute, code: AiConnectErrorCode): void {\n const previous = this.getHealth(route);\n const failureCount = previous.failureCount + 1;\n const cooldownMs = this.config.routing.fallback.cooldownMs[code] ?? 0;\n\n if (\n code === \"rate_limit\" ||\n code === \"quota_exhausted\" ||\n code === \"temporary_unavailable\" ||\n code === \"local_harness_unavailable\"\n ) {\n this.#health.set(route.id, {\n state: cooldownMs > 0 ? \"cooling_down\" : \"degraded\",\n failureCount,\n ...(cooldownMs > 0 ? { cooldownUntil: this.#now() + cooldownMs } : {}),\n });\n return;\n }\n\n if (\n code === \"invalid_credentials\" ||\n code === \"auth_error\" ||\n code === \"validation_error\"\n ) {\n this.#health.set(route.id, {\n state: \"unavailable\",\n failureCount,\n });\n return;\n }\n\n this.#health.set(route.id, {\n state: \"degraded\",\n failureCount,\n });\n }\n\n #order(\n strategy: RoutingStrategy,\n eligible: NormalizedRoute[],\n healthyIds: Set<string>,\n preferredProviders: string[] | undefined,\n cursorKey: string,\n ): NormalizedRoute[] {\n // Sort/shuffle the STABLE eligible pool under the stable cursorKey (see resolveCandidates),\n // then skip currently-unhealthy members when producing the candidate order. This keeps the\n // shuffle cache and cursor counter keyed on something that doesn't change across a health\n // flap, while unhealthy routes still never appear as candidates.\n const sorted = baseSort(eligible, preferredProviders);\n const orderedFull = this.config.routing.shuffleOnInit\n ? this.#shuffle(cursorKey, sorted)\n : sorted;\n const ordered = orderedFull.filter((route) => healthyIds.has(route.id));\n\n const strategyFn = ROUTING_STRATEGIES[strategy];\n return strategyFn(ordered, (key, length) => this.#cursor(key, length), cursorKey);\n }\n\n #shuffle(key: string, routes: NormalizedRoute[]): NormalizedRoute[] {\n const cached = this.#shuffles.get(key);\n if (cached) {\n return cached;\n }\n\n const items = [...routes];\n for (let index = items.length - 1; index > 0; index -= 1) {\n const nextIndex = Math.floor(Math.random() * (index + 1));\n const current = items[index]!;\n const next = items[nextIndex]!;\n items[index] = next;\n items[nextIndex] = current;\n }\n\n this.#shuffles.set(key, items);\n return items;\n }\n\n #cursor(key: string, length: number): number {\n if (length === 0) {\n return 0;\n }\n\n const current = this.#cursors.get(key) ?? 0;\n this.#cursors.set(key, current + 1);\n return current;\n }\n\n #now(): number {\n return this.runtime.now?.() ?? Date.now();\n }\n}\n\nexport function canFallbackBetween(\n failed: NormalizedRoute,\n next: NormalizedRoute,\n actions: string[],\n): boolean {\n for (const action of actions) {\n if (\n action === \"rotate-credential\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.accountId === next.accountId &&\n failed.model === next.model &&\n failed.credentialId !== next.credentialId\n ) {\n return true;\n }\n\n if (\n action === \"rotate-account\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.model === next.model &&\n failed.accountId !== next.accountId\n ) {\n return true;\n }\n\n if (\n action === \"fallback-model\" &&\n failed.provider === next.provider &&\n failed.transport.id === next.transport.id &&\n failed.model !== next.model\n ) {\n return true;\n }\n\n if (\n action === \"fallback-transport\" &&\n failed.provider === next.provider &&\n failed.transport.id !== next.transport.id\n ) {\n return true;\n }\n\n if (action === \"fallback-provider\" && failed.provider !== next.provider) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Apply a request-level model override to a candidate route (C7 / CD-8 / INV-ROUTE-1).\n *\n * - No `requestedModel` \u2192 the route is returned unchanged.\n * - `requestedModel` already equals `route.model` \u2192 returned unchanged (no synthetic copy).\n * - `strict` route + undeclared model \u2192 returns `undefined` (DROP \u2014 never silently billed; OQ-6).\n * - `shortlist` route + undeclared model \u2192 returns a synthetic copy with `model: requestedModel`\n * while PRESERVING the original `route.id` (R12 \u2014 health/cursors keyed on `id` never fragment).\n *\n * Pure and route-local: the input route object is never mutated.\n */\nexport function applyRequestedModel(\n route: NormalizedRoute,\n requestedModel: string | undefined,\n): NormalizedRoute | undefined {\n if (!requestedModel || requestedModel === route.model) {\n return route;\n }\n\n if (route.advertisedModels.includes(requestedModel)) {\n // Declared model \u2014 verbatim passthrough on a synthetic copy (id preserved).\n return { ...route, model: requestedModel };\n }\n\n if (route.modelAllowlistMode === \"strict\") {\n // Undeclared on a strict route \u2014 DROP so it can never be billed.\n return undefined;\n }\n\n // shortlist: advisory allowlist \u2014 pass the undeclared model through verbatim, id preserved.\n return { ...route, model: requestedModel };\n}\n", "import type {\n AcpModelInfo,\n ModelContextResolution,\n ModelPricing,\n ModelReferenceEntry,\n ResolveModelContextInput,\n} from \"./types.js\";\n\n/**\n * Browser-safe model-reference primitive (C4 / UR-007, UR-009, UR-015).\n *\n * This module is a PURE data + functions reuse primitive: it has ZERO `node:*` imports,\n * needs no client instance, and references no provider/transport/bs-search symbol except\n * inside the curated `MODEL_REFERENCE` id-string literals (INV-REUSE-1). Everything here is\n * synchronous and side-effect-free \u2014 safe to run in a browser bundle.\n *\n * The fallback default context window when nothing else is known.\n */\nexport const DEFAULT_CONTEXT_WINDOW = 8192;\n\n/**\n * Curated reference table of model context windows / pricing / free-tier flags.\n *\n * Keys are NORMALIZED model keys (see {@link normalizeModelKey}): lowercase, provider prefix\n * dropped, `:free`/`:beta` suffixes dropped. Covers every model id that appears in\n * `src/catalog.ts` plus the common public model families so the flat-8192 default rarely\n * fires (R-OQ3). The provider/model NAMES that appear here are inert string DATA, not symbol\n * references \u2014 the reusability gate (INV-REUSE-1) explicitly allows them inside these literals.\n */\nexport const MODEL_REFERENCE: Record<string, ModelReferenceEntry> = {\n // --- OpenAI (gpt / codex families; catalog: gpt-4.1, gpt-5.4/xhigh) ---\n \"gpt-4.1\": { key: \"gpt-4.1\", contextLength: 1_047_576 },\n \"gpt-4.1-mini\": { key: \"gpt-4.1-mini\", contextLength: 1_047_576 },\n \"gpt-4.1-nano\": { key: \"gpt-4.1-nano\", contextLength: 1_047_576 },\n \"gpt-4o\": { key: \"gpt-4o\", contextLength: 128_000 },\n \"gpt-4o-mini\": { key: \"gpt-4o-mini\", contextLength: 128_000 },\n \"gpt-4-turbo\": { key: \"gpt-4-turbo\", contextLength: 128_000 },\n \"gpt-4\": { key: \"gpt-4\", contextLength: 8_192 },\n \"gpt-3.5-turbo\": { key: \"gpt-3.5-turbo\", contextLength: 16_385 },\n \"gpt-5\": { key: \"gpt-5\", contextLength: 400_000 },\n \"gpt-5.4\": { key: \"gpt-5.4\", contextLength: 400_000 },\n o1: { key: \"o1\", contextLength: 200_000 },\n \"o1-mini\": { key: \"o1-mini\", contextLength: 128_000 },\n \"o3-mini\": { key: \"o3-mini\", contextLength: 200_000 },\n\n // --- Anthropic (claude families; catalog: claude-sonnet-4-6, claude-sonnet-4) ---\n \"claude-sonnet-4-6\": { key: \"claude-sonnet-4-6\", contextLength: 200_000 },\n \"claude-sonnet-4\": { key: \"claude-sonnet-4\", contextLength: 200_000 },\n \"claude-opus-4\": { key: \"claude-opus-4\", contextLength: 200_000 },\n \"claude-haiku-4\": { key: \"claude-haiku-4\", contextLength: 200_000 },\n \"claude-3-5-sonnet\": { key: \"claude-3-5-sonnet\", contextLength: 200_000 },\n \"claude-3-5-haiku\": { key: \"claude-3-5-haiku\", contextLength: 200_000 },\n \"claude-3-opus\": { key: \"claude-3-opus\", contextLength: 200_000 },\n \"claude-3-sonnet\": { key: \"claude-3-sonnet\", contextLength: 200_000 },\n \"claude-3-haiku\": { key: \"claude-3-haiku\", contextLength: 200_000 },\n\n // --- Gemini (catalog: gemini-3.1-flash-lite, gemini-2.5-flash, auto-gemini-3) ---\n \"gemini-3.1-flash-lite\": {\n key: \"gemini-3.1-flash-lite\",\n contextLength: 1_048_576,\n },\n \"gemini-3.1-pro\": { key: \"gemini-3.1-pro\", contextLength: 1_048_576 },\n \"gemini-3-pro\": { key: \"gemini-3-pro\", contextLength: 2_097_152 },\n \"auto-gemini-3\": { key: \"auto-gemini-3\", contextLength: 1_048_576 },\n \"gemini-2.5-flash\": { key: \"gemini-2.5-flash\", contextLength: 1_048_576 },\n \"gemini-2.5-pro\": { key: \"gemini-2.5-pro\", contextLength: 2_097_152 },\n \"gemini-2.0-flash\": { key: \"gemini-2.0-flash\", contextLength: 1_048_576 },\n \"gemini-1.5-flash\": { key: \"gemini-1.5-flash\", contextLength: 1_048_576 },\n \"gemini-1.5-pro\": { key: \"gemini-1.5-pro\", contextLength: 2_097_152 },\n};\n\n/**\n * Reasoning-effort suffix tokens that some catalogs append to a model id after a `/`\n * (e.g. Codex-style `gpt-5.4/xhigh`). These are NOT provider namespaces \u2014 they must be\n * stripped as a trailing suffix BEFORE the leading `provider/` segment is dropped, or the\n * provider-prefix strip misreads `gpt-5.4/xhigh` as `provider=gpt-5.4, model=xhigh` (H9).\n */\nconst REASONING_EFFORT_SUFFIXES = new Set([\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n]);\n\n/**\n * Normalize a model id into a {@link MODEL_REFERENCE} lookup key:\n * 1. lowercase\n * 2. drop a trailing `/<reasoning-effort>` suffix (e.g. `gpt-5.4/xhigh` \u2192 `gpt-5.4`) \u2014\n * see {@link REASONING_EFFORT_SUFFIXES}; done BEFORE the provider-prefix strip so a\n * reasoning-effort suffix is never misread as the model half of `provider/model` (H9)\n * 3. drop a leading `provider/` segment (e.g. `openai/gpt-4.1` \u2192 `gpt-4.1`)\n * 4. drop a trailing `:free` / `:beta` modifier (e.g. `gpt-4.1:free` \u2192 `gpt-4.1`)\n *\n * Pure string transform \u2014 provider/transport-blind.\n */\nexport function normalizeModelKey(model: string): string {\n let key = model.trim().toLowerCase();\n\n // Drop a trailing reasoning-effort suffix FIRST (e.g. `gpt-5.4/xhigh` \u2192 `gpt-5.4`), so it\n // is never mistaken for a `provider/model` split below.\n const lastSlashIndex = key.lastIndexOf(\"/\");\n if (lastSlashIndex > 0 && lastSlashIndex < key.length - 1) {\n const tail = key.slice(lastSlashIndex + 1);\n if (REASONING_EFFORT_SUFFIXES.has(tail)) {\n key = key.slice(0, lastSlashIndex);\n }\n }\n\n // Drop provider prefix: only the FIRST `/`-delimited segment is treated as a provider.\n const slashIndex = key.indexOf(\"/\");\n if (slashIndex > 0) {\n key = key.slice(slashIndex + 1);\n }\n // Drop a trailing free/beta modifier.\n key = key.replace(/:(?:free|beta)$/i, \"\");\n return key.trim();\n}\n\n/**\n * Minimum reference-key length eligible for the substring fallback (match order step 3).\n * Keys shorter than this (e.g. `o1`) are excluded from substring matching to avoid matching\n * mid-token inside an unrelated id (`logo1`, `photo1`) \u2014 they can still resolve via exact or\n * prefix match.\n */\nconst MIN_SUBSTRING_MATCH_KEY_LENGTH = 4;\n\n/**\n * Look up a curated {@link ModelReferenceEntry} for a model id. Normalizes the id first\n * (see {@link normalizeModelKey}) then matches by, in order: EXACT key, longest PREFIX key,\n * longest SUBSTRING key. When several keys tie, the LONGEST key wins (R18 \u2014 avoids a short\n * key shadowing a more specific one). Returns `undefined` when nothing matches.\n */\nexport function lookupModelRef(model: string): ModelReferenceEntry | undefined {\n const normalized = normalizeModelKey(model);\n if (!normalized) {\n return undefined;\n }\n\n // 1. Exact match.\n const exact = MODEL_REFERENCE[normalized];\n if (exact) {\n return exact;\n }\n\n // 2. Prefix match \u2014 the normalized id starts with a reference key.\n let prefixWinner: ModelReferenceEntry | undefined;\n for (const [key, entry] of Object.entries(MODEL_REFERENCE)) {\n if (normalized.startsWith(key)) {\n if (!prefixWinner || key.length > prefixWinner.key.length) {\n prefixWinner = entry;\n }\n }\n }\n if (prefixWinner) {\n return prefixWinner;\n }\n\n // 3. Substring match \u2014 a reference key appears anywhere in the normalized id. A minimum\n // key length guards against short keys (e.g. \"o1\") matching mid-token inside an unrelated\n // id (e.g. \"logo1\", \"photo1\") \u2014 see MEDIUM finding \"model-reference substring false-positives\".\n let substringWinner: ModelReferenceEntry | undefined;\n for (const [key, entry] of Object.entries(MODEL_REFERENCE)) {\n if (key.length >= MIN_SUBSTRING_MATCH_KEY_LENGTH && normalized.includes(key)) {\n if (!substringWinner || key.length > substringWinner.key.length) {\n substringWinner = entry;\n }\n }\n }\n return substringWinner;\n}\n\nfunction isUsableContextLength(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Extract a context-window length from a raw provider model record. Probes a FIXED key order\n * (first usable value wins): `context_length` \u2192 `max_model_len` \u2192 `context_window` \u2192\n * `top_provider.context_length`. Zero, negative, NaN, and non-number values are ignored.\n * Returns `undefined` when no usable value is present.\n */\nexport function extractModelContextLength(raw: unknown): number | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined;\n }\n const record = raw as Record<string, unknown>;\n\n if (isUsableContextLength(record.context_length)) {\n return record.context_length;\n }\n if (isUsableContextLength(record.max_model_len)) {\n return record.max_model_len;\n }\n if (isUsableContextLength(record.context_window)) {\n return record.context_window;\n }\n const topProvider = record.top_provider;\n if (topProvider && typeof topProvider === \"object\") {\n const nested = (topProvider as Record<string, unknown>).context_length;\n if (isUsableContextLength(nested)) {\n return nested;\n }\n }\n return undefined;\n}\n\nfunction asPricingNumber(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n // Provider pricing tables frequently encode amounts as decimal strings.\n if (typeof value === \"string\" && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return undefined;\n}\n\n/**\n * Parse a {@link ModelPricing} block from a raw provider model record's `pricing` object.\n * Numbers and numeric strings are accepted; other shapes are dropped. Returns `undefined`\n * when no pricing components are present.\n */\nexport function parseModelPricing(raw: unknown): ModelPricing | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined;\n }\n const pricing = (raw as Record<string, unknown>).pricing;\n if (!pricing || typeof pricing !== \"object\") {\n return undefined;\n }\n const record = pricing as Record<string, unknown>;\n\n const prompt = asPricingNumber(record.prompt);\n const completion = asPricingNumber(record.completion);\n const request = asPricingNumber(record.request);\n const image = asPricingNumber(record.image);\n const currency =\n typeof record.currency === \"string\" ? record.currency : undefined;\n\n const result: ModelPricing = {\n ...(prompt !== undefined ? { prompt } : {}),\n ...(completion !== undefined ? { completion } : {}),\n ...(request !== undefined ? { request } : {}),\n ...(image !== undefined ? { image } : {}),\n ...(currency !== undefined ? { currency } : {}),\n };\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Determine whether a model is free. Two independent signals (INV \u2014 dual-free-detection):\n * 1. the model id carries a `:free` suffix, OR\n * 2. every DEFINED pricing component (prompt/completion/request/image) is exactly 0.\n *\n * A PARTIAL zero (some components 0, others positive) is NOT free. When no pricing is supplied\n * and there is no `:free` suffix, returns `false`.\n */\nexport function detectModelFree(\n modelId: string,\n pricing?: ModelPricing,\n raw?: unknown,\n): boolean {\n if (/:free$/i.test(modelId.trim())) {\n return true;\n }\n\n const effectivePricing = pricing ?? parseModelPricing(raw);\n if (!effectivePricing) {\n return false;\n }\n\n const components = [\n effectivePricing.prompt,\n effectivePricing.completion,\n effectivePricing.request,\n effectivePricing.image,\n ].filter((value): value is number => typeof value === \"number\");\n\n if (components.length === 0) {\n return false;\n }\n\n return components.every((value) => value === 0);\n}\n\n/**\n * Standalone context-window resolver (no client instance required \u2014 INV-REUSE-1). Precedence\n * is FIXED: discovered > reference > configured > default. Each candidate must be a usable\n * positive finite number to participate; otherwise the next source is consulted. When nothing\n * is usable, falls back to `defaultContextWindow` (default {@link DEFAULT_CONTEXT_WINDOW}).\n */\nexport function resolveModelContextWindow(input: {\n discovered?: number;\n reference?: number;\n configured?: number;\n defaultContextWindow?: number;\n}): { contextWindow: number; source: ModelContextResolution[\"source\"] } {\n if (isUsableContextLength(input.discovered)) {\n return { contextWindow: input.discovered, source: \"discovered\" };\n }\n if (isUsableContextLength(input.reference)) {\n return { contextWindow: input.reference, source: \"reference\" };\n }\n if (isUsableContextLength(input.configured)) {\n return { contextWindow: input.configured, source: \"configured\" };\n }\n const fallback = isUsableContextLength(input.defaultContextWindow)\n ? input.defaultContextWindow\n : DEFAULT_CONTEXT_WINDOW;\n return { contextWindow: fallback, source: \"default\" };\n}\n\n/**\n * GAP-A: surface a route's CONFIGURED context window into a discovery catalog's\n * `ModelInfo.contextLength` (TASK-028 / UR-002).\n *\n * Monotonic + configured-only: writes `contextLength` ONLY when the entry has no\n * usable value yet AND `route.contextWindow` is usable (>0). Live/discovered\n * values (e.g. from an OpenAI/Anthropic /models response) are therefore never\n * overwritten. Only the route's own model (`route.model`) is filled so a static\n * catalog with one entry per route stays correct. A `metadata.contextWindowSource:\n * \"configured\"` tag marks the provenance so external consumers that map\n * `contextLength` into {@link resolveModelContextWindow}'s `discovered` slot can\n * gate on it (a configured value must feed `configured`, not `discovered`, to keep\n * the discovered>reference>configured>default precedence honest).\n */\nexport function fillConfiguredContextLength(\n route: { model?: string; contextWindow?: number },\n models: AcpModelInfo[],\n): AcpModelInfo[] {\n if (!isUsableContextLength(route.contextWindow)) {\n return models;\n }\n const configured = route.contextWindow;\n return models.map((entry) => {\n if (isUsableContextLength(entry.contextLength)) {\n return entry;\n }\n if (route.model !== undefined && entry.modelId !== route.model) {\n return entry;\n }\n return {\n ...entry,\n contextLength: configured,\n // FT-002: typed provenance (canonical) + metadata alias (back-compat).\n contextWindowSource: \"configured\",\n metadata: { ...(entry.metadata ?? {}), contextWindowSource: \"configured\" },\n };\n });\n}\n\n/**\n * Compute the cache key + model id for a {@link ResolveModelContextInput}. Cache scope is\n * per-(baseUrl|transportId)::model so two routes pointing at different gateways do not share a\n * cached window.\n */\nexport function modelContextCacheKey(input: ResolveModelContextInput): {\n key: string;\n model: string;\n} {\n if (typeof input === \"string\") {\n return { key: `::${input}`, model: input };\n }\n const scope = input.baseUrl ?? input.transportId ?? \"\";\n return { key: `${scope}::${input.model}`, model: input.model };\n}\n", "// C8 \u2014 health/probe pure primitives (UR-008 / UR-015 / CD-7 / CD-9).\n//\n// CLIENT-FREE by construction: this module has TYPE-ONLY imports, ZERO Node builtins, no import\n// from the client / transport modules, and no provider-vendor symbol. It is\n// a browser-safe, reusable primitive (INV-REUSE-1) \u2014 there is NO module-level mutable state: the\n// probe cache map is OWNED by the caller (the client) and passed in, and `now` is always a param\n// (fake-clock friendly, D6/INV-DET-1). Per CD-4 there is NO probe-local `withTimeout`; the per-\n// probe timeout is scheduled by the client via the `deriveAbort` / `runtime.setTimer` seam.\n\nimport type { AiConnectError } from \"./errors.js\";\nimport type { AiConnectErrorCode, ProbeModelResult } from \"./types.js\";\n\n/** Default per-probe timeout (ms). The probe ping aborts independently after this elapses. */\nexport const PROBE_DEFAULT_TIMEOUT_MS = 8000;\n/** Default TTL (ms) for the per-(route::sorted-models) probe cache. */\nexport const PROBE_DEFAULT_TTL_MS = 300000;\n/** Default bounded fan-out concurrency for `probeModels`. */\nexport const PROBE_DEFAULT_CONCURRENCY = 4;\n\n/**\n * Outcome of classifying a single probe ping. `ok` is true ONLY when the ping produced usable\n * output (non-empty `text` OR at least one `toolCall`). `broken` flags a route-side fault that a\n * retry will NOT fix: `400 \u2264 httpStatus < 500 \u2227 httpStatus \u2260 429` (INV-PROBE-1). Everything else\n * (429 / 5xx / status-less transport errors) is transient (`broken:false`).\n */\nexport interface ProbeOutcomeClassification {\n ok: boolean;\n broken: boolean;\n detail: string;\n code?: AiConnectErrorCode | \"not_supported\";\n httpStatus?: number;\n}\n\n/** Internal cache entry \u2014 exported as a type only so the client can own a typed `Map`. */\nexport interface ProbeCacheEntry {\n expiresAt: number;\n results: ProbeModelResult[];\n}\n\n/** The probe cache shape. The client owns one of these per-client; this module never mutates a global. */\nexport type ProbeCache = Map<string, ProbeCacheEntry>;\n\n/**\n * Extract the raw HTTP status carried on an {@link AiConnectError} via `details.httpStatus`\n * (CD-7 \u2014 attached by `classifyApiError` for every api error). Returns `undefined` for non-HTTP\n * transports (acp/cli/server) or when the carrier is absent.\n */\nfunction extractHttpStatus(error: AiConnectError | undefined): number | undefined {\n const raw = error?.details?.[\"httpStatus\"];\n return typeof raw === \"number\" && Number.isFinite(raw) ? raw : undefined;\n}\n\n/**\n * Classify a probe ping into {ok, broken, detail, code?, httpStatus?} (INV-PROBE-1).\n *\n * - On error: `ok=false`; `broken` is true exactly when `400 \u2264 httpStatus < 500 \u2227 httpStatus \u2260 429`\n * (the route-side, retry-won't-fix band). 429 / 5xx / status-less are transient (`broken=false`).\n * - On success: `ok=true` ONLY when `text` is non-empty OR `toolCalls` is present; an empty/blank\n * response is treated as a model-side failure (`ok=false`, `broken=false`).\n *\n * Pure and provider-blind \u2014 keys off `httpStatus` + output presence only, never a provider symbol.\n */\nexport function classifyProbeOutcome(input: {\n error?: AiConnectError;\n text?: string;\n toolCalls?: unknown[];\n}): ProbeOutcomeClassification {\n if (input.error) {\n const httpStatus = extractHttpStatus(input.error);\n const broken =\n httpStatus !== undefined &&\n httpStatus >= 400 &&\n httpStatus < 500 &&\n httpStatus !== 429;\n return {\n ok: false,\n broken,\n detail: input.error.message,\n code: input.error.code,\n ...(httpStatus !== undefined ? { httpStatus } : {}),\n };\n }\n\n const hasText = typeof input.text === \"string\" && input.text.trim().length > 0;\n const hasToolCalls = Array.isArray(input.toolCalls) && input.toolCalls.length > 0;\n if (hasText || hasToolCalls) {\n return { ok: true, broken: false, detail: \"ok\" };\n }\n\n return {\n ok: false,\n broken: false,\n detail: \"model returned an empty response\",\n };\n}\n\n/**\n * Stable, order-independent cache key for a route::model-set probe. Models are sorted+deduped so\n * `['a','b']` and `['b','a']` collide (scenario #47). The `routeId` is the namespace; the joined\n * sorted model list is the discriminant.\n */\nexport function probeCacheKey(routeId: string, models: readonly string[]): string {\n const sorted = [...new Set(models)].sort();\n return `${routeId}::${sorted.join(\",\")}`;\n}\n\n/**\n * Read a non-expired cache entry. A hit requires `now < entry.expiresAt` (so `now = expiresAt - 1`\n * hits and `now = expiresAt` / `+1` misses \u2014 scenario #47). Returns `undefined` on miss/absence.\n * Pure read; never mutates the cache or reads wall-clock (`now` is injected).\n */\nexport function readProbeCache(\n cache: ProbeCache,\n key: string,\n now: number,\n): ProbeModelResult[] | undefined {\n const entry = cache.get(key);\n if (!entry || now >= entry.expiresAt) {\n return undefined;\n }\n // Return shallow copies flagged `cached:true` so callers never mutate the stored results.\n return entry.results.map((result) => ({ ...result, cached: true }));\n}\n\n/**\n * Write a cache entry expiring at `now + ttlMs`. Stored results are normalized to `cached:false`\n * (the stored copy represents a freshly-probed result; `readProbeCache` re-flags hits). Mutates\n * only the caller-owned `cache` \u2014 no module-level state.\n */\nexport function writeProbeCache(\n cache: ProbeCache,\n key: string,\n results: ProbeModelResult[],\n now: number,\n ttlMs: number,\n): void {\n cache.set(key, {\n expiresAt: now + ttlMs,\n results: results.map((result) => ({ ...result, cached: false })),\n });\n}\n\n/**\n * Bounded-concurrency runner (INV: max in-flight \u2264 `limit` at all times). Runs `fn` over every\n * item with at most `limit` concurrent in-flight, preserving input order in the resolved array.\n * `fn` receives the item index so callers can correlate results. Rejections propagate (the first\n * rejection rejects the whole run) \u2014 probe callers therefore make `fn` total (it never rejects).\n *\n * Pure scheduling primitive: no timers, no clock, no provider/transport symbol (UR-015).\n */\nexport async function runBounded<T, R>(\n items: readonly T[],\n limit: number,\n fn: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const total = items.length;\n const results = new Array<R>(total);\n if (total === 0) {\n return results;\n }\n const effectiveLimit = Math.max(1, Math.min(limit, total));\n let cursor = 0;\n\n async function worker(): Promise<void> {\n while (true) {\n const index = cursor;\n cursor += 1;\n if (index >= total) {\n return;\n }\n results[index] = await fn(items[index]!, index);\n }\n }\n\n const workers: Promise<void>[] = [];\n for (let i = 0; i < effectiveLimit; i += 1) {\n workers.push(worker());\n }\n await Promise.all(workers);\n return results;\n}\n", "import type {\n RuntimeEnvironment,\n RuntimeKind,\n} from \"./types.js\";\n\nexport function inferRuntimeKind(): RuntimeKind {\n if (\n typeof window !== \"undefined\" &&\n typeof document !== \"undefined\"\n ) {\n return \"browser\";\n }\n\n return \"local\";\n}\n\nexport function createRuntimeEnvironment(\n kind: RuntimeKind,\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return {\n kind,\n now: overrides.now ?? (() => Date.now()),\n ...(overrides.getEnv ? { getEnv: overrides.getEnv } : {}),\n ...(overrides.hasCommand ? { hasCommand: overrides.hasCommand } : {}),\n // Forward the optional timer seam (F-P-3) so a seeded fake-clock `setTimer`\n // injected via factory overrides actually reaches `deriveAbort`. When omitted,\n // `deriveAbort` falls back to real `setTimeout`+`unref`.\n ...(overrides.setTimer ? { setTimer: overrides.setTimer } : {}),\n };\n}\n\nexport function createBrowserRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createRuntimeEnvironment(\"browser\", overrides);\n}\n\nexport function createLocalRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createRuntimeEnvironment(\"local\", overrides);\n}\n", "import {\n defineConfig,\n isNormalizedConfig,\n mergeFanoutPolicy,\n normalizeFanoutPolicy,\n resolveRouteSelectors,\n toPublicCapabilities,\n} from \"./config.js\";\nimport { AiConnectError, mapAbortError, toAiConnectError } from \"./errors.js\";\nimport { createFanoutLimiter } from \"./fanout.js\";\nimport {\n isPortableDocumentFile,\n isPortableImageFile,\n preparePortableFile,\n} from \"./files.js\";\nimport { redactBaseUrl, shouldEmitWideEvent } from \"./logging.js\";\nimport { RouteRegistry, canFallbackBetween } from \"./router.js\";\nimport {\n lookupModelRef,\n modelContextCacheKey,\n resolveModelContextWindow,\n} from \"./model-reference.js\";\nimport {\n PROBE_DEFAULT_CONCURRENCY,\n PROBE_DEFAULT_TIMEOUT_MS,\n PROBE_DEFAULT_TTL_MS,\n classifyProbeOutcome,\n probeCacheKey,\n readProbeCache,\n runBounded,\n writeProbeCache,\n} from \"./probe.js\";\nimport type { ProbeCache } from \"./probe.js\";\nimport { createRuntimeEnvironment, inferRuntimeKind } from \"./runtime.js\";\nimport type {\n AbortContext,\n AbortReason,\n AcpModelDiscoveryReport,\n AcpModelDiscoveryRouteReport,\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CandidateModel,\n CheckHealthTarget,\n ClientToolDefinition,\n ClientToolExecutionResult,\n ClientOperationName,\n CreateClientOptions,\n DiscoverModelsTarget,\n DiscoverAcpModelsTarget,\n FanoutLimiter,\n FanoutPolicy,\n GenerateCallOptions,\n GenerateParameters,\n GenerateRequest,\n GenerateResult,\n GenerateStreamEvent,\n GenerateToolDefinition,\n ModelSelector,\n HealthModelStageResult,\n HealthReport,\n HealthStageResult,\n OperationKind,\n OperationTimeoutDefaults,\n ListedRoute,\n MessageInput,\n ModelContextResolution,\n ProbeModelResult,\n ProbeModelsOptions,\n ProbeModelsTarget,\n PublicRoute,\n RouteHealthReport,\n ResolveModelContextInput,\n ResolveModelContextOptions,\n NormalizedGenerateRequest,\n NormalizedRoute,\n PortableFile,\n RouteAttempt,\n RouteHandler,\n RouteHandlerGenerateResult,\n RouteHealthState,\n ToolCallInput,\n VerificationIssue,\n VerificationReport,\n VerificationRouteReport,\n TransportKind,\n WideEventAcpModelDiscoverySummary,\n WideEvent,\n WideEventAttempt,\n WideEventHealthRouteSummary,\n WideEventHealthSummary,\n WideEventParameterSummary,\n WideEventProbeRouteSummary,\n WideEventProbeSummary,\n WideEventRequestSummary,\n WideEventResultSummary,\n WideEventRouteSummary,\n WideEventTransportSummary,\n WideEventVerificationSummary,\n} from \"./types.js\";\n\nconst DEFAULT_LOGGING_SERVICE = \"ai-connect\";\n\nfunction splitCredentialValues(value: string, delimiter: string): string[] {\n return value\n .split(delimiter)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\n/**\n * D5 / SYS-6: a distinct marker wrapping a failure that originates in the CALLER's\n * own client-tool orchestration \u2014 a `tool.execute()` throw, a missing handler, or\n * exceeding the tool-call loop depth. It is deliberately NOT an {@link AiConnectError}\n * so the fallback loop can intercept it BEFORE provider-health classification and\n * therefore never `recordFailure` / rotate / cool down a perfectly healthy route on\n * a client-side bug. It carries the terminal {@link AiConnectError} to surface.\n */\nclass ClientToolExecutionError extends Error {\n readonly aiError: AiConnectError;\n\n constructor(aiError: AiConnectError) {\n super(aiError.message);\n this.name = \"ClientToolExecutionError\";\n this.aiError = aiError;\n }\n}\n\nfunction materializeRuntimeConfig(config: AiConnectConfig, runtime: NonNullable<CreateClientOptions[\"runtime\"]>): AiConnectConfig {\n const routeExpansion = new Map<string, string[]>();\n const routes: NormalizedRoute[] = [];\n\n for (const route of config.routes) {\n const delimiter = route.credential.apiKeyDelimiter;\n const envName = route.credential.apiKeyEnv;\n const envValue = delimiter && envName ? runtime.getEnv?.(envName)?.trim() : undefined;\n const values = delimiter && envValue ? splitCredentialValues(envValue, delimiter) : undefined;\n\n if (!values || values.length <= 1) {\n routeExpansion.set(route.id, [route.id]);\n routes.push(route);\n continue;\n }\n\n const expandedIds: string[] = [];\n // C1a LOW: redistribute the route's configured weight across the expanded\n // credential routes instead of hard-coding 1 \u2014 a route weighted N-way should\n // keep its relative share, split evenly among its credentials. The router\n // consumes weight as an integer repeat-count, so floor + a floor-of-1 keeps\n // every expanded route selectable.\n const expandedWeight = Math.max(1, Math.floor(route.weight / values.length));\n values.forEach((apiKey, index) => {\n const credentialId = `${route.credentialId}#${index + 1}`;\n const expandedRoute: NormalizedRoute = {\n ...route,\n id: `${route.id}#${index + 1}`,\n credentialId,\n weight: expandedWeight,\n credential: {\n ...route.credential,\n id: credentialId,\n apiKey,\n ...(route.credential.apiKeyEnv ? { apiKeyEnv: route.credential.apiKeyEnv } : {}),\n },\n };\n expandedIds.push(expandedRoute.id);\n routes.push(expandedRoute);\n });\n routeExpansion.set(route.id, expandedIds);\n }\n\n return {\n ...config,\n routes,\n routing: {\n ...config.routing,\n operations: {\n text: {\n ...config.routing.operations.text,\n pool: config.routing.operations.text.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n image: {\n ...config.routing.operations.image,\n pool: config.routing.operations.image.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n file: {\n ...config.routing.operations.file,\n pool: config.routing.operations.file.pool.flatMap((routeId) => routeExpansion.get(routeId) ?? [routeId]),\n },\n },\n },\n };\n}\n\nasync function sleep(delayMs: number): Promise<void> {\n if (delayMs <= 0) {\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n}\n\n/**\n * SYS-1 / H3 / H6: race an already-issued handler promise against a derived-abort.\n * If `abort.signal` fires (caller cancel OR an elapsed operation deadline) before\n * the handler settles, this rejects with the canonical abort/timeout error EVEN IF\n * the handler never resolves \u2014 so a non-cooperative handler on ANY transport (a\n * shared-conn ACP that ignores session/cancel, a hung server POST /session, \u2026)\n * can no longer hang `generate({timeoutMs})` forever. The handler already holds\n * `abort` and may cancel its own I/O; this race only guarantees liveness on top of\n * that. A late handler settlement is swallowed so it never surfaces as an unhandled\n * rejection after the race has already resolved. Generalized from the ping path.\n */\nasync function runWithAbortRace<T>(\n handlerPromise: Promise<T>,\n abort: AbortContext,\n): Promise<T> {\n if (abort.signal.aborted) {\n // Swallow the in-flight handler's late settlement, then surface the abort.\n void Promise.resolve(handlerPromise).catch(() => {});\n throw mapAbortError(abort.reason);\n }\n let onAbort: (() => void) | undefined;\n const abortPromise = new Promise<never>((_, reject) => {\n onAbort = () => reject(mapAbortError(abort.reason));\n abort.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n return await Promise.race([handlerPromise, abortPromise]);\n } finally {\n if (onAbort) {\n abort.signal.removeEventListener(\"abort\", onAbort);\n }\n void Promise.resolve(handlerPromise).catch(() => {});\n }\n}\n\nfunction normalizeWorkingDirectory(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n throw new AiConnectError(\n \"validation_error\",\n \"Generate request workingDirectory must be a non-empty string when provided.\",\n );\n }\n\n return trimmed;\n}\n\nfunction normalizeClientToolDefinition(\n input: ClientToolDefinition,\n): ClientToolDefinition {\n const name = input.function.name.trim();\n if (!name) {\n throw new AiConnectError(\n \"validation_error\",\n \"Client tool function.name must be a non-empty string.\",\n );\n }\n\n if (typeof input.execute !== \"function\") {\n throw new AiConnectError(\n \"validation_error\",\n `Client tool \"${name}\" must provide an execute handler.`,\n );\n }\n\n return {\n ...input,\n function: {\n ...input.function,\n name,\n ...(input.function.description !== undefined\n ? { description: input.function.description }\n : {}),\n ...(input.function.parameters !== undefined\n ? { parameters: input.function.parameters }\n : {}),\n },\n };\n}\n\nfunction normalizeClientToolRegistry(\n tools: ClientToolDefinition[] | undefined,\n): Map<string, ClientToolDefinition> {\n const registry = new Map<string, ClientToolDefinition>();\n\n for (const tool of tools ?? []) {\n const normalized = normalizeClientToolDefinition(tool);\n // LOW: a duplicate function.name would silently clobber the earlier tool \u2014\n // a registration ambiguity the caller almost certainly did not intend. Reject\n // it up front rather than picking last-writer-wins.\n if (registry.has(normalized.function.name)) {\n throw new AiConnectError(\n \"validation_error\",\n `Duplicate client tool name \"${normalized.function.name}\" registered on this client.`,\n );\n }\n registry.set(normalized.function.name, normalized);\n }\n\n return registry;\n}\n\nfunction resolveClientToolSelections(\n selections: GenerateRequest[\"clientTools\"] | undefined,\n registry: Map<string, ClientToolDefinition>,\n): ClientToolDefinition[] {\n if (!selections || selections.length === 0) {\n return [];\n }\n\n const resolved = new Map<string, ClientToolDefinition>();\n\n for (const selection of selections) {\n if (typeof selection === \"string\") {\n const name = selection.trim();\n if (!name) {\n throw new AiConnectError(\n \"validation_error\",\n \"Client tool references must be non-empty strings.\",\n );\n }\n\n const registered = registry.get(name);\n if (!registered) {\n throw new AiConnectError(\n \"validation_error\",\n `No client tool named \"${name}\" is registered on this client.`,\n );\n }\n\n if (resolved.has(name)) {\n throw new AiConnectError(\n \"validation_error\",\n `Duplicate client tool \"${name}\" in the clientTools selection.`,\n );\n }\n resolved.set(name, registered);\n continue;\n }\n\n const normalized = normalizeClientToolDefinition(selection);\n // LOW: a name collision (between two inline defs, or an inline def and an\n // earlier reference) is a caller mistake \u2014 surface it instead of silently\n // dropping the shadowed definition.\n if (resolved.has(normalized.function.name)) {\n throw new AiConnectError(\n \"validation_error\",\n `Duplicate client tool \"${normalized.function.name}\" in the clientTools selection.`,\n );\n }\n resolved.set(normalized.function.name, normalized);\n }\n\n return Array.from(resolved.values());\n}\n\nfunction mergeToolDefinitions(\n existing: GenerateParameters[\"tools\"] | undefined,\n clientTools: ClientToolDefinition[],\n): GenerateToolDefinition[] | undefined {\n if (!existing?.length && clientTools.length === 0) {\n return existing;\n }\n\n const merged = new Map<string, GenerateToolDefinition>();\n for (const tool of existing ?? []) {\n merged.set(tool.function.name, tool);\n }\n for (const tool of clientTools) {\n merged.set(tool.function.name, {\n type: \"function\",\n function: {\n ...tool.function,\n },\n });\n }\n\n return Array.from(merged.values());\n}\n\nfunction requiresClientToolExecution(\n request: NormalizedGenerateRequest,\n): boolean {\n return Boolean(request.clientTools?.length);\n}\n\nfunction normalizeToolResult(\n result: ClientToolExecutionResult,\n): Pick<MessageInput, \"content\" | \"data\" | \"isError\"> {\n if (typeof result === \"string\") {\n return {\n content: result,\n };\n }\n\n const content =\n result.content !== undefined\n ? result.content\n : result.data !== undefined\n ? JSON.stringify(result.data)\n : \"\";\n\n return {\n content,\n ...(result.data !== undefined ? { data: result.data } : {}),\n ...(result.isError !== undefined ? { isError: result.isError } : {}),\n };\n}\n\nfunction sumOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number | undefined {\n if (left === undefined) {\n return right;\n }\n if (right === undefined) {\n return left;\n }\n\n return left + right;\n}\n\nfunction mergeUsage(\n current: GenerateResult[\"usage\"] | undefined,\n next: GenerateResult[\"usage\"] | undefined,\n): GenerateResult[\"usage\"] | undefined {\n if (!current) {\n return next;\n }\n if (!next) {\n return current;\n }\n\n const inputTokens = sumOptionalNumbers(current.inputTokens, next.inputTokens);\n const outputTokens = sumOptionalNumbers(current.outputTokens, next.outputTokens);\n const reasoningTokens = sumOptionalNumbers(\n current.reasoningTokens,\n next.reasoningTokens,\n );\n const totalTokens = sumOptionalNumbers(current.totalTokens, next.totalTokens);\n const cachedReadTokens = sumOptionalNumbers(\n current.cachedReadTokens,\n next.cachedReadTokens,\n );\n const contextWindowUsed =\n next.contextWindowUsed ?? current.contextWindowUsed;\n const contextWindowSize =\n next.contextWindowSize ?? current.contextWindowSize;\n const durationMs = sumOptionalNumbers(current.durationMs, next.durationMs);\n const calls = sumOptionalNumbers(current.calls, next.calls);\n const costAmount = sumOptionalNumbers(current.cost?.amount, next.cost?.amount);\n const costCurrency = next.cost?.currency ?? current.cost?.currency;\n const modelUsage = next.modelUsage ?? current.modelUsage;\n\n const merged = {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n ...(contextWindowUsed !== undefined ? { contextWindowUsed } : {}),\n ...(contextWindowSize !== undefined ? { contextWindowSize } : {}),\n ...(durationMs !== undefined ? { durationMs } : {}),\n ...(calls !== undefined ? { calls } : {}),\n ...(current.cost || next.cost\n ? {\n cost: {\n amount: costAmount ?? 0,\n ...(costCurrency !== undefined ? { currency: costCurrency } : {}),\n },\n }\n : {}),\n ...(modelUsage !== undefined ? { modelUsage } : {}),\n };\n\n return merged;\n}\n\nfunction requiresToolSchema(\n request: NormalizedGenerateRequest,\n): boolean {\n return Boolean(\n request.parameters?.tools?.length ||\n request.parameters?.toolChoice !== undefined ||\n request.parameters?.parallelToolCalls !== undefined,\n );\n}\n\n/**\n * True when any attachment (or the image-operation source/reference inputs) is an\n * image \u2014 the request can only be served by a route advertising\n * `supportsImageInput`. (C6 \u2014 UR-012.)\n */\nfunction requiresImageInput(\n request: NormalizedGenerateRequest,\n): boolean {\n if (request.attachments.some((file) => isPortableImageFile(file))) {\n return true;\n }\n const image = request.image;\n if (!image) {\n return false;\n }\n return Boolean(\n image.sourceImage ||\n image.mask ||\n (image.referenceImages && image.referenceImages.length > 0),\n );\n}\n\n/**\n * True when any attachment is a supported document (PDF) \u2014 the request can only\n * be served by a route advertising `supportsFileUpload`. (C6 \u2014 UR-003.)\n */\nfunction requiresFileUpload(\n request: NormalizedGenerateRequest,\n): boolean {\n return request.attachments.some((file) => isPortableDocumentFile(file));\n}\n\ninterface RequiredCapabilityResolution {\n requiresSchema: boolean;\n requiresClientTools: boolean;\n requiresImage: boolean;\n requiresFile: boolean;\n requiresAnyCapability: boolean;\n /**\n * The request re-projected with `routeHints.requiredCapabilities` populated from\n * the detected requirements \u2014 feed THIS into `router.resolveCandidates` so a\n * multimodal / tool request only routes to a route advertising the capability\n * (an empty candidate set then maps to a clean capability error, no spawn/fetch).\n */\n request: NormalizedGenerateRequest;\n}\n\n/**\n * H1 / C6: single source of truth for capability gating shared by generate() AND\n * stream(). Previously stream() only gated `supportsToolSchema`, so an image/PDF\n * attachment could be dispatched to a route that never advertised the capability;\n * routing both paths through this helper makes stream() enforce image/file gating\n * exactly like generate().\n */\nfunction resolveRequiredCapabilities(\n request: NormalizedGenerateRequest,\n): RequiredCapabilityResolution {\n const requiresSchema = requiresToolSchema(request);\n const requiresClientTools = requiresClientToolExecution(request);\n const requiresImage = requiresImageInput(request);\n const requiresFile = requiresFileUpload(request);\n const requiresAnyCapability =\n requiresSchema || requiresClientTools || requiresImage || requiresFile;\n\n const projected: NormalizedGenerateRequest = requiresAnyCapability\n ? {\n ...request,\n routeHints: {\n ...(request.routeHints ?? {}),\n requiredCapabilities: {\n ...(request.routeHints?.requiredCapabilities ?? {}),\n ...(requiresSchema ? { supportsToolSchema: true } : {}),\n ...(requiresClientTools\n ? { supportsClientToolExecution: true }\n : {}),\n ...(requiresImage ? { supportsImageInput: true } : {}),\n ...(requiresFile ? { supportsFileUpload: true } : {}),\n },\n },\n }\n : request;\n\n return {\n requiresSchema,\n requiresClientTools,\n requiresImage,\n requiresFile,\n requiresAnyCapability,\n request: projected,\n };\n}\n\nfunction normalizeRequestBase(request: GenerateRequest): NormalizedGenerateRequest {\n if (request.messages.length === 0) {\n throw new AiConnectError(\"validation_error\", \"Unified generate/stream requests must include at least one message.\");\n }\n\n const workingDirectory = normalizeWorkingDirectory(request.workingDirectory);\n const rest = {\n messages: request.messages,\n ...(request.parameters ? { parameters: request.parameters } : {}),\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n ...(request.logContext ? { logContext: request.logContext } : {}),\n ...(workingDirectory !== undefined ? { workingDirectory } : {}),\n };\n const normalizedImage: NormalizedGenerateRequest[\"image\"] = request.image\n ? {\n ...(request.image.size !== undefined ? { size: request.image.size } : {}),\n ...(request.image.rawPrompt !== undefined ? { rawPrompt: request.image.rawPrompt } : {}),\n ...(request.image.aspectRatio ? { aspectRatio: request.image.aspectRatio } : {}),\n ...(request.image.quality ? { quality: request.image.quality } : {}),\n ...(request.image.imageSize ? { imageSize: request.image.imageSize } : {}),\n ...(request.image.style ? { style: request.image.style } : {}),\n ...(request.image.sourceImage ? { sourceImage: preparePortableFile(request.image.sourceImage) } : {}),\n ...(request.image.mask ? { mask: preparePortableFile(request.image.mask) } : {}),\n ...(request.image.referenceImages\n ? {\n referenceImages: request.image.referenceImages.map((input) => preparePortableFile(input)),\n }\n : {}),\n }\n : undefined;\n\n return {\n ...rest,\n operation: request.operation ?? \"text\",\n attachments: [...(request.attachments ?? []), ...(normalizedImage?.referenceImages ?? [])].map((input) => preparePortableFile(input)),\n ...(normalizedImage ? { image: normalizedImage } : {}),\n };\n}\n\nfunction resolveHandler(route: NormalizedRoute, handlers: Record<string, RouteHandler>): RouteHandler | undefined {\n return handlers[route.handlerKey] ?? handlers[`${route.provider}:${route.transport.kind}`] ?? handlers[`*:${route.transport.kind}`];\n}\n\n/**\n * Inject the selected route's explicit per-route config (C7 / R14) onto a request just before it\n * reaches the handler:\n *\n * - `route.defaultResponseFormat` \u2192 `parameters.responseFormat`, ONLY when the caller supplied\n * none (caller override always wins).\n * - `route.systemPrompt` \u2192 a leading `{role:\"system\"}` message, ONLY when the caller authored no\n * system message.\n *\n * Always derived from the ORIGINAL normalized request, so it is idempotent across retry/fallback\n * (a second route's defaults never stack on a first route's injection). This is explicit\n * consumer-config-authored content, NOT ai-connect ambient \u2014 so it is applied in BOTH `workspace`\n * and `clean` context modes (OQ-15 / INV-CLEAN-1: clean suppresses ambient, not explicit config).\n */\nfunction applyRouteDefaults(\n route: NormalizedRoute,\n request: NormalizedGenerateRequest,\n): NormalizedGenerateRequest {\n const callerHasSystemMessage = request.messages.some(\n (message) => message.role === \"system\",\n );\n const injectSystemPrompt =\n route.systemPrompt !== undefined && !callerHasSystemMessage;\n\n const callerHasResponseFormat =\n request.parameters?.responseFormat !== undefined;\n const injectResponseFormat =\n route.defaultResponseFormat !== undefined && !callerHasResponseFormat;\n\n if (!injectSystemPrompt && !injectResponseFormat) {\n return request;\n }\n\n const messages: MessageInput[] = injectSystemPrompt\n ? [{ role: \"system\", content: route.systemPrompt! }, ...request.messages]\n : request.messages;\n\n const parameters: GenerateParameters | undefined = injectResponseFormat\n ? {\n ...(request.parameters ?? {}),\n responseFormat: route.defaultResponseFormat!,\n }\n : request.parameters;\n\n return {\n ...request,\n messages,\n ...(parameters !== undefined ? { parameters } : {}),\n };\n}\n\n/**\n * Secret-free projection of a normalized route (C7 / INV-PROJ-1). Built by EXPLICIT construction \u2014\n * the {@link NormalizedRoute} is NEVER spread, so credential/baseUrl/apiKeyEnv/accountId/\n * handlerKey/credentialId can never leak into a public surface. Each capability flag is copied\n * field-by-field from the safe {@link PublicRouteCapabilities} `Pick`.\n */\nfunction toPublicRoute(\n route: NormalizedRoute,\n health: RouteHealthState,\n): PublicRoute {\n // INV-PROJ-1: the shared secret-free projector (also used by the router's\n // candidateModels) \u2014 never spread the full RouteCapabilities (#12).\n const capabilities = toPublicCapabilities(route.capabilities);\n\n return {\n id: route.id,\n label: route.label ?? route.id,\n provider: route.provider,\n transportKind: route.transport.kind,\n models: [...route.advertisedModels],\n defaultModel: route.model,\n ...(route.contextWindow !== undefined\n ? { contextWindow: route.contextWindow }\n : {}),\n modelAllowlistMode: route.modelAllowlistMode,\n ...(route.defaultResponseFormat !== undefined\n ? { defaultResponseFormat: route.defaultResponseFormat }\n : {}),\n ...(route.systemPrompt !== undefined\n ? { systemPrompt: route.systemPrompt }\n : {}),\n capabilities,\n health,\n };\n}\n\n/**\n * Build the minimal chat ping for Stage-2 health-checks and model probes (C8). A single user\n * message + `maxTokens: 1` keeps the billable cost as low as possible; the goal is liveness, not\n * content. The request is already normalized (no attachments, no client tools, no image).\n */\nfunction buildPingRequest(): NormalizedGenerateRequest {\n return {\n operation: \"text\",\n messages: [{ role: \"user\", content: \"ping\" }],\n attachments: [],\n parameters: { maxTokens: 1 },\n };\n}\n\nfunction normalizeResult(route: NormalizedRoute, output: Awaited<ReturnType<NonNullable<RouteHandler[\"generate\"]>>>, attempts: RouteAttempt[]): GenerateResult {\n return {\n route,\n attachments: (output.attachments ?? []).map((item) => preparePortableFile(item)),\n warnings: output.warnings ?? [],\n attempts,\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.reasoning !== undefined ? { reasoning: output.reasoning } : {}),\n ...(output.data !== undefined ? { data: output.data } : {}),\n ...(output.usage !== undefined ? { usage: output.usage } : {}),\n };\n}\n\nfunction runtimeIssue(route: NormalizedRoute): VerificationIssue | undefined {\n if (route.transport.kind === \"acp\") {\n return {\n code: \"runtime_mismatch\",\n message: \"ACP routes are local-only and cannot run in a browser runtime.\",\n };\n }\n\n return route.runtime === \"local\"\n ? {\n code: \"runtime_mismatch\",\n message: \"This route is marked local-only and cannot run in a browser runtime.\",\n }\n : undefined;\n}\n\nfunction nowMs(runtime: NonNullable<CreateClientOptions[\"runtime\"]>): number {\n return runtime.now?.() ?? Date.now();\n}\n\n/** Per-operation timeout tier (CD-6). */\ntype OperationTimeoutTier = \"generateMs\" | \"probeMs\";\n\nconst OPERATION_TIMEOUT_DEFAULTS: Record<OperationTimeoutTier, number> = {\n generateMs: 120_000,\n probeMs: 12_000,\n};\n\n/**\n * Resolve the effective per-operation timeout (CD-6). Precedence: explicit caller\n * `opts.timeoutMs` \u2192 client tier default \u2192 built-in tier default. A value `<= 0` or\n * non-finite (`Infinity`) DISABLES the timer (returns `undefined`). This is policy data\n * only; it is provider/transport-blind.\n */\nfunction resolveOpTimeout(\n opts: Pick<GenerateCallOptions, \"timeoutMs\"> | undefined,\n tier: OperationTimeoutTier,\n timeouts: OperationTimeoutDefaults | undefined,\n): number | undefined {\n const explicit = opts?.timeoutMs;\n const candidate =\n explicit !== undefined\n ? explicit\n : timeouts?.[tier] ?? OPERATION_TIMEOUT_DEFAULTS[tier];\n\n if (candidate === undefined || !Number.isFinite(candidate) || candidate <= 0) {\n return undefined;\n }\n\n return candidate;\n}\n\n/**\n * The SINGLE abort/timeout merge point (CD-4). Merges the caller `signal` \u2295 an op timeout\n * into ONE derived `AbortController`; the `reason` is first-writer-wins ('caller' vs\n * 'timeout') so the thrown code is deterministic (INV-ABORT-2). The timeout is scheduled\n * via `runtime.setTimer?` (default real `setTimeout`+`unref`) so a seeded DST fake-clock\n * controls it (F-P-3). `pauseSignal` is passed THROUGH untouched. `dispose()` clears the\n * timer and removes listeners \u2014 callers MUST invoke it in a `finally`.\n *\n * Provider-blind by construction: this function references no provider/transport symbol\n * (UR-015 INV-REUSE).\n */\nfunction deriveAbort(\n opts: Pick<GenerateCallOptions, \"signal\" | \"pauseSignal\" | \"timeoutMs\"> | undefined,\n timeoutMs: number | undefined,\n runtime: NonNullable<CreateClientOptions[\"runtime\"]>,\n config: { pauseAsAbort?: boolean } = {},\n): { abort: AbortContext; dispose: () => void } {\n const controller = new AbortController();\n const callerSignal = opts?.signal;\n // `pauseAsAbort` is set by generate(): a non-streamed call cannot retain a partial, so a\n // mid-call pause degenerates to a caller abort. stream() leaves it false and instead reads\n // `abort.pauseSignal` to emit a terminal {type:'paused'}.\n const pauseAbortSignal = config.pauseAsAbort ? opts?.pauseSignal : undefined;\n\n let reason: AbortReason | undefined;\n let cancelTimer: (() => void) | undefined;\n let callerListener: (() => void) | undefined;\n let pauseListener: (() => void) | undefined;\n\n const abortWith = (next: AbortReason): void => {\n if (reason !== undefined) {\n return; // first-writer-wins (INV-ABORT-2)\n }\n reason = next;\n abortContext.reason = next;\n if (!controller.signal.aborted) {\n controller.abort();\n }\n };\n\n const abortContext: AbortContext = {\n signal: controller.signal,\n ...(opts?.pauseSignal ? { pauseSignal: opts.pauseSignal } : {}),\n };\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n abortWith(\"caller\");\n } else {\n callerListener = () => abortWith(\"caller\");\n callerSignal.addEventListener(\"abort\", callerListener, { once: true });\n }\n }\n\n if (reason === undefined && pauseAbortSignal) {\n if (pauseAbortSignal.aborted) {\n abortWith(\"caller\");\n } else {\n pauseListener = () => abortWith(\"caller\");\n pauseAbortSignal.addEventListener(\"abort\", pauseListener, { once: true });\n }\n }\n\n if (reason === undefined && timeoutMs !== undefined) {\n const fire = () => abortWith(\"timeout\");\n if (typeof runtime.setTimer === \"function\") {\n cancelTimer = runtime.setTimer(timeoutMs, fire);\n } else {\n const handle = setTimeout(fire, timeoutMs);\n (handle as { unref?: () => void }).unref?.();\n cancelTimer = () => clearTimeout(handle);\n }\n }\n\n const dispose = (): void => {\n cancelTimer?.();\n cancelTimer = undefined;\n if (callerSignal && callerListener) {\n callerSignal.removeEventListener(\"abort\", callerListener);\n callerListener = undefined;\n }\n if (pauseAbortSignal && pauseListener) {\n pauseAbortSignal.removeEventListener(\"abort\", pauseListener);\n pauseListener = undefined;\n }\n };\n\n return { abort: abortContext, dispose };\n}\n\nfunction isoTimestamp(value: number): string {\n return new Date(value).toISOString();\n}\n\nfunction createRequestId(): string {\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction resolveEventRequestId(context: Record<string, unknown> | undefined): string {\n const requestId = typeof context?.request_id === \"string\" ? context.request_id : typeof context?.requestId === \"string\" ? context.requestId : undefined;\n\n return requestId?.trim() || createRequestId();\n}\n\nfunction summarizeRoute(route: NormalizedRoute): WideEventRouteSummary {\n return {\n id: route.id,\n provider: route.provider,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n runtime: route.runtime,\n accountId: route.accountId,\n credentialId: route.credentialId,\n model: route.model,\n handlerKey: route.handlerKey,\n profileId: route.profileId,\n // SYS-3 / C1a: never emit a raw baseUrl into a wide event \u2014 a token embedded in\n // userinfo (`https://user:secret@host`) or the query string would leak verbatim,\n // unlike the secret-safe toPublicRoute projection. Strip credentials first.\n ...(route.transport.baseUrl\n ? { baseUrl: redactBaseUrl(route.transport.baseUrl) }\n : {}),\n };\n}\n\nfunction summarizeFiles(files: PortableFile[]): {\n count: number;\n kinds: PortableFile[\"kind\"][];\n names: string[];\n} {\n return {\n count: files.length,\n kinds: files.map((file) => file.kind),\n names: files.map((file) => file.name),\n };\n}\n\nfunction summarizeToolChoice(choice: GenerateParameters[\"toolChoice\"]): string | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (typeof choice === \"string\") {\n return choice;\n }\n\n if (choice.type === \"function\" && choice.name.trim().length > 0) {\n return `function:${choice.name}`;\n }\n\n return undefined;\n}\n\nfunction summarizeParameters(parameters: GenerateParameters | undefined): WideEventParameterSummary | undefined {\n if (!parameters) {\n return undefined;\n }\n\n const keys = Object.keys(parameters).sort();\n const stopCount = Array.isArray(parameters.stop) ? parameters.stop.length : typeof parameters.stop === \"string\" ? 1 : undefined;\n const thinkingMode = parameters.thinking?.mode ?? (parameters.thinking?.enabled === true ? \"enabled\" : parameters.thinking?.enabled === false ? \"disabled\" : undefined);\n const providerOptionKeys = Object.fromEntries(\n Object.entries(parameters.providerOptions ?? {})\n .filter((entry): entry is [string, Record<string, unknown>] => Boolean(entry[1]))\n .map(([providerId, value]) => [providerId, Object.keys(value).sort()]),\n );\n const toolChoice = summarizeToolChoice(parameters.toolChoice);\n\n return {\n keys,\n ...(parameters.maxTokens !== undefined ? { maxTokens: parameters.maxTokens } : {}),\n ...(parameters.temperature !== undefined ? { temperature: parameters.temperature } : {}),\n ...(parameters.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopCount !== undefined ? { stopCount } : {}),\n ...(parameters.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters.candidateCount !== undefined ? { candidateCount: parameters.candidateCount } : {}),\n ...(parameters.presencePenalty !== undefined ? { presencePenalty: parameters.presencePenalty } : {}),\n ...(parameters.frequencyPenalty !== undefined ? { frequencyPenalty: parameters.frequencyPenalty } : {}),\n ...(parameters.responseFormat ? { responseFormatType: parameters.responseFormat.type } : {}),\n ...(parameters.tools ? { toolCount: parameters.tools.length } : {}),\n ...(toolChoice ? { toolChoice } : {}),\n ...(parameters.parallelToolCalls !== undefined ? { parallelToolCalls: parameters.parallelToolCalls } : {}),\n ...(thinkingMode ? { thinkingMode } : {}),\n ...(parameters.thinking?.budgetTokens !== undefined ? { thinkingBudgetTokens: parameters.thinking.budgetTokens } : {}),\n ...(parameters.thinking?.effort ? { thinkingEffort: parameters.thinking.effort } : {}),\n ...(parameters.thinking?.includeThoughts !== undefined ? { includeThoughts: parameters.thinking.includeThoughts } : {}),\n ...(parameters.safetySettings ? { safetySettingsCount: parameters.safetySettings.length } : {}),\n ...(parameters.metadata ? { metadataKeys: Object.keys(parameters.metadata).sort() } : {}),\n ...(parameters.extra ? { extraKeys: Object.keys(parameters.extra).sort() } : {}),\n ...(Object.keys(providerOptionKeys).length > 0 ? { providerOptionKeys } : {}),\n };\n}\n\nfunction summarizeRequest(request: NormalizedGenerateRequest, candidates: WideEventRouteSummary[]): WideEventRequestSummary {\n const attachments = summarizeFiles(request.attachments);\n const parameters = summarizeParameters(request.parameters);\n\n return {\n messageCount: request.messages.length,\n messageRoles: request.messages.map((message) => message.role),\n inputChars: request.messages.reduce((sum, message) => sum + message.content.length, 0),\n attachmentCount: attachments.count,\n attachmentKinds: attachments.kinds,\n attachmentNames: attachments.names,\n candidateRouteIds: candidates.map((route) => route.id),\n ...(request.clientTools?.length\n ? {\n clientToolCount: request.clientTools.length,\n clientToolNames: request.clientTools.map((tool) => tool.function.name),\n }\n : {}),\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n ...(request.workingDirectory\n ? { workingDirectory: request.workingDirectory }\n : {}),\n ...(request.image?.size ? { imageSize: String(request.image.size) } : {}),\n ...(request.image?.aspectRatio ? { imageAspectRatio: request.image.aspectRatio } : {}),\n ...(request.image?.quality ? { imageQuality: request.image.quality } : {}),\n ...(request.image?.imageSize ? { imageOutputSize: request.image.imageSize } : {}),\n ...(request.image?.style ? { imageStyle: request.image.style } : {}),\n ...(request.image?.rawPrompt !== undefined ? { rawImagePrompt: request.image.rawPrompt } : {}),\n ...(request.image?.referenceImages?.length ? { imageReferenceCount: request.image.referenceImages.length } : {}),\n ...(request.image?.sourceImage ? { imageHasSourceImage: true } : {}),\n ...(request.image?.mask ? { imageHasMask: true } : {}),\n ...(parameters ? { parameters } : {}),\n };\n}\n\nfunction summarizeResult(result: GenerateResult): WideEventResultSummary {\n const attachments = summarizeFiles(result.attachments);\n\n return {\n warningsCount: result.warnings.length,\n warnings: result.warnings,\n attachmentCount: attachments.count,\n attachmentKinds: attachments.kinds,\n attachmentNames: attachments.names,\n ...(result.text !== undefined ? { outputTextChars: result.text.length } : {}),\n ...(result.toolCalls?.length ? { toolCallCount: result.toolCalls.length } : {}),\n ...(result.usage !== undefined ? { usage: result.usage } : {}),\n };\n}\n\nfunction summarizeVerification(report: VerificationReport, targetIds: Set<string> | undefined): WideEventVerificationSummary {\n const issueCodes = report.routes.flatMap((route) => route.issues.map((issue) => issue.code));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n issueCount: issueCodes.length,\n issueCodes,\n routeReports: report.routes.map((route) => ({\n routeId: route.routeId,\n ok: route.ok,\n issueCodes: route.issues.map((issue) => issue.code),\n })),\n };\n}\n\nfunction summarizeAcpModelDiscovery(report: AcpModelDiscoveryReport, targetIds: Set<string> | undefined): WideEventAcpModelDiscoverySummary {\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n routeReports: report.routes.map((route) => ({\n routeId: route.routeId,\n provider: route.provider,\n ok: route.ok,\n transportKind: route.transportKind,\n transportId: route.transportId,\n ...(route.requestedModelId ? { requestedModelId: route.requestedModelId } : {}),\n ...(route.requestedModelAdvertised !== undefined ? { requestedModelAdvertised: route.requestedModelAdvertised } : {}),\n ...(route.canonicalModelId ? { canonicalModelId: route.canonicalModelId } : {}),\n ...(route.resolvedModelId ? { resolvedModelId: route.resolvedModelId } : {}),\n ...(route.currentModelId ? { currentModelId: route.currentModelId } : {}),\n availableModelCount: route.availableModels.length,\n availableModelIds: route.availableModels.map((model) => model.modelId),\n ...(route.error\n ? {\n errorCode: route.error.code,\n message: route.error.message,\n }\n : {}),\n })),\n };\n}\n\nfunction summarizeHealth(\n report: HealthReport,\n reachabilityOnly: boolean,\n targetIds: Set<string> | undefined,\n): WideEventHealthSummary {\n const routeReports: WideEventHealthRouteSummary[] = report.routes.map((route) => ({\n routeId: route.routeId,\n provider: route.provider,\n transportKind: route.transportKind,\n ok: route.ok,\n endpointOk: route.endpoint.ok,\n modelOk: route.model.ok,\n ...(route.endpoint.code ? { endpointCode: route.endpoint.code } : {}),\n ...(route.model.code ? { modelCode: route.model.code } : {}),\n ...(route.model.latencyMs !== undefined\n ? { modelLatencyMs: route.model.latencyMs }\n : {}),\n }));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n reachabilityOnly,\n routesChecked: report.routes.length,\n routesPassed: report.routes.filter((route) => route.ok).length,\n routesFailed: report.routes.filter((route) => !route.ok).length,\n routeReports,\n };\n}\n\nfunction summarizeProbe(\n results: ProbeModelResult[],\n targetIds: Set<string> | undefined,\n): WideEventProbeSummary {\n const routeReports: WideEventProbeRouteSummary[] = results.map((result) => ({\n routeId: result.routeId,\n modelId: result.modelId,\n ok: result.ok,\n broken: result.broken,\n cached: result.cached === true,\n ...(result.code ? { code: result.code } : {}),\n ...(result.httpStatus !== undefined ? { httpStatus: result.httpStatus } : {}),\n ...(result.latencyMs !== undefined ? { latencyMs: result.latencyMs } : {}),\n }));\n\n return {\n ...(targetIds?.size ? { requestedRouteIds: Array.from(targetIds) } : {}),\n probesIssued: results.length,\n probesOk: results.filter((result) => result.ok).length,\n probesBroken: results.filter((result) => result.broken).length,\n probesCached: results.filter((result) => result.cached === true).length,\n routeReports,\n };\n}\n\nexport function createClient(configOrInput: AiConnectConfig | AiConnectConfigInput, options: CreateClientOptions = {}): AiConnectClient {\n const baseConfig = isNormalizedConfig(configOrInput) ? configOrInput : defineConfig(configOrInput);\n const runtime = options.runtime ?? createRuntimeEnvironment(inferRuntimeKind());\n const config = materializeRuntimeConfig(baseConfig, runtime);\n const handlers = options.handlers ?? {};\n const clientToolRegistry = normalizeClientToolRegistry(options.clientTools);\n const router = new RouteRegistry(config, runtime);\n // C4 \u2014 per-(baseUrl|transportId)::model context-window cache. A hit returns the cached\n // value+source with cached:true and IGNORES options.discovered (OQ-4 / INV-CTX-1).\n const modelContextCache = new Map<string, ModelContextResolution>();\n // C8 \u2014 per-client probe cache keyed by `routeId::sorted-models` (probeCacheKey). Owned HERE,\n // never inside probe.ts (which is a stateless reusable primitive). TTL default 5min.\n const probeCache: ProbeCache = new Map();\n const logging = options.logging;\n const dispose = options.dispose ?? (async () => {});\n\n // C9 \u2014 fan-out throttle. The CLIENT-level limiter is built once from `options.fanout` and shared\n // across requests that don't override it (lifetime `maxCalls` is a per-client ceiling). A request\n // with its own `request.fanout` gets a request-SCOPED limiter (merged per-field over the client\n // default) so it NEVER mutates the shared client limiter (R15).\n const clientFanoutPolicy: FanoutPolicy | undefined = options.fanout;\n const clientFanoutLimiter: FanoutLimiter = createFanoutLimiter(\n normalizeFanoutPolicy(clientFanoutPolicy),\n runtime,\n );\n // C9 \u2014 the client-scoped ModelSelector hook (OQ-11). `failOpen` (default false) flips a throwing\n // selector from fail-closed `validation_error` to a silent fall-through to normal routing.\n const modelSelector: ModelSelector | undefined =\n options.routeHints?.modelSelector;\n const modelSelectorFailOpen = options.routeHints?.failOpen === true;\n\n /**\n * Pick the fan-out limiter for one request (R15). When the request carries its own `fanout`, a\n * fresh request-scoped limiter is built from the per-field merge over the client default \u2014 the\n * shared `clientFanoutLimiter` is never touched. Otherwise the shared client limiter is used.\n */\n function limiterForRequest(request: GenerateRequest): FanoutLimiter {\n if (request.fanout === undefined) {\n return clientFanoutLimiter;\n }\n return createFanoutLimiter(\n normalizeFanoutPolicy(mergeFanoutPolicy(clientFanoutPolicy, request.fanout)),\n runtime,\n );\n }\n\n /**\n * Resolve the effective request-level model (C9 / UR-014 / OQ-11). Precedence:\n * 1. explicit `routeHints.model` \u2014 wins outright; the selector is NOT invoked\n * (explicit-routeHints.model-beats-selector).\n * 2. the consumer `modelSelector` hook \u2014 invoked with the neutral input + eligible candidates;\n * an eligible returned id is applied; an undefined/ineligible id falls through (normal\n * routing). A throwing/rejecting selector FAILS CLOSED to `validation_error` unless `failOpen`.\n * 3. neither \u2014 undefined (normal routing).\n * Returns the model id to thread into `routeHints.model`, or undefined to leave routing untouched.\n */\n async function resolveSelectedModel(\n request: NormalizedGenerateRequest,\n ): Promise<string | undefined> {\n const explicit = request.routeHints?.model;\n if (explicit !== undefined) {\n return explicit;\n }\n if (!modelSelector) {\n return undefined;\n }\n const candidates = router.candidateModels({ operation: request.operation });\n let picked: string | undefined;\n try {\n picked = await modelSelector(\n {\n text: request.messages.map((message) => message.content).join(\"\\n\"),\n messages: request.messages,\n operation: request.operation,\n ...(request.routeHints ? { routeHints: request.routeHints } : {}),\n },\n candidates,\n );\n } catch {\n // OQ-11: fail-closed by default \u2014 a throwing/rejecting selector yields a single deterministic\n // validation_error without consuming a fan-out slot or corrupting candidate ordering.\n if (modelSelectorFailOpen) {\n return undefined;\n }\n throw new AiConnectError(\n \"validation_error\",\n \"The configured modelSelector hook threw or rejected.\",\n );\n }\n if (picked === undefined) {\n return undefined;\n }\n // Only apply an eligible candidate; an ineligible id falls through so the strict-route DROP in\n // applyRequestedModel can surface a deterministic not_supported on empty candidates.\n return candidates.some((candidate) => candidate.model === picked)\n ? picked\n : undefined;\n }\n\n /**\n * Inject the selector-chosen model into the request's `routeHints.model` (when one was chosen and\n * the caller did not set an explicit one). Pure \u2014 returns a fresh request; never mutates input.\n */\n function withSelectedModel(\n request: NormalizedGenerateRequest,\n selectedModel: string | undefined,\n ): NormalizedGenerateRequest {\n if (selectedModel === undefined || request.routeHints?.model !== undefined) {\n return request;\n }\n return {\n ...request,\n routeHints: { ...(request.routeHints ?? {}), model: selectedModel },\n };\n }\n\n function prepareRequest(request: GenerateRequest): NormalizedGenerateRequest {\n const normalized = normalizeRequestBase(request);\n const clientTools = resolveClientToolSelections(\n request.clientTools,\n clientToolRegistry,\n );\n\n if (\n clientTools.length > 0 &&\n (normalized.operation !== \"text\" ||\n normalized.attachments.length > 0 ||\n normalized.image !== undefined)\n ) {\n throw new AiConnectError(\n \"validation_error\",\n \"clientTools are currently supported only for text requests without attachments or image options.\",\n );\n }\n\n const mergedTools = clientTools.length\n ? mergeToolDefinitions(normalized.parameters?.tools, clientTools)\n : undefined;\n\n return {\n ...normalized,\n ...(clientTools.length > 0 ? { clientTools } : {}),\n ...(mergedTools\n ? {\n parameters: {\n ...(normalized.parameters ?? {}),\n tools: mergedTools,\n },\n }\n : {}),\n };\n }\n\n async function executeClientToolLoop(\n route: NormalizedRoute,\n handler: NonNullable<RouteHandler[\"generate\"]>,\n request: NormalizedGenerateRequest,\n initialOutput: RouteHandlerGenerateResult,\n baseAttempt: number,\n abort: AbortContext,\n ): Promise<{\n output: RouteHandlerGenerateResult;\n transportSummary?: WideEventTransportSummary;\n }> {\n if (!request.clientTools?.length || !initialOutput.toolCalls?.length) {\n return { output: initialOutput };\n }\n\n const registry = new Map(\n request.clientTools.map((tool) => [tool.function.name, tool] as const),\n );\n const warnings = [...(initialOutput.warnings ?? [])];\n let usage = initialOutput.usage;\n let output = initialOutput;\n let messages = [...request.messages];\n let transportSummary: WideEventTransportSummary | undefined;\n\n for (let round = 0; round < 8; round += 1) {\n const toolCalls = output.toolCalls ?? [];\n if (toolCalls.length === 0) {\n return {\n output: {\n ...output,\n warnings,\n ...(usage ? { usage } : {}),\n },\n ...(transportSummary ? { transportSummary } : {}),\n };\n }\n\n const assistantMessage: MessageInput = {\n role: \"assistant\",\n content: output.text ?? \"\",\n toolCalls,\n };\n const toolMessages: MessageInput[] = [];\n\n for (const toolCall of toolCalls) {\n const tool = registry.get(toolCall.name);\n if (!tool) {\n // D5: a missing handler is a client-config error, not provider health.\n throw new ClientToolExecutionError(\n new AiConnectError(\n \"validation_error\",\n `No client tool handler is registered for \"${toolCall.name}\".`,\n ),\n );\n }\n\n // client-tool cancellation (MEDIUM): honor a caller/timeout abort BEFORE\n // EACH tool.execute() \u2014 not just once per round \u2014 so a long tool sequence\n // stops promptly on cancel instead of running every remaining tool first.\n // Wave 4: promote to ClientToolContext.abort so the tool itself can observe\n // the signal; for now we gate on the abort already in scope.\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n let execution: ReturnType<typeof normalizeToolResult>;\n try {\n execution = normalizeToolResult(\n await tool.execute(toolCall.arguments, {\n route,\n request,\n runtime,\n toolCall,\n messages,\n ...(request.workingDirectory\n ? { workingDirectory: request.workingDirectory }\n : {}),\n }),\n );\n } catch (error) {\n // A cancel that fired while the tool ran is abort semantics, not a tool bug.\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n // D5 / SYS-6: an error thrown by the caller's own tool.execute() is a\n // CLIENT-SIDE bug. Wrap it so the fallback loop neither records route\n // failure nor rotates/cools down a healthy route on it.\n throw new ClientToolExecutionError(\n new AiConnectError(\n \"validation_error\",\n `Client tool \"${tool.function.name}\" threw during execution: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { cause: error },\n ),\n );\n }\n\n toolMessages.push({\n role: \"tool\",\n content: execution.content,\n toolName: tool.function.name,\n toolCallId: toolCall.id,\n ...(execution.data !== undefined ? { data: execution.data } : {}),\n ...(execution.isError !== undefined\n ? { isError: execution.isError }\n : {}),\n });\n }\n\n messages = [...messages, assistantMessage, ...toolMessages];\n\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n // SYS-1: the follow-up model call in the tool loop is another generate call\n // site \u2014 race it against abort too so a non-cooperative handler cannot hang\n // the loop past a caller cancel / timeout.\n output = await runWithAbortRace(\n handler({\n route,\n request: {\n ...request,\n messages,\n attachments: [],\n },\n runtime,\n attempt: baseAttempt,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n }),\n abort,\n );\n warnings.push(...(output.warnings ?? []));\n usage = mergeUsage(usage, output.usage);\n }\n\n // D5: exceeding the loop depth is a client-tool orchestration outcome, not a\n // provider-health failure \u2014 mark it so it does not rotate the route either.\n throw new ClientToolExecutionError(\n new AiConnectError(\n \"validation_error\",\n \"clientTools exceeded the maximum tool-call loop depth of 8.\",\n ),\n );\n }\n\n async function emitWideEvent(event: Omit<WideEvent, \"service\" | \"library\">): Promise<void> {\n if (!logging?.logger) {\n return;\n }\n\n const mergedContext = {\n ...(logging.baseContext ?? {}),\n ...(event.context ?? {}),\n };\n const finalEvent: WideEvent = {\n ...event,\n service: logging.service ?? DEFAULT_LOGGING_SERVICE,\n library: \"ai-connect\",\n ...(Object.keys(mergedContext).length > 0 ? { context: mergedContext } : {}),\n ...(logging.version ? { version: logging.version } : {}),\n ...(logging.deploymentId ? { deploymentId: logging.deploymentId } : {}),\n ...(logging.region ? { region: logging.region } : {}),\n };\n\n if (!(await shouldEmitWideEvent(finalEvent, logging.sampling))) {\n return;\n }\n\n try {\n await logging.logger(finalEvent);\n } catch {\n // Logging should never break request handling.\n }\n }\n\n async function executeGenerateOperation(\n normalizedRequest: NormalizedGenerateRequest,\n operationName: ClientOperationName,\n abort: AbortContext,\n seed: {\n startMs?: number;\n requestId?: string;\n candidates?: WideEventRouteSummary[];\n attempts?: RouteAttempt[];\n wideAttempts?: WideEventAttempt[];\n } = {},\n ): Promise<GenerateResult> {\n const startedAt = seed.startMs ?? nowMs(runtime);\n const requestId = seed.requestId ?? resolveEventRequestId(normalizedRequest.logContext);\n // C6/H1: inject multimodal capability requirements so a PDF/image request only\n // routes to a candidate that advertises it; an empty candidate set then maps\n // to a clean `unsupported_capability` (no spawn/fetch \u2014 INV the design calls\n // pdf-on-unsupported-route-clean-error). Shared with stream() via the helper.\n const { requiresImage, requiresFile, request: capabilityScopedRequest } =\n resolveRequiredCapabilities(normalizedRequest);\n const resolvedCandidates = router.resolveCandidates(capabilityScopedRequest);\n const candidates = seed.candidates ?? resolvedCandidates.map(summarizeRoute);\n const requestSummary = summarizeRequest(normalizedRequest, candidates);\n\n if (resolvedCandidates.length === 0) {\n const error =\n requiresImage || requiresFile\n ? new AiConnectError(\n \"unsupported_capability\",\n `No eligible route supports the required ${\n requiresFile ? \"document/file\" : \"image\"\n } input for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`,\n )\n : new AiConnectError(\"not_supported\", `No eligible routes are available for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: seed.wideAttempts ?? [],\n request: requestSummary,\n error: {\n code: error.code,\n message: error.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw error;\n }\n\n const attempts = [...(seed.attempts ?? [])];\n const wideAttempts = [...(seed.wideAttempts ?? [])];\n let failedRoute: NormalizedRoute | undefined;\n let allowedFallbacks: string[] | undefined;\n\n for (const route of resolvedCandidates) {\n // INV-ABORT-1 / R2: a caller abort or fired timeout MUST short-circuit the fallback\n // loop BEFORE selecting/retrying any route \u2014 a cancel must never rotate credentials.\n if (abort.signal.aborted) {\n const abortError = mapAbortError(abort.reason);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: abortError.code,\n message: abortError.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw abortError;\n }\n\n if (failedRoute && allowedFallbacks && !canFallbackBetween(failedRoute, route, allowedFallbacks)) {\n continue;\n }\n\n const routeSummary = summarizeRoute(route);\n const handler = resolveHandler(route, handlers);\n if (!handler?.generate) {\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: \"not_supported\",\n message: `No generate handler is registered for ${route.handlerKey}.`,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: 0,\n outcome: \"error\",\n retryCount: 0,\n errorCode: \"not_supported\",\n message: `No generate handler is registered for ${route.handlerKey}.`,\n fallbackActions: config.routing.fallback.on.not_supported,\n });\n failedRoute = route;\n allowedFallbacks = config.routing.fallback.on.not_supported;\n router.recordFailure(route, \"not_supported\");\n continue;\n }\n\n let retryCount = 0;\n\n // C7 / R14: inject this route's explicit per-route defaults (systemPrompt /\n // defaultResponseFormat) when the caller omitted them. Derived from the ORIGINAL request so\n // it stays idempotent across retries and fallback to another route.\n const routeRequest = applyRouteDefaults(route, normalizedRequest);\n\n while (true) {\n const attemptStartedAt = nowMs(runtime);\n let transportSummary: WideEventTransportSummary | undefined;\n\n try {\n // SYS-1 / H3: race the handler against the derived-abort so a\n // non-cooperative handler (e.g. a shared-conn ACP that ignores\n // session/cancel) can no longer hang generate({timeoutMs}) forever \u2014 the\n // race rejects with the canonical abort/timeout even if the handler never\n // settles.\n let output = await runWithAbortRace(\n handler.generate({\n route,\n request: routeRequest,\n runtime,\n attempt: attempts.length + 1,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n }),\n abort,\n );\n\n if (routeRequest.clientTools?.length && output.toolCalls?.length) {\n const loopResult = await executeClientToolLoop(\n route,\n handler.generate,\n routeRequest,\n output,\n attempts.length + 1,\n abort,\n );\n output = loopResult.output;\n if (loopResult.transportSummary) {\n transportSummary = loopResult.transportSummary;\n }\n }\n\n // H3 / SYS-1: a handler (or the client-tool follow-up) can RESOLVE after\n // the abort already fired. Re-check before we treat it as success \u2014 a\n // resolved-after-abort result must still surface as aborted and MUST NOT\n // recordSuccess. The throw lands in the catch's abort branch below.\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n router.recordSuccess(route);\n\n const result = normalizeResult(route, output, attempts);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n result: summarizeResult(result),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n return result;\n } catch (error) {\n // INV-ABORT-1 / R2: if the derived signal aborted, normalize to the canonical\n // abort/timeout code from `abort.reason` (NOT post-hoc DOMException sniffing) and\n // throw immediately \u2014 BEFORE consulting fallback policy, recording route health,\n // or rotating credentials. The handler's thrown error (an AbortError from the\n // underlying fetch/child) is discarded in favour of the authoritative reason.\n if (abort.signal.aborted) {\n const abortError = mapAbortError(abort.reason);\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: abortError.code,\n message: abortError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount,\n errorCode: abortError.code,\n message: abortError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: abortError.code,\n message: abortError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw new AiConnectError(abortError.code, abortError.message, {\n attempts,\n routeId: route.id,\n });\n }\n\n // D5 / SYS-6: a failure originating in the caller's own client-tool\n // orchestration (tool.execute() threw, no handler, loop-depth exceeded) is\n // NOT a provider-health signal. Surface it terminally WITHOUT recordFailure\n // and WITHOUT consulting fallback.on \u2014 a client-side tool bug must never\n // rotate/cool down a healthy route.\n if (error instanceof ClientToolExecutionError) {\n const toolError = error.aiError;\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: toolError.code,\n message: toolError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount,\n errorCode: toolError.code,\n message: toolError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: toolError.code,\n message: toolError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw new AiConnectError(toolError.code, toolError.message, {\n ...toolError.details,\n attempts,\n routeId: route.id,\n });\n }\n\n const normalizedError = toAiConnectError(error);\n const actions = config.routing.fallback.on[normalizedError.code] ?? [];\n\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n ...(actions.length ? { fallbackActions: actions } : {}),\n });\n\n const maxRetries = config.routing.retry.maxAttempts[normalizedError.code] ?? 0;\n if (actions.includes(\"retry\") && retryCount < maxRetries) {\n retryCount += 1;\n await sleep(config.routing.retry.delayMs[normalizedError.code] ?? 0);\n continue;\n }\n\n router.recordFailure(route, normalizedError.code);\n if (actions.length === 0) {\n const finalError = new AiConnectError(normalizedError.code, normalizedError.message, {\n // Preserve original error details (e.g. httpStatus from classifyApiError,\n // CD-7) through the terminal re-wrap \u2014 F-PF-1. `...undefined` is a no-op.\n ...normalizedError.details,\n attempts,\n routeId: route.id,\n });\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: finalError.code,\n message: finalError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw finalError;\n }\n\n failedRoute = route;\n allowedFallbacks = actions;\n break;\n }\n }\n }\n\n const finalError = new AiConnectError(\"temporary_unavailable\", \"No eligible fallback routes remained after route failures.\", { attempts });\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName,\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: finalError.code,\n message: finalError.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw finalError;\n }\n\n async function executeModelDiscoveryOperation(\n target:\n | {\n routes?: string[];\n logContext?: Record<string, unknown>;\n transports?: TransportKind[];\n }\n | undefined,\n options: {\n operationName: \"discoverModels\" | \"discoverAcpModels\";\n acpOnly?: boolean;\n abort: AbortContext;\n },\n ): Promise<AcpModelDiscoveryReport> {\n const startedAt = nowMs(runtime);\n const abort = options.abort;\n const targetIds = target?.routes?.length ? new Set(resolveRouteSelectors(target.routes, config.routes)) : undefined;\n const transportFilter = target?.transports && target.transports.length > 0 ? new Set(target.transports) : undefined;\n const reports: AcpModelDiscoveryRouteReport[] = [];\n const wideAttempts: WideEventAttempt[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n\n if (options.acpOnly && route.transport.kind !== \"acp\") {\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: \"not_supported\",\n message: `Route \"${route.id}\" is not an ACP route.`,\n },\n });\n continue;\n }\n\n const routeSummary = summarizeRoute(route);\n const handler = resolveHandler(route, handlers);\n if (!handler?.discoverModels) {\n const message = options.acpOnly\n ? `No ACP model discovery handler is registered for ${route.handlerKey}.`\n : `No model discovery handler is registered for ${route.handlerKey}.`;\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: \"not_supported\",\n message,\n },\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: 0,\n outcome: \"error\",\n retryCount: 0,\n errorCode: \"not_supported\",\n message,\n });\n continue;\n }\n\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const attemptStartedAt = nowMs(runtime);\n let transportSummary: WideEventTransportSummary | undefined;\n\n try {\n const catalog = await handler.discoverModels({\n route,\n runtime,\n abort,\n telemetry: {\n captureTransport(summary) {\n transportSummary = summary;\n },\n },\n });\n\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: true,\n ...(catalog.requestedModelId ? { requestedModelId: catalog.requestedModelId } : {}),\n ...(catalog.requestedModelAdvertised !== undefined ? { requestedModelAdvertised: catalog.requestedModelAdvertised } : {}),\n ...(catalog.canonicalModelId ? { canonicalModelId: catalog.canonicalModelId } : {}),\n ...(catalog.resolvedModelId ? { resolvedModelId: catalog.resolvedModelId } : {}),\n ...(catalog.currentModelId ? { currentModelId: catalog.currentModelId } : {}),\n availableModels: catalog.availableModels,\n ...(catalog.warnings?.length ? { warnings: catalog.warnings } : {}),\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n } catch (error) {\n // A caller abort / fired timeout terminates the whole probe-tier sweep (it is\n // hard-terminal, never per-route health) \u2014 surface the canonical reason.\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalizedError = toAiConnectError(error);\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n ok: false,\n requestedModelId: route.model,\n availableModels: [],\n error: {\n code: normalizedError.code,\n message: normalizedError.message,\n },\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount: 0,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n ...(transportSummary ? { transport: transportSummary } : {}),\n });\n }\n }\n\n const report = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n const candidates = config.routes\n .filter((route) => {\n if (targetIds && !targetIds.has(route.id)) {\n return false;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n return false;\n }\n return true;\n })\n .map(summarizeRoute);\n const discoverySummary = summarizeAcpModelDiscovery(report, targetIds);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: options.operationName,\n operation: \"discover_models\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates,\n attempts: wideAttempts,\n modelDiscovery: discoverySummary,\n ...(options.acpOnly ? { acpModelDiscovery: discoverySummary } : {}),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n }\n\n // \u2500\u2500 C8 \u2014 live health-check + model probe (UR-008 / INV-PROBE-1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // READ-ONLY re router health: NEITHER checkHealth NOR probeModels (NOR their helpers below)\n // ever calls `router.recordFailure`/`router.recordSuccess`. A probe is diagnostic, not a live\n // request \u2014 letting it mutate route-health would let a cheap liveness ping cool down a route\n // (R16-adjacent). The only router call here is the READ-ONLY `router.getHealth(...)` used for\n // candidate selection / projection elsewhere. (INV-PROBE-1; enforced by discipline + DST #52.)\n\n /**\n * Await `handler.generate` BUT lose the race to a derived-abort: if `abort.signal` fires (caller\n * cancel mid-fan-out OR the per-probe timeout) before the handler settles, this rejects with the\n * canonical abort/timeout error EVEN IF the handler never resolves (DST #50 \u2014 a hung tuple yields\n * a timeout while siblings complete). The handler is also passed `abort` so a compliant handler\n * can cancel its own fetch; the race guarantees liveness regardless.\n */\n async function runPingWithAbort(\n route: NormalizedRoute,\n handler: NonNullable<RouteHandler[\"generate\"]>,\n abort: AbortContext,\n ): Promise<RouteHandlerGenerateResult> {\n // SYS-1: the ping path now shares the single `runWithAbortRace` primitive with\n // generate()/stream() so all transports enforce the same cooperative-abort\n // liveness contract (DST #49/#50).\n return runWithAbortRace(\n handler({\n route,\n request: buildPingRequest(),\n runtime,\n attempt: 1,\n abort,\n }),\n abort,\n );\n }\n\n /**\n * Stage-1 reachability probe. For api routes this is the GET /models discovery (`discoverModels`);\n * for acp/cli/server it is the session/availability `verify`. Returns a {@link HealthStageResult}\n * \u2014 `ok=false` carries the normalized error code + (CD-7) httpStatus when available. READ-ONLY.\n */\n async function checkEndpointReachable(\n route: NormalizedRoute,\n handler: RouteHandler | undefined,\n abort: AbortContext,\n ): Promise<HealthStageResult> {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n if (!handler) {\n return {\n ok: false,\n detail: `No handler is registered for ${route.handlerKey}.`,\n code: \"not_supported\",\n };\n }\n\n try {\n if (route.transport.kind === \"api\" && handler.discoverModels) {\n await handler.discoverModels({ route, runtime, abort });\n return { ok: true, detail: \"reachable\" };\n }\n if (handler.verify) {\n const issues = await handler.verify({ route, runtime });\n if (issues.length === 0) {\n return { ok: true, detail: \"reachable\" };\n }\n return {\n ok: false,\n detail: issues.map((issue) => issue.message).join(\"; \"),\n code: \"local_harness_unavailable\",\n };\n }\n // No reachability primitive available \u2014 treat as a soft pass so Stage-2 can still attempt.\n return { ok: true, detail: \"reachability check not supported; assuming reachable\" };\n } catch (error) {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalized = toAiConnectError(error);\n const httpStatus = normalized.details?.[\"httpStatus\"];\n return {\n ok: false,\n detail: normalized.message,\n code: normalized.code,\n ...(typeof httpStatus === \"number\" ? { httpStatus } : {}),\n };\n }\n }\n\n /**\n * Stage-2 minimal chat ping. Issues a max-1-token ping via `handler.generate` and classifies the\n * outcome with `classifyProbeOutcome` (empty response \u21D2 model fail). Captures `latencyMs` off the\n * injected clock (fake-clock deterministic). READ-ONLY re router health.\n */\n async function pingModel(\n route: NormalizedRoute,\n handler: RouteHandler | undefined,\n abort: AbortContext,\n ): Promise<HealthModelStageResult> {\n if (!handler?.generate) {\n return {\n ok: false,\n detail: `No generate handler is registered for ${route.handlerKey}.`,\n code: \"not_supported\",\n };\n }\n const startedAt = nowMs(runtime);\n try {\n const output = await runPingWithAbort(route, handler.generate, abort);\n const classification = classifyProbeOutcome({\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n });\n return {\n ok: classification.ok,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - startedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n };\n } catch (error) {\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n const normalized = toAiConnectError(error);\n const classification = classifyProbeOutcome({ error: normalized });\n return {\n ok: classification.ok,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - startedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n };\n }\n }\n\n async function executeCheckHealth(target?: CheckHealthTarget): Promise<HealthReport> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length\n ? new Set(resolveRouteSelectors(target.routes, config.routes))\n : undefined;\n const transportFilter =\n target?.transports && target.transports.length > 0\n ? new Set(target.transports)\n : undefined;\n const reachabilityOnly = target?.reachabilityOnly === true;\n const { abort, dispose: disposeAbort } = deriveAbort(\n target?.signal ? { signal: target.signal } : undefined,\n resolveOpTimeout(target, \"probeMs\", options.timeouts),\n runtime,\n );\n\n try {\n const reports: RouteHealthReport[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const handler = resolveHandler(route, handlers);\n const endpoint = await checkEndpointReachable(route, handler, abort);\n\n let model: HealthModelStageResult;\n if (!endpoint.ok) {\n // Stage-1 short-circuit (DST #51): never invoke handler.generate when unreachable.\n model = { ok: false, detail: \"skipped: endpoint unreachable\" };\n } else if (reachabilityOnly) {\n model = { ok: true, detail: \"skipped: reachabilityOnly\" };\n } else {\n model = await pingModel(route, handler, abort);\n }\n\n reports.push({\n routeId: route.id,\n provider: route.provider,\n handlerKey: route.handlerKey,\n transportKind: route.transport.kind,\n transportId: route.transport.id,\n modelId: route.model,\n ok: endpoint.ok && model.ok,\n endpoint,\n model,\n });\n }\n\n const report: HealthReport = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"checkHealth\",\n operation: \"check_health\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: config.routes\n .filter((route) => {\n if (targetIds && !targetIds.has(route.id)) {\n return false;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n return false;\n }\n return true;\n })\n .map(summarizeRoute),\n attempts: [],\n health: summarizeHealth(report, reachabilityOnly, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n } finally {\n disposeAbort();\n }\n }\n\n /**\n * Shared engine for `probeModels` / `probeModelsStream`. Yields each {@link ProbeModelResult} as\n * it settles (the streaming surface) while the array form simply drains the generator. Uses a\n * per-(route::sorted-models) TTL cache, bounded concurrency, a per-probe timeout via the\n * `deriveAbort` seam, and honors the fan-out-level `opts.signal` mid-flight. READ-ONLY re router.\n */\n async function* runProbeModels(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): AsyncGenerator<ProbeModelResult, void, void> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length\n ? new Set(resolveRouteSelectors(target.routes, config.routes))\n : undefined;\n const transportFilter =\n target?.transports && target.transports.length > 0\n ? new Set(target.transports)\n : undefined;\n const modelFilter =\n target?.models && target.models.length > 0\n ? new Set(target.models)\n : undefined;\n const concurrency =\n opts?.concurrency && opts.concurrency > 0\n ? opts.concurrency\n : PROBE_DEFAULT_CONCURRENCY;\n const perProbeTimeoutMs =\n opts?.timeoutMs !== undefined ? opts.timeoutMs : PROBE_DEFAULT_TIMEOUT_MS;\n const ttlMs =\n opts?.cacheTtlMs !== undefined ? opts.cacheTtlMs : PROBE_DEFAULT_TTL_MS;\n const fanoutSignal = opts?.signal;\n\n // The route::model tuples to probe (the route advertises its own models; `modelFilter` narrows).\n const tuples: { route: NormalizedRoute; modelId: string }[] = [];\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (transportFilter && !transportFilter.has(route.transport.kind)) {\n continue;\n }\n const models = route.advertisedModels.length\n ? route.advertisedModels\n : [route.model];\n for (const modelId of models) {\n if (modelFilter && !modelFilter.has(modelId)) {\n continue;\n }\n tuples.push({ route, modelId });\n }\n }\n\n // TTL cache is keyed per-route over its (sorted) probed model set (#47). Group tuples by route\n // so a route's whole probe set shares one cache entry.\n const byRoute = new Map<string, { route: NormalizedRoute; models: string[] }>();\n for (const tuple of tuples) {\n const existing = byRoute.get(tuple.route.id);\n if (existing) {\n existing.models.push(tuple.modelId);\n } else {\n byRoute.set(tuple.route.id, { route: tuple.route, models: [tuple.modelId] });\n }\n }\n\n const emitted: ProbeModelResult[] = [];\n const cachedRouteResults = new Map<string, ProbeModelResult[]>();\n const liveGroups: { route: NormalizedRoute; models: string[] }[] = [];\n\n for (const group of byRoute.values()) {\n const key = probeCacheKey(group.route.id, group.models);\n if (!opts?.forceRefresh) {\n const hit = readProbeCache(probeCache, key, nowMs(runtime));\n if (hit) {\n cachedRouteResults.set(group.route.id, hit);\n continue;\n }\n }\n liveGroups.push(group);\n }\n\n // Pre-abort short-circuit (DST #49): a pre-aborted fan-out signal does zero handler work.\n if (fanoutSignal?.aborted) {\n throw mapAbortError(\"caller\");\n }\n\n // Flatten live tuples for bounded fan-out; cached tuples are emitted without any handler call.\n const liveTuples: { route: NormalizedRoute; modelId: string }[] = [];\n for (const group of liveGroups) {\n for (const modelId of group.models) {\n liveTuples.push({ route: group.route, modelId });\n }\n }\n\n const liveResults = await runBounded(\n liveTuples,\n concurrency,\n async (tuple): Promise<ProbeModelResult> => {\n // A fan-out abort that already fired means later tuples must not start (#49).\n if (fanoutSignal?.aborted) {\n throw mapAbortError(\"caller\");\n }\n // Per-probe derived abort: fan-out signal \u2295 this probe's own timeout, scheduled on the\n // `runtime.setTimer` seam so a fake clock fires it (#50). NO probe-local withTimeout (CD-4).\n const { abort, dispose: disposeAbort } = deriveAbort(\n {\n ...(fanoutSignal ? { signal: fanoutSignal } : {}),\n ...(perProbeTimeoutMs !== undefined ? { timeoutMs: perProbeTimeoutMs } : {}),\n },\n resolveOpTimeout({ timeoutMs: perProbeTimeoutMs }, \"probeMs\", options.timeouts),\n runtime,\n );\n const probeStartedAt = nowMs(runtime);\n const handler = resolveHandler(tuple.route, handlers);\n const probeRoute: NormalizedRoute = { ...tuple.route, model: tuple.modelId };\n try {\n if (!handler?.generate) {\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: false,\n broken: false,\n detail: `No generate handler is registered for ${tuple.route.handlerKey}.`,\n code: \"not_supported\",\n cached: false,\n };\n }\n const output = await runPingWithAbort(probeRoute, handler.generate, abort);\n const classification = classifyProbeOutcome({\n ...(output.text !== undefined ? { text: output.text } : {}),\n ...(output.toolCalls ? { toolCalls: output.toolCalls } : {}),\n });\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: classification.ok,\n broken: classification.broken,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - probeStartedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n cached: false,\n };\n } catch (error) {\n const normalized = toAiConnectError(error);\n // A per-probe timeout/abort: ok=false, broken=false (transient), detail ~ timeout (#50).\n if (\n normalized.code === \"timeout\" ||\n normalized.code === \"aborted\"\n ) {\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: false,\n broken: false,\n detail:\n normalized.code === \"timeout\"\n ? `probe timed out after ${perProbeTimeoutMs}ms`\n : normalized.message,\n latencyMs: nowMs(runtime) - probeStartedAt,\n code: normalized.code,\n cached: false,\n };\n }\n const classification = classifyProbeOutcome({ error: normalized });\n return {\n routeId: tuple.route.id,\n modelId: tuple.modelId,\n ok: classification.ok,\n broken: classification.broken,\n detail: classification.detail,\n latencyMs: nowMs(runtime) - probeStartedAt,\n ...(classification.code ? { code: classification.code } : {}),\n ...(classification.httpStatus !== undefined\n ? { httpStatus: classification.httpStatus }\n : {}),\n cached: false,\n };\n } finally {\n disposeAbort();\n }\n },\n );\n\n // Write fresh per-route results back to the TTL cache, then assemble final emission order:\n // iterate the original `byRoute` order, emitting cached hits verbatim and fresh results once.\n const liveByRoute = new Map<string, ProbeModelResult[]>();\n for (const result of liveResults) {\n const bucket = liveByRoute.get(result.routeId);\n if (bucket) {\n bucket.push(result);\n } else {\n liveByRoute.set(result.routeId, [result]);\n }\n }\n for (const group of liveGroups) {\n const results = liveByRoute.get(group.route.id) ?? [];\n writeProbeCache(\n probeCache,\n probeCacheKey(group.route.id, group.models),\n results,\n nowMs(runtime),\n ttlMs,\n );\n }\n\n for (const group of byRoute.values()) {\n const cached = cachedRouteResults.get(group.route.id);\n const results = cached ?? liveByRoute.get(group.route.id) ?? [];\n for (const result of results) {\n emitted.push(result);\n yield result;\n }\n }\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"probeModels\",\n operation: \"probe_models\",\n runtime: runtime.kind,\n outcome: emitted.every((result) => result.ok) ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: liveGroups.map((group) => summarizeRoute(group.route)),\n attempts: [],\n probe: summarizeProbe(emitted, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n }\n\n return {\n config,\n runtime,\n listRoutes(filter): ListedRoute[] {\n return router.listRoutes(filter).map((route) => ({\n ...route,\n health: router.getHealth(route),\n }));\n },\n listPublicRoutes(filter): PublicRoute[] {\n // C7 / INV-PROJ-1: project each route through the explicit secret-free `toPublicRoute`.\n // `operation` reuses the existing router pool filter; `provider` narrows further. The\n // projection is stable under health changes \u2014 only the `health` field tracks live state.\n const operationFilter: { operation?: OperationKind } | undefined =\n filter?.operation ? { operation: filter.operation } : undefined;\n return router\n .listRoutes(operationFilter)\n .filter((route) =>\n filter?.provider ? route.provider === filter.provider : true,\n )\n .map((route) => toPublicRoute(route, router.getHealth(route).state));\n },\n listCandidateModels(filter): CandidateModel[] {\n // C9 / UR-014: the same secret-free candidate projection offered to a ModelSelector.\n return router.candidateModels(filter);\n },\n prepareFile(input) {\n return preparePortableFile(input);\n },\n resolveModelContext(\n input: ResolveModelContextInput,\n options?: ResolveModelContextOptions,\n ): ModelContextResolution {\n const { key, model } = modelContextCacheKey(input);\n const cached = modelContextCache.get(key);\n if (cached) {\n return { ...cached, cached: true };\n }\n const reference = lookupModelRef(model)?.contextLength;\n const { contextWindow, source } = resolveModelContextWindow({\n ...(options?.discovered !== undefined\n ? { discovered: options.discovered }\n : {}),\n ...(reference !== undefined ? { reference } : {}),\n ...(options?.configured !== undefined\n ? { configured: options.configured }\n : {}),\n ...(options?.defaultContextWindow !== undefined\n ? { defaultContextWindow: options.defaultContextWindow }\n : {}),\n });\n const result: ModelContextResolution = {\n contextWindow,\n source,\n model,\n cached: false,\n };\n modelContextCache.set(key, result);\n return result;\n },\n async verify(target, opts): Promise<VerificationReport> {\n const startedAt = nowMs(runtime);\n const targetIds = target?.routes?.length ? new Set(resolveRouteSelectors(target.routes, config.routes)) : undefined;\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n\n try {\n const reports: VerificationRouteReport[] = [];\n\n for (const route of config.routes) {\n if (targetIds && !targetIds.has(route.id)) {\n continue;\n }\n if (abort.signal.aborted) {\n throw mapAbortError(abort.reason);\n }\n\n const issues: VerificationIssue[] = [];\n\n if (runtime.kind === \"browser\") {\n const issue = runtimeIssue(route);\n if (issue) {\n issues.push(issue);\n }\n }\n\n for (const envName of route.verify.env) {\n const value = runtime.getEnv?.(envName);\n if (!value) {\n issues.push({\n code: \"missing_env\",\n message: `Missing required environment variable \"${envName}\" for route \"${route.id}\".`,\n });\n }\n }\n\n if (route.verify.command) {\n const hasCommand = await runtime.hasCommand?.(route.verify.command);\n if (!hasCommand) {\n issues.push({\n code: \"missing_command\",\n message: `Required command \"${route.verify.command}\" is unavailable for route \"${route.id}\".`,\n });\n }\n }\n\n if (route.verify.session && route.transport.kind === \"acp\") {\n const sessionValue = runtime.getEnv?.(route.verify.session);\n if (!sessionValue) {\n issues.push({\n code: \"missing_session\",\n message: `Missing required local session reference \"${route.verify.session}\" for route \"${route.id}\".`,\n });\n }\n }\n\n const handler = resolveHandler(route, handlers);\n if (!handler) {\n issues.push({\n code: \"handler_issue\",\n message: `No handler is registered for ${route.handlerKey}.`,\n });\n }\n const handlerIssues = await handler?.verify?.({\n route,\n runtime,\n });\n if (handlerIssues?.length) {\n issues.push(...handlerIssues);\n }\n\n reports.push({\n routeId: route.id,\n ok: issues.length === 0,\n issues,\n });\n }\n\n const report = {\n ok: reports.every((routeReport) => routeReport.ok),\n routes: reports,\n };\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId: resolveEventRequestId(target?.logContext),\n operationName: \"verify\",\n operation: \"verify\",\n runtime: runtime.kind,\n outcome: report.ok ? \"success\" : \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: config.routes.map(summarizeRoute),\n attempts: [],\n verification: summarizeVerification(report, targetIds),\n ...(target?.logContext ? { context: target.logContext } : {}),\n });\n\n return report;\n } finally {\n disposeAbort();\n }\n },\n async discoverModels(target?: DiscoverModelsTarget, opts?): Promise<AcpModelDiscoveryReport> {\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n try {\n return await executeModelDiscoveryOperation(target, {\n operationName: \"discoverModels\",\n abort,\n });\n } finally {\n disposeAbort();\n }\n },\n async discoverAcpModels(target?: DiscoverAcpModelsTarget, opts?): Promise<AcpModelDiscoveryReport> {\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"probeMs\", options.timeouts),\n runtime,\n );\n try {\n return await executeModelDiscoveryOperation(target, {\n operationName: \"discoverAcpModels\",\n acpOnly: true,\n abort,\n });\n } finally {\n disposeAbort();\n }\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1): checkHealth NEVER calls\n // router.recordFailure/recordSuccess; a diagnostic ping must not cool down a route.\n async checkHealth(target?: CheckHealthTarget): Promise<HealthReport> {\n return executeCheckHealth(target);\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1): probeModels NEVER calls\n // router.recordFailure/recordSuccess.\n async probeModels(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): Promise<ProbeModelResult[]> {\n const results: ProbeModelResult[] = [];\n for await (const result of runProbeModels(target, opts)) {\n results.push(result);\n }\n return results;\n },\n // C8 \u2014 READ-ONLY re router health (INV-PROBE-1).\n probeModelsStream(\n target?: ProbeModelsTarget,\n opts?: ProbeModelsOptions,\n ): AsyncIterable<ProbeModelResult> {\n return runProbeModels(target, opts);\n },\n async generate(request, opts): Promise<GenerateResult> {\n // pauseAsAbort: a non-streamed call cannot retain a partial, so a mid-call pause\n // degenerates to a caller abort (CD-3 / pause-degenerates-on-generate).\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"generateMs\", options.timeouts),\n runtime,\n { pauseAsAbort: true },\n );\n // C9 / R16: acquire a fan-out slot BEFORE any route/selector/health work, so a maxCalls\n // exhaustion raises `fanout_limit` ahead of route selection and never becomes route-health\n // (INV-FANOUT-1). Released in the finally regardless of outcome (never mutates the client\n // limiter for a per-request override \u2014 limiterForRequest returns a request-scoped instance).\n const limiter = limiterForRequest(request);\n // R16 leak-safety: `deriveAbort` ABOVE already registered a caller-signal\n // listener + scheduled the timeout timer, so `disposeAbort()` MUST run even\n // when `limiter.acquire()` rejects (fanout_limit / pre-aborted signal /\n // abort-while-parked). Hence acquire is INSIDE the try and `release` is\n // guarded in the finally \u2014 otherwise the listener+timer leak per call on a\n // reused caller signal.\n let release: (() => void) | undefined;\n try {\n release = await limiter.acquire(abort.signal);\n const normalizedRequest = prepareRequest(request);\n const selectedModel = await resolveSelectedModel(normalizedRequest);\n return await executeGenerateOperation(\n withSelectedModel(normalizedRequest, selectedModel),\n \"generate\",\n abort,\n );\n } finally {\n release?.();\n disposeAbort();\n }\n },\n async *stream(request, opts): AsyncIterable<GenerateStreamEvent> {\n const preparedRequest = prepareRequest(request);\n if (preparedRequest.clientTools?.length) {\n throw new AiConnectError(\n \"not_supported\",\n \"clientTools are currently supported only by generate(), not stream().\",\n );\n }\n // stream() keeps pause SEPARATE from abort: caller/timeout abort discards partials and\n // throws; a pauseSignal stops reading and yields a terminal {type:'paused'} KEEPING the\n // accumulated partial (INV-ABORT-3). So deriveAbort is built WITHOUT pauseAsAbort.\n const { abort, dispose: disposeAbort } = deriveAbort(\n opts,\n resolveOpTimeout(opts, \"generateMs\", options.timeouts),\n runtime,\n );\n const pauseSignal = abort.pauseSignal;\n // C9 / R16: acquire a fan-out slot BEFORE route selection (so fanout_limit precedes any\n // route-health work); R15: a per-request override uses a request-scoped limiter.\n const limiter = limiterForRequest(request);\n // R16 leak-safety (mirrors generate()): acquire INSIDE the try so a rejected\n // `limiter.acquire()` (fanout_limit / pre-aborted signal / abort-while-parked)\n // still reaches `disposeAbort()` in the finally and never leaks the\n // caller-signal listener + timeout timer that `deriveAbort` registered above.\n let release: (() => void) | undefined;\n let released = false;\n const releaseOnce = (): void => {\n if (!released && release) {\n released = true;\n release();\n }\n };\n try {\n release = await limiter.acquire(abort.signal);\n // C9 / OQ-11: apply the ModelSelector (explicit routeHints.model still wins) BEFORE routing.\n const selectedModel = await resolveSelectedModel(preparedRequest);\n const normalizedRequest = withSelectedModel(preparedRequest, selectedModel);\n // H1: stream() now enforces image/file capability gating exactly like\n // generate() (previously it only gated supportsToolSchema, so a PDF/image\n // attachment could reach a route that never advertised the capability).\n const { requiresImage, requiresFile, request: capabilityScopedRequest } =\n resolveRequiredCapabilities(normalizedRequest);\n const candidates = router.resolveCandidates(capabilityScopedRequest);\n const startedAt = nowMs(runtime);\n const requestId = resolveEventRequestId(normalizedRequest.logContext);\n const candidateSummaries = candidates.map(summarizeRoute);\n const requestSummary = summarizeRequest(normalizedRequest, candidateSummaries);\n const attempts: RouteAttempt[] = [];\n const wideAttempts: WideEventAttempt[] = [];\n\n if (candidates.length === 0) {\n // H1: mirror generate()'s clean capability error when the empty candidate\n // set is due to an image/file requirement no route advertises.\n const error =\n requiresImage || requiresFile\n ? new AiConnectError(\n \"unsupported_capability\",\n `No eligible route supports the required ${\n requiresFile ? \"document/file\" : \"image\"\n } input for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`,\n )\n : new AiConnectError(\"not_supported\", `No eligible routes are available for operation \"${normalizedRequest.operation}\" in runtime \"${runtime.kind}\".`);\n\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: error.code,\n message: error.message,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n\n throw error;\n }\n\n for (const route of candidates) {\n const handler = resolveHandler(route, handlers);\n if (!handler) {\n continue;\n }\n\n if (handler.stream) {\n const routeSummary = summarizeRoute(route);\n const attemptStartedAt = nowMs(runtime);\n let lastResult: GenerateResult | undefined;\n // Accumulate the partial so a pause can yield a terminal {type:'paused'} carrying\n // everything received so far, even if the producer only emitted deltas.\n let accumulatedText = \"\";\n\n // C7 / R14: inject this route's explicit per-route defaults before streaming.\n const routeRequest = applyRouteDefaults(route, normalizedRequest);\n\n const iterable = handler.stream({\n route,\n request: routeRequest,\n runtime,\n attempt: 1,\n abort,\n });\n const iterator = iterable[Symbol.asyncIterator]();\n let iteratorReturned = false;\n const returnIterator = async (): Promise<void> => {\n if (iteratorReturned) {\n return;\n }\n iteratorReturned = true;\n try {\n await iterator.return?.();\n } catch {\n // A producer that throws on return() must not mask the abort/pause outcome.\n }\n };\n\n try {\n while (true) {\n // Caller/timeout abort: discard partials, throw, close the producer exactly once.\n if (abort.signal.aborted) {\n await returnIterator();\n throw mapAbortError(abort.reason);\n }\n // Pause: stop reading, keep the accumulated partial, emit ONE terminal\n // {type:'paused'} and return without throwing.\n if (pauseSignal?.aborted) {\n await returnIterator();\n const pausedResult: GenerateResult =\n lastResult ?? {\n route,\n text: accumulatedText,\n attachments: [],\n warnings: [],\n attempts,\n };\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n });\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n result: summarizeResult(pausedResult),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n yield { type: \"paused\", result: pausedResult };\n return;\n }\n\n const next = await iterator.next();\n if (next.done) {\n break;\n }\n const event = next.value;\n if (event.type === \"delta\") {\n accumulatedText += event.text;\n yield event;\n continue;\n }\n // A producer-emitted terminal (`result` | `paused`) ends this stream:\n // yield it ONCE, then break so the post-loop success path emits the\n // wide event exactly once. Continuing the loop here would let a\n // misbehaving producer emit a SECOND terminal (double-terminal).\n lastResult = event.result;\n yield event;\n break;\n }\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"success\",\n retryCount: 0,\n });\n router.recordSuccess(route);\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"success\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n selectedRoute: routeSummary,\n request: requestSummary,\n ...(lastResult ? { result: summarizeResult(lastResult) } : {}),\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n return;\n } catch (error) {\n await returnIterator();\n const normalizedError = abort.signal.aborted\n ? mapAbortError(abort.reason)\n : toAiConnectError(error);\n attempts.push({\n routeId: route.id,\n handlerKey: route.handlerKey,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n wideAttempts.push({\n index: wideAttempts.length + 1,\n route: routeSummary,\n durationMs: nowMs(runtime) - attemptStartedAt,\n outcome: \"error\",\n retryCount: 0,\n errorCode: normalizedError.code,\n message: normalizedError.message,\n });\n // A caller/timeout abort is hard-terminal: it never rotates credentials or falls\n // back (R2). Surface it immediately rather than trying the next route.\n if (abort.signal.aborted) {\n await emitWideEvent({\n timestamp: isoTimestamp(startedAt),\n event: \"ai_connect.operation\",\n requestId,\n operationName: \"stream\",\n operation: normalizedRequest.operation,\n runtime: runtime.kind,\n outcome: \"error\",\n durationMs: nowMs(runtime) - startedAt,\n candidates: candidateSummaries,\n attempts: wideAttempts,\n request: requestSummary,\n error: {\n code: normalizedError.code,\n message: normalizedError.message,\n routeId: route.id,\n },\n ...(normalizedRequest.logContext ? { context: normalizedRequest.logContext } : {}),\n });\n throw normalizedError;\n }\n router.recordFailure(route, normalizedError.code);\n continue;\n }\n }\n\n if (handler.generate) {\n break;\n }\n }\n\n const result = await executeGenerateOperation(normalizedRequest, \"stream\", abort, {\n startMs: startedAt,\n requestId,\n candidates: candidateSummaries,\n attempts,\n wideAttempts,\n });\n yield {\n type: \"result\",\n result,\n };\n } finally {\n releaseOnce();\n disposeAbort();\n }\n },\n async dispose(): Promise<void> {\n await dispose();\n },\n };\n}\n", "import type {\n GenerateRequest,\n ImageSizePreset,\n MessageInput,\n PortableFile,\n} from \"./types.js\";\n\nexport const IMAGE_PROMPT_PROTOCOL = \"ai_connect_image_json_v1\";\nexport const DEFAULT_IMAGE_SIZE: ImageSizePreset = \"1024x1024\";\n\nexport const IMAGE_SIZE_PRESETS: Record<string, string> = {\n \"1024x1024\": \"Square (1:1) - general use\",\n \"1280x720\": \"Landscape (16:9) - presentations and video\",\n \"720x1280\": \"Portrait (9:16) - mobile and stories\",\n \"1216x896\": \"Wide (4:3) - documents and slides\",\n \"1200x1696\": \"A3 portrait print\",\n \"848x1200\": \"A4 portrait print\",\n \"600x848\": \"A5 portrait print\",\n \"424x600\": \"A6 portrait print\",\n \"597x822\": \"Mini card\",\n \"747x1122\": \"Bridge card\",\n \"822x1122\": \"Poker card\",\n \"897x1479\": \"Tarot card\",\n \"1122x1797\": \"Large card\",\n \"1536x1024\": \"Landscape high-detail\",\n \"1024x1536\": \"Portrait high-detail\",\n auto: \"Let the provider choose the canvas size\",\n};\n\nconst SYSTEM_TEMPLATE = {\n protocol: IMAGE_PROMPT_PROTOCOL,\n kind: \"system_preference\",\n generation_goal: \"image_generation\",\n policies: {\n render_only_user_content: true,\n do_not_render_structural_markers: true,\n treat_parenthetical_text_as_visual_hints: true,\n },\n};\n\nconst DEFAULT_VISUAL_RULES = [\n \"Render only semantic content, never structural labels.\",\n \"Treat parenthetical text as visual hint metadata.\",\n \"Use strong visual hierarchy and legible typography when text is required.\",\n];\n\nconst STRUCTURAL_MARKERS = new Set([\n \"\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\",\n \"\u043F\u043E\u0434\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\",\n \"\u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u044B\u0439 \u043E\u0431\u0440\u0430\u0437\",\n \"\u0431\u043B\u043E\u043A\",\n \"\u0441\u0435\u043A\u0446\u0438\u044F\",\n \"\u0440\u0430\u0437\u0434\u0435\u043B\",\n \"\u0444\u0443\u0442\u0435\u0440\",\n \"\u043F\u043E\u0434\u0432\u0430\u043B\",\n \"header\",\n \"title\",\n \"subtitle\",\n \"central image\",\n \"block\",\n \"section\",\n \"footer\",\n]);\n\nconst STRUCTURAL_PATTERNS = [\n /^\u0431\u043B\u043E\u043A\\s+\\d+:/i,\n /^\u0441\u0435\u043A\u0446\u0438\u044F\\s+\\d+:/i,\n /^\u0440\u0430\u0437\u0434\u0435\u043B\\s+\\d+:/i,\n /^block\\s+\\d+:/i,\n /^section\\s+\\d+:/i,\n];\n\nfunction tryParseJsonPayload(content: string): unknown | null {\n const stripped = content.trim();\n if (!stripped.startsWith(\"{\") && !stripped.startsWith(\"[\")) {\n return null;\n }\n\n try {\n return JSON.parse(stripped);\n } catch {\n return null;\n }\n}\n\nexport function normalizeImageSource(messages: MessageInput[]): string {\n return messages\n .map((message) => `${message.role.toUpperCase()}:\\n${message.content}`)\n .join(\"\\n\\n\");\n}\n\nexport function filterStructuralMarkers(content: string): {\n cleanContent: string;\n structure: Record<string, unknown>;\n hasStructure: boolean;\n} {\n const lines = content.split(\"\\n\");\n const cleanLines: string[] = [];\n const blocks: Array<{ name?: string; content: string[] }> = [];\n let currentBlock: { name?: string; content: string[] } | undefined;\n\n for (const originalLine of lines) {\n const trimmed = originalLine.trim();\n const lowered = trimmed.toLowerCase();\n\n if (trimmed.length === 0) {\n continue;\n }\n\n if (STRUCTURAL_MARKERS.has(lowered.replace(/:$/, \"\"))) {\n continue;\n }\n\n const matchedPattern = STRUCTURAL_PATTERNS.find((pattern) =>\n pattern.test(trimmed),\n );\n if (matchedPattern) {\n const [, blockName] = trimmed.split(\":\", 2);\n currentBlock = {\n ...(blockName?.trim() ? { name: blockName.trim() } : {}),\n content: [],\n };\n blocks.push(currentBlock);\n if (blockName?.trim()) {\n cleanLines.push(blockName.trim());\n }\n continue;\n }\n\n const cleanedLine = originalLine.replace(\n /^(\u0431\u043B\u043E\u043A|block|\u0441\u0435\u043A\u0446\u0438\u044F|section|\u0440\u0430\u0437\u0434\u0435\u043B)\\s*\\d*:\\s*/i,\n \"\",\n ).trim();\n\n if (cleanedLine.length === 0) {\n continue;\n }\n\n cleanLines.push(cleanedLine);\n currentBlock?.content.push(cleanedLine);\n }\n\n return {\n cleanContent: cleanLines.join(\"\\n\"),\n structure: {\n blocks,\n },\n hasStructure: blocks.length > 0,\n };\n}\n\nexport function buildImageSystemPreferencePayload(input: {\n size: string;\n model: string;\n rawPrompt: boolean;\n aspectRatio?: string;\n quality?: string;\n imageSize?: string;\n style?: string;\n}): Record<string, unknown> {\n return {\n ...SYSTEM_TEMPLATE,\n runtime: {\n model: input.model,\n size: input.size,\n raw_prompt_mode: input.rawPrompt,\n ...(input.aspectRatio\n ? { requested_aspect_ratio: input.aspectRatio }\n : {}),\n ...(input.quality ? { requested_quality: input.quality } : {}),\n ...(input.imageSize ? { requested_image_size: input.imageSize } : {}),\n ...(input.style ? { requested_style: input.style } : {}),\n },\n };\n}\n\nexport function buildImageUserPromptPayload(input: {\n content: string;\n size: string;\n rawPrompt: boolean;\n referenceImages: PortableFile[];\n hasSourceImage: boolean;\n hasMask: boolean;\n}): Record<string, unknown> {\n const parsed = tryParseJsonPayload(input.content);\n if (parsed !== null) {\n return {\n protocol: IMAGE_PROMPT_PROTOCOL,\n input_format: \"json\",\n task: \"generate_image\",\n canvas: { size: input.size },\n source_prompt_json: parsed,\n raw_prompt_mode: input.rawPrompt,\n reference_images_present: input.referenceImages.length > 0,\n source_image_present: input.hasSourceImage,\n mask_present: input.hasMask,\n };\n }\n\n const filtered = filterStructuralMarkers(input.content);\n return {\n protocol: IMAGE_PROMPT_PROTOCOL,\n input_format: \"text\",\n task: \"generate_image\",\n canvas: { size: input.size },\n raw_prompt_mode: input.rawPrompt,\n reference_images_present: input.referenceImages.length > 0,\n source_image_present: input.hasSourceImage,\n mask_present: input.hasMask,\n visual_rules: DEFAULT_VISUAL_RULES,\n content: {\n original_text: input.content,\n normalized_text: filtered.cleanContent,\n has_structure: filtered.hasStructure,\n structure: filtered.structure,\n },\n };\n}\n\nexport function serializeImagePayload(\n payload: Record<string, unknown>,\n): string {\n return JSON.stringify(payload, ensure_ascii_false_replacer, 0);\n}\n\nfunction ensure_ascii_false_replacer(_key: string, value: unknown): unknown {\n return value;\n}\n\nexport function buildImagePromptBundle(input: {\n request: GenerateRequest;\n model: string;\n referenceImages: PortableFile[];\n}): {\n size: string;\n systemPreference: Record<string, unknown>;\n userPrompt: Record<string, unknown>;\n prompt: string;\n} {\n const size =\n input.request.image?.size ??\n input.request.image?.aspectRatio ??\n DEFAULT_IMAGE_SIZE;\n const rawPrompt = input.request.image?.rawPrompt ?? false;\n const content = normalizeImageSource(input.request.messages);\n const systemPreference = buildImageSystemPreferencePayload({\n size,\n model: input.model,\n rawPrompt,\n ...(input.request.image?.aspectRatio\n ? { aspectRatio: input.request.image.aspectRatio }\n : {}),\n ...(input.request.image?.quality\n ? { quality: input.request.image.quality }\n : {}),\n ...(input.request.image?.imageSize\n ? { imageSize: input.request.image.imageSize }\n : {}),\n ...(input.request.image?.style ? { style: input.request.image.style } : {}),\n });\n const userPrompt = buildImageUserPromptPayload({\n content,\n size,\n rawPrompt,\n referenceImages: input.referenceImages,\n hasSourceImage: Boolean(input.request.image?.sourceImage),\n hasMask: Boolean(input.request.image?.mask),\n });\n\n return {\n size,\n systemPreference,\n userPrompt,\n prompt: JSON.stringify(\n {\n system_preference: systemPreference,\n user_prompt: userPrompt,\n },\n null,\n 0,\n ),\n };\n}\n\nfunction toPlainData(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => toPlainData(item));\n }\n\n if (typeof value === \"object\") {\n const modelDump = (value as { model_dump?: () => unknown }).model_dump;\n if (typeof modelDump === \"function\") {\n return toPlainData(modelDump());\n }\n\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n toPlainData(entry),\n ]),\n );\n }\n\n return String(value);\n}\n\nfunction normalizeImagePayloadString(payload: string): string {\n if (payload.startsWith(\"data:image/\")) {\n return payload;\n }\n\n return `data:image/png;base64,${payload}`;\n}\n\nfunction collectImagePayloads(node: unknown, out: string[]): void {\n const plain = toPlainData(node);\n\n if (Array.isArray(plain)) {\n for (const item of plain) {\n collectImagePayloads(item, out);\n }\n return;\n }\n\n if (plain && typeof plain === \"object\") {\n for (const [key, value] of Object.entries(plain as Record<string, unknown>)) {\n const lowerKey = key.toLowerCase();\n if (typeof value === \"string\") {\n if (value.startsWith(\"data:image/\")) {\n out.push(value);\n } else if (\n lowerKey === \"b64_json\" ||\n lowerKey === \"base64\" ||\n lowerKey === \"image_base64\"\n ) {\n out.push(normalizeImagePayloadString(value));\n } else if (lowerKey === \"url\" && value.startsWith(\"http\")) {\n out.push(value);\n }\n }\n\n collectImagePayloads(value, out);\n }\n }\n}\n\nexport function extractImagePayloads(...nodes: unknown[]): string[] {\n const items: string[] = [];\n for (const node of nodes) {\n collectImagePayloads(node, items);\n }\n\n return [...new Set(items)];\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport {\n inferPortableFileMimeType,\n isPortableDocumentFile,\n isPortableImageFile,\n materializePortableFile,\n portableFileRemoteUri,\n portableFileToBytes,\n portableFileToDataUrl,\n portableFileToText,\n preparePortableFile,\n} from \"./files.js\";\nimport {\n buildImagePromptBundle,\n extractImagePayloads,\n} from \"./image.js\";\nimport {\n detectModelFree,\n extractModelContextLength,\n fillConfiguredContextLength,\n parseModelPricing,\n} from \"./model-reference.js\";\nimport type {\n AcpModelCatalog,\n AcpModelInfo,\n CreateClientOptions,\n DiscoverAcpModelsContext,\n FetchLike,\n GenerateParameters,\n GenerateResponseFormat,\n GenerateContext,\n GenerateResult,\n GenerateStreamEvent,\n GenerateThinkingOptions,\n GenerateToolChoice,\n GenerateToolDefinition,\n MessageInput,\n NormalizedRoute,\n PortableFile,\n PortableFilePayload,\n RouteHandlerRegistry,\n RuntimeEnvironment,\n ToolCallInput,\n WideEventParameterSummary,\n WideEventTransportSummary,\n} from \"./types.js\";\n\nconst INLINE_ATTACHMENT_TEXT_LIMIT = 16_000;\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction appendPath(baseUrl: string, suffix: string): string {\n return `${trimTrailingSlash(baseUrl)}/${suffix.replace(/^\\/+/, \"\")}`;\n}\n\n/**\n * True when `error` is (or wraps) a cancellation \u2014 a DOM `AbortError`/`TimeoutError`\n * or our own `AiConnectError` with code `aborted`. Used by the file-upload helpers to\n * distinguish a genuine cancellation (which must propagate) from an ordinary upload\n * failure (which is swallowed so the caller falls back to inline base64).\n */\nfunction isAbortError(error: unknown): boolean {\n if (error instanceof AiConnectError) {\n return error.code === \"aborted\";\n }\n return (\n error instanceof Error &&\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n );\n}\n\n/**\n * Locate the last `user` turn in a provider conversation and return it so the caller\n * can append attachment parts to it. When there is no user turn yet, a fresh empty one\n * (built by `createEmptyUserTurn`) is pushed and returned. Shared by the OpenAI,\n * Anthropic, and Gemini request builders (SYS-7 dedup) \u2014 behavior identical to the\n * three former inline backward-scan blocks; the per-provider content merge stays with\n * each caller.\n */\nfunction attachPartsToLastUserTurn<T extends { role: string }>(\n conversation: T[],\n createEmptyUserTurn: () => T,\n): T {\n let targetIndex = -1;\n for (let index = conversation.length - 1; index >= 0; index -= 1) {\n if (conversation[index]?.role === \"user\") {\n targetIndex = index;\n break;\n }\n }\n\n if (targetIndex === -1) {\n conversation.push(createEmptyUserTurn());\n targetIndex = conversation.length - 1;\n }\n\n return conversation[targetIndex]!;\n}\n\nfunction resolveOpenAiEndpoint(\n route: NormalizedRoute,\n operation: \"text\" | \"image\",\n): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return operation === \"image\"\n ? \"https://api.openai.com/v1/images/generations\"\n : \"https://api.openai.com/v1/chat/completions\";\n }\n\n // Only honor the exact-suffix shortcut when it matches the CURRENT operation \u2014\n // a base URL ending in `/chat/completions` must not be returned verbatim for an\n // image request (and vice-versa); otherwise the wrong endpoint is hit.\n if (\n (operation === \"text\" && configured.endsWith(\"/chat/completions\")) ||\n (operation === \"image\" && configured.endsWith(\"/images/generations\"))\n ) {\n return configured;\n }\n\n return appendPath(\n configured,\n operation === \"image\" ? \"/images/generations\" : \"/chat/completions\",\n );\n}\n\nfunction resolveOpenAiImageEditEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.openai.com/v1/images/edits\";\n }\n\n if (configured.endsWith(\"/images/edits\")) {\n return configured;\n }\n if (configured.endsWith(\"/images/generations\")) {\n return `${configured.slice(0, -\"/images/generations\".length)}/images/edits`;\n }\n\n return appendPath(configured, \"/images/edits\");\n}\n\nfunction resolveOpenAiModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.openai.com/v1/models\";\n }\n\n if (configured.endsWith(\"/models\")) {\n return configured;\n }\n if (configured.endsWith(\"/chat/completions\")) {\n return `${configured.slice(0, -\"/chat/completions\".length)}/models`;\n }\n if (configured.endsWith(\"/images/generations\")) {\n return `${configured.slice(0, -\"/images/generations\".length)}/models`;\n }\n\n return appendPath(configured, \"/models\");\n}\n\nfunction resolveAnthropicEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.anthropic.com/v1/messages\";\n }\n\n if (configured.endsWith(\"/messages\")) {\n return configured;\n }\n\n return appendPath(configured, \"/messages\");\n}\n\nfunction resolveAnthropicModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://api.anthropic.com/v1/models\";\n }\n\n if (configured.endsWith(\"/models\")) {\n return configured;\n }\n if (configured.endsWith(\"/messages\")) {\n return `${configured.slice(0, -\"/messages\".length)}/models`;\n }\n\n return appendPath(configured, \"/models\");\n}\n\n/**\n * Header used to authenticate Gemini REST calls WITHOUT placing the API key in\n * the URL (SEC: Gemini key leak). The endpoint string flows unredacted into the\n * wide-event `transportSummary.endpoint`; carrying the key in the URL `?key=`\n * query param would emit it to the logger. The `x-goog-api-key` request header\n * is the Google-supported alternative that keeps the secret out of telemetry.\n */\nconst GEMINI_API_KEY_HEADER = \"x-goog-api-key\";\n\n/**\n * Build the `x-goog-api-key` header bag for Gemini REST transports. The key is\n * delivered out-of-band of the URL so it never reaches the wide-event endpoint.\n */\nfunction geminiApiKeyHeaders(apiKey: string): Record<string, string> {\n return { [GEMINI_API_KEY_HEADER]: apiKey };\n}\n\nfunction resolveGeminiTextEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return `https://generativelanguage.googleapis.com/v1beta/models/${route.model}:generateContent`;\n }\n\n if (configured.includes(\"{model}\")) {\n return configured.replaceAll(\"{model}\", route.model);\n }\n if (!configured.endsWith(\":generateContent\")) {\n return appendPath(configured, `${route.model}:generateContent`);\n }\n\n return configured;\n}\n\nfunction resolveGeminiModelsEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/models\";\n }\n\n let url = trimTrailingSlash(configured);\n const modelPlaceholderIndex = url.indexOf(\"{model}\");\n if (modelPlaceholderIndex >= 0) {\n url = trimTrailingSlash(url.slice(0, modelPlaceholderIndex));\n } else if (url.endsWith(\":generateContent\")) {\n url = url.replace(/\\/[^/?#]+:generateContent$/, \"\");\n }\n\n return url.endsWith(\"/models\") ? url : appendPath(url, \"/models\");\n}\n\nfunction resolveGeminiImageEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/openai/images/generations\";\n }\n\n if (configured.endsWith(\"/openai/images/generations\")) {\n return configured;\n }\n\n const normalized = trimTrailingSlash(configured);\n if (normalized.endsWith(\"/v1beta/models\")) {\n return `${normalized.slice(0, -\"/v1beta/models\".length)}/v1/images/generations`;\n }\n if (normalized.endsWith(\"/models\")) {\n return `${normalized.slice(0, -\"/models\".length)}/images/generations`;\n }\n\n return appendPath(normalized, \"/openai/images/generations\");\n}\n\nfunction resolveGeminiImageEditEndpoint(route: NormalizedRoute): string {\n const configured = route.transport.baseUrl?.trim();\n if (!configured) {\n return \"https://generativelanguage.googleapis.com/v1beta/openai/images/edits\";\n }\n\n if (configured.endsWith(\"/openai/images/edits\")) {\n return configured;\n }\n if (configured.endsWith(\"/openai/images/generations\")) {\n return `${configured.slice(0, -\"/openai/images/generations\".length)}/openai/images/edits`;\n }\n\n const normalized = trimTrailingSlash(configured);\n if (normalized.endsWith(\"/v1beta/models\")) {\n return `${normalized.slice(0, -\"/v1beta/models\".length)}/v1/images/edits`;\n }\n if (normalized.endsWith(\"/models\")) {\n return `${normalized.slice(0, -\"/models\".length)}/images/edits`;\n }\n\n return appendPath(normalized, \"/openai/images/edits\");\n}\n\nfunction getFetch(fetchImpl?: FetchLike): FetchLike {\n if (fetchImpl) {\n return fetchImpl;\n }\n\n if (typeof fetch === \"function\") {\n return fetch;\n }\n\n throw new AiConnectError(\n \"not_supported\",\n \"No fetch implementation is available for API transports.\",\n );\n}\n\nfunction resolveApiKey(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n): string {\n if (route.credential.apiKey) {\n return route.credential.apiKey;\n }\n\n if (route.credential.apiKeyEnv) {\n const value = runtime.getEnv?.(route.credential.apiKeyEnv);\n if (value) {\n return value;\n }\n }\n\n throw new AiConnectError(\n \"auth_error\",\n `No API key is available for route \"${route.id}\".`,\n );\n}\n\nasync function readPayload(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n}\n\n/** Max levels of nested `.error` / `.message` unwrap (R20 / INV-ROBUST-1). */\nconst PAYLOAD_MESSAGE_MAX_DEPTH = 3;\n\n/**\n * Parse a message string ONE level deeper iff it is itself JSON encoding an\n * object that carries `error`/`message` (the \"double-JSON-decode\" of an error\n * string, R20). Primitives, arrays, and plain objects WITHOUT error/message are\n * left verbatim \u2014 the caller keeps the original string. Never throws.\n */\nfunction decodeErrorMessageString(value: string): unknown {\n const trimmed = value.trim();\n // Cheap pre-filter: only attempt JSON.parse on something object-shaped.\n if (!trimmed.startsWith(\"{\")) {\n return undefined;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n return undefined;\n }\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const record = parsed as Record<string, unknown>;\n if (\"error\" in record || \"message\" in record) {\n return parsed;\n }\n }\n return undefined;\n}\n\n/**\n * Depth-bounded (\u22643 levels), cycle-safe recursive unwrap of a provider error\n * payload to its most specific human-readable message (R20 / INV-ROBUST-1).\n *\n * - Strings are returned verbatim UNLESS they are themselves JSON carrying\n * `.error`/`.message`, in which case they are decoded ONCE (the single\n * double-JSON-decode) and the unwrap continues on the decoded object.\n * - Objects are unwrapped via `.message` then `.error` (string or nested\n * object), recursing with a decremented depth budget.\n * - Bounded by `depth` and a `seen` set, so cyclic / pathological inputs\n * terminate; never throws. Returns `undefined` so the caller can fall back\n * to the status-text message.\n */\nfunction unwrapPayloadMessage(\n value: unknown,\n depth: number,\n seen: Set<object>,\n decodeBudget: { value: number },\n): string | undefined {\n // A string is a terminal leaf \u2014 evaluable at ANY remaining depth (depth\n // counts OBJECT-nesting levels, not string leaves).\n if (typeof value === \"string\") {\n if (value.trim().length === 0) {\n return undefined;\n }\n // Single double-JSON-decode: if the string is itself JSON carrying\n // error/message, decode it ONCE (consuming the shared budget) and recurse\n // into the decoded object. The decode does not consume an object-depth\n // level; it is bounded independently by `decodeBudget`.\n if (decodeBudget.value > 0) {\n const decoded = decodeErrorMessageString(value);\n if (decoded !== undefined) {\n decodeBudget.value -= 1;\n const fromDecoded = unwrapPayloadMessage(\n decoded,\n depth,\n seen,\n decodeBudget,\n );\n if (fromDecoded !== undefined) {\n return fromDecoded;\n }\n }\n }\n return value;\n }\n\n // Object-nesting budget exhausted \u21D2 stop (status-text fallback).\n if (depth < 0) {\n return undefined;\n }\n\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n // Cycle guard: a value already on the current unwrap path is not revisited.\n if (seen.has(value as object)) {\n return undefined;\n }\n seen.add(value as object);\n\n const record = value as Record<string, unknown>;\n\n const directMessage = record.message;\n if (directMessage !== undefined) {\n const message = unwrapPayloadMessage(\n directMessage,\n depth - 1,\n seen,\n decodeBudget,\n );\n if (message !== undefined) {\n return message;\n }\n }\n\n const errorValue = record.error;\n if (errorValue !== undefined) {\n const message = unwrapPayloadMessage(\n errorValue,\n depth - 1,\n seen,\n decodeBudget,\n );\n if (message !== undefined) {\n return message;\n }\n }\n }\n\n return undefined;\n}\n\nfunction payloadMessage(payload: unknown): string | undefined {\n return unwrapPayloadMessage(payload, PAYLOAD_MESSAGE_MAX_DEPTH, new Set(), {\n value: 1,\n });\n}\n\nfunction classifyApiError(\n provider: string,\n response: Response,\n payload: unknown,\n): AiConnectError {\n const message =\n payloadMessage(payload) ??\n `${provider} API request failed with status ${response.status}.`;\n const normalized = message.toLowerCase();\n // CD-7: carry the raw HTTP status on EVERY constructed error so Health's `classifyProbeOutcome`\n // can derive `broken` (400\u2264s<500\u2227\u2260429). Harmless to other consumers \u2014 Robustness keys off the\n // message, never the status, so the two never conflict.\n const details = { httpStatus: response.status };\n\n if (response.status === 429) {\n if (normalized.includes(\"quota\")) {\n return new AiConnectError(\"quota_exhausted\", message, details);\n }\n return new AiConnectError(\"rate_limit\", message, details);\n }\n\n if (response.status === 401 || response.status === 403) {\n if (normalized.includes(\"quota\")) {\n return new AiConnectError(\"quota_exhausted\", message, details);\n }\n return new AiConnectError(\"auth_error\", message, details);\n }\n\n if (response.status === 404) {\n return new AiConnectError(\"not_supported\", message, details);\n }\n\n if (response.status >= 500) {\n return new AiConnectError(\"temporary_unavailable\", message, details);\n }\n\n return new AiConnectError(\"validation_error\", message, details);\n}\n\n/** Tokens that mark a 400 as a response_format / structured-output rejection. */\nconst RESPONSE_FORMAT_REJECTION_TOKENS = [\n \"response_format\",\n \"response format\",\n \"json_schema\",\n \"json schema\",\n \"schema\",\n \"strict\",\n] as const;\n\n/**\n * True ONLY when `response` is a 400 whose `message` references one of the\n * response_format / json_schema / schema / strict tokens (R21 / INV-ROBUST-1).\n *\n * R21 also requires the request to have actually carried `response_format`; the\n * caller (`runOpenAi`) enforces that precondition by only consulting this gate\n * when it added `response_format` to the request body \u2014 so this predicate is\n * narrow (400 + specific token) and never mis-fires on unrelated validation\n * errors that merely contain the generic word \"schema\" on a non-400 status.\n */\nfunction isResponseFormatRejection(\n response: Response,\n message: string,\n): boolean {\n if (response.status !== 400) {\n return false;\n }\n const normalized = message.toLowerCase();\n return RESPONSE_FORMAT_REJECTION_TOKENS.some((token) =>\n normalized.includes(token),\n );\n}\n\nfunction truncateInlineText(content: string): string {\n if (content.length <= INLINE_ATTACHMENT_TEXT_LIMIT) {\n return content;\n }\n\n return `${content.slice(0, INLINE_ATTACHMENT_TEXT_LIMIT)}\\n...[truncated]`;\n}\n\nfunction attachmentDescriptor(file: PortableFile): string {\n const uri = portableFileRemoteUri(file);\n if (uri) {\n return uri;\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n return file.source;\n }\n\n return file.name;\n}\n\ntype OpenAiContentPart =\n | { type: \"text\"; text: string }\n | { type: \"image_url\"; image_url: { url: string } }\n // C6: OpenAI file input \u2014 base64 (file_data + filename) for inline, or an\n // uploaded Files-API id (file_id). Used for PDF documents.\n | {\n type: \"file\";\n file: { file_id?: string; file_data?: string; filename?: string };\n };\n\ntype AnthropicContentPart =\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: Record<string, unknown> }\n | { type: \"tool_result\"; tool_use_id: string; content: string; is_error?: boolean }\n | {\n type: \"image\";\n source: {\n type: \"base64\";\n media_type: string;\n data: string;\n };\n }\n // C6: Anthropic document block \u2014 base64 (inline), file (Files-API id), or url\n // (remote). media_type is application/pdf for PDFs.\n | {\n type: \"document\";\n source:\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | { type: \"url\"; url: string };\n };\n\ntype GeminiPart =\n | { text: string }\n | { functionCall: { name: string; args: Record<string, unknown> } }\n | { functionResponse: { name: string; response: Record<string, unknown> } }\n | {\n inlineData: {\n mimeType: string;\n data: string;\n };\n }\n // C6: Gemini File API reference \u2014 used for documents/images uploaded to the\n // File API (or remote references with a fileUri).\n | {\n fileData: {\n mimeType: string;\n fileUri: string;\n };\n };\n\nconst TRANSPORT_CONTENT_KEYS = new Set([\n \"messages\",\n \"contents\",\n \"systemInstruction\",\n \"prompt\",\n \"input\",\n]);\n\nfunction hasAssistantToolCalls(\n message: MessageInput,\n): message is MessageInput & { role: \"assistant\"; toolCalls: ToolCallInput[] } {\n return (\n message.role === \"assistant\" &&\n Array.isArray(message.toolCalls) &&\n message.toolCalls.length > 0\n );\n}\n\nfunction isToolMessage(\n message: MessageInput,\n): message is MessageInput & {\n role: \"tool\";\n toolCallId: string;\n toolName?: string;\n} {\n return message.role === \"tool\" && typeof message.toolCallId === \"string\";\n}\n\nfunction parseToolArguments(\n value: unknown,\n provider: string,\n toolName: string,\n): Record<string, unknown> {\n if (isRecord(value)) {\n return value;\n }\n\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (!trimmed) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(trimmed);\n if (isRecord(parsed)) {\n return parsed;\n }\n } catch {\n // fall through\n }\n }\n\n throw new AiConnectError(\n \"validation_error\",\n `${provider} returned invalid tool arguments for \"${toolName}\".`,\n );\n}\n\nfunction openAiToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const calls =\n (payload as {\n choices?: Array<{\n message?: {\n tool_calls?: Array<{\n id?: unknown;\n function?: {\n name?: unknown;\n arguments?: unknown;\n };\n }>;\n };\n }>;\n })?.choices?.[0]?.message?.tool_calls ?? [];\n\n return calls.flatMap((call, index) => {\n const name =\n typeof call?.function?.name === \"string\" ? call.function.name.trim() : \"\";\n if (!name) {\n return [];\n }\n\n return [\n {\n id:\n typeof call.id === \"string\" && call.id.trim().length > 0\n ? call.id\n : `openai-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(\n call.function?.arguments,\n \"OpenAI-compatible API\",\n name,\n ),\n },\n ];\n });\n}\n\nfunction anthropicToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const parts =\n (payload as {\n content?: Array<{\n type?: unknown;\n id?: unknown;\n name?: unknown;\n input?: unknown;\n }>;\n })?.content ?? [];\n\n return parts.flatMap((part, index) => {\n if (part?.type !== \"tool_use\" || typeof part.name !== \"string\") {\n return [];\n }\n\n const name = part.name.trim();\n if (!name) {\n return [];\n }\n\n return [\n {\n id:\n typeof part.id === \"string\" && part.id.trim().length > 0\n ? part.id\n : `anthropic-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(part.input, \"Anthropic API\", name),\n },\n ];\n });\n}\n\nfunction geminiToolCallsFromPayload(payload: unknown): ToolCallInput[] {\n const parts =\n (payload as {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n functionCall?: {\n name?: unknown;\n args?: unknown;\n };\n }>;\n };\n }>;\n })?.candidates?.[0]?.content?.parts ?? [];\n\n return parts.flatMap((part, index) => {\n const name =\n typeof part?.functionCall?.name === \"string\"\n ? part.functionCall.name.trim()\n : \"\";\n if (!name) {\n return [];\n }\n\n return [\n {\n id: `gemini-tool-call-${index + 1}`,\n name,\n arguments: parseToolArguments(part.functionCall?.args, \"Gemini API\", name),\n },\n ];\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction sortedKeys(value: unknown): string[] {\n return isRecord(value) ? Object.keys(value).sort() : [];\n}\n\nfunction metadataFromRecord(\n value: Record<string, unknown>,\n omittedKeys: string[],\n): Record<string, unknown> | undefined {\n const metadata = Object.fromEntries(\n Object.entries(value).filter(\n ([key, entryValue]) =>\n !omittedKeys.includes(key) && entryValue !== undefined,\n ),\n );\n\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction summarizeToolChoice(\n choice: GenerateToolChoice | undefined,\n): string | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (typeof choice === \"string\") {\n return choice;\n }\n\n return choice.type === \"function\" ? `function:${choice.name}` : undefined;\n}\n\nfunction summarizeParameters(\n parameters: GenerateParameters | undefined,\n): WideEventParameterSummary | undefined {\n if (!parameters) {\n return undefined;\n }\n\n const stopCount = Array.isArray(parameters.stop)\n ? parameters.stop.length\n : typeof parameters.stop === \"string\"\n ? 1\n : undefined;\n const thinkingMode =\n parameters.thinking?.mode ??\n (parameters.thinking?.enabled === true\n ? \"enabled\"\n : parameters.thinking?.enabled === false\n ? \"disabled\"\n : undefined);\n const providerOptionKeys = Object.fromEntries(\n Object.entries(parameters.providerOptions ?? {})\n .filter((entry): entry is [string, Record<string, unknown>] =>\n Boolean(entry[1]),\n )\n .map(([providerId, value]) => [providerId, Object.keys(value).sort()]),\n );\n const toolChoice = summarizeToolChoice(parameters.toolChoice);\n\n return {\n keys: Object.keys(parameters).sort(),\n ...(parameters.maxTokens !== undefined\n ? { maxTokens: parameters.maxTokens }\n : {}),\n ...(parameters.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopCount !== undefined ? { stopCount } : {}),\n ...(parameters.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters.candidateCount !== undefined\n ? { candidateCount: parameters.candidateCount }\n : {}),\n ...(parameters.presencePenalty !== undefined\n ? { presencePenalty: parameters.presencePenalty }\n : {}),\n ...(parameters.frequencyPenalty !== undefined\n ? { frequencyPenalty: parameters.frequencyPenalty }\n : {}),\n ...(parameters.responseFormat\n ? { responseFormatType: parameters.responseFormat.type }\n : {}),\n ...(parameters.tools ? { toolCount: parameters.tools.length } : {}),\n ...(toolChoice ? { toolChoice } : {}),\n ...(parameters.parallelToolCalls !== undefined\n ? { parallelToolCalls: parameters.parallelToolCalls }\n : {}),\n ...(thinkingMode ? { thinkingMode } : {}),\n ...(parameters.thinking?.budgetTokens !== undefined\n ? { thinkingBudgetTokens: parameters.thinking.budgetTokens }\n : {}),\n ...(parameters.thinking?.effort\n ? { thinkingEffort: parameters.thinking.effort }\n : {}),\n ...(parameters.thinking?.includeThoughts !== undefined\n ? { includeThoughts: parameters.thinking.includeThoughts }\n : {}),\n ...(parameters.safetySettings\n ? { safetySettingsCount: parameters.safetySettings.length }\n : {}),\n ...(parameters.metadata\n ? { metadataKeys: Object.keys(parameters.metadata).sort() }\n : {}),\n ...(parameters.extra\n ? { extraKeys: Object.keys(parameters.extra).sort() }\n : {}),\n ...(Object.keys(providerOptionKeys).length > 0\n ? { providerOptionKeys }\n : {}),\n };\n}\n\nfunction providerExtra(\n context: GenerateContext,\n): Record<string, unknown> | undefined {\n const extra = context.request.parameters?.extra;\n const providerOptions =\n context.request.parameters?.providerOptions?.[context.route.provider];\n\n if (!extra && !providerOptions) {\n return undefined;\n }\n\n return {\n ...(extra ?? {}),\n ...(providerOptions ?? {}),\n };\n}\n\nfunction captureTransport(\n context: GenerateContext,\n summary: Omit<WideEventTransportSummary, \"parameters\">,\n): void {\n const parameters = summarizeParameters(context.request.parameters);\n context.telemetry?.captureTransport({\n ...summary,\n ...(parameters ? { parameters } : {}),\n });\n}\n\nfunction captureDiscoveryTransport(\n context: DiscoverAcpModelsContext,\n summary: Omit<WideEventTransportSummary, \"parameters\">,\n): void {\n context.telemetry?.captureTransport(summary);\n}\n\nfunction transportSummary(\n context: GenerateContext,\n protocol: string,\n endpoint: string,\n method: string,\n stream: boolean,\n body: Record<string, unknown>,\n): void {\n const bodyKeys = Object.keys(body).sort();\n captureTransport(context, {\n protocol,\n endpoint,\n method,\n stream,\n bodyKeys,\n parameterKeys: bodyKeys.filter((key) => !TRANSPORT_CONTENT_KEYS.has(key)),\n });\n}\n\nfunction discoveryTransportSummary(\n context: DiscoverAcpModelsContext,\n protocol: string,\n endpoint: string,\n method: string,\n): void {\n captureDiscoveryTransport(context, {\n protocol,\n endpoint,\n method,\n stream: false,\n bodyKeys: [],\n parameterKeys: [],\n });\n}\n\nexport function currentModelIdForRoute(\n route: NormalizedRoute,\n modelIds: string[],\n): string | undefined {\n return modelIds.includes(route.model) ? route.model : undefined;\n}\n\nfunction canonicalGeminiImageModelId(modelId: string | undefined): string | undefined {\n if (!modelId) {\n return undefined;\n }\n\n return modelId.toLowerCase().includes(\"image\")\n ? \"gemini-3-pro-image\"\n : undefined;\n}\n\nexport function buildModelCatalog(\n route: NormalizedRoute,\n availableModels: AcpModelInfo[],\n currentModelId?: string,\n): AcpModelCatalog {\n const requestedModelId = route.model;\n // GAP-A (TASK-028 / UR-002): surface the route's configured contextWindow onto\n // entries that have no discovered contextLength. Monotonic + configured-only,\n // so live values are never overwritten. This single call covers the API\n // providers AND the cli static/command discovery paths, which both route\n // through buildModelCatalog.\n const filledModels = fillConfiguredContextLength(route, availableModels);\n const requestedModelAdvertised = filledModels.some(\n (model) => model.modelId === requestedModelId,\n );\n const canonicalModelId =\n route.provider === \"gemini\"\n ? canonicalGeminiImageModelId(requestedModelId)\n : undefined;\n const resolvedModelId = requestedModelAdvertised\n ? requestedModelId\n : canonicalModelId &&\n filledModels.some((model) => model.modelId === canonicalModelId)\n ? canonicalModelId\n : undefined;\n\n return {\n requestedModelId,\n requestedModelAdvertised,\n ...(canonicalModelId ? { canonicalModelId } : {}),\n ...(resolvedModelId ? { resolvedModelId } : {}),\n ...(currentModelId ? { currentModelId } : {}),\n availableModels: filledModels,\n };\n}\n\nfunction parseOpenAiModelCatalog(\n route: NormalizedRoute,\n payload: unknown,\n): AcpModelCatalog {\n const data = isRecord(payload) && Array.isArray(payload.data) ? payload.data : [];\n const availableModels = data.flatMap((entry) => {\n if (!isRecord(entry) || typeof entry.id !== \"string\") {\n return [];\n }\n\n const metadata = metadataFromRecord(entry, [\n \"id\",\n \"name\",\n \"display_name\",\n \"description\",\n ]);\n\n const contextLength = extractModelContextLength(entry);\n const pricing = parseModelPricing(entry);\n const free = detectModelFree(entry.id, pricing, entry);\n\n return [\n {\n modelId: entry.id,\n name:\n typeof entry.display_name === \"string\"\n ? entry.display_name\n : typeof entry.name === \"string\"\n ? entry.name\n : entry.id,\n ...(typeof entry.description === \"string\"\n ? { description: entry.description }\n : {}),\n ...(contextLength !== undefined\n ? { contextLength, contextWindowSource: \"discovered\" as const }\n : {}),\n ...(pricing ? { pricing } : {}),\n ...(free ? { free } : {}),\n ...(metadata\n ? {\n metadata,\n }\n : {}),\n },\n ];\n });\n const currentModelId = currentModelIdForRoute(\n route,\n availableModels.map((model) => model.modelId),\n );\n\n return buildModelCatalog(route, availableModels, currentModelId);\n}\n\nfunction parseGeminiModelId(value: string): string {\n return value.startsWith(\"models/\") ? value.slice(\"models/\".length) : value;\n}\n\nfunction parseGeminiModelCatalog(\n route: NormalizedRoute,\n payload: unknown,\n): AcpModelCatalog {\n const models =\n isRecord(payload) && Array.isArray(payload.models) ? payload.models : [];\n const availableModels = models.flatMap((entry) => {\n if (!isRecord(entry) || typeof entry.name !== \"string\") {\n return [];\n }\n\n const modelId = parseGeminiModelId(entry.name);\n const canonicalModelId = canonicalGeminiImageModelId(modelId);\n const metadata = metadataFromRecord(entry, [\n \"name\",\n \"displayName\",\n \"description\",\n ]);\n return [\n {\n modelId,\n name:\n typeof entry.displayName === \"string\"\n ? entry.displayName\n : modelId,\n ...(typeof entry.description === \"string\"\n ? { description: entry.description }\n : {}),\n ...(canonicalModelId && canonicalModelId !== modelId\n ? { canonicalModelId }\n : {}),\n ...(metadata\n ? {\n metadata,\n }\n : {}),\n },\n ];\n });\n const currentModelId = currentModelIdForRoute(\n route,\n availableModels.map((model) => model.modelId),\n );\n\n return buildModelCatalog(route, availableModels, currentModelId);\n}\n\nasync function discoverOpenAiModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveOpenAiModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"openai-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n },\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"openai\", response, payload);\n }\n\n return parseOpenAiModelCatalog(context.route, payload);\n}\n\nasync function discoverAnthropicModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveAnthropicModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"anthropic-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: {\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"anthropic\", response, payload);\n }\n\n return parseOpenAiModelCatalog(context.route, payload);\n}\n\nasync function discoverGeminiModels(\n fetchImpl: FetchLike,\n context: DiscoverAcpModelsContext,\n): Promise<AcpModelCatalog> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const endpoint = resolveGeminiModelsEndpoint(context.route);\n discoveryTransportSummary(context, \"gemini-models\", endpoint, \"GET\");\n const response = await fetchImpl(endpoint, {\n method: \"GET\",\n headers: geminiApiKeyHeaders(apiKey),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(context.route.provider, response, payload);\n }\n\n return parseGeminiModelCatalog(context.route, payload);\n}\n\nfunction openAiToolChoice(\n choice: GenerateToolChoice | undefined,\n): GenerateToolChoice | undefined {\n return choice;\n}\n\nfunction anthropicToolChoice(\n choice: GenerateToolChoice | undefined,\n): Record<string, unknown> | undefined {\n if (!choice || choice === \"none\") {\n return undefined;\n }\n\n if (choice === \"auto\") {\n return { type: \"auto\" };\n }\n\n if (choice === \"required\") {\n return { type: \"any\" };\n }\n\n if (choice.type === \"function\") {\n return { type: \"tool\", name: choice.name };\n }\n\n return undefined;\n}\n\nfunction geminiToolConfig(\n choice: GenerateToolChoice | undefined,\n): Record<string, unknown> | undefined {\n if (!choice) {\n return undefined;\n }\n\n if (choice === \"auto\") {\n return { functionCallingConfig: { mode: \"AUTO\" } };\n }\n\n if (choice === \"required\") {\n return { functionCallingConfig: { mode: \"ANY\" } };\n }\n\n if (choice === \"none\") {\n return { functionCallingConfig: { mode: \"NONE\" } };\n }\n\n if (choice.type === \"function\") {\n return {\n functionCallingConfig: {\n mode: \"ANY\",\n allowedFunctionNames: [choice.name],\n },\n };\n }\n\n return undefined;\n}\n\nfunction openAiTools(\n tools: GenerateToolDefinition[] | undefined,\n): GenerateToolDefinition[] | undefined {\n return tools;\n}\n\nfunction anthropicTools(\n tools: GenerateToolDefinition[] | undefined,\n): Array<Record<string, unknown>> | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n\n return tools.map((tool) => ({\n name: tool.function.name,\n ...(tool.function.description\n ? { description: tool.function.description }\n : {}),\n input_schema: tool.function.parameters ?? {\n type: \"object\",\n properties: {},\n },\n }));\n}\n\nfunction geminiTools(\n tools: GenerateToolDefinition[] | undefined,\n): Array<Record<string, unknown>> | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n\n return [\n {\n functionDeclarations: tools.map((tool) => ({\n name: tool.function.name,\n ...(tool.function.description\n ? { description: tool.function.description }\n : {}),\n parameters: tool.function.parameters ?? {\n type: \"object\",\n properties: {},\n },\n })),\n },\n ];\n}\n\nfunction openAiResponseFormat(\n format: GenerateResponseFormat | undefined,\n): unknown {\n if (!format || format.type === \"text\") {\n return undefined;\n }\n\n if (format.type === \"json_object\") {\n return { type: \"json_object\" };\n }\n\n if (format.type === \"json_schema\") {\n return {\n type: \"json_schema\",\n json_schema: {\n name: format.name ?? \"response\",\n schema: format.schema,\n // Conditional spread: forward `strict` ONLY when the caller set it, so\n // the wire body omits the field entirely when undefined (INV-ROBUST-1).\n ...(format.strict !== undefined ? { strict: format.strict } : {}),\n },\n };\n }\n\n return format.value;\n}\n\nfunction geminiResponseFormat(\n format: GenerateResponseFormat | undefined,\n): Record<string, unknown> | undefined {\n if (!format || format.type === \"text\") {\n return undefined;\n }\n\n if (format.type === \"json_object\") {\n return {\n responseMimeType: \"application/json\",\n };\n }\n\n if (format.type === \"json_schema\") {\n return {\n responseMimeType: \"application/json\",\n responseSchema: format.schema,\n };\n }\n\n return isRecord(format.value) ? format.value : undefined;\n}\n\nfunction normalizeThinkingMode(\n thinking: GenerateThinkingOptions | undefined,\n): \"enabled\" | \"disabled\" | \"adaptive\" | undefined {\n if (!thinking) {\n return undefined;\n }\n\n if (thinking.mode) {\n return thinking.mode;\n }\n\n if (thinking.enabled === true) {\n return \"enabled\";\n }\n\n if (thinking.enabled === false) {\n return \"disabled\";\n }\n\n return undefined;\n}\n\nfunction openAiThinking(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n const mode = normalizeThinkingMode(thinking);\n if (!thinking || !mode) {\n return undefined;\n }\n\n return {\n type: mode,\n ...(thinking.budgetTokens !== undefined\n ? { budget_tokens: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n ...(thinking.includeThoughts !== undefined\n ? { includeThoughts: thinking.includeThoughts }\n : {}),\n };\n}\n\nfunction anthropicThinking(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n const mode = normalizeThinkingMode(thinking);\n if (!thinking || !mode || mode === \"disabled\") {\n return undefined;\n }\n\n return {\n type: mode,\n ...(thinking.budgetTokens !== undefined\n ? { budget_tokens: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n };\n}\n\nfunction geminiThinkingConfig(\n thinking: GenerateThinkingOptions | undefined,\n): Record<string, unknown> | undefined {\n if (!thinking) {\n return undefined;\n }\n\n const mode = normalizeThinkingMode(thinking);\n const config: Record<string, unknown> = {\n ...(thinking.includeThoughts !== undefined\n ? { includeThoughts: thinking.includeThoughts }\n : {}),\n ...(thinking.budgetTokens !== undefined\n ? { thinkingBudget: thinking.budgetTokens }\n : {}),\n ...(thinking.effort ? { effort: thinking.effort } : {}),\n };\n\n if (mode === \"disabled\") {\n config.includeThoughts = false;\n } else if (mode && mode !== \"enabled\") {\n config.thinkingType = mode;\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\nfunction stopSequences(\n stop: GenerateParameters[\"stop\"],\n): string[] | undefined {\n if (!stop) {\n return undefined;\n }\n\n return Array.isArray(stop) ? stop : [stop];\n}\n\n/**\n * Optional uploader threaded into the attachment builders (C6 / OQ-9). When\n * present, oversize documents are uploaded to the provider Files API and\n * referenced by id; when absent (or for small documents), the inline base64 path\n * is used. Kept OPTIONAL so existing handler call sites stay source-compatible.\n */\ninterface AttachmentUploader {\n fetchImpl: FetchLike;\n context: GenerateContext;\n apiKey: string;\n /** Sink for size-guard / upload-failure warnings surfaced on the result. */\n warnings: string[];\n}\n\n/**\n * Inline-base64 size guard (OQ-9). Documents whose decoded base64 length is at or\n * below this threshold ride inline; larger ones attempt a Files-API upload (when\n * an uploader is threaded). base64 length \u2248 4/3 of byte length, so ~5MB of base64\n * \u2248 ~3.75MB of bytes \u2014 comfortably under every provider's inline cap while\n * keeping the inline request small. Anthropic inline PDF cap is 32MB, OpenAI ~?,\n * Gemini ~20MB; the guard is conservative and identical across providers for\n * deterministic routing (the upload path is purely additive).\n */\nconst INLINE_DOCUMENT_BASE64_LIMIT = 4_500_000;\n\nfunction isOversizeDocument(payload: PortableFilePayload): boolean {\n return (\n payload.base64 !== undefined &&\n payload.base64.length > INLINE_DOCUMENT_BASE64_LIMIT\n );\n}\n\nfunction base64ToBlob(base64: string, mimeType: string): Blob {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return new Blob([bytes], { type: mimeType });\n}\n\nfunction recordOf(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n}\n\n/**\n * Upload a materialized document to the Anthropic Files API (beta\n * `files-api-2025-04-14`) and return the `file_id`, or `undefined` on any\n * failure (the caller falls back to inline base64 + a size warning). Threads the\n * abort signal (C2b parity). Verified shape: `POST /v1/files` multipart `file`\n * field \u2192 response `.id`.\n */\nasync function uploadAnthropicFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n const root = base\n ? trimTrailingSlash(base).replace(/\\/(messages|models)$/, \"\")\n : \"https://api.anthropic.com/v1\";\n const endpoint = appendPath(root, \"/files\");\n const form = new FormData();\n form.append(\n \"file\",\n base64ToBlob(payload.base64, payload.mimeType),\n payload.name,\n );\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"x-api-key\": uploader.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"anthropic-beta\": \"files-api-2025-04-14\",\n },\n body: form,\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const id = recordOf(data).id;\n return typeof id === \"string\" ? id : undefined;\n } catch (error) {\n // A cancellation must short-circuit (and let the caller surface the canonical\n // aborted/timeout error) rather than be swallowed as an ordinary upload failure.\n if (uploader.context.abort.signal.aborted || isAbortError(error)) {\n throw error;\n }\n return undefined;\n }\n}\n\n/**\n * Upload a materialized document to the OpenAI Files API and return the `file_id`\n * (purpose `user_data` for chat file inputs), or `undefined` on failure. Verified\n * shape: `POST /v1/files` multipart `file` + `purpose` \u2192 response `.id`.\n */\nasync function uploadOpenAiFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n const root = base\n ? base.replace(/\\/(chat\\/completions|images\\/generations|models)$/, \"\")\n : \"https://api.openai.com/v1\";\n const endpoint = appendPath(root, \"/files\");\n const form = new FormData();\n form.append(\n \"file\",\n base64ToBlob(payload.base64, payload.mimeType),\n payload.name,\n );\n form.append(\"purpose\", \"user_data\");\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${uploader.apiKey}`,\n },\n body: form,\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const id = recordOf(data).id;\n return typeof id === \"string\" ? id : undefined;\n } catch (error) {\n // A cancellation must short-circuit rather than be swallowed as an upload failure.\n if (uploader.context.abort.signal.aborted || isAbortError(error)) {\n throw error;\n }\n return undefined;\n }\n}\n\n/**\n * Upload a materialized document to the Gemini File API and return the `fileUri`,\n * or `undefined` on failure. Verified shape: simple media upload to\n * `POST /upload/v1beta/files` with `X-Goog-Upload-Protocol: raw` \u2192\n * response `.file.uri`. The API key rides the `x-goog-api-key` header (NOT a\n * `?key=` query param) so it stays out of any captured endpoint string (SEC).\n */\nasync function uploadGeminiFile(\n payload: PortableFilePayload,\n uploader: AttachmentUploader,\n): Promise<string | undefined> {\n if (!payload.base64) {\n return undefined;\n }\n try {\n const base = uploader.context.route.transport.baseUrl?.trim();\n // Gemini media uploads live on the `/upload` host prefix. Build the endpoint by\n // prefixing `/upload` onto the resolved API root (\u2026/v1beta) rather than a fragile\n // post-hoc string replace on the fully-assembled URL.\n const root = base\n ? trimTrailingSlash(base.replace(/\\/v1beta\\/models.*$/, \"/v1beta\"))\n : undefined;\n const endpoint = root\n ? appendPath(\n root.endsWith(\"/v1beta\")\n ? `${root.slice(0, -\"/v1beta\".length)}/upload/v1beta`\n : `${root}/upload`,\n \"/files\",\n )\n : \"https://generativelanguage.googleapis.com/upload/v1beta/files\";\n const response = await uploader.fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n ...geminiApiKeyHeaders(uploader.apiKey),\n \"X-Goog-Upload-Protocol\": \"raw\",\n \"X-Goog-Upload-Header-Content-Type\": payload.mimeType,\n \"content-type\": payload.mimeType,\n },\n body: base64ToBlob(payload.base64, payload.mimeType),\n signal: uploader.context.abort.signal,\n });\n const data = await readPayload(response);\n if (!response.ok) {\n return undefined;\n }\n const file = recordOf(recordOf(data).file);\n const uri = file.uri ?? recordOf(data).uri;\n return typeof uri === \"string\" ? uri : undefined;\n } catch (error) {\n // A cancellation must short-circuit rather than be swallowed as an upload failure.\n if (uploader.context.abort.signal.aborted || isAbortError(error)) {\n throw error;\n }\n return undefined;\n }\n}\n\nasync function openAiAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<OpenAiContentPart[]> {\n const parts: OpenAiContentPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const imageUrl =\n (await portableFileToDataUrl(file)) ?? portableFileRemoteUri(file);\n if (imageUrl) {\n parts.push({\n type: \"image_url\",\n image_url: { url: imageUrl },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n // Already-uploaded providerFileId (remote reference) wins.\n if (payload.providerFileId) {\n parts.push({ type: \"file\", file: { file_id: payload.providerFileId } });\n continue;\n }\n // Oversize \u2192 Files-API upload (file_id); fall back to inline + warning.\n if (uploader && isOversizeDocument(payload)) {\n const fileId = await uploadOpenAiFile(payload, uploader);\n if (fileId) {\n parts.push({ type: \"file\", file: { file_id: fileId } });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the OpenAI Files API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n type: \"file\",\n file: {\n filename: file.name,\n file_data: `data:${payload.mimeType};base64,${payload.base64}`,\n },\n });\n continue;\n }\n // Remote document with only a uri \u2192 descriptor (OpenAI has no url source).\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n type: \"text\",\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n type: \"text\",\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nasync function anthropicAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<AnthropicContentPart[]> {\n const parts: AnthropicContentPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const dataUrl = await portableFileToDataUrl(file);\n const mimeType = inferPortableFileMimeType(file);\n if (dataUrl && mimeType) {\n const [, base64Data = \"\"] = dataUrl.split(\",\", 2);\n parts.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: mimeType,\n data: base64Data,\n },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.providerFileId) {\n parts.push({\n type: \"document\",\n source: { type: \"file\", file_id: payload.providerFileId },\n });\n continue;\n }\n // Remote PDF with only a URL \u2192 Anthropic url source (no bytes; never empty\n // base64 \u2014 INV remote-pdf-url-prefers-url-source).\n if (!payload.base64 && payload.uri) {\n parts.push({\n type: \"document\",\n source: { type: \"url\", url: payload.uri },\n });\n continue;\n }\n if (uploader && isOversizeDocument(payload)) {\n const fileId = await uploadAnthropicFile(payload, uploader);\n if (fileId) {\n parts.push({\n type: \"document\",\n source: { type: \"file\", file_id: fileId },\n });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the Anthropic Files API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n type: \"document\",\n source: {\n type: \"base64\",\n media_type: payload.mimeType,\n data: payload.base64,\n },\n });\n continue;\n }\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n type: \"text\",\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n type: \"text\",\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nasync function geminiAttachmentParts(\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<GeminiPart[]> {\n const parts: GeminiPart[] = [];\n\n for (const file of attachments) {\n if (isPortableImageFile(file)) {\n const dataUrl = await portableFileToDataUrl(file);\n const mimeType = inferPortableFileMimeType(file);\n if (dataUrl && mimeType) {\n const [, base64Data = \"\"] = dataUrl.split(\",\", 2);\n parts.push({\n inlineData: {\n mimeType,\n data: base64Data,\n },\n });\n continue;\n }\n }\n\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.uri && !payload.base64) {\n parts.push({\n fileData: { mimeType: payload.mimeType, fileUri: payload.uri },\n });\n continue;\n }\n if (uploader && isOversizeDocument(payload)) {\n const fileUri = await uploadGeminiFile(payload, uploader);\n if (fileUri) {\n parts.push({\n fileData: { mimeType: payload.mimeType, fileUri },\n });\n continue;\n }\n uploader.warnings.push(\n `Document \"${file.name}\" exceeds the inline size guard and the Gemini File API upload failed; sent inline.`,\n );\n }\n if (payload.base64) {\n parts.push({\n inlineData: { mimeType: payload.mimeType, data: payload.base64 },\n });\n continue;\n }\n }\n\n const text = await portableFileToText(file);\n if (text) {\n parts.push({\n text: `Attached file (${file.name}):\\n${truncateInlineText(text)}`,\n });\n continue;\n }\n\n parts.push({\n text: `Attached resource (${file.name}): ${attachmentDescriptor(file)}`,\n });\n }\n\n return parts;\n}\n\nfunction attachOpenAiParts(\n conversation: Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n }>,\n parts: OpenAiContentPart[],\n): Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}> {\n if (parts.length === 0) {\n return conversation;\n }\n\n const target = attachPartsToLastUserTurn(conversation, () => ({\n role: \"user\" as const,\n content: \"\",\n }));\n const baseParts =\n typeof target.content === \"string\" && target.content.trim().length > 0\n ? [{ type: \"text\", text: target.content } satisfies OpenAiContentPart]\n : Array.isArray(target.content)\n ? target.content\n : [];\n target.content = [...baseParts, ...parts];\n return conversation;\n}\n\nasync function openAiMessages(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}>> {\n const conversation: Array<{\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | OpenAiContentPart[];\n tool_call_id?: string;\n tool_calls?: Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n }>;\n }> = messages.map((message) => {\n if (isToolMessage(message)) {\n return {\n role: \"tool\",\n content: message.content,\n tool_call_id: message.toolCallId,\n };\n }\n\n if (hasAssistantToolCalls(message)) {\n return {\n role: \"assistant\",\n content: message.content,\n tool_calls: message.toolCalls.map((call) => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: JSON.stringify(call.arguments),\n },\n })),\n };\n }\n\n return {\n role:\n message.role === \"assistant\"\n ? \"assistant\"\n : message.role === \"system\"\n ? \"system\"\n : \"user\",\n content: message.content,\n };\n });\n\n return attachOpenAiParts(\n conversation,\n await openAiAttachmentParts(attachments, uploader),\n );\n}\n\nasync function anthropicRequest(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<{\n system?: string;\n messages: Array<{\n role: \"user\" | \"assistant\";\n content: string | AnthropicContentPart[];\n }>;\n}> {\n const system = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\");\n\n const conversation: Array<{\n role: \"user\" | \"assistant\";\n content: string | AnthropicContentPart[];\n }> = [];\n\n for (const message of messages.filter((item) => item.role !== \"system\")) {\n if (isToolMessage(message)) {\n const toolResult: AnthropicContentPart = {\n type: \"tool_result\",\n tool_use_id: message.toolCallId,\n content: message.content,\n ...(message.isError !== undefined ? { is_error: message.isError } : {}),\n };\n const last = conversation[conversation.length - 1];\n if (last?.role === \"user\" && Array.isArray(last.content)) {\n last.content.push(toolResult);\n } else {\n conversation.push({\n role: \"user\",\n content: [toolResult],\n });\n }\n continue;\n }\n\n if (hasAssistantToolCalls(message)) {\n const content: AnthropicContentPart[] = [];\n if (message.content.trim().length > 0) {\n content.push({ type: \"text\", text: message.content });\n }\n content.push(\n ...message.toolCalls.map((call) => ({\n type: \"tool_use\" as const,\n id: call.id,\n name: call.name,\n input: call.arguments,\n })),\n );\n conversation.push({\n role: \"assistant\",\n content,\n });\n continue;\n }\n\n conversation.push({\n role: (message.role === \"assistant\" ? \"assistant\" : \"user\") as\n | \"user\"\n | \"assistant\",\n content: message.content,\n });\n }\n\n const attachmentParts = await anthropicAttachmentParts(attachments, uploader);\n if (attachmentParts.length > 0) {\n const target = attachPartsToLastUserTurn(conversation, () => ({\n role: \"user\" as const,\n content: \"\",\n }));\n const baseParts =\n typeof target.content === \"string\" && target.content.trim().length > 0\n ? [{ type: \"text\", text: target.content } satisfies AnthropicContentPart]\n : Array.isArray(target.content)\n ? target.content\n : [];\n target.content = [...baseParts, ...attachmentParts];\n }\n\n return {\n ...(system ? { system } : {}),\n messages:\n conversation.length > 0\n ? conversation\n : [{ role: \"user\", content: \"\" }],\n };\n}\n\nasync function geminiRequest(\n messages: MessageInput[],\n attachments: PortableFile[],\n uploader?: AttachmentUploader,\n): Promise<{\n systemInstruction?: { parts: Array<{ text: string }> };\n contents: Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }>;\n}> {\n const system = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\");\n // Gemini's `functionResponse.name` must match the originating `functionCall.name`.\n // Map every assistant tool-call id \u2192 its name so a tool-result message can resolve\n // the correct name instead of guessing a placeholder.\n const toolNameByCallId = new Map<string, string>();\n for (const message of messages) {\n if (hasAssistantToolCalls(message)) {\n for (const call of message.toolCalls) {\n toolNameByCallId.set(call.id, call.name);\n }\n }\n }\n const contents: Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }> = messages\n .filter((message) => message.role !== \"system\")\n .reduce<Array<{ role: \"user\" | \"model\"; parts: GeminiPart[] }>>(\n (conversation, message) => {\n if (isToolMessage(message)) {\n // Prefer an explicit toolName, else derive it from the preceding assistant\n // toolCall matching this toolCallId. Never silently guess a placeholder \u2014\n // an unresolvable name means the caller supplied a malformed tool turn.\n const resolvedName =\n message.toolName ?? toolNameByCallId.get(message.toolCallId);\n if (!resolvedName) {\n throw new AiConnectError(\n \"validation_error\",\n `Gemini functionResponse requires a tool name: the tool message for toolCallId \"${message.toolCallId}\" has no toolName and no matching assistant toolCall was found.`,\n );\n }\n const response: GeminiPart = {\n functionResponse: {\n name: resolvedName,\n response:\n isRecord(message.data)\n ? message.data\n : {\n content: message.content,\n ...(message.isError !== undefined\n ? { isError: message.isError }\n : {}),\n },\n },\n };\n const last = conversation[conversation.length - 1];\n if (last?.role === \"user\") {\n last.parts.push(response);\n } else {\n conversation.push({\n role: \"user\",\n parts: [response],\n });\n }\n return conversation;\n }\n\n if (hasAssistantToolCalls(message)) {\n const parts: GeminiPart[] = [];\n if (message.content.trim().length > 0) {\n parts.push({ text: message.content });\n }\n parts.push(\n ...message.toolCalls.map((call) => ({\n functionCall: {\n name: call.name,\n args: call.arguments,\n },\n })),\n );\n conversation.push({\n role: \"model\",\n parts,\n });\n return conversation;\n }\n\n conversation.push({\n role: (message.role === \"assistant\" ? \"model\" : \"user\") as\n | \"user\"\n | \"model\",\n parts: [{ text: message.content } satisfies GeminiPart],\n });\n return conversation;\n },\n [],\n );\n\n const attachmentParts = await geminiAttachmentParts(attachments, uploader);\n if (attachmentParts.length > 0) {\n const target = attachPartsToLastUserTurn(contents, () => ({\n role: \"user\" as const,\n parts: [] as GeminiPart[],\n }));\n target.parts.push(...attachmentParts);\n }\n\n return {\n ...(system\n ? {\n systemInstruction: {\n parts: [{ text: system }],\n },\n }\n : {}),\n contents,\n };\n}\n\nfunction extractText(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value\n .flatMap((part) => {\n if (typeof part === \"string\") {\n return [part];\n }\n if (part && typeof part === \"object\") {\n // Skip the model's REASONING parts (Gemini marks them `{ thought: true, text }`) \u2014 they are the\n // internal chain-of-thought, NOT the answer; without this they leak into the answer text.\n // extractThoughts() collects them separately into GenerateResult.reasoning. Other providers'\n // parts never carry `thought`, so this is a no-op for them.\n if ((part as Record<string, unknown>).thought === true) {\n return [];\n }\n const candidate = (part as Record<string, unknown>).text;\n if (typeof candidate === \"string\") {\n return [candidate];\n }\n }\n return [];\n })\n .join(\"\\n\")\n .trim();\n }\n\n return \"\";\n}\n\n// Collect the model's REASONING (\"thought\") parts' text (Gemini `{ thought: true, text }`), separately from\n// the answer. Returns undefined when there are none so a non-thinking response carries no reasoning field.\nfunction extractThoughts(value: unknown): string | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const thoughts = value.flatMap((part) => {\n if (part && typeof part === \"object\" && (part as Record<string, unknown>).thought === true) {\n const candidate = (part as Record<string, unknown>).text;\n if (typeof candidate === \"string\") {\n return [candidate];\n }\n }\n return [];\n });\n const joined = thoughts.join(\"\\n\").trim();\n return joined.length > 0 ? joined : undefined;\n}\n\n// Collect Anthropic extended-thinking blocks (`{ type: 'thinking', thinking }`), joined and\n// separated from the answer, mirroring the Gemini `extractThoughts` path. Returns undefined\n// when there are none so a non-thinking response carries no `reasoning` field. Thinking blocks\n// have no `.text`, so `extractText` already excludes them from the answer.\nfunction extractThinking(value: unknown): string | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const thinking = value.flatMap((part) => {\n if (\n part &&\n typeof part === \"object\" &&\n (part as Record<string, unknown>).type === \"thinking\"\n ) {\n const candidate = (part as Record<string, unknown>).thinking;\n if (typeof candidate === \"string\") {\n return [candidate];\n }\n }\n return [];\n });\n const joined = thinking.join(\"\\n\").trim();\n return joined.length > 0 ? joined : undefined;\n}\n\nfunction imageAttachmentsFromPayload(\n payload: unknown,\n ...sources: unknown[]\n) {\n return extractImagePayloads(payload, ...sources).map((item) =>\n preparePortableFile(item),\n );\n}\n\nfunction imageReferenceFiles(context: GenerateContext): PortableFile[] {\n if (context.request.image?.referenceImages?.length) {\n return context.request.image.referenceImages;\n }\n\n return context.request.attachments.filter((file) => isPortableImageFile(file));\n}\n\nfunction shouldUseImageEditEndpoint(context: GenerateContext): boolean {\n return Boolean(\n context.request.image?.sourceImage ||\n context.request.image?.mask ||\n imageReferenceFiles(context).length > 0,\n );\n}\n\nfunction shouldUseProxyImageExtensions(route: NormalizedRoute): boolean {\n return route.provider === \"gemini\" || Boolean(route.transport.baseUrl?.trim());\n}\n\nfunction resolveImageRequestSize(context: GenerateContext, fallbackSize: string): string {\n return String(\n context.request.image?.size ??\n context.request.image?.aspectRatio ??\n fallbackSize,\n );\n}\n\nfunction buildImageRequestFields(\n context: GenerateContext,\n bundle: ReturnType<typeof buildImagePromptBundle>,\n): Record<string, unknown> {\n const image = context.request.image;\n return {\n model: context.route.model,\n prompt: bundle.prompt,\n size: resolveImageRequestSize(context, bundle.size),\n response_format: \"b64_json\",\n n: context.request.parameters?.candidateCount ?? 1,\n ...(image?.quality ? { quality: image.quality } : {}),\n ...(image?.style ? { style: image.style } : {}),\n ...(shouldUseProxyImageExtensions(context.route) && image?.aspectRatio\n ? { aspect_ratio: image.aspectRatio }\n : {}),\n ...(shouldUseProxyImageExtensions(context.route) && image?.imageSize\n ? { image_size: image.imageSize }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n}\n\nasync function appendMultipartPortableFile(\n formData: FormData,\n fieldName: string,\n file: PortableFile,\n): Promise<void> {\n const bytes = await portableFileToBytes(file);\n if (!bytes) {\n throw new AiConnectError(\n \"validation_error\",\n `Multipart image uploads require local, browser, or data-url sources for \"${fieldName}\".`,\n );\n }\n\n const mimeType = inferPortableFileMimeType(file) ?? \"application/octet-stream\";\n const arrayBuffer = bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength,\n ) as ArrayBuffer;\n formData.append(\n fieldName,\n new Blob([arrayBuffer], { type: mimeType }),\n file.name,\n );\n}\n\nasync function buildImageEditFormData(\n context: GenerateContext,\n fields: Record<string, unknown>,\n): Promise<FormData> {\n const formData = new FormData();\n for (const [key, value] of Object.entries(fields)) {\n if (value === undefined || value === null) {\n continue;\n }\n formData.append(key, String(value));\n }\n\n if (context.request.image?.sourceImage) {\n await appendMultipartPortableFile(\n formData,\n \"image\",\n context.request.image.sourceImage,\n );\n }\n\n if (context.request.image?.mask) {\n await appendMultipartPortableFile(formData, \"mask\", context.request.image.mask);\n }\n\n const referenceImages = imageReferenceFiles(context);\n for (const [index, file] of referenceImages.entries()) {\n await appendMultipartPortableFile(formData, `image${index + 1}`, file);\n }\n\n return formData;\n}\n\n/**\n * SHARED OpenAI-compatible chat-completions body builder (C3 + C9). Both the `generate` path's\n * one-shot `response_format`-drop retry AND the new `runOpenAiStream` SSE producer build their body\n * through THIS single function \u2014 there is no duplicated body assembly (LEVER / plan \u00A72). The only\n * per-caller deltas are `stream` (false for generate, true for SSE) and `dropResponseFormat` (the\n * C3 fallback omits `response_format`). `messages`/`responseFormat` are precomputed by the caller\n * (the stream producer reuses the same `openAiMessages` + `openAiResponseFormat` upstream).\n */\nfunction buildOpenAiChatBody(\n context: GenerateContext,\n messages: unknown,\n parameters: GenerateContext[\"request\"][\"parameters\"],\n responseFormat: ReturnType<typeof openAiResponseFormat>,\n opts: { stream: boolean; dropResponseFormat: boolean },\n): Record<string, unknown> {\n return {\n model: context.route.model,\n messages,\n stream: opts.stream,\n // Ask OpenAI-compatible streaming routes for the trailing usage chunk; without\n // `stream_options.include_usage` the SSE stream carries no `usage` block and\n // `runOpenAiStream` would always report `usage: undefined` (H5).\n ...(opts.stream ? { stream_options: { include_usage: true } } : {}),\n ...(parameters?.maxTokens !== undefined\n ? { max_tokens: parameters.maxTokens }\n : {}),\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { top_p: parameters.topP } : {}),\n ...(parameters?.stop ? { stop: parameters.stop } : {}),\n ...(parameters?.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(parameters?.candidateCount !== undefined\n ? { n: parameters.candidateCount }\n : {}),\n ...(parameters?.presencePenalty !== undefined\n ? { presence_penalty: parameters.presencePenalty }\n : {}),\n ...(parameters?.frequencyPenalty !== undefined\n ? { frequency_penalty: parameters.frequencyPenalty }\n : {}),\n ...(openAiTools(parameters?.tools)\n ? { tools: openAiTools(parameters?.tools) }\n : {}),\n ...(openAiToolChoice(parameters?.toolChoice)\n ? { tool_choice: openAiToolChoice(parameters?.toolChoice) }\n : {}),\n ...(parameters?.parallelToolCalls !== undefined\n ? { parallel_tool_calls: parameters.parallelToolCalls }\n : {}),\n ...(!opts.dropResponseFormat && responseFormat\n ? { response_format: responseFormat }\n : {}),\n ...(openAiThinking(parameters?.thinking)\n ? { thinking: openAiThinking(parameters?.thinking) }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n}\n\nasync function runOpenAi(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n if (context.request.operation === \"image\") {\n return runOpenAiImage(fetchImpl, context);\n }\n\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const messages = await openAiMessages(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const responseFormat = openAiResponseFormat(parameters?.responseFormat);\n const endpoint = resolveOpenAiEndpoint(context.route, \"text\");\n\n /**\n * Build the chat-completions body via the SHARED `buildOpenAiChatBody`. When\n * `dropResponseFormat` is true the `response_format` field is omitted (the\n * one-shot fallback body). `stream:false` for the generate path.\n */\n const buildBody = (dropResponseFormat: boolean): Record<string, unknown> =>\n buildOpenAiChatBody(context, messages, parameters, responseFormat, {\n stream: false,\n dropResponseFormat,\n });\n\n /**\n * One POST + classify. On a non-ok response it throws the classified error\n * EXCEPT it returns `{ rejection: true }` when this is the first (non-dropped)\n * attempt, `response_format` was actually sent, the failure is a\n * response_format-rejection 400, and the operation is NOT aborted \u2014 so the\n * caller can re-issue exactly once without `response_format` (INV-ROBUST-1).\n * The abort guard ensures a deadline that fired during the call surfaces the\n * canonical abort/timeout error (via the client) rather than a schema retry.\n */\n const attempt = async (\n dropResponseFormat: boolean,\n ): Promise<\n | { rejection: true }\n | {\n rejection: false;\n data: {\n choices?: Array<{ message?: { content?: unknown } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n };\n };\n }\n > => {\n const body = buildBody(dropResponseFormat);\n transportSummary(context, \"openai-chat\", endpoint, \"POST\", false, body);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n const error = classifyApiError(\"openai\", response, payload);\n // R21 precondition: only the FIRST attempt that actually sent\n // `response_format` is eligible for the one-shot drop fallback, and only\n // when the operation has not been aborted/timed-out (C2 dep).\n if (\n !dropResponseFormat &&\n responseFormat !== undefined &&\n !context.abort.signal.aborted &&\n isResponseFormatRejection(response, error.message)\n ) {\n return { rejection: true };\n }\n throw error;\n }\n\n return {\n rejection: false,\n data: payload as {\n choices?: Array<{ message?: { content?: unknown } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n };\n },\n };\n };\n\n let outcome = await attempt(false);\n let droppedResponseFormat = false;\n if (outcome.rejection) {\n // One-shot fallback: re-issue exactly once WITHOUT `response_format`.\n droppedResponseFormat = true;\n const retried = await attempt(true);\n if (retried.rejection) {\n // attempt(true) never returns a rejection sentinel (dropResponseFormat\n // disables the gate), but narrow the type defensively.\n throw classifyApiError(\n \"openai\",\n new Response(null, { status: 400 }),\n undefined,\n );\n }\n outcome = retried;\n }\n\n const data = outcome.data;\n\n const baseWarnings: string[] = [...uploaderWarnings];\n if (parameters?.candidateCount && parameters.candidateCount > 1) {\n baseWarnings.push(\n \"candidateCount > 1 is forwarded to OpenAI-compatible text routes, but the normalized result returns only the first choice.\",\n );\n }\n if (droppedResponseFormat) {\n baseWarnings.push(\n \"response_format was rejected by the OpenAI-compatible route (HTTP 400); the request was retried once without response_format and structured-output formatting was NOT enforced.\",\n );\n }\n\n return {\n text: extractText(data.choices?.[0]?.message?.content),\n data,\n ...(openAiToolCallsFromPayload(data).length > 0\n ? { toolCalls: openAiToolCallsFromPayload(data) }\n : {}),\n ...(baseWarnings.length > 0 ? { warnings: baseWarnings } : {}),\n ...(data.usage?.prompt_tokens !== undefined ||\n data.usage?.completion_tokens !== undefined ||\n data.usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usage?.prompt_tokens !== undefined\n ? { inputTokens: data.usage.prompt_tokens }\n : {}),\n ...(data.usage?.completion_tokens !== undefined\n ? { outputTokens: data.usage.completion_tokens }\n : {}),\n ...(data.usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n reasoningTokens:\n data.usage.completion_tokens_details.reasoning_tokens,\n }\n : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * REAL OpenAI-compatible SSE streaming producer (C9 / OQ-13 / UR-013). The first default `stream`\n * handler that emits genuine incremental `{type:'delta', text}` events parsed from the\n * chat-completions SSE wire, then exactly one terminal `{type:'result', result}` (INV-ABORT-3 /\n * stream-emits-deltas-then-exactly-one-terminal-result).\n *\n * Shares the body builder with the `generate` path (`buildOpenAiChatBody`, `stream:true`) \u2014 no\n * duplication. Honors `context.abort.signal`: passed into `fetch` init AND, on mid-stream abort,\n * the reader is `cancel()`ed so the underlying connection is released even if the `FetchLike`\n * ignored `init.signal` (R17 \u2014 `reader.cancel()` releases our side). Usage is captured ONLY when\n * the stream actually reports a `usage` block (stream_options) \u2014 never fabricated (R17).\n */\nasync function* runOpenAiStream(\n fetchImpl: FetchLike,\n context: GenerateContext,\n): AsyncIterable<GenerateStreamEvent> {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const messages = await openAiMessages(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const responseFormat = openAiResponseFormat(parameters?.responseFormat);\n const endpoint = resolveOpenAiEndpoint(context.route, \"text\");\n\n /**\n * Issue ONE streaming POST. On a non-ok response it returns the\n * `{ rejection: true }` sentinel ONLY for the first (non-dropped) attempt that\n * actually sent `response_format`, the failure is a response_format-rejection\n * 400, and the operation is not aborted \u2014 so the caller can re-issue exactly\n * once WITHOUT `response_format` (R21 parity with `runOpenAi`). Otherwise it\n * throws the classified error or returns the streaming `response`.\n */\n const attempt = async (\n dropResponseFormat: boolean,\n ): Promise<{ rejection: true } | { rejection: false; response: Response }> => {\n const body = buildOpenAiChatBody(context, messages, parameters, responseFormat, {\n stream: true,\n dropResponseFormat,\n });\n transportSummary(context, \"openai-chat\", endpoint, \"POST\", true, body);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: context.abort.signal,\n });\n\n if (!response.ok) {\n const payload = await readPayload(response);\n const error = classifyApiError(\"openai\", response, payload);\n if (\n !dropResponseFormat &&\n responseFormat !== undefined &&\n !context.abort.signal.aborted &&\n isResponseFormatRejection(response, error.message)\n ) {\n return { rejection: true };\n }\n throw error;\n }\n\n return { rejection: false, response };\n };\n\n let outcome = await attempt(false);\n let droppedResponseFormat = false;\n if (outcome.rejection) {\n // One-shot fallback: re-issue exactly once WITHOUT `response_format`.\n droppedResponseFormat = true;\n const retried = await attempt(true);\n if (retried.rejection) {\n // attempt(true) never returns a rejection sentinel (dropResponseFormat\n // disables the gate); narrow defensively.\n throw classifyApiError(\n \"openai\",\n new Response(null, { status: 400 }),\n undefined,\n );\n }\n outcome = retried;\n }\n const response = outcome.response;\n\n const streamWarnings = [...uploaderWarnings];\n if (parameters?.candidateCount && parameters.candidateCount > 1) {\n streamWarnings.push(\n \"candidateCount > 1 is forwarded to OpenAI-compatible text routes, but the normalized result returns only the first choice.\",\n );\n }\n if (droppedResponseFormat) {\n streamWarnings.push(\n \"response_format was rejected by the OpenAI-compatible route (HTTP 400); the request was retried once without response_format and structured-output formatting was NOT enforced.\",\n );\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n // No streaming body \u2014 fall back to a single terminal result from the parsed payload.\n const payload = (await readPayload(response)) as {\n choices?: Array<{ message?: { content?: unknown } }>;\n };\n yield {\n type: \"result\",\n result: buildOpenAiStreamResult(\n context,\n extractText(payload.choices?.[0]?.message?.content),\n [],\n undefined,\n streamWarnings,\n ),\n };\n return;\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let accumulatedText = \"\";\n // Tool-call fragments are BUFFERED by `index` and never JSON.parsed per chunk:\n // OpenAI streams a tool call's `function.name` on the first fragment and the\n // `function.arguments` JSON across N later fragments. Parsing a partial args\n // string would throw out of this generator and abort the whole stream with no\n // terminal result; instead we concatenate by index and parse ONCE at the end.\n const toolCallFragments = new Map<\n number,\n { id?: string; name?: string; argsString: string }\n >();\n let usage: OpenAiStreamUsage | undefined;\n let drained = false;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (context.abort.signal.aborted) {\n // Mid-stream abort: rethrow so the client surfaces the canonical aborted/timeout code (it\n // never reaches a terminal event). The connection is released in the `finally` via\n // `reader.cancel()` (R17 \u2014 fires whether we throw here OR the consumer calls return()).\n throw new AiConnectError(\"aborted\", \"Operation aborted.\");\n }\n const { done, value } = await reader.read();\n if (done) {\n drained = true;\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n let newlineIndex = buffer.indexOf(\"\\n\");\n while (newlineIndex !== -1) {\n const line = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n newlineIndex = buffer.indexOf(\"\\n\");\n if (!line.startsWith(\"data:\")) {\n continue;\n }\n const payloadText = line.slice(\"data:\".length).trim();\n if (payloadText === \"[DONE]\") {\n continue;\n }\n let chunk: OpenAiStreamChunk;\n try {\n chunk = JSON.parse(payloadText) as OpenAiStreamChunk;\n } catch {\n continue;\n }\n const delta = chunk.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : \"\";\n if (text.length > 0) {\n accumulatedText += text;\n yield { type: \"delta\", text };\n }\n if (Array.isArray(delta?.tool_calls)) {\n for (const fragment of delta.tool_calls) {\n accumulateOpenAiToolCallFragment(toolCallFragments, fragment);\n }\n }\n if (chunk.usage) {\n usage = chunk.usage;\n }\n }\n }\n } finally {\n // R17: if the stream was NOT fully drained (mid-stream abort, OR the consumer called\n // iterator.return() to stop early), cancel the reader so the underlying connection is released\n // from our side even when a non-compliant FetchLike ignored init.signal.\n if (!drained) {\n await reader.cancel().catch(() => {});\n }\n reader.releaseLock?.();\n }\n\n // Assemble + parse the buffered tool-call fragments ONCE, at stream end.\n const toolCalls = assembleOpenAiToolCalls(toolCallFragments);\n\n yield {\n type: \"result\",\n result: buildOpenAiStreamResult(\n context,\n accumulatedText,\n toolCalls,\n usage,\n streamWarnings,\n ),\n };\n}\n\n/** One OpenAI streaming `tool_calls` delta fragment (R17). */\ninterface OpenAiToolCallFragment {\n index?: unknown;\n id?: unknown;\n function?: { name?: unknown; arguments?: unknown };\n}\n\n/**\n * Fold one streamed `tool_calls` delta fragment into the by-`index` buffer.\n * Appends the `function.arguments` string delta verbatim (NO per-chunk parse)\n * and latches the first non-empty `id`/`function.name` seen for that index. A\n * fragment whose `index` is absent falls back to the current map size so a\n * single un-indexed call still accumulates coherently.\n */\nfunction accumulateOpenAiToolCallFragment(\n fragments: Map<number, { id?: string; name?: string; argsString: string }>,\n fragment: OpenAiToolCallFragment,\n): void {\n if (!fragment || typeof fragment !== \"object\") {\n return;\n }\n const index =\n typeof fragment.index === \"number\" ? fragment.index : fragments.size;\n const existing = fragments.get(index) ?? { argsString: \"\" };\n if (\n existing.id === undefined &&\n typeof fragment.id === \"string\" &&\n fragment.id.trim().length > 0\n ) {\n existing.id = fragment.id;\n }\n const name = fragment.function?.name;\n if (\n existing.name === undefined &&\n typeof name === \"string\" &&\n name.trim().length > 0\n ) {\n existing.name = name;\n }\n const args = fragment.function?.arguments;\n if (typeof args === \"string\") {\n existing.argsString += args;\n }\n fragments.set(index, existing);\n}\n\n/**\n * Assemble the buffered fragments into a synthetic non-streaming `tool_calls`\n * payload and parse it ONCE through the shared `openAiToolCallsFromPayload`\n * (which runs `parseToolArguments` on the fully-concatenated args string).\n * Fragments are emitted in ascending index order so the call ordering matches\n * the wire. A fragment that never received a `name` is dropped (same contract\n * as the non-streaming path).\n */\nfunction assembleOpenAiToolCalls(\n fragments: Map<number, { id?: string; name?: string; argsString: string }>,\n): ToolCallInput[] {\n if (fragments.size === 0) {\n return [];\n }\n const ordered = [...fragments.entries()]\n .sort((a, b) => a[0] - b[0])\n .map(([, fragment]) => ({\n ...(fragment.id !== undefined ? { id: fragment.id } : {}),\n function: {\n ...(fragment.name !== undefined ? { name: fragment.name } : {}),\n arguments: fragment.argsString,\n },\n }));\n return openAiToolCallsFromPayload({\n choices: [{ message: { tool_calls: ordered } }],\n });\n}\n\ninterface OpenAiStreamUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n}\n\ninterface OpenAiStreamChunk {\n choices?: Array<{\n delta?: { content?: unknown; tool_calls?: OpenAiToolCallFragment[] };\n }>;\n usage?: OpenAiStreamUsage;\n}\n\n/**\n * Build the terminal {@link GenerateResult} for the SSE producer from the accumulated text/usage.\n * Usage seeds `calls:1` ONLY when the stream reported a usage block (never fabricated, R17).\n */\nfunction buildOpenAiStreamResult(\n context: GenerateContext,\n text: string,\n toolCalls: ToolCallInput[],\n usage: OpenAiStreamUsage | undefined,\n warnings: string[],\n): GenerateResult {\n const hasUsage =\n usage?.prompt_tokens !== undefined ||\n usage?.completion_tokens !== undefined ||\n usage?.completion_tokens_details?.reasoning_tokens !== undefined;\n return {\n route: context.route,\n text,\n attachments: [],\n warnings: [...warnings],\n attempts: [],\n ...(toolCalls.length > 0 ? { toolCalls } : {}),\n ...(hasUsage\n ? {\n usage: {\n calls: 1,\n ...(usage?.prompt_tokens !== undefined\n ? { inputTokens: usage.prompt_tokens }\n : {}),\n ...(usage?.completion_tokens !== undefined\n ? { outputTokens: usage.completion_tokens }\n : {}),\n ...(usage?.completion_tokens_details?.reasoning_tokens !== undefined\n ? {\n reasoningTokens:\n usage.completion_tokens_details.reasoning_tokens,\n }\n : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * SHARED image-generation/edit producer for OpenAI-compatible AND Gemini image routes\n * (SYS-7 dedup). The two former `runOpenAiImage`/`runGeminiImage` bodies were byte-identical\n * except for endpoint resolution, the transport-summary label, the auth headers, and the\n * `classifyApiError` provider \u2014 all injected via `opts`. Behavior is preserved exactly:\n * the edit branch sends only `opts.authHeaders`; the generate branch additionally sets\n * `content-type: application/json`.\n */\nasync function runProviderImage(\n fetchImpl: FetchLike,\n context: GenerateContext,\n opts: {\n resolveEndpoint: (route: NormalizedRoute) => string;\n resolveEditEndpoint: (route: NormalizedRoute) => string;\n authHeaders: Record<string, string>;\n providerLabel: string;\n classifyProvider: string;\n },\n) {\n const referenceImages = imageReferenceFiles(context);\n const bundle = buildImagePromptBundle({\n request: context.request,\n model: context.route.model,\n referenceImages,\n });\n const baseFields = buildImageRequestFields(context, bundle);\n const useEditEndpoint = shouldUseImageEditEndpoint(context);\n const endpoint = useEditEndpoint\n ? opts.resolveEditEndpoint(context.route)\n : opts.resolveEndpoint(context.route);\n transportSummary(\n context,\n useEditEndpoint\n ? `${opts.providerLabel}-image-edit`\n : `${opts.providerLabel}-image`,\n endpoint,\n \"POST\",\n false,\n {\n ...baseFields,\n source_image: Boolean(context.request.image?.sourceImage),\n mask: Boolean(context.request.image?.mask),\n reference_image_count: referenceImages.length,\n },\n );\n const response = await fetchImpl(endpoint, useEditEndpoint\n ? {\n method: \"POST\",\n headers: { ...opts.authHeaders },\n body: await buildImageEditFormData(context, baseFields),\n signal: context.abort.signal,\n }\n : {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...opts.authHeaders,\n },\n body: JSON.stringify(baseFields),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(opts.classifyProvider, response, payload);\n }\n\n return {\n data: {\n request: bundle,\n response: payload,\n },\n attachments: imageAttachmentsFromPayload(payload),\n };\n}\n\nasync function runOpenAiImage(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n return runProviderImage(fetchImpl, context, {\n resolveEndpoint: (route) => resolveOpenAiEndpoint(route, \"image\"),\n resolveEditEndpoint: (route) => resolveOpenAiImageEditEndpoint(route),\n authHeaders: { authorization: `Bearer ${apiKey}` },\n providerLabel: \"openai\",\n classifyProvider: \"openai\",\n });\n}\n\nasync function runAnthropic(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const body = await anthropicRequest(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const requestBody = {\n model: context.route.model,\n // Anthropic REQUIRES `max_tokens` (unlike OpenAI/Gemini, where it is optional), so a\n // provider-specific default of 4096 is applied when the caller omits `maxTokens`.\n max_tokens: parameters?.maxTokens ?? 4096,\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { top_p: parameters.topP } : {}),\n ...(parameters?.topK !== undefined ? { top_k: parameters.topK } : {}),\n ...(stopSequences(parameters?.stop)\n ? { stop_sequences: stopSequences(parameters?.stop) }\n : {}),\n ...body,\n ...(anthropicTools(parameters?.tools)\n ? { tools: anthropicTools(parameters?.tools) }\n : {}),\n ...(anthropicToolChoice(parameters?.toolChoice)\n ? { tool_choice: anthropicToolChoice(parameters?.toolChoice) }\n : {}),\n ...(anthropicThinking(parameters?.thinking)\n ? { thinking: anthropicThinking(parameters?.thinking) }\n : {}),\n ...(parameters?.metadata ? { metadata: parameters.metadata } : {}),\n ...(providerExtra(context) ?? {}),\n };\n const endpoint = resolveAnthropicEndpoint(context.route);\n transportSummary(context, \"anthropic-messages\", endpoint, \"POST\", false, requestBody);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(requestBody),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(\"anthropic\", response, payload);\n }\n\n const data = payload as {\n content?: Array<{ type?: string; text?: string; thinking?: string }>;\n usage?: { input_tokens?: number; output_tokens?: number };\n };\n\n const anthropicReasoning = extractThinking(data.content);\n return {\n text: extractText(data.content),\n // Anthropic extended-thinking blocks, separated from the answer (consumers route this\n // to a thinking UI), mirroring the Gemini `reasoning` path.\n ...(anthropicReasoning ? { reasoning: anthropicReasoning } : {}),\n data,\n ...(anthropicToolCallsFromPayload(data).length > 0\n ? { toolCalls: anthropicToolCallsFromPayload(data) }\n : {}),\n ...(uploaderWarnings.length > 0 ? { warnings: uploaderWarnings } : {}),\n ...(data.usage?.input_tokens !== undefined ||\n data.usage?.output_tokens !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usage?.input_tokens !== undefined\n ? { inputTokens: data.usage.input_tokens }\n : {}),\n ...(data.usage?.output_tokens !== undefined\n ? { outputTokens: data.usage.output_tokens }\n : {}),\n },\n }\n : {}),\n };\n}\n\nasync function runGemini(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n if (context.request.operation === \"image\") {\n return runGeminiImage(fetchImpl, context);\n }\n\n const apiKey = resolveApiKey(context.route, context.runtime);\n const uploaderWarnings: string[] = [];\n const body = await geminiRequest(\n context.request.messages,\n context.request.attachments,\n { fetchImpl, context, apiKey, warnings: uploaderWarnings },\n );\n const parameters = context.request.parameters;\n const generationConfig = {\n ...(parameters?.maxTokens !== undefined\n ? { maxOutputTokens: parameters.maxTokens }\n : {}),\n ...(parameters?.temperature !== undefined\n ? { temperature: parameters.temperature }\n : {}),\n ...(parameters?.topP !== undefined ? { topP: parameters.topP } : {}),\n ...(parameters?.topK !== undefined ? { topK: parameters.topK } : {}),\n ...(stopSequences(parameters?.stop)\n ? { stopSequences: stopSequences(parameters?.stop) }\n : {}),\n ...(parameters?.candidateCount !== undefined\n ? { candidateCount: parameters.candidateCount }\n : {}),\n ...(parameters?.presencePenalty !== undefined\n ? { presencePenalty: parameters.presencePenalty }\n : {}),\n ...(parameters?.frequencyPenalty !== undefined\n ? { frequencyPenalty: parameters.frequencyPenalty }\n : {}),\n ...(parameters?.seed !== undefined ? { seed: parameters.seed } : {}),\n ...(geminiResponseFormat(parameters?.responseFormat) ?? {}),\n ...(geminiThinkingConfig(parameters?.thinking)\n ? { thinkingConfig: geminiThinkingConfig(parameters?.thinking) }\n : {}),\n };\n const provider = context.route.provider;\n const endpoint = resolveGeminiTextEndpoint(context.route);\n const requestBody = {\n ...body,\n ...(Object.keys(generationConfig).length > 0\n ? { generationConfig }\n : {}),\n ...(geminiTools(parameters?.tools)\n ? { tools: geminiTools(parameters?.tools) }\n : {}),\n ...(geminiToolConfig(parameters?.toolChoice)\n ? { toolConfig: geminiToolConfig(parameters?.toolChoice) }\n : {}),\n ...(parameters?.safetySettings\n ? { safetySettings: parameters.safetySettings }\n : {}),\n ...(providerExtra(context) ?? {}),\n };\n transportSummary(context, \"gemini-generate-content\", endpoint, \"POST\", false, requestBody);\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: {\n ...geminiApiKeyHeaders(apiKey),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal: context.abort.signal,\n });\n const payload = await readPayload(response);\n\n if (!response.ok) {\n throw classifyApiError(provider, response, payload);\n }\n\n const data = payload as {\n candidates?: Array<{\n content?: {\n parts?: Array<{ text?: string; thought?: boolean }>;\n };\n }>;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n thoughtsTokenCount?: number;\n };\n };\n\n const geminiThoughts = extractThoughts(data.candidates?.[0]?.content?.parts);\n return {\n text: extractText(data.candidates?.[0]?.content?.parts),\n // The model's `{ thought: true }` parts, separated from the answer (consumers route this to a thinking UI).\n ...(geminiThoughts ? { reasoning: geminiThoughts } : {}),\n data,\n ...(geminiToolCallsFromPayload(data).length > 0\n ? { toolCalls: geminiToolCallsFromPayload(data) }\n : {}),\n ...((() => {\n const warnings = [...uploaderWarnings];\n if (parameters?.candidateCount && parameters.candidateCount > 1) {\n warnings.push(\n \"candidateCount > 1 is forwarded to Gemini text routes, but the normalized result returns only the first candidate.\",\n );\n }\n return warnings.length > 0 ? { warnings } : {};\n })()),\n // INV-USAGE-1: gate on the PRESENCE of an actual token field (mirrors\n // OpenAI/Anthropic), never on `usageMetadata` truthiness. A present-but-empty\n // `usageMetadata:{}` carries no tokens, so fabricating `usage:{calls:1}` would\n // invent a billed call that never happened.\n ...(data.usageMetadata?.promptTokenCount !== undefined ||\n data.usageMetadata?.candidatesTokenCount !== undefined ||\n data.usageMetadata?.thoughtsTokenCount !== undefined\n ? {\n usage: {\n calls: 1,\n ...(data.usageMetadata?.promptTokenCount !== undefined\n ? { inputTokens: data.usageMetadata.promptTokenCount }\n : {}),\n ...(data.usageMetadata?.candidatesTokenCount !== undefined\n ? { outputTokens: data.usageMetadata.candidatesTokenCount }\n : {}),\n ...(data.usageMetadata?.thoughtsTokenCount !== undefined\n ? { reasoningTokens: data.usageMetadata.thoughtsTokenCount }\n : {}),\n },\n }\n : {}),\n };\n}\n\nasync function runGeminiImage(\n fetchImpl: FetchLike,\n context: GenerateContext,\n) {\n const apiKey = resolveApiKey(context.route, context.runtime);\n return runProviderImage(fetchImpl, context, {\n resolveEndpoint: (route) => resolveGeminiImageEndpoint(route),\n resolveEditEndpoint: (route) => resolveGeminiImageEditEndpoint(route),\n authHeaders: { authorization: `Bearer ${apiKey}` },\n providerLabel: \"gemini\",\n classifyProvider: context.route.provider,\n });\n}\n\nfunction verifyApiRoute(\n route: NormalizedRoute,\n runtime: RuntimeEnvironment,\n) {\n resolveApiKey(route, runtime);\n return [];\n}\n\nexport function createDefaultRouteHandlers(\n options: {\n fetch?: FetchLike;\n } = {},\n): RouteHandlerRegistry {\n const fetchImpl = getFetch(options.fetch);\n\n return {\n \"openai:api\": {\n async generate(context) {\n return runOpenAi(fetchImpl, context);\n },\n stream(context) {\n return runOpenAiStream(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverOpenAiModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"OpenAI API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n \"anthropic:api\": {\n async generate(context) {\n return runAnthropic(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverAnthropicModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"Anthropic API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n \"gemini:api\": {\n async generate(context) {\n return runGemini(fetchImpl, context);\n },\n async discoverModels(context) {\n return discoverGeminiModels(fetchImpl, context);\n },\n verify({ route, runtime }) {\n try {\n return verifyApiRoute(route, runtime);\n } catch (error) {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(\"auth_error\", \"Gemini API key verification failed.\");\n return [{ code: \"handler_issue\", message: normalized.message }];\n }\n },\n },\n };\n}\n", "export const AI_CONNECT_DEFAULT_ACP_COMMANDS: Record<string, string> = {\n \"anthropic:claude-code-acp\": \"npx -y @agentclientprotocol/claude-agent-acp@^0.25.0\",\n \"openai:codex-acp\": \"npx @zed-industries/codex-acp@^0.11.1\",\n \"opencode:opencode-acp\": \"opencode acp\",\n};\n", "export type ServerTransportPreset = {\n id: string;\n label: string;\n command: string;\n transportId: string;\n};\n\n// SYS-4: keyed by `string` (not the literal `\"opencode\"`) so registering a\n// second preset is not a breaking type change.\nexport const AI_CONNECT_DEFAULT_SERVER_PRESETS: Record<\n string,\n ServerTransportPreset\n> =\n {\n opencode: {\n id: \"opencode\",\n label: \"OpenCode Server\",\n command: \"opencode serve\",\n transportId: \"opencode-server\",\n },\n };\n\nexport const AI_CONNECT_DEFAULT_SERVER_COMMANDS: Record<string, string> =\n Object.fromEntries(\n Object.values(AI_CONNECT_DEFAULT_SERVER_PRESETS).map((preset) => [\n `${preset.id}:${preset.transportId}`,\n preset.command,\n ]),\n );\n", "import { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport { AI_CONNECT_DEFAULT_CLI_COMMANDS } from \"./cli-presets.js\";\nimport { AI_CONNECT_DEFAULT_SERVER_COMMANDS } from \"./server-presets.js\";\nimport type { RuntimeKind, TransportKind } from \"./types.js\";\n\nexport type TextTransportCatalogEntry = {\n providerId: string;\n providerLabel: string;\n transportKind: TransportKind;\n transportId: string;\n transportLabel: string;\n runtime: RuntimeKind | \"universal\";\n defaultModel: string;\n defaultBaseUrl?: string;\n defaultCommand?: string;\n};\n\nexport type TextProviderCatalogEntry = {\n providerId: string;\n label: string;\n transports: TextTransportCatalogEntry[];\n};\n\nconst TEXT_PROVIDER_CATALOG: TextProviderCatalogEntry[] = [\n {\n providerId: \"openai\",\n label: \"OpenAI\",\n transports: [\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"OpenAI API\",\n runtime: \"universal\",\n defaultModel: \"gpt-4.1\",\n defaultBaseUrl: \"\",\n },\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"cli\",\n transportId: \"codex-cli\",\n transportLabel: \"Codex CLI\",\n runtime: \"local\",\n defaultModel: \"gpt-5.4/xhigh\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"openai:codex-cli\"]!,\n },\n {\n providerId: \"openai\",\n providerLabel: \"OpenAI\",\n transportKind: \"acp\",\n transportId: \"codex-acp\",\n transportLabel: \"Codex ACP\",\n runtime: \"local\",\n defaultModel: \"gpt-5.4/xhigh\",\n defaultCommand: AI_CONNECT_DEFAULT_ACP_COMMANDS[\"openai:codex-acp\"]!,\n },\n ],\n },\n {\n providerId: \"anthropic\",\n label: \"Anthropic\",\n transports: [\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"Anthropic API\",\n runtime: \"universal\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultBaseUrl: \"\",\n },\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"cli\",\n transportId: \"claude-cli\",\n transportLabel: \"Claude CLI\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"anthropic:claude-cli\"]!,\n },\n {\n providerId: \"anthropic\",\n providerLabel: \"Anthropic\",\n transportKind: \"acp\",\n transportId: \"claude-code-acp\",\n transportLabel: \"Claude Code ACP\",\n runtime: \"local\",\n defaultModel: \"default\",\n defaultCommand:\n AI_CONNECT_DEFAULT_ACP_COMMANDS[\"anthropic:claude-code-acp\"]!,\n },\n ],\n },\n {\n providerId: \"openclaude\",\n label: \"OpenClaude\",\n transports: [\n {\n providerId: \"openclaude\",\n providerLabel: \"OpenClaude\",\n transportKind: \"cli\",\n transportId: \"openclaude-cli\",\n transportLabel: \"OpenClaude CLI\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4-6\",\n defaultCommand:\n AI_CONNECT_DEFAULT_CLI_COMMANDS[\"openclaude:openclaude-cli\"]!,\n },\n ],\n },\n {\n providerId: \"gemini\",\n label: \"Gemini\",\n transports: [\n {\n providerId: \"gemini\",\n providerLabel: \"Gemini\",\n transportKind: \"api\",\n transportId: \"api\",\n transportLabel: \"Gemini API\",\n runtime: \"universal\",\n defaultModel: \"gemini-3.1-flash-lite\",\n defaultBaseUrl: \"\",\n },\n ],\n },\n {\n providerId: \"pi\",\n label: \"pi\",\n transports: [\n {\n providerId: \"pi\",\n providerLabel: \"pi\",\n transportKind: \"cli\",\n transportId: \"pi-cli\",\n transportLabel: \"pi CLI\",\n runtime: \"local\",\n defaultModel: \"gemini-3.1-pro-low\",\n defaultCommand: AI_CONNECT_DEFAULT_CLI_COMMANDS[\"pi:pi-cli\"]!,\n },\n ],\n },\n {\n providerId: \"opencode\",\n label: \"OpenCode\",\n transports: [\n {\n providerId: \"opencode\",\n providerLabel: \"OpenCode\",\n transportKind: \"server\",\n transportId: \"opencode-server\",\n transportLabel: \"OpenCode Server\",\n runtime: \"local\",\n defaultModel: \"claude-sonnet-4\",\n defaultCommand:\n AI_CONNECT_DEFAULT_SERVER_COMMANDS[\"opencode:opencode-server\"]!,\n },\n {\n providerId: \"opencode\",\n providerLabel: \"OpenCode\",\n transportKind: \"acp\",\n transportId: \"opencode-acp\",\n transportLabel: \"OpenCode ACP\",\n runtime: \"local\",\n defaultModel: \"default\",\n defaultCommand: AI_CONNECT_DEFAULT_ACP_COMMANDS[\"opencode:opencode-acp\"]!,\n },\n ],\n },\n];\n\nfunction matchesRuntime(\n transport: TextTransportCatalogEntry,\n runtime: RuntimeKind | undefined,\n): boolean {\n if (!runtime) {\n return true;\n }\n if (transport.runtime === \"universal\") {\n return true;\n }\n return transport.runtime === runtime;\n}\n\nexport function listTextProviderCatalog(options: {\n runtime?: RuntimeKind;\n} = {}): TextProviderCatalogEntry[] {\n const runtime = options.runtime;\n return TEXT_PROVIDER_CATALOG.map((provider) => ({\n ...provider,\n transports: provider.transports.filter((transport) =>\n matchesRuntime(transport, runtime),\n ),\n })).filter((provider) => provider.transports.length > 0);\n}\n\nexport function getTextProviderCatalogEntry(\n providerId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextProviderCatalogEntry | undefined {\n return listTextProviderCatalog(options).find(\n (provider) => provider.providerId === providerId,\n );\n}\n\nexport function getTextTransportPreset(\n providerId: string,\n transportKind: TransportKind,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n return getTextProviderCatalogEntry(providerId, options)?.transports.find(\n (transport) => transport.transportKind === transportKind,\n );\n}\n\nexport function getTextTransportPresetById(\n providerId: string,\n transportId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n return getTextProviderCatalogEntry(providerId, options)?.transports.find(\n (transport) => transport.transportId === transportId,\n );\n}\n\nexport function getDefaultTextTransportPreset(\n providerId: string,\n options: {\n runtime?: RuntimeKind;\n } = {},\n): TextTransportCatalogEntry | undefined {\n const provider = getTextProviderCatalogEntry(providerId, options);\n if (!provider) {\n return undefined;\n }\n return (\n provider.transports.find((transport) => transport.transportKind === \"api\") ||\n provider.transports[0]\n );\n}\n", "import { createClient } from \"./client.js\";\nimport { defineConfig, isNormalizedConfig } from \"./config.js\";\nimport { createDefaultRouteHandlers } from \"./default-handlers.js\";\nimport { createBrowserRuntimeEnvironment } from \"./runtime.js\";\nimport type {\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CreateClientOptions,\n RuntimeEnvironment,\n} from \"./types.js\";\n\nexport function createBrowserClient(\n configOrInput: AiConnectConfig | AiConnectConfigInput,\n options: Omit<CreateClientOptions, \"runtime\"> & {\n runtime?: Partial<RuntimeEnvironment>;\n } = {},\n): AiConnectClient {\n const config = isNormalizedConfig(configOrInput)\n ? configOrInput\n : defineConfig(configOrInput);\n\n return createClient(config, {\n ...options,\n handlers: {\n ...createDefaultRouteHandlers(\n options.fetch ? { fetch: options.fetch } : {},\n ),\n ...(options.handlers ?? {}),\n },\n runtime: createBrowserRuntimeEnvironment(options.runtime),\n });\n}\n", "import { accessSync, constants } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\n\nimport { createClient } from \"./client.js\";\nimport { defineConfig, isNormalizedConfig } from \"./config.js\";\nimport { createDefaultRouteHandlers } from \"./default-handlers.js\";\nimport { createLocalRouteHandlers } from \"./local-handlers.js\";\nimport { createLocalRuntimeEnvironment } from \"./runtime.js\";\nimport type {\n AiConnectClient,\n AiConnectConfig,\n AiConnectConfigInput,\n CreateClientOptions,\n RuntimeEnvironment,\n} from \"./types.js\";\n\nfunction executableExists(pathValue: string): boolean {\n try {\n accessSync(pathValue, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findCommand(command: string): boolean {\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n return executableExists(command);\n }\n\n const pathValue = process.env.PATH ?? \"\";\n const segments = pathValue.split(delimiter).filter(Boolean);\n const extensions =\n process.platform === \"win32\" ? [\"\", \".exe\", \".cmd\", \".bat\"] : [\"\"];\n\n for (const segment of segments) {\n for (const extension of extensions) {\n if (executableExists(join(segment, `${command}${extension}`))) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function createDefaultLocalRuntimeEnvironment(\n overrides: Partial<RuntimeEnvironment> = {},\n): RuntimeEnvironment {\n return createLocalRuntimeEnvironment({\n ...overrides,\n getEnv: overrides.getEnv ?? ((name) => process.env[name]),\n hasCommand: overrides.hasCommand ?? ((command) => findCommand(command)),\n });\n}\n\nexport function createLocalClient(\n configOrInput: AiConnectConfig | AiConnectConfigInput,\n options: Omit<CreateClientOptions, \"runtime\"> & {\n runtime?: Partial<RuntimeEnvironment>;\n } = {},\n): AiConnectClient {\n const config = isNormalizedConfig(configOrInput)\n ? configOrInput\n : defineConfig(configOrInput);\n const localHandlers = createLocalRouteHandlers({\n ...(options.acp ? { acp: options.acp } : {}),\n ...(options.cli ? { cli: options.cli } : {}),\n ...(options.server || options.fetch\n ? {\n server: {\n ...(options.server ?? {}),\n ...(options.fetch && !options.server?.fetch\n ? { fetch: options.fetch }\n : {}),\n },\n }\n : {}),\n });\n\n return createClient(config, {\n ...options,\n handlers: {\n ...createDefaultRouteHandlers(\n options.fetch ? { fetch: options.fetch } : {},\n ),\n ...localHandlers.handlers,\n ...(options.handlers ?? {}),\n },\n runtime: createDefaultLocalRuntimeEnvironment(options.runtime),\n dispose: async () => {\n await localHandlers.dispose();\n await options.dispose?.();\n },\n });\n}\n", "import { Buffer } from \"node:buffer\";\nimport { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport {\n isPortableDocumentFile,\n materializePortableFile,\n preparePortableFile,\n} from \"./files.js\";\nimport { fillConfiguredContextLength } from \"./model-reference.js\";\nimport {\n killProcessTree,\n resolveChildEnv,\n resolveManagedCommand,\n trackChild,\n} from \"./transport-runtime.js\";\nimport type {\n AcpLaunchOptions,\n AcpModelCatalog,\n AcpModelInfo,\n AcpClientOptions,\n AcpPermissionMode,\n AcpSessionCacheOptions,\n DiscoverAcpModelsContext,\n GenerateContext,\n GenerateResult,\n GenerateStreamEvent,\n NormalizedRoute,\n PortableFile,\n PortableFileInput,\n RuntimeEnvironment,\n UsageInfo,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype JsonRpcId = number | string | null;\n\ntype JsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: Record<string, unknown>;\n};\n\ntype JsonRpcResponse = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n};\n\ntype JsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n};\n\ntype JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\ntype PromptBlock =\n | {\n type: \"text\";\n text: string;\n }\n | {\n type: \"image\";\n mimeType: string;\n data: string;\n }\n | {\n type: \"resource_link\";\n uri: string;\n title?: string;\n name?: string;\n }\n | {\n type: \"resource\";\n resource: {\n uri: string;\n text?: string;\n // ACP/MCP EmbeddedResource blob shape (C6): base64 contents for binary\n // resources such as PDFs that have no text representation.\n blob?: string;\n mimeType?: string;\n };\n };\n\ntype PendingRequest = {\n resolve: (value: unknown) => void;\n reject: (error: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n};\n\ntype AcpLaunchRuntime = {\n commandLine: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n};\n\ntype PreparedAcpLaunchRuntime = AcpLaunchRuntime & {\n launch: AcpLaunchOptions;\n cleanup?: () => Promise<void>;\n};\n\ntype AcpSandboxPaths = {\n root: string;\n home: string;\n config: string;\n cache: string;\n data: string;\n};\n\ntype AcpPromptOutput = {\n text: string;\n attachments: PortableFileInput[];\n usage?: UsageInfo;\n warnings: string[];\n data: {\n command: string;\n sessionId: string;\n stopReason?: string;\n };\n};\n\ntype AcpAuthRequest = {\n methodId: string;\n params: Record<string, unknown>;\n lifecycleKeys: string[];\n};\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_SESSION_CACHE_IDLE_TTL_MS = 60_000;\n/** Bound the retained stderr buffer on a warm/pooled connection (MEDIUM). */\nconst MAX_ACP_STDERR_CHARS = 64 * 1024;\n/** Bound the in-flight streaming-delta queue so a fast producer cannot grow it without bound (MEDIUM). */\nconst MAX_ACP_STREAM_QUEUE = 1_024;\nconst IMAGE_EXTENSIONS = new Map<string, string>([\n [\".png\", \"image/png\"],\n [\".jpg\", \"image/jpeg\"],\n [\".jpeg\", \"image/jpeg\"],\n [\".webp\", \"image/webp\"],\n [\".gif\", \"image/gif\"],\n [\".svg\", \"image/svg+xml\"],\n]);\n\nconst TEXT_EXTENSIONS = new Set([\n \".txt\",\n \".md\",\n \".json\",\n \".jsonl\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".ts\",\n \".tsx\",\n \".css\",\n \".html\",\n \".xml\",\n \".yaml\",\n \".yml\",\n \".toml\",\n \".ini\",\n \".env\",\n \".csv\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Curated interactive-harness marker patterns (TASK-033 / UR-003). An\n * `claude-agent-acp`-style harness, driven headlessly, sometimes emits these as\n * the `agent_message_chunk` \"answer\" instead of the task output:\n * - a model-switch announcement (\"\u041C\u043E\u0434\u0435\u043B\u044C \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0430 \u043D\u0430 \u2026 \u0413\u043E\u0442\u043E\u0432 \u043A \u0440\u0430\u0431\u043E\u0442\u0435\"),\n * - a standalone readiness/idle greeting (\"\u0413\u043E\u0442\u043E\u0432 \u043A \u0440\u0430\u0431\u043E\u0442\u0435\", \"\u0416\u0434\u0443 \u2026\"),\n * - commentary on its own local-command harness markers.\n * Each regex is ANCHORED to a whole TRIMMED line (`^\u2026$`, case-insensitive,\n * Unicode) so a marker phrase appearing INSIDE a larger legitimate sentence is\n * NOT stripped (F-PLAN-5). The list is intentionally Claude/RU-locale specific;\n * a reworded / other-locale greeting is a documented limitation (F-PLAN-4) \u2014\n * the model-switch root cause is independently removed by `session/set_model`.\n */\nconst ACP_HARNESS_NOISE_PATTERNS: RegExp[] = [\n /^\u043C\u043E\u0434\u0435\u043B\u044C \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0430 \u043D\u0430 .+?\\.?(?:\\s*\u0433\u043E\u0442\u043E\u0432 \u043A \u0440\u0430\u0431\u043E\u0442\u0435[.!\u2026]*)?$/iu,\n /^\u0433\u043E\u0442\u043E\u0432 \u043A \u0440\u0430\u0431\u043E\u0442\u0435[.!\u2026]*$/iu,\n /^\u0436\u0434\u0443 (?:\u0432\u0430\u0448\u0435\u0433\u043E \u0432\u043E\u043F\u0440\u043E\u0441\u0430|\u0432\u043E\u043F\u0440\u043E\u0441\u0430 \u0438\u043B\u0438 \u0437\u0430\u0434\u0430\u0447\u0438|\u0432\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438|\u0432\u0430\u0448\u0435\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430|\u044F\u0432\u043D\u043E\u0433\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430)[^]*$/iu,\n /^\u044D\u0442\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043F\u043E\u043C\u0435\u0447\u0435\u043D\u043E \u043A\u0430\u043A \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430[^]*$/iu,\n /^<local-command-(?:caveat|stdout|name|message|args)[^>]*>[^]*$/iu,\n];\n\n/**\n * True iff `line` (after trimming) is ENTIRELY one of the curated harness\n * markers. Empty/whitespace lines are NOT markers (a real answer may contain\n * blank lines); they are handled by the buffer/join logic, not classified here.\n */\nfunction isHarnessNoiseLine(line: string): boolean {\n const trimmed = line.trim();\n if (trimmed.length === 0) {\n return false;\n }\n return ACP_HARNESS_NOISE_PATTERNS.some((pattern) => pattern.test(trimmed));\n}\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\n \"validation_error\",\n \"ACP command line is empty.\",\n );\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction normalizeLaunchOptions(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): AcpLaunchOptions {\n return {\n contextMode:\n route.transport.launch?.contextMode ??\n options?.launch?.contextMode ??\n \"workspace\",\n skillsMode:\n route.transport.launch?.skillsMode ??\n options?.launch?.skillsMode ??\n \"default\",\n };\n}\n\nfunction appendCommandArg(\n commandLine: string,\n argument: string,\n): string {\n const { args } = splitCommandLine(commandLine);\n if (args.includes(argument)) {\n return commandLine;\n }\n\n return `${commandLine} ${argument}`;\n}\n\nfunction appendCommandSnippet(\n commandLine: string,\n snippet: string,\n): string {\n return `${commandLine} ${snippet}`;\n}\n\nfunction resolveHomeDir(env: NodeJS.ProcessEnv): string {\n return env.HOME ?? os.homedir();\n}\n\nfunction resolveXdgConfigHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_CONFIG_HOME ?? path.join(resolveHomeDir(env), \".config\");\n}\n\nfunction resolveXdgCacheHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_CACHE_HOME ?? path.join(resolveHomeDir(env), \".cache\");\n}\n\nfunction resolveXdgDataHome(env: NodeJS.ProcessEnv): string {\n return env.XDG_DATA_HOME ?? path.join(resolveHomeDir(env), \".local\", \"share\");\n}\n\nfunction resolveCodexHome(env: NodeJS.ProcessEnv): string {\n return env.CODEX_HOME ?? path.join(resolveHomeDir(env), \".codex\");\n}\n\nfunction resolveCodexSqliteHome(env: NodeJS.ProcessEnv): string {\n return env.CODEX_SQLITE_HOME ?? resolveCodexHome(env);\n}\n\nfunction resolveOpencodeConfigDir(env: NodeJS.ProcessEnv): string {\n return (\n env.OPENCODE_CONFIG_DIR ??\n path.join(resolveXdgConfigHome(env), \"opencode\")\n );\n}\n\nasync function createSandboxPaths(\n prefix: string,\n): Promise<AcpSandboxPaths> {\n const root = await fs.mkdtemp(path.join(os.tmpdir(), prefix));\n const home = path.join(root, \"home\");\n const config = path.join(root, \"config\");\n const cache = path.join(root, \"cache\");\n const data = path.join(root, \"data\");\n\n await Promise.all(\n [home, config, cache, data].map((directory) =>\n fs.mkdir(directory, { recursive: true }),\n ),\n );\n\n return {\n root,\n home,\n config,\n cache,\n data,\n };\n}\n\nasync function maybeCopyFile(\n sourcePath: string,\n destinationPath: string,\n): Promise<void> {\n try {\n await fs.mkdir(path.dirname(destinationPath), { recursive: true });\n await fs.copyFile(sourcePath, destinationPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\nasync function maybeCopyDirectory(\n sourcePath: string,\n destinationPath: string,\n): Promise<void> {\n try {\n await fs.cp(sourcePath, destinationPath, { recursive: true });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\nasync function removeIfExists(targetPath: string): Promise<void> {\n await fs.rm(targetPath, { recursive: true, force: true }).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n}\n\nasync function readJsonFile(\n filePath: string,\n): Promise<Record<string, unknown> | undefined> {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(raw);\n return isRecord(parsed) ? parsed : undefined;\n } catch (error) {\n if (\n error instanceof SyntaxError ||\n (error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction mergeRecordValues(\n current: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...current };\n\n for (const [key, value] of Object.entries(next)) {\n const existing = merged[key];\n if (isRecord(existing) && isRecord(value)) {\n merged[key] = mergeRecordValues(existing, value);\n continue;\n }\n merged[key] = value;\n }\n\n return merged;\n}\n\nasync function writeJsonFile(\n filePath: string,\n value: Record<string, unknown>,\n): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nasync function writeTextFile(\n filePath: string,\n value: string,\n): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, value, \"utf8\");\n}\n\nasync function prepareOpenCodeLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): Promise<PreparedAcpLaunchRuntime> {\n if (\n launch.contextMode === \"workspace\" &&\n launch.skillsMode === \"default\"\n ) {\n return {\n ...base,\n launch,\n };\n }\n\n const sandbox = await createSandboxPaths(\"ai-connect-opencode-acp-\");\n const originalConfigDir = resolveOpencodeConfigDir(base.env);\n const sandboxConfigDir = path.join(sandbox.config, \"opencode\");\n await fs.mkdir(sandboxConfigDir, { recursive: true });\n await Promise.all(\n [\n \"config.json\",\n \"config.jsonc\",\n \"opencode.json\",\n \"opencode.jsonc\",\n \"tui.json\",\n \"tui.jsonc\",\n ].map((fileName) =>\n maybeCopyFile(\n path.join(originalConfigDir, fileName),\n path.join(sandboxConfigDir, fileName),\n ),\n ),\n );\n\n return {\n commandLine: base.commandLine,\n cwd: base.cwd,\n env: {\n ...base.env,\n OPENCODE_CONFIG_DIR: sandboxConfigDir,\n ...(launch.contextMode === \"clean\"\n ? {\n OPENCODE_DISABLE_PROJECT_CONFIG: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE_PROMPT: \"1\",\n }\n : {}),\n ...(launch.skillsMode === \"disabled\"\n ? {\n OPENCODE_DISABLE_EXTERNAL_SKILLS: \"1\",\n OPENCODE_DISABLE_CLAUDE_CODE_SKILLS: \"1\",\n }\n : {}),\n },\n launch,\n cleanup: async () => {\n await removeIfExists(sandbox.root);\n },\n };\n}\n\nasync function prepareCodexLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): Promise<PreparedAcpLaunchRuntime> {\n if (\n launch.contextMode === \"workspace\" &&\n launch.skillsMode === \"default\"\n ) {\n return {\n ...base,\n launch,\n };\n }\n\n const sandbox = await createSandboxPaths(\"ai-connect-codex-acp-\");\n const originalCodexHome = resolveCodexHome(base.env);\n const originalCodexSqliteHome = resolveCodexSqliteHome(base.env);\n const sandboxCodexHome = path.join(sandbox.home, \".codex\");\n const isolatedCwd =\n launch.contextMode === \"clean\" || launch.skillsMode === \"disabled\"\n ? sandbox.root\n : base.cwd;\n\n await Promise.all([\n maybeCopyFile(\n path.join(originalCodexHome, \"config.toml\"),\n path.join(sandboxCodexHome, \"config.toml\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"auth.json\"),\n path.join(sandboxCodexHome, \"auth.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \".credentials.json\"),\n path.join(sandboxCodexHome, \".credentials.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"models_cache.json\"),\n path.join(sandboxCodexHome, \"models_cache.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \"version.json\"),\n path.join(sandboxCodexHome, \"version.json\"),\n ),\n maybeCopyFile(\n path.join(originalCodexHome, \".codex-global-state.json\"),\n path.join(sandboxCodexHome, \".codex-global-state.json\"),\n ),\n ]);\n\n let commandLine = base.commandLine;\n const cleanOverrides = [\n \"project_doc_max_bytes=0\",\n \"project_doc_fallback_filenames=[]\",\n \"history.persistence=\\\"none\\\"\",\n \"memories.use_memories=false\",\n \"memories.generate_memories=false\",\n \"features.plugins=false\",\n \"features.apps=false\",\n \"features.shell_snapshot=false\",\n \"mcp_servers={}\",\n ];\n\n for (const override of cleanOverrides) {\n commandLine = appendCommandSnippet(commandLine, `-c ${override}`);\n }\n\n if (launch.skillsMode === \"disabled\") {\n commandLine = appendCommandSnippet(\n commandLine,\n \"-c skills.bundled.enabled=false\",\n );\n }\n\n if (launch.contextMode === \"clean\" || launch.skillsMode === \"disabled\") {\n commandLine = appendCommandSnippet(\n commandLine,\n `-c projects.\"${isolatedCwd}\".trust_level=\"trusted\"`,\n );\n }\n\n const env: NodeJS.ProcessEnv = {\n ...base.env,\n HOME: sandbox.home,\n XDG_CONFIG_HOME: sandbox.config,\n XDG_CACHE_HOME: sandbox.cache,\n XDG_DATA_HOME: sandbox.data,\n CODEX_HOME: sandboxCodexHome,\n CODEX_SQLITE_HOME: originalCodexSqliteHome,\n };\n\n for (const key of [\n \"CODEX_THREAD_ID\",\n \"CODEX_INTERNAL_ORIGINATOR_OVERRIDE\",\n \"CODEX_SHELL\",\n \"CODEX_CI\",\n ]) {\n delete env[key];\n }\n\n return {\n commandLine,\n cwd: isolatedCwd,\n env,\n launch,\n cleanup: async () => {\n await removeIfExists(sandbox.root);\n },\n };\n}\n\nfunction prepareClaudeLaunchRuntime(\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n): PreparedAcpLaunchRuntime {\n let commandLine = base.commandLine;\n\n if (launch.contextMode === \"clean\") {\n commandLine = appendCommandArg(commandLine, \"--bare\");\n }\n if (launch.skillsMode === \"disabled\") {\n commandLine = appendCommandArg(commandLine, \"--disable-slash-commands\");\n }\n\n return {\n commandLine,\n cwd: base.cwd,\n env: base.env,\n launch,\n };\n}\n\ntype LaunchRuntimePreparer = (\n base: AcpLaunchRuntime,\n launch: AcpLaunchOptions,\n) => PreparedAcpLaunchRuntime | Promise<PreparedAcpLaunchRuntime>;\n\n/**\n * SYS-4/D4: transport-id \u2192 launch-runtime preparer registry. Replaces the\n * hardcoded if/else dispatch on `route.transport.id`; adding an ACP transport is\n * now a single registry entry rather than a new branch.\n */\nconst ACP_LAUNCH_PREPARERS: Record<string, LaunchRuntimePreparer> = {\n \"opencode-acp\": prepareOpenCodeLaunchRuntime,\n \"codex-acp\": prepareCodexLaunchRuntime,\n \"claude-code-acp\": prepareClaudeLaunchRuntime,\n};\n\nasync function prepareAcpLaunchRuntime(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n commandLine: string,\n cwdOverride?: string,\n): Promise<PreparedAcpLaunchRuntime> {\n const launch = normalizeLaunchOptions(route, options);\n const base: AcpLaunchRuntime = {\n commandLine,\n cwd: path.resolve(cwdOverride ?? options?.cwd ?? process.cwd()),\n // SYS-2: minimal env by default \u2014 do NOT hand the host's full process.env\n // (other-provider keys, CI tokens) to third-party ACP agents. Extra env is\n // layered via options.env.\n env: resolveChildEnv({ extra: options?.env ?? {} }),\n };\n\n const preparer = ACP_LAUNCH_PREPARERS[route.transport.id];\n if (preparer) {\n return await preparer(base, launch);\n }\n\n // D4: unknown transport id \u2014 no preparer can honor context/skills isolation\n // generically. Warn (rather than silently ignore) when isolation was requested\n // so a partially-wired preset surfaces, then fall back to a plain launch.\n if (launch.contextMode !== \"workspace\" || launch.skillsMode !== \"default\") {\n console.warn(\n `[ai-connect] ACP transport \"${route.transport.id}\" has no launch-runtime ` +\n `preparer; requested contextMode/skillsMode isolation is not applied.`,\n );\n }\n\n return {\n ...base,\n launch,\n };\n}\n\nfunction promptTimeout(options: AcpClientOptions | undefined): number {\n return options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n}\n\nfunction basename(value: string): string {\n const normalized = value.replaceAll(\"\\\\\", \"/\");\n const tail = normalized.split(\"/\").pop();\n return tail && tail.length > 0 ? tail : \"file\";\n}\n\nfunction parseDataUrl(value: string): {\n mimeType: string;\n data: string;\n} | null {\n // Tolerate intermediate media-type params before `;base64`, e.g.\n // `data:text/plain;charset=utf-8;base64,...` (F-S1-1, mirrors src/files.ts #14).\n const match = /^data:([^,]*?);base64,(.*)$/i.exec(value);\n if (!match) {\n return null;\n }\n\n const mediaType = (match[1] ?? \"\").split(\";\")[0]?.trim() ?? \"\";\n return {\n mimeType: mediaType.length > 0 ? mediaType : \"application/octet-stream\",\n data: match[2] ?? \"\",\n };\n}\n\nfunction mimeTypeFromPath(filePath: string): string | undefined {\n return IMAGE_EXTENSIONS.get(path.extname(filePath).toLowerCase());\n}\n\nfunction isTextPath(filePath: string): boolean {\n return TEXT_EXTENSIONS.has(path.extname(filePath).toLowerCase());\n}\n\n/**\n * Resolve the realpath of `target`, tolerating a not-yet-existing target\n * (e.g. a `writeTextFile` to a new file) by resolving the nearest existing\n * ancestor and re-appending the remaining segments. This ensures a symlinked\n * PARENT directory cannot smuggle a path outside the sandbox root.\n */\nasync function resolveRealPathTolerant(target: string): Promise<string> {\n try {\n return await fs.realpath(target);\n } catch {\n const parent = path.dirname(target);\n if (parent === target) {\n return target;\n }\n const realParent = await resolveRealPathTolerant(parent);\n return path.join(realParent, path.basename(target));\n }\n}\n\n/**\n * Containment check hardened against symlink escape (MEDIUM): both the root and\n * the target are canonicalized via `fs.realpath` before comparison, so an\n * `approve-all` agent cannot read/write outside the cwd through a symlink.\n */\nasync function isWithinRoot(\n rootDir: string,\n targetPath: string,\n): Promise<boolean> {\n let realRoot: string;\n try {\n realRoot = await fs.realpath(rootDir);\n } catch {\n realRoot = path.resolve(rootDir);\n }\n const realTarget = await resolveRealPathTolerant(path.resolve(targetPath));\n const relative = path.relative(realRoot, realTarget);\n return (\n relative.length === 0 ||\n (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n );\n}\n\nfunction buildMessageTranscript(context: GenerateContext): string {\n return context.request.messages\n .map((message) => `${message.role.toUpperCase()}:\\n${message.content}`)\n .join(\"\\n\\n\")\n .trim();\n}\n\nasync function fileToPromptBlocks(file: PortableFile): Promise<PromptBlock[]> {\n // C6: PDF (and any SUPPORTED_DOCUMENT_MIME_TYPES) \u2192 an ACP EmbeddedResource\n // blob via the single decode path. A remote document with only a uri degrades\n // to a resource_link; never an empty blob.\n if (isPortableDocumentFile(file)) {\n const payload = await materializePortableFile(file);\n if (payload.base64) {\n return [\n {\n type: \"resource\",\n resource: {\n uri:\n payload.uri ??\n (file.kind === \"path\" && typeof file.source === \"string\"\n ? pathToFileURL(file.source).href\n : `attachment:${file.name}`),\n blob: payload.base64,\n mimeType: payload.mimeType,\n },\n },\n ];\n }\n if (payload.uri) {\n return [\n {\n type: \"resource_link\",\n uri: payload.uri,\n name: file.name,\n title: file.name,\n },\n ];\n }\n }\n\n if (file.kind === \"data-url\" && typeof file.source === \"string\") {\n const parsed = parseDataUrl(file.source);\n if (parsed && parsed.mimeType.startsWith(\"image/\")) {\n return [\n {\n type: \"image\",\n mimeType: parsed.mimeType,\n data: parsed.data,\n },\n ];\n }\n }\n\n if (file.kind === \"remote\") {\n const source = isRecord(file.source) ? file.source : {};\n const uri = typeof source.uri === \"string\" ? source.uri : undefined;\n if (uri) {\n return [\n {\n type: \"resource_link\",\n uri,\n name: file.name,\n title: file.name,\n },\n ];\n }\n }\n\n if (file.kind === \"path\" && typeof file.source === \"string\") {\n const imageMimeType = mimeTypeFromPath(file.source);\n if (imageMimeType) {\n const data = await fs.readFile(file.source);\n return [\n {\n type: \"image\",\n mimeType: imageMimeType,\n data: data.toString(\"base64\"),\n },\n ];\n }\n\n if (isTextPath(file.source)) {\n const content = await fs.readFile(file.source, \"utf8\");\n return [\n {\n type: \"resource\",\n resource: {\n uri: pathToFileURL(file.source).href,\n text: content,\n },\n },\n ];\n }\n\n return [\n {\n type: \"resource_link\",\n uri: pathToFileURL(file.source).href,\n name: basename(file.source),\n title: basename(file.source),\n },\n ];\n }\n\n return [\n {\n type: \"text\",\n text: `[attachment] ${file.name}`,\n },\n ];\n}\n\nasync function toPromptBlocks(context: GenerateContext): Promise<PromptBlock[]> {\n const blocks: PromptBlock[] = [];\n const transcript = buildMessageTranscript(context);\n\n if (transcript) {\n blocks.push({\n type: \"text\",\n text: transcript,\n });\n }\n\n for (const attachment of context.request.attachments) {\n const next = await fileToPromptBlocks(attachment);\n blocks.push(...next);\n }\n\n return blocks;\n}\n\nfunction inferPermissionKind(request: Record<string, unknown>): string | undefined {\n const toolCall = isRecord(request.toolCall) ? request.toolCall : undefined;\n const explicitKind =\n toolCall && typeof toolCall.kind === \"string\" ? toolCall.kind : undefined;\n if (explicitKind) {\n return explicitKind;\n }\n\n const title =\n toolCall && typeof toolCall.title === \"string\"\n ? toolCall.title.trim().toLowerCase()\n : \"\";\n if (!title) {\n return undefined;\n }\n\n if (title.includes(\"read\") || title.includes(\"cat\")) {\n return \"read\";\n }\n if (title.includes(\"search\") || title.includes(\"find\") || title.includes(\"grep\")) {\n return \"search\";\n }\n if (title.includes(\"write\") || title.includes(\"edit\") || title.includes(\"patch\")) {\n return \"edit\";\n }\n if (title.includes(\"delete\") || title.includes(\"remove\")) {\n return \"delete\";\n }\n if (title.includes(\"run\") || title.includes(\"execute\") || title.includes(\"bash\")) {\n return \"execute\";\n }\n\n return \"other\";\n}\n\nfunction selectPermissionResponse(\n params: Record<string, unknown>,\n mode: AcpPermissionMode,\n): Record<string, unknown> {\n const options = Array.isArray(params.options)\n ? params.options.filter((value): value is Record<string, unknown> => isRecord(value))\n : [];\n\n const allowOption = options.find((option) => {\n const kind = option.kind;\n return kind === \"allow_once\" || kind === \"allow_always\";\n });\n const rejectOption = options.find((option) => {\n const kind = option.kind;\n return kind === \"reject_once\" || kind === \"reject_always\";\n });\n\n const selected = (optionId: unknown) => ({\n outcome: {\n outcome: \"selected\",\n optionId,\n },\n });\n\n if (mode === \"approve-all\") {\n return selected(\n allowOption?.optionId ?? options[0]?.optionId ?? \"allow-once\",\n );\n }\n\n if (mode === \"approve-reads\") {\n const kind = inferPermissionKind(params);\n if ((kind === \"read\" || kind === \"search\") && allowOption?.optionId) {\n return selected(allowOption.optionId);\n }\n }\n\n if (rejectOption?.optionId) {\n return selected(rejectOption.optionId);\n }\n\n return {\n outcome: {\n outcome: \"cancelled\",\n },\n };\n}\n\nfunction readNumberField(\n record: Record<string, unknown>,\n keys: string[],\n): number | undefined {\n for (const key of keys) {\n if (typeof record[key] === \"number\") {\n return record[key] as number;\n }\n }\n\n return undefined;\n}\n\nfunction normalizeUsageModel(\n value: unknown,\n): UsageInfo[\"modelUsage\"] extends Array<infer T> ? T | undefined : never {\n if (!isRecord(value)) {\n return undefined as never;\n }\n\n const modelId =\n typeof value.modelId === \"string\"\n ? value.modelId\n : typeof value.model === \"string\"\n ? value.model\n : typeof value.id === \"string\"\n ? value.id\n : undefined;\n if (!modelId?.trim()) {\n return undefined as never;\n }\n\n const tokenCount = isRecord(value.token_count) ? value.token_count : undefined;\n const inputTokens =\n readNumberField(value, [\"inputTokens\", \"input_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"input_tokens\", \"inputTokens\"]) : undefined);\n const outputTokens =\n readNumberField(value, [\"outputTokens\", \"output_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"output_tokens\", \"outputTokens\"]) : undefined);\n const totalTokens =\n readNumberField(value, [\"totalTokens\", \"total_tokens\"]) ??\n (tokenCount ? readNumberField(tokenCount, [\"total_tokens\", \"totalTokens\"]) : undefined);\n const reasoningTokens =\n readNumberField(value, [\"reasoningTokens\", \"reasoning_tokens\", \"thoughtTokens\", \"thought_tokens\"]) ??\n (tokenCount\n ? readNumberField(tokenCount, [\n \"reasoning_tokens\",\n \"reasoningTokens\",\n \"thought_tokens\",\n \"thoughtTokens\",\n ])\n : undefined);\n const cachedReadTokens =\n readNumberField(value, [\"cachedReadTokens\", \"cached_read_tokens\"]) ??\n (tokenCount\n ? readNumberField(tokenCount, [\"cached_read_tokens\", \"cachedReadTokens\"])\n : undefined);\n const name =\n typeof value.name === \"string\" && value.name.trim().length > 0\n ? value.name\n : undefined;\n\n return {\n modelId,\n ...(name ? { name } : {}),\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n } as never;\n}\n\nfunction mergeModelUsage(\n current: UsageInfo[\"modelUsage\"] | undefined,\n next: UsageInfo[\"modelUsage\"] | undefined,\n): UsageInfo[\"modelUsage\"] | undefined {\n if (!current?.length) {\n return next?.length ? [...next] : undefined;\n }\n if (!next?.length) {\n return [...current];\n }\n\n const merged = new Map(current.map((entry) => [entry.modelId, { ...entry }]));\n\n for (const entry of next) {\n const existing = merged.get(entry.modelId);\n if (!existing) {\n merged.set(entry.modelId, { ...entry });\n continue;\n }\n\n merged.set(entry.modelId, {\n ...existing,\n ...(entry.name ? { name: entry.name } : {}),\n ...(entry.inputTokens !== undefined\n ? { inputTokens: (existing.inputTokens ?? 0) + entry.inputTokens }\n : {}),\n ...(entry.outputTokens !== undefined\n ? { outputTokens: (existing.outputTokens ?? 0) + entry.outputTokens }\n : {}),\n ...(entry.totalTokens !== undefined\n ? { totalTokens: (existing.totalTokens ?? 0) + entry.totalTokens }\n : {}),\n ...(entry.reasoningTokens !== undefined\n ? {\n reasoningTokens:\n (existing.reasoningTokens ?? 0) + entry.reasoningTokens,\n }\n : {}),\n ...(entry.cachedReadTokens !== undefined\n ? {\n cachedReadTokens:\n (existing.cachedReadTokens ?? 0) + entry.cachedReadTokens,\n }\n : {}),\n });\n }\n\n return [...merged.values()];\n}\n\nfunction sumOptionalNumbers(\n left: number | undefined,\n right: number | undefined,\n): number | undefined {\n if (left === undefined) {\n return right;\n }\n if (right === undefined) {\n return left;\n }\n\n return left + right;\n}\n\nfunction mergeUsageInfo(\n current: UsageInfo | undefined,\n next: UsageInfo | undefined,\n): UsageInfo | undefined {\n if (!current) {\n return next ? { ...next } : undefined;\n }\n if (!next) {\n return { ...current };\n }\n\n const modelUsage = mergeModelUsage(\n current.modelUsage,\n next.modelUsage,\n );\n\n // INV-USAGE-1: the shallow `...next` spread CLOBBERS `calls`; sum it back so\n // two prompt results yield calls:2 not 1. Must come AFTER `...next`.\n const calls = sumOptionalNumbers(current.calls, next.calls);\n\n return {\n ...current,\n ...next,\n ...(modelUsage ? { modelUsage } : {}),\n ...(calls !== undefined ? { calls } : {}),\n };\n}\n\nfunction usageFromGenericUsageRecord(\n usage: Record<string, unknown>,\n): UsageInfo | undefined {\n const inputTokens = readNumberField(usage, [\"inputTokens\", \"input_tokens\"]);\n const outputTokens = readNumberField(usage, [\"outputTokens\", \"output_tokens\"]);\n const totalTokens = readNumberField(usage, [\"totalTokens\", \"total_tokens\"]);\n const reasoningTokens = readNumberField(usage, [\n \"reasoningTokens\",\n \"reasoning_tokens\",\n \"thoughtTokens\",\n \"thought_tokens\",\n ]);\n const cachedReadTokens = readNumberField(usage, [\n \"cachedReadTokens\",\n \"cached_read_tokens\",\n ]);\n\n const hasAny =\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n totalTokens !== undefined ||\n reasoningTokens !== undefined ||\n cachedReadTokens !== undefined;\n\n return hasAny\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n }\n : undefined;\n}\n\nfunction usageFromMeta(meta: Record<string, unknown>): UsageInfo | undefined {\n const usage = isRecord(meta.usage) ? usageFromGenericUsageRecord(meta.usage) : undefined;\n const durationMs = readNumberField(meta, [\"durationMs\", \"duration_ms\"]);\n\n return mergeUsageInfo(\n usage,\n durationMs !== undefined\n ? {\n durationMs,\n }\n : undefined,\n );\n}\n\nfunction usageFromUpdate(update: Record<string, unknown>): UsageInfo | undefined {\n const generic = usageFromGenericUsageRecord(update);\n const contextWindowUsed = readNumberField(update, [\"used\"]);\n const contextWindowSize = readNumberField(update, [\"size\"]);\n const costRecord = isRecord(update.cost) ? update.cost : undefined;\n const costAmount = costRecord ? readNumberField(costRecord, [\"amount\"]) : undefined;\n const costCurrency =\n costRecord && typeof costRecord.currency === \"string\"\n ? costRecord.currency\n : undefined;\n\n return mergeUsageInfo(\n generic,\n contextWindowUsed !== undefined ||\n contextWindowSize !== undefined ||\n costAmount !== undefined\n ? {\n ...(contextWindowUsed !== undefined ? { contextWindowUsed } : {}),\n ...(contextWindowSize !== undefined ? { contextWindowSize } : {}),\n ...(costAmount !== undefined\n ? {\n cost: {\n amount: costAmount,\n ...(costCurrency ? { currency: costCurrency } : {}),\n },\n }\n : {}),\n }\n : undefined,\n );\n}\n\n/**\n * True iff `usage` carries an ACTUAL token measurement \u2014 input/output/reasoning/\n * total/cached token counts or a per-model token breakdown. Timing-only or\n * context-window-only metadata (`durationMs`, `contextWindowUsed/Size`) is NOT\n * token usage: stamping `calls:1` on it (INV-USAGE-1) would fabricate a billed\n * call with zero tokens. Used to gate the call counter in usageFromPromptResult.\n */\nfunction hasTokenUsage(usage: UsageInfo): boolean {\n return (\n usage.inputTokens !== undefined ||\n usage.outputTokens !== undefined ||\n usage.reasoningTokens !== undefined ||\n usage.totalTokens !== undefined ||\n usage.cachedReadTokens !== undefined ||\n (usage.modelUsage?.length ?? 0) > 0\n );\n}\n\nfunction usageFromPromptResult(result: unknown): UsageInfo | undefined {\n if (!isRecord(result)) {\n return undefined;\n }\n\n const meta = isRecord(result._meta) ? result._meta : undefined;\n const quota = meta && isRecord(meta.quota) ? meta.quota : undefined;\n if (!quota) {\n const metaUsage = meta ? usageFromMeta(meta) : undefined;\n // INV-USAGE-1: a TOKEN-bearing prompt result counts as exactly one call.\n // Forced ONLY here (never in usageFromMeta/usageFromUpdate/...) so streaming\n // chunks do not inflate the counter. Gate on actual token usage so a\n // timing-only `_meta:{durationMs}` does NOT fabricate `calls:1` (zero tokens).\n if (!metaUsage) {\n return undefined;\n }\n return hasTokenUsage(metaUsage) ? { ...metaUsage, calls: 1 } : metaUsage;\n }\n\n const tokenCount = isRecord(quota.token_count) ? quota.token_count : undefined;\n const inputTokens = tokenCount\n ? readNumberField(tokenCount, [\"input_tokens\", \"inputTokens\"])\n : undefined;\n const outputTokens = tokenCount\n ? readNumberField(tokenCount, [\"output_tokens\", \"outputTokens\"])\n : undefined;\n const modelUsage = Array.isArray(quota.model_usage)\n ? quota.model_usage\n .map((entry) => normalizeUsageModel(entry))\n .filter((entry) => entry !== undefined)\n : undefined;\n\n const merged = mergeUsageInfo(\n meta ? usageFromMeta(meta) : undefined,\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n modelUsage?.length\n ? {\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(modelUsage?.length ? { modelUsage } : {}),\n }\n : undefined,\n );\n\n // INV-USAGE-1: force a single call count at the tail of usageFromPromptResult\n // only (never in usageFromMeta/usageFromUpdate/usageFromGenericUsageRecord), and\n // ONLY when actual token usage is present \u2014 timing-only metadata must not\n // fabricate a billed call with zero tokens.\n if (!merged) {\n return undefined;\n }\n return hasTokenUsage(merged) ? { ...merged, calls: 1 } : merged;\n}\n\nfunction normalizeAcpModel(value: unknown): AcpModelInfo | undefined {\n if (!isRecord(value)) {\n return undefined;\n }\n\n const modelId =\n typeof value.modelId === \"string\"\n ? value.modelId\n : typeof value.id === \"string\"\n ? value.id\n : undefined;\n if (!modelId?.trim()) {\n return undefined;\n }\n\n const name =\n typeof value.name === \"string\" && value.name.trim().length > 0\n ? value.name\n : modelId;\n const description =\n typeof value.description === \"string\" && value.description.trim().length > 0\n ? value.description\n : undefined;\n const metadata = Object.fromEntries(\n Object.entries(value).filter(([key]) =>\n ![\"modelId\", \"id\", \"name\", \"description\"].includes(key),\n ),\n );\n\n return {\n modelId,\n name,\n ...(description ? { description } : {}),\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n };\n}\n\nfunction modelCatalogFromSession(result: unknown): AcpModelCatalog | undefined {\n if (!isRecord(result)) {\n return undefined;\n }\n\n const models = result.models;\n const modelState = isRecord(models)\n ? models\n : Array.isArray(models)\n ? { availableModels: models }\n : undefined;\n if (!modelState) {\n return undefined;\n }\n\n const availableModels = Array.isArray(modelState.availableModels)\n ? modelState.availableModels\n .map((entry) => normalizeAcpModel(entry))\n .filter((entry) => entry !== undefined)\n : [];\n const currentModelId =\n typeof modelState.currentModelId === \"string\" &&\n modelState.currentModelId.trim().length > 0\n ? modelState.currentModelId\n : availableModels[0]?.modelId;\n\n if (!currentModelId && availableModels.length === 0) {\n return undefined;\n }\n\n return {\n ...(currentModelId ? { currentModelId } : {}),\n availableModels,\n };\n}\n\nfunction attachmentFromContent(\n content: Record<string, unknown>,\n): PortableFileInput | undefined {\n if (content.type === \"image\") {\n const mimeType =\n typeof content.mimeType === \"string\"\n ? content.mimeType\n : \"image/png\";\n const data = typeof content.data === \"string\" ? content.data : undefined;\n if (data) {\n return `data:${mimeType};base64,${data}`;\n }\n }\n\n if (content.type === \"resource_link\" && typeof content.uri === \"string\") {\n return {\n uri: content.uri,\n name:\n typeof content.name === \"string\"\n ? content.name\n : typeof content.title === \"string\"\n ? content.title\n : basename(content.uri),\n };\n }\n\n return undefined;\n}\n\nfunction extractTextChunk(update: Record<string, unknown>): string | undefined {\n if (typeof update.text === \"string\" && update.text.length > 0) {\n return update.text;\n }\n\n const content = isRecord(update.content) ? update.content : undefined;\n if (content?.type !== \"text\") {\n return undefined;\n }\n\n return typeof content.text === \"string\" && content.text.length > 0\n ? content.text\n : undefined;\n}\n\n// Precise auth-failure classification. The bare substring \"auth\" over-matched\n// incidental words (\"authorization\" header mentions, \"oauth\", module paths) and\n// misclassified generic transport errors as non-retryable auth_error (TASK-035\n// CODE_REVIEW). Match only genuine authentication/authorization failure phrasing.\nfunction isAuthErrorMessage(message: string): boolean {\n return /unauthor|authentication|invalid[_\\s-]?(api[_\\s-]?key|credential|token)|forbidden|\\b40[13]\\b/i.test(\n message,\n );\n}\n\nfunction normalizeAcpError(error: unknown): AiConnectError {\n if (error instanceof AiConnectError) {\n return error;\n }\n\n // NB: check `instanceof Error` BEFORE `isRecord` \u2014 a real Error is also a\n // record, so the record branch would otherwise shadow raw-OS-error handling\n // (a spawn ENOENT has a STRING `.code`, not the numeric JSON-RPC code the\n // record branch special-cases) and misclassify it as `temporary_unavailable`\n // instead of `local_harness_unavailable` (TASK-035 W5G3 regression).\n if (error instanceof Error) {\n const message = error.message || \"ACP transport failed.\";\n const errno = (error as NodeJS.ErrnoException).code;\n if (\n errno === \"ENOENT\" ||\n errno === \"EACCES\" ||\n errno === \"ENOEXEC\" ||\n message.toLowerCase().includes(\"timed out\")\n ) {\n return new AiConnectError(\"local_harness_unavailable\", message);\n }\n\n if (isAuthErrorMessage(message)) {\n return new AiConnectError(\"auth_error\", message);\n }\n\n return new AiConnectError(\"temporary_unavailable\", message);\n }\n\n if (isRecord(error)) {\n const code = typeof error.code === \"number\" ? error.code : undefined;\n const message =\n typeof error.message === \"string\"\n ? error.message\n : \"ACP transport failed.\";\n\n if (code === -32601 || code === -32602) {\n return new AiConnectError(\"not_supported\", message);\n }\n\n if (isAuthErrorMessage(message)) {\n return new AiConnectError(\"auth_error\", message);\n }\n\n return new AiConnectError(\"temporary_unavailable\", message);\n }\n\n return new AiConnectError(\n \"temporary_unavailable\",\n \"ACP transport failed.\",\n );\n}\n\nexport function resolveAcpCommand(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): string {\n // SYS-5: shared precedence (options.commands wins \u2192 transport.command \u2192 preset).\n const key = `${route.provider}:${route.transport.id}`;\n const optionsOverride =\n options?.commands?.[key] ??\n options?.commands?.[route.transport.id] ??\n options?.commands?.[route.provider];\n\n try {\n return resolveManagedCommand(\n key,\n optionsOverride ? { [key]: optionsOverride } : undefined,\n route.transport.command,\n AI_CONNECT_DEFAULT_ACP_COMMANDS[key],\n );\n } catch {\n throw new AiConnectError(\n \"validation_error\",\n `No ACP command is configured for route \"${route.id}\".`,\n );\n }\n}\n\nexport function resolveAcpExecutable(\n route: NormalizedRoute,\n options: AcpClientOptions | undefined,\n): string {\n return splitCommandLine(resolveAcpCommand(route, options)).command;\n}\n\nfunction initializePayload(\n mode: AcpPermissionMode,\n): Record<string, unknown> {\n return {\n protocolVersion: 1,\n clientCapabilities: {\n fs: {\n readTextFile: true,\n writeTextFile: mode === \"approve-all\",\n },\n terminal: false,\n },\n clientInfo: {\n name: \"ai-connect\",\n version: \"0.1.0\",\n },\n };\n}\n\nfunction buildAcpAuthRequest(\n route: NormalizedRoute,\n _runtime: RuntimeEnvironment,\n): AcpAuthRequest | undefined {\n const auth = route.transport.auth;\n if (!auth?.methodId) {\n return undefined;\n }\n\n const params = {\n ...(auth.params ?? {}),\n methodId: auth.methodId,\n };\n\n return {\n methodId: auth.methodId,\n params,\n lifecycleKeys: [\n \"authenticate.methodId\",\n ...Object.keys(auth.params ?? {})\n .sort()\n .map((key) => `authenticate.${key}`),\n ],\n };\n}\n\nfunction advertisedAuthMethods(\n result: unknown,\n): Set<string> | undefined {\n if (!isRecord(result) || !Array.isArray(result.authMethods)) {\n return undefined;\n }\n\n return new Set(\n result.authMethods.flatMap((method) => {\n if (!isRecord(method) || typeof method.id !== \"string\") {\n return [];\n }\n return [method.id];\n }),\n );\n}\n\nfunction resolveSessionCacheOptions(\n options: AcpClientOptions | undefined,\n): Required<AcpSessionCacheOptions> & { enabled: boolean } {\n if (options?.sessionCache === false) {\n return {\n enabled: false,\n idleTtlMs: 0,\n };\n }\n\n if (options?.sessionCache === true || options?.sessionCache === undefined) {\n return {\n enabled: true,\n idleTtlMs: DEFAULT_SESSION_CACHE_IDLE_TTL_MS,\n };\n }\n\n return {\n enabled: options.sessionCache.enabled ?? true,\n idleTtlMs:\n options.sessionCache.idleTtlMs ??\n DEFAULT_SESSION_CACHE_IDLE_TTL_MS,\n };\n}\n\nfunction buildAcpLifecycle(\n route: NormalizedRoute,\n authRequest: AcpAuthRequest | undefined,\n mode: \"prompt\" | \"discover\",\n): {\n steps: string[];\n keys: string[];\n} {\n const steps = [\"initialize\"];\n const keys = [...(authRequest?.lifecycleKeys ?? [])];\n if (authRequest) {\n steps.push(\"authenticate\");\n }\n steps.push(\"session/new\");\n if (mode === \"prompt\") {\n // session/set_model may run between session/new and session/prompt when the\n // agent advertises a model catalog (TASK-033 / F-PLAN-6); listed so the\n // wide-event bodyKeys stay consistent with the measured phases.\n steps.push(\"session/set_model\");\n steps.push(\"session/prompt\");\n }\n\n return { steps, keys };\n}\n\nfunction createAcpTransportSummary(\n commandLine: string,\n parameterKeys: string[],\n lifecycleSteps: string[],\n lifecycleKeys: string[],\n method: string,\n stream: boolean,\n cache: {\n enabled: boolean;\n hit: boolean;\n },\n): WideEventTransportSummary {\n return {\n protocol: \"acp\",\n endpoint: commandLine,\n method,\n stream,\n bodyKeys: lifecycleSteps,\n parameterKeys: [\n ...new Set([\n ...lifecycleKeys,\n ...parameterKeys,\n ]),\n ].sort(),\n phases: [],\n cache,\n };\n}\n\nfunction recordPhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\nasync function measurePhase<T>(\n phases: WideEventTransportPhase[],\n name: string,\n task: () => Promise<T>,\n): Promise<T> {\n const startedAt = Date.now();\n try {\n return await task();\n } finally {\n recordPhase(phases, name, startedAt);\n }\n}\n\nasync function closeChild(\n child: ReturnType<typeof spawn>,\n): Promise<void> {\n if (child.exitCode !== null || child.killed) {\n return;\n }\n\n child.stdin?.end();\n const closed = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), 250);\n child.once(\"close\", () => {\n clearTimeout(timer);\n resolve(true);\n });\n });\n\n if (closed) {\n return;\n }\n\n killAcpProcess(child, \"SIGTERM\");\n await new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n killAcpProcess(child, \"SIGKILL\");\n resolve();\n }, 1_000);\n child.once(\"close\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\nasync function settleClosePromise(\n closePromise: Promise<void>,\n timeoutMs = 1_500,\n): Promise<void> {\n await Promise.race([\n closePromise.catch(() => {}),\n new Promise<void>((resolve) => {\n setTimeout(resolve, timeoutMs);\n }),\n ]);\n}\n\nfunction killAcpProcess(\n child: ReturnType<typeof spawn>,\n signal: NodeJS.Signals,\n): void {\n // ACP children are spawned `detached` (except win32), so delegate to the\n // shared process-group-aware kill (C2/C3). `killProcessTree` handles the\n // win32 (non-detached) and group-already-gone fallbacks internally.\n killProcessTree(child, signal, process.platform !== \"win32\");\n}\n\ntype AcpPromptState = {\n sessionId: string;\n text: string;\n usage: UsageInfo | undefined;\n attachments: PortableFileInput[];\n warnings: string[];\n /**\n * Streaming sink (C9). When `streamPrompt` drives the prompt, every `agent_message_chunk`\n * incremental text fires this BEFORE it is accumulated, so the ACP `stream` handler can emit a\n * `{type:'delta'}` per chunk. Undefined for the plain `runPrompt` (generate) path.\n */\n onDelta?: (text: string) => void;\n /**\n * Harness-noise filtering (TASK-033 / UR-003). When true, `agent_message_chunk`\n * text is line-buffered: complete lines matching a curated harness marker are\n * DROPPED (before `onDelta` and before accumulation, so streaming consumers do\n * not see them either); non-marker lines pass through. `lineBuffer` holds the\n * trailing partial line until a newline or the end-of-turn flush. Dropped\n * markers accumulate in `harnessMarkers` for observability + the harness-only\n * guard. When false, chunks pass through raw (legacy behavior).\n */\n suppressNoise: boolean;\n lineBuffer: string;\n harnessMarkers: string[];\n};\n\ntype AcpConnectionOptions = {\n commandLine: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeoutMs: number;\n permissionMode: AcpPermissionMode;\n /** Forward `route.model` via `session/set_model` after `session/new` (default true). */\n selectModel: boolean;\n /** Filter curated harness-marker lines from the answer text + deltas (default true). */\n suppressHarnessNoise: boolean;\n /** A harness-noise-only turn \u2192 `temporary_unavailable` rather than a success (default true). */\n failOnHarnessOnlyTurn: boolean;\n};\n\nclass AcpConnection {\n private readonly commandLine: string;\n private readonly cwd: string;\n private readonly env: NodeJS.ProcessEnv;\n private readonly timeoutMs: number;\n private readonly permissionMode: AcpPermissionMode;\n private readonly selectModel: boolean;\n private readonly suppressHarnessNoise: boolean;\n private readonly failOnHarnessOnlyTurn: boolean;\n private readonly command: string;\n private readonly args: string[];\n\n private child: ReturnType<typeof spawn> | undefined;\n private closePromise: Promise<void> | undefined;\n private nextId = 1;\n private buffer = \"\";\n private stderr = \"\";\n private pending = new Map<JsonRpcId, PendingRequest>();\n private messageQueue = Promise.resolve();\n private initializeResult: unknown;\n private authMethodId: string | undefined;\n private activePrompt: AcpPromptState | undefined;\n private opQueue = Promise.resolve();\n private idleTimer: ReturnType<typeof setTimeout> | undefined;\n private disposed = false;\n\n constructor(options: AcpConnectionOptions) {\n this.commandLine = options.commandLine;\n this.cwd = options.cwd;\n this.env = options.env;\n this.timeoutMs = options.timeoutMs;\n this.permissionMode = options.permissionMode;\n this.selectModel = options.selectModel;\n this.suppressHarnessNoise = options.suppressHarnessNoise;\n this.failOnHarnessOnlyTurn = options.failOnHarnessOnlyTurn;\n const resolved = splitCommandLine(options.commandLine);\n this.command = resolved.command;\n this.args = resolved.args;\n }\n\n async runPrompt(\n context: GenerateContext,\n transport: WideEventTransportSummary,\n onDelta?: (text: string) => void,\n /**\n * Returns true iff THIS prompt is the sole in-flight user of the (possibly\n * pooled+shared) connection. When the pool is saturated the same child is\n * shared across concurrent prompts (`inFlight > 1`); aborting one MUST NOT\n * SIGKILL the child out from under the others. Absent \u21D2 treated as sole owner\n * (the non-pooled fallback gives every call its own connection).\n */\n isSoleInFlight?: () => boolean,\n ): Promise<AcpPromptOutput> {\n return this.withLock(async () => {\n this.clearIdleTimer();\n const prompt = await toPromptBlocks(context);\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const stderrOffset = this.stderr.length;\n\n await this.ensureReady(context.route, authRequest, transport.phases ?? []);\n\n const session = await measurePhase(\n transport.phases ?? [],\n \"session/new\",\n async () =>\n this.request(\"session/new\", {\n cwd: this.cwd,\n mcpServers: [],\n }),\n );\n if (!isRecord(session) || typeof session.sessionId !== \"string\") {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"ACP session/new did not return a sessionId.\",\n );\n }\n\n const sessionId = session.sessionId;\n\n this.activePrompt = {\n sessionId,\n text: \"\",\n usage: undefined,\n attachments: [],\n warnings: [],\n suppressNoise: this.suppressHarnessNoise,\n lineBuffer: \"\",\n harnessMarkers: [],\n ...(onDelta ? { onDelta } : {}),\n };\n\n // TASK-033 / UR-002: select the route's model through the ACP protocol\n // (session/set_model), superseding the consumer's ANTHROPIC_MODEL env hack\n // and the env-driven \"model switched\" announcement. Best-effort: any\n // mismatch / failure is surfaced as a warning; the prompt still proceeds.\n await this.selectSessionModel(\n sessionId,\n context.route,\n session,\n transport.phases ?? [],\n this.activePrompt.warnings,\n );\n\n let stopReason: string | undefined;\n\n // On the merged abort signal (caller cancel OR op timeout, CD-4): ask the agent to\n // cancel cooperatively via the `session/cancel` notification, then process-group kill\n // (killAcpProcess) so the local harness cannot outlive the cancellation. The pending\n // session/prompt request rejects; the client maps it to the canonical reason.\n const abortSignal = context.abort.signal;\n let abortListener: (() => void) | undefined;\n const onAbort = (): void => {\n // ALWAYS ask the agent to cancel THIS session cooperatively.\n this.notify(\"session/cancel\", { sessionId });\n // Only SIGKILL the child when this prompt is the SOLE in-flight user of a\n // (possibly shared) pooled connection. With `inFlight > 1` the child is\n // shared with concurrent prompts, so a hard kill would tear those down too\n // (SEC/correctness). In that case the cooperative session/cancel is enough;\n // the connection is reclaimed when the last in-flight user releases it.\n const soleOwner = isSoleInFlight ? isSoleInFlight() : true;\n if (!soleOwner) {\n return;\n }\n const child = this.child;\n if (child) {\n killAcpProcess(child, \"SIGKILL\");\n }\n };\n if (abortSignal.aborted) {\n onAbort();\n } else {\n abortListener = onAbort;\n abortSignal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n try {\n const promptResult = await measurePhase(\n transport.phases ?? [],\n \"session/prompt\",\n async () =>\n this.request(\"session/prompt\", {\n sessionId,\n prompt,\n }),\n );\n if (\n isRecord(promptResult) &&\n typeof promptResult.stopReason === \"string\"\n ) {\n stopReason = promptResult.stopReason;\n }\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n usageFromPromptResult(promptResult),\n );\n } finally {\n if (abortListener) {\n abortSignal.removeEventListener(\"abort\", abortListener);\n }\n this.bumpIdleTimer();\n }\n\n // TASK-033 / UR-003: flush the trailing partial line through the same\n // harness-noise classifier so a final line without a newline is filtered\n // too (claude-agent-acp greetings often arrive as one newline-less chunk).\n this.flushHarnessLineBuffer();\n\n const stderrSlice = this.stderr.slice(stderrOffset).trim();\n const warnings = [...this.activePrompt.warnings];\n if (this.activePrompt.harnessMarkers.length > 0) {\n warnings.push(\n `ACP: filtered ${this.activePrompt.harnessMarkers.length} interactive-harness line(s) from the response.`,\n );\n }\n if (stderrSlice.length > 0) {\n warnings.push(stderrSlice);\n }\n\n // MEDIUM: this prompt's slice is consumed \u2014 cap the retained stderr to a\n // bounded tail so a long-lived warm connection cannot grow it without bound.\n if (this.stderr.length > MAX_ACP_STDERR_CHARS) {\n this.stderr = this.stderr.slice(-MAX_ACP_STDERR_CHARS);\n }\n\n const text = this.activePrompt.text.trim();\n\n // TASK-033 / UR-004: a turn that yielded ONLY harness-noise lines (no\n // substantive content) is surfaced as `temporary_unavailable` so the\n // consumer can retry / fall back, rather than returning the chatter as a\n // successful generation. Default-on; relies on the suppress path having\n // classified the lines.\n if (\n this.failOnHarnessOnlyTurn &&\n this.activePrompt.harnessMarkers.length > 0 &&\n text.length === 0\n ) {\n this.activePrompt = undefined;\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"ACP turn returned only interactive-harness output (no task output).\",\n );\n }\n\n const result: AcpPromptOutput = {\n text,\n attachments: [...this.activePrompt.attachments],\n warnings,\n ...(this.activePrompt.usage ? { usage: this.activePrompt.usage } : {}),\n data: {\n command: this.commandLine,\n sessionId,\n ...(stopReason ? { stopReason } : {}),\n },\n };\n this.activePrompt = undefined;\n return result;\n });\n }\n\n async discoverModels(\n context: DiscoverAcpModelsContext,\n transport: WideEventTransportSummary,\n ): Promise<AcpModelCatalog> {\n return this.withLock(async () => {\n this.clearIdleTimer();\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n\n try {\n await this.ensureReady(context.route, authRequest, transport.phases ?? []);\n const session = await measurePhase(\n transport.phases ?? [],\n \"session/new\",\n async () =>\n this.request(\"session/new\", {\n cwd: this.cwd,\n mcpServers: [],\n }),\n );\n const catalog = modelCatalogFromSession(session);\n if (!catalog) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `ACP route \"${context.route.id}\" did not return an ACP model catalog in session/new.`,\n );\n }\n // GAP-A (TASK-028 / UR-002): the acp path builds its catalog via\n // modelCatalogFromSession, bypassing buildModelCatalog, so surface the\n // configured contextWindow here too (covers cli-via-acp + direct acp).\n catalog.availableModels = fillConfiguredContextLength(\n context.route,\n catalog.availableModels,\n );\n return catalog;\n } finally {\n this.bumpIdleTimer();\n }\n });\n }\n\n isWarm(): boolean {\n return !this.disposed && Boolean(this.child) && this.initializeResult !== undefined;\n }\n\n scheduleIdleDispose(\n idleTtlMs: number,\n /**\n * Re-checked WHEN the idle timer fires (not when it was scheduled). Returns\n * true iff the connection is still idle and should actually be torn down; a\n * false return means the slot was re-acquired/queued in the meantime, so the\n * dispose is skipped (#10 \u2014 never tear down a re-acquired connection\n * mid-prompt). The pool removal is also done by this callback.\n */\n onIdleFire: () => boolean,\n ): void {\n this.clearIdleTimer();\n if (idleTtlMs <= 0 || this.disposed) {\n return;\n }\n\n this.idleTimer = setTimeout(() => {\n if (!onIdleFire()) {\n return;\n }\n void this.dispose();\n }, idleTtlMs);\n this.idleTimer.unref?.();\n }\n\n async dispose(): Promise<void> {\n this.disposed = true;\n this.clearIdleTimer();\n\n const child = this.child;\n const closePromise = this.closePromise;\n this.child = undefined;\n this.closePromise = undefined;\n this.initializeResult = undefined;\n this.authMethodId = undefined;\n this.activePrompt = undefined;\n\n if (!child) {\n return;\n }\n\n try {\n await closeChild(child);\n } catch {\n killAcpProcess(child, \"SIGKILL\");\n }\n\n if (closePromise) {\n await settleClosePromise(closePromise);\n }\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer);\n this.idleTimer = undefined;\n }\n }\n\n private bumpIdleTimer(): void {\n this.clearIdleTimer();\n }\n\n private async withLock<T>(task: () => Promise<T>): Promise<T> {\n const previous = this.opQueue.catch(() => {});\n let release!: () => void;\n this.opQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await previous;\n try {\n return await task();\n } finally {\n release();\n }\n }\n\n private async ensureReady(\n route: NormalizedRoute,\n authRequest: AcpAuthRequest | undefined,\n phases: WideEventTransportPhase[],\n ): Promise<void> {\n if (this.disposed) {\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" has already been disposed.`,\n );\n }\n\n await this.spawnChild(phases);\n\n if (this.initializeResult === undefined) {\n this.initializeResult = await measurePhase(\n phases,\n \"initialize\",\n async () =>\n this.request(\n \"initialize\",\n initializePayload(this.permissionMode),\n ),\n );\n }\n\n if (!authRequest) {\n return;\n }\n\n const methods = advertisedAuthMethods(this.initializeResult);\n if (methods && !methods.has(authRequest.methodId)) {\n throw new AiConnectError(\n \"not_supported\",\n `ACP agent \"${route.id}\" does not advertise auth method \"${authRequest.methodId}\".`,\n );\n }\n\n if (this.authMethodId === authRequest.methodId) {\n return;\n }\n\n await measurePhase(phases, \"authenticate\", async () =>\n this.request(\"authenticate\", authRequest.params),\n );\n this.authMethodId = authRequest.methodId;\n }\n\n private async spawnChild(\n phases: WideEventTransportPhase[],\n ): Promise<void> {\n if (this.child) {\n return;\n }\n\n await measurePhase(phases, \"spawn\", async () => {\n const child = spawn(this.command, this.args, {\n cwd: this.cwd,\n env: this.env,\n stdio: \"pipe\",\n detached: process.platform !== \"win32\",\n });\n\n this.child = child;\n this.buffer = \"\";\n this.stderr = \"\";\n this.pending.clear();\n this.messageQueue = Promise.resolve();\n\n // H4 (arguably CRITICAL): an async EPIPE / write-after-end on stdin emits an\n // 'error' event; without a listener Node treats it as an unhandled stream\n // error and CRASHES the entire host process. Attach a handler right after\n // spawn so a broken pipe becomes recoverable stderr context instead.\n child.stdin?.on(\"error\", (error) => {\n const message = error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP stdin error: ${message}\\n`;\n });\n\n // Orphaned-process safety net (F-TS-3): register the child so a host exit\n // without dispose() still tears it down. trackChild auto-untracks on\n // close/exit.\n trackChild(child, process.platform !== \"win32\");\n\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n this.buffer += chunk;\n const lines = this.buffer.split(/\\r?\\n/);\n this.buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n this.messageQueue = this.messageQueue\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP message handler error: ${message}\\n`;\n })\n .then(() => this.handleMessage(line))\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP message handler error: ${message}\\n`;\n });\n }\n });\n\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n this.stderr += chunk;\n });\n\n this.closePromise = new Promise<void>((resolve, reject) => {\n child.once(\"error\", (error) => {\n const normalized = normalizeAcpError(error);\n this.failPending(normalized);\n this.resetConnectionState();\n reject(normalized);\n });\n child.once(\"close\", (code) => {\n const hadPending = this.pending.size > 0;\n const normalized = new AiConnectError(\n \"local_harness_unavailable\",\n this.stderr.trim() ||\n `ACP command \"${this.commandLine}\" exited before completing the prompt (code ${code ?? \"null\"}).`,\n );\n if (hadPending) {\n this.failPending(normalized);\n }\n this.resetConnectionState();\n if (hadPending) {\n reject(normalized);\n return;\n }\n resolve();\n });\n });\n // The close rejection is authoritatively surfaced through the pending\n // session/prompt await (and via settleClosePromise on dispose). A process-group\n // kill on abort (C2b) can reject closePromise before any awaiter attaches, so\n // attach a no-op catch to keep that rejection from becoming \"unhandled\".\n this.closePromise.catch(() => {});\n });\n }\n\n private resetConnectionState(): void {\n this.child = undefined;\n this.closePromise = undefined;\n this.initializeResult = undefined;\n this.authMethodId = undefined;\n this.activePrompt = undefined;\n this.nextId = 1;\n this.clearIdleTimer();\n }\n\n private reply(message: JsonRpcResponse): void {\n const stdin = this.child?.stdin;\n if (!stdin) {\n return;\n }\n\n // H4: a synchronous throw on write (e.g. stdin already ended) must not\n // escape into the message-handler queue and crash the host. The peer will\n // time out the corresponding request if the reply is lost.\n try {\n stdin.write(`${JSON.stringify(message)}\\n`);\n } catch (error) {\n const messageText = error instanceof Error ? error.message : String(error);\n this.stderr += `[ai-connect] ACP stdin write error (reply): ${messageText}\\n`;\n }\n }\n\n private failPending(error: unknown): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timer);\n entry.reject(error);\n }\n this.pending.clear();\n }\n\n private async handleAgentRequest(\n message: JsonRpcRequest,\n ): Promise<void> {\n const params = isRecord(message.params) ? message.params : {};\n\n if (message.method === \"requestPermission\") {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: selectPermissionResponse(params, this.permissionMode),\n });\n return;\n }\n\n if (message.method === \"readTextFile\") {\n const filePath =\n typeof params.path === \"string\"\n ? path.resolve(params.path)\n : undefined;\n if (!filePath || !(await isWithinRoot(this.cwd, filePath))) {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32000,\n message: \"Path is outside the allowed ACP cwd.\",\n },\n });\n return;\n }\n\n const content = await fs.readFile(filePath, \"utf8\");\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: { content },\n });\n return;\n }\n\n if (message.method === \"writeTextFile\") {\n if (this.permissionMode !== \"approve-all\") {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32001,\n message: \"ACP write access is disabled.\",\n },\n });\n return;\n }\n\n const filePath =\n typeof params.path === \"string\"\n ? path.resolve(params.path)\n : undefined;\n const content =\n typeof params.content === \"string\"\n ? params.content\n : undefined;\n if (\n !filePath ||\n content === undefined ||\n !(await isWithinRoot(this.cwd, filePath))\n ) {\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32000,\n message: \"Invalid ACP write request.\",\n },\n });\n return;\n }\n\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf8\");\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n result: {},\n });\n return;\n }\n\n this.reply({\n jsonrpc: \"2.0\",\n id: message.id,\n error: {\n code: -32601,\n message: `Unsupported ACP client method \"${message.method}\".`,\n },\n });\n }\n\n /**\n * Select the route's model through the ACP protocol (TASK-033 / UR-002).\n * Best-effort matrix: skip when disabled / no model / no advertised catalog /\n * already current; warn (not silently default) when the requested model is not\n * in the agent's `availableModels`; otherwise `session/set_model` and surface\n * any error as a warning. Never throws \u2014 a failed protocol selection must not\n * fail the generation.\n */\n private async selectSessionModel(\n sessionId: string,\n route: NormalizedRoute,\n sessionResult: unknown,\n phases: WideEventTransportPhase[],\n warnings: string[],\n ): Promise<void> {\n if (!this.selectModel) {\n return;\n }\n const desiredModel = route.model?.trim();\n if (!desiredModel) {\n return;\n }\n\n const catalog = modelCatalogFromSession(sessionResult);\n if (!catalog) {\n // Agent advertises no model catalog (e.g. some codex/opencode builds) \u21D2\n // protocol model-selection is unsupported; skip silently to preserve\n // existing behavior and avoid per-prompt noise.\n return;\n }\n\n if (catalog.currentModelId === desiredModel) {\n // Already the active model \u21D2 no switch \u21D2 no \"model switched\" announcement.\n return;\n }\n\n const available = catalog.availableModels ?? [];\n if (\n available.length > 0 &&\n !available.some((entry) => entry.modelId === desiredModel)\n ) {\n // F-PLAN-2: surface the mismatch instead of silently running the agent\n // default after the ANTHROPIC_MODEL hack is removed.\n warnings.push(\n `ACP agent's available models [${available\n .map((entry) => entry.modelId)\n .join(\", \")}] do not include route model \"${desiredModel}\"; model not switched via protocol.`,\n );\n return;\n }\n\n try {\n await measurePhase(phases, \"session/set_model\", async () =>\n this.request(\"session/set_model\", {\n sessionId,\n modelId: desiredModel,\n }),\n );\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : isRecord(error) && typeof error.message === \"string\"\n ? error.message\n : String(error);\n warnings.push(\n `ACP session/set_model(\"${desiredModel}\") failed: ${message}`,\n );\n }\n }\n\n /**\n * Append `agent_message_chunk` text (TASK-033 / UR-003). With suppression off\n * (legacy) the chunk streams + accumulates raw. With suppression on, the chunk\n * is line-buffered: each COMPLETE line is classified and either dropped (a\n * harness marker \u2014 no delta, no accumulation) or emitted; the trailing partial\n * line waits in `lineBuffer` for the next chunk or the end-of-turn flush.\n */\n private appendAgentText(chunk: string): void {\n const state = this.activePrompt;\n if (!state) {\n return;\n }\n if (!state.suppressNoise) {\n state.onDelta?.(chunk);\n state.text += chunk;\n return;\n }\n\n state.lineBuffer += chunk;\n let newlineIndex = state.lineBuffer.indexOf(\"\\n\");\n while (newlineIndex !== -1) {\n const line = state.lineBuffer.slice(0, newlineIndex + 1);\n state.lineBuffer = state.lineBuffer.slice(newlineIndex + 1);\n this.emitAgentLine(line);\n newlineIndex = state.lineBuffer.indexOf(\"\\n\");\n }\n }\n\n /** Flush any trailing partial line through the harness-noise classifier. */\n private flushHarnessLineBuffer(): void {\n const state = this.activePrompt;\n if (!state || !state.suppressNoise) {\n return;\n }\n const remaining = state.lineBuffer;\n state.lineBuffer = \"\";\n if (remaining.length > 0) {\n this.emitAgentLine(remaining);\n }\n }\n\n /**\n * Emit one classified line: a curated harness marker is recorded + dropped\n * (no delta, no accumulation); any other line streams + accumulates. `line`\n * may carry a trailing newline \u2014 classification runs on the content.\n */\n private emitAgentLine(line: string): void {\n const state = this.activePrompt;\n if (!state) {\n return;\n }\n const content = line.endsWith(\"\\n\") ? line.slice(0, -1) : line;\n if (isHarnessNoiseLine(content)) {\n state.harnessMarkers.push(content.trim());\n return;\n }\n state.onDelta?.(line);\n state.text += line;\n }\n\n private handleNotification(message: JsonRpcNotification): void {\n if (message.method !== \"session/update\" || !this.activePrompt) {\n return;\n }\n\n const params = isRecord(message.params) ? message.params : {};\n if (\n typeof params.sessionId === \"string\" &&\n params.sessionId !== this.activePrompt.sessionId\n ) {\n return;\n }\n\n const update = isRecord(params.update) ? params.update : undefined;\n if (!update || typeof update.sessionUpdate !== \"string\") {\n return;\n }\n\n const chunk = extractTextChunk(update);\n if (update.sessionUpdate === \"agent_message_chunk\" && chunk) {\n // C9 / TASK-033: append through the harness-noise filter. With suppression\n // on (default) the text is line-buffered and complete marker lines are\n // dropped BEFORE the streaming sink fires, so streaming consumers do not\n // receive harness chatter either; otherwise the chunk passes through raw.\n this.appendAgentText(chunk);\n }\n\n if (update.sessionUpdate === \"agent_thought_chunk\" && chunk) {\n this.activePrompt.warnings.push(chunk);\n }\n\n const meta = isRecord(update._meta) ? update._meta : undefined;\n if (meta) {\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n usageFromMeta(meta),\n );\n }\n\n if (update.sessionUpdate === \"agent_message_chunk\") {\n const content = isRecord(update.content) ? update.content : undefined;\n if (content) {\n const attachment = attachmentFromContent(content);\n if (attachment) {\n this.activePrompt.attachments.push(attachment);\n }\n }\n }\n\n if (update.sessionUpdate === \"usage_update\") {\n const nextUsage = usageFromUpdate(update);\n if (nextUsage) {\n this.activePrompt.usage = mergeUsageInfo(\n this.activePrompt.usage,\n nextUsage,\n );\n }\n }\n }\n\n private async handleMessage(raw: string): Promise<void> {\n const trimmed = raw.trim();\n if (!trimmed) {\n return;\n }\n\n let message: JsonRpcMessage;\n try {\n message = JSON.parse(trimmed) as JsonRpcMessage;\n } catch {\n return;\n }\n\n if (\n isRecord(message) &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n Object.hasOwn(message, \"id\")\n ) {\n await this.handleAgentRequest(message as JsonRpcRequest);\n return;\n }\n\n if (\n isRecord(message) &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n !Object.hasOwn(message, \"id\")\n ) {\n this.handleNotification(message as JsonRpcNotification);\n return;\n }\n\n if (isRecord(message) && Object.hasOwn(message, \"id\")) {\n const response = message as JsonRpcResponse;\n const pendingRequest = this.pending.get(response.id);\n if (!pendingRequest) {\n return;\n }\n\n clearTimeout(pendingRequest.timer);\n this.pending.delete(response.id);\n\n if (response.error) {\n pendingRequest.reject(response.error);\n return;\n }\n\n pendingRequest.resolve(response.result);\n }\n }\n\n /**\n * Send a fire-and-forget JSON-RPC notification (no `id`, no response awaited). Used for\n * `session/cancel` on abort (CD-4): the agent is asked to cancel cooperatively before we\n * fall back to a process-group kill. Best-effort \u2014 a missing stdin is silently ignored.\n */\n private notify(method: string, params: Record<string, unknown>): void {\n const stdin = this.child?.stdin;\n if (!stdin) {\n return;\n }\n const payload: JsonRpcNotification = {\n jsonrpc: \"2.0\",\n method,\n params,\n };\n try {\n stdin.write(`${JSON.stringify(payload)}\\n`);\n } catch {\n // Best-effort: a broken pipe on cancel is non-fatal (we kill the process next).\n }\n }\n\n private request(\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const child = this.child;\n if (!child) {\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" is not running.`,\n );\n }\n\n const id = this.nextId;\n this.nextId += 1;\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(\n new Error(\n `ACP request \"${method}\" timed out after ${this.timeoutMs}ms.`,\n ),\n );\n }, this.timeoutMs);\n // Match the idle timer: do not keep the event loop alive on this per-request\n // deadline so a hung agent cannot block process exit.\n (timer as { unref?: () => void }).unref?.();\n\n this.pending.set(id, {\n resolve,\n reject,\n timer,\n });\n\n const payload: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id,\n method,\n params,\n };\n const stdin = child.stdin;\n if (!stdin) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(\n new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" does not expose stdin.`,\n ),\n );\n return;\n }\n\n // H4: a synchronous write failure (broken pipe / ended stream) must reject\n // THIS request deterministically rather than throw an uncaught error that\n // crashes the host.\n try {\n stdin.write(`${JSON.stringify(payload)}\\n`);\n } catch (error) {\n clearTimeout(timer);\n this.pending.delete(id);\n const messageText =\n error instanceof Error ? error.message : String(error);\n reject(\n new AiConnectError(\n \"local_harness_unavailable\",\n `ACP command \"${this.commandLine}\" stdin write failed: ${messageText}`,\n ),\n );\n }\n });\n }\n}\n\nfunction cacheKeyForConnection(\n route: NormalizedRoute,\n runtime: PreparedAcpLaunchRuntime,\n options: AcpConnectionOptions,\n): string {\n const envEntries = Object.entries(options.env)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\u0001\");\n\n return [\n route.id,\n runtime.commandLine,\n options.cwd,\n options.permissionMode,\n String(options.timeoutMs),\n runtime.launch.contextMode,\n runtime.launch.skillsMode,\n envEntries,\n ].join(\"\\u0002\");\n}\n\nexport function createAcpTransportManager(\n options?: AcpClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<AcpPromptOutput>;\n streamPrompt: (\n context: GenerateContext,\n ) => AsyncIterable<GenerateStreamEvent>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n dispose: () => Promise<void>;\n} {\n type ManagedAcpConnection = {\n connection: AcpConnection;\n inFlight: number;\n };\n\n const connectionPools = new Map<string, ManagedAcpConnection[]>();\n const preparedLaunches = new Map<string, PreparedAcpLaunchRuntime>();\n const cacheOptions = resolveSessionCacheOptions(options);\n const maxConcurrentConnections = Math.max(\n 1,\n Math.floor(options?.maxConcurrentConnections ?? 1),\n );\n\n function launchCacheKey(\n route: NormalizedRoute,\n commandLine: string,\n cwdOverride?: string,\n ): string {\n const launch = normalizeLaunchOptions(route, options);\n return [\n route.id,\n commandLine,\n path.resolve(cwdOverride ?? options?.cwd ?? process.cwd()),\n launch.contextMode,\n launch.skillsMode,\n JSON.stringify(options?.env ?? {}),\n ].join(\"\\u0002\");\n }\n\n async function getPreparedLaunchRuntime(\n route: NormalizedRoute,\n commandLine: string,\n cwdOverride?: string,\n ): Promise<PreparedAcpLaunchRuntime> {\n const key = launchCacheKey(route, commandLine, cwdOverride);\n const existing = preparedLaunches.get(key);\n if (existing) {\n return existing;\n }\n\n const prepared = await prepareAcpLaunchRuntime(\n route,\n options,\n commandLine,\n cwdOverride,\n );\n preparedLaunches.set(key, prepared);\n return prepared;\n }\n\n function buildConnectionOptions(\n runtime: PreparedAcpLaunchRuntime,\n ): AcpConnectionOptions {\n return {\n commandLine: runtime.commandLine,\n cwd: runtime.cwd,\n env: runtime.env,\n timeoutMs: promptTimeout(options),\n permissionMode: options?.permissionMode ?? \"deny-all\",\n selectModel: options?.selectModel ?? true,\n suppressHarnessNoise: options?.suppressHarnessNoise ?? true,\n failOnHarnessOnlyTurn: options?.failOnHarnessOnlyTurn ?? true,\n };\n }\n\n function getPool(key: string): ManagedAcpConnection[] {\n const existing = connectionPools.get(key);\n if (existing) {\n return existing;\n }\n\n const created: ManagedAcpConnection[] = [];\n connectionPools.set(key, created);\n return created;\n }\n\n function removeManagedConnection(\n key: string,\n entry: ManagedAcpConnection,\n ): void {\n const pool = connectionPools.get(key);\n if (!pool) {\n return;\n }\n\n const nextPool = pool.filter((item) => item !== entry);\n if (nextPool.length === 0) {\n connectionPools.delete(key);\n return;\n }\n\n connectionPools.set(key, nextPool);\n }\n\n function acquireManagedConnection(\n key: string,\n connectionOptions: AcpConnectionOptions,\n ): ManagedAcpConnection {\n const pool = getPool(key);\n const idleWarm = pool.find(\n (entry) => entry.inFlight === 0 && entry.connection.isWarm(),\n );\n if (idleWarm) {\n idleWarm.inFlight += 1;\n return idleWarm;\n }\n\n const idleCold = pool.find((entry) => entry.inFlight === 0);\n if (idleCold) {\n idleCold.inFlight += 1;\n return idleCold;\n }\n\n if (pool.length < maxConcurrentConnections) {\n const created: ManagedAcpConnection = {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n pool.push(created);\n return created;\n }\n\n const fallback =\n pool.reduce((selected, entry) =>\n entry.inFlight < selected.inFlight ? entry : selected,\n );\n fallback.inFlight += 1;\n return fallback;\n }\n\n async function runWithCommand(\n context: GenerateContext,\n commandLine: string,\n onDelta?: (text: string) => void,\n ): Promise<AcpPromptOutput> {\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const lifecycle = buildAcpLifecycle(\n context.route,\n authRequest,\n \"prompt\",\n );\n const preparedRuntime = await getPreparedLaunchRuntime(\n context.route,\n commandLine,\n context.request.workingDirectory,\n );\n const connectionOptions = buildConnectionOptions(preparedRuntime);\n const key = cacheKeyForConnection(\n context.route,\n preparedRuntime,\n connectionOptions,\n );\n\n const entry = cacheOptions.enabled\n ? acquireManagedConnection(key, connectionOptions)\n : {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n const connection = entry.connection;\n const cacheHit = connection.isWarm();\n\n const transport = createAcpTransportSummary(\n preparedRuntime.commandLine,\n [\n \"prompt\",\n `launch.contextMode:${preparedRuntime.launch.contextMode}`,\n `launch.skillsMode:${preparedRuntime.launch.skillsMode}`,\n ...Object.keys(context.request.parameters ?? {}),\n ],\n lifecycle.steps,\n lifecycle.keys,\n \"session/prompt\",\n true,\n {\n enabled: cacheOptions.enabled,\n hit: cacheHit,\n },\n );\n context.telemetry?.captureTransport(transport);\n\n try {\n // Sole-owner predicate (#4): a SIGKILL on abort is only safe when this prompt\n // is the last in-flight user of the shared pooled connection.\n return await connection.runPrompt(\n context,\n transport,\n onDelta,\n () => entry.inFlight <= 1,\n );\n } catch (error) {\n // #4: only tear down the connection when THIS prompt is the sole in-flight\n // user (inFlight not yet decremented here). With a SHARED pooled connection\n // (inFlight > 1) a failed/aborted prompt must NOT evict the entry or dispose\n // the child out from under the concurrent prompt(s) still using it.\n if (entry.inFlight <= 1) {\n if (cacheOptions.enabled) {\n removeManagedConnection(key, entry);\n }\n await connection.dispose();\n }\n throw normalizeAcpError(error);\n } finally {\n entry.inFlight = Math.max(0, entry.inFlight - 1);\n if (!cacheOptions.enabled) {\n await connection.dispose();\n } else {\n if (entry.inFlight === 0) {\n connection.scheduleIdleDispose(cacheOptions.idleTtlMs, () => {\n // Re-checked at fire time: a slot re-acquired (or a prompt queued)\n // since scheduling \u21D2 skip the dispose (#10).\n if (entry.inFlight !== 0) {\n return false;\n }\n\n removeManagedConnection(key, entry);\n return true;\n });\n }\n }\n }\n }\n\n async function discoverWithCommand(\n context: DiscoverAcpModelsContext,\n commandLine: string,\n ): Promise<AcpModelCatalog> {\n const authRequest = buildAcpAuthRequest(context.route, context.runtime);\n const lifecycle = buildAcpLifecycle(\n context.route,\n authRequest,\n \"discover\",\n );\n const preparedRuntime = await getPreparedLaunchRuntime(\n context.route,\n commandLine,\n );\n const connectionOptions = buildConnectionOptions(preparedRuntime);\n const key = cacheKeyForConnection(\n context.route,\n preparedRuntime,\n connectionOptions,\n );\n\n const entry = cacheOptions.enabled\n ? acquireManagedConnection(key, connectionOptions)\n : {\n connection: new AcpConnection(connectionOptions),\n inFlight: 1,\n };\n const connection = entry.connection;\n const cacheHit = connection.isWarm();\n\n const transport = createAcpTransportSummary(\n preparedRuntime.commandLine,\n [\n `launch.contextMode:${preparedRuntime.launch.contextMode}`,\n `launch.skillsMode:${preparedRuntime.launch.skillsMode}`,\n ...lifecycle.keys,\n ],\n lifecycle.steps,\n lifecycle.keys,\n \"session/new\",\n false,\n {\n enabled: cacheOptions.enabled,\n hit: cacheHit,\n },\n );\n context.telemetry?.captureTransport(transport);\n\n try {\n return await connection.discoverModels(context, transport);\n } catch (error) {\n if (cacheOptions.enabled) {\n removeManagedConnection(key, entry);\n }\n await connection.dispose();\n throw normalizeAcpError(error);\n } finally {\n entry.inFlight = Math.max(0, entry.inFlight - 1);\n if (!cacheOptions.enabled) {\n await connection.dispose();\n } else {\n if (entry.inFlight === 0) {\n connection.scheduleIdleDispose(cacheOptions.idleTtlMs, () => {\n // Re-checked at fire time: a slot re-acquired (or a prompt queued)\n // since scheduling \u21D2 skip the dispose (#10).\n if (entry.inFlight !== 0) {\n return false;\n }\n\n removeManagedConnection(key, entry);\n return true;\n });\n }\n }\n }\n }\n\n async function drivePrompt(\n context: GenerateContext,\n onDelta?: (text: string) => void,\n ): Promise<AcpPromptOutput> {\n const commandLine = resolveAcpCommand(context.route, options);\n return await runWithCommand(context, commandLine, onDelta);\n }\n\n return {\n async runPrompt(context): Promise<AcpPromptOutput> {\n return drivePrompt(context);\n },\n /**\n * Streaming ACP prompt (C9 / OQ-13). Drives `runPrompt` with an `onDelta` sink that pushes each\n * `agent_message_chunk` into a bounded async queue; this generator yields one `{type:'delta'}`\n * per chunk IN ORDER, then exactly one terminal `{type:'result'}` from the resolved prompt\n * output (INV-ABORT-3). Abort is handled upstream by the client + `runPrompt`'s `session/cancel`\n * + process-kill on `context.abort.signal`.\n */\n async *streamPrompt(\n context: GenerateContext,\n ): AsyncIterable<GenerateStreamEvent> {\n const deltas: string[] = [];\n let notify: (() => void) | undefined;\n const onDelta = (text: string): void => {\n deltas.push(text);\n // MEDIUM: bound the queue. If the consumer falls behind, coalesce the\n // oldest entries into one so total content/order is preserved while the\n // entry count stays capped.\n if (deltas.length > MAX_ACP_STREAM_QUEUE) {\n const overflow = deltas.splice(0, deltas.length - MAX_ACP_STREAM_QUEUE);\n deltas.unshift(overflow.join(\"\"));\n }\n notify?.();\n };\n let settled = false;\n let promptError: unknown;\n let output: AcpPromptOutput | undefined;\n const promptPromise = drivePrompt(context, onDelta).then(\n (result) => {\n output = result;\n settled = true;\n notify?.();\n },\n (error) => {\n promptError = error;\n settled = true;\n notify?.();\n },\n );\n\n while (true) {\n while (deltas.length > 0) {\n const text = deltas.shift()!;\n if (text.length > 0) {\n yield { type: \"delta\", text };\n }\n }\n if (settled) {\n break;\n }\n await new Promise<void>((resolve) => {\n notify = resolve;\n });\n notify = undefined;\n }\n await promptPromise;\n if (promptError !== undefined) {\n throw promptError;\n }\n\n const result: GenerateResult = {\n route: context.route,\n text: output?.text ?? \"\",\n attachments: (output?.attachments ?? []).map((item) =>\n preparePortableFile(item),\n ),\n warnings: output?.warnings ?? [],\n attempts: [],\n ...(output?.usage ? { usage: output.usage } : {}),\n ...(output?.data !== undefined ? { data: output.data } : {}),\n };\n yield { type: \"result\", result };\n },\n async discoverModels(context): Promise<AcpModelCatalog> {\n const commandLine = resolveAcpCommand(context.route, options);\n return await discoverWithCommand(context, commandLine);\n },\n async dispose(): Promise<void> {\n const values = [...connectionPools.values()].flat();\n connectionPools.clear();\n await Promise.all(\n values.map(async (entry) => entry.connection.dispose()),\n );\n const launchValues = [...preparedLaunches.values()];\n preparedLaunches.clear();\n await Promise.all(\n launchValues.map(async (runtime) => {\n await runtime.cleanup?.();\n }),\n );\n },\n };\n}\n\nexport async function runAcpPrompt(\n context: GenerateContext,\n options?: AcpClientOptions,\n): Promise<AcpPromptOutput> {\n const manager = createAcpTransportManager({\n ...options,\n sessionCache: false,\n });\n\n try {\n return await manager.runPrompt(context);\n } finally {\n await manager.dispose();\n }\n}\n\n/**\n * Internal usage-merge primitives surfaced for deterministic unit tests\n * (C5/INV-USAGE-1). NOT re-exported from `src/index*.ts`, so the public package\n * surface is unchanged.\n * @internal\n */\nexport const __acpUsageInternals = {\n mergeUsageInfo,\n usageFromPromptResult,\n usageFromUpdate,\n usageFromMeta,\n} as const;\n\n/**\n * Internal harness-noise primitives surfaced for deterministic unit tests\n * (TASK-033 / UR-003, F-PLAN-5). NOT re-exported from `src/index*.ts`.\n * @internal\n */\nexport const __acpHarnessInternals = {\n isHarnessNoiseLine,\n} as const;\n", "import type { ChildProcess, StdioOptions } from \"node:child_process\";\nimport { spawn } from \"node:child_process\";\n\nimport { AiConnectError } from \"./errors.js\";\n\n/**\n * Shared transport-runtime primitives (TASK-035 Wave 1).\n *\n * Consolidates the process-spawning concerns that were previously duplicated\n * (and subtly divergent) across the ACP, CLI, and server transport managers:\n * - child-environment scoping (SYS-2): a minimal-by-default env so the full\n * `process.env` (host credentials, CI tokens) does NOT leak into third-party\n * `npx`-loaded binaries;\n * - process-group kill (C2/C3): reliably tear down a detached child *and its\n * descendants*, not just the direct child;\n * - command-override precedence (SYS-5): a single precedence rule\n * (`options.commands` wins) shared by every transport;\n * - an orphaned-process safety net: a single best-effort process-exit hook\n * that kills every tracked child on host teardown.\n *\n * This is a node-runtime-only module (transports are node-only), so a direct\n * import of `node:child_process` is intentional and safe here.\n */\n\nexport type EnvMode = \"inherit\" | \"minimal\";\n\nexport interface ChildEnvOptions {\n /**\n * `'minimal'` (default) exposes only PATH + HOME + explicitly allowlisted keys\n * from `process.env`, plus `extra`. `'inherit'` forwards the full `process.env`\n * (plus `extra`) \u2014 opt-in only, for callers that knowingly trust the child.\n */\n envMode?: EnvMode;\n /** Additional `process.env` keys to forward in `'minimal'` mode. */\n allowlist?: string[];\n /** Explicit key/value pairs layered on top (always win). */\n extra?: Record<string, string>;\n}\n\n/**\n * Minimal env keys forwarded even without an explicit allowlist. These are\n * OPERATIONAL, non-secret variables a spawned child needs to run and reach the\n * network \u2014 NOT provider credentials (the whole point of minimal mode is to keep\n * host secrets like `OPENAI_API_KEY` out of third-party child processes).\n *\n * - PATH: resolve non-absolute executables.\n * - HOME / USERPROFILE: locate per-user config (HOME on POSIX, USERPROFILE on Windows).\n * - Proxy / TLS: HTTPS_PROXY/HTTP_PROXY/NO_PROXY (+ lowercase), NODE_EXTRA_CA_CERTS,\n * SSL_CERT_FILE/SSL_CERT_DIR \u2014 without these, a child in a corporate proxy/custom-CA\n * environment cannot make outbound HTTPS (TASK-035 CODE_REVIEW regression fix).\n * - Windows essentials: SystemRoot/windir/APPDATA/LOCALAPPDATA/TEMP/TMP/PATHEXT/ComSpec/\n * NUMBER_OF_PROCESSORS \u2014 many Windows binaries (incl. node/npx) fail to start without\n * SystemRoot; the rest are commonly required.\n *\n * A key absent from `process.env` simply isn't forwarded, so listing extras is\n * harmless on platforms where they don't apply.\n */\nconst MINIMAL_ENV_KEYS = [\n \"PATH\",\n \"HOME\",\n \"USERPROFILE\",\n \"HTTPS_PROXY\",\n \"HTTP_PROXY\",\n \"NO_PROXY\",\n \"https_proxy\",\n \"http_proxy\",\n \"no_proxy\",\n \"NODE_EXTRA_CA_CERTS\",\n \"SSL_CERT_FILE\",\n \"SSL_CERT_DIR\",\n \"SystemRoot\",\n \"windir\",\n \"APPDATA\",\n \"LOCALAPPDATA\",\n \"TEMP\",\n \"TMP\",\n \"PATHEXT\",\n \"ComSpec\",\n \"NUMBER_OF_PROCESSORS\",\n] as const;\n\n/**\n * Build the environment for a spawned child process (SYS-2).\n *\n * Default is `'minimal'`: the host's full `process.env` is NOT inherited, so\n * unrelated provider keys / CI tokens are not handed to third-party binaries.\n * Callers that genuinely need full inheritance pass `envMode: 'inherit'`.\n */\nexport function resolveChildEnv(\n opts: ChildEnvOptions = {},\n): Record<string, string> {\n const extra = opts.extra ?? {};\n\n if (opts.envMode === \"inherit\") {\n const inherited: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (typeof value === \"string\") {\n inherited[key] = value;\n }\n }\n return { ...inherited, ...extra };\n }\n\n const minimal: Record<string, string> = {};\n const keys = new Set<string>([...MINIMAL_ENV_KEYS, ...(opts.allowlist ?? [])]);\n for (const key of keys) {\n const value = process.env[key];\n if (typeof value === \"string\") {\n minimal[key] = value;\n }\n }\n return { ...minimal, ...extra };\n}\n\n/**\n * Kill a spawned child and its descendants (C2/C3).\n *\n * When the child was spawned `detached` on a POSIX platform it is a process\n * group leader, so `process.kill(-pid, signal)` reaches the whole group. On\n * win32 (no POSIX process groups) \u2014 or if the group kill throws (already gone)\n * \u2014 fall back to killing the direct child.\n */\nexport function killProcessTree(\n child: ChildProcess,\n signal: NodeJS.Signals,\n detached: boolean,\n): void {\n if (\n process.platform !== \"win32\" &&\n detached &&\n typeof child.pid === \"number\"\n ) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n // Group already gone / not a leader \u2014 fall back to the direct child.\n }\n }\n\n try {\n child.kill(signal);\n } catch {\n // Best-effort: the child may have already exited.\n }\n}\n\n/**\n * Resolve a managed transport command with a single, transport-agnostic\n * precedence (SYS-5): an explicit `options.commands[key]` override always wins,\n * then the route's `transport.command`, then the built-in preset command.\n */\nexport function resolveManagedCommand(\n key: string,\n optionsCommands: Record<string, string> | undefined,\n routeCommand: string | undefined,\n presetCommand: string | undefined,\n): string {\n const resolved =\n optionsCommands?.[key]?.trim() ||\n routeCommand?.trim() ||\n presetCommand?.trim();\n\n if (!resolved) {\n throw new AiConnectError(\n \"validation_error\",\n `No managed command is configured for \"${key}\".`,\n );\n }\n\n return resolved;\n}\n\nexport interface SpawnManagedOptions {\n cwd?: string;\n env?: Record<string, string>;\n stdio?: StdioOptions;\n detached?: boolean;\n}\n\n/**\n * Thin wrapper over `child_process.spawn` that applies the shared env-scoping\n * default and registers the child in the orphaned-process safety net. Callers\n * that already build their own env pass it via `opts.env`; otherwise a minimal\n * env is resolved.\n */\nexport function spawnManaged(\n cmd: string,\n args: string[],\n opts: SpawnManagedOptions = {},\n): ChildProcess {\n const detached =\n opts.detached ?? process.platform !== \"win32\";\n const child = spawn(cmd, args, {\n ...(opts.cwd ? { cwd: opts.cwd } : {}),\n env: opts.env ?? resolveChildEnv(),\n stdio: opts.stdio ?? \"pipe\",\n detached,\n });\n trackChild(child, detached);\n return child;\n}\n\n/**\n * Orphaned-process safety net (seed L70 MEDIUM). A single, best-effort\n * process-level hook kills every tracked child on host teardown so a crashed or\n * `dispose()`-less consumer cannot leak detached agent/server processes. Managers\n * still own graceful teardown via `dispose()`; this is the last resort.\n */\ntype TrackedChild = { child: ChildProcess; detached: boolean };\nconst trackedChildren = new Set<TrackedChild>();\nlet exitHookRegistered = false;\n\nfunction killAllTrackedChildren(): void {\n for (const tracked of trackedChildren) {\n killProcessTree(tracked.child, \"SIGKILL\", tracked.detached);\n }\n trackedChildren.clear();\n}\n\nfunction ensureExitHook(): void {\n if (exitHookRegistered) {\n return;\n }\n exitHookRegistered = true;\n\n // Synchronous only \u2014 'exit' cannot await.\n process.on(\"exit\", () => {\n killAllTrackedChildren();\n });\n\n // On SIGINT/SIGTERM kill tracked children, then restore the default\n // termination *only* if no other listener is handling the signal \u2014 never\n // hijack a host that manages its own graceful shutdown.\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n const handler = (): void => {\n killAllTrackedChildren();\n process.removeListener(signal, handler);\n if (process.listenerCount(signal) === 0) {\n process.kill(process.pid, signal);\n }\n };\n process.on(signal, handler);\n }\n}\n\n/**\n * Register a spawned child in the orphaned-process safety net. Returns an\n * `untrack()` function the caller MUST invoke once the child is reaped (on\n * `close`/`exit` and in `dispose()`), so the registry does not grow unbounded.\n */\nexport function trackChild(\n child: ChildProcess,\n detached: boolean,\n): () => void {\n ensureExitHook();\n const entry: TrackedChild = { child, detached };\n trackedChildren.add(entry);\n const untrack = (): void => {\n trackedChildren.delete(entry);\n };\n child.once(\"close\", untrack);\n child.once(\"exit\", untrack);\n return untrack;\n}\n", "import { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { AI_CONNECT_DEFAULT_ACP_COMMANDS } from \"./acp-presets.js\";\nimport {\n AI_CONNECT_DEFAULT_CLI_COMMANDS,\n getCliTransportPreset,\n} from \"./cli-presets.js\";\nimport {\n buildModelCatalog,\n currentModelIdForRoute,\n} from \"./default-handlers.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport {\n extensionForMime,\n materializePortableFile,\n portableFileCategory,\n portableFileToBytes,\n preparePortableFile,\n} from \"./files.js\";\nimport {\n killProcessTree,\n resolveChildEnv,\n resolveManagedCommand,\n} from \"./transport-runtime.js\";\nimport type {\n AcpLaunchOptions,\n AcpModelCatalog,\n AcpModelInfo,\n CliClientOptions,\n CliDiscoveryAcpOptions,\n CliDiscoveryCommandModelsSelector,\n CliDiscoveryCommandParser,\n CliFileInputOptions,\n CliJsonLineSelector,\n CliTransportOptions,\n CliTransportParser,\n CliTransportPresetId,\n CliDiscoveryVia,\n DiscoverAcpModelsContext,\n GenerateContext,\n NormalizedCliDiscoveryCommand,\n NormalizedRoute,\n PortableFileInput,\n RouteHandlerGenerateResult,\n UsageInfo,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype CliExecutionResult = {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n};\n\ntype CliInvocation = {\n command: string;\n args: string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n tempDir?: string;\n outputFile?: string;\n parameterKeys: string[];\n /** When true, the per-invocation tempDir (output + staged attachments) is retained (debug). */\n keepStaging?: boolean;\n};\n\nexport type CliResolvedDiscoverySource =\n | {\n via: \"none\";\n }\n | {\n via: \"static\";\n }\n | {\n via: \"command\";\n command: NormalizedCliDiscoveryCommand;\n fallback: \"static\" | \"none\";\n }\n | {\n via: \"acp\";\n providerId: string;\n transportId: string;\n auth?: {\n methodId: string;\n params: Record<string, unknown>;\n };\n launch?: AcpLaunchOptions;\n };\n\nconst CLI_PRESET_ACP_DISCOVERY_DEFAULTS: Partial<\n Record<\n CliTransportPresetId,\n {\n transportId: string;\n providerId: string;\n }\n >\n> = {\n claude: {\n transportId: \"claude-code-acp\",\n providerId: \"anthropic\",\n },\n codex: {\n transportId: \"codex-acp\",\n providerId: \"openai\",\n },\n};\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\"validation_error\", \"CLI command line is empty.\");\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction quoteArg(value: string): string {\n return /\\s/.test(value) ? JSON.stringify(value) : value;\n}\n\nfunction buildCliPrompt(\n context: GenerateContext,\n fileInputEnabled: boolean,\n): string {\n if (context.request.operation !== \"text\") {\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${context.route.transport.id}\" only supports text requests.`,\n );\n }\n\n // Image *operations* (generation) have no CLI channel regardless of fileInput.\n if (context.request.image) {\n throw new AiConnectError(\n \"unsupported_capability\",\n `CLI transport \"${context.route.transport.id}\" does not support image output.`,\n );\n }\n\n // Attachments: when the route has NO resolved fileInput, a CLI text preset has\n // no binary input channel \u2192 reject (defense-in-depth; the client capability\n // gate normally rejects image/document before reaching here). When fileInput\n // IS enabled (REQ-024) the attachments are staged in buildCliInvocation, so\n // they are allowed through here.\n if (!fileInputEnabled && context.request.attachments.length > 0) {\n const hasBinary = context.request.attachments.some(\n (file) =>\n portableFileCategory(file) === \"image\" ||\n portableFileCategory(file) === \"document\",\n );\n throw new AiConnectError(\n hasBinary ? \"unsupported_capability\" : \"not_supported\",\n hasBinary\n ? `CLI transport \"${context.route.transport.id}\" does not support image or document inputs.`\n : `CLI transport \"${context.route.transport.id}\" does not support attachments.`,\n );\n }\n\n return context.request.messages\n .map((message) => {\n if (message.role === \"user\") {\n return message.content;\n }\n\n const roleLabel = message.role.toUpperCase();\n return `${roleLabel}:\\n${message.content}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction resolveCliCommand(\n route: NormalizedRoute,\n options?: CliClientOptions,\n): string {\n // SYS-5: unified command-override precedence via the shared resolver \u2014 an\n // explicit `options.commands` override wins over `transport.command` (this\n // resolver was transport-command-first before), matching the ACP/server\n // transports. Precedence: options.commands > transport.command > preset.\n const key = `${route.provider}:${route.transport.id}`;\n const optionsOverride =\n options?.commands?.[key]?.trim() ||\n options?.commands?.[route.transport.id]?.trim() ||\n options?.commands?.[route.provider]?.trim() ||\n undefined;\n\n const presetId =\n route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n const presetCommand =\n (presetId ? getCliTransportPreset(presetId).command.trim() : \"\") ||\n AI_CONNECT_DEFAULT_CLI_COMMANDS[key] ||\n undefined;\n\n try {\n return resolveManagedCommand(\n key,\n optionsOverride ? { [key]: optionsOverride } : undefined,\n route.transport.command,\n presetCommand,\n );\n } catch {\n throw new AiConnectError(\n \"validation_error\",\n `No CLI command preset is registered for route \"${route.id}\". Provide transport.command or cli.commands.`,\n );\n }\n}\n\nexport function resolveCliExecutable(\n route: NormalizedRoute,\n options?: CliClientOptions,\n): string {\n return splitCommandLine(resolveCliCommand(route, options)).command;\n}\n\nfunction buildCliEnvironment(options?: CliClientOptions): NodeJS.ProcessEnv {\n // SYS-2: minimal-by-default child env via the shared resolver. The host's full\n // `process.env` (other providers' keys, CI tokens) is NOT forwarded to the\n // third-party CLI binary (commonly an npx-loaded agent); `options.env` is\n // layered on top as explicit extras. One-shot CLI invocations ignore stdin, so\n // a minimal env is safe (no interactive credential handshake to satisfy).\n return resolveChildEnv({ extra: options?.env ?? {} });\n}\n\nfunction buildCliCwd(\n context: GenerateContext,\n options?: CliClientOptions,\n): string {\n return path.resolve(\n context.request.workingDirectory ?? options?.cwd ?? process.cwd(),\n );\n}\n\nfunction defaultCliPresetIdForRoute(\n route: NormalizedRoute,\n): CliTransportPresetId | undefined {\n switch (route.transport.id) {\n case \"pi-cli\":\n return \"pi\";\n case \"claude-cli\":\n return \"claude\";\n case \"openclaude-cli\":\n return \"openclaude\";\n case \"codex-cli\":\n return \"codex\";\n default:\n return undefined;\n }\n}\n\nfunction defaultCliDiscoveryPresetForRoute(\n route: NormalizedRoute,\n): CliTransportPresetId | undefined {\n return route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n}\n\nfunction defaultCliDiscoveryTransportIdForRoute(\n route: NormalizedRoute,\n): string | undefined {\n const presetId = defaultCliDiscoveryPresetForRoute(route);\n return presetId\n ? CLI_PRESET_ACP_DISCOVERY_DEFAULTS[presetId]?.transportId\n : undefined;\n}\n\nfunction defaultCliDiscoveryProviderForRoute(\n route: NormalizedRoute,\n transportId: string,\n): string | undefined {\n if (AI_CONNECT_DEFAULT_ACP_COMMANDS[`${route.provider}:${transportId}`]) {\n return route.provider;\n }\n\n const presetId = defaultCliDiscoveryPresetForRoute(route);\n return presetId\n ? CLI_PRESET_ACP_DISCOVERY_DEFAULTS[presetId]?.providerId\n : undefined;\n}\n\nfunction normalizeCliDiscoveryAcpSource(\n route: NormalizedRoute,\n discovery: CliDiscoveryAcpOptions | undefined,\n): CliResolvedDiscoverySource {\n const transportId =\n discovery?.transportId?.trim() ??\n defaultCliDiscoveryTransportIdForRoute(route);\n if (!transportId) {\n return { via: \"none\" };\n }\n\n const providerId =\n discovery?.providerId?.trim() ??\n defaultCliDiscoveryProviderForRoute(route, transportId);\n if (!providerId) {\n return { via: \"none\" };\n }\n\n return {\n via: \"acp\",\n providerId,\n transportId,\n ...(discovery?.auth ? { auth: discovery.auth } : {}),\n ...(discovery?.launch ? { launch: discovery.launch } : {}),\n };\n}\n\nexport function resolveCliDiscoverySource(\n route: NormalizedRoute,\n): CliResolvedDiscoverySource {\n const discovery = route.transport.cli?.discovery;\n const hasModels = (route.advertisedModels?.length ?? 0) > 0;\n const hasAcpDefault = Boolean(defaultCliDiscoveryTransportIdForRoute(route));\n\n // Resolution chain (when `via` is unset): command > acp > static > none.\n // An explicit `via` short-circuits the chain.\n const via: CliDiscoveryVia =\n discovery?.via ??\n (discovery?.command\n ? \"command\"\n : hasAcpDefault\n ? \"acp\"\n : hasModels\n ? \"static\"\n : \"none\");\n\n switch (via) {\n case \"none\":\n return { via: \"none\" };\n case \"static\":\n return { via: \"static\" };\n case \"command\": {\n const command = discovery?.command;\n if (!command) {\n // Misconfiguration (explicit via:\"command\" without a command block).\n // config normalization rejects this; treat defensively as no discovery.\n return { via: \"none\" };\n }\n const fallback = discovery?.fallback ?? (hasModels ? \"static\" : \"none\");\n return { via: \"command\", command, fallback };\n }\n default:\n return normalizeCliDiscoveryAcpSource(route, discovery?.acp);\n }\n}\n\nexport function createCliDiscoveryAcpRoute(\n route: NormalizedRoute,\n): NormalizedRoute | undefined {\n const discovery = resolveCliDiscoverySource(route);\n if (discovery.via !== \"acp\") {\n return undefined;\n }\n\n return {\n ...route,\n id: `${route.id}::cli-discovery::${discovery.providerId}:${discovery.transportId}`,\n provider: discovery.providerId,\n handlerKey: `${discovery.providerId}:${discovery.transportId}`,\n transport: {\n kind: \"acp\",\n id: discovery.transportId,\n ...(discovery.auth ? { auth: discovery.auth } : {}),\n ...(discovery.launch ? { launch: discovery.launch } : {}),\n },\n };\n}\n\nfunction resolveCliTransportOptions(\n route: NormalizedRoute,\n): CliTransportOptions & { argsTemplate: string[] } {\n const presetId =\n route.transport.cli?.preset ?? defaultCliPresetIdForRoute(route);\n const preset = presetId ? getCliTransportPreset(presetId) : undefined;\n\n // Deep-merge fileInput per-field (preset default under route override) so a\n // route overriding one field (e.g. mentionTemplate) keeps the preset's other\n // defaults (e.g. perFileArgs) instead of wiping them via the shallow spread.\n const mergedFileInput: CliFileInputOptions | undefined =\n preset?.options.fileInput || route.transport.cli?.fileInput\n ? {\n ...(preset?.options.fileInput ?? {}),\n ...(route.transport.cli?.fileInput ?? {}),\n }\n : undefined;\n\n const merged: CliTransportOptions = {\n ...(preset?.options ?? {}),\n // `...route.transport.cli` already spreads argsTemplate + parser (when set on\n // the route) over the preset defaults, so the previously-present conditional\n // re-spreads of those two fields were dead/redundant (they re-assigned the\n // identical value) and have been dropped. fileInput/preset below are NOT\n // redundant: fileInput is a per-field DEEP merge (mergedFileInput) and preset\n // is derived (route.transport.cli.preset ?? default), not a plain passthrough.\n ...(route.transport.cli ?? {}),\n ...(mergedFileInput ? { fileInput: mergedFileInput } : {}),\n ...(presetId ? { preset: presetId } : {}),\n };\n\n if (!merged.argsTemplate?.length) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI route \"${route.id}\" does not define argsTemplate and has no matching built-in preset.`,\n );\n }\n\n return merged as CliTransportOptions & { argsTemplate: string[] };\n}\n\nasync function createCliTempDir(\n baseDir?: string,\n prefix?: string,\n): Promise<{\n tempDir: string;\n outputFile: string;\n}> {\n const tempDir = await fs.mkdtemp(\n path.join(baseDir ?? os.tmpdir(), prefix ?? \"ai-connect-cli-\"),\n );\n\n return {\n tempDir,\n outputFile: path.join(tempDir, \"last-message.txt\"),\n };\n}\n\n// Sanitize an attachment name to a safe basename inside the staging dir: strip\n// any directory / traversal / absolute prefix; fall back to attachment-${i}.<ext>\n// when the result is empty or all-dots (REQ-024, F-CR-4).\nfunction safeStagedBasename(name: string, index: number, mimeType: string): string {\n const base = path.basename(name.replace(/\\\\/g, \"/\"));\n if (base === \"\" || base === \".\" || base === \"..\") {\n return `attachment-${index}.${extensionForMime(mimeType)}`;\n }\n return base;\n}\n\n// Materialize attachments to disk under attachDir and return the ordered list of\n// staged references (absolute paths, or a remote uri when the source has no\n// bytes). Only categories in `categories` are staged; others are skipped.\nasync function stageCliAttachments(\n attachments: PortableFileInput[],\n attachDir: string,\n fileInput: CliFileInputOptions,\n): Promise<string[]> {\n const categories = new Set(\n fileInput.categories ?? [\"image\", \"document\", \"text\", \"other\"],\n );\n await fs.mkdir(attachDir, { recursive: true });\n\n const refs: string[] = [];\n const usedNames = new Map<string, number>();\n for (let i = 0; i < attachments.length; i += 1) {\n const file = preparePortableFile(attachments[i]!);\n const payload = await materializePortableFile(file);\n if (!categories.has(payload.category)) {\n continue;\n }\n\n // De-dup names within the batch (index-prefix on collision).\n let destName = safeStagedBasename(payload.name, i, payload.mimeType);\n const seen = usedNames.get(destName);\n if (seen !== undefined) {\n destName = `${i}-${destName}`;\n }\n usedNames.set(destName, i);\n const dest = path.join(attachDir, destName);\n\n if (payload.category === \"text\") {\n if (payload.text !== undefined) {\n await fs.writeFile(dest, payload.text, \"utf8\");\n refs.push(dest);\n continue;\n }\n } else {\n const bytes = payload.base64\n ? Buffer.from(payload.base64, \"base64\")\n : await portableFileToBytes(file);\n if (bytes !== undefined) {\n await fs.writeFile(dest, bytes);\n refs.push(dest);\n continue;\n }\n }\n\n // No local bytes/text: degrade to the remote uri reference (no disk write),\n // mirroring the acp resource_link path.\n if (payload.uri) {\n refs.push(payload.uri);\n }\n }\n return refs;\n}\n\n// Expand the {files} placeholder to argv tokens, one group per staged file via\n// the route's perFileArgs ({path}/{name}). Returns [] for prompt placement\n// (files go into the prompt text instead). The staged absolute paths are values,\n// not telemetry keys (F-P1-3 \u2014 the caller registers a single synthetic '{files}').\nfunction expandFileArgs(\n staged: string[],\n fileInput: CliFileInputOptions | undefined,\n): string[] {\n // H10 (flag injection): for presets whose files are BARE positionals (e.g. pi's\n // `@{path}`), the built-in argsTemplate places `--` before `{files}` so a staged\n // reference is never mis-parsed as a flag. For presets that pass files via an\n // explicit flag (e.g. codex `--image {path}`), `--` sits AFTER `{files}` instead\n // so the flag itself keeps working \u2014 the path is that flag's VALUE, not a\n // positional. Placement per preset lives in cli-presets.ts.\n const perFileArgs = fileInput?.perFileArgs ?? [\"@{path}\"];\n if (fileInput?.placement === \"prompt\") {\n return [];\n }\n return staged.flatMap((ref) =>\n perFileArgs.map((tpl) =>\n tpl.replace(\"{path}\", ref).replace(\"{name}\", path.basename(ref)),\n ),\n );\n}\n\nfunction materializeTemplateArg(\n templateArg: string,\n values: {\n prompt: string;\n model: string;\n outputFile?: string;\n },\n parameterKeys: string[],\n): string {\n switch (templateArg) {\n case \"{prompt}\":\n parameterKeys.push(\"prompt\");\n // H10 (flag injection): the built-in preset argsTemplates now place a\n // literal `--` end-of-options token before this trailing `{prompt}`\n // positional (see cli-presets.ts), so a prompt whose text starts with `-`\n // (e.g. \"--dangerously-skip-permissions\") is parsed by a compliant wrapped\n // CLI as a POSITIONAL, not a flag. We deliberately do NOT reject a leading\n // dash here: rejecting would break legitimate prompts (e.g. \"-> summarize\"),\n // and the `--` separator is the correct, non-lossy defense. Custom\n // argsTemplates that omit `--` accept the caller's own ordering by contract.\n return values.prompt;\n case \"{model}\":\n parameterKeys.push(\"model\");\n return values.model;\n case \"{output_file}\":\n parameterKeys.push(\"output_file\");\n if (!values.outputFile) {\n throw new AiConnectError(\n \"validation_error\",\n \"CLI argsTemplate references {output_file} but no output file was prepared.\",\n );\n }\n return values.outputFile;\n default:\n // Record only NAMED flags (`--foo`) as telemetry parameter keys. The bare\n // `--` end-of-options separator (H10) is a structural token, not a flag, so\n // it is passed through verbatim without polluting parameterKeys.\n if (templateArg.startsWith(\"--\") && templateArg.length > 2) {\n parameterKeys.push(templateArg);\n }\n return templateArg;\n }\n}\n\nasync function buildCliInvocation(\n context: GenerateContext,\n options?: CliClientOptions,\n): Promise<CliInvocation> {\n const route = context.route;\n // Resolve options BEFORE building the prompt so buildCliPrompt knows whether\n // the route can accept attachments (F-TS-1) \u2014 single resolution point.\n const cliOptions = resolveCliTransportOptions(route);\n const fileInput = cliOptions.fileInput;\n const attachments = context.request.attachments;\n const hasStageable = Boolean(fileInput) && attachments.length > 0;\n\n let prompt = buildCliPrompt(context, Boolean(fileInput));\n const commandLine = resolveCliCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const parameterKeys: string[] = [];\n let tempDir: string | undefined;\n let outputFile: string | undefined;\n\n const needsOutputFile = cliOptions.argsTemplate.includes(\"{output_file}\");\n if (needsOutputFile || hasStageable) {\n const created = await createCliTempDir(\n fileInput?.stagingDir ?? options?.staging?.dir,\n options?.staging?.prefix,\n );\n tempDir = created.tempDir;\n outputFile = created.outputFile;\n }\n\n // Stage attachments to disk (REQ-024) and resolve their references.\n let staged: string[] = [];\n if (hasStageable && tempDir && fileInput) {\n staged = await stageCliAttachments(\n attachments,\n path.join(tempDir, \"attachments\"),\n fileInput,\n );\n // prompt placement: append the staged references to the prompt text.\n if (fileInput.placement === \"prompt\" && staged.length > 0) {\n const separator = fileInput.separator ?? \" \";\n const mentionTemplate = fileInput.mentionTemplate ?? \"@{path}\";\n const mentions = staged\n .map((ref) =>\n mentionTemplate\n .replace(\"{path}\", ref)\n .replace(\"{name}\", path.basename(ref)),\n )\n .join(separator);\n prompt = `${prompt}${separator}${mentions}`;\n }\n }\n\n const args = [\n ...resolved.args,\n ...cliOptions.argsTemplate.flatMap((part) => {\n if (part === \"{files}\") {\n // Single synthetic telemetry key \u2014 never the expanded paths (F-P1-3).\n if (staged.length > 0) {\n parameterKeys.push(\"{files}\");\n }\n return expandFileArgs(staged, fileInput);\n }\n return [\n materializeTemplateArg(\n part,\n {\n prompt,\n model: route.model,\n ...(outputFile ? { outputFile } : {}),\n },\n parameterKeys,\n ),\n ];\n }),\n ];\n\n return {\n command: resolved.command,\n args,\n cwd: buildCliCwd(context, options),\n env: buildCliEnvironment(options),\n ...(tempDir ? { tempDir } : {}),\n ...(outputFile ? { outputFile } : {}),\n ...(options?.staging?.keep ? { keepStaging: true } : {}),\n parameterKeys,\n };\n}\n\n// Build a CliInvocation for a discovery \"list models\" command. Unlike\n// buildCliInvocation it has no GenerateContext (DiscoverAcpModelsContext carries\n// no request), so cwd falls back to options.cwd ?? process.cwd(), and there is no\n// {prompt}/{output_file} (the discovery argsTemplate is a plain list command;\n// {model} substitution is still honored for CLIs that need a model to list).\nfunction buildCliDiscoveryInvocation(\n route: NormalizedRoute,\n command: NormalizedCliDiscoveryCommand,\n options?: CliClientOptions,\n): CliInvocation {\n const commandLine = command.command?.trim()\n ? command.command\n : resolveCliCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const parameterKeys: string[] = [];\n // Discovery substitutes ONLY {model}; {prompt}/{output_file} are left literal\n // (a list command takes neither).\n const args = [\n ...resolved.args,\n ...command.argsTemplate.map((part) => {\n if (part === \"{model}\") {\n parameterKeys.push(\"model\");\n return route.model;\n }\n if (part.startsWith(\"--\")) {\n parameterKeys.push(part);\n }\n return part;\n }),\n ];\n\n return {\n command: resolved.command,\n args,\n cwd: path.resolve(options?.cwd ?? process.cwd()),\n env: buildCliEnvironment(options),\n parameterKeys,\n };\n}\n\n// Build a discovery catalog from the route's configured static model list\n// (advertisedModels + contextWindow). Reuses buildModelCatalog so the entry\n// shape (name id-fallback, requestedModelAdvertised, resolvedModelId) and the\n// GAP-A configured-contextWindow fill match every other provider's catalog.\nfunction buildStaticCliCatalog(\n route: NormalizedRoute,\n warning?: string,\n): AcpModelCatalog {\n const models: AcpModelInfo[] = route.advertisedModels.map((id) => ({\n modelId: id,\n name: id,\n }));\n const catalog = buildModelCatalog(\n route,\n models,\n currentModelIdForRoute(route, route.advertisedModels),\n );\n // FT-001: a static catalog produced as a FALLBACK from a failed/empty command\n // discovery carries a warning so it is distinguishable from a healthy static\n // catalog; a pure via:static route passes no warning.\n if (warning) {\n catalog.warnings = [...(catalog.warnings ?? []), warning];\n }\n return catalog;\n}\n\nfunction statsToUsage(stats: unknown): UsageInfo | undefined {\n if (!stats || typeof stats !== \"object\") {\n return undefined;\n }\n\n const record = stats as Record<string, unknown>;\n const inputTokens =\n typeof record.inputTokens === \"number\"\n ? record.inputTokens\n : typeof record.promptTokens === \"number\"\n ? record.promptTokens\n : typeof record.prompt_tokens === \"number\"\n ? record.prompt_tokens\n : undefined;\n const outputTokens =\n typeof record.outputTokens === \"number\"\n ? record.outputTokens\n : typeof record.completionTokens === \"number\"\n ? record.completionTokens\n : typeof record.output_tokens === \"number\"\n ? record.output_tokens\n : undefined;\n const totalTokens =\n typeof record.totalTokens === \"number\"\n ? record.totalTokens\n : inputTokens !== undefined || outputTokens !== undefined\n ? (inputTokens ?? 0) + (outputTokens ?? 0)\n : undefined;\n\n if (\n inputTokens === undefined &&\n outputTokens === undefined &&\n totalTokens === undefined\n ) {\n return undefined;\n }\n\n return {\n calls: 1,\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n };\n}\n\nfunction getValueByPath(\n value: unknown,\n dotPath: string,\n): unknown {\n const segments = dotPath.split(\".\").filter(Boolean);\n let current: unknown = value;\n\n for (const segment of segments) {\n if (Array.isArray(current)) {\n const index = Number(segment);\n if (!Number.isInteger(index)) {\n return undefined;\n }\n current = current[index];\n continue;\n }\n\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\n// Wrap JSON.parse of CLI stdout so a malformed payload surfaces as a canonical\n// AiConnectError('temporary_unavailable') carrying route/preset context, instead\n// of a raw SyntaxError leaking through the retry/fallback contract (which keys on\n// AiConnectError.code). `context` describes the route/preset for the log trail.\nfunction parseCliJson(raw: string, context: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new AiConnectError(\n \"temporary_unavailable\",\n `${context} produced output that is not valid JSON (${detail}).`,\n );\n }\n}\n\n// Split newline-delimited JSON (one object per non-empty line) into parsed\n// records. Shared by parseGenericJsonlCli, parseCodexCli, and parseCliModelList.\nfunction splitJsonlLines(\n stdout: string,\n context = \"CLI jsonl parser\",\n): unknown[] {\n return stdout\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => parseCliJson(line, context));\n}\n\nfunction normalizeErrorMessage(\n value: unknown,\n): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n\n if (\n value &&\n typeof value === \"object\" &&\n \"message\" in value &&\n typeof (value as Record<string, unknown>).message === \"string\"\n ) {\n return ((value as Record<string, unknown>).message as string).trim();\n }\n\n return undefined;\n}\n\nfunction findJsonlSelection(\n entries: unknown[],\n selector: CliJsonLineSelector,\n): unknown {\n for (const entry of entries) {\n if (selector.wherePath) {\n const whereValue = getValueByPath(entry, selector.wherePath);\n if (whereValue !== selector.whereEquals) {\n continue;\n }\n }\n\n const value = getValueByPath(entry, selector.path);\n if (value !== undefined) {\n return value;\n }\n }\n\n return undefined;\n}\n\nfunction parseGenericJsonCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"json\" }>,\n context: string,\n): RouteHandlerGenerateResult {\n const payload = parseCliJson(stdout, context);\n const errorValue = parser.errorPath\n ? getValueByPath(payload, parser.errorPath)\n : undefined;\n const errorMessage = normalizeErrorMessage(errorValue);\n if (errorMessage) {\n throw new AiConnectError(\"temporary_unavailable\", errorMessage);\n }\n\n const text = getValueByPath(payload, parser.textPath);\n if (typeof text !== \"string\" || !text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI json parser did not find text at path \"${parser.textPath}\".`,\n );\n }\n\n const usageValue = parser.usagePath\n ? getValueByPath(payload, parser.usagePath)\n : undefined;\n const usage = statsToUsage(usageValue);\n\n return {\n text: text.trim(),\n ...(usage ? { usage } : {}),\n data: payload,\n };\n}\n\nfunction parseGenericJsonlCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"jsonl\" }>,\n context: string,\n): RouteHandlerGenerateResult {\n const entries = splitJsonlLines(stdout, context);\n const errorValue = parser.error\n ? findJsonlSelection(entries, parser.error)\n : undefined;\n const errorMessage = normalizeErrorMessage(errorValue);\n if (errorMessage) {\n throw new AiConnectError(\"temporary_unavailable\", errorMessage);\n }\n\n const text = findJsonlSelection(entries, parser.text);\n if (typeof text !== \"string\" || !text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI jsonl parser did not resolve text using selector \"${parser.text.path}\".`,\n );\n }\n\n const usageValue = parser.usage\n ? findJsonlSelection(entries, parser.usage)\n : undefined;\n const usage = statsToUsage(usageValue);\n\n return {\n text: text.trim(),\n ...(usage ? { usage } : {}),\n data: entries,\n };\n}\n\n// Matches ANSI/VT100 escape sequences (CSI color/cursor codes, spinner noise)\n// emitted by interactive print-mode CLIs. Used only by the raw `text` parser.\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escapes are control chars by definition.\nconst ANSI_ESCAPE_PATTERN = /\u001B\\[[0-?]*[ -/]*[@-~]/g;\n\nfunction parseTextCli(\n stdout: string,\n parser: Extract<CliTransportParser, { kind: \"text\" }>,\n): RouteHandlerGenerateResult {\n let text = stdout;\n if (parser.stripAnsi) {\n text = text.replace(ANSI_ESCAPE_PATTERN, \"\");\n }\n if (parser.trim !== false) {\n text = text.trim();\n }\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"CLI text parser produced no output.\",\n );\n }\n\n // Print-mode plain text carries no usage/token information; none is fabricated.\n return { text, data: stdout };\n}\n\nfunction modelInfoFromRecord(\n record: unknown,\n selector: CliDiscoveryCommandModelsSelector,\n): AcpModelInfo | undefined {\n const rawId = getValueByPath(record, selector.idPath);\n const modelId = typeof rawId === \"string\" ? rawId.trim() : \"\";\n if (!modelId) {\n return undefined;\n }\n // name id-fallback mirrors parseOpenAiModelCatalog / normalizeAcpModel so cli\n // entries match every other provider's catalog shape (AcpModelInfo.name is required).\n const rawName = selector.namePath\n ? getValueByPath(record, selector.namePath)\n : undefined;\n const name =\n typeof rawName === \"string\" && rawName.trim().length > 0 ? rawName : modelId;\n const rawDescription = selector.descriptionPath\n ? getValueByPath(record, selector.descriptionPath)\n : undefined;\n const description =\n typeof rawDescription === \"string\" && rawDescription.trim().length > 0\n ? rawDescription\n : undefined;\n const rawContext = selector.contextLengthPath\n ? getValueByPath(record, selector.contextLengthPath)\n : undefined;\n const contextLength =\n typeof rawContext === \"number\" && Number.isFinite(rawContext) && rawContext > 0\n ? Math.floor(rawContext)\n : undefined;\n\n return {\n modelId,\n name,\n ...(description ? { description } : {}),\n // FT-002: a contextLength read from the list-command output is a discovered\n // value (consistent with the API parsers), so tag its provenance.\n ...(contextLength !== undefined\n ? { contextLength, contextWindowSource: \"discovered\" as const }\n : {}),\n };\n}\n\n/**\n * Parse the stdout of a CLI \"list models\" command into AcpModelInfo[].\n * Reuses the json|jsonl|text parser enum (no generation-parser overlap):\n * - text: one trimmed non-empty line per model id (name = id).\n * - jsonl: one model record per line, mapped via the selector.\n * - json: a model array at selector.path (or the payload root), mapped via the selector.\n */\nfunction parseCliModelList(\n stdout: string,\n parser: CliDiscoveryCommandParser,\n selector?: CliDiscoveryCommandModelsSelector,\n): AcpModelInfo[] {\n if (parser.kind === \"text\") {\n let text = stdout;\n if (parser.stripAnsi) {\n text = text.replace(ANSI_ESCAPE_PATTERN, \"\");\n }\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => ({ modelId: line, name: line }));\n }\n\n if (!selector) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI ${parser.kind} discovery parser requires a models selector with idPath.`,\n );\n }\n\n const records: unknown[] =\n parser.kind === \"jsonl\"\n ? splitJsonlLines(stdout)\n : (() => {\n const payload = parseCliJson(stdout, \"CLI discovery json parser\");\n const arr = selector.path\n ? getValueByPath(payload, selector.path)\n : payload;\n return Array.isArray(arr) ? arr : [];\n })();\n\n const models: AcpModelInfo[] = [];\n for (const record of records) {\n const info = modelInfoFromRecord(record, selector);\n if (info) {\n models.push(info);\n }\n }\n return models;\n}\n\nfunction parseClaudeCli(\n stdout: string,\n context: string,\n): RouteHandlerGenerateResult {\n const payload = parseCliJson(stdout, context) as Record<string, unknown>;\n const text =\n typeof payload.result === \"string\"\n ? payload.result\n : typeof payload.response === \"string\"\n ? payload.response\n : typeof payload.text === \"string\"\n ? payload.text\n : undefined;\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Claude/OpenClaude CLI JSON output did not contain result text.\",\n );\n }\n const usage = payload.usage ? statsToUsage(payload.usage) : undefined;\n\n return {\n text,\n ...(usage ? { usage } : {}),\n data: payload,\n };\n}\n\nfunction parseCodexCli(\n stdout: string,\n outputFileContent: string | undefined,\n context: string,\n): RouteHandlerGenerateResult {\n const events = splitJsonlLines(stdout, context) as Record<string, unknown>[];\n let text = outputFileContent?.trim() || undefined;\n let usage: UsageInfo | undefined;\n\n for (const event of events) {\n if (event.type === \"turn.completed\" && event.usage) {\n const rawUsage = event.usage as Record<string, unknown>;\n // ACCUMULATE across turns (#7): a multi-turn Codex run emits one\n // `turn.completed` per turn. ASSIGNING here would discard every turn but\n // the last and pin `calls` to 1; instead sum the token fields and count one\n // call per usage-bearing turn.\n const base = usage ?? { calls: 0 };\n const turnInput =\n typeof rawUsage.input_tokens === \"number\"\n ? rawUsage.input_tokens\n : undefined;\n const turnCached =\n typeof rawUsage.cached_input_tokens === \"number\"\n ? rawUsage.cached_input_tokens\n : undefined;\n const turnOutput =\n typeof rawUsage.output_tokens === \"number\"\n ? rawUsage.output_tokens\n : undefined;\n const inputTokens =\n turnInput !== undefined\n ? (base.inputTokens ?? 0) + turnInput\n : base.inputTokens;\n const cachedReadTokens =\n turnCached !== undefined\n ? (base.cachedReadTokens ?? 0) + turnCached\n : base.cachedReadTokens;\n const outputTokens =\n turnOutput !== undefined\n ? (base.outputTokens ?? 0) + turnOutput\n : base.outputTokens;\n usage = {\n calls: (base.calls ?? 0) + 1,\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(cachedReadTokens !== undefined ? { cachedReadTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n };\n if (\n usage.inputTokens !== undefined ||\n usage.outputTokens !== undefined\n ) {\n usage.totalTokens =\n (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);\n }\n }\n\n const item =\n event.item && typeof event.item === \"object\"\n ? (event.item as Record<string, unknown>)\n : undefined;\n const details =\n item?.details && typeof item.details === \"object\"\n ? (item.details as Record<string, unknown>)\n : undefined;\n if (\n !text &&\n details?.type === \"agent_message\" &&\n typeof details.text === \"string\"\n ) {\n text = details.text;\n }\n }\n\n if (!text) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Codex CLI JSON output did not contain final text output.\",\n );\n }\n\n return {\n text,\n ...(usage ? { usage } : {}),\n data: events,\n };\n}\n\nfunction parseCliResult(\n route: NormalizedRoute,\n result: CliExecutionResult,\n outputFileContent: string | undefined,\n): RouteHandlerGenerateResult {\n const stdout = result.stdout.trim();\n if (!stdout && !outputFileContent?.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n result.stderr.trim() ||\n `CLI transport \"${route.transport.id}\" produced no output.`,\n );\n }\n const cliOptions = resolveCliTransportOptions(route);\n const parseContext = `CLI transport \"${route.transport.id}\"${\n cliOptions.preset ? ` (preset ${cliOptions.preset})` : \"\"\n }`;\n // Dispatch contract (sentinel-is-documentation-only): a route that declares its\n // OWN parser (`route.transport.cli.parser`) is parsed generically by that\n // parser's declared paths below. When NO route-level parser is set, dispatch\n // falls through to the built-in preset switch, which calls a DEDICATED parser\n // (parseClaudeCli / parseCodexCli / raw text). The built-in presets in\n // cli-presets.ts carry a `parser` block whose `textPath`/`error` values are the\n // `__preset__:*` SENTINELS \u2014 those are documentation-only markers describing\n // which dedicated parser a preset maps to; they are NEVER resolved as live JSON\n // paths (this branch is skipped for preset routes because they set no\n // route-level parser). See cli-presets.ts for the mirrored note.\n if (route.transport.cli?.parser) {\n const parser = cliOptions.parser;\n if (!parser) {\n throw new AiConnectError(\n \"validation_error\",\n `CLI route \"${route.id}\" declared a parser override but normalization did not preserve it.`,\n );\n }\n\n switch (parser.kind) {\n case \"text\":\n // Pass the RAW stdout (not the upstream-trimmed copy) so the parser's\n // own `trim` option fully controls leading/trailing whitespace.\n return parseTextCli(result.stdout, parser);\n case \"json\":\n return parseGenericJsonCli(stdout, parser, parseContext);\n default:\n return parseGenericJsonlCli(stdout, parser, parseContext);\n }\n }\n\n switch (cliOptions.preset) {\n case \"pi\":\n // pi print mode emits the answer as plain text on stdout.\n return parseTextCli(stdout, { kind: \"text\" });\n case \"claude\":\n case \"openclaude\":\n return parseClaudeCli(stdout, parseContext);\n case \"codex\":\n return parseCodexCli(stdout, outputFileContent, parseContext);\n default:\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${route.transport.id}\" does not define a parser and has no matching built-in preset.`,\n );\n }\n}\n\nfunction capturePhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\n// Upper bound on combined stdout+stderr retained from a one-shot CLI child\n// (~64M UTF-16 chars \u2248 128 MB). Generous enough for large LLM generations, but\n// bounded so a runaway/looping child cannot grow the buffers without limit and\n// OOM the host. On overflow the child is killed and the call fails loud.\nconst MAX_CLI_OUTPUT_CHARS = 64 * 1024 * 1024;\n\nasync function executeCliInvocation(\n invocation: CliInvocation,\n timeoutMs: number,\n phases: WideEventTransportPhase[],\n signal?: AbortSignal,\n): Promise<CliExecutionResult> {\n const spawnStartedAt = Date.now();\n // C3 (process-group kill): spawn detached on POSIX so the child is a process\n // group leader and `killProcessTree` can tear down the WHOLE group (child + any\n // grandchildren it forks) on abort/timeout \u2014 a plain `child.kill` would orphan\n // grandchildren. stdio stays [\"ignore\",\"pipe\",\"pipe\"]: stdin is ignored (a\n // one-shot invocation has no input channel), unaffected by detachment; the\n // stdout/stderr pipes work identically. The child is intentionally NOT\n // `unref()`-ed so the parent still awaits its exit.\n const detached = process.platform !== \"win32\";\n const child = spawn(invocation.command, invocation.args, {\n cwd: invocation.cwd,\n env: invocation.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached,\n });\n capturePhase(phases, \"spawn\", spawnStartedAt);\n\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.setEncoding(\"utf8\");\n child.stderr.setEncoding(\"utf8\");\n\n const executeStartedAt = Date.now();\n return await new Promise((resolve, reject) => {\n let abortListener: (() => void) | undefined;\n let overflowed = false;\n\n const timer = setTimeout(() => {\n killProcessTree(child, \"SIGKILL\", detached);\n reject(\n new AiConnectError(\n \"temporary_unavailable\",\n `CLI transport \"${quoteArg(invocation.command)}\" timed out after ${timeoutMs}ms.`,\n ),\n );\n }, timeoutMs);\n\n const cleanup = (): void => {\n clearTimeout(timer);\n if (signal && abortListener) {\n signal.removeEventListener(\"abort\", abortListener);\n abortListener = undefined;\n }\n };\n\n // Buffer-cap guard (LOW): stop accumulating and fail loud once the combined\n // stdout+stderr exceeds MAX_CLI_OUTPUT_CHARS, killing the child group so a\n // runaway process cannot exhaust host memory. `overflowed` makes the reject\n // idempotent across further data events / the trailing close.\n const enforceBufferCap = (): void => {\n if (overflowed || stdout.length + stderr.length <= MAX_CLI_OUTPUT_CHARS) {\n return;\n }\n overflowed = true;\n killProcessTree(child, \"SIGKILL\", detached);\n cleanup();\n reject(\n new AiConnectError(\n \"temporary_unavailable\",\n `CLI transport \"${quoteArg(invocation.command)}\" exceeded the ${MAX_CLI_OUTPUT_CHARS}-character output cap.`,\n ),\n );\n };\n\n child.stdout.on(\"data\", (chunk: string) => {\n if (overflowed) {\n return;\n }\n stdout += chunk;\n enforceBufferCap();\n });\n child.stderr.on(\"data\", (chunk: string) => {\n if (overflowed) {\n return;\n }\n stderr += chunk;\n enforceBufferCap();\n });\n\n // On the merged abort signal (caller cancel OR op timeout, CD-4) SIGKILL the child\n // (and its group, C3) so a cancellation propagates to the spawned process and any\n // grandchildren. The reject reason is normalized to the canonical abort/timeout code\n // by the client via abort.reason.\n if (signal) {\n if (signal.aborted) {\n killProcessTree(child, \"SIGKILL\", detached);\n cleanup();\n reject(new AiConnectError(\"aborted\", \"CLI transport aborted before execution.\"));\n return;\n }\n abortListener = () => {\n killProcessTree(child, \"SIGKILL\", detached);\n cleanup();\n reject(new AiConnectError(\"aborted\", \"CLI transport aborted.\"));\n };\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n child.once(\"error\", (error) => {\n cleanup();\n reject(\n new AiConnectError(\n \"local_harness_unavailable\",\n error instanceof Error ? error.message : String(error),\n ),\n );\n });\n\n child.once(\"close\", (exitCode) => {\n if (overflowed) {\n // Already settled by the buffer-cap guard; the trailing close is a no-op.\n return;\n }\n cleanup();\n capturePhase(phases, \"execute\", executeStartedAt);\n resolve({\n stdout,\n stderr,\n exitCode,\n });\n });\n });\n}\n\nasync function cleanupCliInvocation(invocation: CliInvocation): Promise<void> {\n // keepStaging retains the ENTIRE per-invocation temp dir (output + staged\n // attachments) for debugging (REQ-024, F-CR-3).\n if (invocation.tempDir && !invocation.keepStaging) {\n await fs.rm(invocation.tempDir, { recursive: true, force: true });\n }\n}\n\nexport function createCliTransportManager(\n options?: CliClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<RouteHandlerGenerateResult>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n} {\n return {\n async discoverModels(context): Promise<AcpModelCatalog> {\n const source = resolveCliDiscoverySource(context.route);\n\n if (source.via === \"none\") {\n throw new AiConnectError(\n \"not_supported\",\n `CLI transport \"${context.route.transport.id}\" does not support model discovery (no list command, no ACP sidecar, and no configured models[]).`,\n );\n }\n if (source.via === \"acp\") {\n // The dispatch layer handles acp by delegating to a synthetic ACP route\n // (createCliDiscoveryAcpRoute); the cli manager should not be reached.\n throw new AiConnectError(\n \"not_supported\",\n `CLI route \"${context.route.id}\" resolves discovery via acp; dispatch to the acp discovery route instead.`,\n );\n }\n if (source.via === \"static\") {\n return buildStaticCliCatalog(context.route);\n }\n\n // via === \"command\": run the configured list command and parse its stdout.\n const phases: WideEventTransportPhase[] = [];\n const invocation = buildCliDiscoveryInvocation(\n context.route,\n source.command,\n options,\n );\n context.telemetry?.captureTransport({\n protocol: \"cli\",\n endpoint: invocation.command,\n method: \"process\",\n bodyKeys: [\"argv\"],\n parameterKeys: invocation.parameterKeys,\n phases,\n stream: false,\n });\n\n try {\n let models: AcpModelInfo[];\n try {\n const execution = await executeCliInvocation(\n invocation,\n options?.timeoutMs ?? 60_000,\n phases,\n context.abort.signal,\n );\n if (execution.exitCode !== 0 || !execution.stdout.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n execution.stderr.trim() ||\n `CLI discovery command for \"${context.route.transport.id}\" exited with code ${execution.exitCode ?? \"null\"}.`,\n );\n }\n models = parseCliModelList(\n execution.stdout,\n source.command.parser,\n source.command.models,\n );\n } catch (error) {\n // Never swallow a caller cancellation; propagate it.\n if (error instanceof AiConnectError && error.code === \"aborted\") {\n throw error;\n }\n if (source.fallback === \"static\") {\n const detail =\n error instanceof Error ? error.message : String(error);\n return buildStaticCliCatalog(\n context.route,\n `CLI discovery command for \"${context.route.transport.id}\" failed (${detail}); fell back to the static models[] catalog.`,\n );\n }\n throw error;\n }\n\n if (models.length === 0) {\n // Zero parseable models: fall back to static only when configured;\n // otherwise fail loud (fallback:'none' is a deliberate no-safety-net).\n if (source.fallback === \"static\") {\n return buildStaticCliCatalog(\n context.route,\n `CLI discovery command for \"${context.route.transport.id}\" returned no models; fell back to the static models[] catalog.`,\n );\n }\n throw new AiConnectError(\n \"temporary_unavailable\",\n `CLI discovery command for \"${context.route.transport.id}\" returned no models.`,\n );\n }\n\n return buildModelCatalog(\n context.route,\n models,\n currentModelIdForRoute(\n context.route,\n models.map((model) => model.modelId),\n ),\n );\n } finally {\n // D5 / SYS-6 (capture-then-cleanup): the in-flight result or error is\n // already committed to propagate through this `finally`. Run staging\n // cleanup in its OWN try/catch so a cleanup failure (e.g. fs.rm racing a\n // still-open handle) can never REPLACE the original success value or the\n // original error \u2014 swallow the cleanup fault as best-effort.\n try {\n await cleanupCliInvocation(invocation);\n } catch {\n // best-effort: staging teardown must not mask the transport outcome.\n }\n }\n },\n\n async runPrompt(context): Promise<RouteHandlerGenerateResult> {\n const invocation = await buildCliInvocation(context, options);\n const phases: WideEventTransportPhase[] = [];\n const transport: WideEventTransportSummary = {\n protocol: \"cli\",\n endpoint: invocation.command,\n method: \"process\",\n bodyKeys: [\"argv\"],\n parameterKeys: invocation.parameterKeys,\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n try {\n const execution = await executeCliInvocation(\n invocation,\n options?.timeoutMs ?? 60_000,\n phases,\n context.abort.signal,\n );\n\n const outputFileContent = invocation.outputFile\n ? await fs.readFile(invocation.outputFile, \"utf8\").catch(() => \"\")\n : undefined;\n\n if (execution.exitCode !== 0) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n execution.stderr.trim() ||\n `CLI transport \"${context.route.transport.id}\" exited with code ${execution.exitCode ?? \"null\"}.`,\n );\n }\n\n const result = parseCliResult(\n context.route,\n execution,\n outputFileContent,\n );\n if (execution.stderr.trim()) {\n result.warnings = [...(result.warnings ?? []), execution.stderr.trim()];\n }\n return result;\n } finally {\n // D5 / SYS-6 (capture-then-cleanup): the in-flight result or error is\n // already committed to propagate through this `finally`. Run staging\n // cleanup in its OWN try/catch so a cleanup failure (e.g. fs.rm racing a\n // still-open handle) can never REPLACE the original success value or the\n // original error \u2014 swallow the cleanup fault as best-effort.\n try {\n await cleanupCliInvocation(invocation);\n } catch {\n // best-effort: staging teardown must not mask the transport outcome.\n }\n }\n },\n };\n}\n", "import type { ChildProcess } from \"node:child_process\";\nimport { spawn } from \"node:child_process\";\nimport net from \"node:net\";\n\nimport { AI_CONNECT_DEFAULT_SERVER_COMMANDS } from \"./server-presets.js\";\nimport { AiConnectError } from \"./errors.js\";\nimport {\n killProcessTree,\n resolveChildEnv,\n resolveManagedCommand,\n trackChild,\n} from \"./transport-runtime.js\";\nimport type {\n AcpModelCatalog,\n AcpModelInfo,\n DiscoverAcpModelsContext,\n FetchLike,\n GenerateContext,\n NormalizedRoute,\n RouteHandlerGenerateResult,\n ServerClientOptions,\n WideEventTransportPhase,\n WideEventTransportSummary,\n} from \"./types.js\";\n\ntype ServerInstance = {\n origin: string;\n /** The spawned child, if any. Absent for baseUrl-attach instances (H7 evict). */\n child?: ChildProcess;\n dispose: () => Promise<void>;\n};\n\nfunction splitCommandLine(commandLine: string): {\n command: string;\n args: string[];\n} {\n const matches = commandLine.match(/\"[^\"]*\"|'[^']*'|[^\\s]+/g) ?? [];\n const parts = matches.map((part) => {\n if (\n (part.startsWith(\"\\\"\") && part.endsWith(\"\\\"\")) ||\n (part.startsWith(\"'\") && part.endsWith(\"'\"))\n ) {\n return part.slice(1, -1);\n }\n\n return part;\n });\n\n if (parts.length === 0) {\n throw new AiConnectError(\"validation_error\", \"Server command line is empty.\");\n }\n\n const [command, ...args] = parts;\n return {\n command: command!,\n args,\n };\n}\n\nfunction resolveServerCommand(\n route: NormalizedRoute,\n options?: ServerClientOptions,\n): string {\n // SYS-5: unified precedence \u2014 an explicit `options.commands` override wins over\n // `transport.command`, matching the ACP resolver (was transport-first here).\n const key = `${route.provider}:${route.transport.id}`;\n const optionsOverride =\n options?.commands?.[key]?.trim() ||\n options?.commands?.[route.transport.id]?.trim() ||\n options?.commands?.[route.provider]?.trim() ||\n undefined;\n\n try {\n return resolveManagedCommand(\n key,\n optionsOverride ? { [key]: optionsOverride } : undefined,\n route.transport.command,\n AI_CONNECT_DEFAULT_SERVER_COMMANDS[key],\n );\n } catch {\n throw new AiConnectError(\n \"validation_error\",\n `No server command preset is registered for route \"${route.id}\". Provide transport.command or server.commands.`,\n );\n }\n}\n\nexport function resolveServerExecutable(\n route: NormalizedRoute,\n options?: ServerClientOptions,\n): string {\n return splitCommandLine(resolveServerCommand(route, options)).command;\n}\n\nfunction resolveFetch(fetchLike: FetchLike | undefined): FetchLike {\n if (fetchLike) {\n return fetchLike;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new AiConnectError(\n \"validation_error\",\n \"No fetch implementation is available for server transport.\",\n );\n}\n\nfunction joinUrl(baseUrl: string, pathname: string): string {\n const normalizedBase = baseUrl.endsWith(\"/\")\n ? baseUrl.slice(0, -1)\n : baseUrl;\n\n return `${normalizedBase}${pathname.startsWith(\"/\") ? pathname : `/${pathname}`}`;\n}\n\nfunction buildServerPrompt(context: GenerateContext): string {\n if (context.request.operation !== \"text\") {\n throw new AiConnectError(\n \"not_supported\",\n `Server transport \"${context.route.transport.id}\" only supports text requests.`,\n );\n }\n\n if (context.request.attachments.length > 0 || context.request.image) {\n throw new AiConnectError(\n \"not_supported\",\n `Server transport \"${context.route.transport.id}\" does not support attachments or image inputs.`,\n );\n }\n\n return context.request.messages\n .map((message) => {\n if (message.role === \"user\") {\n return message.content;\n }\n\n return `${message.role.toUpperCase()}:\\n${message.content}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction capturePhase(\n phases: WideEventTransportPhase[],\n name: string,\n startedAt: number,\n): void {\n phases.push({\n name,\n durationMs: Date.now() - startedAt,\n });\n}\n\nasync function findAvailablePort(host = \"127.0.0.1\"): Promise<number> {\n return await new Promise((resolve, reject) => {\n const server = net.createServer();\n server.once(\"error\", reject);\n server.listen(0, host, () => {\n const address = server.address();\n const port =\n address && typeof address === \"object\" ? address.port : undefined;\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n\n if (!port) {\n reject(new Error(\"Failed to allocate an ephemeral port.\"));\n return;\n }\n\n resolve(port);\n });\n });\n });\n}\n\nasync function waitForServerHealth(\n fetchLike: FetchLike,\n origin: string,\n timeoutMs: number,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastError: unknown;\n // Per-attempt probe timeout (LOW): a hung health endpoint must not consume the\n // whole startup budget in a single request. Cap each probe at 2s (or the\n // remaining budget, whichever is smaller).\n const perAttemptTimeoutMs = Math.min(2_000, Math.max(250, timeoutMs));\n\n while (Date.now() < deadline) {\n try {\n const response = await fetchLike(joinUrl(origin, \"/global/health\"), {\n signal: AbortSignal.timeout(perAttemptTimeoutMs),\n });\n if (response.ok) {\n return;\n }\n lastError = new Error(\n `Server health probe failed with status ${response.status}.`,\n );\n } catch (error) {\n lastError = error;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n const message =\n lastError instanceof Error ? lastError.message : \"Unknown server startup failure.\";\n throw new AiConnectError(\n \"local_harness_unavailable\",\n `Server transport did not become healthy within ${timeoutMs}ms. ${message}`,\n );\n}\n\nasync function spawnServerInstance(\n route: NormalizedRoute,\n options: ServerClientOptions | undefined,\n phases: WideEventTransportPhase[],\n cwdOverride?: string,\n): Promise<ServerInstance> {\n const commandLine = resolveServerCommand(route, options);\n const resolved = splitCommandLine(commandLine);\n const port = await findAvailablePort();\n const host = \"127.0.0.1\";\n const origin = `http://${host}:${port}`;\n const args = [...resolved.args];\n if (!args.includes(\"serve\")) {\n args.push(\"serve\");\n }\n args.push(\"--hostname\", host, \"--port\", String(port));\n\n const spawnStartedAt = Date.now();\n // SYS-2: minimal env by default \u2014 the host's full `process.env` no longer leaks\n // into the spawned (third-party) server. Additional env is supplied via\n // `options.env`. Detached so the whole process group can be torn down (C3).\n const detached = process.platform !== \"win32\";\n const child = spawn(resolved.command, args, {\n cwd: cwdOverride ?? options?.cwd ?? process.cwd(),\n env: resolveChildEnv({ extra: options?.env ?? {} }),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached,\n });\n const untrack = trackChild(child, detached);\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n capturePhase(phases, \"spawn\", spawnStartedAt);\n\n const healthStartedAt = Date.now();\n try {\n await waitForServerHealth(\n resolveFetch(options?.fetch),\n origin,\n options?.startupTimeoutMs ?? 15_000,\n );\n capturePhase(phases, \"health\", healthStartedAt);\n } catch (error) {\n untrack();\n killProcessTree(child, \"SIGKILL\", detached);\n throw new AiConnectError(\n \"local_harness_unavailable\",\n stderr.trim() ||\n (error instanceof Error\n ? error.message\n : \"Failed to start local server transport.\"),\n );\n }\n\n return {\n origin,\n child,\n dispose: async () => {\n untrack();\n if (child.killed) {\n return;\n }\n\n killProcessTree(child, \"SIGTERM\", detached);\n await new Promise<void>((resolve) => {\n child.once(\"close\", () => resolve());\n setTimeout(() => {\n killProcessTree(child, \"SIGKILL\", detached);\n resolve();\n }, 1_000).unref?.();\n });\n },\n };\n}\n\nfunction providerIdsForRoute(\n route: NormalizedRoute,\n providers: Record<string, unknown>[],\n): string[] {\n if (route.provider === \"opencode\") {\n return providers\n .map((provider) =>\n typeof provider.id === \"string\" ? provider.id : undefined,\n )\n .filter((value): value is string => Boolean(value));\n }\n\n return [route.provider];\n}\n\nfunction modelsFromServerPayload(\n route: NormalizedRoute,\n payload: Record<string, unknown>,\n): AcpModelCatalog {\n const providers = Array.isArray(payload.providers)\n ? payload.providers.filter(\n (provider): provider is Record<string, unknown> =>\n Boolean(provider) && typeof provider === \"object\",\n )\n : [];\n const selectedProviders = new Set(providerIdsForRoute(route, providers));\n const availableModels: AcpModelInfo[] = [];\n\n for (const provider of providers) {\n if (\n typeof provider.id !== \"string\" ||\n !selectedProviders.has(provider.id) ||\n !provider.models ||\n typeof provider.models !== \"object\"\n ) {\n continue;\n }\n\n for (const [modelId, value] of Object.entries(\n provider.models as Record<string, unknown>,\n )) {\n const model =\n value && typeof value === \"object\"\n ? (value as Record<string, unknown>)\n : {};\n availableModels.push({\n modelId,\n name: typeof model.name === \"string\" ? model.name : modelId,\n ...(typeof model.family === \"string\"\n ? { description: model.family }\n : {}),\n metadata: {\n providerId: provider.id,\n },\n });\n }\n }\n\n const defaults =\n payload.default && typeof payload.default === \"object\"\n ? (payload.default as Record<string, unknown>)\n : undefined;\n const currentModelId = (() => {\n for (const providerId of selectedProviders) {\n const candidate = defaults?.[providerId];\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate;\n }\n }\n\n return undefined;\n })();\n const requestedModelAdvertised = availableModels.some(\n (model) => model.modelId === route.model,\n );\n\n return {\n requestedModelId: route.model,\n requestedModelAdvertised,\n ...(requestedModelAdvertised ? { resolvedModelId: route.model } : {}),\n ...(currentModelId ? { currentModelId } : {}),\n availableModels,\n };\n}\n\nfunction parseServerGenerateResult(\n payload: Record<string, unknown>,\n): RouteHandlerGenerateResult {\n const parts = Array.isArray(payload.parts)\n ? payload.parts.filter(\n (part): part is Record<string, unknown> =>\n Boolean(part) && typeof part === \"object\",\n )\n : [];\n const text = parts\n .map((part) => (typeof part.text === \"string\" ? part.text : \"\"))\n .filter(Boolean)\n .join(\"\");\n\n if (!text.trim()) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Server transport response did not contain text parts.\",\n );\n }\n\n return {\n text: text.trim(),\n data: payload,\n };\n}\n\nexport function createServerTransportManager(\n options?: ServerClientOptions,\n): {\n runPrompt: (context: GenerateContext) => Promise<RouteHandlerGenerateResult>;\n discoverModels: (\n context: DiscoverAcpModelsContext,\n ) => Promise<AcpModelCatalog>;\n verifyRoute: (\n route: NormalizedRoute,\n ) => Promise<{\n ok: boolean;\n message?: string;\n }>;\n dispose: () => Promise<void>;\n} {\n const fetchLike = resolveFetch(options?.fetch);\n const instances = new Map<string, Promise<ServerInstance>>();\n\n async function getInstance(\n route: NormalizedRoute,\n phases: WideEventTransportPhase[],\n cwdOverride?: string,\n ): Promise<ServerInstance> {\n const baseUrl = route.transport.baseUrl?.trim();\n if (baseUrl) {\n return {\n origin: baseUrl,\n dispose: async () => {},\n };\n }\n\n const key = [\n route.id,\n cwdOverride ?? options?.cwd ?? process.cwd(),\n JSON.stringify(options?.env ?? {}),\n ].join(\"\\u0002\");\n const existing = instances.get(key);\n if (existing) {\n return await existing;\n }\n\n const pending = spawnServerInstance(route, options, phases, cwdOverride);\n instances.set(key, pending);\n try {\n const instance = await pending;\n // H7: a spawned instance that later crashes must not stay cached forever\n // (that turned every subsequent call into a guaranteed failure). Evict the\n // entry on child exit/error so the next call respawns a fresh server.\n if (instance.child) {\n const evict = (): void => {\n if (instances.get(key) === pending) {\n instances.delete(key);\n }\n };\n instance.child.once(\"exit\", evict);\n instance.child.once(\"error\", evict);\n }\n return instance;\n } catch (error) {\n instances.delete(key);\n throw error;\n }\n }\n\n return {\n async runPrompt(context): Promise<RouteHandlerGenerateResult> {\n const phases: WideEventTransportPhase[] = [];\n const instance = await getInstance(\n context.route,\n phases,\n context.request.workingDirectory,\n );\n const transport: WideEventTransportSummary = {\n protocol: \"http\",\n endpoint: joinUrl(instance.origin, \"/session/:id/message\"),\n method: \"POST\",\n bodyKeys: [\"model\", \"parts\"],\n parameterKeys: [\"model\", \"parts[0].text\"],\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n const sessionStartedAt = Date.now();\n const sessionResponse = await fetchLike(joinUrl(instance.origin, \"/session\"), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n // H6: honor caller cancel / operation timeout on session creation too\n // (was only wired on the message fetch).\n signal: context.abort.signal,\n });\n capturePhase(phases, \"session/create\", sessionStartedAt);\n if (!sessionResponse.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport failed to create session (${sessionResponse.status}).`,\n );\n }\n\n const sessionPayload = (await sessionResponse.json()) as Record<string, unknown>;\n const sessionId =\n typeof sessionPayload.id === \"string\"\n ? sessionPayload.id\n : typeof sessionPayload.sessionID === \"string\"\n ? sessionPayload.sessionID\n : undefined;\n if (!sessionId) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n \"Server transport did not return a session id.\",\n );\n }\n\n try {\n const promptStartedAt = Date.now();\n const response = await fetchLike(\n joinUrl(instance.origin, `/session/${sessionId}/message`),\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: context.route.model,\n parts: [\n {\n type: \"text\",\n text: buildServerPrompt(context),\n },\n ],\n }),\n signal: context.abort.signal,\n },\n );\n capturePhase(phases, \"session/prompt\", promptStartedAt);\n if (!response.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport prompt failed (${response.status}).`,\n );\n }\n\n return parseServerGenerateResult(\n (await response.json()) as Record<string, unknown>,\n );\n } finally {\n void fetchLike(joinUrl(instance.origin, `/session/${sessionId}`), {\n method: \"DELETE\",\n }).catch(() => {});\n }\n },\n async discoverModels(context): Promise<AcpModelCatalog> {\n const phases: WideEventTransportPhase[] = [];\n const instance = await getInstance(context.route, phases);\n const transport: WideEventTransportSummary = {\n protocol: \"http\",\n endpoint: joinUrl(instance.origin, \"/config/providers\"),\n method: \"GET\",\n bodyKeys: [],\n parameterKeys: [],\n phases,\n stream: false,\n };\n context.telemetry?.captureTransport(transport);\n\n const startedAt = Date.now();\n // H6: propagate abort to model discovery as well.\n const response = await fetchLike(\n joinUrl(instance.origin, \"/config/providers\"),\n { signal: context.abort.signal },\n );\n capturePhase(phases, \"config/providers\", startedAt);\n if (!response.ok) {\n throw new AiConnectError(\n \"temporary_unavailable\",\n `Server transport model discovery failed (${response.status}).`,\n );\n }\n\n return modelsFromServerPayload(\n context.route,\n (await response.json()) as Record<string, unknown>,\n );\n },\n async verifyRoute(route): Promise<{ ok: boolean; message?: string }> {\n if (route.transport.baseUrl?.trim()) {\n try {\n const response = await fetchLike(\n joinUrl(route.transport.baseUrl, \"/global/health\"),\n );\n if (response.ok) {\n return { ok: true };\n }\n\n return {\n ok: false,\n message: `Server health endpoint returned ${response.status}.`,\n };\n } catch (error) {\n return {\n ok: false,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n return { ok: true };\n },\n async dispose(): Promise<void> {\n const values = await Promise.all([...instances.values()]);\n instances.clear();\n await Promise.all(values.map((instance) => instance.dispose()));\n },\n };\n}\n", "import { AiConnectError } from \"./errors.js\";\nimport {\n createAcpTransportManager,\n resolveAcpExecutable,\n} from \"./acp.js\";\nimport {\n createCliDiscoveryAcpRoute,\n createCliTransportManager,\n resolveCliDiscoverySource,\n resolveCliExecutable,\n} from \"./cli.js\";\nimport {\n createServerTransportManager,\n resolveServerExecutable,\n} from \"./server.js\";\nimport type {\n AcpClientOptions,\n AiConnectErrorCode,\n CliClientOptions,\n RouteHandlerRegistry,\n ServerClientOptions,\n VerificationIssue,\n} from \"./types.js\";\n\ntype LocalRouteHandlers = {\n handlers: RouteHandlerRegistry;\n dispose: () => Promise<void>;\n};\n\n/**\n * SYS-7 (duplication): the ACP/CLI/Server `verify` handlers each repeat the same\n * try/catch \u2192 AiConnectError \u2192 `[{code:'handler_issue', message}]` shape. Extracted so all\n * three (and any future transport verify handler) normalize an unknown catch value the same\n * way. Preserves the exact previous per-handler behavior: an `AiConnectError` is passed\n * through as-is (its own `.message` is used); anything else is wrapped in a fresh\n * `AiConnectError(fallbackCode, fallbackMessage)` before its `.message` is read.\n */\nfunction normalizeVerifyIssue(\n error: unknown,\n fallbackCode: AiConnectErrorCode,\n fallbackMessage: string,\n): VerificationIssue[] {\n const normalized =\n error instanceof AiConnectError\n ? error\n : new AiConnectError(fallbackCode, fallbackMessage);\n\n return [\n {\n code: \"handler_issue\",\n message: normalized.message,\n },\n ];\n}\n\nexport function createLocalRouteHandlers(\n options: {\n acp?: AcpClientOptions;\n cli?: CliClientOptions;\n server?: ServerClientOptions;\n } = {},\n): LocalRouteHandlers {\n const acpTransport = createAcpTransportManager(options.acp);\n const cliTransport = createCliTransportManager(options.cli);\n const serverTransport = createServerTransportManager(options.server);\n\n return {\n handlers: {\n \"*:acp\": {\n async generate(context) {\n return acpTransport.runPrompt(context);\n },\n stream(context) {\n // C9 / OQ-13: the first real ACP delta producer \u2014 emits {type:'delta'} per\n // agent_message_chunk then exactly one terminal {type:'result'}.\n return acpTransport.streamPrompt(context);\n },\n async discoverModels(context) {\n return acpTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n const executable = resolveAcpExecutable(route, options.acp);\n const available = await runtime.hasCommand?.(executable);\n if (available) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message: `Required ACP executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n } catch (error) {\n return normalizeVerifyIssue(\n error,\n \"validation_error\",\n \"ACP route verification failed.\",\n );\n }\n },\n },\n \"*:cli\": {\n async generate(context) {\n return cliTransport.runPrompt(context);\n },\n async discoverModels(context) {\n const source = resolveCliDiscoverySource(context.route);\n // acp source: delegate to a synthetic ACP discovery route (unchanged).\n if (source.via === \"acp\") {\n const discoveryRoute = createCliDiscoveryAcpRoute(context.route);\n if (!discoveryRoute) {\n throw new AiConnectError(\n \"not_supported\",\n `CLI route \"${context.route.id}\" does not define a model discovery backend.`,\n );\n }\n return acpTransport.discoverModels({\n ...context,\n route: discoveryRoute,\n });\n }\n // command / static / none: handled by the cli transport manager\n // (none throws not_supported there).\n return cliTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n const executable = resolveCliExecutable(route, options.cli);\n const available = await runtime.hasCommand?.(executable);\n if (available) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message: `Required CLI executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n } catch (error) {\n return normalizeVerifyIssue(\n error,\n \"validation_error\",\n \"CLI route verification failed.\",\n );\n }\n },\n },\n \"*:server\": {\n async generate(context) {\n return serverTransport.runPrompt(context);\n },\n async discoverModels(context) {\n return serverTransport.discoverModels(context);\n },\n async verify({ route, runtime }) {\n try {\n if (!route.transport.baseUrl) {\n const executable = resolveServerExecutable(route, options.server);\n const available = await runtime.hasCommand?.(executable);\n if (!available) {\n return [\n {\n code: \"handler_issue\",\n message: `Required server executable \"${executable}\" is unavailable for route \"${route.id}\".`,\n },\n ];\n }\n }\n\n const result = await serverTransport.verifyRoute(route);\n if (result.ok) {\n return [];\n }\n\n return [\n {\n code: \"handler_issue\",\n message:\n result.message ??\n `Server route \"${route.id}\" did not pass verification.`,\n },\n ];\n } catch (error) {\n return normalizeVerifyIssue(\n error,\n \"validation_error\",\n \"Server route verification failed.\",\n );\n }\n },\n },\n },\n dispose: async () => {\n await acpTransport.dispose();\n await serverTransport.dispose();\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["inferredId", "extension", "delimiter", "transportSummary", "finalError", "options", "summarizeToolChoice", "summarizeParameters", "response", "TEXT_EXTENSIONS", "isRecord", "basename", "parseDataUrl", "TEXT_EXTENSIONS", "isRecord", "sumOptionalNumbers", "result", "spawn", "fs", "os", "path", "splitCommandLine", "path", "fs", "os", "spawn", "spawn", "splitCommandLine", "capturePhase", "spawn", "extension"]
7
7
  }