agentlife 2.6.11 → 2.6.13
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 +43 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -908,12 +908,9 @@ All inter-system signals are fixed strings. Nothing else is a signal.
|
|
|
908
908
|
**Work-order markers — you RECEIVE (always process, never treat as end-of-conversation):**
|
|
909
909
|
- \`[action:<name>] surfaceId=<id> [key=value ...]\` — user tapped a button on a widget you own. \`<name>\` is whatever you put in \`action=\` when you pushed the widget. Process it, then update or delete the source widget in the same turn.
|
|
910
910
|
- \`[system:dismiss-requested] surfaceId=<id>\` — user tapped dismiss on a widget. You have ~30s to push an \`input\` surface with contextual alternatives before the platform finalizes the dismiss.
|
|
911
|
-
- \`[event:dismissed] surfaceId=<id>\` — dismiss
|
|
911
|
+
- \`[event:dismissed] surfaceId=<id>\` — the platform deleted a widget without your involvement (non-guided dismiss path). The widget is already gone — do NOT push \`delete\`. Clean up any custom infra tied to the surface, then \`NO_REPLY\`. Does NOT fire for widgets you deleted yourself with the \`delete\` DSL — no notification is needed when you initiated the delete.
|
|
912
912
|
- \`[system:cancelled]\` — user cancelled the turn mid-flight. Reply \`NO_REPLY\` and stop.
|
|
913
|
-
|
|
914
|
-
**Input-surface control signals — platform EMITS when the user closes/skips an input surface:**
|
|
915
|
-
- \`input_closed\` — user tapped the [×] on an input surface. Push it again later if still relevant.
|
|
916
|
-
- \`input_skipped\` — user tapped Skip. Do not re-ask this session.
|
|
913
|
+
- \`[system] <free-form text>\` — platform-generated instruction (scheduled followup firing, Supervisor notification, quality/regression signal). The \`<text>\` after \`[system] \` is the instruction; read it and act. No fixed playbook — the text is the playbook.
|
|
917
914
|
|
|
918
915
|
**Input-surface \`action=\` values — canonical set (anything else is a QUALITY ERROR on input surfaces):**
|
|
919
916
|
- \`action=choice\` or \`action=select\` → numbered single-select (one tap fires). Dispatched as \`[action:choice] label=<label>\`.
|
|
@@ -954,7 +951,7 @@ A widget is a **goal** — a persistent objective that lives on the dashboard un
|
|
|
954
951
|
|
|
955
952
|
**Goal validation:** could you have written this goal text BEFORE doing the work? If yes, it's a template — the goal must be derived from your findings. For one-shot operations, the goal is the unresolved question, decision, or opportunity your work surfaces.
|
|
956
953
|
|
|
957
|
-
**Face vs detail.** Face = metrics, badges, gauges, one-line headers (2-second glance).
|
|
954
|
+
**Face vs detail.** Face = metrics, badges, gauges, one-line headers (2-second glance). \`detail:\` = markdown: analysis, trends, patterns, next-step context, personality. Every final (non-loading, non-input) widget MUST include \`detail:\` — that is where your expertise and voice live. Without it the widget is just a receipt and the platform enforces with a QUALITY ERROR. If you genuinely have nothing meaningful to add beyond the face, the goal is too shallow — rethink the goal before pushing an empty-detail widget.
|
|
958
955
|
|
|
959
956
|
### surfaceId
|
|
960
957
|
|
|
@@ -993,7 +990,7 @@ Button shapes and dispatch format for input surfaces are in **Signal Protocol**
|
|
|
993
990
|
|
|
994
991
|
**One widget, one goal.** Set at creation, MUST NOT change. If an action shifts the objective, delete and create with a new surfaceId. Platform rejects goal mutations with a QUALITY ERROR.
|
|
995
992
|
|
|
996
|
-
**User-initiated dismiss** (\`[system:dismiss-requested] surfaceId=<id>\`): you have ~30s to push an \`input\` surface with 2-3 contextual options + "Remove it" last. If the user picks an alternative, act on it and the dismiss is cancelled. If the user picks "Remove it" or
|
|
993
|
+
**User-initiated dismiss** (\`[system:dismiss-requested] surfaceId=<id>\`): you have ~30s to push an \`input\` surface with 2-3 contextual options + "Remove it" last. If the user picks an alternative, act on it and the dismiss is cancelled. If the user picks "Remove it" or the followup fires on timeout, push \`delete <parentSurfaceId>\` to finalize removal (and delete the dismiss-alt input surface in the same block). See \`DISMISS_ALTERNATIVES_GUIDANCE\` (injected on the dismiss event) for crafting rules.
|
|
997
994
|
|
|
998
995
|
### Autonomy & approval
|
|
999
996
|
|
|
@@ -1223,7 +1220,11 @@ The user is dismissing this widget. You have ~30s to push an \`input\` surface w
|
|
|
1223
1220
|
- "Remove it" is always last. Use \`action=choice\` so it renders as a numbered list.
|
|
1224
1221
|
- surfaceId: \`dismiss-alt-{parent-surfaceId}\`. Goal: reference the parent. Followup: ~1m so the flow doesn't stall if the user walks away.
|
|
1225
1222
|
|
|
1226
|
-
If the user picks an alternative → act on it; the dismiss is cancelled.
|
|
1223
|
+
If the user picks an alternative → act on it; the dismiss is cancelled.
|
|
1224
|
+
|
|
1225
|
+
If the user picks "Remove it" → push \`delete <parentSurfaceId>\` in the same turn (and delete the dismiss-alt input surface alongside it; both go in one \`agentlife_push\` with \`---\` between them). No \`[event:dismissed]\` fires in the guided flow — you initiated the delete, so no notification is needed. Clean up any custom infra inline before the delete.
|
|
1226
|
+
|
|
1227
|
+
If the 1-minute followup fires with no user response → same move: push \`delete <parentSurfaceId>\` + \`delete dismiss-alt-<parentSurfaceId>\`.`;
|
|
1227
1228
|
var ORCHESTRATOR_AGENTS_MD = `# AgentLife Orchestrator
|
|
1228
1229
|
|
|
1229
1230
|
You are a message router. You never answer questions, perform tasks, push widgets, or produce content.
|
|
@@ -1918,6 +1919,27 @@ function matchMetadata(block, key) {
|
|
|
1918
1919
|
}
|
|
1919
1920
|
return v || null;
|
|
1920
1921
|
}
|
|
1922
|
+
function hasDetailContent(rawDsl) {
|
|
1923
|
+
const lines = rawDsl.split(`
|
|
1924
|
+
`);
|
|
1925
|
+
for (let i = 0;i < lines.length; i++) {
|
|
1926
|
+
const m = lines[i].match(/^\s*detail:\s*(.*)$/);
|
|
1927
|
+
if (!m)
|
|
1928
|
+
continue;
|
|
1929
|
+
if (m[1].trim())
|
|
1930
|
+
return true;
|
|
1931
|
+
for (let j = i + 1;j < lines.length; j++) {
|
|
1932
|
+
const next = lines[j];
|
|
1933
|
+
if (next.trim() === "")
|
|
1934
|
+
continue;
|
|
1935
|
+
if (/^\s/.test(next))
|
|
1936
|
+
return true;
|
|
1937
|
+
return false;
|
|
1938
|
+
}
|
|
1939
|
+
return false;
|
|
1940
|
+
}
|
|
1941
|
+
return false;
|
|
1942
|
+
}
|
|
1921
1943
|
|
|
1922
1944
|
// dsl/validate.ts
|
|
1923
1945
|
var KNOWN_BODY_KEYWORDS = new Set([
|
|
@@ -4724,7 +4746,7 @@ ${parts.join(`
|
|
|
4724
4746
|
});
|
|
4725
4747
|
}
|
|
4726
4748
|
var QUALITY_CHECK_MAX_WAIT_MS = 5000;
|
|
4727
|
-
var TERMINAL_MARKERS = new Set(["NO_REPLY", "ANNOUNCE_SKIP", "REPLY_SKIP", "HEARTBEAT_OK"
|
|
4749
|
+
var TERMINAL_MARKERS = new Set(["NO_REPLY", "ANNOUNCE_SKIP", "REPLY_SKIP", "HEARTBEAT_OK"]);
|
|
4728
4750
|
function processPendingQualityChecks(state) {
|
|
4729
4751
|
if (state.disabled || !state.historyDb)
|
|
4730
4752
|
return 0;
|
|
@@ -6316,6 +6338,7 @@ function registerWidgetPushTool(api, state2) {
|
|
|
6316
6338
|
const errors = [];
|
|
6317
6339
|
const goalChanges = [];
|
|
6318
6340
|
const missingFollowup = [];
|
|
6341
|
+
const missingDetail = [];
|
|
6319
6342
|
for (const r of results) {
|
|
6320
6343
|
if (r.kind !== "push")
|
|
6321
6344
|
continue;
|
|
@@ -6334,11 +6357,19 @@ function registerWidgetPushTool(api, state2) {
|
|
|
6334
6357
|
data: JSON.stringify({ issue: "missing_followup", surfaceId: r.surfaceId })
|
|
6335
6358
|
});
|
|
6336
6359
|
}
|
|
6360
|
+
if (view && view.state !== "loading" && !view.isInput && !hasDetailContent(view.rawDsl) && !goalChanges.includes(r.surfaceId) && !missingFollowup.includes(r.surfaceId)) {
|
|
6361
|
+
missingDetail.push(r.surfaceId);
|
|
6362
|
+
recordActivity(state2, "quality_warning", sessionKey, agentId, {
|
|
6363
|
+
data: JSON.stringify({ issue: "missing_detail", surfaceId: r.surfaceId })
|
|
6364
|
+
});
|
|
6365
|
+
}
|
|
6337
6366
|
}
|
|
6338
6367
|
if (goalChanges.length > 0)
|
|
6339
6368
|
errors.push(buildGoalChangedError(goalChanges));
|
|
6340
6369
|
if (missingFollowup.length > 0)
|
|
6341
6370
|
errors.push(buildMissingFollowupError(missingFollowup));
|
|
6371
|
+
if (missingDetail.length > 0)
|
|
6372
|
+
errors.push(buildMissingDetailError(missingDetail));
|
|
6342
6373
|
const validationErrors = collectValidationErrors(state2, results, sessionKey, agentId);
|
|
6343
6374
|
errors.push(...validationErrors);
|
|
6344
6375
|
if (ownershipViolations.length > 0) {
|
|
@@ -6370,6 +6401,9 @@ function buildGoalChangedError(ids) {
|
|
|
6370
6401
|
function buildMissingFollowupError(ids) {
|
|
6371
6402
|
return `[QUALITY ERROR] ${ids.join(", ")}: missing followup. Every widget MUST have a followup — it is the widget's heartbeat and ownership signal. Push again with a followup: line, or delete the widget if work is done.`;
|
|
6372
6403
|
}
|
|
6404
|
+
function buildMissingDetailError(ids) {
|
|
6405
|
+
return `[QUALITY ERROR] ${ids.join(", ")}: missing detail. Every final widget MUST include a \`detail:\` block — it's where your analysis, trends, and voice live. The face alone is just a receipt. Push again with a detail: block containing analysis/personality/next-step context appropriate to the domain.`;
|
|
6406
|
+
}
|
|
6373
6407
|
function collectValidationErrors(state2, results, sessionKey, agentId) {
|
|
6374
6408
|
const errors = [];
|
|
6375
6409
|
const unknownKeywordHits = [];
|