Download crates/forge_config/src/config.rs from SaylorTwift/forgecode: direct link, hf CLI and curl.
- Browser
- Download file 20.1 kB
-
https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_config/src/config.rs
- Command line
-
hf download hf://SaylorTwift/forgecode/crates/forge_config/src/config.rs
-
curl -L -o config.rs https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_config/src/config.rs
20.1 kB
| use std::collections::HashMap; | |
| use std::path::PathBuf; | |
| use derive_setters::Setters; | |
| use fake::Dummy; | |
| use schemars::JsonSchema; | |
| use serde::{Deserialize, Serialize}; | |
| use crate::reader::ConfigReader; | |
| use crate::writer::ConfigWriter; | |
| use crate::{ | |
| AutoDumpFormat, Compact, Decimal, HttpConfig, ModelConfig, ReasoningConfig, RetryConfig, Update, | |
| }; | |
| /// Wire protocol a provider uses for chat completions. | |
| pub enum ProviderResponseType { | |
| OpenAI, | |
| OpenAIResponses, | |
| Anthropic, | |
| Bedrock, | |
| Google, | |
| OpenCode, | |
| } | |
| /// Category of a provider. | |
| pub enum ProviderTypeEntry { | |
| /// LLM provider for chat completions. | |
| Llm, | |
| /// Context engine provider for code indexing and search. | |
| ContextEngine, | |
| } | |
| /// Authentication method supported by a provider. | |
| /// | |
| /// Only the simple (non-OAuth) methods are available here; providers that | |
| /// require OAuth device or authorization-code flows must be configured via the | |
| /// file-based `provider.json` override instead. | |
| pub enum ProviderAuthMethod { | |
| ApiKey, | |
| GoogleAdc, | |
| } | |
| /// A URL parameter variable for a provider, used to substitute template | |
| /// variables in URL strings. | |
| pub struct ProviderUrlParam { | |
| /// The environment variable name used as the template variable key. | |
| pub name: String, | |
| /// Optional preset values for this parameter shown as suggestions in the | |
| /// UI. | |
| pub options: Vec<String>, | |
| /// Whether this parameter is optional. When `true`, the parameter may be | |
| /// left blank without causing an error. | |
| pub optional: bool, | |
| } | |
| /// Source of models for a provider: either a URL to fetch them from or a | |
| /// static list defined inline. | |
| pub enum ModelListConfig { | |
| /// URL template used to fetch the model list dynamically. | |
| Url(String), | |
| /// A static list of models defined directly in the configuration. | |
| Hardcoded(Vec<forge_domain::Model>), | |
| } | |
| /// A single provider entry defined inline in `forge.toml`. | |
| /// | |
| /// Inline providers are merged with the built-in provider list; entries with | |
| /// the same `id` override the corresponding built-in entry field-by-field, | |
| /// while entries with a new `id` are appended to the list. | |
| pub struct ProviderEntry { | |
| /// Unique provider identifier used in model paths (e.g. `"my_provider"`). | |
| pub id: String, | |
| /// Environment variable holding the API key for this provider. | |
| pub api_key_var: Option<String>, | |
| /// URL template for chat completions; may contain `{{VAR}}` placeholders | |
| /// that are substituted from the credential's url params. | |
| pub url: String, | |
| /// Model source: either a URL template for dynamic discovery or a static | |
| /// list of models defined inline. | |
| pub models: Option<ModelListConfig>, | |
| /// Wire protocol used by this provider. | |
| pub response_type: Option<ProviderResponseType>, | |
| /// Environment variables whose values are substituted into `{{VAR}}` | |
| /// placeholders in the `url` and `models` templates. | |
| pub url_param_vars: Vec<ProviderUrlParam>, | |
| /// Additional HTTP headers sent with every request to this provider. | |
| pub custom_headers: Option<HashMap<String, String>>, | |
| /// Provider category; defaults to `llm` when omitted. | |
| pub provider_type: Option<ProviderTypeEntry>, | |
| /// Authentication methods supported by this provider; defaults to | |
| /// `["api_key"]` when omitted. | |
| pub auth_methods: Vec<ProviderAuthMethod>, | |
| } | |
| /// Top-level Forge configuration merged from all sources (defaults, file, | |
| /// environment). | |
| pub struct ForgeConfig { | |
| /// Retry settings applied at the system level to all IO operations. | |
| pub retry: Option<RetryConfig>, | |
| /// Maximum number of lines returned by a single file search operation. | |
| pub max_search_lines: usize, | |
| /// Maximum number of bytes returned by a single file search operation. | |
| pub max_search_result_bytes: usize, | |
| /// Maximum number of characters returned from a URL fetch. | |
| pub max_fetch_chars: usize, | |
| /// Maximum number of lines captured from the leading portion of shell | |
| /// command output. | |
| pub max_stdout_prefix_lines: usize, | |
| /// Maximum number of lines captured from the trailing portion of shell | |
| /// command output. | |
| pub max_stdout_suffix_lines: usize, | |
| /// Maximum number of characters per line in shell command output. | |
| pub max_stdout_line_chars: usize, | |
| /// Maximum number of characters per line when reading a file. | |
| pub max_line_chars: usize, | |
| /// Maximum number of lines read from a file in a single operation. | |
| pub max_read_lines: u64, | |
| /// Maximum number of files read in a single batch operation. | |
| pub max_file_read_batch_size: usize, | |
| /// HTTP client settings including proxy, TLS, and timeout configuration. | |
| pub http: Option<HttpConfig>, | |
| /// Maximum file size in bytes permitted for read operations. | |
| pub max_file_size_bytes: u64, | |
| /// Maximum image file size in bytes permitted for read operations. | |
| pub max_image_size_bytes: u64, | |
| /// Maximum time in seconds a single tool call may run before being | |
| /// cancelled. | |
| pub tool_timeout_secs: u64, | |
| /// Whether to automatically open HTML dump files in the browser after | |
| /// creation. | |
| pub auto_open_dump: bool, | |
| /// Directory where debug request files are written; disabled when absent. | |
| pub debug_requests: Option<PathBuf>, | |
| /// Path to the conversation history file; defaults to the global history | |
| /// location when absent. | |
| pub custom_history_path: Option<PathBuf>, | |
| /// Maximum number of conversations shown in the conversation list. | |
| pub max_conversations: usize, | |
| /// Maximum number of candidate results returned from the initial semantic | |
| /// search vector query. | |
| pub max_sem_search_results: usize, | |
| /// Number of top results retained after re-ranking in semantic search. | |
| pub sem_search_top_k: usize, | |
| /// Base URL of the Forge services API used for semantic search and | |
| /// indexing. | |
| pub services_url: String, | |
| /// Maximum number of file extensions included in the agent system prompt. | |
| pub max_extensions: usize, | |
| /// Format used when automatically creating a session dump after task | |
| /// completion; disabled when absent. | |
| pub auto_dump: Option<AutoDumpFormat>, | |
| /// Maximum number of files read concurrently during batch operations. | |
| pub max_parallel_file_reads: usize, | |
| /// Time-to-live in seconds for the cached model API list. | |
| pub model_cache_ttl_secs: u64, | |
| /// Default model and provider configuration used when not overridden by | |
| /// individual agents. | |
| pub session: Option<ModelConfig>, | |
| /// Model and provider configuration used for commit message generation. | |
| pub commit: Option<ModelConfig>, | |
| /// Whether `forge commit` should override `GIT_COMMITTER_NAME` and | |
| /// `GIT_COMMITTER_EMAIL` with the Forge identity. Defaults to `true` via | |
| /// the embedded `.forge.toml` defaults. | |
| pub use_forge_committer: bool, | |
| /// Maximum number of recent commits included as context for commit message | |
| /// generation. | |
| pub max_commit_count: usize, | |
| /// Model and provider configuration used for shell command suggestion | |
| /// generation. | |
| pub suggest: Option<ModelConfig>, | |
| // --- Workflow fields --- | |
| /// Configuration for automatic Forge updates. | |
| pub updates: Option<Update>, | |
| /// Output randomness for all agents; lower values are deterministic, higher | |
| /// values are creative (0.0–2.0). | |
| pub temperature: Option<Decimal>, | |
| /// Nucleus sampling threshold for all agents; limits token selection to the | |
| /// top cumulative probability mass (0.0–1.0). | |
| pub top_p: Option<Decimal>, | |
| /// Top-k vocabulary cutoff for all agents; restricts sampling to the k | |
| /// highest-probability tokens (1–1000). | |
| pub top_k: Option<u32>, | |
| /// Maximum tokens the model may generate per response for all agents | |
| /// (1–100,000). | |
| pub max_tokens: Option<u32>, | |
| /// Maximum tool failures per turn before the orchestrator forces | |
| /// completion. | |
| pub max_tool_failure_per_turn: Option<usize>, | |
| /// Maximum number of requests that can be made in a single turn. | |
| pub max_requests_per_turn: Option<usize>, | |
| /// Context compaction settings applied to all agents; falls back to each | |
| /// agent's individual setting when absent. | |
| pub compact: Option<Compact>, | |
| /// Whether restricted mode is active; when enabled, tool execution requires | |
| /// explicit permission grants. | |
| pub restricted: bool, | |
| /// Whether tool use is supported in the current environment; when false, | |
| /// all tool calls are disabled. | |
| pub tool_supported: bool, | |
| /// Reasoning configuration applied to all agents; controls effort level, | |
| /// token budget, and visibility of the model's thinking process. | |
| pub reasoning: Option<ReasoningConfig>, | |
| /// Additional provider definitions merged with the built-in provider list. | |
| /// | |
| /// Entries with an `id` matching a built-in provider override its fields; | |
| /// entries with a new `id` are appended and become available for model | |
| /// selection. | |
| pub providers: Vec<ProviderEntry>, | |
| /// Currency symbol displayed in the shell rprompt next to the session cost | |
| /// (e.g. `"$"`, `"€"`, `"₹"`). Defaults to `"$"`. | |
| pub currency_symbol: String, | |
| /// Conversion rate applied to costs before display in the shell rprompt. | |
| /// The raw USD cost is multiplied by this value, allowing costs to be shown | |
| /// in a local currency. Defaults to `1.0` (no conversion). | |
| pub currency_conversion_rate: Decimal, | |
| /// Enables the pending todos hook that checks for incomplete todo items | |
| /// when a task ends and reminds the LLM about them. | |
| pub verify_todos: bool, | |
| /// Switches patch replacement fallback from the legacy fuzzy-search range | |
| /// lookup to the newer text-patch gRPC API. | |
| /// Defaults to `false` so patching continues to use the legacy fallback | |
| /// behavior unless explicitly enabled in `forge.toml`. | |
| pub use_text_patch_fallback: bool, | |
| /// Whether the deep research agent is available. | |
| /// | |
| /// When set to `true`, the Sage agent is added to the agent list and | |
| /// the `:sage` app command is enabled. Defaults to `false`. | |
| pub research_subagent: bool, | |
| /// Enables subagent support via the task tool; when true the forge agent | |
| /// gains access to the `task` tool for delegating work to specialised | |
| /// sub-agents, and the `sage` research-only agent tool is removed. | |
| /// When false the `task` tool is disabled and `sage` is available instead. | |
| pub subagents: bool, | |
| /// Enables automatic VS Code extension installation when Forge runs inside | |
| /// VS Code and the extension is not already installed. | |
| pub auto_install_vscode_extension: bool, | |
| /// When `true`, all system messages in the conversation are merged into a | |
| /// single leading system message before the request is sent. Enable this | |
| /// for providers that reject requests containing system messages after | |
| /// user or assistant turns (e.g. vLLM, NVIDIA NIM). | |
| pub merge_system_messages: bool, | |
| } | |
| impl ForgeConfig { | |
| /// Reads and merges configuration from all sources, returning the resolved | |
| /// [`ForgeConfig`]. | |
| /// | |
| /// # Errors | |
| /// | |
| /// Returns an error if the config path cannot be resolved, the file cannot | |
| /// be read, or deserialization fails. | |
| pub fn read() -> crate::Result<ForgeConfig> { | |
| ConfigReader::default() | |
| .read_legacy() | |
| .read_defaults() | |
| .read_global() | |
| .read_env() | |
| .build() | |
| } | |
| /// Writes the configuration to the user config file. | |
| /// | |
| /// # Errors | |
| /// | |
| /// Returns an error if the configuration cannot be serialized or written to | |
| /// disk. | |
| pub fn write(&self) -> crate::Result<()> { | |
| let path = ConfigReader::config_path(); | |
| ConfigWriter::new(self.clone()).write(&path) | |
| } | |
| } | |
| mod tests { | |
| use pretty_assertions::assert_eq; | |
| use super::*; | |
| use crate::reader::ConfigReader; | |
| fn test_f32_temperature_round_trip() { | |
| let fixture = ForgeConfig { temperature: Some(Decimal(0.1)), ..Default::default() }; | |
| let toml = toml_edit::ser::to_string_pretty(&fixture).unwrap(); | |
| assert!( | |
| toml.contains("temperature = 0.1\n"), | |
| "expected `temperature = 0.1` in TOML output, got:\n{toml}" | |
| ); | |
| } | |
| fn test_f32_top_p_round_trip() { | |
| let fixture = ForgeConfig { top_p: Some(Decimal(0.9)), ..Default::default() }; | |
| let toml = toml_edit::ser::to_string_pretty(&fixture).unwrap(); | |
| assert!( | |
| toml.contains("top_p = 0.9\n"), | |
| "expected `top_p = 0.9` in TOML output, got:\n{toml}" | |
| ); | |
| } | |
| fn test_f32_temperature_deserialize_round_trip() { | |
| let fixture = ForgeConfig { temperature: Some(Decimal(0.1)), ..Default::default() }; | |
| let toml = toml_edit::ser::to_string_pretty(&fixture).unwrap(); | |
| let actual = ConfigReader::default().read_toml(&toml).build().unwrap(); | |
| assert_eq!(actual.temperature, fixture.temperature); | |
| } | |
| fn test_provider_static_model_list_deserialization() { | |
| let fixture = r#" | |
| [[providers]] | |
| id = "ollama" | |
| url = "http://127.0.0.1:8000/v1/chat/completions" | |
| response_type = "OpenAI" | |
| auth_methods = ["api_key"] | |
| [[providers.models]] | |
| id = "Qwen3.6-35B-A3b-q3-mlx" | |
| name = "Qwen3.5-35B" | |
| description = "Qwen local reasoning model with advanced problem-solving capabilities" | |
| context_length = 262144 | |
| tools_supported = true | |
| supports_parallel_tool_calls = true | |
| supports_reasoning = true | |
| input_modalities = ["text"] | |
| [[providers.models]] | |
| id = "llama3.2-3b" | |
| name = "Llama 3.2 3B" | |
| description = "Meta Llama 3.2 3B lightweight local model" | |
| context_length = 131072 | |
| tools_supported = true | |
| supports_parallel_tool_calls = false | |
| supports_reasoning = false | |
| input_modalities = ["text"] | |
| "#; | |
| let actual = ConfigReader::default().read_toml(fixture).build().unwrap(); | |
| let expected = vec![ProviderEntry { | |
| id: "ollama".to_string(), | |
| url: "http://127.0.0.1:8000/v1/chat/completions".to_string(), | |
| response_type: Some(ProviderResponseType::OpenAI), | |
| auth_methods: vec![ProviderAuthMethod::ApiKey], | |
| models: Some(ModelListConfig::Hardcoded(vec![ | |
| forge_domain::Model::new("Qwen3.6-35B-A3b-q3-mlx") | |
| .name("Qwen3.5-35B".to_string()) | |
| .description( | |
| "Qwen local reasoning model with advanced problem-solving capabilities" | |
| .to_string(), | |
| ) | |
| .context_length(262144) | |
| .tools_supported(true) | |
| .supports_parallel_tool_calls(true) | |
| .supports_reasoning(true) | |
| .input_modalities(vec![forge_domain::InputModality::Text]), | |
| forge_domain::Model::new("llama3.2-3b") | |
| .name("Llama 3.2 3B".to_string()) | |
| .description("Meta Llama 3.2 3B lightweight local model".to_string()) | |
| .context_length(131072) | |
| .tools_supported(true) | |
| .supports_parallel_tool_calls(false) | |
| .supports_reasoning(false) | |
| .input_modalities(vec![forge_domain::InputModality::Text]), | |
| ])), | |
| ..Default::default() | |
| }]; | |
| assert_eq!(actual.providers, expected); | |
| } | |
| fn test_provider_url_model_list_deserialization() { | |
| let fixture = r#" | |
| [[providers]] | |
| id = "my_provider" | |
| url = "http://example.com/v1/chat/completions" | |
| models = "http://example.com/v1/models" | |
| "#; | |
| let actual = ConfigReader::default().read_toml(fixture).build().unwrap(); | |
| let expected = vec![ProviderEntry { | |
| id: "my_provider".to_string(), | |
| url: "http://example.com/v1/chat/completions".to_string(), | |
| models: Some(ModelListConfig::Url( | |
| "http://example.com/v1/models".to_string(), | |
| )), | |
| ..Default::default() | |
| }]; | |
| assert_eq!(actual.providers, expected); | |
| } | |
| fn test_auto_install_vscode_extension_defaults_to_true() { | |
| let actual = ConfigReader::default().read_defaults().build().unwrap(); | |
| assert_eq!(actual.auto_install_vscode_extension, true); | |
| } | |
| fn test_auto_install_vscode_extension_can_be_disabled() { | |
| let toml = "auto_install_vscode_extension = false\n"; | |
| let actual = ConfigReader::default() | |
| .read_defaults() | |
| .read_toml(toml) | |
| .build() | |
| .unwrap(); | |
| assert_eq!(actual.auto_install_vscode_extension, false); | |
| } | |
| } | |