@kolisachint/hoocode-agent 0.4.73 → 0.4.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli/args.d.ts.map +1 -1
  3. package/dist/cli/args.js +1 -1
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/core/model-registry.d.ts.map +1 -1
  6. package/dist/core/model-registry.js +0 -1
  7. package/dist/core/model-registry.js.map +1 -1
  8. package/dist/core/routing/local-inference.d.ts +14 -15
  9. package/dist/core/routing/local-inference.d.ts.map +1 -1
  10. package/dist/core/routing/local-inference.js +6 -15
  11. package/dist/core/routing/local-inference.js.map +1 -1
  12. package/dist/core/subagent-pool-instance.d.ts.map +1 -1
  13. package/dist/core/subagent-pool-instance.js +27 -0
  14. package/dist/core/subagent-pool-instance.js.map +1 -1
  15. package/dist/core/subagent-pool.d.ts +26 -0
  16. package/dist/core/subagent-pool.d.ts.map +1 -1
  17. package/dist/core/subagent-pool.js +65 -18
  18. package/dist/core/subagent-pool.js.map +1 -1
  19. package/dist/core/system-prompt.d.ts.map +1 -1
  20. package/dist/core/system-prompt.js +4 -0
  21. package/dist/core/system-prompt.js.map +1 -1
  22. package/dist/core/task-store.d.ts +7 -0
  23. package/dist/core/task-store.d.ts.map +1 -1
  24. package/dist/core/task-store.js +3 -0
  25. package/dist/core/task-store.js.map +1 -1
  26. package/dist/modes/interactive/components/task-panel.d.ts.map +1 -1
  27. package/dist/modes/interactive/components/task-panel.js +4 -1
  28. package/dist/modes/interactive/components/task-panel.js.map +1 -1
  29. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  30. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  31. package/examples/extensions/sandbox/package.json +1 -1
  32. package/examples/extensions/with-deps/package.json +1 -1
  33. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model registry - manages built-in and custom models, provides API key resolution.\n */\n\nimport {\n\ttype AnthropicMessagesCompat,\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OAuthProviderInterface,\n\ttype OpenAICompletionsCompat,\n\ttype OpenAIResponsesCompat,\n\tregisterApiProvider,\n\tresetApiProviders,\n\ttype SimpleStreamOptions,\n} from \"@kolisachint/hoocode-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@kolisachint/hoocode-ai/oauth\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStatus, AuthStorage } from \"./auth-storage.js\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"./provider-display-names.js\";\nimport {\n\tclearConfigValueCache,\n\tresolveConfigValueOrThrow,\n\tresolveConfigValueUncached,\n\tresolveHeadersOrThrow,\n} from \"./resolve-config-value.js\";\nimport type { RoutingConfig } from \"./routing/local-inference.js\";\n\n// Schema for OpenRouter routing preferences\nconst PercentileCutoffsSchema = Type.Object({\n\tp50: Type.Optional(Type.Number()),\n\tp75: Type.Optional(Type.Number()),\n\tp90: Type.Optional(Type.Number()),\n\tp99: Type.Optional(Type.Number()),\n});\n\nconst OpenRouterRoutingSchema = Type.Object({\n\tallow_fallbacks: Type.Optional(Type.Boolean()),\n\trequire_parameters: Type.Optional(Type.Boolean()),\n\tdata_collection: Type.Optional(Type.Union([Type.Literal(\"deny\"), Type.Literal(\"allow\")])),\n\tzdr: Type.Optional(Type.Boolean()),\n\tenforce_distillable_text: Type.Optional(Type.Boolean()),\n\torder: Type.Optional(Type.Array(Type.String())),\n\tonly: Type.Optional(Type.Array(Type.String())),\n\tignore: Type.Optional(Type.Array(Type.String())),\n\tquantizations: Type.Optional(Type.Array(Type.String())),\n\tsort: Type.Optional(\n\t\tType.Union([\n\t\t\tType.String(),\n\t\t\tType.Object({\n\t\t\t\tby: Type.Optional(Type.String()),\n\t\t\t\tpartition: Type.Optional(Type.Union([Type.String(), Type.Null()])),\n\t\t\t}),\n\t\t]),\n\t),\n\tmax_price: Type.Optional(\n\t\tType.Object({\n\t\t\tprompt: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\tcompletion: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\timage: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\taudio: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\trequest: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t}),\n\t),\n\tpreferred_min_throughput: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n\tpreferred_max_latency: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n});\n\n// Schema for Vercel AI Gateway routing preferences\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for thinking level support and provider-specific values\nconst ThinkingLevelMapValueSchema = Type.Union([Type.String(), Type.Null()]);\nconst ThinkingLevelMapSchema = Type.Object({\n\toff: Type.Optional(ThinkingLevelMapValueSchema),\n\tminimal: Type.Optional(ThinkingLevelMapValueSchema),\n\tlow: Type.Optional(ThinkingLevelMapValueSchema),\n\tmedium: Type.Optional(ThinkingLevelMapValueSchema),\n\thigh: Type.Optional(ThinkingLevelMapValueSchema),\n\txhigh: Type.Optional(ThinkingLevelMapValueSchema),\n});\n\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresReasoningContentOnAssistantMessages: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"openai\"),\n\t\t\tType.Literal(\"openrouter\"),\n\t\t\tType.Literal(\"together\"),\n\t\t\tType.Literal(\"deepseek\"),\n\t\t\tType.Literal(\"zai\"),\n\t\t\tType.Literal(\"qwen\"),\n\t\t\tType.Literal(\"qwen-chat-template\"),\n\t\t]),\n\t),\n\tcacheControlFormat: Type.Optional(Type.Literal(\"anthropic\")),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tpromptSuffix: Type.Optional(Type.String()),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\tsendSessionIdHeader: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst AnthropicMessagesCompatSchema = Type.Object({\n\tsupportsEagerToolInputStreaming: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst ProviderCompatSchema = Type.Union([\n\tOpenAICompletionsCompatSchema,\n\tOpenAIResponsesCompatSchema,\n\tAnthropicMessagesCompatSchema,\n]);\n\n// Schema for custom model definition\n// Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Number(),\n\t\t\toutput: Type.Number(),\n\t\t\tcacheRead: Type.Number(),\n\t\t\tcacheWrite: Type.Number(),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\n// Schema for per-model overrides (all fields optional, merged with built-in model)\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ExecutorServerConfigSchema = Type.Object({\n\tcommand: Type.Optional(Type.String({ minLength: 1 })),\n\targs: Type.Optional(Type.Array(Type.String())),\n\thost: Type.Optional(Type.String({ minLength: 1 })),\n\tport: Type.Optional(Type.Number()),\n\tstartupTimeoutMs: Type.Optional(Type.Number()),\n});\n\nconst ExecutorConfigSchema = Type.Object({\n\tprovider: Type.String({ minLength: 1 }),\n\tmodel: Type.String({ minLength: 1 }),\n\tminBytes: Type.Optional(Type.Number()),\n\tmaxBytes: Type.Optional(Type.Number()),\n\tserver: Type.Optional(ExecutorServerConfigSchema),\n});\n\nconst RoutingConfigSchema = Type.Object({\n\tmode: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"primary-only\"),\n\t\t\tType.Literal(\"executor-for-summarization\"),\n\t\t\tType.Literal(\"executor-for-tool-results\"),\n\t\t\tType.Literal(\"shadow-executor\"),\n\t\t]),\n\t),\n\texecutor: Type.Optional(ExecutorConfigSchema),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n\trouting: Type.Optional(RoutingConfigSchema),\n});\n\nconst validateModelsConfig = Compile(ModelsConfigSchema);\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\n/** Strip `//` line comments and trailing commas from JSON, leaving string literals untouched. */\nfunction stripJsonComments(input: string): string {\n\treturn input\n\t\t.replace(/\"(?:\\\\.|[^\"\\\\])*\"|\\/\\/[^\\n]*/g, (m) => (m[0] === '\"' ? m : \"\"))\n\t\t.replace(/\"(?:\\\\.|[^\"\\\\])*\"|,(\\s*[}\\]])/g, (m, tail) => tail ?? (m[0] === '\"' ? m : \"\"));\n}\n\n/** Provider override config (baseUrl, compat) without request auth/headers */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\tcompat?: Model<Api>[\"compat\"];\n}\n\ninterface ProviderRequestConfig {\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n}\n\nexport type ResolvedRequestAuth =\n\t| {\n\t\t\tok: true;\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t }\n\t| {\n\t\t\tok: false;\n\t\t\terror: string;\n\t };\n\n/** Result of loading custom models from models.json */\ninterface CustomModelsResult {\n\tmodels: Model<Api>[];\n\t/** Providers with baseUrl/headers/apiKey overrides for built-in models */\n\toverrides: Map<string, ProviderOverride>;\n\t/** Per-model overrides: provider -> modelId -> override */\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>;\n\terror: string | undefined;\n}\n\nfunction emptyCustomModelsResult(error?: string): CustomModelsResult {\n\treturn { models: [], overrides: new Map(), modelOverrides: new Map(), error };\n}\n\nfunction mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\n/**\n * Deep merge a model override into a model.\n * Handles nested objects (cost, compat) by merging rather than replacing.\n */\nfunction applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\t// Simple field overrides\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\t// Merge cost (partial override)\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\n/** Clear the config value command cache. Exported for testing. */\nexport const clearApiKeyCache = clearConfigValueCache;\n\n/**\n * Model registry - loads and manages models, resolves API keys via AuthStorage.\n */\nexport class ModelRegistry {\n\tprivate models: Model<Api>[] = [];\n\tprivate providerRequestConfigs: Map<string, ProviderRequestConfig> = new Map();\n\tprivate modelRequestHeaders: Map<string, Record<string, string>> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\tprivate routingConfig: RoutingConfig | undefined = undefined;\n\n\tprivate constructor(\n\t\treadonly authStorage: AuthStorage,\n\t\tprivate modelsJsonPath: string | undefined,\n\t) {\n\t\tthis.loadModels();\n\t}\n\n\tstatic create(authStorage: AuthStorage, modelsJsonPath: string = join(getAgentDir(), \"models.json\")): ModelRegistry {\n\t\treturn new ModelRegistry(authStorage, modelsJsonPath);\n\t}\n\n\tstatic inMemory(authStorage: AuthStorage): ModelRegistry {\n\t\treturn new ModelRegistry(authStorage, undefined);\n\t}\n\n\t/**\n\t * Reload models from disk (built-in + custom from models.json).\n\t */\n\trefresh(): void {\n\t\tthis.providerRequestConfigs.clear();\n\t\tthis.modelRequestHeaders.clear();\n\t\tthis.loadError = undefined;\n\n\t\t// Ensure dynamic API/OAuth registrations are rebuilt from current provider state.\n\t\tresetApiProviders();\n\t\tresetOAuthProviders();\n\n\t\tthis.loadModels();\n\n\t\tfor (const [providerName, config] of this.registeredProviders.entries()) {\n\t\t\tthis.applyProviderConfig(providerName, config);\n\t\t}\n\t}\n\n\t/**\n\t * Get any error from loading models.json (undefined if no error).\n\t */\n\tgetError(): string | undefined {\n\t\treturn this.loadError;\n\t}\n\n\tprivate loadModels(): void {\n\t\tthis.routingConfig = undefined;\n\t\t// Load custom models and overrides from models.json\n\t\tconst {\n\t\t\tmodels: customModels,\n\t\t\toverrides,\n\t\t\tmodelOverrides,\n\t\t\terror,\n\t\t} = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();\n\n\t\tif (error) {\n\t\t\tthis.loadError = error;\n\t\t\t// Keep built-in models even if custom models failed to load\n\t\t}\n\n\t\tconst builtInModels = this.loadBuiltInModels(overrides, modelOverrides);\n\t\tlet combined = this.mergeCustomModels(builtInModels, customModels);\n\n\t\t// Let OAuth providers modify their models (e.g., update baseUrl)\n\t\tfor (const oauthProvider of this.authStorage.getOAuthProviders()) {\n\t\t\tconst cred = this.authStorage.get(oauthProvider.id);\n\t\t\tif (cred?.type === \"oauth\" && oauthProvider.modifyModels) {\n\t\t\t\tcombined = oauthProvider.modifyModels(combined, cred);\n\t\t\t}\n\t\t}\n\n\t\tthis.models = combined;\n\t}\n\n\t/** Load built-in models and apply provider/model overrides */\n\tprivate loadBuiltInModels(\n\t\toverrides: Map<string, ProviderOverride>,\n\t\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n\t): Model<Api>[] {\n\t\treturn getProviders().flatMap((provider) => {\n\t\t\tconst models = getModels(provider as KnownProvider) as Model<Api>[];\n\t\t\tconst providerOverride = overrides.get(provider);\n\t\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\t\treturn models.map((m) => {\n\t\t\t\tlet model = m;\n\n\t\t\t\t// Apply provider-level baseUrl/headers/compat override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tmodel = {\n\t\t\t\t\t\t...model,\n\t\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Apply per-model override\n\t\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\t\tif (modelOverride) {\n\t\t\t\t\tmodel = applyModelOverride(model, modelOverride);\n\t\t\t\t}\n\n\t\t\t\treturn model;\n\t\t\t});\n\t\t});\n\t}\n\n\t/** Merge custom models into built-in list by provider+id (custom wins on conflicts). */\n\tprivate mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\t\tconst merged = [...builtInModels];\n\t\tfor (const customModel of customModels) {\n\t\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tmerged[existingIndex] = customModel;\n\t\t\t} else {\n\t\t\t\tmerged.push(customModel);\n\t\t\t}\n\t\t}\n\t\treturn merged;\n\t}\n\n\tprivate loadCustomModels(modelsJsonPath: string): CustomModelsResult {\n\t\tif (!existsSync(modelsJsonPath)) {\n\t\t\treturn emptyCustomModelsResult();\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(modelsJsonPath, \"utf-8\");\n\t\t\tconst parsed = JSON.parse(stripJsonComments(content)) as unknown;\n\n\t\t\tif (!validateModelsConfig.Check(parsed)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidateModelsConfig\n\t\t\t\t\t\t.Errors(parsed)\n\t\t\t\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t\t\t\t.join(\"\\n\") || \"Unknown schema error\";\n\t\t\t\treturn emptyCustomModelsResult(`Invalid models.json schema:\\n${errors}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\n\t\t\tconst config = parsed as ModelsConfig;\n\n\t\t\t// Additional validation\n\t\t\tthis.validateConfig(config);\n\n\t\t\tthis.routingConfig = config.routing as RoutingConfig | undefined;\n\n\t\t\tconst overrides = new Map<string, ProviderOverride>();\n\t\t\tconst modelOverrides = new Map<string, Map<string, ModelOverride>>();\n\n\t\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.compat) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\tcompat: providerConfig.compat,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.storeProviderRequestConfig(providerName, providerConfig);\n\n\t\t\t\tif (providerConfig.modelOverrides) {\n\t\t\t\t\tmodelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));\n\t\t\t\t\tfor (const [modelId, modelOverride] of Object.entries(providerConfig.modelOverrides)) {\n\t\t\t\t\t\tthis.storeModelHeaders(providerName, modelId, modelOverride.headers);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { models: this.parseModels(config), overrides, modelOverrides, error: undefined };\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\treturn emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\t\t\treturn emptyCustomModelsResult(\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${modelsJsonPath}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate validateConfig(config: ModelsConfig): void {\n\t\tconst builtInProviders = new Set<string>(getProviders());\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst isBuiltIn = builtInProviders.has(providerName);\n\t\t\tconst hasProviderApi = !!providerConfig.api;\n\t\t\tconst models = providerConfig.models ?? [];\n\t\t\tconst hasModelOverrides =\n\t\t\t\tproviderConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;\n\n\t\t\tif (models.length === 0) {\n\t\t\t\t// Override-only config: needs baseUrl, headers, compat, modelOverrides, or some combination.\n\t\t\t\tif (!providerConfig.baseUrl && !providerConfig.headers && !providerConfig.compat && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}: must specify \"baseUrl\", \"headers\", \"compat\", \"modelOverrides\", or \"models\".`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (!isBuiltIn) {\n\t\t\t\t// Non-built-in providers with custom models require endpoint + auth.\n\t\t\t\tif (!providerConfig.baseUrl) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t\tif (!providerConfig.apiKey) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Built-in providers with custom models: baseUrl/apiKey/api are optional,\n\t\t\t// inherited from built-in models. Auth comes from env vars / auth storage.\n\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi && !isBuiltIn) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified. Set at provider or model level.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// For built-in providers, api is optional — inherited from built-in models.\n\n\t\t\t\tif (!modelDef.id) throw new Error(`Provider ${providerName}: model missing \"id\"`);\n\t\t\t\t// Validate contextWindow/maxTokens only if provided (they have defaults)\n\t\t\t\tif (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);\n\t\t\t\tif (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate parseModels(config: ModelsConfig): Model<Api>[] {\n\t\tconst models: Model<Api>[] = [];\n\t\tconst builtInProviders = new Set<string>(getProviders());\n\n\t\t// Cache built-in defaults (api, baseUrl) per provider, extracted from first model.\n\t\tconst builtInDefaultsCache = new Map<string, { api: string; baseUrl: string }>();\n\t\tconst getBuiltInDefaults = (providerName: string): { api: string; baseUrl: string } | undefined => {\n\t\t\tif (!builtInProviders.has(providerName)) return undefined;\n\t\t\tif (builtInDefaultsCache.has(providerName)) return builtInDefaultsCache.get(providerName);\n\t\t\tconst builtIn = getModels(providerName as KnownProvider) as Model<Api>[];\n\t\t\tif (builtIn.length === 0) return undefined;\n\t\t\tconst defaults = { api: builtIn[0].api, baseUrl: builtIn[0].baseUrl };\n\t\t\tbuiltInDefaultsCache.set(providerName, defaults);\n\t\t\treturn defaults;\n\t\t};\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst modelDefs = providerConfig.models ?? [];\n\t\t\tif (modelDefs.length === 0) continue; // Override-only, no custom models\n\n\t\t\tconst builtInDefaults = getBuiltInDefaults(providerName);\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api ?? providerConfig.api ?? builtInDefaults?.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\tconst baseUrl = modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl;\n\t\t\t\tif (!baseUrl) continue;\n\n\t\t\t\tconst compat = mergeCompat(providerConfig.compat, modelDef.compat);\n\t\t\t\tthis.storeModelHeaders(providerName, modelDef.id, modelDef.headers);\n\n\t\t\t\tconst defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\t\t\t\tmodels.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name ?? modelDef.id,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\n\t\t\t\t\tthinkingLevelMap: modelDef.thinkingLevelMap,\n\t\t\t\t\tinput: (modelDef.input ?? [\"text\"]) as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost ?? defaultCost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens ?? 16384,\n\t\t\t\t\theaders: undefined,\n\t\t\t\t\tcompat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\n\t\treturn models;\n\t}\n\n\t/**\n\t * Get all models (built-in + custom).\n\t * If models.json had errors, returns only built-in models.\n\t */\n\tgetAll(): Model<Api>[] {\n\t\treturn this.models;\n\t}\n\n\t/**\n\t * Get only models that have auth configured.\n\t * This is a fast check that doesn't refresh OAuth tokens.\n\t */\n\tgetAvailable(): Model<Api>[] {\n\t\treturn this.models.filter((m) => this.hasConfiguredAuth(m));\n\t}\n\n\t/**\n\t * Find a model by provider and ID.\n\t */\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.find((m) => m.provider === provider && m.id === modelId);\n\t}\n\n\t/**\n\t * Local-inference routing config from models.json (`routing` block), if any.\n\t */\n\tgetRoutingConfig(): RoutingConfig | undefined {\n\t\treturn this.routingConfig;\n\t}\n\n\t/**\n\t * Get API key for a model.\n\t */\n\thasConfiguredAuth(model: Model<Api>): boolean {\n\t\treturn (\n\t\t\tthis.authStorage.hasAuth(model.provider) ||\n\t\t\tthis.providerRequestConfigs.get(model.provider)?.apiKey !== undefined\n\t\t);\n\t}\n\n\tprivate getModelRequestKey(provider: string, modelId: string): string {\n\t\treturn `${provider}:${modelId}`;\n\t}\n\n\tprivate storeProviderRequestConfig(\n\t\tproviderName: string,\n\t\tconfig: {\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t\t\tauthHeader?: boolean;\n\t\t},\n\t): void {\n\t\tif (!config.apiKey && !config.headers && !config.authHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.providerRequestConfigs.set(providerName, {\n\t\t\tapiKey: config.apiKey,\n\t\t\theaders: config.headers,\n\t\t\tauthHeader: config.authHeader,\n\t\t});\n\t}\n\n\tprivate storeModelHeaders(providerName: string, modelId: string, headers?: Record<string, string>): void {\n\t\tconst key = this.getModelRequestKey(providerName, modelId);\n\t\tif (!headers || Object.keys(headers).length === 0) {\n\t\t\tthis.modelRequestHeaders.delete(key);\n\t\t\treturn;\n\t\t}\n\t\tthis.modelRequestHeaders.set(key, headers);\n\t}\n\n\t/**\n\t * Get API key and request headers for a model.\n\t */\n\tasync getApiKeyAndHeaders(model: Model<Api>): Promise<ResolvedRequestAuth> {\n\t\ttry {\n\t\t\tconst providerConfig = this.providerRequestConfigs.get(model.provider);\n\t\t\tconst apiKeyFromAuthStorage = await this.authStorage.getApiKey(model.provider, { includeFallback: false });\n\t\t\tconst apiKey =\n\t\t\t\tapiKeyFromAuthStorage ??\n\t\t\t\t(providerConfig?.apiKey\n\t\t\t\t\t? resolveConfigValueOrThrow(providerConfig.apiKey, `API key for provider \"${model.provider}\"`)\n\t\t\t\t\t: undefined);\n\n\t\t\tconst providerHeaders = resolveHeadersOrThrow(providerConfig?.headers, `provider \"${model.provider}\"`);\n\t\t\tconst modelHeaders = resolveHeadersOrThrow(\n\t\t\t\tthis.modelRequestHeaders.get(this.getModelRequestKey(model.provider, model.id)),\n\t\t\t\t`model \"${model.provider}/${model.id}\"`,\n\t\t\t);\n\n\t\t\tlet headers =\n\t\t\t\tmodel.headers || providerHeaders || modelHeaders\n\t\t\t\t\t? { ...model.headers, ...providerHeaders, ...modelHeaders }\n\t\t\t\t\t: undefined;\n\n\t\t\tif (providerConfig?.authHeader) {\n\t\t\t\tif (!apiKey) {\n\t\t\t\t\treturn { ok: false, error: `No API key found for \"${model.provider}\"` };\n\t\t\t\t}\n\t\t\t\theaders = { ...headers, Authorization: `Bearer ${apiKey}` };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tapiKey,\n\t\t\t\theaders: headers && Object.keys(headers).length > 0 ? headers : undefined,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Return auth status for a provider, including request auth configured in models.json.\n\t * This intentionally does not execute command-backed config values.\n\t */\n\tgetProviderAuthStatus(provider: string): AuthStatus {\n\t\tconst authStatus = this.authStorage.getAuthStatus(provider);\n\t\tif (authStatus.source) {\n\t\t\treturn authStatus;\n\t\t}\n\n\t\tconst providerApiKey = this.providerRequestConfigs.get(provider)?.apiKey;\n\t\tif (!providerApiKey) {\n\t\t\treturn authStatus;\n\t\t}\n\n\t\tif (providerApiKey.startsWith(\"!\")) {\n\t\t\treturn { configured: true, source: \"models_json_command\" };\n\t\t}\n\n\t\tif (process.env[providerApiKey]) {\n\t\t\treturn { configured: true, source: \"environment\", label: providerApiKey };\n\t\t}\n\n\t\treturn { configured: true, source: \"models_json_key\" };\n\t}\n\n\t/**\n\t * Get display name for a provider.\n\t */\n\tgetProviderDisplayName(provider: string): string {\n\t\tconst registeredProvider = this.registeredProviders.get(provider);\n\t\tconst oauthProvider = this.authStorage.getOAuthProviders().find((p) => p.id === provider);\n\n\t\treturn (\n\t\t\tregisteredProvider?.name ??\n\t\t\tregisteredProvider?.oauth?.name ??\n\t\t\toauthProvider?.name ??\n\t\t\tBUILT_IN_PROVIDER_DISPLAY_NAMES[provider] ??\n\t\t\tprovider\n\t\t);\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t */\n\tasync getApiKeyForProvider(provider: string): Promise<string | undefined> {\n\t\tconst apiKey = await this.authStorage.getApiKey(provider, { includeFallback: false });\n\t\tif (apiKey !== undefined) {\n\t\t\treturn apiKey;\n\t\t}\n\n\t\tconst providerApiKey = this.providerRequestConfigs.get(provider)?.apiKey;\n\t\treturn providerApiKey ? resolveConfigValueUncached(providerApiKey) : undefined;\n\t}\n\n\t/**\n\t * Check if a model is using OAuth credentials (subscription).\n\t */\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\tconst cred = this.authStorage.get(model.provider);\n\t\treturn cred?.type === \"oauth\";\n\t}\n\n\t/**\n\t * Register a provider dynamically (from extensions).\n\t *\n\t * If provider has models: replaces all existing models for this provider.\n\t * If provider has only baseUrl/headers: overrides existing models' URLs.\n\t * If provider has oauth: registers OAuth provider for /login support.\n\t */\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.validateProviderConfig(providerName, config);\n\t\tthis.applyProviderConfig(providerName, config);\n\t\tthis.upsertRegisteredProvider(providerName, config);\n\t}\n\n\t/**\n\t * Unregister a previously registered provider.\n\t *\n\t * Removes the provider from the registry and reloads models from disk so that\n\t * built-in models overridden by this provider are restored to their original state.\n\t * Also resets dynamic OAuth and API stream registrations before reapplying\n\t * remaining dynamic providers.\n\t * Has no effect if the provider was never registered.\n\t */\n\tunregisterProvider(providerName: string): void {\n\t\tif (!this.registeredProviders.has(providerName)) return;\n\t\tthis.registeredProviders.delete(providerName);\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Upsert a provider config into registeredProviders.\n\t * If the provider is already registered, defined values in the incoming config\n\t * override existing ones; undefined values are preserved from the stored config.\n\t * If the provider is not registered, the incoming config is stored as-is.\n\t */\n\tprivate upsertRegisteredProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tconst existing = this.registeredProviders.get(providerName);\n\t\tif (!existing) {\n\t\t\tthis.registeredProviders.set(providerName, config);\n\t\t\treturn;\n\t\t}\n\t\tfor (const k of Object.keys(config) as (keyof ProviderConfigInput)[]) {\n\t\t\tif (config[k] !== undefined) {\n\t\t\t\t(existing as Record<string, unknown>)[k] = config[k];\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\tif (config.streamSimple && !config.api) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t}\n\n\t\tif (!config.models || config.models.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!config.baseUrl) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t}\n\t\tif (!config.apiKey && !config.oauth) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when defining models.`);\n\t\t}\n\n\t\tfor (const modelDef of config.models) {\n\t\t\tconst api = modelDef.api || config.api;\n\t\t\tif (!api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate applyProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\t// Register OAuth provider if provided\n\t\tif (config.oauth) {\n\t\t\t// Ensure the OAuth provider ID matches the provider name\n\t\t\tconst oauthProvider: OAuthProviderInterface = {\n\t\t\t\t...config.oauth,\n\t\t\t\tid: providerName,\n\t\t\t};\n\t\t\tregisterOAuthProvider(oauthProvider);\n\t\t}\n\n\t\tif (config.streamSimple) {\n\t\t\tconst streamSimple = config.streamSimple;\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api!,\n\t\t\t\t\tstream: (model, context, options) => streamSimple(model, context, options as SimpleStreamOptions),\n\t\t\t\t\tstreamSimple,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.storeProviderRequestConfig(providerName, config);\n\n\t\tif (config.models && config.models.length > 0) {\n\t\t\t// Full replacement: remove existing models for this provider\n\t\t\tthis.models = this.models.filter((m) => m.provider !== providerName);\n\n\t\t\t// Parse and add new models\n\t\t\tfor (const modelDef of config.models) {\n\t\t\t\tconst api = modelDef.api || config.api;\n\t\t\t\tthis.storeModelHeaders(providerName, modelDef.id, modelDef.headers);\n\n\t\t\t\tthis.models.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: modelDef.baseUrl ?? config.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning,\n\t\t\t\t\tthinkingLevelMap: modelDef.thinkingLevelMap,\n\t\t\t\t\tinput: modelDef.input as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens,\n\t\t\t\t\theaders: undefined,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\n\t\t\t// Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)\n\t\t\tif (config.oauth?.modifyModels) {\n\t\t\t\tconst cred = this.authStorage.get(providerName);\n\t\t\t\tif (cred?.type === \"oauth\") {\n\t\t\t\t\tthis.models = config.oauth.modifyModels(this.models, cred);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (config.baseUrl || config.headers) {\n\t\t\t// Override-only: update baseUrl for existing models. Request headers are resolved per request.\n\t\t\tthis.models = this.models.map((m) => {\n\t\t\t\tif (m.provider !== providerName) return m;\n\t\t\t\treturn {\n\t\t\t\t\t...m,\n\t\t\t\t\tbaseUrl: config.baseUrl ?? m.baseUrl,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tname?: string;\n\tbaseUrl?: string;\n\tapiKey?: string;\n\tapi?: Api;\n\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n\t/** OAuth provider for /login support */\n\toauth?: Omit<OAuthProviderInterface, \"id\">;\n\tmodels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tapi?: Api;\n\t\tbaseUrl?: string;\n\t\treasoning: boolean;\n\t\tthinkingLevelMap?: Model<Api>[\"thinkingLevelMap\"];\n\t\tinput: (\"text\" | \"image\")[];\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\t\tcontextWindow: number;\n\t\tmaxTokens: number;\n\t\theaders?: Record<string, string>;\n\t\tcompat?: Model<Api>[\"compat\"];\n\t}>;\n}\n"]}
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model registry - manages built-in and custom models, provides API key resolution.\n */\n\nimport {\n\ttype AnthropicMessagesCompat,\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OAuthProviderInterface,\n\ttype OpenAICompletionsCompat,\n\ttype OpenAIResponsesCompat,\n\tregisterApiProvider,\n\tresetApiProviders,\n\ttype SimpleStreamOptions,\n} from \"@kolisachint/hoocode-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@kolisachint/hoocode-ai/oauth\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStatus, AuthStorage } from \"./auth-storage.js\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"./provider-display-names.js\";\nimport {\n\tclearConfigValueCache,\n\tresolveConfigValueOrThrow,\n\tresolveConfigValueUncached,\n\tresolveHeadersOrThrow,\n} from \"./resolve-config-value.js\";\nimport type { RoutingConfig } from \"./routing/local-inference.js\";\n\n// Schema for OpenRouter routing preferences\nconst PercentileCutoffsSchema = Type.Object({\n\tp50: Type.Optional(Type.Number()),\n\tp75: Type.Optional(Type.Number()),\n\tp90: Type.Optional(Type.Number()),\n\tp99: Type.Optional(Type.Number()),\n});\n\nconst OpenRouterRoutingSchema = Type.Object({\n\tallow_fallbacks: Type.Optional(Type.Boolean()),\n\trequire_parameters: Type.Optional(Type.Boolean()),\n\tdata_collection: Type.Optional(Type.Union([Type.Literal(\"deny\"), Type.Literal(\"allow\")])),\n\tzdr: Type.Optional(Type.Boolean()),\n\tenforce_distillable_text: Type.Optional(Type.Boolean()),\n\torder: Type.Optional(Type.Array(Type.String())),\n\tonly: Type.Optional(Type.Array(Type.String())),\n\tignore: Type.Optional(Type.Array(Type.String())),\n\tquantizations: Type.Optional(Type.Array(Type.String())),\n\tsort: Type.Optional(\n\t\tType.Union([\n\t\t\tType.String(),\n\t\t\tType.Object({\n\t\t\t\tby: Type.Optional(Type.String()),\n\t\t\t\tpartition: Type.Optional(Type.Union([Type.String(), Type.Null()])),\n\t\t\t}),\n\t\t]),\n\t),\n\tmax_price: Type.Optional(\n\t\tType.Object({\n\t\t\tprompt: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\tcompletion: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\timage: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\taudio: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\trequest: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t}),\n\t),\n\tpreferred_min_throughput: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n\tpreferred_max_latency: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n});\n\n// Schema for Vercel AI Gateway routing preferences\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for thinking level support and provider-specific values\nconst ThinkingLevelMapValueSchema = Type.Union([Type.String(), Type.Null()]);\nconst ThinkingLevelMapSchema = Type.Object({\n\toff: Type.Optional(ThinkingLevelMapValueSchema),\n\tminimal: Type.Optional(ThinkingLevelMapValueSchema),\n\tlow: Type.Optional(ThinkingLevelMapValueSchema),\n\tmedium: Type.Optional(ThinkingLevelMapValueSchema),\n\thigh: Type.Optional(ThinkingLevelMapValueSchema),\n\txhigh: Type.Optional(ThinkingLevelMapValueSchema),\n});\n\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresReasoningContentOnAssistantMessages: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"openai\"),\n\t\t\tType.Literal(\"openrouter\"),\n\t\t\tType.Literal(\"together\"),\n\t\t\tType.Literal(\"deepseek\"),\n\t\t\tType.Literal(\"zai\"),\n\t\t\tType.Literal(\"qwen\"),\n\t\t\tType.Literal(\"qwen-chat-template\"),\n\t\t]),\n\t),\n\tcacheControlFormat: Type.Optional(Type.Literal(\"anthropic\")),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tpromptSuffix: Type.Optional(Type.String()),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\tsendSessionIdHeader: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst AnthropicMessagesCompatSchema = Type.Object({\n\tsupportsEagerToolInputStreaming: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst ProviderCompatSchema = Type.Union([\n\tOpenAICompletionsCompatSchema,\n\tOpenAIResponsesCompatSchema,\n\tAnthropicMessagesCompatSchema,\n]);\n\n// Schema for custom model definition\n// Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Number(),\n\t\t\toutput: Type.Number(),\n\t\t\tcacheRead: Type.Number(),\n\t\t\tcacheWrite: Type.Number(),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\n// Schema for per-model overrides (all fields optional, merged with built-in model)\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ExecutorServerConfigSchema = Type.Object({\n\tcommand: Type.Optional(Type.String({ minLength: 1 })),\n\targs: Type.Optional(Type.Array(Type.String())),\n\thost: Type.Optional(Type.String({ minLength: 1 })),\n\tport: Type.Optional(Type.Number()),\n\tstartupTimeoutMs: Type.Optional(Type.Number()),\n});\n\nconst ExecutorConfigSchema = Type.Object({\n\tprovider: Type.String({ minLength: 1 }),\n\tmodel: Type.String({ minLength: 1 }),\n\tminBytes: Type.Optional(Type.Number()),\n\tmaxBytes: Type.Optional(Type.Number()),\n\tserver: Type.Optional(ExecutorServerConfigSchema),\n});\n\nconst RoutingConfigSchema = Type.Object({\n\tmode: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"primary-only\"),\n\t\t\tType.Literal(\"executor-for-summarization\"),\n\t\t\tType.Literal(\"executor-for-tool-results\"),\n\t\t]),\n\t),\n\texecutor: Type.Optional(ExecutorConfigSchema),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n\trouting: Type.Optional(RoutingConfigSchema),\n});\n\nconst validateModelsConfig = Compile(ModelsConfigSchema);\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\n/** Strip `//` line comments and trailing commas from JSON, leaving string literals untouched. */\nfunction stripJsonComments(input: string): string {\n\treturn input\n\t\t.replace(/\"(?:\\\\.|[^\"\\\\])*\"|\\/\\/[^\\n]*/g, (m) => (m[0] === '\"' ? m : \"\"))\n\t\t.replace(/\"(?:\\\\.|[^\"\\\\])*\"|,(\\s*[}\\]])/g, (m, tail) => tail ?? (m[0] === '\"' ? m : \"\"));\n}\n\n/** Provider override config (baseUrl, compat) without request auth/headers */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\tcompat?: Model<Api>[\"compat\"];\n}\n\ninterface ProviderRequestConfig {\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n}\n\nexport type ResolvedRequestAuth =\n\t| {\n\t\t\tok: true;\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t }\n\t| {\n\t\t\tok: false;\n\t\t\terror: string;\n\t };\n\n/** Result of loading custom models from models.json */\ninterface CustomModelsResult {\n\tmodels: Model<Api>[];\n\t/** Providers with baseUrl/headers/apiKey overrides for built-in models */\n\toverrides: Map<string, ProviderOverride>;\n\t/** Per-model overrides: provider -> modelId -> override */\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>;\n\terror: string | undefined;\n}\n\nfunction emptyCustomModelsResult(error?: string): CustomModelsResult {\n\treturn { models: [], overrides: new Map(), modelOverrides: new Map(), error };\n}\n\nfunction mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat | AnthropicMessagesCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\n/**\n * Deep merge a model override into a model.\n * Handles nested objects (cost, compat) by merging rather than replacing.\n */\nfunction applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\t// Simple field overrides\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\t// Merge cost (partial override)\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\n/** Clear the config value command cache. Exported for testing. */\nexport const clearApiKeyCache = clearConfigValueCache;\n\n/**\n * Model registry - loads and manages models, resolves API keys via AuthStorage.\n */\nexport class ModelRegistry {\n\tprivate models: Model<Api>[] = [];\n\tprivate providerRequestConfigs: Map<string, ProviderRequestConfig> = new Map();\n\tprivate modelRequestHeaders: Map<string, Record<string, string>> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\tprivate routingConfig: RoutingConfig | undefined = undefined;\n\n\tprivate constructor(\n\t\treadonly authStorage: AuthStorage,\n\t\tprivate modelsJsonPath: string | undefined,\n\t) {\n\t\tthis.loadModels();\n\t}\n\n\tstatic create(authStorage: AuthStorage, modelsJsonPath: string = join(getAgentDir(), \"models.json\")): ModelRegistry {\n\t\treturn new ModelRegistry(authStorage, modelsJsonPath);\n\t}\n\n\tstatic inMemory(authStorage: AuthStorage): ModelRegistry {\n\t\treturn new ModelRegistry(authStorage, undefined);\n\t}\n\n\t/**\n\t * Reload models from disk (built-in + custom from models.json).\n\t */\n\trefresh(): void {\n\t\tthis.providerRequestConfigs.clear();\n\t\tthis.modelRequestHeaders.clear();\n\t\tthis.loadError = undefined;\n\n\t\t// Ensure dynamic API/OAuth registrations are rebuilt from current provider state.\n\t\tresetApiProviders();\n\t\tresetOAuthProviders();\n\n\t\tthis.loadModels();\n\n\t\tfor (const [providerName, config] of this.registeredProviders.entries()) {\n\t\t\tthis.applyProviderConfig(providerName, config);\n\t\t}\n\t}\n\n\t/**\n\t * Get any error from loading models.json (undefined if no error).\n\t */\n\tgetError(): string | undefined {\n\t\treturn this.loadError;\n\t}\n\n\tprivate loadModels(): void {\n\t\tthis.routingConfig = undefined;\n\t\t// Load custom models and overrides from models.json\n\t\tconst {\n\t\t\tmodels: customModels,\n\t\t\toverrides,\n\t\t\tmodelOverrides,\n\t\t\terror,\n\t\t} = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();\n\n\t\tif (error) {\n\t\t\tthis.loadError = error;\n\t\t\t// Keep built-in models even if custom models failed to load\n\t\t}\n\n\t\tconst builtInModels = this.loadBuiltInModels(overrides, modelOverrides);\n\t\tlet combined = this.mergeCustomModels(builtInModels, customModels);\n\n\t\t// Let OAuth providers modify their models (e.g., update baseUrl)\n\t\tfor (const oauthProvider of this.authStorage.getOAuthProviders()) {\n\t\t\tconst cred = this.authStorage.get(oauthProvider.id);\n\t\t\tif (cred?.type === \"oauth\" && oauthProvider.modifyModels) {\n\t\t\t\tcombined = oauthProvider.modifyModels(combined, cred);\n\t\t\t}\n\t\t}\n\n\t\tthis.models = combined;\n\t}\n\n\t/** Load built-in models and apply provider/model overrides */\n\tprivate loadBuiltInModels(\n\t\toverrides: Map<string, ProviderOverride>,\n\t\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n\t): Model<Api>[] {\n\t\treturn getProviders().flatMap((provider) => {\n\t\t\tconst models = getModels(provider as KnownProvider) as Model<Api>[];\n\t\t\tconst providerOverride = overrides.get(provider);\n\t\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\t\treturn models.map((m) => {\n\t\t\t\tlet model = m;\n\n\t\t\t\t// Apply provider-level baseUrl/headers/compat override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tmodel = {\n\t\t\t\t\t\t...model,\n\t\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Apply per-model override\n\t\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\t\tif (modelOverride) {\n\t\t\t\t\tmodel = applyModelOverride(model, modelOverride);\n\t\t\t\t}\n\n\t\t\t\treturn model;\n\t\t\t});\n\t\t});\n\t}\n\n\t/** Merge custom models into built-in list by provider+id (custom wins on conflicts). */\n\tprivate mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\t\tconst merged = [...builtInModels];\n\t\tfor (const customModel of customModels) {\n\t\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tmerged[existingIndex] = customModel;\n\t\t\t} else {\n\t\t\t\tmerged.push(customModel);\n\t\t\t}\n\t\t}\n\t\treturn merged;\n\t}\n\n\tprivate loadCustomModels(modelsJsonPath: string): CustomModelsResult {\n\t\tif (!existsSync(modelsJsonPath)) {\n\t\t\treturn emptyCustomModelsResult();\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(modelsJsonPath, \"utf-8\");\n\t\t\tconst parsed = JSON.parse(stripJsonComments(content)) as unknown;\n\n\t\t\tif (!validateModelsConfig.Check(parsed)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidateModelsConfig\n\t\t\t\t\t\t.Errors(parsed)\n\t\t\t\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t\t\t\t.join(\"\\n\") || \"Unknown schema error\";\n\t\t\t\treturn emptyCustomModelsResult(`Invalid models.json schema:\\n${errors}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\n\t\t\tconst config = parsed as ModelsConfig;\n\n\t\t\t// Additional validation\n\t\t\tthis.validateConfig(config);\n\n\t\t\tthis.routingConfig = config.routing as RoutingConfig | undefined;\n\n\t\t\tconst overrides = new Map<string, ProviderOverride>();\n\t\t\tconst modelOverrides = new Map<string, Map<string, ModelOverride>>();\n\n\t\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.compat) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\tcompat: providerConfig.compat,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.storeProviderRequestConfig(providerName, providerConfig);\n\n\t\t\t\tif (providerConfig.modelOverrides) {\n\t\t\t\t\tmodelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));\n\t\t\t\t\tfor (const [modelId, modelOverride] of Object.entries(providerConfig.modelOverrides)) {\n\t\t\t\t\t\tthis.storeModelHeaders(providerName, modelId, modelOverride.headers);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { models: this.parseModels(config), overrides, modelOverrides, error: undefined };\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\treturn emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\t\t\treturn emptyCustomModelsResult(\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${modelsJsonPath}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate validateConfig(config: ModelsConfig): void {\n\t\tconst builtInProviders = new Set<string>(getProviders());\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst isBuiltIn = builtInProviders.has(providerName);\n\t\t\tconst hasProviderApi = !!providerConfig.api;\n\t\t\tconst models = providerConfig.models ?? [];\n\t\t\tconst hasModelOverrides =\n\t\t\t\tproviderConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;\n\n\t\t\tif (models.length === 0) {\n\t\t\t\t// Override-only config: needs baseUrl, headers, compat, modelOverrides, or some combination.\n\t\t\t\tif (!providerConfig.baseUrl && !providerConfig.headers && !providerConfig.compat && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}: must specify \"baseUrl\", \"headers\", \"compat\", \"modelOverrides\", or \"models\".`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (!isBuiltIn) {\n\t\t\t\t// Non-built-in providers with custom models require endpoint + auth.\n\t\t\t\tif (!providerConfig.baseUrl) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t\tif (!providerConfig.apiKey) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Built-in providers with custom models: baseUrl/apiKey/api are optional,\n\t\t\t// inherited from built-in models. Auth comes from env vars / auth storage.\n\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi && !isBuiltIn) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified. Set at provider or model level.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// For built-in providers, api is optional — inherited from built-in models.\n\n\t\t\t\tif (!modelDef.id) throw new Error(`Provider ${providerName}: model missing \"id\"`);\n\t\t\t\t// Validate contextWindow/maxTokens only if provided (they have defaults)\n\t\t\t\tif (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);\n\t\t\t\tif (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate parseModels(config: ModelsConfig): Model<Api>[] {\n\t\tconst models: Model<Api>[] = [];\n\t\tconst builtInProviders = new Set<string>(getProviders());\n\n\t\t// Cache built-in defaults (api, baseUrl) per provider, extracted from first model.\n\t\tconst builtInDefaultsCache = new Map<string, { api: string; baseUrl: string }>();\n\t\tconst getBuiltInDefaults = (providerName: string): { api: string; baseUrl: string } | undefined => {\n\t\t\tif (!builtInProviders.has(providerName)) return undefined;\n\t\t\tif (builtInDefaultsCache.has(providerName)) return builtInDefaultsCache.get(providerName);\n\t\t\tconst builtIn = getModels(providerName as KnownProvider) as Model<Api>[];\n\t\t\tif (builtIn.length === 0) return undefined;\n\t\t\tconst defaults = { api: builtIn[0].api, baseUrl: builtIn[0].baseUrl };\n\t\t\tbuiltInDefaultsCache.set(providerName, defaults);\n\t\t\treturn defaults;\n\t\t};\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst modelDefs = providerConfig.models ?? [];\n\t\t\tif (modelDefs.length === 0) continue; // Override-only, no custom models\n\n\t\t\tconst builtInDefaults = getBuiltInDefaults(providerName);\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api ?? providerConfig.api ?? builtInDefaults?.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\tconst baseUrl = modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl;\n\t\t\t\tif (!baseUrl) continue;\n\n\t\t\t\tconst compat = mergeCompat(providerConfig.compat, modelDef.compat);\n\t\t\t\tthis.storeModelHeaders(providerName, modelDef.id, modelDef.headers);\n\n\t\t\t\tconst defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\t\t\t\tmodels.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name ?? modelDef.id,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\n\t\t\t\t\tthinkingLevelMap: modelDef.thinkingLevelMap,\n\t\t\t\t\tinput: (modelDef.input ?? [\"text\"]) as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost ?? defaultCost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens ?? 16384,\n\t\t\t\t\theaders: undefined,\n\t\t\t\t\tcompat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\n\t\treturn models;\n\t}\n\n\t/**\n\t * Get all models (built-in + custom).\n\t * If models.json had errors, returns only built-in models.\n\t */\n\tgetAll(): Model<Api>[] {\n\t\treturn this.models;\n\t}\n\n\t/**\n\t * Get only models that have auth configured.\n\t * This is a fast check that doesn't refresh OAuth tokens.\n\t */\n\tgetAvailable(): Model<Api>[] {\n\t\treturn this.models.filter((m) => this.hasConfiguredAuth(m));\n\t}\n\n\t/**\n\t * Find a model by provider and ID.\n\t */\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.find((m) => m.provider === provider && m.id === modelId);\n\t}\n\n\t/**\n\t * Local-inference routing config from models.json (`routing` block), if any.\n\t */\n\tgetRoutingConfig(): RoutingConfig | undefined {\n\t\treturn this.routingConfig;\n\t}\n\n\t/**\n\t * Get API key for a model.\n\t */\n\thasConfiguredAuth(model: Model<Api>): boolean {\n\t\treturn (\n\t\t\tthis.authStorage.hasAuth(model.provider) ||\n\t\t\tthis.providerRequestConfigs.get(model.provider)?.apiKey !== undefined\n\t\t);\n\t}\n\n\tprivate getModelRequestKey(provider: string, modelId: string): string {\n\t\treturn `${provider}:${modelId}`;\n\t}\n\n\tprivate storeProviderRequestConfig(\n\t\tproviderName: string,\n\t\tconfig: {\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t\t\tauthHeader?: boolean;\n\t\t},\n\t): void {\n\t\tif (!config.apiKey && !config.headers && !config.authHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.providerRequestConfigs.set(providerName, {\n\t\t\tapiKey: config.apiKey,\n\t\t\theaders: config.headers,\n\t\t\tauthHeader: config.authHeader,\n\t\t});\n\t}\n\n\tprivate storeModelHeaders(providerName: string, modelId: string, headers?: Record<string, string>): void {\n\t\tconst key = this.getModelRequestKey(providerName, modelId);\n\t\tif (!headers || Object.keys(headers).length === 0) {\n\t\t\tthis.modelRequestHeaders.delete(key);\n\t\t\treturn;\n\t\t}\n\t\tthis.modelRequestHeaders.set(key, headers);\n\t}\n\n\t/**\n\t * Get API key and request headers for a model.\n\t */\n\tasync getApiKeyAndHeaders(model: Model<Api>): Promise<ResolvedRequestAuth> {\n\t\ttry {\n\t\t\tconst providerConfig = this.providerRequestConfigs.get(model.provider);\n\t\t\tconst apiKeyFromAuthStorage = await this.authStorage.getApiKey(model.provider, { includeFallback: false });\n\t\t\tconst apiKey =\n\t\t\t\tapiKeyFromAuthStorage ??\n\t\t\t\t(providerConfig?.apiKey\n\t\t\t\t\t? resolveConfigValueOrThrow(providerConfig.apiKey, `API key for provider \"${model.provider}\"`)\n\t\t\t\t\t: undefined);\n\n\t\t\tconst providerHeaders = resolveHeadersOrThrow(providerConfig?.headers, `provider \"${model.provider}\"`);\n\t\t\tconst modelHeaders = resolveHeadersOrThrow(\n\t\t\t\tthis.modelRequestHeaders.get(this.getModelRequestKey(model.provider, model.id)),\n\t\t\t\t`model \"${model.provider}/${model.id}\"`,\n\t\t\t);\n\n\t\t\tlet headers =\n\t\t\t\tmodel.headers || providerHeaders || modelHeaders\n\t\t\t\t\t? { ...model.headers, ...providerHeaders, ...modelHeaders }\n\t\t\t\t\t: undefined;\n\n\t\t\tif (providerConfig?.authHeader) {\n\t\t\t\tif (!apiKey) {\n\t\t\t\t\treturn { ok: false, error: `No API key found for \"${model.provider}\"` };\n\t\t\t\t}\n\t\t\t\theaders = { ...headers, Authorization: `Bearer ${apiKey}` };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tapiKey,\n\t\t\t\theaders: headers && Object.keys(headers).length > 0 ? headers : undefined,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Return auth status for a provider, including request auth configured in models.json.\n\t * This intentionally does not execute command-backed config values.\n\t */\n\tgetProviderAuthStatus(provider: string): AuthStatus {\n\t\tconst authStatus = this.authStorage.getAuthStatus(provider);\n\t\tif (authStatus.source) {\n\t\t\treturn authStatus;\n\t\t}\n\n\t\tconst providerApiKey = this.providerRequestConfigs.get(provider)?.apiKey;\n\t\tif (!providerApiKey) {\n\t\t\treturn authStatus;\n\t\t}\n\n\t\tif (providerApiKey.startsWith(\"!\")) {\n\t\t\treturn { configured: true, source: \"models_json_command\" };\n\t\t}\n\n\t\tif (process.env[providerApiKey]) {\n\t\t\treturn { configured: true, source: \"environment\", label: providerApiKey };\n\t\t}\n\n\t\treturn { configured: true, source: \"models_json_key\" };\n\t}\n\n\t/**\n\t * Get display name for a provider.\n\t */\n\tgetProviderDisplayName(provider: string): string {\n\t\tconst registeredProvider = this.registeredProviders.get(provider);\n\t\tconst oauthProvider = this.authStorage.getOAuthProviders().find((p) => p.id === provider);\n\n\t\treturn (\n\t\t\tregisteredProvider?.name ??\n\t\t\tregisteredProvider?.oauth?.name ??\n\t\t\toauthProvider?.name ??\n\t\t\tBUILT_IN_PROVIDER_DISPLAY_NAMES[provider] ??\n\t\t\tprovider\n\t\t);\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t */\n\tasync getApiKeyForProvider(provider: string): Promise<string | undefined> {\n\t\tconst apiKey = await this.authStorage.getApiKey(provider, { includeFallback: false });\n\t\tif (apiKey !== undefined) {\n\t\t\treturn apiKey;\n\t\t}\n\n\t\tconst providerApiKey = this.providerRequestConfigs.get(provider)?.apiKey;\n\t\treturn providerApiKey ? resolveConfigValueUncached(providerApiKey) : undefined;\n\t}\n\n\t/**\n\t * Check if a model is using OAuth credentials (subscription).\n\t */\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\tconst cred = this.authStorage.get(model.provider);\n\t\treturn cred?.type === \"oauth\";\n\t}\n\n\t/**\n\t * Register a provider dynamically (from extensions).\n\t *\n\t * If provider has models: replaces all existing models for this provider.\n\t * If provider has only baseUrl/headers: overrides existing models' URLs.\n\t * If provider has oauth: registers OAuth provider for /login support.\n\t */\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.validateProviderConfig(providerName, config);\n\t\tthis.applyProviderConfig(providerName, config);\n\t\tthis.upsertRegisteredProvider(providerName, config);\n\t}\n\n\t/**\n\t * Unregister a previously registered provider.\n\t *\n\t * Removes the provider from the registry and reloads models from disk so that\n\t * built-in models overridden by this provider are restored to their original state.\n\t * Also resets dynamic OAuth and API stream registrations before reapplying\n\t * remaining dynamic providers.\n\t * Has no effect if the provider was never registered.\n\t */\n\tunregisterProvider(providerName: string): void {\n\t\tif (!this.registeredProviders.has(providerName)) return;\n\t\tthis.registeredProviders.delete(providerName);\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Upsert a provider config into registeredProviders.\n\t * If the provider is already registered, defined values in the incoming config\n\t * override existing ones; undefined values are preserved from the stored config.\n\t * If the provider is not registered, the incoming config is stored as-is.\n\t */\n\tprivate upsertRegisteredProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tconst existing = this.registeredProviders.get(providerName);\n\t\tif (!existing) {\n\t\t\tthis.registeredProviders.set(providerName, config);\n\t\t\treturn;\n\t\t}\n\t\tfor (const k of Object.keys(config) as (keyof ProviderConfigInput)[]) {\n\t\t\tif (config[k] !== undefined) {\n\t\t\t\t(existing as Record<string, unknown>)[k] = config[k];\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\tif (config.streamSimple && !config.api) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t}\n\n\t\tif (!config.models || config.models.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!config.baseUrl) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t}\n\t\tif (!config.apiKey && !config.oauth) {\n\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when defining models.`);\n\t\t}\n\n\t\tfor (const modelDef of config.models) {\n\t\t\tconst api = modelDef.api || config.api;\n\t\t\tif (!api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate applyProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\t// Register OAuth provider if provided\n\t\tif (config.oauth) {\n\t\t\t// Ensure the OAuth provider ID matches the provider name\n\t\t\tconst oauthProvider: OAuthProviderInterface = {\n\t\t\t\t...config.oauth,\n\t\t\t\tid: providerName,\n\t\t\t};\n\t\t\tregisterOAuthProvider(oauthProvider);\n\t\t}\n\n\t\tif (config.streamSimple) {\n\t\t\tconst streamSimple = config.streamSimple;\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api!,\n\t\t\t\t\tstream: (model, context, options) => streamSimple(model, context, options as SimpleStreamOptions),\n\t\t\t\t\tstreamSimple,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.storeProviderRequestConfig(providerName, config);\n\n\t\tif (config.models && config.models.length > 0) {\n\t\t\t// Full replacement: remove existing models for this provider\n\t\t\tthis.models = this.models.filter((m) => m.provider !== providerName);\n\n\t\t\t// Parse and add new models\n\t\t\tfor (const modelDef of config.models) {\n\t\t\t\tconst api = modelDef.api || config.api;\n\t\t\t\tthis.storeModelHeaders(providerName, modelDef.id, modelDef.headers);\n\n\t\t\t\tthis.models.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: modelDef.baseUrl ?? config.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning,\n\t\t\t\t\tthinkingLevelMap: modelDef.thinkingLevelMap,\n\t\t\t\t\tinput: modelDef.input as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens,\n\t\t\t\t\theaders: undefined,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\n\t\t\t// Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)\n\t\t\tif (config.oauth?.modifyModels) {\n\t\t\t\tconst cred = this.authStorage.get(providerName);\n\t\t\t\tif (cred?.type === \"oauth\") {\n\t\t\t\t\tthis.models = config.oauth.modifyModels(this.models, cred);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (config.baseUrl || config.headers) {\n\t\t\t// Override-only: update baseUrl for existing models. Request headers are resolved per request.\n\t\t\tthis.models = this.models.map((m) => {\n\t\t\t\tif (m.provider !== providerName) return m;\n\t\t\t\treturn {\n\t\t\t\t\t...m,\n\t\t\t\t\tbaseUrl: config.baseUrl ?? m.baseUrl,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tname?: string;\n\tbaseUrl?: string;\n\tapiKey?: string;\n\tapi?: Api;\n\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n\t/** OAuth provider for /login support */\n\toauth?: Omit<OAuthProviderInterface, \"id\">;\n\tmodels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tapi?: Api;\n\t\tbaseUrl?: string;\n\t\treasoning: boolean;\n\t\tthinkingLevelMap?: Model<Api>[\"thinkingLevelMap\"];\n\t\tinput: (\"text\" | \"image\")[];\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\t\tcontextWindow: number;\n\t\tmaxTokens: number;\n\t\theaders?: Record<string, string>;\n\t\tcompat?: Model<Api>[\"compat\"];\n\t}>;\n}\n"]}
@@ -19,7 +19,7 @@ import type { Api, Model } from "@kolisachint/hoocode-ai";
19
19
  import type { ModelRegistry } from "../model-registry.js";
