From 20fa444f31fe5bd83c83955536e6107892b5f2b8 Mon Sep 17 00:00:00 2001 From: Dax Date: Thu, 6 Aug 2026 13:06:03 -0700 Subject: [PATCH] fix(config): omit unset optional values (#40918) --- .../client/src/promise/generated/types.ts | 240 +- packages/core/src/v1/config/migrate.ts | 111 +- packages/core/test/config/config.test.ts | 2 +- packages/protocol/openapi.json | 2181 +++++------------ packages/schema/src/config.ts | 60 +- packages/schema/src/config/agent.ts | 22 +- packages/schema/src/config/command.ts | 9 +- packages/schema/src/config/compaction.ts | 10 +- packages/schema/src/config/experimental.ts | 6 +- packages/schema/src/config/formatter.ts | 9 +- packages/schema/src/config/lsp.ts | 9 +- packages/schema/src/config/mcp.ts | 5 +- packages/schema/src/config/media.ts | 12 +- packages/schema/src/config/model.ts | 3 +- packages/schema/src/config/plugin.ts | 3 +- packages/schema/src/config/provider.ts | 49 +- packages/schema/src/config/reference.ts | 11 +- packages/schema/src/config/tool-output.ts | 6 +- packages/schema/src/config/warming.ts | 7 +- packages/schema/src/config/watcher.ts | 3 +- packages/schema/src/mcp.ts | 36 +- packages/schema/test/config.test.ts | 48 +- packages/server/test/config.test.ts | 24 +- packages/www/openapi.json | 2181 +++++------------ packages/www/public/openapi.json | 2181 +++++------------ 25 files changed, 2407 insertions(+), 4821 deletions(-) diff --git a/packages/client/src/promise/generated/types.ts b/packages/client/src/promise/generated/types.ts index 1566a319f80..6d4046c5575 100644 --- a/packages/client/src/promise/generated/types.ts +++ b/packages/client/src/promise/generated/types.ts @@ -1693,44 +1693,43 @@ export type AgentInfo = { export type ConfigEntry = | { type: "document" - path?: string | null + path?: string info: { - $schema?: string | null - shell?: string | null - model?: string | { providerID: string; model: string; variant?: string | null } | null - default_agent?: string | null - autoupdate?: boolean | "notify" | null - share?: "manual" | "auto" | "disabled" | null - enterprise?: { url?: string | null } | null - username?: string | null - permissions?: PermissionRuleset | null + $schema?: string + shell?: string + model?: string | { providerID: string; model: string; variant?: string } + default_agent?: string + autoupdate?: boolean | "notify" + share?: "manual" | "auto" | "disabled" + enterprise?: { url?: string } + username?: string + permissions?: PermissionRuleset agents?: { [x: string]: { - model?: string | { providerID: string; model: string; variant?: string | null } | null - request?: { headers?: { [x: string]: string } | null; body?: { [x: string]: JsonValue } | null } | null - system?: string | null - description?: string | null - mode?: "subagent" | "primary" | "all" | null - hidden?: boolean | null - color?: string | null - steps?: number | null - disabled?: boolean | null - permissions?: PermissionRuleset | null + model?: string | { providerID: string; model: string; variant?: string } + request?: { headers?: { [x: string]: string }; body?: { [x: string]: JsonValue } } + system?: string + description?: string + mode?: "subagent" | "primary" | "all" + hidden?: boolean + color?: string + steps?: number + disabled?: boolean + permissions?: PermissionRuleset } - } | null - snapshots?: boolean | null - watcher?: { ignore?: Array | null } | null + } + snapshots?: boolean + watcher?: { ignore?: Array } formatter?: | boolean | { [x: string]: { - disabled?: boolean | null - command?: Array | null - environment?: { [x: string]: string } | null - extensions?: Array | null + disabled?: boolean + command?: Array + environment?: { [x: string]: string } + extensions?: Array } } - | null lsp?: | boolean | { @@ -1738,125 +1737,117 @@ export type ConfigEntry = | { disabled: true } | { command: Array - extensions?: Array | null - disabled?: boolean | null - env?: { [x: string]: string } | null - initialization?: { [x: string]: JsonValue } | null + extensions?: Array + disabled?: boolean + env?: { [x: string]: string } + initialization?: { [x: string]: JsonValue } } } - | null media?: { - image?: { - auto_resize?: boolean | null - max_width?: number | null - max_height?: number | null - max_base64_bytes?: number | null - } | null - } | null - tool_output?: { max_lines?: number | null; max_bytes?: number | null } | null + image?: { auto_resize?: boolean; max_width?: number; max_height?: number; max_base64_bytes?: number } + } + tool_output?: { max_lines?: number; max_bytes?: number } mcp?: { - timeout?: { startup?: number | null; catalog?: number | null; execution?: number | null } | null + timeout?: { startup?: number; catalog?: number; execution?: number } servers?: { [x: string]: | { type: "local" command: Array - cwd?: string | null - environment?: { [x: string]: string } | null - disabled?: boolean | null - codemode?: boolean | null - timeout?: { startup?: number | null; catalog?: number | null; execution?: number | null } | null + cwd?: string + environment?: { [x: string]: string } + disabled?: boolean + codemode?: boolean + timeout?: { startup?: number; catalog?: number; execution?: number } } | { type: "remote" url: string - headers?: { [x: string]: string } | null + headers?: { [x: string]: string } oauth?: | { - client_id?: string | null - client_secret?: string | null - scope?: string | null - callback_port?: number | null - redirect_uri?: string | null + client_id?: string + client_secret?: string + scope?: string + callback_port?: number + redirect_uri?: string } | false - | null - disabled?: boolean | null - codemode?: boolean | null - timeout?: { startup?: number | null; catalog?: number | null; execution?: number | null } | null + disabled?: boolean + codemode?: boolean + timeout?: { startup?: number; catalog?: number; execution?: number } } - } | null - } | null - compaction?: { auto?: boolean | null; keep?: { tokens?: number | null } | null; buffer?: number | null } | null - skills?: Array | null + } + } + compaction?: { auto?: boolean; keep?: { tokens?: number }; buffer?: number } + skills?: Array commands?: { [x: string]: { template: string - description?: string | null - agent?: string | null - model?: string | { providerID: string; model: string; variant?: string | null } | null - subtask?: boolean | null + description?: string + agent?: string + model?: string | { providerID: string; model: string; variant?: string } + subtask?: boolean } - } | null - instructions?: Array | null + } + instructions?: Array references?: { [x: string]: | string - | { repository: string; branch?: string | null; description?: string | null; hidden?: boolean | null } - | { path: string; description?: string | null; hidden?: boolean | null } - } | null - websearch?: { provider: string } | null - plugins?: Array | null - warming?: boolean | { prompt?: string | null; interval?: string | null; duration?: string | null } | null + | { repository: string; branch?: string; description?: string; hidden?: boolean } + | { path: string; description?: string; hidden?: boolean } + } + websearch?: { provider: string } + plugins?: Array + warming?: boolean | { prompt?: string; interval?: string; duration?: string } providers?: { [x: string]: { - name?: string | null - env?: Array | null - package?: string | null - settings?: { [x: string]: JsonValue } | null - headers?: { [x: string]: string } | null - body?: { [x: string]: JsonValue } | null + name?: string + env?: Array + package?: string + settings?: { [x: string]: JsonValue } + headers?: { [x: string]: string } + body?: { [x: string]: JsonValue } models?: { [x: string]: { - modelID?: string | null - family?: string | null - name?: string | null - compatibility?: ModelCompatibility | null - package?: string | null - settings?: { [x: string]: JsonValue } | null - headers?: { [x: string]: string } | null - body?: { [x: string]: JsonValue } | null - capabilities?: ModelCapabilities | null + modelID?: string + family?: string + name?: string + compatibility?: ModelCompatibility + package?: string + settings?: { [x: string]: JsonValue } + headers?: { [x: string]: string } + body?: { [x: string]: JsonValue } + capabilities?: ModelCapabilities variants?: Array<{ id: string - settings?: { [x: string]: JsonValue } | null - headers?: { [x: string]: string } | null - body?: { [x: string]: JsonValue } | null - }> | null + settings?: { [x: string]: JsonValue } + headers?: { [x: string]: string } + body?: { [x: string]: JsonValue } + }> cost?: | { - tier?: { type: "context"; size: number } | null + tier?: { type: "context"; size: number } input: MoneyUSDPerMillionTokens output: MoneyUSDPerMillionTokens - cache?: { read?: MoneyUSDPerMillionTokens | null; write?: MoneyUSDPerMillionTokens | null } | null + cache?: { read?: MoneyUSDPerMillionTokens; write?: MoneyUSDPerMillionTokens } } | Array<{ - tier?: { type: "context"; size: number } | null + tier?: { type: "context"; size: number } input: MoneyUSDPerMillionTokens output: MoneyUSDPerMillionTokens - cache?: { read?: MoneyUSDPerMillionTokens | null; write?: MoneyUSDPerMillionTokens | null } | null + cache?: { read?: MoneyUSDPerMillionTokens; write?: MoneyUSDPerMillionTokens } }> - | null - disabled?: boolean | null - limit?: { context?: number | null; input?: number | null; output?: number | null } | null + disabled?: boolean + limit?: { context?: number; input?: number; output?: number } } - } | null + } } - } | null + } experimental?: { - subagent_depth?: number | null - policies?: Array<{ action: "provider.use"; resource: string; effect: "allow" | "deny" }> | null - } | null + subagent_depth?: number + policies?: Array<{ action: "provider.use"; resource: string; effect: "allow" | "deny" }> + } } } | { type: "directory"; path: string } @@ -3242,41 +3233,28 @@ export type McpAddInput = { | { readonly type: "local" readonly command: ReadonlyArray - readonly cwd?: string | undefined - readonly environment?: { readonly [x: string]: string } | undefined - readonly disabled?: boolean | undefined - readonly codemode?: boolean | undefined - readonly timeout?: - | { - readonly startup?: number | undefined - readonly catalog?: number | undefined - readonly execution?: number | undefined - } - | undefined + readonly cwd?: string + readonly environment?: { readonly [x: string]: string } + readonly disabled?: boolean + readonly codemode?: boolean + readonly timeout?: { readonly startup?: number; readonly catalog?: number; readonly execution?: number } } | { readonly type: "remote" readonly url: string - readonly headers?: { readonly [x: string]: string } | undefined + readonly headers?: { readonly [x: string]: string } readonly oauth?: | { - readonly client_id?: string | undefined - readonly client_secret?: string | undefined - readonly scope?: string | undefined - readonly callback_port?: number | undefined - readonly redirect_uri?: string | undefined + readonly client_id?: string + readonly client_secret?: string + readonly scope?: string + readonly callback_port?: number + readonly redirect_uri?: string } | false - | undefined - readonly disabled?: boolean | undefined - readonly codemode?: boolean | undefined - readonly timeout?: - | { - readonly startup?: number | undefined - readonly catalog?: number | undefined - readonly execution?: number | undefined - } - | undefined + readonly disabled?: boolean + readonly codemode?: boolean + readonly timeout?: { readonly startup?: number; readonly catalog?: number; readonly execution?: number } } }["config"] } diff --git a/packages/core/src/v1/config/migrate.ts b/packages/core/src/v1/config/migrate.ts index 89e5d78b8a4..3b0b6704b7a 100644 --- a/packages/core/src/v1/config/migrate.ts +++ b/packages/core/src/v1/config/migrate.ts @@ -1,5 +1,8 @@ export * as ConfigMigrateV1 from "./migrate" +import { Info } from "@opencode-ai/schema/config" +import { ConfigAgent } from "@opencode-ai/schema/config/agent" +import { Schema } from "effect" import { ConfigV1 } from "./config" import { ConfigAgentV1 } from "./agent" import { ConfigCommandV1 } from "./command" @@ -10,6 +13,12 @@ import { ConfigProviderOptionsV1 } from "./provider-options" import { Provider } from "../../provider" import { Model } from "../../model" +const decodeOptions = { errors: "all", onExcessProperty: "ignore", propertyOrder: "original" } as const +const decodeInfo = Schema.decodeUnknownSync(Schema.fromJsonString(Info), decodeOptions) +const encodeInfo = Schema.encodeSync(Info) +const decodeAgent = Schema.decodeUnknownSync(Schema.fromJsonString(ConfigAgent.Info), decodeOptions) +const encodeAgent = Schema.encodeSync(ConfigAgent.Info) + const keys = new Set([ "logLevel", "server", @@ -48,42 +57,46 @@ export function isV1(input: unknown) { } export function migrate(info: typeof ConfigV1.Info.Type) { - return { - $schema: info.$schema, - shell: info.shell, - model: modelSelection(info.model), - default_agent: info.default_agent, - autoupdate: info.autoupdate, - share: info.share ?? (info.autoshare ? "auto" : undefined), - enterprise: info.enterprise, - username: info.username, - permissions: permissions(info.permission, info.tools), - agents: agents(info), - snapshots: info.snapshot, - watcher: info.watcher, - formatter: info.formatter, - lsp: info.lsp, - media: info.attachment, - tool_output: info.tool_output, - mcp: mcp(info), - compaction: info.compaction && { - auto: info.compaction.auto, - prune: info.compaction.prune, - keep: { - tokens: info.compaction.preserve_recent_tokens, - }, - buffer: info.compaction.reserved, - }, - skills: info.skills && [...(info.skills.paths ?? []), ...(info.skills.urls ?? [])], - commands: commands(info.command), - instructions: info.instructions, - references: info.references ?? info.reference, - experimental: experimental(info), - plugins: info.plugin?.map((plugin) => - typeof plugin === "string" ? plugin : { package: plugin[0], options: plugin[1] }, + return encodeInfo( + decodeInfo( + JSON.stringify({ + $schema: info.$schema, + shell: info.shell, + model: modelSelection(info.model), + default_agent: info.default_agent, + autoupdate: info.autoupdate, + share: info.share ?? (info.autoshare ? "auto" : undefined), + enterprise: info.enterprise, + username: info.username, + permissions: permissions(info.permission, info.tools), + agents: agents(info), + snapshots: info.snapshot, + watcher: info.watcher, + formatter: info.formatter, + lsp: info.lsp, + media: info.attachment, + tool_output: info.tool_output, + mcp: mcp(info), + compaction: info.compaction && { + auto: info.compaction.auto, + prune: info.compaction.prune, + keep: { + tokens: info.compaction.preserve_recent_tokens, + }, + buffer: info.compaction.reserved, + }, + skills: info.skills && [...(info.skills.paths ?? []), ...(info.skills.urls ?? [])], + commands: commands(info.command), + instructions: info.instructions, + references: info.references ?? info.reference, + experimental: experimental(info), + plugins: info.plugin?.map((plugin) => + typeof plugin === "string" ? plugin : { package: plugin[0], options: plugin[1] }, + ), + providers: providers(info.provider), + }), ), - providers: providers(info.provider), - } + ) } function experimental(info: typeof ConfigV1.Info.Type) { @@ -154,18 +167,22 @@ export function migrateAgent(info: ConfigAgentV1.Info) { ...(info.temperature === undefined ? {} : { temperature: info.temperature }), ...(info.top_p === undefined ? {} : { top_p: info.top_p }), } - return { - model: modelSelection(info.model, info.variant), - request: Object.keys(body).length ? { body } : undefined, - system: info.prompt, - description: info.description, - mode: info.mode, - hidden: info.hidden, - color: info.color === undefined ? undefined : info.color.startsWith("#") ? info.color : "#aaaaaa", - steps: info.steps, - disabled: info.disable, - permissions: permissions(info.permission), - } + return encodeAgent( + decodeAgent( + JSON.stringify({ + model: modelSelection(info.model, info.variant), + request: Object.keys(body).length ? { body } : undefined, + system: info.prompt, + description: info.description, + mode: info.mode, + hidden: info.hidden, + color: info.color === undefined ? undefined : info.color.startsWith("#") ? info.color : "#aaaaaa", + steps: info.steps, + disabled: info.disable, + permissions: permissions(info.permission), + }), + ), + ) } function commands(info?: Readonly>) { diff --git a/packages/core/test/config/config.test.ts b/packages/core/test/config/config.test.ts index 8e10d5801a0..04e876e4d08 100644 --- a/packages/core/test/config/config.test.ts +++ b/packages/core/test/config/config.test.ts @@ -516,12 +516,12 @@ describe("Config", () => { }) expect(migrated.providers?.["azure-cognitive-services"]).toBeUndefined() expect(migrated.providers?.["google-vertex"]).toMatchObject({ - package: undefined, settings: { project: "test-project", location: "us-central1" }, models: { "claude-sonnet": { package: Provider.aisdk("@ai-sdk/google-vertex/anthropic") }, }, }) + expect(migrated.providers?.["google-vertex"]).not.toHaveProperty("package") expect(migrated.providers?.["google-vertex-anthropic"]).toBeUndefined() }), ) diff --git a/packages/protocol/openapi.json b/packages/protocol/openapi.json index 01eafbf26e5..17b55e7f060 100644 --- a/packages/protocol/openapi.json +++ b/packages/protocol/openapi.json @@ -20722,60 +20722,6 @@ ], "additionalProperties": false }, - "Mcp.TimeoutConfig": { - "type": "object", - "properties": { - "startup": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to establish and initialize the MCP server." - }, - "catalog": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP discovery requests such as tools/list and prompts/list." - }, - "execution": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP tool and prompt execution." - } - }, - "additionalProperties": false - }, "Mcp.LocalConfig": { "type": "object", "properties": { @@ -20792,59 +20738,49 @@ } }, "cwd": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Working directory for the MCP server process. Relative paths resolve from the workspace directory." + "type": "string" }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -20857,60 +20793,25 @@ "type": "object", "properties": { "client_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "client_secret": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "scope": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "callback_port": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "minimum": 1, - "maximum": 65535 - } - ] - }, - { - "type": "null" + "minimum": 1, + "maximum": 65535 } ] }, "redirect_uri": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -20928,68 +20829,59 @@ "type": "string" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "oauth": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.OAuthConfig" - }, - { - "type": "boolean", - "enum": [ - false - ] - } - ] + "$ref": "#/components/schemas/Mcp.OAuthConfig" }, { - "type": "null" + "type": "boolean", + "enum": [ + false + ] } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -26490,38 +26382,31 @@ ], "additionalProperties": false }, - "Config.ModelSelection": { - "anyOf": [ - { - "type": "string", - "allOf": [ + "Config.Agent": { + "type": "object", + "properties": { + "model": { + "anyOf": [ { - "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" - } - ] - }, - { - "type": "object", - "properties": { - "providerID": { "type": "string", "allOf": [ { - "pattern": "^[^/#]+$" + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" } ] }, - "model": { - "type": "string", - "allOf": [ - { - "pattern": "^[^#]+$" - } - ] - }, - "variant": { - "anyOf": [ - { + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { "type": "string", "allOf": [ { @@ -26529,185 +26414,76 @@ } ] }, - { - "type": "null" + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] } - ] + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } - }, - "required": [ - "providerID", - "model" - ], - "additionalProperties": false - } - ] - }, - "Config.Provider.Request": { - "type": "object", - "properties": { - "headers": { - "anyOf": [ - { + ] + }, + "request": { + "type": "object", + "properties": { + "headers": { "type": "object", "additionalProperties": { "type": "string" } }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { + "body": { "type": "object" - }, - { - "type": "null" } - ] - } - }, - "additionalProperties": false - }, - "Config.Agent": { - "type": "object", - "properties": { - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ] - }, - "request": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Provider.Request" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false }, "system": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "mode": { - "anyOf": [ - { - "type": "string", - "enum": [ - "subagent", - "primary", - "all" - ] - }, - { - "type": "null" - } + "type": "string", + "enum": [ + "subagent", + "primary", + "all" ] }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "color": { - "anyOf": [ + "type": "string", + "allOf": [ { - "type": "string", - "allOf": [ - { - "pattern": "^#[0-9a-fA-F]{6}$" - } - ] - }, - { - "type": "null" + "pattern": "^#[0-9a-fA-F]{6}$" } ] }, "steps": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" + "exclusiveMinimum": 0 } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Watcher": { - "type": "object", - "properties": { - "ignore": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Permission.Ruleset" } }, "additionalProperties": false @@ -26716,53 +26492,25 @@ "type": "object", "properties": { "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "command": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } } }, "additionalProperties": false @@ -26777,50 +26525,22 @@ } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "env": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "initialization": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -26828,217 +26548,6 @@ ], "additionalProperties": false }, - "Config.Media.Image": { - "type": "object", - "properties": { - "auto_resize": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "max_width": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_height": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_base64_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Media": { - "type": "object", - "properties": { - "image": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media.Image" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.ToolOutput": { - "type": "object", - "properties": { - "max_lines": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.MCP": { - "type": "object", - "properties": { - "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" - }, - { - "type": "null" - } - ] - }, - "servers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.LocalConfig" - }, - { - "$ref": "#/components/schemas/Mcp.RemoteConfig" - } - ] - } - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction.Keep": { - "type": "object", - "properties": { - "tokens": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction": { - "type": "object", - "properties": { - "auto": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "keep": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction.Keep" - }, - { - "type": "null" - } - ] - }, - "buffer": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Command": { "type": "object", "properties": { @@ -27046,44 +26555,59 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "model": { "anyOf": [ { - "$ref": "#/components/schemas/Config.ModelSelection" + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] }, { - "type": "null" + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } ] }, "subtask": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27098,34 +26622,13 @@ "type": "string" }, "branch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27140,24 +26643,10 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27165,18 +26654,6 @@ ], "additionalProperties": false }, - "ConfigWebSearch.Info": { - "type": "object", - "properties": { - "provider": { - "type": "string" - } - }, - "required": [ - "provider" - ], - "additionalProperties": false - }, "Config.Plugin.Entry": { "type": "object", "properties": { @@ -27184,14 +26661,7 @@ "type": "string" }, "options": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -27203,63 +26673,13 @@ "type": "object", "properties": { "prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Prompt sent for keep-alive requests" + "type": "string" }, "interval": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Idle time between keep-alive requests (default: \"4 minutes\")" + "type": "string" }, "duration": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Time after the last active request to keep a session warm (default: \"30 minutes\")" - } - }, - "additionalProperties": false - }, - "Config.Model.Cost.Cache": { - "type": "object", - "properties": { - "read": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] - }, - "write": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -27268,30 +26688,23 @@ "type": "object", "properties": { "tier": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "context" - ] - }, - "size": { - "type": "integer" - } - }, - "required": [ - "type", - "size" - ], - "additionalProperties": false + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "context" + ] }, - { - "type": "null" + "size": { + "type": "integer" } - ] + }, + "required": [ + "type", + "size" + ], + "additionalProperties": false }, "input": { "$ref": "#/components/schemas/Money.USDPerMillionTokens" @@ -27300,14 +26713,16 @@ "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, "cache": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost.Cache" + "type": "object", + "properties": { + "read": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, - { - "type": "null" + "write": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" } - ] + }, + "additionalProperties": false } }, "required": [ @@ -27316,232 +26731,96 @@ ], "additionalProperties": false }, - "Config.Model.Limit": { - "type": "object", - "properties": { - "context": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "input": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "output": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Model": { "type": "object", "properties": { "modelID": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "family": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "compatibility": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Compatibility" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Compatibility" }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "capabilities": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Capabilities" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Capabilities" }, "variants": { - "anyOf": [ - { - "type": "array", - "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "settings": { + "type": "object" + }, + "headers": { "type": "object", - "properties": { - "id": { - "type": "string" - }, - "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - }, - "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id" - ], - "additionalProperties": false + "additionalProperties": { + "type": "string" + } + }, + "body": { + "type": "object" } }, - { - "type": "null" - } - ] + "required": [ + "id" + ], + "additionalProperties": false + } }, "cost": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost" - }, - { - "type": "array", - "items": { - "$ref": "#/components/schemas/Config.Model.Cost" - } - } - ] + "$ref": "#/components/schemas/Config.Model.Cost" }, { - "type": "null" + "type": "array", + "items": { + "$ref": "#/components/schemas/Config.Model.Cost" + } } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "limit": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Limit" + "type": "object", + "properties": { + "context": { + "type": "integer" }, - { - "type": "null" + "input": { + "type": "integer" + }, + "output": { + "type": "integer" } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -27550,93 +26829,418 @@ "type": "object", "properties": { "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "env": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "models": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Model" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Model" + } } }, "additionalProperties": false }, - "ConfigExperimental.Info": { + "Config.Info": { "type": "object", "properties": { - "subagent_depth": { + "$schema": { + "type": "string" + }, + "shell": { + "type": "string" + }, + "model": { "anyOf": [ { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] + }, + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false + } + ] + }, + "default_agent": { + "type": "string" + }, + "autoupdate": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string", + "enum": [ + "notify" + ] + } + ] + }, + "share": { + "type": "string", + "enum": [ + "manual", + "auto", + "disabled" + ] + }, + "enterprise": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "username": { + "type": "string" + }, + "permissions": { + "$ref": "#/components/schemas/Permission.Ruleset" + }, + "agents": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Agent" + } + }, + "snapshots": { + "type": "boolean" + }, + "watcher": { + "type": "object", + "properties": { + "ignore": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "formatter": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Formatter.Entry" + } + } + ] + }, + "lsp": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "enum": [ + true + ] + } + }, + "required": [ + "disabled" + ], + "additionalProperties": false + }, + { + "$ref": "#/components/schemas/Config.LSP.Server" + } + ] + } + } + ] + }, + "media": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "auto_resize": { + "type": "boolean" + }, + "max_width": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_height": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_base64_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "tool_output": { + "type": "object", + "properties": { + "max_lines": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "mcp": { + "type": "object", + "properties": { + "timeout": { + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "servers": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/components/schemas/Mcp.LocalConfig" + }, + { + "$ref": "#/components/schemas/Mcp.RemoteConfig" + } + ] + } + } + }, + "additionalProperties": false + }, + "compaction": { + "type": "object", + "properties": { + "auto": { + "type": "boolean" + }, + "keep": { + "type": "object", + "properties": { + "tokens": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "buffer": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "skills": { + "type": "array", + "items": { + "type": "string" + } + }, + "commands": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Command" + } + }, + "instructions": { + "type": "array", + "items": { + "type": "string" + } + }, + "references": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Reference.Git" + }, + { + "$ref": "#/components/schemas/Config.Reference.Local" + } + ] + } + }, + "websearch": { + "type": "object", + "properties": { + "provider": { + "type": "string" + } + }, + "required": [ + "provider" + ], + "additionalProperties": false + }, + "plugins": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Plugin.Entry" + } + ] + } + }, + "warming": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/components/schemas/Config.Warming" + } + ] + }, + "providers": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Provider" + } + }, + "experimental": { + "type": "object", + "properties": { + "subagent_depth": { "type": "integer", "allOf": [ { @@ -27644,15 +27248,7 @@ } ] }, - { - "type": "null" - } - ], - "description": "Maximum subagent nesting depth. Defaults to 1." - }, - "policies": { - "anyOf": [ - { + "policies": { "type": "array", "items": { "type": "object", @@ -27681,425 +27277,9 @@ ], "additionalProperties": false } - }, - { - "type": "null" } - ], - "description": "Ordered policies controlling access to configured resources" - } - }, - "additionalProperties": false - }, - "Config.Info": { - "type": "object", - "properties": { - "$schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "JSON schema reference for configuration validation" - }, - "shell": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default shell to use for terminal and shell tool execution" - }, - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ], - "description": "Default model to use when no session or agent model is selected" - }, - "default_agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default primary agent to use when no session agent is selected" - }, - "autoupdate": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string", - "enum": [ - "notify" - ] - } - ] - }, - { - "type": "null" - } - ], - "description": "Automatically update or notify when a new version is available" - }, - "share": { - "anyOf": [ - { - "type": "string", - "enum": [ - "manual", - "auto", - "disabled" - ] - }, - { - "type": "null" - } - ], - "description": "Control whether sessions may be shared manually, automatically, or not at all" - }, - "enterprise": { - "anyOf": [ - { - "type": "object", - "properties": { - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "null" - } - ], - "description": "Enterprise sharing service configuration" - }, - "username": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Username displayed in conversations and used for telemetry identity" - }, - "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ], - "description": "Ordered tool permission rules applied to agent tool use" - }, - "agents": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Agent" - } - }, - { - "type": "null" - } - ], - "description": "Named built-in agent overrides and custom agent definitions" - }, - "snapshots": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Enable snapshots used for undo and revert behavior" - }, - "watcher": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Watcher" - }, - { - "type": "null" - } - ], - "description": "Filesystem watcher configuration" - }, - "formatter": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Formatter.Entry" - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in formatters or configure formatter overrides" - }, - "lsp": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "object", - "properties": { - "disabled": { - "type": "boolean", - "enum": [ - true - ] - } - }, - "required": [ - "disabled" - ], - "additionalProperties": false - }, - { - "$ref": "#/components/schemas/Config.LSP.Server" - } - ] - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in language servers or configure server overrides" - }, - "media": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media" - }, - { - "type": "null" - } - ], - "description": "Media processing configuration" - }, - "tool_output": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ToolOutput" - }, - { - "type": "null" - } - ], - "description": "Tool output truncation thresholds" - }, - "mcp": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.MCP" - }, - { - "type": "null" - } - ], - "description": "MCP server configuration" - }, - "compaction": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction" - }, - { - "type": "null" - } - ], - "description": "Conversation compaction behavior" - }, - "skills": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs to discover skills from" - }, - "commands": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Command" - } - }, - { - "type": "null" - } - ], - "description": "Named slash command definitions" - }, - "instructions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs supplying ambient instructions" - }, - "references": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Reference.Git" - }, - { - "$ref": "#/components/schemas/Config.Reference.Local" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Named local directories or Git repositories available as external context" - }, - "websearch": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigWebSearch.Info" - }, - { - "type": "null" - } - ], - "description": "Web search provider selection" - }, - "plugins": { - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Plugin.Entry" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Ordered plugin enablement directives and external package declarations" - }, - "warming": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/components/schemas/Config.Warming" - } - ] - }, - { - "type": "null" - } - ], - "description": "Keep recently active sessions warm with transient model requests (default: false)" - }, - "providers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Provider" - } - }, - { - "type": "null" - } - ] - }, - "experimental": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigExperimental.Info" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -28114,14 +27294,7 @@ ] }, "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "info": { "$ref": "#/components/schemas/Config.Info" diff --git a/packages/schema/src/config.ts b/packages/schema/src/config.ts index 17c2fbc9f6e..fad355eb81b 100644 --- a/packages/schema/src/config.ts +++ b/packages/schema/src/config.ts @@ -3,7 +3,7 @@ export * as Config from "./config.js" import { Schema } from "effect" import { ephemeral, inventory } from "./event.js" import { Permission } from "./permission.js" -import { AbsolutePath } from "./schema.js" +import { AbsolutePath, optional } from "./schema.js" import { ConfigAgent } from "./config/agent.js" import { ConfigMedia } from "./config/media.js" import { ConfigCompaction } from "./config/compaction.js" @@ -22,94 +22,94 @@ import { ConfigWatcher } from "./config/watcher.js" import { ConfigWarming } from "./config/warming.js" export class Info extends Schema.Class("Config.Info")({ - $schema: Schema.optional(Schema.String).annotate({ + $schema: optional(Schema.String).annotate({ description: "JSON schema reference for configuration validation", }), - shell: Schema.String.pipe(Schema.optional).annotate({ + shell: Schema.String.pipe(optional).annotate({ description: "Default shell to use for terminal and shell tool execution", }), - model: ConfigModel.Selection.pipe(Schema.optional).annotate({ + model: ConfigModel.Selection.pipe(optional).annotate({ description: "Default model to use when no session or agent model is selected", }), - default_agent: Schema.String.pipe(Schema.optional).annotate({ + default_agent: Schema.String.pipe(optional).annotate({ description: "Default primary agent to use when no session agent is selected", }), autoupdate: Schema.Union([Schema.Boolean, Schema.Literal("notify")]) - .pipe(Schema.optional) + .pipe(optional) .annotate({ description: "Automatically update or notify when a new version is available", }), - share: Schema.Literals(["manual", "auto", "disabled"]).pipe(Schema.optional).annotate({ + share: Schema.Literals(["manual", "auto", "disabled"]).pipe(optional).annotate({ description: "Control whether sessions may be shared manually, automatically, or not at all", }), enterprise: Schema.Struct({ - url: Schema.String.pipe(Schema.optional), + url: Schema.String.pipe(optional), }) - .pipe(Schema.optional) + .pipe(optional) .annotate({ description: "Enterprise sharing service configuration", }), - username: Schema.String.pipe(Schema.optional).annotate({ + username: Schema.String.pipe(optional).annotate({ description: "Username displayed in conversations and used for telemetry identity", }), - permissions: Permission.Ruleset.pipe(Schema.optional).annotate({ + permissions: Permission.Ruleset.pipe(optional).annotate({ description: "Ordered tool permission rules applied to agent tool use", }), - agents: Schema.Record(Schema.String, ConfigAgent.Info).pipe(Schema.optional).annotate({ + agents: Schema.Record(Schema.String, ConfigAgent.Info).pipe(optional).annotate({ description: "Named built-in agent overrides and custom agent definitions", }), - snapshots: Schema.Boolean.pipe(Schema.optional).annotate({ + snapshots: Schema.Boolean.pipe(optional).annotate({ description: "Enable snapshots used for undo and revert behavior", }), - watcher: ConfigWatcher.Info.pipe(Schema.optional).annotate({ + watcher: ConfigWatcher.Info.pipe(optional).annotate({ description: "Filesystem watcher configuration", }), - formatter: ConfigFormatter.Info.pipe(Schema.optional).annotate({ + formatter: ConfigFormatter.Info.pipe(optional).annotate({ description: "Enable built-in formatters or configure formatter overrides", }), - lsp: ConfigLSP.Info.pipe(Schema.optional).annotate({ + lsp: ConfigLSP.Info.pipe(optional).annotate({ description: "Enable built-in language servers or configure server overrides", }), - media: ConfigMedia.Info.pipe(Schema.optional).annotate({ + media: ConfigMedia.Info.pipe(optional).annotate({ description: "Media processing configuration", }), - tool_output: ConfigToolOutput.Info.pipe(Schema.optional).annotate({ + tool_output: ConfigToolOutput.Info.pipe(optional).annotate({ description: "Tool output truncation thresholds", }), - mcp: ConfigMCP.Info.pipe(Schema.optional).annotate({ + mcp: ConfigMCP.Info.pipe(optional).annotate({ description: "MCP server configuration", }), - compaction: ConfigCompaction.Info.pipe(Schema.optional).annotate({ + compaction: ConfigCompaction.Info.pipe(optional).annotate({ description: "Conversation compaction behavior", }), - skills: Schema.String.pipe(Schema.Array, Schema.optional).annotate({ + skills: Schema.String.pipe(Schema.Array, optional).annotate({ description: "Additional paths or URLs to discover skills from", }), - commands: Schema.Record(Schema.String, ConfigCommand.Info).pipe(Schema.optional).annotate({ + commands: Schema.Record(Schema.String, ConfigCommand.Info).pipe(optional).annotate({ description: "Named slash command definitions", }), - instructions: Schema.String.pipe(Schema.Array, Schema.optional).annotate({ + instructions: Schema.String.pipe(Schema.Array, optional).annotate({ description: "Additional paths or URLs supplying ambient instructions", }), - references: ConfigReference.Info.pipe(Schema.optional).annotate({ + references: ConfigReference.Info.pipe(optional).annotate({ description: "Named local directories or Git repositories available as external context", }), - websearch: ConfigWebSearch.Info.pipe(Schema.optional).annotate({ + websearch: ConfigWebSearch.Info.pipe(optional).annotate({ description: "Web search provider selection", }), - plugins: ConfigPlugin.Plugins.pipe(Schema.optional).annotate({ + plugins: ConfigPlugin.Plugins.pipe(optional).annotate({ description: "Ordered plugin enablement directives and external package declarations", }), - warming: ConfigWarming.Warming.pipe(Schema.optional).annotate({ + warming: ConfigWarming.Warming.pipe(optional).annotate({ description: "Keep recently active sessions warm with transient model requests (default: false)", }), - providers: Schema.Record(Schema.String, ConfigProvider.Info).pipe(Schema.optional), - experimental: ConfigExperimental.Info.pipe(Schema.optional), + providers: Schema.Record(Schema.String, ConfigProvider.Info).pipe(optional), + experimental: ConfigExperimental.Info.pipe(optional), }) {} export class Document extends Schema.Class("Config.Document")({ type: Schema.Literal("document"), - path: Schema.String.pipe(Schema.optional), + path: Schema.String.pipe(optional), info: Info, }) {} diff --git a/packages/schema/src/config/agent.ts b/packages/schema/src/config/agent.ts index 704ac92625d..f8a38e00e88 100644 --- a/packages/schema/src/config/agent.ts +++ b/packages/schema/src/config/agent.ts @@ -2,21 +2,21 @@ export * as ConfigAgent from "./agent.js" import { Schema } from "effect" import { Permission } from "../permission.js" -import { PositiveInt } from "../schema.js" +import { optional, PositiveInt } from "../schema.js" import { ConfigModel } from "./model.js" import { ConfigProvider } from "./provider.js" export const Color = Schema.String.check(Schema.isPattern(/^#[0-9a-fA-F]{6}$/)) export class Info extends Schema.Class("Config.Agent")({ - model: ConfigModel.Selection.pipe(Schema.optional), - request: ConfigProvider.Request.pipe(Schema.optional), - system: Schema.String.pipe(Schema.optional), - description: Schema.String.pipe(Schema.optional), - mode: Schema.Literals(["subagent", "primary", "all"]).pipe(Schema.optional), - hidden: Schema.Boolean.pipe(Schema.optional), - color: Color.pipe(Schema.optional), - steps: PositiveInt.pipe(Schema.optional), - disabled: Schema.Boolean.pipe(Schema.optional), - permissions: Permission.Ruleset.pipe(Schema.optional), + model: ConfigModel.Selection.pipe(optional), + request: ConfigProvider.Request.pipe(optional), + system: Schema.String.pipe(optional), + description: Schema.String.pipe(optional), + mode: Schema.Literals(["subagent", "primary", "all"]).pipe(optional), + hidden: Schema.Boolean.pipe(optional), + color: Color.pipe(optional), + steps: PositiveInt.pipe(optional), + disabled: Schema.Boolean.pipe(optional), + permissions: Permission.Ruleset.pipe(optional), }) {} diff --git a/packages/schema/src/config/command.ts b/packages/schema/src/config/command.ts index 05caa2fbe6c..511b5984174 100644 --- a/packages/schema/src/config/command.ts +++ b/packages/schema/src/config/command.ts @@ -1,12 +1,13 @@ export * as ConfigCommand from "./command.js" import { Schema } from "effect" +import { optional } from "../schema.js" import { ConfigModel } from "./model.js" export class Info extends Schema.Class("Config.Command")({ template: Schema.String, - description: Schema.String.pipe(Schema.optional), - agent: Schema.String.pipe(Schema.optional), - model: ConfigModel.Selection.pipe(Schema.optional), - subtask: Schema.Boolean.pipe(Schema.optional), + description: Schema.String.pipe(optional), + agent: Schema.String.pipe(optional), + model: ConfigModel.Selection.pipe(optional), + subtask: Schema.Boolean.pipe(optional), }) {} diff --git a/packages/schema/src/config/compaction.ts b/packages/schema/src/config/compaction.ts index 6ad7b9d3a2a..7661e57d2a0 100644 --- a/packages/schema/src/config/compaction.ts +++ b/packages/schema/src/config/compaction.ts @@ -1,14 +1,14 @@ export * as ConfigCompaction from "./compaction.js" import { Schema } from "effect" -import { NonNegativeInt } from "../schema.js" +import { NonNegativeInt, optional } from "../schema.js" export class Keep extends Schema.Class("Config.Compaction.Keep")({ - tokens: NonNegativeInt.pipe(Schema.optional), + tokens: NonNegativeInt.pipe(optional), }) {} export class Info extends Schema.Class("Config.Compaction")({ - auto: Schema.Boolean.pipe(Schema.optional), - keep: Keep.pipe(Schema.optional), - buffer: NonNegativeInt.pipe(Schema.optional), + auto: Schema.Boolean.pipe(optional), + keep: Keep.pipe(optional), + buffer: NonNegativeInt.pipe(optional), }) {} diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index ee583506ee1..06369d56c1a 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -1,14 +1,14 @@ export * as ConfigExperimental from "./experimental.js" import { Schema } from "effect" -import { NonNegativeInt } from "../schema.js" +import { NonNegativeInt, optional } from "../schema.js" import { ConfigPolicy } from "./policy.js" export class Info extends Schema.Class("ConfigExperimental.Info")({ - subagent_depth: NonNegativeInt.pipe(Schema.optional).annotate({ + subagent_depth: NonNegativeInt.pipe(optional).annotate({ description: "Maximum subagent nesting depth. Defaults to 1.", }), - policies: ConfigPolicy.Info.pipe(Schema.Array, Schema.optional).annotate({ + policies: ConfigPolicy.Info.pipe(Schema.Array, optional).annotate({ description: "Ordered policies controlling access to configured resources", }), }) {} diff --git a/packages/schema/src/config/formatter.ts b/packages/schema/src/config/formatter.ts index facd57b8e8d..95b6c8bc6f9 100644 --- a/packages/schema/src/config/formatter.ts +++ b/packages/schema/src/config/formatter.ts @@ -1,12 +1,13 @@ export * as ConfigFormatter from "./formatter.js" import { Schema } from "effect" +import { optional } from "../schema.js" export class Entry extends Schema.Class("Config.Formatter.Entry")({ - disabled: Schema.Boolean.pipe(Schema.optional), - command: Schema.String.pipe(Schema.Array, Schema.optional), - environment: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional), - extensions: Schema.String.pipe(Schema.Array, Schema.optional), + disabled: Schema.Boolean.pipe(optional), + command: Schema.String.pipe(Schema.Array, optional), + environment: Schema.Record(Schema.String, Schema.String).pipe(optional), + extensions: Schema.String.pipe(Schema.Array, optional), }) {} export const Info = Schema.Union([Schema.Boolean, Schema.Record(Schema.String, Entry)]) diff --git a/packages/schema/src/config/lsp.ts b/packages/schema/src/config/lsp.ts index 09567b5f20d..771af792f4a 100644 --- a/packages/schema/src/config/lsp.ts +++ b/packages/schema/src/config/lsp.ts @@ -1,6 +1,7 @@ export * as ConfigLSP from "./lsp.js" import { Schema } from "effect" +import { optional } from "../schema.js" export const Disabled = Schema.Struct({ disabled: Schema.Literal(true), @@ -8,10 +9,10 @@ export const Disabled = Schema.Struct({ export class Server extends Schema.Class("Config.LSP.Server")({ command: Schema.String.pipe(Schema.Array), - extensions: Schema.String.pipe(Schema.Array, Schema.optional), - disabled: Schema.Boolean.pipe(Schema.optional), - env: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional), - initialization: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional), + extensions: Schema.String.pipe(Schema.Array, optional), + disabled: Schema.Boolean.pipe(optional), + env: Schema.Record(Schema.String, Schema.String).pipe(optional), + initialization: Schema.Record(Schema.String, Schema.Unknown).pipe(optional), }) {} export const Entry = Schema.Union([Disabled, Server]) diff --git a/packages/schema/src/config/mcp.ts b/packages/schema/src/config/mcp.ts index 0b5ae4ace02..9825125a228 100644 --- a/packages/schema/src/config/mcp.ts +++ b/packages/schema/src/config/mcp.ts @@ -2,6 +2,7 @@ export * as ConfigMCP from "./mcp.js" import { Schema } from "effect" import { Mcp } from "../mcp.js" +import { optional } from "../schema.js" export const Timeout = Mcp.TimeoutConfig export type Timeout = Mcp.TimeoutConfig @@ -14,6 +15,6 @@ export type Remote = Mcp.RemoteConfig export const Server = Mcp.ServerConfig export class Info extends Schema.Class("Config.MCP")({ - timeout: Timeout.pipe(Schema.optional), - servers: Schema.Record(Schema.String, Server).pipe(Schema.optional), + timeout: Timeout.pipe(optional), + servers: Schema.Record(Schema.String, Server).pipe(optional), }) {} diff --git a/packages/schema/src/config/media.ts b/packages/schema/src/config/media.ts index f2f858d6596..ffba2547eb9 100644 --- a/packages/schema/src/config/media.ts +++ b/packages/schema/src/config/media.ts @@ -1,15 +1,15 @@ export * as ConfigMedia from "./media.js" import { Schema } from "effect" -import { PositiveInt } from "../schema.js" +import { optional, PositiveInt } from "../schema.js" export class Image extends Schema.Class("Config.Media.Image")({ - auto_resize: Schema.Boolean.pipe(Schema.optional), - max_width: PositiveInt.pipe(Schema.optional), - max_height: PositiveInt.pipe(Schema.optional), - max_base64_bytes: PositiveInt.pipe(Schema.optional), + auto_resize: Schema.Boolean.pipe(optional), + max_width: PositiveInt.pipe(optional), + max_height: PositiveInt.pipe(optional), + max_base64_bytes: PositiveInt.pipe(optional), }) {} export class Info extends Schema.Class("Config.Media")({ - image: Image.pipe(Schema.optional), + image: Image.pipe(optional), }) {} diff --git a/packages/schema/src/config/model.ts b/packages/schema/src/config/model.ts index e7154d7c68f..dc2a0a212a6 100644 --- a/packages/schema/src/config/model.ts +++ b/packages/schema/src/config/model.ts @@ -3,6 +3,7 @@ export * as ConfigModel from "./model.js" import { Schema, SchemaGetter } from "effect" import { Model } from "../model.js" import { Provider } from "../provider.js" +import { optional } from "../schema.js" const ProviderID = Provider.ID.check(Schema.isPattern(/^[^/#]+$/)) const ModelID = Model.ID.check(Schema.isPattern(/^[^#]+$/)) @@ -11,7 +12,7 @@ const VariantID = Model.VariantID.check(Schema.isPattern(/^[^#]+$/)) const Explicit = Schema.Struct({ providerID: ProviderID, model: ModelID, - variant: VariantID.pipe(Schema.optional), + variant: VariantID.pipe(optional), }) const Short = Schema.String.check(Schema.isPattern(/^[^/#]+\/[^#]+(?:#[^#]+)?$/)) diff --git a/packages/schema/src/config/plugin.ts b/packages/schema/src/config/plugin.ts index bc28165430b..aba3c3e1a34 100644 --- a/packages/schema/src/config/plugin.ts +++ b/packages/schema/src/config/plugin.ts @@ -1,10 +1,11 @@ export * as ConfigPlugin from "./plugin.js" import { Schema } from "effect" +import { optional } from "../schema.js" export class Entry extends Schema.Class("Config.Plugin.Entry")({ package: Schema.String, - options: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional), + options: Schema.Record(Schema.String, Schema.Unknown).pipe(optional), }) {} export const Plugin = Schema.Union([Schema.String, Entry]) diff --git a/packages/schema/src/config/provider.ts b/packages/schema/src/config/provider.ts index b3eba949caa..4947a1f5757 100644 --- a/packages/schema/src/config/provider.ts +++ b/packages/schema/src/config/provider.ts @@ -3,13 +3,14 @@ export * as ConfigProvider from "./provider.js" import { Schema } from "effect" import { Money } from "../money.js" import { Capabilities, Compatibility, Family, ID, VariantID } from "../model.js" +import { optional } from "../schema.js" const JsonRecord = Schema.Record(Schema.String, Schema.Json) export const Overlays = { - settings: JsonRecord.pipe(Schema.optional), - headers: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional), - body: JsonRecord.pipe(Schema.optional), + settings: JsonRecord.pipe(optional), + headers: Schema.Record(Schema.String, Schema.String).pipe(optional), + body: JsonRecord.pipe(optional), } export class Request extends Schema.Class("Config.Provider.Request")({ @@ -18,47 +19,47 @@ export class Request extends Schema.Class("Config.Provider.Request")({ }) {} class Cache extends Schema.Class("Config.Model.Cost.Cache")({ - read: Money.USDPerMillionTokens.pipe(Schema.optional), - write: Money.USDPerMillionTokens.pipe(Schema.optional), + read: Money.USDPerMillionTokens.pipe(optional), + write: Money.USDPerMillionTokens.pipe(optional), }) {} class Cost extends Schema.Class("Config.Model.Cost")({ tier: Schema.Struct({ type: Schema.Literal("context"), size: Schema.Int, - }).pipe(Schema.optional), + }).pipe(optional), input: Money.USDPerMillionTokens, output: Money.USDPerMillionTokens, - cache: Cache.pipe(Schema.optional), + cache: Cache.pipe(optional), }) {} class Limit extends Schema.Class("Config.Model.Limit")({ - context: Schema.Int.pipe(Schema.optional), - input: Schema.Int.pipe(Schema.optional), - output: Schema.Int.pipe(Schema.optional), + context: Schema.Int.pipe(optional), + input: Schema.Int.pipe(optional), + output: Schema.Int.pipe(optional), }) {} class Model extends Schema.Class("Config.Model")({ - modelID: ID.pipe(Schema.optional), - family: Family.pipe(Schema.optional), - name: Schema.String.pipe(Schema.optional), - compatibility: Compatibility.pipe(Schema.optional), - package: Schema.String.pipe(Schema.optional), + modelID: ID.pipe(optional), + family: Family.pipe(optional), + name: Schema.String.pipe(optional), + compatibility: Compatibility.pipe(optional), + package: Schema.String.pipe(optional), ...Overlays, - capabilities: Capabilities.pipe(Schema.optional), + capabilities: Capabilities.pipe(optional), variants: Schema.Struct({ id: VariantID, ...Overlays, - }).pipe(Schema.Array, Schema.optional), - cost: Schema.Union([Cost, Cost.pipe(Schema.Array)]).pipe(Schema.optional), - disabled: Schema.Boolean.pipe(Schema.optional), - limit: Limit.pipe(Schema.optional), + }).pipe(Schema.Array, optional), + cost: Schema.Union([Cost, Cost.pipe(Schema.Array)]).pipe(optional), + disabled: Schema.Boolean.pipe(optional), + limit: Limit.pipe(optional), }) {} export class Info extends Schema.Class("Config.Provider")({ - name: Schema.String.pipe(Schema.optional), - env: Schema.String.pipe(Schema.Array, Schema.optional), - package: Schema.String.pipe(Schema.optional), + name: Schema.String.pipe(optional), + env: Schema.String.pipe(Schema.Array, optional), + package: Schema.String.pipe(optional), ...Overlays, - models: Schema.Record(Schema.String, Model).pipe(Schema.optional), + models: Schema.Record(Schema.String, Model).pipe(optional), }) {} diff --git a/packages/schema/src/config/reference.ts b/packages/schema/src/config/reference.ts index 7e1e8cf0dec..8d4160e8147 100644 --- a/packages/schema/src/config/reference.ts +++ b/packages/schema/src/config/reference.ts @@ -1,18 +1,19 @@ export * as ConfigReference from "./reference.js" import { Schema } from "effect" +import { optional } from "../schema.js" export class Git extends Schema.Class("Config.Reference.Git")({ repository: Schema.String, - branch: Schema.String.pipe(Schema.optional), - description: Schema.String.pipe(Schema.optional), - hidden: Schema.Boolean.pipe(Schema.optional), + branch: Schema.String.pipe(optional), + description: Schema.String.pipe(optional), + hidden: Schema.Boolean.pipe(optional), }) {} export class Local extends Schema.Class("Config.Reference.Local")({ path: Schema.String, - description: Schema.String.pipe(Schema.optional), - hidden: Schema.Boolean.pipe(Schema.optional), + description: Schema.String.pipe(optional), + hidden: Schema.Boolean.pipe(optional), }) {} export const Entry = Schema.Union([Schema.String, Git, Local]) diff --git a/packages/schema/src/config/tool-output.ts b/packages/schema/src/config/tool-output.ts index 68ba0526983..3e9cebaa127 100644 --- a/packages/schema/src/config/tool-output.ts +++ b/packages/schema/src/config/tool-output.ts @@ -1,9 +1,9 @@ export * as ConfigToolOutput from "./tool-output.js" import { Schema } from "effect" -import { PositiveInt } from "../schema.js" +import { optional, PositiveInt } from "../schema.js" export class Info extends Schema.Class("Config.ToolOutput")({ - max_lines: PositiveInt.pipe(Schema.optional), - max_bytes: PositiveInt.pipe(Schema.optional), + max_lines: PositiveInt.pipe(optional), + max_bytes: PositiveInt.pipe(optional), }) {} diff --git a/packages/schema/src/config/warming.ts b/packages/schema/src/config/warming.ts index 8f0ab1a546e..94bd6327c83 100644 --- a/packages/schema/src/config/warming.ts +++ b/packages/schema/src/config/warming.ts @@ -1,15 +1,16 @@ export * as ConfigWarming from "./warming.js" import { Schema } from "effect" +import { optional } from "../schema.js" export class Info extends Schema.Class("Config.Warming")({ - prompt: Schema.String.pipe(Schema.optional).annotate({ + prompt: Schema.String.pipe(optional).annotate({ description: "Prompt sent for keep-alive requests", }), - interval: Schema.DurationFromString.pipe(Schema.optional).annotate({ + interval: Schema.DurationFromString.pipe(optional).annotate({ description: 'Idle time between keep-alive requests (default: "4 minutes")', }), - duration: Schema.DurationFromString.pipe(Schema.optional).annotate({ + duration: Schema.DurationFromString.pipe(optional).annotate({ description: 'Time after the last active request to keep a session warm (default: "30 minutes")', }), }) {} diff --git a/packages/schema/src/config/watcher.ts b/packages/schema/src/config/watcher.ts index 78d6ddbe60a..d3c6da25579 100644 --- a/packages/schema/src/config/watcher.ts +++ b/packages/schema/src/config/watcher.ts @@ -1,7 +1,8 @@ export * as ConfigWatcher from "./watcher.js" import { Schema } from "effect" +import { optional } from "../schema.js" export class Info extends Schema.Class("Config.Watcher")({ - ignore: Schema.String.pipe(Schema.Array, Schema.optional), + ignore: Schema.String.pipe(Schema.Array, optional), }) {} diff --git a/packages/schema/src/mcp.ts b/packages/schema/src/mcp.ts index a4a97519d94..6fc4ac40b7b 100644 --- a/packages/schema/src/mcp.ts +++ b/packages/schema/src/mcp.ts @@ -5,13 +5,13 @@ import { optional, PositiveInt } from "./schema.js" import { IntegrationID } from "./integration-id.js" export class TimeoutConfig extends Schema.Class("Mcp.TimeoutConfig")({ - startup: PositiveInt.pipe(Schema.optional).annotate({ + startup: PositiveInt.pipe(optional).annotate({ description: "Maximum time in milliseconds to establish and initialize the MCP server.", }), - catalog: PositiveInt.pipe(Schema.optional).annotate({ + catalog: PositiveInt.pipe(optional).annotate({ description: "Maximum time in milliseconds to wait for MCP discovery requests such as tools/list and prompts/list.", }), - execution: PositiveInt.pipe(Schema.optional).annotate({ + execution: PositiveInt.pipe(optional).annotate({ description: "Maximum time in milliseconds to wait for MCP tool and prompt execution.", }), }) {} @@ -19,35 +19,35 @@ export class TimeoutConfig extends Schema.Class("Mcp.TimeoutConfi export class LocalConfig extends Schema.Class("Mcp.LocalConfig")({ type: Schema.Literal("local"), command: Schema.String.pipe(Schema.Array), - cwd: Schema.String.pipe(Schema.optional).annotate({ + cwd: Schema.String.pipe(optional).annotate({ description: "Working directory for the MCP server process. Relative paths resolve from the workspace directory.", }), - environment: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional), - disabled: Schema.Boolean.pipe(Schema.optional), - codemode: Schema.Boolean.pipe(Schema.optional).annotate({ + environment: Schema.Record(Schema.String, Schema.String).pipe(optional), + disabled: Schema.Boolean.pipe(optional), + codemode: Schema.Boolean.pipe(optional).annotate({ description: "Expose this server's tools through Code Mode. Defaults to true.", }), - timeout: TimeoutConfig.pipe(Schema.optional), + timeout: TimeoutConfig.pipe(optional), }) {} export class OAuthConfig extends Schema.Class("Mcp.OAuthConfig")({ - client_id: Schema.String.pipe(Schema.optional), - client_secret: Schema.String.pipe(Schema.optional), - scope: Schema.String.pipe(Schema.optional), - callback_port: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 65535 })).pipe(Schema.optional), - redirect_uri: Schema.String.pipe(Schema.optional), + client_id: Schema.String.pipe(optional), + client_secret: Schema.String.pipe(optional), + scope: Schema.String.pipe(optional), + callback_port: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 65535 })).pipe(optional), + redirect_uri: Schema.String.pipe(optional), }) {} export class RemoteConfig extends Schema.Class("Mcp.RemoteConfig")({ type: Schema.Literal("remote"), url: Schema.String, - headers: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional), - oauth: Schema.Union([OAuthConfig, Schema.Literal(false)]).pipe(Schema.optional), - disabled: Schema.Boolean.pipe(Schema.optional), - codemode: Schema.Boolean.pipe(Schema.optional).annotate({ + headers: Schema.Record(Schema.String, Schema.String).pipe(optional), + oauth: Schema.Union([OAuthConfig, Schema.Literal(false)]).pipe(optional), + disabled: Schema.Boolean.pipe(optional), + codemode: Schema.Boolean.pipe(optional).annotate({ description: "Expose this server's tools through Code Mode. Defaults to true.", }), - timeout: TimeoutConfig.pipe(Schema.optional), + timeout: TimeoutConfig.pipe(optional), }) {} export const ServerConfig = Schema.Union([LocalConfig, RemoteConfig]).pipe(Schema.toTaggedUnion("type")) diff --git a/packages/schema/test/config.test.ts b/packages/schema/test/config.test.ts index e58723993d1..9cc4e5cb3c7 100644 --- a/packages/schema/test/config.test.ts +++ b/packages/schema/test/config.test.ts @@ -1,6 +1,10 @@ import { describe, expect, test } from "bun:test" import { Schema } from "effect" import { Config } from "../src/config.js" +import { ConfigAgent } from "../src/config/agent.js" +import { ConfigMCP } from "../src/config/mcp.js" +import { ConfigProvider } from "../src/config/provider.js" +import { Mcp } from "../src/mcp.js" import { AbsolutePath } from "../src/schema.js" describe("Config.Entry", () => { @@ -29,7 +33,14 @@ describe("Config.Entry", () => { expect(decoded).toEqual(entries) expect(decoded[0]).toBeInstanceOf(Config.Document) expect(decoded[1]).not.toHaveProperty("path") - expect(decoded.map((entry) => entry.type)).toEqual(["document", "document", "directory", "file", "agents", "claude"]) + expect(decoded.map((entry) => entry.type)).toEqual([ + "document", + "document", + "directory", + "file", + "agents", + "claude", + ]) expect(decoded[0]?.type === "document" ? decoded[0].info.permissions : undefined).toEqual([ { action: "shell", resource: "*", effect: "ask" }, { action: "shell", resource: "git status", effect: "allow" }, @@ -39,4 +50,39 @@ describe("Config.Entry", () => { test("has a stable public identifier", () => { expect(Config.Entry.ast.annotations?.identifier).toBe("Config.Entry") }) + + test("omits undefined optional properties while encoding", () => { + const entry = new Config.Document({ + type: "document", + path: undefined, + info: new Config.Info({ + default_agent: undefined, + agents: { reviewer: new ConfigAgent.Info({ description: undefined }) }, + mcp: new ConfigMCP.Info({ + timeout: undefined, + servers: { + docs: new Mcp.RemoteConfig({ + type: "remote", + url: "https://example.com/mcp", + headers: undefined, + oauth: new Mcp.OAuthConfig({ client_id: undefined }), + }), + }, + }), + providers: { custom: new ConfigProvider.Info({ headers: undefined }) }, + }), + }) + const encoded = Schema.encodeSync(Config.Entry)(entry) + if (encoded.type !== "document") throw new Error("Expected a config document") + + expect(encoded).not.toHaveProperty("path") + expect(encoded.info).not.toHaveProperty("default_agent") + expect(encoded.info.agents?.reviewer).not.toHaveProperty("description") + expect(encoded.info.mcp).not.toHaveProperty("timeout") + const docs = encoded.info.mcp?.servers?.docs + if (docs?.type !== "remote" || docs.oauth === false) throw new Error("Expected a remote MCP server") + expect(docs).not.toHaveProperty("headers") + expect(docs.oauth).not.toHaveProperty("client_id") + expect(encoded.info.providers?.custom).not.toHaveProperty("headers") + }) }) diff --git a/packages/server/test/config.test.ts b/packages/server/test/config.test.ts index 4ab941986c5..2f899741b64 100644 --- a/packages/server/test/config.test.ts +++ b/packages/server/test/config.test.ts @@ -16,7 +16,9 @@ it.live("returns ordered config entries for the requested directory", () => const global = path.join(tmp.path, "global") const project = path.join(tmp.path, "project") const config = path.join(project, "opencode.json") - yield* Effect.promise(() => Promise.all([fs.mkdir(global, { recursive: true }), fs.mkdir(project, { recursive: true })])) + yield* Effect.promise(() => + Promise.all([fs.mkdir(global, { recursive: true }), fs.mkdir(project, { recursive: true })]), + ) yield* Effect.promise(() => fs.writeFile( config, @@ -25,6 +27,7 @@ it.live("returns ordered config entries for the requested directory", () => { action: "shell", resource: "*", effect: "ask" }, { action: "shell", resource: "git status", effect: "allow" }, ], + mcp: { servers: { docs: { type: "remote", url: "https://example.com/mcp" } } }, }), ), ) @@ -42,9 +45,8 @@ it.live("returns ordered config entries for the requested directory", () => const response = yield* Effect.promise(() => fetch(url, { headers: { authorization: `Basic ${btoa("opencode:secret")}` } }), ) - const entries = Schema.decodeUnknownSync(Schema.Array(Config.Entry))( - yield* Effect.promise(() => response.json()), - ) + const body: unknown = yield* Effect.promise(() => response.json()) + const entries = Schema.decodeUnknownSync(Schema.Array(Config.Entry))(body) expect(response.status).toBe(200) expect(Array.isArray(entries)).toBe(true) @@ -56,7 +58,21 @@ it.live("returns ordered config entries for the requested directory", () => { action: "shell", resource: "git status", effect: "allow" }, ]) expect(entries.some((entry) => entry.type === "file" && entry.path === config)).toBe(true) + if (!Array.isArray(body)) throw new Error("Expected a config entry array") + const raw = body.find((entry) => isRecord(entry) && entry["type"] === "document" && entry["path"] === config) + if (!isRecord(raw) || !isRecord(raw["info"])) throw new Error("Expected a config document") + expect(raw["info"]).not.toHaveProperty("default_agent") + expect(raw["info"]).not.toHaveProperty("model") + const mcp = raw["info"]["mcp"] + if (!isRecord(mcp) || !isRecord(mcp["servers"]) || !isRecord(mcp["servers"]["docs"])) + throw new Error("Expected an MCP server config") + expect(mcp["servers"]["docs"]).not.toHaveProperty("headers") + expect(mcp["servers"]["docs"]).not.toHaveProperty("oauth") }), (tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()), ), ) + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value) +} diff --git a/packages/www/openapi.json b/packages/www/openapi.json index 01eafbf26e5..17b55e7f060 100644 --- a/packages/www/openapi.json +++ b/packages/www/openapi.json @@ -20722,60 +20722,6 @@ ], "additionalProperties": false }, - "Mcp.TimeoutConfig": { - "type": "object", - "properties": { - "startup": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to establish and initialize the MCP server." - }, - "catalog": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP discovery requests such as tools/list and prompts/list." - }, - "execution": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP tool and prompt execution." - } - }, - "additionalProperties": false - }, "Mcp.LocalConfig": { "type": "object", "properties": { @@ -20792,59 +20738,49 @@ } }, "cwd": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Working directory for the MCP server process. Relative paths resolve from the workspace directory." + "type": "string" }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -20857,60 +20793,25 @@ "type": "object", "properties": { "client_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "client_secret": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "scope": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "callback_port": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "minimum": 1, - "maximum": 65535 - } - ] - }, - { - "type": "null" + "minimum": 1, + "maximum": 65535 } ] }, "redirect_uri": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -20928,68 +20829,59 @@ "type": "string" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "oauth": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.OAuthConfig" - }, - { - "type": "boolean", - "enum": [ - false - ] - } - ] + "$ref": "#/components/schemas/Mcp.OAuthConfig" }, { - "type": "null" + "type": "boolean", + "enum": [ + false + ] } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -26490,38 +26382,31 @@ ], "additionalProperties": false }, - "Config.ModelSelection": { - "anyOf": [ - { - "type": "string", - "allOf": [ + "Config.Agent": { + "type": "object", + "properties": { + "model": { + "anyOf": [ { - "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" - } - ] - }, - { - "type": "object", - "properties": { - "providerID": { "type": "string", "allOf": [ { - "pattern": "^[^/#]+$" + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" } ] }, - "model": { - "type": "string", - "allOf": [ - { - "pattern": "^[^#]+$" - } - ] - }, - "variant": { - "anyOf": [ - { + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { "type": "string", "allOf": [ { @@ -26529,185 +26414,76 @@ } ] }, - { - "type": "null" + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] } - ] + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } - }, - "required": [ - "providerID", - "model" - ], - "additionalProperties": false - } - ] - }, - "Config.Provider.Request": { - "type": "object", - "properties": { - "headers": { - "anyOf": [ - { + ] + }, + "request": { + "type": "object", + "properties": { + "headers": { "type": "object", "additionalProperties": { "type": "string" } }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { + "body": { "type": "object" - }, - { - "type": "null" } - ] - } - }, - "additionalProperties": false - }, - "Config.Agent": { - "type": "object", - "properties": { - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ] - }, - "request": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Provider.Request" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false }, "system": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "mode": { - "anyOf": [ - { - "type": "string", - "enum": [ - "subagent", - "primary", - "all" - ] - }, - { - "type": "null" - } + "type": "string", + "enum": [ + "subagent", + "primary", + "all" ] }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "color": { - "anyOf": [ + "type": "string", + "allOf": [ { - "type": "string", - "allOf": [ - { - "pattern": "^#[0-9a-fA-F]{6}$" - } - ] - }, - { - "type": "null" + "pattern": "^#[0-9a-fA-F]{6}$" } ] }, "steps": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" + "exclusiveMinimum": 0 } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Watcher": { - "type": "object", - "properties": { - "ignore": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Permission.Ruleset" } }, "additionalProperties": false @@ -26716,53 +26492,25 @@ "type": "object", "properties": { "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "command": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } } }, "additionalProperties": false @@ -26777,50 +26525,22 @@ } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "env": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "initialization": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -26828,217 +26548,6 @@ ], "additionalProperties": false }, - "Config.Media.Image": { - "type": "object", - "properties": { - "auto_resize": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "max_width": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_height": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_base64_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Media": { - "type": "object", - "properties": { - "image": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media.Image" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.ToolOutput": { - "type": "object", - "properties": { - "max_lines": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.MCP": { - "type": "object", - "properties": { - "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" - }, - { - "type": "null" - } - ] - }, - "servers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.LocalConfig" - }, - { - "$ref": "#/components/schemas/Mcp.RemoteConfig" - } - ] - } - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction.Keep": { - "type": "object", - "properties": { - "tokens": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction": { - "type": "object", - "properties": { - "auto": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "keep": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction.Keep" - }, - { - "type": "null" - } - ] - }, - "buffer": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Command": { "type": "object", "properties": { @@ -27046,44 +26555,59 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "model": { "anyOf": [ { - "$ref": "#/components/schemas/Config.ModelSelection" + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] }, { - "type": "null" + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } ] }, "subtask": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27098,34 +26622,13 @@ "type": "string" }, "branch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27140,24 +26643,10 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27165,18 +26654,6 @@ ], "additionalProperties": false }, - "ConfigWebSearch.Info": { - "type": "object", - "properties": { - "provider": { - "type": "string" - } - }, - "required": [ - "provider" - ], - "additionalProperties": false - }, "Config.Plugin.Entry": { "type": "object", "properties": { @@ -27184,14 +26661,7 @@ "type": "string" }, "options": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -27203,63 +26673,13 @@ "type": "object", "properties": { "prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Prompt sent for keep-alive requests" + "type": "string" }, "interval": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Idle time between keep-alive requests (default: \"4 minutes\")" + "type": "string" }, "duration": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Time after the last active request to keep a session warm (default: \"30 minutes\")" - } - }, - "additionalProperties": false - }, - "Config.Model.Cost.Cache": { - "type": "object", - "properties": { - "read": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] - }, - "write": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -27268,30 +26688,23 @@ "type": "object", "properties": { "tier": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "context" - ] - }, - "size": { - "type": "integer" - } - }, - "required": [ - "type", - "size" - ], - "additionalProperties": false + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "context" + ] }, - { - "type": "null" + "size": { + "type": "integer" } - ] + }, + "required": [ + "type", + "size" + ], + "additionalProperties": false }, "input": { "$ref": "#/components/schemas/Money.USDPerMillionTokens" @@ -27300,14 +26713,16 @@ "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, "cache": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost.Cache" + "type": "object", + "properties": { + "read": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, - { - "type": "null" + "write": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" } - ] + }, + "additionalProperties": false } }, "required": [ @@ -27316,232 +26731,96 @@ ], "additionalProperties": false }, - "Config.Model.Limit": { - "type": "object", - "properties": { - "context": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "input": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "output": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Model": { "type": "object", "properties": { "modelID": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "family": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "compatibility": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Compatibility" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Compatibility" }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "capabilities": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Capabilities" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Capabilities" }, "variants": { - "anyOf": [ - { - "type": "array", - "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "settings": { + "type": "object" + }, + "headers": { "type": "object", - "properties": { - "id": { - "type": "string" - }, - "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - }, - "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id" - ], - "additionalProperties": false + "additionalProperties": { + "type": "string" + } + }, + "body": { + "type": "object" } }, - { - "type": "null" - } - ] + "required": [ + "id" + ], + "additionalProperties": false + } }, "cost": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost" - }, - { - "type": "array", - "items": { - "$ref": "#/components/schemas/Config.Model.Cost" - } - } - ] + "$ref": "#/components/schemas/Config.Model.Cost" }, { - "type": "null" + "type": "array", + "items": { + "$ref": "#/components/schemas/Config.Model.Cost" + } } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "limit": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Limit" + "type": "object", + "properties": { + "context": { + "type": "integer" }, - { - "type": "null" + "input": { + "type": "integer" + }, + "output": { + "type": "integer" } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -27550,93 +26829,418 @@ "type": "object", "properties": { "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "env": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "models": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Model" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Model" + } } }, "additionalProperties": false }, - "ConfigExperimental.Info": { + "Config.Info": { "type": "object", "properties": { - "subagent_depth": { + "$schema": { + "type": "string" + }, + "shell": { + "type": "string" + }, + "model": { "anyOf": [ { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] + }, + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false + } + ] + }, + "default_agent": { + "type": "string" + }, + "autoupdate": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string", + "enum": [ + "notify" + ] + } + ] + }, + "share": { + "type": "string", + "enum": [ + "manual", + "auto", + "disabled" + ] + }, + "enterprise": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "username": { + "type": "string" + }, + "permissions": { + "$ref": "#/components/schemas/Permission.Ruleset" + }, + "agents": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Agent" + } + }, + "snapshots": { + "type": "boolean" + }, + "watcher": { + "type": "object", + "properties": { + "ignore": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "formatter": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Formatter.Entry" + } + } + ] + }, + "lsp": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "enum": [ + true + ] + } + }, + "required": [ + "disabled" + ], + "additionalProperties": false + }, + { + "$ref": "#/components/schemas/Config.LSP.Server" + } + ] + } + } + ] + }, + "media": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "auto_resize": { + "type": "boolean" + }, + "max_width": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_height": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_base64_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "tool_output": { + "type": "object", + "properties": { + "max_lines": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "mcp": { + "type": "object", + "properties": { + "timeout": { + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "servers": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/components/schemas/Mcp.LocalConfig" + }, + { + "$ref": "#/components/schemas/Mcp.RemoteConfig" + } + ] + } + } + }, + "additionalProperties": false + }, + "compaction": { + "type": "object", + "properties": { + "auto": { + "type": "boolean" + }, + "keep": { + "type": "object", + "properties": { + "tokens": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "buffer": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "skills": { + "type": "array", + "items": { + "type": "string" + } + }, + "commands": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Command" + } + }, + "instructions": { + "type": "array", + "items": { + "type": "string" + } + }, + "references": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Reference.Git" + }, + { + "$ref": "#/components/schemas/Config.Reference.Local" + } + ] + } + }, + "websearch": { + "type": "object", + "properties": { + "provider": { + "type": "string" + } + }, + "required": [ + "provider" + ], + "additionalProperties": false + }, + "plugins": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Plugin.Entry" + } + ] + } + }, + "warming": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/components/schemas/Config.Warming" + } + ] + }, + "providers": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Provider" + } + }, + "experimental": { + "type": "object", + "properties": { + "subagent_depth": { "type": "integer", "allOf": [ { @@ -27644,15 +27248,7 @@ } ] }, - { - "type": "null" - } - ], - "description": "Maximum subagent nesting depth. Defaults to 1." - }, - "policies": { - "anyOf": [ - { + "policies": { "type": "array", "items": { "type": "object", @@ -27681,425 +27277,9 @@ ], "additionalProperties": false } - }, - { - "type": "null" } - ], - "description": "Ordered policies controlling access to configured resources" - } - }, - "additionalProperties": false - }, - "Config.Info": { - "type": "object", - "properties": { - "$schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "JSON schema reference for configuration validation" - }, - "shell": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default shell to use for terminal and shell tool execution" - }, - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ], - "description": "Default model to use when no session or agent model is selected" - }, - "default_agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default primary agent to use when no session agent is selected" - }, - "autoupdate": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string", - "enum": [ - "notify" - ] - } - ] - }, - { - "type": "null" - } - ], - "description": "Automatically update or notify when a new version is available" - }, - "share": { - "anyOf": [ - { - "type": "string", - "enum": [ - "manual", - "auto", - "disabled" - ] - }, - { - "type": "null" - } - ], - "description": "Control whether sessions may be shared manually, automatically, or not at all" - }, - "enterprise": { - "anyOf": [ - { - "type": "object", - "properties": { - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "null" - } - ], - "description": "Enterprise sharing service configuration" - }, - "username": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Username displayed in conversations and used for telemetry identity" - }, - "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ], - "description": "Ordered tool permission rules applied to agent tool use" - }, - "agents": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Agent" - } - }, - { - "type": "null" - } - ], - "description": "Named built-in agent overrides and custom agent definitions" - }, - "snapshots": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Enable snapshots used for undo and revert behavior" - }, - "watcher": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Watcher" - }, - { - "type": "null" - } - ], - "description": "Filesystem watcher configuration" - }, - "formatter": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Formatter.Entry" - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in formatters or configure formatter overrides" - }, - "lsp": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "object", - "properties": { - "disabled": { - "type": "boolean", - "enum": [ - true - ] - } - }, - "required": [ - "disabled" - ], - "additionalProperties": false - }, - { - "$ref": "#/components/schemas/Config.LSP.Server" - } - ] - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in language servers or configure server overrides" - }, - "media": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media" - }, - { - "type": "null" - } - ], - "description": "Media processing configuration" - }, - "tool_output": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ToolOutput" - }, - { - "type": "null" - } - ], - "description": "Tool output truncation thresholds" - }, - "mcp": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.MCP" - }, - { - "type": "null" - } - ], - "description": "MCP server configuration" - }, - "compaction": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction" - }, - { - "type": "null" - } - ], - "description": "Conversation compaction behavior" - }, - "skills": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs to discover skills from" - }, - "commands": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Command" - } - }, - { - "type": "null" - } - ], - "description": "Named slash command definitions" - }, - "instructions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs supplying ambient instructions" - }, - "references": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Reference.Git" - }, - { - "$ref": "#/components/schemas/Config.Reference.Local" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Named local directories or Git repositories available as external context" - }, - "websearch": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigWebSearch.Info" - }, - { - "type": "null" - } - ], - "description": "Web search provider selection" - }, - "plugins": { - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Plugin.Entry" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Ordered plugin enablement directives and external package declarations" - }, - "warming": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/components/schemas/Config.Warming" - } - ] - }, - { - "type": "null" - } - ], - "description": "Keep recently active sessions warm with transient model requests (default: false)" - }, - "providers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Provider" - } - }, - { - "type": "null" - } - ] - }, - "experimental": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigExperimental.Info" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -28114,14 +27294,7 @@ ] }, "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "info": { "$ref": "#/components/schemas/Config.Info" diff --git a/packages/www/public/openapi.json b/packages/www/public/openapi.json index 01eafbf26e5..17b55e7f060 100644 --- a/packages/www/public/openapi.json +++ b/packages/www/public/openapi.json @@ -20722,60 +20722,6 @@ ], "additionalProperties": false }, - "Mcp.TimeoutConfig": { - "type": "object", - "properties": { - "startup": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to establish and initialize the MCP server." - }, - "catalog": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP discovery requests such as tools/list and prompts/list." - }, - "execution": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ], - "description": "Maximum time in milliseconds to wait for MCP tool and prompt execution." - } - }, - "additionalProperties": false - }, "Mcp.LocalConfig": { "type": "object", "properties": { @@ -20792,59 +20738,49 @@ } }, "cwd": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Working directory for the MCP server process. Relative paths resolve from the workspace directory." + "type": "string" }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -20857,60 +20793,25 @@ "type": "object", "properties": { "client_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "client_secret": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "scope": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "callback_port": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "minimum": 1, - "maximum": 65535 - } - ] - }, - { - "type": "null" + "minimum": 1, + "maximum": 65535 } ] }, "redirect_uri": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -20928,68 +20829,59 @@ "type": "string" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "oauth": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.OAuthConfig" - }, - { - "type": "boolean", - "enum": [ - false - ] - } - ] + "$ref": "#/components/schemas/Mcp.OAuthConfig" }, { - "type": "null" + "type": "boolean", + "enum": [ + false + ] } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "codemode": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Expose this server's tools through Code Mode. Defaults to true." + "type": "boolean" }, "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] }, - { - "type": "null" + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] } - ] + }, + "additionalProperties": false } }, "required": [ @@ -26490,38 +26382,31 @@ ], "additionalProperties": false }, - "Config.ModelSelection": { - "anyOf": [ - { - "type": "string", - "allOf": [ + "Config.Agent": { + "type": "object", + "properties": { + "model": { + "anyOf": [ { - "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" - } - ] - }, - { - "type": "object", - "properties": { - "providerID": { "type": "string", "allOf": [ { - "pattern": "^[^/#]+$" + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" } ] }, - "model": { - "type": "string", - "allOf": [ - { - "pattern": "^[^#]+$" - } - ] - }, - "variant": { - "anyOf": [ - { + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { "type": "string", "allOf": [ { @@ -26529,185 +26414,76 @@ } ] }, - { - "type": "null" + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] } - ] + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } - }, - "required": [ - "providerID", - "model" - ], - "additionalProperties": false - } - ] - }, - "Config.Provider.Request": { - "type": "object", - "properties": { - "headers": { - "anyOf": [ - { + ] + }, + "request": { + "type": "object", + "properties": { + "headers": { "type": "object", "additionalProperties": { "type": "string" } }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { + "body": { "type": "object" - }, - { - "type": "null" } - ] - } - }, - "additionalProperties": false - }, - "Config.Agent": { - "type": "object", - "properties": { - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ] - }, - "request": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Provider.Request" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false }, "system": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "mode": { - "anyOf": [ - { - "type": "string", - "enum": [ - "subagent", - "primary", - "all" - ] - }, - { - "type": "null" - } + "type": "string", + "enum": [ + "subagent", + "primary", + "all" ] }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "color": { - "anyOf": [ + "type": "string", + "allOf": [ { - "type": "string", - "allOf": [ - { - "pattern": "^#[0-9a-fA-F]{6}$" - } - ] - }, - { - "type": "null" + "pattern": "^#[0-9a-fA-F]{6}$" } ] }, "steps": { - "anyOf": [ + "type": "integer", + "allOf": [ { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" + "exclusiveMinimum": 0 } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Watcher": { - "type": "object", - "properties": { - "ignore": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Permission.Ruleset" } }, "additionalProperties": false @@ -26716,53 +26492,25 @@ "type": "object", "properties": { "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "command": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "environment": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } } }, "additionalProperties": false @@ -26777,50 +26525,22 @@ } }, "extensions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "env": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "initialization": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -26828,217 +26548,6 @@ ], "additionalProperties": false }, - "Config.Media.Image": { - "type": "object", - "properties": { - "auto_resize": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "max_width": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_height": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_base64_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Media": { - "type": "object", - "properties": { - "image": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media.Image" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.ToolOutput": { - "type": "object", - "properties": { - "max_lines": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "max_bytes": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "exclusiveMinimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.MCP": { - "type": "object", - "properties": { - "timeout": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.TimeoutConfig" - }, - { - "type": "null" - } - ] - }, - "servers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "$ref": "#/components/schemas/Mcp.LocalConfig" - }, - { - "$ref": "#/components/schemas/Mcp.RemoteConfig" - } - ] - } - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction.Keep": { - "type": "object", - "properties": { - "tokens": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Config.Compaction": { - "type": "object", - "properties": { - "auto": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "keep": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction.Keep" - }, - { - "type": "null" - } - ] - }, - "buffer": { - "anyOf": [ - { - "type": "integer", - "allOf": [ - { - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Command": { "type": "object", "properties": { @@ -27046,44 +26555,59 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "model": { "anyOf": [ { - "$ref": "#/components/schemas/Config.ModelSelection" + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] }, { - "type": "null" + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false } ] }, "subtask": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27098,34 +26622,13 @@ "type": "string" }, "branch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27140,24 +26643,10 @@ "type": "string" }, "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "hidden": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" } }, "required": [ @@ -27165,18 +26654,6 @@ ], "additionalProperties": false }, - "ConfigWebSearch.Info": { - "type": "object", - "properties": { - "provider": { - "type": "string" - } - }, - "required": [ - "provider" - ], - "additionalProperties": false - }, "Config.Plugin.Entry": { "type": "object", "properties": { @@ -27184,14 +26661,7 @@ "type": "string" }, "options": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" } }, "required": [ @@ -27203,63 +26673,13 @@ "type": "object", "properties": { "prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Prompt sent for keep-alive requests" + "type": "string" }, "interval": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Idle time between keep-alive requests (default: \"4 minutes\")" + "type": "string" }, "duration": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Time after the last active request to keep a session warm (default: \"30 minutes\")" - } - }, - "additionalProperties": false - }, - "Config.Model.Cost.Cache": { - "type": "object", - "properties": { - "read": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] - }, - "write": { - "anyOf": [ - { - "$ref": "#/components/schemas/Money.USDPerMillionTokens" - }, - { - "type": "null" - } - ] + "type": "string" } }, "additionalProperties": false @@ -27268,30 +26688,23 @@ "type": "object", "properties": { "tier": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "context" - ] - }, - "size": { - "type": "integer" - } - }, - "required": [ - "type", - "size" - ], - "additionalProperties": false + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "context" + ] }, - { - "type": "null" + "size": { + "type": "integer" } - ] + }, + "required": [ + "type", + "size" + ], + "additionalProperties": false }, "input": { "$ref": "#/components/schemas/Money.USDPerMillionTokens" @@ -27300,14 +26713,16 @@ "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, "cache": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost.Cache" + "type": "object", + "properties": { + "read": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" }, - { - "type": "null" + "write": { + "$ref": "#/components/schemas/Money.USDPerMillionTokens" } - ] + }, + "additionalProperties": false } }, "required": [ @@ -27316,232 +26731,96 @@ ], "additionalProperties": false }, - "Config.Model.Limit": { - "type": "object", - "properties": { - "context": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "input": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "output": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, "Config.Model": { "type": "object", "properties": { "modelID": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "family": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "compatibility": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Compatibility" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Compatibility" }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "capabilities": { - "anyOf": [ - { - "$ref": "#/components/schemas/Model.Capabilities" - }, - { - "type": "null" - } - ] + "$ref": "#/components/schemas/Model.Capabilities" }, "variants": { - "anyOf": [ - { - "type": "array", - "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "settings": { + "type": "object" + }, + "headers": { "type": "object", - "properties": { - "id": { - "type": "string" - }, - "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - }, - "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id" - ], - "additionalProperties": false + "additionalProperties": { + "type": "string" + } + }, + "body": { + "type": "object" } }, - { - "type": "null" - } - ] + "required": [ + "id" + ], + "additionalProperties": false + } }, "cost": { "anyOf": [ { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Cost" - }, - { - "type": "array", - "items": { - "$ref": "#/components/schemas/Config.Model.Cost" - } - } - ] + "$ref": "#/components/schemas/Config.Model.Cost" }, { - "type": "null" + "type": "array", + "items": { + "$ref": "#/components/schemas/Config.Model.Cost" + } } ] }, "disabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ] + "type": "boolean" }, "limit": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Model.Limit" + "type": "object", + "properties": { + "context": { + "type": "integer" }, - { - "type": "null" + "input": { + "type": "integer" + }, + "output": { + "type": "integer" } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -27550,93 +26829,418 @@ "type": "object", "properties": { "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "env": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "array", + "items": { + "type": "string" + } }, "package": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "settings": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "headers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "type": "string" + } }, "body": { - "anyOf": [ - { - "type": "object" - }, - { - "type": "null" - } - ] + "type": "object" }, "models": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Model" - } - }, - { - "type": "null" - } - ] + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Model" + } } }, "additionalProperties": false }, - "ConfigExperimental.Info": { + "Config.Info": { "type": "object", "properties": { - "subagent_depth": { + "$schema": { + "type": "string" + }, + "shell": { + "type": "string" + }, + "model": { "anyOf": [ { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+\\/[^#]+(?:#[^#]+)?$" + } + ] + }, + { + "type": "object", + "properties": { + "providerID": { + "type": "string", + "allOf": [ + { + "pattern": "^[^/#]+$" + } + ] + }, + "model": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + }, + "variant": { + "type": "string", + "allOf": [ + { + "pattern": "^[^#]+$" + } + ] + } + }, + "required": [ + "providerID", + "model" + ], + "additionalProperties": false + } + ] + }, + "default_agent": { + "type": "string" + }, + "autoupdate": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string", + "enum": [ + "notify" + ] + } + ] + }, + "share": { + "type": "string", + "enum": [ + "manual", + "auto", + "disabled" + ] + }, + "enterprise": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "username": { + "type": "string" + }, + "permissions": { + "$ref": "#/components/schemas/Permission.Ruleset" + }, + "agents": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Agent" + } + }, + "snapshots": { + "type": "boolean" + }, + "watcher": { + "type": "object", + "properties": { + "ignore": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "formatter": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Formatter.Entry" + } + } + ] + }, + "lsp": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "enum": [ + true + ] + } + }, + "required": [ + "disabled" + ], + "additionalProperties": false + }, + { + "$ref": "#/components/schemas/Config.LSP.Server" + } + ] + } + } + ] + }, + "media": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "auto_resize": { + "type": "boolean" + }, + "max_width": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_height": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_base64_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "tool_output": { + "type": "object", + "properties": { + "max_lines": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "max_bytes": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "mcp": { + "type": "object", + "properties": { + "timeout": { + "type": "object", + "properties": { + "startup": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "catalog": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + }, + "execution": { + "type": "integer", + "allOf": [ + { + "exclusiveMinimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "servers": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/components/schemas/Mcp.LocalConfig" + }, + { + "$ref": "#/components/schemas/Mcp.RemoteConfig" + } + ] + } + } + }, + "additionalProperties": false + }, + "compaction": { + "type": "object", + "properties": { + "auto": { + "type": "boolean" + }, + "keep": { + "type": "object", + "properties": { + "tokens": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "buffer": { + "type": "integer", + "allOf": [ + { + "minimum": 0 + } + ] + } + }, + "additionalProperties": false + }, + "skills": { + "type": "array", + "items": { + "type": "string" + } + }, + "commands": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Command" + } + }, + "instructions": { + "type": "array", + "items": { + "type": "string" + } + }, + "references": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Reference.Git" + }, + { + "$ref": "#/components/schemas/Config.Reference.Local" + } + ] + } + }, + "websearch": { + "type": "object", + "properties": { + "provider": { + "type": "string" + } + }, + "required": [ + "provider" + ], + "additionalProperties": false + }, + "plugins": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/Config.Plugin.Entry" + } + ] + } + }, + "warming": { + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/components/schemas/Config.Warming" + } + ] + }, + "providers": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Config.Provider" + } + }, + "experimental": { + "type": "object", + "properties": { + "subagent_depth": { "type": "integer", "allOf": [ { @@ -27644,15 +27248,7 @@ } ] }, - { - "type": "null" - } - ], - "description": "Maximum subagent nesting depth. Defaults to 1." - }, - "policies": { - "anyOf": [ - { + "policies": { "type": "array", "items": { "type": "object", @@ -27681,425 +27277,9 @@ ], "additionalProperties": false } - }, - { - "type": "null" } - ], - "description": "Ordered policies controlling access to configured resources" - } - }, - "additionalProperties": false - }, - "Config.Info": { - "type": "object", - "properties": { - "$schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "JSON schema reference for configuration validation" - }, - "shell": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default shell to use for terminal and shell tool execution" - }, - "model": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ModelSelection" - }, - { - "type": "null" - } - ], - "description": "Default model to use when no session or agent model is selected" - }, - "default_agent": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Default primary agent to use when no session agent is selected" - }, - "autoupdate": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string", - "enum": [ - "notify" - ] - } - ] - }, - { - "type": "null" - } - ], - "description": "Automatically update or notify when a new version is available" - }, - "share": { - "anyOf": [ - { - "type": "string", - "enum": [ - "manual", - "auto", - "disabled" - ] - }, - { - "type": "null" - } - ], - "description": "Control whether sessions may be shared manually, automatically, or not at all" - }, - "enterprise": { - "anyOf": [ - { - "type": "object", - "properties": { - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "null" - } - ], - "description": "Enterprise sharing service configuration" - }, - "username": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Username displayed in conversations and used for telemetry identity" - }, - "permissions": { - "anyOf": [ - { - "$ref": "#/components/schemas/Permission.Ruleset" - }, - { - "type": "null" - } - ], - "description": "Ordered tool permission rules applied to agent tool use" - }, - "agents": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Agent" - } - }, - { - "type": "null" - } - ], - "description": "Named built-in agent overrides and custom agent definitions" - }, - "snapshots": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Enable snapshots used for undo and revert behavior" - }, - "watcher": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Watcher" - }, - { - "type": "null" - } - ], - "description": "Filesystem watcher configuration" - }, - "formatter": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Formatter.Entry" - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in formatters or configure formatter overrides" - }, - "lsp": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "object", - "properties": { - "disabled": { - "type": "boolean", - "enum": [ - true - ] - } - }, - "required": [ - "disabled" - ], - "additionalProperties": false - }, - { - "$ref": "#/components/schemas/Config.LSP.Server" - } - ] - } - } - ] - }, - { - "type": "null" - } - ], - "description": "Enable built-in language servers or configure server overrides" - }, - "media": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Media" - }, - { - "type": "null" - } - ], - "description": "Media processing configuration" - }, - "tool_output": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.ToolOutput" - }, - { - "type": "null" - } - ], - "description": "Tool output truncation thresholds" - }, - "mcp": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.MCP" - }, - { - "type": "null" - } - ], - "description": "MCP server configuration" - }, - "compaction": { - "anyOf": [ - { - "$ref": "#/components/schemas/Config.Compaction" - }, - { - "type": "null" - } - ], - "description": "Conversation compaction behavior" - }, - "skills": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs to discover skills from" - }, - "commands": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Command" - } - }, - { - "type": "null" - } - ], - "description": "Named slash command definitions" - }, - "instructions": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Additional paths or URLs supplying ambient instructions" - }, - "references": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Reference.Git" - }, - { - "$ref": "#/components/schemas/Config.Reference.Local" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Named local directories or Git repositories available as external context" - }, - "websearch": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigWebSearch.Info" - }, - { - "type": "null" - } - ], - "description": "Web search provider selection" - }, - "plugins": { - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/Config.Plugin.Entry" - } - ] - } - }, - { - "type": "null" - } - ], - "description": "Ordered plugin enablement directives and external package declarations" - }, - "warming": { - "anyOf": [ - { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#/components/schemas/Config.Warming" - } - ] - }, - { - "type": "null" - } - ], - "description": "Keep recently active sessions warm with transient model requests (default: false)" - }, - "providers": { - "anyOf": [ - { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Config.Provider" - } - }, - { - "type": "null" - } - ] - }, - "experimental": { - "anyOf": [ - { - "$ref": "#/components/schemas/ConfigExperimental.Info" - }, - { - "type": "null" - } - ] + }, + "additionalProperties": false } }, "additionalProperties": false @@ -28114,14 +27294,7 @@ ] }, "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "type": "string" }, "info": { "$ref": "#/components/schemas/Config.Info"