{ "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "ForgeConfig", "description": "Top-level Forge configuration merged from all sources (defaults, file,\nenvironment).", "type": "object", "properties": { "auto_dump": { "description": "Format used when automatically creating a session dump after task\ncompletion; disabled when absent.", "anyOf": [ { "$ref": "#/$defs/AutoDumpFormat" }, { "type": "null" } ] }, "auto_open_dump": { "description": "Whether to automatically open HTML dump files in the browser after\ncreation.", "type": "boolean", "default": false }, "commit": { "description": "Model and provider configuration used for commit message generation.", "anyOf": [ { "$ref": "#/$defs/ModelConfig" }, { "type": "null" } ] }, "compact": { "description": "Context compaction settings applied to all agents; falls back to each\nagent's individual setting when absent.", "anyOf": [ { "$ref": "#/$defs/Compact" }, { "type": "null" } ] }, "currency_conversion_rate": { "description": "Conversion rate applied to costs before display in the shell rprompt.\nThe raw USD cost is multiplied by this value, allowing costs to be shown\nin a local currency. Defaults to `1.0` (no conversion).", "$ref": "#/$defs/double", "default": 0.0 }, "currency_symbol": { "description": "Currency symbol displayed in the shell rprompt next to the session cost\n(e.g. `\"$\"`, `\"€\"`, `\"₹\"`). Defaults to `\"$\"`.", "type": "string", "default": "" }, "custom_history_path": { "description": "Path to the conversation history file; defaults to the global history\nlocation when absent.", "type": [ "string", "null" ] }, "debug_requests": { "description": "Directory where debug request files are written; disabled when absent.", "type": [ "string", "null" ] }, "http": { "description": "HTTP client settings including proxy, TLS, and timeout configuration.", "anyOf": [ { "$ref": "#/$defs/HttpConfig" }, { "type": "null" } ] }, "max_commit_count": { "description": "Maximum number of recent commits included as context for commit message\ngeneration.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_conversations": { "description": "Maximum number of conversations shown in the conversation list.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_extensions": { "description": "Maximum number of file extensions included in the agent system prompt.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_fetch_chars": { "description": "Maximum number of characters returned from a URL fetch.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_file_read_batch_size": { "description": "Maximum number of files read in a single batch operation.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_file_size_bytes": { "description": "Maximum file size in bytes permitted for read operations.", "type": "integer", "format": "uint64", "default": 0, "minimum": 0 }, "max_image_size_bytes": { "description": "Maximum image file size in bytes permitted for read operations.", "type": "integer", "format": "uint64", "default": 0, "minimum": 0 }, "max_line_chars": { "description": "Maximum number of characters per line when reading a file.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_parallel_file_reads": { "description": "Maximum number of files read concurrently during batch operations.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_read_lines": { "description": "Maximum number of lines read from a file in a single operation.", "type": "integer", "format": "uint64", "default": 0, "minimum": 0 }, "max_requests_per_turn": { "description": "Maximum number of requests that can be made in a single turn.", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 }, "max_search_lines": { "description": "Maximum number of lines returned by a single file search operation.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_search_result_bytes": { "description": "Maximum number of bytes returned by a single file search operation.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_sem_search_results": { "description": "Maximum number of candidate results returned from the initial semantic\nsearch vector query.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_stdout_line_chars": { "description": "Maximum number of characters per line in shell command output.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_stdout_prefix_lines": { "description": "Maximum number of lines captured from the leading portion of shell\ncommand output.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_stdout_suffix_lines": { "description": "Maximum number of lines captured from the trailing portion of shell\ncommand output.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "max_tokens": { "description": "Maximum tokens the model may generate per response for all agents\n(1–100,000).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0 }, "max_tool_failure_per_turn": { "description": "Maximum tool failures per turn before the orchestrator forces\ncompletion.", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 }, "model_cache_ttl_secs": { "description": "Time-to-live in seconds for the cached model API list.", "type": "integer", "format": "uint64", "default": 0, "minimum": 0 }, "providers": { "description": "Additional provider definitions merged with the built-in provider list.\n\nEntries with an `id` matching a built-in provider override its fields;\nentries with a new `id` are appended and become available for model\nselection.", "type": "array", "items": { "$ref": "#/$defs/ProviderEntry" } }, "reasoning": { "description": "Reasoning configuration applied to all agents; controls effort level,\ntoken budget, and visibility of the model's thinking process.", "anyOf": [ { "$ref": "#/$defs/ReasoningConfig" }, { "type": "null" } ] }, "restricted": { "description": "Whether restricted mode is active; when enabled, tool execution requires\nexplicit permission grants.", "type": "boolean", "default": false }, "retry": { "description": "Retry settings applied at the system level to all IO operations.", "anyOf": [ { "$ref": "#/$defs/RetryConfig" }, { "type": "null" } ] }, "sem_search_top_k": { "description": "Number of top results retained after re-ranking in semantic search.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "services_url": { "description": "Base URL of the Forge services API used for semantic search and\nindexing.", "type": "string", "default": "" }, "session": { "description": "Default model and provider configuration used when not overridden by\nindividual agents.", "anyOf": [ { "$ref": "#/$defs/ModelConfig" }, { "type": "null" } ] }, "suggest": { "description": "Model and provider configuration used for shell command suggestion\ngeneration.", "anyOf": [ { "$ref": "#/$defs/ModelConfig" }, { "type": "null" } ] }, "temperature": { "description": "Output randomness for all agents; lower values are deterministic, higher\nvalues are creative (0.0–2.0).", "anyOf": [ { "$ref": "#/$defs/double" }, { "type": "null" } ] }, "tool_supported": { "description": "Whether tool use is supported in the current environment; when false,\nall tool calls are disabled.", "type": "boolean", "default": false }, "tool_timeout_secs": { "description": "Maximum time in seconds a single tool call may run before being\ncancelled.", "type": "integer", "format": "uint64", "default": 0, "minimum": 0 }, "top_k": { "description": "Top-k vocabulary cutoff for all agents; restricts sampling to the k\nhighest-probability tokens (1–1000).", "type": [ "integer", "null" ], "format": "uint32", "minimum": 0 }, "top_p": { "description": "Nucleus sampling threshold for all agents; limits token selection to the\ntop cumulative probability mass (0.0–1.0).", "anyOf": [ { "$ref": "#/$defs/double" }, { "type": "null" } ] }, "updates": { "description": "Configuration for automatic Forge updates.", "anyOf": [ { "$ref": "#/$defs/Update" }, { "type": "null" } ] }, "verify_todos": { "description": "Enables the pending todos hook that checks for incomplete todo items\nwhen a task ends and reminds the LLM about them.", "type": "boolean", "default": false } }, "$defs": { "AutoDumpFormat": { "description": "The output format used when auto-dumping a conversation on task completion.", "oneOf": [ { "description": "Dump as a JSON file", "type": "string", "const": "json" }, { "description": "Dump as an HTML file", "type": "string", "const": "html" } ] }, "Compact": { "description": "Configuration for automatic context compaction for all agents", "type": "object", "properties": { "eviction_window": { "description": "Maximum percentage of the context that can be summarized during\ncompaction. Valid values are between 0.0 and 1.0, where 0.0 means no\ncompaction and 1.0 allows summarizing all messages. Works alongside\nretention_window - the more conservative limit (fewer messages to\ncompact) takes precedence.", "$ref": "#/$defs/double", "default": 0.0 }, "max_tokens": { "description": "Maximum number of tokens to keep after compaction", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 }, "message_threshold": { "description": "Maximum number of messages before triggering compaction", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 }, "model": { "description": "Model ID to use for compaction, useful when compacting with a\ncheaper/faster model. If not specified, the root level model will be\nused.", "type": [ "string", "null" ] }, "on_turn_end": { "description": "Whether to trigger compaction when the last message is from a user", "type": [ "boolean", "null" ] }, "retention_window": { "description": "Number of most recent messages to preserve during compaction.\nThese messages won't be considered for summarization. Works alongside\neviction_window - the more conservative limit (fewer messages to\ncompact) takes precedence.", "type": "integer", "format": "uint", "default": 0, "minimum": 0 }, "token_threshold": { "description": "Maximum number of tokens before triggering compaction", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 }, "turn_threshold": { "description": "Maximum number of conversation turns before triggering compaction", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 } } }, "Effort": { "description": "Effort level for model reasoning.", "oneOf": [ { "description": "No reasoning; skips the thinking step entirely.", "type": "string", "const": "none" }, { "description": "Minimal reasoning; fastest and cheapest.", "type": "string", "const": "minimal" }, { "description": "Low reasoning effort.", "type": "string", "const": "low" }, { "description": "Medium reasoning effort; the default for most providers.", "type": "string", "const": "medium" }, { "description": "High reasoning effort.", "type": "string", "const": "high" }, { "description": "Extra-high reasoning effort (OpenAI / OpenRouter).", "type": "string", "const": "xhigh" }, { "description": "Maximum reasoning effort; only available on select Anthropic models.", "type": "string", "const": "max" } ] }, "HttpConfig": { "description": "HTTP client configuration.", "type": "object", "properties": { "accept_invalid_certs": { "description": "Accept invalid certificates", "type": "boolean" }, "adaptive_window": { "description": "Adaptive window sizing for improved flow control", "type": "boolean" }, "connect_timeout_secs": { "type": "integer", "format": "uint64", "minimum": 0 }, "hickory": { "type": "boolean" }, "keep_alive_interval_secs": { "description": "Keep-alive interval in seconds", "type": [ "integer", "null" ], "format": "uint64", "minimum": 0 }, "keep_alive_timeout_secs": { "description": "Keep-alive timeout in seconds", "type": "integer", "format": "uint64", "minimum": 0 }, "keep_alive_while_idle": { "description": "Keep-alive while connection is idle", "type": "boolean" }, "max_redirects": { "type": "integer", "format": "uint", "minimum": 0 }, "max_tls_version": { "description": "Maximum TLS protocol version to use", "anyOf": [ { "$ref": "#/$defs/TlsVersion" }, { "type": "null" } ] }, "min_tls_version": { "description": "Minimum TLS protocol version to use", "anyOf": [ { "$ref": "#/$defs/TlsVersion" }, { "type": "null" } ] }, "pool_idle_timeout_secs": { "type": "integer", "format": "uint64", "minimum": 0 }, "pool_max_idle_per_host": { "type": "integer", "format": "uint", "minimum": 0 }, "read_timeout_secs": { "type": "integer", "format": "uint64", "minimum": 0 }, "root_cert_paths": { "description": "Paths to root certificate files", "type": [ "array", "null" ], "items": { "type": "string" } }, "tls_backend": { "$ref": "#/$defs/TlsBackend" } }, "required": [ "connect_timeout_secs", "read_timeout_secs", "pool_idle_timeout_secs", "pool_max_idle_per_host", "max_redirects", "hickory", "tls_backend", "adaptive_window", "keep_alive_timeout_secs", "keep_alive_while_idle", "accept_invalid_certs" ] }, "ModelConfig": { "description": "Pairs a provider and model together for a specific operation.", "type": "object", "properties": { "model_id": { "description": "The model to use for this operation.", "type": "string" }, "provider_id": { "description": "The provider to use for this operation.", "type": "string" } }, "required": [ "provider_id", "model_id" ] }, "ProviderAuthMethod": { "description": "Authentication method supported by a provider.\n\nOnly the simple (non-OAuth) methods are available here; providers that\nrequire OAuth device or authorization-code flows must be configured via the\nfile-based `provider.json` override instead.", "type": "string", "enum": [ "api_key", "google_adc" ] }, "ProviderEntry": { "description": "A single provider entry defined inline in `forge.toml`.\n\nInline providers are merged with the built-in provider list; entries with\nthe same `id` override the corresponding built-in entry field-by-field,\nwhile entries with a new `id` are appended to the list.", "type": "object", "properties": { "api_key_var": { "description": "Environment variable holding the API key for this provider.", "type": [ "string", "null" ] }, "auth_methods": { "description": "Authentication methods supported by this provider; defaults to\n`[\"api_key\"]` when omitted.", "type": "array", "items": { "$ref": "#/$defs/ProviderAuthMethod" } }, "custom_headers": { "description": "Additional HTTP headers sent with every request to this provider.", "type": [ "object", "null" ], "additionalProperties": { "type": "string" } }, "id": { "description": "Unique provider identifier used in model paths (e.g. `\"my_provider\"`).", "type": "string" }, "models": { "description": "URL template for fetching the model list; may contain `{{VAR}}`\nplaceholders.", "type": [ "string", "null" ] }, "provider_type": { "description": "Provider category; defaults to `llm` when omitted.", "anyOf": [ { "$ref": "#/$defs/ProviderTypeEntry" }, { "type": "null" } ] }, "response_type": { "description": "Wire protocol used by this provider.", "anyOf": [ { "$ref": "#/$defs/ProviderResponseType" }, { "type": "null" } ] }, "url": { "description": "URL template for chat completions; may contain `{{VAR}}` placeholders\nthat are substituted from the credential's url params.", "type": "string" }, "url_param_vars": { "description": "Environment variables whose values are substituted into `{{VAR}}`\nplaceholders in the `url` and `models` templates.", "type": "array", "items": { "$ref": "#/$defs/ProviderUrlParam" } } }, "required": [ "id", "url" ] }, "ProviderResponseType": { "description": "Wire protocol a provider uses for chat completions.", "type": "string", "enum": [ "OpenAI", "OpenAIResponses", "Anthropic", "Bedrock", "Google", "OpenCode" ] }, "ProviderTypeEntry": { "description": "Category of a provider.", "oneOf": [ { "description": "LLM provider for chat completions.", "type": "string", "const": "llm" }, { "description": "Context engine provider for code indexing and search.", "type": "string", "const": "context_engine" } ] }, "ProviderUrlParam": { "description": "A URL parameter variable for a provider, used to substitute template\nvariables in URL strings.", "type": "object", "properties": { "name": { "description": "The environment variable name used as the template variable key.", "type": "string" }, "options": { "description": "Optional preset values for this parameter shown as suggestions in the\nUI.", "type": "array", "items": { "type": "string" } } }, "required": [ "name" ] }, "ReasoningConfig": { "description": "Controls the reasoning behaviour of a model, including effort level, token\nbudget, and visibility of the thinking process.", "type": "object", "properties": { "effort": { "description": "Controls the effort level of the model's reasoning.\nSupported by openrouter and forge provider.", "anyOf": [ { "$ref": "#/$defs/Effort" }, { "type": "null" } ] }, "enabled": { "description": "Enables reasoning at the \"medium\" effort level with no exclusions.\nSupported by openrouter, anthropic, and forge provider.", "type": [ "boolean", "null" ] }, "exclude": { "description": "When true, the model thinks deeply but the reasoning is hidden from the\ncaller. Supported by openrouter and forge provider.", "type": [ "boolean", "null" ] }, "max_tokens": { "description": "Controls how many tokens the model can spend thinking.\nShould be greater than 1024 but less than the overall max_tokens.\nSupported by openrouter, anthropic, and forge provider.", "type": [ "integer", "null" ], "format": "uint", "minimum": 0 } } }, "RetryConfig": { "description": "Configuration for retry mechanism.", "type": "object", "properties": { "backoff_factor": { "description": "Backoff multiplication factor for each retry attempt", "type": "integer", "format": "uint64", "minimum": 0 }, "initial_backoff_ms": { "description": "Initial backoff delay in milliseconds for retry operations", "type": "integer", "format": "uint64", "minimum": 0 }, "max_attempts": { "description": "Maximum number of retry attempts", "type": "integer", "format": "uint", "minimum": 0 }, "max_delay_secs": { "description": "Maximum delay between retries in seconds", "type": [ "integer", "null" ], "format": "uint64", "minimum": 0 }, "min_delay_ms": { "description": "Minimum delay in milliseconds between retry attempts", "type": "integer", "format": "uint64", "minimum": 0 }, "status_codes": { "description": "HTTP status codes that should trigger retries", "type": "array", "items": { "type": "integer", "format": "uint16", "maximum": 65535, "minimum": 0 } }, "suppress_errors": { "description": "Whether to suppress retry error logging and events", "type": "boolean" } }, "required": [ "initial_backoff_ms", "min_delay_ms", "backoff_factor", "max_attempts", "status_codes", "suppress_errors" ] }, "TlsBackend": { "description": "TLS backend option.", "type": "string", "enum": [ "default", "rustls" ] }, "TlsVersion": { "description": "TLS version enum for configuring TLS protocol versions.", "type": "string", "enum": [ "1.0", "1.1", "1.2", "1.3" ] }, "Update": { "description": "Configuration for automatic forge updates", "type": "object", "properties": { "auto_update": { "description": "Whether to automatically install updates without prompting", "type": [ "boolean", "null" ] }, "frequency": { "description": "How frequently forge checks for updates", "anyOf": [ { "$ref": "#/$defs/UpdateFrequency" }, { "type": "null" } ] } } }, "UpdateFrequency": { "description": "Frequency at which forge checks for updates", "type": "string", "enum": [ "daily", "weekly", "always" ] }, "double": { "type": "number", "format": "double" } } }