20
20
  /** Work that may be routed to the executor instead of the primary model. */
21
21
  export type TurnKind = "primary" | "summarization" | "tool-result";
22
- export type RoutingMode = "primary-only" | "executor-for-summarization" | "executor-for-tool-results" | "shadow-executor";
22
+ export type RoutingMode = "primary-only" | "executor-for-summarization" | "executor-for-tool-results";
23
23
  export declare const ROUTING_MODES: readonly RoutingMode[];
24
24
  /**
25
25
  * Tool names whose output is worth compressing (validated). Others pass
@@ -29,15 +29,6 @@ export declare const ROUTING_MODES: readonly RoutingMode[];
29
29
  * (grep/find/ls) were never compressible (every line is a distinct fact).
30
30
  */
31
31
  export declare const COMPRESSIBLE_TOOLS: Set<string>;
32
- /**
33
- * Global size band (bytes) for local-inference routing. Applies to BOTH
34
- * tool-result compression and compaction summarization. Inputs below the
35
- * minimum are not worth offloading; inputs above the maximum are slow and risk
36
- * GPU OOM on small machines, so they fall back to the primary model. Tunable
37
- * per-machine via `minBytes`/`maxBytes` in the executor config block.
38
- */
39
- export declare const DEFAULT_MIN_BYTES = 2048;
40
- export declare const DEFAULT_MAX_BYTES = 8192;
41
32
  /** Optional local server the harness manages for the executor. */
