agentlife 2.4.4 → 2.4.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/index.js +48 -43
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
3
|
|
|
4
4
|
// index.ts
|
|
5
|
-
import { homedir as
|
|
5
|
+
import { homedir as homedir13 } from "node:os";
|
|
6
6
|
import * as path16 from "node:path";
|
|
7
7
|
import { existsSync as existsSync6 } from "node:fs";
|
|
8
8
|
|
|
@@ -1110,9 +1110,9 @@ Triggered when the orchestrator routes a "create X agent" / "track Y for me" / n
|
|
|
1110
1110
|
- \`USER.md\` — domain-specific user facts (name, timezone, language + domain knowledge). Read the user's other USER.md files for identity; don't invent.
|
|
1111
1111
|
- \`HEARTBEAT.md\` — periodic check instructions, or empty placeholder \`# Keep empty to skip\`.
|
|
1112
1112
|
4. **Register the agent via \`exec\`**:
|
|
1113
|
-
\`exec openclaw gateway call agentlife.createAgent --params '{"id":"{agentId}","name":"{Name}","model":"{model}","workspace":"/abs/path","description":"one sentence","tools":{"
|
|
1113
|
+
\`exec openclaw gateway call agentlife.createAgent --params '{"id":"{agentId}","name":"{Name}","model":"{model}","workspace":"/abs/path","description":"one sentence","tools":{"profile":"full","alsoAllow":["agentlife_push"]},"identity":{"name":"{Name}","emoji":"{emoji}"}}'\`
|
|
1114
1114
|
- Description drives the orchestrator's routing — make it specific (domains, actions, data types).
|
|
1115
|
-
- \`tools: {
|
|
1115
|
+
- \`tools: {profile:"full", alsoAllow:["agentlife_push"]}\` for agents needing every core tool plus widget push. \`{allow:["agentlife_push"]}\` for widget-only agents.
|
|
1116
1116
|
5. **Hand off in ONE final turn, all in this order, before \`done\`:**
|
|
1117
1117
|
a. Push ONE actionable first widget for the newly-created agent under a surfaceId you own (\`{agentId}-today\`, \`{agentId}-start\`, similar). It must invite the FIRST user interaction — an input prompt, a starter metric with a CTA, a question the user can answer right now. NEVER an identity/confirmation card ("Agent ready", "Welcome to X"). The plugin no longer pushes a placeholder intro widget; this first push IS the dashboard's anchor for the new agent.
|
|
1118
1118
|
b. \`delete {domain}-building\` — the loading widget from step 1.
|
|
@@ -1247,7 +1247,7 @@ var PROVISIONED_AGENTS = [
|
|
|
1247
1247
|
id: "agentlife-builder",
|
|
1248
1248
|
name: "AgentLife Builder",
|
|
1249
1249
|
agentsMd: BUILDER_AGENTS_MD,
|
|
1250
|
-
tools: {
|
|
1250
|
+
tools: { profile: "full", alsoAllow: ["agentlife_push"] }
|
|
1251
1251
|
},
|
|
1252
1252
|
{
|
|
1253
1253
|
id: "supervisor",
|
|
@@ -1440,26 +1440,7 @@ async function provisionAgents(state, cfg, runtime, log) {
|
|
|
1440
1440
|
globalAllowWritten = true;
|
|
1441
1441
|
}
|
|
1442
1442
|
}
|
|
1443
|
-
|
|
1444
|
-
let alsoAllowWritten = false;
|
|
1445
|
-
if (!currentAlsoAllow.includes("agentlife_push")) {
|
|
1446
|
-
try {
|
|
1447
|
-
let backup = {};
|
|
1448
|
-
try {
|
|
1449
|
-
backup = JSON.parse(readFileSync(backupPath, "utf-8"));
|
|
1450
|
-
} catch {}
|
|
1451
|
-
if (backup.toolsAlsoAllow === undefined) {
|
|
1452
|
-
backup.toolsAlsoAllow = [...currentAlsoAllow];
|
|
1453
|
-
writeFileSync(backupPath, JSON.stringify(backup, null, 2) + `
|
|
1454
|
-
`, "utf-8");
|
|
1455
|
-
}
|
|
1456
|
-
} catch {}
|
|
1457
|
-
if (!rawCfgForVisibility.tools)
|
|
1458
|
-
rawCfgForVisibility.tools = {};
|
|
1459
|
-
rawCfgForVisibility.tools.alsoAllow = [...currentAlsoAllow, "agentlife_push"];
|
|
1460
|
-
alsoAllowWritten = true;
|
|
1461
|
-
}
|
|
1462
|
-
if (visibilityWritten || a2aWritten || globalAllowWritten || alsoAllowWritten) {
|
|
1443
|
+
if (visibilityWritten || a2aWritten || globalAllowWritten) {
|
|
1463
1444
|
writeFileSync(configPath, JSON.stringify(rawCfgForVisibility, null, 2) + `
|
|
1464
1445
|
`, "utf-8");
|
|
1465
1446
|
configChanged = true;
|
|
@@ -1469,8 +1450,6 @@ async function provisionAgents(state, cfg, runtime, log) {
|
|
|
1469
1450
|
log("[agentlife] set tools.agentToAgent.enabled=true (cross-agent sends)");
|
|
1470
1451
|
if (globalAllowWritten)
|
|
1471
1452
|
log('[agentlife] added "*" to tools.allow (unblock exec/read/write for provisioned agents)');
|
|
1472
|
-
if (alsoAllowWritten)
|
|
1473
|
-
log("[agentlife] added agentlife_push to tools.alsoAllow (tool-policy pipeline intersection pass-through)");
|
|
1474
1453
|
}
|
|
1475
1454
|
if (configChanged) {
|
|
1476
1455
|
const configPath2 = path3.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
@@ -2779,7 +2758,7 @@ Each turn:
|
|
|
2779
2758
|
- Workspace under \`$HOME/.openclaw/workspace-{id}\` (id = slugified short name or "me")
|
|
2780
2759
|
- \`AGENTS.md\` — generalist scope covering mentioned domains; Data Schema must include a \`domain TEXT NOT NULL\` column on every user-data table so future split by domain is trivial; add self-evolution clause ("when activity_log rows for one domain exceed a natural threshold, push a split-suggest widget")
|
|
2781
2760
|
- \`SOUL.md\`, \`IDENTITY.md\`, \`USER.md\` (user's own words), \`HEARTBEAT.md\` (empty)
|
|
2782
|
-
- \`exec openclaw gateway call agentlife.createAgent --params '{...}'\` with \`tools: {
|
|
2761
|
+
- \`exec openclaw gateway call agentlife.createAgent --params '{...}'\` with \`tools: {profile:"full", alsoAllow:["agentlife_push"]}\`. Plugin auto-deletes welcome + welcome-input on success.
|
|
2783
2762
|
- **Final step, same turn, before \`done\`:** push ONE actionable first widget for the newly-created agent — an input prompt ("Log your first meal", "Enter today's weight"), a starter metric, or an inviting CTA that owns a surfaceId like \`{id}-today\` / \`{id}-start\`. This is what the user sees when onboarding ends; it MUST invite interaction, not just announce existence. Then delete your \`{domain}-building\` loading widget. Then emit \`done\`.
|
|
2784
2763
|
`;
|
|
2785
2764
|
function renderWelcomeWidget(state, log) {
|
|
@@ -6082,6 +6061,7 @@ ${dashboardState}` : ONBOARDING_PLAYBOOK : dashboardState;
|
|
|
6082
6061
|
|
|
6083
6062
|
// gateway/agents.ts
|
|
6084
6063
|
import * as fs8 from "node:fs";
|
|
6064
|
+
import * as os7 from "node:os";
|
|
6085
6065
|
import * as path11 from "node:path";
|
|
6086
6066
|
function registerAgentGateway(api, state2) {
|
|
6087
6067
|
api.registerGatewayMethod("agentlife.createAgent", async ({ params, respond }) => {
|
|
@@ -6190,7 +6170,7 @@ function registerAgentGateway(api, state2) {
|
|
|
6190
6170
|
respond(false, { error: "cannot delete provisioned agent" });
|
|
6191
6171
|
return;
|
|
6192
6172
|
}
|
|
6193
|
-
const cleanup = { sessions: 0, cronJobs: 0, historyRows: 0, agentDbDeleted: false };
|
|
6173
|
+
const cleanup = { sessions: 0, cronJobs: 0, historyRows: 0, agentDbDeleted: false, workspaceDeleted: false, stateDeleted: false };
|
|
6194
6174
|
if (state2.runCommand) {
|
|
6195
6175
|
try {
|
|
6196
6176
|
const sessResult = await state2.runCommand(["openclaw", "gateway", "call", "sessions.list"], { timeoutMs: 1e4 });
|
|
@@ -6251,8 +6231,33 @@ function registerAgentGateway(api, state2) {
|
|
|
6251
6231
|
}
|
|
6252
6232
|
const cfg = api.runtime.config.loadConfig();
|
|
6253
6233
|
const currentList = cfg.agents?.list ?? [];
|
|
6234
|
+
const existingEntry = currentList.find((a) => a.id === id);
|
|
6254
6235
|
const filtered = currentList.filter((a) => a.id !== id);
|
|
6255
6236
|
const removedFromConfig = filtered.length < currentList.length;
|
|
6237
|
+
const openclawHome = path11.join(os7.homedir(), ".openclaw");
|
|
6238
|
+
const stateDir = path11.join(openclawHome, "agents", id);
|
|
6239
|
+
if (stateDir.startsWith(path11.join(openclawHome, "agents") + path11.sep)) {
|
|
6240
|
+
try {
|
|
6241
|
+
if (fs8.existsSync(stateDir)) {
|
|
6242
|
+
fs8.rmSync(stateDir, { recursive: true, force: true });
|
|
6243
|
+
cleanup.stateDeleted = true;
|
|
6244
|
+
}
|
|
6245
|
+
} catch (e) {
|
|
6246
|
+
console.warn("[agentlife] deleteAgent: failed to delete state dir:", e?.message);
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
const defaultWorkspace = path11.join(openclawHome, `workspace-${id}`);
|
|
6250
|
+
const workspaceToDelete = typeof existingEntry?.workspace === "string" && existingEntry.workspace.trim() ? path11.resolve(existingEntry.workspace) : defaultWorkspace;
|
|
6251
|
+
if (workspaceToDelete.startsWith(openclawHome + path11.sep) && workspaceToDelete !== openclawHome) {
|
|
6252
|
+
try {
|
|
6253
|
+
if (fs8.existsSync(workspaceToDelete)) {
|
|
6254
|
+
fs8.rmSync(workspaceToDelete, { recursive: true, force: true });
|
|
6255
|
+
cleanup.workspaceDeleted = true;
|
|
6256
|
+
}
|
|
6257
|
+
} catch (e) {
|
|
6258
|
+
console.warn("[agentlife] deleteAgent: failed to delete workspace dir:", e?.message);
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6256
6261
|
if (removedFromConfig) {
|
|
6257
6262
|
const updatedCfg = {
|
|
6258
6263
|
...cfg,
|
|
@@ -6267,7 +6272,7 @@ function registerAgentGateway(api, state2) {
|
|
|
6267
6272
|
if (removedFromRegistry) {
|
|
6268
6273
|
await saveRegistryToDisk(state2);
|
|
6269
6274
|
}
|
|
6270
|
-
console.log("[agentlife] deleted agent: %s (config=%s, registry=%s, sessions=%d, cron=%d, historyRows=%d, agentDb=%s)", id, removedFromConfig, removedFromRegistry, cleanup.sessions, cleanup.cronJobs, cleanup.historyRows, cleanup.agentDbDeleted);
|
|
6275
|
+
console.log("[agentlife] deleted agent: %s (config=%s, registry=%s, sessions=%d, cron=%d, historyRows=%d, agentDb=%s, state=%s, workspace=%s)", id, removedFromConfig, removedFromRegistry, cleanup.sessions, cleanup.cronJobs, cleanup.historyRows, cleanup.agentDbDeleted, cleanup.stateDeleted, cleanup.workspaceDeleted);
|
|
6271
6276
|
respond(true, { status: "deleted", id, removedFromConfig, removedFromRegistry, cleanup });
|
|
6272
6277
|
});
|
|
6273
6278
|
api.registerGatewayMethod("agentlife.agents", ({ respond }) => {
|
|
@@ -6887,10 +6892,10 @@ function registerAutomationsGateway(api, state2) {
|
|
|
6887
6892
|
// gateway/admin.ts
|
|
6888
6893
|
import * as fs9 from "node:fs/promises";
|
|
6889
6894
|
import * as fsSync4 from "node:fs";
|
|
6890
|
-
import * as
|
|
6895
|
+
import * as os8 from "node:os";
|
|
6891
6896
|
import * as path12 from "node:path";
|
|
6892
6897
|
function pluginConfigPath() {
|
|
6893
|
-
return path12.join(
|
|
6898
|
+
return path12.join(os8.homedir(), ".openclaw", "agentlife", "plugin-config.json");
|
|
6894
6899
|
}
|
|
6895
6900
|
function readPluginConfig() {
|
|
6896
6901
|
try {
|
|
@@ -6999,7 +7004,7 @@ function registerAdminGateway(api, state2) {
|
|
|
6999
7004
|
api.registerGatewayMethod("agentlife.uninstall", async ({ respond }) => {
|
|
7000
7005
|
try {
|
|
7001
7006
|
const cleaned = [];
|
|
7002
|
-
const baseDir = state2.agentlifeStateDir ?? path12.join(
|
|
7007
|
+
const baseDir = state2.agentlifeStateDir ?? path12.join(os8.homedir(), ".openclaw", "agentlife");
|
|
7003
7008
|
const identity = loadDeviceIdentity();
|
|
7004
7009
|
if (!identity) {
|
|
7005
7010
|
cleaned.push("server deprovision skipped (no device identity)");
|
|
@@ -7105,7 +7110,7 @@ function registerAdminGateway(api, state2) {
|
|
|
7105
7110
|
for (const agent of PROVISIONED_AGENTS) {
|
|
7106
7111
|
if (agent.existingAgent)
|
|
7107
7112
|
continue;
|
|
7108
|
-
const wsDir = agent.workspaceDir ?? path12.join(
|
|
7113
|
+
const wsDir = agent.workspaceDir ?? path12.join(os8.homedir(), ".openclaw", `workspace-${agent.id}`);
|
|
7109
7114
|
try {
|
|
7110
7115
|
await fs9.rm(wsDir, { recursive: true, force: true });
|
|
7111
7116
|
cleaned.push(`deleted workspace ${agent.id}`);
|
|
@@ -7366,10 +7371,10 @@ import {
|
|
|
7366
7371
|
|
|
7367
7372
|
// gateway/config-utils.ts
|
|
7368
7373
|
import * as fs10 from "node:fs";
|
|
7369
|
-
import * as
|
|
7374
|
+
import * as os9 from "node:os";
|
|
7370
7375
|
import * as path13 from "node:path";
|
|
7371
7376
|
function configPath() {
|
|
7372
|
-
return path13.join(
|
|
7377
|
+
return path13.join(os9.homedir(), ".openclaw", "openclaw.json");
|
|
7373
7378
|
}
|
|
7374
7379
|
function readConfig() {
|
|
7375
7380
|
try {
|
|
@@ -7385,10 +7390,10 @@ function writeConfig(cfg) {
|
|
|
7385
7390
|
|
|
7386
7391
|
// gateway/providers.ts
|
|
7387
7392
|
import * as fs11 from "node:fs";
|
|
7388
|
-
import * as
|
|
7393
|
+
import * as os10 from "node:os";
|
|
7389
7394
|
import * as path14 from "node:path";
|
|
7390
7395
|
function siblingAgentDirs() {
|
|
7391
|
-
const root = path14.join(
|
|
7396
|
+
const root = path14.join(os10.homedir(), ".openclaw", "agents");
|
|
7392
7397
|
let entries;
|
|
7393
7398
|
try {
|
|
7394
7399
|
entries = fs11.readdirSync(root, { withFileTypes: true });
|
|
@@ -7473,8 +7478,8 @@ function readOAuthExpiries() {
|
|
|
7473
7478
|
const result = new Map;
|
|
7474
7479
|
const fs12 = __require("node:fs");
|
|
7475
7480
|
const path15 = __require("node:path");
|
|
7476
|
-
const
|
|
7477
|
-
const agentsDir = path15.join(
|
|
7481
|
+
const os11 = __require("node:os");
|
|
7482
|
+
const agentsDir = path15.join(os11.homedir(), ".openclaw", "agents");
|
|
7478
7483
|
let entries;
|
|
7479
7484
|
try {
|
|
7480
7485
|
entries = fs12.readdirSync(agentsDir);
|
|
@@ -7766,10 +7771,10 @@ ${result?.stderr ?? ""}`;
|
|
|
7766
7771
|
|
|
7767
7772
|
// gateway/models-config.ts
|
|
7768
7773
|
import * as fs12 from "node:fs";
|
|
7769
|
-
import * as
|
|
7774
|
+
import * as os11 from "node:os";
|
|
7770
7775
|
import * as path15 from "node:path";
|
|
7771
7776
|
function pluginConfigPath2() {
|
|
7772
|
-
return path15.join(
|
|
7777
|
+
return path15.join(os11.homedir(), ".openclaw", "agentlife", "plugin-config.json");
|
|
7773
7778
|
}
|
|
7774
7779
|
function readPluginConfig2() {
|
|
7775
7780
|
try {
|
|
@@ -7926,7 +7931,7 @@ var stopQualityCheckPoller = null;
|
|
|
7926
7931
|
var stopCloudflared = null;
|
|
7927
7932
|
function resolveInternalModel(api) {
|
|
7928
7933
|
try {
|
|
7929
|
-
const pluginCfgPath = path16.join(
|
|
7934
|
+
const pluginCfgPath = path16.join(homedir13(), ".openclaw", "agentlife", "plugin-config.json");
|
|
7930
7935
|
try {
|
|
7931
7936
|
const raw = __require("node:fs").readFileSync(pluginCfgPath, "utf-8");
|
|
7932
7937
|
const pluginCfg = JSON.parse(raw);
|
|
@@ -7962,7 +7967,7 @@ function register(api) {
|
|
|
7962
7967
|
return;
|
|
7963
7968
|
}
|
|
7964
7969
|
registered = true;
|
|
7965
|
-
const fallbackDir = path16.join(
|
|
7970
|
+
const fallbackDir = path16.join(homedir13(), ".openclaw", "agentlife");
|
|
7966
7971
|
const state2 = {
|
|
7967
7972
|
surfaceDb: null,
|
|
7968
7973
|
agentRegistry: new Map,
|