1mod claude;
2mod gemini;
3mod settings;
4mod stdio_agent_server;
5
6pub use claude::*;
7pub use gemini::*;
8pub use settings::*;
9pub use stdio_agent_server::*;
10
11use acp_thread::AcpThread;
12use anyhow::Result;
13use collections::HashMap;
14use gpui::{App, Entity, SharedString, Task};
15use project::Project;
16use schemars::JsonSchema;
17use serde::{Deserialize, Serialize};
18use std::path::{Path, PathBuf};
19
20pub fn init(cx: &mut App) {
21 settings::init(cx);
22}
23
24#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema)]
25pub struct AgentServerCommand {
26 #[serde(rename = "command")]
27 pub path: PathBuf,
28 #[serde(default)]
29 pub args: Vec<String>,
30 pub env: Option<HashMap<String, String>>,
31}
32
33pub enum AgentServerVersion {
34 Supported,
35 Unsupported {
36 error_message: SharedString,
37 upgrade_message: SharedString,
38 upgrade_command: String,
39 },
40}
41
42pub trait AgentServer: Send {
43 fn logo(&self) -> ui::IconName;
44 fn name(&self) -> &'static str;
45 fn empty_state_headline(&self) -> &'static str;
46 fn empty_state_message(&self) -> &'static str;
47 fn supports_always_allow(&self) -> bool;
48
49 fn new_thread(
50 &self,
51 root_dir: &Path,
52 project: &Entity<Project>,
53 cx: &mut App,
54 ) -> Task<Result<Entity<AcpThread>>>;
55}
56
57impl std::fmt::Debug for AgentServerCommand {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 let filtered_env = self.env.as_ref().map(|env| {
60 env.iter()
61 .map(|(k, v)| {
62 (
63 k,
64 if util::redact::should_redact(k) {
65 "[REDACTED]"
66 } else {
67 v
68 },
69 )
70 })
71 .collect::<Vec<_>>()
72 });
73
74 f.debug_struct("AgentServerCommand")
75 .field("path", &self.path)
76 .field("args", &self.args)
77 .field("env", &filtered_env)
78 .finish()
79 }
80}