Skip to main content

embacle_server/runner/
factory.rs

1// ABOUTME: Factory for creating embacle LlmProvider instances from runner type identifiers
2// ABOUTME: Resolves binary paths and constructs the appropriate runner with default config
3//
4// SPDX-License-Identifier: Apache-2.0
5// Copyright (c) 2026 dravr.ai
6
7use std::env;
8
9use embacle::config::{CliRunnerType, RunnerConfig};
10use embacle::discovery::resolve_binary;
11use embacle::types::{LlmProvider, RunnerError};
12use embacle::{
13    ClaudeCodeRunner, ClineCliRunner, CodexCliRunner, ContinueCliRunner, CopilotRunner,
14    CursorAgentRunner, GeminiCliRunner, GooseCliRunner, OpenCodeRunner,
15};
16
17/// Create an `LlmProvider` instance for the given runner type
18///
19/// Resolves the CLI binary via environment variable override or PATH lookup,
20/// then constructs the appropriate runner with default configuration.
21///
22/// # Errors
23///
24/// Returns [`RunnerError`] if the CLI binary cannot be found.
25pub async fn create_runner(
26    runner_type: CliRunnerType,
27) -> Result<Box<dyn LlmProvider>, RunnerError> {
28    let binary_name = runner_type.binary_name();
29    let env_key = runner_type.env_override_key();
30    let env_override = env::var(env_key).ok();
31
32    let binary_path = resolve_binary(binary_name, env_override.as_deref())?;
33    let config = RunnerConfig::new(binary_path);
34
35    let runner: Box<dyn LlmProvider> = match runner_type {
36        CliRunnerType::ClaudeCode => Box::new(ClaudeCodeRunner::new(config)),
37        CliRunnerType::Copilot => Box::new(CopilotRunner::new(config).await),
38        CliRunnerType::CursorAgent => Box::new(CursorAgentRunner::new(config)),
39        CliRunnerType::OpenCode => Box::new(OpenCodeRunner::new(config)),
40        CliRunnerType::GeminiCli => Box::new(GeminiCliRunner::new(config)),
41        CliRunnerType::CodexCli => Box::new(CodexCliRunner::new(config)),
42        CliRunnerType::GooseCli => Box::new(GooseCliRunner::new(config)),
43        CliRunnerType::ClineCli => Box::new(ClineCliRunner::new(config)),
44        CliRunnerType::ContinueCli => Box::new(ContinueCliRunner::new(config)),
45    };
46
47    Ok(runner)
48}