gsd-pi 2.63.0-dev.351157b → 2.63.0-dev.786f0ff

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 (99) hide show
  1. package/dist/cli.js +4 -0
  2. package/dist/headless-query.js +11 -1
  3. package/dist/resources/extensions/gsd/auto/detect-stuck.js +27 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +34 -0
  5. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  6. package/dist/resources/extensions/gsd/auto-model-selection.js +32 -0
  7. package/dist/resources/extensions/gsd/auto-post-unit.js +79 -0
  8. package/dist/resources/extensions/gsd/auto-timers.js +2 -1
  9. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +87 -28
  10. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +23 -0
  11. package/dist/resources/extensions/gsd/bootstrap/system-context.js +30 -2
  12. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  13. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  14. package/dist/resources/extensions/gsd/prompts/system.md +3 -7
  15. package/dist/resources/extensions/gsd/safety/content-validator.js +73 -0
  16. package/dist/resources/extensions/gsd/safety/destructive-guard.js +34 -0
  17. package/dist/resources/extensions/gsd/safety/evidence-collector.js +109 -0
  18. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +83 -0
  19. package/dist/resources/extensions/gsd/safety/file-change-validator.js +71 -0
  20. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +91 -0
  21. package/dist/resources/extensions/gsd/safety/safety-harness.js +64 -0
  22. package/dist/resources/extensions/ollama/index.js +22 -10
  23. package/dist/resources/extensions/ollama/ollama-chat-provider.js +1 -1
  24. package/dist/update-cmd.js +4 -2
  25. package/dist/web/standalone/.next/BUILD_ID +1 -1
  26. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
  27. package/dist/web/standalone/.next/build-manifest.json +2 -2
  28. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  29. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  30. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/index.html +1 -1
  46. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -18
  53. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  54. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  55. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  56. package/package.json +1 -1
  57. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts +2 -0
  58. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts.map +1 -0
  59. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js +46 -0
  60. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js.map +1 -0
  61. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  62. package/packages/pi-coding-agent/dist/core/model-registry.js +11 -0
  63. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  64. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  65. package/packages/pi-coding-agent/dist/core/sdk.js +2 -3
  66. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  67. package/packages/pi-coding-agent/src/core/extensions/provider-registration.test.ts +81 -0
  68. package/packages/pi-coding-agent/src/core/model-registry.ts +12 -0
  69. package/packages/pi-coding-agent/src/core/sdk.ts +2 -3
  70. package/src/resources/extensions/gsd/auto/detect-stuck.ts +27 -0
  71. package/src/resources/extensions/gsd/auto/phases.ts +39 -0
  72. package/src/resources/extensions/gsd/auto/session.ts +5 -0
  73. package/src/resources/extensions/gsd/auto-model-selection.ts +36 -0
  74. package/src/resources/extensions/gsd/auto-post-unit.ts +88 -0
  75. package/src/resources/extensions/gsd/auto-timers.ts +2 -1
  76. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +86 -28
  77. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +27 -0
  78. package/src/resources/extensions/gsd/bootstrap/system-context.ts +31 -2
  79. package/src/resources/extensions/gsd/preferences-types.ts +13 -0
  80. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  81. package/src/resources/extensions/gsd/prompts/system.md +3 -7
  82. package/src/resources/extensions/gsd/safety/content-validator.ts +98 -0
  83. package/src/resources/extensions/gsd/safety/destructive-guard.ts +49 -0
  84. package/src/resources/extensions/gsd/safety/evidence-collector.ts +151 -0
  85. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +120 -0
  86. package/src/resources/extensions/gsd/safety/file-change-validator.ts +108 -0
  87. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +106 -0
  88. package/src/resources/extensions/gsd/safety/safety-harness.ts +105 -0
  89. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +211 -0
  90. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +50 -0
  91. package/src/resources/extensions/gsd/tests/git-checkpoint.test.ts +94 -0
  92. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +42 -0
  93. package/src/resources/extensions/gsd/workflow-logger.ts +2 -1
  94. package/src/resources/extensions/ollama/index.ts +20 -11
  95. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +20 -0
  96. package/src/resources/extensions/ollama/ollama-chat-provider.ts +1 -1
  97. package/src/resources/extensions/ollama/tests/ollama-chat-provider-stream.test.ts +82 -0
  98. /package/dist/web/standalone/.next/static/{QmuF-eAbuU_2MQ03t38qr → SDB1T-4NqkMjYirjjqQhr}/_buildManifest.js +0 -0
  99. /package/dist/web/standalone/.next/static/{QmuF-eAbuU_2MQ03t38qr → SDB1T-4NqkMjYirjjqQhr}/_ssgManifest.js +0 -0
