@arrislink/axon 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/README.zh-CN.md +7 -7
- package/dist/index.js +444 -161
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -161,8 +161,8 @@ ax plan # Uses configured provider
|
|
|
161
161
|
|
|
162
162
|
**Provider Priority:**
|
|
163
163
|
1. **CLI Mode** - Uses OpenCode CLI (inherits full OMO capabilities)
|
|
164
|
-
2. **Direct Mode** - Reads OMO config
|
|
165
|
-
3. **Fallback Mode** - Uses `ANTHROPIC_API_KEY` environment
|
|
164
|
+
2. **Direct Mode** - Reads OMO config and resolves **Antigravity** tokens automatically
|
|
165
|
+
3. **Fallback Mode** - Uses `ANTHROPIC_API_KEY` etc. environment variables
|
|
166
166
|
|
|
167
167
|
### Environment Variables
|
|
168
168
|
|
|
@@ -216,8 +216,8 @@ graph TD
|
|
|
216
216
|
|
|
217
217
|
subgraph "LLM Layer"
|
|
218
218
|
Orch --> LLMInt[Unified LLM Interface]
|
|
219
|
-
LLMInt --> OMO[
|
|
220
|
-
OMO --> Providers[Providers: Anthropic,
|
|
219
|
+
LLMInt --> OMO[OMO Config & Antigravity Auth]
|
|
220
|
+
OMO --> Providers[Providers: Anthropic, Google Gemini, OpenAI, etc.]
|
|
221
221
|
end
|
|
222
222
|
```
|
|
223
223
|
|
package/README.zh-CN.md
CHANGED
|
@@ -156,12 +156,12 @@ omo config set-provider antigravity
|
|
|
156
156
|
|
|
157
157
|
# Axon 自动检测并使用 OMO 配置
|
|
158
158
|
ax plan # 使用配置的提供商
|
|
159
|
-
```
|
|
160
159
|
|
|
161
|
-
|
|
162
|
-
1. **CLI 模式** - 使用 OpenCode CLI
|
|
163
|
-
2.
|
|
164
|
-
3.
|
|
160
|
+
**Provider 优先级:**
|
|
161
|
+
1. **CLI 模式** - 使用 OpenCode CLI (继承完整的 OMO 能力)
|
|
162
|
+
2. **Direct 模式** - 读取 OMO 配置并自动解析 **Antigravity** 刷新令牌
|
|
163
|
+
3. **Fallback 模式** - 使用 `ANTHROPIC_API_KEY` 等环境变量
|
|
164
|
+
```
|
|
165
165
|
|
|
166
166
|
### 环境变量
|
|
167
167
|
|
|
@@ -215,8 +215,8 @@ graph TD
|
|
|
215
215
|
|
|
216
216
|
subgraph "LLM 层"
|
|
217
217
|
Orch --> LLMInt[统一 LLM 接口]
|
|
218
|
-
LLMInt --> OMO[
|
|
219
|
-
OMO --> Providers[
|
|
218
|
+
LLMInt --> OMO[OMO 配置 & Antigravity 认证]
|
|
219
|
+
OMO --> Providers[提供商: Anthropic, Google Gemini, OpenAI, etc.]
|
|
220
220
|
end
|
|
221
221
|
```
|
|
222
222
|
|
package/dist/index.js
CHANGED
|
@@ -2427,9 +2427,15 @@ var init_defaults = __esm(() => {
|
|
|
2427
2427
|
MODEL_PRICING = {
|
|
2428
2428
|
"claude-sonnet-4-20250514": { input: 3, output: 15 },
|
|
2429
2429
|
"claude-opus-4-5-20251101": { input: 15, output: 75 },
|
|
2430
|
+
"claude-opus-4-6": { input: 15, output: 75 },
|
|
2430
2431
|
"gemini-2.0-flash-exp": { input: 0.5, output: 0.5 },
|
|
2432
|
+
"gemini-3-pro": { input: 1.25, output: 3.75 },
|
|
2433
|
+
"gemini-3-flash": { input: 0.1, output: 0.4 },
|
|
2431
2434
|
"gpt-4-turbo": { input: 10, output: 30 },
|
|
2432
|
-
"gpt-4o": { input: 5, output: 15 }
|
|
2435
|
+
"gpt-4o": { input: 5, output: 15 },
|
|
2436
|
+
"gpt-5.3-codex": { input: 10, output: 30 },
|
|
2437
|
+
"gpt-5-nano": { input: 0.5, output: 1.5 },
|
|
2438
|
+
"glm-4.7-free": { input: 0, output: 0 }
|
|
2433
2439
|
};
|
|
2434
2440
|
});
|
|
2435
2441
|
|
|
@@ -16398,120 +16404,6 @@ var init_anthropic = __esm(() => {
|
|
|
16398
16404
|
init_errors();
|
|
16399
16405
|
});
|
|
16400
16406
|
|
|
16401
|
-
// src/core/llm/opencode-client.ts
|
|
16402
|
-
class OpenCodeLLMClient {
|
|
16403
|
-
agent;
|
|
16404
|
-
command;
|
|
16405
|
-
constructor(agent = "sisyphus", command = ["opencode"]) {
|
|
16406
|
-
this.agent = agent;
|
|
16407
|
-
this.command = command;
|
|
16408
|
-
}
|
|
16409
|
-
async chat(messages, options) {
|
|
16410
|
-
const iterator = this.streamChat(messages, options);
|
|
16411
|
-
let result = await iterator.next();
|
|
16412
|
-
while (!result.done) {
|
|
16413
|
-
result = await iterator.next();
|
|
16414
|
-
}
|
|
16415
|
-
return result.value;
|
|
16416
|
-
}
|
|
16417
|
-
async* streamChat(messages, options) {
|
|
16418
|
-
const prompt = this.formatMessages(messages);
|
|
16419
|
-
const args = [...this.command, "run", "--agent", this.agent, "--format", "json"];
|
|
16420
|
-
if (options?.model) {
|
|
16421
|
-
args.push("--model", options.model);
|
|
16422
|
-
}
|
|
16423
|
-
const proc = Bun.spawn(args, {
|
|
16424
|
-
stdin: new Blob([prompt]),
|
|
16425
|
-
stdout: "pipe",
|
|
16426
|
-
stderr: "pipe"
|
|
16427
|
-
});
|
|
16428
|
-
let fullResponse = "";
|
|
16429
|
-
let metadata = {
|
|
16430
|
-
model: "unknown",
|
|
16431
|
-
tokens: { input: 0, output: 0 },
|
|
16432
|
-
cost: 0
|
|
16433
|
-
};
|
|
16434
|
-
const decoder = new TextDecoder;
|
|
16435
|
-
const reader = proc.stdout.getReader();
|
|
16436
|
-
let buffer = "";
|
|
16437
|
-
try {
|
|
16438
|
-
while (true) {
|
|
16439
|
-
const { done, value } = await reader.read();
|
|
16440
|
-
if (done)
|
|
16441
|
-
break;
|
|
16442
|
-
buffer += decoder.decode(value, { stream: true });
|
|
16443
|
-
const lines = buffer.split(`
|
|
16444
|
-
`);
|
|
16445
|
-
buffer = lines.pop() || "";
|
|
16446
|
-
for (const line of lines) {
|
|
16447
|
-
if (!line.trim())
|
|
16448
|
-
continue;
|
|
16449
|
-
try {
|
|
16450
|
-
const event = JSON.parse(line);
|
|
16451
|
-
if (event.type === "config" && event.part?.model) {
|
|
16452
|
-
metadata.model = event.part.model;
|
|
16453
|
-
} else if (event.model && metadata.model === "unknown") {
|
|
16454
|
-
metadata.model = event.model;
|
|
16455
|
-
}
|
|
16456
|
-
if (event.type === "text" && event.part?.text) {
|
|
16457
|
-
const text = event.part.text;
|
|
16458
|
-
fullResponse += text;
|
|
16459
|
-
yield text;
|
|
16460
|
-
} else if (event.type === "content" && event.part?.content) {
|
|
16461
|
-
const text = event.part.content;
|
|
16462
|
-
fullResponse += text;
|
|
16463
|
-
yield text;
|
|
16464
|
-
} else if (event.type === "step_finish") {
|
|
16465
|
-
if (event.part?.snapshot) {}
|
|
16466
|
-
if (event.part?.tokens) {
|
|
16467
|
-
metadata.tokens.input = event.part.tokens.input || 0;
|
|
16468
|
-
metadata.tokens.output = event.part.tokens.output || 0;
|
|
16469
|
-
}
|
|
16470
|
-
if (event.part?.cost) {
|
|
16471
|
-
metadata.cost = event.part.cost;
|
|
16472
|
-
}
|
|
16473
|
-
}
|
|
16474
|
-
} catch (e) {}
|
|
16475
|
-
}
|
|
16476
|
-
}
|
|
16477
|
-
} finally {
|
|
16478
|
-
reader.releaseLock();
|
|
16479
|
-
proc.kill();
|
|
16480
|
-
}
|
|
16481
|
-
const exitCode = await proc.exited;
|
|
16482
|
-
const stderr = await new Response(proc.stderr).text();
|
|
16483
|
-
if (exitCode !== 0) {
|
|
16484
|
-
throw new Error(`OpenCode CLI Error: ${stderr || "Unknown error"}`);
|
|
16485
|
-
}
|
|
16486
|
-
if (fullResponse.trim() === "" && stderr.trim().length > 0) {
|
|
16487
|
-
if (stderr.includes("Error") || stderr.includes("NotFound") || stderr.includes("|")) {
|
|
16488
|
-
throw new Error(`OpenCode CLI Silent Crash: ${stderr.split(`
|
|
16489
|
-
`)[0]}`);
|
|
16490
|
-
}
|
|
16491
|
-
}
|
|
16492
|
-
if (fullResponse.trim() === "") {
|
|
16493
|
-
throw new Error("OpenCode CLI returned an empty response");
|
|
16494
|
-
}
|
|
16495
|
-
return {
|
|
16496
|
-
content: fullResponse,
|
|
16497
|
-
model: metadata.model,
|
|
16498
|
-
tokens: metadata.tokens,
|
|
16499
|
-
cost: metadata.cost
|
|
16500
|
-
};
|
|
16501
|
-
}
|
|
16502
|
-
async complete(prompt, options) {
|
|
16503
|
-
const result = await this.chat([{ role: "user", content: prompt }], options);
|
|
16504
|
-
return result.content;
|
|
16505
|
-
}
|
|
16506
|
-
formatMessages(messages) {
|
|
16507
|
-
return messages.map((m) => `<${m.role}>
|
|
16508
|
-
${m.content}
|
|
16509
|
-
</${m.role}>`).join(`
|
|
16510
|
-
|
|
16511
|
-
`);
|
|
16512
|
-
}
|
|
16513
|
-
}
|
|
16514
|
-
|
|
16515
16407
|
// src/core/llm/omo-config-reader.ts
|
|
16516
16408
|
var exports_omo_config_reader = {};
|
|
16517
16409
|
__export(exports_omo_config_reader, {
|
|
@@ -16521,6 +16413,18 @@ __export(exports_omo_config_reader, {
|
|
|
16521
16413
|
});
|
|
16522
16414
|
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
16523
16415
|
import { homedir as homedir2 } from "os";
|
|
16416
|
+
function resolveProviderType(modelString) {
|
|
16417
|
+
const [prefix] = (modelString || "").split("/");
|
|
16418
|
+
const typeMap = {
|
|
16419
|
+
opencode: "antigravity",
|
|
16420
|
+
anthropic: "anthropic",
|
|
16421
|
+
google: "google",
|
|
16422
|
+
openai: "openai",
|
|
16423
|
+
mistral: "mistral",
|
|
16424
|
+
deepseek: "deepseek"
|
|
16425
|
+
};
|
|
16426
|
+
return typeMap[prefix] || prefix;
|
|
16427
|
+
}
|
|
16524
16428
|
function getOMOConfigPaths() {
|
|
16525
16429
|
const home = homedir2();
|
|
16526
16430
|
return [
|
|
@@ -16538,8 +16442,10 @@ class OMOConfigReader {
|
|
|
16538
16442
|
configSource = "";
|
|
16539
16443
|
defaultProvider;
|
|
16540
16444
|
fallbackChain = [];
|
|
16445
|
+
antigravityToken;
|
|
16541
16446
|
constructor() {
|
|
16542
16447
|
this.loadConfig();
|
|
16448
|
+
this.loadAntigravityToken();
|
|
16543
16449
|
}
|
|
16544
16450
|
loadConfig() {
|
|
16545
16451
|
const paths = getOMOConfigPaths();
|
|
@@ -16550,7 +16456,7 @@ class OMOConfigReader {
|
|
|
16550
16456
|
if (path.endsWith(".yaml") || path.endsWith(".yml")) {
|
|
16551
16457
|
this.loadYamlConfig(content);
|
|
16552
16458
|
} else if (path.endsWith(".json")) {
|
|
16553
|
-
this.loadJsonConfig(content);
|
|
16459
|
+
this.loadJsonConfig(content, path);
|
|
16554
16460
|
}
|
|
16555
16461
|
if (this.providers.length > 0) {
|
|
16556
16462
|
this.configSource = path;
|
|
@@ -16561,6 +16467,45 @@ class OMOConfigReader {
|
|
|
16561
16467
|
}
|
|
16562
16468
|
}
|
|
16563
16469
|
}
|
|
16470
|
+
if (this.providers.length > 0 && !this.configSource.endsWith("opencode.json")) {
|
|
16471
|
+
this.mergeOpenCodeProviders();
|
|
16472
|
+
}
|
|
16473
|
+
}
|
|
16474
|
+
loadAntigravityToken() {
|
|
16475
|
+
try {
|
|
16476
|
+
const accountsPath = `${homedir2()}/.config/opencode/antigravity-accounts.json`;
|
|
16477
|
+
if (existsSync4(accountsPath)) {
|
|
16478
|
+
const accounts = JSON.parse(readFileSync2(accountsPath, "utf-8"));
|
|
16479
|
+
if (accounts.accounts?.length > 0) {
|
|
16480
|
+
const activeIdx = accounts.activeIndex ?? 0;
|
|
16481
|
+
const account = accounts.accounts.find((a) => a.enabled !== false) || accounts.accounts[activeIdx];
|
|
16482
|
+
if (account) {
|
|
16483
|
+
this.antigravityToken = account.token || account.refreshToken;
|
|
16484
|
+
}
|
|
16485
|
+
}
|
|
16486
|
+
}
|
|
16487
|
+
} catch {}
|
|
16488
|
+
}
|
|
16489
|
+
mergeOpenCodeProviders() {
|
|
16490
|
+
const opencodePath = `${homedir2()}/.config/opencode/opencode.json`;
|
|
16491
|
+
if (!existsSync4(opencodePath))
|
|
16492
|
+
return;
|
|
16493
|
+
try {
|
|
16494
|
+
const content = readFileSync2(opencodePath, "utf-8");
|
|
16495
|
+
const config = JSON.parse(content);
|
|
16496
|
+
if (config.provider) {
|
|
16497
|
+
for (const [name, details] of Object.entries(config.provider)) {
|
|
16498
|
+
if (!this.providers.some((p) => p.name === name)) {
|
|
16499
|
+
this.providers.push({
|
|
16500
|
+
name,
|
|
16501
|
+
type: name,
|
|
16502
|
+
models: Object.keys(details.models || {}),
|
|
16503
|
+
endpoint: details.endpoint
|
|
16504
|
+
});
|
|
16505
|
+
}
|
|
16506
|
+
}
|
|
16507
|
+
}
|
|
16508
|
+
} catch {}
|
|
16564
16509
|
}
|
|
16565
16510
|
loadYamlConfig(content) {
|
|
16566
16511
|
const config = $parse(content);
|
|
@@ -16570,15 +16515,15 @@ class OMOConfigReader {
|
|
|
16570
16515
|
this.fallbackChain = config.fallback_chain || [];
|
|
16571
16516
|
}
|
|
16572
16517
|
}
|
|
16573
|
-
loadJsonConfig(content) {
|
|
16518
|
+
loadJsonConfig(content, _filePath) {
|
|
16574
16519
|
const config = JSON.parse(content);
|
|
16575
16520
|
if (config.agents) {
|
|
16576
16521
|
this.providers = Object.entries(config.agents).map(([name, agent]) => {
|
|
16577
|
-
const
|
|
16522
|
+
const resolvedType = resolveProviderType(agent.model || "");
|
|
16578
16523
|
return {
|
|
16579
16524
|
name,
|
|
16580
16525
|
models: [agent.model || "unknown"],
|
|
16581
|
-
type:
|
|
16526
|
+
type: resolvedType,
|
|
16582
16527
|
endpoint: undefined,
|
|
16583
16528
|
api_key: undefined
|
|
16584
16529
|
};
|
|
@@ -16612,11 +16557,14 @@ class OMOConfigReader {
|
|
|
16612
16557
|
if (p)
|
|
16613
16558
|
return p;
|
|
16614
16559
|
}
|
|
16615
|
-
const priority2 = ["antigravity", "anthropic", "openai", "google"
|
|
16616
|
-
for (const
|
|
16617
|
-
const
|
|
16618
|
-
if (
|
|
16619
|
-
return
|
|
16560
|
+
const priority2 = ["antigravity", "anthropic", "openai", "google"];
|
|
16561
|
+
for (const target of priority2) {
|
|
16562
|
+
const byName = this.getProvider(target);
|
|
16563
|
+
if (byName)
|
|
16564
|
+
return byName;
|
|
16565
|
+
const byType = this.providers.find((p) => p.type === target);
|
|
16566
|
+
if (byType)
|
|
16567
|
+
return byType;
|
|
16620
16568
|
}
|
|
16621
16569
|
return this.providers[0] || null;
|
|
16622
16570
|
}
|
|
@@ -16633,20 +16581,155 @@ class OMOConfigReader {
|
|
|
16633
16581
|
getConfigSource() {
|
|
16634
16582
|
return this.configSource;
|
|
16635
16583
|
}
|
|
16584
|
+
hasAntigravityAuth() {
|
|
16585
|
+
return !!this.antigravityToken;
|
|
16586
|
+
}
|
|
16587
|
+
getAntigravityToken() {
|
|
16588
|
+
return this.antigravityToken;
|
|
16589
|
+
}
|
|
16636
16590
|
getProviderApiKey(provider) {
|
|
16637
16591
|
if (provider.api_key) {
|
|
16638
16592
|
const match = provider.api_key.match(/^\$\{(\w+)\}$/);
|
|
16639
16593
|
return match ? process.env[match[1]] : provider.api_key;
|
|
16640
16594
|
}
|
|
16641
16595
|
const type = provider.type || provider.name;
|
|
16642
|
-
const
|
|
16643
|
-
|
|
16596
|
+
const envMappings = {
|
|
16597
|
+
anthropic: ["ANTHROPIC_API_KEY"],
|
|
16598
|
+
openai: ["OPENAI_API_KEY"],
|
|
16599
|
+
google: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
|
|
16600
|
+
antigravity: ["ANTIGRAVITY_API_KEY"],
|
|
16601
|
+
deepseek: ["DEEPSEEK_API_KEY"]
|
|
16602
|
+
};
|
|
16603
|
+
const envVars = envMappings[type] || [`${type.toUpperCase()}_API_KEY`];
|
|
16604
|
+
for (const envVar of envVars) {
|
|
16605
|
+
const envKey = process.env[envVar];
|
|
16606
|
+
if (envKey)
|
|
16607
|
+
return envKey;
|
|
16608
|
+
}
|
|
16609
|
+
if (this.antigravityToken) {
|
|
16610
|
+
return this.antigravityToken;
|
|
16611
|
+
}
|
|
16612
|
+
return;
|
|
16644
16613
|
}
|
|
16645
16614
|
}
|
|
16646
16615
|
var init_omo_config_reader = __esm(() => {
|
|
16647
16616
|
init_dist();
|
|
16648
16617
|
});
|
|
16649
16618
|
|
|
16619
|
+
// src/core/llm/opencode-client.ts
|
|
16620
|
+
class OpenCodeLLMClient {
|
|
16621
|
+
agent;
|
|
16622
|
+
command;
|
|
16623
|
+
constructor(agent = "sisyphus", command = ["opencode"]) {
|
|
16624
|
+
this.agent = agent;
|
|
16625
|
+
this.command = command;
|
|
16626
|
+
}
|
|
16627
|
+
async chat(messages, options) {
|
|
16628
|
+
const iterator = this.streamChat(messages, options);
|
|
16629
|
+
let result = await iterator.next();
|
|
16630
|
+
while (!result.done) {
|
|
16631
|
+
result = await iterator.next();
|
|
16632
|
+
}
|
|
16633
|
+
return result.value;
|
|
16634
|
+
}
|
|
16635
|
+
async* streamChat(messages, options) {
|
|
16636
|
+
const prompt = this.formatMessages(messages);
|
|
16637
|
+
const args = [...this.command, "run", "--agent", this.agent, "--format", "json"];
|
|
16638
|
+
if (options?.model) {
|
|
16639
|
+
args.push("--model", options.model);
|
|
16640
|
+
}
|
|
16641
|
+
const proc = Bun.spawn(args, {
|
|
16642
|
+
stdin: new Blob([prompt]),
|
|
16643
|
+
stdout: "pipe",
|
|
16644
|
+
stderr: "pipe"
|
|
16645
|
+
});
|
|
16646
|
+
let fullResponse = "";
|
|
16647
|
+
let metadata = {
|
|
16648
|
+
model: "unknown",
|
|
16649
|
+
tokens: { input: 0, output: 0 },
|
|
16650
|
+
cost: 0
|
|
16651
|
+
};
|
|
16652
|
+
const decoder = new TextDecoder;
|
|
16653
|
+
const reader = proc.stdout.getReader();
|
|
16654
|
+
let buffer = "";
|
|
16655
|
+
try {
|
|
16656
|
+
while (true) {
|
|
16657
|
+
const { done, value } = await reader.read();
|
|
16658
|
+
if (done)
|
|
16659
|
+
break;
|
|
16660
|
+
buffer += decoder.decode(value, { stream: true });
|
|
16661
|
+
const lines = buffer.split(`
|
|
16662
|
+
`);
|
|
16663
|
+
buffer = lines.pop() || "";
|
|
16664
|
+
for (const line of lines) {
|
|
16665
|
+
if (!line.trim())
|
|
16666
|
+
continue;
|
|
16667
|
+
try {
|
|
16668
|
+
const event = JSON.parse(line);
|
|
16669
|
+
if (event.type === "config" && event.part?.model) {
|
|
16670
|
+
metadata.model = event.part.model;
|
|
16671
|
+
} else if (event.model && metadata.model === "unknown") {
|
|
16672
|
+
metadata.model = event.model;
|
|
16673
|
+
}
|
|
16674
|
+
if (event.type === "text" && event.part?.text) {
|
|
16675
|
+
const text = event.part.text;
|
|
16676
|
+
fullResponse += text;
|
|
16677
|
+
yield text;
|
|
16678
|
+
} else if (event.type === "content" && event.part?.content) {
|
|
16679
|
+
const text = event.part.content;
|
|
16680
|
+
fullResponse += text;
|
|
16681
|
+
yield text;
|
|
16682
|
+
} else if (event.type === "step_finish") {
|
|
16683
|
+
if (event.part?.snapshot) {}
|
|
16684
|
+
if (event.part?.tokens) {
|
|
16685
|
+
metadata.tokens.input = event.part.tokens.input || 0;
|
|
16686
|
+
metadata.tokens.output = event.part.tokens.output || 0;
|
|
16687
|
+
}
|
|
16688
|
+
if (event.part?.cost) {
|
|
16689
|
+
metadata.cost = event.part.cost;
|
|
16690
|
+
}
|
|
16691
|
+
}
|
|
16692
|
+
} catch (e) {}
|
|
16693
|
+
}
|
|
16694
|
+
}
|
|
16695
|
+
} finally {
|
|
16696
|
+
reader.releaseLock();
|
|
16697
|
+
proc.kill();
|
|
16698
|
+
}
|
|
16699
|
+
const exitCode = await proc.exited;
|
|
16700
|
+
const stderr = await new Response(proc.stderr).text();
|
|
16701
|
+
if (exitCode !== 0) {
|
|
16702
|
+
throw new Error(`OpenCode CLI Error: ${stderr || "Unknown error"}`);
|
|
16703
|
+
}
|
|
16704
|
+
if (fullResponse.trim() === "" && stderr.trim().length > 0) {
|
|
16705
|
+
if (stderr.includes("Error") || stderr.includes("NotFound") || stderr.includes("|")) {
|
|
16706
|
+
throw new Error(`OpenCode CLI Silent Crash: ${stderr.split(`
|
|
16707
|
+
`)[0]}`);
|
|
16708
|
+
}
|
|
16709
|
+
}
|
|
16710
|
+
if (fullResponse.trim() === "") {
|
|
16711
|
+
throw new Error("OpenCode CLI returned an empty response");
|
|
16712
|
+
}
|
|
16713
|
+
return {
|
|
16714
|
+
content: fullResponse,
|
|
16715
|
+
model: metadata.model,
|
|
16716
|
+
tokens: metadata.tokens,
|
|
16717
|
+
cost: metadata.cost
|
|
16718
|
+
};
|
|
16719
|
+
}
|
|
16720
|
+
async complete(prompt, options) {
|
|
16721
|
+
const result = await this.chat([{ role: "user", content: prompt }], options);
|
|
16722
|
+
return result.content;
|
|
16723
|
+
}
|
|
16724
|
+
formatMessages(messages) {
|
|
16725
|
+
return messages.map((m) => `<${m.role}>
|
|
16726
|
+
${m.content}
|
|
16727
|
+
</${m.role}>`).join(`
|
|
16728
|
+
|
|
16729
|
+
`);
|
|
16730
|
+
}
|
|
16731
|
+
}
|
|
16732
|
+
|
|
16650
16733
|
// src/core/llm/unified-client.ts
|
|
16651
16734
|
class UnifiedLLMClient {
|
|
16652
16735
|
omoConfig;
|
|
@@ -16658,11 +16741,20 @@ class UnifiedLLMClient {
|
|
|
16658
16741
|
if (!provider) {
|
|
16659
16742
|
throw new Error("\u672A\u627E\u5230\u53EF\u7528\u7684 LLM Provider");
|
|
16660
16743
|
}
|
|
16661
|
-
|
|
16744
|
+
const providerType = provider.type || provider.name;
|
|
16745
|
+
switch (providerType) {
|
|
16662
16746
|
case "anthropic":
|
|
16663
|
-
case "antigravity":
|
|
16664
16747
|
return this.chatAnthropic(provider, messages, options);
|
|
16748
|
+
case "antigravity":
|
|
16749
|
+
return this.chatAntigravity(provider, messages, options);
|
|
16750
|
+
case "google":
|
|
16751
|
+
return this.chatGoogle(provider, messages, options);
|
|
16752
|
+
case "openai":
|
|
16753
|
+
return this.chatOpenAI(provider, messages, options);
|
|
16754
|
+
case "deepseek":
|
|
16755
|
+
return this.chatOpenAI(provider, messages, options, "https://api.deepseek.com/v1");
|
|
16665
16756
|
default:
|
|
16757
|
+
console.warn(`\uD83E\uDDE0 Axon: \u672A\u77E5 provider type '${providerType}'\uFF0C\u4F7F\u7528 Anthropic \u517C\u5BB9\u6A21\u5F0F`);
|
|
16666
16758
|
return this.chatAnthropic(provider, messages, options);
|
|
16667
16759
|
}
|
|
16668
16760
|
}
|
|
@@ -16670,17 +16762,40 @@ class UnifiedLLMClient {
|
|
|
16670
16762
|
const result = await this.chat([{ role: "user", content: prompt }], options);
|
|
16671
16763
|
return result.content;
|
|
16672
16764
|
}
|
|
16765
|
+
cleanModelName(model) {
|
|
16766
|
+
const parts = model.split("/");
|
|
16767
|
+
return parts.length > 1 ? parts.slice(1).join("/") : model;
|
|
16768
|
+
}
|
|
16673
16769
|
async chatAnthropic(provider, messages, options) {
|
|
16674
16770
|
const apiKey = this.omoConfig.getProviderApiKey(provider) || process.env["ANTHROPIC_API_KEY"];
|
|
16675
16771
|
if (!apiKey) {
|
|
16676
16772
|
throw new Error(`\u672A\u627E\u5230 ${provider.name} \u7684 API \u5BC6\u94A5`);
|
|
16677
16773
|
}
|
|
16774
|
+
const model = this.cleanModelName(options?.model || provider.models?.[0] || "claude-sonnet-4-20250514");
|
|
16775
|
+
const client = new AnthropicClient(apiKey, {
|
|
16776
|
+
model,
|
|
16777
|
+
provider: "anthropic",
|
|
16778
|
+
temperature: options?.temperature ?? 0.7,
|
|
16779
|
+
max_tokens: options?.maxTokens || 8000
|
|
16780
|
+
}, provider.endpoint || "https://api.anthropic.com/v1");
|
|
16781
|
+
return this.executeAnthropicChat(client, model, messages, options);
|
|
16782
|
+
}
|
|
16783
|
+
async chatAntigravity(provider, messages, options) {
|
|
16784
|
+
const apiKey = this.omoConfig.getProviderApiKey(provider);
|
|
16785
|
+
if (!apiKey) {
|
|
16786
|
+
throw new Error(`\u672A\u627E\u5230 ${provider.name} \u7684 API \u5BC6\u94A5 (Antigravity token \u6216\u73AF\u5883\u53D8\u91CF\u5747\u672A\u8BBE\u7F6E)`);
|
|
16787
|
+
}
|
|
16788
|
+
const rawModel = options?.model || provider.models?.[0] || "claude-sonnet-4-20250514";
|
|
16789
|
+
const displayModel = this.cleanModelName(rawModel);
|
|
16678
16790
|
const client = new AnthropicClient(apiKey, {
|
|
16679
|
-
model:
|
|
16791
|
+
model: rawModel,
|
|
16680
16792
|
provider: "anthropic",
|
|
16681
16793
|
temperature: options?.temperature ?? 0.7,
|
|
16682
16794
|
max_tokens: options?.maxTokens || 8000
|
|
16683
|
-
}, provider.endpoint);
|
|
16795
|
+
}, provider.endpoint || "https://api.opencode.ai/v1");
|
|
16796
|
+
return this.executeAnthropicChat(client, displayModel, messages, options);
|
|
16797
|
+
}
|
|
16798
|
+
async executeAnthropicChat(client, model, messages, options) {
|
|
16684
16799
|
const systemMessage = messages.find((m) => m.role === "system");
|
|
16685
16800
|
const chatMessages = messages.filter((m) => m.role !== "system").map((m) => ({
|
|
16686
16801
|
role: m.role,
|
|
@@ -16691,12 +16806,120 @@ class UnifiedLLMClient {
|
|
|
16691
16806
|
});
|
|
16692
16807
|
return {
|
|
16693
16808
|
content: response.content,
|
|
16694
|
-
model
|
|
16809
|
+
model,
|
|
16695
16810
|
tokens: {
|
|
16696
16811
|
input: response.usage.input_tokens,
|
|
16697
16812
|
output: response.usage.output_tokens
|
|
16698
16813
|
},
|
|
16699
|
-
cost: this.calculateCost(
|
|
16814
|
+
cost: this.calculateCost(model, response.usage)
|
|
16815
|
+
};
|
|
16816
|
+
}
|
|
16817
|
+
async chatGoogle(provider, messages, options) {
|
|
16818
|
+
const apiKey = this.omoConfig.getProviderApiKey(provider);
|
|
16819
|
+
if (!apiKey) {
|
|
16820
|
+
throw new Error(`\u672A\u627E\u5230 ${provider.name} \u7684 API \u5BC6\u94A5`);
|
|
16821
|
+
}
|
|
16822
|
+
const model = this.cleanModelName(options?.model || provider.models?.[0] || "gemini-2.0-flash");
|
|
16823
|
+
const isAntigravityAuth = this.omoConfig.hasAntigravityAuth() && apiKey === this.omoConfig.getAntigravityToken();
|
|
16824
|
+
if (isAntigravityAuth) {
|
|
16825
|
+
return this.chatAntigravity({
|
|
16826
|
+
...provider,
|
|
16827
|
+
type: "antigravity",
|
|
16828
|
+
endpoint: provider.endpoint || "https://api.opencode.ai/v1"
|
|
16829
|
+
}, messages, options);
|
|
16830
|
+
}
|
|
16831
|
+
const systemMessage = messages.find((m) => m.role === "system");
|
|
16832
|
+
const chatMessages = messages.filter((m) => m.role !== "system").map((m) => ({
|
|
16833
|
+
role: m.role === "assistant" ? "model" : "user",
|
|
16834
|
+
parts: [{ text: m.content }]
|
|
16835
|
+
}));
|
|
16836
|
+
const endpoint = provider.endpoint || "https://generativelanguage.googleapis.com/v1beta";
|
|
16837
|
+
const url = `${endpoint}/models/${model}:generateContent?key=${apiKey}`;
|
|
16838
|
+
const body = {
|
|
16839
|
+
contents: chatMessages,
|
|
16840
|
+
generationConfig: {
|
|
16841
|
+
temperature: options?.temperature ?? 0.7,
|
|
16842
|
+
maxOutputTokens: options?.maxTokens || 8000
|
|
16843
|
+
}
|
|
16844
|
+
};
|
|
16845
|
+
if (systemMessage) {
|
|
16846
|
+
body.systemInstruction = { parts: [{ text: systemMessage.content }] };
|
|
16847
|
+
}
|
|
16848
|
+
const response = await fetch(url, {
|
|
16849
|
+
method: "POST",
|
|
16850
|
+
headers: { "Content-Type": "application/json" },
|
|
16851
|
+
body: JSON.stringify(body)
|
|
16852
|
+
});
|
|
16853
|
+
if (!response.ok) {
|
|
16854
|
+
const errorData = await response.json().catch(() => ({}));
|
|
16855
|
+
throw new Error(`Google API \u8C03\u7528\u5931\u8D25 (${response.status}): ${errorData.error?.message || response.statusText}`);
|
|
16856
|
+
}
|
|
16857
|
+
const data = await response.json();
|
|
16858
|
+
const content = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
|
|
16859
|
+
const usageMetadata = data.usageMetadata || {};
|
|
16860
|
+
return {
|
|
16861
|
+
content,
|
|
16862
|
+
model,
|
|
16863
|
+
tokens: {
|
|
16864
|
+
input: usageMetadata.promptTokenCount || 0,
|
|
16865
|
+
output: usageMetadata.candidatesTokenCount || 0
|
|
16866
|
+
},
|
|
16867
|
+
cost: this.calculateCost(model, {
|
|
16868
|
+
input_tokens: usageMetadata.promptTokenCount || 0,
|
|
16869
|
+
output_tokens: usageMetadata.candidatesTokenCount || 0
|
|
16870
|
+
})
|
|
16871
|
+
};
|
|
16872
|
+
}
|
|
16873
|
+
async chatOpenAI(provider, messages, options, defaultEndpoint = "https://api.openai.com/v1") {
|
|
16874
|
+
const apiKey = this.omoConfig.getProviderApiKey(provider);
|
|
16875
|
+
if (!apiKey) {
|
|
16876
|
+
throw new Error(`\u672A\u627E\u5230 ${provider.name} \u7684 API \u5BC6\u94A5`);
|
|
16877
|
+
}
|
|
16878
|
+
const isAntigravityAuth = this.omoConfig.hasAntigravityAuth() && apiKey === this.omoConfig.getAntigravityToken();
|
|
16879
|
+
if (isAntigravityAuth) {
|
|
16880
|
+
return this.chatAntigravity({
|
|
16881
|
+
...provider,
|
|
16882
|
+
type: "antigravity"
|
|
16883
|
+
}, messages, options);
|
|
16884
|
+
}
|
|
16885
|
+
const model = this.cleanModelName(options?.model || provider.models?.[0] || "gpt-4o");
|
|
16886
|
+
const endpoint = provider.endpoint || defaultEndpoint;
|
|
16887
|
+
const url = `${endpoint}/chat/completions`;
|
|
16888
|
+
const openaiMessages = messages.map((m) => ({
|
|
16889
|
+
role: m.role,
|
|
16890
|
+
content: m.content
|
|
16891
|
+
}));
|
|
16892
|
+
const response = await fetch(url, {
|
|
16893
|
+
method: "POST",
|
|
16894
|
+
headers: {
|
|
16895
|
+
"Content-Type": "application/json",
|
|
16896
|
+
Authorization: `Bearer ${apiKey}`
|
|
16897
|
+
},
|
|
16898
|
+
body: JSON.stringify({
|
|
16899
|
+
model,
|
|
16900
|
+
messages: openaiMessages,
|
|
16901
|
+
temperature: options?.temperature ?? 0.7,
|
|
16902
|
+
max_tokens: options?.maxTokens || 8000
|
|
16903
|
+
})
|
|
16904
|
+
});
|
|
16905
|
+
if (!response.ok) {
|
|
16906
|
+
const errorData = await response.json().catch(() => ({}));
|
|
16907
|
+
throw new Error(`OpenAI API \u8C03\u7528\u5931\u8D25 (${response.status}): ${errorData.error?.message || response.statusText}`);
|
|
16908
|
+
}
|
|
16909
|
+
const data = await response.json();
|
|
16910
|
+
const content = data.choices?.[0]?.message?.content || "";
|
|
16911
|
+
const usage = data.usage || {};
|
|
16912
|
+
return {
|
|
16913
|
+
content,
|
|
16914
|
+
model,
|
|
16915
|
+
tokens: {
|
|
16916
|
+
input: usage.prompt_tokens || 0,
|
|
16917
|
+
output: usage.completion_tokens || 0
|
|
16918
|
+
},
|
|
16919
|
+
cost: this.calculateCost(model, {
|
|
16920
|
+
input_tokens: usage.prompt_tokens || 0,
|
|
16921
|
+
output_tokens: usage.completion_tokens || 0
|
|
16922
|
+
})
|
|
16700
16923
|
};
|
|
16701
16924
|
}
|
|
16702
16925
|
calculateCost(model, usage) {
|
|
@@ -16746,7 +16969,10 @@ class AxonLLMClient {
|
|
|
16746
16969
|
}
|
|
16747
16970
|
} catch {}
|
|
16748
16971
|
if (hasOMOConfig() && this.omoConfig.hasProviders()) {
|
|
16749
|
-
|
|
16972
|
+
const primary = this.omoConfig.getPrimaryProvider();
|
|
16973
|
+
if (primary && this.omoConfig.getProviderApiKey(primary)) {
|
|
16974
|
+
return "direct";
|
|
16975
|
+
}
|
|
16750
16976
|
}
|
|
16751
16977
|
return "fallback";
|
|
16752
16978
|
}
|
|
@@ -16759,18 +16985,32 @@ class AxonLLMClient {
|
|
|
16759
16985
|
this.unifiedClient = new UnifiedLLMClient(this.omoConfig);
|
|
16760
16986
|
break;
|
|
16761
16987
|
case "fallback":
|
|
16762
|
-
|
|
16763
|
-
if (apiKey) {
|
|
16764
|
-
this.anthropicClient = new AnthropicClient(apiKey, {
|
|
16765
|
-
model: "claude-3-5-sonnet-20240620",
|
|
16766
|
-
provider: "anthropic",
|
|
16767
|
-
temperature: 0.7,
|
|
16768
|
-
max_tokens: 4000
|
|
16769
|
-
});
|
|
16770
|
-
}
|
|
16988
|
+
this.initFallbackClient();
|
|
16771
16989
|
break;
|
|
16772
16990
|
}
|
|
16773
16991
|
}
|
|
16992
|
+
initFallbackClient() {
|
|
16993
|
+
const envKeys = [
|
|
16994
|
+
{ key: "ANTHROPIC_API_KEY", model: "claude-sonnet-4-20250514", provider: "anthropic" },
|
|
16995
|
+
{ key: "OPENAI_API_KEY", model: "gpt-4o", provider: "openai" },
|
|
16996
|
+
{ key: "GOOGLE_API_KEY", model: "gemini-2.0-flash", provider: "google" }
|
|
16997
|
+
];
|
|
16998
|
+
for (const { key, model, provider } of envKeys) {
|
|
16999
|
+
const apiKey = process.env[key];
|
|
17000
|
+
if (apiKey) {
|
|
17001
|
+
this.anthropicClient = new AnthropicClient(apiKey, {
|
|
17002
|
+
model,
|
|
17003
|
+
provider,
|
|
17004
|
+
temperature: 0.7,
|
|
17005
|
+
max_tokens: 4000
|
|
17006
|
+
});
|
|
17007
|
+
return;
|
|
17008
|
+
}
|
|
17009
|
+
}
|
|
17010
|
+
if (this.omoConfig.hasProviders() && this.omoConfig.hasAntigravityAuth()) {
|
|
17011
|
+
this.unifiedClient = new UnifiedLLMClient(this.omoConfig);
|
|
17012
|
+
}
|
|
17013
|
+
}
|
|
16774
17014
|
async chat(messages, options) {
|
|
16775
17015
|
try {
|
|
16776
17016
|
if (this.mode === "cli" && this.openCodeClient) {
|
|
@@ -16783,20 +17023,54 @@ class AxonLLMClient {
|
|
|
16783
17023
|
if (this.anthropicClient) {
|
|
16784
17024
|
return await this.chatAnthropicFallback(messages, options);
|
|
16785
17025
|
}
|
|
16786
|
-
|
|
17026
|
+
if (this.unifiedClient) {
|
|
17027
|
+
return await this.unifiedClient.chat(messages, options);
|
|
17028
|
+
}
|
|
17029
|
+
const diagInfo = this.getDiagnosticInfo();
|
|
17030
|
+
throw new APIError(`\u672A\u627E\u5230\u6709\u6548\u7684 LLM \u914D\u7F6E\u6216 API \u5BC6\u94A5 (${diagInfo})`, 401);
|
|
16787
17031
|
}
|
|
16788
17032
|
throw new Error(`\u672A\u652F\u6301\u7684 LLM \u6A21\u5F0F: ${this.mode}`);
|
|
16789
17033
|
} catch (error) {
|
|
16790
|
-
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
17034
|
+
return this.handleChatError(error, messages, options);
|
|
17035
|
+
}
|
|
17036
|
+
}
|
|
17037
|
+
async handleChatError(error, messages, options) {
|
|
17038
|
+
if (this.mode === "cli") {
|
|
17039
|
+
console.warn("\uD83E\uDDE0 Axon: CLI \u6A21\u5F0F\u8C03\u7528\u5931\u8D25\uFF0C\u5C1D\u8BD5 Direct \u6A21\u5F0F...");
|
|
17040
|
+
if (process.env["DEBUG"])
|
|
17041
|
+
console.error(error);
|
|
17042
|
+
if (this.omoConfig.hasProviders()) {
|
|
17043
|
+
const primary = this.omoConfig.getPrimaryProvider();
|
|
17044
|
+
if (primary && this.omoConfig.getProviderApiKey(primary)) {
|
|
17045
|
+
this.mode = "direct";
|
|
17046
|
+
this.initClient();
|
|
17047
|
+
return await this.chat(messages, options);
|
|
17048
|
+
}
|
|
17049
|
+
}
|
|
17050
|
+
console.warn("\uD83E\uDDE0 Axon: Direct \u6A21\u5F0F\u65E0\u53EF\u7528 Provider\uFF0C\u5C1D\u8BD5 Fallback \u6A21\u5F0F...");
|
|
17051
|
+
this.mode = "fallback";
|
|
17052
|
+
this.initClient();
|
|
17053
|
+
return await this.chat(messages, options);
|
|
17054
|
+
}
|
|
17055
|
+
if (this.mode === "direct") {
|
|
17056
|
+
console.warn("\uD83E\uDDE0 Axon: Direct \u6A21\u5F0F\u8C03\u7528\u5931\u8D25\uFF0C\u5C1D\u8BD5 Fallback \u6A21\u5F0F...");
|
|
17057
|
+
if (process.env["DEBUG"])
|
|
17058
|
+
console.error(error);
|
|
17059
|
+
this.mode = "fallback";
|
|
17060
|
+
this.initClient();
|
|
17061
|
+
return await this.chat(messages, options);
|
|
16799
17062
|
}
|
|
17063
|
+
throw error;
|
|
17064
|
+
}
|
|
17065
|
+
getDiagnosticInfo() {
|
|
17066
|
+
return [
|
|
17067
|
+
`\u914D\u7F6E\u6587\u4EF6: ${this.omoConfig.getConfigSource() || "\u672A\u627E\u5230"}`,
|
|
17068
|
+
`Providers: ${this.omoConfig.getAllProviders().length}`,
|
|
17069
|
+
`Antigravity Token: ${this.omoConfig.hasAntigravityAuth() ? "\u5DF2\u627E\u5230" : "\u672A\u627E\u5230"}`,
|
|
17070
|
+
`ANTHROPIC_API_KEY: ${process.env["ANTHROPIC_API_KEY"] ? "\u5DF2\u8BBE\u7F6E" : "\u672A\u8BBE\u7F6E"}`,
|
|
17071
|
+
`OPENAI_API_KEY: ${process.env["OPENAI_API_KEY"] ? "\u5DF2\u8BBE\u7F6E" : "\u672A\u8BBE\u7F6E"}`,
|
|
17072
|
+
`GOOGLE_API_KEY: ${process.env["GOOGLE_API_KEY"] ? "\u5DF2\u8BBE\u7F6E" : "\u672A\u8BBE\u7F6E"}`
|
|
17073
|
+
].join(", ");
|
|
16800
17074
|
}
|
|
16801
17075
|
async chatAnthropicFallback(messages, options) {
|
|
16802
17076
|
if (!this.anthropicClient)
|
|
@@ -16813,7 +17087,7 @@ class AxonLLMClient {
|
|
|
16813
17087
|
});
|
|
16814
17088
|
return {
|
|
16815
17089
|
content: response.content,
|
|
16816
|
-
model: options?.model || "claude-
|
|
17090
|
+
model: options?.model || "claude-sonnet-4-20250514",
|
|
16817
17091
|
tokens: {
|
|
16818
17092
|
input: response.usage.input_tokens,
|
|
16819
17093
|
output: response.usage.output_tokens
|
|
@@ -16845,10 +17119,10 @@ class AxonLLMClient {
|
|
|
16845
17119
|
}
|
|
16846
17120
|
}
|
|
16847
17121
|
var init_llm = __esm(() => {
|
|
17122
|
+
init_errors();
|
|
16848
17123
|
init_anthropic();
|
|
16849
|
-
init_unified_client();
|
|
16850
17124
|
init_omo_config_reader();
|
|
16851
|
-
|
|
17125
|
+
init_unified_client();
|
|
16852
17126
|
});
|
|
16853
17127
|
|
|
16854
17128
|
// node_modules/underscore/underscore-node-f.cjs
|
|
@@ -54081,12 +54355,19 @@ var doctorCommand = new Command("doctor").description(t("Diagnose environment is
|
|
|
54081
54355
|
let apiKey = process.env[envVar];
|
|
54082
54356
|
let source = "environment";
|
|
54083
54357
|
if (!apiKey) {
|
|
54084
|
-
|
|
54358
|
+
let provider = omoReader.getProvider(name);
|
|
54359
|
+
if (!provider) {
|
|
54360
|
+
provider = omoReader.getAllProviders().find((p) => p.type === name) || null;
|
|
54361
|
+
}
|
|
54085
54362
|
if (provider) {
|
|
54086
54363
|
apiKey = omoReader.getProviderApiKey(provider);
|
|
54087
|
-
source =
|
|
54364
|
+
source = `OMO config (${omoReader.getConfigSource()})`;
|
|
54088
54365
|
}
|
|
54089
54366
|
}
|
|
54367
|
+
if (!apiKey && omoReader.hasAntigravityAuth()) {
|
|
54368
|
+
apiKey = omoReader.getAntigravityToken();
|
|
54369
|
+
source = "Antigravity token (~/.config/opencode/antigravity-accounts.json)";
|
|
54370
|
+
}
|
|
54090
54371
|
if (apiKey) {
|
|
54091
54372
|
if (options.checkKeys) {
|
|
54092
54373
|
spinner.start(`\u9A8C\u8BC1 ${name} API \u5BC6\u94A5 (${source})...`);
|
|
@@ -54287,7 +54568,7 @@ configCommand.command("show").description(t("Show current Axon running mode", "\
|
|
|
54287
54568
|
console.log(source_default.cyan(" bunx oh-my-opencode install"));
|
|
54288
54569
|
}
|
|
54289
54570
|
});
|
|
54290
|
-
configCommand.command("test").description(t("Test Provider connection", "\u6D4B\u8BD5 Provider \u8FDE\u63A5")).option("-p, --provider <name>", t("Specify Provider to test", "\u6307\u5B9A Provider \u6D4B\u8BD5")).option("-m, --model <model>", t("Specify model for testing", "\u6307\u5B9A\u6D4B\u8BD5\u4F7F\u7528\u7684\u6A21\u578B")).action(async (options) => {
|
|
54571
|
+
configCommand.command("test").description(t("Test Provider connection", "\u6D4B\u8BD5 Provider \u8FDE\u63A5")).option("-p, --provider <name>", t("Specify Provider to test", "\u6307\u5B9A Provider \u6D4B\u8BD5")).option("-m, --model <model>", t("Specify model for testing", "\u6307\u5B9A\u6D4B\u8BD5\u4F7F\u7528\u7684\u6A21\u578B")).option("--mode <mode>", t("Force specific LLM mode (cli, direct, fallback)", "\u5F3A\u5236\u4F7F\u7528\u7279\u5B9A LLM \u6A21\u5F0F (cli, direct, fallback)")).action(async (options) => {
|
|
54291
54572
|
const spinner2 = ora("\u6B63\u5728\u521D\u59CB\u5316 LLM \u5BA2\u6237\u7AEF...").start();
|
|
54292
54573
|
try {
|
|
54293
54574
|
const omo = new OMOConfigReader;
|
|
@@ -54307,8 +54588,9 @@ configCommand.command("test").description(t("Test Provider connection", "\u6D4B\
|
|
|
54307
54588
|
}
|
|
54308
54589
|
}
|
|
54309
54590
|
const model = options.model || primary?.models?.[0];
|
|
54310
|
-
|
|
54311
|
-
|
|
54591
|
+
const mode = options.mode;
|
|
54592
|
+
spinner2.text = `\u6D4B\u8BD5\u8FDE\u63A5: ${source_default.cyan(providerName)}${model ? ` (\u6A21\u578B: ${source_default.cyan(model)})` : ""}${mode ? ` [\u6A21\u5F0F: ${source_default.cyan(mode)}]` : ""}...`;
|
|
54593
|
+
const client = new AxonLLMClient(mode);
|
|
54312
54594
|
const start = Date.now();
|
|
54313
54595
|
const response = await client.chat([{ role: "user", content: 'Say "OK" if you can hear me.' }], {
|
|
54314
54596
|
model,
|
|
@@ -54508,7 +54790,8 @@ var VERSION = pkg.version;
|
|
|
54508
54790
|
var program2 = new Command;
|
|
54509
54791
|
program2.name("ax").description(`${source_default.green("\uD83E\uDDE0")} ${source_default.bold("Axon")} - AI-Powered Development Operating System (v${VERSION})
|
|
54510
54792
|
|
|
54511
|
-
|
|
54793
|
+
From requirements to code, let AI be your development partner, not a tool.
|
|
54794
|
+
\u4ECE\u9700\u6C42\u5230\u4EE3\u7801\uFF0C\u8BA9 AI \u6210\u4E3A\u4F60\u7684\u5F00\u53D1\u4F19\u4F34\uFF0C\u800C\u975E\u5DE5\u5177\u3002`).version(VERSION, "-v, --version", "Show version").helpOption("-h, --help", "Show help information");
|
|
54512
54795
|
program2.addCommand(initCommand);
|
|
54513
54796
|
program2.addCommand(specCommand);
|
|
54514
54797
|
program2.addCommand(planCommand);
|