agentlife 2.2.0 → 2.3.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 +34 -44
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2807,29 +2807,27 @@ function renderAllAgentWidgets(state, runtime, log) {
2807
2807
  var WELCOME_SURFACE_ID = "welcome";
2808
2808
  var WELCOME_INPUT_SURFACE_ID = "welcome-input";
2809
2809
  var ONBOARDING_SESSION_KEY = "agent:agentlife-builder:agentlife:onboarding:operator";
2810
- var ONBOARDING_PLAYBOOK = `[system:onboarding]
2810
+ var ONBOARDING_PLAYBOOK = `## Zero-agent onboarding
2811
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.
2812
+ You are agent-builder running a one-time onboarding for a fresh user (no agents yet). The plugin already pushed a \`welcome-input\` surface; the user's reply in this session is a tap or text on that surface.
2813
2813
 
2814
- Your job: run a 2–4 turn guided interview, then create ONE **generalist** agent for the user (not a narrow specialist).
2814
+ Run a 2–4 turn guided interview, then create ONE **generalist** agent.
2815
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)
2816
+ Each turn:
2817
+ 1. Decide: do you have enough signal? Minimum = name/persona hint + 2–3 concrete life areas. Don't drag past 4 turns.
2818
+ 2. Not enough \`agentlife_push\` the SAME surfaceId \`welcome-input\` with:
2819
+ - h3 question generated from what the user just said
2820
+ - 2–4 multichoice buttons \`action=choice\`, options derived from the user's own words (NEVER hardcoded domain lists)
2821
2821
  - \`textfield placeholder="Something else…"\` escape hatch
2822
2822
  - updated \`context: {"phase":"welcome","turn":N+1,"answers":[...]}\`
2823
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.
2824
+ Respond \`done\`.
2825
+ 3. Enough create the generalist:
2826
+ - Workspace under \`$HOME/.openclaw/workspace-{id}\` (id = slugified short name or "me")
2827
+ - \`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")
2828
+ - \`SOUL.md\`, \`IDENTITY.md\`, \`USER.md\` (user's own words), \`HEARTBEAT.md\` (empty)
2829
+ - \`exec openclaw gateway call agentlife.createAgent --params '{...}'\` with \`tools: {profile:"full"}\`. Plugin auto-deletes welcome + welcome-input and renders {id}-intro — do NOT push an intro.
2830
2830
  - Respond \`done\`.
2831
-
2832
- The user's first reply follows this system preamble. Proceed.
2833
2831
  `;
2834
2832
  function renderWelcomeWidget(state, log) {
2835
2833
  const welcomeDsl = [
@@ -2862,25 +2860,6 @@ function renderWelcomeWidget(state, log) {
2862
2860
  pluginPushSurface(state, { agentId: "agentlife-builder", dsl: welcomeInputDsl });
2863
2861
  state.surfaceDb?.setOriginSessionKey(WELCOME_INPUT_SURFACE_ID, ONBOARDING_SESSION_KEY);
2864
2862
  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
2863
  }
2885
2864
  function deleteWelcomeWidget(state, log) {
2886
2865
  for (const id of [WELCOME_SURFACE_ID, WELCOME_INPUT_SURFACE_ID]) {
@@ -3004,11 +2983,14 @@ function registerSurfacesService(api, state) {
3004
2983
  state.surfaceDb = new SurfaceDb(db);
3005
2984
  }
3006
2985
  runStartupPurge(state);
2986
+ const FLOW_INPUT_IDS = new Set(["welcome-input"]);
3007
2987
  let inputPurged = 0;
3008
2988
  for (const [surfaceId, meta] of state.surfaceDb.entries()) {
3009
2989
  const headerLine = meta.lines[0] ?? "";
3010
2990
  if (!/\binput\b/.test(headerLine))
3011
2991
  continue;
2992
+ if (FLOW_INPUT_IDS.has(surfaceId))
2993
+ continue;
3012
2994
  state.surfaceDb.delete(surfaceId);
3013
2995
  inputPurged++;
3014
2996
  }
@@ -6123,23 +6105,30 @@ function registerPromptStateHook(api, state2) {
6123
6105
  api.on("before_prompt_build", (event, ctx) => {
6124
6106
  if (state2.disabled)
6125
6107
  return;
6126
- if (!isAgentlifeSession(ctx?.sessionKey))
6108
+ const sessionKey = ctx?.sessionKey;
6109
+ if (!isAgentlifeSession(sessionKey))
6127
6110
  return;
6128
6111
  const agentId = ctx?.agentId;
6129
6112
  const isOrchestrator = agentId === "agentlife";
6130
6113
  if (isOrchestrator)
6131
6114
  return;
6132
- if (isInternalSession(ctx?.sessionKey))
6115
+ if (isInternalSession(sessionKey))
6133
6116
  return;
6134
6117
  const dashboardState = buildDashboardStateContext(state2, agentId);
6135
- if (!dashboardState) {
6136
- console.log("[agentlife:prompt-state] agentId=%s no dashboard state (surfaceDb size=%d)", agentId ?? "NONE", state2.surfaceDb?.size ?? 0);
6118
+ const isOnboarding = sessionKey === ONBOARDING_SESSION_KEY;
6119
+ const appendSystemContext = isOnboarding ? dashboardState ? `${ONBOARDING_PLAYBOOK}
6120
+
6121
+ ${dashboardState}` : ONBOARDING_PLAYBOOK : dashboardState;
6122
+ if (!appendSystemContext) {
6123
+ console.log("[agentlife:prompt-state] agentId=%s — no context to inject (surfaceDb size=%d)", agentId ?? "NONE", state2.surfaceDb?.size ?? 0);
6137
6124
  return;
6138
6125
  }
6139
- console.log("[agentlife:prompt-state] agentId=%s injecting %d chars dashboard state", agentId ?? "NONE", dashboardState.length);
6140
- return {
6141
- appendSystemContext: dashboardState
6142
- };
6126
+ if (isOnboarding) {
6127
+ console.log("[agentlife:prompt-state] onboarding session — injecting %d chars (playbook + dashboard)", appendSystemContext.length);
6128
+ } else {
6129
+ console.log("[agentlife:prompt-state] agentId=%s injecting %d chars dashboard state", agentId ?? "NONE", appendSystemContext.length);
6130
+ }
6131
+ return { appendSystemContext };
6143
6132
  });
6144
6133
  }
6145
6134
 
@@ -6644,12 +6633,13 @@ function registerSurfacesGateway(api, state2) {
6644
6633
  respond(true, { surfaces: [] });
6645
6634
  return;
6646
6635
  }
6636
+ const FLOW_INPUT_IDS = new Set(["welcome-input"]);
6647
6637
  for (const [surfaceId, meta] of state2.surfaceDb.entries()) {
6648
6638
  if (isExpired(meta, now))
6649
6639
  continue;
6650
6640
  const headerLine = meta.lines[0] ?? "";
6651
6641
  const isInput = /\binput\b/.test(headerLine);
6652
- if (isInput)
6642
+ if (isInput && !FLOW_INPUT_IDS.has(surfaceId))
6653
6643
  continue;
6654
6644
  if (meta.lines.length > 0) {
6655
6645
  surfaceEntries.push({ surfaceId, dsl: meta.lines.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlife",
3
- "version": "2.2.0",
3
+ "version": "2.3.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",