mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-16 22:03:52 +00:00
feat: show help with docs link when no command provided
This commit is contained in:
parent
0ae99e97d5
commit
daca313d2c
1 changed files with 58 additions and 32 deletions
|
|
@ -6,21 +6,22 @@ use std::sync::Arc;
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
use reqwest::blocking::Client as HttpClient;
|
use reqwest::blocking::Client as HttpClient;
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
|
use sandbox_agent::router::{build_router_with_state, shutdown_servers};
|
||||||
|
use sandbox_agent::router::{
|
||||||
|
AgentInstallRequest, AppState, AuthConfig, CreateSessionRequest, MessageRequest,
|
||||||
|
PermissionReply, PermissionReplyRequest, QuestionReplyRequest,
|
||||||
|
};
|
||||||
|
use sandbox_agent::router::{
|
||||||
|
AgentListResponse, AgentModesResponse, CreateSessionResponse, EventsResponse,
|
||||||
|
SessionListResponse,
|
||||||
|
};
|
||||||
|
use sandbox_agent::telemetry;
|
||||||
|
use sandbox_agent::ui;
|
||||||
use sandbox_agent_agent_management::agents::{AgentId, AgentManager, InstallOptions};
|
use sandbox_agent_agent_management::agents::{AgentId, AgentManager, InstallOptions};
|
||||||
use sandbox_agent_agent_management::credentials::{
|
use sandbox_agent_agent_management::credentials::{
|
||||||
extract_all_credentials, AuthType, CredentialExtractionOptions, ExtractedCredentials,
|
extract_all_credentials, AuthType, CredentialExtractionOptions, ExtractedCredentials,
|
||||||
ProviderCredentials,
|
ProviderCredentials,
|
||||||
};
|
};
|
||||||
use sandbox_agent::router::{
|
|
||||||
AgentInstallRequest, AppState, AuthConfig, CreateSessionRequest, MessageRequest,
|
|
||||||
PermissionReply, PermissionReplyRequest, QuestionReplyRequest,
|
|
||||||
};
|
|
||||||
use sandbox_agent::telemetry;
|
|
||||||
use sandbox_agent::router::{
|
|
||||||
AgentListResponse, AgentModesResponse, CreateSessionResponse, EventsResponse, SessionListResponse,
|
|
||||||
};
|
|
||||||
use sandbox_agent::router::{build_router_with_state, shutdown_servers};
|
|
||||||
use sandbox_agent::ui;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
@ -33,10 +34,11 @@ const DEFAULT_PORT: u16 = 2468;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(name = "sandbox-agent", bin_name = "sandbox-agent")]
|
#[command(name = "sandbox-agent", bin_name = "sandbox-agent")]
|
||||||
#[command(about = "Sandbox agent server for managing coding agents", version)]
|
#[command(about = "https://sandboxagent.dev", version)]
|
||||||
|
#[command(arg_required_else_help = true)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Command>,
|
command: Command,
|
||||||
|
|
||||||
#[arg(long, short = 't', global = true)]
|
#[arg(long, short = 't', global = true)]
|
||||||
token: Option<String>,
|
token: Option<String>,
|
||||||
|
|
@ -325,8 +327,6 @@ struct CredentialsExtractEnvArgs {
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
enum CliError {
|
enum CliError {
|
||||||
#[error("missing command: run `sandbox-agent server` to start the server")]
|
|
||||||
MissingCommand,
|
|
||||||
#[error("missing --token or --no-token for server mode")]
|
#[error("missing --token or --no-token for server mode")]
|
||||||
MissingToken,
|
MissingToken,
|
||||||
#[error("invalid cors origin: {0}")]
|
#[error("invalid cors origin: {0}")]
|
||||||
|
|
@ -352,9 +352,8 @@ fn main() {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let result = match &cli.command {
|
let result = match &cli.command {
|
||||||
Some(Command::Server(args)) => run_server(&cli, args),
|
Command::Server(args) => run_server(&cli, args),
|
||||||
Some(command) => run_client(command, &cli),
|
command => run_client(command, &cli),
|
||||||
None => Err(CliError::MissingCommand),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
|
|
@ -367,7 +366,11 @@ fn init_logging() {
|
||||||
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(filter)
|
.with(filter)
|
||||||
.with(tracing_logfmt::builder().layer().with_writer(std::io::stderr))
|
.with(
|
||||||
|
tracing_logfmt::builder()
|
||||||
|
.layer()
|
||||||
|
.with_writer(std::io::stderr),
|
||||||
|
)
|
||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,8 +383,8 @@ fn run_server(cli: &Cli, server: &ServerArgs) -> Result<(), CliError> {
|
||||||
return Err(CliError::MissingToken);
|
return Err(CliError::MissingToken);
|
||||||
};
|
};
|
||||||
|
|
||||||
let agent_manager =
|
let agent_manager = AgentManager::new(default_install_dir())
|
||||||
AgentManager::new(default_install_dir()).map_err(|err| CliError::Server(err.to_string()))?;
|
.map_err(|err| CliError::Server(err.to_string()))?;
|
||||||
let state = Arc::new(AppState::new(auth, agent_manager));
|
let state = Arc::new(AppState::new(auth, agent_manager));
|
||||||
let (mut router, state) = build_router_with_state(state);
|
let (mut router, state) = build_router_with_state(state);
|
||||||
|
|
||||||
|
|
@ -514,7 +517,11 @@ fn run_sessions(command: &SessionsCommand, cli: &Cli) -> Result<(), CliError> {
|
||||||
&body,
|
&body,
|
||||||
&[(
|
&[(
|
||||||
"include_raw",
|
"include_raw",
|
||||||
if args.include_raw { Some("true".to_string()) } else { None },
|
if args.include_raw {
|
||||||
|
Some("true".to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
)],
|
)],
|
||||||
)?;
|
)?;
|
||||||
print_text_response(response)
|
print_text_response(response)
|
||||||
|
|
@ -535,7 +542,11 @@ fn run_sessions(command: &SessionsCommand, cli: &Cli) -> Result<(), CliError> {
|
||||||
("limit", args.limit.map(|v| v.to_string())),
|
("limit", args.limit.map(|v| v.to_string())),
|
||||||
(
|
(
|
||||||
"include_raw",
|
"include_raw",
|
||||||
if args.include_raw { Some("true".to_string()) } else { None },
|
if args.include_raw {
|
||||||
|
Some("true".to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -550,7 +561,11 @@ fn run_sessions(command: &SessionsCommand, cli: &Cli) -> Result<(), CliError> {
|
||||||
("offset", args.offset.map(|v| v.to_string())),
|
("offset", args.offset.map(|v| v.to_string())),
|
||||||
(
|
(
|
||||||
"include_raw",
|
"include_raw",
|
||||||
if args.include_raw { Some("true".to_string()) } else { None },
|
if args.include_raw {
|
||||||
|
Some("true".to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -675,8 +690,12 @@ enum CredentialAgent {
|
||||||
|
|
||||||
fn credentials_to_output(credentials: ExtractedCredentials, reveal: bool) -> CredentialsOutput {
|
fn credentials_to_output(credentials: ExtractedCredentials, reveal: bool) -> CredentialsOutput {
|
||||||
CredentialsOutput {
|
CredentialsOutput {
|
||||||
anthropic: credentials.anthropic.map(|cred| summarize_credential(&cred, reveal)),
|
anthropic: credentials
|
||||||
openai: credentials.openai.map(|cred| summarize_credential(&cred, reveal)),
|
.anthropic
|
||||||
|
.map(|cred| summarize_credential(&cred, reveal)),
|
||||||
|
openai: credentials
|
||||||
|
.openai
|
||||||
|
.map(|cred| summarize_credential(&cred, reveal)),
|
||||||
other: credentials
|
other: credentials
|
||||||
.other
|
.other
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -715,11 +734,10 @@ fn redact_key(key: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install_agent_local(args: &InstallAgentArgs) -> Result<(), CliError> {
|
fn install_agent_local(args: &InstallAgentArgs) -> Result<(), CliError> {
|
||||||
let agent_id = AgentId::parse(&args.agent).ok_or_else(|| {
|
let agent_id = AgentId::parse(&args.agent)
|
||||||
CliError::Server(format!("unsupported agent: {}", args.agent))
|
.ok_or_else(|| CliError::Server(format!("unsupported agent: {}", args.agent)))?;
|
||||||
})?;
|
let manager = AgentManager::new(default_install_dir())
|
||||||
let manager =
|
.map_err(|err| CliError::Server(err.to_string()))?;
|
||||||
AgentManager::new(default_install_dir()).map_err(|err| CliError::Server(err.to_string()))?;
|
|
||||||
manager
|
manager
|
||||||
.install(
|
.install(
|
||||||
agent_id,
|
agent_id,
|
||||||
|
|
@ -903,7 +921,11 @@ impl ClientContext {
|
||||||
.endpoint
|
.endpoint
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| format!("http://{}:{}", DEFAULT_HOST, DEFAULT_PORT));
|
.unwrap_or_else(|| format!("http://{}:{}", DEFAULT_HOST, DEFAULT_PORT));
|
||||||
let token = if cli.no_token { None } else { cli.token.clone() };
|
let token = if cli.no_token {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
cli.token.clone()
|
||||||
|
};
|
||||||
let client = HttpClient::builder().build()?;
|
let client = HttpClient::builder().build()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
@ -943,7 +965,11 @@ impl ClientContext {
|
||||||
Ok(request.send()?)
|
Ok(request.send()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<T: Serialize>(&self, path: &str, body: &T) -> Result<reqwest::blocking::Response, CliError> {
|
fn post<T: Serialize>(
|
||||||
|
&self,
|
||||||
|
path: &str,
|
||||||
|
body: &T,
|
||||||
|
) -> Result<reqwest::blocking::Response, CliError> {
|
||||||
Ok(self.request(Method::POST, path).json(body).send()?)
|
Ok(self.request(Method::POST, path).json(body).send()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue