agentlife 1.5.2 → 1.5.4
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/index.js +345 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
3
|
|
|
4
4
|
// index.ts
|
|
5
|
-
import { homedir as
|
|
6
|
-
import * as
|
|
5
|
+
import { homedir as homedir13 } from "node:os";
|
|
6
|
+
import * as path17 from "node:path";
|
|
7
7
|
import { existsSync as existsSync6 } from "node:fs";
|
|
8
8
|
|
|
9
9
|
// db.ts
|
|
@@ -1812,6 +1812,27 @@ async function provisionAgents(state, cfg, runtime, log) {
|
|
|
1812
1812
|
rawCfgForVisibility.tools.sessions.visibility = "all";
|
|
1813
1813
|
visibilityWritten = true;
|
|
1814
1814
|
}
|
|
1815
|
+
const currentA2A = rawCfgForVisibility?.tools?.agentToAgent?.enabled;
|
|
1816
|
+
let a2aWritten = false;
|
|
1817
|
+
if (currentA2A !== true) {
|
|
1818
|
+
try {
|
|
1819
|
+
let backup = {};
|
|
1820
|
+
try {
|
|
1821
|
+
backup = JSON.parse(readFileSync(backupPath, "utf-8"));
|
|
1822
|
+
} catch {}
|
|
1823
|
+
if (backup.agentToAgentEnabled === undefined) {
|
|
1824
|
+
backup.agentToAgentEnabled = currentA2A ?? null;
|
|
1825
|
+
writeFileSync(backupPath, JSON.stringify(backup, null, 2) + `
|
|
1826
|
+
`, "utf-8");
|
|
1827
|
+
}
|
|
1828
|
+
} catch {}
|
|
1829
|
+
if (!rawCfgForVisibility.tools)
|
|
1830
|
+
rawCfgForVisibility.tools = {};
|
|
1831
|
+
if (!rawCfgForVisibility.tools.agentToAgent)
|
|
1832
|
+
rawCfgForVisibility.tools.agentToAgent = {};
|
|
1833
|
+
rawCfgForVisibility.tools.agentToAgent.enabled = true;
|
|
1834
|
+
a2aWritten = true;
|
|
1835
|
+
}
|
|
1815
1836
|
const currentAllow = rawCfgForVisibility?.tools?.allow;
|
|
1816
1837
|
let globalAllowWritten = false;
|
|
1817
1838
|
if (Array.isArray(currentAllow) && currentAllow.length > 0 && !currentAllow.includes("*")) {
|
|
@@ -1832,12 +1853,14 @@ async function provisionAgents(state, cfg, runtime, log) {
|
|
|
1832
1853
|
globalAllowWritten = true;
|
|
1833
1854
|
}
|
|
1834
1855
|
}
|
|
1835
|
-
if (visibilityWritten || globalAllowWritten) {
|
|
1856
|
+
if (visibilityWritten || a2aWritten || globalAllowWritten) {
|
|
1836
1857
|
writeFileSync(configPath, JSON.stringify(rawCfgForVisibility, null, 2) + `
|
|
1837
1858
|
`, "utf-8");
|
|
1838
1859
|
configChanged = true;
|
|
1839
1860
|
if (visibilityWritten)
|
|
1840
1861
|
log("[agentlife] set tools.sessions.visibility=all (cross-agent delegation)");
|
|
1862
|
+
if (a2aWritten)
|
|
1863
|
+
log("[agentlife] set tools.agentToAgent.enabled=true (cross-agent sends)");
|
|
1841
1864
|
if (globalAllowWritten)
|
|
1842
1865
|
log('[agentlife] added "*" to tools.allow (unblock exec/read/write for provisioned agents)');
|
|
1843
1866
|
}
|
|
@@ -2215,6 +2238,10 @@ async function transition(state, runtime, log, trigger) {
|
|
|
2215
2238
|
if (visionSurfaceCount(state) >= 1) {
|
|
2216
2239
|
return enterPhase(state, runtime, log, "READY");
|
|
2217
2240
|
}
|
|
2241
|
+
if (lastText.length === 0) {
|
|
2242
|
+
log(`[cold-start] agentlife-vision replied empty in SYNTHESIZING — model error or silent fail`);
|
|
2243
|
+
return enterFailed(state, log, "vision_agent_empty_reply");
|
|
2244
|
+
}
|
|
2218
2245
|
return cur;
|
|
2219
2246
|
}
|
|
2220
2247
|
if (cur.phase === "AWAITING_BASELINE") {
|
|
@@ -2956,6 +2983,7 @@ function computeEnhancedMetrics(db, agentId, since) {
|
|
|
2956
2983
|
|
|
2957
2984
|
// followup.ts
|
|
2958
2985
|
var pollerInterval = null;
|
|
2986
|
+
var startupPollTimeout = null;
|
|
2959
2987
|
var sweepCounter = 0;
|
|
2960
2988
|
function initFollowupSystem(api, state) {
|
|
2961
2989
|
if (!state.runCommand) {
|
|
@@ -2983,14 +3011,26 @@ function initFollowupSystem(api, state) {
|
|
|
2983
3011
|
CREATE INDEX IF NOT EXISTS idx_followups_status ON followups(status);
|
|
2984
3012
|
`);
|
|
2985
3013
|
pollerInterval = setInterval(() => pollFollowups(state), 60000);
|
|
2986
|
-
setTimeout(() =>
|
|
3014
|
+
startupPollTimeout = setTimeout(() => {
|
|
3015
|
+
startupPollTimeout = null;
|
|
3016
|
+
pollFollowups(state);
|
|
3017
|
+
}, 5000);
|
|
2987
3018
|
console.log("[agentlife:followup] system initialized — polling every 60s");
|
|
2988
3019
|
}
|
|
2989
|
-
function stopFollowupSystem() {
|
|
3020
|
+
function stopFollowupSystem(state) {
|
|
2990
3021
|
if (pollerInterval) {
|
|
2991
3022
|
clearInterval(pollerInterval);
|
|
2992
3023
|
pollerInterval = null;
|
|
2993
3024
|
}
|
|
3025
|
+
if (startupPollTimeout) {
|
|
3026
|
+
clearTimeout(startupPollTimeout);
|
|
3027
|
+
startupPollTimeout = null;
|
|
3028
|
+
}
|
|
3029
|
+
if (state) {
|
|
3030
|
+
for (const handle of state.pendingFollowups.values())
|
|
3031
|
+
clearTimeout(handle);
|
|
3032
|
+
state.pendingFollowups.clear();
|
|
3033
|
+
}
|
|
2994
3034
|
}
|
|
2995
3035
|
function parseFollowup(raw) {
|
|
2996
3036
|
const match = raw.match(/^(\+\d+(?:ms|s|m|h|d))\s+(.+)/);
|
|
@@ -3012,7 +3052,15 @@ function scheduleFollowup(state, surfaceId, followupRaw, agentId) {
|
|
|
3012
3052
|
clearTimeout(existing);
|
|
3013
3053
|
state.pendingFollowups.set(surfaceId, setTimeout(() => {
|
|
3014
3054
|
state.pendingFollowups.delete(surfaceId);
|
|
3015
|
-
|
|
3055
|
+
if (state.disabled)
|
|
3056
|
+
return;
|
|
3057
|
+
try {
|
|
3058
|
+
executeSchedule(state, surfaceId, parsed, agentId);
|
|
3059
|
+
} catch (err) {
|
|
3060
|
+
if (err?.code === "ERR_INVALID_STATE")
|
|
3061
|
+
return;
|
|
3062
|
+
console.warn("[agentlife:followup] executeSchedule threw: %s", err?.message ?? err);
|
|
3063
|
+
}
|
|
3016
3064
|
}, 2000));
|
|
3017
3065
|
}
|
|
3018
3066
|
function removeFollowup(state, surfaceId) {
|
|
@@ -7622,14 +7670,13 @@ function registerAdminGateway(api, state2) {
|
|
|
7622
7670
|
} catch {
|
|
7623
7671
|
cleaned.push("maxPingPongTurns already at default (no backup found)");
|
|
7624
7672
|
}
|
|
7625
|
-
stopFollowupSystem();
|
|
7673
|
+
stopFollowupSystem(state2);
|
|
7626
7674
|
if (state2.surfaceDb)
|
|
7627
7675
|
state2.surfaceDb.clear();
|
|
7628
7676
|
closeAllDbs(state2);
|
|
7629
7677
|
state2.agentRegistry.clear();
|
|
7630
7678
|
state2.usageAccumulator.clear();
|
|
7631
7679
|
state2.sessionBootstrapSnapshots.clear();
|
|
7632
|
-
state2.pendingFollowups.clear();
|
|
7633
7680
|
state2.surfaceDb = null;
|
|
7634
7681
|
state2.disabled = true;
|
|
7635
7682
|
cleaned.push("stopped runtime (poller, DBs, in-memory state)");
|
|
@@ -7910,17 +7957,17 @@ function parseOffset2(offset) {
|
|
|
7910
7957
|
}
|
|
7911
7958
|
|
|
7912
7959
|
// gateway/providers.ts
|
|
7913
|
-
import * as fs11 from "node:fs";
|
|
7914
|
-
import * as os9 from "node:os";
|
|
7915
|
-
import * as path14 from "node:path";
|
|
7916
7960
|
import {
|
|
7917
7961
|
upsertApiKeyProfile,
|
|
7962
|
+
upsertAuthProfile,
|
|
7963
|
+
buildApiKeyCredential,
|
|
7918
7964
|
applyAuthProfileConfig
|
|
7919
7965
|
} from "openclaw/plugin-sdk/provider-auth-api-key";
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7966
|
+
|
|
7967
|
+
// gateway/config-utils.ts
|
|
7968
|
+
import * as fs11 from "node:fs";
|
|
7969
|
+
import * as os9 from "node:os";
|
|
7970
|
+
import * as path14 from "node:path";
|
|
7924
7971
|
function configPath() {
|
|
7925
7972
|
return path14.join(os9.homedir(), ".openclaw", "openclaw.json");
|
|
7926
7973
|
}
|
|
@@ -7935,6 +7982,35 @@ function writeConfig(cfg) {
|
|
|
7935
7982
|
fs11.writeFileSync(configPath(), JSON.stringify(cfg, null, 2) + `
|
|
7936
7983
|
`, "utf-8");
|
|
7937
7984
|
}
|
|
7985
|
+
|
|
7986
|
+
// gateway/providers.ts
|
|
7987
|
+
import * as fs12 from "node:fs";
|
|
7988
|
+
import * as os10 from "node:os";
|
|
7989
|
+
import * as path15 from "node:path";
|
|
7990
|
+
function siblingAgentDirs() {
|
|
7991
|
+
const root = path15.join(os10.homedir(), ".openclaw", "agents");
|
|
7992
|
+
let entries;
|
|
7993
|
+
try {
|
|
7994
|
+
entries = fs12.readdirSync(root, { withFileTypes: true });
|
|
7995
|
+
} catch {
|
|
7996
|
+
return [];
|
|
7997
|
+
}
|
|
7998
|
+
const out = [];
|
|
7999
|
+
for (const entry of entries) {
|
|
8000
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
8001
|
+
continue;
|
|
8002
|
+
const dir = path15.join(root, entry.name, "agent");
|
|
8003
|
+
try {
|
|
8004
|
+
if (fs12.statSync(dir).isDirectory())
|
|
8005
|
+
out.push(dir);
|
|
8006
|
+
} catch {}
|
|
8007
|
+
}
|
|
8008
|
+
return out;
|
|
8009
|
+
}
|
|
8010
|
+
var catalogCache = null;
|
|
8011
|
+
var catalogPromise = null;
|
|
8012
|
+
var modelsCache = null;
|
|
8013
|
+
var modelsPromise = null;
|
|
7938
8014
|
async function fetchCatalog(run) {
|
|
7939
8015
|
const result = await run(["openclaw", "infer", "model", "providers", "--json"], { timeoutMs: 60000 });
|
|
7940
8016
|
if ((result?.code ?? 0) !== 0)
|
|
@@ -7993,6 +8069,37 @@ async function ensureModels(run) {
|
|
|
7993
8069
|
}
|
|
7994
8070
|
return modelsPromise;
|
|
7995
8071
|
}
|
|
8072
|
+
function readOAuthExpiries() {
|
|
8073
|
+
const result = new Map;
|
|
8074
|
+
const fs13 = __require("node:fs");
|
|
8075
|
+
const path16 = __require("node:path");
|
|
8076
|
+
const os11 = __require("node:os");
|
|
8077
|
+
const agentsDir = path16.join(os11.homedir(), ".openclaw", "agents");
|
|
8078
|
+
let entries;
|
|
8079
|
+
try {
|
|
8080
|
+
entries = fs13.readdirSync(agentsDir);
|
|
8081
|
+
} catch {
|
|
8082
|
+
return result;
|
|
8083
|
+
}
|
|
8084
|
+
for (const name of entries) {
|
|
8085
|
+
const filePath = path16.join(agentsDir, name, "agent", "auth-profiles.json");
|
|
8086
|
+
try {
|
|
8087
|
+
const raw = fs13.readFileSync(filePath, "utf-8");
|
|
8088
|
+
const data = JSON.parse(raw);
|
|
8089
|
+
const profiles = data?.profiles ?? {};
|
|
8090
|
+
for (const entry of Object.values(profiles)) {
|
|
8091
|
+
const p = entry;
|
|
8092
|
+
if (p?.type === "oauth" && typeof p.provider === "string" && typeof p.expires === "number") {
|
|
8093
|
+
const prev = result.get(p.provider);
|
|
8094
|
+
if (!prev || p.expires > prev.expiresAt) {
|
|
8095
|
+
result.set(p.provider, { expiresAt: p.expires });
|
|
8096
|
+
}
|
|
8097
|
+
}
|
|
8098
|
+
}
|
|
8099
|
+
} catch {}
|
|
8100
|
+
}
|
|
8101
|
+
return result;
|
|
8102
|
+
}
|
|
7996
8103
|
function authenticatedProviders() {
|
|
7997
8104
|
const cfg = readConfig();
|
|
7998
8105
|
const profiles = cfg?.auth?.profiles ?? {};
|
|
@@ -8112,6 +8219,12 @@ function registerProvidersGateway(api, state2) {
|
|
|
8112
8219
|
} catch {}
|
|
8113
8220
|
try {
|
|
8114
8221
|
const profileId = upsertApiKeyProfile({ provider, input: apiKey });
|
|
8222
|
+
const credential = buildApiKeyCredential(provider, apiKey);
|
|
8223
|
+
for (const agentDir of siblingAgentDirs()) {
|
|
8224
|
+
try {
|
|
8225
|
+
upsertAuthProfile({ profileId, credential, agentDir });
|
|
8226
|
+
} catch {}
|
|
8227
|
+
}
|
|
8115
8228
|
const cfg = readConfig();
|
|
8116
8229
|
const nextCfg = applyAuthProfileConfig(cfg, {
|
|
8117
8230
|
profileId,
|
|
@@ -8142,6 +8255,29 @@ function registerProvidersGateway(api, state2) {
|
|
|
8142
8255
|
delete cfg.auth.order[provider];
|
|
8143
8256
|
}
|
|
8144
8257
|
writeConfig(cfg);
|
|
8258
|
+
for (const agentDir of siblingAgentDirs()) {
|
|
8259
|
+
const file = path15.join(agentDir, "auth-profiles.json");
|
|
8260
|
+
try {
|
|
8261
|
+
const raw = fs12.readFileSync(file, "utf-8");
|
|
8262
|
+
const data = JSON.parse(raw);
|
|
8263
|
+
const agentProfiles = data?.profiles;
|
|
8264
|
+
if (!agentProfiles || typeof agentProfiles !== "object")
|
|
8265
|
+
continue;
|
|
8266
|
+
let changed = false;
|
|
8267
|
+
for (const [id, entry] of Object.entries(agentProfiles)) {
|
|
8268
|
+
if (entry?.provider === provider) {
|
|
8269
|
+
delete agentProfiles[id];
|
|
8270
|
+
changed = true;
|
|
8271
|
+
}
|
|
8272
|
+
}
|
|
8273
|
+
if (data?.order?.[provider]) {
|
|
8274
|
+
delete data.order[provider];
|
|
8275
|
+
changed = true;
|
|
8276
|
+
}
|
|
8277
|
+
if (changed)
|
|
8278
|
+
fs12.writeFileSync(file, JSON.stringify(data, null, 2), "utf-8");
|
|
8279
|
+
} catch {}
|
|
8280
|
+
}
|
|
8145
8281
|
respond(true, { provider, configured: false });
|
|
8146
8282
|
} catch (err) {
|
|
8147
8283
|
respond(false, { error: err?.message ?? String(err) });
|
|
@@ -8180,6 +8316,36 @@ function registerProvidersGateway(api, state2) {
|
|
|
8180
8316
|
respond(false, { error: err?.message ?? String(err) });
|
|
8181
8317
|
}
|
|
8182
8318
|
}, { scope: "operator.read" });
|
|
8319
|
+
api.registerGatewayMethod("agentlife.providers.health", ({ respond }) => {
|
|
8320
|
+
try {
|
|
8321
|
+
const cfg = readConfig();
|
|
8322
|
+
const profiles = cfg?.auth?.profiles ?? {};
|
|
8323
|
+
const oauthInfo = readOAuthExpiries();
|
|
8324
|
+
const probes = [];
|
|
8325
|
+
for (const entry of Object.values(profiles)) {
|
|
8326
|
+
const p = entry;
|
|
8327
|
+
if (typeof p?.provider !== "string")
|
|
8328
|
+
continue;
|
|
8329
|
+
const provider = p.provider;
|
|
8330
|
+
const probe2 = {
|
|
8331
|
+
provider,
|
|
8332
|
+
configured: true,
|
|
8333
|
+
supported: true
|
|
8334
|
+
};
|
|
8335
|
+
if (p.mode === "oauth") {
|
|
8336
|
+
const info = oauthInfo.get(provider);
|
|
8337
|
+
if (info?.expiresAt) {
|
|
8338
|
+
probe2.expiresAt = info.expiresAt;
|
|
8339
|
+
probe2.oauthExpired = info.expiresAt < Date.now();
|
|
8340
|
+
}
|
|
8341
|
+
}
|
|
8342
|
+
probes.push(probe2);
|
|
8343
|
+
}
|
|
8344
|
+
respond(true, { probes });
|
|
8345
|
+
} catch (err) {
|
|
8346
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8347
|
+
}
|
|
8348
|
+
}, { scope: "operator.read" });
|
|
8183
8349
|
api.registerGatewayMethod("agentlife.providers.loginCodex", async ({ respond }) => {
|
|
8184
8350
|
if (!run)
|
|
8185
8351
|
return respond(false, { error: "runCommand unavailable" });
|
|
@@ -8198,6 +8364,159 @@ ${result?.stderr ?? ""}`;
|
|
|
8198
8364
|
}, { scope: "operator.write" });
|
|
8199
8365
|
}
|
|
8200
8366
|
|
|
8367
|
+
// gateway/models-config.ts
|
|
8368
|
+
import * as fs13 from "node:fs";
|
|
8369
|
+
import * as os11 from "node:os";
|
|
8370
|
+
import * as path16 from "node:path";
|
|
8371
|
+
function pluginConfigPath2() {
|
|
8372
|
+
return path16.join(os11.homedir(), ".openclaw", "agentlife", "plugin-config.json");
|
|
8373
|
+
}
|
|
8374
|
+
function readPluginConfig2() {
|
|
8375
|
+
try {
|
|
8376
|
+
return JSON.parse(fs13.readFileSync(pluginConfigPath2(), "utf-8"));
|
|
8377
|
+
} catch {
|
|
8378
|
+
return {};
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
function writePluginConfig2(cfg) {
|
|
8382
|
+
fs13.mkdirSync(path16.dirname(pluginConfigPath2()), { recursive: true });
|
|
8383
|
+
fs13.writeFileSync(pluginConfigPath2(), JSON.stringify(cfg, null, 2) + `
|
|
8384
|
+
`, "utf-8");
|
|
8385
|
+
}
|
|
8386
|
+
function registerModelsConfigGateway(api) {
|
|
8387
|
+
api.registerGatewayMethod("agentlife.models.defaults.get", ({ respond }) => {
|
|
8388
|
+
try {
|
|
8389
|
+
const cfg = readConfig();
|
|
8390
|
+
const m = cfg?.agents?.defaults?.model ?? {};
|
|
8391
|
+
const pluginCfg = readPluginConfig2();
|
|
8392
|
+
respond(true, {
|
|
8393
|
+
primary: typeof m.primary === "string" ? m.primary : "",
|
|
8394
|
+
internal: typeof pluginCfg.internalModel === "string" ? pluginCfg.internalModel : "",
|
|
8395
|
+
fallbacks: Array.isArray(m.fallbacks) ? m.fallbacks.filter((x) => typeof x === "string") : []
|
|
8396
|
+
});
|
|
8397
|
+
} catch (err) {
|
|
8398
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8399
|
+
}
|
|
8400
|
+
}, { scope: "operator.read" });
|
|
8401
|
+
api.registerGatewayMethod("agentlife.models.defaults.setPrimary", ({ params, respond }) => {
|
|
8402
|
+
const model = typeof params?.model === "string" ? params.model.trim() : "";
|
|
8403
|
+
if (!model)
|
|
8404
|
+
return respond(false, { error: "model is required" });
|
|
8405
|
+
try {
|
|
8406
|
+
const cfg = readConfig();
|
|
8407
|
+
cfg.agents = cfg.agents ?? {};
|
|
8408
|
+
cfg.agents.defaults = cfg.agents.defaults ?? {};
|
|
8409
|
+
cfg.agents.defaults.model = cfg.agents.defaults.model ?? {};
|
|
8410
|
+
cfg.agents.defaults.model.primary = model;
|
|
8411
|
+
writeConfig(cfg);
|
|
8412
|
+
respond(true, { ok: true });
|
|
8413
|
+
} catch (err) {
|
|
8414
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8415
|
+
}
|
|
8416
|
+
}, { scope: "operator.write" });
|
|
8417
|
+
api.registerGatewayMethod("agentlife.models.defaults.setInternal", ({ params, respond }) => {
|
|
8418
|
+
const model = typeof params?.model === "string" ? params.model.trim() : "";
|
|
8419
|
+
if (!model)
|
|
8420
|
+
return respond(false, { error: "model is required" });
|
|
8421
|
+
try {
|
|
8422
|
+
const cfg = readPluginConfig2();
|
|
8423
|
+
cfg.internalModel = model;
|
|
8424
|
+
writePluginConfig2(cfg);
|
|
8425
|
+
respond(true, { ok: true });
|
|
8426
|
+
} catch (err) {
|
|
8427
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8428
|
+
}
|
|
8429
|
+
}, { scope: "operator.write" });
|
|
8430
|
+
api.registerGatewayMethod("agentlife.models.fallbacks.set", ({ params, respond }) => {
|
|
8431
|
+
const models = Array.isArray(params?.models) ? params.models.filter((x) => typeof x === "string") : null;
|
|
8432
|
+
if (!models)
|
|
8433
|
+
return respond(false, { error: "models must be an array of strings" });
|
|
8434
|
+
try {
|
|
8435
|
+
const cfg = readConfig();
|
|
8436
|
+
cfg.agents = cfg.agents ?? {};
|
|
8437
|
+
cfg.agents.defaults = cfg.agents.defaults ?? {};
|
|
8438
|
+
cfg.agents.defaults.model = cfg.agents.defaults.model ?? {};
|
|
8439
|
+
cfg.agents.defaults.model.fallbacks = models;
|
|
8440
|
+
writeConfig(cfg);
|
|
8441
|
+
respond(true, { ok: true });
|
|
8442
|
+
} catch (err) {
|
|
8443
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8444
|
+
}
|
|
8445
|
+
}, { scope: "operator.write" });
|
|
8446
|
+
api.registerGatewayMethod("agentlife.agents.list", ({ respond }) => {
|
|
8447
|
+
try {
|
|
8448
|
+
const cfg = readConfig();
|
|
8449
|
+
const list = Array.isArray(cfg?.agents?.list) ? cfg.agents.list : [];
|
|
8450
|
+
const agents = list.map((a) => ({
|
|
8451
|
+
id: typeof a?.id === "string" ? a.id : null,
|
|
8452
|
+
name: typeof a?.name === "string" ? a.name : null,
|
|
8453
|
+
modelOverride: typeof a?.model === "string" ? a.model : null
|
|
8454
|
+
})).filter((a) => a.id !== null && a.name !== null);
|
|
8455
|
+
respond(true, { agents });
|
|
8456
|
+
} catch (err) {
|
|
8457
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8458
|
+
}
|
|
8459
|
+
}, { scope: "operator.read" });
|
|
8460
|
+
api.registerGatewayMethod("agentlife.agents.setModel", ({ params, respond }) => {
|
|
8461
|
+
const agentId = typeof params?.agentId === "string" ? params.agentId.trim() : "";
|
|
8462
|
+
if (!agentId)
|
|
8463
|
+
return respond(false, { error: "agentId is required" });
|
|
8464
|
+
const model = params?.model;
|
|
8465
|
+
if (model !== null && typeof model !== "string") {
|
|
8466
|
+
return respond(false, { error: "model must be string or null" });
|
|
8467
|
+
}
|
|
8468
|
+
try {
|
|
8469
|
+
const cfg = readConfig();
|
|
8470
|
+
const list = Array.isArray(cfg?.agents?.list) ? cfg.agents.list : [];
|
|
8471
|
+
const idx = list.findIndex((a) => a?.id === agentId);
|
|
8472
|
+
if (idx < 0)
|
|
8473
|
+
return respond(false, { error: `agent not found: ${agentId}` });
|
|
8474
|
+
if (model === null) {
|
|
8475
|
+
delete list[idx].model;
|
|
8476
|
+
} else {
|
|
8477
|
+
list[idx].model = model.trim();
|
|
8478
|
+
}
|
|
8479
|
+
writeConfig(cfg);
|
|
8480
|
+
respond(true, { ok: true });
|
|
8481
|
+
} catch (err) {
|
|
8482
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8483
|
+
}
|
|
8484
|
+
}, { scope: "operator.write" });
|
|
8485
|
+
api.registerGatewayMethod("agentlife.agents.setModel.bulk", ({ params, respond }) => {
|
|
8486
|
+
const updates = Array.isArray(params?.updates) ? params.updates : null;
|
|
8487
|
+
if (!updates)
|
|
8488
|
+
return respond(false, { error: "updates must be an array" });
|
|
8489
|
+
for (const u of updates) {
|
|
8490
|
+
if (!u || typeof u.agentId !== "string" || !u.agentId.trim()) {
|
|
8491
|
+
return respond(false, { error: "each update needs agentId (string)" });
|
|
8492
|
+
}
|
|
8493
|
+
if (u.model !== null && typeof u.model !== "string") {
|
|
8494
|
+
return respond(false, { error: "each update model must be string or null" });
|
|
8495
|
+
}
|
|
8496
|
+
}
|
|
8497
|
+
try {
|
|
8498
|
+
const cfg = readConfig();
|
|
8499
|
+
const list = Array.isArray(cfg?.agents?.list) ? cfg.agents.list : [];
|
|
8500
|
+
let applied = 0;
|
|
8501
|
+
for (const u of updates) {
|
|
8502
|
+
const idx = list.findIndex((a) => a?.id === u.agentId);
|
|
8503
|
+
if (idx < 0)
|
|
8504
|
+
continue;
|
|
8505
|
+
if (u.model === null) {
|
|
8506
|
+
delete list[idx].model;
|
|
8507
|
+
} else {
|
|
8508
|
+
list[idx].model = u.model.trim();
|
|
8509
|
+
}
|
|
8510
|
+
applied++;
|
|
8511
|
+
}
|
|
8512
|
+
writeConfig(cfg);
|
|
8513
|
+
respond(true, { ok: true, applied });
|
|
8514
|
+
} catch (err) {
|
|
8515
|
+
respond(false, { error: err?.message ?? String(err) });
|
|
8516
|
+
}
|
|
8517
|
+
}, { scope: "operator.write" });
|
|
8518
|
+
}
|
|
8519
|
+
|
|
8201
8520
|
// index.ts
|
|
8202
8521
|
var currentState = null;
|
|
8203
8522
|
var registered = false;
|
|
@@ -8207,7 +8526,7 @@ var stopQualityCheckPoller = null;
|
|
|
8207
8526
|
var stopCloudflared = null;
|
|
8208
8527
|
function resolveInternalModel(api) {
|
|
8209
8528
|
try {
|
|
8210
|
-
const pluginCfgPath =
|
|
8529
|
+
const pluginCfgPath = path17.join(homedir13(), ".openclaw", "agentlife", "plugin-config.json");
|
|
8211
8530
|
try {
|
|
8212
8531
|
const raw = __require("node:fs").readFileSync(pluginCfgPath, "utf-8");
|
|
8213
8532
|
const pluginCfg = JSON.parse(raw);
|
|
@@ -8243,7 +8562,7 @@ function register(api) {
|
|
|
8243
8562
|
return;
|
|
8244
8563
|
}
|
|
8245
8564
|
registered = true;
|
|
8246
|
-
const fallbackDir =
|
|
8565
|
+
const fallbackDir = path17.join(homedir13(), ".openclaw", "agentlife");
|
|
8247
8566
|
const state2 = {
|
|
8248
8567
|
surfaceDb: null,
|
|
8249
8568
|
agentRegistry: new Map,
|
|
@@ -8253,9 +8572,9 @@ function register(api) {
|
|
|
8253
8572
|
agentDbs: new Map,
|
|
8254
8573
|
historyDb: null,
|
|
8255
8574
|
agentlifeStateDir: fallbackDir,
|
|
8256
|
-
registryFilePath:
|
|
8257
|
-
dbBaseDir:
|
|
8258
|
-
historyDbPath:
|
|
8575
|
+
registryFilePath: path17.join(fallbackDir, "agent-registry.json"),
|
|
8576
|
+
dbBaseDir: path17.join(fallbackDir, "db"),
|
|
8577
|
+
historyDbPath: path17.join(fallbackDir, "agentlife.db"),
|
|
8259
8578
|
runCommand: api.runtime.system?.runCommandWithTimeout ?? null,
|
|
8260
8579
|
enqueueSystemEvent: null,
|
|
8261
8580
|
requestHeartbeatNow: null,
|
|
@@ -8296,7 +8615,7 @@ function register(api) {
|
|
|
8296
8615
|
id: "agentlife-shutdown",
|
|
8297
8616
|
start: () => {},
|
|
8298
8617
|
stop: () => {
|
|
8299
|
-
stopFollowupSystem();
|
|
8618
|
+
stopFollowupSystem(state2);
|
|
8300
8619
|
if (stopObservability) {
|
|
8301
8620
|
stopObservability();
|
|
8302
8621
|
stopObservability = null;
|
|
@@ -8331,8 +8650,9 @@ function register(api) {
|
|
|
8331
8650
|
registerFollowupsGateway(api, state2);
|
|
8332
8651
|
registerAdminGateway(api, state2);
|
|
8333
8652
|
registerProvidersGateway(api, state2);
|
|
8653
|
+
registerModelsConfigGateway(api);
|
|
8334
8654
|
registerWebApp(api);
|
|
8335
|
-
const notifyConfigPath =
|
|
8655
|
+
const notifyConfigPath = path17.join(fallbackDir, "notification-config.json");
|
|
8336
8656
|
api.registerGatewayMethod("agentlife.notifications.register", ({ params, respond }) => {
|
|
8337
8657
|
const serverUrl = typeof params?.serverUrl === "string" ? params.serverUrl.trim() : "";
|
|
8338
8658
|
const apiKey = typeof params?.apiKey === "string" ? params.apiKey.trim() : "";
|
|
@@ -8340,9 +8660,9 @@ function register(api) {
|
|
|
8340
8660
|
return respond(false, { error: "missing serverUrl or apiKey" });
|
|
8341
8661
|
}
|
|
8342
8662
|
try {
|
|
8343
|
-
const { writeFileSync:
|
|
8344
|
-
|
|
8345
|
-
|
|
8663
|
+
const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync7 } = __require("node:fs");
|
|
8664
|
+
mkdirSync7(path17.dirname(notifyConfigPath), { recursive: true });
|
|
8665
|
+
writeFileSync10(notifyConfigPath, JSON.stringify({ serverUrl, apiKey }));
|
|
8346
8666
|
} catch {}
|
|
8347
8667
|
respond(true, { registered: true });
|
|
8348
8668
|
}, { scope: "operator.write" });
|