asimov_cli/commands/proxy/
config.rs1use crate::{BoxError, StandardOptions};
4use clap::ValueEnum;
5
6#[derive(Clone, Copy, Debug, ValueEnum)]
7pub enum ProxyConfigTarget {
8 Aider,
10
11 Bash,
13
14 #[cfg(feature = "unstable")]
16 ClaudeCode,
17
18 #[cfg(feature = "unstable")]
20 Cline,
21
22 Dotenv,
24
25 Goose,
27
28 Langchain,
30
31 Litellm,
33
34 Llamaindex,
36
37 Opencode,
39
40 Openhands,
42
43 Pi,
45
46 Powershell,
48
49 Zed,
51
52 Zsh,
54}
55
56pub async fn config(
57 app: ProxyConfigTarget,
58 format: Option<String>,
59 _flags: &StandardOptions,
60) -> Result<(), BoxError> {
61 use ProxyConfigTarget::*;
62 let base_url = "http://127.0.0.1:1920/v1"; let default_model = "openrouter/free";
64 match app {
65 Aider => match format.as_deref() {
67 None => {
68 let export = if cfg!(windows) { "setx" } else { "export" };
69 println!("{export} {}={}", "OPENAI_API_BASE", base_url);
70 println!("{export} {}={}", "OPENAI_API_KEY", "aider");
71 },
72 Some(_) => {},
73 },
74
75 Bash | Zsh => match format.as_deref() {
76 Some("export") | None => {
77 println!("export {}={}", "OPENAI_API_BASE", base_url);
78 println!("export {}={}", "OPENAI_API_KEY", "sh");
79 },
80 Some(_) => {},
81 },
82
83 #[cfg(feature = "unstable")]
84 ClaudeCode => todo!(), #[cfg(feature = "unstable")]
88 Cline => todo!(), Dotenv => match format.as_deref() {
91 Some("env") | None => {
92 println!("{}={}", "OPENAI_API_BASE", base_url);
93 println!("{}={}", "OPENAI_API_KEY", "dotenv");
94 },
95 Some(_) => {},
96 },
97
98 Goose => match format.as_deref() {
102 Some("json") => {
103 print!("{}", include_str!("config/goose.json"));
104 },
105 Some("jsonc") | None => {
106 print!(
107 "// {}\n{}",
108 "~/.config/goose/custom_providers/asimov.json",
109 include_str!("config/goose.json")
110 );
111 },
112 Some(_) => {},
113 },
114
115 Langchain => match format.as_deref() {
118 Some("py") | None => {
119 print!("{}", include_str!("config/langchain.py"));
120 },
121 Some("js") | Some("ts") => {
122 print!("{}", include_str!("config/langchain.js"));
123 },
124 Some(_) => {},
125 },
126
127 Litellm => match format.as_deref() {
129 Some("json") => {
130 print!("{}", include_str!("config/litellm.json"));
131 },
132 Some("jsonc") | None => {
133 print!(
134 "// {}\n{}",
135 "litellm/llms/openai_like/providers.json",
136 include_str!("config/litellm.json")
137 );
138 },
139 Some(_) => {},
140 },
141
142 Llamaindex => match format.as_deref() {
144 Some("py") | None => {
145 print!("{}", include_str!("config/llamaindex.py"));
146 },
147 Some(_) => {},
148 },
149
150 Opencode => match format.as_deref() {
152 Some("json") => {
153 print!("{}", include_str!("config/opencode.json"));
154 },
155 Some("jsonc") | None => {
156 print!(
157 "// {}\n{}",
158 "~/.config/opencode/opencode.json",
159 include_str!("config/opencode.json")
160 );
161 },
162 Some(_) => {},
163 },
164
165 Openhands => match format.as_deref() {
168 Some("env") => {
169 println!("{}={}", "LLM_BASE_URL", base_url);
170 println!("{}={}", "LLM_API_KEY", "openhands");
171 println!("{}={}", "LLM_MODEL", default_model);
172 },
173 Some("toml") | None => {
174 println!("[llm.asimov]");
175 println!("base_url = \"{}\"", base_url);
176 println!("api_key = \"{}\"", "openhands");
177 println!("model = \"{}\"", default_model);
178 },
179 Some(_) => {},
180 },
181
182 Powershell => match format.as_deref() {
183 Some("dotnet") | None => {
184 println!(
185 r#"[Environment]::SetEnvironmentVariable("{}", "{}", "User")"#,
186 "OPENAI_API_BASE", base_url
187 );
188 println!(
189 r#"[Environment]::SetEnvironmentVariable("{}", "{}", "User")"#,
190 "OPENAI_API_KEY", "powershell"
191 );
192 },
193 Some("set") | Some("setx") => {
194 println!("setx {}={}", "OPENAI_API_BASE", base_url);
195 println!("setx {}={}", "OPENAI_API_KEY", "powershell");
196 },
197 Some(_) => {},
198 },
199
200 Pi => match format.as_deref() {
203 Some("json") => {
204 print!("{}", include_str!("config/pi.json"));
205 },
206 Some("jsonc") | None => {
207 print!(
208 "// {}\n{}",
209 "~/.pi/agent/models.json",
210 include_str!("config/pi.json")
211 );
212 },
213 Some(_) => {},
214 },
215
216 Zed => match format.as_deref() {
218 Some("json") => {
219 println!("{}", zed_asimov_config()?);
220 },
221 Some("jsonc") | None => {
222 println!(
223 "// {}\n{}",
224 "~/.config/zed/settings.json",
225 zed_asimov_config()?
226 );
227 },
228 Some(_) => {},
229 },
230 };
231 Ok(())
232}
233
234pub(crate) fn zed_asimov_config() -> Result<String, jsonc_parser::errors::ParseError> {
235 use jsonc_parser::{ParseOptions, cst::CstRootNode};
236 let cst = CstRootNode::parse(&"{}", &ParseOptions::default())?;
237 let root = cst.object_value_or_set();
238 root.object_value_or_set("language_models")
239 .object_value_or_set("openai_compatible")
240 .append("ASIMOV", zed_asimov_provider());
241 Ok(cst.to_string())
242}
243
244pub(crate) fn zed_asimov_provider() -> jsonc_parser::cst::CstInputValue {
245 use jsonc_parser::json;
246 json!({
247 "api_url": "http://127.0.0.1:1920/v1", "available_models": [], })
250}