diff --git a/crates/forge_config/.forge.toml b/crates/forge_config/.forge.toml index f807226064..930fae6bb0 100644 --- a/crates/forge_config/.forge.toml +++ b/crates/forge_config/.forge.toml @@ -64,3 +64,6 @@ frequency = "daily" [reasoning] enabled = true effort = "high" + +currency_symbol = "$" +currency_conversion_rate = 1.0 diff --git a/crates/forge_config/src/config.rs b/crates/forge_config/src/config.rs index 0f189de0e3..f705d308c3 100644 --- a/crates/forge_config/src/config.rs +++ b/crates/forge_config/src/config.rs @@ -265,6 +265,17 @@ pub struct ForgeConfig { /// selection. #[serde(default, skip_serializing_if = "Vec::is_empty")] pub providers: Vec, + + /// Currency symbol displayed in the shell rprompt next to the session cost + /// (e.g. `"$"`, `"€"`, `"₹"`). Defaults to `"$"`. + #[serde(default)] + 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). + #[serde(default)] + pub currency_conversion_rate: Decimal, } impl ForgeConfig { diff --git a/crates/forge_main/src/ui.rs b/crates/forge_main/src/ui.rs index 66288447e4..618b8f2fba 100644 --- a/crates/forge_main/src/ui.rs +++ b/crates/forge_main/src/ui.rs @@ -3761,17 +3761,7 @@ impl A + Send + Sync> UI .map(|val| val == "1") .unwrap_or(true); // Default to true - // Get currency symbol from environment variable, default to "$" - let currency_symbol = - std::env::var("FORGE_CURRENCY_SYMBOL").unwrap_or_else(|_| "$".to_string()); - - // Get conversion ratio from environment variable, default to 1.0 - let conversion_ratio = std::env::var("FORGE_CURRENCY_CONVERSION_RATE") - .ok() - .and_then(|val| val.parse::().ok()) - .unwrap_or(1.0); - - let rprompt = ZshRPrompt::default() + let rprompt = ZshRPrompt::from_config(&self.config) .agent( std::env::var("_FORGE_ACTIVE_AGENT") .ok() @@ -3781,9 +3771,7 @@ impl A + Send + Sync> UI .model(model_id) .token_count(conversation.and_then(|conversation| conversation.token_count())) .cost(cost) - .use_nerd_font(use_nerd_font) - .currency_symbol(currency_symbol) - .conversion_ratio(conversion_ratio); + .use_nerd_font(use_nerd_font); Some(rprompt.to_string()) } diff --git a/crates/forge_main/src/zsh/rprompt.rs b/crates/forge_main/src/zsh/rprompt.rs index 6e01059302..58cbfd7813 100644 --- a/crates/forge_main/src/zsh/rprompt.rs +++ b/crates/forge_main/src/zsh/rprompt.rs @@ -7,6 +7,7 @@ use std::fmt::{self, Display}; use convert_case::{Case, Casing}; use derive_setters::Setters; +use forge_config::ForgeConfig; use forge_domain::{AgentId, ModelId, TokenCount}; use super::style::{ZshColor, ZshStyle}; @@ -34,6 +35,16 @@ pub struct ZshRPrompt { /// Defaults to 1.0. conversion_ratio: f64, } +impl ZshRPrompt { + /// Constructs a [`ZshRPrompt`] with currency settings populated from the + /// provided [`ForgeConfig`]. + pub fn from_config(config: &ForgeConfig) -> Self { + Self::default() + .currency_symbol(config.currency_symbol.clone()) + .conversion_ratio(config.currency_conversion_rate.value()) + } +} + impl Default for ZshRPrompt { fn default() -> Self { Self { diff --git a/forge.default.yaml b/forge.default.yaml deleted file mode 100644 index b311bbd4e8..0000000000 --- a/forge.default.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# yaml-language-server: $schema=./forge.schema.json -variables: - operating_agent: Forge - # Define model anchors with simpler, purpose-based names - advanced_model: &advanced_model anthropic/claude-sonnet-4 - -max_requests_per_turn: 100 -max_tool_failure_per_turn: 3 -top_p: 0.8 -top_k: 30 -max_tokens: 20480 -max_walker_depth: 1 -tool_supported: true - -# Global compact configuration applied to all agents -compact: - max_tokens: 2000 - token_threshold: 100000 - retention_window: 6 - message_threshold: 200 - eviction_window: 0.2 - on_turn_end: false - -updates: - frequency: "daily" - auto_update: false -model: *advanced_model diff --git a/forge.schema.json b/forge.schema.json index f925ff6a5f..7420e9f736 100644 --- a/forge.schema.json +++ b/forge.schema.json @@ -42,6 +42,16 @@ } ] }, + "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": [