mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
* refactor: encapsulate leaked abstractions from main.rs and app.rs into owning modules Move module-specific initialization logic out of main.rs (1222→665 lines, -46%) and app.rs (944→780 lines, -17%) into their respective owning modules as public factory functions. This enforces separation of concerns so that adding a new DB backend, MCP transport, or channel doesn't require editing main.rs/app.rs. Key changes: - Tracing init functions → src/tracing_fmt.rs - DB connection factory (connect_with_handles + DatabaseHandles) → src/db/mod.rs - Secrets store factory (create_secrets_store) → src/secrets/mod.rs - MCP transport dispatch factory (create_client_from_config) → src/tools/mcp/factory.rs - Orchestrator setup (setup_orchestrator + OrchestratorSetup) → src/orchestrator/mod.rs - WASM channel setup (setup_wasm_channels) → src/channels/wasm/setup.rs - Worker entry points (run_worker, run_claude_bridge) → src/worker/mod.rs - Shared CLI secrets init (init_secrets_store) → src/cli/mod.rs - Tunnel startup (start_managed_tunnel) → src/tunnel/mod.rs - Onboard check (check_onboard_needed) → src/setup/mod.rs - ExtensionManager unified MCP: uses create_client_from_config via McpProcessManager, enabling stdio/Unix transports for hot-activated MCP servers - Deduplicated ~130 lines of secrets store init across cli/mcp.rs and cli/tool.rs - CLAUDE.md updated with module-owned initialization guideline [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * refactor: address review feedback — deduplicate db factory, extract channel helper - connect_from_config() now delegates to connect_with_handles() to eliminate duplicated backend-matching logic (Copilot review feedback) - Extract register_channel() helper from setup_wasm_channels() loop body to improve readability (Gemini review feedback) [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * style: fix rustfmt line wrapping in setup_wasm_channels Co-Authored-By: Claude Opus 4.6 <[email protected]> * test: add integration test for module-owned initialization factories Exercises the full factory chain end-to-end to verify nothing was lost when initialization logic was moved from main.rs/app.rs into owning modules: - connect_with_handles returns Database + populated backend handles - connect_from_config delegates correctly (produces working Database) - secrets::create_secrets_store builds working store from DatabaseHandles - db::create_secrets_store standalone factory round-trips secrets - Both secrets factories produce compatible stores (cross-read works) - ExtensionManager constructs with McpProcessManager and is functional - DatabaseHandles default is empty All tests run without external services using libsql in-memory/tempfile. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: wire cli/mcp.rs and cli/tool.rs to shared init_secrets_store() Both files had inline implementations identical to cli::init_secrets_store(). Replace with delegation to complete the claimed deduplication. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * style: fix rustfmt line wrapping in integration test Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(review): remove unused Config import and deduplicate Error Handling section - Remove `#[allow(unused_imports)]` and unused `use crate::config::Config` from cli/tool.rs (no longer needed after delegating to shared `cli::init_secrets_store()`) - Remove duplicate Error Handling subsection from CLAUDE.md Key Patterns (all four bullets already exist in Code Style section and review-discipline.md) Addresses Copilot review comments. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(review): address remaining Copilot review comments - secrets/mod.rs: clarify docstring that None is a normal no-db condition - app.rs: add comment explaining the empty_handles fallback path - orchestrator/mod.rs: combine duplicated sandbox condition into single block - setup/mod.rs: document env var reads and thread-safety caveat [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Henry Park <[email protected]>
94 lines
3.1 KiB
Rust
94 lines
3.1 KiB
Rust
//! Worker mode for running inside Docker containers.
|
|
//!
|
|
//! When `ironclaw worker` is invoked, the binary starts in worker mode:
|
|
//! - Connects to the orchestrator over HTTP
|
|
//! - Uses a `ProxyLlmProvider` that routes LLM calls through the orchestrator
|
|
//! - Runs container-safe tools (shell, file ops, patch)
|
|
//! - Reports status and completion back to the orchestrator
|
|
//!
|
|
//! ```text
|
|
//! ┌────────────────────────────────┐
|
|
//! │ Docker Container │
|
|
//! │ │
|
|
//! │ ironclaw worker │
|
|
//! │ ├─ ProxyLlmProvider ─────────┼──▶ Orchestrator /worker/{id}/llm/complete
|
|
//! │ ├─ SafetyLayer │
|
|
//! │ ├─ ToolRegistry │
|
|
//! │ │ ├─ shell │
|
|
//! │ │ ├─ read_file │
|
|
//! │ │ ├─ write_file │
|
|
//! │ │ ├─ list_dir │
|
|
//! │ │ └─ apply_patch │
|
|
//! │ └─ WorkerHttpClient ─────────┼──▶ Orchestrator /worker/{id}/status
|
|
//! │ │
|
|
//! └────────────────────────────────┘
|
|
//! ```
|
|
|
|
pub mod api;
|
|
pub mod claude_bridge;
|
|
pub mod proxy_llm;
|
|
pub mod runtime;
|
|
|
|
pub use api::WorkerHttpClient;
|
|
pub use claude_bridge::ClaudeBridgeRuntime;
|
|
pub use proxy_llm::ProxyLlmProvider;
|
|
pub use runtime::WorkerRuntime;
|
|
|
|
/// Run the Worker subcommand (inside Docker containers).
|
|
pub async fn run_worker(
|
|
job_id: uuid::Uuid,
|
|
orchestrator_url: &str,
|
|
max_iterations: u32,
|
|
) -> anyhow::Result<()> {
|
|
tracing::info!(
|
|
"Starting worker for job {} (orchestrator: {})",
|
|
job_id,
|
|
orchestrator_url
|
|
);
|
|
|
|
let config = runtime::WorkerConfig {
|
|
job_id,
|
|
orchestrator_url: orchestrator_url.to_string(),
|
|
max_iterations,
|
|
timeout: std::time::Duration::from_secs(600),
|
|
};
|
|
|
|
let rt =
|
|
WorkerRuntime::new(config).map_err(|e| anyhow::anyhow!("Worker init failed: {}", e))?;
|
|
|
|
rt.run()
|
|
.await
|
|
.map_err(|e| anyhow::anyhow!("Worker failed: {}", e))
|
|
}
|
|
|
|
/// Run the Claude Code bridge subcommand (inside Docker containers).
|
|
pub async fn run_claude_bridge(
|
|
job_id: uuid::Uuid,
|
|
orchestrator_url: &str,
|
|
max_turns: u32,
|
|
model: &str,
|
|
) -> anyhow::Result<()> {
|
|
tracing::info!(
|
|
"Starting Claude Code bridge for job {} (orchestrator: {}, model: {})",
|
|
job_id,
|
|
orchestrator_url,
|
|
model
|
|
);
|
|
|
|
let config = claude_bridge::ClaudeBridgeConfig {
|
|
job_id,
|
|
orchestrator_url: orchestrator_url.to_string(),
|
|
max_turns,
|
|
model: model.to_string(),
|
|
timeout: std::time::Duration::from_secs(1800),
|
|
allowed_tools: crate::config::ClaudeCodeConfig::from_env().allowed_tools,
|
|
};
|
|
|
|
let rt = ClaudeBridgeRuntime::new(config)
|
|
.map_err(|e| anyhow::anyhow!("Claude bridge init failed: {}", e))?;
|
|
|
|
rt.run()
|
|
.await
|
|
.map_err(|e| anyhow::anyhow!("Claude bridge failed: {}", e))
|
|
}
|