agentlife 2.0.0 → 2.2.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 +98 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2792,7 +2792,8 @@ function renderAgentWidget(state, runtime, agentId, log) {
2792
2792
  function renderAllAgentWidgets(state, runtime, log) {
2793
2793
  const ids = listSpecialistIds(runtime);
2794
2794
  if (ids.length === 0) {
2795
- log("[render-widgets] no user agents — nothing to render");
2795
+ log("[render-widgets] no user agents — rendering welcome widget");
2796
+ renderWelcomeWidget(state, log);
2796
2797
  return;
2797
2798
  }
2798
2799
  for (const id of ids) {
@@ -2803,6 +2804,101 @@ function renderAllAgentWidgets(state, runtime, log) {
2803
2804
  }
2804
2805
  }
2805
2806
  }
2807
+ var WELCOME_SURFACE_ID = "welcome";
2808
+ var WELCOME_INPUT_SURFACE_ID = "welcome-input";
2809
+ var ONBOARDING_SESSION_KEY = "agent:agentlife-builder:agentlife:onboarding:operator";
2810
+ var ONBOARDING_PLAYBOOK = `[system:onboarding]
2811
+
2812
+ You are the agent-builder operating in the one-time zero-agent onboarding session. A fresh user (no agents yet) just installed AgentLife. The plugin pushed a welcome-input surface into the dashboard; the user's first submission on it is coming next in this session.
2813
+
2814
+ Your job: run a 2–4 turn guided interview, then create ONE **generalist** agent for the user (not a narrow specialist).
2815
+
2816
+ Each turn after the user replies:
2817
+ 1. Decide whether you have enough signal — minimum: name/persona hint + 2–3 concrete life areas they care about. Don't drag past 4 turns.
2818
+ 2. Not enough? \`agentlife_push\` the SAME surfaceId \`welcome-input\` with:
2819
+ - h3 question you generate from what the user just said
2820
+ - 2–4 multichoice buttons \`action=choice\` with options derived from their words (NEVER hardcoded domain lists)
2821
+ - \`textfield placeholder="Something else…"\` escape hatch
2822
+ - updated \`context: {"phase":"welcome","turn":N+1,"answers":[...]}\`
2823
+ - goal + followup unchanged
2824
+ Respond \`done\` after the push.
2825
+ 3. Enough? Create the generalist:
2826
+ - Write workspace files under \`$HOME/.openclaw/workspace-{id}\` (id = user-slugified short name or "me")
2827
+ - \`AGENTS.md\` — generalist scope covering the domains mentioned; Data Schema must include a \`domain TEXT NOT NULL\` column on every user-data table so a future split by domain is trivial; include a self-evolution clause ("when activity_log rows for a single domain exceed a natural threshold, push a split-suggest widget")
2828
+ - \`SOUL.md\`, \`IDENTITY.md\`, \`USER.md\` (user's own words from the interview), \`HEARTBEAT.md\` (empty placeholder)
2829
+ - \`exec openclaw gateway call agentlife.createAgent --params '{...}'\` with \`tools: {profile:"full"}\`. The plugin deletes welcome + welcome-input and renders {id}-intro automatically — do NOT push an intro yourself.
2830
+ - Respond \`done\`.
2831
+
2832
+ The user's first reply follows this system preamble. Proceed.
2833
+ `;
2834
+ function renderWelcomeWidget(state, log) {
2835
+ const welcomeDsl = [
2836
+ `surface ${WELCOME_SURFACE_ID} size=m`,
2837
+ ` card`,
2838
+ ` column`,
2839
+ ` text "\uD83D\uDC4B Welcome to Agent Life" h3`,
2840
+ ` text "Answer below and I'll build your first agent from it." body`,
2841
+ ` divider`,
2842
+ ` badge "Setup" color=#6366F1 outlined`,
2843
+ `goal: Welcome the user and anchor the onboarding flow`,
2844
+ `followup: +24h "If still zero agents, push an encouraging nudge."`,
2845
+ `context: {"phase":"welcome","autoRendered":true}`
2846
+ ].join(`
2847
+ `);
2848
+ pluginPushSurface(state, { agentId: "agentlife", dsl: welcomeDsl });
2849
+ log(`[render-widgets] rendered ${WELCOME_SURFACE_ID}`);
2850
+ const welcomeInputDsl = [
2851
+ `surface ${WELCOME_INPUT_SURFACE_ID} input`,
2852
+ ` card`,
2853
+ ` column`,
2854
+ ` text "What do you want to track or improve?" h3`,
2855
+ ` text "One line. Anything — meals, money, a project, a habit." body`,
2856
+ ` textfield placeholder="Type anything…"`,
2857
+ `goal: Onboard the user to their first agent via a guided interview`,
2858
+ `followup: +30m "If unanswered, replace the question with a gentler prompt."`,
2859
+ `context: {"phase":"welcome","turn":1,"answers":[]}`
2860
+ ].join(`
2861
+ `);
2862
+ pluginPushSurface(state, { agentId: "agentlife-builder", dsl: welcomeInputDsl });
2863
+ state.surfaceDb?.setOriginSessionKey(WELCOME_INPUT_SURFACE_ID, ONBOARDING_SESSION_KEY);
2864
+ log(`[render-widgets] rendered ${WELCOME_INPUT_SURFACE_ID} (onboarding session)`);
2865
+ seedOnboardingSession(state, log);
2866
+ }
2867
+ function seedOnboardingSession(state, log) {
2868
+ if (!state.runCommand) {
2869
+ log(`[render-widgets] runCommand unavailable — onboarding session not seeded`);
2870
+ return;
2871
+ }
2872
+ const model = state.internalModel;
2873
+ const createParams = JSON.stringify({ key: ONBOARDING_SESSION_KEY, agentId: "agentlife-builder", model });
2874
+ state.runCommand(["openclaw", "gateway", "call", "sessions.create", "--params", createParams], { timeoutMs: 1e4 }).then(() => {
2875
+ const chatParams = JSON.stringify({
2876
+ sessionKey: ONBOARDING_SESSION_KEY,
2877
+ message: ONBOARDING_PLAYBOOK,
2878
+ idempotencyKey: `onboarding-seed-${ONBOARDING_SESSION_KEY}`
2879
+ });
2880
+ state.runCommand(["openclaw", "gateway", "call", "chat.send", "--params", chatParams], { timeoutMs: 30000 }).catch((e) => console.warn("[agentlife] onboarding seed chat.send failed: %s", e?.message));
2881
+ }).catch((e) => {
2882
+ console.log("[agentlife] onboarding session create skipped: %s", e?.message);
2883
+ });
2884
+ }
2885
+ function deleteWelcomeWidget(state, log) {
2886
+ for (const id of [WELCOME_SURFACE_ID, WELCOME_INPUT_SURFACE_ID]) {
2887
+ if (state.surfaceDb?.has(id)) {
2888
+ state.surfaceDb.delete(id);
2889
+ broadcastDelete(id);
2890
+ log(`[render-widgets] deleted ${id}`);
2891
+ }
2892
+ }
2893
+ if (state.runCommand) {
2894
+ const deleteParams = JSON.stringify({ key: ONBOARDING_SESSION_KEY, deleteTranscript: true });
2895
+ state.runCommand(["openclaw", "gateway", "call", "sessions.delete", "--params", deleteParams], { timeoutMs: 1e4 }).then(() => {
2896
+ log(`[render-widgets] deleted onboarding session`);
2897
+ }).catch((e) => {
2898
+ console.log("[agentlife] onboarding session delete skipped: %s", e?.message);
2899
+ });
2900
+ }
2901
+ }
2806
2902
 
2807
2903
  // services/surfaces-init.ts
2808
2904
  import * as path4 from "node:path";
@@ -6142,6 +6238,7 @@ function registerAgentGateway(api, state2) {
6142
6238
  if (!provisionedIds.has(id)) {
6143
6239
  try {
6144
6240
  renderAgentWidget(state2, api.runtime, id, console.log);
6241
+ deleteWelcomeWidget(state2, console.log);
6145
6242
  } catch (e) {
6146
6243
  console.warn("[agentlife] renderAgentWidget failed for %s: %s", id, e?.message);
6147
6244
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlife",
3
- "version": "2.0.0",
3
+ "version": "2.2.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",