{
  "$ref": "#/definitions/AgentConfig",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "AgentCardConfig": {
      "additionalProperties": false,
      "description": "Agent identity and capabilities advertised via the A2A Agent Card.\n\nThis interface captures all fields that appear in the public-facing agent card served at `/.well-known/agent-card.json`. Orchestrators and callers use this metadata to discover the agent's name, supported modes, streaming capability, and available skills.",
      "properties": {
        "defaultInputModes": {
          "default": [
            "text"
          ],
          "description": "Supported input content modes.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "defaultOutputModes": {
          "default": [
            "text"
          ],
          "description": "Supported output content modes.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "description": {
          "description": "Agent description shown to orchestrators and callers. Should concisely explain the agent's purpose and domain expertise.",
          "type": "string"
        },
        "name": {
          "description": "Human-readable agent name. Displayed in orchestrator UIs and agent discovery listings.",
          "type": "string"
        },
        "protocolVersion": {
          "default": "0.3.0",
          "deprecated": "Superseded by A2A v1.0's per-interface `protocolVersion`\n(see `AgentCard.supportedInterfaces[]`, built by `buildAgentCard`).\nKept for backward compatibility with existing config files only —\nthe agent card builder no longer reads this value.",
          "description": "A2A protocol version this agent supports.",
          "type": "string"
        },
        "provider": {
          "additionalProperties": false,
          "description": "Agent provider information. Identifies the organization responsible for this agent deployment.",
          "properties": {
            "organization": {
              "description": "Organization name.",
              "type": "string"
            },
            "url": {
              "description": "Optional URL for the provider's website or documentation.",
              "type": "string"
            }
          },
          "required": [
            "organization"
          ],
          "type": "object"
        },
        "pushNotifications": {
          "default": false,
          "description": "Whether the agent supports push notifications.",
          "type": "boolean"
        },
        "signing": {
          "additionalProperties": false,
          "description": "Optional Signed Agent Card support (A2A v1.0, JWS per RFC 7515). Off by default. When enabled, the private key is read from the environment variable named by `privateKeyJwkEnvVar`, whose value must be a JSON-serialized JWK — never store key material in the config file itself.",
          "properties": {
            "algorithm": {
              "description": "JWS algorithm (e.g. `\"RS256\"`, `\"ES256\"`).",
              "type": "string"
            },
            "enabled": {
              "default": false,
              "type": "boolean"
            },
            "keyId": {
              "description": "Key ID (`kid`) to embed in the JWS protected header.",
              "type": "string"
            },
            "privateKeyJwkEnvVar": {
              "description": "Name of the env var holding the signing private key as a JSON JWK.",
              "type": "string"
            }
          },
          "required": [
            "privateKeyJwkEnvVar",
            "keyId",
            "algorithm"
          ],
          "type": "object"
        },
        "skills": {
          "description": "Skills this agent exposes to callers. Each skill represents a discrete capability advertised in the agent card.",
          "items": {
            "$ref": "#/definitions/SkillConfig"
          },
          "type": "array"
        },
        "stateTransitionHistory": {
          "default": false,
          "deprecated": "This capability is not implemented in the A2A v1.0 spec and\nwas removed. Kept for backward compatibility only — value is ignored.\nThe agent card builder always sets this to `false`.",
          "description": "Enable state transition history capability advertisement.",
          "type": "boolean"
        },
        "streaming": {
          "default": true,
          "description": "Whether the agent supports streaming responses.",
          "type": "boolean"
        },
        "version": {
          "default": "1.0.0",
          "description": "Agent software version string.",
          "type": "string"
        }
      },
      "required": [
        "name",
        "description"
      ],
      "type": "object"
    },
    "AgentConfig": {
      "additionalProperties": false,
      "description": "Complete agent configuration.\n\nThis is what a JSON config file (e.g. `agents/example/config.json`) maps to. All fields are optional — sensible defaults are applied for everything.",
      "properties": {
        "agentCard": {
          "$ref": "#/definitions/AgentCardConfig",
          "description": "Agent card identity & capabilities"
        },
        "configDir": {
          "description": "Directory containing the agent's config.json file. Populated automatically by the CLI scaffold when a config file path is provided. Used by the materializer for resolving relative paths in memory config.",
          "type": "string"
        },
        "copilot": {
          "$ref": "#/definitions/CopilotConfig",
          "description": "Copilot SDK connection settings"
        },
        "customAgents": {
          "description": "Custom agent definitions to register with Copilot sessions.",
          "items": {
            "$ref": "#/definitions/CustomAgentConfig"
          },
          "type": "array"
        },
        "events": {
          "$ref": "#/definitions/EventsConfig",
          "description": "Event transport configuration for sideband observability events."
        },
        "features": {
          "$ref": "#/definitions/FeatureFlags",
          "description": "Feature flags"
        },
        "logging": {
          "$ref": "#/definitions/LoggingConfig",
          "description": "Logging settings"
        },
        "mcp": {
          "additionalProperties": {
            "$ref": "#/definitions/McpServerConfig"
          },
          "description": "MCP servers to connect via Copilot SDK at session creation. Keys are server names, values are server configs.",
          "type": "object"
        },
        "memory": {
          "$ref": "#/definitions/MemoryConfig",
          "description": "Optional memory configuration for persisting instructions and skills. When present, the materializer writes these to backend-specific paths in the workspace directory during executor initialization."
        },
        "server": {
          "$ref": "#/definitions/ServerConfig",
          "description": "Network / server settings"
        },
        "session": {
          "$ref": "#/definitions/SessionConfig",
          "description": "Session management"
        },
        "subAgents": {
          "$ref": "#/definitions/SubAgentsConfig",
          "description": "Optional sub-agents to expose as MCP tools via the `a2a-mcp-skillmap` bridge. When present, the parent agent spawns skillmap as a stdio MCP server and registers it under the reserved `a2a-subagents` key in the resolved  {@link  mcp }  map. Sub-agents declared here become callable as ordinary MCP tools by the Copilot SDK runtime.\n\nWhen this field is absent or `agents` is empty, the parent skips every sub-agent code path with no side effects."
        },
        "timeouts": {
          "$ref": "#/definitions/TimeoutConfig",
          "description": "Timeout settings"
        }
      },
      "required": [
        "agentCard"
      ],
      "type": "object"
    },
    "AzureProviderOptions": {
      "additionalProperties": false,
      "description": "Azure-specific provider options. Only relevant when `type` is \"azure\".",
      "properties": {
        "apiVersion": {
          "description": "Azure OpenAI API version. Default: \"2024-10-21\"",
          "type": "string"
        }
      },
      "type": "object"
    },
    "CopilotConfig": {
      "additionalProperties": false,
      "description": "How the wrapper connects to and interacts with GitHub Copilot SDK.",
      "properties": {
        "cliUrl": {
          "description": "External Copilot CLI server URL (e.g. \"localhost:4321\"). If set, the SDK connects to this pre-running CLI server instead of managing its own CLI process.",
          "type": "string"
        },
        "contextFile": {
          "description": "Filename for the pre-built domain context file in the workspace directory. Default: \"context.md\"",
          "type": "string"
        },
        "contextPrompt": {
          "description": "Default prompt sent to build the domain context file. The LLM will write its findings to the contextFile.",
          "type": "string"
        },
        "githubToken": {
          "description": "GitHub Personal Access Token for authentication. Required in Docker containers where `gh` CLI is not available. Maps to the SDK's `githubToken` option.",
          "type": "string"
        },
        "model": {
          "description": "Default model for sessions (e.g. \"gpt-4.1\", \"claude-sonnet-4.5\")",
          "type": "string"
        },
        "provider": {
          "$ref": "#/definitions/ProviderConfig",
          "description": "Custom LLM provider configuration (BYOK — Bring Your Own Key).\n\nWhen set, bypasses GitHub Copilot and connects directly to the specified provider. Supports Ollama (local), OpenAI, Anthropic, Azure OpenAI, Azure AI Foundry, vLLM, LiteLLM, and any OpenAI-compatible endpoint.\n\nOmit this field entirely to use the default GitHub Copilot API.\n\nNote: when provider is set, the `model` field is REQUIRED — the SDK cannot auto-detect models from custom providers."
        },
        "streaming": {
          "description": "Enable streaming by default on sessions (default: true)",
          "type": "boolean"
        },
        "systemPrompt": {
          "description": "System prompt prepended to the first message of every session. Use this to give the LLM its persona, role, and behavioral rules.",
          "type": "string"
        },
        "systemPromptMode": {
          "description": "How the system prompt is applied to the SDK-managed system message.\n\n- \"append\" (default): your prompt is appended after the SDK's built-in   system message. The SDK's coding-assistant persona remains active.   Safe choice when you want to add constraints without replacing the base.\n\n- \"replace\": your prompt completely replaces the SDK's system message.   A production-ready preamble is automatically prepended to instruct the   model to act as a deployed agent (no tool disclosure, no internal detail   leakage). Use this when you need a clean, custom persona.",
          "enum": [
            "append",
            "replace"
          ],
          "type": "string"
        },
        "workspaceDirectory": {
          "description": "Working directory for context file operations",
          "type": "string"
        }
      },
      "type": "object"
    },
    "CustomAgentConfig": {
      "additionalProperties": false,
      "description": "A custom agent definition passed to the Copilot SDK session.",
      "properties": {
        "description": {
          "type": "string"
        },
        "displayName": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "prompt": {
          "type": "string"
        }
      },
      "required": [
        "name"
      ],
      "type": "object"
    },
    "EventsConfig": {
      "additionalProperties": false,
      "description": "Event transport configuration for sideband observability events.\n\nControls how trace events (MCP tool calls, agent reasoning, lifecycle) are delivered. Only the two built-in transports are configurable via JSON config — for custom transports (Kafka, Redis, DB, etc.), use the programmatic API and pass a transport function to `createA2AServer()`.",
      "properties": {
        "enabled": {
          "default": true,
          "description": "Enable event emission.",
          "type": "boolean"
        },
        "httpHeaders": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Custom HTTP headers sent with every event POST. Useful for authentication tokens: ```json { \"Authorization\": \"Bearer ${CORTEX_TOKEN}\" } ```",
          "type": "object"
        },
        "httpTimeout": {
          "default": "10_000",
          "description": "HTTP request timeout in milliseconds for the `\"http\"` transport.",
          "type": "number"
        },
        "httpUrl": {
          "description": "HTTP endpoint URL for the `\"http\"` transport. Required when `transport` is `\"http\"`.",
          "type": "string"
        },
        "transport": {
          "default": "a2a",
          "description": "Built-in transport type.\n\n- `\"a2a\"` — publish as sideband trace artifacts on the A2A   ExecutionEventBus (default, zero dependencies).\n- `\"http\"` — POST events as JSON to  {@link  httpUrl } .\n\nFor custom transports, leave this unset and provide a transport function via the programmatic `createA2AServer()` API.",
          "enum": [
            "a2a",
            "http"
          ],
          "type": "string"
        }
      },
      "type": "object"
    },
    "FeatureFlags": {
      "additionalProperties": false,
      "description": "Feature toggles for runtime behavior.",
      "properties": {
        "streamArtifactChunks": {
          "description": "Stream artifact chunks individually (A2A spec-correct) vs buffer and send single artifact (inspector-compatible). Default: false (buffered).",
          "type": "boolean"
        },
        "trackUsage": {
          "type": "boolean"
        }
      },
      "type": "object"
    },
    "LoggingConfig": {
      "additionalProperties": false,
      "description": "Logging settings.",
      "properties": {
        "level": {
          "description": "Log level: \"debug\" | \"info\" | \"warn\" | \"error\" (default: \"info\")",
          "type": "string"
        }
      },
      "type": "object"
    },
    "McpHttpServerConfig": {
      "additionalProperties": false,
      "description": "Configuration for an MCP server connected via HTTP (streamable).",
      "properties": {
        "enabled": {
          "description": "Enable on startup (default: true)",
          "type": "boolean"
        },
        "headers": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Optional HTTP headers sent with every request to this server. Use for auth tokens, API keys, etc. Values support `${ENV_VAR}` (or `$ENV_VAR`) substitution so secrets stay out of config.json — e.g. `{ \"Authorization\": \"Bearer ${LINEAR_API_KEY}\" }`.",
          "type": "object"
        },
        "type": {
          "const": "http",
          "type": "string"
        },
        "url": {
          "description": "URL of the remote MCP server (e.g. http://127.0.0.1:8002/mcp)",
          "type": "string"
        }
      },
      "required": [
        "type",
        "url"
      ],
      "type": "object"
    },
    "McpServerConfig": {
      "anyOf": [
        {
          "$ref": "#/definitions/McpHttpServerConfig"
        },
        {
          "$ref": "#/definitions/McpSseServerConfig"
        },
        {
          "$ref": "#/definitions/McpStdioServerConfig"
        }
      ],
      "description": "Union of MCP server configs."
    },
    "McpSseServerConfig": {
      "additionalProperties": false,
      "description": "Configuration for an MCP server connected via SSE.",
      "properties": {
        "enabled": {
          "description": "Enable on startup (default: true)",
          "type": "boolean"
        },
        "headers": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Optional HTTP headers sent with every request to this server. Use for auth tokens, API keys, etc. Values support `${ENV_VAR}` (or `$ENV_VAR`) substitution so secrets stay out of config.json — e.g. `{ \"Authorization\": \"Bearer ${NOTION_TOKEN}\" }`.",
          "type": "object"
        },
        "type": {
          "const": "sse",
          "type": "string"
        },
        "url": {
          "description": "URL of the SSE MCP server endpoint (e.g. http://127.0.0.1:8001/sse)",
          "type": "string"
        }
      },
      "required": [
        "type",
        "url"
      ],
      "type": "object"
    },
    "McpStdioServerConfig": {
      "additionalProperties": false,
      "description": "Configuration for a stdio-based MCP server.",
      "properties": {
        "args": {
          "description": "Arguments to pass to the command. Values support `${ENV_VAR}` (or `$ENV_VAR`) substitution.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "command": {
          "description": "Command to launch the MCP server",
          "type": "string"
        },
        "enabled": {
          "description": "Enable on startup (default: true)",
          "type": "boolean"
        },
        "env": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Environment variables for the spawned process. Values support `${ENV_VAR}` (or `$ENV_VAR`) substitution so secrets stay out of config.json — e.g. `{ \"API_KEY\": \"${MY_API_KEY}\" }`.",
          "type": "object"
        },
        "type": {
          "const": "stdio",
          "type": "string"
        }
      },
      "required": [
        "type",
        "command"
      ],
      "type": "object"
    },
    "MemoryConfig": {
      "additionalProperties": false,
      "description": "Optional memory configuration section in agent config.json.\n\nDeclares instructions and skills to materialize into the agent's workspace at startup. Both fields are optional — operators can declare instructions only, skills only, or both.\n\nPaths are resolved relative to the directory containing config.json (Config_Directory) unless they are absolute.",
      "properties": {
        "instructions": {
          "description": "Path to a markdown instructions file. Resolved relative to Config_Directory when relative, used as-is when absolute.",
          "type": "string"
        },
        "skills": {
          "description": "Paths to skill directories, each containing a SKILL.md file. Resolved relative to Config_Directory when relative, used as-is when absolute.",
          "items": {
            "type": "string"
          },
          "type": "array"
        }
      },
      "type": "object"
    },
    "ProviderConfig": {
      "additionalProperties": false,
      "description": "Custom LLM provider configuration (BYOK — Bring Your Own Key).\n\nWhen set, sessions use this provider instead of GitHub Copilot. Omit entirely to use the default GitHub Copilot API (no BYOK).\n\nSupported providers and their recommended settings:\n\n| Provider          | type        | baseUrl                                | wireApi        | |-------------------|-------------|----------------------------------------|----------------| | GitHub Copilot    | (omit)      | (omit)                                 | (omit)         | | Ollama (local)    | \"openai\"    | http://localhost:11434/v1              | \"completions\"  | | OpenAI            | \"openai\"    | https://api.openai.com/v1              | \"responses\"    | | Anthropic         | \"anthropic\" | https://api.anthropic.com              | (N/A)          | | Azure OpenAI      | \"azure\"     | https://<resource>.openai.azure.com    | \"completions\"  | | Azure AI Foundry  | \"openai\"    | https://<resource>.openai.azure.com/openai/v1/ | \"responses\" | | vLLM / LiteLLM   | \"openai\"    | http://<host>:<port>/v1                | \"completions\"  |",
      "properties": {
        "apiKey": {
          "description": "API key for authentication. Optional for local providers (e.g. Ollama).\n\nCan also be set via environment variable COPILOT_PROVIDER_API_KEY.",
          "type": "string"
        },
        "azure": {
          "$ref": "#/definitions/AzureProviderOptions",
          "description": "Azure-specific options. Only relevant when type is \"azure\"."
        },
        "baseUrl": {
          "description": "Required. API endpoint base URL.\n\n- OpenAI / compatible: include the full path, e.g. https://api.openai.com/v1\n- Ollama local: http://localhost:11434/v1\n- Azure (native): just the host, e.g. https://my-resource.openai.azure.com   (do NOT append /openai/v1 — the SDK constructs the path)\n- Anthropic: https://api.anthropic.com",
          "type": "string"
        },
        "bearerToken": {
          "description": "Bearer token for authentication. Sets the Authorization header directly. Takes precedence over apiKey when both are set. Use for services that require bearer token auth instead of an API key.",
          "type": "string"
        },
        "type": {
          "description": "Provider type. Determines the API format and auth mechanism.\n\n- \"openai\"    — OpenAI Chat Completions API and any compatible endpoint                 (Ollama, vLLM, LiteLLM, Azure AI Foundry, etc.)\n- \"azure\"     — Native Azure OpenAI Service (*.openai.azure.com)\n- \"anthropic\" — Anthropic Messages API (Claude models)\n\nDefault: \"openai\"",
          "enum": [
            "openai",
            "azure",
            "anthropic"
          ],
          "type": "string"
        },
        "wireApi": {
          "description": "Wire API format used to communicate with the model endpoint. Only applies to \"openai\" and \"azure\" provider types. Anthropic always uses the Messages API regardless of this setting.\n\n- \"completions\" (default) — Chat Completions API (/chat/completions).   Broadest model compatibility. Recommended for Ollama, vLLM, local models.\n- \"responses\" — Responses API. Provides multi-turn state management,   tool namespacing, and reasoning support.   Recommended for OpenAI GPT-4+ and Azure AI Foundry (GPT-5 series).",
          "enum": [
            "completions",
            "responses"
          ],
          "type": "string"
        }
      },
      "required": [
        "baseUrl"
      ],
      "type": "object"
    },
    "ServerConfig": {
      "additionalProperties": false,
      "description": "Network and server settings.",
      "properties": {
        "advertiseHost": {
          "description": "Hostname advertised in agent card URLs (default: \"localhost\"). Set to machine IP or \"host.containers.internal\" for Docker.",
          "type": "string"
        },
        "advertiseProtocol": {
          "description": "Protocol used in advertised URLs (default: \"http\"). Set to \"https\" when the agent is deployed behind TLS or a TLS-terminating reverse proxy. The A2A spec requires HTTPS for production deployments.",
          "enum": [
            "http",
            "https"
          ],
          "type": "string"
        },
        "hostname": {
          "description": "Bind address (default: \"0.0.0.0\")",
          "type": "string"
        },
        "port": {
          "description": "A2A server port (default: 3000)",
          "type": "number"
        }
      },
      "type": "object"
    },
    "SessionConfig": {
      "additionalProperties": false,
      "description": "Session lifecycle management.",
      "properties": {
        "cleanupInterval": {
          "description": "Session cleanup interval in ms (default: 300_000 = 5 min)",
          "type": "number"
        },
        "reuseByContext": {
          "description": "Reuse sessions by A2A contextId (default: true)",
          "type": "boolean"
        },
        "titlePrefix": {
          "description": "Session title prefix (default: \"A2A Session\")",
          "type": "string"
        },
        "ttl": {
          "description": "Session TTL in ms (default: 3_600_000 = 1 hour)",
          "type": "number"
        }
      },
      "type": "object"
    },
    "SkillConfig": {
      "additionalProperties": false,
      "description": "A single skill exposed on the agent card.\n\nSkills describe discrete capabilities the agent advertises to orchestrators and callers via the A2A Agent Card. Each skill has a unique identifier, human-readable metadata, and optional usage examples.",
      "properties": {
        "description": {
          "description": "Detailed description of what this skill does. Helps orchestrators decide whether to route a task to this agent.",
          "type": "string"
        },
        "examples": {
          "description": "Optional example prompts demonstrating how to invoke this skill. Included in the agent card only when non-empty.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "id": {
          "description": "Unique identifier for this skill. Used as the stable key when referencing the skill programmatically.",
          "type": "string"
        },
        "name": {
          "description": "Human-readable display name for the skill. Shown in agent card UIs and orchestrator dashboards.",
          "type": "string"
        },
        "tags": {
          "description": "Optional tags for categorization and discovery. Orchestrators may use tags to filter or group agents by capability.",
          "items": {
            "type": "string"
          },
          "type": "array"
        }
      },
      "required": [
        "id",
        "name",
        "description"
      ],
      "type": "object"
    },
    "SubAgentAuthConfig": {
      "anyOf": [
        {
          "additionalProperties": false,
          "properties": {
            "mode": {
              "const": "none",
              "type": "string"
            }
          },
          "required": [
            "mode"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "properties": {
            "mode": {
              "const": "bearer",
              "type": "string"
            },
            "token": {
              "type": "string"
            }
          },
          "required": [
            "mode",
            "token"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "properties": {
            "headerName": {
              "type": "string"
            },
            "mode": {
              "const": "api_key",
              "type": "string"
            },
            "token": {
              "type": "string"
            }
          },
          "required": [
            "mode",
            "token"
          ],
          "type": "object"
        }
      ],
      "description": "Outbound credentials the bridge presents when calling a remote A2A sub-agent. Forwarded verbatim into the bridge config consumed by `a2a-mcp-skillmap`.\n\n`mode: \"none\"` is equivalent to omitting the `auth` field entirely and produces no auth block in the generated bridge config.\n\nFor `mode: \"api_key\"`, the optional `headerName` defaults to whatever `a2a-mcp-skillmap` uses (typically `X-API-Key`).\n\nTokens may reference environment variables via `${VAR_NAME}` syntax; the substitution happens during validation and missing variables cause the auth block to be omitted with a warning."
    },
    "SubAgentConfig": {
      "additionalProperties": false,
      "description": "One remote A2A agent the parent will expose as MCP tools via the `a2a-mcp-skillmap` bridge.",
      "properties": {
        "agentCardUrl": {
          "description": "URL of the sub-agent's A2A agent card. Required.\n\nTypically `https://<host>/.well-known/agent-card.json`, but any URL the bridge can probe is valid. Must use the `http:` or `https:` protocol.",
          "type": "string"
        },
        "auth": {
          "$ref": "#/definitions/SubAgentAuthConfig",
          "description": "Outbound credentials the bridge presents when calling this sub-agent. Forwarded verbatim into the bridge config.\n\nOmitting this field is equivalent to `{ mode: \"none\" }`."
        },
        "endpointUrlOverride": {
          "description": "Optional override for the URL the bridge probes. Useful when the agent card declares an endpoint that differs from where the agent is actually reachable (NAT, port-forward, internal vs external).\n\nWhen set, this URL is passed to the bridge instead of  {@link  agentCardUrl } . The bridge still resolves a card from this URL — point it at a card URL or a base URL it can probe under `/.well-known/`. Must use the `http:` or `https:` protocol.",
          "type": "string"
        },
        "name": {
          "description": "Stable identifier for this sub-agent. Becomes the prefix on generated MCP tool names (`{name}__{skillId}`). Required.\n\nAllowed characters: ASCII letters, digits, hyphens, and underscores (must match `/^[A-Za-z0-9_-]+$/`). Must be unique across all entries in the `subAgents.agents` array.",
          "type": "string"
        }
      },
      "required": [
        "name",
        "agentCardUrl"
      ],
      "type": "object"
    },
    "SubAgentsConfig": {
      "additionalProperties": false,
      "description": "Top-level shape of the `subAgents` field merged into the agent's `BaseAgentConfig`.\n\nWhen this field is absent or `agents` is an empty array, the parent skips every sub-agent code path with no side effects (no bridge config written, no MCP entry injected).",
      "properties": {
        "agents": {
          "description": "The list of remote A2A agents to expose as MCP tools.",
          "items": {
            "$ref": "#/definitions/SubAgentConfig"
          },
          "type": "array"
        },
        "options": {
          "$ref": "#/definitions/SubAgentsOptions",
          "description": "Optional bridge-wide knobs."
        }
      },
      "required": [
        "agents"
      ],
      "type": "object"
    },
    "SubAgentsOptions": {
      "additionalProperties": false,
      "description": "Optional knobs that apply to the bridge process as a whole, not to any single sub-agent.",
      "properties": {
        "probeTimeoutMs": {
          "description": "Probe timeout in milliseconds for the startup reachability check the parent performs against each sub-agent. Defaults to `5000` when unset.",
          "type": "number"
        },
        "responseMode": {
          "description": "Skillmap response shaping mode passed through to the bridge config. Defaults to `\"artifact\"` when unset.",
          "enum": [
            "structured",
            "compact",
            "artifact",
            "raw"
          ],
          "type": "string"
        },
        "syncBudgetMs": {
          "description": "Sync budget in milliseconds passed to `a2a-mcp-skillmap` via the bridge config. Controls how long the bridge waits for an A2A agent to respond before switching to async task-handle mode.\n\nWhen the budget expires the bridge immediately returns a `taskId` to the MCP client; the A2A dispatch continues in the background. The LLM can then poll via the built-in `task_result` / `task_status` tools which actively re-query the remote agent before responding.\n\n- Set lower (e.g. `10000`) for interactive use where you want fast   task-handle responses.\n- Set to `0` to wait indefinitely (no async fallback).\n- Defaults to `30000` (30 s) when unset — skillmap's own default.",
          "type": "number"
        }
      },
      "type": "object"
    },
    "TimeoutConfig": {
      "additionalProperties": false,
      "description": "Timeout settings.",
      "properties": {
        "prompt": {
          "description": "Timeout for a single prompt in ms (default: 600_000 = 10 min)",
          "type": "number"
        }
      },
      "type": "object"
    }
  }
}