agentlife 2.5.0 → 2.6.1
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 +47 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3458,6 +3458,48 @@ async function executeAgentNotify(state, db, surfaceId, payload) {
|
|
|
3458
3458
|
}
|
|
3459
3459
|
}
|
|
3460
3460
|
|
|
3461
|
+
// rehydrate.ts
|
|
3462
|
+
var REHYDRATE_PROMPT = `You have just come online on this user's AgentLife dashboard. The dashboard is currently empty for you — no widgets. This is your chance to populate it with what matters to the user right now.
|
|
3463
|
+
|
|
3464
|
+
Look at what you know about the user from:
|
|
3465
|
+
- your memory (memory_search / memory_get)
|
|
3466
|
+
- USER.md and your workspace files
|
|
3467
|
+
- your data tables (surfaces, activity, domain-specific rows)
|
|
3468
|
+
- the current date and time
|
|
3469
|
+
|
|
3470
|
+
Based on what you actually find — not templates, not placeholders — push widgets that represent the user's current goals and next actions. Every widget must have a goal grounded in something concrete from the user's state: an unresolved task, a recent decision, a pending followup, today's domain metric. If you can't tie a widget to real user state, don't push it.
|
|
3471
|
+
|
|
3472
|
+
Push as many genuinely-relevant widgets as you find, one per distinct goal. Then emit done.
|
|
3473
|
+
|
|
3474
|
+
If you find nothing grounded to push, emit done without pushing anything. An empty dashboard is the correct signal when the user hasn't engaged yet.`;
|
|
3475
|
+
function findOrphanedAgents(state, runtime) {
|
|
3476
|
+
if (!state.fileSurfaceStorage)
|
|
3477
|
+
return [];
|
|
3478
|
+
const users = userAgentIds(runtime);
|
|
3479
|
+
return users.filter((id) => state.fileSurfaceStorage.listAgent(id).length === 0);
|
|
3480
|
+
}
|
|
3481
|
+
function dispatchRehydrate(state, runtime, log = console.log) {
|
|
3482
|
+
if (!state.runCommand) {
|
|
3483
|
+
log("[agentlife:rehydrate] runCommand unavailable — skipping");
|
|
3484
|
+
return;
|
|
3485
|
+
}
|
|
3486
|
+
const orphaned = findOrphanedAgents(state, runtime);
|
|
3487
|
+
if (orphaned.length === 0) {
|
|
3488
|
+
log("[agentlife:rehydrate] all user agents have widget files — nothing to rehydrate");
|
|
3489
|
+
return;
|
|
3490
|
+
}
|
|
3491
|
+
const bootId = Date.now();
|
|
3492
|
+
for (const agentId of orphaned) {
|
|
3493
|
+
const params = JSON.stringify({
|
|
3494
|
+
sessionKey: buildAgentSessionKey(agentId),
|
|
3495
|
+
message: REHYDRATE_PROMPT,
|
|
3496
|
+
idempotencyKey: `rehydrate-${agentId}-${bootId}`
|
|
3497
|
+
});
|
|
3498
|
+
state.runCommand(["openclaw", "gateway", "call", "chat.send", "--params", params], { timeoutMs: 60000 }).then((result) => log(`[agentlife:rehydrate] ${agentId} dispatched: code=${result?.code ?? "?"}`)).catch((e) => log(`[agentlife:rehydrate] ${agentId} dispatch failed: ${e?.message ?? e}`));
|
|
3499
|
+
}
|
|
3500
|
+
log(`[agentlife:rehydrate] dispatched rehydrate to ${orphaned.length} orphaned agent(s): ${orphaned.join(", ")}`);
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3461
3503
|
// services/surfaces-init.ts
|
|
3462
3504
|
function registerSurfacesService(api, state) {
|
|
3463
3505
|
api.registerService({
|
|
@@ -3490,6 +3532,11 @@ function registerSurfacesService(api, state) {
|
|
|
3490
3532
|
} catch (err) {
|
|
3491
3533
|
console.warn("[agentlife] boot reconciler failed (non-critical):", err?.message);
|
|
3492
3534
|
}
|
|
3535
|
+
try {
|
|
3536
|
+
dispatchRehydrate(state, api.runtime);
|
|
3537
|
+
} catch (err) {
|
|
3538
|
+
console.warn("[agentlife] rehydrate dispatch failed (non-critical):", err?.message);
|
|
3539
|
+
}
|
|
3493
3540
|
setTimeout(async () => {
|
|
3494
3541
|
try {
|
|
3495
3542
|
const reset = resetInterruptedTasks(state);
|