"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"
}
]
},
"research_subagent": {
"description": "Whether the deep research agent is available.\n\nWhen set to `true`, the Sage agent is added to the agent list and\nthe `:sage` app command is enabled. Defaults to `false`.",
"type": "boolean",
"default": false
},
"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"
}
]
},
"subagents": {
"description": "Enables subagent support via the task tool; when true the forge agent\ngains access to the `task` tool for delegating work to specialised\nsub-agents, and the `sage` research-only agent tool is removed.\nWhen false the `task` tool is disabled and `sage` is available instead.",
"type": "boolean",
"default": false
},
"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"
}
]
},
"use_forge_committer": {
"description": "Whether `forge commit` should override `GIT_COMMITTER_NAME` and\n`GIT_COMMITTER_EMAIL` with the Forge identity. Defaults to `true` via\nthe embedded `.forge.toml` defaults.",
"type": "boolean",
"default": false
},
"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. This acts as an\nabsolute cap and is combined with\n`token_threshold_percentage` by taking the lower value.",
"type": [
"integer",
"null"
],
"format": "uint",
"minimum": 0
},
"token_threshold_percentage": {
"description": "Maximum percentage of the model context window used to derive the token\nthreshold before triggering compaction. This is combined with\n`token_threshold` by taking the lower value.",
"anyOf": [
{
"$ref": "#/$defs/double"
},
{
"type": "null"
}
]
},
"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.",
"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: daily, weekly, always, or never",
"anyOf": [
{
"$ref": "#/$defs/UpdateFrequency"
},
{
"type": "null"
}
]
}
}
},
"UpdateFrequency": {
"description": "Frequency at which forge checks for updates",