agentlife 2.5.0 → 2.6.0

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.
Files changed (2) hide show
  1. package/dist/index.js +48 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3458,6 +3458,49 @@ 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
+ timeoutSeconds: 0
3498
+ });
3499
+ state.runCommand(["openclaw", "gateway", "call", "chat.send", "--params", params], { timeoutMs: 1e4 }).then(() => log(`[agentlife:rehydrate] dispatched to ${agentId}`)).catch((e) => log(`[agentlife:rehydrate] ${agentId} dispatch failed: ${e?.message ?? e}`));
3500
+ }
3501
+ log(`[agentlife:rehydrate] dispatched rehydrate to ${orphaned.length} orphaned agent(s): ${orphaned.join(", ")}`);
3502
+ }
3503
+
3461
3504
  // services/surfaces-init.ts
3462
3505
  function registerSurfacesService(api, state) {
3463
3506
  api.registerService({
@@ -3490,6 +3533,11 @@ function registerSurfacesService(api, state) {
3490
3533
  } catch (err) {
3491
3534
  console.warn("[agentlife] boot reconciler failed (non-critical):", err?.message);
3492
3535
  }
3536
+ try {
3537
+ dispatchRehydrate(state, api.runtime);
3538
+ } catch (err) {
3539
+ console.warn("[agentlife] rehydrate dispatch failed (non-critical):", err?.message);
3540
+ }
3493
3541
  setTimeout(async () => {
3494
3542
  try {
3495
3543
  const reset = resetInterruptedTasks(state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlife",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "bun build index.ts --outfile dist/index.js --target node --external openclaw/plugin-sdk",