opencode2api-proxy 0.0.0-stage → 1.1.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/config/defaults.ts", "../src/config/strict-json.ts", "../src/config/normalize.ts", "../src/config/schema.ts", "../src/config/loader.ts", "../src/cli/commands/start.ts", "../src/config/store.ts", "../src/protocol/sha256.ts", "../src/config/secrets.ts", "../src/auth/key-pool.ts", "../src/protocol/json-util.ts", "../src/proxy/model-discovery.ts", "../src/proxy/catalog-state.ts", "../src/proxy/model-catalog.ts", "../src/protocol/lanes.ts", "../src/protocol/paths.ts", "../src/protocol/identity.ts", "../src/protocol/anthropic-betas.ts", "../src/protocol/upstream-headers.ts", "../src/protocol/upstream-request.ts", "../src/unlimited/lane.ts", "../src/unlimited/guard.ts", "../src/unlimited/doctor.ts", "../src/protocol/block.ts", "../src/protocol/response-usage.ts", "../src/protocol/encode-blocks.ts", "../src/protocol/encode-shared.ts", "../src/protocol/response-encode.ts", "../src/protocol/sse.ts", "../src/protocol/stream-types.ts", "../src/protocol/stream-parser-shared.ts", "../src/protocol/stream-parser-anthropic.ts", "../src/protocol/stream-parser-chat.ts", "../src/protocol/decode-reasoning.ts", "../src/protocol/stream-parser-responses.ts", "../src/protocol/stream-parser.ts", "../src/protocol/stream-writer.ts", "../src/protocol/collapse.ts", "../src/protocol/error.ts", "../src/protocol/decode-blocks.ts", "../src/protocol/response-decode.ts", "../src/protocol/response.ts", "../src/protocol/tools/opencode_tools.json", "../src/protocol/tools.ts", "../src/unlimited/kilo.ts", "../src/proxy/upstream-client.ts", "../src/proxy/attempt-helpers.ts", "../src/proxy/attempt-runner.ts", "../src/telemetry/logger.ts", "../src/telemetry/log-broker.ts", "../src/telemetry/metric-types.ts", "../src/telemetry/metric-helpers.ts", "../src/telemetry/metrics.ts", "../src/protocol/request-identity.ts", "../src/protocol/stream-writer-chat.ts", "../src/protocol/stream-writer-anthropic.ts", "../src/protocol/stream-writer-responses.ts", "../src/protocol/stream-encoder.ts", "../src/protocol/stream-usage-tracker.ts", "../src/protocol/stream.ts", "../src/protocol/stream-renamer.ts", "../src/proxy/delivery.ts", "../src/proxy/request-shaping.ts", "../src/server/gateway-helpers.ts", "../src/server/completion-handler.ts", "../src/server/gateway.ts", "../src/server/dispatcher.ts", "../src/server/routes.ts", "../src/server/admin/server.ts", "../src/webui/theme.ts", "../src/webui/styles.ts", "../src/webui/script-core.ts", "../src/webui/script-monitor.ts", "../src/webui/script-settings.ts", "../src/webui/document.ts", "../src/server/admin/session.ts", "../src/server/admin/responses.ts", "../src/server/admin/views.ts", "../src/server/admin/config-routes.ts", "../src/server/admin/rate-limiter.ts", "../src/server/admin/key-routes.ts", "../src/server/admin/log-routes.ts", "../src/server/admin/routes.ts", "../src/proxy/catalog-refresh.ts", "../src/cli/index.ts"],
4
+ "sourcesContent": ["import type { Config } from \"../types/config.js\";\n\nexport const SOTA_MODELS = [\n \"deepseek-v4.1-flash\",\n \"glm-5.3\",\n \"grok-4.6\",\n \"kimi-k3\",\n \"qwen3.8-max\",\n] as const;\n\nexport const ANONYMOUS_KEY = \"public\";\n\nexport const V1_BASE = \"https://opencode.ai/zen\";\n\nexport const DEFAULT_CONFIG: Config = {\n listen: \"127.0.0.1:8080\",\n server_keys: [],\n server_key_metadata: {},\n zen_keys: [],\n go_keys: [],\n anonymous: false,\n proxies: [],\n proxyfile: \"\",\n upstream: {\n zen: V1_BASE,\n go: \"https://opencode.ai/zen/go\",\n anonymous: \"https://opencode.ai/inference\",\n },\n retry: {\n max_attempts: 3,\n timeout_seconds: 300,\n },\n models: {\n refresh_seconds: 300,\n protocols: {},\n free_only: false,\n },\n performance: {\n max_idle_conns: 2048,\n max_idle_conns_per_host: 256,\n max_conns_per_host: 0,\n idle_conn_timeout_seconds: 120,\n connect_timeout_seconds: 5,\n failure_cooldown_seconds: 15,\n attempt_timeout_seconds: 0,\n first_event_timeout_seconds: 0,\n },\n logging: {\n level: \"info\",\n ring_size: 2000,\n dump_request_bodies: false,\n },\n webui: {\n enabled: true,\n listen: \"0.0.0.0:8081\",\n username: \"admin\",\n session_ttl_minutes: 720,\n },\n prefer: \"go\",\n reasoning: {\n effort: \"\",\n effort_by_model: {},\n },\n rotation: {\n sota: { alias: \"sota\", order: [...SOTA_MODELS] },\n sweet: { alias: \"sweet\", order: [] },\n first_output_seconds: 30,\n },\n};\n\nexport function cloneConfig(config: Config): Config {\n return {\n ...config,\n server_keys: [...config.server_keys],\n server_key_metadata: { ...config.server_key_metadata },\n zen_keys: [...config.zen_keys],\n go_keys: [...config.go_keys],\n proxies: [...config.proxies],\n upstream: { ...config.upstream },\n retry: { ...config.retry },\n models: {\n ...config.models,\n protocols: { ...config.models.protocols },\n },\n performance: { ...config.performance },\n logging: { ...config.logging },\n webui: { ...config.webui },\n reasoning: {\n effort: config.reasoning.effort,\n effort_by_model: { ...config.reasoning.effort_by_model },\n },\n rotation: {\n sota: { ...config.rotation.sota, order: [...config.rotation.sota.order] },\n sweet: { ...config.rotation.sweet, order: [...config.rotation.sweet.order] },\n first_output_seconds: config.rotation.first_output_seconds,\n },\n };\n}\n", "export class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nexport type FieldType =\n | { kind: \"string\"; values?: string[] }\n | { kind: \"number\"; integer?: boolean; min?: number; max?: number }\n | { kind: \"boolean\" }\n | { kind: \"string[]\" }\n | { kind: \"record\"; values?: FieldType }\n | { kind: \"object\"; fields: Record<string, FieldType>; optional?: string[] }\n | { kind: \"any\" };\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nfunction decodeField(\n value: unknown,\n type: FieldType,\n path: string,\n): unknown {\n switch (type.kind) {\n case \"any\":\n return value;\n case \"string\": {\n if (typeof value !== \"string\") {\n throw new ConfigError(`${path} must be a string`);\n }\n if (type.values && !type.values.includes(value)) {\n throw new ConfigError(\n `${path} must be one of ${type.values.join(\", \")}`,\n );\n }\n return value;\n }\n case \"number\": {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ConfigError(`${path} must be a number`);\n }\n if (type.integer && !Number.isInteger(value)) {\n throw new ConfigError(`${path} must be an integer`);\n }\n if (type.min !== undefined && value < type.min) {\n throw new ConfigError(`${path} must be at least ${type.min}`);\n }\n if (type.max !== undefined && value > type.max) {\n throw new ConfigError(`${path} must be at most ${type.max}`);\n }\n return value;\n }\n case \"boolean\": {\n if (typeof value !== \"boolean\") {\n throw new ConfigError(`${path} must be a boolean`);\n }\n return value;\n }\n case \"string[]\": {\n if (!Array.isArray(value)) {\n throw new ConfigError(`${path} must be an array`);\n }\n return value.map((item, index) => {\n if (typeof item !== \"string\") {\n throw new ConfigError(`${path}[${index}] must be a string`);\n }\n return item;\n });\n }\n case \"record\": {\n if (!isPlainObject(value)) {\n throw new ConfigError(`${path} must be an object`);\n }\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n result[key] = type.values\n ? decodeField(item, type.values, `${path}.${key}`)\n : item;\n }\n return result;\n }\n case \"object\": {\n if (!isPlainObject(value)) {\n throw new ConfigError(`${path} must be an object`);\n }\n const optional = new Set(type.optional ?? []);\n for (const key of Object.keys(value)) {\n if (!(key in type.fields) && !optional.has(key)) {\n throw new ConfigError(`${path}.${key} is not a known field`);\n }\n }\n const result: Record<string, unknown> = {};\n for (const [key, fieldType] of Object.entries(type.fields)) {\n if (value[key] === undefined) {\n continue;\n }\n result[key] = decodeField(value[key], fieldType, `${path}.${key}`);\n }\n for (const key of optional) {\n if (value[key] !== undefined) {\n result[key] = value[key];\n }\n }\n return result;\n }\n }\n}\n\nexport function decodeStrict(\n value: unknown,\n type: FieldType,\n path = \"config\",\n): Record<string, unknown> {\n return decodeField(value, type, path) as Record<string, unknown>;\n}\n", "import { dirname, resolve } from \"node:path\";\nimport type {\n Config,\n ReasoningEffort,\n RotationConfig,\n RotationGroupConfig,\n} from \"../types/config.js\";\nimport { SOTA_MODELS } from \"./defaults.js\";\nimport { ConfigError } from \"./strict-json.js\";\n\nconst VALID_EFFORTS: ReasoningEffort[] = [\n \"\",\n \"auto\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n \"none\",\n];\n\nconst ALIAS_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;\n\nexport function isSotaModel(model: string): boolean {\n return SOTA_MODELS.includes(model as (typeof SOTA_MODELS)[number]);\n}\n\nfunction trimList(values: string[]): string[] {\n return values.map((value) => value.trim()).filter((value) => value.length > 0);\n}\n\nfunction applyRotationDefaults(rotation: RotationConfig): void {\n if (!rotation.sota.alias) {\n rotation.sota.alias = \"sota\";\n }\n if (!rotation.sweet.alias) {\n rotation.sweet.alias = \"sweet\";\n }\n if (rotation.sota.order.length === 0) {\n rotation.sota.order = [...SOTA_MODELS];\n }\n if (rotation.first_output_seconds === 0) {\n rotation.first_output_seconds = 30;\n }\n}\n\nfunction validateRotation(rotation: RotationConfig, realModels: string[]): void {\n if (rotation.first_output_seconds < 1 || rotation.first_output_seconds > 300) {\n throw new ConfigError(\n \"rotation.first_output_seconds must be between 1 and 300\",\n );\n }\n if (rotation.sota.alias === rotation.sweet.alias) {\n throw new ConfigError(\"the two rotation group aliases must differ\");\n }\n const groups: [RotationGroupConfig, number][] = [\n [rotation.sota, 0],\n [rotation.sweet, 1],\n ];\n for (const [group, index] of groups) {\n if (!ALIAS_PATTERN.test(group.alias)) {\n throw new ConfigError(\n \"rotation aliases must be 1-64 letters, digits, dots, dashes or underscores\",\n );\n }\n if (\n realModels.includes(group.alias) ||\n isSotaModel(group.alias) ||\n rotation.sweet.order.includes(group.alias)\n ) {\n throw new ConfigError(\"rotation aliases must not shadow a model ID\");\n }\n const seen = new Set<string>();\n for (const model of group.order) {\n if (!model || seen.has(model)) {\n throw new ConfigError(\"rotation order contains a duplicate or empty entry\");\n }\n if (isSotaModel(model) !== (index === 0)) {\n throw new ConfigError(\n \"rotation order contains a model that does not belong to its group\",\n );\n }\n seen.add(model);\n }\n if (index === 0 && group.order.length !== SOTA_MODELS.length) {\n throw new ConfigError(\"the sota group must contain the five SOTA models\");\n }\n }\n}\n\nfunction validateUrl(name: string, raw: string): void {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new ConfigError(`${name} must be an http or https URL`);\n }\n const scheme = parsed.protocol.replace(\":\", \"\").toLowerCase();\n if (scheme !== \"http\" && scheme !== \"https\") {\n throw new ConfigError(`${name} must be an http or https URL`);\n }\n}\n\nfunction validateProxyScheme(raw: string): void {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new ConfigError(`invalid proxy URL \"${raw}\"`);\n }\n const scheme = parsed.protocol.replace(\":\", \"\").toLowerCase();\n if (![\"http\", \"https\", \"socks5\", \"socks5h\"].includes(scheme)) {\n throw new ConfigError(`unsupported proxy scheme \"${scheme}\"`);\n }\n}\n\nexport function normalizeConfig(config: Config, configPath = \"\"): Config {\n const normalized = { ...config };\n normalized.reasoning = {\n effort: normalized.reasoning.effort.trim().toLowerCase() as ReasoningEffort,\n effort_by_model: { ...normalized.reasoning.effort_by_model },\n };\n normalized.rotation = {\n sota: { ...normalized.rotation.sota, order: [...normalized.rotation.sota.order] },\n sweet: { ...normalized.rotation.sweet, order: [...normalized.rotation.sweet.order] },\n first_output_seconds: normalized.rotation.first_output_seconds,\n };\n applyRotationDefaults(normalized.rotation);\n validateRotation(normalized.rotation, []);\n\n normalized.server_keys = trimList(normalized.server_keys);\n normalized.zen_keys = trimList(normalized.zen_keys);\n normalized.go_keys = trimList(normalized.go_keys);\n normalized.proxies = trimList(normalized.proxies);\n normalized.proxyfile = normalized.proxyfile.trim();\n\n if (normalized.prefer !== \"zen\" && normalized.prefer !== \"go\") {\n throw new ConfigError('prefer must be \"zen\" or \"go\"');\n }\n if (!normalized.listen.trim()) {\n throw new ConfigError(\"listen must not be empty\");\n }\n normalized.upstream.zen = normalized.upstream.zen.trim();\n normalized.upstream.go = normalized.upstream.go.trim();\n normalized.upstream.anonymous = normalized.upstream.anonymous.trim();\n if (!normalized.upstream.anonymous) {\n normalized.upstream.anonymous = \"https://opencode.ai/inference\";\n }\n validateUrl(\"upstream.zen\", normalized.upstream.zen);\n validateUrl(\"upstream.go\", normalized.upstream.go);\n validateUrl(\"upstream.anonymous\", normalized.upstream.anonymous);\n\n if (normalized.server_keys.length === 0) {\n throw new ConfigError(\n \"server_keys must contain at least one local key\",\n );\n }\n if (\n !normalized.anonymous &&\n normalized.zen_keys.length === 0 &&\n normalized.go_keys.length === 0\n ) {\n throw new ConfigError(\n \"zen_keys or go_keys must contain at least one upstream key unless anonymous is enabled\",\n );\n }\n if (normalized.retry.max_attempts < 1) {\n throw new ConfigError(\"retry.max_attempts must be at least 1\");\n }\n if (normalized.retry.timeout_seconds < 1) {\n throw new ConfigError(\"retry.timeout_seconds must be at least 1\");\n }\n if (normalized.models.refresh_seconds < 1) {\n throw new ConfigError(\"models.refresh_seconds must be at least 1\");\n }\n const perf = normalized.performance;\n if (\n perf.max_idle_conns < 1 ||\n perf.max_idle_conns_per_host < 1 ||\n perf.max_conns_per_host < 0 ||\n perf.idle_conn_timeout_seconds < 1 ||\n perf.connect_timeout_seconds < 1 ||\n perf.failure_cooldown_seconds < 1\n ) {\n throw new ConfigError(\n \"performance values must be positive (max_conns_per_host may be zero for unlimited)\",\n );\n }\n if (perf.attempt_timeout_seconds < 0) {\n throw new ConfigError(\n \"performance.attempt_timeout_seconds must not be negative (0 keeps the retry timeout)\",\n );\n }\n if (\n perf.first_event_timeout_seconds < 0 ||\n perf.first_event_timeout_seconds > 86400\n ) {\n throw new ConfigError(\n \"performance.first_event_timeout_seconds must be between 0 and 86400\",\n );\n }\n if (![\"debug\", \"info\", \"warn\", \"error\"].includes(normalized.logging.level)) {\n throw new ConfigError(\"logging.level must be debug, info, warn, or error\");\n }\n if (\n normalized.logging.ring_size < 100 ||\n normalized.logging.ring_size > 50000\n ) {\n throw new ConfigError(\"logging.ring_size must be between 100 and 50000\");\n }\n if (normalized.webui.password && normalized.webui.password.length < 10) {\n throw new ConfigError(\"webui.password must contain at least 10 characters\");\n }\n if (normalized.webui.enabled) {\n normalized.webui.listen = normalized.webui.listen.trim();\n normalized.webui.username = normalized.webui.username.trim();\n if (!normalized.webui.listen) {\n throw new ConfigError(\n \"webui.listen must not be empty when webui is enabled\",\n );\n }\n if (!normalized.webui.username) {\n throw new ConfigError(\n \"webui.username must not be empty when webui is enabled\",\n );\n }\n if (!normalized.webui.password && !normalized.webui.password_hash) {\n throw new ConfigError(\"webui.password is required for first-time setup\");\n }\n if (\n normalized.webui.session_ttl_minutes < 5 ||\n normalized.webui.session_ttl_minutes > 10080\n ) {\n throw new ConfigError(\n \"webui.session_ttl_minutes must be between 5 and 10080\",\n );\n }\n }\n for (const proxy of normalized.proxies) {\n if (proxy !== \"direct\") {\n validateProxyScheme(proxy);\n }\n }\n for (const [model, protocol] of Object.entries(normalized.models.protocols)) {\n if (!model.trim() || ![\"chat\", \"responses\", \"anthropic\"].includes(protocol)) {\n throw new ConfigError(\n `models.protocols contains an invalid mapping \"${model}\": \"${protocol}\"`,\n );\n }\n }\n if (!VALID_EFFORTS.includes(normalized.reasoning.effort)) {\n throw new ConfigError(\"reasoning.effort is not a valid effort level\");\n }\n for (const [model, effort] of Object.entries(normalized.reasoning.effort_by_model)) {\n if (!model.trim()) {\n throw new ConfigError(\n \"reasoning.effort_by_model must not contain an empty model ID\",\n );\n }\n if (!VALID_EFFORTS.includes(effort.toLowerCase() as ReasoningEffort)) {\n throw new ConfigError(\n `reasoning.effort_by_model[\"${model}\"] is not a valid effort level`,\n );\n }\n }\n\n if (normalized.proxyfile && configPath) {\n normalized.proxyfile = resolve(dirname(configPath), normalized.proxyfile);\n }\n return normalized;\n}\n", "import type { FieldType } from \"./strict-json.js\";\n\nexport const CONFIG_SCHEMA: FieldType = {\n kind: \"object\",\n fields: {\n listen: { kind: \"string\" },\n server_keys: { kind: \"string[]\" },\n server_key_metadata: {\n kind: \"record\",\n values: {\n kind: \"object\",\n fields: {\n name: { kind: \"string\" },\n disabled: { kind: \"boolean\" },\n created_at: { kind: \"string\" },\n },\n optional: [\"disabled\", \"created_at\"],\n },\n },\n zen_keys: { kind: \"string[]\" },\n go_keys: { kind: \"string[]\" },\n anonymous: { kind: \"boolean\" },\n proxies: { kind: \"string[]\" },\n proxyfile: { kind: \"string\" },\n upstream: {\n kind: \"object\",\n fields: {\n zen: { kind: \"string\" },\n go: { kind: \"string\" },\n anonymous: { kind: \"string\" },\n },\n },\n retry: {\n kind: \"object\",\n fields: {\n max_attempts: { kind: \"number\", integer: true },\n timeout_seconds: { kind: \"number\", integer: true },\n },\n },\n models: {\n kind: \"object\",\n fields: {\n refresh_seconds: { kind: \"number\", integer: true },\n protocols: { kind: \"record\", values: { kind: \"string\" } },\n free_only: { kind: \"boolean\" },\n },\n },\n performance: {\n kind: \"object\",\n fields: {\n max_idle_conns: { kind: \"number\", integer: true },\n max_idle_conns_per_host: { kind: \"number\", integer: true },\n max_conns_per_host: { kind: \"number\", integer: true },\n idle_conn_timeout_seconds: { kind: \"number\", integer: true },\n connect_timeout_seconds: { kind: \"number\", integer: true },\n failure_cooldown_seconds: { kind: \"number\", integer: true },\n attempt_timeout_seconds: { kind: \"number\", integer: true },\n first_event_timeout_seconds: { kind: \"number\", integer: true },\n },\n },\n logging: {\n kind: \"object\",\n fields: {\n level: { kind: \"string\", values: [\"debug\", \"info\", \"warn\", \"error\"] },\n ring_size: { kind: \"number\", integer: true },\n dump_request_bodies: { kind: \"boolean\" },\n },\n },\n webui: {\n kind: \"object\",\n fields: {\n enabled: { kind: \"boolean\" },\n listen: { kind: \"string\" },\n username: { kind: \"string\" },\n password: { kind: \"string\" },\n password_hash: { kind: \"string\" },\n session_ttl_minutes: { kind: \"number\", integer: true },\n },\n optional: [\"password\", \"password_hash\"],\n },\n prefer: { kind: \"string\", values: [\"zen\", \"go\"] },\n reasoning: {\n kind: \"object\",\n fields: {\n effort: {\n kind: \"string\",\n values: [\n \"\",\n \"auto\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n \"none\",\n ],\n },\n effort_by_model: { kind: \"record\", values: { kind: \"string\" } },\n },\n },\n rotation: {\n kind: \"object\",\n fields: {\n sota: rotationGroup(),\n sweet: rotationGroup(),\n first_output_seconds: { kind: \"number\", integer: true },\n },\n },\n },\n};\n\n// rotationGroup is the schema of one rotation group.\nfunction rotationGroup(): FieldType {\n return {\n kind: \"object\",\n fields: {\n alias: { kind: \"string\" },\n order: { kind: \"string[]\" },\n },\n };\n}\n", "import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Config } from \"../types/config.js\";\nimport { cloneConfig, DEFAULT_CONFIG } from \"./defaults.js\";\nimport { normalizeConfig } from \"./normalize.js\";\nimport { CONFIG_SCHEMA } from \"./schema.js\";\nimport { ConfigError, decodeStrict } from \"./strict-json.js\";\n\nexport function stripJsonComments(text: string): string {\n const lines = text.split(/\\r?\\n/);\n const kept = lines.filter((line) => !/^\\s*\\/\\//.test(line));\n return kept.join(\"\\n\");\n}\n\nexport function parseConfig(text: string, source: string): Config {\n let parsed: unknown;\n try {\n parsed = JSON.parse(stripJsonComments(text));\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new ConfigError(`parse ${source}: ${detail}`);\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new ConfigError(`parse ${source}: config must be a JSON object`);\n }\n const decoded = decodeStrict(parsed, CONFIG_SCHEMA, \"config\");\n return { ...cloneConfig(DEFAULT_CONFIG), ...decoded } as unknown as Config;\n}\n\nexport function resolveConfigPath(explicit?: string): string {\n if (explicit) {\n return resolve(explicit);\n }\n const fromEnv = process.env.OPENCODE2API_CONFIG;\n if (fromEnv) {\n return resolve(fromEnv);\n }\n return resolve(process.cwd(), \"config.json\");\n}\n\nexport async function loadConfig(path: string): Promise<Config> {\n let text: string;\n try {\n text = await readFile(path, \"utf8\");\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new ConfigError(`read ${path}: ${detail}`);\n }\n const config = parseConfig(text, path);\n return normalizeConfig(config, path);\n}\n", "import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Config } from \"../../types/config.js\";\nimport { loadConfig } from \"../../config/loader.js\";\nimport { ConfigStore, resolveConfigPath } from \"../../config/store.js\";\nimport { Gateway } from \"../../server/gateway.js\";\nimport { RequestDispatcher, startServer } from \"../../server/dispatcher.js\";\nimport { registerRoutes } from \"../../server/routes.js\";\nimport { startWebUIServer } from \"../../server/admin/server.js\";\nimport { CatalogRefresher } from \"../../proxy/catalog-refresh.js\";\n\n// StartOptions are the options the start command accepts.\nexport interface StartOptions {\n port?: number;\n host?: string;\n key?: string;\n config?: string;\n webui?: boolean;\n}\n\n// runStartCommand starts the local daemon: the API server and, when the\n// WebUI is enabled, the control WebUI server.\nexport async function runStartCommand(options: StartOptions): Promise<void> {\n const configPath = resolveConfigPath(options.config);\n const config = await loadConfig(configPath);\n const applied = applyOverrides(config, options);\n const store = new ConfigStore(applied, configPath);\n void store;\n const gateway = new Gateway(applied);\n\n const dispatcher = new RequestDispatcher(() => gateway.serverKeys());\n registerRoutes(dispatcher, gateway);\n const listen = hostPort(applied.listen, options);\n const server = await startServer(dispatcher, listen);\n console.log(\n `[OpenCode2API] API server listening on ${listen} (models: ${gateway.catalog.list().length})`,\n );\n\n const refresher = new CatalogRefresher(gateway, applied);\n await refresher.start();\n\n let webuiServer: Awaited<ReturnType<typeof startWebUIServer>> | undefined;\n if (applied.webui.enabled) {\n webuiServer = await startWebUIServer(gateway, applied.webui.listen);\n console.log(`[OpenCode2API] Control WebUI listening on ${applied.webui.listen}`);\n }\n\n const shutdown = (): void => {\n console.log(\"[OpenCode2API] Shutting down...\");\n refresher.stop();\n server.close();\n webuiServer?.close();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\n// applyOverrides applies the command line overrides to a configuration.\nexport function applyOverrides(config: Config, options: StartOptions): Config {\n const result = { ...config };\n if (options.key !== undefined && options.key !== \"\") {\n result.server_keys = [options.key];\n }\n if (options.host !== undefined || options.port !== undefined) {\n const host = options.host ?? hostOf(result.listen);\n const port = options.port ?? portOf(result.listen);\n result.listen = `${host}:${port}`;\n }\n if (options.webui === false) {\n result.webui = { ...result.webui, enabled: false };\n }\n return result;\n}\n\n// hostOf reads the host of a listen address.\nexport function hostOf(listen: string): string {\n const index = listen.lastIndexOf(\":\");\n return index === -1 ? \"127.0.0.1\" : listen.slice(0, index);\n}\n\n// portOf reads the port of a listen address.\nexport function portOf(listen: string): number {\n const index = listen.lastIndexOf(\":\");\n if (index === -1) {\n return 8080;\n }\n const port = Number(listen.slice(index + 1));\n return Number.isFinite(port) ? port : 8080;\n}\n\n// hostPort builds the listen address of the API server.\nexport function hostPort(listen: string, options: StartOptions): string {\n const host = options.host ?? hostOf(listen);\n const port = options.port ?? portOf(listen);\n return `${host}:${port}`;\n}\n\n// readConfigFile reads a configuration file, returning undefined when it does\n// not exist.\nexport async function readConfigFile(path: string): Promise<Config | undefined> {\n try {\n const text = await readFile(resolve(path), \"utf8\");\n const { parseConfig } = await import(\"../../config/loader.js\");\n return parseConfig(text, path);\n } catch {\n return undefined;\n }\n}\n", "import { copyFile, mkdir, rename, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type { Config } from \"../types/config.js\";\nimport { cloneConfig } from \"./defaults.js\";\nimport { normalizeConfig } from \"./normalize.js\";\nimport { fingerprintSecret } from \"./secrets.js\";\n\nexport function resolveConfigPath(explicit?: string): string {\n if (explicit) {\n return resolve(explicit);\n }\n const fromEnv = process.env.OPENCODE2API_CONFIG;\n if (fromEnv) {\n return resolve(fromEnv);\n }\n const besideBinary = resolve(dirname(process.execPath), \"config.json\");\n return besideBinary;\n}\n\nexport function configSidecarPath(configPath: string, suffix: string): string {\n return `${configPath}${suffix}`;\n}\n\nexport class ConfigStore {\n private config: Config;\n private readonly path: string;\n\n constructor(config: Config, path: string) {\n this.config = config;\n this.path = path;\n }\n\n get current(): Config {\n return this.config;\n }\n\n get filePath(): string {\n return this.path;\n }\n\n replace(config: Config): Config {\n this.config = normalizeConfig(config, this.path);\n return this.config;\n }\n\n async save(): Promise<void> {\n const payload = cloneConfig(this.config);\n const serialized = `${JSON.stringify(payload, null, 2)}\\n`;\n const tempPath = `${this.path}.tmp`;\n const backupPath = `${this.path}.bak`;\n await mkdir(dirname(this.path), { recursive: true });\n try {\n await copyFile(this.path, backupPath);\n } catch {\n // No previous config to back up on the first save.\n }\n await writeFile(tempPath, serialized, \"utf8\");\n await rename(tempPath, this.path);\n }\n\n serverKeyMetadata(): Record<string, { name: string; disabled: boolean }> {\n const result: Record<string, { name: string; disabled: boolean }> = {};\n for (const [id, meta] of Object.entries(this.config.server_key_metadata)) {\n result[id] = { name: meta.name, disabled: meta.disabled ?? false };\n }\n return result;\n }\n\n isServerKeyEnabled(key: string): boolean {\n const meta = this.config.server_key_metadata[fingerprintSecret(key)];\n return meta?.disabled !== true;\n }\n\n firstEnabledServerKey(): string {\n for (const key of this.config.server_keys) {\n if (this.isServerKeyEnabled(key)) {\n return key;\n }\n }\n return \"\";\n }\n}\n", "// SHA-256 in pure TypeScript. The Cloudflare Worker bundle cannot use\n// node:crypto, and the Web Crypto digest is asynchronous while the identity\n// helpers are synchronous, so the hash is implemented here. It is used by\n// both the Node and the Worker builds.\n\n// The round constants of the SHA-256 specification.\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\n// sha256 returns the SHA-256 digest of a buffer.\nexport function sha256(input: Uint8Array): Uint8Array {\n const h = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,\n 0x1f83d9ab, 0x5be0cd19,\n ]);\n const bitLength = input.length * 8;\n const paddedLength = Math.ceil((input.length + 9) / 64) * 64;\n const block = new Uint8Array(paddedLength);\n block.set(input);\n block[input.length] = 0x80;\n const view = new DataView(block.buffer);\n view.setUint32(paddedLength - 4, bitLength >>> 0, false);\n view.setUint32(paddedLength - 8, Math.floor(bitLength / 0x100000000), false);\n\n const w = new Uint32Array(64);\n for (let offset = 0; offset < paddedLength; offset += 64) {\n for (let i = 0; i < 16; i += 1) {\n w[i] = view.getUint32(offset + i * 4, false);\n }\n for (let i = 16; i < 64; i += 1) {\n const s0 =\n (rotr(w[i - 15] ?? 0, 7) ^ (rotr(w[i - 15] ?? 0, 18) ^ ((w[i - 15] ?? 0) >>> 3)));\n const s1 =\n (rotr(w[i - 2] ?? 0, 17) ^ (rotr(w[i - 2] ?? 0, 19) ^ ((w[i - 2] ?? 0) >>> 10)));\n w[i] = ((w[i - 16] ?? 0) + s0 + (w[i - 7] ?? 0) + s1) >>> 0;\n }\n let a = h[0] ?? 0;\n let b = h[1] ?? 0;\n let c = h[2] ?? 0;\n let d = h[3] ?? 0;\n let e = h[4] ?? 0;\n let f = h[5] ?? 0;\n let g = h[6] ?? 0;\n let hh = h[7] ?? 0;\n for (let i = 0; i < 64; i += 1) {\n const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const temp1 = (hh + S1 + ch + (K[i] ?? 0) + (w[i] ?? 0)) >>> 0;\n const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (S0 + maj) >>> 0;\n hh = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n h[0] = ((h[0] ?? 0) + a) >>> 0;\n h[1] = ((h[1] ?? 0) + b) >>> 0;\n h[2] = ((h[2] ?? 0) + c) >>> 0;\n h[3] = ((h[3] ?? 0) + d) >>> 0;\n h[4] = ((h[4] ?? 0) + e) >>> 0;\n h[5] = ((h[5] ?? 0) + f) >>> 0;\n h[6] = ((h[6] ?? 0) + g) >>> 0;\n h[7] = ((h[7] ?? 0) + hh) >>> 0;\n }\n const digest = new Uint8Array(32);\n const digestView = new DataView(digest.buffer);\n for (let i = 0; i < 8; i += 1) {\n digestView.setUint32(i * 4, h[i] ?? 0, false);\n }\n return digest;\n}\n\n// rotr rotates a 32-bit value right.\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\n// sha256Hex returns the hex SHA-256 digest of a string.\nexport function sha256Hex(input: string): string {\n return toHex(sha256(utf8(input)));\n}\n\n// sha256Bytes returns the SHA-256 digest of a string.\nexport function sha256Bytes(input: string): Uint8Array {\n return sha256(utf8(input));\n}\n\n// sha256OfBytes returns the SHA-256 digest of raw bytes.\nexport function sha256OfBytes(input: Uint8Array): Uint8Array {\n return sha256(input);\n}\n\n// toHex renders bytes as lowercase hex.\nexport function toHex(bytes: Uint8Array): string {\n let out = \"\";\n for (const byte of bytes) {\n out += byte.toString(16).padStart(2, \"0\");\n }\n return out;\n}\n\n// utf8 encodes a string into bytes.\nexport function utf8(input: string): Uint8Array {\n return new TextEncoder().encode(input);\n}\n\n// randomBytes returns the requested number of random bytes. The Worker has no\n// node:crypto, so the Web Crypto generator is used there.\nexport function randomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size);\n crypto.getRandomValues(bytes);\n return bytes;\n}\n", "import { sha256Hex } from \"../protocol/sha256.js\";\n\nexport function maskSecret(value: string): string {\n if (value.length <= 5) {\n return \"\u2022\u2022\u2022\u2022\";\n }\n return `\u2022\u2022\u2022\u2022${value.slice(-5)}`;\n}\n\nexport function fingerprintSecret(value: string): string {\n return sha256Hex(value).slice(0, 16);\n}\n\nexport function keyDisplayId(value: string): string {\n if (value.length <= 5) {\n return value;\n }\n return value.slice(-5);\n}\n\nexport function redactUrl(raw: string): string {\n try {\n const url = new URL(raw);\n if (url.username || url.password) {\n url.username = \"***\";\n url.password = \"\";\n }\n return url.toString();\n } catch {\n return \"<invalid>\";\n }\n}\n\nexport class SecretRedactor {\n private values: string[] = [];\n\n replace(values: string[]): void {\n this.values = [...values].sort((a, b) => b.length - a.length);\n }\n\n redact(text: string): string {\n let result = text;\n for (const secret of this.values) {\n if (secret.length >= 4) {\n result = result.split(secret).join(\"***\");\n }\n }\n return result;\n }\n}\n", "import { fingerprintSecret } from \"../config/secrets.js\";\n\n// The base cooldown a failing key is held back for, and the largest multiple\n// of it the cooldown grows to.\nconst MAX_COOLDOWN_MULTIPLIER = 8;\n\n// KeyNode is one upstream key in a tier's pool. It remembers how often it\n// failed and until when it is held back, so a failing key is skipped for a\n// while instead of being retried on every request.\nexport interface KeyNode {\n key: string;\n id: string;\n failures: number;\n cooldownUntil: number;\n}\n\n// KeyPool is one tier's key pool. It hands out keys in a round-robin order\n// and honours the cooldown of the keys that recently failed.\nexport class KeyPool {\n readonly nodes: KeyNode[];\n private next = 0;\n\n constructor(keys: readonly string[]) {\n this.nodes = keys.map((key) => ({\n key,\n id: fingerprintSecret(key),\n failures: 0,\n cooldownUntil: 0,\n }));\n }\n\n // size reports how many keys the pool holds.\n size(): number {\n return this.nodes.length;\n }\n\n // isEmpty reports whether the pool holds no keys.\n isEmpty(): boolean {\n return this.nodes.length === 0;\n }\n\n // keys returns the pool's keys.\n keys(): string[] {\n return this.nodes.map((node) => node.key);\n }\n\n // ids returns the pool's key fingerprints.\n ids(): string[] {\n return this.nodes.map((node) => node.id);\n }\n\n // cursor returns a cursor over the pool. The starting node is reserved per\n // cursor, so concurrent requests start on different keys.\n cursor(): KeyCursor {\n if (this.nodes.length === 0) {\n return new KeyCursor(this, 0);\n }\n const start = this.next % this.nodes.length;\n this.next = (this.next + 1) % this.nodes.length;\n return new KeyCursor(this, start);\n }\n\n // cursorFor returns a cursor whose first choice is stable for the supplied\n // affinity key, so every turn of a conversation stays on the same upstream\n // key. An empty affinity keeps the round-robin behavior.\n cursorFor(affinity: string): KeyCursor {\n if (affinity === \"\" || this.nodes.length === 0) {\n return this.cursor();\n }\n let hash = 0xcbf29ce484222325n;\n for (const byte of Buffer.from(affinity, \"utf8\")) {\n hash = ((hash ^ BigInt(byte)) * 0x100000001b3n) & 0xffffffffffffffffn;\n }\n return new KeyCursor(this, Number(hash % BigInt(this.nodes.length)));\n }\n\n // markSuccess clears a key's failure count and cooldown.\n markSuccess(node: KeyNode): void {\n node.failures = 0;\n node.cooldownUntil = 0;\n }\n\n // markFailure cools a key down after an error or a 401, 403, 429 or 5xx\n // response; any other response leaves it untouched. The cooldown doubles\n // with each consecutive failure, from the base cooldown up to eight times\n // it, and a longer Retry-After is honored in full.\n markFailure(\n node: KeyNode,\n status: number,\n retryAfter: number,\n cooldownSeconds: number,\n now: number = Date.now(),\n ): void {\n const failed =\n status === 0 ||\n status === 401 ||\n status === 403 ||\n status === 429 ||\n status >= 500;\n if (!failed) {\n return;\n }\n node.failures += 1;\n const multiplier = 2 ** Math.min(node.failures - 1, 3);\n let delay = cooldownSeconds * 1000 * multiplier;\n delay = Math.min(delay, cooldownSeconds * 1000 * MAX_COOLDOWN_MULTIPLIER);\n if (retryAfter > delay) {\n delay = retryAfter;\n }\n node.cooldownUntil = now + delay;\n }\n}\n\n// KeyCursor walks a pool's keys. It prefers a key that is not cooling down\n// and moves past the key it returned, so the next call continues the\n// round-robin.\nexport class KeyCursor {\n private readonly pool: KeyPool;\n private position: number;\n\n constructor(pool: KeyPool, start: number) {\n this.pool = pool;\n this.position = start;\n }\n\n // next returns the key to try, or undefined when the pool is empty.\n next(): KeyNode | undefined {\n const nodes = this.pool.nodes;\n if (nodes.length === 0) {\n return undefined;\n }\n const now = Date.now();\n let ready = -1;\n let earliest = -1;\n let earliestUntil = 0;\n for (let offset = 0; offset < nodes.length; offset += 1) {\n const index = (this.position + offset) % nodes.length;\n const node = nodes[index];\n if (node === undefined) {\n continue;\n }\n if (node.cooldownUntil <= now) {\n ready = index;\n break;\n }\n if (earliest < 0 || node.cooldownUntil < earliestUntil) {\n earliest = index;\n earliestUntil = node.cooldownUntil;\n }\n }\n const choice = ready >= 0 ? ready : earliest;\n if (choice < 0) {\n return undefined;\n }\n this.position = (choice + 1) % nodes.length;\n return nodes[choice];\n }\n}\n\n// parseRetryAfter reads a Retry-After header in delta-seconds or HTTP-date\n// form. It returns 0 for an empty, non-positive or unparsable value and for\n// a date already in the past.\nexport function parseRetryAfter(value: string, now: number = Date.now()): number {\n const trimmed = value.trim();\n if (trimmed === \"\") {\n return 0;\n }\n const seconds = Number(trimmed);\n if (Number.isFinite(seconds) && Number.isInteger(seconds) && seconds > 0) {\n return seconds * 1000;\n }\n const when = Date.parse(trimmed);\n if (Number.isNaN(when)) {\n return 0;\n }\n return Math.max(when - now, 0);\n}\n", "export function isPlainObject(\n value: unknown,\n): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function stringAt(\n value: unknown,\n ...path: string[]\n): string {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return \"\";\n }\n current = current[key];\n }\n return typeof current === \"string\" ? current : \"\";\n}\n\nexport function numberAt(value: unknown, ...path: string[]): number | undefined {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return undefined;\n }\n current = current[key];\n }\n return typeof current === \"number\" ? current : undefined;\n}\n\nexport function boolAt(value: unknown, ...path: string[]): boolean | undefined {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return undefined;\n }\n current = current[key];\n }\n return typeof current === \"boolean\" ? current : undefined;\n}\n\nexport function mapAt(value: unknown, ...path: string[]): Record<string, unknown> {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return {};\n }\n current = current[key];\n }\n return isPlainObject(current) ? current : {};\n}\n\nexport function sliceAt(value: unknown, ...path: string[]): unknown[] {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return [];\n }\n current = current[key];\n }\n return Array.isArray(current) ? current : [];\n}\n\nexport function asSlice(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (value === undefined || value === null) {\n return [];\n }\n return [value];\n}\n\nexport function anyAt(value: unknown, ...path: string[]): unknown {\n let current: unknown = value;\n for (const key of path) {\n if (!isPlainObject(current)) {\n return undefined;\n }\n current = current[key];\n }\n return current;\n}\n\nexport function intAt(value: unknown, ...path: string[]): number {\n const found = anyAt(value, ...path);\n return typeof found === \"number\" ? Math.trunc(found) : 0;\n}\n\nexport function firstAny(...values: unknown[]): unknown {\n for (const value of values) {\n if (value !== undefined && value !== null) {\n return value;\n }\n }\n return undefined;\n}\n\nexport function firstString(...values: string[]): string {\n for (const value of values) {\n if (value) {\n return value.trim();\n }\n }\n return \"\";\n}\n\nexport function put(\n target: Record<string, unknown>,\n key: string,\n value: unknown,\n): void {\n if (value === undefined || value === null) {\n return;\n }\n target[key] = value;\n}\n\nexport function parseJSONOrString(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return value;\n }\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return value;\n }\n}\n\nexport function cloneMap(value: Record<string, unknown>): Record<string, unknown> {\n return { ...value };\n}\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport { isPlainObject, sliceAt, stringAt } from \"../protocol/json-util.js\";\nimport type {\n AnonymousDecision,\n ModelMetadata,\n TierMap,\n} from \"./catalog-types.js\";\n\n// The endpoints the discovery reads.\nexport const CAPABILITIES_URL = \"https://models.opencode.ai/api.json\";\n\nexport const ZEN_DOCS_URL =\n \"https://raw.githubusercontent.com/anomalyco/opencode/dev/packages/web/src/content/docs/zen.mdx\";\n\nexport const GO_DOCS_URL =\n \"https://raw.githubusercontent.com/anomalyco/opencode/dev/packages/web/src/content/docs/go.mdx\";\n\n// The body limits the discovery reads enforce.\nconst CAPABILITIES_BODY_LIMIT = 64 * 1024 * 1024;\nconst MODELS_BODY_LIMIT = 8 * 1024 * 1024;\nconst DOCS_BODY_LIMIT = 8 * 1024 * 1024;\n\n// The row of a documentation endpoint table, \"| name | `model-id` | `.../v1/<endpoint>` |\".\nconst DOC_ENDPOINT_PATTERN =\n /\\|[^|]+\\|\\s*`?([^|`\\s]+)`?\\s*\\|\\s*`[^`]+\\/v1\\/(chat\\/completions|responses|messages|systemone)`/;\n\n// Capabilities is the per-tier result of a capability fetch: the native protocol of every\n// model, the models whose SDK maps to no supported protocol, and the metadata of every\n// listed model.\nexport interface Capabilities {\n protocols: TierMap<Record<string, Protocol>>;\n unsupported: TierMap<Record<string, boolean>>;\n metadata: TierMap<Record<string, ModelMetadata>>;\n}\n\n// emptyCapabilities builds a capability set with empty maps on every tier.\nexport function emptyCapabilities(): Capabilities {\n return {\n protocols: { zen: {}, go: {} },\n unsupported: { zen: {}, go: {} },\n metadata: { zen: {}, go: {} },\n };\n}\n\n// capabilityTier maps a catalog provider to a tier by its ID and API URL: an\n// opencode-go provider or a /go/ URL is Go, any other OpenCode provider or a\n// /zen/ URL is Zen, and every other provider is skipped.\nexport function capabilityTier(\n providerID: string,\n api: string,\n): Tier | undefined {\n const value = `${providerID} ${api}`.trim().toLowerCase();\n if (value.includes(\"opencode-go\") || value.includes(\"/go/\")) {\n return \"go\";\n }\n if (value.includes(\"opencode\") || value.includes(\"/zen/\")) {\n return \"zen\";\n }\n return undefined;\n}\n\n// protocolForSDK maps the AI SDK package a model is served through to its wire\n// protocol. It reports undefined for a package the gateway cannot speak.\nexport function protocolForSDK(npm: string): Protocol | undefined {\n const value = npm.trim().toLowerCase();\n if (value.includes(\"anthropic\")) {\n return \"anthropic\";\n }\n if (value === \"@ai-sdk/openai\" || value.endsWith(\"/openai\")) {\n return \"responses\";\n }\n if (value.includes(\"openai-compatible\")) {\n return \"chat\";\n }\n return undefined;\n}\n\n// parseCapabilities reads the capability catalog into the per-tier maps.\nexport function parseCapabilities(body: string): Capabilities {\n const result = emptyCapabilities();\n let providers: unknown;\n try {\n providers = JSON.parse(body) as unknown;\n } catch {\n throw new Error(\"OpenCode capability endpoint returned invalid JSON\");\n }\n if (!isPlainObject(providers)) {\n throw new Error(\"OpenCode capability endpoint returned invalid JSON\");\n }\n for (const [providerID, rawProvider] of Object.entries(providers)) {\n const provider = isPlainObject(rawProvider) ? rawProvider : {};\n const tier = capabilityTier(providerID, stringAt(provider, \"api\"));\n if (tier === undefined) {\n continue;\n }\n const models = provider[\"models\"];\n if (!isPlainObject(models)) {\n continue;\n }\n for (const [mapKey, rawModel] of Object.entries(models)) {\n const model = isPlainObject(rawModel) ? rawModel : {};\n const modelID = stringAt(model, \"id\") !== \"\" ? stringAt(model, \"id\") : mapKey;\n let npm = stringAt(provider, \"npm\");\n const modelProvider = model[\"provider\"];\n if (isPlainObject(modelProvider) && stringAt(modelProvider, \"npm\") !== \"\") {\n npm = stringAt(modelProvider, \"npm\");\n }\n const protocol = protocolForSDK(npm);\n if (protocol === undefined) {\n result.unsupported[tier][modelID] = true;\n } else {\n result.protocols[tier][modelID] = protocol;\n }\n result.metadata[tier][modelID] = parseMetadata(model);\n }\n }\n return result;\n}\n\n// parseMetadata reads the capability fields of one model.\nfunction parseMetadata(model: Record<string, unknown>): ModelMetadata {\n const limit = model[\"limit\"];\n const modalities = model[\"modalities\"];\n const parsed: ModelMetadata = {\n contextWindow: 0,\n maxInput: 0,\n maxOutput: 0,\n reasoning: model[\"reasoning\"] === true,\n toolCall: model[\"tool_call\"] === true,\n structuredOutput: model[\"structured_output\"] === true,\n inputModalities: [],\n outputModalities: [],\n };\n if (isPlainObject(limit)) {\n parsed.contextWindow = intOrZero(limit[\"context\"]);\n parsed.maxInput = intOrZero(limit[\"input\"]);\n parsed.maxOutput = intOrZero(limit[\"output\"]);\n }\n if (isPlainObject(modalities)) {\n parsed.inputModalities = stringList(modalities[\"input\"]);\n parsed.outputModalities = stringList(modalities[\"output\"]);\n }\n return parsed;\n}\n\n// parseProtocolDocs parses the endpoint table of a documentation page into a\n// model-to-protocol map, deriving the protocol from the endpoint path of each\n// row. It fails when no row matches.\nexport function parseProtocolDocs(body: string): Record<string, Protocol> {\n const result: Record<string, Protocol> = {};\n for (const line of body.split(\"\\n\")) {\n const match = DOC_ENDPOINT_PATTERN.exec(line);\n if (match === null) {\n continue;\n }\n const modelID = (match[1] ?? \"\").trim();\n if (modelID === \"\" || /[ `|]/.test(modelID)) {\n continue;\n }\n const protocol = docEndpointProtocol(match[2] ?? \"\");\n if (protocol !== undefined) {\n result[modelID] = protocol;\n }\n }\n if (Object.keys(result).length === 0) {\n throw new Error(\"OpenCode endpoint documentation returned no protocol rows\");\n }\n return result;\n}\n\n// docEndpointProtocol maps a documentation endpoint path onto its protocol.\nfunction docEndpointProtocol(endpoint: string): Protocol | undefined {\n switch (endpoint) {\n case \"chat/completions\":\n return \"chat\";\n case \"responses\":\n return \"responses\";\n case \"messages\":\n return \"anthropic\";\n case \"systemone\":\n return \"systemone\";\n default:\n return undefined;\n }\n}\n\n// parseModels reads a /v1/models listing into the model ids it advertises.\n// An empty list is an error.\nexport function parseModels(body: string): string[] {\n let payload: unknown;\n try {\n payload = JSON.parse(body) as unknown;\n } catch {\n throw new Error(\"models endpoint returned invalid JSON\");\n }\n const models: string[] = [];\n for (const raw of sliceAt(payload, \"data\")) {\n const id = stringAt(raw, \"id\");\n if (id !== \"\") {\n models.push(id);\n }\n }\n if (models.length === 0) {\n throw new Error(\"models endpoint returned an empty list\");\n }\n return models;\n}\n\n// capabilitiesBodyLimit is the body limit the capability read enforces.\nexport { CAPABILITIES_BODY_LIMIT, MODELS_BODY_LIMIT, DOCS_BODY_LIMIT };\n\nconst EXTRA_FREE_MODELS = new Set([\n \"big-pickle\",\n \"stealth/crouton-alpha\",\n \"stealth/glyph-cluster\",\n \"auto\",\n \"main\",\n \"fast\",\n \"deep\",\n \"code\",\n \"vision\",\n \"vl\",\n]);\n\n// isFreeModel is the name rule: a model whose ID contains \"free\" in any case\n// or belongs to the known keyless free model set.\nexport function isFreeModel(model: string): boolean {\n const lower = model.trim().toLowerCase();\n return lower.includes(\"free\") || EXTRA_FREE_MODELS.has(lower);\n}\n\n// nameDecision is the free-model decision taken from the name alone, used\n// before the pricing metadata is available.\nexport function nameDecision(model: string): AnonymousDecision {\n return {\n allowed: isFreeModel(model),\n source: \"name_fallback_metadata_pending\",\n };\n}\n\nfunction intOrZero(value: unknown): number {\n return typeof value === \"number\" ? Math.trunc(value) : 0;\n}\n\nfunction stringList(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.filter((item): item is string => typeof item === \"string\");\n}\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport type { Route } from \"../types/inference.js\";\nimport type {\n AnonymousDecision,\n ModelMetadata,\n TierMap,\n} from \"./catalog-types.js\";\n\n// CatalogOptions are the settings the catalog needs to route.\nexport interface CatalogOptions {\n prefer: Tier;\n protocols: Record<string, string>;\n freeOnly: boolean;\n}\n\n// CatalogState is the discovered model data the catalog routes on.\nexport interface CatalogState {\n zen: Record<string, boolean>;\n go: Record<string, boolean>;\n nativeProtocols: TierMap<Record<string, Protocol>>;\n unsupported: TierMap<Record<string, boolean>>;\n metadata: TierMap<Record<string, ModelMetadata>>;\n disabled: Set<string>;\n updatedAt: number;\n cacheSource: \"none\" | \"live\" | \"disk\";\n refreshAfter: number;\n}\n\n// emptyCatalogState builds a state with no discovered model.\nexport function emptyCatalogState(): CatalogState {\n return {\n zen: {},\n go: {},\n nativeProtocols: { zen: {}, go: {} },\n unsupported: { zen: {}, go: {} },\n metadata: { zen: {}, go: {} },\n disabled: new Set<string>(),\n updatedAt: 0,\n cacheSource: \"none\",\n refreshAfter: 300,\n };\n}\n\n// tierModels returns the models a tier advertises.\nexport function tierModels(\n state: CatalogState,\n tier: Tier,\n): string[] {\n const source = tier === \"go\" ? state.go : state.zen;\n return Object.keys(source)\n .filter((model) => source[model] === true)\n .sort();\n}\n\n// modelIDs returns the sorted union of the models both tiers advertise.\nexport function modelIDs(state: CatalogState): string[] {\n return [\n ...new Set([...tierModels(state, \"zen\"), ...tierModels(state, \"go\")]),\n ].sort();\n}\n\n// isPending reports whether the catalog has not been filled yet. While it is\n// pending every model is supported, so a temporary discovery failure does not\n// take the gateway offline.\nexport function isPending(state: CatalogState): boolean {\n return Object.keys(state.zen).length === 0 && Object.keys(state.go).length === 0;\n}\n\n// tierSupported reports whether a tier can carry a model's protocol. A\n// configured override always can; otherwise the tier's capability data\n// decides, and a model it does not know is accepted only while the catalog\n// is pending.\nexport function tierSupported(\n state: CatalogState,\n options: CatalogOptions,\n model: string,\n tier: Tier,\n): boolean {\n if (options.protocols[model] !== undefined) {\n return true;\n }\n if (state.unsupported[tier][model] === true) {\n return false;\n }\n if (state.nativeProtocols[tier][model] !== undefined) {\n return true;\n }\n return isPending(state);\n}\n\n// protocolFor resolves the protocol of a model on a tier: the configured\n// override first, then the tier's capability data, then Chat.\nexport function protocolFor(\n state: CatalogState,\n options: CatalogOptions,\n model: string,\n tier: Tier,\n): Protocol {\n const configured = options.protocols[model];\n if (configured !== undefined && configured !== \"\") {\n return configured as Protocol;\n }\n const native = state.nativeProtocols[tier][model];\n if (native !== undefined) {\n return native;\n }\n return \"chat\";\n}\n\n// protocolsFor resolves the protocol of every tier in keyTiers, plus Zen\n// when includeZen is set for an anonymous route.\nexport function protocolsFor(\n state: CatalogState,\n options: CatalogOptions,\n model: string,\n keyTiers: Tier[],\n includeZen: boolean,\n): TierMap<Protocol> {\n const protocols: TierMap<Protocol> = { zen: \"chat\", go: \"chat\" };\n if (includeZen) {\n protocols.zen = protocolFor(state, options, model, \"zen\");\n }\n for (const tier of keyTiers) {\n protocols[tier] = protocolFor(state, options, model, tier);\n }\n return protocols;\n}\n\n// keyTierOrder builds an authenticated route in prefer order. A tier is\n// included only when it has a key, advertises the model, and can carry its\n// protocol.\nexport function keyTierOrder(\n state: CatalogState,\n options: CatalogOptions,\n model: string,\n hasZenKeys: boolean,\n hasGoKeys: boolean,\n): Tier[] {\n const pending = isPending(state);\n const order: Tier[] =\n options.prefer === \"go\" ? [\"go\", \"zen\"] : [\"zen\", \"go\"];\n const result: Tier[] = [];\n for (const tier of order) {\n const hasKeys = tier === \"go\" ? hasGoKeys : hasZenKeys;\n if (!hasKeys) {\n continue;\n }\n const advertised = tier === \"go\" ? state.go[model] : state.zen[model];\n if (!pending && advertised !== true) {\n continue;\n }\n if (!tierSupported(state, options, model, tier)) {\n continue;\n }\n result.push(tier);\n }\n return result;\n}\n\n// supported reports whether some tier advertises a model with a usable\n// protocol. Every model is supported while the catalog is still pending.\nexport function supported(\n state: CatalogState,\n options: CatalogOptions,\n model: string,\n): boolean {\n if (isPending(state)) {\n return true;\n }\n if (state.zen[model] === true && tierSupported(state, options, model, \"zen\")) {\n return true;\n }\n if (state.go[model] === true && tierSupported(state, options, model, \"go\")) {\n return true;\n }\n return false;\n}\n\n// emptyMetadata builds the zero metadata of a model neither source describes.\nexport function emptyMetadata(): ModelMetadata {\n return {\n contextWindow: 0,\n maxInput: 0,\n maxOutput: 0,\n reasoning: false,\n toolCall: false,\n structuredOutput: false,\n inputModalities: [],\n outputModalities: [],\n };\n}\n\nexport type { AnonymousDecision, ModelMetadata, TierMap, Route };\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport type { Route } from \"../types/inference.js\";\nimport {\n emptyCapabilities,\n isFreeModel,\n nameDecision,\n parseCapabilities,\n parseModels,\n parseProtocolDocs,\n type Capabilities,\n} from \"./model-discovery.js\";\nimport {\n emptyCatalogState,\n emptyMetadata,\n isPending,\n keyTierOrder,\n modelIDs,\n protocolFor,\n protocolsFor,\n supported,\n tierModels,\n tierSupported,\n type CatalogOptions,\n type CatalogState,\n} from \"./catalog-state.js\";\nimport type {\n AnonymousDecision,\n CatalogSnapshot,\n ModelMetadata,\n RouteDiagnostic,\n TierMap,\n} from \"./catalog-types.js\";\n\n// ModelCatalog holds the discovered models and plans how each one is served.\nexport class ModelCatalog {\n private readonly state: CatalogState = emptyCatalogState();\n private options: CatalogOptions;\n\n constructor(options: CatalogOptions) {\n this.options = options;\n }\n\n // setOptions replaces the routing options, so a configuration change takes\n // effect on the next request.\n setOptions(options: CatalogOptions): void {\n this.options = options;\n }\n\n // isEmpty reports whether no model has been discovered yet.\n isEmpty(): boolean {\n return isPending(this.state);\n }\n\n // isPending reports whether the catalog has not been filled yet.\n isPending(): boolean {\n return isPending(this.state);\n }\n\n // tierModels returns the models a tier advertises.\n tierModels(tier: Tier): string[] {\n return tierModels(this.state, tier);\n }\n\n // modelIDs returns the sorted union of the models both tiers advertise.\n modelIDs(): string[] {\n return modelIDs(this.state);\n }\n\n // list returns the sorted ids of the advertised models that have a usable\n // protocol on a tier advertising them. It ignores credentials, availability\n // and models.free_only.\n list(): string[] {\n return this.modelIDs().filter((model) => this.supported(model));\n }\n\n // supported reports whether some tier advertises a model with a usable\n // protocol.\n supported(model: string): boolean {\n return supported(this.state, this.options, model);\n }\n\n // route plans how a model is served given which credentials exist. A free\n // model can start on the anonymous lane when the anonymous lane is enabled;\n // otherwise, and as the fallback, the key tiers are tried in prefer order.\n route(\n model: string,\n hasZenKeys: boolean,\n hasGoKeys: boolean,\n hasAnonymous: boolean,\n ): Route {\n if (this.state.disabled.has(model)) {\n throw new Error(\n `model ${JSON.stringify(model)} is disabled after a failed availability check; restore it in the WebUI or wait for the next probe`,\n );\n }\n this.checkFreeOnly(model);\n const keyTiers = keyTierOrder(\n this.state,\n this.options,\n model,\n hasZenKeys,\n hasGoKeys,\n );\n // OpenCode's public credential belongs to the Zen tier. Every free model\n // starts there unless the Zen capability data marks it unsupported, even if\n // the current catalog only advertises it on Go: an upstream rejection will\n // move the request into the authenticated fallback plan.\n const decision = this.anonymousDecision(model);\n const advertised =\n this.state.zen[model] === true || this.state.go[model] === true;\n if (\n hasAnonymous &&\n decision.allowed &&\n (this.options.protocols[model] !== undefined ||\n this.state.unsupported.zen[model] !== true) &&\n (isPending(this.state) || advertised)\n ) {\n const protocols = protocolsFor(\n this.state,\n this.options,\n model,\n keyTiers,\n true,\n );\n return {\n id: model,\n tier: \"zen\",\n protocol: protocols.zen,\n protocols,\n anonymous: true,\n keyTiers,\n };\n }\n if (keyTiers.length > 0) {\n const tier = keyTiers[0] as Tier;\n const protocols = protocolsFor(\n this.state,\n this.options,\n model,\n keyTiers,\n false,\n );\n return {\n id: model,\n tier,\n protocol: protocols[tier],\n protocols,\n anonymous: false,\n keyTiers,\n };\n }\n throw new Error(\n `model ${JSON.stringify(model)} is not available in the configured Zen or Go pools`,\n );\n }\n\n // routeForTier builds a route pinned to one tier, used by the Playground's\n // per-key diagnostics. It never selects the anonymous lane and never adds a\n // fallback tier.\n routeForTier(\n model: string,\n tier: Tier,\n hasZenKeys: boolean,\n hasGoKeys: boolean,\n ): Route {\n const hasKeys = tier === \"go\" ? hasGoKeys : hasZenKeys;\n if (!hasKeys) {\n throw new Error(`no ${tier} key is configured`);\n }\n if (this.state.disabled.has(model)) {\n throw new Error(\n `model ${JSON.stringify(model)} is disabled after a failed availability check`,\n );\n }\n this.checkFreeOnly(model);\n const advertised =\n tier === \"go\" ? this.state.go[model] : this.state.zen[model];\n if (!isPending(this.state) && advertised !== true) {\n throw new Error(\n `model ${JSON.stringify(model)} is not available in the selected ${tier} key tier`,\n );\n }\n if (!tierSupported(this.state, this.options, model, tier)) {\n throw new Error(\n `model ${JSON.stringify(model)} uses an upstream protocol that is not available on the selected ${tier} key tier`,\n );\n }\n const protocol = protocolFor(this.state, this.options, model, tier);\n return {\n id: model,\n tier,\n protocol,\n protocols: {\n zen: tier === \"zen\" ? protocol : \"chat\",\n go: tier === \"go\" ? protocol : \"chat\",\n },\n anonymous: false,\n keyTiers: [tier],\n };\n }\n\n // diagnostic explains the protocol choice and the route of a model. It never\n // fails: a routing error is reported in routeError.\n diagnostic(\n model: string,\n requested: Protocol,\n hasZenKeys: boolean,\n hasGoKeys: boolean,\n hasAnonymous: boolean,\n ): RouteDiagnostic {\n const configured = this.options.protocols[model];\n const explicit = configured !== undefined && configured !== \"\";\n const zenKnown = this.state.nativeProtocols.zen[model] !== undefined;\n const goKnown = this.state.nativeProtocols.go[model] !== undefined;\n const nativeProtocols: TierMap<Protocol> = {\n zen: protocolFor(this.state, this.options, model, \"zen\"),\n go: protocolFor(this.state, this.options, model, \"go\"),\n };\n let source: RouteDiagnostic[\"protocolSource\"] = \"configured\";\n if (!explicit) {\n source = zenKnown || goKnown ? \"upstream\" : \"default\";\n }\n let protocol = explicit ? (configured as Protocol) : nativeProtocols.zen;\n if (!explicit && this.options.prefer === \"go\") {\n protocol = nativeProtocols.go;\n }\n const diagnostic: RouteDiagnostic = {\n model,\n requestedProtocol: requested,\n nativeProtocol: protocol,\n nativeProtocols,\n protocolSource: source,\n availableZen: this.state.zen[model] === true,\n availableGo: this.state.go[model] === true,\n tier: \"\",\n anonymous: false,\n keyTiers: [],\n anonymousEligibility: this.anonymousDecision(model),\n routeError: \"\",\n };\n try {\n const route = this.route(model, hasZenKeys, hasGoKeys, hasAnonymous);\n diagnostic.nativeProtocol = route.protocol;\n diagnostic.nativeProtocols = route.protocols;\n diagnostic.tier = route.tier;\n diagnostic.anonymous = route.anonymous;\n diagnostic.keyTiers = [...route.keyTiers];\n } catch (error) {\n diagnostic.routeError = error instanceof Error ? error.message : String(error);\n }\n return diagnostic;\n }\n\n // availableModels provides discovery and readiness with the same route\n // filtering, including configured key tiers and anonymous eligibility.\n availableModels(\n hasZenKeys: boolean,\n hasGoKeys: boolean,\n hasAnonymous: boolean,\n ): { routes: Route[]; snapshot: CatalogSnapshot } {\n const routes: Route[] = [];\n for (const model of this.modelIDs()) {\n if (!this.supported(model)) {\n continue;\n }\n try {\n routes.push(this.route(model, hasZenKeys, hasGoKeys, hasAnonymous));\n } catch {\n // A model that cannot be routed is not exposed.\n }\n }\n const snapshot = this.snapshot();\n snapshot.exposed = routes.length;\n return { routes, snapshot };\n }\n\n // snapshot summarizes the catalog without route filtering.\n snapshot(): CatalogSnapshot {\n const ids = this.modelIDs();\n let exposed = 0;\n for (const model of ids) {\n if (this.supported(model)) {\n exposed += 1;\n }\n }\n let stale = this.state.cacheSource === \"disk\";\n if (this.state.updatedAt > 0 && this.state.refreshAfter > 0) {\n const limit = Math.max(2 * this.state.refreshAfter, 60);\n stale = stale || Date.now() - this.state.updatedAt > limit * 1000;\n }\n return {\n zen: Object.keys(this.state.zen).length,\n go: Object.keys(this.state.go).length,\n total: ids.length,\n exposed,\n updatedAt: this.state.updatedAt,\n cacheSource: this.state.cacheSource,\n stale,\n };\n }\n\n // metadataForTier returns the rich per-model metadata for the tier that\n // will actually serve the request.\n metadataForTier(model: string, tier: Tier): ModelMetadata {\n return this.state.metadata[tier][model] ?? emptyMetadata();\n }\n\n // anonymousDecision reports whether a model may be served on the anonymous\n // lane.\n anonymousDecision(model: string): AnonymousDecision {\n return nameDecision(model);\n }\n\n // isFree reports whether the catalog considers the model free-tier.\n isFree(model: string): boolean {\n return this.anonymousDecision(model).allowed;\n }\n\n // setDisabled marks a model as unavailable after a failed availability check.\n setDisabled(model: string, disabled: boolean): void {\n if (disabled) {\n this.state.disabled.add(model);\n } else {\n this.state.disabled.delete(model);\n }\n }\n\n // disabledModels lists the models a failed availability check disabled.\n disabledModels(): string[] {\n return [...this.state.disabled].sort();\n }\n\n // applyTier replaces the models a tier advertises.\n applyTier(tier: Tier, models: string[]): void {\n const target: Record<string, boolean> = {};\n for (const model of models) {\n target[model] = true;\n }\n if (tier === \"go\") {\n this.state.go = target;\n } else {\n this.state.zen = target;\n }\n }\n\n // applyCapabilities replaces the capability data of both tiers.\n applyCapabilities(capabilities: Capabilities): void {\n this.state.nativeProtocols = {\n zen: { ...capabilities.protocols.zen },\n go: { ...capabilities.protocols.go },\n };\n this.state.unsupported = {\n zen: { ...capabilities.unsupported.zen },\n go: { ...capabilities.unsupported.go },\n };\n this.state.metadata = {\n zen: { ...capabilities.metadata.zen },\n go: { ...capabilities.metadata.go },\n };\n }\n\n // markLive records that the catalog was filled from the live endpoints.\n markLive(refreshAfter: number): void {\n this.state.updatedAt = Date.now();\n this.state.cacheSource = \"live\";\n this.state.refreshAfter = refreshAfter;\n }\n\n // markDisk records that the catalog was loaded from the cache file.\n markDisk(refreshAfter: number): void {\n this.state.cacheSource = \"disk\";\n this.state.refreshAfter = refreshAfter;\n }\n\n // checkFreeOnly rejects a model that is not free when free_only is enabled.\n private checkFreeOnly(model: string): void {\n if (!this.options.freeOnly) {\n return;\n }\n if (!this.isFree(model)) {\n throw new Error(\n `model ${JSON.stringify(model)} is not free and models.free_only is enabled`,\n );\n }\n }\n}\n\nexport {\n emptyCapabilities,\n isFreeModel,\n nameDecision,\n parseCapabilities,\n parseModels,\n parseProtocolDocs,\n};\nexport type {\n AnonymousDecision,\n CatalogOptions,\n CatalogSnapshot,\n ModelMetadata,\n RouteDiagnostic,\n TierMap,\n};\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport { V1_BASE } from \"../config/defaults.js\";\nimport { protocolPath } from \"./paths.js\";\n\n// The user agents the upstream gates fingerprint. The v1 lane reports the AI\n// SDK package that serves the protocol, the v2 lane reports the CLI.\nexport const V2_USER_AGENT = \"opencode/latest/2.2.5/cli\";\n\nexport const V1_RESPONSES_SDK = \"4.0.40\";\nexport const V1_ANTHROPIC_SDK = \"4.0.46\";\nexport const V1_CHAT_SDK = \"4.0.23\";\n\n// isV1Upstream reports whether a base URL is the v1 lane. The v1 lane serves\n// the OpenCode 1.x request shape, so its headers and body gates differ from\n// the v2 lane's.\nexport function isV1Upstream(baseURL: string): boolean {\n const normalized = baseURL.trim().toLowerCase().replace(/\\/+$/, \"\");\n return normalized === V1_BASE || normalized.endsWith(\"/zen\");\n}\n\n// v1ProviderUtils names the provider-utils version of the AI SDK package the\n// OpenCode 1.x client routes a protocol through. System One has no v1\n// counterpart and reports the chat package.\nexport function v1ProviderUtils(protocol: Protocol): string {\n switch (protocol) {\n case \"responses\":\n return V1_RESPONSES_SDK;\n case \"anthropic\":\n return V1_ANTHROPIC_SDK;\n default:\n return V1_CHAT_SDK;\n }\n}\n\n// v1UserAgent renders the v1 lane's model user agent.\nexport function v1UserAgent(providerUtils: string): string {\n return `opencode/1.19.3 ai-sdk/provider-utils/${providerUtils} runtime/bun/1.3.14`;\n}\n\n// tierBaseURL returns the base URL of a key tier.\nexport function tierBaseURL(\n upstream: { zen: string; go: string; anonymous: string },\n tier: Tier,\n): string {\n return tier === \"go\" ? upstream.go : upstream.zen;\n}\n\n// upstreamURL builds the URL of an upstream endpoint.\nexport function upstreamURL(baseURL: string, protocol: Protocol): string {\n const trimmed = baseURL.replace(/\\/+$/, \"\");\n if (trimmed.toLowerCase().endsWith(\"/inference\")) {\n const family = protocol === \"anthropic\" ? \"/anthropic\" : \"/openai\";\n return `${trimmed}${family}${protocolPath(protocol)}`;\n }\n return trimmed + protocolPath(protocol);\n}\n", "import type { Protocol } from \"../types/config.js\";\n\n// protocolPath returns the endpoint path that serves a protocol, relative to\n// an API base. The gateway's own routes and the upstream endpoints share these\n// paths. An unknown protocol gets the Chat path.\nexport function protocolPath(protocol: Protocol): string {\n switch (protocol) {\n case \"responses\":\n return \"/v1/responses\";\n case \"anthropic\":\n return \"/v1/messages\";\n case \"systemone\":\n return \"/v1/systemone\";\n default:\n return \"/v1/chat/completions\";\n }\n}\n\n// isValidProtocol reports whether the protocol is one the gateway serves.\nexport function isValidProtocol(protocol: string): protocol is Protocol {\n return (\n protocol === \"chat\" ||\n protocol === \"responses\" ||\n protocol === \"anthropic\" ||\n protocol === \"systemone\"\n );\n}\n", "import { randomBytes, sha256Bytes, toHex } from \"./sha256.js\";\n\nconst BASE62 = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nconst CANONICAL_SESSION_PATTERN = /^ses_[0-9a-f]{12}[0-9A-Za-z]{14}$/;\nconst DESCENDING_TIME_PART_PATTERN = /^[0-9a-f]{9}f[c-f][0-9a-f]$/;\nconst CLAUDE_CODE_SESSION_PATTERN = /_session_([0-9A-Fa-f-]{36})$/;\n\nexport interface RequestIDs {\n session: string;\n request: string;\n message: string;\n project: string;\n parentSession: string;\n}\n\nexport function isOfficialSessionID(signal: string): boolean {\n return (\n CANONICAL_SESSION_PATTERN.test(signal) &&\n DESCENDING_TIME_PART_PATTERN.test(signal.slice(4, 16))\n );\n}\n\nexport function canonicalSessionID(signal: string): string {\n if (isOfficialSessionID(signal)) {\n return signal;\n }\n const sum = sha256Bytes(`ses\\x00${signal}`);\n const timePart = descendingTimePart(sum.subarray(0, 6));\n const randomPart = base62Fixed(sum.subarray(6, 16), 14);\n return `ses_${timePart}${randomPart}`;\n}\n\nfunction descendingTimePart(hash: Uint8Array): string {\n const current =\n ((BigInt(hash[0] ?? 0) << 28n) |\n (BigInt(hash[1] ?? 0) << 20n) |\n (BigInt(hash[2] ?? 0) << 12n) |\n (BigInt(hash[3] ?? 0) << 4n) |\n (BigInt(hash[4] ?? 0) >> 4n)) <<\n 12n;\n const withCounter = current | 1n;\n const inverted = ~withCounter & 0xffffffffffffn;\n return inverted.toString(16).padStart(12, \"0\");\n}\n\nfunction base62Fixed(bytes: Uint8Array, width: number): string {\n let value = 0n;\n for (const byte of bytes) {\n value = (value << 8n) | BigInt(byte);\n }\n const base = 62n;\n const out = new Array<string>(width);\n for (let i = width - 1; i >= 0; i--) {\n const remainder = value % base;\n value /= base;\n out[i] = BASE62[Number(remainder)] ?? \"0\";\n }\n return out.join(\"\");\n}\n\nfunction randomBase62(length: number): string {\n const bytes = randomBytes(length);\n let out = \"\";\n for (const byte of bytes) {\n out += BASE62[byte % 62];\n }\n return out;\n}\n\nlet ascendingLast = 0n;\nlet ascendingCounter = 0n;\n\nexport function ascendingID(prefix: string, now: number = Date.now()): string {\n const ms = BigInt(now);\n if (ms !== ascendingLast) {\n ascendingLast = ms;\n ascendingCounter = 0n;\n }\n ascendingCounter += 1n;\n // The id carries the low 48 bits of the timestamp and the counter.\n const value = BigInt.asUintN(48, (ms << 12n) | ascendingCounter);\n const timePart = value.toString(16).padStart(12, \"0\");\n return `${prefix}_${timePart}${randomBase62(14)}`;\n}\n\n// mintFreshSessionID formats an OpenCode v2.2.5 session identifier\n// (ses_<12-hex-inv-ts><14-base62>) encoding ~((now_ms << 12) | seq) & 0xffffffffffff.\nexport function mintFreshSessionID(now: number = Date.now()): string {\n const ms = BigInt(now);\n if (ms !== ascendingLast) {\n ascendingLast = ms;\n ascendingCounter = 0n;\n }\n ascendingCounter = (ascendingCounter + 1n) & 0xfffn;\n if (ascendingCounter === 0n) {\n ascendingCounter = 1n;\n }\n const raw = (ms << 12n) | ascendingCounter;\n const inverted = ~raw & 0xffffffffffffn;\n const timePart = inverted.toString(16).padStart(12, \"0\");\n return `ses_${timePart}${randomBase62(14)}`;\n}\n\nexport function randomID(prefix: string, size: number): string {\n return `${prefix}_${toHex(randomBytes(size))}`;\n}\n\n// asPrefix returns the id in the target protocol's ID style, prefix plus \"_\".\n// An id that already has that prefix is returned unchanged; otherwise any\n// \"chatcmpl_\", \"resp_\" or \"msg_\" prefix is stripped first, so one upstream ID\n// maps consistently onto every protocol.\nexport function asPrefix(id: string, prefix: string): string {\n if (id.startsWith(`${prefix}_`)) {\n return id;\n }\n let trimmed = id;\n for (const current of [\"chatcmpl_\", \"resp_\", \"msg_\"]) {\n if (trimmed.startsWith(current)) {\n trimmed = trimmed.slice(current.length);\n }\n }\n return `${prefix}_${trimmed}`;\n}\n\nexport function claudeCodeSessionID(userId: string): string {\n if (!userId) {\n return \"\";\n }\n const match = CLAUDE_CODE_SESSION_PATTERN.exec(userId);\n if (match?.[1]) {\n return match[1];\n }\n try {\n const value: unknown = JSON.parse(userId);\n if (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as Record<string, unknown>).session_id === \"string\"\n ) {\n return (value as Record<string, unknown>).session_id as string;\n }\n } catch {\n // Not a JSON user id.\n }\n return \"\";\n}\n\nexport function scopedSessionID(scope: string, signal: string): string {\n if (isOfficialSessionID(signal)) {\n return signal;\n }\n const seeded = scope ? `${scope}\\x00${signal}` : signal;\n return canonicalSessionID(seeded);\n}\n", "import { isPlainObject, mapAt, sliceAt, stringAt } from \"./json-util.js\";\n\n// The server tool types of a Messages body and the beta flag the AI SDK\n// anthropic provider sends with each.\nconst TOOL_BETAS: Record<string, string> = {\n code_execution_20250522: \"code-execution-2025-05-22\",\n code_execution_20250825: \"code-execution-2025-08-25\",\n computer_20241022: \"computer-use-2024-10-22\",\n computer_20250124: \"computer-use-2025-01-24\",\n computer_20251124: \"computer-use-2025-11-24\",\n text_editor_20241022: \"computer-use-2024-10-22\",\n text_editor_20250124: \"computer-use-2025-01-24\",\n text_editor_20250429: \"computer-use-2025-01-24\",\n bash_20241022: \"computer-use-2024-10-22\",\n bash_20250124: \"computer-use-2025-01-24\",\n memory_20250818: \"context-management-2025-06-27\",\n web_fetch_20250910: \"web-fetch-2025-09-10\",\n web_fetch_20260209: \"code-execution-web-tools-2026-02-09\",\n web_search_20260209: \"code-execution-web-tools-2026-02-09\",\n advisor_20260301: \"advisor-tool-2026-03-01\",\n};\n\n// The Claude model families older than Claude 4 that the AI SDK treats as\n// lacking structured output.\nconst CLAUDE_3_OR_OLDER =\n /claude-(?:instant(?:-|$)|v?2(?:$|[-.:])|3(?:$|[-.]))/;\n\n// The Claude models the AI SDK treats as supporting structured output.\nconst STRUCTURED_OUTPUT_MODELS = [\n \"claude-opus-5\",\n \"claude-opus-4-8\",\n \"claude-opus-4-7\",\n \"claude-fable-5\",\n \"claude-sonnet-5\",\n \"claude-sonnet-4-6\",\n \"claude-opus-4-6\",\n \"claude-sonnet-4-5\",\n \"claude-opus-4-5\",\n \"claude-haiku-4-5\",\n \"claude-sonnet-4-1\",\n];\n\n// v1AnthropicBetas returns the anthropic-beta value the v1 lane sends with a\n// Messages body, or \"\" when no flag applies. The AI SDK derives the flags\n// from the request features \u2014 body features first, then tools, in the SDK's\n// order \u2014 and the opencode provider sets no fixed betas of its own.\nexport function v1AnthropicBetas(body: string): string {\n let payload: unknown;\n try {\n payload = JSON.parse(body) as unknown;\n } catch {\n return \"\";\n }\n if (!isPlainObject(payload)) {\n return \"\";\n }\n const betas: string[] = [];\n const add = (beta: string): void => {\n if (!betas.includes(beta)) {\n betas.push(beta);\n }\n };\n\n if (sliceAt(payload, \"mcp_servers\").length > 0) {\n add(\"mcp-client-2025-04-04\");\n }\n const management = mapAt(payload, \"context_management\");\n if (Object.keys(management).length > 0) {\n add(\"context-management-2025-06-27\");\n for (const raw of sliceAt(management, \"edits\")) {\n if (stringAt(raw, \"type\") === \"compact_20260112\") {\n add(\"compact-2026-01-12\");\n }\n }\n }\n const container = payload[\"container\"];\n if (isPlainObject(container) && sliceAt(container, \"skills\").length > 0) {\n add(\"code-execution-2025-08-25\");\n add(\"skills-2025-10-02\");\n add(\"files-api-2025-04-14\");\n }\n if (isPresentJSON(mapAt(payload, \"output_config\")[\"task_budget\"])) {\n add(\"task-budgets-2026-03-13\");\n }\n if (payload[\"speed\"] === \"fast\") {\n add(\"fast-mode-2026-02-01\");\n }\n const fallbacks = payload[\"fallbacks\"];\n if (fallbacks === \"default\") {\n add(\"server-side-fallback-2026-07-01\");\n } else if (Array.isArray(fallbacks) && fallbacks.length > 0) {\n add(\"server-side-fallback-2026-06-01\");\n }\n if (isPresentJSON(mapAt(payload, \"thinking\")[\"block_binding\"])) {\n add(\"thinking-binding-controls-2026-08-01\");\n }\n const model = stringAt(payload, \"model\");\n for (const rawTool of sliceAt(payload, \"tools\")) {\n const tool = isPlainObject(rawTool) ? rawTool : {};\n const type = stringAt(tool, \"type\");\n if (type === \"\" || type === \"custom\") {\n if (anthropicSupportsStructuredOutput(model)) {\n add(\"structured-outputs-2025-11-13\");\n }\n if (\n isPresentJSON(tool[\"input_examples\"]) ||\n isPresentJSON(tool[\"allowed_callers\"])\n ) {\n add(\"advanced-tool-use-2025-11-20\");\n }\n continue;\n }\n const beta = TOOL_BETAS[type];\n if (beta !== undefined) {\n add(beta);\n }\n }\n return betas.join(\",\");\n}\n\n// isPresentJSON reports whether a raw JSON field carries a value.\nfunction isPresentJSON(value: unknown): boolean {\n return value !== undefined && value !== null;\n}\n\n// anthropicSupportsStructuredOutput mirrors the AI SDK anthropic provider's\n// model capability table: the dated Claude 4.0 releases and Claude 3 and\n// older lack structured output, every other Claude model has it, and\n// non-Claude models do not.\nexport function anthropicSupportsStructuredOutput(model: string): boolean {\n for (const supported of STRUCTURED_OUTPUT_MODELS) {\n if (model.includes(supported)) {\n return true;\n }\n }\n if (\n model.includes(\"claude-sonnet-4-\") ||\n model.includes(\"claude-opus-4-\") ||\n model.includes(\"claude-3-haiku\") ||\n CLAUDE_3_OR_OLDER.test(model)\n ) {\n return false;\n }\n return model.includes(\"claude-\");\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport { sha256Bytes, toHex } from \"./sha256.js\";\nimport type { RequestIDs } from \"./identity.js\";\nimport { canonicalSessionID } from \"./identity.js\";\nimport { v1AnthropicBetas } from \"./anthropic-betas.js\";\nimport { V2_USER_AGENT, v1ProviderUtils, v1UserAgent } from \"./lanes.js\";\n\n// The v2 lane's fixed Anthropic beta set.\nconst V2_ANTHROPIC_BETAS =\n \"interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14\";\n\nconst GIT_COMMIT = /^[0-9a-f]{40}$/;\n\n// v1ProjectID renders the project header the way the OpenCode 1.x client does:\n// the git root commit hash of the project, or \"global\" outside a git\n// repository. A genuine value from a v1 client is kept verbatim; any other\n// project is hashed into the commit shape.\nexport function v1ProjectID(project: string): string {\n if (project === \"global\" || GIT_COMMIT.test(project)) {\n return project;\n }\n return v2ProjectID(project);\n}\n\n// v2ProjectID renders the project header in the shape the OpenCode 2.x CLI\n// sends to the v2 gates: a bare 40-character lowercase hex id. The value\n// itself is not checked upstream, only its shape, but hashing keeps one\n// project mapped to one stable upstream project id.\nexport function v2ProjectID(project: string): string {\n const sum = sha256Bytes(`opencode-project\\0${project}`);\n return toHex(sum.subarray(0, 20));\n}\n\n// setV1Headers renders the v1 lane's header set, that of an OpenCode 1.19.3\n// model request on its opencode provider: the AI SDK User-Agent of the\n// package serving the protocol, both session headers, the user message id as\n// x-opencode-request, the git root commit as the project, and the canonical\n// parent session under both parent headers. The v1 client sends no\n// x-session-affinity or X-Session-Id to this provider.\nexport function setV1Headers(\n headers: Headers,\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n): void {\n headers.set(\"Accept\", \"*/*\");\n headers.set(\"User-Agent\", v1UserAgent(v1ProviderUtils(protocol)));\n headers.set(\"x-opencode-client\", \"cli\");\n headers.set(\"x-opencode-session\", ids.session);\n headers.set(\"x-opencode-session-id\", ids.session);\n headers.set(\"x-opencode-request\", ids.message);\n headers.set(\"x-opencode-project\", v1ProjectID(ids.project));\n if (ids.parentSession !== \"\") {\n const parent = canonicalSessionID(ids.parentSession);\n headers.set(\"x-opencode-parent-session-id\", parent);\n headers.set(\"x-parent-session-id\", parent);\n }\n if (protocol === \"anthropic\") {\n const betas = v1AnthropicBetas(body);\n if (betas !== \"\") {\n headers.set(\"anthropic-beta\", betas);\n }\n }\n}\n\n// setV2Headers renders the OpenCode 2.x CLI header set the v2 gates\n// fingerprint: the \"opencode/<channel>/<version>/cli\" User-Agent, every\n// session header set to the same descending-encoded id, and a bare\n// 40-character hex x-opencode-project. The v2 gate rejects x-opencode-request\n// and canonical prj_* project ids with 403 FreeTierError, so neither is sent.\nexport function setV2Headers(\n headers: Headers,\n protocol: Protocol,\n ids: RequestIDs,\n): void {\n headers.set(\"Accept\", \"application/json, text/event-stream\");\n headers.set(\"x-opencode-client\", \"cli\");\n headers.set(\"x-opencode-session\", ids.session);\n headers.set(\"x-session-affinity\", ids.session);\n headers.set(\"X-Session-Id\", ids.session);\n headers.set(\"User-Agent\", V2_USER_AGENT);\n headers.set(\"x-opencode-session-id\", ids.session);\n headers.set(\"x-opencode-project\", v2ProjectID(ids.project));\n if (ids.parentSession !== \"\") {\n headers.set(\"x-parent-session-id\", ids.parentSession);\n }\n if (protocol === \"anthropic\") {\n headers.set(\"anthropic-beta\", V2_ANTHROPIC_BETAS);\n }\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport type { RequestIDs } from \"./identity.js\";\nimport { isV1Upstream, upstreamURL } from \"./lanes.js\";\nimport { setV1Headers, setV2Headers } from \"./upstream-headers.js\";\n\n// UpstreamRequest is one request the proxy sends to an upstream lane.\nexport interface UpstreamRequest {\n url: string;\n headers: Headers;\n body: string;\n}\n\n// buildUpstreamRequest builds the request for one upstream lane. The v1 lane\n// sends the OpenCode 1.x header set, the v2 lane the 2.x one, and the\n// credential is sent the way the target protocol expects it.\nexport function buildUpstreamRequest(\n baseURL: string,\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n key: string,\n): UpstreamRequest {\n const headers = new Headers();\n headers.set(\"Content-Type\", \"application/json\");\n if (isV1Upstream(baseURL)) {\n setV1Headers(headers, protocol, body, ids);\n } else {\n setV2Headers(headers, protocol, ids);\n }\n if (protocol === \"anthropic\") {\n headers.set(\"x-api-key\", key);\n headers.set(\"anthropic-version\", \"2023-06-01\");\n } else {\n // The anonymous credential is the literal token \"public\". The 2026-10-14\n // gate rejects keyless requests (an absent header used to pass) and is\n // case-sensitive: \"Bearer PUBLIC\" 401s.\n headers.set(\"Authorization\", `Bearer ${key}`);\n }\n return { url: upstreamURL(baseURL, protocol), headers, body };\n}\n\n// isNonRetryableClientResponse reports whether a response is a 4xx that\n// retrying on another key of the same tier cannot fix: every 4xx except 401,\n// 403 and 429, which can be specific to the key. A transport error is never\n// non-retryable.\nexport function isNonRetryableClientResponse(status: number): boolean {\n return (\n status >= 400 &&\n status < 500 &&\n status !== 401 &&\n status !== 403 &&\n status !== 429\n );\n}\n\n// isRotatableStatus reports whether a status makes the request worth\n// retrying on another key of the same tier.\nexport function isRotatableStatus(status: number): boolean {\n return status === 401 || status === 403 || status === 429;\n}\n", "import {\n ascendingID,\n mintFreshSessionID,\n randomID,\n type RequestIDs,\n} from \"../protocol/identity.js\";\nimport { randomBytes, sha256Bytes, toHex } from \"../protocol/sha256.js\";\n\n// Verified Cloudflare IPv6 edge literals for opencode.ai (from zen-lane.sh).\nexport const DEFAULT_AAAA_POOL = [\n \"2606:4700:10::ac42:ad95\",\n \"2606:4700:10::ac42:ad96\",\n \"2606:4700:10::6814:2011\",\n] as const;\n\nconst DOH_URL = \"https://1.1.1.1/dns-query?name=opencode.ai&type=AAAA\";\nconst IPV6_HEX_COLON = /^[0-9A-Fa-f:]+$/;\n\n// LaneIdentity represents one isolated identity + Cloudflare edge combo.\nexport interface LaneIdentity {\n readonly ids: RequestIDs;\n readonly machineId: string;\n readonly edge: string;\n readonly prefix64: string;\n}\n\n// normalizePrefix64 expands an IPv6 address and returns its normalized /64\n// prefix (first 4 hextets). Non-IPv6 values are returned trimmed and lowercased.\nexport function normalizePrefix64(ipv6: string): string {\n const trimmed = ipv6.trim().toLowerCase();\n if (!trimmed.includes(\":\") || !IPV6_HEX_COLON.test(trimmed)) {\n return trimmed;\n }\n const expanded = expandIPv6Hextets(trimmed);\n if (expanded.length < 4) {\n return trimmed;\n }\n return expanded\n .slice(0, 4)\n .map((group) => {\n const parsed = Number.parseInt(group, 16);\n return Number.isNaN(parsed) ? \"0\" : parsed.toString(16);\n })\n .join(\":\");\n}\n\n// expandIPv6Hextets expands \"::\" zero-compression into 8 hextet strings.\nfunction expandIPv6Hextets(ipv6: string): string[] {\n if (!ipv6.includes(\"::\")) {\n return ipv6.split(\":\");\n }\n const [leftRaw = \"\", rightRaw = \"\"] = ipv6.split(\"::\");\n const left = leftRaw === \"\" ? [] : leftRaw.split(\":\");\n const right = rightRaw === \"\" ? [] : rightRaw.split(\":\");\n const missing = Math.max(8 - (left.length + right.length), 0);\n const middle = new Array<string>(missing).fill(\"0\");\n return [...left, ...middle, ...right];\n}\n\n// resolveEdgePool resolves opencode.ai AAAA records over Cloudflare DoH\n// (1.1.1.1) and falls back to DEFAULT_AAAA_POOL on failure or empty result.\nexport async function resolveEdgePool(\n fetchImpl: typeof fetch = fetch,\n timeoutMs = 3000,\n): Promise<string[]> {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort();\n }, timeoutMs);\n try {\n const response = await fetchImpl(DOH_URL, {\n headers: { Accept: \"application/dns-json\" },\n signal: controller.signal,\n });\n if (!response.ok) {\n return [...DEFAULT_AAAA_POOL];\n }\n const payload = (await response.json()) as Record<string, unknown>;\n const answers = Array.isArray(payload[\"Answer\"]) ? payload[\"Answer\"] : [];\n const seen = new Set<string>();\n for (const entry of answers) {\n if (typeof entry !== \"object\" || entry === null) {\n continue;\n }\n const data = (entry as Record<string, unknown>)[\"data\"];\n if (\n typeof data === \"string\" &&\n data.includes(\":\") &&\n IPV6_HEX_COLON.test(data.trim())\n ) {\n seen.add(data.trim().toLowerCase());\n }\n }\n if (seen.size === 0) {\n return [...DEFAULT_AAAA_POOL];\n }\n return [...seen].sort();\n } catch {\n return [...DEFAULT_AAAA_POOL];\n } finally {\n clearTimeout(timer);\n }\n}\n\n// createLaneIdentity generates a fresh device/session/project identity and\n// binds it to the selected Cloudflare edge (zen-lane equivalent).\nexport function createLaneIdentity(\n scope: string,\n edge: string = DEFAULT_AAAA_POOL[0],\n): LaneIdentity {\n const seed = `${scope}\\0${randomID(\"lane\", 16)}`;\n const projectDigest = sha256Bytes(`opencode-project\\0${seed}`);\n const ids: RequestIDs = {\n session: mintFreshSessionID(),\n request: randomID(\"req\", 16),\n message: ascendingID(\"msg\"),\n project: toHex(projectDigest.subarray(0, 20)),\n parentSession: \"\",\n };\n return {\n ids,\n machineId: toHex(randomBytes(16)),\n edge,\n prefix64: normalizePrefix64(edge),\n };\n}\n\n// buildEdgeFetchInit attaches Cloudflare Workers cf.resolveOverride steering\n// without mutating the caller's RequestInit.\nexport function buildEdgeFetchInit(\n init: RequestInit,\n edge: string,\n): RequestInit {\n if (edge.trim() === \"\") {\n return { ...init };\n }\n const existingCf =\n typeof (init as Record<string, unknown>)[\"cf\"] === \"object\" &&\n (init as Record<string, unknown>)[\"cf\"] !== null\n ? ((init as Record<string, unknown>)[\"cf\"] as Record<string, unknown>)\n : {};\n return {\n ...init,\n cf: {\n ...existingCf,\n resolveOverride: edge,\n },\n } as RequestInit;\n}\n", "import {\n DEFAULT_AAAA_POOL,\n createLaneIdentity,\n normalizePrefix64,\n type LaneIdentity,\n} from \"./lane.js\";\n\n// Constants from scripts/zen-guard.sh.\nexport const COOLDOWN_SECONDS = 75;\nexport const MAX_HOP_TRIES = 8;\nexport const BLACKLIST_MAX = 200;\n\n// GuardSnapshot describes the current state of the self-healing guard.\nexport interface GuardSnapshot {\n readonly blacklist: readonly string[];\n readonly lastHop: number;\n readonly hops: number;\n readonly currentEdge: string;\n readonly currentPrefix64: string;\n readonly currentSession: string;\n readonly currentMachineId: string;\n readonly pool: readonly string[];\n}\n\n// GuardAttemptResult is the outcome of one guarded upstream call.\nexport interface GuardAttemptResult<T> {\n readonly status: number;\n readonly bodyPreview: string;\n readonly value: T;\n}\n\n// isQuotaWall detects OpenCode's free usage wall from HTTP status and/or\n// response text (matches zen-guard.sh QuotaExceeded & Free usage limit checks).\nexport function isQuotaWall(status: number, bodyText: string): boolean {\n if (status === 429) {\n return true;\n }\n const lower = bodyText.toLowerCase();\n if (\n lower.includes(\"quotaexceeded\") ||\n lower.includes(\"free usage limit reached\") ||\n lower.includes(\"freetiererror\") ||\n lower.includes(\"rate_limit_exceeded\")\n ) {\n return true;\n }\n return false;\n}\n\n// UnlimitedGuard implements zen-guard and zen-hop: /64 prefix blacklisting,\n// oldest-block recycling, manual hop, and up-to-8-try self-healing rotation.\nexport class UnlimitedGuard {\n private blacklist: string[] = [];\n private lastHop = 0;\n private hops = 0;\n private pool: string[];\n private activeLane: LaneIdentity | undefined;\n private readonly scope: string;\n\n constructor(\n initialPool: readonly string[] = DEFAULT_AAAA_POOL,\n scope = \"unlimited\",\n ) {\n this.scope = scope;\n this.pool =\n initialPool.length > 0 ? [...initialPool] : [...DEFAULT_AAAA_POOL];\n }\n\n // current returns the active lane identity and edge, lazily initializing it\n // inside a request handler so Cloudflare Workers global scope never calls\n // crypto.getRandomValues().\n current(): LaneIdentity {\n if (this.activeLane === undefined) {\n this.activeLane = createLaneIdentity(\n this.scope,\n this.pool[0] ?? DEFAULT_AAAA_POOL[0],\n );\n }\n return this.activeLane;\n }\n\n // setPool updates the known AAAA edge pool.\n setPool(pool: readonly string[]): void {\n if (pool.length > 0) {\n this.pool = [...pool];\n }\n }\n\n // blacklistAdd normalizes an IPv6 address to its /64 prefix and appends it\n // to the lifetime blacklist (capped at BLACKLIST_MAX = 200).\n blacklistAdd(ipv6: string): void {\n const prefix = normalizePrefix64(ipv6);\n if (prefix === \"\") {\n return;\n }\n const filtered = this.blacklist.filter(\n (entry) => entry !== \"\" && normalizePrefix64(entry) !== prefix,\n );\n const updated = [...filtered, prefix];\n this.blacklist = updated.slice(-BLACKLIST_MAX);\n }\n\n // isBurnt reports whether an IPv6 address belongs to a blacklisted /64 block.\n isBurnt(ipv6: string): boolean {\n const prefix = normalizePrefix64(ipv6);\n if (prefix === \"\") {\n return false;\n }\n return this.blacklist.some(\n (entry) => entry !== \"\" && normalizePrefix64(entry) === prefix,\n );\n }\n\n // hop blacklists the current edge (when requested), selects a fresh unburned\n // edge (or recycles the oldest block when all are burned), and rotates the\n // device/session/project identity.\n hop(\n candidatePool?: readonly string[],\n burnCurrent = false,\n nowSeconds: number = Math.floor(Date.now() / 1000),\n ): LaneIdentity {\n if (burnCurrent) {\n this.blacklistAdd(this.current().edge);\n }\n const effectivePool =\n candidatePool !== undefined && candidatePool.length > 0\n ? [...candidatePool]\n : this.pool;\n let chosen = \"\";\n let tries = 0;\n while (tries < MAX_HOP_TRIES) {\n const candidate =\n effectivePool[(this.hops + tries) % effectivePool.length] ??\n DEFAULT_AAAA_POOL[0];\n tries += 1;\n if (!this.isBurnt(candidate)) {\n chosen = candidate;\n break;\n }\n }\n // Every block in the pool is blacklisted -> recycle the oldest /64 block\n // (buckets reset daily around midnight, matching zen-guard.sh lines 154-159).\n if (chosen === \"\") {\n const oldestPrefix = this.blacklist[0];\n if (oldestPrefix !== undefined) {\n this.blacklist = this.blacklist.slice(1);\n const match = effectivePool.find(\n (edge) => normalizePrefix64(edge) === oldestPrefix,\n );\n chosen = match ?? effectivePool[0] ?? DEFAULT_AAAA_POOL[0];\n } else {\n chosen = effectivePool[0] ?? DEFAULT_AAAA_POOL[0];\n }\n }\n this.hops += 1;\n this.lastHop = nowSeconds;\n this.activeLane = createLaneIdentity(this.scope, chosen);\n return this.activeLane;\n }\n\n // executeWithGuard runs an upstream attempt and automatically hops up to\n // MAX_HOP_TRIES times when a quota wall is encountered.\n async executeWithGuard<T>(\n attemptFn: (lane: LaneIdentity, attempt: number) => Promise<GuardAttemptResult<T>>,\n ): Promise<GuardAttemptResult<T>> {\n let lane = this.current();\n let lastResult = await attemptFn(lane, 1);\n if (!isQuotaWall(lastResult.status, lastResult.bodyPreview)) {\n return lastResult;\n }\n let tries = 0;\n while (tries < MAX_HOP_TRIES) {\n tries += 1;\n lane = this.hop(this.pool, true);\n lastResult = await attemptFn(lane, tries + 1);\n if (!isQuotaWall(lastResult.status, lastResult.bodyPreview)) {\n return lastResult;\n }\n }\n return lastResult;\n }\n\n // snapshot returns an immutable copy of the guard's state.\n snapshot(): GuardSnapshot {\n const active = this.current();\n return {\n blacklist: [...this.blacklist],\n lastHop: this.lastHop,\n hops: this.hops,\n currentEdge: active.edge,\n currentPrefix64: active.prefix64,\n currentSession: active.ids.session,\n currentMachineId: active.machineId,\n pool: [...this.pool],\n };\n }\n}\n", "import { COOLDOWN_SECONDS, type GuardSnapshot, type UnlimitedGuard } from \"./guard.js\";\nimport { normalizePrefix64 } from \"./lane.js\";\n\nconst IPIFY_V6_URL = \"https://api64.ipify.org\";\n\n// EgressStatus describes the current outbound network identity (warp-keeper & doctor).\nexport interface EgressStatus {\n readonly ip: string;\n readonly prefix64: string;\n readonly isCloudflare: boolean;\n readonly leakGuardActive: boolean;\n}\n\n// DoctorReport is the structured JSON equivalent of scripts/doctor.sh.\nexport interface DoctorReport {\n readonly status: \"ok\" | \"degraded\";\n readonly runtime: \"cloudflare-worker\" | \"node\";\n readonly egress: EgressStatus;\n readonly guard: {\n readonly hops: number;\n readonly last_hop: number;\n readonly cooldown_seconds: number;\n readonly blacklisted_count: number;\n readonly blacklist: readonly string[];\n };\n readonly lane: {\n readonly current_edge: string;\n readonly current_prefix64: string;\n readonly current_session: string;\n readonly current_machine_id: string;\n readonly pool_size: number;\n readonly pool: readonly string[];\n };\n}\n\n// isCloudflareEgress checks whether an IP belongs to Cloudflare WARP / edge\n// ranges (2606:4700::/32, 2a09:bac5::/32, 162.159.0.0/16, 188.114.0.0/16, 104.16.0.0/12).\nexport function isCloudflareEgress(ip: string): boolean {\n const normalized = ip.trim().toLowerCase();\n if (normalized.startsWith(\"2606:\") || normalized.startsWith(\"2a09:\")) {\n return true;\n }\n if (\n normalized.startsWith(\"162.159.\") ||\n normalized.startsWith(\"188.114.\") ||\n normalized.startsWith(\"104.\") ||\n normalized.startsWith(\"172.64.\") ||\n normalized.startsWith(\"172.65.\") ||\n normalized.startsWith(\"172.66.\") ||\n normalized.startsWith(\"172.67.\")\n ) {\n return true;\n }\n return false;\n}\n\n// probeEgress checks the outbound IP via api64.ipify.org (matching doctor.sh).\nexport async function probeEgress(\n fetchImpl: typeof fetch = fetch,\n runtime: \"cloudflare-worker\" | \"node\" = \"node\",\n timeoutMs = 3000,\n): Promise<EgressStatus> {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort();\n }, timeoutMs);\n try {\n const response = await fetchImpl(IPIFY_V6_URL, {\n signal: controller.signal,\n });\n if (!response.ok) {\n return fallbackEgress(runtime);\n }\n const ip = (await response.text()).trim();\n if (ip === \"\") {\n return fallbackEgress(runtime);\n }\n const isCf = runtime === \"cloudflare-worker\" || isCloudflareEgress(ip);\n return {\n ip,\n prefix64: normalizePrefix64(ip),\n isCloudflare: isCf,\n leakGuardActive: isCf,\n };\n } catch {\n return fallbackEgress(runtime);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction fallbackEgress(runtime: \"cloudflare-worker\" | \"node\"): EgressStatus {\n if (runtime === \"cloudflare-worker\") {\n return {\n ip: \"2606:4700::worker\",\n prefix64: \"2606:4700:0:0\",\n isCloudflare: true,\n leakGuardActive: true,\n };\n }\n return {\n ip: \"\",\n prefix64: \"\",\n isCloudflare: false,\n leakGuardActive: false,\n };\n}\n\n// buildDoctorReport runs the health checks and returns the full DoctorReport.\nexport async function buildDoctorReport(\n guard: UnlimitedGuard,\n fetchImpl: typeof fetch = fetch,\n runtime: \"cloudflare-worker\" | \"node\" = \"node\",\n): Promise<DoctorReport> {\n const egress = await probeEgress(fetchImpl, runtime);\n const snap: GuardSnapshot = guard.snapshot();\n const healthy =\n (runtime === \"cloudflare-worker\" || egress.isCloudflare) &&\n snap.pool.length > 0;\n return {\n status: healthy ? \"ok\" : \"degraded\",\n runtime,\n egress,\n guard: {\n hops: snap.hops,\n last_hop: snap.lastHop,\n cooldown_seconds: COOLDOWN_SECONDS,\n blacklisted_count: snap.blacklist.length,\n blacklist: snap.blacklist,\n },\n lane: {\n current_edge: snap.currentEdge,\n current_prefix64: snap.currentPrefix64,\n current_session: snap.currentSession,\n current_machine_id: snap.currentMachineId,\n pool_size: snap.pool.length,\n pool: snap.pool,\n },\n };\n}\n", "import type { BridgeBlock, BlockKind } from \"../types/inference.js\";\n\nexport const ANTHROPIC_REDACTED_THINKING_PLACEHOLDER = \"[redacted thinking]\";\n\nexport function emptyBlock(kind: BlockKind): BridgeBlock {\n return {\n kind,\n text: \"\",\n signature: \"\",\n encrypted: \"\",\n url: \"\",\n mediaType: \"\",\n data: \"\",\n fileId: \"\",\n filename: \"\",\n id: \"\",\n name: \"\",\n arguments: undefined,\n argumentsJSON: \"\",\n callId: \"\",\n result: undefined,\n isError: false,\n };\n}\n\nexport function withText(block: BridgeBlock, text: string): BridgeBlock {\n return { ...block, text };\n}\n\nexport function withURL(block: BridgeBlock, url: string): BridgeBlock {\n return { ...block, url };\n}\n\nexport function isBridgeBlockArray(value: unknown[]): value is BridgeBlock[] {\n return value.every(\n (item) =>\n typeof item === \"object\" &&\n item !== null &&\n typeof (item as BridgeBlock).kind === \"string\",\n );\n}\n\nexport function parseJSONOrStringValue(value: string): unknown {\n if (value === \"\") {\n return undefined;\n }\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return value;\n }\n}\n", "import type { BridgeBlock, Usage } from \"../types/inference.js\";\nimport { intAt } from \"./json-util.js\";\n\n// firstNonZero returns the first value that is not zero.\nexport function firstNonZero(...values: number[]): number {\n for (const value of values) {\n if (value !== 0) {\n return value;\n }\n }\n return 0;\n}\n\n// decodeOpenAIUsage reads a Chat or Responses usage object. Either spelling of\n// each field is accepted, prompt/input and completion/output alike, and the\n// cache-read, cache-write and reasoning details are read from both the Chat\n// and the Responses nesting.\nexport function decodeOpenAIUsage(usage: Record<string, unknown>): Usage {\n const input = firstNonZero(\n intAt(usage, \"prompt_tokens\"),\n intAt(usage, \"input_tokens\"),\n );\n const output = firstNonZero(\n intAt(usage, \"completion_tokens\"),\n intAt(usage, \"output_tokens\"),\n );\n let total = intAt(usage, \"total_tokens\");\n if (total === 0) {\n total = input + output;\n }\n const cached = firstNonZero(\n intAt(usage, \"prompt_tokens_details\", \"cached_tokens\"),\n intAt(usage, \"input_tokens_details\", \"cached_tokens\"),\n );\n const cacheCreation = firstNonZero(\n intAt(usage, \"cache_creation_input_tokens\"),\n intAt(usage, \"prompt_tokens_details\", \"cache_creation_input_tokens\"),\n intAt(usage, \"prompt_tokens_details\", \"cache_write_tokens\"),\n intAt(usage, \"input_tokens_details\", \"cache_creation_input_tokens\"),\n );\n const reasoning = firstNonZero(\n intAt(usage, \"completion_tokens_details\", \"reasoning_tokens\"),\n intAt(usage, \"output_tokens_details\", \"reasoning_tokens\"),\n );\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens: total,\n cachedInputTokens: cached,\n cacheCreationTokens: cacheCreation,\n reasoningTokens: reasoning,\n };\n}\n\n// decodeAnthropicUsage reads an Anthropic usage object. Anthropic reports the\n// cache parts separately from input_tokens, so the prompt input is the sum of\n// the three, matching the prompt-token semantics the bridge uses.\nexport function decodeAnthropicUsage(usage: Record<string, unknown>): Usage {\n const cached = intAt(usage, \"cache_read_input_tokens\");\n const cacheCreation = intAt(usage, \"cache_creation_input_tokens\");\n const output = intAt(usage, \"output_tokens\");\n const input = intAt(usage, \"input_tokens\") + cached + cacheCreation;\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens: input + output,\n cachedInputTokens: cached,\n cacheCreationTokens: cacheCreation,\n reasoningTokens: 0,\n };\n}\n\n// openAIUsage renders bridge usage in the Chat usage shape.\nexport function openAIUsage(usage: Usage): Record<string, unknown> {\n return {\n prompt_tokens: usage.inputTokens,\n completion_tokens: usage.outputTokens,\n total_tokens: usage.totalTokens,\n prompt_tokens_details: { cached_tokens: usage.cachedInputTokens },\n completion_tokens_details: { reasoning_tokens: usage.reasoningTokens },\n };\n}\n\n// anthropicUsage renders bridge usage in the Anthropic shape, where\n// input_tokens excludes the cache parts, so it is the prompt input minus the\n// cache parts, floored at zero.\nexport function anthropicUsage(usage: Usage): Record<string, unknown> {\n return {\n input_tokens: Math.max(\n usage.inputTokens - usage.cachedInputTokens - usage.cacheCreationTokens,\n 0,\n ),\n output_tokens: usage.outputTokens,\n cache_creation_input_tokens: usage.cacheCreationTokens,\n cache_read_input_tokens: usage.cachedInputTokens,\n };\n}\n\n// chatStop maps a canonical bridge stop reason onto Chat's finish_reason.\nexport function chatStop(stop: string): string {\n switch (stop) {\n case \"tool_use\":\n case \"tool_calls\":\n return \"tool_calls\";\n case \"max_tokens\":\n case \"length\":\n return \"length\";\n case \"content_filter\":\n case \"error\":\n return stop;\n default:\n return \"stop\";\n }\n}\n\n// anthropicStop maps a canonical bridge stop reason onto Anthropic's\n// stop_reason.\nexport function anthropicStop(stop: string): string {\n switch (stop) {\n case \"tool_use\":\n case \"tool_calls\":\n return \"tool_use\";\n case \"max_tokens\":\n case \"length\":\n return \"max_tokens\";\n case \"stop_sequence\":\n case \"pause_turn\":\n case \"refusal\":\n return stop;\n default:\n return \"end_turn\";\n }\n}\n\n// canonicalChatStop maps Chat's finish_reason onto a canonical bridge stop\n// reason.\nexport function canonicalChatStop(stop: string): string {\n switch (stop) {\n case \"tool_calls\":\n case \"function_call\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"content_filter\":\n return \"content_filter\";\n case \"error\":\n case \"network_error\":\n case \"server_error\":\n return \"error\";\n default:\n return \"stop\";\n }\n}\n\n// canonicalAnthropicStop maps Anthropic's stop_reason onto a canonical bridge\n// stop reason.\nexport function canonicalAnthropicStop(stop: string): string {\n switch (stop) {\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n case \"pause_turn\":\n case \"refusal\":\n return stop;\n case \"error\":\n case \"network_error\":\n case \"server_error\":\n return \"error\";\n default:\n return \"stop\";\n }\n}\n\n// isToolStop reports whether a stop reason promises tool calls downstream. It\n// accepts the canonical \"tool_calls\" as well as the raw \"tool_use\" and\n// \"function_call\" spellings an upstream may report.\nexport function isToolStop(stop: string): boolean {\n return (\n stop === \"tool_calls\" || stop === \"tool_use\" || stop === \"function_call\"\n );\n}\n\n// usableToolBlocks drops phantom tool blocks that cannot be executed by a\n// downstream client. Empty arguments are valid, so the tool name is the\n// minimum required signal here.\nexport function usableToolBlocks(tools: BridgeBlock[]): BridgeBlock[] {\n return tools.filter((tool) => tool.name.trim() !== \"\");\n}\n\n// canonicalResponsesIncomplete maps a Responses incomplete_details.reason onto\n// a canonical bridge stop reason: \"content_filter\" stays itself and any other\n// reason, max_output_tokens included, becomes \"length\".\nexport function canonicalResponsesIncomplete(reason: string): string {\n return reason === \"content_filter\" ? \"content_filter\" : \"length\";\n}\n\n// responsesIncompleteReason is the inverse of canonicalResponsesIncomplete.\nexport function responsesIncompleteReason(stop: string): string {\n return stop === \"content_filter\" ? \"content_filter\" : \"max_output_tokens\";\n}\n", "import type { BridgeBlock } from \"../types/inference.js\";\nimport { firstString, isPlainObject, put } from \"./json-util.js\";\nimport { isBridgeBlockArray, parseJSONOrStringValue } from \"./block.js\";\nimport { ANTHROPIC_REDACTED_THINKING_PLACEHOLDER } from \"./block.js\";\n\n// bridgeReasoningText joins reasoning blocks into the single text Chat's\n// reasoning_content holds, using a placeholder for a block that carries only\n// encrypted content.\nexport function bridgeReasoningText(\n blocks: BridgeBlock[],\n): { text: string; ok: boolean } {\n if (blocks.length === 0) {\n return { text: \"\", ok: false };\n }\n let text = \"\";\n for (const block of blocks) {\n if (block.text !== \"\") {\n text += block.text;\n } else if (block.encrypted !== \"\") {\n text += ANTHROPIC_REDACTED_THINKING_PLACEHOLDER;\n }\n }\n return { text, ok: true };\n}\n\n// bridgeReasoningSignature returns the signature of the last signed reasoning\n// block, or \"\" when no block is signed.\nexport function bridgeReasoningSignature(blocks: BridgeBlock[]): string {\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i];\n if (block !== undefined && block.signature !== \"\") {\n return block.signature;\n }\n }\n return \"\";\n}\n\n// encodeChatBlocks renders blocks as Chat message content: a lone text block\n// becomes a plain string and anything else an array of text, image_url and\n// file parts.\nexport function encodeChatBlocks(blocks: BridgeBlock[]): unknown {\n const only = blocks.length === 1 ? blocks[0] : undefined;\n if (only !== undefined && only.kind === \"text\") {\n return only.text;\n }\n const parts: unknown[] = [];\n for (const block of blocks) {\n switch (block.kind) {\n case \"text\":\n parts.push({ type: \"text\", text: block.text });\n break;\n case \"image\": {\n let url = block.url;\n if (url === \"\" && block.data !== \"\") {\n url = `data:${block.mediaType};base64,${block.data}`;\n }\n parts.push({ type: \"image_url\", image_url: { url } });\n break;\n }\n case \"file\": {\n const file: Record<string, unknown> = {};\n put(file, \"file_id\", block.fileId);\n put(file, \"file_data\", block.data);\n put(file, \"filename\", block.filename);\n parts.push({ type: \"file\", file });\n break;\n }\n default:\n break;\n }\n }\n return parts;\n}\n\n// encodeAnthropicBlocks renders blocks as Anthropic content blocks.\nexport function encodeAnthropicBlocks(blocks: BridgeBlock[]): unknown[] {\n const parts: unknown[] = [];\n for (const block of blocks) {\n switch (block.kind) {\n case \"text\":\n parts.push({ type: \"text\", text: block.text });\n break;\n case \"image\":\n if (block.url !== \"\") {\n parts.push({\n type: \"image\",\n source: { type: \"url\", url: block.url },\n });\n } else {\n parts.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: block.mediaType,\n data: block.data,\n },\n });\n }\n break;\n case \"file\": {\n let source: Record<string, unknown> | undefined;\n if (block.url !== \"\") {\n source = { type: \"url\", url: block.url };\n } else if (block.data !== \"\") {\n source = {\n type: \"base64\",\n media_type: firstString(block.mediaType, \"application/octet-stream\"),\n data: block.data,\n };\n }\n if (source) {\n const part: Record<string, unknown> = { type: \"document\", source };\n put(part, \"title\", block.filename);\n parts.push(part);\n }\n break;\n }\n case \"tool_call\": {\n const input =\n block.arguments === undefined || block.arguments === null\n ? parseJSONOrStringValue(block.argumentsJSON)\n : block.arguments;\n parts.push({\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input,\n });\n break;\n }\n case \"tool_result\": {\n let content = block.result;\n if (Array.isArray(content) && isBridgeBlockArray(content)) {\n content = encodeAnthropicBlocks(content);\n }\n parts.push({\n type: \"tool_result\",\n tool_use_id: block.callId,\n content,\n is_error: block.isError,\n });\n break;\n }\n case \"reasoning\": {\n if (block.encrypted !== \"\") {\n parts.push({ type: \"redacted_thinking\", data: block.encrypted });\n break;\n }\n parts.push({\n type: \"thinking\",\n thinking: block.text,\n signature: block.signature,\n });\n break;\n }\n default:\n break;\n }\n }\n return parts;\n}\n\n// bridgeArgumentsJSON returns a tool call's arguments as JSON text.\nexport function bridgeArgumentsJSON(block: BridgeBlock): string {\n if (block.argumentsJSON !== \"\") {\n return block.argumentsJSON;\n }\n if (block.arguments === undefined || block.arguments === null) {\n return \"{}\";\n }\n try {\n return JSON.stringify(block.arguments);\n } catch {\n return \"{}\";\n }\n}\n\n// bridgeToolResultContent flattens a tool result into a string.\nexport function bridgeToolResultContent(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (Array.isArray(value)) {\n let text = \"\";\n let allText = true;\n for (const raw of value) {\n if (!isPlainObject(raw) || (raw as Record<string, unknown>)[\"type\"] !== \"text\") {\n allText = false;\n break;\n }\n text += typeof raw[\"text\"] === \"string\" ? (raw[\"text\"] as string) : \"\";\n }\n if (allText) {\n return text;\n }\n }\n try {\n return JSON.stringify(value) ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n// bridgeBlocksText concatenates the text of the \"text\" blocks and ignores\n// every other kind.\nexport function bridgeBlocksText(blocks: BridgeBlock[]): string {\n let text = \"\";\n for (const block of blocks) {\n if (block.kind === \"text\") {\n text += block.text;\n }\n }\n return text;\n}\n", "import type { BridgeBlock, BridgeToolChoice } from \"../types/inference.js\";\nimport { isPlainObject, stringAt } from \"./json-util.js\";\nimport { randomID } from \"./identity.js\";\n\n// schemaOrDefault substitutes an empty object schema for a tool that declared\n// no parameters.\nexport function schemaOrDefault(value: unknown): unknown {\n if (value === undefined || value === null) {\n return { type: \"object\", properties: {} };\n }\n return value;\n}\n\n// chatResponseFormat converts a bridge-level response format into the Chat\n// Completions shape. A value with no Chat equivalent is omitted.\nexport function chatResponseFormat(format: unknown): unknown {\n if (!isPlainObject(format)) {\n return undefined;\n }\n switch (stringAt(format, \"type\")) {\n case \"json_object\":\n return { type: \"json_object\" };\n case \"json_schema\": {\n const nested = format[\"json_schema\"];\n if (isPlainObject(nested)) {\n return { type: \"json_schema\", json_schema: nested };\n }\n const built: Record<string, unknown> = {};\n for (const key of [\"name\", \"description\", \"schema\", \"strict\"]) {\n if (key in format) {\n built[key] = format[key];\n }\n }\n return Object.keys(built).length === 0\n ? undefined\n : { type: \"json_schema\", json_schema: built };\n }\n default:\n return undefined;\n }\n}\n\n// responsesTextFormat converts a bridge-level response format into the object\n// accepted by the Responses \"text.format\" field. A Chat-style nested\n// json_schema is flattened into the inline shape Responses expects.\nexport function responsesTextFormat(format: unknown): unknown {\n if (!isPlainObject(format)) {\n return undefined;\n }\n switch (stringAt(format, \"type\")) {\n case \"text\":\n case \"json_object\":\n return format;\n case \"json_schema\": {\n const nested = format[\"json_schema\"];\n if (!isPlainObject(nested)) {\n return format;\n }\n return { ...nested, type: \"json_schema\" };\n }\n default:\n return undefined;\n }\n}\n\n// encodeChatToolChoice renders a bridge tool choice for Chat, nesting the name\n// under a function object.\nexport function encodeChatToolChoice(choice: BridgeToolChoice): unknown {\n switch (choice.mode) {\n case \"named\":\n return { type: \"function\", function: { name: choice.name } };\n case \"auto\":\n case \"none\":\n case \"required\":\n return choice.mode;\n default:\n return undefined;\n }\n}\n\n// encodeResponsesToolChoice renders a bridge tool choice for Responses, with\n// the name at the top level.\nexport function encodeResponsesToolChoice(choice: BridgeToolChoice): unknown {\n switch (choice.mode) {\n case \"named\":\n return { type: \"function\", name: choice.name };\n case \"auto\":\n case \"none\":\n case \"required\":\n return choice.mode;\n default:\n return undefined;\n }\n}\n\n// encodeAnthropicToolChoice renders a bridge tool choice for Anthropic. It\n// returns undefined for \"none\", which Anthropic cannot express: the encoder\n// omits the tools instead.\nexport function encodeAnthropicToolChoice(choice: BridgeToolChoice): unknown {\n switch (choice.mode) {\n case \"named\":\n return { type: \"tool\", name: choice.name };\n case \"required\":\n return { type: \"any\" };\n case \"auto\":\n return { type: choice.mode };\n default:\n return undefined;\n }\n}\n\n// normalizeResponsesRole maps a bridge message role onto a Responses message\n// role: assistant stays, everything else becomes user.\nexport function normalizeResponsesRole(role: string): \"assistant\" | \"user\" {\n return role === \"assistant\" ? \"assistant\" : \"user\";\n}\n\n// minResponsesMaxOutputTokens is the smallest max_output_tokens the Zen\n// Responses endpoint accepts; anything lower is rejected with a 400.\nexport const MIN_RESPONSES_MAX_OUTPUT_TOKENS = 16;\n\n// floorResponsesMaxTokens keeps tiny downstream budgets from failing Zen\n// responses validation.\nexport function floorResponsesMaxTokens(value: unknown): unknown {\n if (\n typeof value === \"number\" &&\n value > 0 &&\n value < MIN_RESPONSES_MAX_OUTPUT_TOKENS\n ) {\n return MIN_RESPONSES_MAX_OUTPUT_TOKENS;\n }\n return value;\n}\n\n// encodeResponsesReasoning renders a reasoning block as a Responses reasoning\n// item with its text as the summary, synthesizing an ID when the block has\n// none.\nexport function encodeResponsesReasoning(\n block: BridgeBlock,\n completed: boolean,\n): Record<string, unknown> {\n const id = block.id !== \"\" ? block.id : randomID(\"rs\", 12);\n const summary: unknown[] = [];\n if (block.text !== \"\") {\n summary.push({ type: \"summary_text\", text: block.text });\n }\n const item: Record<string, unknown> = { id, type: \"reasoning\", summary };\n if (block.encrypted !== \"\") {\n item[\"encrypted_content\"] = block.encrypted;\n }\n if (completed) {\n item[\"status\"] = \"completed\";\n }\n return item;\n}\n\n// encodeResponsesReasoningInput renders a reasoning block for the request\n// path. Only reasoning the upstream actually issued is replayed: a block that\n// arrived as plain text has no server-side id, and synthesizing one guarantees\n// a stale reasoning-reference rejection.\nexport function encodeResponsesReasoningInput(\n block: BridgeBlock,\n): { item: Record<string, unknown>; ok: boolean } {\n if (block.id === \"\" && block.encrypted === \"\") {\n return { item: {}, ok: false };\n }\n return { item: encodeResponsesReasoning(block, false), ok: true };\n}\n", "import type { BridgeBlock, BridgeResponse } from \"../types/inference.js\";\nimport { isPlainObject } from \"./json-util.js\";\nimport { asPrefix, randomID } from \"./identity.js\";\nimport {\n anthropicStop,\n anthropicUsage,\n chatStop,\n decodeAnthropicUsage,\n decodeOpenAIUsage,\n isToolStop,\n openAIUsage,\n responsesIncompleteReason,\n usableToolBlocks,\n} from \"./response-usage.js\";\nimport {\n bridgeArgumentsJSON,\n bridgeReasoningSignature,\n bridgeReasoningText,\n encodeAnthropicBlocks,\n} from \"./encode-blocks.js\";\nimport { encodeResponsesReasoning } from \"./encode-shared.js\";\nimport { parseJSONOrStringValue } from \"./block.js\";\n\n// encodeBridgeResponse encodes a bridge response as the target protocol's body.\n// A tool stop with no usable tool block is demoted to a plain stop first, and\n// an ID is synthesized when the response has none.\nexport function encodeBridgeResponse(\n protocol: string,\n input: BridgeResponse,\n): Record<string, unknown> {\n const response = demotePhantomToolStop(input);\n const id = response.id !== \"\" ? response.id : randomID(\"resp\", 12);\n switch (protocol) {\n case \"chat\":\n return encodeChatResponse(response, id);\n case \"responses\":\n return encodeResponsesResponse(response, id);\n case \"anthropic\":\n return encodeAnthropicResponse(response, id);\n default:\n return {};\n }\n}\n\n// demotePhantomToolStop returns a copy of the response whose tool stop is\n// demoted to a plain stop when no usable tool block was assembled. A tool_use\n// stop with no usable tool blocks makes strict clients end the turn running\n// nothing and reporting no error.\nfunction demotePhantomToolStop(input: BridgeResponse): BridgeResponse {\n if (!isToolStop(input.stop)) {\n return input;\n }\n const tools = usableToolBlocks(input.tools);\n if (tools.length > 0) {\n return { ...input, tools };\n }\n return { ...input, tools: [], stop: \"stop\" };\n}\n\nfunction encodeChatResponse(\n response: BridgeResponse,\n id: string,\n): Record<string, unknown> {\n const message: Record<string, unknown> = {\n role: \"assistant\",\n content: response.text,\n };\n const reasoning = bridgeReasoningText(response.reasoning);\n if (reasoning.ok) {\n message[\"reasoning_content\"] = reasoning.text;\n }\n const signature = bridgeReasoningSignature(response.reasoning);\n if (signature !== \"\") {\n message[\"reasoning_signature\"] = signature;\n }\n if (response.tools.length > 0) {\n const calls = response.tools.map((tool) => ({\n id: tool.id,\n type: \"function\",\n function: {\n name: tool.name,\n arguments: bridgeArgumentsJSON(tool),\n },\n }));\n message[\"tool_calls\"] = calls;\n }\n return {\n id: asPrefix(id, \"chatcmpl\"),\n object: \"chat.completion\",\n created: response.created,\n model: response.model,\n choices: [\n {\n index: 0,\n message,\n finish_reason: chatStop(response.stop),\n },\n ],\n usage: openAIUsage(response.usage),\n };\n}\n\nfunction encodeResponsesResponse(\n response: BridgeResponse,\n id: string,\n): Record<string, unknown> {\n const output: unknown[] = [];\n for (const reasoning of response.reasoning) {\n output.push(encodeResponsesReasoning(reasoning, true));\n }\n if (response.text !== \"\") {\n output.push({\n id: randomID(\"msg\", 12),\n type: \"message\",\n status: \"completed\",\n role: \"assistant\",\n content: [\n { type: \"output_text\", text: response.text, annotations: [] },\n ],\n });\n }\n for (const tool of response.tools) {\n output.push({\n id: randomID(\"fc\", 12),\n type: \"function_call\",\n status: \"completed\",\n call_id: tool.id,\n name: tool.name,\n arguments: bridgeArgumentsJSON(tool),\n });\n }\n let status = \"completed\";\n let incomplete: unknown = null;\n if (response.stop === \"length\" || response.stop === \"content_filter\") {\n status = \"incomplete\";\n incomplete = { reason: responsesIncompleteReason(response.stop) };\n } else if (response.stop === \"error\") {\n status = \"failed\";\n }\n return {\n id: asPrefix(id, \"resp\"),\n object: \"response\",\n created_at: response.created,\n status,\n model: response.model,\n output,\n error: null,\n incomplete_details: incomplete,\n usage: {\n input_tokens: response.usage.inputTokens,\n output_tokens: response.usage.outputTokens,\n total_tokens: response.usage.totalTokens,\n input_tokens_details: { cached_tokens: response.usage.cachedInputTokens },\n output_tokens_details: {\n reasoning_tokens: response.usage.reasoningTokens,\n },\n },\n };\n}\n\nfunction encodeAnthropicResponse(\n response: BridgeResponse,\n id: string,\n): Record<string, unknown> {\n const content: unknown[] = [...encodeAnthropicBlocks(response.reasoning)];\n if (response.text !== \"\") {\n content.push({ type: \"text\", text: response.text });\n }\n for (const tool of response.tools) {\n content.push({\n type: \"tool_use\",\n id: tool.id,\n name: tool.name,\n input: toolInput(tool),\n });\n }\n return {\n id: asPrefix(id, \"msg\"),\n type: \"message\",\n role: \"assistant\",\n model: response.model,\n content,\n stop_reason: anthropicStop(response.stop),\n stop_sequence: null,\n usage: anthropicUsage(response.usage),\n };\n}\n\n// toolInput returns a tool call's decoded arguments, falling back to its raw\n// JSON text.\nfunction toolInput(tool: BridgeBlock): unknown {\n if (tool.arguments === undefined || tool.arguments === null) {\n return parseJSONOrStringValue(tool.argumentsJSON);\n }\n return tool.arguments;\n}\n\n// responseUsage extracts the usage of a serialized response body and reports\n// whether it carried any.\nexport function responseUsage(\n protocol: string,\n body: unknown,\n): { usage: BridgeResponse[\"usage\"]; present: boolean } {\n if (!isPlainObject(body)) {\n return { usage: emptyUsage(), present: false };\n }\n const usage = body[\"usage\"];\n if (!isPlainObject(usage) || Object.keys(usage).length === 0) {\n return { usage: emptyUsage(), present: false };\n }\n if (protocol === \"anthropic\") {\n return { usage: decodeAnthropicUsage(usage), present: true };\n }\n return { usage: decodeOpenAIUsage(usage), present: true };\n}\n\nfunction emptyUsage(): BridgeResponse[\"usage\"] {\n return {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n reasoningTokens: 0,\n };\n}\n", "// SSERecord is one parsed SSE record: the event name and its data payload.\nexport interface SSERecord {\n event: string;\n data: string;\n}\n\n// The scanner caps one line at 16 MiB, the same limit Go's bufio.Scanner\n// applies, so a single oversized line is a stream failure rather than an\n// unbounded allocation.\nconst MAX_LINE_BYTES = 16 * 1024 * 1024;\n\nexport class SSELineTooLongError extends Error {\n constructor() {\n super(\"upstream SSE line exceeds the 16 MiB limit\");\n }\n}\n\n// SSEReader reads SSE records from a byte stream. It is line based: a record\n// ends on a blank line, a line starting with a colon is a comment and does not\n// end a record, and a trailing record without its blank line is dropped.\nexport class SSEReader {\n private buffer = \"\";\n private readonly decoder = new TextDecoder(\"utf-8\");\n private readonly encoder = new TextEncoder();\n private eventName = \"\";\n private dataLines: string[] = [];\n private sawData = false;\n private closed = false;\n\n // push feeds bytes into the reader and returns the records that became\n // complete. Bytes are decoded as a stream so a character split across two\n // pushes is not corrupted.\n push(chunk: Uint8Array): SSERecord[] {\n if (this.closed) {\n return [];\n }\n this.buffer += this.decoder.decode(chunk, { stream: true });\n return this.drain(false);\n }\n\n // close flushes the decoder and reports that the stream ended. A record that\n // was never terminated by a blank line is dropped, and the caller is told the\n // stream ended unexpectedly.\n close(): { records: SSERecord[]; truncated: boolean } {\n if (this.closed) {\n return { records: [], truncated: false };\n }\n this.closed = true;\n const tail = this.decoder.decode();\n if (tail !== \"\") {\n this.buffer += tail;\n }\n const records = this.drain(false);\n return { records, truncated: this.sawData };\n }\n\n private drain(final: boolean): SSERecord[] {\n const records: SSERecord[] = [];\n for (;;) {\n const boundary = this.nextLineBoundary();\n if (boundary === undefined) {\n break;\n }\n const line = this.buffer.slice(0, boundary);\n this.buffer = this.buffer.slice(boundary + 1);\n const record = this.consumeLine(line);\n if (record !== undefined) {\n records.push(record);\n }\n }\n if (final && this.buffer !== \"\") {\n this.buffer = \"\";\n }\n return records;\n }\n\n // nextLineBoundary returns the index of the next newline, or undefined when\n // the buffer holds no complete line yet.\n private nextLineBoundary(): number | undefined {\n const index = this.buffer.indexOf(\"\\n\");\n return index === -1 ? undefined : index;\n }\n\n // consumeLine applies one line of the SSE grammar and returns a record when\n // the line closes one.\n private consumeLine(raw: string): SSERecord | undefined {\n if (this.encoder.encode(raw).length > MAX_LINE_BYTES) {\n throw new SSELineTooLongError();\n }\n const line = raw.endsWith(\"\\r\") ? raw.slice(0, -1) : raw;\n if (line === \"\") {\n if (!this.sawData) {\n // A record without a data line is not delivered.\n this.eventName = \"\";\n this.dataLines = [];\n return undefined;\n }\n const record: SSERecord = {\n event: this.eventName,\n data: this.dataLines.join(\"\\n\"),\n };\n this.eventName = \"\";\n this.dataLines = [];\n this.sawData = false;\n return record;\n }\n if (line.startsWith(\":\")) {\n return undefined;\n }\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n switch (field) {\n case \"event\":\n this.eventName = value.trim();\n break;\n case \"data\":\n this.dataLines.push(value.trim());\n this.sawData = true;\n break;\n default:\n break;\n }\n return undefined;\n }\n}\n\n// nextSSEBoundary returns the end index of the first complete SSE frame in\n// buffer, preferring whichever of the two line endings comes first. A frame\n// ends at the blank line that follows it.\nexport function nextSSEBoundary(buffer: string): number | undefined {\n const lf = buffer.indexOf(\"\\n\\n\");\n const crlf = buffer.indexOf(\"\\r\\n\\r\\n\");\n if (lf === -1 && crlf === -1) {\n return undefined;\n }\n if (lf === -1) {\n return crlf + 4;\n }\n if (crlf === -1) {\n return lf + 2;\n }\n return Math.min(lf + 2, crlf + 4);\n}\n", "import type { Usage } from \"../types/inference.js\";\n\nexport type BridgeStreamKind =\n | \"start\"\n | \"text\"\n | \"reasoning\"\n | \"reasoning_signature\"\n | \"tool_start\"\n | \"tool_delta\"\n | \"usage\"\n | \"finish\"\n | \"error\"\n | \"done\";\n\n// BridgeStreamEvent is one protocol-neutral streaming event. Every field is\n// always present so the event can be compared and copied without optional\n// handling; only the fields of the event's kind carry meaning.\nexport interface BridgeStreamEvent {\n kind: BridgeStreamKind;\n responseID: string;\n model: string;\n text: string;\n signature: string;\n toolKey: string;\n toolID: string;\n toolName: string;\n stop: string;\n error: string;\n errorType: string;\n encrypted: string;\n usage: Usage | undefined;\n}\n\nexport function streamEvent(\n kind: BridgeStreamKind,\n fields: Partial<BridgeStreamEvent> = {},\n): BridgeStreamEvent {\n return {\n kind,\n responseID: \"\",\n model: \"\",\n text: \"\",\n signature: \"\",\n toolKey: \"\",\n toolID: \"\",\n toolName: \"\",\n stop: \"\",\n error: \"\",\n errorType: \"\",\n encrypted: \"\",\n usage: undefined,\n ...fields,\n };\n}\n\n// The three stream sentinels are compared by identity, so each one is a\n// distinct value rather than a shared message.\nexport const errStreamUpstreamFailure = new Error(\n \"upstream stream failure delivered\",\n);\nexport const errStreamNormalTermination = new Error(\n \"upstream stream terminated normally\",\n);\nexport const errSSEUnexpectedEOF = new Error(\"unexpected end of SSE stream\");\n\n// StreamSink receives the encoded SSE bytes. It is byte-oriented so a\n// multi-byte character split across two writes is never corrupted.\nexport interface StreamSink {\n write(chunk: Uint8Array): void;\n}\n\n// StreamEncoder turns bridge stream events into one downstream protocol's SSE\n// stream.\nexport interface StreamEncoder {\n emit(event: BridgeStreamEvent): void;\n finish(): void;\n readonly usage: Usage;\n readonly usageReported: boolean;\n}\n", "import { firstString, stringAt } from \"./json-util.js\";\n\n// sprint mirrors Go's fmt.Sprint for the values a stream event can carry: a\n// number, a string, or a missing value that Go prints as \"<nil>\".\nexport function sprint(value: unknown): string {\n if (value === undefined || value === null) {\n return \"<nil>\";\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return JSON.stringify(value);\n}\n\n// mergeToolName folds a Chat name fragment into the name accumulated so far. A\n// fragment that repeats or extends the current name replaces it, and anything\n// else is appended.\nexport function mergeToolName(current: string, fragment: string): string {\n if (current === \"\" || fragment === current) {\n return fragment;\n }\n if (fragment.startsWith(current)) {\n return fragment;\n }\n return current + fragment;\n}\n\n// responseToolKey identifies the tool call a Responses event belongs to: the\n// item's id when the event carries an item, else the event's item_id, else its\n// output_index.\nexport function responseToolKey(\n event: Record<string, unknown>,\n item: Record<string, unknown> | undefined,\n): string {\n if (item !== undefined) {\n const id = stringAt(item, \"id\");\n if (id !== \"\") {\n return id;\n }\n }\n const id = stringAt(event, \"item_id\");\n if (id !== \"\") {\n return id;\n }\n return sprint(event[\"output_index\"]);\n}\n\n// streamErrorMessage extracts the upstream error text, accepting the OpenAI\n// nested error object, a top-level message and a bare error string.\nexport function streamErrorMessage(\n value: Record<string, unknown>,\n fallback: string,\n): string {\n const nested = stringAt(value, \"error\", \"message\");\n if (nested !== \"\") {\n return nested;\n }\n const top = stringAt(value, \"message\");\n if (top !== \"\") {\n return top;\n }\n const bare = value[\"error\"];\n if (typeof bare === \"string\" && bare !== \"\") {\n return bare;\n }\n return fallback;\n}\n\n// streamErrorType extracts the upstream error type, falling back to its code\n// and then to \"upstream_error\".\nexport function streamErrorType(value: Record<string, unknown>): string {\n return firstString(\n stringAt(value, \"error\", \"type\"),\n stringAt(value, \"error\", \"code\"),\n \"upstream_error\",\n );\n}\n\n// isStreamErrorFinish reports whether a finish or stop reason reports an\n// upstream error rather than a normal end.\nexport function isStreamErrorFinish(stop: string): boolean {\n const normalized = stop.trim().toLowerCase();\n return (\n normalized === \"error\" ||\n normalized === \"network_error\" ||\n normalized === \"server_error\"\n );\n}\n\n// ToolTracker remembers the tool calls a stream has seen. It keeps the\n// identity of each call, the order the calls appeared in, and whether their\n// arguments or reasoning already arrived, so a call is only started once and\n// a delta is not repeated by the closing event.\nexport class ToolTracker {\n private readonly started = new Map<string, boolean>();\n private readonly ids = new Map<string, string>();\n private readonly names = new Map<string, string>();\n private readonly order: string[] = [];\n private readonly argumentKeys = new Set<string>();\n private readonly reasoningKeys = new Set<string>();\n\n // ensure registers a tool key the first time it is seen and keeps the order\n // in which the calls appeared.\n ensure(key: string): void {\n if (this.started.has(key)) {\n return;\n }\n this.started.set(key, false);\n this.order.push(key);\n }\n\n setID(key: string, id: string): void {\n if (id !== \"\") {\n this.ids.set(key, id);\n }\n }\n\n setName(key: string, name: string): void {\n if (name !== \"\") {\n this.names.set(key, name);\n }\n }\n\n id(key: string): string {\n return this.ids.get(key) ?? \"\";\n }\n\n name(key: string): string {\n return this.names.get(key) ?? \"\";\n }\n\n isStarted(key: string): boolean {\n return this.started.get(key) === true;\n }\n\n markStarted(key: string): void {\n this.started.set(key, true);\n }\n\n keys(): string[] {\n return [...this.order];\n }\n\n markArguments(key: string): void {\n this.argumentKeys.add(key);\n }\n\n hasArguments(key: string): boolean {\n return this.argumentKeys.has(key);\n }\n\n markReasoning(key: string): void {\n this.reasoningKeys.add(key);\n }\n\n hasReasoning(key: string): boolean {\n return this.reasoningKeys.has(key);\n }\n}\n", "import type { BridgeStreamEvent } from \"./stream-types.js\";\nimport type { ProtocolStreamParser } from \"./stream-parser-types.js\";\nimport { firstString, mapAt, stringAt } from \"./json-util.js\";\nimport { decodeAnthropicUsage } from \"./response-usage.js\";\nimport { streamEvent } from \"./stream-types.js\";\nimport { isStreamErrorFinish, sprint } from \"./stream-parser-shared.js\";\n\n// AnthropicStreamParser turns Anthropic message events into bridge events.\n// The payload's own type decides what an event is, falling back to the SSE\n// event name when the payload carries none.\nexport class AnthropicStreamParser implements ProtocolStreamParser {\n parse(\n eventName: string,\n value: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n const typeName = stringAt(value, \"type\") || eventName;\n switch (typeName) {\n case \"message_start\":\n return this.messageStart(value);\n case \"content_block_start\":\n return this.contentBlockStart(value);\n case \"content_block_delta\":\n return this.contentBlockDelta(value);\n case \"message_delta\":\n return this.messageDelta(value);\n case \"message_stop\":\n return [streamEvent(\"done\")];\n case \"error\":\n return [\n streamEvent(\"error\", {\n error: firstString(\n stringAt(value, \"error\", \"message\"),\n \"upstream Anthropic stream error\",\n ),\n errorType: firstString(\n stringAt(value, \"error\", \"type\"),\n \"upstream_error\",\n ),\n }),\n ];\n default:\n return [];\n }\n }\n\n private messageStart(value: Record<string, unknown>): BridgeStreamEvent[] {\n const message = mapAt(value, \"message\");\n const events = [\n streamEvent(\"start\", {\n responseID: stringAt(message, \"id\"),\n model: stringAt(message, \"model\"),\n }),\n ];\n const usageMap = mapAt(message, \"usage\");\n if (Object.keys(usageMap).length > 0) {\n events.push(streamEvent(\"usage\", { usage: decodeAnthropicUsage(usageMap) }));\n }\n return events;\n }\n\n private contentBlockStart(value: Record<string, unknown>): BridgeStreamEvent[] {\n const block = mapAt(value, \"content_block\");\n switch (stringAt(block, \"type\")) {\n case \"thinking\": {\n const events: BridgeStreamEvent[] = [];\n const thinking = stringAt(block, \"thinking\");\n if (thinking !== \"\") {\n events.push(streamEvent(\"reasoning\", { text: thinking }));\n }\n const signature = stringAt(block, \"signature\");\n if (signature !== \"\") {\n events.push(streamEvent(\"reasoning_signature\", { signature }));\n }\n return events;\n }\n case \"redacted_thinking\":\n return [\n streamEvent(\"reasoning\", { encrypted: stringAt(block, \"data\") }),\n ];\n case \"tool_use\":\n return [\n streamEvent(\"tool_start\", {\n toolKey: sprint(value[\"index\"]),\n toolID: stringAt(block, \"id\"),\n toolName: stringAt(block, \"name\"),\n }),\n ];\n case \"text\": {\n const text = stringAt(block, \"text\");\n return text === \"\" ? [] : [streamEvent(\"text\", { text })];\n }\n default:\n return [];\n }\n }\n\n private contentBlockDelta(value: Record<string, unknown>): BridgeStreamEvent[] {\n const delta = mapAt(value, \"delta\");\n switch (stringAt(delta, \"type\")) {\n case \"thinking_delta\":\n return [\n streamEvent(\"reasoning\", { text: stringAt(delta, \"thinking\") }),\n ];\n case \"signature_delta\":\n return [\n streamEvent(\"reasoning_signature\", {\n signature: stringAt(delta, \"signature\"),\n }),\n ];\n case \"text_delta\":\n return [streamEvent(\"text\", { text: stringAt(delta, \"text\") })];\n case \"input_json_delta\":\n return [\n streamEvent(\"tool_delta\", {\n toolKey: sprint(value[\"index\"]),\n text: stringAt(delta, \"partial_json\"),\n }),\n ];\n default:\n return [];\n }\n }\n\n private messageDelta(value: Record<string, unknown>): BridgeStreamEvent[] {\n const events: BridgeStreamEvent[] = [];\n const usageMap = mapAt(value, \"usage\");\n if (Object.keys(usageMap).length > 0) {\n events.push(streamEvent(\"usage\", { usage: decodeAnthropicUsage(usageMap) }));\n }\n const stop = stringAt(value, \"delta\", \"stop_reason\");\n if (stop === \"\") {\n return events;\n }\n if (isStreamErrorFinish(stop)) {\n events.push(\n streamEvent(\"error\", {\n error: \"upstream Anthropic stream failed\",\n errorType: \"upstream_error\",\n }),\n );\n return events;\n }\n events.push(streamEvent(\"finish\", { stop }));\n return events;\n }\n}\n", "import type { BridgeStreamEvent } from \"./stream-types.js\";\nimport type { ProtocolStreamParser } from \"./stream-parser-types.js\";\nimport { firstString, mapAt, sliceAt, stringAt } from \"./json-util.js\";\nimport { decodeOpenAIUsage } from \"./response-usage.js\";\nimport { streamEvent } from \"./stream-types.js\";\nimport {\n isStreamErrorFinish,\n mergeToolName,\n sprint,\n streamErrorMessage,\n streamErrorType,\n ToolTracker,\n} from \"./stream-parser-shared.js\";\n\n// ChatStreamParser turns OpenAI Chat completion chunks into bridge events. The\n// first chunk carrying an id opens the response, and a tool call is only\n// announced once its name is known.\nexport class ChatStreamParser implements ProtocolStreamParser {\n private readonly tracker = new ToolTracker();\n private started = false;\n\n parse(\n eventName: string,\n value: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n if (eventName === \"error\") {\n return [this.errorEvent(value, \"upstream Chat stream error\")];\n }\n if (value[\"error\"] !== undefined && value[\"error\"] !== null) {\n return [this.errorEvent(value, \"upstream Chat stream error\")];\n }\n const events: BridgeStreamEvent[] = [];\n if (!this.started) {\n const id = stringAt(value, \"id\");\n if (id !== \"\") {\n this.started = true;\n events.push(\n streamEvent(\"start\", {\n responseID: id,\n model: stringAt(value, \"model\"),\n }),\n );\n }\n }\n const usageMap = mapAt(value, \"usage\");\n if (Object.keys(usageMap).length > 0) {\n events.push(streamEvent(\"usage\", { usage: decodeOpenAIUsage(usageMap) }));\n }\n for (const raw of sliceAt(value, \"choices\")) {\n const choice = mapAt(raw);\n events.push(...this.parseChoice(choice));\n }\n return events;\n }\n\n private parseChoice(choice: Record<string, unknown>): BridgeStreamEvent[] {\n const events: BridgeStreamEvent[] = [];\n const delta = mapAt(choice, \"delta\");\n const reasoning = firstString(\n stringAt(delta, \"reasoning_content\"),\n stringAt(delta, \"reasoning\"),\n );\n if (reasoning !== \"\") {\n events.push(streamEvent(\"reasoning\", { text: reasoning }));\n }\n const text = stringAt(delta, \"content\");\n if (text !== \"\") {\n events.push(streamEvent(\"text\", { text }));\n }\n for (const rawCall of sliceAt(delta, \"tool_calls\")) {\n events.push(...this.parseToolCall(mapAt(rawCall)));\n }\n const stop = stringAt(choice, \"finish_reason\");\n if (stop !== \"\") {\n if (isStreamErrorFinish(stop)) {\n events.push(\n streamEvent(\"error\", {\n error: firstString(\n stringAt(choice, \"error\", \"message\"),\n \"upstream Chat stream failed\",\n ),\n errorType: \"upstream_error\",\n }),\n );\n return events;\n }\n events.push(...this.startPendingTools());\n events.push(streamEvent(\"finish\", { stop }));\n }\n return events;\n }\n\n private parseToolCall(call: Record<string, unknown>): BridgeStreamEvent[] {\n const events: BridgeStreamEvent[] = [];\n const key = sprint(firstAnyIndex(call));\n const fn = mapAt(call, \"function\");\n this.tracker.ensure(key);\n this.tracker.setID(key, stringAt(call, \"id\"));\n const name = stringAt(fn, \"name\");\n if (name !== \"\") {\n this.tracker.setName(\n key,\n mergeToolName(this.tracker.name(key), name),\n );\n }\n const args = stringAt(fn, \"arguments\");\n if (args === \"\") {\n return events;\n }\n if (!this.tracker.isStarted(key) && this.tracker.name(key) !== \"\") {\n this.tracker.markStarted(key);\n events.push(this.toolStart(key));\n }\n events.push(\n streamEvent(\"tool_delta\", {\n toolKey: key,\n toolID: this.tracker.id(key),\n toolName: this.tracker.name(key),\n text: args,\n }),\n );\n return events;\n }\n\n // startPendingTools announces the calls whose arguments never arrived, so a\n // tool that only carries a name is still delivered to the client.\n private startPendingTools(): BridgeStreamEvent[] {\n const events: BridgeStreamEvent[] = [];\n for (const key of this.tracker.keys()) {\n if (!this.tracker.isStarted(key) && this.tracker.name(key) !== \"\") {\n this.tracker.markStarted(key);\n events.push(this.toolStart(key));\n }\n }\n return events;\n }\n\n private toolStart(key: string): BridgeStreamEvent {\n return streamEvent(\"tool_start\", {\n toolKey: key,\n toolID: this.tracker.id(key),\n toolName: this.tracker.name(key),\n });\n }\n\n private errorEvent(\n value: Record<string, unknown>,\n fallback: string,\n ): BridgeStreamEvent {\n return streamEvent(\"error\", {\n error: streamErrorMessage(value, fallback),\n errorType: streamErrorType(value),\n });\n }\n}\n\n// firstAnyIndex mirrors the tool key of a Chat call: the call's index, else\n// its id, else a missing value.\nfunction firstAnyIndex(call: Record<string, unknown>): unknown {\n const index = call[\"index\"];\n if (index !== undefined && index !== null) {\n return index;\n }\n return stringAt(call, \"id\");\n}\n", "import type { BridgeBlock } from \"../types/inference.js\";\nimport { emptyBlock } from \"./block.js\";\nimport { firstAny, isPlainObject, mapAt, sliceAt, stringAt } from \"./json-util.js\";\n\n// decodeChatReasoning reads a Chat message's reasoning into one block.\nexport function decodeChatReasoning(\n message: Record<string, unknown>,\n): BridgeBlock[] {\n let value: unknown;\n if (\"reasoning_content\" in message) {\n value = message[\"reasoning_content\"];\n } else {\n value = message[\"reasoning\"];\n }\n if (typeof value !== \"string\") {\n return [];\n }\n const block = emptyBlock(\"reasoning\");\n block.text = value;\n block.signature = stringAt(message, \"reasoning_signature\");\n return [block];\n}\n\n// decodeResponsesReasoning folds a Responses reasoning item into one block.\nexport function decodeResponsesReasoning(\n item: Record<string, unknown>,\n): BridgeBlock[] {\n let text = \"\";\n for (const raw of sliceAt(item, \"summary\")) {\n text += stringAt(raw, \"text\");\n }\n const content = item[\"content\"];\n if (content !== undefined && content !== null) {\n for (const raw of Array.isArray(content) ? content : [content]) {\n text += stringAt(raw, \"text\");\n }\n }\n const encrypted = stringAt(item, \"encrypted_content\");\n if (text === \"\" && encrypted === \"\") {\n return [];\n }\n const block = emptyBlock(\"reasoning\");\n block.id = stringAt(item, \"id\");\n block.text = text;\n block.encrypted = encrypted;\n return [block];\n}\n\n// anthropicReasoning decodes the reasoning controls of an Anthropic Messages\n// request into a single bridge-level value. An effort the client states\n// explicitly outranks a thinking block's budget.\nexport function anthropicReasoning(input: Record<string, unknown>): unknown {\n const stated = firstAny(\n mapAt(input, \"output_config\")[\"effort\"],\n input[\"effort\"],\n );\n const effort = normalizeEffort(stated);\n if (effort.ok) {\n if (effort.value === undefined) {\n return undefined;\n }\n const thinking = input[\"thinking\"];\n if (isPlainObject(thinking)) {\n return { ...thinking, effort: effort.value };\n }\n return effort.value;\n }\n return input[\"thinking\"];\n}\n\n// normalizeEffort maps a stated effort onto the bridge's effort value. \"none\"\n// and \"disabled\" mean no effort at all, and an empty value states nothing.\nfunction normalizeEffort(value: unknown): { value: unknown; ok: boolean } {\n if (typeof value !== \"string\") {\n return { value: undefined, ok: false };\n }\n const mode = value.trim().toLowerCase();\n if (mode === \"none\" || mode === \"disabled\") {\n return { value: undefined, ok: true };\n }\n if (mode === \"\") {\n return { value: undefined, ok: false };\n }\n return { value, ok: true };\n}\n", "import type { BridgeStreamEvent } from \"./stream-types.js\";\nimport type { ProtocolStreamParser } from \"./stream-parser-types.js\";\nimport { firstString, mapAt, sliceAt, stringAt } from \"./json-util.js\";\nimport { decodeResponsesReasoning } from \"./decode-reasoning.js\";\nimport { canonicalResponsesIncomplete, decodeOpenAIUsage } from \"./response-usage.js\";\nimport { streamEvent } from \"./stream-types.js\";\nimport {\n responseToolKey,\n streamErrorMessage,\n streamErrorType,\n ToolTracker,\n} from \"./stream-parser-shared.js\";\n\n// ResponsesStreamParser turns Responses events into bridge events. A tool call\n// is only announced once its item is known, and a closing event never repeats\n// arguments or reasoning that already arrived as a delta.\nexport class ResponsesStreamParser implements ProtocolStreamParser {\n private readonly tracker = new ToolTracker();\n\n parse(\n eventName: string,\n value: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n const typeName = stringAt(value, \"type\") || eventName;\n switch (typeName) {\n case \"error\":\n return [\n streamEvent(\"error\", {\n error: streamErrorMessage(\n value,\n \"upstream Responses stream error\",\n ),\n errorType: streamErrorType(value),\n }),\n ];\n case \"response.created\": {\n const response = mapAt(value, \"response\");\n return [\n streamEvent(\"start\", {\n responseID: stringAt(response, \"id\"),\n model: stringAt(response, \"model\"),\n }),\n ];\n }\n case \"response.output_text.delta\":\n return [streamEvent(\"text\", { text: stringAt(value, \"delta\") })];\n case \"response.reasoning_summary_text.delta\": {\n this.tracker.markReasoning(responseToolKey(value, undefined));\n return [streamEvent(\"reasoning\", { text: stringAt(value, \"delta\") })];\n }\n case \"response.output_item.added\":\n return this.outputItemAdded(value);\n case \"response.function_call_arguments.delta\":\n return this.argumentsDelta(value);\n case \"response.function_call_arguments.done\":\n return this.argumentsDone(value);\n case \"response.output_item.done\":\n return this.outputItemDone(value);\n case \"response.completed\":\n case \"response.incomplete\":\n case \"response.failed\":\n case \"response.done\":\n return this.terminated(typeName, value);\n default:\n return [];\n }\n }\n\n private outputItemAdded(\n value: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n const item = mapAt(value, \"item\");\n if (stringAt(item, \"type\") !== \"function_call\") {\n return [];\n }\n const key = responseToolKey(value, item);\n this.tracker.ensure(key);\n this.tracker.setID(key, stringAt(item, \"call_id\"));\n this.tracker.setName(key, stringAt(item, \"name\"));\n if (this.tracker.name(key) === \"\") {\n return [];\n }\n this.tracker.markStarted(key);\n return [this.toolStart(key)];\n }\n\n private argumentsDelta(value: Record<string, unknown>): BridgeStreamEvent[] {\n const key = responseToolKey(value, undefined);\n this.tracker.markArguments(key);\n return [\n streamEvent(\"tool_delta\", {\n toolKey: key,\n toolID: this.tracker.id(key),\n toolName: this.tracker.name(key),\n text: stringAt(value, \"delta\"),\n }),\n ];\n }\n\n private argumentsDone(value: Record<string, unknown>): BridgeStreamEvent[] {\n const key = responseToolKey(value, undefined);\n if (this.tracker.hasArguments(key)) {\n return [];\n }\n this.tracker.markArguments(key);\n return [\n streamEvent(\"tool_delta\", {\n toolKey: key,\n toolID: this.tracker.id(key),\n toolName: this.tracker.name(key),\n text: stringAt(value, \"arguments\"),\n }),\n ];\n }\n\n private outputItemDone(value: Record<string, unknown>): BridgeStreamEvent[] {\n const item = mapAt(value, \"item\");\n const type = stringAt(item, \"type\");\n if (type === \"reasoning\") {\n return this.reasoningDone(value, item);\n }\n if (type !== \"function_call\") {\n return [];\n }\n const key = responseToolKey(value, item);\n this.tracker.ensure(key);\n this.tracker.setID(key, stringAt(item, \"call_id\"));\n this.tracker.setName(key, stringAt(item, \"name\"));\n const events: BridgeStreamEvent[] = [];\n if (!this.tracker.isStarted(key)) {\n this.tracker.markStarted(key);\n events.push(this.toolStart(key));\n }\n if (!this.tracker.hasArguments(key)) {\n const args = stringAt(item, \"arguments\");\n if (args !== \"\") {\n events.push(streamEvent(\"tool_delta\", { toolKey: key, text: args }));\n }\n }\n return events;\n }\n\n private reasoningDone(\n value: Record<string, unknown>,\n item: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n const key = responseToolKey(value, item);\n if (this.tracker.hasReasoning(key)) {\n return [];\n }\n const first = decodeResponsesReasoning(item)[0];\n if (first === undefined) {\n return [];\n }\n return [\n streamEvent(\"reasoning\", {\n text: first.text,\n encrypted: first.encrypted,\n }),\n ];\n }\n\n private terminated(\n typeName: string,\n value: Record<string, unknown>,\n ): BridgeStreamEvent[] {\n const response = mapAt(value, \"response\");\n const usageMap = mapAt(response, \"usage\");\n if (\n typeName === \"response.failed\" ||\n stringAt(response, \"status\") === \"failed\"\n ) {\n const errorEvent = streamEvent(\"error\", {\n error: firstString(\n stringAt(response, \"error\", \"message\"),\n stringAt(value, \"error\", \"message\"),\n \"upstream Responses request failed\",\n ),\n errorType: firstString(\n stringAt(response, \"error\", \"code\"),\n \"upstream_error\",\n ),\n });\n if (Object.keys(usageMap).length === 0) {\n return [errorEvent];\n }\n return [\n streamEvent(\"usage\", { usage: decodeOpenAIUsage(usageMap) }),\n errorEvent,\n ];\n }\n const stop =\n typeName === \"response.incomplete\"\n ? canonicalResponsesIncomplete(\n stringAt(response, \"incomplete_details\", \"reason\"),\n )\n : this.completedStop(response);\n const events: BridgeStreamEvent[] = [];\n if (Object.keys(usageMap).length > 0) {\n events.push(streamEvent(\"usage\", { usage: decodeOpenAIUsage(usageMap) }));\n }\n events.push(streamEvent(\"finish\", { stop }));\n events.push(streamEvent(\"done\"));\n return events;\n }\n\n // completedStop decides how a finished Responses turn is reported. The\n // completed event carries no stop reason, so the function_call items in its\n // output \u2014 or the tool calls seen earlier \u2014 are the only signal that the\n // turn ended waiting for tool results.\n private completedStop(response: Record<string, unknown>): string {\n for (const raw of sliceAt(response, \"output\")) {\n if (stringAt(mapAt(raw), \"type\") === \"function_call\") {\n return \"tool_calls\";\n }\n }\n return this.tracker.keys().length > 0 ? \"tool_calls\" : \"stop\";\n }\n\n private toolStart(key: string): BridgeStreamEvent {\n return streamEvent(\"tool_start\", {\n toolKey: key,\n toolID: this.tracker.id(key),\n toolName: this.tracker.name(key),\n });\n }\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport { mapAt } from \"./json-util.js\";\nimport { AnthropicStreamParser } from \"./stream-parser-anthropic.js\";\nimport { ChatStreamParser } from \"./stream-parser-chat.js\";\nimport { ResponsesStreamParser } from \"./stream-parser-responses.js\";\nimport type { ProtocolStreamParser } from \"./stream-parser-types.js\";\nimport { streamEvent, type BridgeStreamEvent } from \"./stream-types.js\";\n\n// StreamParser turns one upstream protocol's SSE events into bridge stream\n// events. It picks the parser for the upstream protocol once and forwards\n// every event to it.\nexport class StreamParser {\n private readonly protocol: Protocol;\n private readonly parser: ProtocolStreamParser;\n\n constructor(protocol: Protocol) {\n this.protocol = protocol;\n this.parser = createParser(protocol);\n }\n\n // parse turns one SSE event into zero or more bridge events. A \"[DONE]\"\n // terminator is only valid on Chat, which uses it to end the stream.\n parse(eventName: string, data: string): BridgeStreamEvent[] {\n if (data === \"[DONE]\") {\n if (this.protocol !== \"chat\") {\n throw new Error(\n `unexpected [DONE] terminator for ${this.protocol} stream`,\n );\n }\n return [streamEvent(\"done\")];\n }\n let value: unknown;\n try {\n value = JSON.parse(data) as unknown;\n } catch (error) {\n throw new Error(`invalid upstream SSE JSON: ${errorMessage(error)}`);\n }\n return this.parser.parse(eventName, mapAt(value));\n }\n}\n\nfunction createParser(protocol: Protocol): ProtocolStreamParser {\n switch (protocol) {\n case \"chat\":\n return new ChatStreamParser();\n case \"anthropic\":\n return new AnthropicStreamParser();\n case \"responses\":\n return new ResponsesStreamParser();\n default:\n throw new Error(`unsupported stream protocol \"${protocol}\"`);\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import type { Usage } from \"../types/inference.js\";\nimport type { StreamSink } from \"./stream-types.js\";\n\n// StreamTool accumulates one tool call while a stream is encoded. Key is the\n// parser's stream key, ID and ItemID the call and output-item identifiers,\n// Arguments the full argument text so far and EmittedArguments how much of it\n// has reached the client in bytes. Index is the Chat index or the Responses\n// output index, AnthropicIndex the content block index, and Started records\n// whether the tool was opened downstream.\nexport interface StreamTool {\n key: string;\n id: string;\n itemID: string;\n name: string;\n arguments: string;\n index: number;\n anthropicIndex: number;\n started: boolean;\n emittedArguments: number;\n}\n\n// StreamState is the text and usage a stream has accumulated so far. The\n// writers read it to build the closing events, which repeat the whole text.\nexport interface StreamState {\n id: string;\n model: string;\n created: number;\n text: string;\n reasoning: string;\n reasoningSignature: string;\n reasoningEncrypted: string;\n stop: string;\n usage: Usage;\n tools: StreamTool[];\n}\n\n// StreamWriter is one downstream protocol's half of the encoder. Each writer\n// owns the block ordering of its protocol, so the shared encoder only decides\n// which events to forward.\nexport interface StreamWriter {\n start(): void;\n emitText(text: string): void;\n emitReasoning(text: string): void;\n emitReasoningSignature(signature: string): void;\n startTool(tool: StreamTool): void;\n emitToolDelta(tool: StreamTool, delta: string): void;\n emitError(message: string, errorType: string): void;\n finish(state: StreamState): void;\n}\n// SSEWriter writes SSE events to a sink, one event per flush.\nexport class SSEWriter {\n private readonly sink: StreamSink;\n private readonly encoder = new TextEncoder();\n\n constructor(sink: StreamSink) {\n this.sink = sink;\n }\n\n // sse writes value as the data of one SSE event.\n sse(eventName: string, value: unknown): void {\n this.rawSSE(eventName, JSON.stringify(value));\n }\n\n // rawSSE writes one SSE event. An empty event name omits the event line, as\n // Chat streams do.\n rawSSE(eventName: string, data: string): void {\n let frame = \"\";\n if (eventName !== \"\") {\n frame += `event: ${eventName}\\n`;\n }\n frame += `data: ${data}\\n\\n`;\n this.sink.write(this.encoder.encode(frame));\n }\n}\n\n// mergeBridgeUsage folds a usage report into the accumulated usage. A non-zero\n// field replaces the stored one, Total keeps the larger of the two, and Total\n// is finally raised to at least Input+Output so a report that leaves it out\n// still adds up.\nexport function mergeBridgeUsage(destination: Usage, source: Usage): Usage {\n const merged: Usage = {\n inputTokens:\n source.inputTokens !== 0 ? source.inputTokens : destination.inputTokens,\n outputTokens:\n source.outputTokens !== 0\n ? source.outputTokens\n : destination.outputTokens,\n totalTokens:\n source.totalTokens !== 0\n ? Math.max(destination.totalTokens, source.totalTokens)\n : destination.totalTokens,\n cachedInputTokens:\n source.cachedInputTokens !== 0\n ? source.cachedInputTokens\n : destination.cachedInputTokens,\n cacheCreationTokens:\n source.cacheCreationTokens !== 0\n ? source.cacheCreationTokens\n : destination.cacheCreationTokens,\n reasoningTokens:\n source.reasoningTokens !== 0\n ? source.reasoningTokens\n : destination.reasoningTokens,\n };\n merged.totalTokens = Math.max(\n merged.totalTokens,\n merged.inputTokens + merged.outputTokens,\n );\n return merged;\n}\n", "import type { BridgeBlock, BridgeResponse, Usage } from \"../types/inference.js\";\nimport type { Protocol } from \"../types/config.js\";\nimport { emptyBlock } from \"./block.js\";\nimport { encodeBridgeResponse } from \"./response-encode.js\";\nimport { SSEReader } from \"./sse.js\";\nimport { StreamParser } from \"./stream-parser.js\";\nimport { mergeBridgeUsage } from \"./stream-writer.js\";\nimport {\n errSSEUnexpectedEOF,\n type BridgeStreamEvent,\n} from \"./stream-types.js\";\n\n// collapseStream consumes one complete upstream SSE stream and synthesizes the\n// equivalent single (non-streaming) response document in the same protocol.\n//\n// It exists for upstream lanes that only serve streaming responses: the\n// gateway forces stream:true on the wire and collapses the events back so\n// downstream clients that asked for a plain JSON reply keep working. model is\n// the response's model name unless the stream's start event names one. A\n// stream that reports an error, cannot be parsed or ends without a terminal\n// event is an error.\nexport async function collapseStream(\n source: AsyncIterable<Uint8Array>,\n protocol: Protocol,\n model: string,\n): Promise<string> {\n const parser = new StreamParser(protocol);\n const accumulator = new CollapseAccumulator(model);\n const reader = new SSEReader();\n let terminated = false;\n let streamError: Error | undefined;\n\n for await (const chunk of source) {\n for (const record of reader.push(chunk)) {\n const outcome = consumeRecord(\n parser,\n accumulator,\n record.event,\n record.data,\n );\n if (outcome.stop) {\n terminated = true;\n break;\n }\n if (outcome.error !== undefined) {\n streamError = outcome.error;\n break;\n }\n }\n if (terminated || streamError !== undefined) {\n break;\n }\n }\n\n if (streamError !== undefined) {\n throw streamError;\n }\n if (!terminated) {\n // A record that was never terminated by a blank line is a truncated\n // stream, and so is a stream that ended without a terminal event.\n reader.close();\n throw errSSEUnexpectedEOF;\n }\n const response = accumulator.response();\n return JSON.stringify(encodeBridgeResponse(protocol, response));\n}\n\n// consumeRecord parses one SSE record and folds its events into the\n// accumulator. A done event stops the read, an error event fails it.\nfunction consumeRecord(\n parser: StreamParser,\n accumulator: CollapseAccumulator,\n eventName: string,\n data: string,\n): { stop: boolean; error: Error | undefined } {\n let events: BridgeStreamEvent[];\n try {\n events = parser.parse(eventName, data);\n } catch (error) {\n return { stop: false, error: asError(error) };\n }\n for (const event of events) {\n if (event.kind === \"done\") {\n return { stop: true, error: undefined };\n }\n if (event.kind === \"error\") {\n const message =\n event.error !== \"\" ? event.error : \"upstream stream failed\";\n return { stop: false, error: new Error(message) };\n }\n accumulator.apply(event);\n }\n return { stop: false, error: undefined };\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\n// CollapseAccumulator folds bridge stream events into one bridge response.\n// It keeps the index of each tool call and the reasoning block that deltas\n// currently accumulate into.\nexport class CollapseAccumulator {\n private text = \"\";\n private readonly reasoning: BridgeBlock[] = [];\n private readonly tools: BridgeBlock[] = [];\n private readonly toolIndex = new Map<string, number>();\n private openReasoning: number | undefined;\n private id = \"\";\n private model: string;\n private stop = \"\";\n private usage: Usage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n reasoningTokens: 0,\n };\n private readonly created: number;\n\n constructor(model: string) {\n this.model = model;\n this.created = Math.floor(Date.now() / 1000);\n }\n\n // apply folds one stream event into the response. Reasoning text and\n // signatures accumulate into the open reasoning block, while encrypted\n // reasoning is stored in a block of its own that is closed at once.\n apply(event: BridgeStreamEvent): void {\n switch (event.kind) {\n case \"start\":\n if (event.responseID !== \"\") {\n this.id = event.responseID;\n }\n if (event.model !== \"\") {\n this.model = event.model;\n }\n return;\n case \"text\":\n this.text += event.text;\n return;\n case \"reasoning\": {\n if (\n event.text === \"\" &&\n event.encrypted === \"\" &&\n event.signature === \"\"\n ) {\n return;\n }\n const block = this.openReasoningBlock();\n block.text += event.text;\n if (event.encrypted !== \"\") {\n this.closeReasoning();\n const encrypted = this.openReasoningBlock();\n encrypted.encrypted += event.encrypted;\n this.closeReasoning();\n }\n return;\n }\n case \"reasoning_signature\": {\n const block = this.openReasoningBlock();\n block.signature += event.signature;\n return;\n }\n case \"tool_start\":\n this.toolBlock(event.toolKey, event.toolID, event.toolName);\n return;\n case \"tool_delta\": {\n const block = this.toolBlock(event.toolKey, event.toolID, event.toolName);\n block.argumentsJSON += event.text;\n return;\n }\n case \"usage\":\n if (event.usage !== undefined) {\n this.usage = mergeBridgeUsage(this.usage, event.usage);\n }\n return;\n case \"finish\":\n this.stop = event.stop;\n return;\n default:\n return;\n }\n }\n\n // openReasoningBlock returns the reasoning block that deltas accumulate\n // into, appending a new one when none is open: before the first reasoning\n // event, and after an encrypted event closed the previous block.\n private openReasoningBlock(): BridgeBlock {\n if (this.openReasoning === undefined) {\n this.reasoning.push(emptyBlock(\"reasoning\"));\n this.openReasoning = this.reasoning.length - 1;\n }\n const block = this.reasoning[this.openReasoning];\n if (block === undefined) {\n throw new Error(\"collapse accumulator lost its reasoning block\");\n }\n return block;\n }\n\n // closeReasoning closes the open reasoning block, so the next reasoning\n // delta starts a new one.\n private closeReasoning(): void {\n this.openReasoning = undefined;\n }\n\n // toolBlock returns the tool call for a stream tool key, appending it on\n // first sight and filling in an ID or name that earlier events lacked.\n private toolBlock(key: string, id: string, name: string): BridgeBlock {\n const index = this.toolIndex.get(key);\n if (index !== undefined) {\n const block = this.tools[index];\n if (block === undefined) {\n throw new Error(\"collapse accumulator lost its tool block\");\n }\n if (block.id === \"\") {\n block.id = id;\n }\n if (block.name === \"\") {\n block.name = name;\n }\n return block;\n }\n const block = emptyBlock(\"tool_call\");\n block.id = id;\n block.name = name;\n this.tools.push(block);\n this.toolIndex.set(key, this.tools.length - 1);\n return block;\n }\n\n response(): BridgeResponse {\n return {\n id: this.id,\n model: this.model,\n text: this.text,\n reasoning: [...this.reasoning],\n tools: [...this.tools],\n stop: this.stop,\n error: \"\",\n usage: this.usage,\n created: this.created,\n };\n }\n}\n", "export class ProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ProtocolError\";\n }\n}\n\nexport type ProtocolErrorKind =\n | \"invalid_request_error\"\n | \"authentication_error\"\n | \"client_canceled\"\n | \"proxy_error\"\n | \"upstream_timeout\"\n | \"upstream_error\"\n | \"rotation_unavailable\"\n | \"server_error\";\n\nexport interface ErrorEnvelope {\n status: number;\n body: Record<string, unknown>;\n}\n\n// buildErrorEnvelope renders the error body in the shape the protocol's clients\n// expect: {\"type\":\"error\",\"error\":{...}} for Anthropic, and the OpenAI\n// {\"error\":{message,type,param,code}} shape for every other protocol.\nexport function buildErrorEnvelope(\n protocol: string,\n status: number,\n message: string,\n kind: ProtocolErrorKind,\n): ErrorEnvelope {\n if (protocol === \"anthropic\") {\n return {\n status,\n body: { type: \"error\", error: { type: kind, message } },\n };\n }\n return {\n status,\n body: {\n error: { message, type: kind, param: null, code: null },\n },\n };\n}\n", "import type { BridgeBlock } from \"../types/inference.js\";\nimport {\n boolAt,\n firstString,\n isPlainObject,\n mapAt,\n stringAt,\n} from \"./json-util.js\";\nimport { emptyBlock, withText, withURL } from \"./block.js\";\nimport { ProtocolError } from \"./error.js\";\n\n// decodeOpenAIBlocks decodes Chat or Responses content into bridge blocks. It\n// accepts a plain string, a single part object or an array of parts; null and\n// \"\" decode to no blocks. Any other part type is an error rather than being\n// dropped.\nexport function decodeOpenAIBlocks(value: unknown): BridgeBlock[] {\n if (typeof value === \"string\") {\n return value === \"\" ? [] : [withText(emptyBlock(\"text\"), value)];\n }\n if (isPlainObject(value)) {\n return decodeOpenAIBlocks([value]);\n }\n if (Array.isArray(value)) {\n const blocks: BridgeBlock[] = [];\n for (const raw of value) {\n if (!isPlainObject(raw)) {\n throw new ProtocolError(\"OpenAI content block must be an object\");\n }\n const type = stringAt(raw, \"type\");\n switch (type) {\n case \"text\":\n case \"input_text\":\n case \"output_text\":\n blocks.push(withText(emptyBlock(\"text\"), stringAt(raw, \"text\")));\n break;\n case \"image_url\":\n blocks.push(\n withURL(\n emptyBlock(\"image\"),\n firstString(\n stringAt(raw, \"image_url\", \"url\"),\n stringAt(raw, \"image_url\"),\n ),\n ),\n );\n break;\n case \"input_image\":\n blocks.push(withURL(emptyBlock(\"image\"), stringAt(raw, \"image_url\")));\n break;\n case \"file\":\n case \"input_file\": {\n const file = mapAt(raw, \"file\");\n const block = emptyBlock(\"file\");\n block.fileId = firstString(\n stringAt(raw, \"file_id\"),\n stringAt(file, \"file_id\"),\n );\n block.filename = firstString(\n stringAt(raw, \"filename\"),\n stringAt(file, \"filename\"),\n );\n block.mediaType = firstString(\n stringAt(raw, \"media_type\"),\n stringAt(file, \"media_type\"),\n );\n block.data = firstString(\n stringAt(raw, \"file_data\"),\n stringAt(file, \"file_data\"),\n );\n blocks.push(block);\n break;\n }\n default:\n throw new ProtocolError(\n `unsupported OpenAI content block type ${JSON.stringify(type)}`,\n );\n }\n }\n return blocks;\n }\n if (value === undefined || value === null) {\n return [];\n }\n throw new ProtocolError(\"unsupported OpenAI content value\");\n}\n\n// decodeAnthropicBlocks decodes Anthropic content (a string, a single block or\n// an array of blocks) into bridge blocks. thinking and redacted_thinking\n// become reasoning blocks, a text document becomes plain text and any other\n// document a file, and an unknown block type is an error.\nexport function decodeAnthropicBlocks(value: unknown): BridgeBlock[] {\n if (typeof value === \"string\") {\n return value === \"\" ? [] : [withText(emptyBlock(\"text\"), value)];\n }\n const blocks: BridgeBlock[] = [];\n for (const raw of asBlocks(value)) {\n if (!isPlainObject(raw)) {\n throw new ProtocolError(\"Anthropic content block must be an object\");\n }\n const type = stringAt(raw, \"type\");\n switch (type) {\n case \"thinking\": {\n const block = emptyBlock(\"reasoning\");\n block.text = stringAt(raw, \"thinking\");\n block.signature = stringAt(raw, \"signature\");\n blocks.push(block);\n break;\n }\n case \"redacted_thinking\": {\n const block = emptyBlock(\"reasoning\");\n block.encrypted = stringAt(raw, \"data\");\n blocks.push(block);\n break;\n }\n case \"text\":\n blocks.push(withText(emptyBlock(\"text\"), stringAt(raw, \"text\")));\n break;\n case \"image\": {\n const source = mapAt(raw, \"source\");\n const block = emptyBlock(\"image\");\n if (stringAt(source, \"type\") === \"url\") {\n block.url = stringAt(source, \"url\");\n } else {\n block.mediaType = stringAt(source, \"media_type\");\n block.data = stringAt(source, \"data\");\n }\n blocks.push(block);\n break;\n }\n case \"document\": {\n const source = mapAt(raw, \"source\");\n if (stringAt(source, \"type\") === \"text\") {\n blocks.push(\n withText(\n emptyBlock(\"text\"),\n firstString(stringAt(source, \"data\"), stringAt(source, \"text\")),\n ),\n );\n break;\n }\n const block = emptyBlock(\"file\");\n block.url = stringAt(source, \"url\");\n block.mediaType = stringAt(source, \"media_type\");\n block.data = firstString(\n stringAt(source, \"data\"),\n stringAt(source, \"text\"),\n );\n block.filename = stringAt(raw, \"title\");\n blocks.push(block);\n break;\n }\n case \"tool_use\": {\n const block = emptyBlock(\"tool_call\");\n block.id = stringAt(raw, \"id\");\n block.name = stringAt(raw, \"name\");\n block.arguments = raw[\"input\"];\n blocks.push(block);\n break;\n }\n case \"tool_result\": {\n const block = emptyBlock(\"tool_result\");\n block.callId = stringAt(raw, \"tool_use_id\");\n block.result = raw[\"content\"];\n block.isError = boolAt(raw, \"is_error\") ?? false;\n blocks.push(block);\n break;\n }\n default:\n throw new ProtocolError(\n `unsupported Anthropic content block type ${JSON.stringify(type)}`,\n );\n }\n }\n return blocks;\n}\n\n// asBlocks returns the value as an array of parts, promoting a single part.\nfunction asBlocks(value: unknown): unknown[] {\n if (value === undefined || value === null) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n", "import type { BridgeBlock, BridgeResponse } from \"../types/inference.js\";\r\nimport { firstString, intAt, isPlainObject, sliceAt, stringAt } from \"./json-util.js\";\r\nimport { emptyBlock } from \"./block.js\";\r\nimport { ProtocolError } from \"./error.js\";\r\nimport { decodeAnthropicBlocks, decodeOpenAIBlocks } from \"./decode-blocks.js\";\r\nimport {\r\n canonicalAnthropicStop,\r\n canonicalChatStop,\r\n canonicalResponsesIncomplete,\r\n decodeAnthropicUsage,\r\n decodeOpenAIUsage,\r\n} from \"./response-usage.js\";\r\n\r\n// decodeChatReasoning reads a Chat message's reasoning into one block: the\r\n// reasoning_content string, or the \"reasoning\" string when reasoning_content\r\n// is absent, together with any reasoning_signature.\r\nfunction decodeChatReasoning(\r\n message: Record<string, unknown>,\r\n): BridgeBlock[] {\r\n let value = message[\"reasoning_content\"];\r\n if (value === undefined) {\r\n value = message[\"reasoning\"];\r\n }\r\n if (typeof value !== \"string\") {\r\n return [];\r\n }\r\n const block = emptyBlock(\"reasoning\");\r\n block.text = value;\r\n block.signature = stringAt(message, \"reasoning_signature\");\r\n return [block];\r\n}\r\n\r\n// decodeResponsesReasoning folds a Responses reasoning item into one block: its\r\n// summary and content texts are concatenated, and its ID and encrypted_content\r\n// are kept.\r\nfunction decodeResponsesReasoning(\r\n item: Record<string, unknown>,\r\n): BridgeBlock[] {\r\n let text = \"\";\r\n for (const raw of asArray(item[\"summary\"])) {\r\n text += stringAt(raw, \"text\");\r\n }\r\n const content = item[\"content\"];\r\n if (content !== undefined && content !== null) {\r\n for (const raw of asArray(content)) {\r\n text += stringAt(raw, \"text\");\r\n }\r\n }\r\n const encrypted = stringAt(item, \"encrypted_content\");\r\n if (text === \"\" && encrypted === \"\") {\r\n return [];\r\n }\r\n const block = emptyBlock(\"reasoning\");\r\n block.id = stringAt(item, \"id\");\r\n block.text = text;\r\n block.encrypted = encrypted;\r\n return [block];\r\n}\r\n\r\n// asArray returns the value as an array, promoting a single value.\r\nfunction asArray(value: unknown): unknown[] {\r\n if (value === undefined || value === null) {\r\n return [];\r\n }\r\n return Array.isArray(value) ? value : [value];\r\n}\r\n\r\n// decodeBridgeResponse decodes a complete response body of the given protocol\r\n// into the bridge model. An error envelope or error status is reported in\r\n// response.error, an unknown output item, content block or protocol is an\r\n// error, and a missing creation time defaults to now.\r\nexport function decodeBridgeResponse(\r\n protocol: string,\r\n input: Record<string, unknown>,\r\n): BridgeResponse {\r\n const response: BridgeResponse = {\r\n id: stringAt(input, \"id\"),\r\n model: stringAt(input, \"model\"),\r\n text: \"\",\r\n reasoning: [],\r\n tools: [],\r\n stop: \"\",\r\n error: \"\",\r\n usage: {\r\n inputTokens: 0,\r\n outputTokens: 0,\r\n totalTokens: 0,\r\n cachedInputTokens: 0,\r\n cacheCreationTokens: 0,\r\n reasoningTokens: 0,\r\n },\r\n created: intAt(input, \"created\"),\r\n };\r\n if (response.created === 0) {\r\n response.created = intAt(input, \"created_at\");\r\n }\r\n if (response.created === 0) {\r\n response.created = Math.floor(Date.now() / 1000);\r\n }\r\n switch (protocol) {\r\n case \"chat\":\r\n decodeChatResponse(response, input);\r\n break;\r\n case \"responses\":\r\n decodeResponsesResponse(response, input);\r\n break;\r\n case \"anthropic\":\r\n decodeAnthropicResponse(response, input);\r\n break;\r\n default:\r\n throw new ProtocolError(\r\n `unsupported response protocol ${JSON.stringify(protocol)}`,\r\n );\r\n }\r\n return response;\r\n}\r\n\r\nfunction decodeChatResponse(\r\n response: BridgeResponse,\r\n input: Record<string, unknown>,\r\n): void {\r\n const message = stringAt(input, \"error\", \"message\");\r\n if (message !== \"\") {\r\n response.error = message;\r\n return;\r\n }\r\n const choices = sliceAt(input, \"choices\");\r\n if (choices.length === 0) {\r\n throw new ProtocolError(\"chat response contains no choices\");\r\n }\r\n const choice = choices[0];\r\n const body = isPlainObject(choice) ? choice : {};\r\n const messageBody = isPlainObject(body[\"message\"]) ? body[\"message\"] : {};\r\n response.reasoning = decodeChatReasoning(messageBody);\r\n const blocks = decodeOpenAIBlocks(messageBody[\"content\"]);\r\n response.text = responseTextBlocks(blocks, \"Chat\");\r\n for (const raw of sliceAt(messageBody, \"tool_calls\")) {\r\n const call = isPlainObject(raw) ? raw : {};\r\n const fn = isPlainObject(call[\"function\"]) ? call[\"function\"] : {};\r\n const block = emptyBlock(\"tool_call\");\r\n block.id = stringAt(call, \"id\");\r\n block.name = stringAt(fn, \"name\");\r\n block.argumentsJSON = stringAt(fn, \"arguments\");\r\n response.tools.push(block);\r\n }\r\n response.stop = canonicalChatStop(stringAt(body, \"finish_reason\"));\r\n response.usage = decodeOpenAIUsage(mapOrEmpty(input, \"usage\"));\r\n}\r\n\r\nfunction decodeResponsesResponse(\r\n response: BridgeResponse,\r\n input: Record<string, unknown>,\r\n): void {\r\n for (const raw of sliceAt(input, \"output\")) {\r\n const item = isPlainObject(raw) ? raw : {};\r\n switch (stringAt(item, \"type\")) {\r\n case \"reasoning\":\r\n response.reasoning.push(...decodeResponsesReasoning(item));\r\n break;\r\n case \"message\": {\r\n const blocks = decodeOpenAIBlocks(item[\"content\"]);\r\n response.text += responseTextBlocks(blocks, \"Responses\");\r\n break;\r\n }\r\n case \"function_call\": {\r\n const block = emptyBlock(\"tool_call\");\r\n block.id = firstString(stringAt(item, \"call_id\"), stringAt(item, \"id\"));\r\n block.name = stringAt(item, \"name\");\r\n block.argumentsJSON = stringAt(item, \"arguments\");\r\n response.tools.push(block);\r\n break;\r\n }\r\n default:\r\n throw new ProtocolError(\r\n `Responses response has unsupported output item type ${JSON.stringify(stringAt(item, \"type\"))}`,\r\n );\r\n }\r\n }\r\n response.stop = response.tools.length > 0 ? \"tool_calls\" : \"stop\";\r\n const status = stringAt(input, \"status\");\r\n if (status === \"incomplete\") {\r\n response.stop = canonicalResponsesIncomplete(\r\n stringAt(input, \"incomplete_details\", \"reason\"),\r\n );\r\n } else if (status === \"failed\") {\r\n response.stop = \"error\";\r\n response.error = firstString(\r\n stringAt(input, \"error\", \"message\"),\r\n \"upstream Responses request failed\",\r\n );\r\n }\r\n response.usage = decodeOpenAIUsage(mapOrEmpty(input, \"usage\"));\r\n}\r\n\r\nfunction decodeAnthropicResponse(\r\n response: BridgeResponse,\r\n input: Record<string, unknown>,\r\n): void {\r\n if (stringAt(input, \"type\") === \"error\") {\r\n response.error = firstString(\r\n stringAt(input, \"error\", \"message\"),\r\n \"upstream Anthropic request failed\",\r\n );\r\n }\r\n const blocks = decodeAnthropicBlocks(input[\"content\"]);\r\n for (const block of blocks) {\r\n if (block.kind === \"reasoning\") {\r\n response.reasoning.push(block);\r\n } else if (block.kind === \"text\") {\r\n response.text += block.text;\r\n } else if (block.kind === \"tool_call\") {\r\n response.tools.push(block);\r\n } else {\r\n throw new ProtocolError(\r\n `Anthropic response contains unsupported ${block.kind} content block`,\r\n );\r\n }\r\n }\r\n response.stop = canonicalAnthropicStop(stringAt(input, \"stop_reason\"));\r\n response.usage = decodeAnthropicUsage(mapOrEmpty(input, \"usage\"));\r\n}\r\n\r\n// mapOrEmpty returns the value at the key as an object, or an empty object.\r\nexport function mapOrEmpty(\r\n value: Record<string, unknown>,\r\n key: string,\r\n): Record<string, unknown> {\r\n const found = value[key];\r\n return isPlainObject(found) ? found : {};\r\n}\r\n\r\n// responseTextBlocks joins the text of blocks, erroring on any other kind:\r\n// neither a Chat message nor a Responses output message may carry more than\r\n// text.\r\nfunction responseTextBlocks(blocks: BridgeBlock[], protocol: string): string {\r\n let text = \"\";\r\n for (const block of blocks) {\r\n if (block.kind !== \"text\") {\r\n throw new ProtocolError(\r\n `${protocol} response contains unsupported ${block.kind} content block`,\r\n );\r\n }\r\n text += block.text;\r\n }\r\n return text;\r\n}\r\n", "import type { BridgeResponse } from \"../types/inference.js\";\nimport { isPlainObject, sliceAt, stringAt } from \"./json-util.js\";\nimport { ProtocolError } from \"./error.js\";\nimport { decodeBridgeResponse } from \"./response-decode.js\";\nimport { encodeBridgeResponse } from \"./response-encode.js\";\n\n// convertResponse converts a serialized response body from one protocol to\n// another. A same-protocol body is returned unchanged; otherwise the body is\n// decoded into the bridge model and re-encoded for the target. An upstream\n// error envelope becomes an error, and so does a body the target protocol\n// cannot represent.\nexport function convertResponse(\n from: string,\n to: string,\n body: string,\n): string {\n if (from === to) {\n return body;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(body) as unknown;\n } catch (error) {\n throw new ProtocolError(\n `invalid upstream response JSON: ${(error as Error).message}`,\n );\n }\n if (!isPlainObject(parsed)) {\n throw new ProtocolError(\"upstream response must be a JSON object\");\n }\n const response = decodeBridgeResponse(from, parsed);\n if (response.error !== \"\" || response.stop === \"error\") {\n throw new ProtocolError(\n `upstream response failed: ${response.error !== \"\" ? response.error : \"upstream response failed\"}`,\n );\n }\n return JSON.stringify(encodeBridgeResponse(to, response));\n}\n\n// renameResponseTool rewrites tool call names matching fromName to toName\n// inside a serialized JSON response or SSE event data object for the given\n// protocol. It restores a client's original read-related tool name after the\n// v1 lane's shaper aliased it to \"read\" on the outbound wire.\nexport function renameResponseTool(\n body: string,\n protocol: string,\n fromName: string,\n toName: string,\n): string {\n if (fromName === \"\" || toName === \"\" || fromName === toName || body === \"\") {\n return body;\n }\n if (!body.includes(fromName)) {\n return body;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(body) as unknown;\n } catch {\n return body;\n }\n if (!isPlainObject(parsed)) {\n return body;\n }\n if (!renameToolInMap(parsed, protocol, fromName, toName)) {\n return body;\n }\n return JSON.stringify(parsed);\n}\n\n// renameToolInMap rewrites matching tool names in a decoded response or stream\n// event and reports whether anything changed. Every place a protocol reports a\n// tool call is visited.\nfunction renameToolInMap(\n payload: Record<string, unknown>,\n protocol: string,\n fromName: string,\n toName: string,\n): boolean {\n let changed = false;\n switch (protocol) {\n case \"chat\": {\n for (const rawChoice of sliceAt(payload, \"choices\")) {\n const choice = isPlainObject(rawChoice) ? rawChoice : {};\n for (const key of [\"message\", \"delta\"]) {\n const container = isPlainObject(choice[key]) ? choice[key] : {};\n for (const rawCall of sliceAt(container, \"tool_calls\")) {\n const call = isPlainObject(rawCall) ? rawCall : {};\n const fn = call[\"function\"];\n if (isPlainObject(fn) && stringAt(fn, \"name\") === fromName) {\n fn[\"name\"] = toName;\n changed = true;\n }\n }\n }\n }\n break;\n }\n case \"responses\": {\n const item = payload[\"item\"];\n if (\n isPlainObject(item) &&\n stringAt(item, \"type\") === \"function_call\" &&\n stringAt(item, \"name\") === fromName\n ) {\n item[\"name\"] = toName;\n changed = true;\n }\n changed =\n renameItems(sliceAt(payload, \"output\"), fromName, toName) || changed;\n const envelope = payload[\"response\"];\n if (isPlainObject(envelope)) {\n changed =\n renameItems(sliceAt(envelope, \"output\"), fromName, toName) || changed;\n }\n break;\n }\n case \"anthropic\": {\n const block = payload[\"content_block\"];\n if (\n isPlainObject(block) &&\n stringAt(block, \"type\") === \"tool_use\" &&\n stringAt(block, \"name\") === fromName\n ) {\n block[\"name\"] = toName;\n changed = true;\n }\n changed =\n renameItems(sliceAt(payload, \"content\"), fromName, toName) || changed;\n break;\n }\n default:\n break;\n }\n return changed;\n}\n\n// renameItems rewrites the name of every tool_use or function_call item.\nfunction renameItems(\n items: unknown[],\n fromName: string,\n toName: string,\n): boolean {\n let changed = false;\n for (const raw of items) {\n const item = isPlainObject(raw) ? raw : {};\n const isTool =\n stringAt(item, \"type\") === \"function_call\" ||\n stringAt(item, \"type\") === \"tool_use\";\n if (isTool && stringAt(item, \"name\") === fromName) {\n item[\"name\"] = toName;\n changed = true;\n }\n }\n return changed;\n}\n\nexport type { BridgeResponse };\n", "{\n \"edit\": {\n \"description\": \"Edit the contents of a file by finding and replacing exact text. When editing text from Read output, preserve the exact indentation (tabs or spaces) and omit the line-number prefix, such as `1: `. Never include the prefix in oldString or newString. Write line breaks as \\\\n; the file's existing CRLF or LF line endings are matched and preserved. To change line endings themselves, make oldString and newString differ only in \\\\r; that edit applies to the exact bytes. If there is no exact match, the edit retries while ignoring typographic quote, dash, and space variants, then trailing whitespace on each line. The edit fails if oldString is not found. By default, oldString must identify a UNIQUE location. Multiple matches FAIL unless replaceAll is true. Add more surrounding context to disambiguate, or set replaceAll to true to replace every occurrence. Use replaceAll when the change should apply to every occurrence, such as renaming a variable.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"newString\": {\n \"description\": \"Text to replace oldString with (must differ from oldString)\",\n \"type\": \"string\"\n },\n \"oldString\": {\n \"description\": \"Exact text to find and replace\",\n \"type\": \"string\"\n },\n \"path\": {\n \"description\": \"File to edit\",\n \"type\": \"string\"\n },\n \"replaceAll\": {\n \"description\": \"Whether to replace every occurrence of oldString. When false, oldString must match exactly once. Defaults to false.\",\n \"type\": \"boolean\"\n }\n },\n \"required\": [\"path\", \"oldString\", \"newString\"],\n \"type\": \"object\"\n }\n },\n \"execute\": {\n \"description\": \"Run JavaScript in a confined Code Mode runtime to script tool calls and HTTP requests and compose their results.\\n`fetch` is available for HTTP requests. Imports, direct filesystem access, and timers are unavailable; all other external access goes through `tools`.\\nWithin `{ code }`, the only callable tools are those explicitly listed in the Code Mode catalog instructions or returned by the `search` function. Inside `{ code }`, ignore tools shown outside the Code Mode catalog. They are not available in the Code Mode runtime.\\nCall tools through `tools` using only exact paths and signatures from the catalog. Do not infer or normalize tool names; preserve bracket notation such as `tools.<namespace>[\\\"tool-name\\\"](input)`.\\nPrefer an explicit `return`; if omitted, the final top-level expression becomes the result.\\nAwait every call whose completion matters; pending calls are interrupted when execution ends. Run independent calls concurrently with `Promise.allSettled`.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"code\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\"code\"],\n \"type\": \"object\"\n }\n },\n \"glob\": {\n \"description\": \"Search file paths using a glob pattern (examples: \\\"**/*.ts\\\", \\\"src/**/*.tsx\\\").\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"hidden\": {\n \"description\": \"Include hidden files and directories (default: false).\",\n \"type\": \"boolean\"\n },\n \"limit\": {\n \"description\": \"Maximum number of matching files to return (default: 100)\",\n \"exclusiveMinimum\": 0,\n \"type\": \"integer\"\n },\n \"path\": {\n \"description\": \"Directory to search. Defaults to the current working directory.\",\n \"type\": \"string\"\n },\n \"pattern\": {\n \"description\": \"Glob pattern to match files against\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"pattern\"],\n \"type\": \"object\"\n }\n },\n \"grep\": {\n \"description\": \"Search file contents using ripgrep's regular expression syntax or literal text matching. Use it to locate specific code, symbols, or text patterns, and narrow searches with `path` or `include`. Returns matching file paths, line numbers, and line previews.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"caseSensitive\": {\n \"description\": \"Use case-sensitive matching (default: true).\",\n \"type\": \"boolean\"\n },\n \"include\": {\n \"description\": \"Glob pattern to filter files (for example, \\\"*.js\\\" or \\\"*.{ts,tsx}\\\")\",\n \"type\": \"string\"\n },\n \"limit\": {\n \"description\": \"Maximum number of matching lines to return (default: 100)\",\n \"exclusiveMinimum\": 0,\n \"type\": \"integer\"\n },\n \"literal\": {\n \"description\": \"Treat `pattern` as exact text instead of a regular expression (default: false).\",\n \"type\": \"boolean\"\n },\n \"path\": {\n \"description\": \"File or directory to search. Defaults to the current working directory.\",\n \"type\": \"string\"\n },\n \"pattern\": {\n \"description\": \"Regular expression or literal text to match in file contents.\",\n \"minLength\": 1,\n \"type\": \"string\"\n }\n },\n \"required\": [\"pattern\"],\n \"type\": \"object\"\n }\n },\n \"question\": {\n \"description\": \"Use this tool when you need to ask the user questions during execution. This allows you to:\\n1. Gather user preferences or requirements\\n2. Clarify ambiguous instructions\\n3. Get decisions on implementation choices as you work\\n4. Offer choices to the user about what direction to take.\\n\\nUsage notes:\\n- A \\\"Type your own answer\\\" option is added automatically; don't include a separate option for free form answers\\n- Set `multiple: true` to allow selecting more than one option\\n- If you recommend a specific option, make that the first option in the list and add \\\"(Recommended)\\\" at the end of the label\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"questions\": {\n \"description\": \"Questions to ask\",\n \"items\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"header\": {\n \"description\": \"Very short label (max 30 chars)\",\n \"type\": \"string\"\n },\n \"multiple\": {\n \"type\": \"boolean\"\n },\n \"options\": {\n \"description\": \"Available choices\",\n \"items\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"description\": {\n \"description\": \"Explanation of choice\",\n \"type\": \"string\"\n },\n \"label\": {\n \"description\": \"Display text (1-5 words, concise)\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"label\", \"description\"],\n \"type\": \"object\"\n },\n \"type\": \"array\"\n },\n \"question\": {\n \"description\": \"Complete question\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"question\", \"header\", \"options\"],\n \"type\": \"object\"\n },\n \"minItems\": 1,\n \"type\": \"array\"\n }\n },\n \"required\": [\"questions\"],\n \"type\": \"object\"\n }\n },\n \"read\": {\n \"description\": \"Read the contents of a file or directory. Supports text files, images, and PDFs. Images and PDFs are presented directly to the model. Each text line is prefixed by its 1-based line number as <line>: <content>. The prefix is for reference and is not part of the file content. Directory entries are returned one per line. Use offset and limit to read large files or directories in sections. Prefer one larger read over many small slices, and use grep to find specific content in large files.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"limit\": {\n \"description\": \"The maximum number of lines or directory entries to read (defaults to and capped at 2000)\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"offset\": {\n \"description\": \"The line or directory entry to start reading from (1-based)\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"path\": {\n \"description\": \"File or directory to read\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"path\"],\n \"type\": \"object\"\n }\n },\n \"shell\": {\n \"description\": \"Execute a shell command and return its output. Commands run on Linux using bash. Quote file paths containing spaces or special characters. Prefer dedicated tools over shell commands when possible. When output is large, the full result is saved to a file and a truncated preview is returned. Rely on automatic truncation unless filtering the output is more useful. Commands accept an optional timeout, background commands have no timeout by default. Background commands return immediately, and you will be notified when they complete.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"background\": {\n \"description\": \"Run the command in the background and return immediately (useful for dev servers and long-running builds). You do not need to use '&' at the end of the command when using this parameter. You will be notified when it completes. DO NOT poll for completion.\",\n \"type\": \"boolean\"\n },\n \"command\": {\n \"description\": \"Shell command string to execute\",\n \"type\": \"string\"\n },\n \"timeout\": {\n \"description\": \"Timeout in milliseconds. Set to 0 to disable the timeout. Defaults to 120000 for foreground commands. Background commands have no timeout by default.\",\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"workdir\": {\n \"description\": \"Working directory to execute the command in. Defaults to the current working directory. When possible, avoid changing directories in the command and set the working directory here instead.\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"command\"],\n \"type\": \"object\"\n }\n },\n \"skill\": {\n \"description\": \"Load a specialized skill's instructions and resources into the current conversation when the task at hand matches its description.\\n\\nThe skill ID must match an available skill or a skill explicitly referenced by the user.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"id\": {\n \"description\": \"The ID of an available skill or a skill explicitly referenced by the user\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"id\"],\n \"type\": \"object\"\n }\n },\n \"subagent\": {\n \"description\": \"Spawns an agent in a child session to work on the specified task.\\nThe output includes a sessionID you can pass back later to continue that specific conversation with the subagent.\\nNew child sessions start with fresh context, so include all relevant context and instructions when you don't pass a sessionID.\\nForeground (default) runs the subagent to completion and returns its final response.\\nBackground mode (background=true) launches it asynchronously and returns immediately; you are notified when it finishes.\\nUse background only for independent work that can run while you continue elsewhere.\\n\\nAvailable subagents:\\n- explore: Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. \\\"src/components/**/*.tsx\\\"), search code for keywords (eg. \\\"API endpoints\\\"), or answer questions about the codebase (eg. \\\"how do API endpoints work?\\\"). When calling this agent, specify the desired thoroughness level: \\\"quick\\\" for basic searches, \\\"medium\\\" for moderate exploration, or \\\"very thorough\\\" for comprehensive analysis across multiple locations and naming conventions.\\n- general: General-purpose agent for researching complex questions and executing multi-step tasks. Use this agent to execute multiple units of work in parallel.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"agent\": {\n \"description\": \"The type of specialized agent to use for this task. If the user asks for a subagent by a name that is not one of the available subagents, they most likely mean a model: pick a suitable agent and pass the name through the model parameter instead.\",\n \"type\": \"string\"\n },\n \"background\": {\n \"description\": \"Run the subagent in the background and return immediately. You will be notified when it completes. DO NOT sleep, poll, or proactively check on its progress.\",\n \"type\": \"boolean\"\n },\n \"description\": {\n \"description\": \"A short 3-5 word label for the task, displayed to the user\",\n \"type\": \"string\"\n },\n \"model\": {\n \"description\": \"NEVER set this unless the user explicitly asks for a particular model or variant. The value is written as \\\"providerID/modelID\\\", or \\\"providerID/modelID#variant\\\" to include a variant. Do not guess the ID: look the model up with the models tool, filtering to your own provider first.\",\n \"type\": \"string\"\n },\n \"prompt\": {\n \"description\": \"The task for the subagent to perform\",\n \"type\": \"string\"\n },\n \"sessionID\": {\n \"description\": \"Continue a specific previous subagent conversation by passing its sessionID. Calls without a sessionID start a new conversation.\",\n \"pattern\": \"^ses\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"agent\", \"description\", \"prompt\"],\n \"type\": \"object\"\n }\n },\n \"webfetch\": {\n \"description\": \"Fetch content from an HTTP or HTTPS URL and return it as text, markdown, or HTML. Markdown is the default.\\n\\nUse a more targeted tool when one is available. This tool is read-only. Large text results may be replaced with a preview while the complete output is retained in managed storage.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"format\": {\n \"description\": \"The format to return the content in. Defaults to markdown.\",\n \"enum\": [\"text\", \"markdown\", \"html\"],\n \"type\": \"string\"\n },\n \"timeout\": {\n \"description\": \"Optional timeout in seconds (maximum: 120)\",\n \"exclusiveMinimum\": 0,\n \"maximum\": 120,\n \"type\": \"number\"\n },\n \"url\": {\n \"description\": \"The HTTP or HTTPS URL to fetch content from\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"url\"],\n \"type\": \"object\"\n }\n },\n \"websearch\": {\n \"description\": \"Search the web using the user's selected search integration. Use this for current information beyond knowledge cutoff.\\n\\nThe current year is 2026. Use this year when searching for recent information or current events.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"query\": {\n \"description\": \"Websearch query\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"query\"],\n \"type\": \"object\"\n }\n },\n \"write\": {\n \"description\": \"Writes a file to the local filesystem, overwriting if one exists.\\n\\nMissing parent directories are created automatically.\\n\\nUse this tool to create new files or overwrite existing files. For partial changes, use the edit tool instead.\",\n \"parameters\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"content\": {\n \"description\": \"Content to write to the file\",\n \"type\": \"string\"\n },\n \"path\": {\n \"description\": \"Path to the file to write to\",\n \"type\": \"string\"\n }\n },\n \"required\": [\"path\", \"content\"],\n \"type\": \"object\"\n }\n }\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport { isPlainObject, sliceAt, stringAt } from \"./json-util.js\";\n\nexport const V1_READ_TOOL = \"read\";\n\nexport const V2_CORE_TOOLS = [\"shell\", \"edit\", \"glob\", \"grep\", \"read\"] as const;\n\nconst V1_DEPRECATED_READ_DESCRIPTION =\n \"Deprecated. This tool is provided for compatibility only. Do not call it.\";\n\ninterface ToolDefinition {\n description: string;\n parameters: Record<string, unknown>;\n}\n\nconst KNOWN_TOOLS: Map<string, ToolDefinition> = loadKnownTools();\n\nfunction loadKnownTools(): Map<string, ToolDefinition> {\n const map = new Map<string, ToolDefinition>();\n try {\n const raw = opencodeToolsJSON as unknown;\n if (isPlainObject(raw)) {\n for (const [name, value] of Object.entries(raw)) {\n if (!isPlainObject(value)) {\n continue;\n }\n const description =\n typeof value.description === \"string\" ? value.description : \"\";\n const parameters = isPlainObject(value.parameters)\n ? value.parameters\n : { type: \"object\", properties: {} };\n map.set(name, { description, parameters });\n }\n }\n } catch {\n // A missing tool table only degrades the free-tier tool gate.\n }\n return map;\n}\n\nimport opencodeToolsJSON from \"./tools/opencode_tools.json\" with { type: \"json\" };\n\nexport function knownOpencodeTool(name: string): ToolDefinition | undefined {\n return KNOWN_TOOLS.get(name);\n}\n\nexport function toolName(protocol: Protocol, item: unknown): string {\n if (protocol === \"chat\") {\n return stringAt(item, \"function\", \"name\");\n }\n return stringAt(item, \"name\");\n}\n\nfunction setToolName(protocol: Protocol, item: unknown, name: string): void {\n if (!isPlainObject(item)) {\n return;\n }\n if (protocol === \"chat\") {\n const fn = item.function;\n if (isPlainObject(fn)) {\n fn.name = name;\n }\n return;\n }\n item.name = name;\n}\n\nexport function v2Tool(protocol: Protocol, name: string): Record<string, unknown> {\n const definition = knownOpencodeTool(name);\n const description = definition?.description ?? `Agent tool ${name}`;\n const parameters = definition?.parameters ?? {\n type: \"object\",\n properties: {},\n };\n if (protocol === \"chat\") {\n return {\n type: \"function\",\n function: { name, description, parameters, strict: false },\n };\n }\n if (protocol === \"anthropic\") {\n return { name, description, input_schema: parameters };\n }\n return { type: \"function\", name, description, parameters };\n}\n\nexport function v2Toolset(\n protocol: Protocol,\n names: readonly string[] = V2_CORE_TOOLS,\n): Record<string, unknown>[] {\n return names.map((name) => v2Tool(protocol, name));\n}\n\nexport function isV1ReadToolCandidate(name: string): boolean {\n const lower = name.trim().toLowerCase();\n if (lower === \"\") {\n return false;\n }\n if (lower === V1_READ_TOOL) {\n return true;\n }\n const normalized = lower.replace(/[_\\-.]/g, \"\");\n if (\n [\n \"readfile\",\n \"fileread\",\n \"readfiles\",\n \"readtext\",\n \"readtextfile\",\n \"readcontent\",\n \"viewfile\",\n ].includes(normalized)\n ) {\n return true;\n }\n return (\n lower.startsWith(\"read_\") ||\n lower.startsWith(\"read-\") ||\n lower.endsWith(\"_read\") ||\n lower.endsWith(\"-read\")\n );\n}\n\nfunction v1DeprecatedReadTool(protocol: Protocol): Record<string, unknown> {\n const parameters = { type: \"object\", properties: {} };\n if (protocol === \"chat\") {\n return {\n type: \"function\",\n function: {\n name: V1_READ_TOOL,\n description: V1_DEPRECATED_READ_DESCRIPTION,\n parameters,\n },\n };\n }\n if (protocol === \"anthropic\") {\n return {\n name: V1_READ_TOOL,\n description: V1_DEPRECATED_READ_DESCRIPTION,\n input_schema: parameters,\n };\n }\n return {\n type: \"function\",\n name: V1_READ_TOOL,\n description: V1_DEPRECATED_READ_DESCRIPTION,\n parameters,\n };\n}\n\nexport function rewriteV1ToolReferences(\n payload: Record<string, unknown>,\n protocol: Protocol,\n fromName: string,\n toName: string,\n): void {\n if (fromName === \"\" || fromName === toName) {\n return;\n }\n if (protocol === \"chat\") {\n const choice = payload.tool_choice;\n if (isPlainObject(choice) && isPlainObject(choice.function)) {\n if (choice.function.name === fromName) {\n choice.function.name = toName;\n }\n }\n for (const raw of sliceAt(payload, \"messages\")) {\n for (const rawCall of sliceAt(raw, \"tool_calls\")) {\n if (isPlainObject(rawCall) && isPlainObject(rawCall.function)) {\n if (rawCall.function.name === fromName) {\n rawCall.function.name = toName;\n }\n }\n }\n }\n return;\n }\n if (protocol === \"responses\") {\n const choice = payload.tool_choice;\n if (isPlainObject(choice) && choice.name === fromName) {\n choice.name = toName;\n }\n for (const item of sliceAt(payload, \"input\")) {\n if (\n isPlainObject(item) &&\n item.type === \"function_call\" &&\n item.name === fromName\n ) {\n item.name = toName;\n }\n }\n return;\n }\n const choice = payload.tool_choice;\n if (isPlainObject(choice) && choice.name === fromName) {\n choice.name = toName;\n }\n for (const msg of sliceAt(payload, \"messages\")) {\n for (const block of sliceAt(msg, \"content\")) {\n if (\n isPlainObject(block) &&\n block.type === \"tool_use\" &&\n block.name === fromName\n ) {\n block.name = toName;\n }\n }\n }\n}\n\nexport interface V1ReadToolResult {\n alias: string;\n changed: boolean;\n}\n\nexport function ensureV1ReadTool(\n payload: Record<string, unknown>,\n protocol: Protocol,\n): V1ReadToolResult {\n const raw = payload.tools;\n if (raw === undefined) {\n payload.tools = [v1DeprecatedReadTool(protocol)];\n return { alias: \"\", changed: true };\n }\n if (!Array.isArray(raw)) {\n return { alias: \"\", changed: false };\n }\n const items = raw as unknown[];\n let candidateIndex = -1;\n let candidateName = \"\";\n let caseFoldCandidate = false;\n for (const [index, item] of items.entries()) {\n const name = toolName(protocol, item);\n if (name === \"\") {\n continue;\n }\n if (name === V1_READ_TOOL) {\n return { alias: \"\", changed: false };\n }\n if (name.toLowerCase() === V1_READ_TOOL) {\n if (!caseFoldCandidate) {\n candidateIndex = index;\n candidateName = name;\n caseFoldCandidate = true;\n }\n continue;\n }\n if (candidateIndex < 0 && isV1ReadToolCandidate(name)) {\n candidateIndex = index;\n candidateName = name;\n }\n }\n if (candidateIndex >= 0) {\n setToolName(protocol, items[candidateIndex], V1_READ_TOOL);\n rewriteV1ToolReferences(payload, protocol, candidateName, V1_READ_TOOL);\n payload.tools = items;\n return { alias: candidateName, changed: true };\n }\n items.push(v1DeprecatedReadTool(protocol));\n payload.tools = items;\n return { alias: \"\", changed: true };\n}\n\nexport function ensureV2Tools(\n payload: Record<string, unknown>,\n protocol: Protocol,\n): boolean {\n let changed = false;\n if (protocol === \"chat\") {\n if (payload.tool_choice === \"none\") {\n delete payload.tool_choice;\n changed = true;\n }\n if (payload.max_tokens !== undefined) {\n if (payload.max_completion_tokens === undefined) {\n payload.max_completion_tokens = payload.max_tokens;\n }\n delete payload.max_tokens;\n changed = true;\n } else if (payload.max_completion_tokens === undefined) {\n payload.max_completion_tokens = 32000;\n changed = true;\n }\n }\n const raw = payload.tools;\n if (raw === undefined) {\n payload.tools = v2Toolset(protocol);\n return true;\n }\n if (!Array.isArray(raw)) {\n return changed;\n }\n const items = raw as unknown[];\n const present = new Set<string>();\n for (const [index, item] of items.entries()) {\n const name = toolName(protocol, item);\n if (name === \"\") {\n continue;\n }\n present.add(name);\n if (knownOpencodeTool(name)) {\n items[index] = v2Tool(protocol, name);\n changed = true;\n }\n }\n const missing = V2_CORE_TOOLS.filter((name) => !present.has(name));\n if (missing.length > 0) {\n items.push(...v2Toolset(protocol, missing));\n changed = true;\n }\n if (!changed) {\n return false;\n }\n payload.tools = items;\n return true;\n}\n\nexport function ensureAnonymousChatUsage(\n payload: Record<string, unknown>,\n protocol: Protocol,\n): boolean {\n if (protocol !== \"chat\") {\n return false;\n }\n const options = payload.stream_options;\n if (!isPlainObject(options)) {\n payload.stream_options = { include_usage: true };\n return true;\n }\n if (options.include_usage === true) {\n return false;\n }\n options.include_usage = true;\n return true;\n}\n\nexport interface PreparedBody {\n body: string;\n alias: string;\n shaped: boolean;\n}\n\nexport function prepareAnonymousBody(\n rawBody: string,\n protocol: Protocol,\n v1: boolean,\n): PreparedBody {\n if (protocol === \"systemone\") {\n return { body: rawBody, alias: \"\", shaped: false };\n }\n let payload: unknown;\n try {\n payload = JSON.parse(rawBody);\n } catch {\n return { body: rawBody, alias: \"\", shaped: false };\n }\n if (!isPlainObject(payload)) {\n return { body: rawBody, alias: \"\", shaped: false };\n }\n let changed = false;\n if (payload.stream !== true) {\n payload.stream = true;\n changed = true;\n }\n if (ensureAnonymousChatUsage(payload, protocol)) {\n changed = true;\n }\n let alias = \"\";\n if (v1) {\n const result = ensureV1ReadTool(payload, protocol);\n alias = result.alias;\n if (result.changed) {\n changed = true;\n }\n } else if (ensureV2Tools(payload, protocol)) {\n changed = true;\n }\n if (!changed) {\n return { body: rawBody, alias, shaped: false };\n }\n return { body: JSON.stringify(payload), alias, shaped: true };\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport { collapseStream } from \"../protocol/collapse.js\";\nimport { convertRequest } from \"../protocol/convert.js\";\nimport { V2_USER_AGENT } from \"../protocol/lanes.js\";\nimport { convertResponse, renameResponseTool } from \"../protocol/response.js\";\nimport { V1_READ_TOOL } from \"../protocol/tools.js\";\nimport type { UpstreamRequest } from \"../protocol/upstream-request.js\";\n\nexport const KILO_GATEWAY_BASE = \"https://api.kilo.ai/api/gateway\";\nexport const KILO_ANONYMOUS_TOKEN = \"anonymous\";\n\n// Built-in free models across OpenCode Zen v2.2.5 and Kilo Free Gateway.\nexport const BUILTIN_FREE_MODELS = [\n \"beam-free\",\n \"deepseek-v4.1-flash-free\",\n \"glm-5.3-flash-free\",\n \"mimo-v2.6-flash-free\",\n \"nemotron-3.5-super-vl-free\",\n \"nemotron-3.5-lightning-free\",\n \"flint-40b-free\",\n \"big-pickle\",\n \"crouton-alpha-free\",\n \"iceman-free\",\n \"inkling-2-small-free\",\n \"kilo-auto/free\",\n \"reflection/beam-free\",\n \"nvidia/nemotron-3.5-super-vl:free\",\n \"nvidia/nemotron-3.5-lightning:free\",\n \"nvidia/nemotron-3-ultra-550b-a55b:free\",\n \"cohere/north-mini-code:free\",\n \"dots-studio/dots-3-note-preview:free\",\n \"stealth/crouton-alpha\",\n \"stealth/glyph-cluster\",\n \"liquid/lfm-3-1.7b:free\",\n \"openrouter/free\",\n] as const;\n\nconst KILO_DEFAULT_CHAIN = [\n \"reflection/beam-free\",\n \"kilo-auto/free\",\n \"nvidia/nemotron-3.5-lightning:free\",\n \"nvidia/nemotron-3.5-super-vl:free\",\n \"cohere/north-mini-code:free\",\n \"stealth/crouton-alpha\",\n \"openrouter/free\",\n] as const;\n\nconst KILO_EQUIVALENTS: Readonly<Record<string, string>> = {\n \"beam-free\": \"reflection/beam-free\",\n \"nemotron-3.5-lightning-free\": \"nvidia/nemotron-3.5-lightning:free\",\n \"nemotron-3.5-super-vl-free\": \"nvidia/nemotron-3.5-super-vl:free\",\n \"nemotron-3-super-free\": \"nvidia/nemotron-3.5-super-vl:free\",\n \"crouton-alpha-free\": \"stealth/crouton-alpha\",\n \"flint-40b-free\": \"openrouter/free\",\n \"deepseek-v4.1-flash-free\": \"cohere/north-mini-code:free\",\n \"deepseek-v4.1-flash\": \"cohere/north-mini-code:free\",\n \"north-mini-code-free\": \"cohere/north-mini-code:free\",\n \"glm-5.3-flash-free\": \"reflection/beam-free\",\n \"glm-5.3\": \"reflection/beam-free\",\n \"glm-5-free\": \"reflection/beam-free\",\n \"mimo-v2.6-flash-free\": \"reflection/beam-free\",\n \"mimo-v2-pro-free\": \"reflection/beam-free\",\n \"mimo-v2-omni-free\": \"reflection/beam-free\",\n \"minimax-m2.5-free\": \"reflection/beam-free\",\n \"minimax-m2.5\": \"reflection/beam-free\",\n \"big-pickle\": \"reflection/beam-free\",\n \"auto\": \"reflection/beam-free\",\n \"main\": \"reflection/beam-free\",\n \"fast\": \"reflection/beam-free\",\n \"sota\": \"reflection/beam-free\",\n \"sweet\": \"reflection/beam-free\",\n \"deep\": \"cohere/north-mini-code:free\",\n \"code\": \"cohere/north-mini-code:free\",\n \"vision\": \"nvidia/nemotron-3.5-super-vl:free\",\n \"vl\": \"nvidia/nemotron-3.5-super-vl:free\",\n};\n\nconst OPENCODE_FREE_EQUIVALENTS: Readonly<Record<string, string>> = {\n \"glm-5-free\": \"glm-5.3-flash-free\",\n \"glm-5.3\": \"glm-5.3-flash-free\",\n \"deepseek-v4.1-flash\": \"deepseek-v4.1-flash-free\",\n \"mimo-v2-pro-free\": \"mimo-v2.6-flash-free\",\n \"mimo-v2-omni-free\": \"mimo-v2.6-flash-free\",\n \"nemotron-3-super-free\": \"nemotron-3.5-super-vl-free\",\n \"minimax-m2.5-free\": \"beam-free\",\n \"minimax-m2.5\": \"beam-free\",\n \"kimi-k2.5-free\": \"beam-free\",\n \"kimi-k3\": \"beam-free\",\n \"qwen3.6-plus-free\": \"beam-free\",\n \"qwen3.8-max\": \"beam-free\",\n \"grok-4.6\": \"beam-free\",\n \"gpt-5-nano\": \"beam-free\",\n \"auto\": \"beam-free\",\n \"main\": \"beam-free\",\n \"fast\": \"beam-free\",\n \"sota\": \"beam-free\",\n \"sweet\": \"beam-free\",\n \"deep\": \"deepseek-v4.1-flash-free\",\n \"code\": \"deepseek-v4.1-flash-free\",\n \"vision\": \"nemotron-3.5-super-vl-free\",\n \"vl\": \"nemotron-3.5-super-vl-free\",\n \"reflection/beam-free\": \"beam-free\",\n \"nvidia/nemotron-3.5-lightning:free\": \"nemotron-3.5-lightning-free\",\n \"nvidia/nemotron-3.5-super-vl:free\": \"nemotron-3.5-super-vl-free\",\n \"stealth/crouton-alpha\": \"crouton-alpha-free\",\n};\n\nfunction stripModelDecorators(raw: string): string {\n let base = raw.trim();\n const parenIndex = base.lastIndexOf(\"(\");\n if (parenIndex > 0 && base.endsWith(\")\")) {\n base = base.slice(0, parenIndex).trim();\n }\n if (base.startsWith(\"opencode/\")) {\n return base.slice(\"opencode/\".length);\n }\n if (base.startsWith(\"kilo/\")) {\n return base.slice(\"kilo/\".length);\n }\n return base;\n}\n\n// isKiloModelId reports whether a model ID natively targets the Kilo Free Gateway.\nexport function isKiloModelId(raw: string): boolean {\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"kilo/\")) {\n return true;\n }\n const clean = stripModelDecorators(trimmed);\n return clean.includes(\"/\") || clean.endsWith(\":free\");\n}\n\n// resolveOpenCodeFreeModel maps aliases and retired v1 free model IDs onto\n// active OpenCode Zen v2.2.5 free model IDs.\nexport function resolveOpenCodeFreeModel(raw: string): string {\n const clean = stripModelDecorators(raw);\n return OPENCODE_FREE_EQUIVALENTS[clean] ?? clean;\n}\n\n// kiloFallbackChain returns the ordered list of Kilo Free Gateway model IDs\n// to try when failing over from an OpenCode Zen quota wall.\nexport function kiloFallbackChain(raw: string): string[] {\n const clean = stripModelDecorators(raw);\n const chain: string[] = [];\n if (isKiloModelId(raw)) {\n chain.push(clean);\n } else {\n const mapped = KILO_EQUIVALENTS[clean];\n if (mapped !== undefined) {\n chain.push(mapped);\n }\n }\n for (const fallback of KILO_DEFAULT_CHAIN) {\n if (!chain.includes(fallback)) {\n chain.push(fallback);\n }\n }\n return chain;\n}\n\n// buildKiloUpstreamRequest formats an OpenAI-compatible request for the\n// keyless Kilo Free Gateway.\nexport function buildKiloUpstreamRequest(\n kiloModel: string,\n protocol: Protocol,\n payload: Record<string, unknown>,\n stream: boolean,\n baseURL: string = KILO_GATEWAY_BASE,\n): UpstreamRequest {\n const converted =\n protocol === \"chat\" || protocol === \"systemone\"\n ? { ...payload }\n : convertRequest(protocol, \"chat\", payload);\n const bodyObj: Record<string, unknown> = {\n ...converted,\n model: kiloModel,\n stream,\n };\n const headers = new Headers({\n Authorization: `Bearer ${KILO_ANONYMOUS_TOKEN}`,\n \"Content-Type\": \"application/json\",\n Accept: stream ? \"text/event-stream\" : \"application/json\",\n \"User-Agent\": V2_USER_AGENT,\n });\n const url = `${baseURL.replace(/\\/+$/, \"\")}/v1/chat/completions`;\n return {\n url,\n headers,\n body: JSON.stringify(bodyObj),\n };\n}\n\n// normalizeUnlimitedResponse collapses SSE to JSON when the client requested\n// stream: false and converts protocol shapes when served via a fallback lane.\nexport async function normalizeUnlimitedResponse(\n response: Response,\n upstreamProtocol: Protocol,\n clientProtocol: Protocol,\n requestedModel: string,\n alias: string,\n clientWantsStream: boolean,\n): Promise<Response> {\n if (clientWantsStream) {\n return response;\n }\n const contentType = (response.headers.get(\"content-type\") ?? \"\").toLowerCase();\n const rawText = await response.text();\n const trimmed = rawText.trimStart();\n const isSSE =\n contentType.includes(\"text/event-stream\") ||\n trimmed.startsWith(\"data:\") ||\n trimmed.startsWith(\"event:\");\n let jsonText = rawText;\n if (isSSE) {\n const bytes = new TextEncoder().encode(`${rawText}\\n\\n`);\n const stream = {\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n yield bytes;\n },\n };\n jsonText = await collapseStream(stream, upstreamProtocol, requestedModel);\n }\n if (alias !== \"\") {\n jsonText = renameResponseTool(jsonText, upstreamProtocol, V1_READ_TOOL, alias);\n }\n if (upstreamProtocol !== clientProtocol) {\n jsonText = convertResponse(upstreamProtocol, clientProtocol, jsonText);\n }\n const headers = new Headers(response.headers);\n headers.set(\"Content-Type\", \"application/json\");\n return new Response(jsonText, { status: response.status, headers });\n}\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport type { RequestIDs } from \"../protocol/identity.js\";\nimport { buildUpstreamRequest } from \"../protocol/upstream-request.js\";\nimport { tierBaseURL } from \"../protocol/lanes.js\";\n\n// The anonymous credential is the literal token \"public\".\nexport const ANONYMOUS_CREDENTIAL = \"public\";\n\n// UpstreamResponse is the response of one upstream attempt.\nexport interface UpstreamResponse {\n status: number;\n headers: Headers;\n stream: AsyncIterable<Uint8Array>;\n}\n\n// UpstreamAttempt is one attempt at one key of one tier.\nexport interface UpstreamAttempt {\n tier: Tier;\n key: string;\n keyId: string;\n status: number;\n error: Error | undefined;\n durationMs: number;\n}\n\n// UpstreamClient sends the requests to the upstream lanes.\nexport class UpstreamClient {\n constructor(\n private readonly fetchImpl: typeof fetch = fetch,\n private readonly timeoutSeconds = 300,\n ) {}\n\n // send performs one attempt and returns the response. A non-2xx response is\n // returned as it is, so the caller can decide whether to rotate the key.\n async send(\n baseURL: string,\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n key: string,\n ): Promise<UpstreamResponse> {\n const request = buildUpstreamRequest(baseURL, protocol, body, ids, key);\n const controller = new AbortController();\n const timer = setTimeout(\n () => {\n controller.abort();\n },\n this.timeoutSeconds * 1000,\n );\n try {\n const response = await this.fetchImpl(request.url, {\n method: \"POST\",\n headers: request.headers,\n body: request.body,\n signal: controller.signal,\n });\n return {\n status: response.status,\n headers: response.headers,\n stream: streamOf(response),\n };\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n// streamOf turns a fetch response into a byte stream.\nfunction streamOf(response: Response): AsyncIterable<Uint8Array> {\n const body = response.body;\n if (body === null) {\n return emptyStream();\n }\n return body as unknown as AsyncIterable<Uint8Array>;\n}\n\n// emptyStream is a stream with no bytes.\nfunction emptyStream(): AsyncIterable<Uint8Array> {\n return {\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n return undefined;\n },\n };\n}\n\n// upstreamBaseURL returns the base URL of a tier.\nexport function upstreamBaseURL(\n upstream: { zen: string; go: string; anonymous: string },\n tier: Tier,\n anonymous: boolean,\n): string {\n if (anonymous) {\n return upstream.anonymous;\n }\n return tierBaseURL(upstream, tier);\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport type { RequestIDs } from \"../protocol/identity.js\";\nimport { isV1Upstream } from \"../protocol/lanes.js\";\nimport { buildUpstreamRequest } from \"../protocol/upstream-request.js\";\nimport { prepareAnonymousBody } from \"../protocol/tools.js\";\nimport { V1_BASE } from \"../config/defaults.js\";\nimport type { Logger } from \"../telemetry/logger.js\";\nimport type { Metrics } from \"../telemetry/metrics.js\";\nimport type { UpstreamAttemptRecord } from \"../types/inference.js\";\nimport { keyDisplayId } from \"../config/secrets.js\";\nimport { buildEdgeFetchInit } from \"../unlimited/lane.js\";\nimport { KILO_ANONYMOUS_TOKEN, KILO_GATEWAY_BASE } from \"../unlimited/kilo.js\";\nimport {\n type UpstreamResponse,\n} from \"./upstream-client.js\";\n\n// AttemptOutcome is the result of one upstream attempt.\nexport interface AttemptOutcome {\n response: UpstreamResponse | undefined;\n error: Error | undefined;\n attempts: number;\n records: UpstreamAttemptRecord[];\n // alias is the tool name the v1 lane aliased, which the response restores.\n alias: string;\n // shaped reports whether the body was force streamed upstream, so the\n // gateway collapses the events back for a non-streaming client.\n shaped: boolean;\n}\n\n// AttemptPools are the key pools of the two tiers.\nexport interface AttemptPools {\n zen: KeyPoolLike;\n go: KeyPoolLike;\n}\n\n// KeyPoolLike is the part of the key pool the runner uses.\nexport interface KeyPoolLike {\n isEmpty(): boolean;\n cursorFor(affinity: string): KeyCursorLike;\n markSuccess(node: KeyNodeLike): void;\n markFailure(\n node: KeyNodeLike,\n status: number,\n retryAfter: number,\n cooldownSeconds: number,\n ): void;\n}\n\n// KeyNodeLike is the part of a key node the runner uses.\nexport interface KeyNodeLike {\n key: string;\n failures: number;\n cooldownUntil: number;\n}\n\n// KeyCursorLike is the part of a key cursor the runner uses.\nexport interface KeyCursorLike {\n next(): KeyNodeLike | undefined;\n}\n\n// The upstream base URLs of the two tiers and the anonymous lane.\nexport interface UpstreamLanes {\n zen: string;\n go: string;\n anonymous: string;\n}\n\n// sendRequest performs one upstream request and returns the response.\nexport async function sendRequest(\n baseURL: string,\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n key: string,\n timeoutSeconds: number,\n edge = \"\",\n): Promise<UpstreamResponse> {\n const request = buildUpstreamRequest(baseURL, protocol, body, ids, key);\n const controller = new AbortController();\n const timer = setTimeout(\n () => {\n controller.abort();\n },\n timeoutSeconds * 1000,\n );\n try {\n const init = buildEdgeFetchInit(\n {\n method: \"POST\",\n headers: request.headers,\n body: request.body,\n signal: controller.signal,\n },\n edge,\n );\n const response = await fetch(request.url, init);\n return {\n status: response.status,\n headers: response.headers,\n stream: response.body as unknown as AsyncIterable<Uint8Array>,\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\n// shapeBody applies the upstream gate's request shaping to a body. The v1 lane\n// needs a read tool and the v2 lane the core tools.\nexport function shapeBody(\n body: string,\n protocol: Protocol,\n baseURL: string,\n): { body: string; alias: string; shaped: boolean } {\n return prepareAnonymousBody(body, protocol, isV1Upstream(baseURL));\n}\n\n// anonymousUpstreams lists the lanes the anonymous phase tries, in order. The\n// v2 /inference lane comes first, followed by the v1 /zen lane.\nexport function anonymousUpstreams(lanes: UpstreamLanes): string[] {\n const v1 = V1_BASE.replace(/\\/+$/, \"\");\n const primary = lanes.anonymous.replace(/\\/+$/, \"\");\n if (primary === \"\" || primary.toLowerCase() === v1.toLowerCase()) {\n return [v1];\n }\n return [primary, v1];\n}\n\n// outcomeFor classifies the result of one attempt.\nexport function outcomeFor(status: number, error: Error | undefined): string {\n if (error !== undefined) {\n return \"transport_error\";\n }\n if (status >= 200 && status < 300) {\n return \"success\";\n }\n if (status === 401 || status === 403) {\n return \"rejected\";\n }\n if (status === 429) {\n return \"quota_or_rate_limit\";\n }\n if (status >= 500) {\n return \"upstream_error\";\n }\n return \"request_error\";\n}\n\n// parseRetryAfterHeader reads the Retry-After header of a response.\nexport function parseRetryAfterHeader(headers: Headers | undefined): number {\n if (headers === undefined) {\n return 0;\n }\n const value = headers.get(\"retry-after\");\n if (value === null) {\n return 0;\n }\n const seconds = Number(value.trim());\n if (Number.isFinite(seconds) && seconds > 0) {\n return seconds * 1000;\n }\n const when = Date.parse(value);\n if (Number.isNaN(when)) {\n return 0;\n }\n return Math.max(when - Date.now(), 0);\n}\n\n// keyDisplayOf returns the display id of a key.\nexport function keyDisplayOf(key: string): string {\n return keyDisplayId(key);\n}\n\n// buildAttemptRecord builds and records one UpstreamAttemptRecord.\nexport function buildAttemptRecord(\n metrics: Metrics,\n params: {\n requestID: string;\n model: string;\n tier: \"zen\" | \"go\";\n attempt: number;\n keyID: string;\n channel: \"key\" | \"anonymous\";\n anonymous: boolean;\n proxyNode?: string;\n status: number;\n durationMs: number;\n error: Error | undefined;\n },\n): UpstreamAttemptRecord {\n const success =\n params.error === undefined && params.status >= 200 && params.status < 300;\n const record: UpstreamAttemptRecord = {\n time: new Date().toISOString(),\n request_id: params.requestID,\n model: params.model,\n tier: params.tier,\n attempt: params.attempt,\n key_id: params.keyID,\n channel: params.channel,\n anonymous: params.anonymous,\n proxy_node: params.proxyNode ?? \"\",\n status: params.status,\n duration_ms: params.durationMs,\n success,\n outcome: success ? \"success\" : outcomeFor(params.status, params.error),\n };\n metrics.recordAttempt({ ...record });\n return record;\n}\n\n// attemptKiloAnonymous performs one keyless attempt against the Kilo Free Gateway.\nexport async function attemptKiloAnonymous(\n metrics: Metrics,\n timeoutSeconds: number,\n body: string,\n ids: RequestIDs,\n requestID: string,\n model: string,\n kiloModel: string,\n): Promise<AttemptOutcome> {\n let payload: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(body) as unknown;\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n payload = { ...(parsed as Record<string, unknown>), model: kiloModel, stream: true };\n }\n } catch {\n // Keep original body if invalid JSON.\n }\n const kiloBody = Object.keys(payload).length > 0 ? JSON.stringify(payload) : body;\n const started = Date.now();\n let response: UpstreamResponse | undefined;\n let error: Error | undefined;\n try {\n response = await sendRequest(\n KILO_GATEWAY_BASE,\n \"chat\",\n kiloBody,\n ids,\n KILO_ANONYMOUS_TOKEN,\n timeoutSeconds,\n \"\",\n );\n } catch (caught) {\n error = caught instanceof Error ? caught : new Error(String(caught));\n }\n const durationMs = Date.now() - started;\n const status = response?.status ?? 0;\n const record = buildAttemptRecord(metrics, {\n requestID,\n model,\n tier: \"zen\",\n attempt: 1,\n keyID: \"kilo-anonymous\",\n channel: \"anonymous\",\n anonymous: true,\n proxyNode: \"kilo\",\n status,\n durationMs,\n error,\n });\n return {\n response,\n error,\n attempts: 1,\n records: [record],\n alias: \"\",\n shaped: true,\n };\n}\n\nexport type { Logger, Metrics, UpstreamAttemptRecord };\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport type { RequestIDs } from \"../protocol/identity.js\";\nimport { isNonRetryableClientResponse } from \"../protocol/upstream-request.js\";\nimport { tierBaseURL } from \"../protocol/lanes.js\";\nimport type { Logger } from \"../telemetry/logger.js\";\nimport type { Metrics } from \"../telemetry/metrics.js\";\nimport type { UpstreamAttemptRecord } from \"../types/inference.js\";\nimport { KeyPool } from \"../auth/key-pool.js\";\nimport {\n DEFAULT_AAAA_POOL,\n UnlimitedGuard,\n kiloFallbackChain,\n} from \"../unlimited/index.js\";\nimport {\n ANONYMOUS_CREDENTIAL,\n type UpstreamResponse,\n} from \"./upstream-client.js\";\nimport {\n anonymousUpstreams,\n attemptKiloAnonymous,\n buildAttemptRecord,\n keyDisplayOf,\n parseRetryAfterHeader,\n sendRequest,\n shapeBody,\n type AttemptOutcome,\n} from \"./attempt-helpers.js\";\n\n// AttemptRunner walks the keys of a tier and returns the first successful\n// response. A 401, 403 or 429 rotates to the next key, and any other 4xx is\n// returned immediately because retrying it on another key cannot help.\nexport class AttemptRunner {\n readonly guard = new UnlimitedGuard(DEFAULT_AAAA_POOL, \"gateway\");\n\n constructor(\n private readonly pools: Record<Tier, KeyPool>,\n private readonly upstream: { zen: string; go: string; anonymous: string },\n private readonly maxAttempts: number,\n private readonly timeoutSeconds: number,\n private readonly logger: Logger,\n private readonly metrics: Metrics,\n ) {}\n\n // runTier tries the keys of one tier until one of them succeeds.\n async runTier(\n tier: Tier,\n routeProtocol: Protocol,\n body: string,\n ids: RequestIDs,\n requestID: string,\n model: string,\n ): Promise<AttemptOutcome> {\n const pool = this.pools[tier];\n const records: UpstreamAttemptRecord[] = [];\n if (pool.isEmpty()) {\n return {\n response: undefined,\n error: new Error(`no ${tier} nodes configured`),\n attempts: 0,\n records,\n alias: \"\",\n shaped: false,\n };\n }\n const baseURL = tierBaseURL(this.upstream, tier);\n const cursor = pool.cursorFor(ids.session);\n let attempts = 0;\n let lastResponse: UpstreamResponse | undefined;\n let lastError: Error | undefined;\n const shaped = shapeBody(body, routeProtocol, baseURL);\n const sendBody = shaped.shaped ? shaped.body : body;\n\n while (attempts < this.maxAttempts) {\n const node = cursor.next();\n if (node === undefined) {\n break;\n }\n attempts += 1;\n const started = Date.now();\n let response: UpstreamResponse | undefined;\n let error: Error | undefined;\n const lane = this.guard.current();\n try {\n response = await sendRequest(\n baseURL,\n routeProtocol,\n sendBody,\n ids,\n node.key,\n this.timeoutSeconds,\n lane.edge,\n );\n } catch (caught) {\n error = caught instanceof Error ? caught : new Error(String(caught));\n }\n const durationMs = Date.now() - started;\n const status = response?.status ?? 0;\n const keyID = keyDisplayOf(node.key);\n const record = buildAttemptRecord(this.metrics, {\n requestID,\n model,\n tier,\n attempt: attempts,\n keyID,\n channel: \"key\",\n anonymous: false,\n proxyNode: lane.edge,\n status,\n durationMs,\n error,\n });\n records.push(record);\n\n if (record.success) {\n pool.markSuccess(node);\n this.logger.debug(\"upstream accepted request\", \"upstream\", {\n event: \"attempt_succeeded\",\n request_id: requestID,\n attempt: attempts,\n tier,\n key_id: keyID,\n status,\n duration_ms: durationMs,\n });\n return {\n response,\n error: undefined,\n attempts,\n records,\n alias: shaped.alias,\n shaped: shaped.shaped,\n };\n }\n if (response !== undefined && isNonRetryableClientResponse(status)) {\n this.logger.debug(\"upstream rejected a non-retryable request\", \"upstream\", {\n event: \"attempt_rejected\",\n request_id: requestID,\n attempt: attempts,\n tier,\n key_id: keyID,\n status,\n duration_ms: durationMs,\n });\n return {\n response,\n error: undefined,\n attempts,\n records,\n alias: shaped.alias,\n shaped: shaped.shaped,\n };\n }\n if (status === 429) {\n this.guard.hop(undefined, true);\n }\n pool.markFailure(\n node,\n status,\n parseRetryAfterHeader(response?.headers),\n this.timeoutSeconds,\n );\n lastResponse = response;\n lastError = error;\n }\n return {\n response: lastResponse,\n error: lastError,\n attempts,\n records,\n alias: shaped.alias,\n shaped: shaped.shaped,\n };\n }\n\n // runAnonymous tries the anonymous lane with the shared public credential\n // and self-healing guard rotation on quota walls (429 / FreeTierError).\n async runAnonymous(\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n requestID: string,\n model: string,\n ): Promise<AttemptOutcome> {\n const records: UpstreamAttemptRecord[] = [];\n const upstreams = anonymousUpstreams(this.upstream);\n let attempts = 0;\n\n const guarded = await this.guard.executeWithGuard(async (lane, hopAttempt) => {\n const activeIDs = hopAttempt === 1 ? ids : lane.ids;\n let lastOutcome: AttemptOutcome = {\n response: undefined,\n error: undefined,\n attempts: 0,\n records: [],\n alias: \"\",\n shaped: false,\n };\n for (const baseURL of upstreams) {\n const result = await this.attemptAnonymous(\n baseURL,\n protocol,\n body,\n activeIDs,\n requestID,\n model,\n lane.edge,\n );\n attempts += result.attempts;\n records.push(...result.records);\n lastOutcome = result;\n if (result.response !== undefined && result.response.status < 300) {\n return {\n status: result.response.status,\n bodyPreview: \"\",\n value: result,\n };\n }\n }\n if (protocol === \"chat\") {\n const kiloChain = kiloFallbackChain(model);\n const kiloModel = kiloChain[(hopAttempt - 1) % kiloChain.length] ?? \"reflection/beam-free\";\n const kiloResult = await attemptKiloAnonymous(\n this.metrics,\n this.timeoutSeconds,\n body,\n activeIDs,\n requestID,\n model,\n kiloModel,\n );\n attempts += kiloResult.attempts;\n records.push(...kiloResult.records);\n lastOutcome = kiloResult;\n if (kiloResult.response !== undefined && kiloResult.response.status < 300) {\n return {\n status: kiloResult.response.status,\n bodyPreview: \"\",\n value: kiloResult,\n };\n }\n }\n const status = lastOutcome.response?.status ?? 0;\n return {\n status,\n bodyPreview: status === 429 || status === 403 ? \"QuotaExceeded\" : \"\",\n value: lastOutcome,\n };\n });\n\n const final = guarded.value;\n return {\n response: final.response,\n error: final.response !== undefined && final.response.status < 300 ? undefined : final.error,\n attempts,\n records,\n alias: final.alias,\n shaped: final.shaped,\n };\n }\n\n // attemptAnonymous performs one anonymous attempt against one lane.\n private async attemptAnonymous(\n baseURL: string,\n protocol: Protocol,\n body: string,\n ids: RequestIDs,\n requestID: string,\n model: string,\n edge: string,\n ): Promise<AttemptOutcome> {\n const shaped = shapeBody(body, protocol, baseURL);\n const started = Date.now();\n let response: UpstreamResponse | undefined;\n let error: Error | undefined;\n try {\n response = await sendRequest(\n baseURL,\n protocol,\n shaped.shaped ? shaped.body : body,\n ids,\n ANONYMOUS_CREDENTIAL,\n this.timeoutSeconds,\n edge,\n );\n } catch (caught) {\n error = caught instanceof Error ? caught : new Error(String(caught));\n }\n const durationMs = Date.now() - started;\n const status = response?.status ?? 0;\n const record = buildAttemptRecord(this.metrics, {\n requestID,\n model,\n tier: \"zen\",\n attempt: 1,\n keyID: \"anonymous\",\n channel: \"anonymous\",\n anonymous: true,\n proxyNode: edge,\n status,\n durationMs,\n error,\n });\n return {\n response,\n error,\n attempts: 1,\n records: [record],\n alias: shaped.alias,\n shaped: shaped.shaped,\n };\n }\n}\n", "import type { LogLevel } from \"../types/config.js\";\nimport { SecretRedactor } from \"../config/secrets.js\";\nimport { LogBroker, type LogEvent } from \"./log-broker.js\";\n\n// The attribute keys whose value is masked in a log event.\nconst SENSITIVE_KEYS = [\"password\", \"authorization\", \"cookie\", \"secret\"];\n\n// The level order the logger filters on.\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n// Logger writes structured JSON lines to stdout and publishes the redacted\n// events to the broker the WebUI reads.\nexport class Logger {\n private level: LogLevel = \"info\";\n private readonly redactor = new SecretRedactor();\n\n constructor(private readonly broker: LogBroker) {}\n\n // setLevel changes the minimum level the logger emits.\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n // currentLevel reports the minimum level the logger emits.\n currentLevel(): LogLevel {\n return this.level;\n }\n\n // replaceSecrets sets the secrets the logger masks out of its output.\n replaceSecrets(secrets: string[]): void {\n this.redactor.replace(secrets);\n }\n\n // redact masks the configured secrets out of a text.\n redact(text: string): string {\n return this.redactor.redact(text);\n }\n\n debug(message: string, component: string, fields?: Record<string, unknown>): void {\n this.write(\"debug\", message, component, fields);\n }\n\n info(message: string, component: string, fields?: Record<string, unknown>): void {\n this.write(\"info\", message, component, fields);\n }\n\n warn(message: string, component: string, fields?: Record<string, unknown>): void {\n this.write(\"warn\", message, component, fields);\n }\n\n error(message: string, component: string, fields?: Record<string, unknown>): void {\n this.write(\"error\", message, component, fields);\n }\n\n private write(\n level: LogLevel,\n message: string,\n component: string,\n fields?: Record<string, unknown>,\n ): void {\n if (LEVEL_ORDER[level] < LEVEL_ORDER[this.level]) {\n return;\n }\n const redactedMessage = this.redact(message);\n const safeFields: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(fields ?? {})) {\n if (key === \"component\") {\n continue;\n }\n safeFields[key] = this.sanitizeValue(key, value);\n }\n const event: LogEvent = {\n sequence: 0,\n time: new Date().toISOString(),\n level,\n message: redactedMessage,\n component,\n fields: safeFields,\n };\n const line = JSON.stringify({\n time: event.time,\n level: level.toUpperCase(),\n msg: redactedMessage,\n component,\n ...safeFields,\n });\n process.stdout.write(`${line}\\n`);\n this.broker.publish(event);\n }\n\n // sanitizeValue masks the sensitive keys and redacts every string value.\n private sanitizeValue(key: string, value: unknown): unknown {\n if (isSensitiveKey(key)) {\n return \"***\";\n }\n if (typeof value === \"string\") {\n return this.redact(value);\n }\n if (value instanceof Error) {\n return this.redact(value.message);\n }\n return value;\n }\n}\n\n// isSensitiveKey reports whether a log attribute's key names a secret.\nexport function isSensitiveKey(key: string): boolean {\n const lower = key.toLowerCase();\n return SENSITIVE_KEYS.some((hint) => lower.includes(hint));\n}\n", "import type { Usage } from \"../types/inference.js\";\n\n// LogEvent is one structured log record. The sequence is monotonic and is\n// the SSE event id the WebUI resumes from.\nexport interface LogEvent {\n sequence: number;\n time: string;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n message: string;\n component: string;\n fields: Record<string, unknown>;\n}\n\n// The minimum ring size the broker keeps.\nconst MIN_RING_SIZE = 100;\n\n// The depth of a subscriber's channel. A subscriber that falls behind drops\n// events, which leaves a gap in the sequence the client detects.\nconst SUBSCRIBER_BUFFER = 128;\n\ntype Subscriber = (event: LogEvent) => void;\n\n// LogBroker keeps the recent log events in a ring and fans them out to the\n// live subscribers.\nexport class LogBroker {\n private buffer: LogEvent[] = [];\n private next = 0;\n\n private readonly subscribers = new Map<number, Subscriber>();\n private nextSubscriber = 0;\n\n constructor(private capacity: number) {\n this.capacity = clampCapacity(capacity);\n }\n\n // resize changes the ring size, keeping the newest events.\n resize(capacity: number): void {\n const next = clampCapacity(capacity);\n if (next === this.capacity) {\n return;\n }\n this.capacity = next;\n if (this.buffer.length > next) {\n this.buffer = this.buffer.slice(this.buffer.length - next);\n }\n }\n\n // publish stores an event and offers it to every subscriber.\n publish(event: LogEvent): void {\n this.next += 1;\n const published: LogEvent = { ...event, sequence: this.next };\n this.buffer.push(published);\n if (this.buffer.length > this.capacity) {\n this.buffer.shift();\n }\n for (const subscriber of [...this.subscribers.values()]) {\n subscriber(published);\n }\n }\n\n // recent returns the events after a cursor, oldest first, trimmed to the\n // newest limit. It reports a gap when the cursor is older than the oldest\n // retained event.\n recent(after: number, limit: number): { events: LogEvent[]; gap: boolean } {\n const first = this.buffer[0];\n const oldest = first?.sequence ?? 0;\n const gap = after > 0 && oldest > 0 && after + 1 < oldest;\n const events = this.buffer.filter((event) => event.sequence > after);\n const effective =\n limit < 1 || limit > events.length ? events.length : limit;\n return { events: events.slice(events.length - effective), gap };\n }\n\n // subscribe registers a live subscriber and returns the function that\n // removes it again.\n subscribe(subscriber: Subscriber): () => void {\n const id = this.nextSubscriber;\n this.nextSubscriber += 1;\n this.subscribers.set(id, subscriber);\n return () => {\n this.subscribers.delete(id);\n };\n }\n\n // size reports how many events the ring holds.\n size(): number {\n return this.buffer.length;\n }\n}\n\n// clampCapacity keeps the ring size within its allowed range.\nfunction clampCapacity(capacity: number): number {\n if (!Number.isFinite(capacity) || capacity < MIN_RING_SIZE) {\n return MIN_RING_SIZE;\n }\n return Math.trunc(capacity);\n}\n\nexport { SUBSCRIBER_BUFFER };\n\n// usageLogFields turns a usage report into log fields.\nexport function usageLogFields(usage: Usage): Record<string, unknown> {\n return {\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n total_tokens: usage.totalTokens,\n };\n}\n", "import type { Usage } from \"../types/inference.js\";\n\n// The latency bounds of the histogram, in milliseconds. The last bucket is\n// the overflow above the final bound.\nexport const LATENCY_BOUNDS = [\n 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000, 60000,\n] as const;\n\n// The minimum ring size the broker keeps.\nexport const BUCKET_COUNT = 60;\n\n// The capacity of the recent request and attempt buffers.\nexport const RECENT_REQUEST_CAPACITY = 10000;\nexport const RECENT_ATTEMPT_CAPACITY = 20000;\n\n// How many entries a snapshot returns.\nexport const RECENT_OUTPUT_LIMIT = 500;\n\n// The cap of the lifetime per-session token map.\nexport const MAX_LIFETIME_SESSIONS = 500;\n\n// TokenCounts is a token total.\nexport interface TokenCounts {\n input_tokens: number;\n output_tokens: number;\n cached_tokens: number;\n reasoning_tokens: number;\n total_tokens: number;\n}\n\n// ServerKeyUsage is the usage one local server key produced.\nexport interface ServerKeyUsage {\n requests: number;\n token_counts: TokenCounts;\n}\n\n// UsagePeriod is the usage of one period.\nexport interface UsagePeriod {\n requests: number;\n reported: number;\n coverage: number;\n tokens: TokenCounts;\n models: Record<string, TokenCounts>;\n tiers: Record<string, TokenCounts>;\n sessions: Record<string, TokenCounts>;\n server_keys: Record<string, ServerKeyUsage>;\n}\n\n// UsageSnapshot is the usage of the lifetime and of the last hour.\nexport interface UsageSnapshot {\n lifetime: UsagePeriod;\n last_hour: UsagePeriod;\n}\n\n// AttemptCounts counts the upstream attempts.\nexport interface AttemptCounts {\n total: number;\n success: number;\n failed: number;\n}\n\n// AttemptAggregate is the aggregate of the upstream attempts.\nexport interface AttemptAggregate extends AttemptCounts {\n success_rate: number;\n tiers: Record<string, AttemptCounts>;\n channels: Record<string, AttemptCounts>;\n keys: Record<string, AttemptCounts>;\n}\n\n// UpstreamAttempt is one upstream attempt.\nexport interface UpstreamAttempt {\n time: string;\n request_id: string;\n model: string;\n tier: string;\n attempt: number;\n key_id: string;\n channel: string;\n anonymous: boolean;\n proxy_node: string;\n status: number;\n duration_ms: number;\n success: boolean;\n outcome: string;\n}\n\n// UpstreamRequest is one routed request.\nexport interface UpstreamRequest {\n time: string;\n request_id: string;\n session: string;\n server_key_id: string;\n model: string;\n tier: string;\n key_id: string;\n channel: string;\n anonymous: boolean;\n proxy_node: string;\n attempts: number;\n status: number;\n duration_ms: number;\n success: boolean;\n outcome: string;\n}\n\n// UpstreamSnapshot is the upstream activity.\nexport interface UpstreamSnapshot {\n lifetime: AttemptAggregate;\n last_hour: AttemptAggregate;\n requests: UpstreamRequest[];\n recent: UpstreamAttempt[];\n}\n\n// MetricSummary is the counter summary of one period.\nexport interface MetricSummary {\n total: number;\n success: number;\n errors: number;\n success_rate: number;\n average_ms: number;\n p50_ms: number;\n p95_ms: number;\n p99_ms: number;\n}\n\n// MetricSeries is one minute of the last-hour series.\nexport interface MetricSeries {\n minute: string;\n total: number;\n success: number;\n errors: number;\n input_tokens: number;\n output_tokens: number;\n cached_tokens: number;\n reasoning_tokens: number;\n total_tokens: number;\n usage_reported: number;\n}\n\n// MonitorSnapshot is the whole metrics state.\nexport interface MonitorSnapshot {\n started_at: string;\n uptime_seconds: number;\n active_requests: number;\n active_streams: number;\n lifetime: MetricSummary;\n last_hour: MetricSummary;\n series: MetricSeries[];\n endpoints: Record<string, number>;\n models: Record<string, number>;\n tiers: Record<string, number>;\n statuses: Record<string, number>;\n usage: UsageSnapshot;\n upstream: UpstreamSnapshot;\n}\n\n// RequestMeta is the trace of one request.\nexport interface RequestMeta {\n modelAlias: string;\n model: string;\n tier: string;\n protocol: string;\n request: string;\n session: string;\n keyId: string;\n channel: string;\n anonymous: boolean;\n proxy: string;\n attempts: number;\n legs: string[];\n stop: string;\n tail: string;\n stream: boolean;\n serverKeyId: string;\n shaped: boolean;\n toolAlias: string;\n usage: Usage | undefined;\n usageReported: boolean;\n attemptOutcome: string;\n outcome: string;\n}\n\n// emptyUsage builds the zero token total.\nexport function emptyTokenCounts(): TokenCounts {\n return {\n input_tokens: 0,\n output_tokens: 0,\n cached_tokens: 0,\n reasoning_tokens: 0,\n total_tokens: 0,\n };\n}\n\n// emptyUsagePeriod builds the zero usage period.\nexport function emptyUsagePeriod(): UsagePeriod {\n return {\n requests: 0,\n reported: 0,\n coverage: 0,\n tokens: emptyTokenCounts(),\n models: {},\n tiers: {},\n sessions: {},\n server_keys: {},\n };\n}\n\n// emptyAttemptCounts builds the zero attempt counts.\nexport function emptyAttemptCounts(): AttemptCounts {\n return { total: 0, success: 0, failed: 0 };\n}\n\n// emptyAttemptAggregate builds the zero attempt aggregate.\nexport function emptyAttemptAggregate(): AttemptAggregate {\n return {\n ...emptyAttemptCounts(),\n success_rate: 0,\n tiers: {},\n channels: {},\n keys: {},\n };\n}\n", "import type { Usage } from \"../types/inference.js\";\nimport { LATENCY_BOUNDS, type ServerKeyUsage, type TokenCounts } from \"./metric-types.js\";\n\n// addTokens folds a usage report into a token total. The bridge usage and the\n// telemetry token total name their fields differently, so the bridge usage is\n// translated on the way in.\nexport function addTokens(\n target: TokenCounts,\n usage: Usage | TokenCounts,\n): void {\n if (\"inputTokens\" in usage) {\n target.input_tokens += usage.inputTokens;\n target.output_tokens += usage.outputTokens;\n target.cached_tokens += usage.cachedInputTokens;\n target.reasoning_tokens += usage.reasoningTokens;\n target.total_tokens += usage.totalTokens;\n return;\n }\n target.input_tokens += usage.input_tokens;\n target.output_tokens += usage.output_tokens;\n target.cached_tokens += usage.cached_tokens;\n target.reasoning_tokens += usage.reasoning_tokens;\n target.total_tokens += usage.total_tokens;\n}\n\n// mergeCounts folds a counter map into another.\nexport function mergeCounts(\n target: Record<string, number>,\n source: Record<string, number>,\n): void {\n for (const [key, value] of Object.entries(source)) {\n target[key] = (target[key] ?? 0) + value;\n }\n}\n\n// mergeTokenCounts folds a token map into another.\nexport function mergeTokenCounts(\n target: Record<string, TokenCounts>,\n source: Record<string, TokenCounts>,\n): void {\n for (const [key, value] of Object.entries(source)) {\n const entry = target[key] ?? (target[key] = emptyTokens());\n addTokens(entry, value);\n }\n}\n\n// mergeServerKeyUsage folds a server-key usage map into another.\nexport function mergeServerKeyUsage(\n target: Record<string, ServerKeyUsage>,\n source: Record<string, ServerKeyUsage>,\n): void {\n for (const [key, value] of Object.entries(source)) {\n const entry = target[key] ?? (target[key] = {\n requests: 0,\n token_counts: emptyTokens(),\n });\n entry.requests += value.requests;\n addTokens(entry.token_counts, value.token_counts);\n }\n}\n\n// emptyTokens builds a zero token total.\nexport function emptyTokens(): TokenCounts {\n return {\n input_tokens: 0,\n output_tokens: 0,\n cached_tokens: 0,\n reasoning_tokens: 0,\n total_tokens: 0,\n };\n}\n\n// histogramIndex returns the bucket a duration falls into.\nexport function histogramIndex(milliseconds: number): number {\n for (let i = 0; i < LATENCY_BOUNDS.length; i += 1) {\n const bound = LATENCY_BOUNDS[i];\n if (bound !== undefined && milliseconds <= bound) {\n return i;\n }\n }\n return LATENCY_BOUNDS.length;\n}\n\n// histogramPercentile returns the upper bound of the bucket holding the\n// percentile. The overflow bucket reports one millisecond above the final\n// bound.\nexport function histogramPercentile(\n histogram: number[],\n percentile: number,\n): number {\n let total = 0;\n for (const count of histogram) {\n total += count;\n }\n if (total === 0) {\n return 0;\n }\n const target = Math.ceil(total * percentile);\n let seen = 0;\n for (let i = 0; i < histogram.length; i += 1) {\n seen += histogram[i] ?? 0;\n if (seen >= target) {\n const bound = LATENCY_BOUNDS[i];\n return bound === undefined\n ? (LATENCY_BOUNDS[LATENCY_BOUNDS.length - 1] ?? 0) + 1\n : bound;\n }\n }\n return (LATENCY_BOUNDS[LATENCY_BOUNDS.length - 1] ?? 0) + 1;\n}\n\n// trim keeps the newest entries of a buffer.\nexport function trim<T>(buffer: T[], capacity: number): void {\n while (buffer.length > capacity) {\n buffer.shift();\n }\n}\n\n// minuteStamp returns the current minute in epoch milliseconds.\nexport function minuteStamp(): number {\n return Math.floor(Date.now() / 60_000) * 60_000;\n}\n\n// minuteStampIndex maps a minute onto its bucket index.\nexport function minuteStampIndex(minute: number, count: number): number {\n return Math.floor(minute / 60_000) % count;\n}\n", "import {\n emptyAttemptAggregate,\n emptyAttemptCounts,\n emptyTokenCounts,\n emptyUsagePeriod,\n LATENCY_BOUNDS,\n RECENT_ATTEMPT_CAPACITY,\n RECENT_OUTPUT_LIMIT,\n type AttemptAggregate,\n type AttemptCounts,\n type MetricSeries,\n type MetricSummary,\n type MonitorSnapshot,\n type RequestMeta,\n type ServerKeyUsage,\n type TokenCounts,\n type UpstreamAttempt,\n type UpstreamRequest,\n type UpstreamSnapshot,\n type UsageSnapshot,\n} from \"./metric-types.js\";\nimport {\n addTokens,\n histogramIndex,\n histogramPercentile,\n mergeCounts,\n mergeServerKeyUsage,\n mergeTokenCounts,\n minuteStamp,\n minuteStampIndex,\n trim,\n} from \"./metric-helpers.js\";\n\n// The number of one-minute buckets the metrics keep.\nconst BUCKET_COUNT = 60;\n\n// A minute bucket holds the counters of one minute.\ninterface MetricBucket {\n minute: number;\n total: number;\n success: number;\n errors: number;\n duration: number;\n histogram: number[];\n endpoints: Record<string, number>;\n models: Record<string, number>;\n tiers: Record<string, number>;\n statuses: Record<string, number>;\n usageRequests: number;\n usage_reported: number;\n tokens: TokenCounts;\n usageModels: Record<string, TokenCounts>;\n usageTiers: Record<string, TokenCounts>;\n usageSessions: Record<string, TokenCounts>;\n usageKeys: Record<string, ServerKeyUsage>;\n}\n\n// An attempt bucket holds the upstream attempts of one minute.\ninterface AttemptBucket {\n minute: number;\n aggregate: AttemptAggregate;\n}\n\n// emptyBucket builds a blank minute bucket.\nfunction emptyBucket(minute: number): MetricBucket {\n return {\n minute,\n total: 0,\n success: 0,\n errors: 0,\n duration: 0,\n histogram: new Array<number>(LATENCY_BOUNDS.length + 1).fill(0),\n endpoints: {},\n models: {},\n tiers: {},\n statuses: {},\n usageRequests: 0,\n usage_reported: 0,\n tokens: emptyTokenCounts(),\n usageModels: {},\n usageTiers: {},\n usageSessions: {},\n usageKeys: {},\n };\n}\n\n// emptyAttemptBucket builds a blank attempt bucket.\nfunction emptyAttemptBucket(minute: number): AttemptBucket {\n return { minute, aggregate: emptyAttemptAggregate() };\n}\n\n// Metrics collects the request counters, the latency histogram, the token\n// usage and the upstream attempts.\nexport class Metrics {\n private readonly started_at = Date.now();\n private active = 0;\n private active_streams = 0;\n private total = 0;\n private success = 0;\n private errors = 0;\n\n private readonly buckets: MetricBucket[] = [];\n private readonly attemptBuckets: AttemptBucket[] = [];\n private readonly lifetimeUsage = emptyUsagePeriod();\n private readonly attemptLifetime = emptyAttemptAggregate();\n private readonly recentRequests: UpstreamRequest[] = [];\n private readonly recentAttempts: UpstreamAttempt[] = [];\n\n constructor() {\n for (let i = 0; i < BUCKET_COUNT; i++) {\n this.buckets.push(emptyBucket(0));\n this.attemptBuckets.push(emptyAttemptBucket(0));\n }\n }\n\n // enter counts a request that is in flight.\n enter(): void {\n this.active += 1;\n }\n\n // leave counts a request that finished.\n leave(): void {\n this.active -= 1;\n }\n\n // enterStream counts a stream that is in flight.\n enterStream(): void {\n this.active_streams += 1;\n }\n\n // leaveStream counts a stream that finished.\n leaveStream(): void {\n this.active_streams -= 1;\n }\n\n // record folds one finished request into the metrics.\n record(\n endpoint: string,\n status: number,\n duration_ms: number,\n meta: RequestMeta | undefined,\n ): void {\n const succeeded = requestSucceeded(status, meta);\n this.total += 1;\n if (succeeded) {\n this.success += 1;\n } else {\n this.errors += 1;\n }\n const minute = minuteStamp();\n const bucket = this.bucket(minute);\n bucket.total += 1;\n if (succeeded) {\n bucket.success += 1;\n } else {\n bucket.errors += 1;\n }\n const ms = Math.max(Math.trunc(duration_ms), 0);\n bucket.duration += ms;\n const index = histogramIndex(ms);\n bucket.histogram[index] = (bucket.histogram[index] ?? 0) + 1;\n bucket.endpoints[endpoint] = (bucket.endpoints[endpoint] ?? 0) + 1;\n const statusKey = String(status);\n bucket.statuses[statusKey] = (bucket.statuses[statusKey] ?? 0) + 1;\n if (meta === undefined) {\n return;\n }\n this.recordUsage(bucket, meta);\n }\n\n // recordUsage folds a request's usage into the bucket and the lifetime.\n private recordUsage(bucket: MetricBucket, meta: RequestMeta): void {\n if (meta.model !== \"\") {\n bucket.models[meta.model] = (bucket.models[meta.model] ?? 0) + 1;\n }\n if (meta.tier === \"\") {\n return;\n }\n bucket.tiers[meta.tier] = (bucket.tiers[meta.tier] ?? 0) + 1;\n bucket.usageRequests += 1;\n this.lifetimeUsage.requests += 1;\n if (meta.usageReported) {\n bucket.usage_reported += 1;\n this.lifetimeUsage.reported += 1;\n }\n if (meta.usage === undefined) {\n return;\n }\n addTokens(bucket.tokens, meta.usage);\n addTokens(this.lifetimeUsage.tokens, meta.usage);\n addTokens(\n bucket.usageModels[meta.model] ??\n (bucket.usageModels[meta.model] = emptyTokenCounts()),\n meta.usage,\n );\n addTokens(\n bucket.usageTiers[meta.tier] ??\n (bucket.usageTiers[meta.tier] = emptyTokenCounts()),\n meta.usage,\n );\n if (meta.session !== \"\") {\n addTokens(\n bucket.usageSessions[meta.session] ??\n (bucket.usageSessions[meta.session] = emptyTokenCounts()),\n meta.usage,\n );\n }\n const keyID = meta.serverKeyId;\n if (keyID === \"\") {\n return;\n }\n const usage = bucket.usageKeys[keyID] ?? (bucket.usageKeys[keyID] = {\n requests: 0,\n token_counts: emptyTokenCounts(),\n });\n usage.requests += 1;\n addTokens(usage.token_counts, meta.usage);\n const lifetime = this.lifetimeUsage.server_keys[keyID] ??\n (this.lifetimeUsage.server_keys[keyID] = {\n requests: 0,\n token_counts: emptyTokenCounts(),\n });\n lifetime.requests += 1;\n addTokens(lifetime.token_counts, meta.usage);\n }\n\n // recordAttempt folds one upstream attempt into the metrics.\n recordAttempt(attempt: UpstreamAttempt): void {\n const minute = minuteStamp();\n const bucket = this.attemptBucket(minute);\n const aggregate = bucket.aggregate;\n aggregate.total += 1;\n if (attempt.success) {\n aggregate.success += 1;\n } else {\n aggregate.failed += 1;\n }\n countAttempt(aggregate.tiers, attempt.tier || \"unknown\", attempt.success);\n countAttempt(\n aggregate.channels,\n attempt.channel || \"unknown\",\n attempt.success,\n );\n countAttempt(aggregate.keys, attempt.key_id || \"unknown\", attempt.success);\n aggregate.success_rate =\n aggregate.total > 0 ? aggregate.success / aggregate.total : 0;\n\n this.attemptLifetime.total += 1;\n if (attempt.success) {\n this.attemptLifetime.success += 1;\n } else {\n this.attemptLifetime.failed += 1;\n }\n this.attemptLifetime.success_rate =\n this.attemptLifetime.total > 0\n ? this.attemptLifetime.success / this.attemptLifetime.total\n : 0;\n\n this.recentAttempts.push(attempt);\n trim(this.recentAttempts, RECENT_ATTEMPT_CAPACITY);\n }\n\n // serverKeyUsage returns the lifetime and the last-hour usage of the local\n // server keys.\n serverKeyUsage(): {\n lifetime: Record<string, ServerKeyUsage>;\n last_hour: Record<string, ServerKeyUsage>;\n } {\n const window: Record<string, ServerKeyUsage> = {};\n for (const bucket of this.buckets) {\n if (bucket.minute === 0) {\n continue;\n }\n mergeServerKeyUsage(window, bucket.usageKeys);\n }\n return {\n lifetime: this.lifetimeUsage.server_keys,\n last_hour: window as Record<string, ServerKeyUsage>,\n };\n }\n\n // snapshot returns the whole metrics state.\n snapshot(): MonitorSnapshot {\n const now = Date.now();\n const series: MetricSeries[] = [];\n const endpoints: Record<string, number> = {};\n const models: Record<string, number> = {};\n const tiers: Record<string, number> = {};\n const statuses: Record<string, number> = {};\n const windowUsage = emptyUsagePeriod();\n let total = 0;\n let success = 0;\n let errors = 0;\n let duration = 0;\n const histogram = new Array<number>(LATENCY_BOUNDS.length + 1).fill(0);\n\n for (let offset = BUCKET_COUNT - 1; offset >= 0; offset -= 1) {\n const minute = minuteStamp() - offset * 60_000;\n const bucket = this.bucketFor(minute);\n series.unshift({\n minute: new Date(minute).toISOString(),\n total: bucket.total,\n success: bucket.success,\n errors: bucket.errors,\n input_tokens: bucket.tokens.input_tokens,\n output_tokens: bucket.tokens.output_tokens,\n cached_tokens: bucket.tokens.cached_tokens,\n reasoning_tokens: bucket.tokens.reasoning_tokens,\n total_tokens: bucket.tokens.total_tokens,\n usage_reported: bucket.usage_reported,\n });\n total += bucket.total;\n success += bucket.success;\n errors += bucket.errors;\n duration += bucket.duration;\n for (let i = 0; i < histogram.length; i += 1) {\n histogram[i] = (histogram[i] ?? 0) + (bucket.histogram[i] ?? 0);\n }\n mergeCounts(endpoints, bucket.endpoints);\n mergeCounts(models, bucket.models);\n mergeCounts(tiers, bucket.tiers);\n mergeCounts(statuses, bucket.statuses);\n windowUsage.requests += bucket.usageRequests;\n windowUsage.reported += bucket.usage_reported;\n addTokens(windowUsage.tokens, bucket.tokens);\n mergeTokenCounts(windowUsage.models, bucket.usageModels);\n mergeTokenCounts(windowUsage.tiers, bucket.usageTiers);\n mergeTokenCounts(windowUsage.sessions, bucket.usageSessions);\n mergeServerKeyUsage(windowUsage.server_keys, bucket.usageKeys);\n }\n windowUsage.coverage =\n windowUsage.requests > 0\n ? windowUsage.reported / windowUsage.requests\n : 0;\n\n const cutoff = now - 60 * 60 * 1000;\n const requests = this.recentRequests.filter(\n (entry) => Date.parse(entry.time) >= cutoff,\n );\n const attempts = this.recentAttempts.filter(\n (entry) => Date.parse(entry.time) >= cutoff,\n );\n\n const usage: UsageSnapshot = {\n lifetime: this.lifetimeUsage,\n last_hour: windowUsage,\n };\n const upstream: UpstreamSnapshot = {\n lifetime: this.attemptLifetime,\n last_hour: this.attemptAggregate(),\n requests: requests.slice(-RECENT_OUTPUT_LIMIT),\n recent: attempts.slice(-RECENT_OUTPUT_LIMIT),\n };\n return {\n started_at: new Date(this.started_at).toISOString(),\n uptime_seconds: Math.trunc((now - this.started_at) / 1000),\n active_requests: this.active,\n active_streams: this.active_streams,\n lifetime: this.lifetimeSummary(),\n last_hour: {\n total,\n success,\n errors,\n success_rate: total > 0 ? success / total : 0,\n average_ms: total > 0 ? duration / total : 0,\n p50_ms: histogramPercentile(histogram, 0.5),\n p95_ms: histogramPercentile(histogram, 0.95),\n p99_ms: histogramPercentile(histogram, 0.99),\n },\n series,\n endpoints,\n models,\n tiers,\n statuses,\n usage,\n upstream,\n };\n }\n\n // lifetimeSummary returns the lifetime counters. It carries no latency\n // fields, because the lifetime has no single latency distribution.\n private lifetimeSummary(): MetricSummary {\n return {\n total: this.total,\n success: this.success,\n errors: this.errors,\n success_rate: this.total > 0 ? this.success / this.total : 0,\n average_ms: 0,\n p50_ms: 0,\n p95_ms: 0,\n p99_ms: 0,\n };\n }\n\n // attemptAggregate returns the upstream attempts of the last hour.\n private attemptAggregate(): AttemptAggregate {\n const aggregate = emptyAttemptAggregate();\n const cutoff = minuteStamp() - (BUCKET_COUNT - 1) * 60_000;\n for (const bucket of this.attemptBuckets) {\n if (bucket.minute < cutoff || bucket.minute === 0) {\n continue;\n }\n const source = bucket.aggregate;\n aggregate.total += source.total;\n aggregate.success += source.success;\n aggregate.failed += source.failed;\n mergeAttemptCounts(aggregate.tiers, source.tiers);\n mergeAttemptCounts(aggregate.channels, source.channels);\n mergeAttemptCounts(aggregate.keys, source.keys);\n }\n aggregate.success_rate =\n aggregate.total > 0 ? aggregate.success / aggregate.total : 0;\n return aggregate;\n }\n\n // bucket returns the bucket of a minute, resetting it when the minute\n // changed.\n private bucket(minute: number): MetricBucket {\n const index = minuteStampIndex(minute, BUCKET_COUNT);\n const bucket = this.buckets[index];\n if (bucket === undefined) {\n throw new Error(\"metrics bucket index out of range\");\n }\n if (bucket.minute !== minute) {\n this.buckets[index] = emptyBucket(minute);\n return this.buckets[index] as MetricBucket;\n }\n return bucket;\n }\n\n // bucketFor returns the bucket of a minute without creating it.\n private bucketFor(minute: number): MetricBucket {\n const index = minuteStampIndex(minute, BUCKET_COUNT);\n const bucket = this.buckets[index];\n if (bucket === undefined || bucket.minute !== minute) {\n return emptyBucket(minute);\n }\n return bucket;\n }\n\n // attemptBucket returns the attempt bucket of a minute.\n private attemptBucket(minute: number): AttemptBucket {\n const index = minuteStampIndex(minute, BUCKET_COUNT);\n const bucket = this.attemptBuckets[index];\n if (bucket === undefined) {\n throw new Error(\"metrics attempt bucket index out of range\");\n }\n if (bucket.minute !== minute) {\n this.attemptBuckets[index] = emptyAttemptBucket(minute);\n return this.attemptBuckets[index] as AttemptBucket;\n }\n return bucket;\n }\n}\n\n// countAttempt folds one attempt into a per-key counter map.\nfunction countAttempt(\n counts: Record<string, AttemptCounts>,\n key: string,\n success: boolean,\n): void {\n const entry = counts[key] ?? (counts[key] = emptyAttemptCounts());\n entry.total += 1;\n if (success) {\n entry.success += 1;\n } else {\n entry.failed += 1;\n }\n}\n\n// mergeAttemptCounts folds an attempt count map into another.\nfunction mergeAttemptCounts(\n target: Record<string, AttemptCounts>,\n source: Record<string, AttemptCounts>,\n): void {\n for (const [key, value] of Object.entries(source)) {\n const entry = target[key] ?? (target[key] = emptyAttemptCounts());\n entry.total += value.total;\n entry.success += value.success;\n entry.failed += value.failed;\n }\n}\n\n// requestSucceeded reports whether a request counts as a success. Without\n// metadata the request is conservatively counted as a failure.\nfunction requestSucceeded(\n status: number,\n meta: RequestMeta | undefined,\n): boolean {\n return status >= 200 && status < 400 && meta !== undefined && meta.outcome === \"\";\n}\n", "import type { IncomingHttpHeaders } from \"node:http\";\nimport { sha256Bytes, toHex } from \"./sha256.js\";\nimport {\n ascendingID,\n claudeCodeSessionID,\n randomID,\n scopedSessionID,\n type RequestIDs,\n} from \"./identity.js\";\nimport { firstString, isPlainObject, sliceAt, stringAt } from \"./json-util.js\";\n\nexport type { RequestIDs };\n\nfunction headerValue(headers: IncomingHttpHeaders, name: string): string {\n const value = headers[name];\n if (Array.isArray(value)) {\n return value[0] ?? \"\";\n }\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction conversationSeed(body: Record<string, unknown>): string {\n const prelude: unknown[] = [];\n for (const field of [\"system\", \"instructions\"]) {\n if (body[field] !== undefined && body[field] !== null) {\n prelude.push(body[field]);\n }\n }\n const first = firstUserTurn(body, prelude);\n if (first === undefined) {\n return \"\";\n }\n try {\n return JSON.stringify([...prelude, first]);\n } catch {\n return \"\";\n }\n}\n\nfunction firstUserTurn(\n body: Record<string, unknown>,\n prelude: unknown[],\n): unknown {\n const input = body[\"input\"];\n if (typeof input === \"string\" && input !== \"\") {\n return input;\n }\n for (const field of [\"messages\", \"input\"]) {\n for (const raw of sliceAt(body, field)) {\n if (!isPlainObject(raw)) {\n continue;\n }\n const role = stringAt(raw, \"role\");\n if (role === \"system\" || role === \"developer\") {\n prelude.push(raw[\"content\"]);\n } else if (role === \"user\") {\n const content = raw[\"content\"];\n if (content !== undefined && content !== null) {\n return content;\n }\n }\n }\n }\n return undefined;\n}\n\nfunction turnFingerprint(count: number, content: unknown): string {\n let encoded: string;\n try {\n encoded = JSON.stringify(content) ?? \"\";\n } catch {\n encoded = String(content);\n }\n const sum = sha256Bytes(encoded);\n return `${count}:${toHex(sum.subarray(0, 8))}`;\n}\n\nfunction carriesToolResult(content: unknown): boolean {\n if (!Array.isArray(content)) {\n return false;\n }\n return content.some(\n (block) =>\n isPlainObject(block) && stringAt(block, \"type\") === \"tool_result\",\n );\n}\n\nfunction userTurn(body: Record<string, unknown>): string {\n const input = body[\"input\"];\n if (typeof input === \"string\" && input !== \"\") {\n return turnFingerprint(1, input);\n }\n let count = 0;\n let last: unknown;\n for (const field of [\"messages\", \"input\"]) {\n for (const raw of sliceAt(body, field)) {\n if (!isPlainObject(raw) || stringAt(raw, \"role\") !== \"user\") {\n continue;\n }\n if (carriesToolResult(raw[\"content\"])) {\n continue;\n }\n count += 1;\n last = raw[\"content\"];\n }\n }\n if (count === 0) {\n return \"\";\n }\n return turnFingerprint(count, last);\n}\n\nconst MESSAGE_TTL_MS = 6 * 60 * 60 * 1000;\nconst MESSAGE_STORE_LIMIT = 8192;\n\ninterface MessageEntry {\n id: string;\n seen: number;\n}\n\nclass MessageStore {\n private readonly turns = new Map<string, MessageEntry>();\n private readonly latest = new Map<string, MessageEntry>();\n\n idFor(session: string, turn: string, now: number): string {\n const key = `${session}\\x00${turn}`;\n let entry = turn ? this.turns.get(key) : this.latest.get(session);\n if (!entry || now - entry.seen > MESSAGE_TTL_MS) {\n entry = { id: ascendingID(\"msg\", now), seen: now };\n }\n entry.seen = now;\n if (turn) {\n this.turns.set(key, entry);\n }\n this.latest.set(session, entry);\n if (\n this.turns.size > MESSAGE_STORE_LIMIT ||\n this.latest.size > MESSAGE_STORE_LIMIT\n ) {\n this.prune(now);\n }\n return entry.id;\n }\n\n private prune(now: number): void {\n for (const [key, entry] of this.turns) {\n if (now - entry.seen > MESSAGE_TTL_MS) {\n this.turns.delete(key);\n }\n }\n for (const [key, entry] of this.latest) {\n if (now - entry.seen > MESSAGE_TTL_MS) {\n this.latest.delete(key);\n }\n }\n while (this.turns.size > (MESSAGE_STORE_LIMIT * 3) / 4) {\n const oldest = this.turns.keys().next();\n if (oldest.done) {\n break;\n }\n this.turns.delete(oldest.value);\n }\n while (this.latest.size > (MESSAGE_STORE_LIMIT * 3) / 4) {\n const oldest = this.latest.keys().next();\n if (oldest.done) {\n break;\n }\n this.latest.delete(oldest.value);\n }\n }\n}\n\nconst userMessages = new MessageStore();\n\nexport function userMessageID(\n headers: IncomingHttpHeaders,\n body: Record<string, unknown>,\n session: string,\n): string {\n const header = headerValue(headers, \"x-opencode-request\");\n if (MESSAGE_ID.test(header)) {\n return header;\n }\n return userMessages.idFor(session, userTurn(body), Date.now());\n}\n\nconst MESSAGE_ID = /^msg_[0-9a-f]{12}[0-9A-Za-z]{14}$/;\n\nexport function deriveRequestIDs(\n headers: IncomingHttpHeaders,\n body: Record<string, unknown>,\n scope: string,\n): RequestIDs {\n const signal = firstString(\n headerValue(headers, \"x-opencode-session\"),\n headerValue(headers, \"x-opencode-session-id\"),\n headerValue(headers, \"x-session-affinity\"),\n headerValue(headers, \"x-session-id\"),\n headerValue(headers, \"session_id\"),\n headerValue(headers, \"conversation-id\"),\n headerValue(headers, \"conversation_id\"),\n stringAt(body, \"conversation_id\"),\n stringAt(body, \"metadata\", \"session_id\"),\n claudeCodeSessionID(stringAt(body, \"metadata\", \"user_id\")),\n );\n\n let effective = signal;\n if (!effective) {\n effective = conversationSeed(body);\n }\n if (!effective) {\n effective = stringAt(body, \"previous_response_id\");\n }\n if (!effective || effective === \"{}\") {\n effective = randomID(\"fallback\", 16);\n }\n\n const session = scopedSessionID(scope, effective);\n\n let projectSignal = firstString(\n headerValue(headers, \"x-opencode-project\"),\n stringAt(body, \"metadata\", \"project_id\"),\n );\n if (!projectSignal) {\n projectSignal = \"opencode2api:default-project\";\n if (scope) {\n projectSignal += `:${scope}`;\n }\n }\n\n const parentSession = firstString(\n headerValue(headers, \"x-parent-session-id\"),\n stringAt(body, \"metadata\", \"parent_session_id\"),\n );\n\n return {\n session,\n request: randomID(\"req\", 16),\n message: userMessageID(headers, body, session),\n project: projectSignal,\n parentSession,\n };\n}\n", "import { asPrefix } from \"./identity.js\";\nimport { chatStop, openAIUsage } from \"./response-usage.js\";\nimport {\n SSEWriter,\n type StreamState,\n type StreamTool,\n type StreamWriter,\n} from \"./stream-writer.js\";\n\n// ChatWriter encodes a Chat completion chunk stream.\nexport class ChatWriter implements StreamWriter {\n private readonly sse: SSEWriter;\n private readonly state: StreamState;\n private readonly created: number;\n\n constructor(sse: SSEWriter, state: StreamState, created: number) {\n this.sse = sse;\n this.state = state;\n this.created = created;\n }\n\n start(): void {\n this.chunk({ role: \"assistant\", content: \"\" }, null);\n }\n\n emitText(text: string): void {\n this.chunk({ content: text }, null);\n }\n\n emitReasoning(text: string): void {\n this.chunk({ reasoning_content: text }, null);\n }\n\n emitReasoningSignature(signature: string): void {\n this.chunk({ reasoning_signature: signature }, null);\n }\n\n startTool(tool: StreamTool): void {\n this.chunk(\n {\n tool_calls: [\n {\n index: tool.index,\n id: tool.id,\n type: \"function\",\n function: { name: tool.name, arguments: \"\" },\n },\n ],\n },\n null,\n );\n }\n\n emitToolDelta(tool: StreamTool, delta: string): void {\n this.chunk(\n {\n tool_calls: [\n {\n index: tool.index,\n function: { arguments: delta },\n },\n ],\n },\n null,\n );\n }\n\n emitError(message: string, errorType: string): void {\n this.sse.sse(\"\", {\n error: { message, type: errorType, param: null, code: null },\n });\n this.sse.rawSSE(\"\", \"[DONE]\");\n }\n\n finish(state: StreamState): void {\n this.chunk({}, chatStop(state.stop));\n this.sse.sse(\"\", {\n id: asPrefix(state.id, \"chatcmpl\"),\n object: \"chat.completion.chunk\",\n created: state.created,\n model: state.model,\n choices: [],\n usage: openAIUsage(state.usage),\n });\n this.sse.rawSSE(\"\", \"[DONE]\");\n }\n\n private chunk(delta: Record<string, unknown>, finish: unknown): void {\n this.sse.sse(\"\", {\n id: asPrefix(this.state.id, \"chatcmpl\"),\n object: \"chat.completion.chunk\",\n created: this.created,\n model: this.state.model,\n choices: [\n {\n index: 0,\n delta,\n finish_reason: finish,\n },\n ],\n });\n }\n}\n", "import { asPrefix } from \"./identity.js\";\nimport { anthropicStop, anthropicUsage } from \"./response-usage.js\";\nimport {\n SSEWriter,\n type StreamState,\n type StreamTool,\n type StreamWriter,\n} from \"./stream-writer.js\";\n\n// AnthropicWriter encodes an Anthropic message stream. Its content blocks are\n// sequential, so the reasoning block is closed before a text or tool block\n// opens.\nexport class AnthropicWriter implements StreamWriter {\n private readonly sse: SSEWriter;\n private readonly state: StreamState;\n private textOpen = false;\n private textIndex = 0;\n private nextAnthropic = 0;\n private reasoningOpen = false;\n private reasoningClosed = false;\n private reasoningIndex = 0;\n\n constructor(sse: SSEWriter, state: StreamState) {\n this.sse = sse;\n this.state = state;\n }\n\n start(): void {\n this.sse.sse(\"message_start\", {\n type: \"message_start\",\n message: {\n id: asPrefix(this.state.id, \"msg\"),\n type: \"message\",\n role: \"assistant\",\n model: this.state.model,\n content: [],\n stop_reason: null,\n stop_sequence: null,\n usage: anthropicUsage({\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n reasoningTokens: 0,\n }),\n },\n });\n }\n\n emitText(text: string): void {\n this.finishReasoning();\n if (!this.textOpen) {\n this.textOpen = true;\n this.textIndex = this.nextAnthropic;\n this.nextAnthropic += 1;\n this.sse.sse(\"content_block_start\", {\n type: \"content_block_start\",\n index: this.textIndex,\n content_block: { type: \"text\", text: \"\" },\n });\n }\n this.sse.sse(\"content_block_delta\", {\n type: \"content_block_delta\",\n index: this.textIndex,\n delta: { type: \"text_delta\", text },\n });\n }\n\n emitReasoning(text: string): void {\n this.startReasoning();\n this.sse.sse(\"content_block_delta\", {\n type: \"content_block_delta\",\n index: this.reasoningIndex,\n delta: { type: \"thinking_delta\", thinking: text },\n });\n }\n\n emitReasoningSignature(signature: string): void {\n this.startReasoning();\n this.sse.sse(\"content_block_delta\", {\n type: \"content_block_delta\",\n index: this.reasoningIndex,\n delta: { type: \"signature_delta\", signature },\n });\n }\n\n startTool(tool: StreamTool): void {\n this.finishReasoning();\n if (this.textOpen) {\n this.sse.sse(\"content_block_stop\", {\n type: \"content_block_stop\",\n index: this.textIndex,\n });\n this.textOpen = false;\n }\n tool.anthropicIndex = this.nextAnthropic;\n this.nextAnthropic += 1;\n this.sse.sse(\"content_block_start\", {\n type: \"content_block_start\",\n index: tool.anthropicIndex,\n content_block: {\n type: \"tool_use\",\n id: tool.id,\n name: tool.name,\n input: {},\n },\n });\n }\n\n emitToolDelta(tool: StreamTool, delta: string): void {\n this.sse.sse(\"content_block_delta\", {\n type: \"content_block_delta\",\n index: tool.anthropicIndex,\n delta: { type: \"input_json_delta\", partial_json: delta },\n });\n }\n\n emitError(message: string, errorType: string): void {\n this.sse.sse(\"error\", {\n type: \"error\",\n error: { type: errorType, message },\n });\n }\n\n finish(state: StreamState): void {\n this.finishReasoning();\n if (this.textOpen) {\n this.sse.sse(\"content_block_stop\", {\n type: \"content_block_stop\",\n index: this.textIndex,\n });\n this.textOpen = false;\n }\n for (const tool of state.tools) {\n if (tool.started) {\n this.sse.sse(\"content_block_stop\", {\n type: \"content_block_stop\",\n index: tool.anthropicIndex,\n });\n }\n }\n this.sse.sse(\"message_delta\", {\n type: \"message_delta\",\n delta: { stop_reason: anthropicStop(state.stop), stop_sequence: null },\n usage: anthropicUsage(state.usage),\n });\n this.sse.sse(\"message_stop\", { type: \"message_stop\" });\n }\n\n private startReasoning(): void {\n if (this.reasoningOpen || this.reasoningClosed) {\n return;\n }\n this.reasoningOpen = true;\n this.reasoningIndex = this.nextAnthropic;\n this.nextAnthropic += 1;\n this.sse.sse(\"content_block_start\", {\n type: \"content_block_start\",\n index: this.reasoningIndex,\n content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n });\n }\n\n private finishReasoning(): void {\n if (!this.reasoningOpen || this.reasoningClosed) {\n return;\n }\n this.reasoningClosed = true;\n this.sse.sse(\"content_block_stop\", {\n type: \"content_block_stop\",\n index: this.reasoningIndex,\n });\n }\n}\n", "import { asPrefix, randomID } from \"./identity.js\";\nimport { encodeBridgeResponse } from \"./response-encode.js\";\nimport type { BridgeBlock } from \"../types/inference.js\";\nimport {\n SSEWriter,\n type StreamState,\n type StreamTool,\n type StreamWriter,\n} from \"./stream-writer.js\";\n\n// ResponsesWriter encodes a Responses stream. Its output items are sequential,\n// so the reasoning item is closed before a message or tool item opens.\nexport class ResponsesWriter implements StreamWriter {\n private readonly sse: SSEWriter;\n private readonly state: StreamState;\n private readonly created: number;\n private sequence = 0;\n private nextOutput = 0;\n private textOpen = false;\n private textItemID = \"\";\n private textOutput = 0;\n private reasoningOpen = false;\n private reasoningClosed = false;\n private reasoningItemID = \"\";\n private reasoningOutput = 0;\n private reasoningText = \"\";\n\n constructor(sse: SSEWriter, state: StreamState, created: number) {\n this.sse = sse;\n this.state = state;\n this.created = created;\n }\n\n start(): void {\n const response = this.responsesBase(\"in_progress\", []);\n this.sse.sse(\"response.created\", {\n type: \"response.created\",\n response,\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.in_progress\", {\n type: \"response.in_progress\",\n response,\n sequence_number: this.nextSequence(),\n });\n }\n\n emitText(text: string): void {\n this.finishReasoning();\n if (!this.textOpen) {\n this.textOpen = true;\n this.textItemID = randomID(\"msg\", 12);\n this.textOutput = this.nextOutput;\n this.nextOutput += 1;\n this.sse.sse(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.textOutput,\n item: {\n id: this.textItemID,\n type: \"message\",\n status: \"in_progress\",\n role: \"assistant\",\n content: [],\n },\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.content_part.added\", {\n type: \"response.content_part.added\",\n item_id: this.textItemID,\n output_index: this.textOutput,\n content_index: 0,\n part: { type: \"output_text\", text: \"\", annotations: [] },\n sequence_number: this.nextSequence(),\n });\n }\n this.sse.sse(\"response.output_text.delta\", {\n type: \"response.output_text.delta\",\n delta: text,\n item_id: this.textItemID,\n output_index: this.textOutput,\n content_index: 0,\n sequence_number: this.nextSequence(),\n });\n }\n\n emitReasoning(text: string): void {\n this.startReasoning();\n this.reasoningText += text;\n this.sse.sse(\"response.reasoning_summary_text.delta\", {\n type: \"response.reasoning_summary_text.delta\",\n delta: text,\n item_id: this.reasoningItemID,\n output_index: this.reasoningOutput,\n summary_index: 0,\n sequence_number: this.nextSequence(),\n });\n }\n\n emitReasoningSignature(_signature: string): void {\n // Responses has no field for a reasoning signature, so it is dropped.\n }\n\n startTool(tool: StreamTool): void {\n this.finishReasoning();\n tool.index = this.nextOutput;\n this.nextOutput += 1;\n this.sse.sse(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: tool.index,\n item: {\n id: tool.itemID,\n type: \"function_call\",\n status: \"in_progress\",\n arguments: \"\",\n call_id: tool.id,\n name: tool.name,\n },\n sequence_number: this.nextSequence(),\n });\n }\n\n emitToolDelta(tool: StreamTool, delta: string): void {\n this.sse.sse(\"response.function_call_arguments.delta\", {\n type: \"response.function_call_arguments.delta\",\n delta,\n item_id: tool.itemID,\n output_index: tool.index,\n sequence_number: this.nextSequence(),\n });\n }\n\n emitError(message: string, errorType: string): void {\n const response = this.responsesBase(\"failed\", []);\n response[\"error\"] = { code: errorType, message };\n this.sse.sse(\"response.failed\", {\n type: \"response.failed\",\n response,\n sequence_number: this.nextSequence(),\n });\n }\n\n finish(state: StreamState): void {\n this.finishReasoning();\n this.finishText(state.text);\n for (const tool of state.tools) {\n const args = tool.arguments === \"\" ? \"{}\" : tool.arguments;\n this.sse.sse(\"response.function_call_arguments.done\", {\n type: \"response.function_call_arguments.done\",\n arguments: args,\n item_id: tool.itemID,\n output_index: tool.index,\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: tool.index,\n item: {\n id: tool.itemID,\n type: \"function_call\",\n status: \"completed\",\n arguments: args,\n call_id: tool.id,\n name: tool.name,\n },\n sequence_number: this.nextSequence(),\n });\n }\n const completed = encodeBridgeResponse(\"responses\", {\n id: state.id,\n model: state.model,\n text: state.text,\n reasoning: this.reasoningBlocks(state),\n tools: state.tools.map((tool) => this.toolBlock(tool)),\n stop: state.stop,\n error: \"\",\n usage: state.usage,\n created: state.created,\n });\n this.sse.sse(\"response.completed\", {\n type: \"response.completed\",\n response: completed,\n sequence_number: this.nextSequence(),\n });\n }\n\n private reasoningBlocks(state: StreamState): BridgeBlock[] {\n if (state.reasoning === \"\" && state.reasoningSignature === \"\") {\n return [];\n }\n const block = emptyBlock(\"reasoning\");\n block.id = this.reasoningItemID;\n block.text = state.reasoning;\n block.signature = state.reasoningSignature;\n return [block];\n }\n\n private toolBlock(tool: StreamTool): BridgeBlock {\n const block = emptyBlock(\"tool_call\");\n block.id = tool.id;\n block.name = tool.name;\n block.argumentsJSON = tool.arguments;\n return block;\n }\n\n private finishText(text: string): void {\n if (!this.textOpen) {\n return;\n }\n this.textOpen = false;\n this.sse.sse(\"response.output_text.done\", {\n type: \"response.output_text.done\",\n text,\n item_id: this.textItemID,\n output_index: this.textOutput,\n content_index: 0,\n sequence_number: this.nextSequence(),\n });\n const part = { type: \"output_text\", text, annotations: [] };\n this.sse.sse(\"response.content_part.done\", {\n type: \"response.content_part.done\",\n item_id: this.textItemID,\n output_index: this.textOutput,\n content_index: 0,\n part,\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.textOutput,\n item: {\n id: this.textItemID,\n type: \"message\",\n status: \"completed\",\n role: \"assistant\",\n content: [part],\n },\n sequence_number: this.nextSequence(),\n });\n }\n\n private startReasoning(): void {\n if (this.reasoningOpen || this.reasoningClosed) {\n return;\n }\n this.reasoningOpen = true;\n this.reasoningItemID = randomID(\"rs\", 12);\n this.reasoningOutput = this.nextOutput;\n this.nextOutput += 1;\n this.sse.sse(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.reasoningOutput,\n item: {\n id: this.reasoningItemID,\n type: \"reasoning\",\n status: \"in_progress\",\n summary: [],\n },\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.reasoning_summary_part.added\", {\n type: \"response.reasoning_summary_part.added\",\n item_id: this.reasoningItemID,\n output_index: this.reasoningOutput,\n summary_index: 0,\n part: { type: \"summary_text\", text: \"\" },\n sequence_number: this.nextSequence(),\n });\n }\n\n private finishReasoning(): void {\n if (!this.reasoningOpen || this.reasoningClosed) {\n return;\n }\n this.reasoningClosed = true;\n this.sse.sse(\"response.reasoning_summary_text.done\", {\n type: \"response.reasoning_summary_text.done\",\n text: this.reasoningText,\n item_id: this.reasoningItemID,\n output_index: this.reasoningOutput,\n summary_index: 0,\n sequence_number: this.nextSequence(),\n });\n const part = { type: \"summary_text\", text: this.reasoningText };\n this.sse.sse(\"response.reasoning_summary_part.done\", {\n type: \"response.reasoning_summary_part.done\",\n item_id: this.reasoningItemID,\n output_index: this.reasoningOutput,\n summary_index: 0,\n part,\n sequence_number: this.nextSequence(),\n });\n this.sse.sse(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.reasoningOutput,\n item: {\n id: this.reasoningItemID,\n type: \"reasoning\",\n status: \"completed\",\n summary: [part],\n },\n sequence_number: this.nextSequence(),\n });\n }\n\n private responsesBase(\n status: string,\n output: unknown[],\n ): Record<string, unknown> {\n return {\n id: asPrefix(this.state.id, \"resp\"),\n object: \"response\",\n created_at: this.created,\n status,\n model: this.state.model,\n output,\n error: null,\n };\n }\n\n private nextSequence(): number {\n const sequence = this.sequence;\n this.sequence += 1;\n return sequence;\n }\n}\n\n// emptyBlock builds a blank block of the given kind for the closing document.\nfunction emptyBlock(kind: BridgeBlock[\"kind\"]): BridgeBlock {\n return {\n kind,\n text: \"\",\n signature: \"\",\n encrypted: \"\",\n url: \"\",\n mediaType: \"\",\n data: \"\",\n fileId: \"\",\n filename: \"\",\n id: \"\",\n name: \"\",\n arguments: undefined,\n argumentsJSON: \"\",\n callId: \"\",\n result: undefined,\n isError: false,\n };\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport type { Usage } from \"../types/inference.js\";\nimport { ANTHROPIC_REDACTED_THINKING_PLACEHOLDER } from \"./block.js\";\nimport { randomID } from \"./identity.js\";\nimport { firstString } from \"./json-util.js\";\nimport { isToolStop } from \"./response-usage.js\";\nimport { ChatWriter } from \"./stream-writer-chat.js\";\nimport { AnthropicWriter } from \"./stream-writer-anthropic.js\";\nimport { ResponsesWriter } from \"./stream-writer-responses.js\";\nimport {\n SSEWriter,\n mergeBridgeUsage,\n type StreamState,\n type StreamTool,\n type StreamWriter,\n} from \"./stream-writer.js\";\nimport {\n errStreamUpstreamFailure,\n type BridgeStreamEvent,\n type StreamEncoder,\n type StreamSink,\n} from \"./stream-types.js\";\n\nconst EMPTY_USAGE: Usage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n reasoningTokens: 0,\n};\n\n// StreamCodec turns bridge stream events into one downstream protocol's SSE\n// stream. It opens the response on the first start or content event (or on\n// finish when the stream carried none), tracks which text, reasoning and tool\n// blocks are open so each protocol's block ordering is respected, and records\n// usage as it goes.\nexport class StreamCodec implements StreamEncoder {\n private readonly writer: StreamWriter;\n private readonly state: StreamState;\n private readonly tools = new Map<string, StreamTool>();\n private order: string[] = [];\n private started = false;\n private done = false;\n\n constructor(\n sink: StreamSink,\n target: Protocol,\n model: string,\n created: number = Math.floor(Date.now() / 1000),\n ) {\n const sse = new SSEWriter(sink);\n this.state = {\n id: \"\",\n model,\n created,\n text: \"\",\n reasoning: \"\",\n reasoningSignature: \"\",\n reasoningEncrypted: \"\",\n stop: \"\",\n usage: { ...EMPTY_USAGE },\n tools: [],\n };\n this.writer = this.createWriter(sse, target, this.state, created);\n }\n\n private createWriter(\n sse: SSEWriter,\n target: Protocol,\n state: StreamState,\n created: number,\n ): StreamWriter {\n switch (target) {\n case \"chat\":\n return new ChatWriter(sse, state, created);\n case \"anthropic\":\n return new AnthropicWriter(sse, state);\n case \"responses\":\n return new ResponsesWriter(sse, state, created);\n default:\n throw new Error(`unsupported stream target \"${target}\"`);\n }\n }\n\n private usageSeen = false;\n\n get usage(): Usage {\n return this.state.usage;\n }\n\n get usageReported(): boolean {\n return this.usageSeen;\n }\n\n // emit encodes one bridge stream event for the target protocol. The response\n // is opened before the first start or content event. An error event writes an\n // in-band error and then reports the upstream failure.\n emit(event: BridgeStreamEvent): void {\n if (event.responseID !== \"\" && this.state.id === \"\") {\n this.state.id = event.responseID;\n }\n if (event.model !== \"\") {\n this.state.model = event.model;\n }\n if (!this.started && this.opensResponse(event)) {\n this.start();\n }\n switch (event.kind) {\n case \"reasoning\":\n this.emitReasoning(event);\n return;\n case \"reasoning_signature\":\n if (event.signature === \"\") {\n return;\n }\n this.state.reasoningSignature += event.signature;\n this.writer.emitReasoningSignature(event.signature);\n return;\n case \"text\":\n if (event.text === \"\") {\n return;\n }\n this.state.text += event.text;\n this.writer.emitText(event.text);\n return;\n case \"tool_start\": {\n const tool = this.tool(event.toolKey);\n this.applyToolIdentity(tool, event);\n this.startTool(tool);\n this.emitPendingToolArguments(tool);\n return;\n }\n case \"tool_delta\": {\n const tool = this.tool(event.toolKey);\n this.applyToolIdentity(tool, event);\n tool.arguments += event.text;\n this.startTool(tool);\n this.emitPendingToolArguments(tool);\n return;\n }\n case \"usage\":\n if (event.usage !== undefined) {\n this.usageSeen = true;\n this.state.usage = mergeBridgeUsage(this.state.usage, event.usage);\n }\n return;\n case \"finish\":\n this.state.stop = event.stop;\n return;\n case \"error\":\n this.done = true;\n this.writer.emitError(\n firstString(event.error, \"upstream stream failed\"),\n firstString(event.errorType, \"upstream_error\"),\n );\n throw errStreamUpstreamFailure;\n case \"done\":\n this.finish();\n return;\n default:\n return;\n }\n }\n\n // opensResponse reports whether an event should open the response. The\n // response stays closed for a stream that only reports usage or a stop.\n private opensResponse(event: BridgeStreamEvent): boolean {\n switch (event.kind) {\n case \"start\":\n case \"reasoning\":\n case \"reasoning_signature\":\n case \"text\":\n case \"tool_start\":\n case \"tool_delta\":\n return true;\n default:\n return false;\n }\n }\n\n private emitReasoning(event: BridgeStreamEvent): void {\n let text = event.text;\n if (event.encrypted !== \"\") {\n this.state.reasoningEncrypted = event.encrypted;\n if (text === \"\") {\n text = ANTHROPIC_REDACTED_THINKING_PLACEHOLDER;\n }\n }\n if (text === \"\") {\n return;\n }\n this.state.reasoning += text;\n this.writer.emitReasoning(text);\n }\n\n private applyToolIdentity(tool: StreamTool, event: BridgeStreamEvent): void {\n if (event.toolID !== \"\") {\n tool.id = event.toolID;\n }\n if (event.toolName !== \"\") {\n tool.name = event.toolName;\n }\n }\n\n // tool returns the state for a stream tool key, creating it with fresh IDs\n // and the next index on first sight. An empty key gets a position-based one,\n // so each unnamed event starts its own tool.\n private tool(key: string): StreamTool {\n const resolved = key === \"\" ? `tool-${this.order.length}` : key;\n const existing = this.tools.get(resolved);\n if (existing !== undefined) {\n return existing;\n }\n const tool: StreamTool = {\n key: resolved,\n id: randomID(\"call\", 12),\n itemID: randomID(\"fc\", 12),\n name: \"\",\n arguments: \"\",\n index: this.order.length,\n anthropicIndex: 0,\n started: false,\n emittedArguments: 0,\n };\n this.tools.set(resolved, tool);\n this.order = [...this.order, resolved];\n return tool;\n }\n\n // startTool opens a tool call downstream once its name is non-empty, closing\n // the reasoning block first. A tool with no name stays unstarted, so a\n // phantom call is never announced.\n private startTool(tool: StreamTool): void {\n if (tool.started || tool.name === \"\") {\n return;\n }\n tool.started = true;\n this.writer.startTool(tool);\n }\n\n // emitPendingToolArguments writes the argument text a tool has accumulated\n // but not yet sent. A tool that has not started holds its arguments until it\n // does, so nothing is lost when the name arrives late.\n private emitPendingToolArguments(tool: StreamTool): void {\n if (!tool.started) {\n return;\n }\n const encoder = new TextEncoder();\n const bytes = encoder.encode(tool.arguments);\n if (tool.emittedArguments >= bytes.length) {\n return;\n }\n const decoder = new TextDecoder();\n const delta = decoder.decode(\n bytes.slice(tool.emittedArguments),\n { stream: true },\n );\n tool.emittedArguments = bytes.length;\n this.writer.emitToolDelta(tool, delta);\n }\n\n // anyToolStarted reports whether at least one tool block was actually opened\n // downstream. A tool stuck without a name never starts, so its stop promise\n // must not be advertised as a tool stop.\n private anyToolStarted(): boolean {\n return this.order.some((key) => this.tools.get(key)?.started === true);\n }\n\n // finish closes the response in the target protocol's shape. The stop reason\n // defaults to \"tool_calls\" when any tool call was seen and \"stop\" otherwise,\n // and a tool stop with no started tool is demoted to \"stop\" so the client\n // does not wait for a call it never received.\n finish(): void {\n if (this.done) {\n return;\n }\n this.done = true;\n if (!this.started) {\n this.start();\n }\n if (this.state.stop === \"\") {\n this.state.stop = this.order.length > 0 ? \"tool_calls\" : \"stop\";\n }\n if (isToolStop(this.state.stop) && !this.anyToolStarted()) {\n this.state.stop = \"stop\";\n }\n this.state.tools = this.order\n .map((key) => this.tools.get(key))\n .filter((tool): tool is StreamTool => tool !== undefined);\n this.writer.finish(this.state);\n }\n\n private start(): void {\n if (this.started) {\n return;\n }\n this.started = true;\n if (this.state.id === \"\") {\n this.state.id = randomID(\"resp\", 12);\n }\n this.writer.start();\n }\n}\n", "import type { Usage } from \"../types/inference.js\";\nimport type { Protocol } from \"../types/config.js\";\nimport { SSEReader } from \"./sse.js\";\nimport { StreamParser } from \"./stream-parser.js\";\nimport { mergeBridgeUsage } from \"./stream-writer.js\";\n\n// StreamUsageTracker reads a relayed SSE stream and reports its usage. It\n// never modifies the bytes it is given: it only parses the frames they\n// contain, so the same bytes can still be forwarded verbatim.\nexport class StreamUsageTracker {\n private readonly parser: StreamParser;\n private readonly reader = new SSEReader();\n private usage: Usage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationTokens: 0,\n reasoningTokens: 0,\n };\n private reported = false;\n private normal = false;\n private error = false;\n private parseError: Error | undefined;\n\n constructor(protocol: Protocol) {\n this.parser = new StreamParser(protocol);\n }\n\n // observe consumes the relayed bytes and records the terminal events and the\n // usage. A parse error is remembered but not thrown, because the relay must\n // keep copying bytes.\n observe(chunk: Uint8Array): void {\n for (const record of this.reader.push(chunk)) {\n this.consume(record.event, record.data);\n }\n }\n\n // finish returns the merged usage and discards the buffered tail. A tail\n // that was never terminated by a blank line is not an SSE frame, so a usage\n // object from a response that was cut off at EOF is not counted.\n finish(): Usage {\n this.reader.close();\n return this.usage;\n }\n\n wasReported(): boolean {\n return this.reported;\n }\n\n normalTermination(): boolean {\n return this.normal;\n }\n\n errorTermination(): boolean {\n return this.error;\n }\n\n parseFailure(): Error | undefined {\n return this.parseError;\n }\n\n private consume(eventName: string, data: string): void {\n let events;\n try {\n events = this.parser.parse(eventName, data);\n } catch (error) {\n if (this.parseError === undefined) {\n this.parseError = asError(error);\n }\n return;\n }\n for (const event of events) {\n if (event.kind === \"done\") {\n this.normal = true;\n }\n if (event.kind === \"error\") {\n this.error = true;\n }\n if (event.usage !== undefined) {\n this.reported = true;\n this.usage = mergeBridgeUsage(this.usage, event.usage);\n }\n }\n }\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport type { Usage } from \"../types/inference.js\";\nimport { SSEReader } from \"./sse.js\";\nimport { StreamCodec } from \"./stream-encoder.js\";\nimport { StreamParser } from \"./stream-parser.js\";\nimport { StreamUsageTracker } from \"./stream-usage-tracker.js\";\nimport {\n errSSEUnexpectedEOF,\n errStreamNormalTermination,\n errStreamUpstreamFailure,\n type BridgeStreamEvent,\n type StreamSink,\n} from \"./stream-types.js\";\n\n// StreamResult reports what a relayed or transcoded stream produced.\nexport interface StreamResult {\n usage: Usage;\n reported: boolean;\n error: Error | undefined;\n}\n\n// forwardStream relays a same-protocol upstream stream to the client byte for\n// byte, while a usage tracker reads the same bytes to parse the usage. The\n// only bytes ever added are a synthetic in-band error event when the stream\n// ended before a terminal event.\nexport async function forwardStream(\n source: AsyncIterable<Uint8Array>,\n sink: StreamSink,\n protocol: Protocol,\n model: string,\n): Promise<StreamResult> {\n const tracker = new StreamUsageTracker(protocol);\n let copyError: Error | undefined;\n try {\n for await (const chunk of source) {\n tracker.observe(chunk);\n sink.write(chunk);\n }\n } catch (error) {\n copyError = asError(error);\n }\n const usage = tracker.finish();\n const reported = tracker.wasReported();\n if (tracker.errorTermination()) {\n return { usage, reported, error: copyError ?? errStreamUpstreamFailure };\n }\n if (tracker.normalTermination() && tracker.parseFailure() === undefined) {\n return { usage, reported, error: copyError };\n }\n const cause = copyError ?? tracker.parseFailure() ?? errSSEUnexpectedEOF;\n const emitted = emitUnexpectedStreamError(sink, protocol, model, cause);\n return { usage, reported, error: emitted ?? cause };\n}\n\n// transcodeStream parses an upstream stream of one protocol and re-encodes it\n// for another, writing each downstream event as it arrives.\n//\n// A stream that ends without a terminal event is reported in-band with an\n// error event first. A stream that failed in a way already reported in-band\n// keeps that report and is not reported twice.\nexport async function transcodeStream(\n source: AsyncIterable<Uint8Array>,\n sink: StreamSink,\n from: Protocol,\n to: Protocol,\n model: string,\n): Promise<StreamResult> {\n const parser = new StreamParser(from);\n const codec = new StreamCodec(sink, to, model);\n const reader = new SSEReader();\n const state: { termination: \"open\" | \"normal\" | \"error\" } = {\n termination: \"open\",\n };\n let readError: Error | undefined;\n\n const read = async (): Promise<void> => {\n for await (const chunk of source) {\n for (const record of reader.push(chunk)) {\n let events: BridgeStreamEvent[];\n try {\n events = parser.parse(record.event, record.data);\n } catch (error) {\n state.termination = \"error\";\n codec.emit(errorEvent(asError(error).message));\n throw errStreamUpstreamFailure;\n }\n for (const event of events) {\n if (event.kind === \"done\") {\n state.termination = \"normal\";\n }\n if (event.kind === \"error\") {\n state.termination = \"error\";\n }\n codec.emit(event);\n if (event.kind === \"done\") {\n throw errStreamNormalTermination;\n }\n }\n }\n }\n };\n\n try {\n await read();\n } catch (error) {\n if (error !== errStreamNormalTermination) {\n readError = asError(error);\n }\n }\n\n const usage = codec.usage;\n const reported = codec.usageReported;\n if (readError === undefined) {\n if (state.termination === \"normal\") {\n return { usage, reported, error: undefined };\n }\n if (state.termination === \"error\") {\n return { usage, reported, error: errStreamUpstreamFailure };\n }\n const emitted = emitUnexpectedStreamError(\n sink,\n to,\n model,\n errSSEUnexpectedEOF,\n );\n return { usage, reported, error: emitted ?? errSSEUnexpectedEOF };\n }\n if (readError === errStreamUpstreamFailure) {\n // The failure was already reported in-band by the emitter.\n return { usage, reported, error: readError };\n }\n if (state.termination === \"open\") {\n const emitted = emitUnexpectedStreamError(sink, to, model, readError);\n return { usage, reported, error: emitted ?? readError };\n }\n return { usage, reported, error: readError };\n}\n\n// emitUnexpectedStreamError reports a stream that ended without a terminal\n// event, as an in-band error event in the downstream protocol. It returns\n// undefined once that event is written, and the write error otherwise.\nexport function emitUnexpectedStreamError(\n sink: StreamSink,\n protocol: Protocol,\n model: string,\n cause: Error | undefined,\n): Error | undefined {\n const message =\n cause !== undefined && cause !== errSSEUnexpectedEOF\n ? `upstream SSE stream failed: ${cause.message}`\n : \"upstream SSE stream ended before a terminal event\";\n const codec = new StreamCodec(sink, protocol, model);\n try {\n codec.emit(errorEvent(message));\n } catch (error) {\n if (error === errStreamUpstreamFailure) {\n return undefined;\n }\n return asError(error);\n }\n return undefined;\n}\n\n// errorEvent builds the in-band error event the emitter writes.\nexport function errorEvent(message: string): BridgeStreamEvent {\n return {\n kind: \"error\",\n responseID: \"\",\n model: \"\",\n text: \"\",\n signature: \"\",\n toolKey: \"\",\n toolID: \"\",\n toolName: \"\",\n stop: \"\",\n error: message,\n errorType: \"upstream_error\",\n encrypted: \"\",\n usage: undefined,\n };\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n", "import type { Protocol } from \"../types/config.js\";\nimport { isPlainObject, sliceAt, stringAt } from \"./json-util.js\";\nimport { renameResponseTool } from \"./response.js\";\nimport { mergeToolName } from \"./stream-parser-shared.js\";\n\n// ToolRenameState tracks how one tool call's name was resolved while a stream\n// is rewritten. Chat deltas may repeat a growing name prefix or append\n// fragments, so a value that is still a prefix of the source name is held back\n// until it either completes the match or diverges.\ninterface ToolRenameState {\n decided: boolean;\n renamed: boolean;\n pending: string;\n}\n\n// StreamToolRenamer rewrites the tool names of one protocol's SSE frames,\n// keeping per-tool state across frames so a name split over several Chat\n// chunks is reassembled before it is matched.\nexport class StreamToolRenamer {\n private readonly protocol: Protocol;\n private readonly fromName: string;\n private readonly toName: string;\n private readonly tools = new Map<string, ToolRenameState>();\n\n constructor(protocol: Protocol, fromName: string, toName: string) {\n this.protocol = protocol;\n this.fromName = fromName;\n this.toName = toName;\n }\n\n // rewriteFrame rewrites one SSE data payload, which is raw JSON text. Frames\n // that cannot carry a tool name are returned untouched, so only a payload\n // that mentions the source name (Anthropic and Responses) or \"tool_calls\"\n // (Chat) is decoded.\n rewriteFrame(raw: string): string {\n if (this.protocol !== \"chat\") {\n // Anthropic and Responses streams always carry a complete tool name in\n // a single event, so the stateless object rewrite is exact.\n if (!raw.includes(this.fromName)) {\n return raw;\n }\n return renameResponseTool(raw, this.protocol, this.fromName, this.toName);\n }\n if (!raw.includes('\"tool_calls\"')) {\n return raw;\n }\n return this.rewriteChatFrame(raw);\n }\n\n // rewriteChatFrame rewrites the tool names of one Chat chunk. Tool calls are\n // keyed by index, then id, then array position, and each name fragment is\n // folded into the call's state so a name split across chunks is restored as\n // a whole. The frame is returned unchanged when nothing was rewritten.\n private rewriteChatFrame(raw: string): string {\n let payload: unknown;\n try {\n payload = JSON.parse(raw) as unknown;\n } catch {\n return raw;\n }\n if (!isPlainObject(payload)) {\n return raw;\n }\n let changed = false;\n for (const rawChoice of sliceAt(payload, \"choices\")) {\n const choice = isPlainObject(rawChoice) ? rawChoice : {};\n for (const container of [\"delta\", \"message\"]) {\n const message = isPlainObject(choice[container]) ? choice[container] : {};\n const calls = sliceAt(message, \"tool_calls\");\n for (let callIndex = 0; callIndex < calls.length; callIndex += 1) {\n const rawCall = calls[callIndex];\n const call = isPlainObject(rawCall) ? rawCall : {};\n const fn = call[\"function\"];\n if (!isPlainObject(fn)) {\n continue;\n }\n const state = this.toolState(callKey(call, callIndex));\n const name = fn[\"name\"];\n if (typeof name === \"string\" && name !== \"\") {\n if (this.applyNameFragment(state, fn, name)) {\n changed = true;\n }\n }\n if (\"arguments\" in fn && !state.decided) {\n // Arguments can only start once the name is complete: flush\n // whatever was held back, verbatim.\n if (state.pending !== \"\") {\n fn[\"name\"] = state.pending;\n changed = true;\n }\n state.decided = true;\n }\n }\n }\n }\n if (!changed) {\n return raw;\n }\n try {\n return JSON.stringify(payload);\n } catch {\n return raw;\n }\n }\n\n // applyNameFragment folds one name fragment into a tool's rename state and\n // reports whether the frame changed. Once the accumulated name completes the\n // source name, it is replaced by the target name; while it is still a prefix\n // the name is held back; on divergence the accumulated name is written out\n // as is. After a resolved rename, any further fragment is dropped, because\n // it belongs to a longer name the client never declared.\n private applyNameFragment(\n state: ToolRenameState,\n fn: Record<string, unknown>,\n fragment: string,\n ): boolean {\n if (state.decided) {\n if (!state.renamed) {\n return false;\n }\n // A resolved alias accepts no further fragments: any continuation\n // belongs to a longer name the client never declared.\n if (\"name\" in fn) {\n delete fn[\"name\"];\n return true;\n }\n return false;\n }\n state.pending = mergeToolName(state.pending, fragment);\n if (state.pending === this.fromName) {\n fn[\"name\"] = this.toName;\n state.decided = true;\n state.renamed = true;\n return true;\n }\n if (this.fromName.startsWith(state.pending)) {\n // Still a prefix of the alias: hold the fragment until a later frame\n // either completes the match or diverges.\n delete fn[\"name\"];\n return true;\n }\n fn[\"name\"] = state.pending;\n state.decided = true;\n return true;\n }\n\n // toolState returns the rename state for a tool key, creating it on first\n // sight.\n private toolState(key: string): ToolRenameState {\n const existing = this.tools.get(key);\n if (existing !== undefined) {\n return existing;\n }\n const state: ToolRenameState = { decided: false, renamed: false, pending: \"\" };\n this.tools.set(key, state);\n return state;\n }\n}\n\n// callKey mirrors the tool key of a Chat call: the call's index, else its id,\n// else its array position.\nfunction callKey(call: Record<string, unknown>, index: number): string {\n const raw = call[\"index\"];\n if (raw !== undefined && raw !== null) {\n return String(raw);\n }\n const id = stringAt(call, \"id\");\n return id !== \"\" ? id : String(index);\n}\n", "import type { Protocol, Tier } from \"../types/config.js\";\nimport type { RequestIDs } from \"../protocol/identity.js\";\nimport type { Route } from \"../types/inference.js\";\nimport { convertResponse, renameResponseTool } from \"../protocol/response.js\";\nimport { responseUsage } from \"../protocol/response-encode.js\";\nimport { collapseStream } from \"../protocol/collapse.js\";\nimport { forwardStream, transcodeStream } from \"../protocol/stream.js\";\nimport { StreamToolRenamer } from \"../protocol/stream-renamer.js\";\nimport { V1_READ_TOOL } from \"../protocol/tools.js\";\nimport type { StreamSink } from \"../protocol/stream-types.js\";\n\n// The body limit the non-streaming path reads.\nconst RESPONSE_BODY_LIMIT = 64 * 1024 * 1024;\n\n// UpstreamOutcome is what the upstream attempt produced.\nexport interface UpstreamOutcome {\n status: number;\n headers: Headers;\n stream: AsyncIterable<Uint8Array>;\n}\n\n// DeliveryResult is what the handler delivers to the client.\nexport interface DeliveryResult {\n status: number;\n headers: Headers;\n body: string;\n usage: ReturnType<typeof responseUsage>[\"usage\"];\n usagePresent: boolean;\n}\n\n// deliverResponse converts an upstream response to the client's protocol and\n// reports the usage it carried.\n//\n// The anonymous lane and a key-tier request shaped like it are force streamed\n// upstream, so the events are collapsed back into the single document the\n// non-streaming client asked for.\nexport async function deliverResponse(\n upstreamProtocol: Protocol,\n external: Protocol,\n outcome: UpstreamOutcome,\n model: string,\n toolAlias: string,\n shaped: boolean,\n): Promise<DeliveryResult> {\n let body = await readBody(outcome);\n let text = decodeBody(body);\n if (shaped || isEventStream(outcome.headers)) {\n text = await collapseStream(bytesOf(text), upstreamProtocol, model);\n }\n text = renameResponseTool(text, upstreamProtocol, V1_READ_TOOL, toolAlias);\n const usage = responseUsage(upstreamProtocol, JSON.parse(text) as unknown);\n let converted = text;\n if (upstreamProtocol !== external) {\n converted = convertResponse(upstreamProtocol, external, text);\n }\n return {\n status: outcome.status,\n headers: outcome.headers,\n body: converted,\n usage: usage.usage,\n usagePresent: usage.present,\n };\n}\n\n// deliverStream relays or transcodes an upstream stream to the client. The\n// tool alias is restored on the way out, so a client sees its own tool name\n// again.\nexport async function deliverStream(\n upstreamProtocol: Protocol,\n external: Protocol,\n outcome: UpstreamOutcome,\n model: string,\n toolAlias: string,\n sink: StreamSink,\n): Promise<{ usage: DeliveryResult[\"usage\"]; usagePresent: boolean; error: Error | undefined }> {\n const source = renameStream(outcome.stream, upstreamProtocol, toolAlias);\n const result =\n upstreamProtocol === external\n ? await forwardStream(source, sink, upstreamProtocol, model)\n : await transcodeStream(source, sink, upstreamProtocol, external, model);\n return {\n usage: result.usage,\n usagePresent: result.reported,\n error: result.error,\n };\n}\n\n// renameStream rewrites the tool names of a relayed stream. A stream without\n// a tool alias is relayed unchanged.\nfunction renameStream(\n source: AsyncIterable<Uint8Array>,\n protocol: Protocol,\n toolAlias: string,\n): AsyncIterable<Uint8Array> {\n if (toolAlias === \"\") {\n return source;\n }\n const renamer = new StreamToolRenamer(protocol, V1_READ_TOOL, toolAlias);\n return {\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n const encoder = new TextEncoder();\n let pending = \"\";\n for await (const chunk of source) {\n pending += new TextDecoder().decode(chunk, { stream: true });\n const lines = pending.split(\"\\n\");\n pending = lines.pop() ?? \"\";\n const rewritten = lines\n .map((line) => rewriteLine(line, renamer))\n .join(\"\\n\");\n if (rewritten !== \"\") {\n yield encoder.encode(`${rewritten}\\n`);\n }\n }\n if (pending !== \"\") {\n yield encoder.encode(rewriteLine(pending, renamer));\n }\n },\n };\n}\n\n// rewriteLine rewrites the data line of an SSE frame, preserving its original\n// bytes when nothing needed rewriting.\nfunction rewriteLine(line: string, renamer: StreamToolRenamer): string {\n if (!line.startsWith(\"data:\")) {\n return line;\n }\n const raw = line.slice(\"data:\".length).trim();\n if (raw === \"\" || raw === \"[DONE]\") {\n return line;\n }\n const rewritten = renamer.rewriteFrame(raw);\n if (rewritten === raw) {\n return line;\n }\n return `data: ${rewritten}`;\n}\n\n// readBody reads the whole upstream body, bounded by the response limit.\nasync function readBody(outcome: UpstreamOutcome): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for await (const chunk of outcome.stream) {\n total += chunk.byteLength;\n if (total > RESPONSE_BODY_LIMIT) {\n throw new Error(\"upstream response exceeded the 64 MiB limit\");\n }\n chunks.push(chunk);\n }\n const body = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return body;\n}\n\n// decodeBody decodes a body into text.\nfunction decodeBody(body: Uint8Array): string {\n return new TextDecoder().decode(body);\n}\n\n// bytesOf turns text into a byte stream.\nfunction bytesOf(text: string): AsyncIterable<Uint8Array> {\n const encoder = new TextEncoder();\n return {\n async *[Symbol.asyncIterator](): AsyncIterator<Uint8Array> {\n yield encoder.encode(text);\n },\n };\n}\n\n// isEventStream reports whether a response carries an SSE stream.\nfunction isEventStream(headers: Headers): boolean {\n return (headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\");\n}\n\n// tierOf returns the tier a route's primary lane uses.\nexport function tierOf(route: Route): Tier {\n return route.tier;\n}\n\nexport type { RequestIDs };\n", "import type { Tier } from \"../types/config.js\";\nimport type { Route } from \"../types/inference.js\";\nimport { isPlainObject, mapAt, stringAt } from \"../protocol/json-util.js\";\nimport { prepareAnonymousBody } from \"../protocol/tools.js\";\n\n// RouteBodies is the request body of each tier the route can fall back to.\nexport interface RouteBodies {\n zen: string;\n go: string;\n}\n\n// The request shaping the upstream lanes need. A shaped request is force\n// streamed upstream and collapsed back for the client that asked for a plain\n// reply.\nexport interface RequestShape {\n shaped: boolean;\n toolAlias: string;\n}\n\n// prepareRouteBodies renders the request body for every tier the route can\n// fall back to. The v1 lane needs a read tool and the v2 lane the core\n// tools, so the body is shaped per tier.\nexport function prepareRouteBodies(\n route: Route,\n payload: Record<string, unknown>,\n isV1: (tier: Tier) => boolean,\n): { bodies: RouteBodies; shape: RequestShape } {\n const raw = JSON.stringify(payload);\n const bodies: RouteBodies = { zen: raw, go: raw };\n const shape: RequestShape = { shaped: false, toolAlias: \"\" };\n\n const tiers: Tier[] = route.anonymous\n ? [\"zen\"]\n : route.keyTiers.length > 0\n ? route.keyTiers\n : [route.tier];\n for (const tier of tiers) {\n if (!isV1(tier)) {\n continue;\n }\n const prepared = prepareAnonymousBody(raw, route.protocol, true);\n if (tier === \"go\") {\n bodies.go = prepared.body;\n } else {\n bodies.zen = prepared.body;\n }\n if (prepared.alias !== \"\") {\n shape.toolAlias = prepared.alias;\n }\n if (prepared.shaped) {\n shape.shaped = true;\n }\n }\n if (route.anonymous) {\n // The anonymous lane shapes its own body per upstream gate, so the raw\n // body is handed on unchanged.\n bodies.zen = raw;\n }\n return { bodies, shape };\n}\n\n// isSystemOnePayload reports whether a payload carries the System One\n// decision shape.\nexport function isSystemOnePayload(payload: Record<string, unknown>): boolean {\n return (\n Object.keys(mapAt(payload, \"questions\")).length > 0 &&\n payload[\"state\"] !== undefined &&\n payload[\"state\"] !== null\n );\n}\n\n// requestModel reads the model a request asks for.\nexport function requestModel(payload: Record<string, unknown>): string {\n return stringAt(payload, \"model\");\n}\n\n// isValidRequestPayload reports whether a decoded body is a JSON object.\nexport function isValidRequestPayload(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value);\n}\n", "import type { ServerResponse } from \"node:http\";\nimport type { Protocol } from \"../types/config.js\";\nimport { buildErrorEnvelope } from \"../protocol/error.js\";\nimport type { RequestMeta } from \"../telemetry/metric-types.js\";\n\n// newRequestMeta builds an empty request trace.\nexport function newRequestMeta(): RequestMeta {\n return {\n modelAlias: \"\",\n model: \"\",\n tier: \"\",\n protocol: \"\",\n request: \"\",\n session: \"\",\n keyId: \"\",\n channel: \"\",\n anonymous: false,\n proxy: \"\",\n attempts: 0,\n legs: [],\n stop: \"\",\n tail: \"\",\n stream: false,\n serverKeyId: \"\",\n shaped: false,\n toolAlias: \"\",\n usage: undefined,\n usageReported: false,\n attemptOutcome: \"\",\n outcome: \"\",\n };\n}\n\n// writeError answers a request with the protocol's error envelope.\nexport function writeError(\n response: ServerResponse,\n protocol: Protocol,\n status: number,\n message: string,\n kind: string,\n): void {\n const envelope = buildErrorEnvelope(protocol, status, message, kind as never);\n response.writeHead(envelope.status, {\n \"Content-Type\": \"application/json\",\n });\n response.end(`${JSON.stringify(envelope.body)}\\n`);\n}\n\n// readAll reads a whole response body as text.\nexport async function readAll(\n stream: AsyncIterable<Uint8Array>,\n): Promise<string> {\n const decoder = new TextDecoder();\n let text = \"\";\n for await (const chunk of stream) {\n text += decoder.decode(chunk, { stream: true });\n }\n return text + decoder.decode();\n}\n", "import type { ServerResponse } from \"node:http\";\nimport type { Protocol, Tier } from \"../types/config.js\";\nimport type { Route } from \"../types/inference.js\";\nimport { boolAt, isPlainObject } from \"../protocol/json-util.js\";\nimport { deriveRequestIDs } from \"../protocol/request-identity.js\";\nimport { isV1Upstream } from \"../protocol/lanes.js\";\nimport { deliverResponse, deliverStream } from \"../proxy/delivery.js\";\nimport { prepareRouteBodies, requestModel } from \"../proxy/request-shaping.js\";\nimport type { RequestMeta } from \"../telemetry/metric-types.js\";\nimport type { Gateway } from \"./gateway.js\";\nimport { newRequestMeta, readAll, writeError } from \"./gateway-helpers.js\";\n\n// The outcome of one upstream attempt.\nexport interface UpstreamOutcome {\n status: number;\n headers: Headers;\n stream: AsyncIterable<Uint8Array>;\n alias: string;\n shaped: boolean;\n}\n\n// handleCompletion serves one completion request. It routes the request to\n// the upstream lane that can serve it, then relays or converts the answer.\nexport async function handleCompletion(\n gateway: Gateway,\n protocol: Protocol,\n body: Buffer,\n headers: NodeJS.Dict<string | string[]>,\n response: ServerResponse,\n scope: string,\n): Promise<void> {\n const meta = newRequestMeta();\n gateway.metrics.enter();\n const started = Date.now();\n let status = 500;\n try {\n const payload = parsePayload(body);\n if (payload === undefined) {\n status = 400;\n writeError(\n response,\n protocol,\n 400,\n \"request body must be a JSON object\",\n \"invalid_request_error\",\n );\n return;\n }\n const model = requestModel(payload);\n if (model === \"\") {\n status = 400;\n writeError(\n response,\n protocol,\n 400,\n \"model is required\",\n \"invalid_request_error\",\n );\n return;\n }\n let route: Route;\n try {\n route = gateway.catalog.route(\n model,\n gateway.hasZenKeys(),\n gateway.hasGoKeys(),\n gateway.current().anonymous,\n );\n } catch (error) {\n status = 400;\n writeError(\n response,\n protocol,\n 400,\n error instanceof Error ? error.message : \"model is not available\",\n \"invalid_request_error\",\n );\n return;\n }\n meta.model = model;\n meta.modelAlias = model;\n meta.tier = route.tier;\n meta.protocol = route.protocol;\n\n const ids = deriveRequestIDs(headers as never, payload, scope);\n meta.request = ids.request;\n meta.session = ids.session;\n\n const { bodies } = prepareRouteBodies(\n route,\n payload,\n (tier: Tier) => isV1Upstream(gateway.tierBase(tier)),\n );\n\n const stream = boolAt(payload, \"stream\") === true;\n meta.stream = stream;\n\n const outcome = await callUpstream(gateway, route, bodies, ids, model, meta);\n if (outcome === undefined) {\n status = 502;\n meta.outcome = \"upstream_error\";\n writeError(\n response,\n protocol,\n 502,\n \"all upstream attempts failed\",\n \"upstream_error\",\n );\n return;\n }\n // The upstream lane reports the tool name it aliased and whether it\n // force streamed the request, so the response can be restored and\n // collapsed back.\n meta.shaped = outcome.shaped;\n meta.toolAlias = outcome.alias;\n status = outcome.status;\n response.setHeader(\"x-request-id\", ids.request);\n\n if (outcome.status < 200 || outcome.status >= 300) {\n meta.outcome = outcome.status >= 500 ? \"server_error\" : \"client_error\";\n const text = await readAll(outcome.stream);\n response.writeHead(outcome.status, {\n \"Content-Type\":\n outcome.headers.get(\"content-type\") ?? \"application/json\",\n });\n response.end(text);\n return;\n }\n\n if (stream) {\n gateway.metrics.enterStream();\n response.writeHead(200, {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n \"x-request-id\": ids.request,\n });\n const delivered = await deliverStream(\n route.protocol,\n protocol,\n outcome,\n model,\n outcome.alias,\n {\n write(chunk: Uint8Array): void {\n response.write(chunk);\n },\n },\n );\n gateway.metrics.leaveStream();\n meta.usage = delivered.usage;\n meta.usageReported = delivered.usagePresent;\n if (delivered.error !== undefined) {\n meta.outcome = \"stream_error\";\n }\n response.end();\n return;\n }\n\n const delivered = await deliverResponse(\n route.protocol,\n protocol,\n outcome,\n model,\n outcome.alias,\n outcome.shaped,\n );\n meta.usage = delivered.usage;\n meta.usageReported = delivered.usagePresent;\n response.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"x-request-id\": ids.request,\n });\n response.end(delivered.body);\n } catch (error) {\n status = 502;\n meta.outcome = \"upstream_error\";\n gateway.logger.warn(\"upstream request failed\", \"upstream\", {\n event: \"request_failed\",\n request_id: meta.request,\n error: error instanceof Error ? error.message : String(error),\n });\n if (!response.headersSent) {\n writeError(\n response,\n protocol,\n 502,\n \"all upstream attempts failed\",\n \"upstream_error\",\n );\n }\n } finally {\n gateway.metrics.leave();\n gateway.metrics.record(\"/v1/completions\", status, Date.now() - started, meta);\n }\n}\n\n// callUpstream walks the route's lanes until one of them answers.\nasync function callUpstream(\n gateway: Gateway,\n route: Route,\n bodies: { zen: string; go: string },\n ids: ReturnType<typeof deriveRequestIDs>,\n model: string,\n meta: RequestMeta,\n): Promise<UpstreamOutcome | undefined> {\n if (route.anonymous) {\n const result = await gateway.runner.runAnonymous(\n route.protocol,\n bodies.zen,\n ids,\n ids.request,\n model,\n );\n meta.attempts += result.attempts;\n meta.anonymous = true;\n meta.channel = \"anonymous\";\n if (result.response !== undefined && result.response.status < 300) {\n return { ...result.response, alias: result.alias, shaped: result.shaped };\n }\n }\n const tiers = route.keyTiers.length > 0 ? route.keyTiers : [route.tier];\n let lastResponse: UpstreamOutcome | undefined;\n for (const tier of tiers) {\n const result = await gateway.runner.runTier(\n tier,\n route.protocol,\n bodies[tier] ?? bodies.zen,\n ids,\n ids.request,\n model,\n );\n meta.attempts += result.attempts;\n meta.tier = tier;\n meta.channel = \"key\";\n meta.keyId = result.records[result.records.length - 1]?.key_id ?? \"\";\n if (result.response === undefined) {\n continue;\n }\n if (result.response.status < 300) {\n return { ...result.response, alias: result.alias, shaped: result.shaped };\n }\n // The last failure is reported to the client as it is, so the reason the\n // upstream rejected the request stays visible.\n lastResponse = { ...result.response, alias: result.alias, shaped: result.shaped };\n }\n return lastResponse;\n}\n\n// parsePayload decodes a request body into a JSON object.\nfunction parsePayload(body: Buffer): Record<string, unknown> | undefined {\n if (body.length === 0) {\n return {};\n }\n let value: unknown;\n try {\n value = JSON.parse(body.toString(\"utf8\")) as unknown;\n } catch {\n return undefined;\n }\n return isPlainObject(value) ? value : undefined;\n}\n", "import type { ServerResponse } from \"node:http\";\nimport type { Config, Tier } from \"../types/config.js\";\nimport { KeyPool } from \"../auth/key-pool.js\";\nimport { ModelCatalog } from \"../proxy/model-catalog.js\";\nimport { AttemptRunner } from \"../proxy/attempt-runner.js\";\nimport { Logger } from \"../telemetry/logger.js\";\nimport { LogBroker } from \"../telemetry/log-broker.js\";\nimport { Metrics } from \"../telemetry/metrics.js\";\nimport { fingerprintSecret } from \"../config/secrets.js\";\nimport { handleCompletion } from \"./completion-handler.js\";\n\n// Gateway serves the public API. It owns the key pools, the model catalog and\n// the telemetry, and routes every client request to the upstream lane that\n// can serve it.\nexport class Gateway {\n readonly logger: Logger;\n readonly logs: LogBroker;\n readonly metrics = new Metrics();\n readonly catalog: ModelCatalog;\n runner: AttemptRunner;\n\n private zenPool: KeyPool;\n private goPool: KeyPool;\n private config: Config;\n constructor(config: Config) {\n this.config = config;\n this.logs = new LogBroker(config.logging.ring_size);\n this.logger = new Logger(this.logs);\n this.catalog = new ModelCatalog({\n prefer: config.prefer,\n protocols: config.models.protocols,\n freeOnly: config.models.free_only,\n });\n this.zenPool = new KeyPool(config.zen_keys);\n this.goPool = new KeyPool(config.go_keys);\n this.runner = this.buildRunner();\n this.logger.setLevel(config.logging.level);\n this.logger.replaceSecrets(this.secrets());\n }\n\n // apply swaps the running configuration.\n apply(config: Config): void {\n this.config = config;\n this.zenPool = new KeyPool(config.zen_keys);\n this.goPool = new KeyPool(config.go_keys);\n this.runner = this.buildRunner();\n this.catalog.setOptions({\n prefer: config.prefer,\n protocols: config.models.protocols,\n freeOnly: config.models.free_only,\n });\n this.logger.setLevel(config.logging.level);\n this.logger.replaceSecrets(this.secrets());\n this.logs.resize(config.logging.ring_size);\n }\n\n // current returns the running configuration.\n current(): Config {\n return this.config;\n }\n\n // buildRunner creates the attempt runner of the running configuration.\n private buildRunner(): AttemptRunner {\n return new AttemptRunner(\n { zen: this.zenPool, go: this.goPool },\n this.config.upstream,\n this.config.retry.max_attempts,\n this.config.retry.timeout_seconds,\n this.logger,\n this.metrics,\n );\n }\n\n // secrets lists the values the logger masks out of its output.\n private secrets(): string[] {\n const config = this.config;\n const values = [\n ...config.server_keys,\n ...config.zen_keys,\n ...config.go_keys,\n ...config.proxies,\n ];\n if (config.webui.password !== undefined) {\n values.push(config.webui.password);\n }\n return values;\n }\n\n // serverKeys returns the local server keys the client authenticates with.\n serverKeys(): string[] {\n return this.config.server_keys;\n }\n\n // hasZenKeys reports whether the Zen tier has a key.\n hasZenKeys(): boolean {\n return !this.zenPool.isEmpty();\n }\n\n // hasGoKeys reports whether the Go tier has a key.\n hasGoKeys(): boolean {\n return !this.goPool.isEmpty();\n }\n\n // tierBase returns the base URL of a tier.\n tierBase(tier: Tier): string {\n return tier === \"go\" ? this.config.upstream.go : this.config.upstream.zen;\n }\n\n // handleCompletion serves one completion request.\n async handleCompletion(\n protocol: Parameters<typeof handleCompletion>[1],\n body: Buffer,\n headers: NodeJS.Dict<string | string[]>,\n response: ServerResponse,\n scope: string,\n ): Promise<void> {\n await handleCompletion(this, protocol, body, headers, response, scope);\n }\n\n // debugRequest runs one request in-process for the Playground. The response\n // is captured rather than forwarded to a client.\n async debugRequest(\n protocol: Parameters<typeof handleCompletion>[1],\n payload: Record<string, unknown>,\n serverKey: string,\n ): Promise<{ status: number; body: unknown; requestId: string }> {\n const body = Buffer.from(JSON.stringify(payload), \"utf8\");\n const headers: NodeJS.Dict<string | string[]> = {\n authorization: `Bearer ${serverKey}`,\n \"content-type\": \"application/json\",\n };\n const chunks: Buffer[] = [];\n let status = 0;\n const response = {\n writeHead(code: number): typeof response {\n status = code;\n return response;\n },\n setHeader(): void {},\n end(chunk?: Buffer | string): void {\n if (chunk !== undefined) {\n chunks.push(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, \"utf8\"),\n );\n }\n },\n headersSent: false,\n } as unknown as ServerResponse;\n await this.handleCompletion(\n protocol,\n body,\n headers,\n response,\n serverKeyScope(serverKey),\n );\n const text = Buffer.concat(chunks).toString(\"utf8\");\n let parsed: unknown = text;\n try {\n parsed = text === \"\" ? null : (JSON.parse(text) as unknown);\n } catch {\n parsed = text;\n }\n return { status, body: parsed, requestId: \"\" };\n }\n}\n\n// serverKeyScope returns the scope a server key scopes its sessions with.\nexport function serverKeyScope(key: string): string {\n return key === \"\" ? \"\" : fingerprintSecret(key);\n}\n", "import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { buildErrorEnvelope } from \"../protocol/error.js\";\nimport type { Protocol } from \"../types/config.js\";\n\n// The body limit a client request may carry.\nexport const MAX_REQUEST_BODY = 32 * 1024 * 1024;\n\n// The CORS headers the API answers with.\nexport const CORS_HEADERS: Record<string, string> = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, PATCH, DELETE, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type, Authorization, x-api-key, x-opencode-session, x-opencode-session-id, x-session-affinity, x-session-id, x-opencode-request, x-opencode-project, x-parent-session-id, x-opencode-client, Accept\",\n \"Access-Control-Max-Age\": \"86400\",\n};\n\n// RouteContext is what a route handler receives.\nexport interface RouteContext {\n request: IncomingMessage;\n response: ServerResponse;\n url: URL;\n protocol: Protocol;\n body: Buffer;\n}\n\n// RouteHandler serves one route.\nexport type RouteHandler = (context: RouteContext) => Promise<void> | void;\n\n// Route is one registered route.\nexport interface Route {\n method: string;\n path: string;\n protocol: Protocol;\n handler: RouteHandler;\n // public routes skip the client authentication, like the health check.\n public?: boolean;\n}\n\n// RequestDispatcher routes the client requests to their handlers. It applies\n// the CORS preflight, the client authentication and the body limit before the\n// handler runs.\nexport class RequestDispatcher {\n private readonly routes: Route[] = [];\n private readonly authKeys: () => string[];\n\n constructor(authKeys: () => string[]) {\n this.authKeys = authKeys;\n }\n\n // register adds a route.\n register(route: Route): void {\n this.routes.push(route);\n }\n\n // dispatch serves one request.\n async dispatch(\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<void> {\n const url = new URL(request.url ?? \"/\", `http://${request.headers.host ?? \"localhost\"}`);\n for (const [name, value] of Object.entries(CORS_HEADERS)) {\n response.setHeader(name, value);\n }\n if (request.method === \"OPTIONS\") {\n response.writeHead(204);\n response.end();\n return;\n }\n const route = this.match(request.method ?? \"GET\", url.pathname);\n if (route === undefined) {\n this.writeError(response, \"chat\", 404, \"not found\", \"invalid_request_error\");\n return;\n }\n if (route.public !== true && !this.authorized(request)) {\n this.writeError(\n response,\n route.protocol,\n 401,\n \"invalid API key\",\n \"authentication_error\",\n );\n return;\n }\n let body: Buffer;\n try {\n body = await readBody(request);\n } catch (error) {\n this.writeError(\n response,\n route.protocol,\n 400,\n error instanceof Error ? error.message : \"request body is too large\",\n \"invalid_request_error\",\n );\n return;\n }\n try {\n await route.handler({ request, response, url, protocol: route.protocol, body });\n } catch (error) {\n this.writeError(\n response,\n route.protocol,\n 500,\n error instanceof Error ? error.message : \"internal error\",\n \"server_error\",\n );\n }\n }\n\n // match finds the route for a method and path.\n private match(method: string, path: string): Route | undefined {\n return this.routes.find(\n (route) => route.method === method && route.path === path,\n );\n }\n\n // authorized reports whether the request carries a valid client key. A\n // server with no keys configured serves every request.\n private authorized(request: IncomingMessage): boolean {\n const keys = this.authKeys();\n if (keys.length === 0) {\n return true;\n }\n const presented = clientKey(request);\n if (presented === \"\") {\n return false;\n }\n return keys.some((key) => constantTimeEquals(key, presented));\n }\n\n // writeError answers a request with the protocol's error envelope.\n private writeError(\n response: ServerResponse,\n protocol: Protocol,\n status: number,\n message: string,\n kind: string,\n ): void {\n const envelope = buildErrorEnvelope(protocol, status, message, kind as never);\n const body = `${JSON.stringify(envelope.body)}\\n`;\n response.writeHead(envelope.status, {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(body),\n });\n response.end(body);\n }\n}\n\n// clientKey reads the client key from the request.\nexport function clientKey(request: IncomingMessage): string {\n const apiKey = request.headers[\"x-api-key\"];\n if (typeof apiKey === \"string\" && apiKey !== \"\") {\n return apiKey;\n }\n const authorization = request.headers.authorization;\n if (typeof authorization !== \"string\") {\n return \"\";\n }\n const prefix = \"bearer \";\n if (!authorization.toLowerCase().startsWith(prefix)) {\n return \"\";\n }\n return authorization.slice(prefix.length).trim();\n}\n\n// constantTimeEquals compares two secrets without leaking their length\n// through the timing.\nexport function constantTimeEquals(left: string, right: string): boolean {\n const a = Buffer.from(left, \"utf8\");\n const b = Buffer.from(right, \"utf8\");\n if (a.length !== b.length) {\n return false;\n }\n return timingSafeEqual(a, b);\n}\n\n// readBody reads the request body, bounded by the body limit.\nexport async function readBody(request: IncomingMessage): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of request) {\n const buffer = chunk as Buffer;\n total += buffer.byteLength;\n if (total > MAX_REQUEST_BODY) {\n throw new Error(\"request body is too large\");\n }\n chunks.push(buffer);\n }\n return Buffer.concat(chunks);\n}\n\n// startServer starts the API server and returns it.\nexport function startServer(\n dispatcher: RequestDispatcher,\n listen: string,\n): Promise<Server> {\n const server = createServer((request, response) => {\n void dispatcher.dispatch(request, response);\n });\n return new Promise((resolve, reject) => {\n server.once(\"error\", reject);\n const { host, port } = parseListen(listen);\n server.listen(port, host, () => {\n server.removeListener(\"error\", reject);\n resolve(server);\n });\n });\n}\n\n// parseListen splits a listen address into its host and port. Node's listen\n// takes a port and a host, not an \"host:port\" string, which it would treat\n// as a named pipe.\nexport function parseListen(listen: string): { host: string; port: number } {\n const index = listen.lastIndexOf(\":\");\n if (index === -1) {\n return { host: \"127.0.0.1\", port: 8080 };\n }\n const host = listen.slice(0, index) || \"127.0.0.1\";\n const port = Number(listen.slice(index + 1));\n return { host, port: Number.isFinite(port) ? port : 8080 };\n}\n", "import type { ServerResponse } from \"node:http\";\nimport type { Protocol } from \"../types/config.js\";\nimport { isPlainObject, sliceAt, stringAt } from \"../protocol/json-util.js\";\nimport { buildDoctorReport, resolveEdgePool } from \"../unlimited/index.js\";\nimport { RequestDispatcher, type RouteContext } from \"./dispatcher.js\";\nimport { serverKeyScope, type Gateway } from \"./gateway.js\";\n\n// registerRoutes wires the public API routes onto a dispatcher.\nexport function registerRoutes(dispatcher: RequestDispatcher, gateway: Gateway): void {\n dispatcher.register({\n method: \"GET\",\n path: \"/healthz\",\n protocol: \"chat\",\n public: true,\n handler: (context) => {\n writeJSON(context.response, 200, healthPayload(gateway));\n },\n });\n dispatcher.register({\n method: \"GET\",\n path: \"/v1/unlimited/doctor\",\n protocol: \"chat\",\n handler: (context) => {\n void handleUnlimitedDoctor(context, gateway);\n },\n });\n dispatcher.register({\n method: \"POST\",\n path: \"/v1/unlimited/hop\",\n protocol: \"chat\",\n handler: (context) => {\n void handleUnlimitedHop(context, gateway);\n },\n });\n dispatcher.register({\n method: \"GET\",\n path: \"/v1/models\",\n protocol: \"chat\",\n handler: (context) => {\n writeJSON(context.response, 200, modelsPayload(gateway));\n },\n });\n for (const [path, protocol] of [\n [\"/v1/chat/completions\", \"chat\"],\n [\"/v1/responses\", \"responses\"],\n [\"/v1/messages\", \"anthropic\"],\n [\"/v1/systemone\", \"systemone\"],\n ] as const) {\n dispatcher.register({\n method: \"POST\",\n path,\n protocol,\n handler: (context) => {\n void handleCompletion(context, gateway, protocol);\n },\n });\n }\n}\n\n// handleUnlimitedDoctor answers with the unlimited guard and egress health report.\nasync function handleUnlimitedDoctor(\n context: RouteContext,\n gateway: Gateway,\n): Promise<void> {\n const guard = gateway.runner.guard;\n const pool = await resolveEdgePool();\n guard.setPool(pool);\n const report = await buildDoctorReport(guard, fetch, \"node\");\n writeJSON(context.response, 200, report);\n}\n\n// handleUnlimitedHop rotates the active edge and device/session identity.\nasync function handleUnlimitedHop(\n context: RouteContext,\n gateway: Gateway,\n): Promise<void> {\n const guard = gateway.runner.guard;\n const oldEdge = guard.current().edge;\n const pool = await resolveEdgePool();\n guard.setPool(pool);\n const rotated = guard.hop(pool, true);\n const snap = guard.snapshot();\n writeJSON(context.response, 200, {\n status: \"rotated\",\n old_edge: oldEdge,\n new_edge: rotated.edge,\n prefix64: rotated.prefix64,\n session: rotated.ids.session,\n machine_id: rotated.machineId,\n hops: snap.hops,\n blacklisted_count: snap.blacklist.length,\n });\n}\n\n// handleCompletion serves one completion request.\nasync function handleCompletion(\n context: RouteContext,\n gateway: Gateway,\n protocol: Protocol,\n): Promise<void> {\n const scope = serverKeyScope(gateway.serverKeys()[0] ?? \"\");\n await gateway.handleCompletion(\n protocol,\n context.body,\n context.request.headers,\n context.response,\n scope,\n );\n}\n\n// healthPayload renders the health document.\nfunction healthPayload(gateway: Gateway): Record<string, unknown> {\n const config = gateway.current();\n const snapshot = gateway.catalog.snapshot();\n return {\n status: \"ok\",\n version: \"dev\",\n uptime_seconds: Math.trunc(process.uptime()),\n models: {\n total: snapshot.total,\n exposed: snapshot.exposed,\n zen: snapshot.zen,\n go: snapshot.go,\n stale: snapshot.stale,\n },\n keys: {\n zen: config.zen_keys.length,\n go: config.go_keys.length,\n server: config.server_keys.length,\n },\n anonymous: config.anonymous,\n };\n}\n\n// modelsPayload renders the model listing. Every model the catalog exposes\n// carries its native protocol and the endpoints it can be served on.\nfunction modelsPayload(gateway: Gateway): Record<string, unknown> {\n const { routes, snapshot } = gateway.catalog.availableModels(\n gateway.hasZenKeys(),\n gateway.hasGoKeys(),\n gateway.current().anonymous,\n );\n const created = Math.floor(Date.now() / 1000);\n const data = routes.map((route) => {\n const metadata = gateway.catalog.metadataForTier(route.id, route.tier);\n const entry: Record<string, unknown> = {\n id: route.id,\n object: \"model\",\n created,\n owned_by: \"opencode\",\n };\n if (metadata.contextWindow > 0) {\n entry[\"context_window\"] = metadata.contextWindow;\n entry[\"context_length\"] = metadata.contextWindow;\n }\n if (metadata.maxInput > 0) {\n entry[\"max_input\"] = metadata.maxInput;\n }\n if (metadata.maxOutput > 0) {\n entry[\"max_output\"] = metadata.maxOutput;\n }\n if (metadata.reasoning) {\n entry[\"reasoning\"] = true;\n entry[\"supports_reasoning\"] = true;\n entry[\"reasoning_efforts\"] = [\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n ];\n }\n if (metadata.toolCall) {\n entry[\"tool_call\"] = true;\n }\n if (metadata.structuredOutput) {\n entry[\"structured_output\"] = true;\n }\n entry[\"native_protocol\"] = route.protocol;\n entry[\"supported_endpoints\"] = [\n \"/v1/chat/completions\",\n \"/v1/responses\",\n \"/v1/messages\",\n ];\n return entry;\n });\n return { object: \"list\", data, total: snapshot.total, exposed: snapshot.exposed };\n}\n\n// writeJSON answers a request with a JSON document.\nexport function writeJSON(\n response: ServerResponse,\n status: number,\n body: unknown,\n): void {\n const text = `${JSON.stringify(body)}\\n`;\n response.writeHead(status, {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(text),\n });\n response.end(text);\n}\n\n// modelIDs reads the model ids of a listing payload.\nexport function modelIDs(payload: unknown): string[] {\n const ids: string[] = [];\n for (const raw of sliceAt(payload, \"data\")) {\n const id = stringAt(raw, \"id\");\n if (id !== \"\") {\n ids.push(id);\n }\n }\n return ids;\n}\n\n// isPayloadObject reports whether a decoded body is a JSON object.\nexport function isPayloadObject(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value);\n}\n", "import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { scryptSync, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport type { Config } from \"../../types/config.js\";\nimport type { Gateway } from \"../gateway.js\";\nimport { WEBUI_HTML } from \"../../webui/document.js\";\nimport {\n SESSION_COOKIE,\n SessionStore,\n authVersionOf,\n} from \"./session.js\";\nimport { handleAdminRequest } from \"./routes.js\";\nimport { writeAdminError } from \"./responses.js\";\n\n// The security headers every response carries.\nexport const SECURITY_HEADERS: Record<string, string> = {\n \"Content-Security-Policy\":\n \"default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:\",\n \"Referrer-Policy\": \"no-referrer\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"X-Frame-Options\": \"DENY\",\n \"Permissions-Policy\": \"camera=(), microphone=(), geolocation=()\",\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n};\n\n// The scrypt parameters the password hash uses.\nconst SCRYPT_N = 16384;\nconst SCRYPT_R = 8;\nconst SCRYPT_P = 1;\nconst SCRYPT_KEY_LENGTH = 32;\nconst SCRYPT_SALT_LENGTH = 16;\n\n// hashPassword derives a storable hash from a password.\nexport function hashPassword(password: string): string {\n const salt = randomBytes(SCRYPT_SALT_LENGTH);\n const derived = scryptSync(password, salt, SCRYPT_KEY_LENGTH, {\n N: SCRYPT_N,\n r: SCRYPT_R,\n p: SCRYPT_P,\n });\n return [\n \"$scrypt\",\n `N=${SCRYPT_N},r=${SCRYPT_R},p=${SCRYPT_P}`,\n salt.toString(\"base64\"),\n derived.toString(\"base64\"),\n ].join(\"$\");\n}\n// verifyPassword checks a password against a storable hash.\nexport function verifyPassword(hash: string, password: string): boolean {\n const parts = hash.split(\"$\");\n // The format is \"$scrypt$N=..,r=..,p=..$<salt>$<hash>\", so the split\n // yields an empty first part and four more.\n if (parts.length !== 5 || parts[1] !== \"scrypt\") {\n return false;\n }\n const params = parts[2] ?? \"\";\n const N = paramValue(params, \"N\");\n const r = paramValue(params, \"r\");\n const p = paramValue(params, \"p\");\n if (N === 0 || r === 0 || p === 0) {\n return false;\n }\n let salt: Buffer;\n let expected: Buffer;\n try {\n salt = Buffer.from(parts[3] ?? \"\", \"base64\");\n expected = Buffer.from(parts[4] ?? \"\", \"base64\");\n } catch {\n return false;\n }\n if (salt.length === 0 || expected.length === 0) {\n return false;\n }\n let derived: Buffer;\n try {\n derived = scryptSync(password, salt, expected.length, { N, r, p });\n } catch {\n return false;\n }\n if (derived.length !== expected.length) {\n return false;\n }\n return constantTimeEquals(derived.toString(\"base64\"), expected.toString(\"base64\"));\n}\n\n// paramValue reads one parameter of a hash's parameter list.\nfunction paramValue(params: string, name: string): number {\n for (const part of params.split(\",\")) {\n const [key, value] = part.split(\"=\");\n if (key === name) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n }\n return 0;\n}\n\n// constantTimeEquals compares two secrets without leaking their length.\nexport function constantTimeEquals(left: string, right: string): boolean {\n const a = Buffer.from(left, \"utf8\");\n const b = Buffer.from(right, \"utf8\");\n if (a.length !== b.length) {\n return false;\n }\n return timingSafeEqual(a, b);\n}\n\n// WebUIServer serves the control panel and the admin API.\nexport class WebUIServer {\n readonly sessions = new SessionStore();\n readonly gateway: Gateway;\n\n constructor(gateway: Gateway, private readonly config: Config) {\n this.gateway = gateway;\n }\n\n // handle serves one request.\n async handle(request: IncomingMessage, response: ServerResponse): Promise<void> {\n for (const [name, value] of Object.entries(SECURITY_HEADERS)) {\n response.setHeader(name, value);\n }\n const url = new URL(\n request.url ?? \"/\",\n `http://${request.headers.host ?? \"localhost\"}`,\n );\n if (url.pathname.startsWith(\"/api/\")) {\n await handleAdminRequest(this, request, response, url);\n return;\n }\n this.serveDocument(response);\n }\n\n // serveDocument answers with the WebUI.\n private serveDocument(response: ServerResponse): void {\n response.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Content-Length\": Buffer.byteLength(WEBUI_HTML),\n });\n response.end(WEBUI_HTML);\n }\n\n // currentConfig returns the running configuration.\n currentConfig(): Config {\n return this.config;\n }\n\n // sessionCookie builds the cookie that carries a session token.\n sessionCookie(token: string, maxAgeSeconds: number, secure: boolean): string {\n const parts = [\n `${SESSION_COOKIE}=${token}`,\n \"Path=/\",\n \"HttpOnly\",\n \"SameSite=Strict\",\n `Max-Age=${maxAgeSeconds}`,\n ];\n if (secure) {\n parts.push(\"Secure\");\n }\n return parts.join(\"; \");\n }\n\n // clearCookie builds the cookie that ends a session.\n clearCookie(secure: boolean): string {\n return this.sessionCookie(\"\", -1, secure);\n }\n\n // tokenFrom reads the session token from a request's cookies.\n tokenFrom(request: IncomingMessage): string {\n const header = request.headers.cookie;\n if (typeof header !== \"string\") {\n return \"\";\n }\n for (const part of header.split(\";\")) {\n const [name, ...rest] = part.trim().split(\"=\");\n if (name === SESSION_COOKIE) {\n return rest.join(\"=\");\n }\n }\n return \"\";\n }\n\n // isSecure reports whether the request arrived over TLS.\n isSecure(request: IncomingMessage): boolean {\n const forwarded = request.headers[\"x-forwarded-proto\"];\n if (\n typeof forwarded === \"string\" &&\n forwarded.trim().toLowerCase() === \"https\"\n ) {\n return true;\n }\n return (request.socket as { encrypted?: boolean }).encrypted === true;\n }\n\n // validSession returns the session a request carries, or undefined.\n validSession(request: IncomingMessage): ReturnType<SessionStore[\"get\"]> {\n const token = this.tokenFrom(request);\n const session = this.sessions.get(token);\n if (session === undefined) {\n return undefined;\n }\n if (session.username !== this.config.webui.username) {\n return undefined;\n }\n if (session.authVersion !== authVersionOf(this.config)) {\n return undefined;\n }\n return session;\n }\n\n // checkCredentials reports whether a username and password match.\n checkCredentials(username: string, password: string): boolean {\n if (username !== this.config.webui.username) {\n return false;\n }\n const hash = this.config.webui.password_hash ?? \"\";\n if (hash !== \"\") {\n return verifyPassword(hash, password);\n }\n return constantTimeEquals(this.config.webui.password ?? \"\", password);\n }\n}\n\n// startWebUIServer starts the control panel server.\nexport async function startWebUIServer(\n gateway: Gateway,\n listen: string,\n): Promise<Server> {\n const server = new WebUIServer(gateway, gateway.current());\n const http = createServer((request, response) => {\n void server.handle(request, response).catch(() => {\n if (!response.headersSent) {\n writeAdminError(response, 500, \"internal_error\", \"internal error\");\n }\n });\n });\n return new Promise((resolve, reject) => {\n http.once(\"error\", reject);\n const { host, port } = parseListen(listen);\n http.listen(port, host, () => {\n http.removeListener(\"error\", reject);\n resolve(http);\n });\n });\n}\n\n// parseListen splits a listen address into its host and port.\nfunction parseListen(listen: string): { host: string; port: number } {\n const index = listen.lastIndexOf(\":\");\n if (index === -1) {\n return { host: \"127.0.0.1\", port: 8081 };\n }\n const host = listen.slice(0, index) || \"127.0.0.1\";\n const port = Number(listen.slice(index + 1));\n return { host, port: Number.isFinite(port) ? port : 8081 };\n}\n", "// The greyscale dark theme tokens, ported from the Go WebUI's tokens.css.\nexport const THEME_TOKENS = `:root {\n --bg: #0a0a0a;\n --bg-subtle: #171717;\n --surface: #121212;\n --surface-2: #0d0d0d;\n --text-1: #ededed;\n --text-2: #a0a0a0;\n --text-3: #787878;\n --border-1: #262626;\n --border-2: #3a3a3a;\n --inverse-bg: #ededed;\n --inverse-text: #0a0a0a;\n --inverse-hover: #cfcfcf;\n --focus-ring: rgba(237, 237, 237, 0.18);\n --overlay: rgba(0, 0, 0, 0.6);\n --ok: #3fb950;\n --warn: #d29922;\n --warn-bg: rgba(210, 153, 34, 0.15);\n --bad: #f85149;\n --bad-bg: rgba(248, 81, 73, 0.15);\n --fs-xs: 12px;\n --fs-sm: 13px;\n --fs-md: 14px;\n --fs-lg: 16px;\n --fs-xl: 20px;\n --fs-2xl: 24px;\n --fs-3xl: 30px;\n --sp-1: 4px;\n --sp-2: 8px;\n --sp-3: 12px;\n --sp-4: 16px;\n --sp-5: 20px;\n --sp-6: 24px;\n --sp-8: 32px;\n --sp-10: 40px;\n --sp-12: 48px;\n --r-sm: 4px;\n --r-md: 6px;\n --r-lg: 10px;\n --sidebar-w: 232px;\n --content-max: 1280px;\n}`;\n", "// The WebUI stylesheet. The layout is a fixed sidebar beside a scrolling\n// content column, and every primitive mirrors the greyscale dark tokens.\nexport const WEBUI_STYLES = `\n* { box-sizing: border-box; margin: 0; padding: 0; }\n\nhtml, body {\n height: 100%;\n background: var(--bg);\n color: var(--text-1);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\",\n \"Microsoft YaHei\", Roboto, Helvetica, Arial, sans-serif;\n font-size: var(--fs-md);\n line-height: 1.55;\n -webkit-font-smoothing: antialiased;\n}\n\na { color: var(--text-1); text-decoration: none; }\na:hover { color: var(--inverse-hover); }\n\ncode, pre, .mono {\n font-family: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas,\n \"Liberation Mono\", monospace;\n font-size: var(--fs-sm);\n}\n\n#layout { display: flex; min-height: 100%; }\n\n#sidebar {\n width: var(--sidebar-w);\n flex: 0 0 var(--sidebar-w);\n background: var(--surface);\n border-right: 1px solid var(--border-1);\n padding: var(--sp-5) var(--sp-3);\n position: sticky;\n top: 0;\n height: 100vh;\n overflow-y: auto;\n}\n\n#brand {\n display: flex;\n align-items: center;\n gap: var(--sp-2);\n padding: 0 var(--sp-3) var(--sp-5);\n font-size: var(--fs-lg);\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n#brand .dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--text-1);\n}\n\n.nav-group { margin-bottom: var(--sp-5); }\n.nav-group h3 {\n font-size: var(--fs-xs);\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--text-3);\n padding: 0 var(--sp-3) var(--sp-2);\n}\n\n.nav-item {\n display: block;\n padding: var(--sp-2) var(--sp-3);\n border-radius: var(--r-md);\n color: var(--text-2);\n font-size: var(--fs-sm);\n cursor: pointer;\n border: 1px solid transparent;\n}\n\n.nav-item:hover { background: var(--bg-subtle); color: var(--text-1); }\n.nav-item.active {\n background: var(--surface-2);\n color: var(--text-1);\n border-color: var(--border-1);\n}\n\n#content {\n flex: 1 1 auto;\n max-width: var(--content-max);\n padding: var(--sp-8) var(--sp-8) var(--sp-12);\n min-width: 0;\n}\n\n.page-head {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--sp-4);\n margin-bottom: var(--sp-6);\n flex-wrap: wrap;\n}\n\n.page-head h1 { font-size: var(--fs-2xl); font-weight: 600; letter-spacing: -0.02em; }\n.page-head p { color: var(--text-3); font-size: var(--fs-sm); }\n\n.card {\n background: var(--surface);\n border: 1px solid var(--border-1);\n border-radius: var(--r-lg);\n padding: var(--sp-5);\n margin-bottom: var(--sp-4);\n}\n\n.card h2 {\n font-size: var(--fs-lg);\n font-weight: 600;\n margin-bottom: var(--sp-4);\n}\n\n.grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: var(--sp-4);\n}\n\n.stat {\n background: var(--surface);\n border: 1px solid var(--border-1);\n border-radius: var(--r-lg);\n padding: var(--sp-4) var(--sp-5);\n}\n\n.stat .label {\n color: var(--text-3);\n font-size: var(--fs-xs);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: var(--sp-2);\n}\n\n.stat .value { font-size: var(--fs-3xl); font-weight: 600; letter-spacing: -0.03em; }\n.stat .sub { color: var(--text-3); font-size: var(--fs-xs); margin-top: var(--sp-1); }\n\ntable { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }\nth {\n text-align: left;\n font-weight: 500;\n color: var(--text-3);\n font-size: var(--fs-xs);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n padding: var(--sp-2) var(--sp-3);\n border-bottom: 1px solid var(--border-1);\n}\ntd { padding: var(--sp-3); border-bottom: 1px solid var(--border-1); }\ntr:last-child td { border-bottom: none; }\ntbody tr:hover { background: var(--bg-subtle); }\n\nbutton, .btn {\n appearance: none;\n border: 1px solid var(--border-2);\n background: var(--surface-2);\n color: var(--text-1);\n border-radius: var(--r-md);\n padding: var(--sp-2) var(--sp-4);\n font-size: var(--fs-sm);\n font-family: inherit;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\nbutton:hover, .btn:hover { background: var(--bg-subtle); border-color: var(--text-3); }\nbutton:focus-visible, .btn:focus-visible, input:focus-visible,\nselect:focus-visible, textarea:focus-visible {\n outline: 2px solid var(--focus-ring);\n outline-offset: 2px;\n}\n\nbutton.primary {\n background: var(--inverse-bg);\n color: var(--inverse-text);\n border-color: var(--inverse-bg);\n font-weight: 500;\n}\nbutton.primary:hover { background: var(--inverse-hover); border-color: var(--inverse-hover); }\nbutton.ghost { background: transparent; border-color: var(--border-1); }\nbutton:disabled { opacity: 0.5; cursor: not-allowed; }\n\ninput, select, textarea {\n width: 100%;\n background: var(--surface-2);\n border: 1px solid var(--border-2);\n border-radius: var(--r-md);\n color: var(--text-1);\n padding: var(--sp-2) var(--sp-3);\n font-size: var(--fs-sm);\n font-family: inherit;\n}\n\ntextarea { min-height: 140px; resize: vertical; font-family: inherit; }\ninput::placeholder, textarea::placeholder { color: var(--text-3); }\n\n.field { margin-bottom: var(--sp-4); }\n.field label {\n display: block;\n font-size: var(--fs-xs);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--text-3);\n margin-bottom: var(--sp-2);\n}\n.field .hint { color: var(--text-3); font-size: var(--fs-xs); margin-top: var(--sp-1); }\n\n.row { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: center; }\n.row > * { flex: 1 1 200px; }\n.row > .shrink { flex: 0 0 auto; }\n\n.badge {\n display: inline-block;\n padding: 1px var(--sp-2);\n border-radius: var(--r-sm);\n font-size: var(--fs-xs);\n border: 1px solid var(--border-2);\n color: var(--text-2);\n white-space: nowrap;\n}\n\n.badge.ok { color: var(--ok); border-color: var(--ok); }\n.badge.warn { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }\n.badge.bad { color: var(--bad); border-color: var(--bad); background: var(--bad-bg); }\n\n#toast {\n position: fixed;\n right: var(--sp-6);\n bottom: var(--sp-6);\n background: var(--surface);\n border: 1px solid var(--border-2);\n border-radius: var(--r-md);\n padding: var(--sp-3) var(--sp-5);\n font-size: var(--fs-sm);\n max-width: 380px;\n display: none;\n z-index: 40;\n}\n\n#toast.show { display: block; }\n#toast.error { border-color: var(--bad); color: var(--bad); }\n\n.log-line {\n display: grid;\n grid-template-columns: 92px 64px 1fr;\n gap: var(--sp-3);\n padding: var(--sp-1) 0;\n border-bottom: 1px solid var(--border-1);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: var(--fs-xs);\n}\n\n.log-line .time { color: var(--text-3); }\n.log-line .level { text-transform: uppercase; }\n.log-line .level.debug { color: var(--text-3); }\n.log-line .level.info { color: var(--text-1); }\n.log-line .level.warn { color: var(--warn); }\n.log-line .level.error { color: var(--bad); }\n.log-line .message { color: var(--text-2); word-break: break-word; }\n\n#login {\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--sp-6);\n}\n\n#login .card { width: 100%; max-width: 380px; margin: 0; }\n#login h1 { font-size: var(--fs-xl); margin-bottom: var(--sp-2); }\n#login p { color: var(--text-3); font-size: var(--fs-sm); margin-bottom: var(--sp-5); }\n\n.hidden { display: none !important; }\n\n.bar {\n height: 6px;\n background: var(--surface-2);\n border-radius: 3px;\n overflow: hidden;\n}\n.bar > span { display: block; height: 100%; background: var(--text-2); }\n\n.empty {\n color: var(--text-3);\n font-size: var(--fs-sm);\n padding: var(--sp-6);\n text-align: center;\n}\n`;\n", "// The shared state, the navigation and the helpers every page uses.\nexport const WEBUI_CORE = `\nconst state = { csrf: \"\", page: \"overview\", config: null, monitor: null };\n\nconst PAGES = [\n { group: \"Monitor\", id: \"overview\", label: \"Overview\" },\n { group: \"Monitor\", id: \"models\", label: \"Models\" },\n { group: \"Monitor\", id: \"keys\", label: \"API Keys\" },\n { group: \"Monitor\", id: \"quota\", label: \"Quota\" },\n { group: \"Tools\", id: \"playground\", label: \"Playground\" },\n { group: \"Tools\", id: \"rotation\", label: \"Rotation\" },\n { group: \"Settings\", id: \"config\", label: \"Configuration\" },\n { group: \"Settings\", id: \"account\", label: \"Account\" },\n { group: \"Settings\", id: \"logs\", label: \"Logs\" },\n];\n\nconst el = (id) => document.getElementById(id);\n\nfunction toast(message, isError) {\n const node = el(\"toast\");\n node.textContent = message;\n node.className = \"show\" + (isError ? \" error\" : \"\");\n clearTimeout(node._timer);\n node._timer = setTimeout(() => { node.className = \"\"; }, 4000);\n}\n\nasync function api(path, options) {\n const settings = Object.assign({ credentials: \"same-origin\" }, options || {});\n settings.headers = Object.assign(\n { \"Content-Type\": \"application/json\" },\n settings.headers || {},\n );\n if (state.csrf && settings.method && settings.method !== \"GET\") {\n settings.headers[\"X-CSRF-Token\"] = state.csrf;\n }\n const response = await fetch(path, settings);\n if (response.status === 401) {\n showLogin();\n throw new Error(\"session expired\");\n }\n const text = await response.text();\n let payload = null;\n if (text) {\n try { payload = JSON.parse(text); } catch { payload = text; }\n }\n if (!response.ok) {\n const message = payload && payload.error\n ? payload.error.message\n : \"request failed with HTTP \" + response.status;\n throw new Error(message);\n }\n return payload;\n}\n\nfunction showLogin() {\n el(\"app\").classList.add(\"hidden\");\n el(\"login\").classList.remove(\"hidden\");\n}\n\nfunction showApp() {\n el(\"login\").classList.add(\"hidden\");\n el(\"app\").classList.remove(\"hidden\");\n}\n\nfunction renderNav() {\n const groups = [];\n for (const page of PAGES) {\n let group = groups.find((entry) => entry.name === page.group);\n if (!group) {\n group = { name: page.group, items: [] };\n groups.push(group);\n }\n group.items.push(page);\n }\n el(\"nav\").innerHTML = groups.map((group) => (\n '<div class=\"nav-group\"><h3>' + group.name + '</h3>' +\n group.items.map((page) => (\n '<a class=\"nav-item\" data-page=\"' + page.id + '\">' + page.label + '</a>'\n )).join(\"\") +\n '</div>'\n )).join(\"\");\n for (const node of document.querySelectorAll(\".nav-item\")) {\n node.addEventListener(\"click\", () => {\n location.hash = \"#\" + node.dataset.page;\n });\n }\n}\n\nfunction markActive() {\n for (const node of document.querySelectorAll(\".nav-item\")) {\n node.classList.toggle(\"active\", node.dataset.page === state.page);\n }\n}\n\nfunction fmt(n) {\n if (n === undefined || n === null) return \"0\";\n return Number(n).toLocaleString(\"en-US\");\n}\n\nfunction pct(value) {\n return (Math.round(value * 1000) / 10).toFixed(1) + \"%\";\n}\n\nfunction escapeHtml(value) {\n return String(value)\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction stat(label, value, sub) {\n return '<div class=\"stat\"><div class=\"label\">' + escapeHtml(label) +\n '</div><div class=\"value\">' + escapeHtml(value) +\n '</div><div class=\"sub\">' + escapeHtml(sub) + '</div></div>';\n}\n`;\n", "// The monitor pages of the control WebUI: the overview, the models, the\n// local keys and the quota.\nexport const WEBUI_MONITOR_PAGES = `\nasync function loadOverview() {\n const data = await api(\"/api/monitor\");\n state.monitor = data;\n const metrics = data.metrics || {};\n const lifetime = metrics.lifetime || {};\n const window = metrics.last_hour || {};\n const usage = metrics.usage || {};\n const upstream = metrics.upstream || {};\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Overview</h1>' +\n '<p>Live traffic, token usage and upstream health</p></div></div>' +\n '<div class=\"grid\">' +\n stat(\"Total requests\", fmt(lifetime.total), fmt(lifetime.errors) + \" errors\") +\n stat(\"Success rate\", pct(lifetime.success_rate || 0), \"lifetime\") +\n stat(\"Active requests\", fmt(metrics.active_requests), fmt(metrics.active_streams) + \" streaming\") +\n stat(\"Uptime\", formatUptime(metrics.uptime_seconds), \"since start\") +\n stat(\"Input tokens\", fmt(usageLifetime(usage, \"input_tokens\")), \"lifetime\") +\n stat(\"Output tokens\", fmt(usageLifetime(usage, \"output_tokens\")), \"lifetime\") +\n stat(\"Last hour\", fmt(window.total), \"requests\") +\n stat(\"Upstream attempts\", fmt((upstream.lifetime || {}).total), \"total\") +\n '</div>' +\n '<div class=\"card\"><h2>Requests per minute</h2>' +\n seriesChart(metrics.series || []) +\n '</div>' +\n '<div class=\"card\"><h2>Models</h2>' +\n countTable(metrics.models || {}) +\n '</div>' +\n '<div class=\"card\"><h2>Recent upstream requests</h2>' +\n upstreamTable(upstream.requests || []) +\n '</div>'\n );\n}\n\nfunction usageLifetime(usage, field) {\n const lifetime = usage.lifetime || {};\n const tokens = lifetime.tokens || {};\n return tokens[field] || 0;\n}\n\nfunction formatUptime(seconds) {\n const total = Math.max(0, Math.floor(seconds || 0));\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n if (hours > 0) return hours + \"h \" + minutes + \"m\";\n return minutes + \"m \" + (total % 60) + \"s\";\n}\n\nfunction seriesChart(series) {\n if (!series.length) return '<div class=\"empty\">No traffic recorded yet</div>';\n const max = series.reduce((acc, point) => Math.max(acc, point.total), 0) || 1;\n const bars = series.slice(-30).map((point) => {\n const height = Math.round((point.total / max) * 100);\n const label = new Date(point.minute).toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\", minute: \"2-digit\",\n });\n return '<div title=\"' + escapeHtml(label) + \": \" + point.total + \" requests, \" +\n point.errors + ' errors\" style=\"flex:1 1 0;height:100%;display:flex;' +\n 'flex-direction:column;justify-content:flex-end\">' +\n '<div style=\"height:' + Math.max(height, 1) + '%;background:var(--text-2);' +\n 'border-radius:2px 2px 0 0\"></div></div>';\n }).join(\"\");\n return '<div style=\"display:flex;align-items:flex-end;gap:2px;height:140px\">' +\n bars + '</div>';\n}\n\nfunction countTable(counts) {\n const entries = Object.entries(counts || {});\n if (!entries.length) return '<div class=\"empty\">No data yet</div>';\n entries.sort((a, b) => b[1] - a[1]);\n return '<table><thead><tr><th>Name</th><th>Count</th></tr></thead><tbody>' +\n entries.map(([name, count]) =>\n '<tr><td class=\"mono\">' + escapeHtml(name) + '</td><td>' + fmt(count) + '</td></tr>'\n ).join(\"\") + '</tbody></table>';\n}\n\nfunction upstreamTable(requests) {\n if (!requests.length) return '<div class=\"empty\">No upstream requests yet</div>';\n return '<table><thead><tr><th>Time</th><th>Model</th><th>Tier</th>' +\n '<th>Status</th><th>Duration</th><th>Outcome</th></tr></thead><tbody>' +\n requests.slice().reverse().slice(0, 50).map((entry) =>\n '<tr><td class=\"mono\">' + escapeHtml(new Date(entry.time).toLocaleTimeString()) +\n '</td><td class=\"mono\">' + escapeHtml(entry.model) +\n '</td><td>' + escapeHtml(entry.tier || \"-\") +\n '</td><td>' + escapeHtml(entry.status) +\n '</td><td>' + fmt(entry.duration_ms) + \" ms\" +\n '</td><td>' + escapeHtml(entry.outcome || \"-\") + '</td></tr>'\n ).join(\"\") + '</tbody></table>';\n}\n\nasync function loadModels() {\n const data = await api(\"/api/debug/models\");\n const models = data.models || [];\n const catalog = data.catalog || {};\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Models</h1>' +\n '<p>' + fmt(catalog.total) + \" discovered, \" + fmt(catalog.exposed) +\n \" exposed\" + (catalog.stale ? \" (stale)\" : \"\") + '</p></div></div>' +\n '<div class=\"card\"><h2>Catalog</h2>' +\n '<div class=\"grid\">' +\n stat(\"Zen models\", fmt(catalog.zen), \"\") +\n stat(\"Go models\", fmt(catalog.go), \"\") +\n stat(\"Total\", fmt(catalog.total), \"\") +\n stat(\"Exposed\", fmt(catalog.exposed), \"\") +\n '</div></div>' +\n '<div class=\"card\"><h2>Routing</h2>' +\n modelsTable(models) +\n '</div>'\n );\n}\n\nfunction modelsTable(models) {\n if (!models.length) return '<div class=\"empty\">No models discovered yet</div>';\n return '<table><thead><tr><th>Model</th><th>Protocol</th><th>Tier</th>' +\n '<th>Anonymous</th><th>Source</th><th>Error</th></tr></thead><tbody>' +\n models.map((entry) =>\n '<tr><td class=\"mono\">' + escapeHtml(entry.model) +\n '</td><td>' + escapeHtml(entry.native_protocol || \"-\") +\n '</td><td>' + escapeHtml(entry.tier || \"-\") +\n '</td><td>' + (entry.anonymous ? \"yes\" : \"no\") +\n '</td><td>' + escapeHtml(entry.protocol_source || \"-\") +\n '</td><td>' + (entry.route_error\n ? '<span class=\"badge bad\">' + escapeHtml(entry.route_error) + '</span>'\n : '<span class=\"badge ok\">ok</span>') +\n '</td></tr>'\n ).join(\"\") + '</tbody></table>';\n}\n\nasync function loadKeys() {\n const data = await api(\"/api/api-keys\");\n const keys = data.keys || [];\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>API Keys</h1>' +\n '<p>Local keys your clients authenticate with</p></div>' +\n '<button class=\"primary shrink\" id=\"create-key\">Create key</button></div>' +\n '<div class=\"card\"><h2>Keys</h2>' + keysTable(keys) + '</div>'\n );\n el(\"create-key\").addEventListener(\"click\", createKey);\n}\n\nfunction keysTable(keys) {\n if (!keys.length) return '<div class=\"empty\">No keys configured</div>';\n return '<table><thead><tr><th>Name</th><th>Value</th><th>State</th>' +\n '<th>Requests</th><th>Created</th><th></th></tr></thead><tbody>' +\n keys.map((entry) =>\n '<tr><td>' + escapeHtml(entry.name) +\n '</td><td class=\"mono\">' + escapeHtml(entry.display) +\n '</td><td>' + (entry.enabled\n ? '<span class=\"badge ok\">enabled</span>'\n : '<span class=\"badge bad\">disabled</span>') +\n '</td><td>' + fmt((entry.usage || {}).lifetime\n ? entry.usage.lifetime.requests : 0) +\n '</td><td class=\"mono\">' + escapeHtml(\n entry.created_at ? new Date(entry.created_at).toLocaleDateString() : \"-\") +\n '</td><td><button class=\"ghost\" data-toggle=\"' + escapeHtml(entry.id) +\n '\">Toggle</button> ' +\n '<button class=\"ghost\" data-delete=\"' + escapeHtml(entry.id) +\n '\">Delete</button></td></tr>'\n ).join(\"\") + '</tbody></table>';\n}\n\nasync function createKey() {\n const name = prompt(\"Name for the new API key\");\n if (!name) return;\n try {\n const result = await api(\"/api/api-keys\", {\n method: \"POST\",\n body: JSON.stringify({ name }),\n });\n toast(\"Key created: \" + result.key);\n await loadKeys();\n } catch (error) {\n toast(error.message, true);\n }\n}\n\nasync function loadQuota() {\n const data = await api(\"/api/model-quotas\");\n const accounts = data.accounts || [];\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Quota</h1>' +\n '<p>' + escapeHtml(data.note || \"\") + '</p></div></div>' +\n '<div class=\"card\"><h2>Accounts</h2>' + quotaTable(accounts) + '</div>'\n );\n}\n\nfunction quotaTable(accounts) {\n if (!accounts.length) return '<div class=\"empty\">No Go keys configured</div>';\n return '<table><thead><tr><th>Key</th><th>Status</th><th>Window</th>' +\n '<th>Used</th></tr></thead><tbody>' +\n accounts.map((entry) => {\n const windows = entry.windows || {};\n const rows = Object.keys(windows).map((name) => {\n const win = windows[name] || {};\n return \"<tr><td>\" + escapeHtml(entry.display) + '</td><td>' +\n escapeHtml(entry.status) + '</td><td>' + escapeHtml(name) +\n '</td><td>' + pct(win.used_percent || 0) + '</td></tr>';\n }).join(\"\");\n return rows || '<tr><td>' + escapeHtml(entry.display) +\n '</td><td>' + escapeHtml(entry.status) + '</td><td>-</td><td>-</td></tr>';\n }).join(\"\") + '</tbody></table>';\n}\n`;\n", "// The tools and settings pages of the control WebUI: the Playground, the\n// rotation, the configuration, the account and the live log stream.\nexport const WEBUI_SETTINGS_PAGES = `\nasync function loadPlayground() {\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Playground</h1>' +\n '<p>Send a test request through the proxy</p></div></div>' +\n '<div class=\"card\"><h2>Request</h2>' +\n '<div class=\"row\">' +\n '<div class=\"field\"><label>Protocol</label><select id=\"pg-protocol\">' +\n '<option value=\"chat\">chat</option>' +\n '<option value=\"responses\">responses</option>' +\n '<option value=\"anthropic\">anthropic</option>' +\n '</select></div>' +\n '<div class=\"field\"><label>Model</label><input id=\"pg-model\" placeholder=\"model id\"></div>' +\n '</div>' +\n '<div class=\"field\"><label>Body</label><textarea id=\"pg-body\">' +\n '{\"model\":\"\",\"messages\":[{\"role\":\"user\",\"content\":\"Hello\"}]}' +\n '</textarea><div class=\"hint\">The model field is filled in from the box above.</div></div>' +\n '<button class=\"primary\" id=\"pg-send\">Send request</button>' +\n '</div>' +\n '<div class=\"card\"><h2>Response</h2><pre id=\"pg-result\" class=\"mono\">' +\n 'No request sent yet.</pre></div>'\n );\n el(\"pg-send\").addEventListener(\"click\", sendPlayground);\n}\n\nasync function sendPlayground() {\n const protocol = el(\"pg-protocol\").value;\n const model = el(\"pg-model\").value.trim();\n let body;\n try {\n body = JSON.parse(el(\"pg-body\").value);\n } catch {\n toast(\"The body must be valid JSON\", true);\n return;\n }\n body.model = model;\n el(\"pg-result\").textContent = \"Sending...\";\n try {\n const result = await api(\"/api/debug/inference\", {\n method: \"POST\",\n body: JSON.stringify({ protocol, request: body }),\n });\n el(\"pg-result\").textContent = JSON.stringify(result, null, 2);\n } catch (error) {\n el(\"pg-result\").textContent = error.message;\n toast(error.message, true);\n }\n}\n\nasync function loadRotation() {\n const data = await api(\"/api/rotation\");\n const groups = data.groups || [];\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Rotation</h1>' +\n '<p>Model groups that rotate between upstreams</p></div></div>' +\n groups.map((group) => (\n '<div class=\"card\"><h2>' + escapeHtml(group.alias || group.id) +\n ' <span class=\"badge\">current: ' + escapeHtml(group.current || \"-\") +\n '</span></h2>' +\n '<table><thead><tr><th>Model</th><th>State</th><th></th></tr></thead><tbody>' +\n (group.order || []).map((model) => (\n '<tr><td class=\"mono\">' + escapeHtml(model) + '</td><td>' +\n (group.current === model\n ? '<span class=\"badge ok\">current</span>'\n : '<span class=\"badge\">idle</span>') +\n '</td><td><button class=\"ghost\" data-group=\"' + escapeHtml(group.id) +\n '\" data-model=\"' + escapeHtml(model) + '\">Use</button></td></tr>'\n )).join(\"\") + '</tbody></table></div>'\n )).join(\"\")\n );\n for (const button of document.querySelectorAll(\"[data-group]\")) {\n button.addEventListener(\"click\", () => selectRotation(\n button.dataset.group, button.dataset.model));\n }\n}\n\nasync function selectRotation(group, model) {\n try {\n await api(\"/api/rotation/current\", {\n method: \"POST\",\n body: JSON.stringify({ group, model }),\n });\n toast(\"Switched to \" + model);\n await loadRotation();\n } catch (error) {\n toast(error.message, true);\n }\n}\n\nasync function loadConfig() {\n const config = await api(\"/api/config\");\n state.config = config;\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Configuration</h1>' +\n '<p>Upstream lanes, retries and server behavior</p></div>' +\n '<button class=\"primary shrink\" id=\"save-config\">Save</button></div>' +\n '<div class=\"card\"><h2>Upstream</h2>' +\n '<div class=\"field\"><label>Zen base URL</label>' +\n '<input id=\"cfg-zen\" value=\"' + escapeHtml(config.upstream.zen) + '\"></div>' +\n '<div class=\"field\"><label>Go base URL</label>' +\n '<input id=\"cfg-go\" value=\"' + escapeHtml(config.upstream.go) + '\"></div>' +\n '<div class=\"field\"><label>Anonymous base URL</label>' +\n '<input id=\"cfg-anon\" value=\"' + escapeHtml(config.upstream.anonymous || \"\") + '\">' +\n '</div></div>' +\n '<div class=\"card\"><h2>Behavior</h2><div class=\"row\">' +\n '<div class=\"field\"><label>Prefer tier</label><select id=\"cfg-prefer\">' +\n '<option value=\"go\"' + (config.prefer === \"go\" ? \" selected\" : \"\") + '>go</option>' +\n '<option value=\"zen\"' + (config.prefer === \"zen\" ? \" selected\" : \"\") + '>zen</option>' +\n '</select></div>' +\n '<div class=\"field\"><label>Max attempts</label><input id=\"cfg-attempts\" type=\"number\" value=\"' +\n escapeHtml(config.retry.max_attempts) + '\"></div>' +\n '<div class=\"field\"><label>Timeout (seconds)</label><input id=\"cfg-timeout\" type=\"number\" value=\"' +\n escapeHtml(config.retry.timeout_seconds) + '\"></div>' +\n '<div class=\"field\"><label>Catalog refresh (seconds)</label>' +\n '<input id=\"cfg-refresh\" type=\"number\" value=\"' +\n escapeHtml(config.models.refresh_seconds) + '\"></div>' +\n '</div>' +\n '<div class=\"row\"><div class=\"field\"><label>Log level</label><select id=\"cfg-level\">' +\n [\"debug\", \"info\", \"warn\", \"error\"].map((level) =>\n '<option value=\"' + level + '\"' +\n (config.logging.level === level ? \" selected\" : \"\") + '>' + level + '</option>'\n ).join(\"\") + '</select></div>' +\n '<div class=\"field\"><label>Log ring size</label><input id=\"cfg-ring\" type=\"number\" value=\"' +\n escapeHtml(config.logging.ring_size) + '\"></div></div>' +\n '<div class=\"field\"><label>Free models only</label>' +\n '<select id=\"cfg-freeonly\"><option value=\"false\"' +\n (!config.models.free_only ? \" selected\" : \"\") + '>no</option>' +\n '<option value=\"true\"' + (config.models.free_only ? \" selected\" : \"\") +\n '>yes</option></select></div></div>' +\n (config.restart_required_fields && config.restart_required_fields.length\n ? '<div class=\"card\"><span class=\"badge warn\">Restart required: ' +\n escapeHtml(config.restart_required_fields.join(\", \")) + '</span></div>'\n : \"\")\n );\n el(\"save-config\").addEventListener(\"click\", saveConfig);\n}\n\nasync function saveConfig() {\n const config = state.config;\n const body = JSON.parse(JSON.stringify(config));\n body.upstream.zen = el(\"cfg-zen\").value.trim();\n body.upstream.go = el(\"cfg-go\").value.trim();\n body.upstream.anonymous = el(\"cfg-anon\").value.trim();\n body.prefer = el(\"cfg-prefer\").value;\n body.retry.max_attempts = Number(el(\"cfg-attempts\").value);\n body.retry.timeout_seconds = Number(el(\"cfg-timeout\").value);\n body.models.refresh_seconds = Number(el(\"cfg-refresh\").value);\n body.models.free_only = el(\"cfg-freeonly\").value === \"true\";\n body.logging.level = el(\"cfg-level\").value;\n body.logging.ring_size = Number(el(\"cfg-ring\").value);\n delete body.effective;\n delete body.restart_required_fields;\n try {\n await api(\"/api/config\", { method: \"PUT\", body: JSON.stringify(body) });\n toast(\"Configuration saved\");\n await loadConfig();\n } catch (error) {\n toast(error.message, true);\n }\n}\n\nasync function loadAccount() {\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Account</h1>' +\n '<p>Change the WebUI credentials</p></div></div>' +\n '<div class=\"card\"><h2>Credentials</h2>' +\n '<div class=\"field\"><label>Current password</label>' +\n '<input id=\"acc-current\" type=\"password\"></div>' +\n '<div class=\"field\"><label>New username</label>' +\n '<input id=\"acc-username\" placeholder=\"leave empty to keep\"></div>' +\n '<div class=\"field\"><label>New password</label>' +\n '<input id=\"acc-password\" type=\"password\" placeholder=\"leave empty to keep\"></div>' +\n '<button class=\"primary\" id=\"acc-save\">Update</button></div>'\n );\n el(\"acc-save\").addEventListener(\"click\", saveAccount);\n}\n\nasync function saveAccount() {\n const body = {\n current_password: el(\"acc-current\").value,\n username: el(\"acc-username\").value.trim(),\n new_password: el(\"acc-password\").value,\n };\n try {\n await api(\"/api/account\", { method: \"PUT\", body: JSON.stringify(body) });\n toast(\"Account updated, please sign in again\");\n showLogin();\n } catch (error) {\n toast(error.message, true);\n }\n}\n\nlet logSource = null;\n\nasync function loadLogs() {\n el(\"content\").innerHTML = (\n '<div class=\"page-head\"><div><h1>Logs</h1>' +\n '<p>Live structured log stream</p></div></div>' +\n '<div class=\"card\"><h2>Stream</h2><div id=\"log-lines\"></div></div>'\n );\n if (logSource) { logSource.close(); logSource = null; }\n const source = new EventSource(\"/api/logs/stream\");\n logSource = source;\n source.addEventListener(\"log\", (event) => {\n const entry = JSON.parse(event.data);\n const container = el(\"log-lines\");\n if (!container) return;\n const line = document.createElement(\"div\");\n line.className = \"log-line\";\n line.innerHTML = '<span class=\"time\">' +\n escapeHtml(new Date(entry.time).toLocaleTimeString()) +\n '</span><span class=\"level ' + escapeHtml(entry.level) + '\">' +\n escapeHtml(entry.level) + '</span><span class=\"message\">' +\n escapeHtml(entry.message) +\n (entry.component ? ' [' + escapeHtml(entry.component) + ']' : \"\") +\n '</span>';\n container.prepend(line);\n while (container.children.length > 500) {\n container.removeChild(container.lastChild);\n }\n });\n source.addEventListener(\"gap\", () => {\n toast(\"Some log events were skipped\", true);\n });\n}\n\nconst LOADERS = {\n overview: loadOverview,\n models: loadModels,\n keys: loadKeys,\n quota: loadQuota,\n playground: loadPlayground,\n rotation: loadRotation,\n config: loadConfig,\n account: loadAccount,\n logs: loadLogs,\n};\n\nasync function render() {\n const hash = location.hash.replace(\"#\", \"\") || \"overview\";\n state.page = LOADERS[hash] ? hash : \"overview\";\n markActive();\n try {\n await LOADERS[state.page]();\n } catch (error) {\n el(\"content\").innerHTML = '<div class=\"empty\">' +\n escapeHtml(error.message) + '</div>';\n }\n}\n\nasync function login(event) {\n event.preventDefault();\n const username = el(\"login-user\").value;\n const password = el(\"login-pass\").value;\n try {\n const result = await api(\"/api/auth/login\", {\n method: \"POST\",\n body: JSON.stringify({ username, password }),\n });\n state.csrf = result.csrf_token;\n showApp();\n await render();\n } catch (error) {\n toast(error.message, true);\n }\n}\n\nasync function boot() {\n renderNav();\n window.addEventListener(\"hashchange\", render);\n el(\"login-form\").addEventListener(\"submit\", login);\n try {\n const session = await api(\"/api/auth/session\");\n state.csrf = session.csrf_token;\n showApp();\n await render();\n } catch {\n showLogin();\n }\n}\n\nboot();\n`;\n", "import { THEME_TOKENS } from \"./theme.js\";\nimport { WEBUI_STYLES } from \"./styles.js\";\nimport {\n WEBUI_CORE,\n WEBUI_MONITOR_PAGES,\n WEBUI_SETTINGS_PAGES,\n} from \"./script.js\";\n\n// The WebUI application script. It is assembled from the shared helpers, the\n// monitor pages and the settings pages, and inlined so the whole UI ships as\n// one self-contained HTML document.\nexport const WEBUI_SCRIPT = `${WEBUI_CORE}${WEBUI_MONITOR_PAGES}${WEBUI_SETTINGS_PAGES}`;\n\n// The WebUI markup. The document is self-contained: the stylesheet and the\n// script are inlined, so the Node build can embed it as a string and the\n// Worker can serve it from its bundle.\nconst WEBUI_BODY = `\n<div id=\"login\" class=\"hidden\">\n <div class=\"card\">\n <h1>OpenCode2API</h1>\n <p>Sign in to the control panel.</p>\n <form id=\"login-form\">\n <div class=\"field\">\n <label for=\"login-user\">Username</label>\n <input id=\"login-user\" value=\"admin\" autocomplete=\"username\">\n </div>\n <div class=\"field\">\n <label for=\"login-pass\">Password</label>\n <input id=\"login-pass\" type=\"password\" autocomplete=\"current-password\">\n </div>\n <button class=\"primary\" type=\"submit\" style=\"width:100%\">Sign in</button>\n </form>\n </div>\n</div>\n\n<div id=\"app\" class=\"hidden\">\n <div id=\"layout\">\n <aside id=\"sidebar\">\n <div id=\"brand\"><span class=\"dot\"></span>OpenCode2API</div>\n <nav id=\"nav\"></nav>\n </aside>\n <main id=\"content\"></main>\n </div>\n</div>\n\n<div id=\"toast\"></div>\n`;\n\n// buildWebUIHTML renders the complete WebUI document.\nexport function buildWebUIHTML(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"referrer\" content=\"no-referrer\">\n<title>OpenCode2API Control Panel</title>\n<style>\n${THEME_TOKENS}\n${WEBUI_STYLES}\n</style>\n</head>\n<body>\n${WEBUI_BODY}\n<script>\n${WEBUI_SCRIPT}\n</script>\n</body>\n</html>\n`;\n}\n\n// The WebUI document, built once at module load so the server can serve it\n// without rebuilding it on every request.\nexport const WEBUI_HTML = buildWebUIHTML();\n", "import { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport type { Config } from \"../../types/config.js\";\nimport { fingerprintSecret, maskSecret } from \"../../config/secrets.js\";\n\n// The name of the session cookie.\nexport const SESSION_COOKIE = \"opencode2api_session\";\n\n// The number of minutes a session stays valid.\nexport const DEFAULT_SESSION_TTL_MINUTES = 720;\n\n// The maximum number of sessions the store holds.\nconst MAX_SESSIONS = 2048;\n\n// The length of the session token and the CSRF token, in bytes.\nconst SESSION_TOKEN_BYTES = 32;\nconst CSRF_TOKEN_BYTES = 24;\n\n// The session record.\nexport interface AdminSession {\n username: string;\n authVersion: string;\n csrf: string;\n expires: number;\n}\n\n// SessionStore holds the admin sessions. The raw token is never stored, only\n// its digest.\nexport class SessionStore {\n private readonly sessions = new Map<string, AdminSession>();\n\n // create issues a new session and returns its token and CSRF token.\n create(username: string, authVersion: string, ttlMinutes: number): {\n token: string;\n csrf: string;\n } {\n if (this.sessions.size >= MAX_SESSIONS) {\n this.evictOldest();\n }\n const token = randomToken(SESSION_TOKEN_BYTES);\n const csrf = randomToken(CSRF_TOKEN_BYTES);\n const expires = Date.now() + ttlMinutes * 60_000;\n this.sessions.set(digest(token), {\n username,\n authVersion,\n csrf,\n expires,\n });\n return { token, csrf };\n }\n\n // get returns the session a token belongs to, or undefined when it is\n // unknown or expired.\n get(token: string): AdminSession | undefined {\n if (token === \"\") {\n return undefined;\n }\n const key = digest(token);\n const session = this.sessions.get(key);\n if (session === undefined) {\n return undefined;\n }\n if (session.expires <= Date.now()) {\n this.sessions.delete(key);\n return undefined;\n }\n return session;\n }\n\n // drop removes a session.\n drop(token: string): void {\n this.sessions.delete(digest(token));\n }\n\n // dropAll removes every session, which a password change forces.\n dropAll(): void {\n this.sessions.clear();\n }\n\n // count reports how many sessions the store holds.\n count(): number {\n return this.sessions.size;\n }\n\n // evictOldest removes the session that expires first.\n private evictOldest(): void {\n let oldestKey = \"\";\n let oldest = Number.POSITIVE_INFINITY;\n for (const [key, session] of this.sessions) {\n if (session.expires < oldest) {\n oldest = session.expires;\n oldestKey = key;\n }\n }\n if (oldestKey !== \"\") {\n this.sessions.delete(oldestKey);\n }\n }\n}\n\n// randomToken returns a base64url token of the requested byte length.\nexport function randomToken(bytes: number): string {\n return randomBytes(bytes).toString(\"base64url\");\n}\n\n// digest returns the hex SHA-256 of a token.\nexport function digest(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n// constantTimeEquals compares two secrets without leaking their length.\nexport function constantTimeEquals(left: string, right: string): boolean {\n const a = Buffer.from(left, \"utf8\");\n const b = Buffer.from(right, \"utf8\");\n if (a.length !== b.length) {\n return false;\n }\n return timingSafeEqual(a, b);\n}\n\n// authVersionOf returns the version a session's credentials carry. Changing\n// the password changes the version and invalidates every session.\nexport function authVersionOf(config: Config): string {\n return fingerprintSecret(config.webui.password_hash ?? config.webui.password ?? \"\");\n}\n\n// maskSecretValue masks a secret for display.\nexport function maskSecretValue(value: string): string {\n return maskSecret(value);\n}\n", "// The response shape the admin helpers write to. It is looser than Node's\n// ServerResponse so the handlers stay testable.\nexport interface AdminResponse {\n statusCode?: number;\n setHeader(name: string, value: string | string[]): void;\n writeHead(status: number, headers?: Record<string, string | string[]>): unknown;\n end(chunk?: string | Buffer): void;\n}\n\n// writeAdminError answers a request with the admin error envelope.\nexport function writeAdminError(\n response: AdminResponse,\n status: number,\n code: string,\n message: string,\n): void {\n const body = `${JSON.stringify({ error: { code, message } })}\\n`;\n response.writeHead(status, {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": String(Buffer.byteLength(body)),\n });\n response.end(body);\n}\n\n// writeAdminJSON answers a request with a JSON document.\nexport function writeAdminJSON(\n response: AdminResponse,\n status: number,\n body: unknown,\n noStore = false,\n): void {\n const text = `${JSON.stringify(body)}\\n`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": String(Buffer.byteLength(text)),\n };\n if (noStore) {\n headers[\"Cache-Control\"] = \"no-store\";\n }\n response.writeHead(status, headers);\n response.end(text);\n}\n", "import type { Config } from \"../../types/config.js\";\nimport { fingerprintSecret, maskSecret } from \"../../config/secrets.js\";\nimport type { WebUIServer } from \"./server.js\";\n\n// A secret as the WebUI shows it.\nexport interface SecretView {\n id: string;\n display: string;\n}\n\n// secretView renders a masked secret.\nexport function secretView(value: string): SecretView {\n return { id: fingerprintSecret(value), display: maskSecret(value) };\n}\n\n// configView renders a configuration for the WebUI. The secrets are masked\n// and the WebUI password is never exposed.\nexport function configView(config: Config): Record<string, unknown> {\n return {\n listen: config.listen,\n server_keys: config.server_keys.map(secretView),\n zen_keys: config.zen_keys.map(secretView),\n go_keys: config.go_keys.map(secretView),\n anonymous: config.anonymous,\n proxies: config.proxies.map(secretView),\n proxyfile: config.proxyfile,\n upstream: config.upstream,\n retry: config.retry,\n models: config.models,\n performance: config.performance,\n logging: config.logging,\n prefer: config.prefer,\n reasoning: config.reasoning,\n webui: {\n enabled: config.webui.enabled,\n listen: config.webui.listen,\n username: config.webui.username,\n session_ttl_minutes: config.webui.session_ttl_minutes,\n },\n effective: {\n listen: config.listen,\n webui_listen: config.webui.listen,\n webui_enabled: config.webui.enabled,\n },\n };\n}\n\n// apiKeyViews renders the local server keys.\nexport function apiKeyViews(config: Config): Record<string, unknown>[] {\n return config.server_keys.map((key, index) => {\n const id = fingerprintSecret(key);\n const meta = config.server_key_metadata[id];\n return {\n id,\n name: meta?.name ?? `Key ${index + 1}`,\n display: maskSecret(key),\n enabled: meta?.disabled !== true,\n created_at: meta?.created_at,\n usage: { lifetime: { requests: 0 }, last_hour: { requests: 0 } },\n };\n });\n}\n\n// monitorPayload renders the monitor document.\nexport function monitorPayload(server: WebUIServer): Record<string, unknown> {\n const metrics = server.gateway.metrics.snapshot();\n return {\n version: \"dev\",\n metrics,\n usage: metrics.usage,\n upstream: metrics.upstream,\n resources: {\n models: server.gateway.catalog.snapshot(),\n keys: [],\n proxies: [],\n anonymous: server.currentConfig().anonymous,\n metadata: { ready: false, models: 0, stale: false },\n },\n };\n}\n\n// debugModelsPayload renders the model diagnostics.\nexport function debugModelsPayload(server: WebUIServer): Record<string, unknown> {\n const config = server.currentConfig();\n const models = server.gateway.catalog.list().map((model) =>\n server.gateway.catalog.diagnostic(\n model,\n \"chat\",\n server.gateway.hasZenKeys(),\n server.gateway.hasGoKeys(),\n config.anonymous,\n ),\n );\n return {\n models,\n keys: {\n zen: config.zen_keys.map((key, index) => ({\n id: fingerprintSecret(key),\n tier: \"zen\",\n display: maskSecret(key),\n index,\n failures: 0,\n })),\n go: config.go_keys.map((key, index) => ({\n id: fingerprintSecret(key),\n tier: \"go\",\n display: maskSecret(key),\n index,\n failures: 0,\n })),\n },\n metadata: { ready: false, models: 0, stale: false },\n catalog: server.gateway.catalog.snapshot(),\n last_inference: null,\n };\n}\n\n// rotationPayload renders the rotation state.\nexport function rotationPayload(server: WebUIServer): Record<string, unknown> {\n const rotation = server.currentConfig().rotation;\n return {\n groups: [\n {\n id: \"sota\",\n alias: rotation.sota.alias,\n order: rotation.sota.order,\n current: rotation.sota.order[0] ?? \"\",\n generation: 0,\n paused: {},\n available: {},\n switches: [],\n },\n {\n id: \"sweet\",\n alias: rotation.sweet.alias,\n order: rotation.sweet.order,\n current: rotation.sweet.order[0] ?? \"\",\n generation: 0,\n paused: {},\n available: {},\n switches: [],\n },\n ],\n attempts: [],\n first_output_seconds: rotation.first_output_seconds,\n };\n}\n\n// quotaPayload renders the Go quota state.\nexport function quotaPayload(server: WebUIServer): Record<string, unknown> {\n const config = server.currentConfig();\n return {\n models: [],\n accounts: config.go_keys.map((key) => ({\n id: fingerprintSecret(key),\n display: maskSecret(key),\n status: \"unavailable\",\n })),\n scope: \"shared_subscription\",\n source: `${config.upstream.go}/v1/usage`,\n cache_seconds: 60,\n catalog: server.gateway.catalog.snapshot(),\n note:\n \"OpenCode returns a shared subscription quota; multiple Go keys may belong to the same plan and cannot be added up.\",\n };\n}\n", "import { randomBytes } from \"node:crypto\";\nimport type { Config } from \"../../types/config.js\";\nimport { fingerprintSecret } from \"../../config/secrets.js\";\nimport { isPlainObject, stringAt } from \"../../protocol/json-util.js\";\nimport type { LogLevel } from \"../../types/config.js\";\nimport { hashPassword, type WebUIServer } from \"./server.js\";\nimport { writeAdminError, writeAdminJSON, type AdminResponse } from \"./responses.js\";\nimport { configView } from \"./views.js\";\n\n// handleUpdateConfig applies a configuration change. The running\n// configuration is validated before it is swapped, so a rejected change leaves\n// the proxy untouched.\nexport async function handleUpdateConfig(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n): Promise<void> {\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const current = server.currentConfig();\n const upstream = body[\"upstream\"];\n const updated: Config = {\n ...current,\n listen: stringOr(body[\"listen\"], current.listen),\n anonymous: booleanOr(body[\"anonymous\"], current.anonymous),\n proxyfile: stringOr(body[\"proxyfile\"], current.proxyfile),\n upstream: {\n zen: stringOr(stringAt(upstream, \"zen\"), current.upstream.zen),\n go: stringOr(stringAt(upstream, \"go\"), current.upstream.go),\n anonymous: stringOr(\n stringAt(upstream, \"anonymous\"),\n current.upstream.anonymous,\n ),\n },\n prefer:\n body[\"prefer\"] === \"zen\"\n ? \"zen\"\n : body[\"prefer\"] === \"go\"\n ? \"go\"\n : current.prefer,\n };\n const retry = body[\"retry\"];\n if (isPlainObject(retry)) {\n updated.retry = {\n max_attempts: numberOr(\n retry[\"max_attempts\"],\n current.retry.max_attempts,\n ),\n timeout_seconds: numberOr(\n retry[\"timeout_seconds\"],\n current.retry.timeout_seconds,\n ),\n };\n }\n const models = body[\"models\"];\n if (isPlainObject(models)) {\n updated.models = {\n refresh_seconds: numberOr(\n models[\"refresh_seconds\"],\n current.models.refresh_seconds,\n ),\n protocols: isPlainObject(models[\"protocols\"])\n ? (models[\"protocols\"] as Record<string, string>)\n : current.models.protocols,\n free_only: booleanOr(models[\"free_only\"], current.models.free_only),\n };\n }\n const logging = body[\"logging\"];\n if (isPlainObject(logging)) {\n const level = stringAt(logging, \"level\");\n updated.logging = {\n level: isLogLevel(level) ? (level as LogLevel) : current.logging.level,\n ring_size: numberOr(logging[\"ring_size\"], current.logging.ring_size),\n dump_request_bodies: booleanOr(\n logging[\"dump_request_bodies\"],\n current.logging.dump_request_bodies,\n ),\n };\n }\n server.gateway.apply(updated);\n writeAdminJSON(\n response,\n 200,\n {\n result: { applied: true, restart_required: false, restart_fields: [] },\n config: configView(updated),\n },\n );\n}\n\n// handleReveal returns the plaintext secrets after a password check.\nexport async function handleReveal(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n): Promise<void> {\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const config = server.currentConfig();\n if (\n !server.checkCredentials(config.webui.username, stringAt(body, \"password\"))\n ) {\n writeAdminError(\n response,\n 403,\n \"verification_failed\",\n \"password verification failed\",\n );\n return;\n }\n writeAdminJSON(\n response,\n 200,\n {\n server_keys: config.server_keys,\n zen_keys: config.zen_keys,\n go_keys: config.go_keys,\n proxies: config.proxies,\n },\n true,\n );\n}\n\n// handleAccount changes the WebUI credentials. Every session is dropped, so\n// the operator signs in again.\nexport async function handleAccount(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n): Promise<void> {\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const current = server.currentConfig();\n if (\n !server.checkCredentials(\n current.webui.username,\n stringAt(body, \"current_password\"),\n )\n ) {\n writeAdminError(\n response,\n 403,\n \"verification_failed\",\n \"current password is incorrect\",\n );\n return;\n }\n const username = stringAt(body, \"username\").trim();\n const newPassword = stringAt(body, \"new_password\");\n const webui = {\n ...current.webui,\n username: username !== \"\" ? username : current.webui.username,\n };\n if (newPassword !== \"\") {\n webui.password_hash = hashPassword(newPassword);\n delete webui.password;\n }\n const updated: Config = { ...current, webui };\n server.gateway.apply(updated);\n server.sessions.dropAll();\n response.setHeader(\"Set-Cookie\", server.clearCookie(server.isSecure(request as never)));\n writeAdminJSON(response, 200, { updated: true, reauthenticate: true });\n}\n\n// handleCreateKey adds a local server key.\nexport async function handleCreateKey(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n): Promise<void> {\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const config = server.currentConfig();\n const name = stringAt(body, \"name\").trim();\n if (name.length < 1 || name.length > 80) {\n writeAdminError(\n response,\n 400,\n \"key_create_failed\",\n \"the name must be 1-80 characters\",\n );\n return;\n }\n const value = stringAt(body, \"value\").trim();\n const key = value !== \"\" ? value : `sk-local-${randomBytes(24).toString(\"hex\")}`;\n if (key.length < 16 || key.length > 256) {\n writeAdminError(\n response,\n 400,\n \"key_create_failed\",\n \"a custom key must be 16-256 characters\",\n );\n return;\n }\n if (!/^[A-Za-z0-9._-]+$/.test(key)) {\n writeAdminError(\n response,\n 400,\n \"key_create_failed\",\n \"a key may only hold letters, digits, dashes, underscores and dots\",\n );\n return;\n }\n if (config.server_keys.length >= 200) {\n writeAdminError(\n response,\n 400,\n \"key_create_failed\",\n \"at most 200 API keys are allowed\",\n );\n return;\n }\n const id = fingerprintSecret(key);\n if (config.server_keys.some((existing) => fingerprintSecret(existing) === id)) {\n writeAdminError(\n response,\n 400,\n \"key_create_failed\",\n \"this API key already exists\",\n );\n return;\n }\n const updated: Config = {\n ...config,\n server_keys: [...config.server_keys, key],\n server_key_metadata: {\n ...config.server_key_metadata,\n [id]: { name, created_at: new Date().toISOString() },\n },\n };\n server.gateway.apply(updated);\n writeAdminJSON(response, 201, { key, keys: apiKeyViewsOf(updated) }, true);\n}\n\n// The request and the response shapes the admin handlers work with. They are\n// looser than Node's types so the handlers stay testable.\nexport interface IncomingMessageLike {\n method?: string;\n url?: string;\n headers: Record<string, string | string[] | undefined>;\n socket: { remoteAddress?: string; encrypted?: boolean };\n on: (event: string, listener: () => void) => void;\n [Symbol.asyncIterator](): AsyncIterator<Buffer>;\n}\n\nexport type ResponseLike = AdminResponse;\n\n// apiKeyViewsOf renders the local server keys.\nfunction apiKeyViewsOf(config: Config): Record<string, unknown>[] {\n return config.server_keys.map((key, index) => {\n const id = fingerprintSecret(key);\n const meta = config.server_key_metadata[id];\n return {\n id,\n name: meta?.name ?? `Key ${index + 1}`,\n display: `\u2022\u2022\u2022\u2022${key.slice(-5)}`,\n enabled: meta?.disabled !== true,\n created_at: meta?.created_at,\n usage: { lifetime: { requests: 0 }, last_hour: { requests: 0 } },\n };\n });\n}\n\n// readJSON reads a request body and decodes it.\nasync function readJSON(\n request: IncomingMessageLike,\n): Promise<Record<string, unknown> | undefined> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of request) {\n const buffer = chunk as Buffer;\n total += buffer.byteLength;\n if (total > ADMIN_BODY_LIMIT) {\n return undefined;\n }\n chunks.push(buffer);\n }\n if (total === 0) {\n return {};\n }\n try {\n const value = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n return isPlainObject(value) ? value : undefined;\n } catch {\n return undefined;\n }\n}\n\n// The body limit an admin request may carry.\nconst ADMIN_BODY_LIMIT = 2 * 1024 * 1024;\n\n// stringOr reads a string value, falling back to a default.\nfunction stringOr(value: unknown, fallback: string): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\n// numberOr reads a number value, falling back to a default.\nfunction numberOr(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\n// booleanOr reads a boolean value, falling back to a default.\nfunction booleanOr(value: unknown, fallback: boolean): boolean {\n return typeof value === \"boolean\" ? value : fallback;\n}\n\n// isLogLevel reports whether a value is a log level.\nfunction isLogLevel(value: string): boolean {\n return (\n value === \"debug\" ||\n value === \"info\" ||\n value === \"warn\" ||\n value === \"error\"\n );\n}\n", "// A fixed-window rate limit counter.\ninterface Window {\n count: number;\n since: number;\n}\n\n// RateLimiter counts the requests of each client within a window.\nexport class RateLimiter {\n private readonly windows = new Map<string, Window>();\n\n // allow reports whether a client may make another request, and counts it.\n allow(key: string, limit: number, windowMs: number): boolean {\n const now = Date.now();\n const window = this.windows.get(key);\n if (window === undefined || now - window.since > windowMs) {\n this.windows.set(key, { count: 1, since: now });\n this.prune(now, windowMs);\n return true;\n }\n if (window.count >= limit) {\n return false;\n }\n window.count += 1;\n return true;\n }\n\n // reset forgets a client's counter.\n reset(key: string): void {\n this.windows.delete(key);\n }\n\n // prune drops the windows that have expired.\n private prune(now: number, windowMs: number): void {\n if (this.windows.size < 1024) {\n return;\n }\n for (const [key, window] of this.windows) {\n if (now - window.since > windowMs) {\n this.windows.delete(key);\n }\n }\n }\n}\n", "import type { Config } from \"../../types/config.js\";\nimport { fingerprintSecret } from \"../../config/secrets.js\";\nimport { isPlainObject, stringAt } from \"../../protocol/json-util.js\";\nimport type { Protocol } from \"../../types/config.js\";\nimport { writeAdminError, writeAdminJSON } from \"./responses.js\";\nimport type { WebUIServer } from \"./server.js\";\nimport { apiKeyViews } from \"./views.js\";\nimport { RateLimiter } from \"./rate-limiter.js\";\nimport type { IncomingMessageLike, ResponseLike } from \"./config-routes.js\";\n\n// The number of Playground requests allowed per client within the window.\nconst PLAYGROUND_LIMIT = 12;\n\n// The length of the Playground rate-limit window, in milliseconds.\nconst PLAYGROUND_WINDOW_MS = 60 * 1000;\n\n// The Playground rate limiter.\nexport const playgroundLimiter = new RateLimiter();\n\n// handleUpdateKey renames, enables or deletes a local server key.\nexport async function handleUpdateKey(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n id: string,\n): Promise<void> {\n const config = server.currentConfig();\n const index = config.server_keys.findIndex(\n (key) => fingerprintSecret(key) === id,\n );\n if (index < 0) {\n writeAdminError(\n response,\n 400,\n \"key_update_failed\",\n \"the API key does not exist\",\n );\n return;\n }\n const body =\n request.method === \"DELETE\" ? {} : await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const updated: Config = {\n ...config,\n server_keys: [...config.server_keys],\n server_key_metadata: { ...config.server_key_metadata },\n };\n const meta = {\n ...(config.server_key_metadata[id] ?? { name: `Key ${index + 1}` }),\n };\n if (request.method === \"DELETE\") {\n if (enabledCount(config) <= 1) {\n writeAdminError(\n response,\n 400,\n \"key_delete_failed\",\n \"keep at least one enabled API key\",\n );\n return;\n }\n updated.server_keys.splice(index, 1);\n delete updated.server_key_metadata[id];\n } else {\n const name = stringAt(body, \"name\").trim();\n if (name !== \"\") {\n if (name.length > 80) {\n writeAdminError(\n response,\n 400,\n \"key_update_failed\",\n \"the name must be 1-80 characters\",\n );\n return;\n }\n meta.name = name;\n }\n if (body[\"enabled\"] === false) {\n if (enabledCount(config) <= 1) {\n writeAdminError(\n response,\n 400,\n \"key_update_failed\",\n \"keep at least one enabled API key\",\n );\n return;\n }\n meta.disabled = true;\n } else if (body[\"enabled\"] === true) {\n delete meta.disabled;\n }\n updated.server_key_metadata[id] = meta;\n }\n server.gateway.apply(updated);\n writeAdminJSON(response, 200, { keys: apiKeyViews(updated) });\n}\n\n// handleDebugInference runs one Playground request in-process.\nexport async function handleDebugInference(\n server: WebUIServer,\n request: IncomingMessageLike,\n response: ResponseLike,\n): Promise<void> {\n const ip = request.socket.remoteAddress ?? \"unknown\";\n if (\n !playgroundLimiter.allow(ip, PLAYGROUND_LIMIT, PLAYGROUND_WINDOW_MS)\n ) {\n writeAdminError(\n response,\n 429,\n \"debug_rate_limited\",\n \"too many Playground requests; retry in one minute\",\n );\n return;\n }\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const protocol = stringAt(body, \"protocol\");\n if (\n protocol !== \"chat\" &&\n protocol !== \"responses\" &&\n protocol !== \"anthropic\"\n ) {\n writeAdminError(\n response,\n 400,\n \"invalid_protocol\",\n \"protocol must be chat, responses, or anthropic\",\n );\n return;\n }\n const payload = body[\"request\"];\n if (!isPlainObject(payload)) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request must be a JSON object\",\n );\n return;\n }\n if (stringAt(payload, \"model\") === \"\") {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request.model is required\",\n );\n return;\n }\n const config = server.currentConfig();\n const key = config.server_keys.find((entry) => enabledKey(config, entry));\n if (key === undefined) {\n writeAdminError(\n response,\n 503,\n \"debug_unavailable\",\n \"no local server key is configured\",\n );\n return;\n }\n const started = Date.now();\n const result = await server.gateway.debugRequest(\n protocol as Protocol,\n payload,\n key,\n );\n writeAdminJSON(\n response,\n 200,\n {\n ok: result.status >= 200 && result.status < 300,\n http_status: result.status,\n duration_ms: Date.now() - started,\n request_id: result.requestId,\n response: result.body,\n },\n true,\n );\n}\n\n// enabledKey reports whether a server key is enabled.\nfunction enabledKey(config: Config, key: string): boolean {\n const meta = config.server_key_metadata[fingerprintSecret(key)];\n return meta?.disabled !== true;\n}\n\n// enabledCount reports how many server keys are enabled.\nfunction enabledCount(config: Config): number {\n return config.server_keys.filter((key) => enabledKey(config, key)).length;\n}\n\n// readJSON reads a request body and decodes it.\nasync function readJSON(\n request: IncomingMessageLike,\n): Promise<Record<string, unknown> | undefined> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of request) {\n const buffer = chunk as Buffer;\n total += buffer.byteLength;\n if (total > 2 * 1024 * 1024) {\n return undefined;\n }\n chunks.push(buffer);\n }\n if (total === 0) {\n return {};\n }\n try {\n const value = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n return isPlainObject(value) ? value : undefined;\n } catch {\n return undefined;\n }\n}\n", "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { writeAdminJSON } from \"./responses.js\";\nimport type { WebUIServer } from \"./server.js\";\n\n// The number of events the log stream replays.\nconst REPLAY_LIMIT = 2000;\n\n// The interval the log stream sends a keepalive at.\nconst KEEPALIVE_MS = 20_000;\n\n// handleLogs answers with the recent log events.\nexport function handleLogs(\n server: WebUIServer,\n response: ServerResponse,\n url: URL,\n): void {\n const after = parseUint(url.searchParams.get(\"after\") ?? \"\");\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"\");\n const result = server.gateway.logs.recent(after, limit);\n writeAdminJSON(response, 200, { events: result.events, gap: result.gap });\n}\n\n// handleLogStream relays the live log events. The cursor comes from the\n// Last-Event-ID header, which the browser resends on a reconnect, or from the\n// after query parameter.\nexport function handleLogStream(\n server: WebUIServer,\n request: IncomingMessage,\n response: ServerResponse,\n url: URL,\n): void {\n const header = request.headers[\"last-event-id\"];\n let cursor = parseUint(typeof header === \"string\" ? header : \"\");\n const query = parseUint(url.searchParams.get(\"after\") ?? \"\");\n if (query > cursor) {\n cursor = query;\n }\n response.writeHead(200, {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-cache, no-store\",\n \"X-Accel-Buffering\": \"no\",\n });\n const replay = server.gateway.logs.recent(cursor, REPLAY_LIMIT);\n if (replay.gap) {\n response.write(\n `event: gap\\ndata: ${JSON.stringify({\n message: \"older log events have expired\",\n })}\\n\\n`,\n );\n }\n for (const event of replay.events) {\n cursor = event.sequence;\n response.write(\n `id: ${event.sequence}\\nevent: log\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n }\n const unsubscribe = server.gateway.logs.subscribe((event) => {\n if (cursor > 0 && event.sequence > cursor + 1) {\n response.write(\n `event: gap\\ndata: ${JSON.stringify({\n message: \"slow client missed log events\",\n after: cursor,\n next: event.sequence,\n })}\\n\\n`,\n );\n }\n cursor = event.sequence;\n response.write(\n `id: ${event.sequence}\\nevent: log\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n });\n const keepalive = setInterval(() => {\n // The session is re-validated before every keepalive, because nothing\n // re-authenticates the stream in the middle of its life.\n if (server.validSession(request) === undefined) {\n clearInterval(keepalive);\n unsubscribe();\n response.end();\n return;\n }\n response.write(\": keepalive\\n\\n\");\n }, KEEPALIVE_MS);\n keepalive.unref?.();\n request.on(\"close\", () => {\n clearInterval(keepalive);\n unsubscribe();\n });\n}\n\n// parseUint reads an unsigned integer, ignoring a parse error.\nfunction parseUint(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed < 0) {\n return 0;\n }\n return Math.trunc(parsed);\n}\n\n// parseInt reads an integer, ignoring a parse error.\nfunction parseInt(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed)) {\n return 0;\n }\n return Math.trunc(parsed);\n}\n", "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { isPlainObject, stringAt } from \"../../protocol/json-util.js\";\nimport { writeAdminError, writeAdminJSON } from \"./responses.js\";\nimport { authVersionOf } from \"./session.js\";\nimport { constantTimeEquals, type WebUIServer } from \"./server.js\";\nimport {\n apiKeyViews,\n configView,\n debugModelsPayload,\n monitorPayload,\n quotaPayload,\n rotationPayload,\n} from \"./views.js\";\nimport {\n handleAccount,\n handleCreateKey,\n handleReveal,\n handleUpdateConfig,\n type IncomingMessageLike,\n type ResponseLike,\n} from \"./config-routes.js\";\nimport { handleDebugInference, handleUpdateKey } from \"./key-routes.js\";\nimport { handleLogs, handleLogStream } from \"./log-routes.js\";\nimport { RateLimiter } from \"./rate-limiter.js\";\n\n// The number of login failures allowed per client within the window.\nconst LOGIN_LIMIT = 5;\n\n// The length of the login rate-limit window, in milliseconds.\nconst LOGIN_WINDOW_MS = 5 * 60 * 1000;\n\n// The login rate limiter.\nexport const loginLimiter = new RateLimiter();\n\n// handleAdminRequest serves one admin API request.\nexport async function handleAdminRequest(\n server: WebUIServer,\n request: IncomingMessage,\n response: ServerResponse,\n url: URL,\n): Promise<void> {\n const method = request.method ?? \"GET\";\n const path = url.pathname;\n if (path === \"/api/auth/login\" && method === \"POST\") {\n await handleLogin(server, request, response);\n return;\n }\n if (path === \"/api/auth/session\" && method === \"GET\") {\n handleSession(server, request, response);\n return;\n }\n if (path === \"/api/auth/logout\" && method === \"POST\") {\n handleLogout(server, request, response);\n return;\n }\n const session = server.validSession(request);\n if (session === undefined) {\n writeAdminError(response, 401, \"authentication_required\", \"login required\");\n return;\n }\n if (method !== \"GET\" && method !== \"HEAD\") {\n const csrf = request.headers[\"x-csrf-token\"];\n if (typeof csrf !== \"string\" || !constantTimeEquals(csrf, session.csrf)) {\n writeAdminError(response, 403, \"csrf_failed\", \"CSRF token mismatch\");\n return;\n }\n const origin = request.headers.origin;\n if (typeof origin === \"string\" && origin !== \"\") {\n if (!originAllowed(origin, request, server.isSecure(request))) {\n writeAdminError(response, 403, \"origin_failed\", \"origin not allowed\");\n return;\n }\n }\n }\n if (path === \"/api/config\" && method === \"GET\") {\n writeAdminJSON(response, 200, configView(server.currentConfig()), true);\n return;\n }\n if (path === \"/api/config\" && method === \"PUT\") {\n await handleUpdateConfig(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n );\n return;\n }\n if (path === \"/api/config/reload\" && method === \"POST\") {\n writeAdminJSON(response, 200, { applied: true, restart_required: false });\n return;\n }\n if (path === \"/api/config/reveal\" && method === \"POST\") {\n await handleReveal(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n );\n return;\n }\n if (path === \"/api/account\" && method === \"PUT\") {\n await handleAccount(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n );\n return;\n }\n if (path === \"/api/monitor\" && method === \"GET\") {\n writeAdminJSON(response, 200, monitorPayload(server));\n return;\n }\n if (path === \"/api/debug/models\" && method === \"GET\") {\n writeAdminJSON(response, 200, debugModelsPayload(server), true);\n return;\n }\n if (path === \"/api/api-keys\" && method === \"GET\") {\n writeAdminJSON(\n response,\n 200,\n { keys: apiKeyViews(server.currentConfig()) },\n true,\n );\n return;\n }\n if (path === \"/api/api-keys\" && method === \"POST\") {\n await handleCreateKey(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n );\n return;\n }\n if (\n path.startsWith(\"/api/api-keys/\") &&\n (method === \"PATCH\" || method === \"DELETE\")\n ) {\n await handleUpdateKey(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n path.slice(\"/api/api-keys/\".length),\n );\n return;\n }\n if (path === \"/api/models/availability\" && method === \"GET\") {\n writeAdminJSON(response, 200, { models: [] }, true);\n return;\n }\n if (path === \"/api/rotation\" && method === \"GET\") {\n writeAdminJSON(response, 200, rotationPayload(server), true);\n return;\n }\n if (path === \"/api/model-quotas\" && method === \"GET\") {\n writeAdminJSON(response, 200, quotaPayload(server), true);\n return;\n }\n if (path === \"/api/debug/inference\" && method === \"POST\") {\n await handleDebugInference(\n server,\n request as unknown as IncomingMessageLike,\n response as unknown as ResponseLike,\n );\n return;\n }\n if (path === \"/api/logs\" && method === \"GET\") {\n handleLogs(server, response, url);\n return;\n }\n if (path === \"/api/logs/stream\" && method === \"GET\") {\n handleLogStream(server, request, response, url);\n return;\n }\n writeAdminError(\n response,\n 404,\n \"not_found\",\n \"management endpoint not found\",\n );\n}\n\n// handleLogin authenticates a client and issues a session.\nasync function handleLogin(\n server: WebUIServer,\n request: IncomingMessage,\n response: ServerResponse,\n): Promise<void> {\n const ip = clientIP(request);\n if (!loginLimiter.allow(ip, LOGIN_LIMIT, LOGIN_WINDOW_MS)) {\n writeAdminError(\n response,\n 429,\n \"rate_limited\",\n \"too many login attempts; try again later\",\n );\n return;\n }\n const body = await readJSON(request);\n if (body === undefined) {\n writeAdminError(\n response,\n 400,\n \"invalid_request\",\n \"request body must be a JSON object\",\n );\n return;\n }\n const username = stringAt(body, \"username\");\n const password = stringAt(body, \"password\");\n if (!server.checkCredentials(username, password)) {\n writeAdminError(\n response,\n 401,\n \"invalid_credentials\",\n \"invalid username or password\",\n );\n return;\n }\n loginLimiter.reset(ip);\n const ttl = server.currentConfig().webui.session_ttl_minutes;\n const { token, csrf } = server.sessions.create(\n username,\n authVersionOf(server.currentConfig()),\n ttl,\n );\n response.setHeader(\n \"Set-Cookie\",\n server.sessionCookie(token, ttl * 60, server.isSecure(request)),\n );\n writeAdminJSON(\n response,\n 200,\n { username, csrf_token: csrf, expires_in: ttl * 60 },\n true,\n );\n}\n\n// handleSession reports the session a request carries.\nfunction handleSession(\n server: WebUIServer,\n request: IncomingMessage,\n response: ServerResponse,\n): void {\n const session = server.validSession(request);\n if (session === undefined) {\n writeAdminError(\n response,\n 401,\n \"authentication_required\",\n \"session expired or invalid\",\n );\n return;\n }\n writeAdminJSON(\n response,\n 200,\n {\n username: session.username,\n csrf_token: session.csrf,\n expires_in: Math.max(\n 0,\n Math.floor((session.expires - Date.now()) / 1000),\n ),\n },\n true,\n );\n}\n\n// handleLogout ends a session.\nfunction handleLogout(\n server: WebUIServer,\n request: IncomingMessage,\n response: ServerResponse,\n): void {\n const token = server.tokenFrom(request);\n server.sessions.drop(token);\n response.setHeader(\"Set-Cookie\", server.clearCookie(server.isSecure(request)));\n writeAdminJSON(response, 200, { ok: true });\n}\n\n// readJSON reads a request body and decodes it.\nasync function readJSON(\n request: IncomingMessage,\n): Promise<Record<string, unknown> | undefined> {\n const chunks: Buffer[] = [];\n let total = 0;\n for await (const chunk of request) {\n const buffer = chunk as Buffer;\n total += buffer.byteLength;\n if (total > 2 * 1024 * 1024) {\n return undefined;\n }\n chunks.push(buffer);\n }\n if (total === 0) {\n return {};\n }\n try {\n const value = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n return isPlainObject(value) ? value : undefined;\n } catch {\n return undefined;\n }\n}\n\n// clientIP reads the client address of a request.\nfunction clientIP(request: IncomingMessage): string {\n return request.socket.remoteAddress ?? \"unknown\";\n}\n\n// originAllowed reports whether a request's origin matches its host.\nfunction originAllowed(\n origin: string,\n request: IncomingMessage,\n secure: boolean,\n): boolean {\n try {\n const parsed = new URL(origin);\n const host = request.headers.host ?? \"\";\n if (parsed.host.toLowerCase() !== host.toLowerCase()) {\n return false;\n }\n return parsed.protocol === (secure ? \"https:\" : \"http:\");\n } catch {\n return false;\n }\n}\n", "import type { Config } from \"../types/config.js\";\nimport { isV1Upstream } from \"../protocol/lanes.js\";\nimport { V2_USER_AGENT } from \"../protocol/lanes.js\";\nimport { ANONYMOUS_KEY } from \"../config/defaults.js\";\nimport {\n CAPABILITIES_URL,\n GO_DOCS_URL,\n ZEN_DOCS_URL,\n parseCapabilities,\n parseModels,\n parseProtocolDocs,\n} from \"./model-discovery.js\";\nimport type { Gateway } from \"../server/gateway.js\";\n\n// The timeout the catalog refresh allows.\nconst REFRESH_TIMEOUT_MS = 30_000;\n\n// CatalogRefresher keeps the model catalog in step with the upstream. It\n// refreshes the two model listings and the capability catalog on a timer.\nexport class CatalogRefresher {\n private timer: NodeJS.Timeout | undefined;\n private running = false;\n\n constructor(\n private readonly gateway: Gateway,\n private readonly config: Config,\n ) {}\n\n // start performs the first refresh and schedules the following ones.\n async start(): Promise<void> {\n await this.refresh();\n const seconds = Math.max(1, this.config.models.refresh_seconds);\n this.timer = setInterval(() => {\n void this.refresh();\n }, seconds * 1000);\n this.timer.unref?.();\n }\n\n // stop ends the refresh timer.\n stop(): void {\n if (this.timer !== undefined) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n // refresh reads the model listings and the capability catalog. The catalog\n // is replaced only when at least one listing succeeded.\n async refresh(): Promise<void> {\n if (this.running) {\n return;\n }\n this.running = true;\n try {\n const [zen, go] = await Promise.all([\n this.fetchTierModels(this.config.upstream.zen, this.config.zen_keys[0] ?? ANONYMOUS_KEY),\n this.fetchTierModels(this.config.upstream.go, this.config.go_keys[0] ?? ANONYMOUS_KEY),\n ]);\n if (zen.length > 0) {\n this.gateway.catalog.applyTier(\"zen\", zen);\n }\n if (go.length > 0) {\n this.gateway.catalog.applyTier(\"go\", go);\n }\n if (zen.length > 0 || go.length > 0) {\n this.gateway.catalog.markLive(this.config.models.refresh_seconds);\n }\n await this.refreshCapabilities();\n } catch (error) {\n this.gateway.logger.warn(\"catalog refresh failed\", \"models\", {\n event: \"catalog_refresh_failed\",\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n this.running = false;\n }\n }\n\n // refreshCapabilities reads the upstream capability catalog. A failure is\n // logged only, because the model listings already carry the routes.\n private async refreshCapabilities(): Promise<void> {\n try {\n const response = await fetch(CAPABILITIES_URL, {\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": V2_USER_AGENT,\n },\n signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),\n });\n if (response.status < 200 || response.status >= 300) {\n throw new Error(\n `OpenCode capability endpoint returned HTTP ${response.status}`,\n );\n }\n const capabilities = parseCapabilities(await response.text());\n await this.applyDocs(capabilities, \"zen\", ZEN_DOCS_URL);\n await this.applyDocs(capabilities, \"go\", GO_DOCS_URL);\n this.gateway.catalog.applyCapabilities(capabilities);\n this.gateway.logger.info(\"model catalog refreshed\", \"models\", {\n event: \"catalog_refreshed\",\n });\n } catch (error) {\n this.gateway.logger.warn(\"capability refresh failed\", \"models\", {\n event: \"capability_refresh_failed\",\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // applyDocs refines the capability data with the endpoint table of a\n // documentation page. A page that cannot be fetched is skipped.\n private async applyDocs(\n capabilities: { protocols: { zen: Record<string, string>; go: Record<string, string> } },\n tier: \"zen\" | \"go\",\n url: string,\n ): Promise<void> {\n try {\n const response = await fetch(url, {\n headers: {\n Accept: \"text/plain, text/markdown, */*\",\n \"User-Agent\": V2_USER_AGENT,\n },\n signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),\n });\n if (response.status < 200 || response.status >= 300) {\n return;\n }\n const protocols = parseProtocolDocs(await response.text());\n for (const [model, protocol] of Object.entries(protocols)) {\n capabilities.protocols[tier][model] = protocol;\n }\n } catch {\n // A documentation page that cannot be fetched only costs the refinement.\n }\n }\n\n // fetchTierModels lists the models a tier advertises.\n private async fetchTierModels(\n baseURL: string,\n key: string,\n ): Promise<string[]> {\n const url = `${baseURL.replace(/\\/+$/, \"\")}/v1/models`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${key}`,\n \"User-Agent\": isV1Upstream(baseURL)\n ? \"opencode/1.19.3\"\n : V2_USER_AGENT,\n \"x-opencode-client\": \"cli\",\n },\n signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),\n });\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`models endpoint returned HTTP ${response.status}`);\n }\n return parseModels(await response.text());\n }\n}\n", "import { runStartCommand, type StartOptions } from \"./commands/start.js\";\n\nconst VERSION = \"1.0.0\";\n\nfunction printHelp(): void {\n console.log(`\nOpenCode2API-Proxy v${VERSION}\nOpenCode Zen and Go to an OpenAI-compatible API proxy\n\nUsage:\n opencode2api-proxy <command> [options]\n\nCommands:\n start Start the local API daemon and control WebUI (default)\n version Display version information\n\nOptions:\n -p, --port <number> Override the API server port\n -h, --host <host> Override the API server host\n -k, --key <string> Set the Bearer API key clients authenticate with\n -c, --config <path> Path to the config file (default: ./config.json)\n --no-webui Disable the control WebUI\n -v, --version Display version information\n --help Display this help message\n\nExamples:\n opencode2api-proxy start --port 8080 --key sk-my-secret-key\n opencode2api-proxy start --config ./config.json\n`);\n}\n\n// CliOptions are the options the command line accepts.\nexport interface CliOptions extends StartOptions {\n version?: boolean;\n help?: boolean;\n}\n\n// parseArgs reads the command line.\nexport function parseArgs(args: string[]): {\n command: string;\n options: CliOptions;\n extraArgs: string[];\n} {\n let command = \"start\";\n const options: CliOptions = {};\n const extraArgs: string[] = [];\n const knownCommands = new Set([\"start\", \"version\"]);\n let index = 0;\n if (args[0] !== undefined && knownCommands.has(args[0])) {\n command = args[0];\n index = 1;\n }\n while (index < args.length) {\n const arg = args[index];\n if (arg === undefined) {\n index += 1;\n continue;\n }\n if (arg === \"-p\" || arg === \"--port\") {\n options.port = Number(args[(index += 1)] ?? \"8080\");\n } else if (arg === \"-h\" || arg === \"--host\") {\n const host = args[index + 1];\n if (host !== undefined) {\n options.host = host;\n }\n index += 1;\n } else if (arg === \"-k\" || arg === \"--key\") {\n const key = args[index + 1];\n if (key !== undefined) {\n options.key = key;\n }\n index += 1;\n } else if (arg === \"-c\" || arg === \"--config\") {\n const config = args[index + 1];\n if (config !== undefined) {\n options.config = config;\n }\n index += 1;\n } else if (arg === \"--no-webui\") {\n options.webui = false;\n } else if (arg === \"-v\" || arg === \"--version\") {\n options.version = true;\n } else if (arg === \"--help\") {\n options.help = true;\n } else {\n extraArgs.push(arg);\n }\n index += 1;\n }\n return { command, options, extraArgs };\n}\n\nasync function main(): Promise<void> {\n const { command, options } = parseArgs(process.argv.slice(2));\n if (options.version === true || command === \"version\") {\n console.log(`opencode2api-proxy v${VERSION}`);\n return;\n }\n if (options.help === true) {\n printHelp();\n return;\n }\n await runStartCommand(options);\n}\n\nmain().catch((error) => {\n console.error(\"[OpenCode2API] Fatal error:\", error);\n process.exit(1);\n});\n"],
5
+ "mappings": "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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCrB,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACDrB,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCnB,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACA5B,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACS7B,IAAM,eAAe,GAAG,UAAU,GAAG,mBAAmB,GAAG,oBAAoB;AAKtF,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCZ,SAAS,iBAAyB;AACvC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP,YAAY;AAAA,EACZ,YAAY;AAAA;AAAA;AAAA;AAAA,EAIZ,UAAU;AAAA;AAAA,EAEV,YAAY;AAAA;AAAA;AAAA;AAAA;AAKd;AAIO,IAAM,aAAa,eAAe;;;AC1EzC,SAAS,YAAY,eAAAC,cAAa,mBAAAC,wBAAuB;AAKlD,IAAM,iBAAiB;AAM9B,IAAM,eAAe;AAGrB,IAAM,sBAAsB;AAC5B,IAAM,mBAAmB;AAYlB,IAAM,eAAN,MAAmB;AAAA,EACP,WAAW,oBAAI,IAA0B;AAAA;AAAA,EAG1D,OAAO,UAAkB,aAAqB,YAG5C;AACA,QAAI,KAAK,SAAS,QAAQ,cAAc;AACtC,WAAK,YAAY;AAAA,IACnB;AACA,UAAM,QAAQ,YAAY,mBAAmB;AAC7C,UAAM,OAAO,YAAY,gBAAgB;AACzC,UAAM,UAAU,KAAK,IAAI,IAAI,aAAa;AAC1C,SAAK,SAAS,IAAI,OAAO,KAAK,GAAG;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,EAAE,OAAO,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA,EAIA,IAAI,OAAyC;AAC3C,QAAI,UAAU,IAAI;AAChB,aAAO;AAAA,IACT;AACA,UAAM,MAAM,OAAO,KAAK;AACxB,UAAM,UAAU,KAAK,SAAS,IAAI,GAAG;AACrC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,WAAW,KAAK,IAAI,GAAG;AACjC,WAAK,SAAS,OAAO,GAAG;AACxB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,KAAK,OAAqB;AACxB,SAAK,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,UAAgB;AACd,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA,EAGA,QAAgB;AACd,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA,EAGQ,cAAoB;AAC1B,QAAI,YAAY;AAChB,QAAI,SAAS,OAAO;AACpB,eAAW,CAAC,KAAK,OAAO,KAAK,KAAK,UAAU;AAC1C,UAAI,QAAQ,UAAU,QAAQ;AAC5B,iBAAS,QAAQ;AACjB,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QAAI,cAAc,IAAI;AACpB,WAAK,SAAS,OAAO,SAAS;AAAA,IAChC;AAAA,EACF;AACF;AAGO,SAAS,YAAY,OAAuB;AACjD,SAAOC,aAAY,KAAK,EAAE,SAAS,WAAW;AAChD;AAGO,SAAS,OAAO,OAAuB;AAC5C,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AACxD;AAcO,SAAS,cAAc,QAAwB;AACpD,SAAO,kBAAkB,OAAO,MAAM,iBAAiB,OAAO,MAAM,YAAY,EAAE;AACpF;;;ACjHO,SAAS,gBACd,UACA,QACA,MACA,SACM;AACN,QAAM,OAAO,GAAG,KAAK,UAAU,EAAE,OAAO,EAAE,MAAM,QAAQ,EAAE,CAAC,CAAC;AAAA;AAC5D,WAAS,UAAU,QAAQ;AAAA,IACzB,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,OAAO,WAAW,IAAI,CAAC;AAAA,EAClD,CAAC;AACD,WAAS,IAAI,IAAI;AACnB;AAGO,SAAS,eACd,UACA,QACA,MACA,UAAU,OACJ;AACN,QAAM,OAAO,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA;AACpC,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,OAAO,WAAW,IAAI,CAAC;AAAA,EAClD;AACA,MAAI,SAAS;AACX,YAAQ,eAAe,IAAI;AAAA,EAC7B;AACA,WAAS,UAAU,QAAQ,OAAO;AAClC,WAAS,IAAI,IAAI;AACnB;;;AC9BO,SAAS,WAAW,OAA2B;AACpD,SAAO,EAAE,IAAI,kBAAkB,KAAK,GAAG,SAAS,WAAW,KAAK,EAAE;AACpE;AAIO,SAAS,WAAW,QAAyC;AAClE,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO,YAAY,IAAI,UAAU;AAAA,IAC9C,UAAU,OAAO,SAAS,IAAI,UAAU;AAAA,IACxC,SAAS,OAAO,QAAQ,IAAI,UAAU;AAAA,IACtC,WAAW,OAAO;AAAA,IAClB,SAAS,OAAO,QAAQ,IAAI,UAAU;AAAA,IACtC,WAAW,OAAO;AAAA,IAClB,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,IACd,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,WAAW,OAAO;AAAA,IAClB,OAAO;AAAA,MACL,SAAS,OAAO,MAAM;AAAA,MACtB,QAAQ,OAAO,MAAM;AAAA,MACrB,UAAU,OAAO,MAAM;AAAA,MACvB,qBAAqB,OAAO,MAAM;AAAA,IACpC;AAAA,IACA,WAAW;AAAA,MACT,QAAQ,OAAO;AAAA,MACf,cAAc,OAAO,MAAM;AAAA,MAC3B,eAAe,OAAO,MAAM;AAAA,IAC9B;AAAA,EACF;AACF;AAGO,SAAS,YAAY,QAA2C;AACrE,SAAO,OAAO,YAAY,IAAI,CAAC,KAAK,UAAU;AAC5C,UAAM,KAAK,kBAAkB,GAAG;AAChC,UAAM,OAAO,OAAO,oBAAoB,EAAE;AAC1C,WAAO;AAAA,MACL;AAAA,MACA,MAAM,MAAM,QAAQ,OAAO,QAAQ,CAAC;AAAA,MACpC,SAAS,WAAW,GAAG;AAAA,MACvB,SAAS,MAAM,aAAa;AAAA,MAC5B,YAAY,MAAM;AAAA,MAClB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,EAAE;AAAA,IACjE;AAAA,EACF,CAAC;AACH;AAGO,SAAS,eAAe,QAA8C;AAC3E,QAAM,UAAU,OAAO,QAAQ,QAAQ,SAAS;AAChD,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ;AAAA,IAClB,WAAW;AAAA,MACT,QAAQ,OAAO,QAAQ,QAAQ,SAAS;AAAA,MACxC,MAAM,CAAC;AAAA,MACP,SAAS,CAAC;AAAA,MACV,WAAW,OAAO,cAAc,EAAE;AAAA,MAClC,UAAU,EAAE,OAAO,OAAO,QAAQ,GAAG,OAAO,MAAM;AAAA,IACpD;AAAA,EACF;AACF;AAGO,SAAS,mBAAmB,QAA8C;AAC/E,QAAM,SAAS,OAAO,cAAc;AACpC,QAAM,SAAS,OAAO,QAAQ,QAAQ,KAAK,EAAE;AAAA,IAAI,CAAC,UAChD,OAAO,QAAQ,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,WAAW;AAAA,MAC1B,OAAO,QAAQ,UAAU;AAAA,MACzB,OAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,MACJ,KAAK,OAAO,SAAS,IAAI,CAAC,KAAK,WAAW;AAAA,QACxC,IAAI,kBAAkB,GAAG;AAAA,QACzB,MAAM;AAAA,QACN,SAAS,WAAW,GAAG;AAAA,QACvB;AAAA,QACA,UAAU;AAAA,MACZ,EAAE;AAAA,MACF,IAAI,OAAO,QAAQ,IAAI,CAAC,KAAK,WAAW;AAAA,QACtC,IAAI,kBAAkB,GAAG;AAAA,QACzB,MAAM;AAAA,QACN,SAAS,WAAW,GAAG;AAAA,QACvB;AAAA,QACA,UAAU;AAAA,MACZ,EAAE;AAAA,IACJ;AAAA,IACA,UAAU,EAAE,OAAO,OAAO,QAAQ,GAAG,OAAO,MAAM;AAAA,IAClD,SAAS,OAAO,QAAQ,QAAQ,SAAS;AAAA,IACzC,gBAAgB;AAAA,EAClB;AACF;AAGO,SAAS,gBAAgB,QAA8C;AAC5E,QAAM,WAAW,OAAO,cAAc,EAAE;AACxC,SAAO;AAAA,IACL,QAAQ;AAAA,MACN;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,SAAS,KAAK;AAAA,QACrB,OAAO,SAAS,KAAK;AAAA,QACrB,SAAS,SAAS,KAAK,MAAM,CAAC,KAAK;AAAA,QACnC,YAAY;AAAA,QACZ,QAAQ,CAAC;AAAA,QACT,WAAW,CAAC;AAAA,QACZ,UAAU,CAAC;AAAA,MACb;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,SAAS,MAAM;AAAA,QACtB,OAAO,SAAS,MAAM;AAAA,QACtB,SAAS,SAAS,MAAM,MAAM,CAAC,KAAK;AAAA,QACpC,YAAY;AAAA,QACZ,QAAQ,CAAC;AAAA,QACT,WAAW,CAAC;AAAA,QACZ,UAAU,CAAC;AAAA,MACb;AAAA,IACF;AAAA,IACA,UAAU,CAAC;AAAA,IACX,sBAAsB,SAAS;AAAA,EACjC;AACF;AAGO,SAAS,aAAa,QAA8C;AACzE,QAAM,SAAS,OAAO,cAAc;AACpC,SAAO;AAAA,IACL,QAAQ,CAAC;AAAA,IACT,UAAU,OAAO,QAAQ,IAAI,CAAC,SAAS;AAAA,MACrC,IAAI,kBAAkB,GAAG;AAAA,MACzB,SAAS,WAAW,GAAG;AAAA,MACvB,QAAQ;AAAA,IACV,EAAE;AAAA,IACF,OAAO;AAAA,IACP,QAAQ,GAAG,OAAO,SAAS,EAAE;AAAA,IAC7B,eAAe;AAAA,IACf,SAAS,OAAO,QAAQ,QAAQ,SAAS;AAAA,IACzC,MACE;AAAA,EACJ;AACF;;;ACrKA,SAAS,eAAAC,oBAAmB;AAY5B,eAAsB,mBACpB,QACA,SACA,UACe;AACf,QAAM,OAAO,MAAM,SAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAU,OAAO,cAAc;AACrC,QAAM,WAAW,KAAK,UAAU;AAChC,QAAM,UAAkB;AAAA,IACtB,GAAG;AAAA,IACH,QAAQ,SAAS,KAAK,QAAQ,GAAG,QAAQ,MAAM;AAAA,IAC/C,WAAW,UAAU,KAAK,WAAW,GAAG,QAAQ,SAAS;AAAA,IACzD,WAAW,SAAS,KAAK,WAAW,GAAG,QAAQ,SAAS;AAAA,IACxD,UAAU;AAAA,MACR,KAAK,SAAS,SAAS,UAAU,KAAK,GAAG,QAAQ,SAAS,GAAG;AAAA,MAC7D,IAAI,SAAS,SAAS,UAAU,IAAI,GAAG,QAAQ,SAAS,EAAE;AAAA,MAC1D,WAAW;AAAA,QACT,SAAS,UAAU,WAAW;AAAA,QAC9B,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF;AAAA,IACA,QACE,KAAK,QAAQ,MAAM,QACf,QACA,KAAK,QAAQ,MAAM,OACjB,OACA,QAAQ;AAAA,EAClB;AACA,QAAM,QAAQ,KAAK,OAAO;AAC1B,MAAIC,eAAc,KAAK,GAAG;AACxB,YAAQ,QAAQ;AAAA,MACd,cAAc;AAAA,QACZ,MAAM,cAAc;AAAA,QACpB,QAAQ,MAAM;AAAA,MAChB;AAAA,MACA,iBAAiB;AAAA,QACf,MAAM,iBAAiB;AAAA,QACvB,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,KAAK,QAAQ;AAC5B,MAAIA,eAAc,MAAM,GAAG;AACzB,YAAQ,SAAS;AAAA,MACf,iBAAiB;AAAA,QACf,OAAO,iBAAiB;AAAA,QACxB,QAAQ,OAAO;AAAA,MACjB;AAAA,MACA,WAAWA,eAAc,OAAO,WAAW,CAAC,IACvC,OAAO,WAAW,IACnB,QAAQ,OAAO;AAAA,MACnB,WAAW,UAAU,OAAO,WAAW,GAAG,QAAQ,OAAO,SAAS;AAAA,IACpE;AAAA,EACF;AACA,QAAM,UAAU,KAAK,SAAS;AAC9B,MAAIA,eAAc,OAAO,GAAG;AAC1B,UAAM,QAAQ,SAAS,SAAS,OAAO;AACvC,YAAQ,UAAU;AAAA,MAChB,OAAO,WAAW,KAAK,IAAK,QAAqB,QAAQ,QAAQ;AAAA,MACjE,WAAW,SAAS,QAAQ,WAAW,GAAG,QAAQ,QAAQ,SAAS;AAAA,MACnE,qBAAqB;AAAA,QACnB,QAAQ,qBAAqB;AAAA,QAC7B,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACA,SAAO,QAAQ,MAAM,OAAO;AAC5B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,SAAS,MAAM,kBAAkB,OAAO,gBAAgB,CAAC,EAAE;AAAA,MACrE,QAAQ,WAAW,OAAO;AAAA,IAC5B;AAAA,EACF;AACF;AAGA,eAAsB,aACpB,QACA,SACA,UACe;AACf,QAAM,OAAO,MAAM,SAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,SAAS,OAAO,cAAc;AACpC,MACE,CAAC,OAAO,iBAAiB,OAAO,MAAM,UAAU,SAAS,MAAM,UAAU,CAAC,GAC1E;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AACF;AAIA,eAAsB,cACpB,QACA,SACA,UACe;AACf,QAAM,OAAO,MAAM,SAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAU,OAAO,cAAc;AACrC,MACE,CAAC,OAAO;AAAA,IACN,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM,kBAAkB;AAAA,EACnC,GACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,WAAW,SAAS,MAAM,UAAU,EAAE,KAAK;AACjD,QAAM,cAAc,SAAS,MAAM,cAAc;AACjD,QAAM,QAAQ;AAAA,IACZ,GAAG,QAAQ;AAAA,IACX,UAAU,aAAa,KAAK,WAAW,QAAQ,MAAM;AAAA,EACvD;AACA,MAAI,gBAAgB,IAAI;AACtB,UAAM,gBAAgB,aAAa,WAAW;AAC9C,WAAO,MAAM;AAAA,EACf;AACA,QAAM,UAAkB,EAAE,GAAG,SAAS,MAAM;AAC5C,SAAO,QAAQ,MAAM,OAAO;AAC5B,SAAO,SAAS,QAAQ;AACxB,WAAS,UAAU,cAAc,OAAO,YAAY,OAAO,SAAS,OAAgB,CAAC,CAAC;AACtF,iBAAe,UAAU,KAAK,EAAE,SAAS,MAAM,gBAAgB,KAAK,CAAC;AACvE;AAGA,eAAsB,gBACpB,QACA,SACA,UACe;AACf,QAAM,OAAO,MAAM,SAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,SAAS,OAAO,cAAc;AACpC,QAAM,OAAO,SAAS,MAAM,MAAM,EAAE,KAAK;AACzC,MAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI;AACvC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,QAAQ,SAAS,MAAM,OAAO,EAAE,KAAK;AAC3C,QAAM,MAAM,UAAU,KAAK,QAAQ,YAAYC,aAAY,EAAE,EAAE,SAAS,KAAK,CAAC;AAC9E,MAAI,IAAI,SAAS,MAAM,IAAI,SAAS,KAAK;AACvC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,CAAC,oBAAoB,KAAK,GAAG,GAAG;AAClC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,KAAK;AACpC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,KAAK,kBAAkB,GAAG;AAChC,MAAI,OAAO,YAAY,KAAK,CAAC,aAAa,kBAAkB,QAAQ,MAAM,EAAE,GAAG;AAC7E;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAkB;AAAA,IACtB,GAAG;AAAA,IACH,aAAa,CAAC,GAAG,OAAO,aAAa,GAAG;AAAA,IACxC,qBAAqB;AAAA,MACnB,GAAG,OAAO;AAAA,MACV,CAAC,EAAE,GAAG,EAAE,MAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE;AAAA,IACrD;AAAA,EACF;AACA,SAAO,QAAQ,MAAM,OAAO;AAC5B,iBAAe,UAAU,KAAK,EAAE,KAAK,MAAM,cAAc,OAAO,EAAE,GAAG,IAAI;AAC3E;AAgBA,SAAS,cAAc,QAA2C;AAChE,SAAO,OAAO,YAAY,IAAI,CAAC,KAAK,UAAU;AAC5C,UAAM,KAAK,kBAAkB,GAAG;AAChC,UAAM,OAAO,OAAO,oBAAoB,EAAE;AAC1C,WAAO;AAAA,MACL;AAAA,MACA,MAAM,MAAM,QAAQ,OAAO,QAAQ,CAAC;AAAA,MACpC,SAAS,2BAAO,IAAI,MAAM,EAAE,CAAC;AAAA,MAC7B,SAAS,MAAM,aAAa;AAAA,MAC5B,YAAY,MAAM;AAAA,MAClB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,UAAU,EAAE,EAAE;AAAA,IACjE;AAAA,EACF,CAAC;AACH;AAGA,eAAe,SACb,SAC8C;AAC9C,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,SAAS;AACjC,UAAM,SAAS;AACf,aAAS,OAAO;AAChB,QAAI,QAAQ,kBAAkB;AAC5B,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACA,MAAI,UAAU,GAAG;AACf,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,QAAQ,KAAK,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,CAAC;AAC/D,WAAOD,eAAc,KAAK,IAAI,QAAQ;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,IAAM,mBAAmB,IAAI,OAAO;AAGpC,SAAS,SAAS,OAAgB,UAA0B;AAC1D,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAGA,SAAS,SAAS,OAAgB,UAA0B;AAC1D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAGA,SAAS,UAAU,OAAgB,UAA4B;AAC7D,SAAO,OAAO,UAAU,YAAY,QAAQ;AAC9C;AAGA,SAAS,WAAW,OAAwB;AAC1C,SACE,UAAU,WACV,UAAU,UACV,UAAU,UACV,UAAU;AAEd;;;ACnVO,IAAM,cAAN,MAAkB;AAAA,EACN,UAAU,oBAAI,IAAoB;AAAA;AAAA,EAGnD,MAAM,KAAa,OAAe,UAA2B;AAC3D,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,SAAS,KAAK,QAAQ,IAAI,GAAG;AACnC,QAAI,WAAW,UAAa,MAAM,OAAO,QAAQ,UAAU;AACzD,WAAK,QAAQ,IAAI,KAAK,EAAE,OAAO,GAAG,OAAO,IAAI,CAAC;AAC9C,WAAK,MAAM,KAAK,QAAQ;AACxB,aAAO;AAAA,IACT;AACA,QAAI,OAAO,SAAS,OAAO;AACzB,aAAO;AAAA,IACT;AACA,WAAO,SAAS;AAChB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAmB;AACvB,SAAK,QAAQ,OAAO,GAAG;AAAA,EACzB;AAAA;AAAA,EAGQ,MAAM,KAAa,UAAwB;AACjD,QAAI,KAAK,QAAQ,OAAO,MAAM;AAC5B;AAAA,IACF;AACA,eAAW,CAAC,KAAK,MAAM,KAAK,KAAK,SAAS;AACxC,UAAI,MAAM,OAAO,QAAQ,UAAU;AACjC,aAAK,QAAQ,OAAO,GAAG;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;;;AC/BA,IAAM,mBAAmB;AAGzB,IAAM,uBAAuB,KAAK;AAG3B,IAAM,oBAAoB,IAAI,YAAY;AAGjD,eAAsB,gBACpB,QACA,SACA,UACA,IACe;AACf,QAAM,SAAS,OAAO,cAAc;AACpC,QAAM,QAAQ,OAAO,YAAY;AAAA,IAC/B,CAAC,QAAQ,kBAAkB,GAAG,MAAM;AAAA,EACtC;AACA,MAAI,QAAQ,GAAG;AACb;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,OACJ,QAAQ,WAAW,WAAW,CAAC,IAAI,MAAME,UAAS,OAAO;AAC3D,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAkB;AAAA,IACtB,GAAG;AAAA,IACH,aAAa,CAAC,GAAG,OAAO,WAAW;AAAA,IACnC,qBAAqB,EAAE,GAAG,OAAO,oBAAoB;AAAA,EACvD;AACA,QAAM,OAAO;AAAA,IACX,GAAI,OAAO,oBAAoB,EAAE,KAAK,EAAE,MAAM,OAAO,QAAQ,CAAC,GAAG;AAAA,EACnE;AACA,MAAI,QAAQ,WAAW,UAAU;AAC/B,QAAI,aAAa,MAAM,KAAK,GAAG;AAC7B;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AACA,YAAQ,YAAY,OAAO,OAAO,CAAC;AACnC,WAAO,QAAQ,oBAAoB,EAAE;AAAA,EACvC,OAAO;AACL,UAAM,OAAO,SAAS,MAAM,MAAM,EAAE,KAAK;AACzC,QAAI,SAAS,IAAI;AACf,UAAI,KAAK,SAAS,IAAI;AACpB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA;AAAA,MACF;AACA,WAAK,OAAO;AAAA,IACd;AACA,QAAI,KAAK,SAAS,MAAM,OAAO;AAC7B,UAAI,aAAa,MAAM,KAAK,GAAG;AAC7B;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA;AAAA,MACF;AACA,WAAK,WAAW;AAAA,IAClB,WAAW,KAAK,SAAS,MAAM,MAAM;AACnC,aAAO,KAAK;AAAA,IACd;AACA,YAAQ,oBAAoB,EAAE,IAAI;AAAA,EACpC;AACA,SAAO,QAAQ,MAAM,OAAO;AAC5B,iBAAe,UAAU,KAAK,EAAE,MAAM,YAAY,OAAO,EAAE,CAAC;AAC9D;AAGA,eAAsB,qBACpB,QACA,SACA,UACe;AACf,QAAM,KAAK,QAAQ,OAAO,iBAAiB;AAC3C,MACE,CAAC,kBAAkB,MAAM,IAAI,kBAAkB,oBAAoB,GACnE;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,OAAO,MAAMA,UAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,WAAW,SAAS,MAAM,UAAU;AAC1C,MACE,aAAa,UACb,aAAa,eACb,aAAa,aACb;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAU,KAAK,SAAS;AAC9B,MAAI,CAACC,eAAc,OAAO,GAAG;AAC3B;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,SAAS,OAAO,MAAM,IAAI;AACrC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,SAAS,OAAO,cAAc;AACpC,QAAM,MAAM,OAAO,YAAY,KAAK,CAAC,UAAU,WAAW,QAAQ,KAAK,CAAC;AACxE,MAAI,QAAQ,QAAW;AACrB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,UAAU,KAAK,IAAI;AACzB,QAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI,OAAO,UAAU,OAAO,OAAO,SAAS;AAAA,MAC5C,aAAa,OAAO;AAAA,MACpB,aAAa,KAAK,IAAI,IAAI;AAAA,MAC1B,YAAY,OAAO;AAAA,MACnB,UAAU,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,WAAW,QAAgB,KAAsB;AACxD,QAAM,OAAO,OAAO,oBAAoB,kBAAkB,GAAG,CAAC;AAC9D,SAAO,MAAM,aAAa;AAC5B;AAGA,SAAS,aAAa,QAAwB;AAC5C,SAAO,OAAO,YAAY,OAAO,CAAC,QAAQ,WAAW,QAAQ,GAAG,CAAC,EAAE;AACrE;AAGA,eAAeD,UACb,SAC8C;AAC9C,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,SAAS;AACjC,UAAM,SAAS;AACf,aAAS,OAAO;AAChB,QAAI,QAAQ,IAAI,OAAO,MAAM;AAC3B,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACA,MAAI,UAAU,GAAG;AACf,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,QAAQ,KAAK,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,CAAC;AAC/D,WAAOC,eAAc,KAAK,IAAI,QAAQ;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACjOA,IAAM,eAAe;AAGrB,IAAM,eAAe;AAGd,SAAS,WACd,QACA,UACA,KACM;AACN,QAAM,QAAQ,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,EAAE;AAC3D,QAAM,QAAQ,SAAS,IAAI,aAAa,IAAI,OAAO,KAAK,EAAE;AAC1D,QAAM,SAAS,OAAO,QAAQ,KAAK,OAAO,OAAO,KAAK;AACtD,iBAAe,UAAU,KAAK,EAAE,QAAQ,OAAO,QAAQ,KAAK,OAAO,IAAI,CAAC;AAC1E;AAKO,SAAS,gBACd,QACA,SACA,UACA,KACM;AACN,QAAM,SAAS,QAAQ,QAAQ,eAAe;AAC9C,MAAI,SAAS,UAAU,OAAO,WAAW,WAAW,SAAS,EAAE;AAC/D,QAAM,QAAQ,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,EAAE;AAC3D,MAAI,QAAQ,QAAQ;AAClB,aAAS;AAAA,EACX;AACA,WAAS,UAAU,KAAK;AAAA,IACtB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,EACvB,CAAC;AACD,QAAM,SAAS,OAAO,QAAQ,KAAK,OAAO,QAAQ,YAAY;AAC9D,MAAI,OAAO,KAAK;AACd,aAAS;AAAA,MACP;AAAA,QAAqB,KAAK,UAAU;AAAA,QAClC,SAAS;AAAA,MACX,CAAC,CAAC;AAAA;AAAA;AAAA,IACJ;AAAA,EACF;AACA,aAAW,SAAS,OAAO,QAAQ;AACjC,aAAS,MAAM;AACf,aAAS;AAAA,MACP,OAAO,MAAM,QAAQ;AAAA;AAAA,QAAuB,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AAAA,IACnE;AAAA,EACF;AACA,QAAM,cAAc,OAAO,QAAQ,KAAK,UAAU,CAAC,UAAU;AAC3D,QAAI,SAAS,KAAK,MAAM,WAAW,SAAS,GAAG;AAC7C,eAAS;AAAA,QACP;AAAA,QAAqB,KAAK,UAAU;AAAA,UAClC,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,MAAM;AAAA,QACd,CAAC,CAAC;AAAA;AAAA;AAAA,MACJ;AAAA,IACF;AACA,aAAS,MAAM;AACf,aAAS;AAAA,MACP,OAAO,MAAM,QAAQ;AAAA;AAAA,QAAuB,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AAAA,IACnE;AAAA,EACF,CAAC;AACD,QAAM,YAAY,YAAY,MAAM;AAGlC,QAAI,OAAO,aAAa,OAAO,MAAM,QAAW;AAC9C,oBAAc,SAAS;AACvB,kBAAY;AACZ,eAAS,IAAI;AACb;AAAA,IACF;AACA,aAAS,MAAM,iBAAiB;AAAA,EAClC,GAAG,YAAY;AACf,YAAU,QAAQ;AAClB,UAAQ,GAAG,SAAS,MAAM;AACxB,kBAAc,SAAS;AACvB,gBAAY;AAAA,EACd,CAAC;AACH;AAGA,SAAS,UAAU,OAAuB;AACxC,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AAC1C,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAM,MAAM;AAC1B;AAGA,SAAS,SAAS,OAAuB;AACvC,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAM,MAAM;AAC1B;;;AC/EA,IAAM,cAAc;AAGpB,IAAM,kBAAkB,IAAI,KAAK;AAG1B,IAAM,eAAe,IAAI,YAAY;AAG5C,eAAsB,mBACpB,QACA,SACA,UACA,KACe;AACf,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,OAAO,IAAI;AACjB,MAAI,SAAS,qBAAqB,WAAW,QAAQ;AACnD,UAAM,YAAY,QAAQ,SAAS,QAAQ;AAC3C;AAAA,EACF;AACA,MAAI,SAAS,uBAAuB,WAAW,OAAO;AACpD,kBAAc,QAAQ,SAAS,QAAQ;AACvC;AAAA,EACF;AACA,MAAI,SAAS,sBAAsB,WAAW,QAAQ;AACpD,iBAAa,QAAQ,SAAS,QAAQ;AACtC;AAAA,EACF;AACA,QAAM,UAAU,OAAO,aAAa,OAAO;AAC3C,MAAI,YAAY,QAAW;AACzB,oBAAgB,UAAU,KAAK,2BAA2B,gBAAgB;AAC1E;AAAA,EACF;AACA,MAAI,WAAW,SAAS,WAAW,QAAQ;AACzC,UAAM,OAAO,QAAQ,QAAQ,cAAc;AAC3C,QAAI,OAAO,SAAS,YAAY,CAACC,oBAAmB,MAAM,QAAQ,IAAI,GAAG;AACvE,sBAAgB,UAAU,KAAK,eAAe,qBAAqB;AACnE;AAAA,IACF;AACA,UAAM,SAAS,QAAQ,QAAQ;AAC/B,QAAI,OAAO,WAAW,YAAY,WAAW,IAAI;AAC/C,UAAI,CAAC,cAAc,QAAQ,SAAS,OAAO,SAAS,OAAO,CAAC,GAAG;AAC7D,wBAAgB,UAAU,KAAK,iBAAiB,oBAAoB;AACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,iBAAiB,WAAW,OAAO;AAC9C,mBAAe,UAAU,KAAK,WAAW,OAAO,cAAc,CAAC,GAAG,IAAI;AACtE;AAAA,EACF;AACA,MAAI,SAAS,iBAAiB,WAAW,OAAO;AAC9C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,wBAAwB,WAAW,QAAQ;AACtD,mBAAe,UAAU,KAAK,EAAE,SAAS,MAAM,kBAAkB,MAAM,CAAC;AACxE;AAAA,EACF;AACA,MAAI,SAAS,wBAAwB,WAAW,QAAQ;AACtD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,kBAAkB,WAAW,OAAO;AAC/C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,kBAAkB,WAAW,OAAO;AAC/C,mBAAe,UAAU,KAAK,eAAe,MAAM,CAAC;AACpD;AAAA,EACF;AACA,MAAI,SAAS,uBAAuB,WAAW,OAAO;AACpD,mBAAe,UAAU,KAAK,mBAAmB,MAAM,GAAG,IAAI;AAC9D;AAAA,EACF;AACA,MAAI,SAAS,mBAAmB,WAAW,OAAO;AAChD;AAAA,MACE;AAAA,MACA;AAAA,MACA,EAAE,MAAM,YAAY,OAAO,cAAc,CAAC,EAAE;AAAA,MAC5C;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,mBAAmB,WAAW,QAAQ;AACjD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MACE,KAAK,WAAW,gBAAgB,MAC/B,WAAW,WAAW,WAAW,WAClC;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,MAAM,iBAAiB,MAAM;AAAA,IACpC;AACA;AAAA,EACF;AACA,MAAI,SAAS,8BAA8B,WAAW,OAAO;AAC3D,mBAAe,UAAU,KAAK,EAAE,QAAQ,CAAC,EAAE,GAAG,IAAI;AAClD;AAAA,EACF;AACA,MAAI,SAAS,mBAAmB,WAAW,OAAO;AAChD,mBAAe,UAAU,KAAK,gBAAgB,MAAM,GAAG,IAAI;AAC3D;AAAA,EACF;AACA,MAAI,SAAS,uBAAuB,WAAW,OAAO;AACpD,mBAAe,UAAU,KAAK,aAAa,MAAM,GAAG,IAAI;AACxD;AAAA,EACF;AACA,MAAI,SAAS,0BAA0B,WAAW,QAAQ;AACxD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,SAAS,eAAe,WAAW,OAAO;AAC5C,eAAW,QAAQ,UAAU,GAAG;AAChC;AAAA,EACF;AACA,MAAI,SAAS,sBAAsB,WAAW,OAAO;AACnD,oBAAgB,QAAQ,SAAS,UAAU,GAAG;AAC9C;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAe,YACb,QACA,SACA,UACe;AACf,QAAM,KAAK,SAAS,OAAO;AAC3B,MAAI,CAAC,aAAa,MAAM,IAAI,aAAa,eAAe,GAAG;AACzD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,OAAO,MAAMC,UAAS,OAAO;AACnC,MAAI,SAAS,QAAW;AACtB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,WAAW,SAAS,MAAM,UAAU;AAC1C,QAAM,WAAW,SAAS,MAAM,UAAU;AAC1C,MAAI,CAAC,OAAO,iBAAiB,UAAU,QAAQ,GAAG;AAChD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,eAAa,MAAM,EAAE;AACrB,QAAM,MAAM,OAAO,cAAc,EAAE,MAAM;AACzC,QAAM,EAAE,OAAO,KAAK,IAAI,OAAO,SAAS;AAAA,IACtC;AAAA,IACA,cAAc,OAAO,cAAc,CAAC;AAAA,IACpC;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,IACA,OAAO,cAAc,OAAO,MAAM,IAAI,OAAO,SAAS,OAAO,CAAC;AAAA,EAChE;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,EAAE,UAAU,YAAY,MAAM,YAAY,MAAM,GAAG;AAAA,IACnD;AAAA,EACF;AACF;AAGA,SAAS,cACP,QACA,SACA,UACM;AACN,QAAM,UAAU,OAAO,aAAa,OAAO;AAC3C,MAAI,YAAY,QAAW;AACzB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,UAAU,QAAQ;AAAA,MAClB,YAAY,QAAQ;AAAA,MACpB,YAAY,KAAK;AAAA,QACf;AAAA,QACA,KAAK,OAAO,QAAQ,UAAU,KAAK,IAAI,KAAK,GAAI;AAAA,MAClD;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,aACP,QACA,SACA,UACM;AACN,QAAM,QAAQ,OAAO,UAAU,OAAO;AACtC,SAAO,SAAS,KAAK,KAAK;AAC1B,WAAS,UAAU,cAAc,OAAO,YAAY,OAAO,SAAS,OAAO,CAAC,CAAC;AAC7E,iBAAe,UAAU,KAAK,EAAE,IAAI,KAAK,CAAC;AAC5C;AAGA,eAAeA,UACb,SAC8C;AAC9C,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,mBAAiB,SAAS,SAAS;AACjC,UAAM,SAAS;AACf,aAAS,OAAO;AAChB,QAAI,QAAQ,IAAI,OAAO,MAAM;AAC3B,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACA,MAAI,UAAU,GAAG;AACf,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,QAAQ,KAAK,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,CAAC;AAC/D,WAAOC,eAAc,KAAK,IAAI,QAAQ;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,SAAS,SAAkC;AAClD,SAAO,QAAQ,OAAO,iBAAiB;AACzC;AAGA,SAAS,cACP,QACA,SACA,QACS;AACT,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,UAAM,OAAO,QAAQ,QAAQ,QAAQ;AACrC,QAAI,OAAO,KAAK,YAAY,MAAM,KAAK,YAAY,GAAG;AACpD,aAAO;AAAA,IACT;AACA,WAAO,OAAO,cAAc,SAAS,WAAW;AAAA,EAClD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AdtTO,IAAM,mBAA2C;AAAA,EACtD,2BACE;AAAA,EACF,mBAAmB;AAAA,EACnB,0BAA0B;AAAA,EAC1B,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,8BAA8B;AAChC;AAGA,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAGpB,SAAS,aAAa,UAA0B;AACrD,QAAM,OAAOC,aAAY,kBAAkB;AAC3C,QAAM,UAAU,WAAW,UAAU,MAAM,mBAAmB;AAAA,IAC5D,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAAA,IACzC,KAAK,SAAS,QAAQ;AAAA,IACtB,QAAQ,SAAS,QAAQ;AAAA,EAC3B,EAAE,KAAK,GAAG;AACZ;AAEO,SAAS,eAAe,MAAc,UAA2B;AACtE,QAAM,QAAQ,KAAK,MAAM,GAAG;AAG5B,MAAI,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM,UAAU;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,CAAC,KAAK;AAC3B,QAAM,IAAI,WAAW,QAAQ,GAAG;AAChC,QAAM,IAAI,WAAW,QAAQ,GAAG;AAChC,QAAM,IAAI,WAAW,QAAQ,GAAG;AAChC,MAAI,MAAM,KAAK,MAAM,KAAK,MAAM,GAAG;AACjC,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,WAAO,OAAO,KAAK,MAAM,CAAC,KAAK,IAAI,QAAQ;AAC3C,eAAW,OAAO,KAAK,MAAM,CAAC,KAAK,IAAI,QAAQ;AAAA,EACjD,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,KAAK,WAAW,KAAK,SAAS,WAAW,GAAG;AAC9C,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACF,cAAU,WAAW,UAAU,MAAM,SAAS,QAAQ,EAAE,GAAG,GAAG,EAAE,CAAC;AAAA,EACnE,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,WAAW,SAAS,QAAQ;AACtC,WAAO;AAAA,EACT;AACA,SAAOC,oBAAmB,QAAQ,SAAS,QAAQ,GAAG,SAAS,SAAS,QAAQ,CAAC;AACnF;AAGA,SAAS,WAAW,QAAgB,MAAsB;AACxD,aAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AACpC,UAAM,CAAC,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG;AACnC,QAAI,QAAQ,MAAM;AAChB,YAAM,SAAS,OAAO,KAAK;AAC3B,aAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAAA,IAC5C;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAASA,oBAAmB,MAAc,OAAwB;AACvE,QAAM,IAAI,OAAO,KAAK,MAAM,MAAM;AAClC,QAAM,IAAI,OAAO,KAAK,OAAO,MAAM;AACnC,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO;AAAA,EACT;AACA,SAAOC,iBAAgB,GAAG,CAAC;AAC7B;AAGO,IAAM,cAAN,MAAkB;AAAA,EAIvB,YAAY,SAAmC,QAAgB;AAAhB;AAC7C,SAAK,UAAU;AAAA,EACjB;AAAA,EALS,WAAW,IAAI,aAAa;AAAA,EAC5B;AAAA;AAAA,EAOT,MAAM,OAAO,SAA0B,UAAyC;AAC9E,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC5D,eAAS,UAAU,MAAM,KAAK;AAAA,IAChC;AACA,UAAM,MAAM,IAAI;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,UAAU,QAAQ,QAAQ,QAAQ,WAAW;AAAA,IAC/C;AACA,QAAI,IAAI,SAAS,WAAW,OAAO,GAAG;AACpC,YAAM,mBAAmB,MAAM,SAAS,UAAU,GAAG;AACrD;AAAA,IACF;AACA,SAAK,cAAc,QAAQ;AAAA,EAC7B;AAAA;AAAA,EAGQ,cAAc,UAAgC;AACpD,aAAS,UAAU,KAAK;AAAA,MACtB,gBAAgB;AAAA,MAChB,kBAAkB,OAAO,WAAW,UAAU;AAAA,IAChD,CAAC;AACD,aAAS,IAAI,UAAU;AAAA,EACzB;AAAA;AAAA,EAGA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,cAAc,OAAe,eAAuB,QAAyB;AAC3E,UAAM,QAAQ;AAAA,MACZ,GAAG,cAAc,IAAI,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,aAAa;AAAA,IAC1B;AACA,QAAI,QAAQ;AACV,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,YAAY,QAAyB;AACnC,WAAO,KAAK,cAAc,IAAI,IAAI,MAAM;AAAA,EAC1C;AAAA;AAAA,EAGA,UAAU,SAAkC;AAC1C,UAAM,SAAS,QAAQ,QAAQ;AAC/B,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,IACT;AACA,eAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AACpC,YAAM,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,KAAK,EAAE,MAAM,GAAG;AAC7C,UAAI,SAAS,gBAAgB;AAC3B,eAAO,KAAK,KAAK,GAAG;AAAA,MACtB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAAS,SAAmC;AAC1C,UAAM,YAAY,QAAQ,QAAQ,mBAAmB;AACrD,QACE,OAAO,cAAc,YACrB,UAAU,KAAK,EAAE,YAAY,MAAM,SACnC;AACA,aAAO;AAAA,IACT;AACA,WAAQ,QAAQ,OAAmC,cAAc;AAAA,EACnE;AAAA;AAAA,EAGA,aAAa,SAA2D;AACtE,UAAM,QAAQ,KAAK,UAAU,OAAO;AACpC,UAAM,UAAU,KAAK,SAAS,IAAI,KAAK;AACvC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,aAAa,KAAK,OAAO,MAAM,UAAU;AACnD,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,gBAAgB,cAAc,KAAK,MAAM,GAAG;AACtD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,iBAAiB,UAAkB,UAA2B;AAC5D,QAAI,aAAa,KAAK,OAAO,MAAM,UAAU;AAC3C,aAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,OAAO,MAAM,iBAAiB;AAChD,QAAI,SAAS,IAAI;AACf,aAAO,eAAe,MAAM,QAAQ;AAAA,IACtC;AACA,WAAOD,oBAAmB,KAAK,OAAO,MAAM,YAAY,IAAI,QAAQ;AAAA,EACtE;AACF;AAGA,eAAsB,iBACpB,SACA,QACiB;AACjB,QAAM,SAAS,IAAI,YAAY,SAAS,QAAQ,QAAQ,CAAC;AACzD,QAAM,OAAOE,cAAa,CAAC,SAAS,aAAa;AAC/C,SAAK,OAAO,OAAO,SAAS,QAAQ,EAAE,MAAM,MAAM;AAChD,UAAI,CAAC,SAAS,aAAa;AACzB,wBAAgB,UAAU,KAAK,kBAAkB,gBAAgB;AAAA,MACnE;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,SAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,SAAK,KAAK,SAAS,MAAM;AACzB,UAAM,EAAE,MAAM,KAAK,IAAIC,aAAY,MAAM;AACzC,SAAK,OAAO,MAAM,MAAM,MAAM;AAC5B,WAAK,eAAe,SAAS,MAAM;AACnC,MAAAD,SAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AACH;AAGA,SAASC,aAAY,QAAgD;AACnE,QAAM,QAAQ,OAAO,YAAY,GAAG;AACpC,MAAI,UAAU,IAAI;AAChB,WAAO,EAAE,MAAM,aAAa,MAAM,KAAK;AAAA,EACzC;AACA,QAAM,OAAO,OAAO,MAAM,GAAG,KAAK,KAAK;AACvC,QAAM,OAAO,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC;AAC3C,SAAO,EAAE,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,OAAO,KAAK;AAC3D;;;Ae1PA;AAYA,IAAM,qBAAqB;AAIpB,IAAM,mBAAN,MAAuB;AAAA,EAI5B,YACmB,SACA,QACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EANK;AAAA,EACA,UAAU;AAAA;AAAA,EAQlB,MAAM,QAAuB;AAC3B,UAAM,KAAK,QAAQ;AACnB,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,eAAe;AAC9D,SAAK,QAAQ,YAAY,MAAM;AAC7B,WAAK,KAAK,QAAQ;AAAA,IACpB,GAAG,UAAU,GAAI;AACjB,SAAK,MAAM,QAAQ;AAAA,EACrB;AAAA;AAAA,EAGA,OAAa;AACX,QAAI,KAAK,UAAU,QAAW;AAC5B,oBAAc,KAAK,KAAK;AACxB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,UAAyB;AAC7B,QAAI,KAAK,SAAS;AAChB;AAAA,IACF;AACA,SAAK,UAAU;AACf,QAAI;AACF,YAAM,CAAC,KAAK,EAAE,IAAI,MAAM,QAAQ,IAAI;AAAA,QAClC,KAAK,gBAAgB,KAAK,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,CAAC,KAAK,aAAa;AAAA,QACvF,KAAK,gBAAgB,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,QAAQ,CAAC,KAAK,aAAa;AAAA,MACvF,CAAC;AACD,UAAI,IAAI,SAAS,GAAG;AAClB,aAAK,QAAQ,QAAQ,UAAU,OAAO,GAAG;AAAA,MAC3C;AACA,UAAI,GAAG,SAAS,GAAG;AACjB,aAAK,QAAQ,QAAQ,UAAU,MAAM,EAAE;AAAA,MACzC;AACA,UAAI,IAAI,SAAS,KAAK,GAAG,SAAS,GAAG;AACnC,aAAK,QAAQ,QAAQ,SAAS,KAAK,OAAO,OAAO,eAAe;AAAA,MAClE;AACA,YAAM,KAAK,oBAAoB;AAAA,IACjC,SAAS,OAAO;AACd,WAAK,QAAQ,OAAO,KAAK,0BAA0B,UAAU;AAAA,QAC3D,OAAO;AAAA,QACP,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH,UAAE;AACA,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAc,sBAAqC;AACjD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,kBAAkB;AAAA,QAC7C,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,QACA,QAAQ,YAAY,QAAQ,kBAAkB;AAAA,MAChD,CAAC;AACD,UAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACnD,cAAM,IAAI;AAAA,UACR,8CAA8C,SAAS,MAAM;AAAA,QAC/D;AAAA,MACF;AACA,YAAM,eAAe,kBAAkB,MAAM,SAAS,KAAK,CAAC;AAC5D,YAAM,KAAK,UAAU,cAAc,OAAO,YAAY;AACtD,YAAM,KAAK,UAAU,cAAc,MAAM,WAAW;AACpD,WAAK,QAAQ,QAAQ,kBAAkB,YAAY;AACnD,WAAK,QAAQ,OAAO,KAAK,2BAA2B,UAAU;AAAA,QAC5D,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,QAAQ,OAAO,KAAK,6BAA6B,UAAU;AAAA,QAC9D,OAAO;AAAA,QACP,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAc,UACZ,cACA,MACA,KACe;AACf,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,QACA,QAAQ,YAAY,QAAQ,kBAAkB;AAAA,MAChD,CAAC;AACD,UAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACnD;AAAA,MACF;AACA,YAAM,YAAY,kBAAkB,MAAM,SAAS,KAAK,CAAC;AACzD,iBAAW,CAAC,OAAO,QAAQ,KAAK,OAAO,QAAQ,SAAS,GAAG;AACzD,qBAAa,UAAU,IAAI,EAAE,KAAK,IAAI;AAAA,MACxC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,gBACZ,SACA,KACmB;AACnB,UAAM,MAAM,GAAG,QAAQ,QAAQ,QAAQ,EAAE,CAAC;AAC1C,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS;AAAA,QACP,eAAe,UAAU,GAAG;AAAA,QAC5B,cAAc,aAAa,OAAO,IAC9B,oBACA;AAAA,QACJ,qBAAqB;AAAA,MACvB;AAAA,MACA,QAAQ,YAAY,QAAQ,kBAAkB;AAAA,IAChD,CAAC;AACD,QAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACnD,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,IACpE;AACA,WAAO,YAAY,MAAM,SAAS,KAAK,CAAC;AAAA,EAC1C;AACF;;;A9EvIA,eAAsB,gBAAgB,SAAsC;AAC1E,QAAM,aAAa,kBAAkB,QAAQ,MAAM;AACnD,QAAM,SAAS,MAAM,WAAW,UAAU;AAC1C,QAAM,UAAU,eAAe,QAAQ,OAAO;AAC9C,QAAM,QAAQ,IAAI,YAAY,SAAS,UAAU;AACjD,OAAK;AACL,QAAM,UAAU,IAAI,QAAQ,OAAO;AAEnC,QAAM,aAAa,IAAI,kBAAkB,MAAM,QAAQ,WAAW,CAAC;AACnE,iBAAe,YAAY,OAAO;AAClC,QAAM,SAAS,SAAS,QAAQ,QAAQ,OAAO;AAC/C,QAAM,SAAS,MAAM,YAAY,YAAY,MAAM;AACnD,UAAQ;AAAA,IACN,0CAA0C,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,MAAM;AAAA,EAC5F;AAEA,QAAM,YAAY,IAAI,iBAAiB,SAAS,OAAO;AACvD,QAAM,UAAU,MAAM;AAEtB,MAAI;AACJ,MAAI,QAAQ,MAAM,SAAS;AACzB,kBAAc,MAAM,iBAAiB,SAAS,QAAQ,MAAM,MAAM;AAClE,YAAQ,IAAI,6CAA6C,QAAQ,MAAM,MAAM,EAAE;AAAA,EACjF;AAEA,QAAM,WAAW,MAAY;AAC3B,YAAQ,IAAI,iCAAiC;AAC7C,cAAU,KAAK;AACf,WAAO,MAAM;AACb,iBAAa,MAAM;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,QAAQ;AAChC;AAGO,SAAS,eAAe,QAAgB,SAA+B;AAC5E,QAAM,SAAS,EAAE,GAAG,OAAO;AAC3B,MAAI,QAAQ,QAAQ,UAAa,QAAQ,QAAQ,IAAI;AACnD,WAAO,cAAc,CAAC,QAAQ,GAAG;AAAA,EACnC;AACA,MAAI,QAAQ,SAAS,UAAa,QAAQ,SAAS,QAAW;AAC5D,UAAM,OAAO,QAAQ,QAAQ,OAAO,OAAO,MAAM;AACjD,UAAM,OAAO,QAAQ,QAAQ,OAAO,OAAO,MAAM;AACjD,WAAO,SAAS,GAAG,IAAI,IAAI,IAAI;AAAA,EACjC;AACA,MAAI,QAAQ,UAAU,OAAO;AAC3B,WAAO,QAAQ,EAAE,GAAG,OAAO,OAAO,SAAS,MAAM;AAAA,EACnD;AACA,SAAO;AACT;AAGO,SAAS,OAAO,QAAwB;AAC7C,QAAM,QAAQ,OAAO,YAAY,GAAG;AACpC,SAAO,UAAU,KAAK,cAAc,OAAO,MAAM,GAAG,KAAK;AAC3D;AAGO,SAAS,OAAO,QAAwB;AAC7C,QAAM,QAAQ,OAAO,YAAY,GAAG;AACpC,MAAI,UAAU,IAAI;AAChB,WAAO;AAAA,EACT;AACA,QAAM,OAAO,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC;AAC3C,SAAO,OAAO,SAAS,IAAI,IAAI,OAAO;AACxC;AAGO,SAAS,SAAS,QAAgB,SAA+B;AACtE,QAAM,OAAO,QAAQ,QAAQ,OAAO,MAAM;AAC1C,QAAM,OAAO,QAAQ,QAAQ,OAAO,MAAM;AAC1C,SAAO,GAAG,IAAI,IAAI,IAAI;AACxB;;;A+E9FA,IAAM,UAAU;AAEhB,SAAS,YAAkB;AACzB,UAAQ,IAAI;AAAA,sBACQ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAsB5B;AACD;AASO,SAAS,UAAU,MAIxB;AACA,MAAI,UAAU;AACd,QAAM,UAAsB,CAAC;AAC7B,QAAM,YAAsB,CAAC;AAC7B,QAAM,gBAAgB,oBAAI,IAAI,CAAC,SAAS,SAAS,CAAC;AAClD,MAAI,QAAQ;AACZ,MAAI,KAAK,CAAC,MAAM,UAAa,cAAc,IAAI,KAAK,CAAC,CAAC,GAAG;AACvD,cAAU,KAAK,CAAC;AAChB,YAAQ;AAAA,EACV;AACA,SAAO,QAAQ,KAAK,QAAQ;AAC1B,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,QAAQ,QAAW;AACrB,eAAS;AACT;AAAA,IACF;AACA,QAAI,QAAQ,QAAQ,QAAQ,UAAU;AACpC,cAAQ,OAAO,OAAO,KAAM,SAAS,CAAE,KAAK,MAAM;AAAA,IACpD,WAAW,QAAQ,QAAQ,QAAQ,UAAU;AAC3C,YAAM,OAAO,KAAK,QAAQ,CAAC;AAC3B,UAAI,SAAS,QAAW;AACtB,gBAAQ,OAAO;AAAA,MACjB;AACA,eAAS;AAAA,IACX,WAAW,QAAQ,QAAQ,QAAQ,SAAS;AAC1C,YAAM,MAAM,KAAK,QAAQ,CAAC;AAC1B,UAAI,QAAQ,QAAW;AACrB,gBAAQ,MAAM;AAAA,MAChB;AACA,eAAS;AAAA,IACX,WAAW,QAAQ,QAAQ,QAAQ,YAAY;AAC7C,YAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAI,WAAW,QAAW;AACxB,gBAAQ,SAAS;AAAA,MACnB;AACA,eAAS;AAAA,IACX,WAAW,QAAQ,cAAc;AAC/B,cAAQ,QAAQ;AAAA,IAClB,WAAW,QAAQ,QAAQ,QAAQ,aAAa;AAC9C,cAAQ,UAAU;AAAA,IACpB,WAAW,QAAQ,UAAU;AAC3B,cAAQ,OAAO;AAAA,IACjB,OAAO;AACL,gBAAU,KAAK,GAAG;AAAA,IACpB;AACA,aAAS;AAAA,EACX;AACA,SAAO,EAAE,SAAS,SAAS,UAAU;AACvC;AAEA,eAAe,OAAsB;AACnC,QAAM,EAAE,SAAS,QAAQ,IAAI,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5D,MAAI,QAAQ,YAAY,QAAQ,YAAY,WAAW;AACrD,YAAQ,IAAI,uBAAuB,OAAO,EAAE;AAC5C;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,MAAM;AACzB,cAAU;AACV;AAAA,EACF;AACA,QAAM,gBAAgB,OAAO;AAC/B;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAQ,KAAK,CAAC;AAChB,CAAC;",
6
+ "names": ["dirname", "resolve", "digest", "resolve", "dirname", "dirname", "isPlainObject", "isPlainObject", "isPlainObject", "isPlainObject", "isPlainObject", "supported", "isPlainObject", "id", "errorEvent", "block", "isPlainObject", "decodeChatReasoning", "decodeResponsesReasoning", "isPlainObject", "isPlainObject", "isPlainObject", "choice", "isPlainObject", "emptyBlock", "asError", "asError", "isPlainObject", "delivered", "isPlainObject", "readBody", "resolve", "handleCompletion", "createServer", "randomBytes", "timingSafeEqual", "randomBytes", "timingSafeEqual", "randomBytes", "randomBytes", "isPlainObject", "randomBytes", "readJSON", "isPlainObject", "constantTimeEquals", "readJSON", "isPlainObject", "randomBytes", "constantTimeEquals", "timingSafeEqual", "createServer", "resolve", "parseListen"]
7
+ }