agent-phonon 0.2.4 → 0.2.5
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/dist/cli.js +181 -231
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +48 -24
- package/dist/daemon.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -4690,6 +4690,8 @@ var CodexSession = class {
|
|
|
4690
4690
|
this.env = env;
|
|
4691
4691
|
}
|
|
4692
4692
|
providerArgs() {
|
|
4693
|
+
if (!this.env.baseUrl || !this.env.apiKey)
|
|
4694
|
+
return [];
|
|
4693
4695
|
const id = this.env.providerId ?? "phonon_gateway";
|
|
4694
4696
|
const name = this.env.providerName ?? "phonon-gateway";
|
|
4695
4697
|
return [
|
|
@@ -4717,14 +4719,14 @@ var CodexSession = class {
|
|
|
4717
4719
|
|
|
4718
4720
|
${prompt}`;
|
|
4719
4721
|
}
|
|
4720
|
-
const args2 = this.threadId ? ["exec", "resume", this.threadId, "-", "--json", ...this.providerArgs(), "--model", this.model, "--dangerously-bypass-approvals-and-sandbox"] : ["exec", "-", "--json", ...this.providerArgs(), "--model", this.model, "--dangerously-bypass-approvals-and-sandbox"];
|
|
4722
|
+
const args2 = this.threadId ? ["exec", "resume", this.threadId, "-", "--json", ...this.providerArgs(), ...this.model !== "default" ? ["--model", this.model] : [], "--dangerously-bypass-approvals-and-sandbox"] : ["exec", "-", "--json", ...this.providerArgs(), ...this.model !== "default" ? ["--model", this.model] : [], "--dangerously-bypass-approvals-and-sandbox"];
|
|
4721
4723
|
await this.run(args2, prompt, turnId, emit, opts);
|
|
4722
4724
|
}
|
|
4723
4725
|
run(args2, stdin, turnId, emit, opts) {
|
|
4724
4726
|
return new Promise((resolve5) => {
|
|
4725
4727
|
const child = spawn3("codex", args2, {
|
|
4726
4728
|
cwd: this.cwd,
|
|
4727
|
-
env: { ...process.env, ...opts.environment ?? {}, OPENAI_API_KEY: this.env.apiKey }
|
|
4729
|
+
env: { ...process.env, ...opts.environment ?? {}, ...this.env.apiKey ? { OPENAI_API_KEY: this.env.apiKey } : {} }
|
|
4728
4730
|
});
|
|
4729
4731
|
this.current = child;
|
|
4730
4732
|
let buf = "";
|
|
@@ -5489,16 +5491,20 @@ var CAPABILITIES5 = {
|
|
|
5489
5491
|
limits: { maxConcurrentSessions: 4 }
|
|
5490
5492
|
};
|
|
5491
5493
|
function writeSettingsFile(env, model) {
|
|
5494
|
+
if (!env.baseUrl || !env.authToken)
|
|
5495
|
+
return void 0;
|
|
5492
5496
|
const dir = mkdtempSync(join10(tmpdir2(), "phonon-cc-"));
|
|
5493
5497
|
const file = join10(dir, "settings.json");
|
|
5494
5498
|
const content = JSON.stringify({
|
|
5495
5499
|
env: {
|
|
5496
5500
|
ANTHROPIC_BASE_URL: env.baseUrl,
|
|
5497
5501
|
ANTHROPIC_AUTH_TOKEN: env.authToken,
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
+
...model !== "default" ? {
|
|
5503
|
+
ANTHROPIC_MODEL: model,
|
|
5504
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: model,
|
|
5505
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: model,
|
|
5506
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: model
|
|
5507
|
+
} : {},
|
|
5502
5508
|
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
|
5503
5509
|
}
|
|
5504
5510
|
});
|
|
@@ -5551,12 +5557,13 @@ ${prompt}`;
|
|
|
5551
5557
|
// 最高权限:bypassPermissions 跳过所有权限确认;不限定 allowedTools = 所有工具可用
|
|
5552
5558
|
// (phonon 定位:全自动执行,牺牲安全换自动化)
|
|
5553
5559
|
"--permission-mode",
|
|
5554
|
-
"bypassPermissions"
|
|
5555
|
-
"--settings",
|
|
5556
|
-
this.settingsFile(),
|
|
5557
|
-
"--model",
|
|
5558
|
-
this.model
|
|
5560
|
+
"bypassPermissions"
|
|
5559
5561
|
];
|
|
5562
|
+
const settings = this.settingsFile();
|
|
5563
|
+
if (settings)
|
|
5564
|
+
args2.push("--settings", settings);
|
|
5565
|
+
if (this.model !== "default")
|
|
5566
|
+
args2.push("--model", this.model);
|
|
5560
5567
|
if (this.started)
|
|
5561
5568
|
args2.push("--resume", this.uuid);
|
|
5562
5569
|
else
|
|
@@ -6127,6 +6134,166 @@ function readOpenClawGatewayToken() {
|
|
|
6127
6134
|
}
|
|
6128
6135
|
}
|
|
6129
6136
|
|
|
6137
|
+
// src/commands.ts
|
|
6138
|
+
import { spawnSync } from "node:child_process";
|
|
6139
|
+
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync5 } from "node:fs";
|
|
6140
|
+
import { homedir as homedir10 } from "node:os";
|
|
6141
|
+
import { join as join12, dirname as dirname5 } from "node:path";
|
|
6142
|
+
import { fileURLToPath } from "node:url";
|
|
6143
|
+
function probe(bin, args2 = ["--version"]) {
|
|
6144
|
+
const r = spawnSync(bin, args2, { timeout: 8e3 });
|
|
6145
|
+
return { ok: r.status === 0, out: (r.stdout?.toString() ?? "").trim().split("\n")[0] ?? "" };
|
|
6146
|
+
}
|
|
6147
|
+
function gatewayReachable(url) {
|
|
6148
|
+
try {
|
|
6149
|
+
const u = new URL(url.replace(/^ws/, "http"));
|
|
6150
|
+
const r = spawnSync("bash", ["-c", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3e3 });
|
|
6151
|
+
return r.status === 0;
|
|
6152
|
+
} catch {
|
|
6153
|
+
return false;
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6156
|
+
function openCodeBin() {
|
|
6157
|
+
const bundled = join12(homedir10(), ".opencode", "bin", "opencode");
|
|
6158
|
+
return existsSync12(bundled) ? bundled : "opencode";
|
|
6159
|
+
}
|
|
6160
|
+
function autoDetectAdapters(adapters) {
|
|
6161
|
+
const out = [...adapters];
|
|
6162
|
+
const has = (type2) => out.some((a) => a.type === type2);
|
|
6163
|
+
if (!has("hermes") && probe("hermes").ok) out.push({ type: "hermes" });
|
|
6164
|
+
const ocBin = openCodeBin();
|
|
6165
|
+
if (!has("opencode") && probe(ocBin).ok) out.push({ type: "opencode", opencodeBinPath: ocBin === "opencode" ? void 0 : ocBin });
|
|
6166
|
+
if (!has("claude-code") && probe("claude").ok) out.push({ type: "claude-code", claudeDefaultModel: "default" });
|
|
6167
|
+
if (!has("codex") && probe("codex").ok) out.push({ type: "codex", codexDefaultModel: "default" });
|
|
6168
|
+
return out;
|
|
6169
|
+
}
|
|
6170
|
+
function cmdDoctor() {
|
|
6171
|
+
console.log("agent-phonon doctor\n");
|
|
6172
|
+
const gwToken = readOpenClawGatewayToken();
|
|
6173
|
+
const gwUrl = "ws://127.0.0.1:18789";
|
|
6174
|
+
const gwOk = gatewayReachable(gwUrl);
|
|
6175
|
+
console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? "\u2713 reachable" : "\u2717 unreachable"}${gwToken ? " (token found)" : " (no token in ~/.openclaw/openclaw.json)"}`);
|
|
6176
|
+
const pluginDir = join12(homedir10(), ".openclaw", "extensions", "agent-phonon-hitl");
|
|
6177
|
+
console.log(`OpenClaw HITL plugin: ${existsSync12(pluginDir) ? "\u2713 installed" : "\u2717 not installed (run: agent-phonon plugin install openclaw)"}`);
|
|
6178
|
+
console.log("\nCLI agents:");
|
|
6179
|
+
for (const [name, bin] of [["Claude Code", "claude"], ["Codex", "codex"], ["Hermes", "hermes"]]) {
|
|
6180
|
+
const p = probe(bin);
|
|
6181
|
+
console.log(` ${name} (${bin}): ${p.ok ? "\u2713 " + p.out : "\u2717 not found"}`);
|
|
6182
|
+
}
|
|
6183
|
+
const ocBin = openCodeBin();
|
|
6184
|
+
const oc = probe(ocBin);
|
|
6185
|
+
console.log(` OpenCode (${ocBin}): ${oc.ok ? "\u2713 " + oc.out : "\u2717 not found"}`);
|
|
6186
|
+
console.log("");
|
|
6187
|
+
try {
|
|
6188
|
+
const cfg = loadConfig();
|
|
6189
|
+
const effective = autoDetectAdapters(cfg.adapters);
|
|
6190
|
+
console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);
|
|
6191
|
+
} catch {
|
|
6192
|
+
console.log("config: not initialized (run: agent-phonon init)");
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6195
|
+
async function cmdDiscover() {
|
|
6196
|
+
let cfg;
|
|
6197
|
+
try {
|
|
6198
|
+
cfg = loadConfig();
|
|
6199
|
+
} catch {
|
|
6200
|
+
console.error("config not initialized \u2014 run 'agent-phonon init' first");
|
|
6201
|
+
process.exit(1);
|
|
6202
|
+
return;
|
|
6203
|
+
}
|
|
6204
|
+
const reg = buildRegistry(cfg.adapters);
|
|
6205
|
+
const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));
|
|
6206
|
+
const agents = nested.flat();
|
|
6207
|
+
console.log(`discovered ${agents.length} agent(s):
|
|
6208
|
+
`);
|
|
6209
|
+
for (const a of agents) {
|
|
6210
|
+
console.log(` ${a.available ? "\u2713" : "\u2717"} ${a.agentId} (${a.displayName})${a.available ? "" : " \u2014 " + (a.unavailableReason ?? "unavailable")}`);
|
|
6211
|
+
if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(", ")}`);
|
|
6212
|
+
}
|
|
6213
|
+
}
|
|
6214
|
+
function buildRegistry(adapters) {
|
|
6215
|
+
const reg = new AdapterRegistry();
|
|
6216
|
+
for (const a of autoDetectAdapters(adapters)) {
|
|
6217
|
+
if (a.type === "openclaw-gateway") {
|
|
6218
|
+
const token = a.gatewayToken ?? readOpenClawGatewayToken();
|
|
6219
|
+
if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? "ws://127.0.0.1:18789", token }, defaultAgent: a.defaultAgent ?? "main" }));
|
|
6220
|
+
} else if (a.type === "claude-code") {
|
|
6221
|
+
reg.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "default", models: a.claudeModels } }));
|
|
6222
|
+
} else if (a.type === "codex") {
|
|
6223
|
+
reg.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "default", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
|
|
6224
|
+
} else if (a.type === "hermes") {
|
|
6225
|
+
reg.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
|
|
6226
|
+
} else if (a.type === "opencode") {
|
|
6227
|
+
reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));
|
|
6228
|
+
}
|
|
6229
|
+
}
|
|
6230
|
+
return reg;
|
|
6231
|
+
}
|
|
6232
|
+
function cmdAdapterAdd(type2, opts) {
|
|
6233
|
+
const cfg = loadConfig();
|
|
6234
|
+
let a;
|
|
6235
|
+
switch (type2) {
|
|
6236
|
+
case "openclaw":
|
|
6237
|
+
case "openclaw-gateway":
|
|
6238
|
+
a = { type: "openclaw-gateway", gatewayUrl: opts.gatewayUrl ?? "ws://127.0.0.1:18789", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? "main" };
|
|
6239
|
+
break;
|
|
6240
|
+
case "claude-code":
|
|
6241
|
+
a = { type: "claude-code", claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? "default" };
|
|
6242
|
+
break;
|
|
6243
|
+
case "codex":
|
|
6244
|
+
a = { type: "codex", codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? "default", codexWireApi: opts.wireApi ?? "responses" };
|
|
6245
|
+
break;
|
|
6246
|
+
case "hermes":
|
|
6247
|
+
a = { type: "hermes", hermesModel: opts.model, hermesProvider: opts.provider };
|
|
6248
|
+
break;
|
|
6249
|
+
case "opencode":
|
|
6250
|
+
a = { type: "opencode", opencodeBinPath: opts.bin, opencodeModel: opts.model };
|
|
6251
|
+
break;
|
|
6252
|
+
default:
|
|
6253
|
+
return fail(`unknown adapter type: ${type2} (openclaw|claude-code|codex|hermes|opencode)`);
|
|
6254
|
+
}
|
|
6255
|
+
cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);
|
|
6256
|
+
cfg.adapters.push(a);
|
|
6257
|
+
writeConfig(cfg);
|
|
6258
|
+
console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);
|
|
6259
|
+
}
|
|
6260
|
+
function cmdAdapterList() {
|
|
6261
|
+
const cfg = loadConfig();
|
|
6262
|
+
const effective = autoDetectAdapters(cfg.adapters);
|
|
6263
|
+
if (effective.length === 0) {
|
|
6264
|
+
console.log("(no adapters available)");
|
|
6265
|
+
return;
|
|
6266
|
+
}
|
|
6267
|
+
for (const a of effective) {
|
|
6268
|
+
const auto = cfg.adapters.some((x) => x.type === a.type) ? "" : " [auto]";
|
|
6269
|
+
console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : ""}${auto}`);
|
|
6270
|
+
}
|
|
6271
|
+
}
|
|
6272
|
+
function cmdPluginInstall(which) {
|
|
6273
|
+
if (which !== "openclaw") return fail(`plugin install supports: openclaw (got: ${which})`);
|
|
6274
|
+
const here = dirname5(fileURLToPath(import.meta.url));
|
|
6275
|
+
const pluginSrc = join12(here, "..", "..", "openclaw-plugin");
|
|
6276
|
+
if (!existsSync12(join12(pluginSrc, "dist", "index.js"))) {
|
|
6277
|
+
return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);
|
|
6278
|
+
}
|
|
6279
|
+
const dist = join12(homedir10(), ".agent-phonon", "openclaw-plugin-dist");
|
|
6280
|
+
rmSync3(dist, { recursive: true, force: true });
|
|
6281
|
+
mkdirSync4(dist, { recursive: true });
|
|
6282
|
+
cpSync(join12(pluginSrc, "dist"), join12(dist, "dist"), { recursive: true });
|
|
6283
|
+
cpSync(join12(pluginSrc, "openclaw.plugin.json"), join12(dist, "openclaw.plugin.json"));
|
|
6284
|
+
const pkg = JSON.parse(readFileSync5(join12(pluginSrc, "package.json"), "utf8"));
|
|
6285
|
+
delete pkg.devDependencies;
|
|
6286
|
+
writeFileSync4(join12(dist, "package.json"), JSON.stringify(pkg, null, 2));
|
|
6287
|
+
console.log(`exported clean plugin \u2192 ${dist}`);
|
|
6288
|
+
const r = spawnSync("openclaw", ["plugins", "install", "--force", dist], { stdio: "inherit" });
|
|
6289
|
+
if (r.status === 0) console.log("\n\u2713 installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service");
|
|
6290
|
+
else fail("openclaw plugins install failed");
|
|
6291
|
+
}
|
|
6292
|
+
function fail(msg) {
|
|
6293
|
+
console.error("error:", msg);
|
|
6294
|
+
process.exit(1);
|
|
6295
|
+
}
|
|
6296
|
+
|
|
6130
6297
|
// src/obs-server.ts
|
|
6131
6298
|
import { createServer as createServer2 } from "node:http";
|
|
6132
6299
|
var ObsServer = class {
|
|
@@ -6254,7 +6421,7 @@ var PhononDaemon = class {
|
|
|
6254
6421
|
this.registerAdapters();
|
|
6255
6422
|
}
|
|
6256
6423
|
registerAdapters() {
|
|
6257
|
-
for (const a of this.cfg.adapters) {
|
|
6424
|
+
for (const a of autoDetectAdapters(this.cfg.adapters)) {
|
|
6258
6425
|
if (a.type === "openclaw-gateway") {
|
|
6259
6426
|
const token = a.gatewayToken ?? readOpenClawGatewayToken();
|
|
6260
6427
|
if (!token) {
|
|
@@ -6268,17 +6435,9 @@ var PhononDaemon = class {
|
|
|
6268
6435
|
this.gatewayAdapters.push(ad);
|
|
6269
6436
|
this.registry.register(ad);
|
|
6270
6437
|
} else if (a.type === "claude-code") {
|
|
6271
|
-
|
|
6272
|
-
this.registry.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "claude-opus-4.6" } }));
|
|
6273
|
-
} else {
|
|
6274
|
-
console.warn("[daemon] claude-code adapter skipped: need claudeBaseUrl + claudeAuthToken");
|
|
6275
|
-
}
|
|
6438
|
+
this.registry.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "default", models: a.claudeModels } }));
|
|
6276
6439
|
} else if (a.type === "codex") {
|
|
6277
|
-
|
|
6278
|
-
this.registry.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "gpt-5.5", wireApi: a.codexWireApi ?? "responses" } }));
|
|
6279
|
-
} else {
|
|
6280
|
-
console.warn("[daemon] codex adapter skipped: need codexBaseUrl + codexApiKey");
|
|
6281
|
-
}
|
|
6440
|
+
this.registry.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "default", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
|
|
6282
6441
|
} else if (a.type === "hermes") {
|
|
6283
6442
|
this.registry.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
|
|
6284
6443
|
} else if (a.type === "opencode") {
|
|
@@ -6383,215 +6542,6 @@ var PhononDaemon = class {
|
|
|
6383
6542
|
|
|
6384
6543
|
// src/cli.ts
|
|
6385
6544
|
import { existsSync as existsSync13 } from "node:fs";
|
|
6386
|
-
|
|
6387
|
-
// src/commands.ts
|
|
6388
|
-
import { spawnSync } from "node:child_process";
|
|
6389
|
-
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync5 } from "node:fs";
|
|
6390
|
-
import { homedir as homedir10 } from "node:os";
|
|
6391
|
-
import { join as join12, dirname as dirname5 } from "node:path";
|
|
6392
|
-
import { fileURLToPath } from "node:url";
|
|
6393
|
-
function probe(bin, args2 = ["--version"]) {
|
|
6394
|
-
const r = spawnSync(bin, args2, { timeout: 8e3 });
|
|
6395
|
-
return { ok: r.status === 0, out: (r.stdout?.toString() ?? "").trim().split("\n")[0] ?? "" };
|
|
6396
|
-
}
|
|
6397
|
-
function gatewayReachable(url) {
|
|
6398
|
-
try {
|
|
6399
|
-
const u = new URL(url.replace(/^ws/, "http"));
|
|
6400
|
-
const r = spawnSync("bash", ["-c", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3e3 });
|
|
6401
|
-
return r.status === 0;
|
|
6402
|
-
} catch {
|
|
6403
|
-
return false;
|
|
6404
|
-
}
|
|
6405
|
-
}
|
|
6406
|
-
function openCodeBin() {
|
|
6407
|
-
const bundled = join12(homedir10(), ".opencode", "bin", "opencode");
|
|
6408
|
-
return existsSync12(bundled) ? bundled : "opencode";
|
|
6409
|
-
}
|
|
6410
|
-
function modelInfosFromProvider(provider) {
|
|
6411
|
-
const raw = Array.isArray(provider.models) ? provider.models : [];
|
|
6412
|
-
const out = [];
|
|
6413
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6414
|
-
for (const m of raw) {
|
|
6415
|
-
const row = m;
|
|
6416
|
-
const id = typeof row.id === "string" ? row.id : typeof row.key === "string" ? row.key : void 0;
|
|
6417
|
-
if (!id || seen.has(id)) continue;
|
|
6418
|
-
seen.add(id);
|
|
6419
|
-
const contextWindow = typeof row.contextWindow === "number" ? row.contextWindow : typeof row.contextTokens === "number" ? row.contextTokens : void 0;
|
|
6420
|
-
out.push({
|
|
6421
|
-
id,
|
|
6422
|
-
...typeof row.name === "string" ? { displayName: row.name } : {},
|
|
6423
|
-
...contextWindow && contextWindow > 0 ? { contextWindow } : {},
|
|
6424
|
-
available: true
|
|
6425
|
-
});
|
|
6426
|
-
}
|
|
6427
|
-
return out;
|
|
6428
|
-
}
|
|
6429
|
-
function readDefaultLlmGateway() {
|
|
6430
|
-
try {
|
|
6431
|
-
const p = join12(homedir10(), ".openclaw", "openclaw.json");
|
|
6432
|
-
const j = JSON.parse(readFileSync5(p, "utf8"));
|
|
6433
|
-
const provider = j.models?.providers?.["phgeek-gw"];
|
|
6434
|
-
if (provider?.baseUrl && provider?.apiKey) {
|
|
6435
|
-
const models = modelInfosFromProvider(provider);
|
|
6436
|
-
return { baseUrl: provider.baseUrl.replace(/\/$/, ""), apiKey: provider.apiKey, models, claudeModels: models.filter((m) => m.id.toLowerCase().includes("claude")) };
|
|
6437
|
-
}
|
|
6438
|
-
} catch {
|
|
6439
|
-
}
|
|
6440
|
-
const baseUrl = process.env.PHONON_LLM_BASE_URL;
|
|
6441
|
-
const apiKey = process.env.PHONON_LLM_API_KEY;
|
|
6442
|
-
return baseUrl && apiKey ? { baseUrl: baseUrl.replace(/\/$/, ""), apiKey, models: [], claudeModels: [] } : void 0;
|
|
6443
|
-
}
|
|
6444
|
-
function autoDetectAdapters(adapters) {
|
|
6445
|
-
const out = [...adapters];
|
|
6446
|
-
const has = (type2) => out.some((a) => a.type === type2);
|
|
6447
|
-
if (!has("hermes") && probe("hermes").ok) out.push({ type: "hermes" });
|
|
6448
|
-
const ocBin = openCodeBin();
|
|
6449
|
-
if (!has("opencode") && probe(ocBin).ok) out.push({ type: "opencode", opencodeBinPath: ocBin === "opencode" ? void 0 : ocBin });
|
|
6450
|
-
const gw = readDefaultLlmGateway();
|
|
6451
|
-
if (gw) {
|
|
6452
|
-
for (const a of out) {
|
|
6453
|
-
if (a.type === "claude-code" && !a.claudeModels?.length) a.claudeModels = gw.claudeModels;
|
|
6454
|
-
if (a.type === "codex" && !a.codexModels?.length) a.codexModels = gw.models;
|
|
6455
|
-
}
|
|
6456
|
-
if (!has("claude-code") && probe("claude").ok) {
|
|
6457
|
-
out.push({ type: "claude-code", claudeBaseUrl: gw.baseUrl, claudeAuthToken: gw.apiKey, claudeDefaultModel: "claude-opus-4.8", claudeModels: gw.claudeModels });
|
|
6458
|
-
}
|
|
6459
|
-
if (!has("codex") && probe("codex").ok) {
|
|
6460
|
-
out.push({ type: "codex", codexBaseUrl: `${gw.baseUrl}/v1`, codexApiKey: gw.apiKey, codexDefaultModel: "gpt-5.5", codexWireApi: "responses", codexModels: gw.models });
|
|
6461
|
-
}
|
|
6462
|
-
}
|
|
6463
|
-
return out;
|
|
6464
|
-
}
|
|
6465
|
-
function cmdDoctor() {
|
|
6466
|
-
console.log("agent-phonon doctor\n");
|
|
6467
|
-
const gwToken = readOpenClawGatewayToken();
|
|
6468
|
-
const gwUrl = "ws://127.0.0.1:18789";
|
|
6469
|
-
const gwOk = gatewayReachable(gwUrl);
|
|
6470
|
-
console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? "\u2713 reachable" : "\u2717 unreachable"}${gwToken ? " (token found)" : " (no token in ~/.openclaw/openclaw.json)"}`);
|
|
6471
|
-
const pluginDir = join12(homedir10(), ".openclaw", "extensions", "agent-phonon-hitl");
|
|
6472
|
-
console.log(`OpenClaw HITL plugin: ${existsSync12(pluginDir) ? "\u2713 installed" : "\u2717 not installed (run: agent-phonon plugin install openclaw)"}`);
|
|
6473
|
-
console.log("\nCLI agents:");
|
|
6474
|
-
for (const [name, bin] of [["Claude Code", "claude"], ["Codex", "codex"], ["Hermes", "hermes"]]) {
|
|
6475
|
-
const p = probe(bin);
|
|
6476
|
-
console.log(` ${name} (${bin}): ${p.ok ? "\u2713 " + p.out : "\u2717 not found"}`);
|
|
6477
|
-
}
|
|
6478
|
-
const ocBin = openCodeBin();
|
|
6479
|
-
const oc = probe(ocBin);
|
|
6480
|
-
console.log(` OpenCode (${ocBin}): ${oc.ok ? "\u2713 " + oc.out : "\u2717 not found"}`);
|
|
6481
|
-
console.log("");
|
|
6482
|
-
try {
|
|
6483
|
-
const cfg = loadConfig();
|
|
6484
|
-
const effective = autoDetectAdapters(cfg.adapters);
|
|
6485
|
-
console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);
|
|
6486
|
-
} catch {
|
|
6487
|
-
console.log("config: not initialized (run: agent-phonon init)");
|
|
6488
|
-
}
|
|
6489
|
-
}
|
|
6490
|
-
async function cmdDiscover() {
|
|
6491
|
-
let cfg;
|
|
6492
|
-
try {
|
|
6493
|
-
cfg = loadConfig();
|
|
6494
|
-
} catch {
|
|
6495
|
-
console.error("config not initialized \u2014 run 'agent-phonon init' first");
|
|
6496
|
-
process.exit(1);
|
|
6497
|
-
return;
|
|
6498
|
-
}
|
|
6499
|
-
const reg = buildRegistry(cfg.adapters);
|
|
6500
|
-
const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));
|
|
6501
|
-
const agents = nested.flat();
|
|
6502
|
-
console.log(`discovered ${agents.length} agent(s):
|
|
6503
|
-
`);
|
|
6504
|
-
for (const a of agents) {
|
|
6505
|
-
console.log(` ${a.available ? "\u2713" : "\u2717"} ${a.agentId} (${a.displayName})${a.available ? "" : " \u2014 " + (a.unavailableReason ?? "unavailable")}`);
|
|
6506
|
-
if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(", ")}`);
|
|
6507
|
-
}
|
|
6508
|
-
}
|
|
6509
|
-
function buildRegistry(adapters) {
|
|
6510
|
-
const reg = new AdapterRegistry();
|
|
6511
|
-
for (const a of autoDetectAdapters(adapters)) {
|
|
6512
|
-
if (a.type === "openclaw-gateway") {
|
|
6513
|
-
const token = a.gatewayToken ?? readOpenClawGatewayToken();
|
|
6514
|
-
if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? "ws://127.0.0.1:18789", token }, defaultAgent: a.defaultAgent ?? "main" }));
|
|
6515
|
-
} else if (a.type === "claude-code" && a.claudeBaseUrl && a.claudeAuthToken) {
|
|
6516
|
-
reg.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "claude-opus-4.6", models: a.claudeModels } }));
|
|
6517
|
-
} else if (a.type === "codex" && a.codexBaseUrl && a.codexApiKey) {
|
|
6518
|
-
reg.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "gpt-5.5", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
|
|
6519
|
-
} else if (a.type === "hermes") {
|
|
6520
|
-
reg.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
|
|
6521
|
-
} else if (a.type === "opencode") {
|
|
6522
|
-
reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));
|
|
6523
|
-
}
|
|
6524
|
-
}
|
|
6525
|
-
return reg;
|
|
6526
|
-
}
|
|
6527
|
-
function cmdAdapterAdd(type2, opts) {
|
|
6528
|
-
const cfg = loadConfig();
|
|
6529
|
-
let a;
|
|
6530
|
-
switch (type2) {
|
|
6531
|
-
case "openclaw":
|
|
6532
|
-
case "openclaw-gateway":
|
|
6533
|
-
a = { type: "openclaw-gateway", gatewayUrl: opts.gatewayUrl ?? "ws://127.0.0.1:18789", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? "main" };
|
|
6534
|
-
break;
|
|
6535
|
-
case "claude-code":
|
|
6536
|
-
if (!opts.baseUrl || !opts.token) return fail("claude-code needs --base-url and --token");
|
|
6537
|
-
a = { type: "claude-code", claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? "claude-opus-4.6" };
|
|
6538
|
-
break;
|
|
6539
|
-
case "codex":
|
|
6540
|
-
if (!opts.baseUrl || !opts.apiKey) return fail("codex needs --base-url and --api-key");
|
|
6541
|
-
a = { type: "codex", codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? "gpt-5.5", codexWireApi: opts.wireApi ?? "responses" };
|
|
6542
|
-
break;
|
|
6543
|
-
case "hermes":
|
|
6544
|
-
a = { type: "hermes", hermesModel: opts.model, hermesProvider: opts.provider };
|
|
6545
|
-
break;
|
|
6546
|
-
case "opencode":
|
|
6547
|
-
a = { type: "opencode", opencodeBinPath: opts.bin, opencodeModel: opts.model };
|
|
6548
|
-
break;
|
|
6549
|
-
default:
|
|
6550
|
-
return fail(`unknown adapter type: ${type2} (openclaw|claude-code|codex|hermes|opencode)`);
|
|
6551
|
-
}
|
|
6552
|
-
cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);
|
|
6553
|
-
cfg.adapters.push(a);
|
|
6554
|
-
writeConfig(cfg);
|
|
6555
|
-
console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);
|
|
6556
|
-
}
|
|
6557
|
-
function cmdAdapterList() {
|
|
6558
|
-
const cfg = loadConfig();
|
|
6559
|
-
const effective = autoDetectAdapters(cfg.adapters);
|
|
6560
|
-
if (effective.length === 0) {
|
|
6561
|
-
console.log("(no adapters available)");
|
|
6562
|
-
return;
|
|
6563
|
-
}
|
|
6564
|
-
for (const a of effective) {
|
|
6565
|
-
const auto = cfg.adapters.some((x) => x.type === a.type) ? "" : " [auto]";
|
|
6566
|
-
console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : ""}${auto}`);
|
|
6567
|
-
}
|
|
6568
|
-
}
|
|
6569
|
-
function cmdPluginInstall(which) {
|
|
6570
|
-
if (which !== "openclaw") return fail(`plugin install supports: openclaw (got: ${which})`);
|
|
6571
|
-
const here = dirname5(fileURLToPath(import.meta.url));
|
|
6572
|
-
const pluginSrc = join12(here, "..", "..", "openclaw-plugin");
|
|
6573
|
-
if (!existsSync12(join12(pluginSrc, "dist", "index.js"))) {
|
|
6574
|
-
return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);
|
|
6575
|
-
}
|
|
6576
|
-
const dist = join12(homedir10(), ".agent-phonon", "openclaw-plugin-dist");
|
|
6577
|
-
rmSync3(dist, { recursive: true, force: true });
|
|
6578
|
-
mkdirSync4(dist, { recursive: true });
|
|
6579
|
-
cpSync(join12(pluginSrc, "dist"), join12(dist, "dist"), { recursive: true });
|
|
6580
|
-
cpSync(join12(pluginSrc, "openclaw.plugin.json"), join12(dist, "openclaw.plugin.json"));
|
|
6581
|
-
const pkg = JSON.parse(readFileSync5(join12(pluginSrc, "package.json"), "utf8"));
|
|
6582
|
-
delete pkg.devDependencies;
|
|
6583
|
-
writeFileSync4(join12(dist, "package.json"), JSON.stringify(pkg, null, 2));
|
|
6584
|
-
console.log(`exported clean plugin \u2192 ${dist}`);
|
|
6585
|
-
const r = spawnSync("openclaw", ["plugins", "install", "--force", dist], { stdio: "inherit" });
|
|
6586
|
-
if (r.status === 0) console.log("\n\u2713 installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service");
|
|
6587
|
-
else fail("openclaw plugins install failed");
|
|
6588
|
-
}
|
|
6589
|
-
function fail(msg) {
|
|
6590
|
-
console.error("error:", msg);
|
|
6591
|
-
process.exit(1);
|
|
6592
|
-
}
|
|
6593
|
-
|
|
6594
|
-
// src/cli.ts
|
|
6595
6545
|
var [cmd, ...args] = process.argv.slice(2);
|
|
6596
6546
|
function flag(name) {
|
|
6597
6547
|
return args.includes(`--${name}`);
|