42
33
  export interface ExecutorServerConfig {
43
34
  /** Command to launch (default: "mlx_lm.server"). */
@@ -51,13 +42,22 @@ export interface ExecutorServerConfig {
51
42
  /** Max milliseconds to wait for the server to become healthy (default: 30000). */
52
43
  startupTimeoutMs?: number;
53
44
  }
54
- /** Executor model reference as configured in models.json. */
45
+ /**
46
+ * Executor model reference as configured in models.json.
47
+ *
48
+ * The size band (`minBytes`/`maxBytes`) is wired entirely from config — there
49
+ * are no built-in byte defaults. When a bound is omitted it is not applied:
50
+ * `minBytes` defaults to 0 (no lower gate) and `maxBytes` to unbounded. Set
51
+ * both in models.json to gate which inputs route to the executor; on local
52
+ * hardware a `maxBytes` guards against slow runs / GPU OOM, while a hosted or
53
+ * large-memory executor can leave it unset (or high) to offload large inputs.
54
+ */
55
55
  export interface ExecutorConfig {
56
56
  provider: string;
57
57
  model: string;
58
- /** Minimum input size (bytes) before local inference is attempted. */
58
+ /** Minimum input size (bytes) before local inference is attempted. Omitted = 0 (no lower gate). */
59
59
  minBytes?: number;
60
- /** Maximum input size (bytes); larger inputs fall back to the primary model. */
60
+ /** Maximum input size (bytes); larger inputs fall back to the primary model. Omitted = unbounded. */
61
61
  maxBytes?: number;
62
62
  /** When set, the harness spawns/health-checks/stops this local server. */
63
63
  server?: ExecutorServerConfig;
@@ -104,8 +104,7 @@ export declare class LocalInferenceRouter {
104
104
  /**
105
105
  * Pick the model to use for a turn. Returns the executor when the mode routes
106
106
  * that turn kind and the executor is available; otherwise returns the primary
107
- * model. `shadow-executor` always returns the primary for the live path (the
108
- * executor is exercised separately for measurement).
107
+ * model.
109
108
  */
110
109
  selectModel(turnKind: TurnKind, primary: Model<Api>): Model<Api>;
111
110
  /** True when an input size falls within the configured local-inference band. */
@@ -1 +1 @@
1
- {"version":3,"file":"local-inference.d.ts","sourceRoot":"","sources":["../../../src/core/routing/local-inference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local-inference routing.\n *\n * Optional, opt-in routing of certain non-critical work (conversation\n * compaction, and large bash tool-result compression) to a local\n * \"executor\" model running on an OpenAI-compatible endpoint (for example an\n * MLX server), while the primary model handles all planning, reasoning, edits,\n * and tool-call synthesis.\n *\n * Everything here is INERT unless explicitly enabled via the\n * `--enable-local-inference` flag or the `HOOCODE_ROUTING_MODE` env var. On any\n * executor resolution/availability problem the caller falls back to the primary\n * model (compaction) or the raw tool result (tool-result compression). The\n * router never throws into the agent loop.\n *\n * Design and validation: see docs/local-executor-routing.md.\n */\n\nimport type { Api, Model } from \"@kolisachint/hoocode-ai\";\nimport type { ModelRegistry } from \"../model-registry.js\";\n\n/** Work that may be routed to the executor instead of the primary model. */\nexport type TurnKind = \"primary\" | \"summarization\" | \"tool-result\";\n\nexport type RoutingMode =\n\t| \"primary-only\"\n\t| \"executor-for-summarization\"\n\t| \"executor-for-tool-results\"\n\t| \"shadow-executor\";\n\nexport const ROUTING_MODES: readonly RoutingMode[] = [\n\t\"primary-only\",\n\t\"executor-for-summarization\",\n\t\"executor-for-tool-results\",\n\t\"shadow-executor\",\n] as const;\n\n/**\n * Tool names whose output is worth compressing (validated). Others pass\n * through. Only `bash` qualifies: its verbose output is mostly low-value noise\n * around a few load-bearing facts. `read` was measured to compress ~0% on real\n * source code (every line is a keep-line) and was removed. Fact-list tools\n * (grep/find/ls) were never compressible (every line is a distinct fact).\n */\nexport const COMPRESSIBLE_TOOLS = new Set([\"bash\"]);\n\n/**\n * Global size band (bytes) for local-inference routing. Applies to BOTH\n * tool-result compression and compaction summarization. Inputs below the\n * minimum are not worth offloading; inputs above the maximum are slow and risk\n * GPU OOM on small machines, so they fall back to the primary model. Tunable\n * per-machine via `minBytes`/`maxBytes` in the executor config block.\n */\nexport const DEFAULT_MIN_BYTES = 2048;\nexport const DEFAULT_MAX_BYTES = 8192;\n\n/** Optional local server the harness manages for the executor. */\nexport interface ExecutorServerConfig {\n\t/** Command to launch (default: \"mlx_lm.server\"). */\n\tcommand?: string;\n\t/** Extra args appended to the launch command. */\n\targs?: string[];\n\t/** Host to health-check and bind (default: derived from executor baseUrl or 127.0.0.1). */\n\thost?: string;\n\t/** Port to health-check and bind (default: derived from executor baseUrl or 8080). */\n\tport?: number;\n\t/** Max milliseconds to wait for the server to become healthy (default: 30000). */\n\tstartupTimeoutMs?: number;\n}\n\n/** Executor model reference as configured in models.json. */\nexport interface ExecutorConfig {\n\tprovider: string;\n\tmodel: string;\n\t/** Minimum input size (bytes) before local inference is attempted. */\n\tminBytes?: number;\n\t/** Maximum input size (bytes); larger inputs fall back to the primary model. */\n\tmaxBytes?: number;\n\t/** When set, the harness spawns/health-checks/stops this local server. */\n\tserver?: ExecutorServerConfig;\n}\n\n/** `routing` block in models.json. */\nexport interface RoutingConfig {\n\tmode?: RoutingMode;\n\texecutor?: ExecutorConfig;\n}\n\nfunction isRoutingMode(value: unknown): value is RoutingMode {\n\treturn typeof value === \"string\" && (ROUTING_MODES as readonly string[]).includes(value);\n}\n\n/**\n * Resolve the effective routing mode from CLI flag, env var, and config.\n *\n * Activation requires either the flag or the env var; config alone never\n * activates routing (decision: explicit opt-in only). When activated without an\n * explicit mode, defaults to `executor-for-summarization` (the lowest-risk\n * mode). When not activated, always `primary-only`.\n */\nexport function resolveRoutingMode(opts: {\n\tenableFlag?: boolean;\n\tenvMode?: string;\n\tconfigMode?: RoutingMode;\n}): RoutingMode {\n\tconst envMode = opts.envMode?.trim();\n\tconst envActivates = envMode !== undefined && envMode !== \"\" && envMode !== \"primary-only\";\n\tconst activated = opts.enableFlag === true || envActivates;\n\tif (!activated) return \"primary-only\";\n\n\tif (envMode && isRoutingMode(envMode)) return envMode;\n\tif (opts.configMode && isRoutingMode(opts.configMode)) return opts.configMode;\n\treturn \"executor-for-summarization\";\n}\n\n/**\n * Router that decides, per turn kind, whether to use the executor model and\n * resolves it from the registry. Holds no mutable state beyond the resolved\n * executor model.\n */\nexport class LocalInferenceRouter {\n\tprivate readonly mode: RoutingMode;\n\tprivate readonly executorConfig: ExecutorConfig | undefined;\n\tprivate readonly executor: Model<Api> | undefined;\n\tprivate readonly minBytes: number;\n\tprivate readonly maxBytes: number;\n\n\tprivate constructor(\n\t\tmode: RoutingMode,\n\t\texecutorConfig: ExecutorConfig | undefined,\n\t\texecutor: Model<Api> | undefined,\n\t) {\n\t\tthis.mode = mode;\n\t\tthis.executorConfig = executorConfig;\n\t\tthis.executor = executor;\n\t\tthis.minBytes = executorConfig?.minBytes ?? DEFAULT_MIN_BYTES;\n\t\tthis.maxBytes = executorConfig?.maxBytes ?? DEFAULT_MAX_BYTES;\n\t}\n\n\tstatic create(opts: {\n\t\tmode: RoutingMode;\n\t\tconfig: RoutingConfig | undefined;\n\t\tregistry: ModelRegistry;\n\t}): LocalInferenceRouter {\n\t\tconst executorConfig = opts.config?.executor;\n\t\tlet executor: Model<Api> | undefined;\n\t\tif (opts.mode !== \"primary-only\" && executorConfig) {\n\t\t\texecutor = opts.registry.find(executorConfig.provider, executorConfig.model);\n\t\t}\n\t\treturn new LocalInferenceRouter(opts.mode, executorConfig, executor);\n\t}\n\n\tgetMode(): RoutingMode {\n\t\treturn this.mode;\n\t}\n\n\t/** True when routing is active and an executor model is resolved and usable. */\n\tisExecutorAvailable(): boolean {\n\t\treturn this.mode !== \"primary-only\" && this.executor !== undefined;\n\t}\n\n\tgetExecutorConfig(): ExecutorConfig | undefined {\n\t\treturn this.executorConfig;\n\t}\n\n\t/**\n\t * Pick the model to use for a turn. Returns the executor when the mode routes\n\t * that turn kind and the executor is available; otherwise returns the primary\n\t * model. `shadow-executor` always returns the primary for the live path (the\n\t * executor is exercised separately for measurement).\n\t */\n\tselectModel(turnKind: TurnKind, primary: Model<Api>): Model<Api> {\n\t\tif (!this.isExecutorAvailable() || !this.executor) return primary;\n\t\tswitch (this.mode) {\n\t\t\tcase \"executor-for-summarization\":\n\t\t\t\treturn turnKind === \"summarization\" ? this.executor : primary;\n\t\t\tcase \"executor-for-tool-results\":\n\t\t\t\treturn turnKind === \"tool-result\" ? this.executor : primary;\n\t\t\tcase \"shadow-executor\":\n\t\t\tcase \"primary-only\":\n\t\t\t\treturn primary;\n\t\t}\n\t}\n\n\t/** True when an input size falls within the configured local-inference band. */\n\twithinSizeBand(bytes: number): boolean {\n\t\treturn bytes >= this.minBytes && bytes <= this.maxBytes;\n\t}\n\n\t/** The configured size band, for logging/diagnostics. */\n\tgetSizeBand(): { minBytes: number; maxBytes: number } {\n\t\treturn { minBytes: this.minBytes, maxBytes: this.maxBytes };\n\t}\n\n\t/** Whether a given tool's result should be compressed via the executor. */\n\tshouldCompressToolResult(toolName: string, contentBytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-tool-results\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\tif (!COMPRESSIBLE_TOOLS.has(toolName)) return false;\n\t\treturn this.withinSizeBand(contentBytes);\n\t}\n\n\t/**\n\t * Whether to route summarization to the executor for a conversation of the\n\t * given serialized size. Requires summarization routing active, the executor\n\t * available, and the size within the band (oversized conversations fall back\n\t * to the primary to avoid slow local runs and GPU OOM).\n\t */\n\tshouldRouteSummarization(bytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-summarization\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\treturn this.withinSizeBand(bytes);\n\t}\n\n\tgetExecutorModel(): Model<Api> | undefined {\n\t\treturn this.executor;\n\t}\n}\n"]}
1
+ {"version":3,"file":"local-inference.d.ts","sourceRoot":"","sources":["../../../src/core/routing/local-inference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local-inference routing.\n *\n * Optional, opt-in routing of certain non-critical work (conversation\n * compaction, and large bash tool-result compression) to a local\n * \"executor\" model running on an OpenAI-compatible endpoint (for example an\n * MLX server), while the primary model handles all planning, reasoning, edits,\n * and tool-call synthesis.\n *\n * Everything here is INERT unless explicitly enabled via the\n * `--enable-local-inference` flag or the `HOOCODE_ROUTING_MODE` env var. On any\n * executor resolution/availability problem the caller falls back to the primary\n * model (compaction) or the raw tool result (tool-result compression). The\n * router never throws into the agent loop.\n *\n * Design and validation: see docs/local-executor-routing.md.\n */\n\nimport type { Api, Model } from \"@kolisachint/hoocode-ai\";\nimport type { ModelRegistry } from \"../model-registry.js\";\n\n/** Work that may be routed to the executor instead of the primary model. */\nexport type TurnKind = \"primary\" | \"summarization\" | \"tool-result\";\n\nexport type RoutingMode = \"primary-only\" | \"executor-for-summarization\" | \"executor-for-tool-results\";\n\nexport const ROUTING_MODES: readonly RoutingMode[] = [\n\t\"primary-only\",\n\t\"executor-for-summarization\",\n\t\"executor-for-tool-results\",\n] as const;\n\n/**\n * Tool names whose output is worth compressing (validated). Others pass\n * through. Only `bash` qualifies: its verbose output is mostly low-value noise\n * around a few load-bearing facts. `read` was measured to compress ~0% on real\n * source code (every line is a keep-line) and was removed. Fact-list tools\n * (grep/find/ls) were never compressible (every line is a distinct fact).\n */\nexport const COMPRESSIBLE_TOOLS = new Set([\"bash\"]);\n\n/** Optional local server the harness manages for the executor. */\nexport interface ExecutorServerConfig {\n\t/** Command to launch (default: \"mlx_lm.server\"). */\n\tcommand?: string;\n\t/** Extra args appended to the launch command. */\n\targs?: string[];\n\t/** Host to health-check and bind (default: derived from executor baseUrl or 127.0.0.1). */\n\thost?: string;\n\t/** Port to health-check and bind (default: derived from executor baseUrl or 8080). */\n\tport?: number;\n\t/** Max milliseconds to wait for the server to become healthy (default: 30000). */\n\tstartupTimeoutMs?: number;\n}\n\n/**\n * Executor model reference as configured in models.json.\n *\n * The size band (`minBytes`/`maxBytes`) is wired entirely from config — there\n * are no built-in byte defaults. When a bound is omitted it is not applied:\n * `minBytes` defaults to 0 (no lower gate) and `maxBytes` to unbounded. Set\n * both in models.json to gate which inputs route to the executor; on local\n * hardware a `maxBytes` guards against slow runs / GPU OOM, while a hosted or\n * large-memory executor can leave it unset (or high) to offload large inputs.\n */\nexport interface ExecutorConfig {\n\tprovider: string;\n\tmodel: string;\n\t/** Minimum input size (bytes) before local inference is attempted. Omitted = 0 (no lower gate). */\n\tminBytes?: number;\n\t/** Maximum input size (bytes); larger inputs fall back to the primary model. Omitted = unbounded. */\n\tmaxBytes?: number;\n\t/** When set, the harness spawns/health-checks/stops this local server. */\n\tserver?: ExecutorServerConfig;\n}\n\n/** `routing` block in models.json. */\nexport interface RoutingConfig {\n\tmode?: RoutingMode;\n\texecutor?: ExecutorConfig;\n}\n\nfunction isRoutingMode(value: unknown): value is RoutingMode {\n\treturn typeof value === \"string\" && (ROUTING_MODES as readonly string[]).includes(value);\n}\n\n/**\n * Resolve the effective routing mode from CLI flag, env var, and config.\n *\n * Activation requires either the flag or the env var; config alone never\n * activates routing (decision: explicit opt-in only). When activated without an\n * explicit mode, defaults to `executor-for-summarization` (the lowest-risk\n * mode). When not activated, always `primary-only`.\n */\nexport function resolveRoutingMode(opts: {\n\tenableFlag?: boolean;\n\tenvMode?: string;\n\tconfigMode?: RoutingMode;\n}): RoutingMode {\n\tconst envMode = opts.envMode?.trim();\n\tconst envActivates = envMode !== undefined && envMode !== \"\" && envMode !== \"primary-only\";\n\tconst activated = opts.enableFlag === true || envActivates;\n\tif (!activated) return \"primary-only\";\n\n\tif (envMode && isRoutingMode(envMode)) return envMode;\n\tif (opts.configMode && isRoutingMode(opts.configMode)) return opts.configMode;\n\treturn \"executor-for-summarization\";\n}\n\n/**\n * Router that decides, per turn kind, whether to use the executor model and\n * resolves it from the registry. Holds no mutable state beyond the resolved\n * executor model.\n */\nexport class LocalInferenceRouter {\n\tprivate readonly mode: RoutingMode;\n\tprivate readonly executorConfig: ExecutorConfig | undefined;\n\tprivate readonly executor: Model<Api> | undefined;\n\tprivate readonly minBytes: number;\n\tprivate readonly maxBytes: number;\n\n\tprivate constructor(\n\t\tmode: RoutingMode,\n\t\texecutorConfig: ExecutorConfig | undefined,\n\t\texecutor: Model<Api> | undefined,\n\t) {\n\t\tthis.mode = mode;\n\t\tthis.executorConfig = executorConfig;\n\t\tthis.executor = executor;\n\t\t// No built-in byte defaults: an omitted bound is simply not applied\n\t\t// (min 0 = no lower gate, max +Infinity = unbounded). The band is wired\n\t\t// entirely from the models.json executor config.\n\t\tthis.minBytes = executorConfig?.minBytes ?? 0;\n\t\tthis.maxBytes = executorConfig?.maxBytes ?? Number.POSITIVE_INFINITY;\n\t}\n\n\tstatic create(opts: {\n\t\tmode: RoutingMode;\n\t\tconfig: RoutingConfig | undefined;\n\t\tregistry: ModelRegistry;\n\t}): LocalInferenceRouter {\n\t\tconst executorConfig = opts.config?.executor;\n\t\tlet executor: Model<Api> | undefined;\n\t\tif (opts.mode !== \"primary-only\" && executorConfig) {\n\t\t\texecutor = opts.registry.find(executorConfig.provider, executorConfig.model);\n\t\t}\n\t\treturn new LocalInferenceRouter(opts.mode, executorConfig, executor);\n\t}\n\n\tgetMode(): RoutingMode {\n\t\treturn this.mode;\n\t}\n\n\t/** True when routing is active and an executor model is resolved and usable. */\n\tisExecutorAvailable(): boolean {\n\t\treturn this.mode !== \"primary-only\" && this.executor !== undefined;\n\t}\n\n\tgetExecutorConfig(): ExecutorConfig | undefined {\n\t\treturn this.executorConfig;\n\t}\n\n\t/**\n\t * Pick the model to use for a turn. Returns the executor when the mode routes\n\t * that turn kind and the executor is available; otherwise returns the primary\n\t * model.\n\t */\n\tselectModel(turnKind: TurnKind, primary: Model<Api>): Model<Api> {\n\t\tif (!this.isExecutorAvailable() || !this.executor) return primary;\n\t\tswitch (this.mode) {\n\t\t\tcase \"executor-for-summarization\":\n\t\t\t\treturn turnKind === \"summarization\" ? this.executor : primary;\n\t\t\tcase \"executor-for-tool-results\":\n\t\t\t\treturn turnKind === \"tool-result\" ? this.executor : primary;\n\t\t\tcase \"primary-only\":\n\t\t\t\treturn primary;\n\t\t}\n\t}\n\n\t/** True when an input size falls within the configured local-inference band. */\n\twithinSizeBand(bytes: number): boolean {\n\t\treturn bytes >= this.minBytes && bytes <= this.maxBytes;\n\t}\n\n\t/** The configured size band, for logging/diagnostics. */\n\tgetSizeBand(): { minBytes: number; maxBytes: number } {\n\t\treturn { minBytes: this.minBytes, maxBytes: this.maxBytes };\n\t}\n\n\t/** Whether a given tool's result should be compressed via the executor. */\n\tshouldCompressToolResult(toolName: string, contentBytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-tool-results\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\tif (!COMPRESSIBLE_TOOLS.has(toolName)) return false;\n\t\treturn this.withinSizeBand(contentBytes);\n\t}\n\n\t/**\n\t * Whether to route summarization to the executor for a conversation of the\n\t * given serialized size. Requires summarization routing active, the executor\n\t * available, and the size within the band (oversized conversations fall back\n\t * to the primary to avoid slow local runs and GPU OOM).\n\t */\n\tshouldRouteSummarization(bytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-summarization\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\treturn this.withinSizeBand(bytes);\n\t}\n\n\tgetExecutorModel(): Model<Api> | undefined {\n\t\treturn this.executor;\n\t}\n}\n"]}
@@ -19,7 +19,6 @@ export const ROUTING_MODES = [
19
19
  "primary-only",
20
20
  "executor-for-summarization",
21
21
  "executor-for-tool-results",
22
- "shadow-executor",
23
22
  ];
24
23
  /**
25
24
  * Tool names whose output is worth compressing (validated). Others pass
@@ -29,15 +28,6 @@ export const ROUTING_MODES = [
29
28
  * (grep/find/ls) were never compressible (every line is a distinct fact).
30
29
  */
31
30
  export const COMPRESSIBLE_TOOLS = new Set(["bash"]);
32
- /**
33
- * Global size band (bytes) for local-inference routing. Applies to BOTH
34
- * tool-result compression and compaction summarization. Inputs below the
35
- * minimum are not worth offloading; inputs above the maximum are slow and risk
36
- * GPU OOM on small machines, so they fall back to the primary model. Tunable
37
- * per-machine via `minBytes`/`maxBytes` in the executor config block.
38
- */
39
- export const DEFAULT_MIN_BYTES = 2048;
40
- export const DEFAULT_MAX_BYTES = 8192;
41
31
  function isRoutingMode(value) {
42
32
  return typeof value === "string" && ROUTING_MODES.includes(value);
43
33
  }
@@ -76,8 +66,11 @@ export class LocalInferenceRouter {
76
66
  this.mode = mode;
77
67
  this.executorConfig = executorConfig;
78
68
  this.executor = executor;
79
- this.minBytes = executorConfig?.minBytes ?? DEFAULT_MIN_BYTES;
80
- this.maxBytes = executorConfig?.maxBytes ?? DEFAULT_MAX_BYTES;
69
+ // No built-in byte defaults: an omitted bound is simply not applied
70
+ // (min 0 = no lower gate, max +Infinity = unbounded). The band is wired
71
+ // entirely from the models.json executor config.
72
+ this.minBytes = executorConfig?.minBytes ?? 0;
73
+ this.maxBytes = executorConfig?.maxBytes ?? Number.POSITIVE_INFINITY;
81
74
  }
82
75
  static create(opts) {
83
76
  const executorConfig = opts.config?.executor;
@@ -100,8 +93,7 @@ export class LocalInferenceRouter {
100
93
  /**
101
94
  * Pick the model to use for a turn. Returns the executor when the mode routes
102
95
  * that turn kind and the executor is available; otherwise returns the primary
103
- * model. `shadow-executor` always returns the primary for the live path (the
104
- * executor is exercised separately for measurement).
96
+ * model.
105
97
  */
106
98
  selectModel(turnKind, primary) {
107
99
  if (!this.isExecutorAvailable() || !this.executor)
@@ -111,7 +103,6 @@ export class LocalInferenceRouter {
111
103
  return turnKind === "summarization" ? this.executor : primary;
112
104
  case "executor-for-tool-results":
113
105
  return turnKind === "tool-result" ? this.executor : primary;
114
- case "shadow-executor":
115
106
  case "primary-only":
116
107
  return primary;
117
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"local-inference.js","sourceRoot":"","sources":["../../../src/core/routing/local-inference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local-inference routing.\n *\n * Optional, opt-in routing of certain non-critical work (conversation\n * compaction, and large bash tool-result compression) to a local\n * \"executor\" model running on an OpenAI-compatible endpoint (for example an\n * MLX server), while the primary model handles all planning, reasoning, edits,\n * and tool-call synthesis.\n *\n * Everything here is INERT unless explicitly enabled via the\n * `--enable-local-inference` flag or the `HOOCODE_ROUTING_MODE` env var. On any\n * executor resolution/availability problem the caller falls back to the primary\n * model (compaction) or the raw tool result (tool-result compression). The\n * router never throws into the agent loop.\n *\n * Design and validation: see docs/local-executor-routing.md.\n */\n\nimport type { Api, Model } from \"@kolisachint/hoocode-ai\";\nimport type { ModelRegistry } from \"../model-registry.js\";\n\n/** Work that may be routed to the executor instead of the primary model. */\nexport type TurnKind = \"primary\" | \"summarization\" | \"tool-result\";\n\nexport type RoutingMode =\n\t| \"primary-only\"\n\t| \"executor-for-summarization\"\n\t| \"executor-for-tool-results\"\n\t| \"shadow-executor\";\n\nexport const ROUTING_MODES: readonly RoutingMode[] = [\n\t\"primary-only\",\n\t\"executor-for-summarization\",\n\t\"executor-for-tool-results\",\n\t\"shadow-executor\",\n] as const;\n\n/**\n * Tool names whose output is worth compressing (validated). Others pass\n * through. Only `bash` qualifies: its verbose output is mostly low-value noise\n * around a few load-bearing facts. `read` was measured to compress ~0% on real\n * source code (every line is a keep-line) and was removed. Fact-list tools\n * (grep/find/ls) were never compressible (every line is a distinct fact).\n */\nexport const COMPRESSIBLE_TOOLS = new Set([\"bash\"]);\n\n/**\n * Global size band (bytes) for local-inference routing. Applies to BOTH\n * tool-result compression and compaction summarization. Inputs below the\n * minimum are not worth offloading; inputs above the maximum are slow and risk\n * GPU OOM on small machines, so they fall back to the primary model. Tunable\n * per-machine via `minBytes`/`maxBytes` in the executor config block.\n */\nexport const DEFAULT_MIN_BYTES = 2048;\nexport const DEFAULT_MAX_BYTES = 8192;\n\n/** Optional local server the harness manages for the executor. */\nexport interface ExecutorServerConfig {\n\t/** Command to launch (default: \"mlx_lm.server\"). */\n\tcommand?: string;\n\t/** Extra args appended to the launch command. */\n\targs?: string[];\n\t/** Host to health-check and bind (default: derived from executor baseUrl or 127.0.0.1). */\n\thost?: string;\n\t/** Port to health-check and bind (default: derived from executor baseUrl or 8080). */\n\tport?: number;\n\t/** Max milliseconds to wait for the server to become healthy (default: 30000). */\n\tstartupTimeoutMs?: number;\n}\n\n/** Executor model reference as configured in models.json. */\nexport interface ExecutorConfig {\n\tprovider: string;\n\tmodel: string;\n\t/** Minimum input size (bytes) before local inference is attempted. */\n\tminBytes?: number;\n\t/** Maximum input size (bytes); larger inputs fall back to the primary model. */\n\tmaxBytes?: number;\n\t/** When set, the harness spawns/health-checks/stops this local server. */\n\tserver?: ExecutorServerConfig;\n}\n\n/** `routing` block in models.json. */\nexport interface RoutingConfig {\n\tmode?: RoutingMode;\n\texecutor?: ExecutorConfig;\n}\n\nfunction isRoutingMode(value: unknown): value is RoutingMode {\n\treturn typeof value === \"string\" && (ROUTING_MODES as readonly string[]).includes(value);\n}\n\n/**\n * Resolve the effective routing mode from CLI flag, env var, and config.\n *\n * Activation requires either the flag or the env var; config alone never\n * activates routing (decision: explicit opt-in only). When activated without an\n * explicit mode, defaults to `executor-for-summarization` (the lowest-risk\n * mode). When not activated, always `primary-only`.\n */\nexport function resolveRoutingMode(opts: {\n\tenableFlag?: boolean;\n\tenvMode?: string;\n\tconfigMode?: RoutingMode;\n}): RoutingMode {\n\tconst envMode = opts.envMode?.trim();\n\tconst envActivates = envMode !== undefined && envMode !== \"\" && envMode !== \"primary-only\";\n\tconst activated = opts.enableFlag === true || envActivates;\n\tif (!activated) return \"primary-only\";\n\n\tif (envMode && isRoutingMode(envMode)) return envMode;\n\tif (opts.configMode && isRoutingMode(opts.configMode)) return opts.configMode;\n\treturn \"executor-for-summarization\";\n}\n\n/**\n * Router that decides, per turn kind, whether to use the executor model and\n * resolves it from the registry. Holds no mutable state beyond the resolved\n * executor model.\n */\nexport class LocalInferenceRouter {\n\tprivate readonly mode: RoutingMode;\n\tprivate readonly executorConfig: ExecutorConfig | undefined;\n\tprivate readonly executor: Model<Api> | undefined;\n\tprivate readonly minBytes: number;\n\tprivate readonly maxBytes: number;\n\n\tprivate constructor(\n\t\tmode: RoutingMode,\n\t\texecutorConfig: ExecutorConfig | undefined,\n\t\texecutor: Model<Api> | undefined,\n\t) {\n\t\tthis.mode = mode;\n\t\tthis.executorConfig = executorConfig;\n\t\tthis.executor = executor;\n\t\tthis.minBytes = executorConfig?.minBytes ?? DEFAULT_MIN_BYTES;\n\t\tthis.maxBytes = executorConfig?.maxBytes ?? DEFAULT_MAX_BYTES;\n\t}\n\n\tstatic create(opts: {\n\t\tmode: RoutingMode;\n\t\tconfig: RoutingConfig | undefined;\n\t\tregistry: ModelRegistry;\n\t}): LocalInferenceRouter {\n\t\tconst executorConfig = opts.config?.executor;\n\t\tlet executor: Model<Api> | undefined;\n\t\tif (opts.mode !== \"primary-only\" && executorConfig) {\n\t\t\texecutor = opts.registry.find(executorConfig.provider, executorConfig.model);\n\t\t}\n\t\treturn new LocalInferenceRouter(opts.mode, executorConfig, executor);\n\t}\n\n\tgetMode(): RoutingMode {\n\t\treturn this.mode;\n\t}\n\n\t/** True when routing is active and an executor model is resolved and usable. */\n\tisExecutorAvailable(): boolean {\n\t\treturn this.mode !== \"primary-only\" && this.executor !== undefined;\n\t}\n\n\tgetExecutorConfig(): ExecutorConfig | undefined {\n\t\treturn this.executorConfig;\n\t}\n\n\t/**\n\t * Pick the model to use for a turn. Returns the executor when the mode routes\n\t * that turn kind and the executor is available; otherwise returns the primary\n\t * model. `shadow-executor` always returns the primary for the live path (the\n\t * executor is exercised separately for measurement).\n\t */\n\tselectModel(turnKind: TurnKind, primary: Model<Api>): Model<Api> {\n\t\tif (!this.isExecutorAvailable() || !this.executor) return primary;\n\t\tswitch (this.mode) {\n\t\t\tcase \"executor-for-summarization\":\n\t\t\t\treturn turnKind === \"summarization\" ? this.executor : primary;\n\t\t\tcase \"executor-for-tool-results\":\n\t\t\t\treturn turnKind === \"tool-result\" ? this.executor : primary;\n\t\t\tcase \"shadow-executor\":\n\t\t\tcase \"primary-only\":\n\t\t\t\treturn primary;\n\t\t}\n\t}\n\n\t/** True when an input size falls within the configured local-inference band. */\n\twithinSizeBand(bytes: number): boolean {\n\t\treturn bytes >= this.minBytes && bytes <= this.maxBytes;\n\t}\n\n\t/** The configured size band, for logging/diagnostics. */\n\tgetSizeBand(): { minBytes: number; maxBytes: number } {\n\t\treturn { minBytes: this.minBytes, maxBytes: this.maxBytes };\n\t}\n\n\t/** Whether a given tool's result should be compressed via the executor. */\n\tshouldCompressToolResult(toolName: string, contentBytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-tool-results\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\tif (!COMPRESSIBLE_TOOLS.has(toolName)) return false;\n\t\treturn this.withinSizeBand(contentBytes);\n\t}\n\n\t/**\n\t * Whether to route summarization to the executor for a conversation of the\n\t * given serialized size. Requires summarization routing active, the executor\n\t * available, and the size within the band (oversized conversations fall back\n\t * to the primary to avoid slow local runs and GPU OOM).\n\t */\n\tshouldRouteSummarization(bytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-summarization\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\treturn this.withinSizeBand(bytes);\n\t}\n\n\tgetExecutorModel(): Model<Api> | undefined {\n\t\treturn this.executor;\n\t}\n}\n"]}
1
+ {"version":3,"file":"local-inference.js","sourceRoot":"","sources":["../../../src/core/routing/local-inference.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local-inference routing.\n *\n * Optional, opt-in routing of certain non-critical work (conversation\n * compaction, and large bash tool-result compression) to a local\n * \"executor\" model running on an OpenAI-compatible endpoint (for example an\n * MLX server), while the primary model handles all planning, reasoning, edits,\n * and tool-call synthesis.\n *\n * Everything here is INERT unless explicitly enabled via the\n * `--enable-local-inference` flag or the `HOOCODE_ROUTING_MODE` env var. On any\n * executor resolution/availability problem the caller falls back to the primary\n * model (compaction) or the raw tool result (tool-result compression). The\n * router never throws into the agent loop.\n *\n * Design and validation: see docs/local-executor-routing.md.\n */\n\nimport type { Api, Model } from \"@kolisachint/hoocode-ai\";\nimport type { ModelRegistry } from \"../model-registry.js\";\n\n/** Work that may be routed to the executor instead of the primary model. */\nexport type TurnKind = \"primary\" | \"summarization\" | \"tool-result\";\n\nexport type RoutingMode = \"primary-only\" | \"executor-for-summarization\" | \"executor-for-tool-results\";\n\nexport const ROUTING_MODES: readonly RoutingMode[] = [\n\t\"primary-only\",\n\t\"executor-for-summarization\",\n\t\"executor-for-tool-results\",\n] as const;\n\n/**\n * Tool names whose output is worth compressing (validated). Others pass\n * through. Only `bash` qualifies: its verbose output is mostly low-value noise\n * around a few load-bearing facts. `read` was measured to compress ~0% on real\n * source code (every line is a keep-line) and was removed. Fact-list tools\n * (grep/find/ls) were never compressible (every line is a distinct fact).\n */\nexport const COMPRESSIBLE_TOOLS = new Set([\"bash\"]);\n\n/** Optional local server the harness manages for the executor. */\nexport interface ExecutorServerConfig {\n\t/** Command to launch (default: \"mlx_lm.server\"). */\n\tcommand?: string;\n\t/** Extra args appended to the launch command. */\n\targs?: string[];\n\t/** Host to health-check and bind (default: derived from executor baseUrl or 127.0.0.1). */\n\thost?: string;\n\t/** Port to health-check and bind (default: derived from executor baseUrl or 8080). */\n\tport?: number;\n\t/** Max milliseconds to wait for the server to become healthy (default: 30000). */\n\tstartupTimeoutMs?: number;\n}\n\n/**\n * Executor model reference as configured in models.json.\n *\n * The size band (`minBytes`/`maxBytes`) is wired entirely from config — there\n * are no built-in byte defaults. When a bound is omitted it is not applied:\n * `minBytes` defaults to 0 (no lower gate) and `maxBytes` to unbounded. Set\n * both in models.json to gate which inputs route to the executor; on local\n * hardware a `maxBytes` guards against slow runs / GPU OOM, while a hosted or\n * large-memory executor can leave it unset (or high) to offload large inputs.\n */\nexport interface ExecutorConfig {\n\tprovider: string;\n\tmodel: string;\n\t/** Minimum input size (bytes) before local inference is attempted. Omitted = 0 (no lower gate). */\n\tminBytes?: number;\n\t/** Maximum input size (bytes); larger inputs fall back to the primary model. Omitted = unbounded. */\n\tmaxBytes?: number;\n\t/** When set, the harness spawns/health-checks/stops this local server. */\n\tserver?: ExecutorServerConfig;\n}\n\n/** `routing` block in models.json. */\nexport interface RoutingConfig {\n\tmode?: RoutingMode;\n\texecutor?: ExecutorConfig;\n}\n\nfunction isRoutingMode(value: unknown): value is RoutingMode {\n\treturn typeof value === \"string\" && (ROUTING_MODES as readonly string[]).includes(value);\n}\n\n/**\n * Resolve the effective routing mode from CLI flag, env var, and config.\n *\n * Activation requires either the flag or the env var; config alone never\n * activates routing (decision: explicit opt-in only). When activated without an\n * explicit mode, defaults to `executor-for-summarization` (the lowest-risk\n * mode). When not activated, always `primary-only`.\n */\nexport function resolveRoutingMode(opts: {\n\tenableFlag?: boolean;\n\tenvMode?: string;\n\tconfigMode?: RoutingMode;\n}): RoutingMode {\n\tconst envMode = opts.envMode?.trim();\n\tconst envActivates = envMode !== undefined && envMode !== \"\" && envMode !== \"primary-only\";\n\tconst activated = opts.enableFlag === true || envActivates;\n\tif (!activated) return \"primary-only\";\n\n\tif (envMode && isRoutingMode(envMode)) return envMode;\n\tif (opts.configMode && isRoutingMode(opts.configMode)) return opts.configMode;\n\treturn \"executor-for-summarization\";\n}\n\n/**\n * Router that decides, per turn kind, whether to use the executor model and\n * resolves it from the registry. Holds no mutable state beyond the resolved\n * executor model.\n */\nexport class LocalInferenceRouter {\n\tprivate readonly mode: RoutingMode;\n\tprivate readonly executorConfig: ExecutorConfig | undefined;\n\tprivate readonly executor: Model<Api> | undefined;\n\tprivate readonly minBytes: number;\n\tprivate readonly maxBytes: number;\n\n\tprivate constructor(\n\t\tmode: RoutingMode,\n\t\texecutorConfig: ExecutorConfig | undefined,\n\t\texecutor: Model<Api> | undefined,\n\t) {\n\t\tthis.mode = mode;\n\t\tthis.executorConfig = executorConfig;\n\t\tthis.executor = executor;\n\t\t// No built-in byte defaults: an omitted bound is simply not applied\n\t\t// (min 0 = no lower gate, max +Infinity = unbounded). The band is wired\n\t\t// entirely from the models.json executor config.\n\t\tthis.minBytes = executorConfig?.minBytes ?? 0;\n\t\tthis.maxBytes = executorConfig?.maxBytes ?? Number.POSITIVE_INFINITY;\n\t}\n\n\tstatic create(opts: {\n\t\tmode: RoutingMode;\n\t\tconfig: RoutingConfig | undefined;\n\t\tregistry: ModelRegistry;\n\t}): LocalInferenceRouter {\n\t\tconst executorConfig = opts.config?.executor;\n\t\tlet executor: Model<Api> | undefined;\n\t\tif (opts.mode !== \"primary-only\" && executorConfig) {\n\t\t\texecutor = opts.registry.find(executorConfig.provider, executorConfig.model);\n\t\t}\n\t\treturn new LocalInferenceRouter(opts.mode, executorConfig, executor);\n\t}\n\n\tgetMode(): RoutingMode {\n\t\treturn this.mode;\n\t}\n\n\t/** True when routing is active and an executor model is resolved and usable. */\n\tisExecutorAvailable(): boolean {\n\t\treturn this.mode !== \"primary-only\" && this.executor !== undefined;\n\t}\n\n\tgetExecutorConfig(): ExecutorConfig | undefined {\n\t\treturn this.executorConfig;\n\t}\n\n\t/**\n\t * Pick the model to use for a turn. Returns the executor when the mode routes\n\t * that turn kind and the executor is available; otherwise returns the primary\n\t * model.\n\t */\n\tselectModel(turnKind: TurnKind, primary: Model<Api>): Model<Api> {\n\t\tif (!this.isExecutorAvailable() || !this.executor) return primary;\n\t\tswitch (this.mode) {\n\t\t\tcase \"executor-for-summarization\":\n\t\t\t\treturn turnKind === \"summarization\" ? this.executor : primary;\n\t\t\tcase \"executor-for-tool-results\":\n\t\t\t\treturn turnKind === \"tool-result\" ? this.executor : primary;\n\t\t\tcase \"primary-only\":\n\t\t\t\treturn primary;\n\t\t}\n\t}\n\n\t/** True when an input size falls within the configured local-inference band. */\n\twithinSizeBand(bytes: number): boolean {\n\t\treturn bytes >= this.minBytes && bytes <= this.maxBytes;\n\t}\n\n\t/** The configured size band, for logging/diagnostics. */\n\tgetSizeBand(): { minBytes: number; maxBytes: number } {\n\t\treturn { minBytes: this.minBytes, maxBytes: this.maxBytes };\n\t}\n\n\t/** Whether a given tool's result should be compressed via the executor. */\n\tshouldCompressToolResult(toolName: string, contentBytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-tool-results\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\tif (!COMPRESSIBLE_TOOLS.has(toolName)) return false;\n\t\treturn this.withinSizeBand(contentBytes);\n\t}\n\n\t/**\n\t * Whether to route summarization to the executor for a conversation of the\n\t * given serialized size. Requires summarization routing active, the executor\n\t * available, and the size within the band (oversized conversations fall back\n\t * to the primary to avoid slow local runs and GPU OOM).\n\t */\n\tshouldRouteSummarization(bytes: number): boolean {\n\t\tif (this.mode !== \"executor-for-summarization\") return false;\n\t\tif (!this.isExecutorAvailable()) return false;\n\t\treturn this.withinSizeBand(bytes);\n\t}\n\n\tgetExecutorModel(): Model<Api> | undefined {\n\t\treturn this.executor;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-pool-instance.d.ts","sourceRoot":"","sources":["../../src/core/subagent-pool-instance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQlD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAqBzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,SAAS,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAG9D;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAElF","sourcesContent":["/**\n * Process-wide SubagentPool singleton.\n *\n * The subagent tool and the `/subagent` command both delegate through one pool\n * so concurrency limits, lifeguard monitoring, and token budgets are shared\n * across every delegation in the session. Created lazily on first use and torn\n * down on process exit.\n */\n\nimport { getSubagentSpawnCommand } from \"../config.js\";\nimport { poolConcurrencyForDepth } from \"./subagent-depth.js\";\nimport { SubagentPool } from \"./subagent-pool.js\";\n\nlet pool: SubagentPool | undefined;\nlet override: SubagentPool | undefined;\nlet exitHandlerRegistered = false;\n/** Latest non-default skill paths to forward to subagents, kept in sync with the resource loader. */\nlet latestSkillPaths: string[] = [];\n\n/** Get the shared pool for a given working directory, creating it on first use. */\nexport function getSubagentPool(cwd: string): SubagentPool {\n\tif (override) return override;\n\tif (!pool) {\n\t\tconst { executable, prefixArgs } = getSubagentSpawnCommand();\n\t\t// Pools created inside a nested subagent (depth >= 1) run with a reduced\n\t\t// concurrency cap so deep delegation trees stay bounded; the root keeps the\n\t\t// SubagentPool default.\n\t\tpool = new SubagentPool({\n\t\t\texecutable,\n\t\t\tprefixArgs,\n\t\t\tcwd,\n\t\t\tskillPaths: latestSkillPaths,\n\t\t\tmaxConcurrency: poolConcurrencyForDepth(),\n\t\t});\n\n\t\tif (!exitHandlerRegistered) {\n\t\t\texitHandlerRegistered = true;\n\t\t\tprocess.once(\"exit\", () => pool?.dispose());\n\t\t}\n\t}\n\treturn pool;\n}\n\n/**\n * Return the shared pool if one already exists, without creating it. Use this for\n * best-effort signaling (e.g. reporting external load) that must not spin up a pool\n * and its lifeguard just because the signal fired before any subagent was dispatched.\n */\nexport function peekSubagentPool(): SubagentPool | undefined {\n\treturn override ?? pool;\n}\n\n/**\n * Update the skill paths forwarded to every subagent.\n * Call this after the resource loader reloads or extends its skill set.\n * If the pool has already been created, updates it immediately.\n * If not, the paths will be passed in when the pool is first created.\n */\nexport function updateSubagentSkillPaths(paths: string[]): void {\n\tlatestSkillPaths = paths;\n\tpool?.updateSkillPaths(paths);\n}\n\n/** Dispose and clear the shared pool. Intended for test isolation and shutdown. */\nexport function disposeSubagentPool(): void {\n\tpool?.dispose();\n\tpool = undefined;\n\tlatestSkillPaths = [];\n}\n\n/**\n * Inject a pool instance for tests, bypassing real child-process spawning.\n * Pass `undefined` to clear the override.\n */\nexport function setSubagentPoolForTesting(testPool: SubagentPool | undefined): void {\n\toverride = testPool;\n}\n"]}
1
+ {"version":3,"file":"subagent-pool-instance.d.ts","sourceRoot":"","sources":["../../src/core/subagent-pool-instance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAuBzD;AA0BD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,SAAS,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAG9D;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAElF","sourcesContent":["/**\n * Process-wide SubagentPool singleton.\n *\n * The subagent tool and the `/subagent` command both delegate through one pool\n * so concurrency limits, lifeguard monitoring, and token budgets are shared\n * across every delegation in the session. Created lazily on first use and torn\n * down on process exit.\n */\n\nimport { getSubagentSpawnCommand } from \"../config.js\";\nimport { poolConcurrencyForDepth } from \"./subagent-depth.js\";\nimport { SubagentPool } from \"./subagent-pool.js\";\nimport { taskStore } from \"./task-store.js\";\n\nlet pool: SubagentPool | undefined;\nlet override: SubagentPool | undefined;\nlet exitHandlerRegistered = false;\n/** Latest non-default skill paths to forward to subagents, kept in sync with the resource loader. */\nlet latestSkillPaths: string[] = [];\n\n/** Get the shared pool for a given working directory, creating it on first use. */\nexport function getSubagentPool(cwd: string): SubagentPool {\n\tif (override) return override;\n\tif (!pool) {\n\t\tconst { executable, prefixArgs } = getSubagentSpawnCommand();\n\t\t// Pools created inside a nested subagent (depth >= 1) run with a reduced\n\t\t// concurrency cap so deep delegation trees stay bounded; the root keeps the\n\t\t// SubagentPool default.\n\t\tpool = new SubagentPool({\n\t\t\texecutable,\n\t\t\tprefixArgs,\n\t\t\tcwd,\n\t\t\tskillPaths: latestSkillPaths,\n\t\t\tmaxConcurrency: poolConcurrencyForDepth(),\n\t\t});\n\n\t\twireProgressToTaskStore(pool);\n\n\t\tif (!exitHandlerRegistered) {\n\t\t\texitHandlerRegistered = true;\n\t\t\tprocess.once(\"exit\", () => pool?.dispose());\n\t\t}\n\t}\n\treturn pool;\n}\n\n/**\n * Surface live subagent progress on the task panel's agent roster row. The pool\n * forwards only coarse lifecycle events; we map the currently-executing tool onto\n * the agent's `activity` and clear it between tools and on completion. This touches\n * only the roster row (keyed by agent type, a no-op if no such row exists), never\n * task nodes — so it cannot collide with the end-of-run task-tree merge. Render\n * coalescing is handled by the TUI's `requestRender`, so per-event patches are fine.\n */\nfunction wireProgressToTaskStore(p: SubagentPool): void {\n\tp.on(\"task_progress\", (data: { agent_type: string; event: { type?: string; toolName?: string } }) => {\n\t\tconst { agent_type, event } = data;\n\t\tif (event.type === \"tool_execution_start\") {\n\t\t\ttaskStore.patchAgent(agent_type, { activity: typeof event.toolName === \"string\" ? event.toolName : \"\" });\n\t\t} else if (event.type === \"tool_execution_end\" || event.type === \"turn_end\") {\n\t\t\ttaskStore.patchAgent(agent_type, { activity: \"\" });\n\t\t}\n\t});\n\tfor (const terminal of [\"task_done\", \"task_failed\", \"task_stalled\", \"task_timeout\"] as const) {\n\t\tp.on(terminal, (data: { agent_type?: string }) => {\n\t\t\tif (data.agent_type) taskStore.patchAgent(data.agent_type, { activity: \"\" });\n\t\t});\n\t}\n}\n\n/**\n * Return the shared pool if one already exists, without creating it. Use this for\n * best-effort signaling (e.g. reporting external load) that must not spin up a pool\n * and its lifeguard just because the signal fired before any subagent was dispatched.\n */\nexport function peekSubagentPool(): SubagentPool | undefined {\n\treturn override ?? pool;\n}\n\n/**\n * Update the skill paths forwarded to every subagent.\n * Call this after the resource loader reloads or extends its skill set.\n * If the pool has already been created, updates it immediately.\n * If not, the paths will be passed in when the pool is first created.\n */\nexport function updateSubagentSkillPaths(paths: string[]): void {\n\tlatestSkillPaths = paths;\n\tpool?.updateSkillPaths(paths);\n}\n\n/** Dispose and clear the shared pool. Intended for test isolation and shutdown. */\nexport function disposeSubagentPool(): void {\n\tpool?.dispose();\n\tpool = undefined;\n\tlatestSkillPaths = [];\n}\n\n/**\n * Inject a pool instance for tests, bypassing real child-process spawning.\n * Pass `undefined` to clear the override.\n */\nexport function setSubagentPoolForTesting(testPool: SubagentPool | undefined): void {\n\toverride = testPool;\n}\n"]}