agent-phonon 0.2.9 → 0.2.10
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 +172 -9
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +170 -7
- package/dist/daemon.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -4624,7 +4624,12 @@ function fileSize(p) {
|
|
|
4624
4624
|
import { spawn as spawn3 } from "node:child_process";
|
|
4625
4625
|
import { homedir as homedir5 } from "node:os";
|
|
4626
4626
|
import { join as join7 } from "node:path";
|
|
4627
|
-
import { existsSync as existsSync7, readdirSync, statSync as statSync2 } from "node:fs";
|
|
4627
|
+
import { existsSync as existsSync7, readdirSync, statSync as statSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
4628
|
+
var CODEX_FALLBACK_MODELS = [
|
|
4629
|
+
{ id: "gpt-5.5", available: true },
|
|
4630
|
+
{ id: "gpt-5.4", available: true },
|
|
4631
|
+
{ id: "gpt-5.3-codex", available: true }
|
|
4632
|
+
];
|
|
4628
4633
|
var CAPABILITIES2 = {
|
|
4629
4634
|
nativeSession: true,
|
|
4630
4635
|
// exec resume <thread_id>
|
|
@@ -4674,6 +4679,60 @@ function resolveCodexSessionFile(threadId, codexHome = join7(homedir5(), ".codex
|
|
|
4674
4679
|
hits.sort((a, b) => b.mtime - a.mtime);
|
|
4675
4680
|
return hits[0].path;
|
|
4676
4681
|
}
|
|
4682
|
+
function parseCodexConfig(configPath = join7(homedir5(), ".codex", "config.toml")) {
|
|
4683
|
+
if (!existsSync7(configPath))
|
|
4684
|
+
return {};
|
|
4685
|
+
const text = readFileSync4(configPath, "utf8");
|
|
4686
|
+
const model = text.match(/^model\s*=\s*"([^"]+)"/m)?.[1];
|
|
4687
|
+
const providerId = text.match(/^model_provider\s*=\s*"([^"]+)"/m)?.[1];
|
|
4688
|
+
let baseUrl;
|
|
4689
|
+
if (providerId) {
|
|
4690
|
+
const escaped = providerId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4691
|
+
const section = text.match(new RegExp(`\\[model_providers\\.${escaped}\\]([\\s\\S]*?)(?:\\n\\[|$)`))?.[1];
|
|
4692
|
+
baseUrl = section?.match(/^base_url\s*=\s*"([^"]+)"/m)?.[1];
|
|
4693
|
+
}
|
|
4694
|
+
return { model, providerId, baseUrl };
|
|
4695
|
+
}
|
|
4696
|
+
function normalizeOpenAiModels(data) {
|
|
4697
|
+
const rows = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : [];
|
|
4698
|
+
const out = [];
|
|
4699
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4700
|
+
for (const row of rows) {
|
|
4701
|
+
const obj = row;
|
|
4702
|
+
const id = typeof obj.id === "string" ? obj.id : void 0;
|
|
4703
|
+
if (!id || seen.has(id))
|
|
4704
|
+
continue;
|
|
4705
|
+
seen.add(id);
|
|
4706
|
+
out.push({ id, ...typeof obj.name === "string" ? { displayName: obj.name } : {}, available: true });
|
|
4707
|
+
}
|
|
4708
|
+
return out;
|
|
4709
|
+
}
|
|
4710
|
+
function fetchJson(url, headers) {
|
|
4711
|
+
return new Promise((resolve5, reject) => {
|
|
4712
|
+
const u = new URL(url);
|
|
4713
|
+
const req = (u.protocol === "http:" ? import("node:http") : import("node:https")).then((mod) => mod.request(url, { method: "GET", headers, timeout: 5e3 }, (res) => {
|
|
4714
|
+
let body = "";
|
|
4715
|
+
res.setEncoding("utf8");
|
|
4716
|
+
res.on("data", (d) => body += d);
|
|
4717
|
+
res.on("end", () => {
|
|
4718
|
+
if ((res.statusCode ?? 500) < 200 || (res.statusCode ?? 500) >= 300) {
|
|
4719
|
+
reject(new Error(`GET ${url} failed: ${res.statusCode}`));
|
|
4720
|
+
return;
|
|
4721
|
+
}
|
|
4722
|
+
try {
|
|
4723
|
+
resolve5(JSON.parse(body));
|
|
4724
|
+
} catch (e) {
|
|
4725
|
+
reject(e);
|
|
4726
|
+
}
|
|
4727
|
+
});
|
|
4728
|
+
}));
|
|
4729
|
+
req.then((r) => {
|
|
4730
|
+
r.on("timeout", () => r.destroy(new Error(`GET ${url} timeout`)));
|
|
4731
|
+
r.on("error", reject);
|
|
4732
|
+
r.end();
|
|
4733
|
+
}, reject);
|
|
4734
|
+
});
|
|
4735
|
+
}
|
|
4677
4736
|
var CodexSession = class {
|
|
4678
4737
|
sessionId;
|
|
4679
4738
|
model;
|
|
@@ -4837,6 +4896,7 @@ var CodexAdapter = class {
|
|
|
4837
4896
|
async discoverAgents() {
|
|
4838
4897
|
const version = await this.probeVersion();
|
|
4839
4898
|
const available = version !== null;
|
|
4899
|
+
const models = await this.discoverModels();
|
|
4840
4900
|
return [{
|
|
4841
4901
|
agentId: "codex",
|
|
4842
4902
|
displayName: "Codex",
|
|
@@ -4844,7 +4904,7 @@ var CodexAdapter = class {
|
|
|
4844
4904
|
available,
|
|
4845
4905
|
...available ? {} : { unavailableReason: "codex CLI not found" },
|
|
4846
4906
|
...version ? { version } : {},
|
|
4847
|
-
models
|
|
4907
|
+
models,
|
|
4848
4908
|
capabilities: CAPABILITIES2,
|
|
4849
4909
|
scannedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4850
4910
|
}];
|
|
@@ -4852,6 +4912,28 @@ var CodexAdapter = class {
|
|
|
4852
4912
|
async createSession(params) {
|
|
4853
4913
|
return new CodexSession(params.sessionId, params.model, params.cwd, this.env);
|
|
4854
4914
|
}
|
|
4915
|
+
async discoverModels() {
|
|
4916
|
+
if (this.env.models?.length)
|
|
4917
|
+
return this.env.models;
|
|
4918
|
+
const cfg = parseCodexConfig();
|
|
4919
|
+
const baseUrl = this.env.baseUrl ?? cfg.baseUrl;
|
|
4920
|
+
if (baseUrl) {
|
|
4921
|
+
try {
|
|
4922
|
+
const data = await fetchJson(`${baseUrl.replace(/\/$/, "")}/models`, this.env.apiKey ? { Authorization: `Bearer ${this.env.apiKey}` } : void 0);
|
|
4923
|
+
const models = normalizeOpenAiModels(data);
|
|
4924
|
+
if (models.length > 0)
|
|
4925
|
+
return models;
|
|
4926
|
+
} catch {
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
const configured = this.env.defaultModel !== "default" ? this.env.defaultModel : cfg.model;
|
|
4930
|
+
const base = configured ? [{ id: configured, available: true }] : [];
|
|
4931
|
+
const seen = new Set(base.map((m) => m.id));
|
|
4932
|
+
for (const m of CODEX_FALLBACK_MODELS)
|
|
4933
|
+
if (!seen.has(m.id))
|
|
4934
|
+
base.push(m);
|
|
4935
|
+
return base.length > 0 ? base : CODEX_FALLBACK_MODELS;
|
|
4936
|
+
}
|
|
4855
4937
|
probeVersion() {
|
|
4856
4938
|
return new Promise((resolve5) => {
|
|
4857
4939
|
const child = spawn3(this.env.binPath ?? "codex", ["--version"], { shell: process.platform === "win32" });
|
|
@@ -5098,7 +5180,29 @@ import { randomUUID as randomUUID3 } from "node:crypto";
|
|
|
5098
5180
|
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
5099
5181
|
import { homedir as homedir7 } from "node:os";
|
|
5100
5182
|
import { join as join9 } from "node:path";
|
|
5101
|
-
import { existsSync as existsSync9 } from "node:fs";
|
|
5183
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
|
|
5184
|
+
var HERMES_PROVIDER_FALLBACK_MODELS = {
|
|
5185
|
+
// Hermes' built-in Copilot picker exposes these account/integrator-safe model ids.
|
|
5186
|
+
copilot: [
|
|
5187
|
+
"gpt-5.4",
|
|
5188
|
+
"gpt-5.4-mini",
|
|
5189
|
+
"gpt-5-mini",
|
|
5190
|
+
"gpt-5.3-codex",
|
|
5191
|
+
"gpt-5.2-codex",
|
|
5192
|
+
"gpt-4.1",
|
|
5193
|
+
"gpt-4o",
|
|
5194
|
+
"gpt-4o-mini",
|
|
5195
|
+
"claude-sonnet-4.6",
|
|
5196
|
+
"claude-sonnet-4",
|
|
5197
|
+
"claude-sonnet-4.5",
|
|
5198
|
+
"claude-haiku-4.5",
|
|
5199
|
+
"gemini-3.1-pro-preview",
|
|
5200
|
+
"gemini-3-pro-preview",
|
|
5201
|
+
"gemini-3-flash-preview",
|
|
5202
|
+
"gemini-2.5-pro"
|
|
5203
|
+
],
|
|
5204
|
+
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"]
|
|
5205
|
+
};
|
|
5102
5206
|
var CAPABILITIES4 = {
|
|
5103
5207
|
nativeSession: true,
|
|
5104
5208
|
// --resume / --pass-session-id
|
|
@@ -5118,6 +5222,49 @@ var CAPABILITIES4 = {
|
|
|
5118
5222
|
// -z 是纯文本一次性输出,非流式 → 用 final 事件
|
|
5119
5223
|
limits: { maxConcurrentSessions: 4 }
|
|
5120
5224
|
};
|
|
5225
|
+
function parseHermesConfig(configPath = join9(homedir7(), ".hermes", "config.yaml")) {
|
|
5226
|
+
if (!existsSync9(configPath))
|
|
5227
|
+
return {};
|
|
5228
|
+
const text = readFileSync5(configPath, "utf8");
|
|
5229
|
+
const modelBlock = text.match(/(?:^|\n)model:\n([\s\S]*?)(?:\n[A-Za-z_][A-Za-z0-9_-]*:|$)/)?.[1] ?? "";
|
|
5230
|
+
const defaultModel = modelBlock.match(/^\s+default:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5231
|
+
const provider = modelBlock.match(/^\s+provider:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5232
|
+
const catalogBlock = text.match(/(?:^|\n)model_catalog:\n([\s\S]*?)(?:\n[A-Za-z_][A-Za-z0-9_-]*:|$)/)?.[1] ?? "";
|
|
5233
|
+
const catalogUrl = catalogBlock.match(/^\s+url:\s*['"]?([^'"\n]+)['"]?/m)?.[1]?.trim();
|
|
5234
|
+
return { defaultModel, provider, catalogUrl };
|
|
5235
|
+
}
|
|
5236
|
+
function fetchHermesCatalogModels(url, provider) {
|
|
5237
|
+
return new Promise((resolve5) => {
|
|
5238
|
+
const u = new URL(url);
|
|
5239
|
+
const reqMod = u.protocol === "http:" ? import("node:http") : import("node:https");
|
|
5240
|
+
reqMod.then((mod) => {
|
|
5241
|
+
const req = mod.request(url, { method: "GET", timeout: 5e3 }, (res) => {
|
|
5242
|
+
let body = "";
|
|
5243
|
+
res.setEncoding("utf8");
|
|
5244
|
+
res.on("data", (d) => body += d);
|
|
5245
|
+
res.on("end", () => {
|
|
5246
|
+
try {
|
|
5247
|
+
const data = JSON.parse(body);
|
|
5248
|
+
const providers = data.providers ?? {};
|
|
5249
|
+
const rows = provider ? providers[provider]?.models ?? [] : Object.values(providers).flatMap((p) => p.models ?? []);
|
|
5250
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5251
|
+
resolve5(rows.flatMap((m) => {
|
|
5252
|
+
if (!m.id || seen.has(m.id))
|
|
5253
|
+
return [];
|
|
5254
|
+
seen.add(m.id);
|
|
5255
|
+
return [{ id: m.id, ...m.description ? { displayName: m.description } : {}, available: true }];
|
|
5256
|
+
}));
|
|
5257
|
+
} catch {
|
|
5258
|
+
resolve5([]);
|
|
5259
|
+
}
|
|
5260
|
+
});
|
|
5261
|
+
});
|
|
5262
|
+
req.on("timeout", () => req.destroy());
|
|
5263
|
+
req.on("error", () => resolve5([]));
|
|
5264
|
+
req.end();
|
|
5265
|
+
}, () => resolve5([]));
|
|
5266
|
+
});
|
|
5267
|
+
}
|
|
5121
5268
|
var HermesSession = class {
|
|
5122
5269
|
sessionId;
|
|
5123
5270
|
model;
|
|
@@ -5311,6 +5458,10 @@ var HermesAdapter = class {
|
|
|
5311
5458
|
}];
|
|
5312
5459
|
}
|
|
5313
5460
|
const profiles = await this.listProfiles();
|
|
5461
|
+
const cfg = parseHermesConfig();
|
|
5462
|
+
const provider = this.env.provider ?? cfg.provider;
|
|
5463
|
+
const catalogModels = cfg.catalogUrl ? await fetchHermesCatalogModels(cfg.catalogUrl, provider) : [];
|
|
5464
|
+
const providerFallbackModels = provider ? (HERMES_PROVIDER_FALLBACK_MODELS[provider] ?? []).map((id) => ({ id, available: true })) : [];
|
|
5314
5465
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5315
5466
|
return profiles.map((p) => ({
|
|
5316
5467
|
agentId: `hermes:${p.name}`,
|
|
@@ -5318,11 +5469,23 @@ var HermesAdapter = class {
|
|
|
5318
5469
|
adapter: "hermes",
|
|
5319
5470
|
available: true,
|
|
5320
5471
|
...version ? { version } : {},
|
|
5321
|
-
models:
|
|
5472
|
+
models: this.modelsForProfile(p.model, [...catalogModels, ...providerFallbackModels], cfg.defaultModel),
|
|
5322
5473
|
capabilities: CAPABILITIES4,
|
|
5323
5474
|
scannedAt: now
|
|
5324
5475
|
}));
|
|
5325
5476
|
}
|
|
5477
|
+
modelsForProfile(profileModel, catalogModels, configDefault) {
|
|
5478
|
+
const preferred = profileModel ?? this.env.defaultModel ?? configDefault;
|
|
5479
|
+
const models = preferred ? [{ id: preferred, available: true }] : [];
|
|
5480
|
+
const seen = new Set(models.map((m) => m.id));
|
|
5481
|
+
for (const m of catalogModels) {
|
|
5482
|
+
if (!seen.has(m.id)) {
|
|
5483
|
+
models.push(m);
|
|
5484
|
+
seen.add(m.id);
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
return models.length > 0 ? models : [{ id: "default", displayName: "Hermes default", available: true }];
|
|
5488
|
+
}
|
|
5326
5489
|
async createSession(params) {
|
|
5327
5490
|
const profile = params.agentId.includes(":") ? params.agentId.split(":")[1] : this.defaultProfile;
|
|
5328
5491
|
const model = params.model && params.model !== "default" ? params.model : this.env.defaultModel ?? "";
|
|
@@ -6070,7 +6233,7 @@ var PhononConnection = class {
|
|
|
6070
6233
|
};
|
|
6071
6234
|
|
|
6072
6235
|
// src/config.ts
|
|
6073
|
-
import { readFileSync as
|
|
6236
|
+
import { readFileSync as readFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, chmodSync as chmodSync2 } from "node:fs";
|
|
6074
6237
|
import { homedir as homedir9, hostname as hostname2 } from "node:os";
|
|
6075
6238
|
import { join as join11, dirname as dirname4 } from "node:path";
|
|
6076
6239
|
var DEFAULT_DIR = join11(homedir9(), ".agent-phonon");
|
|
@@ -6090,7 +6253,7 @@ function loadConfig(path = DEFAULT_CONFIG_PATH) {
|
|
|
6090
6253
|
if (!existsSync11(path)) {
|
|
6091
6254
|
throw new Error(`config not found at ${path} \u2014 run 'agent-phonon init' first`);
|
|
6092
6255
|
}
|
|
6093
|
-
const raw = JSON.parse(
|
|
6256
|
+
const raw = JSON.parse(readFileSync6(path, "utf8"));
|
|
6094
6257
|
const d = defaultConfig();
|
|
6095
6258
|
return {
|
|
6096
6259
|
deviceId: raw.deviceId ?? d.deviceId,
|
|
@@ -6129,7 +6292,7 @@ function redactConfig(cfg) {
|
|
|
6129
6292
|
function readOpenClawGatewayToken() {
|
|
6130
6293
|
try {
|
|
6131
6294
|
const p = join11(homedir9(), ".openclaw", "openclaw.json");
|
|
6132
|
-
const cfg = JSON.parse(
|
|
6295
|
+
const cfg = JSON.parse(readFileSync6(p, "utf8"));
|
|
6133
6296
|
return cfg?.gateway?.auth?.token;
|
|
6134
6297
|
} catch {
|
|
6135
6298
|
return void 0;
|
|
@@ -6138,7 +6301,7 @@ function readOpenClawGatewayToken() {
|
|
|
6138
6301
|
|
|
6139
6302
|
// src/commands.ts
|
|
6140
6303
|
import { spawnSync } from "node:child_process";
|
|
6141
|
-
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as
|
|
6304
|
+
import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync7 } from "node:fs";
|
|
6142
6305
|
import { homedir as homedir10, platform as platform2 } from "node:os";
|
|
6143
6306
|
import { join as join12, dirname as dirname5, delimiter } from "node:path";
|
|
6144
6307
|
import { fileURLToPath } from "node:url";
|
|
@@ -6332,7 +6495,7 @@ function cmdPluginInstall(which) {
|
|
|
6332
6495
|
mkdirSync4(dist, { recursive: true });
|
|
6333
6496
|
cpSync(join12(pluginSrc, "dist"), join12(dist, "dist"), { recursive: true });
|
|
6334
6497
|
cpSync(join12(pluginSrc, "openclaw.plugin.json"), join12(dist, "openclaw.plugin.json"));
|
|
6335
|
-
const pkg = JSON.parse(
|
|
6498
|
+
const pkg = JSON.parse(readFileSync7(join12(pluginSrc, "package.json"), "utf8"));
|
|
6336
6499
|
delete pkg.devDependencies;
|
|
6337
6500
|
writeFileSync4(join12(dist, "package.json"), JSON.stringify(pkg, null, 2));
|
|
6338
6501
|
console.log(`exported clean plugin \u2192 ${dist}`);
|