@useorgx/openclaw-plugin 0.4.9 → 0.7.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.
- package/README.md +35 -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/BXWDRGm-.js +1 -0
- package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
- package/dashboard/dist/assets/BXWDRGm-.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/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/CE38zU4U.js +1 -0
- package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
- package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js +1 -0
- package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
- package/dashboard/dist/assets/CGGR2GZh.js +1 -0
- package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
- package/dashboard/dist/assets/CGGR2GZh.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/CPFiTmlw.js +8 -0
- package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
- package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
- package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.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/D-bf6hEI.js +213 -0
- package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
- package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js +2 -0
- package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js +1 -0
- package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
- package/dashboard/dist/assets/DW_rKUic.js +11 -0
- package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
- package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
- package/dashboard/dist/assets/DbNoijHm.js +1 -0
- package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
- package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js +2 -0
- package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js +1 -0
- package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
- package/dashboard/dist/assets/PAUiij_z.js +1 -0
- package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
- package/dashboard/dist/assets/PAUiij_z.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/h5biQs2I.css +1 -0
- package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
- package/dashboard/dist/assets/h5biQs2I.css.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/nByHNHoW.js +1 -0
- package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
- package/dashboard/dist/assets/nByHNHoW.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/tS9mbYZi.js +1 -0
- package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
- package/dashboard/dist/assets/tS9mbYZi.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/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 +177 -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 +227 -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/fs-utils.js +13 -1
- 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 +2531 -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 +308 -20
- package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
- package/dist/http/helpers/autopilot-slice-utils.js +516 -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 +74 -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 +860 -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 +1354 -97
- package/dist/http/routes/agent-suite.d.ts +9 -0
- package/dist/http/routes/agent-suite.js +207 -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 +294 -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 +48 -2
- package/dist/http/routes/live-snapshot.js +638 -19
- package/dist/http/routes/live-terminal.d.ts +11 -0
- package/dist/http/routes/live-terminal.js +261 -0
- package/dist/http/routes/live-triage.d.ts +61 -0
- package/dist/http/routes/live-triage.js +248 -0
- package/dist/http/routes/mission-control-actions.d.ts +49 -1
- package/dist/http/routes/mission-control-actions.js +1334 -84
- package/dist/http/routes/mission-control-read.d.ts +48 -3
- package/dist/http/routes/mission-control-read.js +1593 -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.js +33 -59
- 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 +24 -5
- package/dist/reporting/rollups.d.ts +53 -0
- package/dist/reporting/rollups.js +148 -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 +14 -4
- 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
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
const DEFAULT_REPORTING_STALE_MS = 15 * 60_000;
|
|
2
|
+
const GENERIC_BLOCKER_REASONS = new Set([
|
|
3
|
+
"agent execution failed",
|
|
4
|
+
"execution failed",
|
|
5
|
+
"run failed",
|
|
6
|
+
"failed",
|
|
7
|
+
"blocked",
|
|
8
|
+
]);
|
|
9
|
+
function statusKey(value) {
|
|
10
|
+
return (value ?? "").trim().toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
function toEpoch(value) {
|
|
13
|
+
if (!value)
|
|
14
|
+
return 0;
|
|
15
|
+
const parsed = Date.parse(value);
|
|
16
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
17
|
+
}
|
|
18
|
+
function nonEmpty(value) {
|
|
19
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
20
|
+
}
|
|
21
|
+
function normalizeReason(value) {
|
|
22
|
+
return (value ?? "").trim().replace(/\s+/g, " ").toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
function isGenericFailureReason(value) {
|
|
25
|
+
const normalized = normalizeReason(value);
|
|
26
|
+
if (!normalized)
|
|
27
|
+
return false;
|
|
28
|
+
return GENERIC_BLOCKER_REASONS.has(normalized);
|
|
29
|
+
}
|
|
30
|
+
function asRecord(value) {
|
|
31
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
32
|
+
return null;
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function metadataVariants(metadata) {
|
|
36
|
+
if (!metadata)
|
|
37
|
+
return [];
|
|
38
|
+
const variants = [metadata];
|
|
39
|
+
const nested = asRecord(metadata.orgx_context);
|
|
40
|
+
if (nested)
|
|
41
|
+
variants.push(nested);
|
|
42
|
+
return variants;
|
|
43
|
+
}
|
|
44
|
+
function metadataString(metadata, keys) {
|
|
45
|
+
for (const source of metadataVariants(metadata)) {
|
|
46
|
+
for (const key of keys) {
|
|
47
|
+
const value = source[key];
|
|
48
|
+
if (typeof value !== "string")
|
|
49
|
+
continue;
|
|
50
|
+
const trimmed = value.trim();
|
|
51
|
+
if (trimmed.length > 0)
|
|
52
|
+
return trimmed;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function metadataStringArray(metadata, keys) {
|
|
58
|
+
for (const source of metadataVariants(metadata)) {
|
|
59
|
+
for (const key of keys) {
|
|
60
|
+
const value = source[key];
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
const normalized = value
|
|
63
|
+
.map((entry) => (typeof entry === "string" ? entry.trim() : ""))
|
|
64
|
+
.filter((entry) => entry.length > 0);
|
|
65
|
+
if (normalized.length > 0)
|
|
66
|
+
return dedupeStrings(normalized);
|
|
67
|
+
}
|
|
68
|
+
if (typeof value === "string") {
|
|
69
|
+
const parsed = value
|
|
70
|
+
.split(/[\n,;]+/g)
|
|
71
|
+
.map((entry) => entry.trim())
|
|
72
|
+
.filter((entry) => entry.length > 0);
|
|
73
|
+
if (parsed.length > 0)
|
|
74
|
+
return dedupeStrings(parsed);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
function metadataBoolean(metadata, keys) {
|
|
81
|
+
for (const source of metadataVariants(metadata)) {
|
|
82
|
+
for (const key of keys) {
|
|
83
|
+
const value = source[key];
|
|
84
|
+
if (typeof value === "boolean")
|
|
85
|
+
return value;
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
const normalized = value.trim().toLowerCase();
|
|
88
|
+
if (normalized === "true")
|
|
89
|
+
return true;
|
|
90
|
+
if (normalized === "false")
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function dedupeStrings(values) {
|
|
98
|
+
const output = [];
|
|
99
|
+
const seen = new Set();
|
|
100
|
+
for (const entry of values) {
|
|
101
|
+
const trimmed = entry.trim();
|
|
102
|
+
if (!trimmed)
|
|
103
|
+
continue;
|
|
104
|
+
const key = trimmed.toLowerCase();
|
|
105
|
+
if (seen.has(key))
|
|
106
|
+
continue;
|
|
107
|
+
seen.add(key);
|
|
108
|
+
output.push(trimmed);
|
|
109
|
+
}
|
|
110
|
+
return output;
|
|
111
|
+
}
|
|
112
|
+
function firstNonEmpty(values) {
|
|
113
|
+
for (const value of values) {
|
|
114
|
+
if (!nonEmpty(value))
|
|
115
|
+
continue;
|
|
116
|
+
return value.trim();
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function firstSpecificReason(values) {
|
|
121
|
+
for (const value of values) {
|
|
122
|
+
if (!nonEmpty(value))
|
|
123
|
+
continue;
|
|
124
|
+
const trimmed = value.trim();
|
|
125
|
+
if (!isGenericFailureReason(trimmed))
|
|
126
|
+
return trimmed;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function hasBlockerContext(context) {
|
|
131
|
+
return Boolean(nonEmpty(context.initiativeId) ||
|
|
132
|
+
(Array.isArray(context.initiativeIds) && context.initiativeIds.length > 0) ||
|
|
133
|
+
nonEmpty(context.workstreamId) ||
|
|
134
|
+
(Array.isArray(context.workstreamIds) && context.workstreamIds.length > 0) ||
|
|
135
|
+
nonEmpty(context.workstreamTitle) ||
|
|
136
|
+
context.taskIds.length > 0 ||
|
|
137
|
+
context.milestoneIds.length > 0 ||
|
|
138
|
+
nonEmpty(context.iwmtId ?? null) ||
|
|
139
|
+
(Array.isArray(context.iwmtIds) && context.iwmtIds.length > 0) ||
|
|
140
|
+
nonEmpty(context.sliceRunId) ||
|
|
141
|
+
nonEmpty(context.parallelMode) ||
|
|
142
|
+
nonEmpty(context.logPath) ||
|
|
143
|
+
nonEmpty(context.outputPath));
|
|
144
|
+
}
|
|
145
|
+
function emptyBlockerContext() {
|
|
146
|
+
return {
|
|
147
|
+
initiativeId: null,
|
|
148
|
+
initiativeIds: [],
|
|
149
|
+
workstreamId: null,
|
|
150
|
+
workstreamIds: [],
|
|
151
|
+
workstreamTitle: null,
|
|
152
|
+
taskIds: [],
|
|
153
|
+
milestoneIds: [],
|
|
154
|
+
iwmtId: null,
|
|
155
|
+
iwmtIds: [],
|
|
156
|
+
sliceRunId: null,
|
|
157
|
+
parallelMode: null,
|
|
158
|
+
logPath: null,
|
|
159
|
+
outputPath: null,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function mergeRunContext(context, item, metadata) {
|
|
163
|
+
const initiativeIds = dedupeStrings([
|
|
164
|
+
...(Array.isArray(context.initiativeIds) ? context.initiativeIds : []),
|
|
165
|
+
...(context.initiativeId ? [context.initiativeId] : []),
|
|
166
|
+
...(item.initiativeId ? [item.initiativeId] : []),
|
|
167
|
+
...metadataStringArray(metadata, ["initiative_ids", "initiativeIds"]),
|
|
168
|
+
]);
|
|
169
|
+
const initiativeId = firstNonEmpty([
|
|
170
|
+
item.initiativeId,
|
|
171
|
+
metadataString(metadata, ["initiative_id", "initiativeId"]),
|
|
172
|
+
initiativeIds[0] ?? null,
|
|
173
|
+
]);
|
|
174
|
+
if (initiativeIds.length > 0)
|
|
175
|
+
context.initiativeIds = initiativeIds;
|
|
176
|
+
if (initiativeId)
|
|
177
|
+
context.initiativeId = initiativeId;
|
|
178
|
+
const workstreamIds = dedupeStrings([
|
|
179
|
+
...(Array.isArray(context.workstreamIds) ? context.workstreamIds : []),
|
|
180
|
+
...(context.workstreamId ? [context.workstreamId] : []),
|
|
181
|
+
...metadataStringArray(metadata, ["workstream_ids", "workstreamIds"]),
|
|
182
|
+
]);
|
|
183
|
+
const workstreamId = firstNonEmpty([
|
|
184
|
+
metadataString(metadata, ["workstream_id", "workstreamId"]),
|
|
185
|
+
workstreamIds[0] ?? null,
|
|
186
|
+
]);
|
|
187
|
+
if (workstreamIds.length > 0)
|
|
188
|
+
context.workstreamIds = workstreamIds;
|
|
189
|
+
if (workstreamId)
|
|
190
|
+
context.workstreamId = workstreamId;
|
|
191
|
+
const workstreamTitle = metadataString(metadata, ["workstream_title", "workstreamTitle"]);
|
|
192
|
+
if (workstreamTitle)
|
|
193
|
+
context.workstreamTitle = workstreamTitle;
|
|
194
|
+
const taskIds = metadataStringArray(metadata, [
|
|
195
|
+
"task_ids",
|
|
196
|
+
"taskIds",
|
|
197
|
+
"active_task_ids",
|
|
198
|
+
"activeTaskIds",
|
|
199
|
+
]);
|
|
200
|
+
if (taskIds.length > 0) {
|
|
201
|
+
context.taskIds = dedupeStrings([...context.taskIds, ...taskIds]);
|
|
202
|
+
}
|
|
203
|
+
const milestoneIds = metadataStringArray(metadata, ["milestone_ids", "milestoneIds"]);
|
|
204
|
+
if (milestoneIds.length > 0) {
|
|
205
|
+
context.milestoneIds = dedupeStrings([...context.milestoneIds, ...milestoneIds]);
|
|
206
|
+
}
|
|
207
|
+
const iwmtIds = dedupeStrings([
|
|
208
|
+
...(Array.isArray(context.iwmtIds) ? context.iwmtIds : []),
|
|
209
|
+
...(context.iwmtId ? [context.iwmtId] : []),
|
|
210
|
+
...metadataStringArray(metadata, ["iwmt_ids", "iwmtIds"]),
|
|
211
|
+
]);
|
|
212
|
+
const iwmtId = firstNonEmpty([
|
|
213
|
+
metadataString(metadata, ["iwmt_id", "iwmtId"]),
|
|
214
|
+
iwmtIds[0] ?? null,
|
|
215
|
+
]);
|
|
216
|
+
if (iwmtIds.length > 0)
|
|
217
|
+
context.iwmtIds = iwmtIds;
|
|
218
|
+
if (iwmtId)
|
|
219
|
+
context.iwmtId = iwmtId;
|
|
220
|
+
const sliceRunId = metadataString(metadata, [
|
|
221
|
+
"slice_run_id",
|
|
222
|
+
"sliceRunId",
|
|
223
|
+
"active_run_id",
|
|
224
|
+
"activeRunId",
|
|
225
|
+
]);
|
|
226
|
+
if (sliceRunId)
|
|
227
|
+
context.sliceRunId = sliceRunId;
|
|
228
|
+
const parallelMode = metadataString(metadata, [
|
|
229
|
+
"parallel_mode",
|
|
230
|
+
"parallelMode",
|
|
231
|
+
"auto_continue_parallel_mode",
|
|
232
|
+
"autoContinueParallelMode",
|
|
233
|
+
]);
|
|
234
|
+
if (parallelMode)
|
|
235
|
+
context.parallelMode = parallelMode;
|
|
236
|
+
const logPath = metadataString(metadata, ["log_path", "logPath"]);
|
|
237
|
+
if (logPath)
|
|
238
|
+
context.logPath = logPath;
|
|
239
|
+
const outputPath = metadataString(metadata, ["output_path", "outputPath"]);
|
|
240
|
+
if (outputPath)
|
|
241
|
+
context.outputPath = outputPath;
|
|
242
|
+
return context;
|
|
243
|
+
}
|
|
244
|
+
function deriveBlockerSignal(item) {
|
|
245
|
+
const metadata = asRecord(item.metadata);
|
|
246
|
+
const reason = firstSpecificReason([
|
|
247
|
+
metadataString(metadata, ["description", "reason", "error", "error_message"]),
|
|
248
|
+
item.summary ?? null,
|
|
249
|
+
item.description ?? null,
|
|
250
|
+
metadataString(metadata, ["message", "summary", "last_error", "lastError"]),
|
|
251
|
+
item.title,
|
|
252
|
+
]) ??
|
|
253
|
+
firstNonEmpty([
|
|
254
|
+
metadataString(metadata, ["description", "reason", "error", "error_message"]),
|
|
255
|
+
item.summary ?? null,
|
|
256
|
+
item.description ?? null,
|
|
257
|
+
metadataString(metadata, ["message", "summary", "last_error", "lastError"]),
|
|
258
|
+
item.title,
|
|
259
|
+
]);
|
|
260
|
+
return {
|
|
261
|
+
reason,
|
|
262
|
+
source: metadataString(metadata, ["source", "runtime_source", "runtimeSource"]),
|
|
263
|
+
errorCode: metadataString(metadata, ["errorCode", "error_code"]),
|
|
264
|
+
errorCategory: metadataString(metadata, ["errorCategory", "error_category"]),
|
|
265
|
+
retryable: metadataBoolean(metadata, [
|
|
266
|
+
"retryable",
|
|
267
|
+
"isRetryable",
|
|
268
|
+
"retry_allowed",
|
|
269
|
+
"retryAllowed",
|
|
270
|
+
]),
|
|
271
|
+
suggestedActions: metadataStringArray(metadata, [
|
|
272
|
+
"suggestedActions",
|
|
273
|
+
"suggested_actions",
|
|
274
|
+
"next_actions",
|
|
275
|
+
"nextActions",
|
|
276
|
+
]),
|
|
277
|
+
eventId: item.id ?? null,
|
|
278
|
+
eventType: item.type ?? null,
|
|
279
|
+
eventTimestamp: item.timestamp ?? null,
|
|
280
|
+
isConsoleRecovery: isConsoleRecoveryBlocker(item),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function isLikelyReportingControlSession(node) {
|
|
284
|
+
if (nonEmpty(node.agentId) || nonEmpty(node.agentName))
|
|
285
|
+
return false;
|
|
286
|
+
const title = statusKey(node.title);
|
|
287
|
+
return title.startsWith("reporting");
|
|
288
|
+
}
|
|
289
|
+
function hasActionableBlockerData(node, signal) {
|
|
290
|
+
const blockerEntries = dedupeStrings([
|
|
291
|
+
...(Array.isArray(node.blockers) ? node.blockers : []),
|
|
292
|
+
node.blockerReason ?? "",
|
|
293
|
+
]);
|
|
294
|
+
const hasSpecificNodeReason = blockerEntries.some((entry) => !isGenericFailureReason(entry));
|
|
295
|
+
if (hasSpecificNodeReason) {
|
|
296
|
+
const consoleRecoveryOnly = Boolean(signal?.latestBlocker?.isConsoleRecovery) && (signal?.hardBlockerCount ?? 0) === 0;
|
|
297
|
+
if (!consoleRecoveryOnly)
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
if (signal && signal.hardBlockerCount > 0)
|
|
301
|
+
return true;
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
function isBlockedLike(node) {
|
|
305
|
+
const normalizedStatus = statusKey(node.status);
|
|
306
|
+
const normalizedPhase = statusKey(node.phase ?? null);
|
|
307
|
+
const normalizedState = statusKey(node.state ?? null);
|
|
308
|
+
return (normalizedStatus === "blocked" ||
|
|
309
|
+
normalizedStatus === "failed" ||
|
|
310
|
+
normalizedPhase === "blocked" ||
|
|
311
|
+
normalizedState === "blocked" ||
|
|
312
|
+
normalizedState === "error");
|
|
313
|
+
}
|
|
314
|
+
function sessionLastTouchedEpoch(node) {
|
|
315
|
+
return toEpoch(node.updatedAt ?? node.lastEventAt ?? node.startedAt);
|
|
316
|
+
}
|
|
317
|
+
function isConsoleRecoveryBlocker(item) {
|
|
318
|
+
if (item.type !== "blocker_created")
|
|
319
|
+
return false;
|
|
320
|
+
const metadata = asRecord(item.metadata);
|
|
321
|
+
const source = statusKey(metadataString(metadata, ["source"]));
|
|
322
|
+
const errorCode = statusKey(metadataString(metadata, ["errorCode", "error_code"]));
|
|
323
|
+
const errorCategory = statusKey(metadataString(metadata, ["errorCategory", "error_category"]));
|
|
324
|
+
return (source === "console_worker" &&
|
|
325
|
+
(errorCode === "state_error" || errorCategory === "state_error"));
|
|
326
|
+
}
|
|
327
|
+
function buildRunActivitySignals(activity) {
|
|
328
|
+
const byRunId = new Map();
|
|
329
|
+
const ordered = [...activity].sort((a, b) => toEpoch(a.timestamp) - toEpoch(b.timestamp));
|
|
330
|
+
for (const item of ordered) {
|
|
331
|
+
const runId = item.runId?.trim();
|
|
332
|
+
if (!runId)
|
|
333
|
+
continue;
|
|
334
|
+
const timestamp = toEpoch(item.timestamp);
|
|
335
|
+
const metadata = asRecord(item.metadata);
|
|
336
|
+
const existing = byRunId.get(runId) ?? {
|
|
337
|
+
completedCount: 0,
|
|
338
|
+
blockerCount: 0,
|
|
339
|
+
hardBlockerCount: 0,
|
|
340
|
+
latestCompletedAt: 0,
|
|
341
|
+
latestHardBlockerAt: 0,
|
|
342
|
+
latestBlockerAt: 0,
|
|
343
|
+
latestBlocker: null,
|
|
344
|
+
context: emptyBlockerContext(),
|
|
345
|
+
};
|
|
346
|
+
existing.context = mergeRunContext(existing.context, item, metadata);
|
|
347
|
+
const phase = statusKey(item.phase ?? null);
|
|
348
|
+
const state = statusKey(item.state ?? null);
|
|
349
|
+
const completedLike = item.type === "run_completed" || phase === "completed" || state === "completed";
|
|
350
|
+
if (completedLike) {
|
|
351
|
+
existing.completedCount += 1;
|
|
352
|
+
existing.latestCompletedAt = Math.max(existing.latestCompletedAt, timestamp);
|
|
353
|
+
}
|
|
354
|
+
const blockerLike = item.type === "run_failed" ||
|
|
355
|
+
item.type === "blocker_created" ||
|
|
356
|
+
phase === "blocked" ||
|
|
357
|
+
state === "blocked" ||
|
|
358
|
+
state === "error";
|
|
359
|
+
if (blockerLike) {
|
|
360
|
+
existing.blockerCount += 1;
|
|
361
|
+
const isConsoleRecovery = isConsoleRecoveryBlocker(item);
|
|
362
|
+
if (timestamp >= existing.latestBlockerAt) {
|
|
363
|
+
existing.latestBlockerAt = timestamp;
|
|
364
|
+
existing.latestBlocker = deriveBlockerSignal(item);
|
|
365
|
+
}
|
|
366
|
+
if (!isConsoleRecovery) {
|
|
367
|
+
existing.hardBlockerCount += 1;
|
|
368
|
+
existing.latestHardBlockerAt = Math.max(existing.latestHardBlockerAt, timestamp);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
byRunId.set(runId, existing);
|
|
372
|
+
}
|
|
373
|
+
return byRunId;
|
|
374
|
+
}
|
|
375
|
+
function arraysEqual(a, b) {
|
|
376
|
+
if (a.length !== b.length)
|
|
377
|
+
return false;
|
|
378
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
379
|
+
if (a[i] !== b[i])
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
function blockerContextsEqual(a, b) {
|
|
385
|
+
return (a.initiativeId === b.initiativeId &&
|
|
386
|
+
arraysEqual(a.initiativeIds ?? [], b.initiativeIds ?? []) &&
|
|
387
|
+
a.workstreamId === b.workstreamId &&
|
|
388
|
+
arraysEqual(a.workstreamIds ?? [], b.workstreamIds ?? []) &&
|
|
389
|
+
a.workstreamTitle === b.workstreamTitle &&
|
|
390
|
+
arraysEqual(a.taskIds, b.taskIds) &&
|
|
391
|
+
arraysEqual(a.milestoneIds, b.milestoneIds) &&
|
|
392
|
+
(a.iwmtId ?? null) === (b.iwmtId ?? null) &&
|
|
393
|
+
arraysEqual(a.iwmtIds ?? [], b.iwmtIds ?? []) &&
|
|
394
|
+
a.sliceRunId === b.sliceRunId &&
|
|
395
|
+
a.parallelMode === b.parallelMode &&
|
|
396
|
+
a.logPath === b.logPath &&
|
|
397
|
+
a.outputPath === b.outputPath);
|
|
398
|
+
}
|
|
399
|
+
function blockerDiagnosticsEqual(a, b) {
|
|
400
|
+
if (!a && !b)
|
|
401
|
+
return true;
|
|
402
|
+
if (!a || !b)
|
|
403
|
+
return false;
|
|
404
|
+
return (a.reason === b.reason &&
|
|
405
|
+
a.source === b.source &&
|
|
406
|
+
a.errorCode === b.errorCode &&
|
|
407
|
+
a.errorCategory === b.errorCategory &&
|
|
408
|
+
a.retryable === b.retryable &&
|
|
409
|
+
arraysEqual(a.suggestedActions, b.suggestedActions) &&
|
|
410
|
+
a.eventId === b.eventId &&
|
|
411
|
+
a.eventType === b.eventType &&
|
|
412
|
+
a.eventTimestamp === b.eventTimestamp &&
|
|
413
|
+
blockerContextsEqual(a.context, b.context));
|
|
414
|
+
}
|
|
415
|
+
function mergeReportingBlockerDetails(node, signal) {
|
|
416
|
+
if (!signal)
|
|
417
|
+
return node;
|
|
418
|
+
const latest = signal.latestBlocker;
|
|
419
|
+
const resolvedReason = firstSpecificReason([
|
|
420
|
+
latest?.reason ?? null,
|
|
421
|
+
node.blockerReason ?? null,
|
|
422
|
+
...(Array.isArray(node.blockers) ? node.blockers : []),
|
|
423
|
+
]) ??
|
|
424
|
+
firstNonEmpty([
|
|
425
|
+
latest?.reason ?? null,
|
|
426
|
+
node.blockerReason ?? null,
|
|
427
|
+
...(Array.isArray(node.blockers) ? node.blockers : []),
|
|
428
|
+
]);
|
|
429
|
+
const currentBlockers = dedupeStrings(Array.isArray(node.blockers) ? node.blockers : []);
|
|
430
|
+
const hasOnlyGenericBlockers = currentBlockers.length > 0 && currentBlockers.every(isGenericFailureReason);
|
|
431
|
+
const nextBlockers = resolvedReason
|
|
432
|
+
? hasOnlyGenericBlockers
|
|
433
|
+
? [resolvedReason]
|
|
434
|
+
: dedupeStrings([...currentBlockers, resolvedReason])
|
|
435
|
+
: hasOnlyGenericBlockers
|
|
436
|
+
? []
|
|
437
|
+
: currentBlockers;
|
|
438
|
+
const context = {
|
|
439
|
+
...signal.context,
|
|
440
|
+
initiativeId: signal.context.initiativeId ?? node.initiativeId ?? null,
|
|
441
|
+
workstreamId: signal.context.workstreamId ?? node.workstreamId ?? null,
|
|
442
|
+
initiativeIds: dedupeStrings([
|
|
443
|
+
...(signal.context.initiativeIds ?? []),
|
|
444
|
+
...(node.initiativeId ? [node.initiativeId] : []),
|
|
445
|
+
]),
|
|
446
|
+
workstreamIds: dedupeStrings([
|
|
447
|
+
...(signal.context.workstreamIds ?? []),
|
|
448
|
+
...(node.workstreamId ? [node.workstreamId] : []),
|
|
449
|
+
]),
|
|
450
|
+
};
|
|
451
|
+
const diagnostics = latest || hasBlockerContext(context)
|
|
452
|
+
? {
|
|
453
|
+
reason: resolvedReason,
|
|
454
|
+
source: latest?.source ?? null,
|
|
455
|
+
errorCode: latest?.errorCode ?? null,
|
|
456
|
+
errorCategory: latest?.errorCategory ?? null,
|
|
457
|
+
retryable: latest?.retryable ?? null,
|
|
458
|
+
suggestedActions: latest?.suggestedActions ?? [],
|
|
459
|
+
eventId: latest?.eventId ?? null,
|
|
460
|
+
eventType: latest?.eventType ?? null,
|
|
461
|
+
eventTimestamp: latest?.eventTimestamp ?? null,
|
|
462
|
+
context,
|
|
463
|
+
}
|
|
464
|
+
: null;
|
|
465
|
+
const nextNode = {
|
|
466
|
+
...node,
|
|
467
|
+
initiativeId: node.initiativeId ?? context.initiativeId ?? null,
|
|
468
|
+
workstreamId: node.workstreamId ?? context.workstreamId ?? null,
|
|
469
|
+
blockerReason: resolvedReason,
|
|
470
|
+
blockers: nextBlockers,
|
|
471
|
+
blockerDiagnostics: diagnostics,
|
|
472
|
+
lastEventSummary: node.lastEventSummary ?? latest?.reason ?? null,
|
|
473
|
+
};
|
|
474
|
+
const unchanged = nextNode.initiativeId === node.initiativeId &&
|
|
475
|
+
nextNode.workstreamId === node.workstreamId &&
|
|
476
|
+
nextNode.blockerReason === node.blockerReason &&
|
|
477
|
+
nextNode.lastEventSummary === node.lastEventSummary &&
|
|
478
|
+
arraysEqual(nextNode.blockers, node.blockers) &&
|
|
479
|
+
blockerDiagnosticsEqual(nextNode.blockerDiagnostics, node.blockerDiagnostics);
|
|
480
|
+
return unchanged ? node : nextNode;
|
|
481
|
+
}
|
|
482
|
+
function reportingSessionShouldBeCompleted(input) {
|
|
483
|
+
const { node, signal, hasRuntimeSignal, hasActionableBlocker, nowMs, staleMs } = input;
|
|
484
|
+
const hasCompletedSignal = Boolean(signal && signal.completedCount > 0);
|
|
485
|
+
const hasHardBlocker = Boolean(signal && signal.hardBlockerCount > 0);
|
|
486
|
+
const completedAfterHardBlocker = Boolean(signal &&
|
|
487
|
+
signal.latestCompletedAt > 0 &&
|
|
488
|
+
(signal.latestHardBlockerAt === 0 || signal.latestCompletedAt >= signal.latestHardBlockerAt));
|
|
489
|
+
if (hasCompletedSignal && (!hasHardBlocker || completedAfterHardBlocker)) {
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
const touchedAt = sessionLastTouchedEpoch(node);
|
|
493
|
+
const stale = touchedAt > 0 && nowMs - touchedAt >= staleMs;
|
|
494
|
+
const latestReason = normalizeReason(signal?.latestBlocker?.reason ?? null);
|
|
495
|
+
const consoleRecoveryLike = Boolean(signal?.latestBlocker?.isConsoleRecovery) ||
|
|
496
|
+
latestReason.includes("automatically recovered") ||
|
|
497
|
+
latestReason.includes("auto-recovered");
|
|
498
|
+
if (stale &&
|
|
499
|
+
!hasRuntimeSignal &&
|
|
500
|
+
!hasHardBlocker &&
|
|
501
|
+
(consoleRecoveryLike || !hasActionableBlocker)) {
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
function completeReportingSession(node) {
|
|
507
|
+
return {
|
|
508
|
+
...node,
|
|
509
|
+
status: "completed",
|
|
510
|
+
phase: "completed",
|
|
511
|
+
state: "completed",
|
|
512
|
+
blockers: [],
|
|
513
|
+
blockerReason: null,
|
|
514
|
+
blockerDiagnostics: null,
|
|
515
|
+
lastEventSummary: node.lastEventSummary && node.lastEventSummary.trim().length > 0
|
|
516
|
+
? node.lastEventSummary
|
|
517
|
+
: "Reporting completed.",
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
export function normalizeReportingBlockedSessions(input) {
|
|
521
|
+
const { sessions } = input;
|
|
522
|
+
if (!Array.isArray(sessions.nodes) || sessions.nodes.length === 0) {
|
|
523
|
+
return sessions;
|
|
524
|
+
}
|
|
525
|
+
const runSignals = buildRunActivitySignals(input.activity ?? []);
|
|
526
|
+
const runtimeRunIds = new Set();
|
|
527
|
+
for (const instance of input.runtimeInstances ?? []) {
|
|
528
|
+
if (nonEmpty(instance.runId))
|
|
529
|
+
runtimeRunIds.add(instance.runId.trim());
|
|
530
|
+
if (nonEmpty(instance.correlationId))
|
|
531
|
+
runtimeRunIds.add(instance.correlationId.trim());
|
|
532
|
+
}
|
|
533
|
+
const nowMs = input.nowMs ?? Date.now();
|
|
534
|
+
const staleMs = Math.max(60_000, input.staleMs ?? DEFAULT_REPORTING_STALE_MS);
|
|
535
|
+
let changed = false;
|
|
536
|
+
const nodes = sessions.nodes.map((node) => {
|
|
537
|
+
if (!isBlockedLike(node))
|
|
538
|
+
return node;
|
|
539
|
+
if (!isLikelyReportingControlSession(node))
|
|
540
|
+
return node;
|
|
541
|
+
const runId = node.runId?.trim();
|
|
542
|
+
if (!runId)
|
|
543
|
+
return node;
|
|
544
|
+
const signal = runSignals.get(runId) ?? null;
|
|
545
|
+
const hydrated = mergeReportingBlockerDetails(node, signal);
|
|
546
|
+
if (hydrated !== node)
|
|
547
|
+
changed = true;
|
|
548
|
+
const hasActionable = hasActionableBlockerData(hydrated, signal);
|
|
549
|
+
const hasRuntimeSignal = runtimeRunIds.has(runId);
|
|
550
|
+
if (!reportingSessionShouldBeCompleted({
|
|
551
|
+
node: hydrated,
|
|
552
|
+
signal,
|
|
553
|
+
hasRuntimeSignal,
|
|
554
|
+
hasActionableBlocker: hasActionable,
|
|
555
|
+
nowMs,
|
|
556
|
+
staleMs,
|
|
557
|
+
})) {
|
|
558
|
+
return hydrated;
|
|
559
|
+
}
|
|
560
|
+
changed = true;
|
|
561
|
+
return completeReportingSession(hydrated);
|
|
562
|
+
});
|
|
563
|
+
return changed ? { ...sessions, nodes } : sessions;
|
|
564
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { LiveActivityItem, SessionTreeNode } from "../../types.js";
|
|
2
|
+
import type { SliceRunProjection } from "./slice-run-projections.js";
|
|
3
|
+
import type { RuntimeInstanceRecord } from "../../runtime-instance-store.js";
|
|
4
|
+
import type { DecisionActionType } from "../../contracts/shared-types.js";
|
|
5
|
+
export type SliceKind = "work_slice" | "runtime_reporting" | "system_maintenance";
|
|
6
|
+
export type SliceLifecycleStateV2 = "queued" | "dispatching" | "running" | "awaiting_input" | "completed" | "failed" | "archived";
|
|
7
|
+
export type OutcomeState = "succeeded_with_artifacts" | "succeeded_without_artifacts" | "failed_actionable" | "failed_non_actionable" | "needs_input";
|
|
8
|
+
export type ActorType = "agent" | "user" | "orgx" | "system";
|
|
9
|
+
export type SliceActionType = DecisionActionType;
|
|
10
|
+
export type ActorProvenance = {
|
|
11
|
+
actorType: ActorType;
|
|
12
|
+
actorId: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
avatarKey: string;
|
|
15
|
+
};
|
|
16
|
+
export type LineageRef = {
|
|
17
|
+
initiativeIds: string[];
|
|
18
|
+
initiativeTitles: string[];
|
|
19
|
+
workstreamIds: string[];
|
|
20
|
+
workstreamTitles: string[];
|
|
21
|
+
taskIds: string[];
|
|
22
|
+
milestoneIds: string[];
|
|
23
|
+
iwmtIds: string[];
|
|
24
|
+
sliceRunId: string;
|
|
25
|
+
sessionId: string | null;
|
|
26
|
+
};
|
|
27
|
+
export type ArtifactEnvelope = {
|
|
28
|
+
artifactId: string;
|
|
29
|
+
sliceRunId: string;
|
|
30
|
+
type: string;
|
|
31
|
+
title: string;
|
|
32
|
+
url: string | null;
|
|
33
|
+
preview: string | null;
|
|
34
|
+
validation: "present" | "missing" | "invalid";
|
|
35
|
+
confidence: number;
|
|
36
|
+
producedAt: string | null;
|
|
37
|
+
producer: "agent" | "system" | "user";
|
|
38
|
+
};
|
|
39
|
+
export type ActionContract = {
|
|
40
|
+
actionType: SliceActionType;
|
|
41
|
+
label: string;
|
|
42
|
+
payloadSchema: Record<string, unknown>;
|
|
43
|
+
primary: boolean;
|
|
44
|
+
};
|
|
45
|
+
export type WorkSliceProjectionV2 = {
|
|
46
|
+
projectionVersion: number;
|
|
47
|
+
lastEventId: string | null;
|
|
48
|
+
consistencyFlags: string[];
|
|
49
|
+
sliceRunId: string;
|
|
50
|
+
runId: string | null;
|
|
51
|
+
sliceKind: SliceKind;
|
|
52
|
+
lifecycleState: SliceLifecycleStateV2;
|
|
53
|
+
outcomeState: OutcomeState;
|
|
54
|
+
statusExplainer: string;
|
|
55
|
+
actorProvenance: ActorProvenance;
|
|
56
|
+
lineage: LineageRef;
|
|
57
|
+
artifacts: ArtifactEnvelope[];
|
|
58
|
+
artifactCount: number;
|
|
59
|
+
hasArtifact: boolean;
|
|
60
|
+
actionContract: ActionContract | null;
|
|
61
|
+
updatedAt: string | null;
|
|
62
|
+
completedAt: string | null;
|
|
63
|
+
failedAt: string | null;
|
|
64
|
+
archivedAt: string | null;
|
|
65
|
+
runtimeState: string | null;
|
|
66
|
+
sourceClient: string | null;
|
|
67
|
+
confidence: "low" | "medium" | "high";
|
|
68
|
+
};
|
|
69
|
+
export type TimelineNarrativeProjection = {
|
|
70
|
+
projectionVersion: number;
|
|
71
|
+
sliceRunId: string;
|
|
72
|
+
title: string;
|
|
73
|
+
occurredAt: string | null;
|
|
74
|
+
actorProvenance: ActorProvenance;
|
|
75
|
+
intent: string;
|
|
76
|
+
dispatch: string;
|
|
77
|
+
highlights: string[];
|
|
78
|
+
outcome: {
|
|
79
|
+
state: OutcomeState;
|
|
80
|
+
summary: string;
|
|
81
|
+
artifactCount: number;
|
|
82
|
+
};
|
|
83
|
+
nextAction: ActionContract | null;
|
|
84
|
+
technicalTrace: {
|
|
85
|
+
eventCount: number;
|
|
86
|
+
eventIds: string[];
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
export type SnapshotV2Payload = {
|
|
90
|
+
generatedAt: string;
|
|
91
|
+
runningWorkSlices: number;
|
|
92
|
+
needsInput: number;
|
|
93
|
+
failedActionable: number;
|
|
94
|
+
completedToday: number;
|
|
95
|
+
inProgress: WorkSliceProjectionV2[];
|
|
96
|
+
needsInputItems: WorkSliceProjectionV2[];
|
|
97
|
+
failedItems: WorkSliceProjectionV2[];
|
|
98
|
+
nextUpByInitiative: Array<{
|
|
99
|
+
initiativeId: string | null;
|
|
100
|
+
initiativeTitle: string;
|
|
101
|
+
pendingCount: number;
|
|
102
|
+
queue: Array<{
|
|
103
|
+
workstreamId: string | null;
|
|
104
|
+
workstreamTitle: string;
|
|
105
|
+
queueState: string;
|
|
106
|
+
priorityNum: number | null;
|
|
107
|
+
dependencySummary: string | null;
|
|
108
|
+
tasksRemaining: number | null;
|
|
109
|
+
}>;
|
|
110
|
+
}>;
|
|
111
|
+
timelineNarrative: TimelineNarrativeProjection[];
|
|
112
|
+
consistencyFlags: string[];
|
|
113
|
+
dataHealth: {
|
|
114
|
+
status: "healthy" | "degraded";
|
|
115
|
+
totals: {
|
|
116
|
+
slices: number;
|
|
117
|
+
missingTerminal: number;
|
|
118
|
+
lineageGap: number;
|
|
119
|
+
artifactMismatch: number;
|
|
120
|
+
invalidActor: number;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
type BuildSliceExperienceV2Input = {
|
|
125
|
+
generatedAt: string;
|
|
126
|
+
sliceRuns: SliceRunProjection[];
|
|
127
|
+
sessions: SessionTreeNode[];
|
|
128
|
+
activity: LiveActivityItem[];
|
|
129
|
+
runtimeInstances: RuntimeInstanceRecord[];
|
|
130
|
+
nextUpItems: Array<Record<string, unknown>>;
|
|
131
|
+
};
|
|
132
|
+
export declare function buildSliceExperienceSnapshotV2(input: BuildSliceExperienceV2Input): SnapshotV2Payload & {
|
|
133
|
+
projections: WorkSliceProjectionV2[];
|
|
134
|
+
};
|
|
135
|
+
export declare function findSliceNarrative(timelineNarrative: TimelineNarrativeProjection[], sliceRunId: string): TimelineNarrativeProjection | null;
|
|
136
|
+
export declare function findSessionDetailProjection(projections: WorkSliceProjectionV2[], sessionId: string): WorkSliceProjectionV2 | null;
|
|
137
|
+
export {};
|