@useorgx/openclaw-plugin 0.4.9 → 0.7.2
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/README.md +77 -11
- package/dashboard/dist/assets/6mILZQ2a.js +1 -0
- package/dashboard/dist/assets/6mILZQ2a.js.br +0 -0
- package/dashboard/dist/assets/6mILZQ2a.js.gz +0 -0
- package/dashboard/dist/assets/8dksYiq4.js +2 -0
- package/dashboard/dist/assets/8dksYiq4.js.br +0 -0
- package/dashboard/dist/assets/8dksYiq4.js.gz +0 -0
- package/dashboard/dist/assets/B5zYRHc3.js +1 -0
- package/dashboard/dist/assets/B5zYRHc3.js.br +0 -0
- package/dashboard/dist/assets/B5zYRHc3.js.gz +0 -0
- package/dashboard/dist/assets/B6wPWJ35.js +1 -0
- package/dashboard/dist/assets/B6wPWJ35.js.br +0 -0
- package/dashboard/dist/assets/B6wPWJ35.js.gz +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
- package/dashboard/dist/assets/BWEwjt1W.js +1 -0
- package/dashboard/dist/assets/BWEwjt1W.js.br +0 -0
- package/dashboard/dist/assets/BWEwjt1W.js.gz +0 -0
- package/dashboard/dist/assets/BgOYB78t.js +4 -0
- package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
- package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
- package/dashboard/dist/assets/BzRbDCAD.css +1 -0
- package/dashboard/dist/assets/BzRbDCAD.css.br +0 -0
- package/dashboard/dist/assets/BzRbDCAD.css.gz +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/C8uM3AX8.js +1 -0
- package/dashboard/dist/assets/C8uM3AX8.js.br +0 -0
- package/dashboard/dist/assets/C8uM3AX8.js.gz +0 -0
- package/dashboard/dist/assets/C9jy61eu.js +212 -0
- package/dashboard/dist/assets/C9jy61eu.js.br +0 -0
- package/dashboard/dist/assets/C9jy61eu.js.gz +0 -0
- package/dashboard/dist/assets/CC63EwFD.js +1 -0
- package/dashboard/dist/assets/CC63EwFD.js.br +0 -0
- package/dashboard/dist/assets/CC63EwFD.js.gz +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js +1 -0
- package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
- package/dashboard/dist/assets/CZaT3ob_.js +1 -0
- package/dashboard/dist/assets/CZaT3ob_.js.br +0 -0
- package/dashboard/dist/assets/CZaT3ob_.js.gz +0 -0
- package/dashboard/dist/assets/CgaottFX.js +1 -0
- package/dashboard/dist/assets/CgaottFX.js.br +0 -0
- package/dashboard/dist/assets/CgaottFX.js.gz +0 -0
- package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
- package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
- package/dashboard/dist/assets/CzCxAZlW.js +1 -0
- package/dashboard/dist/assets/CzCxAZlW.js.br +0 -0
- package/dashboard/dist/assets/CzCxAZlW.js.gz +0 -0
- package/dashboard/dist/assets/D3iMTYEj.js +1 -0
- package/dashboard/dist/assets/D3iMTYEj.js.br +0 -0
- package/dashboard/dist/assets/D3iMTYEj.js.gz +0 -0
- package/dashboard/dist/assets/D8JNX8kq.js +2 -0
- package/dashboard/dist/assets/D8JNX8kq.js.br +0 -0
- package/dashboard/dist/assets/D8JNX8kq.js.gz +0 -0
- package/dashboard/dist/assets/DnA8dpj6.js +1 -0
- package/dashboard/dist/assets/DnA8dpj6.js.br +0 -0
- package/dashboard/dist/assets/DnA8dpj6.js.gz +0 -0
- package/dashboard/dist/assets/IUexzymk.js +1 -0
- package/dashboard/dist/assets/IUexzymk.js.br +0 -0
- package/dashboard/dist/assets/IUexzymk.js.gz +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js +8 -0
- package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js +1 -0
- package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css +1 -0
- package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
- package/dashboard/dist/assets/rttbDbEx.js +1 -0
- package/dashboard/dist/assets/rttbDbEx.js.br +0 -0
- package/dashboard/dist/assets/rttbDbEx.js.gz +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openai-mark.svg.br +0 -0
- package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
- package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
- package/dashboard/dist/index.html +7 -5
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-actor-fields.js +26 -4
- package/dist/activity-store.js +34 -8
- package/dist/agent-context-store.js +79 -17
- package/dist/agent-run-store.js +44 -3
- package/dist/agent-suite.d.ts +9 -0
- package/dist/agent-suite.js +149 -9
- package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
- package/dist/artifacts/artifact-domain-schemas.js +357 -0
- package/dist/artifacts/register-artifact.d.ts +4 -3
- package/dist/artifacts/register-artifact.js +170 -57
- package/dist/chat-store.d.ts +157 -0
- package/dist/chat-store.js +586 -0
- package/dist/cli/orgx.js +11 -0
- package/dist/contracts/client.d.ts +43 -3
- package/dist/contracts/client.js +159 -30
- package/dist/contracts/practice-exercise-schema.d.ts +216 -0
- package/dist/contracts/practice-exercise-schema.js +314 -0
- package/dist/contracts/retro-schema.d.ts +81 -0
- package/dist/contracts/retro-schema.js +80 -0
- package/dist/contracts/shared-types.d.ts +159 -0
- package/dist/contracts/shared-types.js +199 -1
- package/dist/contracts/skill-pack-schema.d.ts +192 -0
- package/dist/contracts/skill-pack-schema.js +180 -0
- package/dist/contracts/types.d.ts +247 -2
- package/dist/entities/auto-assignment.js +43 -17
- package/dist/event-sanitization.d.ts +11 -0
- package/dist/event-sanitization.js +113 -0
- package/dist/gateway-watchdog.d.ts +5 -0
- package/dist/gateway-watchdog.js +50 -0
- package/dist/hooks/post-reporting-event.mjs +1 -5
- package/dist/http/helpers/activity-headline.js +13 -132
- package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
- package/dist/http/helpers/auto-continue-engine.js +3145 -186
- package/dist/http/helpers/autopilot-operations.d.ts +19 -0
- package/dist/http/helpers/autopilot-operations.js +182 -31
- package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
- package/dist/http/helpers/autopilot-runtime.js +328 -25
- package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
- package/dist/http/helpers/autopilot-slice-utils.js +514 -93
- package/dist/http/helpers/decision-mapper.d.ts +40 -0
- package/dist/http/helpers/decision-mapper.js +223 -7
- package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
- package/dist/http/helpers/dispatch-lifecycle.js +242 -37
- package/dist/http/helpers/kickoff-context.js +104 -0
- package/dist/http/helpers/llm-client.d.ts +47 -0
- package/dist/http/helpers/llm-client.js +256 -0
- package/dist/http/helpers/mission-control.d.ts +102 -3
- package/dist/http/helpers/mission-control.js +498 -9
- package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
- package/dist/http/helpers/sentinel-catalog.js +193 -0
- package/dist/http/helpers/session-classification.d.ts +9 -0
- package/dist/http/helpers/session-classification.js +564 -0
- package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
- package/dist/http/helpers/slice-experience-v2.js +677 -0
- package/dist/http/helpers/slice-run-projections.d.ts +72 -0
- package/dist/http/helpers/slice-run-projections.js +877 -0
- package/dist/http/helpers/triage-mapper.d.ts +43 -0
- package/dist/http/helpers/triage-mapper.js +549 -0
- package/dist/http/helpers/value-utils.js +7 -2
- package/dist/http/helpers/workspace-scope.d.ts +15 -0
- package/dist/http/helpers/workspace-scope.js +170 -0
- package/dist/http/index.js +1420 -105
- package/dist/http/routes/agent-suite.d.ts +9 -0
- package/dist/http/routes/agent-suite.js +294 -8
- package/dist/http/routes/agents-catalog.js +64 -19
- package/dist/http/routes/chat.d.ts +19 -0
- package/dist/http/routes/chat.js +522 -0
- package/dist/http/routes/decision-actions.d.ts +8 -1
- package/dist/http/routes/decision-actions.js +42 -5
- package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
- package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
- package/dist/http/routes/entities.d.ts +16 -0
- package/dist/http/routes/entities.js +232 -6
- package/dist/http/routes/live-legacy.d.ts +5 -0
- package/dist/http/routes/live-legacy.js +23 -509
- package/dist/http/routes/live-misc.d.ts +12 -0
- package/dist/http/routes/live-misc.js +251 -31
- package/dist/http/routes/live-snapshot.d.ts +49 -2
- package/dist/http/routes/live-snapshot.js +653 -23
- package/dist/http/routes/live-terminal.d.ts +11 -0
- package/dist/http/routes/live-terminal.js +154 -0
- package/dist/http/routes/live-triage.d.ts +61 -0
- package/dist/http/routes/live-triage.js +192 -0
- package/dist/http/routes/mission-control-actions.d.ts +49 -1
- package/dist/http/routes/mission-control-actions.js +1246 -84
- package/dist/http/routes/mission-control-read.d.ts +48 -3
- package/dist/http/routes/mission-control-read.js +1658 -20
- package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
- package/dist/http/routes/realtime-orchestrator.js +74 -0
- package/dist/http/routes/run-control.d.ts +5 -2
- package/dist/http/routes/run-control.js +10 -0
- package/dist/http/routes/sentinels-catalog.d.ts +7 -0
- package/dist/http/routes/sentinels-catalog.js +24 -0
- package/dist/http/routes/summary.js +10 -3
- package/dist/http/routes/usage.d.ts +24 -0
- package/dist/http/routes/usage.js +362 -0
- package/dist/http/routes/work-artifacts.js +28 -9
- package/dist/index.js +165 -27
- package/dist/local-openclaw.js +29 -6
- package/dist/mcp-client-setup.js +3 -3
- package/dist/mcp-http-handler.d.ts +3 -0
- package/dist/mcp-http-handler.js +34 -60
- package/dist/next-up-queue-store.d.ts +16 -1
- package/dist/next-up-queue-store.js +89 -7
- package/dist/outbox.d.ts +5 -0
- package/dist/outbox.js +113 -9
- package/dist/paths.js +36 -5
- package/dist/reporting/rollups.d.ts +41 -0
- package/dist/reporting/rollups.js +113 -0
- package/dist/retro/domain-templates.d.ts +45 -0
- package/dist/retro/domain-templates.js +297 -0
- package/dist/retro/quality-rubric.d.ts +33 -0
- package/dist/retro/quality-rubric.js +213 -0
- package/dist/runtime-cleanup.d.ts +18 -0
- package/dist/runtime-cleanup.js +87 -0
- package/dist/services/background.d.ts +11 -0
- package/dist/services/background.js +22 -0
- package/dist/services/experiment-randomization.d.ts +21 -0
- package/dist/services/experiment-randomization.js +63 -0
- package/dist/skill-pack-state.d.ts +36 -5
- package/dist/skill-pack-state.js +273 -29
- package/dist/sync/local-agent-telemetry.d.ts +13 -0
- package/dist/sync/local-agent-telemetry.js +128 -0
- package/dist/sync/outbox-replay.js +131 -24
- package/dist/team-context-store.d.ts +23 -0
- package/dist/team-context-store.js +116 -0
- package/dist/telemetry/posthog.js +4 -2
- package/dist/tools/core-tools.d.ts +10 -14
- package/dist/tools/core-tools.js +1289 -24
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/worker-supervisor.js +23 -0
- package/package.json +20 -6
- package/dashboard/dist/assets/B3ziCA02.js +0 -8
- package/dashboard/dist/assets/B5NEElEI.css +0 -1
- package/dashboard/dist/assets/BhapSNAs.js +0 -215
- package/dashboard/dist/assets/iFdvE7lx.js +0 -1
- package/dashboard/dist/assets/jRJsmpYM.js +0 -1
- package/dashboard/dist/assets/sAhvFnpk.js +0 -4
|
@@ -1,8 +1,65 @@
|
|
|
1
1
|
import { appendToOutbox } from "../../outbox.js";
|
|
2
2
|
import { computeMilestoneRollup, computeWorkstreamRollup, } from "../../reporting/rollups.js";
|
|
3
3
|
import { readSkillPackState } from "../../skill-pack-state.js";
|
|
4
|
+
import { normalizeDecisionActionType } from "../../contracts/shared-types.js";
|
|
4
5
|
import { buildMissionControlGraph, deriveExecutionPolicy, inferExecutionDomainFromText, normalizeExecutionDomain, ORGX_SKILL_BY_DOMAIN, spawnGuardIsRateLimited, summarizeSpawnGuardBlockReason, } from "./mission-control.js";
|
|
5
6
|
export function createDispatchLifecycle(deps) {
|
|
7
|
+
const decisionV2Enabled = String(process.env.DECISION_V2_ENABLED ?? "true").trim().toLowerCase() !== "false";
|
|
8
|
+
const decisionDedupeEnabled = String(process.env.DECISION_DEDUPE_ENABLED ?? "true").trim().toLowerCase() !== "false";
|
|
9
|
+
const decisionEvidenceRequiredForBlocking = String(process.env.DECISION_EVIDENCE_REQUIRED_FOR_BLOCKING ?? "false")
|
|
10
|
+
.trim()
|
|
11
|
+
.toLowerCase() === "true";
|
|
12
|
+
const asRecord = (value) => {
|
|
13
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
14
|
+
return null;
|
|
15
|
+
return value;
|
|
16
|
+
};
|
|
17
|
+
const extractDecisionIdsFromChangesetResults = (value) => {
|
|
18
|
+
if (!Array.isArray(value))
|
|
19
|
+
return [];
|
|
20
|
+
const ids = [];
|
|
21
|
+
const seen = new Set();
|
|
22
|
+
const pushId = (candidate) => {
|
|
23
|
+
if (typeof candidate !== "string")
|
|
24
|
+
return;
|
|
25
|
+
const id = candidate.trim();
|
|
26
|
+
if (!id || seen.has(id))
|
|
27
|
+
return;
|
|
28
|
+
seen.add(id);
|
|
29
|
+
ids.push(id);
|
|
30
|
+
};
|
|
31
|
+
for (const entry of value) {
|
|
32
|
+
const record = asRecord(entry);
|
|
33
|
+
if (!record)
|
|
34
|
+
continue;
|
|
35
|
+
pushId(record.decision_id);
|
|
36
|
+
pushId(record.decisionId);
|
|
37
|
+
const directDecision = asRecord(record.decision);
|
|
38
|
+
if (directDecision) {
|
|
39
|
+
pushId(directDecision.id);
|
|
40
|
+
pushId(directDecision.decision_id);
|
|
41
|
+
pushId(directDecision.decisionId);
|
|
42
|
+
}
|
|
43
|
+
const entityType = (typeof record.entity_type === "string" ? record.entity_type : null) ??
|
|
44
|
+
(typeof record.entityType === "string" ? record.entityType : null);
|
|
45
|
+
if (entityType && entityType.trim().toLowerCase() === "decision") {
|
|
46
|
+
pushId(record.entity_id);
|
|
47
|
+
pushId(record.entityId);
|
|
48
|
+
pushId(record.id);
|
|
49
|
+
}
|
|
50
|
+
const created = asRecord(record.created);
|
|
51
|
+
if (created) {
|
|
52
|
+
const createdType = (typeof created.entity_type === "string" ? created.entity_type : null) ??
|
|
53
|
+
(typeof created.entityType === "string" ? created.entityType : null);
|
|
54
|
+
if (createdType && createdType.trim().toLowerCase() === "decision") {
|
|
55
|
+
pushId(created.entity_id);
|
|
56
|
+
pushId(created.entityId);
|
|
57
|
+
pushId(created.id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return ids;
|
|
62
|
+
};
|
|
6
63
|
function withProvenanceMetadata(metadata) {
|
|
7
64
|
const input = metadata ?? {};
|
|
8
65
|
const out = { ...input };
|
|
@@ -62,6 +119,14 @@ export function createDispatchLifecycle(deps) {
|
|
|
62
119
|
const message = input.message.trim();
|
|
63
120
|
if (!message)
|
|
64
121
|
return;
|
|
122
|
+
const normalizedRunId = input.runId?.trim() || null;
|
|
123
|
+
const normalizedCorrelationId = normalizedRunId ? null : (input.correlationId?.trim() || `openclaw-${Date.now()}`);
|
|
124
|
+
const canonicalMetadata = {
|
|
125
|
+
initiative_id: initiativeId,
|
|
126
|
+
run_id: normalizedRunId,
|
|
127
|
+
slice_run_id: normalizedRunId,
|
|
128
|
+
correlation_id: normalizedCorrelationId,
|
|
129
|
+
};
|
|
65
130
|
const metadataWithProvenance = withProvenanceMetadata(input.metadata);
|
|
66
131
|
const activityBucket = deps.deriveStructuredActivityBucket({
|
|
67
132
|
phase: input.phase,
|
|
@@ -70,15 +135,14 @@ export function createDispatchLifecycle(deps) {
|
|
|
70
135
|
});
|
|
71
136
|
const enrichedMetadata = {
|
|
72
137
|
...(metadataWithProvenance ?? {}),
|
|
138
|
+
...canonicalMetadata,
|
|
73
139
|
activity_bucket: activityBucket,
|
|
74
140
|
};
|
|
75
141
|
try {
|
|
76
142
|
await deps.client.emitActivity({
|
|
77
143
|
initiative_id: initiativeId,
|
|
78
|
-
run_id:
|
|
79
|
-
correlation_id:
|
|
80
|
-
? undefined
|
|
81
|
-
: (input.correlationId?.trim() || `openclaw-${Date.now()}`),
|
|
144
|
+
run_id: normalizedRunId ?? undefined,
|
|
145
|
+
correlation_id: normalizedCorrelationId ?? undefined,
|
|
82
146
|
source_client: "openclaw",
|
|
83
147
|
message,
|
|
84
148
|
phase: input.phase,
|
|
@@ -92,7 +156,7 @@ export function createDispatchLifecycle(deps) {
|
|
|
92
156
|
}
|
|
93
157
|
catch (err) {
|
|
94
158
|
const msg = deps.safeErrorMessage(err);
|
|
95
|
-
const runId =
|
|
159
|
+
const runId = normalizedRunId ?? "";
|
|
96
160
|
// If OrgX rejects an unknown run_id, retry by treating the local run_id as a
|
|
97
161
|
// correlation key (non-UUID) so OrgX can create/attach a run deterministically.
|
|
98
162
|
if (runId && /^404\b/.test(msg) && /\brun\b/i.test(msg) && /not found/i.test(msg)) {
|
|
@@ -124,9 +188,7 @@ export function createDispatchLifecycle(deps) {
|
|
|
124
188
|
// Fall back to local outbox so activity is still visible in Mission Control/Activity.
|
|
125
189
|
try {
|
|
126
190
|
const timestamp = new Date().toISOString();
|
|
127
|
-
const runId =
|
|
128
|
-
input.correlationId?.trim() ||
|
|
129
|
-
null;
|
|
191
|
+
const runId = normalizedRunId || normalizedCorrelationId || null;
|
|
130
192
|
const activityItem = {
|
|
131
193
|
id: deps.randomUUID(),
|
|
132
194
|
type: input.phase === "completed"
|
|
@@ -167,10 +229,8 @@ export function createDispatchLifecycle(deps) {
|
|
|
167
229
|
timestamp,
|
|
168
230
|
payload: {
|
|
169
231
|
initiative_id: initiativeId,
|
|
170
|
-
run_id:
|
|
171
|
-
correlation_id:
|
|
172
|
-
? undefined
|
|
173
|
-
: (input.correlationId?.trim() || `openclaw-${Date.now()}`),
|
|
232
|
+
run_id: normalizedRunId ?? undefined,
|
|
233
|
+
correlation_id: normalizedCorrelationId ?? undefined,
|
|
174
234
|
source_client: "openclaw",
|
|
175
235
|
message,
|
|
176
236
|
phase: input.phase,
|
|
@@ -192,10 +252,124 @@ export function createDispatchLifecycle(deps) {
|
|
|
192
252
|
async function requestDecisionSafe(input) {
|
|
193
253
|
const initiativeId = input.initiativeId?.trim() ?? "";
|
|
194
254
|
const title = input.title.trim();
|
|
195
|
-
if (!initiativeId || !title)
|
|
196
|
-
return;
|
|
255
|
+
if (!initiativeId || !title) {
|
|
256
|
+
return { queued: false, decisionIds: [] };
|
|
257
|
+
}
|
|
258
|
+
const normalizedOptions = [];
|
|
259
|
+
for (const entry of Array.isArray(input.options) ? input.options : []) {
|
|
260
|
+
if (typeof entry === "string") {
|
|
261
|
+
const label = entry.trim();
|
|
262
|
+
if (label.length > 0)
|
|
263
|
+
normalizedOptions.push(label);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
267
|
+
continue;
|
|
268
|
+
const record = entry;
|
|
269
|
+
const label = typeof record.label === "string" ? record.label.trim() : "";
|
|
270
|
+
if (!label)
|
|
271
|
+
continue;
|
|
272
|
+
const optionPayload = {
|
|
273
|
+
label,
|
|
274
|
+
};
|
|
275
|
+
if (typeof record.id === "string" && record.id.trim()) {
|
|
276
|
+
optionPayload.id = record.id.trim();
|
|
277
|
+
}
|
|
278
|
+
if (typeof record.description === "string" && record.description.trim()) {
|
|
279
|
+
optionPayload.description = record.description.trim();
|
|
280
|
+
}
|
|
281
|
+
if (typeof record.implied_status === "string" && record.implied_status.trim()) {
|
|
282
|
+
const implied = record.implied_status.trim().toLowerCase();
|
|
283
|
+
if (implied === "approved" ||
|
|
284
|
+
implied === "declined" ||
|
|
285
|
+
implied === "cancelled" ||
|
|
286
|
+
implied === "rejected") {
|
|
287
|
+
optionPayload.implied_status = implied;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const normalizedActionType = normalizeDecisionActionType(record.action_type ?? record.type ?? record.verb ?? record.action);
|
|
291
|
+
if (normalizedActionType) {
|
|
292
|
+
optionPayload.action_type = normalizedActionType;
|
|
293
|
+
}
|
|
294
|
+
if (record.requires_note === true) {
|
|
295
|
+
optionPayload.requires_note = true;
|
|
296
|
+
}
|
|
297
|
+
normalizedOptions.push(optionPayload);
|
|
298
|
+
}
|
|
299
|
+
const normalizedEvidenceRefs = (Array.isArray(input.evidenceRefs) ? input.evidenceRefs : [])
|
|
300
|
+
.map((entry) => (entry && typeof entry === "object" && !Array.isArray(entry) ? entry : null))
|
|
301
|
+
.filter((entry) => Boolean(entry));
|
|
302
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
303
|
+
const asUuid = (value) => {
|
|
304
|
+
const normalized = value?.trim() ?? "";
|
|
305
|
+
return uuidPattern.test(normalized) ? normalized : undefined;
|
|
306
|
+
};
|
|
307
|
+
const asIsoDateTime = (value) => {
|
|
308
|
+
const normalized = value?.trim() ?? "";
|
|
309
|
+
if (!normalized)
|
|
310
|
+
return undefined;
|
|
311
|
+
const epoch = Date.parse(normalized);
|
|
312
|
+
if (!Number.isFinite(epoch))
|
|
313
|
+
return undefined;
|
|
314
|
+
return new Date(epoch).toISOString();
|
|
315
|
+
};
|
|
316
|
+
const sourceRef = input.sourceRef && typeof input.sourceRef === "object" && !Array.isArray(input.sourceRef)
|
|
317
|
+
? input.sourceRef
|
|
318
|
+
: null;
|
|
319
|
+
const metadata = input.metadata && typeof input.metadata === "object" && !Array.isArray(input.metadata)
|
|
320
|
+
? input.metadata
|
|
321
|
+
: null;
|
|
322
|
+
const dedupeKey = input.dedupeKey?.trim() ||
|
|
323
|
+
`decision:${deps.stableHash([
|
|
324
|
+
initiativeId,
|
|
325
|
+
input.workstreamId?.trim() || "none",
|
|
326
|
+
input.conflictSource?.trim() || "general",
|
|
327
|
+
title.toLowerCase(),
|
|
328
|
+
].join("|")).slice(0, 24)}`;
|
|
329
|
+
const blocking = input.blocking ?? true;
|
|
330
|
+
const fallbackEvidenceRefs = blocking && decisionEvidenceRequiredForBlocking && normalizedEvidenceRefs.length === 0
|
|
331
|
+
? [
|
|
332
|
+
{
|
|
333
|
+
evidence_type: "decision_context",
|
|
334
|
+
title: "Decision context",
|
|
335
|
+
summary: input.summary?.trim() ||
|
|
336
|
+
"Blocking decision emitted without explicit evidence payload.",
|
|
337
|
+
payload: {
|
|
338
|
+
source_ref: sourceRef ?? null,
|
|
339
|
+
generated_by: "plugin_guardrail",
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
]
|
|
343
|
+
: [];
|
|
344
|
+
const effectiveEvidenceRefs = [...normalizedEvidenceRefs, ...fallbackEvidenceRefs];
|
|
345
|
+
const operation = {
|
|
346
|
+
op: "decision.create",
|
|
347
|
+
title,
|
|
348
|
+
summary: input.summary ?? undefined,
|
|
349
|
+
urgency: input.urgency ?? "high",
|
|
350
|
+
options: normalizedOptions,
|
|
351
|
+
blocking,
|
|
352
|
+
...(decisionV2Enabled
|
|
353
|
+
? {
|
|
354
|
+
decision_type: input.decisionType?.trim() || undefined,
|
|
355
|
+
workstream_id: asUuid(input.workstreamId),
|
|
356
|
+
agent_id: asUuid(input.agentId),
|
|
357
|
+
due_at: asIsoDateTime(input.dueAt),
|
|
358
|
+
source_system: input.sourceSystem?.trim() || "openclaw",
|
|
359
|
+
conflict_source: input.conflictSource?.trim() || undefined,
|
|
360
|
+
dedupe_key: decisionDedupeEnabled ? dedupeKey : undefined,
|
|
361
|
+
recommended_action: input.recommendedAction?.trim() || undefined,
|
|
362
|
+
source_run_id: asUuid(input.sourceRunId),
|
|
363
|
+
source_session_id: input.sourceSessionId?.trim() || undefined,
|
|
364
|
+
source_stream_id: asUuid(input.sourceStreamId),
|
|
365
|
+
source_ref: sourceRef ?? undefined,
|
|
366
|
+
evidence_refs: effectiveEvidenceRefs.length > 0 ? effectiveEvidenceRefs : undefined,
|
|
367
|
+
metadata: metadata ?? undefined,
|
|
368
|
+
}
|
|
369
|
+
: {}),
|
|
370
|
+
};
|
|
197
371
|
try {
|
|
198
|
-
await deps.client.applyChangeset({
|
|
372
|
+
const response = await deps.client.applyChangeset({
|
|
199
373
|
initiative_id: initiativeId,
|
|
200
374
|
correlation_id: input.correlationId?.trim() || undefined,
|
|
201
375
|
source_client: "openclaw",
|
|
@@ -203,34 +377,21 @@ export function createDispatchLifecycle(deps) {
|
|
|
203
377
|
"openclaw",
|
|
204
378
|
"decision",
|
|
205
379
|
initiativeId,
|
|
380
|
+
dedupeKey,
|
|
206
381
|
title,
|
|
207
382
|
input.correlationId ?? null,
|
|
208
383
|
]),
|
|
209
|
-
operations: [
|
|
210
|
-
{
|
|
211
|
-
op: "decision.create",
|
|
212
|
-
title,
|
|
213
|
-
summary: input.summary ?? undefined,
|
|
214
|
-
urgency: input.urgency ?? "high",
|
|
215
|
-
options: input.options ?? [],
|
|
216
|
-
blocking: input.blocking ?? true,
|
|
217
|
-
},
|
|
218
|
-
],
|
|
384
|
+
operations: [operation],
|
|
219
385
|
});
|
|
386
|
+
return {
|
|
387
|
+
queued: true,
|
|
388
|
+
decisionIds: extractDecisionIdsFromChangesetResults(response?.results),
|
|
389
|
+
};
|
|
220
390
|
}
|
|
221
391
|
catch (err) {
|
|
222
392
|
const timestamp = new Date().toISOString();
|
|
223
393
|
const correlationId = input.correlationId?.trim() || undefined;
|
|
224
|
-
const operations = [
|
|
225
|
-
{
|
|
226
|
-
op: "decision.create",
|
|
227
|
-
title,
|
|
228
|
-
summary: input.summary ?? undefined,
|
|
229
|
-
urgency: input.urgency ?? "high",
|
|
230
|
-
options: input.options ?? [],
|
|
231
|
-
blocking: input.blocking ?? true,
|
|
232
|
-
},
|
|
233
|
-
];
|
|
394
|
+
const operations = [operation];
|
|
234
395
|
const activityItem = {
|
|
235
396
|
id: deps.randomUUID(),
|
|
236
397
|
type: "decision_requested",
|
|
@@ -252,7 +413,17 @@ export function createDispatchLifecycle(deps) {
|
|
|
252
413
|
event: "decision_buffered",
|
|
253
414
|
urgency: input.urgency ?? "high",
|
|
254
415
|
blocking: input.blocking ?? true,
|
|
255
|
-
options:
|
|
416
|
+
options: normalizedOptions,
|
|
417
|
+
dedupe_key: decisionDedupeEnabled ? dedupeKey : null,
|
|
418
|
+
decision_type: decisionV2Enabled
|
|
419
|
+
? input.decisionType?.trim() || null
|
|
420
|
+
: null,
|
|
421
|
+
conflict_source: decisionV2Enabled
|
|
422
|
+
? input.conflictSource?.trim() || null
|
|
423
|
+
: null,
|
|
424
|
+
source_system: decisionV2Enabled
|
|
425
|
+
? input.sourceSystem?.trim() || "openclaw"
|
|
426
|
+
: "openclaw",
|
|
256
427
|
error: deps.safeErrorMessage(err),
|
|
257
428
|
},
|
|
258
429
|
};
|
|
@@ -269,6 +440,7 @@ export function createDispatchLifecycle(deps) {
|
|
|
269
440
|
"openclaw",
|
|
270
441
|
"decision",
|
|
271
442
|
initiativeId,
|
|
443
|
+
dedupeKey,
|
|
272
444
|
title,
|
|
273
445
|
input.correlationId ?? null,
|
|
274
446
|
"outbox",
|
|
@@ -277,9 +449,10 @@ export function createDispatchLifecycle(deps) {
|
|
|
277
449
|
},
|
|
278
450
|
activityItem,
|
|
279
451
|
});
|
|
452
|
+
return { queued: true, decisionIds: [] };
|
|
280
453
|
}
|
|
281
454
|
catch {
|
|
282
|
-
|
|
455
|
+
return { queued: false, decisionIds: [] };
|
|
283
456
|
}
|
|
284
457
|
}
|
|
285
458
|
}
|
|
@@ -581,6 +754,38 @@ export function createDispatchLifecycle(deps) {
|
|
|
581
754
|
"Pause and investigate quality gate",
|
|
582
755
|
],
|
|
583
756
|
blocking: true,
|
|
757
|
+
decisionType: "spawn_guard_blocked",
|
|
758
|
+
workstreamId: workstreamId || null,
|
|
759
|
+
agentId: input.agentId ?? null,
|
|
760
|
+
sourceSystem: "openclaw",
|
|
761
|
+
conflictSource: "spawn_guard_blocked",
|
|
762
|
+
dedupeKey: [
|
|
763
|
+
"dispatch",
|
|
764
|
+
input.initiativeId ?? "none",
|
|
765
|
+
workstreamId || "none",
|
|
766
|
+
taskId || "none",
|
|
767
|
+
"spawn_guard_blocked",
|
|
768
|
+
].join(":"),
|
|
769
|
+
recommendedAction: "Choose exception, reassignment, or pause before retrying dispatch.",
|
|
770
|
+
sourceRunId: input.runId ?? null,
|
|
771
|
+
sourceRef: {
|
|
772
|
+
run_id: input.runId ?? null,
|
|
773
|
+
correlation_id: input.correlationId,
|
|
774
|
+
task_id: taskId || null,
|
|
775
|
+
workstream_id: workstreamId || null,
|
|
776
|
+
domain: input.executionPolicy.domain,
|
|
777
|
+
},
|
|
778
|
+
evidenceRefs: [
|
|
779
|
+
{
|
|
780
|
+
evidence_type: "spawn_guard_result",
|
|
781
|
+
title: `Spawn guard blocked ${targetLabel}`,
|
|
782
|
+
summary: blockedReason,
|
|
783
|
+
payload: {
|
|
784
|
+
spawn_guard: spawnGuardResult,
|
|
785
|
+
required_skills: input.executionPolicy.requiredSkills,
|
|
786
|
+
},
|
|
787
|
+
},
|
|
788
|
+
],
|
|
584
789
|
});
|
|
585
790
|
}
|
|
586
791
|
return {
|
|
@@ -56,6 +56,61 @@ export function renderKickoffMessage(input) {
|
|
|
56
56
|
const allow = normalizeKickoffLines(kickoff.tool_scope?.allow ?? null);
|
|
57
57
|
const deny = normalizeKickoffLines(kickoff.tool_scope?.deny ?? null);
|
|
58
58
|
const toolNotes = (kickoff.tool_scope?.notes ?? "").trim();
|
|
59
|
+
const personaVoice = (kickoff.persona?.voice ?? "").trim();
|
|
60
|
+
const collaborationStyle = (kickoff.persona?.collaboration_style ?? "").trim();
|
|
61
|
+
const personaDefaults = normalizeKickoffLines(kickoff.persona?.defaults ?? null);
|
|
62
|
+
const runtimeSettings = kickoff.runtime_settings && typeof kickoff.runtime_settings === "object"
|
|
63
|
+
? kickoff.runtime_settings
|
|
64
|
+
: null;
|
|
65
|
+
const customRunInstructions = runtimeSettings && typeof runtimeSettings.custom_run_instructions === "string"
|
|
66
|
+
? runtimeSettings.custom_run_instructions.trim()
|
|
67
|
+
: "";
|
|
68
|
+
const runtimeFlagLines = [
|
|
69
|
+
runtimeSettings && typeof runtimeSettings.decision_v2_enabled === "boolean"
|
|
70
|
+
? `- Decision V2: ${runtimeSettings.decision_v2_enabled ? "enabled" : "disabled"}`
|
|
71
|
+
: null,
|
|
72
|
+
runtimeSettings && typeof runtimeSettings.decision_dedupe_enabled === "boolean"
|
|
73
|
+
? `- Decision dedupe: ${runtimeSettings.decision_dedupe_enabled ? "enabled" : "disabled"}`
|
|
74
|
+
: null,
|
|
75
|
+
runtimeSettings &&
|
|
76
|
+
typeof runtimeSettings.decision_evidence_required_for_blocking === "boolean"
|
|
77
|
+
? `- Blocking evidence required: ${runtimeSettings.decision_evidence_required_for_blocking ? "enabled" : "disabled"}`
|
|
78
|
+
: null,
|
|
79
|
+
runtimeSettings &&
|
|
80
|
+
typeof runtimeSettings.decision_auto_resolve_guarded_enabled === "boolean"
|
|
81
|
+
? `- Guarded auto-resolve: ${runtimeSettings.decision_auto_resolve_guarded_enabled ? "enabled" : "disabled"}`
|
|
82
|
+
: null,
|
|
83
|
+
runtimeSettings &&
|
|
84
|
+
typeof runtimeSettings.question_auto_answer_enabled === "boolean"
|
|
85
|
+
? `- Question auto-answer: ${runtimeSettings.question_auto_answer_enabled ? "enabled" : "disabled"}`
|
|
86
|
+
: null,
|
|
87
|
+
runtimeSettings &&
|
|
88
|
+
typeof runtimeSettings.question_auto_answer_timeout_sec === "number"
|
|
89
|
+
? `- Question auto-answer timeout: ${Math.max(10, Math.min(3600, Math.floor(runtimeSettings.question_auto_answer_timeout_sec)))}s`
|
|
90
|
+
: runtimeSettings &&
|
|
91
|
+
typeof runtimeSettings.question_auto_answer_delay_seconds === "number"
|
|
92
|
+
? `- Question auto-answer delay: ${Math.max(1, Math.min(900, Math.floor(runtimeSettings.question_auto_answer_delay_seconds)))}s`
|
|
93
|
+
: null,
|
|
94
|
+
runtimeSettings &&
|
|
95
|
+
typeof runtimeSettings.question_auto_answer_policy === "string"
|
|
96
|
+
? `- Question auto-answer policy: ${runtimeSettings.question_auto_answer_policy}`
|
|
97
|
+
: null,
|
|
98
|
+
runtimeSettings &&
|
|
99
|
+
typeof runtimeSettings.question_blocking_behavior === "string"
|
|
100
|
+
? `- Blocking question behavior: ${runtimeSettings.question_blocking_behavior}`
|
|
101
|
+
: null,
|
|
102
|
+
runtimeSettings &&
|
|
103
|
+
typeof runtimeSettings.question_auto_answer_action === "string"
|
|
104
|
+
? `- Question auto-answer action: ${runtimeSettings.question_auto_answer_action.trim().toLowerCase() === "reject"
|
|
105
|
+
? "reject"
|
|
106
|
+
: "approve"}`
|
|
107
|
+
: null,
|
|
108
|
+
runtimeSettings &&
|
|
109
|
+
runtimeSettings.workspace_question_defaults &&
|
|
110
|
+
typeof runtimeSettings.workspace_question_defaults === "object"
|
|
111
|
+
? "- Workspace question defaults available"
|
|
112
|
+
: null,
|
|
113
|
+
].filter((line) => Boolean(line));
|
|
59
114
|
const contextHash = kickoff.context_hash?.trim() || null;
|
|
60
115
|
const schemaVersion = (kickoff.schema_version ?? "").trim();
|
|
61
116
|
const lines = [];
|
|
@@ -123,6 +178,26 @@ export function renderKickoffMessage(input) {
|
|
|
123
178
|
lines.push("- Communicate early when blocked. Provide options, tradeoffs, and a recommendation.");
|
|
124
179
|
lines.push("- Verify before claiming done. Prefer proof (commands/tests) over confidence.");
|
|
125
180
|
lines.push("");
|
|
181
|
+
if (runtimeFlagLines.length > 0 || customRunInstructions) {
|
|
182
|
+
lines.push("## Runtime Settings");
|
|
183
|
+
for (const line of runtimeFlagLines)
|
|
184
|
+
lines.push(line);
|
|
185
|
+
if (customRunInstructions) {
|
|
186
|
+
lines.push("- Custom run instructions:");
|
|
187
|
+
lines.push(` ${customRunInstructions}`);
|
|
188
|
+
}
|
|
189
|
+
lines.push("");
|
|
190
|
+
}
|
|
191
|
+
if (personaVoice || collaborationStyle || personaDefaults.length > 0) {
|
|
192
|
+
lines.push("## Behavior");
|
|
193
|
+
if (personaVoice)
|
|
194
|
+
lines.push(`- Voice: ${personaVoice}`);
|
|
195
|
+
if (collaborationStyle)
|
|
196
|
+
lines.push(`- Collaboration style: ${collaborationStyle}`);
|
|
197
|
+
for (const item of personaDefaults)
|
|
198
|
+
lines.push(`- Default: ${item}`);
|
|
199
|
+
lines.push("");
|
|
200
|
+
}
|
|
126
201
|
if (allow.length > 0 || deny.length > 0 || toolNotes) {
|
|
127
202
|
lines.push("## Tool Scope");
|
|
128
203
|
if (allow.length > 0)
|
|
@@ -139,6 +214,35 @@ export function renderKickoffMessage(input) {
|
|
|
139
214
|
lines.push(`- ${item}`);
|
|
140
215
|
lines.push("");
|
|
141
216
|
}
|
|
217
|
+
const teamContext = kickoff.team_context;
|
|
218
|
+
if (teamContext) {
|
|
219
|
+
const completions = Array.isArray(teamContext.recent_completions)
|
|
220
|
+
? teamContext.recent_completions.slice(0, 5)
|
|
221
|
+
: [];
|
|
222
|
+
const teamDecisions = Array.isArray(teamContext.recent_decisions)
|
|
223
|
+
? teamContext.recent_decisions.slice(0, 3)
|
|
224
|
+
: [];
|
|
225
|
+
if (completions.length > 0 || teamDecisions.length > 0) {
|
|
226
|
+
lines.push("## Team Activity");
|
|
227
|
+
lines.push("Recent work by other agents (for awareness, not direct action):");
|
|
228
|
+
for (const c of completions) {
|
|
229
|
+
const outputs = Array.isArray(c.key_outputs) && c.key_outputs.length > 0
|
|
230
|
+
? ` (${c.key_outputs.join(", ")})`
|
|
231
|
+
: "";
|
|
232
|
+
lines.push(`- [${c.domain}] ${c.task_title}: ${c.summary}${outputs}`);
|
|
233
|
+
}
|
|
234
|
+
if (teamDecisions.length > 0) {
|
|
235
|
+
lines.push("");
|
|
236
|
+
lines.push("Recent decisions:");
|
|
237
|
+
for (const d of teamDecisions) {
|
|
238
|
+
lines.push(`- ${d.title}: ${d.resolution}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
lines.push("");
|
|
242
|
+
lines.push("Reference naturally when relevant. Do not summarize back.");
|
|
243
|
+
lines.push("");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
142
246
|
if (contextHash || schemaVersion) {
|
|
143
247
|
lines.push("## Provenance");
|
|
144
248
|
if (schemaVersion)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared LLM client for classification, summarization, and generation tasks.
|
|
3
|
+
*
|
|
4
|
+
* Generalizes the pattern from activity-headline.ts into a reusable client
|
|
5
|
+
* with in-memory caching, timeout, and heuristic fallback.
|
|
6
|
+
*/
|
|
7
|
+
export type LlmSource = "llm" | "heuristic";
|
|
8
|
+
export interface LlmRequest {
|
|
9
|
+
/** Namespace for cache keys (e.g. "retro", "turn_summary", "classify_status") */
|
|
10
|
+
taskId: string;
|
|
11
|
+
systemPrompt: string;
|
|
12
|
+
userPrompt: string;
|
|
13
|
+
/** Override default model. Use DEFAULT_GENERATION_MODEL for longer outputs. */
|
|
14
|
+
model?: string;
|
|
15
|
+
/** Default 0.1 */
|
|
16
|
+
temperature?: number;
|
|
17
|
+
/** Default 128 */
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
/** Default 4000ms */
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
/** Default 12h. Set 0 to disable caching. */
|
|
22
|
+
cacheTtlMs?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface LlmResponse<T> {
|
|
25
|
+
result: T;
|
|
26
|
+
source: LlmSource;
|
|
27
|
+
model: string | null;
|
|
28
|
+
}
|
|
29
|
+
export declare function resolveApiKey(): string | null;
|
|
30
|
+
/** Reset cached key (for testing or key rotation). */
|
|
31
|
+
export declare function resetApiKeyCache(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Call LLM for a text completion with automatic caching and heuristic fallback.
|
|
34
|
+
*
|
|
35
|
+
* @param request - The LLM request configuration
|
|
36
|
+
* @param fallback - Heuristic fallback that produces a result when LLM is unavailable
|
|
37
|
+
* @param parse - Optional transform on the raw LLM text (default: identity)
|
|
38
|
+
*/
|
|
39
|
+
export declare function callLlm(request: LlmRequest, fallback: () => string, parse?: (raw: string) => string | null): Promise<LlmResponse<string>>;
|
|
40
|
+
/**
|
|
41
|
+
* Call LLM expecting a JSON response. Parses and validates via the provided parser.
|
|
42
|
+
*
|
|
43
|
+
* @param request - The LLM request (systemPrompt should instruct JSON output)
|
|
44
|
+
* @param parse - Parse raw JSON string into typed result, return null on failure
|
|
45
|
+
* @param fallback - Heuristic fallback
|
|
46
|
+
*/
|
|
47
|
+
export declare function callLlmJson<T>(request: LlmRequest, parse: (raw: string) => T | null, fallback: () => T): Promise<LlmResponse<T>>;
|