mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-07 03:00:29 +00:00
Gate --mode and --server-url CLI args behind server feature
When compiled without the server feature, these args are useless since there is no server to delegate to. Wraps the CLI fields, parser, resolve_mode, build_server_client, and related tests in cfg(feature = "server"), with standalone-only fallback paths in each command handler. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f9d114c521
commit
fc77a2fb24
2 changed files with 114 additions and 65 deletions
|
|
@ -1,7 +1,9 @@
|
|||
pub use arc_config::cli::*;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
use tracing::debug;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ResolvedMode {
|
||||
pub mode: ExecutionMode,
|
||||
|
|
@ -9,8 +11,10 @@ pub struct ResolvedMode {
|
|||
pub tls: Option<ClientTlsConfig>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
const DEFAULT_SERVER_URL: &str = "http://localhost:3000";
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn resolve_mode(
|
||||
cli_mode: Option<ExecutionMode>,
|
||||
cli_server_url: Option<&str>,
|
||||
|
|
@ -36,6 +40,7 @@ pub fn resolve_mode(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub fn build_server_client(tls: Option<&ClientTlsConfig>) -> anyhow::Result<reqwest::Client> {
|
||||
let Some(tls) = tls else {
|
||||
return Ok(reqwest::Client::new());
|
||||
|
|
@ -65,7 +70,7 @@ pub fn build_server_client(tls: Option<&ClientTlsConfig>) -> anyhow::Result<reqw
|
|||
Ok(client)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, feature = "server"))]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ struct Cli {
|
|||
debug: bool,
|
||||
|
||||
/// Execution mode: standalone (in-process) or server (delegate to API)
|
||||
#[cfg(feature = "server")]
|
||||
#[arg(long, global = true, value_parser = parse_execution_mode)]
|
||||
mode: Option<cli_config::ExecutionMode>,
|
||||
|
||||
/// Server URL (overrides server.base_url from cli.toml)
|
||||
#[cfg(feature = "server")]
|
||||
#[arg(long, global = true)]
|
||||
server_url: Option<String>,
|
||||
|
||||
|
|
@ -31,6 +33,7 @@ struct Cli {
|
|||
command: Command,
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn parse_execution_mode(s: &str) -> Result<cli_config::ExecutionMode, String> {
|
||||
match s {
|
||||
"standalone" => Ok(cli_config::ExecutionMode::Standalone),
|
||||
|
|
@ -237,41 +240,63 @@ async fn main_inner() -> Result<()> {
|
|||
if args.model.is_none() {
|
||||
args.model = llm_defaults.and_then(|l| l.model.clone());
|
||||
}
|
||||
let resolved =
|
||||
cli_config::resolve_mode(cli.mode, cli.server_url.as_deref(), &cli_config);
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let server = arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
};
|
||||
arc_llm::cli::run_prompt_via_server(args, &server).await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
arc_llm::cli::run_prompt(args).await?
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
let resolved = cli_config::resolve_mode(
|
||||
cli.mode,
|
||||
cli.server_url.as_deref(),
|
||||
&cli_config,
|
||||
);
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client =
|
||||
cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let server = arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
};
|
||||
arc_llm::cli::run_prompt_via_server(args, &server).await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
arc_llm::cli::run_prompt(args).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
arc_llm::cli::run_prompt(args).await?
|
||||
}
|
||||
}
|
||||
LlmCommand::Chat(mut args) => {
|
||||
if args.model.is_none() {
|
||||
args.model = llm_defaults.and_then(|l| l.model.clone());
|
||||
}
|
||||
let resolved =
|
||||
cli_config::resolve_mode(cli.mode, cli.server_url.as_deref(), &cli_config);
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let server = arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
};
|
||||
arc_llm::cli::run_chat_via_server(args, &server).await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
arc_llm::cli::run_chat(args).await?
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
let resolved = cli_config::resolve_mode(
|
||||
cli.mode,
|
||||
cli.server_url.as_deref(),
|
||||
&cli_config,
|
||||
);
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client =
|
||||
cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let server = arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
};
|
||||
arc_llm::cli::run_chat_via_server(args, &server).await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
arc_llm::cli::run_chat(args).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
arc_llm::cli::run_chat(args).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -284,6 +309,7 @@ async fn main_inner() -> Result<()> {
|
|||
exec_defaults.and_then(|a| a.permissions),
|
||||
exec_defaults.and_then(|a| a.output_format),
|
||||
);
|
||||
#[cfg(feature = "server")]
|
||||
let resolved =
|
||||
cli_config::resolve_mode(cli.mode, cli.server_url.as_deref(), &cli_config);
|
||||
let mcp_servers: Vec<arc_mcp::config::McpServerConfig> = cli_config
|
||||
|
|
@ -291,35 +317,44 @@ async fn main_inner() -> Result<()> {
|
|||
.into_iter()
|
||||
.map(|(name, entry)| entry.into_config(name))
|
||||
.collect();
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
tracing::info!(mode = "server", "Agent session starting");
|
||||
let http_client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let provider_name = args
|
||||
.provider
|
||||
.clone()
|
||||
.unwrap_or_else(|| "anthropic".to_string());
|
||||
let adapter = std::sync::Arc::new(arc_llm::providers::ArcServerAdapter::new(
|
||||
http_client,
|
||||
&resolved.server_base_url,
|
||||
&provider_name,
|
||||
));
|
||||
let mut client = arc_llm::client::Client::new(
|
||||
std::collections::HashMap::new(),
|
||||
None,
|
||||
vec![],
|
||||
);
|
||||
client.register_provider(adapter).await.map_err(|e| {
|
||||
anyhow::anyhow!("Failed to register arc server adapter: {e}")
|
||||
})?;
|
||||
arc_agent::cli::run_with_args_and_client(args, Some(client), mcp_servers)
|
||||
.await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
tracing::info!(mode = "standalone", "Agent session starting");
|
||||
arc_agent::cli::run_with_args(args, mcp_servers).await?
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
tracing::info!(mode = "server", "Agent session starting");
|
||||
let http_client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
let provider_name = args
|
||||
.provider
|
||||
.clone()
|
||||
.unwrap_or_else(|| "anthropic".to_string());
|
||||
let adapter =
|
||||
std::sync::Arc::new(arc_llm::providers::ArcServerAdapter::new(
|
||||
http_client,
|
||||
&resolved.server_base_url,
|
||||
&provider_name,
|
||||
));
|
||||
let mut client = arc_llm::client::Client::new(
|
||||
std::collections::HashMap::new(),
|
||||
None,
|
||||
vec![],
|
||||
);
|
||||
client.register_provider(adapter).await.map_err(|e| {
|
||||
anyhow::anyhow!("Failed to register arc server adapter: {e}")
|
||||
})?;
|
||||
arc_agent::cli::run_with_args_and_client(args, Some(client), mcp_servers)
|
||||
.await?
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => {
|
||||
tracing::info!(mode = "standalone", "Agent session starting");
|
||||
arc_agent::cli::run_with_args(args, mcp_servers).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
tracing::info!(mode = "standalone", "Agent session starting");
|
||||
arc_agent::cli::run_with_args(args, mcp_servers).await?
|
||||
}
|
||||
}
|
||||
Command::Run(mut args) => {
|
||||
let styles: &'static arc_util::terminal::Styles =
|
||||
|
|
@ -362,18 +397,27 @@ async fn main_inner() -> Result<()> {
|
|||
arc_workflows::cli::diff::diff_command(args).await?;
|
||||
}
|
||||
Command::Model { command } => {
|
||||
let cli_config = cli_config::load_cli_config(None)?;
|
||||
let resolved =
|
||||
cli_config::resolve_mode(cli.mode, cli.server_url.as_deref(), &cli_config);
|
||||
let server = match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
Some(arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
})
|
||||
let server = {
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
let cli_config = cli_config::load_cli_config(None)?;
|
||||
let resolved =
|
||||
cli_config::resolve_mode(cli.mode, cli.server_url.as_deref(), &cli_config);
|
||||
match resolved.mode {
|
||||
cli_config::ExecutionMode::Server => {
|
||||
let client = cli_config::build_server_client(resolved.tls.as_ref())?;
|
||||
Some(arc_llm::cli::ServerConnection {
|
||||
client,
|
||||
base_url: resolved.server_base_url,
|
||||
})
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => None,
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
None
|
||||
}
|
||||
cli_config::ExecutionMode::Standalone => None,
|
||||
};
|
||||
arc_llm::cli::run_models(command, server).await?
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue