agent-phonon 0.2.9 → 0.2.11
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 +298 -61
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +222 -59
- package/dist/daemon.js.map +1 -1
- package/package.json +2 -2
package/dist/daemon.js
CHANGED
|
@@ -1724,12 +1724,12 @@ var init_rpc = __esm({
|
|
|
1724
1724
|
requestRaw(method, params, timeoutMs = 12e4) {
|
|
1725
1725
|
const id = this.nextId++;
|
|
1726
1726
|
const msg = { jsonrpc: "2.0", id, method, params };
|
|
1727
|
-
return new Promise((
|
|
1727
|
+
return new Promise((resolve6, reject) => {
|
|
1728
1728
|
const timer = timeoutMs > 0 ? setTimeout(() => {
|
|
1729
1729
|
this.pending.delete(id);
|
|
1730
1730
|
reject(new PhononError("errInternal", `RPC timeout: ${method}`));
|
|
1731
1731
|
}, timeoutMs) : void 0;
|
|
1732
|
-
this.pending.set(id, { resolve:
|
|
1732
|
+
this.pending.set(id, { resolve: resolve6, reject, timer });
|
|
1733
1733
|
this.transport.send(JSON.stringify(msg));
|
|
1734
1734
|
});
|
|
1735
1735
|
}
|
|
@@ -2185,8 +2185,8 @@ var SessionEngine = class {
|
|
|
2185
2185
|
this.interactionWaiters.delete(requestId);
|
|
2186
2186
|
}
|
|
2187
2187
|
}
|
|
2188
|
-
registerInteractionWaiter(requestId,
|
|
2189
|
-
this.interactionWaiters.set(requestId,
|
|
2188
|
+
registerInteractionWaiter(requestId, resolve6) {
|
|
2189
|
+
this.interactionWaiters.set(requestId, resolve6);
|
|
2190
2190
|
}
|
|
2191
2191
|
list(tenantId, filter) {
|
|
2192
2192
|
const all = [];
|
|
@@ -3761,7 +3761,7 @@ ${message}`;
|
|
|
3761
3761
|
return void 0;
|
|
3762
3762
|
}
|
|
3763
3763
|
run(args, signal, environment) {
|
|
3764
|
-
return new Promise((
|
|
3764
|
+
return new Promise((resolve6, reject) => {
|
|
3765
3765
|
const child = spawn2("openclaw", args, { cwd: this.cwd, env: { ...process.env, ...environment ?? {} } });
|
|
3766
3766
|
this.current = child;
|
|
3767
3767
|
let out = "";
|
|
@@ -3779,9 +3779,9 @@ ${message}`;
|
|
|
3779
3779
|
signal?.removeEventListener("abort", onAbort);
|
|
3780
3780
|
this.current = void 0;
|
|
3781
3781
|
if (killed)
|
|
3782
|
-
return
|
|
3782
|
+
return resolve6(null);
|
|
3783
3783
|
if (code === 0)
|
|
3784
|
-
|
|
3784
|
+
resolve6(out);
|
|
3785
3785
|
else
|
|
3786
3786
|
reject(new Error(`openclaw exited ${code}: ${err.slice(0, 500)}`));
|
|
3787
3787
|
});
|
|
@@ -3833,12 +3833,12 @@ var OpenClawAdapter = class {
|
|
|
3833
3833
|
return new OpenClawSession(params.sessionId, params.model, params.cwd, openclawAgent);
|
|
3834
3834
|
}
|
|
3835
3835
|
probeVersion() {
|
|
3836
|
-
return new Promise((
|
|
3836
|
+
return new Promise((resolve6) => {
|
|
3837
3837
|
const child = spawn2("openclaw", ["--version"]);
|
|
3838
3838
|
let out = "";
|
|
3839
3839
|
child.stdout.on("data", (d) => out += d.toString());
|
|
3840
|
-
child.on("error", () =>
|
|
3841
|
-
child.on("close", (code) =>
|
|
3840
|
+
child.on("error", () => resolve6(null));
|
|
3841
|
+
child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
|
|
3842
3842
|
});
|
|
3843
3843
|
}
|
|
3844
3844
|
};
|
|
@@ -3871,7 +3871,7 @@ var GatewayClient = class {
|
|
|
3871
3871
|
return this.connectPromise;
|
|
3872
3872
|
}
|
|
3873
3873
|
doConnect() {
|
|
3874
|
-
return new Promise((
|
|
3874
|
+
return new Promise((resolve6, reject) => {
|
|
3875
3875
|
const wsUrl = this.config.baseUrl.replace(/^http/, "ws");
|
|
3876
3876
|
const ws = new WebSocket(wsUrl);
|
|
3877
3877
|
this.ws = ws;
|
|
@@ -3902,7 +3902,7 @@ var GatewayClient = class {
|
|
|
3902
3902
|
} else if (frame.type === "res" && frame.ok && frame.payload?.type === "hello-ok") {
|
|
3903
3903
|
handshakeDone = true;
|
|
3904
3904
|
this.connected = true;
|
|
3905
|
-
|
|
3905
|
+
resolve6();
|
|
3906
3906
|
} else if (frame.type === "res" && !frame.ok) {
|
|
3907
3907
|
reject(new Error(`handshake failed: ${JSON.stringify(frame.error)}`));
|
|
3908
3908
|
}
|
|
@@ -3948,13 +3948,13 @@ var GatewayClient = class {
|
|
|
3948
3948
|
async rpc(method, params, timeoutMs = 12e4) {
|
|
3949
3949
|
if (!this.connected)
|
|
3950
3950
|
await this.connect();
|
|
3951
|
-
return new Promise((
|
|
3951
|
+
return new Promise((resolve6, reject) => {
|
|
3952
3952
|
const id = randomUUID();
|
|
3953
3953
|
const timer = setTimeout(() => {
|
|
3954
3954
|
this.pending.delete(id);
|
|
3955
3955
|
reject(new Error(`RPC timeout: ${method}`));
|
|
3956
3956
|
}, timeoutMs);
|
|
3957
|
-
this.pending.set(id, { resolve:
|
|
3957
|
+
this.pending.set(id, { resolve: resolve6, reject, timer });
|
|
3958
3958
|
this.ws.send(JSON.stringify({ type: "req", id, method, params }));
|
|
3959
3959
|
});
|
|
3960
3960
|
}
|
|
@@ -4081,14 +4081,14 @@ var GatewaySession = class {
|
|
|
4081
4081
|
|
|
4082
4082
|
${input}`;
|
|
4083
4083
|
}
|
|
4084
|
-
await new Promise((
|
|
4084
|
+
await new Promise((resolve6) => {
|
|
4085
4085
|
let settled = false;
|
|
4086
4086
|
const finish = () => {
|
|
4087
4087
|
if (settled)
|
|
4088
4088
|
return;
|
|
4089
4089
|
settled = true;
|
|
4090
4090
|
clearTimeout(guard);
|
|
4091
|
-
|
|
4091
|
+
resolve6();
|
|
4092
4092
|
};
|
|
4093
4093
|
this.activeTurn = { turnId, emit, verbosity: opts.verbosity, done: finish, acc: "" };
|
|
4094
4094
|
this.gw.rpc("chat.send", {
|
|
@@ -4349,7 +4349,7 @@ var PhononClient = class {
|
|
|
4349
4349
|
}
|
|
4350
4350
|
/** 连接并完成握手,resolve 后即可接收 server 的 session.* 下发。 */
|
|
4351
4351
|
connect() {
|
|
4352
|
-
return new Promise((
|
|
4352
|
+
return new Promise((resolve6, reject) => {
|
|
4353
4353
|
const ws = new WebSocket2(this.serverUrl);
|
|
4354
4354
|
this.ws = ws;
|
|
4355
4355
|
const transport = {
|
|
@@ -4391,7 +4391,7 @@ var PhononClient = class {
|
|
|
4391
4391
|
if (wAck && wAck.length > 0) {
|
|
4392
4392
|
conn.replayPending(wAck.map((a) => ({ sessionId: a.sessionId, fromSeq: a.lastSeq })));
|
|
4393
4393
|
}
|
|
4394
|
-
|
|
4394
|
+
resolve6({ tenantId: welcome.tenantId });
|
|
4395
4395
|
} catch (err) {
|
|
4396
4396
|
reject(err);
|
|
4397
4397
|
}
|
|
@@ -4461,12 +4461,12 @@ var HookBridge = class {
|
|
|
4461
4461
|
this.token = opts?.token;
|
|
4462
4462
|
}
|
|
4463
4463
|
listen(port = 4318, host = "127.0.0.1") {
|
|
4464
|
-
return new Promise((
|
|
4464
|
+
return new Promise((resolve6) => {
|
|
4465
4465
|
const server = createServer((req, res) => this.onRequest(req, res));
|
|
4466
4466
|
this.server = server;
|
|
4467
4467
|
server.listen(port, host, () => {
|
|
4468
4468
|
const addr = server.address();
|
|
4469
|
-
|
|
4469
|
+
resolve6(typeof addr === "object" && addr ? addr.port : port);
|
|
4470
4470
|
});
|
|
4471
4471
|
});
|
|
4472
4472
|
}
|
|
@@ -4519,10 +4519,10 @@ var HookBridge = class {
|
|
|
4519
4519
|
});
|
|
4520
4520
|
}
|
|
4521
4521
|
close() {
|
|
4522
|
-
return new Promise((
|
|
4522
|
+
return new Promise((resolve6) => {
|
|
4523
4523
|
if (!this.server)
|
|
4524
|
-
return
|
|
4525
|
-
this.server.close(() =>
|
|
4524
|
+
return resolve6();
|
|
4525
|
+
this.server.close(() => resolve6());
|
|
4526
4526
|
});
|
|
4527
4527
|
}
|
|
4528
4528
|
};
|
|
@@ -4623,7 +4623,12 @@ function fileSize(p) {
|
|
|
4623
4623
|
import { spawn as spawn3 } from "node:child_process";
|
|
4624
4624
|
import { homedir as homedir5 } from "node:os";
|
|
4625
4625
|
import { join as join7 } from "node:path";
|
|
4626
|
-
import { existsSync as existsSync7, readdirSync, statSync as statSync2 } from "node:fs";
|
|
4626
|
+
import { existsSync as existsSync7, readdirSync, statSync as statSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
4627
|
+
var CODEX_FALLBACK_MODELS = [
|
|
4628
|
+
{ id: "gpt-5.5", available: true },
|
|
4629
|
+
{ id: "gpt-5.4", available: true },
|
|
4630
|
+
{ id: "gpt-5.3-codex", available: true }
|
|
4631
|
+
];
|
|
4627
4632
|
var CAPABILITIES2 = {
|
|
4628
4633
|
nativeSession: true,
|
|
4629
4634
|
// exec resume <thread_id>
|
|
@@ -4673,6 +4678,60 @@ function resolveCodexSessionFile(threadId, codexHome = join7(homedir5(), ".codex
|
|
|
4673
4678
|
hits.sort((a, b) => b.mtime - a.mtime);
|
|
4674
4679
|
return hits[0].path;
|
|
4675
4680
|
}
|
|
4681
|
+
function parseCodexConfig(configPath = join7(homedir5(), ".codex", "config.toml")) {
|
|
4682
|
+
if (!existsSync7(configPath))
|
|
4683
|
+
return {};
|
|
4684
|
+
const text = readFileSync4(configPath, "utf8");
|
|
4685
|
+
const model = text.match(/^model\s*=\s*"([^"]+)"/m)?.[1];
|
|
4686
|
+
const providerId = text.match(/^model_provider\s*=\s*"([^"]+)"/m)?.[1];
|
|
4687
|
+
let baseUrl;
|
|
4688
|
+
if (providerId) {
|
|
4689
|
+
const escaped = providerId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4690
|
+
const section = text.match(new RegExp(`\\[model_providers\\.${escaped}\\]([\\s\\S]*?)(?:\\n\\[|$)`))?.[1];
|
|
4691
|
+
baseUrl = section?.match(/^base_url\s*=\s*"([^"]+)"/m)?.[1];
|
|
4692
|
+
}
|
|
4693
|
+
return { model, providerId, baseUrl };
|
|
4694
|
+
}
|
|
4695
|
+
function normalizeOpenAiModels(data) {
|
|
4696
|
+
const rows = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : [];
|
|
4697
|
+
const out = [];
|
|
4698
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4699
|
+
for (const row of rows) {
|
|
4700
|
+
const obj = row;
|
|
4701
|
+
const id = typeof obj.id === "string" ? obj.id : void 0;
|
|
4702
|
+
if (!id || seen.has(id))
|
|
4703
|
+
continue;
|
|
4704
|
+
seen.add(id);
|
|
4705
|
+
out.push({ id, ...typeof obj.name === "string" ? { displayName: obj.name } : {}, available: true });
|
|
4706
|
+
}
|
|
4707
|
+
return out;
|
|
4708
|
+
}
|
|
4709
|
+
function fetchJson(url, headers) {
|
|
4710
|
+
return new Promise((resolve6, reject) => {
|
|
4711
|
+
const u = new URL(url);
|
|
4712
|
+
const req = (u.protocol === "http:" ? import("node:http") : import("node:https")).then((mod) => mod.request(url, { method: "GET", headers, timeout: 5e3 }, (res) => {
|
|
4713
|
+
let body = "";
|
|
4714
|
+
res.setEncoding("utf8");
|
|
4715
|
+
res.on("data", (d) => body += d);
|
|
4716
|
+
res.on("end", () => {
|
|
4717
|
+
if ((res.statusCode ?? 500) < 200 || (res.statusCode ?? 500) >= 300) {
|
|
4718
|
+
reject(new Error(`GET ${url} failed: ${res.statusCode}`));
|
|
4719
|
+
return;
|
|
4720
|
+
}
|
|
4721
|
+
try {
|
|
4722
|
+
resolve6(JSON.parse(body));
|
|
4723
|
+
} catch (e) {
|
|
4724
|
+
reject(e);
|
|
4725
|
+
}
|
|
4726
|
+
});
|
|
4727
|
+
}));
|
|
4728
|
+
req.then((r) => {
|
|
4729
|
+
r.on("timeout", () => r.destroy(new Error(`GET ${url} timeout`)));
|
|
4730
|
+
r.on("error", reject);
|
|
4731
|
+
r.end();
|
|
4732
|
+
}, reject);
|
|
4733
|
+
});
|
|
4734
|
+
}
|
|
4676
4735
|
var CodexSession = class {
|
|
4677
4736
|
sessionId;
|
|
4678
4737
|
model;
|
|
@@ -4722,7 +4781,7 @@ ${prompt}`;
|
|
|
4722
4781
|
await this.run(args, prompt, turnId, emit, opts);
|
|
4723
4782
|
}
|
|
4724
4783
|
run(args, stdin, turnId, emit, opts) {
|
|
4725
|
-
return new Promise((
|
|
4784
|
+
return new Promise((resolve6) => {
|
|
4726
4785
|
const child = spawn3(this.env.binPath ?? "codex", args, {
|
|
4727
4786
|
cwd: this.cwd,
|
|
4728
4787
|
shell: process.platform === "win32",
|
|
@@ -4743,7 +4802,7 @@ ${prompt}`;
|
|
|
4743
4802
|
} else {
|
|
4744
4803
|
emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
|
|
4745
4804
|
}
|
|
4746
|
-
|
|
4805
|
+
resolve6();
|
|
4747
4806
|
};
|
|
4748
4807
|
const guard = setTimeout(() => finish("timeout", acc), 18e5);
|
|
4749
4808
|
opts.signal?.addEventListener("abort", () => {
|
|
@@ -4836,6 +4895,7 @@ var CodexAdapter = class {
|
|
|
4836
4895
|
async discoverAgents() {
|
|
4837
4896
|
const version = await this.probeVersion();
|
|
4838
4897
|
const available = version !== null;
|
|
4898
|
+
const models = await this.discoverModels();
|
|
4839
4899
|
return [{
|
|
4840
4900
|
agentId: "codex",
|
|
4841
4901
|
displayName: "Codex",
|
|
@@ -4843,7 +4903,7 @@ var CodexAdapter = class {
|
|
|
4843
4903
|
available,
|
|
4844
4904
|
...available ? {} : { unavailableReason: "codex CLI not found" },
|
|
4845
4905
|
...version ? { version } : {},
|
|
4846
|
-
models
|
|
4906
|
+
models,
|
|
4847
4907
|
capabilities: CAPABILITIES2,
|
|
4848
4908
|
scannedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4849
4909
|
}];
|
|
@@ -4851,13 +4911,35 @@ var CodexAdapter = class {
|
|
|
4851
4911
|
async createSession(params) {
|
|
4852
4912
|
return new CodexSession(params.sessionId, params.model, params.cwd, this.env);
|
|
4853
4913
|
}
|
|
4914
|
+
async discoverModels() {
|
|
4915
|
+
if (this.env.models?.length)
|
|
4916
|
+
return this.env.models;
|
|
4917
|
+
const cfg = parseCodexConfig();
|
|
4918
|
+
const baseUrl = this.env.baseUrl ?? cfg.baseUrl;
|
|
4919
|
+
if (baseUrl) {
|
|
4920
|
+
try {
|
|
4921
|
+
const data = await fetchJson(`${baseUrl.replace(/\/$/, "")}/models`, this.env.apiKey ? { Authorization: `Bearer ${this.env.apiKey}` } : void 0);
|
|
4922
|
+
const models = normalizeOpenAiModels(data);
|
|
4923
|
+
if (models.length > 0)
|
|
4924
|
+
return models;
|
|
4925
|
+
} catch {
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
const configured = this.env.defaultModel !== "default" ? this.env.defaultModel : cfg.model;
|
|
4929
|
+
const base = configured ? [{ id: configured, available: true }] : [];
|
|
4930
|
+
const seen = new Set(base.map((m) => m.id));
|
|
4931
|
+
for (const m of CODEX_FALLBACK_MODELS)
|
|
4932
|
+
if (!seen.has(m.id))
|
|
4933
|
+
base.push(m);
|
|
4934
|
+
return base.length > 0 ? base : CODEX_FALLBACK_MODELS;
|
|
4935
|
+
}
|
|
4854
4936
|
probeVersion() {
|
|
4855
|
-
return new Promise((
|
|
4937
|
+
return new Promise((resolve6) => {
|
|
4856
4938
|
const child = spawn3(this.env.binPath ?? "codex", ["--version"], { shell: process.platform === "win32" });
|
|
4857
4939
|
let out = "";
|
|
4858
4940
|
child.stdout.on("data", (d) => out += d.toString());
|
|
4859
|
-
child.on("error", () =>
|
|
4860
|
-
child.on("close", (code) =>
|
|
4941
|
+
child.on("error", () => resolve6(null));
|
|
4942
|
+
child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
|
|
4861
4943
|
});
|
|
4862
4944
|
}
|
|
4863
4945
|
};
|
|
@@ -4933,7 +5015,7 @@ ${message}`;
|
|
|
4933
5015
|
await this.run(args, turnId, emit, opts);
|
|
4934
5016
|
}
|
|
4935
5017
|
run(args, turnId, emit, opts) {
|
|
4936
|
-
return new Promise((
|
|
5018
|
+
return new Promise((resolve6) => {
|
|
4937
5019
|
const child = spawn4(this.bin, args, { cwd: this.cwd, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, ...opts.environment ?? {} } });
|
|
4938
5020
|
this.current = child;
|
|
4939
5021
|
let buf = "";
|
|
@@ -4950,7 +5032,7 @@ ${message}`;
|
|
|
4950
5032
|
} else {
|
|
4951
5033
|
emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
|
|
4952
5034
|
}
|
|
4953
|
-
|
|
5035
|
+
resolve6();
|
|
4954
5036
|
};
|
|
4955
5037
|
const guard = setTimeout(() => finish("timeout", acc), 18e5);
|
|
4956
5038
|
opts.signal?.addEventListener("abort", () => {
|
|
@@ -5081,12 +5163,12 @@ var OpenCodeAdapter = class {
|
|
|
5081
5163
|
return new OpenCodeSession(params.sessionId, model, params.cwd, this.bin);
|
|
5082
5164
|
}
|
|
5083
5165
|
probeVersion() {
|
|
5084
|
-
return new Promise((
|
|
5166
|
+
return new Promise((resolve6) => {
|
|
5085
5167
|
const child = spawn4(this.bin, ["--version"]);
|
|
5086
5168
|
let out = "";
|
|
5087
5169
|
child.stdout.on("data", (d) => out += d.toString());
|
|
5088
|
-
child.on("error", () =>
|
|
5089
|
-
child.on("close", (code) =>
|
|
5170
|
+
child.on("error", () => resolve6(null));
|
|
5171
|
+
child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
|
|
5090
5172
|
});
|
|
5091
5173
|
}
|
|
5092
5174
|
};
|
|
@@ -5097,7 +5179,29 @@ import { randomUUID as randomUUID3 } from "node:crypto";
|
|
|
5097
5179
|
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
5098
5180
|
import { homedir as homedir7 } from "node:os";
|
|
5099
5181
|
import { join as join9 } from "node:path";
|
|
5100
|
-
import { existsSync as existsSync9 } from "node:fs";
|
|
5182
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
5183
|
+
var HERMES_PROVIDER_FALLBACK_MODELS = {
|
|
5184
|
+
// Hermes' built-in Copilot picker exposes these account/integrator-safe model ids.
|
|
5185
|
+
copilot: [
|
|
5186
|
+
"gpt-5.4",
|
|
5187
|
+
"gpt-5.4-mini",
|
|
5188
|
+
"gpt-5-mini",
|
|
5189
|
+
"gpt-5.3-codex",
|
|
5190
|
+
"gpt-5.2-codex",
|
|
5191
|
+
"gpt-4.1",
|
|
5192
|
+
"gpt-4o",
|
|
5193
|
+
"gpt-4o-mini",
|
|
5194
|
+
"claude-sonnet-4.6",
|
|
5195
|
+
"claude-sonnet-4",
|
|
5196
|
+
"claude-sonnet-4.5",
|
|
5197
|
+
"claude-haiku-4.5",
|
|
5198
|
+
"gemini-3.1-pro-preview",
|
|
5199
|
+
"gemini-3-pro-preview",
|
|
5200
|
+
"gemini-3-flash-preview",
|
|
5201
|
+
"gemini-2.5-pro"
|
|
5202
|
+
],
|
|
5203
|
+
zai: ["glm-4.5", "glm-4.5-air", "glm-4.6", "glm-4.7", "glm-5", "glm-5-turbo", "glm-5.1", "glm-5.2"]
|
|
5204
|
+
};
|
|
5101
5205
|
var CAPABILITIES4 = {
|
|
5102
5206
|
nativeSession: true,
|
|
5103
5207
|
// --resume / --pass-session-id
|
|
@@ -5117,6 +5221,49 @@ var CAPABILITIES4 = {
|
|
|
5117
5221
|
// -z 是纯文本一次性输出,非流式 → 用 final 事件
|
|
5118
5222
|
limits: { maxConcurrentSessions: 4 }
|
|
5119
5223
|
};
|
|
5224
|
+
function parseHermesConfig(configPath = join9(homedir7(), ".hermes", "config.yaml")) {
|
|
5225
|
+
if (!existsSync9(configPath))
|
|
5226
|
+
return {};
|
|
5227
|
+
const text = readFileSync5(configPath, "utf8");
|
|
5228
|
+
const modelBlock = text.match(/(?:^|\n)model:\n([\s\S]*?)(?:\n[A-Za-z_][A-Za-z0-9_-]*:|$)/)?.[1] ?? "";
|
|
5229
|
+
const defaultModel = modelBlock.match(/^\s+default:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5230
|
+
const provider = modelBlock.match(/^\s+provider:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5231
|
+
const catalogBlock = text.match(/(?:^|\n)model_catalog:\n([\s\S]*?)(?:\n[A-Za-z_][A-Za-z0-9_-]*:|$)/)?.[1] ?? "";
|
|
5232
|
+
const catalogUrl = catalogBlock.match(/^\s+url:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5233
|
+
return { defaultModel, provider, catalogUrl };
|
|
5234
|
+
}
|
|
5235
|
+
function fetchHermesCatalogModels(url, provider) {
|
|
5236
|
+
return new Promise((resolve6) => {
|
|
5237
|
+
const u = new URL(url);
|
|
5238
|
+
const reqMod = u.protocol === "http:" ? import("node:http") : import("node:https");
|
|
5239
|
+
reqMod.then((mod) => {
|
|
5240
|
+
const req = mod.request(url, { method: "GET", timeout: 5e3 }, (res) => {
|
|
5241
|
+
let body = "";
|
|
5242
|
+
res.setEncoding("utf8");
|
|
5243
|
+
res.on("data", (d) => body += d);
|
|
5244
|
+
res.on("end", () => {
|
|
5245
|
+
try {
|
|
5246
|
+
const data = JSON.parse(body);
|
|
5247
|
+
const providers = data.providers ?? {};
|
|
5248
|
+
const rows = provider ? providers[provider]?.models ?? [] : Object.values(providers).flatMap((p) => p.models ?? []);
|
|
5249
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5250
|
+
resolve6(rows.flatMap((m) => {
|
|
5251
|
+
if (!m.id || seen.has(m.id))
|
|
5252
|
+
return [];
|
|
5253
|
+
seen.add(m.id);
|
|
5254
|
+
return [{ id: m.id, ...m.description ? { displayName: m.description } : {}, available: true }];
|
|
5255
|
+
}));
|
|
5256
|
+
} catch {
|
|
5257
|
+
resolve6([]);
|
|
5258
|
+
}
|
|
5259
|
+
});
|
|
5260
|
+
});
|
|
5261
|
+
req.on("timeout", () => req.destroy());
|
|
5262
|
+
req.on("error", () => resolve6([]));
|
|
5263
|
+
req.end();
|
|
5264
|
+
}, () => resolve6([]));
|
|
5265
|
+
});
|
|
5266
|
+
}
|
|
5120
5267
|
var HermesSession = class {
|
|
5121
5268
|
sessionId;
|
|
5122
5269
|
model;
|
|
@@ -5162,7 +5309,7 @@ ${prompt}`;
|
|
|
5162
5309
|
await this.run(args, turnId, emit, opts);
|
|
5163
5310
|
}
|
|
5164
5311
|
run(args, turnId, emit, opts) {
|
|
5165
|
-
return new Promise((
|
|
5312
|
+
return new Promise((resolve6) => {
|
|
5166
5313
|
const child = spawn5(this.env.binPath ?? "hermes", args, {
|
|
5167
5314
|
cwd: this.cwd,
|
|
5168
5315
|
shell: process.platform === "win32",
|
|
@@ -5185,7 +5332,7 @@ ${prompt}`;
|
|
|
5185
5332
|
emit({ type: "message", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), role: "assistant", text, delta: false });
|
|
5186
5333
|
emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
|
|
5187
5334
|
}
|
|
5188
|
-
|
|
5335
|
+
resolve6();
|
|
5189
5336
|
};
|
|
5190
5337
|
const guard = setTimeout(() => finish("timeout", out), 18e5);
|
|
5191
5338
|
opts.signal?.addEventListener("abort", () => {
|
|
@@ -5310,6 +5457,10 @@ var HermesAdapter = class {
|
|
|
5310
5457
|
}];
|
|
5311
5458
|
}
|
|
5312
5459
|
const profiles = await this.listProfiles();
|
|
5460
|
+
const cfg = parseHermesConfig();
|
|
5461
|
+
const provider = this.env.provider ?? cfg.provider;
|
|
5462
|
+
const catalogModels = cfg.catalogUrl ? await fetchHermesCatalogModels(cfg.catalogUrl, provider) : [];
|
|
5463
|
+
const providerFallbackModels = provider ? (HERMES_PROVIDER_FALLBACK_MODELS[provider] ?? []).map((id) => ({ id, available: true })) : [];
|
|
5313
5464
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5314
5465
|
return profiles.map((p) => ({
|
|
5315
5466
|
agentId: `hermes:${p.name}`,
|
|
@@ -5317,11 +5468,23 @@ var HermesAdapter = class {
|
|
|
5317
5468
|
adapter: "hermes",
|
|
5318
5469
|
available: true,
|
|
5319
5470
|
...version ? { version } : {},
|
|
5320
|
-
models:
|
|
5471
|
+
models: this.modelsForProfile(p.model, [...catalogModels, ...providerFallbackModels], cfg.defaultModel),
|
|
5321
5472
|
capabilities: CAPABILITIES4,
|
|
5322
5473
|
scannedAt: now
|
|
5323
5474
|
}));
|
|
5324
5475
|
}
|
|
5476
|
+
modelsForProfile(profileModel, catalogModels, configDefault) {
|
|
5477
|
+
const preferred = profileModel ?? this.env.defaultModel ?? configDefault;
|
|
5478
|
+
const models = preferred ? [{ id: preferred, available: true }] : [];
|
|
5479
|
+
const seen = new Set(models.map((m) => m.id));
|
|
5480
|
+
for (const m of catalogModels) {
|
|
5481
|
+
if (!seen.has(m.id)) {
|
|
5482
|
+
models.push(m);
|
|
5483
|
+
seen.add(m.id);
|
|
5484
|
+
}
|
|
5485
|
+
}
|
|
5486
|
+
return models.length > 0 ? models : [{ id: "default", displayName: "Hermes default", available: true }];
|
|
5487
|
+
}
|
|
5325
5488
|
async createSession(params) {
|
|
5326
5489
|
const profile = params.agentId.includes(":") ? params.agentId.split(":")[1] : this.defaultProfile;
|
|
5327
5490
|
const model = params.model && params.model !== "default" ? params.model : this.env.defaultModel ?? "";
|
|
@@ -5329,11 +5492,11 @@ var HermesAdapter = class {
|
|
|
5329
5492
|
}
|
|
5330
5493
|
/** 枚举 Hermes profile(去 ANSI 色解析 profile list)。 */
|
|
5331
5494
|
listProfiles() {
|
|
5332
|
-
return new Promise((
|
|
5495
|
+
return new Promise((resolve6) => {
|
|
5333
5496
|
const child = spawn5(this.env.binPath ?? "hermes", ["profile", "list"], { shell: process.platform === "win32" });
|
|
5334
5497
|
let out = "";
|
|
5335
5498
|
child.stdout.on("data", (d) => out += d.toString());
|
|
5336
|
-
child.on("error", () =>
|
|
5499
|
+
child.on("error", () => resolve6([{ name: this.defaultProfile }]));
|
|
5337
5500
|
child.on("close", () => {
|
|
5338
5501
|
const clean = out.replace(/\u001b\[[0-9;]*m/g, "");
|
|
5339
5502
|
const names = [];
|
|
@@ -5344,17 +5507,17 @@ var HermesAdapter = class {
|
|
|
5344
5507
|
names.push({ name: m[1], model: rest[0] || void 0 });
|
|
5345
5508
|
}
|
|
5346
5509
|
}
|
|
5347
|
-
|
|
5510
|
+
resolve6(names.length > 0 ? names : [{ name: this.defaultProfile }]);
|
|
5348
5511
|
});
|
|
5349
5512
|
});
|
|
5350
5513
|
}
|
|
5351
5514
|
probeVersion() {
|
|
5352
|
-
return new Promise((
|
|
5515
|
+
return new Promise((resolve6) => {
|
|
5353
5516
|
const child = spawn5(this.env.binPath ?? "hermes", ["--version"], { shell: process.platform === "win32" });
|
|
5354
5517
|
let out = "";
|
|
5355
5518
|
child.stdout.on("data", (d) => out += d.toString());
|
|
5356
|
-
child.on("error", () =>
|
|
5357
|
-
child.on("close", (code) =>
|
|
5519
|
+
child.on("error", () => resolve6(null));
|
|
5520
|
+
child.on("close", (code) => resolve6(code === 0 ? out.trim().split("\n")[0] ?? "hermes" : null));
|
|
5358
5521
|
});
|
|
5359
5522
|
}
|
|
5360
5523
|
};
|
|
@@ -5577,7 +5740,7 @@ ${prompt}`;
|
|
|
5577
5740
|
await this.run(args, envelope, turnId, emit, opts);
|
|
5578
5741
|
}
|
|
5579
5742
|
run(args, stdin, turnId, emit, opts) {
|
|
5580
|
-
return new Promise((
|
|
5743
|
+
return new Promise((resolve6) => {
|
|
5581
5744
|
const childEnv = {};
|
|
5582
5745
|
for (const [k, v] of Object.entries(process.env)) {
|
|
5583
5746
|
if (k === "CLAUDECODE" || k.startsWith("CLAUDECODE_") || k.startsWith("CLAUDE_CODE_"))
|
|
@@ -5609,7 +5772,7 @@ ${prompt}`;
|
|
|
5609
5772
|
} else {
|
|
5610
5773
|
emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
|
|
5611
5774
|
}
|
|
5612
|
-
|
|
5775
|
+
resolve6();
|
|
5613
5776
|
};
|
|
5614
5777
|
const guard = setTimeout(() => finish("timeout", acc), 18e5);
|
|
5615
5778
|
opts.signal?.addEventListener("abort", () => {
|
|
@@ -5726,12 +5889,12 @@ var ClaudeCodeAdapter = class {
|
|
|
5726
5889
|
return new ClaudeCodeSession(params.sessionId, params.model, params.cwd, this.env);
|
|
5727
5890
|
}
|
|
5728
5891
|
probeVersion() {
|
|
5729
|
-
return new Promise((
|
|
5892
|
+
return new Promise((resolve6) => {
|
|
5730
5893
|
const child = spawn6(this.env.binPath ?? "claude", ["--version"], { shell: process.platform === "win32" });
|
|
5731
5894
|
let out = "";
|
|
5732
5895
|
child.stdout.on("data", (d) => out += d.toString());
|
|
5733
|
-
child.on("error", () =>
|
|
5734
|
-
child.on("close", (code) =>
|
|
5896
|
+
child.on("error", () => resolve6(null));
|
|
5897
|
+
child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
|
|
5735
5898
|
});
|
|
5736
5899
|
}
|
|
5737
5900
|
};
|
|
@@ -6069,7 +6232,7 @@ var PhononConnection = class {
|
|
|
6069
6232
|
};
|
|
6070
6233
|
|
|
6071
6234
|
// src/config.ts
|
|
6072
|
-
import { readFileSync as
|
|
6235
|
+
import { readFileSync as readFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, chmodSync as chmodSync2 } from "node:fs";
|
|
6073
6236
|
import { homedir as homedir9, hostname as hostname2 } from "node:os";
|
|
6074
6237
|
import { join as join11, dirname as dirname4 } from "node:path";
|
|
6075
6238
|
var DEFAULT_DIR = join11(homedir9(), ".agent-phonon");
|
|
@@ -6077,7 +6240,7 @@ var DEFAULT_CONFIG_PATH = process.env.PHONON_CONFIG ?? join11(DEFAULT_DIR, "conf
|
|
|
6077
6240
|
function readOpenClawGatewayToken() {
|
|
6078
6241
|
try {
|
|
6079
6242
|
const p = join11(homedir9(), ".openclaw", "openclaw.json");
|
|
6080
|
-
const cfg = JSON.parse(
|
|
6243
|
+
const cfg = JSON.parse(readFileSync6(p, "utf8"));
|
|
6081
6244
|
return cfg?.gateway?.auth?.token;
|
|
6082
6245
|
} catch {
|
|
6083
6246
|
return void 0;
|
|
@@ -6086,9 +6249,9 @@ function readOpenClawGatewayToken() {
|
|
|
6086
6249
|
|
|
6087
6250
|
// src/commands.ts
|
|
6088
6251
|
import { spawnSync } from "node:child_process";
|
|
6089
|
-
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as
|
|
6252
|
+
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync7, chmodSync as chmodSync3 } from "node:fs";
|
|
6090
6253
|
import { homedir as homedir10, platform as platform2 } from "node:os";
|
|
6091
|
-
import { join as join12, dirname as dirname5, delimiter } from "node:path";
|
|
6254
|
+
import { join as join12, dirname as dirname5, delimiter, resolve as resolve5 } from "node:path";
|
|
6092
6255
|
import { fileURLToPath } from "node:url";
|
|
6093
6256
|
function probe(bin, args = ["--version"]) {
|
|
6094
6257
|
const r = spawnSync(bin, args, { timeout: 8e3, shell: platform2() === "win32" });
|
|
@@ -6171,13 +6334,13 @@ var ObsServer = class {
|
|
|
6171
6334
|
deps.bus.onEvent((e) => this.broadcast(e));
|
|
6172
6335
|
}
|
|
6173
6336
|
listen(port = 4319, host = "127.0.0.1") {
|
|
6174
|
-
return new Promise((
|
|
6337
|
+
return new Promise((resolve6) => {
|
|
6175
6338
|
const server = createServer2((req, res) => this.handle(req, res));
|
|
6176
6339
|
this.server = server;
|
|
6177
6340
|
server.listen(port, host, () => {
|
|
6178
6341
|
const addr = server.address();
|
|
6179
6342
|
this.actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
6180
|
-
|
|
6343
|
+
resolve6(this.actualPort);
|
|
6181
6344
|
});
|
|
6182
6345
|
});
|
|
6183
6346
|
}
|
|
@@ -6255,11 +6418,11 @@ var ObsServer = class {
|
|
|
6255
6418
|
return this.actualPort;
|
|
6256
6419
|
}
|
|
6257
6420
|
close() {
|
|
6258
|
-
return new Promise((
|
|
6421
|
+
return new Promise((resolve6) => {
|
|
6259
6422
|
for (const c of this.sseClients) c.end();
|
|
6260
6423
|
this.sseClients.clear();
|
|
6261
|
-
if (!this.server) return
|
|
6262
|
-
this.server.close(() =>
|
|
6424
|
+
if (!this.server) return resolve6();
|
|
6425
|
+
this.server.close(() => resolve6());
|
|
6263
6426
|
});
|
|
6264
6427
|
}
|
|
6265
6428
|
};
|