@llblab/pi-actors 0.55.0 → 0.56.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/AGENTS.md +108 -20
- package/BACKLOG.md +207 -4
- package/CHANGELOG.md +13 -0
- package/README.md +31 -1
- package/dist/index.js +1 -1
- package/dist/lib/async-runs.d.ts +37 -0
- package/dist/lib/async-runs.js +131 -62
- package/dist/lib/automatic-review-runtime.d.ts +2 -0
- package/dist/lib/automatic-review-runtime.js +3 -2
- package/dist/lib/command-templates.d.ts +37 -0
- package/dist/lib/command-templates.js +263 -129
- package/dist/lib/execution-files.d.ts +32 -0
- package/dist/lib/execution-files.js +128 -0
- package/dist/lib/execution-output.js +5 -4
- package/dist/lib/execution-sessions.d.ts +19 -1
- package/dist/lib/execution-sessions.js +62 -26
- package/dist/lib/execution.d.ts +4 -1
- package/dist/lib/execution.js +6 -1
- package/dist/lib/extension-runtime.d.ts +9 -2
- package/dist/lib/extension-runtime.js +92 -14
- package/dist/lib/file-state.js +21 -2
- package/dist/lib/inspector-command.js +2 -2
- package/dist/lib/inspector-overlay.d.ts +25 -7
- package/dist/lib/inspector-overlay.js +562 -262
- package/dist/lib/inspector.d.ts +20 -10
- package/dist/lib/inspector.js +80 -91
- package/dist/lib/limits.d.ts +1 -0
- package/dist/lib/limits.js +1 -0
- package/dist/lib/observability.d.ts +15 -1
- package/dist/lib/observability.js +216 -99
- package/dist/lib/pi.d.ts +5 -4
- package/dist/lib/pi.js +64 -10
- package/dist/lib/recipe-projection.d.ts +18 -0
- package/dist/lib/recipe-projection.js +220 -0
- package/dist/lib/recipes-context.d.ts +2 -0
- package/dist/lib/recipes-context.js +30 -6
- package/dist/lib/registry.js +270 -36
- package/dist/lib/run-delivery.d.ts +213 -5
- package/dist/lib/run-delivery.js +1909 -40
- package/dist/lib/run-supervision.d.ts +107 -0
- package/dist/lib/run-supervision.js +412 -0
- package/dist/lib/run-ui-runtime.d.ts +9 -2
- package/dist/lib/run-ui-runtime.js +283 -60
- package/dist/lib/runs-artifacts.d.ts +26 -1
- package/dist/lib/runs-artifacts.js +68 -2
- package/dist/lib/runs-context-exports.d.ts +451 -0
- package/dist/lib/runs-context-exports.js +2315 -0
- package/dist/lib/runs-context-index.d.ts +97 -0
- package/dist/lib/runs-context-index.js +368 -0
- package/dist/lib/runs-control-delivery.js +46 -7
- package/dist/lib/runs-control.d.ts +78 -2
- package/dist/lib/runs-control.js +334 -2
- package/dist/lib/runs-controls.js +4 -1
- package/dist/lib/runs-descendant-launches.d.ts +80 -0
- package/dist/lib/runs-descendant-launches.js +287 -0
- package/dist/lib/runs-execution-evidence.d.ts +110 -0
- package/dist/lib/runs-execution-evidence.js +282 -0
- package/dist/lib/runs-index.d.ts +66 -1
- package/dist/lib/runs-index.js +349 -13
- package/dist/lib/runs-native-launches.d.ts +73 -0
- package/dist/lib/runs-native-launches.js +227 -0
- package/dist/lib/runs-outcomes.d.ts +141 -0
- package/dist/lib/runs-outcomes.js +292 -0
- package/dist/lib/runs-ownership.d.ts +10 -1
- package/dist/lib/runs-ownership.js +36 -4
- package/dist/lib/runs-process-windows-mi.d.ts +46 -0
- package/dist/lib/runs-process-windows-mi.js +114 -0
- package/dist/lib/runs-process.d.ts +34 -1
- package/dist/lib/runs-process.js +158 -26
- package/dist/lib/runs-results.d.ts +116 -0
- package/dist/lib/runs-results.js +518 -0
- package/dist/lib/runs-retention.d.ts +15 -2
- package/dist/lib/runs-retention.js +148 -9
- package/dist/lib/runs-session-exports.d.ts +95 -0
- package/dist/lib/runs-session-exports.js +470 -0
- package/dist/lib/runs-snapshot.d.ts +58 -0
- package/dist/lib/runs-snapshot.js +92 -0
- package/dist/lib/runs-start.d.ts +2 -0
- package/dist/lib/runs-start.js +44 -3
- package/dist/lib/runs-status.d.ts +15 -1
- package/dist/lib/runs-status.js +337 -13
- package/dist/lib/runs-supervision.d.ts +105 -0
- package/dist/lib/runs-supervision.js +501 -0
- package/dist/lib/runs-trace.d.ts +1 -0
- package/dist/lib/runs-trace.js +14 -3
- package/dist/lib/runtime.js +22 -3
- package/dist/lib/session-evidence.d.ts +37 -0
- package/dist/lib/session-evidence.js +59 -3
- package/dist/lib/state-readers.d.ts +4 -1
- package/dist/lib/state-readers.js +14 -8
- package/dist/lib/temp.d.ts +2 -4
- package/dist/lib/temp.js +4 -56
- package/dist/lib/tools-access.d.ts +3 -0
- package/dist/lib/tools-access.js +13 -0
- package/dist/lib/tools-inspect.d.ts +1 -0
- package/dist/lib/tools-inspect.js +110 -43
- package/dist/lib/tools-local.d.ts +3 -0
- package/dist/lib/tools-local.js +18 -6
- package/dist/lib/tools-message.d.ts +4 -1
- package/dist/lib/tools-message.js +126 -31
- package/dist/lib/tools-response.d.ts +31 -3
- package/dist/lib/tools-response.js +311 -47
- package/dist/lib/tools-spawn.d.ts +3 -0
- package/dist/lib/tools-spawn.js +29 -7
- package/dist/lib/trace-projection.d.ts +20 -0
- package/dist/lib/trace-projection.js +192 -43
- package/dist/scripts/async-runner.mjs +272 -194
- package/dist/scripts/conformance.mjs +14 -2
- package/dist/skills/actors/SKILL.md +46 -2
- package/dist/skills/actors/references/diagnostics.md +40 -0
- package/dist/skills/actors/references/runs.md +55 -1
- package/docs/README.md +9 -1
- package/docs/actor-inspector.md +84 -15
- package/docs/agent-experience.md +216 -0
- package/docs/async-runs.md +18 -2
- package/docs/composition-transport.md +103 -0
- package/docs/coordinator-delivery.md +204 -4
- package/docs/inspection.md +38 -2
- package/docs/output-projection-map.md +130 -0
- package/docs/releasing.md +19 -2
- package/docs/run-supervision.md +1622 -0
- package/docs/template-recipes.md +4 -0
- package/docs/windows-process-observation.md +248 -0
- package/index.ts +1 -1
- package/lib/async-runs.ts +164 -73
- package/lib/automatic-review-runtime.ts +4 -2
- package/lib/command-templates.ts +287 -138
- package/lib/execution-files.ts +118 -0
- package/lib/execution-output.ts +4 -4
- package/lib/execution-sessions.ts +57 -27
- package/lib/execution.ts +8 -0
- package/lib/extension-runtime.ts +102 -12
- package/lib/file-state.ts +16 -2
- package/lib/inspector-command.ts +2 -2
- package/lib/inspector-overlay.ts +524 -261
- package/lib/inspector.ts +101 -130
- package/lib/limits.ts +1 -0
- package/lib/observability.ts +235 -116
- package/lib/pi.ts +59 -11
- package/lib/recipe-projection.ts +232 -0
- package/lib/recipes-context.ts +27 -6
- package/lib/registry.ts +266 -36
- package/lib/run-delivery.ts +1737 -49
- package/lib/run-supervision.ts +411 -0
- package/lib/run-ui-runtime.ts +237 -73
- package/lib/runs-artifacts.ts +73 -1
- package/lib/runs-context-exports.ts +1871 -0
- package/lib/runs-context-index.ts +372 -0
- package/lib/runs-control-delivery.ts +36 -18
- package/lib/runs-control.ts +297 -1
- package/lib/runs-controls.ts +3 -1
- package/lib/runs-descendant-launches.ts +338 -0
- package/lib/runs-execution-evidence.ts +302 -0
- package/lib/runs-index.ts +345 -17
- package/lib/runs-native-launches.ts +270 -0
- package/lib/runs-outcomes.ts +377 -0
- package/lib/runs-ownership.ts +37 -4
- package/lib/runs-process-windows-mi.ts +113 -0
- package/lib/runs-process.ts +210 -34
- package/lib/runs-results.ts +601 -0
- package/lib/runs-retention.ts +134 -10
- package/lib/runs-session-exports.ts +406 -0
- package/lib/runs-snapshot.ts +143 -0
- package/lib/runs-start.ts +44 -2
- package/lib/runs-status.ts +252 -10
- package/lib/runs-supervision.ts +394 -0
- package/lib/runs-trace.ts +14 -3
- package/lib/runtime.ts +22 -3
- package/lib/session-evidence.ts +76 -4
- package/lib/state-readers.ts +16 -7
- package/lib/temp.ts +3 -56
- package/lib/tools-access.ts +13 -0
- package/lib/tools-inspect.ts +110 -51
- package/lib/tools-local.ts +37 -24
- package/lib/tools-message.ts +120 -37
- package/lib/tools-response.ts +273 -50
- package/lib/tools-spawn.ts +31 -10
- package/lib/trace-projection.ts +165 -42
- package/package.json +10 -6
- package/scripts/async-runner.mjs +272 -194
- package/scripts/conformance.mjs +14 -2
- package/skills/actors/SKILL.md +46 -2
- package/skills/actors/references/diagnostics.md +40 -0
- package/skills/actors/references/runs.md +55 -1
- package/banner.jpg +0 -0
- package/dist/lib/inspector-actions.d.ts +0 -16
- package/dist/lib/inspector-actions.js +0 -57
- package/lib/inspector-actions.ts +0 -79
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
* Zones: causal evidence merge, source filtering, redaction, deterministic ordering
|
|
4
4
|
* Owns public Trace items; source journals and session parsing remain in their domains.
|
|
5
5
|
*/
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
6
7
|
import { existsSync, statSync } from "node:fs";
|
|
7
8
|
import { join, relative } from "node:path";
|
|
8
9
|
import * as ControlProjection from "./control-projection.js";
|
|
9
10
|
import * as ExecutionSessions from "./execution-sessions.js";
|
|
10
11
|
import * as Limits from "./limits.js";
|
|
11
|
-
import {
|
|
12
|
+
import { createRunRecipeEvidenceRedactor } from "./recipe-projection.js";
|
|
13
|
+
import { describeRunArtifactReferences, observeRunArtifactReference, } from "./runs-artifacts.js";
|
|
12
14
|
import * as RunsControls from "./runs-controls.js";
|
|
15
|
+
import { isRunStopResultCapture } from "./runs-outcomes.js";
|
|
13
16
|
import { tailFile } from "./runs-status.js";
|
|
14
17
|
import * as RunsTrace from "./runs-trace.js";
|
|
15
18
|
import * as SessionEvidence from "./session-evidence.js";
|
|
16
19
|
import { readJsonFileResilient, } from "./state-readers.js";
|
|
17
20
|
export const TRACE_ITEM_SEQUENCE = Symbol("trace-item-sequence");
|
|
21
|
+
export const TRACE_ITEM_CHRONOLOGY = Symbol("trace-item-chronology");
|
|
18
22
|
const LIFECYCLE_PREFIXES = ["run.", "command."];
|
|
19
23
|
const SOURCE_LIMIT = 100;
|
|
20
24
|
const SOURCE_RANK = {
|
|
@@ -49,6 +53,69 @@ function compareTraceItems(left, right) {
|
|
|
49
53
|
return SOURCE_RANK[right.item.source] - SOURCE_RANK[left.item.source] ||
|
|
50
54
|
right.item.id.localeCompare(left.item.id);
|
|
51
55
|
}
|
|
56
|
+
// Read-local metadata only; availability is not an original-history, issuer or work capability.
|
|
57
|
+
class TraceChronologyBuilder {
|
|
58
|
+
entries = [];
|
|
59
|
+
bytes = 2;
|
|
60
|
+
reason;
|
|
61
|
+
unavailable(reason) { this.reason ??= reason; this.entries.length = 0; }
|
|
62
|
+
add(item, sourceKey, ordinal) {
|
|
63
|
+
if (this.reason)
|
|
64
|
+
return;
|
|
65
|
+
if (typeof item.id !== "string" || !item.id) {
|
|
66
|
+
this.unavailable("metadata_unavailable");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const projected = redact([item.id, item.ts]);
|
|
70
|
+
if (projected[0] !== item.id || projected[1] !== item.ts) {
|
|
71
|
+
this.unavailable("metadata_private");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (typeof item.ts !== "string" || item.ts.length !== 24 || !Number.isFinite(Date.parse(item.ts)) || new Date(item.ts).toISOString() !== item.ts) {
|
|
75
|
+
this.unavailable("timestamp_unavailable");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const entry = { item: { id: item.id, ts: item.ts, source: item.source }, sourceKey, ordinal };
|
|
79
|
+
this.bytes += Buffer.byteLength(JSON.stringify(entry)) + Number(this.entries.length > 0);
|
|
80
|
+
if (this.bytes > Limits.TRACE_JOURNAL_MAX_BYTES) {
|
|
81
|
+
this.unavailable("metadata_too_large");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.entries.push(entry);
|
|
85
|
+
}
|
|
86
|
+
finish(items) {
|
|
87
|
+
const ranks = new Map();
|
|
88
|
+
if (!this.reason) {
|
|
89
|
+
this.entries.sort(compareTraceItems);
|
|
90
|
+
for (const [index, key] of this.entries.entries()) {
|
|
91
|
+
if (ranks.has(key.item.id)) {
|
|
92
|
+
this.unavailable("metadata_ambiguous");
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
ranks.set(key.item.id, { key, ordinal: this.entries.length - index });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!this.reason && items.some(({ item, sourceKey }) => {
|
|
99
|
+
const entry = ranks.get(item.id);
|
|
100
|
+
return !entry || entry.key.sourceKey !== sourceKey || entry.key.item.ts !== item.ts || entry.key.item.source !== item.source;
|
|
101
|
+
}))
|
|
102
|
+
this.unavailable("metadata_unavailable");
|
|
103
|
+
// The legacy same-source ordinal/cross-source rank tie rule is not always a total order.
|
|
104
|
+
if (!this.reason)
|
|
105
|
+
for (const source of ["all", ...Object.keys(SOURCE_RANK)]) {
|
|
106
|
+
let previous = Infinity;
|
|
107
|
+
const view = items.filter(({ item }) => source === "all" || item.source === source).sort(compareTraceItems);
|
|
108
|
+
if (view.some(({ item }) => { const rank = ranks.get(item.id).ordinal; const mismatch = rank >= previous; previous = rank; return mismatch; })) {
|
|
109
|
+
this.unavailable("metadata_ambiguous");
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const { item } of items)
|
|
114
|
+
Object.defineProperty(item, TRACE_ITEM_CHRONOLOGY, { value: Object.freeze(this.reason
|
|
115
|
+
? { state: "unavailable", basis: "recorded_observations", reason: this.reason }
|
|
116
|
+
: { state: "available", basis: "recorded_observations", ordinal: ranks.get(item.id).ordinal, total: ranks.size }) });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
52
119
|
function latestControlTimestamp(control) {
|
|
53
120
|
return (control.failed_at ??
|
|
54
121
|
control.handled_at ??
|
|
@@ -83,9 +150,16 @@ function controlDiagnosticItems(diagnostics) {
|
|
|
83
150
|
},
|
|
84
151
|
}));
|
|
85
152
|
}
|
|
86
|
-
function traceEventItems(
|
|
87
|
-
const read = RunsTrace.readRunTraceJournal(stateDir);
|
|
153
|
+
function traceEventItems(read, recipe, projectEvidence = recipe ? createRunRecipeEvidenceRedactor(recipe) : redact, chronology) {
|
|
88
154
|
const summary = RunsTrace.summarizeRunTraceJournal(read);
|
|
155
|
+
if (!summary.history_complete)
|
|
156
|
+
chronology?.unavailable("history_incomplete");
|
|
157
|
+
if (chronology)
|
|
158
|
+
for (const { event, ordinal } of read.events) {
|
|
159
|
+
if (redact(event.kind) !== event.kind)
|
|
160
|
+
chronology.unavailable("metadata_private");
|
|
161
|
+
chronology.add({ id: event.id, ts: event.ts, source: sourceForEvent(event) }, "trace", ordinal);
|
|
162
|
+
}
|
|
89
163
|
const sequenceOffset = summary.dropped_events + Math.max(0, summary.compactions_total - 1);
|
|
90
164
|
const retained = read.events.slice(-SOURCE_LIMIT);
|
|
91
165
|
const projected = retained.map(({ event, ordinal }) => ordered({
|
|
@@ -93,9 +167,9 @@ function traceEventItems(stateDir) {
|
|
|
93
167
|
ts: event.ts,
|
|
94
168
|
source: sourceForEvent(event),
|
|
95
169
|
kind: event.kind,
|
|
96
|
-
summary: event.summary ?? event.kind,
|
|
170
|
+
summary: projectEvidence(event.summary ?? event.kind),
|
|
97
171
|
...(event.level ? { level: event.level } : {}),
|
|
98
|
-
detail:
|
|
172
|
+
detail: projectEvidence({
|
|
99
173
|
...(event.attention ? { attention: event.attention } : {}),
|
|
100
174
|
...(event.data !== undefined ? { data: event.data } : {}),
|
|
101
175
|
}),
|
|
@@ -119,8 +193,34 @@ function traceEventItems(stateDir) {
|
|
|
119
193
|
}
|
|
120
194
|
return [...projected, ...diagnostics];
|
|
121
195
|
}
|
|
122
|
-
function controlItems(stateDir) {
|
|
196
|
+
function controlItems(stateDir, chronology) {
|
|
123
197
|
const read = RunsControls.readRunControlJournalFromStateDir(stateDir);
|
|
198
|
+
if (read.diagnostics.length)
|
|
199
|
+
chronology?.unavailable("metadata_unavailable");
|
|
200
|
+
let terminal = 0;
|
|
201
|
+
if (chronology)
|
|
202
|
+
for (const [index, raw] of read.records.entries()) {
|
|
203
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
204
|
+
chronology.unavailable("metadata_unavailable");
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const record = raw;
|
|
208
|
+
if (![record.id, record.action, record.run_instance_id, record.queued_at].every(value => typeof value === "string") || !record.id || !record.run_instance_id ||
|
|
209
|
+
!["queued", "delivered", "claimed", "handled", "failed"].includes(record.status)) {
|
|
210
|
+
chronology.unavailable("metadata_unavailable");
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (record.status === "handled" || record.status === "failed")
|
|
214
|
+
terminal++;
|
|
215
|
+
const metadata = { id: record.id, action: record.action, run_instance_id: record.run_instance_id, queued_at: record.queued_at, status: record.status,
|
|
216
|
+
...Object.fromEntries(["failed_at", "handled_at", "claimed_at", "delivered_at"].flatMap(field => typeof raw[field] === "string" ? [[field, raw[field]]] : [])) };
|
|
217
|
+
const value = ControlProjection.projectRunControl(metadata);
|
|
218
|
+
if (value.id !== record.id || latestControlTimestamp(value) !== latestControlTimestamp(record))
|
|
219
|
+
chronology.unavailable("metadata_unavailable");
|
|
220
|
+
chronology.add({ id: `control:${value.id}`, ts: latestControlTimestamp(value), source: "control" }, "control", index + 1);
|
|
221
|
+
}
|
|
222
|
+
if (terminal >= Limits.RUN_CONTROL_TERMINAL_LIMIT)
|
|
223
|
+
chronology?.unavailable("control_history_unproven");
|
|
124
224
|
const start = Math.max(0, read.records.length - SOURCE_LIMIT);
|
|
125
225
|
const projected = read.records.slice(start).map((control, index) => {
|
|
126
226
|
const value = ControlProjection.projectRunControl(control);
|
|
@@ -139,14 +239,41 @@ function controlItems(stateDir) {
|
|
|
139
239
|
...controlDiagnosticItems(read.diagnostics).map((item, index) => ordered(item, "control", read.records.length + index + 1)),
|
|
140
240
|
];
|
|
141
241
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
242
|
+
function agentIdentity(commandId, sessionFile, index, admitted) {
|
|
243
|
+
const namespace = redact([commandId, sessionFile]);
|
|
244
|
+
const identity = namespace[0] === commandId && namespace[1] === sessionFile ? admitted : undefined;
|
|
245
|
+
const basis = identity?.basis ?? "legacy";
|
|
246
|
+
const key = createHash("sha256").update(JSON.stringify([
|
|
247
|
+
"agent-turn-v1", ...namespace, identity ?? { basis, ordinal: index },
|
|
248
|
+
])).digest("hex");
|
|
249
|
+
return `agent:${basis}:${key}`;
|
|
250
|
+
}
|
|
251
|
+
function agentItems(stateDir, chronology) {
|
|
252
|
+
const turns = ExecutionSessions.readExecutionTurns(stateDir);
|
|
253
|
+
const metadata = turns[ExecutionSessions.EXECUTION_CHRONOLOGY];
|
|
254
|
+
if (!metadata || metadata.state !== "available")
|
|
255
|
+
chronology?.unavailable("metadata_unavailable");
|
|
256
|
+
else
|
|
257
|
+
for (const entry of metadata.entries)
|
|
258
|
+
chronology?.add({
|
|
259
|
+
id: agentIdentity(entry.commandId, entry.sessionFile, entry.ordinal, entry.identity), ts: entry.timestamp, source: "agent",
|
|
260
|
+
}, "agent", entry.ordinal);
|
|
261
|
+
return turns.slice(-SOURCE_LIMIT).map((turn) => {
|
|
146
262
|
const text = turn.assistantText ?? turn.userText ?? "Agent turn";
|
|
147
|
-
const
|
|
263
|
+
const compact = text.replaceAll(/\s+/g, " ").trim();
|
|
264
|
+
let summary = compact;
|
|
265
|
+
if (Buffer.from(compact).toString("utf8") !== compact) {
|
|
266
|
+
summary = "Agent turn [omitted: unknown] (malformed retained text)";
|
|
267
|
+
}
|
|
268
|
+
else if (compact.length > 160) {
|
|
269
|
+
const last = compact.charCodeAt(159), next = compact.charCodeAt(160);
|
|
270
|
+
const end = last >= 0xd800 && last <= 0xdbff && next >= 0xdc00 && next <= 0xdfff ? 159 : 160;
|
|
271
|
+
// Only this normalized retained suffix supplies a count; upstream source loss stays unknown.
|
|
272
|
+
const omitted = Array.from(compact.slice(end)).length;
|
|
273
|
+
summary = `${compact.slice(0, end)}… [omitted: ${omitted} chars] from normalized retained turn; upstream [omitted: unknown]`;
|
|
274
|
+
}
|
|
148
275
|
return ordered({
|
|
149
|
-
id:
|
|
276
|
+
id: agentIdentity(turn.commandId, turn.sessionFile, turn.index, turn[SessionEvidence.SESSION_TURN_IDENTITY]),
|
|
150
277
|
ts: turn.timestamp ?? new Date(0).toISOString(),
|
|
151
278
|
source: "agent",
|
|
152
279
|
kind: "agent.turn",
|
|
@@ -184,51 +311,73 @@ function resultItems(stateDir) {
|
|
|
184
311
|
}
|
|
185
312
|
const stat = statSync(path);
|
|
186
313
|
const failed = Number(read.value.code ?? 0) !== 0;
|
|
314
|
+
const captured = isRunStopResultCapture(read.value);
|
|
187
315
|
return [ordered({
|
|
188
316
|
id: "process:result",
|
|
189
317
|
ts: typeof read.value.completedAt === "string"
|
|
190
318
|
? read.value.completedAt
|
|
191
319
|
: stat.mtime.toISOString(),
|
|
192
320
|
source: "process",
|
|
193
|
-
kind: failed ? "process.failed" : "process.result",
|
|
194
|
-
summary: failed ? "Run process failed" : "Run process completed",
|
|
321
|
+
kind: captured ? "process.result_captured" : failed ? "process.failed" : "process.result",
|
|
322
|
+
summary: captured ? "Workload result captured while stopping" : failed ? "Run process failed" : "Run process completed",
|
|
195
323
|
...(failed ? { level: "error" } : {}),
|
|
196
324
|
detail: redact(read.value),
|
|
197
325
|
}, "process:result", 1, 2), ...diagnosticItems(read.diagnostics).map((item, index) => ordered(item, "process:result", index + 2))];
|
|
198
326
|
}
|
|
199
|
-
function artifactItems(stateDir, declarations) {
|
|
200
|
-
const
|
|
201
|
-
if (
|
|
327
|
+
function artifactItems(stateDir, declarations, chronology) {
|
|
328
|
+
const described = describeRunArtifactReferences(declarations, process.cwd());
|
|
329
|
+
if (described.state !== "available") {
|
|
330
|
+
if (declarations)
|
|
331
|
+
chronology?.unavailable("metadata_unavailable");
|
|
202
332
|
return [];
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
333
|
+
}
|
|
334
|
+
if (described.references.length > SOURCE_LIMIT)
|
|
335
|
+
chronology?.unavailable("metadata_unavailable");
|
|
336
|
+
return described.references.slice(0, SOURCE_LIMIT).map((reference, index) => {
|
|
337
|
+
const artifact = observeRunArtifactReference(reference);
|
|
338
|
+
const exists = artifact.availability === "available";
|
|
339
|
+
if (!artifact.modified_at)
|
|
340
|
+
chronology?.unavailable("timestamp_unavailable");
|
|
341
|
+
return ordered({
|
|
342
|
+
id: `artifact:${artifact.name}`,
|
|
343
|
+
ts: artifact.modified_at ?? new Date(0).toISOString(),
|
|
344
|
+
source: "artifact",
|
|
345
|
+
kind: exists ? "artifact.ready" : artifact.availability === "missing" ? "artifact.missing" : "artifact.unavailable",
|
|
346
|
+
summary: redact(`${artifact.name}: ${exists ? "ready" : artifact.availability}`),
|
|
347
|
+
...(artifact.required && !exists ? { level: "warning" } : {}),
|
|
348
|
+
detail: redact({
|
|
349
|
+
...(artifact.availability !== "unavailable" ? { exists } : {}),
|
|
350
|
+
availability: artifact.availability,
|
|
351
|
+
path: relative(stateDir, artifact.path).replaceAll("\\", "/"),
|
|
352
|
+
required: artifact.required,
|
|
353
|
+
...(artifact.bytes_total !== undefined ? { size: artifact.bytes_total } : {}),
|
|
354
|
+
...(artifact.reason ? { reason: artifact.reason } : {}),
|
|
355
|
+
}),
|
|
356
|
+
}, "artifact", index + 1, index);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
/** Data-only canonical-journal projection; captured Recipe context supplies privacy, never lifecycle/work authority. */
|
|
360
|
+
export function projectRunTraceJournal(read, options = {}) {
|
|
361
|
+
return traceEventItems(read, options.recipe, options.redactEvidence).sort(compareTraceItems)
|
|
362
|
+
.slice(0, Math.max(1, Math.min(options.limit ?? 100, 200))).map(({ item }) => item);
|
|
219
363
|
}
|
|
220
364
|
export function projectRunTrace(stateDir, options = {}) {
|
|
221
365
|
const source = options.source ?? "all";
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
...
|
|
225
|
-
...
|
|
226
|
-
...
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
.
|
|
231
|
-
|
|
366
|
+
const chronology = new TraceChronologyBuilder();
|
|
367
|
+
const entries = [
|
|
368
|
+
...traceEventItems(RunsTrace.readRunTraceJournal(stateDir), undefined, undefined, chronology),
|
|
369
|
+
...controlItems(stateDir, chronology),
|
|
370
|
+
...agentItems(stateDir, chronology),
|
|
371
|
+
];
|
|
372
|
+
const snapshots = [...processItems(stateDir), ...resultItems(stateDir), ...artifactItems(stateDir, options.artifacts, chronology)];
|
|
373
|
+
for (const entry of snapshots) {
|
|
374
|
+
if (entry.item.kind === "state.read_error")
|
|
375
|
+
chronology.unavailable("metadata_unavailable");
|
|
376
|
+
chronology.add(entry.item, entry.sourceKey, entry.ordinal);
|
|
377
|
+
}
|
|
378
|
+
const all = [...entries, ...snapshots];
|
|
379
|
+
chronology.finish(all);
|
|
380
|
+
const items = all.filter(({ item }) => source === "all" || item.source === source).sort(compareTraceItems);
|
|
232
381
|
return items
|
|
233
382
|
.slice(0, Math.max(1, Math.min(options.limit ?? 100, 200)))
|
|
234
383
|
.map(({ item }) => item);
|