@@ -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 Api,\n\tapplyCapabilityPatches,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetApiProvider,\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 \"@gsd/pi-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@gsd/pi-ai/oauth\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport AjvModule from \"ajv\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStorage } from \"./auth-storage.js\";\nimport { ModelDiscoveryCache } from \"./discovery-cache.js\";\nimport type { DiscoveredModel, DiscoveryResult } from \"./model-discovery.js\";\nimport { getDefaultTTL, getDiscoverableProviders, getDiscoveryAdapter } from \"./model-discovery.js\";\nimport { clearConfigValueCache, resolveConfigValue, resolveHeaders } from \"./resolve-config-value.js\";\nimport { isLocalModel } from \"./local-model-check.js\";\n\nconst Ajv = (AjvModule as any).default || AjvModule;\nconst ajv = new Ajv();\n\n// Schema for OpenRouter routing preferences\nconst OpenRouterRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\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 OpenAI compatibility settings\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\trequiresMistralToolIds: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(Type.Union([Type.Literal(\"openai\"), Type.Literal(\"zai\"), Type.Literal(\"qwen\")])),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\t// Reserved for future use\n});\n\nconst OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);\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\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(OpenAICompatSchema),\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\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(OpenAICompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\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\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n});\n\najv.addSchema(ModelsConfigSchema, \"ModelsConfig\");\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nexport type ProviderAuthMode = \"apiKey\" | \"oauth\" | \"externalCli\" | \"none\";\n\n/** Provider override config (baseUrl, headers, apiKey) without custom models */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tapiKey?: string;\n}\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 | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat;\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.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// Merge headers\n\tif (override.headers) {\n\t\tconst resolvedHeaders = resolveHeaders(override.headers);\n\t\tresult.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\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 discoveredModels: Model<Api>[] = [];\n\tprivate discoveryCache: ModelDiscoveryCache;\n\tprivate customProviderApiKeys: Map<string, string> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\n\tconstructor(\n\t\treadonly authStorage: AuthStorage,\n\t\treadonly modelsJsonPath: string | undefined = join(getAgentDir(), \"models.json\"),\n\t) {\n\t\tthis.discoveryCache = new ModelDiscoveryCache();\n\n\t\t// Set up fallback resolver for custom provider API keys\n\t\tthis.authStorage.setFallbackResolver((provider) => {\n\t\t\tconst keyConfig = this.customProviderApiKeys.get(provider);\n\t\t\tif (keyConfig) {\n\t\t\t\treturn resolveConfigValue(keyConfig);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\n\t\t// Refresh models when credentials change (e.g., OAuth token refresh with new model limits)\n\t\tthis.authStorage.onCredentialChange(() => this.refresh());\n\n\t\t// Load models\n\t\tthis.loadModels();\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.customProviderApiKeys.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\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\t// Apply capability patches so custom/discovered/extension models get\n\t\t// capabilities (supportsXhigh, supportsServiceTier, etc.) that the\n\t\t// static pi-ai registry applies at module load for built-in models.\n\t\tthis.models = applyCapabilityPatches(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 override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tconst resolvedHeaders = resolveHeaders(providerOverride.headers);\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\theaders: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,\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 config: ModelsConfig = JSON.parse(content);\n\n\t\t\t// Validate schema\n\t\t\tconst validate = ajv.getSchema(\"ModelsConfig\")!;\n\t\t\tif (!validate(config)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidate.errors?.map((e: any) => ` - ${e.instancePath || \"root\"}: ${e.message}`).join(\"\\n\") ||\n\t\t\t\t\t\"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\t// Additional validation\n\t\t\tthis.validateConfig(config);\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\t// Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\theaders: providerConfig.headers,\n\t\t\t\t\t\tapiKey: providerConfig.apiKey,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Store API key for fallback resolver.\n\t\t\t\tif (providerConfig.apiKey) {\n\t\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t\t}\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}\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\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\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 OR modelOverrides (or both)\n\t\t\t\tif (!providerConfig.baseUrl && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: must specify \"baseUrl\", \"modelOverrides\", or \"models\".`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Custom models are merged into provider models and 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\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi) {\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\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\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\t// Store API key config for fallback resolver\n\t\t\tif (providerConfig.apiKey) {\n\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t}\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api || providerConfig.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\t// Merge headers: provider headers are base, model headers override\n\t\t\t\t// Resolve env vars and shell commands in header values\n\t\t\t\tconst providerHeaders = resolveHeaders(providerConfig.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header with resolved API key\n\t\t\t\tif (providerConfig.authHeader && providerConfig.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(providerConfig.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Provider baseUrl is required when custom models are defined.\n\t\t\t\t// Individual models can override it with modelDef.baseUrl.\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: modelDef.baseUrl ?? providerConfig.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\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,\n\t\t\t\t\tcompat: modelDef.compat,\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.isProviderRequestReady(m.provider));\n\t}\n\n\t/**\n\t * Get auth mode for a provider.\n\t * Defaults to \"apiKey\" for built-ins and providers without explicit mode.\n\t */\n\tgetProviderAuthMode(provider: string): ProviderAuthMode {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (!config) return \"apiKey\";\n\t\tif (config.authMode) return config.authMode;\n\t\tif (config.oauth) return \"oauth\";\n\t\tif (config.apiKey) return \"apiKey\";\n\t\treturn \"apiKey\";\n\t}\n\n\t/**\n\t * Whether a provider can be used for requests/fallback without hard auth gating.\n\t */\n\tisProviderRequestReady(provider: string): boolean {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (config?.isReady) return config.isReady();\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return true;\n\t\treturn this.authStorage.hasAuth(provider);\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 * Get API key for a model.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(model.provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl });\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKeyForProvider(provider: string, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(provider, sessionId);\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.registeredProviders.set(providerName, config);\n\t\tthis.applyProviderConfig(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.customProviderApiKeys.delete(providerName);\n\t\tthis.refresh();\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\tif (!config.api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t\t}\n\t\t\tconst rawStreamSimple = config.streamSimple;\n\t\t\tconst authMode = config.authMode ?? \"apiKey\";\n\n\t\t\t// Keyless providers never see apiKey in options — enforced at registration,\n\t\t\t// not by convention. Prevents undefined from reaching any handler.\n\t\t\tconst streamSimple = (authMode === \"externalCli\" || authMode === \"none\")\n\t\t\t\t? ((model: Model<Api>, context: Context, options?: SimpleStreamOptions) => {\n\t\t\t\t\t\tconst { apiKey: _, ...opts } = options ?? {};\n\t\t\t\t\t\treturn rawStreamSimple(model, context, opts as SimpleStreamOptions);\n\t\t\t\t\t})\n\t\t\t\t: rawStreamSimple;\n\n\t\t\t// Guard: if there's already a handler registered for this API, wrap\n\t\t\t// the new one so it only fires for models from this provider and\n\t\t\t// delegates to the previous handler for all other providers. Without\n\t\t\t// this, a custom provider using api:\"anthropic-messages\" would clobber\n\t\t\t// the built-in Anthropic stream handler (#2536).\n\t\t\tconst existingProvider = getApiProvider(config.api as Api);\n\t\t\tconst scopedStream = existingProvider\n\t\t\t\t? (model: Model<Api>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream => {\n\t\t\t\t\t\tif (model.provider === providerName) {\n\t\t\t\t\t\t\treturn streamSimple(model, context, options);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn existingProvider.streamSimple(model, context, options);\n\t\t\t\t\t}\n\t\t\t\t: streamSimple;\n\n\t\t\tconst newFullStream = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) =>\n\t\t\t\tscopedStream(model, context, options as SimpleStreamOptions);\n\t\t\tconst scopedFullStream = existingProvider\n\t\t\t\t? (model: Model<Api>, context: Context, options?: Record<string, unknown>) => {\n\t\t\t\t\t\tif (model.provider === providerName) {\n\t\t\t\t\t\t\treturn newFullStream(model, context, options as SimpleStreamOptions);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn existingProvider.stream(model, context, options);\n\t\t\t\t\t}\n\t\t\t\t: newFullStream;\n\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api,\n\t\t\t\t\tstream: scopedFullStream as any,\n\t\t\t\t\tstreamSimple: scopedStream,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\t// Store API key for auth resolution\n\t\tif (config.apiKey) {\n\t\t\tthis.customProviderApiKeys.set(providerName, config.apiKey);\n\t\t}\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// Validate required fields\n\t\t\tif (!config.baseUrl) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t\t}\n\t\t\tconst authMode = config.authMode ?? (config.oauth ? \"oauth\" : config.apiKey ? \"apiKey\" : \"apiKey\");\n\t\t\tif (authMode === \"apiKey\" && !config.apiKey && !config.oauth) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when authMode is \"apiKey\" (the default). ` +\n\t\t\t\t\t`Set authMode to \"externalCli\" or \"none\" for keyless providers.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ((authMode === \"externalCli\" || authMode === \"none\") && !config.streamSimple) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"streamSimple\" is required when authMode is \"${authMode}\". ` +\n\t\t\t\t\t`Keyless providers must supply their own stream handler.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ((authMode === \"externalCli\" || authMode === \"none\") && config.apiKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"apiKey\" cannot be set when authMode is \"${authMode}\". ` +\n\t\t\t\t\t`Keyless providers should not provide API key credentials.`,\n\t\t\t\t);\n\t\t\t}\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\tif (!api) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t\t}\n\n\t\t\t\t// Merge headers\n\t\t\t\tconst providerHeaders = resolveHeaders(config.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header\n\t\t\t\tif (config.authHeader && config.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(config.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\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: config.baseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning,\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,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t\tproviderOptions: modelDef.providerOptions,\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\n\t\t\t// Ensure newly added extension models get capability patches\n\t\t\tthis.models = applyCapabilityPatches(this.models);\n\t\t} else if (config.baseUrl) {\n\t\t\t// Override-only: update baseUrl/headers for existing models\n\t\t\tconst resolvedHeaders = resolveHeaders(config.headers);\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\theaders: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Discover models from all providers that support discovery.\n\t * Results are cached and merged into the registry (never overrides existing models).\n\t */\n\tasync discoverModels(providers?: string[]): Promise<DiscoveryResult[]> {\n\t\tconst targetProviders = providers ?? getDiscoverableProviders();\n\t\tconst results: DiscoveryResult[] = [];\n\n\t\tfor (const providerName of targetProviders) {\n\t\t\tconst adapter = getDiscoveryAdapter(providerName);\n\t\t\tif (!adapter.supportsDiscovery) continue;\n\n\t\t\t// Skip if cache is still fresh\n\t\t\tif (!this.discoveryCache.isStale(providerName)) {\n\t\t\t\tconst cached = this.discoveryCache.get(providerName);\n\t\t\t\tif (cached) {\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tprovider: providerName,\n\t\t\t\t\t\tmodels: cached.models,\n\t\t\t\t\t\tfetchedAt: cached.fetchedAt,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = await this.authStorage.getApiKey(providerName);\n\t\t\t\tif (!apiKey && !this.isProviderRequestReady(providerName)) continue;\n\n\t\t\t\tconst models = await adapter.fetchModels(apiKey ?? \"\", undefined);\n\t\t\t\tthis.discoveryCache.set(providerName, models);\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels,\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Convert and merge discovered models, then apply capability patches\n\t\tthis.discoveredModels = applyCapabilityPatches(this.convertDiscoveredModels(results));\n\t\treturn results;\n\t}\n\n\t/**\n\t * Get all models including discovered ones.\n\t * Discovered models are appended but never override existing models.\n\t */\n\tgetAllWithDiscovered(): Model<Api>[] {\n\t\tconst existingIds = new Set(this.models.map((m) => `${m.provider}/${m.id}`));\n\t\tconst unique = this.discoveredModels.filter((m) => !existingIds.has(`${m.provider}/${m.id}`));\n\t\treturn [...this.models, ...unique];\n\t}\n\n\t/**\n\t * Check if a model was added via discovery (not built-in or custom).\n\t */\n\tisDiscovered(model: Model<Api>): boolean {\n\t\treturn this.discoveredModels.some((m) => m.provider === model.provider && m.id === model.id);\n\t}\n\n\t/**\n\t * Get the discovery cache instance.\n\t */\n\tgetDiscoveryCache(): ModelDiscoveryCache {\n\t\treturn this.discoveryCache;\n\t}\n\n\t/**\n\t * Convert DiscoveryResult[] into Model<Api>[] with default values.\n\t */\n\tprivate convertDiscoveredModels(results: DiscoveryResult[]): Model<Api>[] {\n\t\tconst converted: Model<Api>[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.error) continue;\n\t\t\tfor (const dm of result.models) {\n\t\t\t\tconverted.push({\n\t\t\t\t\tid: dm.id,\n\t\t\t\t\tname: dm.name ?? dm.id,\n\t\t\t\t\tapi: \"openai\" as Api,\n\t\t\t\t\tprovider: result.provider,\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\treasoning: dm.reasoning ?? false,\n\t\t\t\t\tinput: dm.input ?? [\"text\"],\n\t\t\t\t\tcost: dm.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\t\tcontextWindow: dm.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: dm.maxTokens ?? 16384,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\t\treturn converted;\n\t}\n\n\t/**\n\t * Check if a model's baseUrl points to a local endpoint.\n\t * Delegates to standalone isLocalModel() function.\n\t */\n\tstatic isLocalModel(model: Model<Api>): boolean {\n\t\treturn isLocalModel(model);\n\t}\n\n\t/**\n\t * Check if all models in the registry are local.\n\t * Returns true only if every model passes isLocalModel().\n\t * Returns false if there are no models.\n\t */\n\tisAllLocalChain(): boolean {\n\t\tconst models = this.getAll();\n\t\tif (models.length === 0) return false;\n\t\treturn models.every((m) => isLocalModel(m));\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tauthMode?: ProviderAuthMode;\n\t/** Optional readiness check. Called by isProviderRequestReady() before default auth checks.\n\t * Trusted at the same level as extension code — extensions already have arbitrary code execution. */\n\tisReady?: () => boolean;\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\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\tproviderOptions?: Record<string, unknown>;\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 Api,\n\tapplyCapabilityPatches,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetApiProvider,\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 \"@gsd/pi-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@gsd/pi-ai/oauth\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport AjvModule from \"ajv\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStorage } from \"./auth-storage.js\";\nimport { ModelDiscoveryCache } from \"./discovery-cache.js\";\nimport type { DiscoveredModel, DiscoveryResult } from \"./model-discovery.js\";\nimport { getDefaultTTL, getDiscoverableProviders, getDiscoveryAdapter } from \"./model-discovery.js\";\nimport { clearConfigValueCache, resolveConfigValue, resolveHeaders } from \"./resolve-config-value.js\";\nimport { isLocalModel } from \"./local-model-check.js\";\n\nconst Ajv = (AjvModule as any).default || AjvModule;\nconst ajv = new Ajv();\n\n// Schema for OpenRouter routing preferences\nconst OpenRouterRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\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 OpenAI compatibility settings\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\trequiresMistralToolIds: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(Type.Union([Type.Literal(\"openai\"), Type.Literal(\"zai\"), Type.Literal(\"qwen\")])),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\t// Reserved for future use\n});\n\nconst OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);\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\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(OpenAICompatSchema),\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\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(OpenAICompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\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\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n});\n\najv.addSchema(ModelsConfigSchema, \"ModelsConfig\");\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nexport type ProviderAuthMode = \"apiKey\" | \"oauth\" | \"externalCli\" | \"none\";\n\n/** Provider override config (baseUrl, headers, apiKey) without custom models */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tapiKey?: string;\n}\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 | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat;\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.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// Merge headers\n\tif (override.headers) {\n\t\tconst resolvedHeaders = resolveHeaders(override.headers);\n\t\tresult.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\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 discoveredModels: Model<Api>[] = [];\n\tprivate discoveryCache: ModelDiscoveryCache;\n\tprivate customProviderApiKeys: Map<string, string> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\n\tconstructor(\n\t\treadonly authStorage: AuthStorage,\n\t\treadonly modelsJsonPath: string | undefined = join(getAgentDir(), \"models.json\"),\n\t) {\n\t\tthis.discoveryCache = new ModelDiscoveryCache();\n\n\t\t// Set up fallback resolver for custom provider API keys\n\t\tthis.authStorage.setFallbackResolver((provider) => {\n\t\t\tconst keyConfig = this.customProviderApiKeys.get(provider);\n\t\t\tif (keyConfig) {\n\t\t\t\treturn resolveConfigValue(keyConfig);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\n\t\t// Refresh models when credentials change (e.g., OAuth token refresh with new model limits)\n\t\tthis.authStorage.onCredentialChange(() => this.refresh());\n\n\t\t// Load models\n\t\tthis.loadModels();\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.customProviderApiKeys.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\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\t// Apply capability patches so custom/discovered/extension models get\n\t\t// capabilities (supportsXhigh, supportsServiceTier, etc.) that the\n\t\t// static pi-ai registry applies at module load for built-in models.\n\t\tthis.models = applyCapabilityPatches(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 override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tconst resolvedHeaders = resolveHeaders(providerOverride.headers);\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\theaders: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,\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 config: ModelsConfig = JSON.parse(content);\n\n\t\t\t// Validate schema\n\t\t\tconst validate = ajv.getSchema(\"ModelsConfig\")!;\n\t\t\tif (!validate(config)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidate.errors?.map((e: any) => ` - ${e.instancePath || \"root\"}: ${e.message}`).join(\"\\n\") ||\n\t\t\t\t\t\"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\t// Additional validation\n\t\t\tthis.validateConfig(config);\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\t// Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\theaders: providerConfig.headers,\n\t\t\t\t\t\tapiKey: providerConfig.apiKey,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Store API key for fallback resolver.\n\t\t\t\tif (providerConfig.apiKey) {\n\t\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t\t}\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}\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\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\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 OR modelOverrides (or both)\n\t\t\t\tif (!providerConfig.baseUrl && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: must specify \"baseUrl\", \"modelOverrides\", or \"models\".`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Custom models are merged into provider models and 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\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi) {\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\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\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\t// Store API key config for fallback resolver\n\t\t\tif (providerConfig.apiKey) {\n\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t}\n\n\t\t\t// Register custom providers so isProviderRequestReady() can find\n\t\t\t// them (#3531). Without this, models.json providers with apiKey\n\t\t\t// fail the auth check and are invisible to the fallback resolver.\n\t\t\tif (!this.registeredProviders.has(providerName)) {\n\t\t\t\tthis.registeredProviders.set(providerName, {\n\t\t\t\t\tauthMode: providerConfig.apiKey ? \"apiKey\" : \"none\",\n\t\t\t\t\tapiKey: providerConfig.apiKey,\n\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\tisReady: providerConfig.apiKey ? () => true : undefined,\n\t\t\t\t} as any);\n\t\t\t}\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api || providerConfig.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\t// Merge headers: provider headers are base, model headers override\n\t\t\t\t// Resolve env vars and shell commands in header values\n\t\t\t\tconst providerHeaders = resolveHeaders(providerConfig.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header with resolved API key\n\t\t\t\tif (providerConfig.authHeader && providerConfig.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(providerConfig.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Provider baseUrl is required when custom models are defined.\n\t\t\t\t// Individual models can override it with modelDef.baseUrl.\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: modelDef.baseUrl ?? providerConfig.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\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,\n\t\t\t\t\tcompat: modelDef.compat,\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.isProviderRequestReady(m.provider));\n\t}\n\n\t/**\n\t * Get auth mode for a provider.\n\t * Defaults to \"apiKey\" for built-ins and providers without explicit mode.\n\t */\n\tgetProviderAuthMode(provider: string): ProviderAuthMode {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (!config) return \"apiKey\";\n\t\tif (config.authMode) return config.authMode;\n\t\tif (config.oauth) return \"oauth\";\n\t\tif (config.apiKey) return \"apiKey\";\n\t\treturn \"apiKey\";\n\t}\n\n\t/**\n\t * Whether a provider can be used for requests/fallback without hard auth gating.\n\t */\n\tisProviderRequestReady(provider: string): boolean {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (config?.isReady) return config.isReady();\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return true;\n\t\treturn this.authStorage.hasAuth(provider);\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 * Get API key for a model.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(model.provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl });\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKeyForProvider(provider: string, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(provider, sessionId);\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.registeredProviders.set(providerName, config);\n\t\tthis.applyProviderConfig(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.customProviderApiKeys.delete(providerName);\n\t\tthis.refresh();\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\tif (!config.api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t\t}\n\t\t\tconst rawStreamSimple = config.streamSimple;\n\t\t\tconst authMode = config.authMode ?? \"apiKey\";\n\n\t\t\t// Keyless providers never see apiKey in options — enforced at registration,\n\t\t\t// not by convention. Prevents undefined from reaching any handler.\n\t\t\tconst streamSimple = (authMode === \"externalCli\" || authMode === \"none\")\n\t\t\t\t? ((model: Model<Api>, context: Context, options?: SimpleStreamOptions) => {\n\t\t\t\t\t\tconst { apiKey: _, ...opts } = options ?? {};\n\t\t\t\t\t\treturn rawStreamSimple(model, context, opts as SimpleStreamOptions);\n\t\t\t\t\t})\n\t\t\t\t: rawStreamSimple;\n\n\t\t\t// Guard: if there's already a handler registered for this API, wrap\n\t\t\t// the new one so it only fires for models from this provider and\n\t\t\t// delegates to the previous handler for all other providers. Without\n\t\t\t// this, a custom provider using api:\"anthropic-messages\" would clobber\n\t\t\t// the built-in Anthropic stream handler (#2536).\n\t\t\tconst existingProvider = getApiProvider(config.api as Api);\n\t\t\tconst scopedStream = existingProvider\n\t\t\t\t? (model: Model<Api>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream => {\n\t\t\t\t\t\tif (model.provider === providerName) {\n\t\t\t\t\t\t\treturn streamSimple(model, context, options);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn existingProvider.streamSimple(model, context, options);\n\t\t\t\t\t}\n\t\t\t\t: streamSimple;\n\n\t\t\tconst newFullStream = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) =>\n\t\t\t\tscopedStream(model, context, options as SimpleStreamOptions);\n\t\t\tconst scopedFullStream = existingProvider\n\t\t\t\t? (model: Model<Api>, context: Context, options?: Record<string, unknown>) => {\n\t\t\t\t\t\tif (model.provider === providerName) {\n\t\t\t\t\t\t\treturn newFullStream(model, context, options as SimpleStreamOptions);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn existingProvider.stream(model, context, options);\n\t\t\t\t\t}\n\t\t\t\t: newFullStream;\n\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api,\n\t\t\t\t\tstream: scopedFullStream as any,\n\t\t\t\t\tstreamSimple: scopedStream,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\t// Store API key for auth resolution\n\t\tif (config.apiKey) {\n\t\t\tthis.customProviderApiKeys.set(providerName, config.apiKey);\n\t\t}\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// Validate required fields\n\t\t\tif (!config.baseUrl) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t\t}\n\t\t\tconst authMode = config.authMode ?? (config.oauth ? \"oauth\" : config.apiKey ? \"apiKey\" : \"apiKey\");\n\t\t\tif (authMode === \"apiKey\" && !config.apiKey && !config.oauth) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when authMode is \"apiKey\" (the default). ` +\n\t\t\t\t\t`Set authMode to \"externalCli\" or \"none\" for keyless providers.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ((authMode === \"externalCli\" || authMode === \"none\") && !config.streamSimple) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"streamSimple\" is required when authMode is \"${authMode}\". ` +\n\t\t\t\t\t`Keyless providers must supply their own stream handler.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ((authMode === \"externalCli\" || authMode === \"none\") && config.apiKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Provider ${providerName}: \"apiKey\" cannot be set when authMode is \"${authMode}\". ` +\n\t\t\t\t\t`Keyless providers should not provide API key credentials.`,\n\t\t\t\t);\n\t\t\t}\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\tif (!api) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t\t}\n\n\t\t\t\t// Merge headers\n\t\t\t\tconst providerHeaders = resolveHeaders(config.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header\n\t\t\t\tif (config.authHeader && config.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(config.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\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: config.baseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning,\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,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t\tproviderOptions: modelDef.providerOptions,\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\n\t\t\t// Ensure newly added extension models get capability patches\n\t\t\tthis.models = applyCapabilityPatches(this.models);\n\t\t} else if (config.baseUrl) {\n\t\t\t// Override-only: update baseUrl/headers for existing models\n\t\t\tconst resolvedHeaders = resolveHeaders(config.headers);\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\theaders: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Discover models from all providers that support discovery.\n\t * Results are cached and merged into the registry (never overrides existing models).\n\t */\n\tasync discoverModels(providers?: string[]): Promise<DiscoveryResult[]> {\n\t\tconst targetProviders = providers ?? getDiscoverableProviders();\n\t\tconst results: DiscoveryResult[] = [];\n\n\t\tfor (const providerName of targetProviders) {\n\t\t\tconst adapter = getDiscoveryAdapter(providerName);\n\t\t\tif (!adapter.supportsDiscovery) continue;\n\n\t\t\t// Skip if cache is still fresh\n\t\t\tif (!this.discoveryCache.isStale(providerName)) {\n\t\t\t\tconst cached = this.discoveryCache.get(providerName);\n\t\t\t\tif (cached) {\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tprovider: providerName,\n\t\t\t\t\t\tmodels: cached.models,\n\t\t\t\t\t\tfetchedAt: cached.fetchedAt,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = await this.authStorage.getApiKey(providerName);\n\t\t\t\tif (!apiKey && !this.isProviderRequestReady(providerName)) continue;\n\n\t\t\t\tconst models = await adapter.fetchModels(apiKey ?? \"\", undefined);\n\t\t\t\tthis.discoveryCache.set(providerName, models);\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels,\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Convert and merge discovered models, then apply capability patches\n\t\tthis.discoveredModels = applyCapabilityPatches(this.convertDiscoveredModels(results));\n\t\treturn results;\n\t}\n\n\t/**\n\t * Get all models including discovered ones.\n\t * Discovered models are appended but never override existing models.\n\t */\n\tgetAllWithDiscovered(): Model<Api>[] {\n\t\tconst existingIds = new Set(this.models.map((m) => `${m.provider}/${m.id}`));\n\t\tconst unique = this.discoveredModels.filter((m) => !existingIds.has(`${m.provider}/${m.id}`));\n\t\treturn [...this.models, ...unique];\n\t}\n\n\t/**\n\t * Check if a model was added via discovery (not built-in or custom).\n\t */\n\tisDiscovered(model: Model<Api>): boolean {\n\t\treturn this.discoveredModels.some((m) => m.provider === model.provider && m.id === model.id);\n\t}\n\n\t/**\n\t * Get the discovery cache instance.\n\t */\n\tgetDiscoveryCache(): ModelDiscoveryCache {\n\t\treturn this.discoveryCache;\n\t}\n\n\t/**\n\t * Convert DiscoveryResult[] into Model<Api>[] with default values.\n\t */\n\tprivate convertDiscoveredModels(results: DiscoveryResult[]): Model<Api>[] {\n\t\tconst converted: Model<Api>[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.error) continue;\n\t\t\tfor (const dm of result.models) {\n\t\t\t\tconverted.push({\n\t\t\t\t\tid: dm.id,\n\t\t\t\t\tname: dm.name ?? dm.id,\n\t\t\t\t\tapi: \"openai\" as Api,\n\t\t\t\t\tprovider: result.provider,\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\treasoning: dm.reasoning ?? false,\n\t\t\t\t\tinput: dm.input ?? [\"text\"],\n\t\t\t\t\tcost: dm.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\t\tcontextWindow: dm.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: dm.maxTokens ?? 16384,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\t\treturn converted;\n\t}\n\n\t/**\n\t * Check if a model's baseUrl points to a local endpoint.\n\t * Delegates to standalone isLocalModel() function.\n\t */\n\tstatic isLocalModel(model: Model<Api>): boolean {\n\t\treturn isLocalModel(model);\n\t}\n\n\t/**\n\t * Check if all models in the registry are local.\n\t * Returns true only if every model passes isLocalModel().\n\t * Returns false if there are no models.\n\t */\n\tisAllLocalChain(): boolean {\n\t\tconst models = this.getAll();\n\t\tif (models.length === 0) return false;\n\t\treturn models.every((m) => isLocalModel(m));\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tauthMode?: ProviderAuthMode;\n\t/** Optional readiness check. Called by isProviderRequestReady() before default auth checks.\n\t * Trusted at the same level as extension code — extensions already have arbitrary code execution. */\n\tisReady?: () => boolean;\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\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\tproviderOptions?: Record<string, unknown>;\n\t}>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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"}
@@ -97,9 +97,8 @@ export async function createAgentSession(options = {}) {
97
97
  for (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {
98
98
  modelRegistry.registerProvider(name, config);
99
99
  }
100
- // Note: we do NOT clear pendingProviderRegistrations here bindCore() will iterate
101
- // an empty array harmlessly, and clearing here would require the runtime to track
102
- // whether the flush already happened.
100
+ // Clear the queue so bindCore() doesn't re-register the same providers.
101
+ extensionsForModelResolution.runtime.pendingProviderRegistrations = [];
103
102
  // If still no model, use findInitialModel (checks settings default, then provider defaults)
104
103
  if (!model) {
105
104
  const result = await findInitialModel({
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAyC,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EACN,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,EACN,aAAa,EACb,QAAQ,EAGR,SAAS,GACT,MAAM,kBAAkB,CAAC;AA6D1B,OAAO;AACN,sCAAsC;AACtC,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,aAAa,EACb,QAAQ,IAAI,eAAe;AAC3B,kCAAkC;AAClC,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY;AACZ,qBAAqB;AACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACtB,CAAC;AAEF,mBAAmB;AAEnB,SAAS,kBAAkB;IAC1B,OAAO,WAAW,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAqC,EAAE;IAC/E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,EAAE,CAAC;IAC1D,IAAI,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAE5C,uDAAuD;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,aAAa,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAE1F,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAE5E,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,cAAc,GAAG,IAAI,qBAAqB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;QAC/E,MAAM,cAAc,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC/B,CAAC;IAED,gDAAgD;IAChD,MAAM,eAAe,GAAG,cAAc,CAAC,mBAAmB,EAAE,CAAC;IAC7D,MAAM,kBAAkB,GAAG,eAAe,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAC;IAE5G,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC1B,IAAI,oBAAwC,CAAC;IAE7C,oDAAoD;IACpD,IAAI,CAAC,KAAK,IAAI,kBAAkB,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxG,IAAI,aAAa,IAAI,CAAC,MAAM,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YACrE,KAAK,GAAG,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,oBAAoB,GAAG,2BAA2B,eAAe,CAAC,KAAK,CAAC,QAAQ,IAAI,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACrH,CAAC;IACF,CAAC;IAED,2FAA2F;IAC3F,0FAA0F;IAC1F,6EAA6E;IAC7E,MAAM,4BAA4B,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC;IACpE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,4BAA4B,CAAC,OAAO,CAAC,4BAA4B,EAAE,CAAC;QAClG,aAAa,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,oFAAoF;IACpF,kFAAkF;IAClF,sCAAsC;IAEtC,4FAA4F;IAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACrC,YAAY,EAAE,EAAE;YAChB,YAAY,EAAE,kBAAkB;YAChC,eAAe,EAAE,eAAe,CAAC,kBAAkB,EAAE;YACrD,cAAc,EAAE,eAAe,CAAC,eAAe,EAAE;YACjD,oBAAoB,EAAE,eAAe,CAAC,uBAAuB,EAAE;YAC/D,aAAa;SACb,CAAC,CAAC;QACH,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,oBAAoB,GAAG,+EAA+E,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,sCAAsC,CAAC;QACjL,CAAC;aAAM,IAAI,oBAAoB,EAAE,CAAC;YACjC,oBAAoB,IAAI,WAAW,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;QACjE,CAAC;IACF,CAAC;IAED,IAAI,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAE1C,sDAAsD;IACtD,IAAI,aAAa,KAAK,SAAS,IAAI,kBAAkB,EAAE,CAAC;QACvD,aAAa,GAAG,gBAAgB;YAC/B,CAAC,CAAE,eAAe,CAAC,aAA+B;YAClD,CAAC,CAAC,CAAC,eAAe,CAAC,uBAAuB,EAAE,IAAI,sBAAsB,CAAC,CAAC;IAC1E,CAAC;IAED,gCAAgC;IAChC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACjC,aAAa,GAAG,eAAe,CAAC,uBAAuB,EAAE,IAAI,sBAAsB,CAAC;IACrF,CAAC;IAED,8BAA8B;IAC9B,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAChC,aAAa,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,sBAAsB,GAAe,QAAQ,KAAK,UAAU;QACjE,CAAC,CAAC,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC;QAC5D,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,sBAAsB,GAAe,OAAO,CAAC,KAAK;QACvD,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC;QAC9E,CAAC,CAAC,sBAAsB,CAAC;IAE1B,IAAI,KAAY,CAAC;IAEjB,+FAA+F;IAC/F,MAAM,2BAA2B,GAAG,CAAC,QAAwB,EAAa,EAAE;QAC3E,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACzC,+DAA+D;QAC/D,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,EAAE,CAAC;YACvC,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,6EAA6E;QAC7E,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACtD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;gBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;oBAC1D,IAAI,SAAS,EAAE,CAAC;wBACf,MAAM,eAAe,GAAG,OAAO;6BAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACV,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CACtF;6BACA,MAAM,CACN,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;wBACb,wDAAwD;wBACxD,CAAC,CACA,CAAC,CAAC,IAAI,KAAK,MAAM;4BACjB,CAAC,CAAC,IAAI,KAAK,4BAA4B;4BACvC,CAAC,GAAG,CAAC;4BACL,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;4BACzB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAoC,CAAC,IAAI,KAAK,4BAA4B,CACpF,CACF,CAAC;wBACH,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;oBAC7C,CAAC;gBACF,CAAC;YACF,CAAC;YACD,OAAO,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAkC,EAAE,CAAC;IAE7D,KAAK,GAAG,IAAI,KAAK,CAAC;QACjB,YAAY,EAAE;YACb,YAAY,EAAE,EAAE;YAChB,KAAK;YACL,aAAa;YACb,KAAK,EAAE,EAAE;SACT;QACD,YAAY,EAAE,2BAA2B;QACzC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACrD,OAAO,OAAO,CAAC;YAChB,CAAC;YACD,OAAO,MAAM,CAAC,yBAAyB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAChE,CAAC;QACD,SAAS,EAAE,cAAc,CAAC,YAAY,EAAE;QACxC,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAC1C,IAAI,CAAC,MAAM;gBAAE,OAAO,QAAQ,CAAC;YAC7B,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;QACD,YAAY,EAAE,eAAe,CAAC,eAAe,EAAE;QAC/C,YAAY,EAAE,eAAe,CAAC,eAAe,EAAE;QAC/C,SAAS,EAAE,eAAe,CAAC,YAAY,EAAE;QACzC,eAAe,EAAE,eAAe,CAAC,kBAAkB,EAAE;QACrD,eAAe,EAAE,eAAe,CAAC,gBAAgB,EAAE,CAAC,UAAU;QAC9D,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,aAAa;QAC7F,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC7B,wDAAwD;YACxD,sDAAsD;YACtD,MAAM,gBAAgB,GAAG,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;YACjE,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACtC,CAAC;YACD,MAAM,QAAQ,GAAG,aAAa,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;YACrE,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACvD,OAAO,SAAS,CAAC;YAClB,CAAC;YAED,yEAAyE;YACzE,sEAAsE;YACtE,MAAM,WAAW,GAAG,CAAC,CAAC;YACtB,MAAM,WAAW,GAAG,IAAI,CAAC;YACzB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;gBACzD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;gBACvE,IAAI,GAAG;oBAAE,OAAO,GAAG,CAAC;gBAEpB,4DAA4D;gBAC5D,IAAI,OAAO,IAAI,WAAW;oBAAE,MAAM;gBAElC,sEAAsE;gBACtE,sDAAsD;gBACtD,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACpE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;gBAChC,MAAM,OAAO,GAAG,KAAK,IAAI,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC3D,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO;oBAAE,MAAM;gBAEhC,gDAAgD;gBAChD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;YAC1E,CAAC;YAED,kDAAkD;YAClD,4DAA4D;YAC5D,iEAAiE;YACjE,gEAAgE;YAChE,gBAAgB;YAChB,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACpE,IAAI,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACd,wBAAwB,gBAAgB,qDAAqD;oBAC5F,iEAAiE,CAClE,CAAC;YACH,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;YAChC,MAAM,OAAO,GAAG,KAAK,IAAI,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC3D,IAAI,OAAO,EAAE,CAAC;gBACb,6EAA6E;gBAC7E,gFAAgF;gBAChF,IAAI,aAAa,CAAC,WAAW,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBAC5E,MAAM,IAAI,KAAK,CACd,6BAA6B,gBAAgB,KAAK;wBACjD,6DAA6D,CAC9D,CAAC;gBACH,CAAC;gBACD,MAAM,IAAI,KAAK,CACd,8BAA8B,gBAAgB,KAAK;oBAClD,0DAA0D;oBAC1D,eAAe,gBAAgB,uBAAuB,CACvD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,KAAK,CACd,yBAAyB,gBAAgB,KAAK;gBAC7C,sDAAsD,gBAAgB,IAAI,CAC3E,CAAC;QACH,CAAC;KACD,CAAC,CAAC;IAEH,gDAAgD;IAChD,IAAI,kBAAkB,EAAE,CAAC;QACxB,KAAK,CAAC,eAAe,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,cAAc,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;SAAM,CAAC;QACP,2FAA2F;QAC3F,IAAI,KAAK,EAAE,CAAC;YACX,cAAc,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,cAAc,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAChC,KAAK;QACL,cAAc;QACd,eAAe;QACf,GAAG;QACH,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,cAAc;QACd,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa;QACb,sBAAsB;QACtB,kBAAkB;KAClB,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC;IAExD,OAAO;QACN,OAAO;QACP,gBAAgB;QAChB,oBAAoB;KACpB,CAAC;AACH,CAAC","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport type { Message, Model } from \"@gsd/pi-ai\";\nimport { getAgentDir, getDocsPath } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tallTools,\n\tbashTool,\n\tcodingTools,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\teditTool,\n\tfindTool,\n\tgrepTool,\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n\tlsTool,\n\treadOnlyTools,\n\treadTool,\n\ttype Tool,\n\ttype ToolName,\n\twriteTool,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: new ModelRegistry(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/** Built-in tools to use. Default: codingTools [read, bash, edit, write] */\n\ttools?: Tool[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandLocation,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\t// Pre-built tools (use process.cwd())\n\treadTool,\n\tbashTool,\n\teditTool,\n\twriteTool,\n\tgrepTool,\n\tfindTool,\n\tlsTool,\n\tcodingTools,\n\treadOnlyTools,\n\tallTools as allBuiltInTools,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\t// Hashline edit mode\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@gsd/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? new ModelRegistry(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd);\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && (await modelRegistry.getApiKey(restoredModel))) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// Flush extension provider registrations so extension-provided models (e.g. claude-code/*)\n\t// are available in the registry before model resolution. Without this, findInitialModel()\n\t// cannot find extension models and falls back to built-in providers (#3534).\n\tconst extensionsForModelResolution = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\t// Note: we do NOT clear pendingProviderRegistrations here — bindCore() will iterate\n\t// an empty array harmlessly, and clearing here would require the runtime to track\n\t// whether the flush already happened.\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `No models available. Use /login or set an API key environment variable. See ${join(getDocsPath(), \"providers.md\")}. Then use /model to select a model.`;\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model || !model.reasoning) {\n\t\tthinkingLevel = \"off\";\n\t}\n\n\tconst editMode = settingsManager.getEditMode();\n\tconst defaultActiveToolNames: ToolName[] = editMode === \"hashline\"\n\t\t? [\"hashline_read\", \"bash\", \"hashline_edit\", \"write\", \"lsp\"]\n\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"lsp\"];\n\tconst initialActiveToolNames: ToolName[] = options.tools\n\t\t? options.tools.map((t) => t.name).filter((n): n is ToolName => n in allTools)\n\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tonPayload: async (payload, currentModel) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload, currentModel);\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getRetrySettings().maxDelayMs,\n\t\texternalToolExecution: (m) => modelRegistry.getProviderAuthMode(m.provider) === \"externalCli\",\n\t\tgetApiKey: async (provider) => {\n\t\t\t// Use the provider argument from the in-flight request;\n\t\t\t// agent.state.model may already be switched mid-turn.\n\t\t\tconst resolvedProvider = provider || agent.state.model?.provider;\n\t\t\tif (!resolvedProvider) {\n\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t}\n\t\t\tconst authMode = modelRegistry.getProviderAuthMode(resolvedProvider);\n\t\t\tif (authMode === \"externalCli\" || authMode === \"none\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Retry key resolution with backoff to handle transient network failures\n\t\t\t// (e.g., OAuth token refresh failing due to brief connectivity loss).\n\t\t\tconst maxAttempts = 3;\n\t\t\tconst baseDelayMs = 2000;\n\t\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\t\tconst key = await modelRegistry.getApiKeyForProvider(resolvedProvider);\n\t\t\t\tif (key) return key;\n\n\t\t\t\t// On the last attempt, fall through to error handling below\n\t\t\t\tif (attempt >= maxAttempts) break;\n\n\t\t\t\t// Only retry if credentials exist (network issue) — no point retrying\n\t\t\t\t// when there are genuinely no credentials configured.\n\t\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\t\tconst model = agent.state.model;\n\t\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\t\tif (!hasAuth && !isOAuth) break;\n\n\t\t\t\t// Wait with exponential backoff before retrying\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, baseDelayMs * attempt));\n\t\t\t}\n\n\t\t\t// All retries exhausted — throw descriptive error\n\t\t\t// Check if credentials exist but are temporarily backed off\n\t\t\t// (e.g., after a 429 quota exhaustion). Provide a specific error\n\t\t\t// so the retry handler knows this is transient, not a permanent\n\t\t\t// auth failure.\n\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\tif (hasAuth) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`All credentials for \"${resolvedProvider}\" are temporarily backed off due to rate limiting. ` +\n\t\t\t\t\t\t`The request will be retried automatically when backoff expires.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst model = agent.state.model;\n\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\tif (isOAuth) {\n\t\t\t\t// If credentials exist but are all in a backoff window (quota / rate-limit),\n\t\t\t\t// surface a specific message instead of the misleading \"Authentication failed\".\n\t\t\t\tif (modelRegistry.authStorage.areAllCredentialsBackedOff(resolvedProvider)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Rate limit in effect for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t\t`Please wait before retrying or switch to a different model.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Authentication failed for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t`Credentials may have expired or network is unavailable. ` +\n\t\t\t\t\t\t`Run '/login ${resolvedProvider}' to re-authenticate.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`No API key found for \"${resolvedProvider}\". ` +\n\t\t\t\t\t`Set an API key environment variable or run '/login ${resolvedProvider}'.`,\n\t\t\t);\n\t\t},\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.replaceMessages(existingSession.messages);\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\textensionRunnerRef,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport type { Message, Model } from \"@gsd/pi-ai\";\nimport { getAgentDir, getDocsPath } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tallTools,\n\tbashTool,\n\tcodingTools,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\teditTool,\n\tfindTool,\n\tgrepTool,\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n\tlsTool,\n\treadOnlyTools,\n\treadTool,\n\ttype Tool,\n\ttype ToolName,\n\twriteTool,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: new ModelRegistry(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/** Built-in tools to use. Default: codingTools [read, bash, edit, write] */\n\ttools?: Tool[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandLocation,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\t// Pre-built tools (use process.cwd())\n\treadTool,\n\tbashTool,\n\teditTool,\n\twriteTool,\n\tgrepTool,\n\tfindTool,\n\tlsTool,\n\tcodingTools,\n\treadOnlyTools,\n\tallTools as allBuiltInTools,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\t// Hashline edit mode\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@gsd/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? new ModelRegistry(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd);\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && (await modelRegistry.getApiKey(restoredModel))) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// Flush extension provider registrations so extension-provided models (e.g. claude-code/*)\n\t// are available in the registry before model resolution. Without this, findInitialModel()\n\t// cannot find extension models and falls back to built-in providers (#3534).\n\tconst extensionsForModelResolution = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\t// Clear the queue so bindCore() doesn't re-register the same providers.\n\textensionsForModelResolution.runtime.pendingProviderRegistrations = [];\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `No models available. Use /login or set an API key environment variable. See ${join(getDocsPath(), \"providers.md\")}. Then use /model to select a model.`;\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model || !model.reasoning) {\n\t\tthinkingLevel = \"off\";\n\t}\n\n\tconst editMode = settingsManager.getEditMode();\n\tconst defaultActiveToolNames: ToolName[] = editMode === \"hashline\"\n\t\t? [\"hashline_read\", \"bash\", \"hashline_edit\", \"write\", \"lsp\"]\n\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"lsp\"];\n\tconst initialActiveToolNames: ToolName[] = options.tools\n\t\t? options.tools.map((t) => t.name).filter((n): n is ToolName => n in allTools)\n\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tonPayload: async (payload, currentModel) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload, currentModel);\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getRetrySettings().maxDelayMs,\n\t\texternalToolExecution: (m) => modelRegistry.getProviderAuthMode(m.provider) === \"externalCli\",\n\t\tgetApiKey: async (provider) => {\n\t\t\t// Use the provider argument from the in-flight request;\n\t\t\t// agent.state.model may already be switched mid-turn.\n\t\t\tconst resolvedProvider = provider || agent.state.model?.provider;\n\t\t\tif (!resolvedProvider) {\n\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t}\n\t\t\tconst authMode = modelRegistry.getProviderAuthMode(resolvedProvider);\n\t\t\tif (authMode === \"externalCli\" || authMode === \"none\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Retry key resolution with backoff to handle transient network failures\n\t\t\t// (e.g., OAuth token refresh failing due to brief connectivity loss).\n\t\t\tconst maxAttempts = 3;\n\t\t\tconst baseDelayMs = 2000;\n\t\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\t\tconst key = await modelRegistry.getApiKeyForProvider(resolvedProvider);\n\t\t\t\tif (key) return key;\n\n\t\t\t\t// On the last attempt, fall through to error handling below\n\t\t\t\tif (attempt >= maxAttempts) break;\n\n\t\t\t\t// Only retry if credentials exist (network issue) — no point retrying\n\t\t\t\t// when there are genuinely no credentials configured.\n\t\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\t\tconst model = agent.state.model;\n\t\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\t\tif (!hasAuth && !isOAuth) break;\n\n\t\t\t\t// Wait with exponential backoff before retrying\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, baseDelayMs * attempt));\n\t\t\t}\n\n\t\t\t// All retries exhausted — throw descriptive error\n\t\t\t// Check if credentials exist but are temporarily backed off\n\t\t\t// (e.g., after a 429 quota exhaustion). Provide a specific error\n\t\t\t// so the retry handler knows this is transient, not a permanent\n\t\t\t// auth failure.\n\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\tif (hasAuth) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`All credentials for \"${resolvedProvider}\" are temporarily backed off due to rate limiting. ` +\n\t\t\t\t\t\t`The request will be retried automatically when backoff expires.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst model = agent.state.model;\n\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\tif (isOAuth) {\n\t\t\t\t// If credentials exist but are all in a backoff window (quota / rate-limit),\n\t\t\t\t// surface a specific message instead of the misleading \"Authentication failed\".\n\t\t\t\tif (modelRegistry.authStorage.areAllCredentialsBackedOff(resolvedProvider)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Rate limit in effect for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t\t`Please wait before retrying or switch to a different model.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Authentication failed for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t`Credentials may have expired or network is unavailable. ` +\n\t\t\t\t\t\t`Run '/login ${resolvedProvider}' to re-authenticate.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`No API key found for \"${resolvedProvider}\". ` +\n\t\t\t\t\t`Set an API key environment variable or run '/login ${resolvedProvider}'.`,\n\t\t\t);\n\t\t},\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.replaceMessages(existingSession.messages);\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\textensionRunnerRef,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
@@ -0,0 +1,81 @@
1
+ // GSD2 — Regression test: pendingProviderRegistrations must be flushed exactly once (#3576)
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ import { describe, it } from "node:test";
5
+ import assert from "node:assert/strict";
6
+
7
+ /**
8
+ * This test validates that the provider preflush pattern in sdk.ts clears
9
+ * pendingProviderRegistrations after iterating, so bindCore() doesn't
10
+ * re-register the same providers.
11
+ *
12
+ * The bug: createAgentSession() iterated pendingProviderRegistrations but
13
+ * did not clear the array. Later, bindCore() replayed and registered the
14
+ * same providers again, stacking wrappers.
15
+ */
16
+
17
+ interface ProviderEntry {
18
+ name: string;
19
+ config: Record<string, unknown>;
20
+ }
21
+
22
+ interface MockRuntime {
23
+ pendingProviderRegistrations: ProviderEntry[];
24
+ }
25
+
26
+ describe("provider registration preflush", () => {
27
+ it("clears pending registrations after preflush so bindCore does not replay", () => {
28
+ const registered: string[] = [];
29
+ const runtime: MockRuntime = {
30
+ pendingProviderRegistrations: [
31
+ { name: "ollama", config: { type: "ollama" } },
32
+ { name: "custom-provider", config: { type: "custom" } },
33
+ ],
34
+ };
35
+
36
+ // Simulate sdk.ts preflush (lines 220-223)
37
+ for (const { name } of runtime.pendingProviderRegistrations) {
38
+ registered.push(name);
39
+ }
40
+ // The fix: clear after preflush
41
+ runtime.pendingProviderRegistrations = [];
42
+
43
+ // Simulate bindCore() flush (runner.ts lines 268-271)
44
+ for (const { name } of runtime.pendingProviderRegistrations) {
45
+ registered.push(name);
46
+ }
47
+ runtime.pendingProviderRegistrations = [];
48
+
49
+ assert.deepEqual(
50
+ registered,
51
+ ["ollama", "custom-provider"],
52
+ "each provider should be registered exactly once",
53
+ );
54
+ });
55
+
56
+ it("without the fix, providers are registered twice", () => {
57
+ const registered: string[] = [];
58
+ const runtime: MockRuntime = {
59
+ pendingProviderRegistrations: [
60
+ { name: "ollama", config: { type: "ollama" } },
61
+ ],
62
+ };
63
+
64
+ // Old behavior: preflush without clearing
65
+ for (const { name } of runtime.pendingProviderRegistrations) {
66
+ registered.push(name);
67
+ }
68
+ // NOT clearing — simulating the old bug
69
+
70
+ // bindCore() replays the same queue
71
+ for (const { name } of runtime.pendingProviderRegistrations) {
72
+ registered.push(name);
73
+ }
74
+
75
+ assert.deepEqual(
76
+ registered,
77
+ ["ollama", "ollama"],
78
+ "without clearing, providers are registered twice (demonstrating the bug)",
79
+ );
80
+ });
81
+ });
@@ -467,6 +467,18 @@ export class ModelRegistry {
467
467
  this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
468
468
  }
469
469
 
470
+ // Register custom providers so isProviderRequestReady() can find
471
+ // them (#3531). Without this, models.json providers with apiKey
472
+ // fail the auth check and are invisible to the fallback resolver.
473
+ if (!this.registeredProviders.has(providerName)) {
474
+ this.registeredProviders.set(providerName, {
475
+ authMode: providerConfig.apiKey ? "apiKey" : "none",
476
+ apiKey: providerConfig.apiKey,
477
+ baseUrl: providerConfig.baseUrl,
478
+ isReady: providerConfig.apiKey ? () => true : undefined,
479
+ } as any);
480
+ }
481
+
470
482
  for (const modelDef of modelDefs) {
471
483
  const api = modelDef.api || providerConfig.api;
472
484
  if (!api) continue;
@@ -221,9 +221,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
221
221
  for (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {
222
222
  modelRegistry.registerProvider(name, config);
223
223
  }
224
- // Note: we do NOT clear pendingProviderRegistrations here bindCore() will iterate
225
- // an empty array harmlessly, and clearing here would require the runtime to track
226
- // whether the flush already happened.
224
+ // Clear the queue so bindCore() doesn't re-register the same providers.
225
+ extensionsForModelResolution.runtime.pendingProviderRegistrations = [];
227
226
 
228
227
  // If still no model, use findInitialModel (checks settings default, then provider defaults)
229
228
  if (!model) {