diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 388ee38..521d713 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,20 @@ jobs: - name: Build dependencies run: npm run build -w ai-config -w ai-credentials + # generate-schema emits two source-controlled artifacts from one source: + # providers.schema.json (the package export, read by editors and the + # Assistant docs generator) and src/generated/providers-schema-source.ts + # (the same bytes inlined, written next to the user's providers.json). + # A stale commit of either is a real bug. Diff against HEAD rather than + # the working tree: `build` above already regenerated both via + # ai-config's prebuild, so a working-tree comparison would always pass. + - name: Check generated schema artifacts are up to date + run: | + npm run generate-schema -w ai-config + git diff --exit-code HEAD -- \ + packages/ai-config/providers.schema.json \ + packages/ai-config/src/generated/providers-schema-source.ts + - name: Type check run: npm run check-types -w ai-provider-bridge diff --git a/.oxfmtrc.json b/.oxfmtrc.json index c38e56c..f537a6a 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -17,7 +17,8 @@ "**/dist/", "**/*.tsbuildinfo", "**/*.html", - "packages/ai-config/providers.schema.json" + "packages/ai-config/providers.schema.json", + "packages/ai-config/src/generated/" ], "overrides": [ { diff --git a/packages/ai-config/providers.schema.json b/packages/ai-config/providers.schema.json index 9163746..be300a9 100644 --- a/packages/ai-config/providers.schema.json +++ b/packages/ai-config/providers.schema.json @@ -5,37 +5,49 @@ "description": "Configuration file for AI provider connections, enablement, and model overrides. See https://github.com/posit-dev/assistant for documentation.", "properties": { "$schema": { + "description": "Path or URL of the JSON Schema for this file. Editors use it for validation and autocomplete.", "type": "string" }, "providers": { "additionalProperties": false, + "description": "Provider configuration, keyed by built-in provider id, plus the reserved `default` and `custom` keys.", "properties": { "anthropic": { "additionalProperties": false, + "description": "Configuration for the built-in anthropic provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -50,47 +62,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -102,24 +125,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -140,12 +169,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -157,30 +188,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -192,24 +230,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -218,7 +262,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -227,6 +273,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -242,42 +289,55 @@ }, "bedrock": { "additionalProperties": false, + "description": "Configuration for the built-in bedrock provider.", "properties": { "aws": { "additionalProperties": false, + "description": "AWS connection settings for Bedrock. Credentials are not stored here.", "properties": { "profile": { + "description": "Named profile from your AWS config and credentials files.", "type": "string" }, "region": { + "description": "AWS region to call, such as `us-east-1`.", "type": "string" } }, "type": "object" }, "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -292,47 +352,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -344,24 +415,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -382,12 +459,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -399,30 +478,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -434,24 +520,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -460,7 +552,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -469,6 +563,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -484,30 +579,40 @@ }, "copilot": { "additionalProperties": false, + "description": "Configuration for the built-in copilot provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -522,47 +627,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -574,24 +690,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -612,12 +734,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -629,30 +753,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -664,24 +795,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -690,7 +827,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -699,6 +838,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -719,28 +859,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -763,47 +912,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -815,24 +975,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -853,12 +1019,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -870,30 +1038,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -905,24 +1080,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -931,7 +1112,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -940,6 +1123,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -952,6 +1136,7 @@ }, "type": { "const": "openai-compatible", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -964,28 +1149,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1008,47 +1202,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1060,24 +1265,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1098,12 +1309,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -1115,30 +1328,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1150,24 +1370,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1176,7 +1402,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -1185,6 +1413,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1197,6 +1426,7 @@ }, "type": { "const": "anthropic", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -1209,28 +1439,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1253,47 +1492,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1305,24 +1555,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1343,12 +1599,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -1360,30 +1618,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1395,24 +1660,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1421,7 +1692,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -1430,6 +1703,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1442,6 +1716,7 @@ }, "type": { "const": "openai", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -1454,28 +1729,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1498,47 +1782,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1550,24 +1845,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1588,12 +1889,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -1605,30 +1908,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1640,24 +1950,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1666,7 +1982,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -1675,6 +1993,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1687,6 +2006,7 @@ }, "type": { "const": "gemini", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -1700,39 +2020,51 @@ "properties": { "aws": { "additionalProperties": false, + "description": "AWS connection settings for Bedrock. Credentials are not stored here.", "properties": { "profile": { + "description": "Named profile from your AWS config and credentials files.", "type": "string" }, "region": { + "description": "AWS region to call, such as `us-east-1`.", "type": "string" } }, "type": "object" }, "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1755,47 +2087,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1807,24 +2150,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1845,12 +2194,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -1862,30 +2213,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1897,24 +2255,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -1923,7 +2287,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -1932,6 +2298,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -1944,6 +2311,7 @@ }, "type": { "const": "aws", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -1956,28 +2324,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2000,47 +2377,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2052,24 +2440,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2090,12 +2484,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -2107,30 +2503,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2142,24 +2545,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2168,7 +2577,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -2177,6 +2588,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2189,17 +2601,22 @@ }, "snowflake": { "additionalProperties": false, + "description": "Snowflake connection settings. Credentials are not stored here.", "properties": { "account": { + "description": "Snowflake account identifier.", "type": "string" }, "connectionName": { + "description": "Which connection from `connections.toml` to use. Ignored in Positron, which uses its own Snowflake sign-in.", "type": "string" }, "home": { + "description": "Directory holding `connections.toml`, the same thing `SNOWFLAKE_HOME` sets. Point this at a managed directory when your credentials are not in the default location.", "type": "string" }, "host": { + "description": "Snowflake host name. Set this when the account identifier alone does not resolve to the right host.", "type": "string" } }, @@ -2207,6 +2624,7 @@ }, "type": { "const": "snowflake", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -2219,28 +2637,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2263,11 +2690,14 @@ }, "googleCloud": { "additionalProperties": false, + "description": "Google Cloud connection settings for Vertex AI.", "properties": { "location": { + "description": "Google Cloud region for Vertex AI, such as `us-central1`.", "type": "string" }, "project": { + "description": "Google Cloud project id for Vertex AI.", "type": "string" } }, @@ -2275,47 +2705,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2327,24 +2768,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2365,12 +2812,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -2382,30 +2831,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2417,24 +2873,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2443,7 +2905,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -2452,6 +2916,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2464,6 +2929,7 @@ }, "type": { "const": "google-vertex", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -2476,28 +2942,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2520,47 +2995,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2572,24 +3058,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2610,12 +3102,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -2627,30 +3121,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2662,24 +3163,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2688,7 +3195,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -2697,6 +3206,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2709,6 +3219,7 @@ }, "type": { "const": "ollama", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -2721,28 +3232,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2765,47 +3285,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2817,24 +3348,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2855,12 +3392,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -2872,30 +3411,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2907,24 +3453,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -2933,7 +3485,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -2942,6 +3496,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -2954,6 +3509,7 @@ }, "type": { "const": "lmstudio", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -2966,28 +3522,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3010,47 +3575,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3062,24 +3638,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3100,12 +3682,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -3117,30 +3701,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3152,24 +3743,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3178,7 +3775,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -3187,6 +3786,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3199,6 +3799,7 @@ }, "type": { "const": "deepseek", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -3211,28 +3812,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3255,47 +3865,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3307,24 +3928,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3345,12 +3972,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -3362,30 +3991,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3397,24 +4033,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3423,7 +4065,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -3432,6 +4076,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3444,6 +4089,7 @@ }, "type": { "const": "openrouter", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -3456,28 +4102,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3500,47 +4155,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3552,24 +4218,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3590,12 +4262,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -3607,30 +4281,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3642,24 +4323,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3668,7 +4355,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -3677,6 +4366,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3689,6 +4379,7 @@ }, "type": { "const": "ms-foundry", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -3701,28 +4392,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3745,47 +4445,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3797,24 +4508,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3835,12 +4552,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -3852,30 +4571,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3887,24 +4613,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -3913,7 +4645,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -3922,6 +4656,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3934,6 +4669,7 @@ }, "type": { "const": "litellm", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -3946,28 +4682,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -3990,47 +4735,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4042,24 +4798,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4080,12 +4842,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -4097,30 +4861,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4132,24 +4903,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4158,7 +4935,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -4167,6 +4946,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4179,6 +4959,7 @@ }, "type": { "const": "portkey", + "description": "Which provider client handles this entry.", "type": "string" } }, @@ -4189,46 +4970,60 @@ } ] }, + "description": "Providers you declare yourself, keyed by a name of your choosing.", "propertyNames": { + "description": "Name of your choosing, also used as the display name.", "type": "string" }, "type": "object" }, "databricks": { "additionalProperties": false, + "description": "Configuration for the built-in databricks provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "databricks": { "additionalProperties": false, + "description": "Databricks workspace settings.", "properties": { "host": { + "description": "Databricks workspace host. This is not a chat base URL: the serving-endpoint URL is derived from it.", "type": "string" } }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4243,47 +5038,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4295,24 +5101,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4333,12 +5145,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -4350,30 +5164,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4385,24 +5206,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4411,7 +5238,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -4420,6 +5249,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4435,30 +5265,40 @@ }, "deepseek": { "additionalProperties": false, + "description": "Configuration for the built-in deepseek provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4473,47 +5313,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4525,24 +5376,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4563,12 +5420,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -4580,30 +5439,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4615,24 +5481,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4641,7 +5513,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -4650,6 +5524,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4665,8 +5540,10 @@ }, "default": { "additionalProperties": false, + "description": "Baseline applied to every provider that does not set the same key itself.", "properties": { "enabled": { + "description": "Default enablement for providers that do not set `enabled` themselves.", "type": "boolean" } }, @@ -4674,30 +5551,40 @@ }, "gemini": { "additionalProperties": false, + "description": "Configuration for the built-in gemini provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4712,47 +5599,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4764,24 +5662,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4802,12 +5706,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -4819,30 +5725,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4854,24 +5767,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -4880,7 +5799,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -4889,6 +5810,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4904,30 +5826,40 @@ }, "google-vertex": { "additionalProperties": false, + "description": "Configuration for the built-in google-vertex provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -4942,11 +5874,14 @@ }, "googleCloud": { "additionalProperties": false, + "description": "Google Cloud connection settings for Vertex AI.", "properties": { "location": { + "description": "Google Cloud region for Vertex AI, such as `us-central1`.", "type": "string" }, "project": { + "description": "Google Cloud project id for Vertex AI.", "type": "string" } }, @@ -4954,47 +5889,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5006,24 +5952,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5044,12 +5996,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -5061,30 +6015,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5096,24 +6057,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5122,7 +6089,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -5131,6 +6100,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5146,30 +6116,40 @@ }, "litellm": { "additionalProperties": false, + "description": "Configuration for the built-in litellm provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5184,47 +6164,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5236,24 +6227,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5274,12 +6271,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -5291,30 +6290,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5326,24 +6332,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5352,7 +6364,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -5361,6 +6375,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5376,30 +6391,40 @@ }, "lmstudio": { "additionalProperties": false, + "description": "Configuration for the built-in lmstudio provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5414,47 +6439,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5466,24 +6502,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5504,12 +6546,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -5521,30 +6565,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5556,24 +6607,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5582,7 +6639,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -5591,6 +6650,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5606,11 +6666,14 @@ }, "ms-foundry": { "additionalProperties": false, + "description": "Configuration for the built-in ms-foundry provider.", "properties": { "azure": { "additionalProperties": false, + "description": "Microsoft Entra ID connection settings for the built-in ms-foundry provider.", "properties": { "authMode": { + "description": "How to authenticate: `apikey` (default, back-compat) or `entra` for Microsoft Entra ID sign-in.", "enum": [ "apikey", "entra" @@ -5618,37 +6681,48 @@ "type": "string" }, "scope": { + "description": "OAuth scope requested when acquiring a Microsoft Entra ID token.", "type": "string" }, "tenantId": { + "description": "Microsoft Entra ID tenant to authenticate against. Uses the default tenant if unset.", "type": "string" } }, "type": "object" }, "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5663,47 +6737,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5715,24 +6800,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5753,12 +6844,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -5770,30 +6863,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5805,24 +6905,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5831,7 +6937,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -5840,6 +6948,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5855,30 +6964,40 @@ }, "ollama": { "additionalProperties": false, + "description": "Configuration for the built-in ollama provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5893,47 +7012,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -5945,24 +7075,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -5983,12 +7119,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -6000,30 +7138,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6035,24 +7180,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6061,7 +7212,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -6070,6 +7223,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6085,30 +7239,40 @@ }, "openai": { "additionalProperties": false, + "description": "Configuration for the built-in openai provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6123,47 +7287,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6175,24 +7350,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6213,12 +7394,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -6230,30 +7413,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6265,24 +7455,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6291,7 +7487,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -6300,6 +7498,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6315,30 +7514,40 @@ }, "openai-compatible": { "additionalProperties": false, + "description": "Configuration for the built-in openai-compatible provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6353,47 +7562,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6405,24 +7625,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6443,12 +7669,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -6460,30 +7688,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6495,24 +7730,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6521,7 +7762,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -6530,6 +7773,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6545,30 +7789,40 @@ }, "openrouter": { "additionalProperties": false, + "description": "Configuration for the built-in openrouter provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6583,47 +7837,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6635,24 +7900,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6673,12 +7944,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -6690,30 +7963,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6725,24 +8005,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6751,7 +8037,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -6760,6 +8048,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6775,30 +8064,40 @@ }, "portkey": { "additionalProperties": false, + "description": "Configuration for the built-in portkey provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6813,47 +8112,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6865,24 +8175,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6903,12 +8219,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -6920,30 +8238,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -6955,24 +8280,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -6981,7 +8312,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -6990,6 +8323,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7005,30 +8339,40 @@ }, "posit-connect": { "additionalProperties": false, + "description": "Configuration for the built-in posit-connect provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7043,47 +8387,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7095,24 +8450,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7133,12 +8494,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -7150,30 +8513,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7185,24 +8555,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7211,7 +8587,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -7220,6 +8598,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7235,30 +8614,40 @@ }, "positai": { "additionalProperties": false, + "description": "Configuration for the built-in positai provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7273,47 +8662,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7325,24 +8725,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7363,12 +8769,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -7380,30 +8788,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7415,24 +8830,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7441,7 +8862,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -7451,20 +8874,25 @@ }, "positaiLogin": { "additionalProperties": false, + "description": "Posit sign-in settings for the built-in positai provider.", "properties": { "clientId": { + "description": "OAuth client id used for the device-authorization sign-in flow.", "type": "string" }, "host": { + "description": "Posit host to sign in against. The device-authorization and token URLs are derived from it.", "type": "string" }, "scope": { + "description": "Space-separated OAuth scopes requested at sign-in.", "type": "string" } }, "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7480,30 +8908,40 @@ }, "snowflake-cortex": { "additionalProperties": false, + "description": "Configuration for the built-in snowflake-cortex provider.", "properties": { "baseUrl": { + "description": "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", "type": "string" }, "customHeaders": { "additionalProperties": { + "description": "Header value.", "type": "string" }, + "description": "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", "propertyNames": { + "description": "Header name.", "type": "string" }, "type": "object" }, "enabled": { + "description": "Whether this provider is available. Set to false to hide it from the model picker.", "type": "boolean" }, "endpoint": { + "description": "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", "type": "string" }, "endpoints": { "additionalProperties": { + "description": "Base URL to use for this protocol.", "type": "string" }, + "description": "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", "propertyNames": { + "description": "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7518,47 +8956,58 @@ }, "models": { "additionalProperties": false, + "description": "Which models this provider offers, and how their metadata is filled in.", "properties": { "allow": { + "description": "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", "items": { "type": "string" }, "type": "array" }, "custom": { + "description": "Models to declare yourself, for models the provider does not return from discovery.", "items": { "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "id": { + "description": "Model id sent to the provider's API.", "minLength": 1, "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "minLength": 1, "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7570,24 +9019,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7608,12 +9063,14 @@ "type": "array" }, "deny": { + "description": "Model ids to hide. Applied after `allow`, so a model listed in both is hidden.", "items": { "type": "string" }, "type": "array" }, "discovery": { + "description": "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", "enum": [ "auto", "off" @@ -7625,30 +9082,37 @@ "additionalProperties": false, "properties": { "baseUrl": { + "description": "Base URL for this model only, overriding the provider's base URL.", "type": "string" }, "family": { + "description": "Model family, used for grouping models and for selecting family-specific system prompt content.", "type": "string" }, "maxContextLength": { + "description": "Total context window, in tokens.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxInputTokens": { + "description": "Maximum number of input tokens accepted in one request.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "maxOutputTokens": { + "description": "Maximum number of tokens the model may generate in one response.", "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" }, "name": { + "description": "Display name shown in the model picker.", "type": "string" }, "protocol": { + "description": "API wire protocol for this model, overriding the provider's protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7660,24 +9124,30 @@ "type": "string" }, "supportedInputMediaTypes": { + "description": "Media types the model accepts as input, such as `image/png`.", "items": { "type": "string" }, "type": "array" }, "supportsImages": { + "description": "Whether the model accepts images as input.", "type": "boolean" }, "supportsToolResultImages": { + "description": "Whether the model accepts images returned by a tool result.", "type": "boolean" }, "supportsTools": { + "description": "Whether the model can call tools.", "type": "boolean" }, "supportsWebSearch": { + "description": "Whether the model supports the provider's own web search.", "type": "boolean" }, "thinkingEffortLevels": { + "description": "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", "items": { "type": "string" }, @@ -7686,7 +9156,9 @@ }, "type": "object" }, + "description": "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", "propertyNames": { + "description": "Model id to patch.", "type": "string" }, "type": "object" @@ -7695,6 +9167,7 @@ "type": "object" }, "protocol": { + "description": "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", "enum": [ "anthropic-messages", "openai-chat", @@ -7707,17 +9180,22 @@ }, "snowflake": { "additionalProperties": false, + "description": "Snowflake connection settings. Credentials are not stored here.", "properties": { "account": { + "description": "Snowflake account identifier.", "type": "string" }, "connectionName": { + "description": "Which connection from `connections.toml` to use. Ignored in Positron, which uses its own Snowflake sign-in.", "type": "string" }, "home": { + "description": "Directory holding `connections.toml`, the same thing `SNOWFLAKE_HOME` sets. Point this at a managed directory when your credentials are not in the default location.", "type": "string" }, "host": { + "description": "Snowflake host name. Set this when the account identifier alone does not resolve to the right host.", "type": "string" } }, @@ -7731,6 +9209,7 @@ }, "version": { "const": 1, + "description": "Version of this config format. Always 1.", "type": "number" } }, diff --git a/packages/ai-config/scripts/generate-schema.ts b/packages/ai-config/scripts/generate-schema.ts index 960b514..6983daf 100644 --- a/packages/ai-config/scripts/generate-schema.ts +++ b/packages/ai-config/scripts/generate-schema.ts @@ -7,9 +7,19 @@ /** * Generate providers.schema.json from the Zod schema. * - * Produces a JSON Schema file at the package root (source-controlled) that - * is also copied into ~/.posit/ai/ alongside providers.json at seed time - * so editors can validate and autocomplete the config file. + * Produces two source-controlled artifacts, both derived from the same bytes: + * + * 1. `providers.schema.json` at the package root — the package export, read by + * the Assistant docs generator and by anyone pointing an editor at it. + * 2. `src/generated/providers-schema-source.ts` — the same content as a string + * constant, so `mutateProvidersConfig` can write the schema next to + * ~/.posit/ai/providers.json without resolving a file at runtime. + * + * The constant exists because consumers bundle ai-config (esbuild inlines it), + * and no consumer ships a `node_modules/ai-config` directory. A runtime + * `require.resolve("ai-config/providers.schema.json")` therefore throws in every + * packaged build, which silently left users with no schema at all. Inlining the + * bytes is the only form that survives bundling. * * Usage: npx tsx scripts/generate-schema.ts */ @@ -189,6 +199,10 @@ function removeRecordRequiredFields(schema: JSONSchema): JSONSchema { // Generation // --------------------------------------------------------------------------- +const COPYRIGHT_HEADER = `/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2026 Posit Software, PBC. All rights reserved. + *--------------------------------------------------------------------------------------------*/`; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -216,10 +230,51 @@ async function generateSchema() { try { const outputPath = path.resolve(__dirname, "../providers.schema.json"); + const contents = serializeProvidersSchema(); - await fs.writeFile(outputPath, serializeProvidersSchema(), "utf-8"); + await fs.writeFile(outputPath, contents, "utf-8"); console.log(`✅ providers.schema.json generated: ${outputPath}`); + + // Stored minified to halve what every consumer bundles (440KB -> 224KB). + // `JSON.stringify(JSON.parse(minified), null, 2) + "\n"` reproduces + // `contents` byte for byte, so the written file is identical either way. + // JSON.stringify of the string yields a fully-escaped JS literal; a + // template literal would not be safe, since descriptions contain backticks. + const minified = JSON.stringify(JSON.parse(contents)); + const sourcePath = path.resolve(__dirname, "../src/generated/providers-schema-source.ts"); + const module = [ + COPYRIGHT_HEADER, + "", + "/**", + " * DO NOT EDIT. Generated by scripts/generate-schema.ts.", + " *", + " * providers.schema.json, minified and inlined so the schema can be written", + " * next to providers.json without resolving a file at runtime (which fails in", + " * bundled consumers \u2014 see the generator's header for why).", + " */", + `const MINIFIED = ${JSON.stringify(minified)};`, + "", + "let cached: string | undefined;", + "", + "/**", + " * The exact bytes to write as providers.schema.json.", + " *", + " * Memoized: the callers check this against a file on every config mutation,", + " * and re-expanding a 224KB constant into 440KB each time is pure waste. The", + " * value is fixed at build time, so caching it is unconditionally safe.", + " */", + "export function providersSchemaFileContents(): string {", + '\tcached ??= JSON.stringify(JSON.parse(MINIFIED), null, 2) + "\\n";', + "\treturn cached;", + "}", + "", + ].join("\n"); + + await fs.mkdir(path.dirname(sourcePath), { recursive: true }); + await fs.writeFile(sourcePath, module, "utf-8"); + + console.log(`✅ providers-schema-source.ts generated: ${sourcePath}`); } catch (error) { console.error("❌ Failed to generate providers.schema.json:", error); process.exit(1); diff --git a/packages/ai-config/src/__tests__/mutate-config.test.ts b/packages/ai-config/src/__tests__/mutate-config.test.ts index ae16e2e..ad55afd 100644 --- a/packages/ai-config/src/__tests__/mutate-config.test.ts +++ b/packages/ai-config/src/__tests__/mutate-config.test.ts @@ -9,6 +9,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createConfigFileFixture } from "../../tests/helpers/config-file-fixture.js"; import type { ConfigFileFixture } from "../../tests/helpers/config-file-fixture.js"; +import { providersSchemaFileContents } from "../generated/providers-schema-source.js"; import { PROVIDERS_CONFIG_VERSION } from "../index.js"; import { mutateProvidersConfig } from "../node/mutate-config.js"; import { parseJsonc } from "../node/parse-jsonc.js"; @@ -158,7 +159,9 @@ describe("mutateProvidersConfig", () => { await mutateProvidersConfig((current) => ({ ...current }), { configPath, logger: mockLogger }); - expect(rename).not.toHaveBeenCalled(); + // A mutation also refreshes the sibling providers.schema.json, so assert + // on the config file specifically rather than on rename as a whole. + expect(rename.mock.calls.filter(([, dest]) => dest === configPath)).toEqual([]); expect(await fixture.readRaw()).toBe(original); }); @@ -379,25 +382,56 @@ describe("mutateProvidersConfig first creation and seed boundaries", () => { expect(content.providers?.anthropic?.enabled).toBe(true); }); - it("copies providers.schema.json alongside the config file on creation", async () => { - await mutateProvidersConfig((current) => current, { configPath, logger: mockLogger }); + it("writes the schema next to the config", async () => { + await mutateProvidersConfig((current) => ({ ...current, version: 1 }), { + configPath, + logger: mockLogger, + }); + + const written = await fs.readFile( + path.join(fixture.directory, "providers.schema.json"), + "utf-8", + ); + expect(written).toBe(providersSchemaFileContents()); + expect(JSON.parse(written).properties).toHaveProperty("providers"); + }); + + it("refreshes a stale schema on a later mutation", async () => { + await fixture.writeTypedConfig({ + providers: { anthropic: { enabled: true } }, + }); + const schemaPath = path.join(fixture.directory, "providers.schema.json"); + await fs.writeFile(schemaPath, '{"stale":true}\n'); + + await mutateProvidersConfig( + (current) => ({ + ...current, + providers: { ...current.providers, anthropic: { enabled: false } }, + }), + { configPath, logger: mockLogger }, + ); + + expect(await fs.readFile(schemaPath, "utf-8")).toBe(providersSchemaFileContents()); + }); + it("leaves a current schema untouched", async () => { + await fixture.writeTypedConfig({ + providers: { anthropic: { enabled: true } }, + }); const schemaPath = path.join(fixture.directory, "providers.schema.json"); - const exists = await fs - .access(schemaPath) - .then(() => true) - .catch(() => false); - - // The schema file should be copied (best-effort — may not exist in all - // environments, but should work when running from the package source) - if (exists) { - const schemaContent = JSON.parse(await fs.readFile(schemaPath, "utf-8")); - expect(schemaContent).toHaveProperty("$schema"); - expect(schemaContent).toHaveProperty("properties"); - } - // Either way, the config file should exist and be valid - const configContent = JSON.parse(await fixture.readRaw()); - expect(configContent).toBeDefined(); + await fs.writeFile(schemaPath, providersSchemaFileContents()); + const rename = vi.spyOn(fs, "rename"); + + await mutateProvidersConfig( + (current) => ({ + ...current, + providers: { ...current.providers, anthropic: { enabled: false } }, + }), + { configPath, logger: mockLogger }, + ); + + expect(rename.mock.calls.filter(([, dest]) => dest === schemaPath)).toEqual([]); + rename.mockRestore(); }); it("does NOT re-inject $schema/version when a user removes them", async () => { diff --git a/packages/ai-config/src/__tests__/schema-descriptions.test.ts b/packages/ai-config/src/__tests__/schema-descriptions.test.ts new file mode 100644 index 0000000..f5e1c2b --- /dev/null +++ b/packages/ai-config/src/__tests__/schema-descriptions.test.ts @@ -0,0 +1,220 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2026 Posit Software, PBC. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +/** + * Every user-addressable field in providers.json must carry a `.describe()`. + * + * Descriptions are load-bearing twice over: editors show them as hover text for + * anyone hand-editing `providers.json` against the generated schema, and the + * Assistant docs site generates its providers.json reference from them. + * + * The walker below deliberately throws on any JSON Schema construct it does not + * explicitly handle. A walker that silently skips an unrecognized construct + * reports vacuous success, which is the one failure mode this test exists to + * prevent. + */ + +import { describe, it, expect } from "vitest"; +import * as z from "zod/v4"; + +import { providersConfigSchema } from "../schema.js"; + +/** + * Keywords that carry no nested schema, so the walker can stop at them. + * Anything outside this list and {@link RECURSING_KEYWORDS} is unhandled. + */ +const LEAF_KEYWORDS = new Set([ + "$id", + "$schema", + "title", + "description", + "type", + "enum", + "const", + "required", + "default", + "examples", + "deprecated", + "format", + "pattern", + "minLength", + "maxLength", + "minimum", + "maximum", + "exclusiveMinimum", + "exclusiveMaximum", + "multipleOf", + "minItems", + "maxItems", + "uniqueItems", +]); + +const RECURSING_KEYWORDS = new Set([ + "properties", + "items", + "additionalProperties", + "propertyNames", + "oneOf", + "anyOf", + "allOf", +]); + +type JsonSchema = boolean | { [keyword: string]: unknown }; + +/** A named property that the walker reached, with the path a user would write. */ +interface DiscoveredField { + path: string; + description: string | undefined; +} + +/** + * Walk a JSON Schema and collect every named property under a `properties` map. + * + * Structural nodes (record wrappers, array `items`, union branches) are not + * themselves user-addressable and are exempt from the description contract, but + * the walker still descends through them so the named properties inside are + * checked. + * + * @throws if the schema uses a construct this walker does not explicitly support. + */ +function collectDescribedFields(root: JsonSchema): DiscoveredField[] { + const found: DiscoveredField[] = []; + + function visit(node: JsonSchema, path: string): void { + // `true`/`false` are valid JSON Schemas meaning "anything"/"nothing". + if (typeof node === "boolean") { + return; + } + + for (const keyword of Object.keys(node)) { + if (LEAF_KEYWORDS.has(keyword)) { + continue; + } + if (!RECURSING_KEYWORDS.has(keyword)) { + throw new Error( + `Unsupported JSON Schema construct \`${keyword}\` at ${path || ""}. ` + + `Teach collectDescribedFields how to traverse it before adding it to the schema.`, + ); + } + } + + const properties = node.properties; + if (properties !== undefined) { + for (const [name, child] of Object.entries(properties as Record)) { + const childPath = path ? `${path}.${name}` : name; + found.push({ + path: childPath, + description: + typeof child === "object" && typeof child.description === "string" + ? child.description + : undefined, + }); + visit(child, childPath); + } + } + + if (node.items !== undefined) { + visit(node.items as JsonSchema, `${path}[]`); + } + + if (node.additionalProperties !== undefined) { + visit(node.additionalProperties as JsonSchema, `${path}.{key}`); + } + + if (node.propertyNames !== undefined) { + visit(node.propertyNames as JsonSchema, `${path}.{keyName}`); + } + + for (const keyword of ["oneOf", "anyOf", "allOf"] as const) { + const branches = node[keyword]; + if (branches !== undefined) { + (branches as JsonSchema[]).forEach((branch, index) => { + visit(branch, `${path}<${keyword}[${index}]>`); + }); + } + } + } + + visit(root, ""); + return found; +} + +describe("collectDescribedFields", () => { + it("finds properties nested under `properties`", () => { + const schema = z.toJSONSchema( + z.object({ outer: z.object({ inner: z.string().describe("INNER") }) }), + ); + expect(collectDescribedFields(schema)).toContainEqual({ + path: "outer.inner", + description: "INNER", + }); + }); + + it("descends into array `items`", () => { + const schema = z.toJSONSchema( + z.object({ list: z.array(z.object({ field: z.string().describe("FIELD") })) }), + ); + expect(collectDescribedFields(schema)).toContainEqual({ + path: "list[].field", + description: "FIELD", + }); + }); + + it("descends into record values via `additionalProperties`", () => { + const schema = z.toJSONSchema( + z.object({ + map: z.record(z.string(), z.object({ field: z.string().describe("VALUE") })), + }), + ); + expect(collectDescribedFields(schema)).toContainEqual({ + path: "map.{key}.field", + description: "VALUE", + }); + }); + + it("descends into record keys via `propertyNames`", () => { + // A record's key schema is structural, so it yields no row and cannot be + // checked by inspecting the output. Nest an unsupported construct inside + // it instead: the walker can only reach it by traversing `propertyNames`, + // so this fails if that branch is ever dropped. + expect(() => + collectDescribedFields({ + type: "object", + propertyNames: { type: "string", patternProperties: {} }, + }), + ).toThrow(/Unsupported JSON Schema construct `patternProperties`/); + }); + + it("descends into every union branch", () => { + const schema = z.toJSONSchema( + z.object({ + choice: z.discriminatedUnion("t", [ + z.object({ t: z.literal("x"), only_x: z.string().describe("ONLY_X") }), + z.object({ t: z.literal("y"), only_y: z.string().describe("ONLY_Y") }), + ]), + }), + ); + const paths = collectDescribedFields(schema).map((f) => f.description); + expect(paths).toContain("ONLY_X"); + expect(paths).toContain("ONLY_Y"); + }); + + it("throws on a construct it does not explicitly support", () => { + expect(() => collectDescribedFields({ type: "object", patternProperties: {} })).toThrow( + /Unsupported JSON Schema construct `patternProperties`/, + ); + }); +}); + +describe("providers.json schema descriptions", () => { + it("describes every user-addressable field", () => { + const fields = collectDescribedFields(z.toJSONSchema(providersConfigSchema)); + + // Guards the guard: an empty walk would pass the assertion below vacuously. + expect(fields.length).toBeGreaterThan(0); + + const undescribed = fields.filter((f) => f.description === undefined).map((f) => f.path); + expect(undescribed).toEqual([]); + }); +}); diff --git a/packages/ai-config/src/generated/providers-schema-source.ts b/packages/ai-config/src/generated/providers-schema-source.ts new file mode 100644 index 0000000..e91c132 --- /dev/null +++ b/packages/ai-config/src/generated/providers-schema-source.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2026 Posit Software, PBC. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +/** + * DO NOT EDIT. Generated by scripts/generate-schema.ts. + * + * providers.schema.json, minified and inlined so the schema can be written + * next to providers.json without resolving a file at runtime (which fails in + * bundled consumers — see the generator's header for why). + */ +const MINIFIED = "{\"$id\":\"https://posit.co/schemas/providers.schema.json\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"additionalProperties\":false,\"description\":\"Configuration file for AI provider connections, enablement, and model overrides. See https://github.com/posit-dev/assistant for documentation.\",\"properties\":{\"$schema\":{\"description\":\"Path or URL of the JSON Schema for this file. Editors use it for validation and autocomplete.\",\"type\":\"string\"},\"providers\":{\"additionalProperties\":false,\"description\":\"Provider configuration, keyed by built-in provider id, plus the reserved `default` and `custom` keys.\",\"properties\":{\"anthropic\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in anthropic provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"bedrock\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in bedrock provider.\",\"properties\":{\"aws\":{\"additionalProperties\":false,\"description\":\"AWS connection settings for Bedrock. Credentials are not stored here.\",\"properties\":{\"profile\":{\"description\":\"Named profile from your AWS config and credentials files.\",\"type\":\"string\"},\"region\":{\"description\":\"AWS region to call, such as `us-east-1`.\",\"type\":\"string\"}},\"type\":\"object\"},\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"copilot\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in copilot provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"custom\":{\"additionalProperties\":{\"oneOf\":[{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"openai-compatible\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"anthropic\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"openai\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"gemini\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"aws\":{\"additionalProperties\":false,\"description\":\"AWS connection settings for Bedrock. Credentials are not stored here.\",\"properties\":{\"profile\":{\"description\":\"Named profile from your AWS config and credentials files.\",\"type\":\"string\"},\"region\":{\"description\":\"AWS region to call, such as `us-east-1`.\",\"type\":\"string\"}},\"type\":\"object\"},\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"aws\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"snowflake\":{\"additionalProperties\":false,\"description\":\"Snowflake connection settings. Credentials are not stored here.\",\"properties\":{\"account\":{\"description\":\"Snowflake account identifier.\",\"type\":\"string\"},\"connectionName\":{\"description\":\"Which connection from `connections.toml` to use. Ignored in Positron, which uses its own Snowflake sign-in.\",\"type\":\"string\"},\"home\":{\"description\":\"Directory holding `connections.toml`, the same thing `SNOWFLAKE_HOME` sets. Point this at a managed directory when your credentials are not in the default location.\",\"type\":\"string\"},\"host\":{\"description\":\"Snowflake host name. Set this when the account identifier alone does not resolve to the right host.\",\"type\":\"string\"}},\"type\":\"object\"},\"type\":{\"const\":\"snowflake\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"googleCloud\":{\"additionalProperties\":false,\"description\":\"Google Cloud connection settings for Vertex AI.\",\"properties\":{\"location\":{\"description\":\"Google Cloud region for Vertex AI, such as `us-central1`.\",\"type\":\"string\"},\"project\":{\"description\":\"Google Cloud project id for Vertex AI.\",\"type\":\"string\"}},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"google-vertex\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"ollama\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"lmstudio\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"deepseek\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"openrouter\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"ms-foundry\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"litellm\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"required\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":{\"const\":\"portkey\",\"description\":\"Which provider client handles this entry.\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"}]},\"description\":\"Providers you declare yourself, keyed by a name of your choosing.\",\"propertyNames\":{\"description\":\"Name of your choosing, also used as the display name.\",\"type\":\"string\"},\"type\":\"object\"},\"databricks\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in databricks provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"databricks\":{\"additionalProperties\":false,\"description\":\"Databricks workspace settings.\",\"properties\":{\"host\":{\"description\":\"Databricks workspace host. This is not a chat base URL: the serving-endpoint URL is derived from it.\",\"type\":\"string\"}},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"deepseek\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in deepseek provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"default\":{\"additionalProperties\":false,\"description\":\"Baseline applied to every provider that does not set the same key itself.\",\"properties\":{\"enabled\":{\"description\":\"Default enablement for providers that do not set `enabled` themselves.\",\"type\":\"boolean\"}},\"type\":\"object\"},\"gemini\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in gemini provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"google-vertex\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in google-vertex provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"googleCloud\":{\"additionalProperties\":false,\"description\":\"Google Cloud connection settings for Vertex AI.\",\"properties\":{\"location\":{\"description\":\"Google Cloud region for Vertex AI, such as `us-central1`.\",\"type\":\"string\"},\"project\":{\"description\":\"Google Cloud project id for Vertex AI.\",\"type\":\"string\"}},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"litellm\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in litellm provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"lmstudio\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in lmstudio provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"ms-foundry\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in ms-foundry provider.\",\"properties\":{\"azure\":{\"additionalProperties\":false,\"description\":\"Microsoft Entra ID connection settings for the built-in ms-foundry provider.\",\"properties\":{\"authMode\":{\"description\":\"How to authenticate: `apikey` (default, back-compat) or `entra` for Microsoft Entra ID sign-in.\",\"enum\":[\"apikey\",\"entra\"],\"type\":\"string\"},\"scope\":{\"description\":\"OAuth scope requested when acquiring a Microsoft Entra ID token.\",\"type\":\"string\"},\"tenantId\":{\"description\":\"Microsoft Entra ID tenant to authenticate against. Uses the default tenant if unset.\",\"type\":\"string\"}},\"type\":\"object\"},\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"ollama\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in ollama provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"openai\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in openai provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"openai-compatible\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in openai-compatible provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"openrouter\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in openrouter provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"portkey\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in portkey provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"posit-connect\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in posit-connect provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"positai\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in positai provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"positaiLogin\":{\"additionalProperties\":false,\"description\":\"Posit sign-in settings for the built-in positai provider.\",\"properties\":{\"clientId\":{\"description\":\"OAuth client id used for the device-authorization sign-in flow.\",\"type\":\"string\"},\"host\":{\"description\":\"Posit host to sign in against. The device-authorization and token URLs are derived from it.\",\"type\":\"string\"},\"scope\":{\"description\":\"Space-separated OAuth scopes requested at sign-in.\",\"type\":\"string\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"}},\"type\":\"object\"},\"snowflake-cortex\":{\"additionalProperties\":false,\"description\":\"Configuration for the built-in snowflake-cortex provider.\",\"properties\":{\"baseUrl\":{\"description\":\"Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.\",\"type\":\"string\"},\"customHeaders\":{\"additionalProperties\":{\"description\":\"Header value.\",\"type\":\"string\"},\"description\":\"Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.\",\"propertyNames\":{\"description\":\"Header name.\",\"type\":\"string\"},\"type\":\"object\"},\"enabled\":{\"description\":\"Whether this provider is available. Set to false to hide it from the model picker.\",\"type\":\"boolean\"},\"endpoint\":{\"description\":\"Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.\",\"type\":\"string\"},\"endpoints\":{\"additionalProperties\":{\"description\":\"Base URL to use for this protocol.\",\"type\":\"string\"},\"description\":\"Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.\",\"propertyNames\":{\"description\":\"API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"type\":\"object\"},\"models\":{\"additionalProperties\":false,\"description\":\"Which models this provider offers, and how their metadata is filled in.\",\"properties\":{\"allow\":{\"description\":\"Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"custom\":{\"description\":\"Models to declare yourself, for models the provider does not return from discovery.\",\"items\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"id\":{\"description\":\"Model id sent to the provider's API.\",\"minLength\":1,\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"minLength\":1,\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"id\",\"name\",\"maxContextLength\",\"supportsTools\",\"supportsImages\",\"supportsToolResultImages\",\"supportsWebSearch\"],\"type\":\"object\"},\"type\":\"array\"},\"deny\":{\"description\":\"Model ids to hide. Applied after `allow`, so a model listed in both is hidden.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"discovery\":{\"description\":\"Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.\",\"enum\":[\"auto\",\"off\"],\"type\":\"string\"},\"overrides\":{\"additionalProperties\":{\"additionalProperties\":false,\"properties\":{\"baseUrl\":{\"description\":\"Base URL for this model only, overriding the provider's base URL.\",\"type\":\"string\"},\"family\":{\"description\":\"Model family, used for grouping models and for selecting family-specific system prompt content.\",\"type\":\"string\"},\"maxContextLength\":{\"description\":\"Total context window, in tokens.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxInputTokens\":{\"description\":\"Maximum number of input tokens accepted in one request.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"maxOutputTokens\":{\"description\":\"Maximum number of tokens the model may generate in one response.\",\"exclusiveMinimum\":0,\"maximum\":9007199254740991,\"type\":\"integer\"},\"name\":{\"description\":\"Display name shown in the model picker.\",\"type\":\"string\"},\"protocol\":{\"description\":\"API wire protocol for this model, overriding the provider's protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"supportedInputMediaTypes\":{\"description\":\"Media types the model accepts as input, such as `image/png`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"supportsImages\":{\"description\":\"Whether the model accepts images as input.\",\"type\":\"boolean\"},\"supportsToolResultImages\":{\"description\":\"Whether the model accepts images returned by a tool result.\",\"type\":\"boolean\"},\"supportsTools\":{\"description\":\"Whether the model can call tools.\",\"type\":\"boolean\"},\"supportsWebSearch\":{\"description\":\"Whether the model supports the provider's own web search.\",\"type\":\"boolean\"},\"thinkingEffortLevels\":{\"description\":\"Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.\",\"propertyNames\":{\"description\":\"Model id to patch.\",\"type\":\"string\"},\"type\":\"object\"}},\"type\":\"object\"},\"protocol\":{\"description\":\"API wire protocol for this provider. Set this only when the provider does not use its default protocol.\",\"enum\":[\"anthropic-messages\",\"openai-chat\",\"openai-responses\",\"mlflow-responses\",\"bedrock-converse\",\"google-generative\"],\"type\":\"string\"},\"snowflake\":{\"additionalProperties\":false,\"description\":\"Snowflake connection settings. Credentials are not stored here.\",\"properties\":{\"account\":{\"description\":\"Snowflake account identifier.\",\"type\":\"string\"},\"connectionName\":{\"description\":\"Which connection from `connections.toml` to use. Ignored in Positron, which uses its own Snowflake sign-in.\",\"type\":\"string\"},\"home\":{\"description\":\"Directory holding `connections.toml`, the same thing `SNOWFLAKE_HOME` sets. Point this at a managed directory when your credentials are not in the default location.\",\"type\":\"string\"},\"host\":{\"description\":\"Snowflake host name. Set this when the account identifier alone does not resolve to the right host.\",\"type\":\"string\"}},\"type\":\"object\"}},\"type\":\"object\"}},\"type\":\"object\"},\"version\":{\"const\":1,\"description\":\"Version of this config format. Always 1.\",\"type\":\"number\"}},\"title\":\"Posit AI Provider Configuration\",\"type\":\"object\"}"; + +let cached: string | undefined; + +/** + * The exact bytes to write as providers.schema.json. + * + * Memoized: the callers check this against a file on every config mutation, + * and re-expanding a 224KB constant into 440KB each time is pure waste. The + * value is fixed at build time, so caching it is unconditionally safe. + */ +export function providersSchemaFileContents(): string { + cached ??= JSON.stringify(JSON.parse(MINIFIED), null, 2) + "\n"; + return cached; +} diff --git a/packages/ai-config/src/node/mutate-config.ts b/packages/ai-config/src/node/mutate-config.ts index 7391356..dd271ce 100644 --- a/packages/ai-config/src/node/mutate-config.ts +++ b/packages/ai-config/src/node/mutate-config.ts @@ -14,13 +14,13 @@ */ import { promises as fs } from "fs"; -import { createRequire } from "module"; import * as path from "path"; import { isDeepStrictEqual } from "util"; import lockfile from "proper-lockfile"; import { editJsonc, normalizeJsonValue } from "../edit-jsonc.js"; +import { providersSchemaFileContents } from "../generated/providers-schema-source.js"; import { PROVIDERS_CONFIG_VERSION } from "../index.js"; import { providersConfigSchema } from "../schema.js"; import type { ProvidersConfig } from "../types.js"; @@ -78,6 +78,11 @@ export async function mutateProvidersConfig( await enqueue(configPath, async () => { await performLockedMutation(configPath, mutator, logger); + + // After the mutation, so it cannot perturb the read/write sequence above, + // and skipped entirely if the mutation failed (a broken config is not the + // moment to refresh an editor hint). Best-effort and idempotent. + await writeSchemaFile(configPath, logger); }); } @@ -209,9 +214,9 @@ async function atomicWrite(configPath: string, text: string): Promise { * where two concurrent callers both observe ENOENT and then one clobbers the * other's completed write with an empty `{}`. * - * On file creation, seeds the file with `$schema` and `version` fields, and - * best-effort copies `providers.schema.json` alongside the config file for - * editor validation/autocomplete. + * On file creation, seeds the file with `$schema` and `version` fields. The + * sibling `providers.schema.json` is written by the caller on every mutation, + * not just on creation. * * @returns `true` if this call created the file (first write), `false` if * it already existed. The caller uses this to inject seed metadata into @@ -240,31 +245,43 @@ async function raceSafeEnsureFile( await fd.close(); } - // Best-effort: copy providers.schema.json alongside the config file. - // This enables editor validation/autocomplete. If it fails (missing - // file, permissions), log but don't fail — the schema hint is a - // nice-to-have, not a correctness requirement. - await copySchemaFile(configPath, logger); return true; } return false; } /** - * Best-effort copy of providers.schema.json from the ai-config package into - * the same directory as the config file. Uses the package export to resolve - * the source path. + * Best-effort write of providers.schema.json next to the config file, so + * editors can validate `providers.json` and show field descriptions on hover. + * + * The bytes are inlined at build time rather than resolved from the package. + * Consumers bundle ai-config and ship no `node_modules/ai-config`, so a runtime + * `require.resolve("ai-config/providers.schema.json")` throws in every packaged + * build — which silently left users with no schema at all. + * + * Runs on every mutation, not just on file creation, so an upgraded schema + * reaches existing installs instead of leaving them pinned to whatever shipped + * the day their config was first written. The content check keeps the common + * case free of a disk write. + * + * Deliberately outside the config lock, unlike everything else in this module: + * concurrent writers all write identical build-time bytes through an atomic + * temp+rename, so there is nothing for the lock to protect. */ -async function copySchemaFile(configPath: string, logger: LoggerLike | undefined): Promise { +async function writeSchemaFile(configPath: string, logger: LoggerLike | undefined): Promise { try { - // Resolve the schema file from the package export - const require = createRequire(import.meta.url); - const schemaSource = require.resolve("ai-config/providers.schema.json"); const schemaTarget = path.join(path.dirname(configPath), "providers.schema.json"); - await fs.copyFile(schemaSource, schemaTarget); - logger?.debug("[ai-config] Copied providers.schema.json to config directory"); + const contents = providersSchemaFileContents(); + + const existing = await fs.readFile(schemaTarget, "utf-8").catch(() => undefined); + if (existing === contents) { + return; + } + + await atomicWrite(schemaTarget, contents); + logger?.debug("[ai-config] Wrote providers.schema.json to config directory"); } catch (error) { - logger?.warn(`[ai-config] Could not copy providers.schema.json: ${errorMessage(error)}`); + logger?.warn(`[ai-config] Could not write providers.schema.json: ${errorMessage(error)}`); } } diff --git a/packages/ai-config/src/schema.ts b/packages/ai-config/src/schema.ts index 4cfd436..a72e85e 100644 --- a/packages/ai-config/src/schema.ts +++ b/packages/ai-config/src/schema.ts @@ -25,11 +25,21 @@ import type { BuiltinProviderId, SupportedCustomClientKind } from "./vocabulary. // Leaf enums // --------------------------------------------------------------------------- -export const protocolSchema = z.enum(PROTOCOL_VALUES); - -export const clientKindSchema = z.enum(CLIENT_KIND_VALUES); - -export const discoverySchema = z.enum(["auto", "off"]); +export const protocolSchema = z + .enum(PROTOCOL_VALUES) + .describe( + "API wire protocol used to talk to a model. Set this only when a provider or model does not use its default protocol.", + ); + +export const clientKindSchema = z + .enum(CLIENT_KIND_VALUES) + .describe("Which built-in provider client handles this entry."); + +export const discoverySchema = z + .enum(["auto", "off"]) + .describe( + "Whether to ask the provider for its model list. `auto` discovers models from the provider; `off` offers only the models declared under `models.custom`.", + ); // --------------------------------------------------------------------------- // Model overrides + custom models @@ -41,19 +51,58 @@ export const discoverySchema = z.enum(["auto", "off"]); */ export const modelOverrideSchema = z .object({ - name: z.string().optional(), - family: z.string().optional(), - maxContextLength: z.number().int().positive().optional(), - maxInputTokens: z.number().int().positive().optional(), - maxOutputTokens: z.number().int().positive().optional(), - protocol: protocolSchema.optional(), - baseUrl: z.string().optional(), - supportsTools: z.boolean().optional(), - supportsImages: z.boolean().optional(), - supportsToolResultImages: z.boolean().optional(), - supportedInputMediaTypes: z.array(z.string()).optional(), - supportsWebSearch: z.boolean().optional(), - thinkingEffortLevels: z.array(z.string()).optional(), + name: z.string().describe("Display name shown in the model picker.").optional(), + family: z + .string() + .describe( + "Model family, used for grouping models and for selecting family-specific system prompt content.", + ) + .optional(), + maxContextLength: z + .number() + .int() + .positive() + .describe("Total context window, in tokens.") + .optional(), + maxInputTokens: z + .number() + .int() + .positive() + .describe("Maximum number of input tokens accepted in one request.") + .optional(), + maxOutputTokens: z + .number() + .int() + .positive() + .describe("Maximum number of tokens the model may generate in one response.") + .optional(), + protocol: protocolSchema + .describe("API wire protocol for this model, overriding the provider's protocol.") + .optional(), + baseUrl: z + .string() + .describe("Base URL for this model only, overriding the provider's base URL.") + .optional(), + supportsTools: z.boolean().describe("Whether the model can call tools.").optional(), + supportsImages: z.boolean().describe("Whether the model accepts images as input.").optional(), + supportsToolResultImages: z + .boolean() + .describe("Whether the model accepts images returned by a tool result.") + .optional(), + supportedInputMediaTypes: z + .array(z.string()) + .describe("Media types the model accepts as input, such as `image/png`.") + .optional(), + supportsWebSearch: z + .boolean() + .describe("Whether the model supports the provider's own web search.") + .optional(), + thinkingEffortLevels: z + .array(z.string()) + .describe( + "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", + ) + .optional(), }) .strict(); @@ -64,21 +113,53 @@ export const modelOverrideSchema = z */ export const customModelSchema = z .object({ - id: z.string().min(1), - name: z.string().min(1), - maxContextLength: z.number().int().positive(), - supportsTools: z.boolean(), - supportsImages: z.boolean(), - supportsToolResultImages: z.boolean(), - supportsWebSearch: z.boolean(), + id: z.string().min(1).describe("Model id sent to the provider's API."), + name: z.string().min(1).describe("Display name shown in the model picker."), + maxContextLength: z.number().int().positive().describe("Total context window, in tokens."), + supportsTools: z.boolean().describe("Whether the model can call tools."), + supportsImages: z.boolean().describe("Whether the model accepts images as input."), + supportsToolResultImages: z + .boolean() + .describe("Whether the model accepts images returned by a tool result."), + supportsWebSearch: z + .boolean() + .describe("Whether the model supports the provider's own web search."), // Optional metadata - family: z.string().optional(), - maxInputTokens: z.number().int().positive().optional(), - maxOutputTokens: z.number().int().positive().optional(), - protocol: protocolSchema.optional(), - baseUrl: z.string().optional(), - supportedInputMediaTypes: z.array(z.string()).optional(), - thinkingEffortLevels: z.array(z.string()).optional(), + family: z + .string() + .describe( + "Model family, used for grouping models and for selecting family-specific system prompt content.", + ) + .optional(), + maxInputTokens: z + .number() + .int() + .positive() + .describe("Maximum number of input tokens accepted in one request.") + .optional(), + maxOutputTokens: z + .number() + .int() + .positive() + .describe("Maximum number of tokens the model may generate in one response.") + .optional(), + protocol: protocolSchema + .describe("API wire protocol for this model, overriding the provider's protocol.") + .optional(), + baseUrl: z + .string() + .describe("Base URL for this model only, overriding the provider's base URL.") + .optional(), + supportedInputMediaTypes: z + .array(z.string()) + .describe("Media types the model accepts as input, such as `image/png`.") + .optional(), + thinkingEffortLevels: z + .array(z.string()) + .describe( + "Thinking effort levels this model accepts. The set varies by model, for example `off`, `low`, `medium`, `high`, `xhigh`.", + ) + .optional(), }) .strict(); @@ -93,10 +174,28 @@ export const customModelSchema = z export const modelsBlockSchema = z .object({ discovery: discoverySchema.optional(), - allow: z.array(z.string()).optional(), - deny: z.array(z.string()).optional(), - overrides: z.record(z.string(), modelOverrideSchema).optional(), - custom: z.array(customModelSchema).optional(), + allow: z + .array(z.string()) + .describe( + "Model ids to offer. When this list is non-empty it is exclusive: no other model from this provider is offered.", + ) + .optional(), + deny: z + .array(z.string()) + .describe("Model ids to hide. Applied after `allow`, so a model listed in both is hidden.") + .optional(), + overrides: z + .record(z.string().describe("Model id to patch."), modelOverrideSchema) + .describe( + "Metadata patches for models the provider already returns, keyed by model id. Only the fields you set are changed.", + ) + .optional(), + custom: z + .array(customModelSchema) + .describe( + "Models to declare yourself, for models the provider does not return from discovery.", + ) + .optional(), }) .strict(); @@ -114,26 +213,43 @@ export const modelsBlockSchema = z */ export const positaiLoginConfigSchema = z .object({ - host: z.string().optional(), - clientId: z.string().optional(), - scope: z.string().optional(), + host: z + .string() + .describe( + "Posit host to sign in against. The device-authorization and token URLs are derived from it.", + ) + .optional(), + clientId: z + .string() + .describe("OAuth client id used for the device-authorization sign-in flow.") + .optional(), + scope: z.string().describe("Space-separated OAuth scopes requested at sign-in.").optional(), }) - .strict(); + .strict() + .describe("Posit sign-in settings for the built-in positai provider."); /** AWS connection config — secret fields (accessKeyId/secretAccessKey/sessionToken) excluded. */ export const awsConfigSchema = z .object({ - region: z.string().optional(), - profile: z.string().optional(), + region: z.string().describe("AWS region to call, such as `us-east-1`.").optional(), + profile: z + .string() + .describe("Named profile from your AWS config and credentials files.") + .optional(), }) - .strict(); + .strict() + .describe("AWS connection settings for Bedrock. Credentials are not stored here."); export const googleCloudConfigSchema = z .object({ - project: z.string().optional(), - location: z.string().optional(), + project: z.string().describe("Google Cloud project id for Vertex AI.").optional(), + location: z + .string() + .describe("Google Cloud region for Vertex AI, such as `us-central1`.") + .optional(), }) - .strict(); + .strict() + .describe("Google Cloud connection settings for Vertex AI."); /** * Microsoft Entra ID auth mode for the built-in `ms-foundry` provider. @@ -149,32 +265,61 @@ export const azureAuthModeSchema = z.enum(["apikey", "entra"]); */ export const azureConfigSchema = z .object({ - authMode: azureAuthModeSchema.optional(), - scope: z.string().optional(), - tenantId: z.string().optional(), + authMode: azureAuthModeSchema + .describe( + "How to authenticate: `apikey` (default, back-compat) or `entra` for Microsoft Entra ID sign-in.", + ) + .optional(), + scope: z + .string() + .describe("OAuth scope requested when acquiring a Microsoft Entra ID token.") + .optional(), + tenantId: z + .string() + .describe( + "Microsoft Entra ID tenant to authenticate against. Uses the default tenant if unset.", + ) + .optional(), }) - .strict(); + .strict() + .describe("Microsoft Entra ID connection settings for the built-in ms-foundry provider."); export const snowflakeConfigSchema = z .object({ - account: z.string().optional(), - host: z.string().optional(), + account: z.string().describe("Snowflake account identifier.").optional(), + host: z + .string() + .describe( + "Snowflake host name. Set this when the account identifier alone does not resolve to the right host.", + ) + .optional(), /** * Directory containing `connections.toml` (the `SNOWFLAKE_HOME` override). * Points Snowflake credential discovery at a non-default location — e.g. * Workbench Managed Credentials, which place `connections.toml` in a * managed directory. Non-secret. */ - home: z.string().optional(), + home: z + .string() + .describe( + "Directory holding `connections.toml`, the same thing `SNOWFLAKE_HOME` sets. Point this at a managed directory when your credentials are not in the default location.", + ) + .optional(), /** * Name of the `connections.toml` connection to use (non-secret). Selects * one entry from the file `home` points at. Consumed by * `@assistant/node`'s Snowflake resolver on Node platforms; ignored in * Positron, which defers Snowflake credentials to `vscode.authentication`. */ - connectionName: z.string().optional(), + connectionName: z + .string() + .describe( + "Which connection from `connections.toml` to use. Ignored in Positron, which uses its own Snowflake sign-in.", + ) + .optional(), }) - .strict(); + .strict() + .describe("Snowflake connection settings. Credentials are not stored here."); /** * Databricks workspace host (NOT a chat base URL — the bridge derives the @@ -183,17 +328,38 @@ export const snowflakeConfigSchema = z */ export const databricksConfigSchema = z .object({ - host: z.string().optional(), + host: z + .string() + .describe( + "Databricks workspace host. This is not a chat base URL: the serving-endpoint URL is derived from it.", + ) + .optional(), }) - .strict(); + .strict() + .describe("Databricks workspace settings."); /** Per-protocol base-URL overrides (partial — only specified protocols). */ -export const endpointsSchema = z.record(protocolSchema, z.string().optional()); +export const endpointsSchema = z.record( + protocolSchema, + z.string().describe("Base URL to use for this protocol.").optional(), +); // --------------------------------------------------------------------------- // Connection field composition // --------------------------------------------------------------------------- +/** + * Base `customHeaders` schema shared by every provider — the canonical + * description and per-key/value descriptions live here so + * {@link gatewayCustomHeadersSchema}'s reserved-header refinement for + * gateway providers cannot silently drop them. + */ +const customHeadersSchema = z + .record(z.string().describe("Header name."), z.string().describe("Header value.")) + .describe( + "Extra HTTP headers sent with each request to this provider, for proxy tenancy or routing markers, on providers whose transport supports custom headers. Do not put credentials or SDK-managed headers such as `Authorization`, `x-api-key`, or `anthropic-version` here.", + ); + /** * Connection fields shared by EVERY provider block (built-in and custom), * regardless of provider. Provider-specific capability sub-sections (`aws`, @@ -201,13 +367,36 @@ export const endpointsSchema = z.record(protocolSchema, z.string().optional()); * per-provider via {@link connectionBlockSchema}. */ const baseConnectionFields = { - enabled: z.boolean().optional(), - baseUrl: z.string().optional(), - endpoint: z.string().optional(), - customHeaders: z.record(z.string(), z.string()).optional(), - protocol: protocolSchema.optional(), - endpoints: endpointsSchema.optional(), - models: modelsBlockSchema.optional(), + enabled: z + .boolean() + .describe("Whether this provider is available. Set to false to hide it from the model picker.") + .optional(), + baseUrl: z + .string() + .describe( + "Base URL for the provider's API. Some providers need a version segment: `https://api.anthropic.com/v1` for Anthropic, `https://api.openai.com/v1` for OpenAI, and `https://generativelanguage.googleapis.com/v1beta` for Gemini. A bare host will fail for those.", + ) + .optional(), + endpoint: z + .string() + .describe( + "Endpoint URL for a self-hosted provider such as Ollama or LM Studio, for example `http://localhost:11434`.", + ) + .optional(), + customHeaders: customHeadersSchema.optional(), + protocol: protocolSchema + .describe( + "API wire protocol for this provider. Set this only when the provider does not use its default protocol.", + ) + .optional(), + endpoints: endpointsSchema + .describe( + "Base URL overrides for one protocol at a time, keyed by protocol. Use this when every model on a protocol shares a path that the provider's other models do not.", + ) + .optional(), + models: modelsBlockSchema + .describe("Which models this provider offers, and how their metadata is filled in.") + .optional(), }; const GATEWAY_RESERVED_AUTH_HEADERS = { @@ -222,9 +411,8 @@ function gatewayCustomHeadersSchema(providerId: BuiltinProviderId) { : providerId === "portkey" ? GATEWAY_RESERVED_AUTH_HEADERS.portkey : undefined; - const schema = z.record(z.string(), z.string()); - if (!reserved) return schema; - return schema.superRefine((headers, ctx) => { + if (!reserved) return customHeadersSchema; + return customHeadersSchema.superRefine((headers, ctx) => { for (const name of Object.keys(headers)) { if (reserved.has(name.toLowerCase())) { ctx.addIssue({ @@ -375,7 +563,10 @@ export const builtinProviderBlockSchema = z.object(allConnectionFields).strict() /** The `providers.default` baseline block — carries `enabled` only for v1. */ export const defaultBlockSchema = z .object({ - enabled: z.boolean().optional(), + enabled: z + .boolean() + .describe("Default enablement for providers that do not set `enabled` themselves.") + .optional(), }) .strict(); @@ -388,7 +579,7 @@ export const defaultBlockSchema = z function customProviderVariantSchema(kind: K) { return z .object({ - type: z.literal(kind), + type: z.literal(kind).describe("Which provider client handles this entry."), ...baseConnectionFields, ...connectionSectionShape(CUSTOM_CONNECTION_SECTIONS[kind]), }) @@ -481,7 +672,9 @@ export const customProviderEntryFragmentSchema = z export const builtinProviderBlockSchemas = Object.fromEntries( BUILTIN_PROVIDER_IDS.map((id) => [ id, - connectionBlockSchema(id, BUILTIN_CONNECTION_SECTIONS[id]), + connectionBlockSchema(id, BUILTIN_CONNECTION_SECTIONS[id]).describe( + `Configuration for the built-in ${id} provider.`, + ), ]), ) as Record; @@ -510,9 +703,18 @@ function validateCustomProviderNames(value: unknown, ctx: z.RefinementCtx): unkn export const providersMapSchema = z .object({ ...builtinProviderKeys, - default: defaultBlockSchema.optional(), + default: defaultBlockSchema + .describe("Baseline applied to every provider that does not set the same key itself.") + .optional(), custom: z - .preprocess(validateCustomProviderNames, z.record(z.string(), customProviderEntrySchema)) + .preprocess( + validateCustomProviderNames, + z.record( + z.string().describe("Name of your choosing, also used as the display name."), + customProviderEntrySchema, + ), + ) + .describe("Providers you declare yourself, keyed by a name of your choosing.") .optional(), }) .strict(); @@ -548,9 +750,18 @@ export const providersConfigSchema = z.preprocess( validateUnsafeObjectKeys, z .object({ - $schema: z.string().optional(), - version: z.literal(1).optional(), - providers: providersMapSchema.optional(), + $schema: z + .string() + .describe( + "Path or URL of the JSON Schema for this file. Editors use it for validation and autocomplete.", + ) + .optional(), + version: z.literal(1).describe("Version of this config format. Always 1.").optional(), + providers: providersMapSchema + .describe( + "Provider configuration, keyed by built-in provider id, plus the reserved `default` and `custom` keys.", + ) + .optional(), }) .strict(), );