mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-26 15:40:18 +00:00
* refactor: simplify config resolution and consolidate main.rs init into AppBuilder - Add parse_bool_env() and parse_string_env() helpers to eliminate repetitive 5-line optional_env/parse/map_err/unwrap_or boilerplate across 12 config files - Add EmbeddingsConfig::create_provider() to centralize embeddings construction (fixes hardcoded 1536 dimensions and missing Ollama provider in app.rs) - Extract init_cli_tracing(), setup_wasm_channels(), start_tunnel(), run_memory_command(), run_worker(), run_claude_bridge() from main.rs - Replace ~600 lines of inline init in main.rs with AppBuilder::build_all() - Expose catalog_entries from AppComponents for gateway registry entries - Net reduction: ~738 lines across 15 files Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: propagate dev_loaded_tool_names from AppBuilder and add parse_option_env helper Address PR review feedback: - Capture dev_loaded_tool_names from WASM loading in init_extensions() and expose via AppComponents so bootstrap_hooks receives the actual dev tool names instead of an empty slice (fixes silent hook skip) - Add parse_option_env<T>() helper for Option<T> config fields, simplifying max_cost_per_day_cents and max_actions_per_hour in agent.rs Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: fetch real NEAR AI pricing and unify cost calculation path CostGuard was independently looking up pricing via costs::model_cost(), falling back to GPT-4o default rates when NEAR AI model names didn't match the static table — causing ~3x cost overestimates in logs. - Add pricing map to NearAiChatProvider that fetches real rates from /v1/model/list at startup (background, non-blocking) - Update cost_per_token() to check fetched pricing first, then static table, then default - Add cost_per_token parameter to CostGuard::record_llm_call() so the dispatcher passes provider-sourced rates directly Co-Authored-By: Claude Opus 4.6 <[email protected]> * chore: update default NEAR AI model to GLM-latest Replace fireworks llama4-maverick-instruct-basic with zai-org/GLM-latest as the default model in config and setup wizard. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: align wizard default model name with config Change "zai/GLM-latest" to "zai-org/GLM-latest" in wizard.rs to match the default in config/llm.rs. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
75 lines
3.1 KiB
Rust
75 lines
3.1 KiB
Rust
use std::time::Duration;
|
|
|
|
use crate::config::helpers::{parse_bool_env, parse_option_env, parse_optional_env};
|
|
use crate::error::ConfigError;
|
|
use crate::settings::Settings;
|
|
|
|
/// Agent behavior configuration.
|
|
#[derive(Debug, Clone)]
|
|
pub struct AgentConfig {
|
|
pub name: String,
|
|
pub max_parallel_jobs: usize,
|
|
pub job_timeout: Duration,
|
|
pub stuck_threshold: Duration,
|
|
pub repair_check_interval: Duration,
|
|
pub max_repair_attempts: u32,
|
|
/// Whether to use planning before tool execution.
|
|
pub use_planning: bool,
|
|
/// Session idle timeout. Sessions inactive longer than this are pruned.
|
|
pub session_idle_timeout: Duration,
|
|
/// Allow chat to use filesystem/shell tools directly (bypass sandbox).
|
|
pub allow_local_tools: bool,
|
|
/// Maximum daily LLM spend in cents (e.g. 10000 = $100). None = unlimited.
|
|
pub max_cost_per_day_cents: Option<u64>,
|
|
/// Maximum LLM/tool actions per hour. None = unlimited.
|
|
pub max_actions_per_hour: Option<u64>,
|
|
/// Maximum tool-call iterations per agentic loop invocation. Default 50.
|
|
pub max_tool_iterations: usize,
|
|
/// When true, skip tool approval checks entirely. For benchmarks/CI.
|
|
pub auto_approve_tools: bool,
|
|
}
|
|
|
|
impl AgentConfig {
|
|
pub(crate) fn resolve(settings: &Settings) -> Result<Self, ConfigError> {
|
|
Ok(Self {
|
|
name: parse_optional_env("AGENT_NAME", settings.agent.name.clone())?,
|
|
max_parallel_jobs: parse_optional_env(
|
|
"AGENT_MAX_PARALLEL_JOBS",
|
|
settings.agent.max_parallel_jobs as usize,
|
|
)?,
|
|
job_timeout: Duration::from_secs(parse_optional_env(
|
|
"AGENT_JOB_TIMEOUT_SECS",
|
|
settings.agent.job_timeout_secs,
|
|
)?),
|
|
stuck_threshold: Duration::from_secs(parse_optional_env(
|
|
"AGENT_STUCK_THRESHOLD_SECS",
|
|
settings.agent.stuck_threshold_secs,
|
|
)?),
|
|
repair_check_interval: Duration::from_secs(parse_optional_env(
|
|
"SELF_REPAIR_CHECK_INTERVAL_SECS",
|
|
settings.agent.repair_check_interval_secs,
|
|
)?),
|
|
max_repair_attempts: parse_optional_env(
|
|
"SELF_REPAIR_MAX_ATTEMPTS",
|
|
settings.agent.max_repair_attempts,
|
|
)?,
|
|
use_planning: parse_bool_env("AGENT_USE_PLANNING", settings.agent.use_planning)?,
|
|
session_idle_timeout: Duration::from_secs(parse_optional_env(
|
|
"SESSION_IDLE_TIMEOUT_SECS",
|
|
settings.agent.session_idle_timeout_secs,
|
|
)?),
|
|
allow_local_tools: parse_bool_env("ALLOW_LOCAL_TOOLS", false)?,
|
|
max_cost_per_day_cents: parse_option_env("MAX_COST_PER_DAY_CENTS")?,
|
|
max_actions_per_hour: parse_option_env("MAX_ACTIONS_PER_HOUR")?,
|
|
max_tool_iterations: parse_optional_env(
|
|
"AGENT_MAX_TOOL_ITERATIONS",
|
|
settings.agent.max_tool_iterations,
|
|
)?,
|
|
auto_approve_tools: parse_bool_env(
|
|
"AGENT_AUTO_APPROVE_TOOLS",
|
|
settings.agent.auto_approve_tools,
|
|
)?,
|
|
})
|
|
}
|
|
}
|