agentlife 2.1.0 → 2.2.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.
Files changed (2) hide show
  1. package/dist/index.js +86 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2805,29 +2805,99 @@ function renderAllAgentWidgets(state, runtime, log) {
2805
2805
  }
2806
2806
  }
2807
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
+ `;
2808
2834
  function renderWelcomeWidget(state, log) {
2809
- const dsl = [
2835
+ const welcomeDsl = [
2810
2836
  `surface ${WELCOME_SURFACE_ID} size=m`,
2811
2837
  ` card`,
2812
2838
  ` column`,
2813
2839
  ` text "\uD83D\uDC4B Welcome to Agent Life" h3`,
2814
- ` text "Type what you want to track or automate — one line, anything. Your first agent builds itself from that intent." body`,
2840
+ ` text "Answer below and I'll build your first agent from it." body`,
2815
2841
  ` divider`,
2816
- ` badge "Ready" color=#6366F1 outlined`,
2817
- `goal: Welcome the user and guide them to create their first agent`,
2818
- `followup: +24h "If the user still has no agents, push an encouraging widget inviting them to try again. If agents now exist, this widget will already be deleted."`,
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."`,
2819
2845
  `context: {"phase":"welcome","autoRendered":true}`
2820
2846
  ].join(`
2821
2847
  `);
2822
- pluginPushSurface(state, { agentId: "agentlife", dsl });
2848
+ pluginPushSurface(state, { agentId: "agentlife", dsl: welcomeDsl });
2823
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);
2824
2866
  }
2825
- function deleteWelcomeWidget(state, log) {
2826
- if (!state.surfaceDb?.has(WELCOME_SURFACE_ID))
2867
+ function seedOnboardingSession(state, log) {
2868
+ if (!state.runCommand) {
2869
+ log(`[render-widgets] runCommand unavailable — onboarding session not seeded`);
2827
2870
  return;
2828
- state.surfaceDb.delete(WELCOME_SURFACE_ID);
2829
- broadcastDelete(WELCOME_SURFACE_ID);
2830
- log(`[render-widgets] deleted ${WELCOME_SURFACE_ID}`);
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
+ }
2831
2901
  }
2832
2902
 
2833
2903
  // services/surfaces-init.ts
@@ -2934,11 +3004,14 @@ function registerSurfacesService(api, state) {
2934
3004
  state.surfaceDb = new SurfaceDb(db);
2935
3005
  }
2936
3006
  runStartupPurge(state);
3007
+ const FLOW_INPUT_IDS = new Set(["welcome-input"]);
2937
3008
  let inputPurged = 0;
2938
3009
  for (const [surfaceId, meta] of state.surfaceDb.entries()) {
2939
3010
  const headerLine = meta.lines[0] ?? "";
2940
3011
  if (!/\binput\b/.test(headerLine))
2941
3012
  continue;
3013
+ if (FLOW_INPUT_IDS.has(surfaceId))
3014
+ continue;
2942
3015
  state.surfaceDb.delete(surfaceId);
2943
3016
  inputPurged++;
2944
3017
  }
@@ -6574,12 +6647,13 @@ function registerSurfacesGateway(api, state2) {
6574
6647
  respond(true, { surfaces: [] });
6575
6648
  return;
6576
6649
  }
6650
+ const FLOW_INPUT_IDS = new Set(["welcome-input"]);
6577
6651
  for (const [surfaceId, meta] of state2.surfaceDb.entries()) {
6578
6652
  if (isExpired(meta, now))
6579
6653
  continue;
6580
6654
  const headerLine = meta.lines[0] ?? "";
6581
6655
  const isInput = /\binput\b/.test(headerLine);
6582
- if (isInput)
6656
+ if (isInput && !FLOW_INPUT_IDS.has(surfaceId))
6583
6657
  continue;
6584
6658
  if (meta.lines.length > 0) {
6585
6659
  surfaceEntries.push({ surfaceId, dsl: meta.lines.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlife",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "bun build index.ts --outfile dist/index.js --target node --external openclaw/plugin-sdk",