@relayflows/sdk 2.0.31 → 2.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authored-preflight.d.ts +4 -0
- package/dist/authored-preflight.d.ts.map +1 -0
- package/dist/authored-preflight.js +50 -0
- package/dist/authored-preflight.js.map +1 -0
- package/dist/authored-worker-step.d.ts.map +1 -1
- package/dist/authored-worker-step.js +3 -2
- package/dist/authored-worker-step.js.map +1 -1
- package/dist/cli/check.d.ts +10 -2
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +16 -137
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cli-probe.d.ts +20 -0
- package/dist/cli/cli-probe.d.ts.map +1 -0
- package/dist/cli/cli-probe.js +166 -0
- package/dist/cli/cli-probe.js.map +1 -0
- package/dist/cli/cloud-mirror-session.d.ts +97 -0
- package/dist/cli/cloud-mirror-session.d.ts.map +1 -0
- package/dist/cli/cloud-mirror-session.js +264 -0
- package/dist/cli/cloud-mirror-session.js.map +1 -0
- package/dist/cli-commands.d.ts +6 -0
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +1 -0
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +84 -18
- package/dist/cli.js.map +1 -1
- package/dist/cloud-deploy.d.ts +1 -1
- package/dist/cloud-deploy.d.ts.map +1 -1
- package/dist/cloud-deploy.js +24 -8
- package/dist/cloud-deploy.js.map +1 -1
- package/dist/cloud-mirror-ledger.d.ts +40 -0
- package/dist/cloud-mirror-ledger.d.ts.map +1 -0
- package/dist/cloud-mirror-ledger.js +142 -0
- package/dist/cloud-mirror-ledger.js.map +1 -0
- package/dist/cloud-mirror-step.d.ts +180 -0
- package/dist/cloud-mirror-step.d.ts.map +1 -0
- package/dist/cloud-mirror-step.js +523 -0
- package/dist/cloud-mirror-step.js.map +1 -0
- package/dist/cloud-mirror-transport.d.ts +94 -0
- package/dist/cloud-mirror-transport.d.ts.map +1 -0
- package/dist/cloud-mirror-transport.js +163 -0
- package/dist/cloud-mirror-transport.js.map +1 -0
- package/dist/cloud-mirror.d.ts +132 -0
- package/dist/cloud-mirror.d.ts.map +1 -0
- package/dist/cloud-mirror.js +556 -0
- package/dist/cloud-mirror.js.map +1 -0
- package/dist/cloud-transcript-codex.d.ts.map +1 -1
- package/dist/cloud-transcript-codex.js +90 -4
- package/dist/cloud-transcript-codex.js.map +1 -1
- package/dist/cloud-transcript-types.d.ts +19 -1
- package/dist/cloud-transcript-types.d.ts.map +1 -1
- package/dist/cloud-transcript-types.js.map +1 -1
- package/dist/cloud-transcript.d.ts +1 -1
- package/dist/cloud-transcript.d.ts.map +1 -1
- package/dist/cloud-transcript.js +10 -0
- package/dist/cloud-transcript.js.map +1 -1
- package/dist/helper-reference.d.ts.map +1 -1
- package/dist/helper-reference.js +134 -6
- package/dist/helper-reference.js.map +1 -1
- package/dist/hosted-extension-runtime.js +1 -1
- package/dist/hosted-extension-sandbox.js +1 -1
- package/dist/package-version.d.ts +10 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +22 -0
- package/dist/package-version.js.map +1 -0
- package/dist/preflight.d.ts +14 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +18 -3
- package/dist/preflight.js.map +1 -1
- package/dist/relay-cli.d.ts.map +1 -1
- package/dist/relay-cli.js +1 -21
- package/dist/relay-cli.js.map +1 -1
- package/package.json +2 -2
- package/src/authored-preflight.ts +46 -0
- package/src/authored-worker-step.ts +4 -3
- package/src/cli/check.ts +25 -163
- package/src/cli/cli-probe.ts +194 -0
- package/src/cli/cloud-mirror-session.ts +329 -0
- package/src/cli-commands.ts +1 -0
- package/src/cli.ts +94 -19
- package/src/cloud-deploy.ts +26 -8
- package/src/cloud-mirror-ledger.ts +161 -0
- package/src/cloud-mirror-step.ts +650 -0
- package/src/cloud-mirror-transport.ts +261 -0
- package/src/cloud-mirror.ts +633 -0
- package/src/cloud-transcript-codex.ts +96 -4
- package/src/cloud-transcript-types.ts +18 -1
- package/src/cloud-transcript.ts +9 -1
- package/src/helper-reference.ts +131 -6
- package/src/hosted-extension-runtime.ts +1 -1
- package/src/hosted-extension-sandbox.ts +1 -1
- package/src/package-version.ts +23 -0
- package/src/preflight.ts +31 -7
- package/src/relay-cli.ts +1 -24
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
// One journal, folded into the two step shapes Cloud stores for a run.
|
|
2
|
+
//
|
|
3
|
+
// A hosted run's steps reach Cloud twice: as a *live snapshot* while it runs
|
|
4
|
+
// (`POST /runs/<id>/steps/snapshot`) and as the *final report* once it is over
|
|
5
|
+
// (`POST /runs/<id>/steps`). The sandbox derives both from `flows status`;
|
|
6
|
+
// this module derives them from the same journal fold `flows status` uses
|
|
7
|
+
// (`run-state.ts`), so a local run and a hosted one put the same facts in the
|
|
8
|
+
// same fields and the dashboard cannot tell which produced a row.
|
|
9
|
+
//
|
|
10
|
+
// Nothing here does I/O or reads a clock: the caller passes the events and
|
|
11
|
+
// `now_ms`, exactly as `foldRunState` does. That is what lets a test fold a
|
|
12
|
+
// hand-built journal and assert the exact bytes a push would carry.
|
|
13
|
+
//
|
|
14
|
+
// ## The bounds are the server's, restated
|
|
15
|
+
//
|
|
16
|
+
// Every cap below is the one Cloud's own parser enforces
|
|
17
|
+
// (`@cloud/core` `storage/step-snapshot.ts` and `storage/step-detail.ts`).
|
|
18
|
+
// They are restated rather than imported because this package cannot depend on
|
|
19
|
+
// the Cloud app — the same reason `cloud-transcript.ts` restates the
|
|
20
|
+
// dashboard's transcript vocabulary. A push that violates one is refused
|
|
21
|
+
// whole, so producing a bounded value here is not politeness: it is the
|
|
22
|
+
// difference between a run that appears on the dashboard and one that does
|
|
23
|
+
// not.
|
|
24
|
+
//
|
|
25
|
+
// ## Redaction
|
|
26
|
+
//
|
|
27
|
+
// Every dynamic string goes through `redact` before it is bounded, never
|
|
28
|
+
// after: clipping first can leave the head of a secret standing where the
|
|
29
|
+
// redactor would have replaced the whole value. Identifier-shaped fields are
|
|
30
|
+
// then normalized into the shape Cloud's parser accepts, because the redactor
|
|
31
|
+
// emits `[redacted:NAME]`, which no identifier pattern admits.
|
|
32
|
+
import { redact } from './redact.js';
|
|
33
|
+
import { foldRunState } from './run-state.js';
|
|
34
|
+
import { AUTHORED_STEP_STREAM, foldAuthoredStepRecords } from './authored-step-index.js';
|
|
35
|
+
/** Steps one snapshot may carry; a longer run publishes its live tail. */
|
|
36
|
+
export const SNAPSHOT_MAX_STEPS = 64;
|
|
37
|
+
/** Serialized snapshot envelope cap, against the real UTF-8 byte count. */
|
|
38
|
+
export const SNAPSHOT_MAX_BYTES = 64 * 1024;
|
|
39
|
+
/** Artifact paths named per step; the rest are counted. */
|
|
40
|
+
export const SNAPSHOT_ARTIFACTS_MAX = 5;
|
|
41
|
+
export const SNAPSHOT_ARTIFACT_MAX_CHARS = 200;
|
|
42
|
+
/** `stepName`, `journalRunId`, `stepType`, `completionReason`, gate, model. */
|
|
43
|
+
export const IDENTIFIER_MAX_CHARS = 128;
|
|
44
|
+
/** Predecessors one live step lists. */
|
|
45
|
+
export const SNAPSHOT_DEPENDS_ON_MAX = 32;
|
|
46
|
+
/** Predecessors a final row lists. */
|
|
47
|
+
export const DEPENDS_ON_MAX_ENTRIES = 256;
|
|
48
|
+
/** The backing columns are PostgreSQL 32-bit integers. */
|
|
49
|
+
export const MAX_INT32 = 2_147_483_647;
|
|
50
|
+
/** `workflow_steps.display_name`, in code points. */
|
|
51
|
+
export const LABEL_MAX_CHARS = 120;
|
|
52
|
+
/** `workflow_steps.output_summary`. */
|
|
53
|
+
export const OUTPUT_SUMMARY_MAX_CHARS = 1000;
|
|
54
|
+
/** `workflow_steps.error`. */
|
|
55
|
+
export const ERROR_MAX_CHARS = 1024;
|
|
56
|
+
/** Serialized `workflow_steps.detail`. */
|
|
57
|
+
export const DETAIL_MAX_BYTES = 16 * 1024;
|
|
58
|
+
/** Attempt rows kept on `detail.attempts`; older ones are counted, not listed. */
|
|
59
|
+
export const DETAIL_MAX_ATTEMPTS = 20;
|
|
60
|
+
/**
|
|
61
|
+
* The one completion reason the kernel uses for success. Cloud keys a step's
|
|
62
|
+
* status off exactly this value, so the live derivation and the final row
|
|
63
|
+
* agree about what "completed" means.
|
|
64
|
+
*/
|
|
65
|
+
export const SUCCESS_COMPLETION_REASON = 'success';
|
|
66
|
+
/** The authored root step spans the whole flow; its children carry the steps. */
|
|
67
|
+
export const AUTHORED_ROOT_STEP = 'authored-root';
|
|
68
|
+
const IDENTIFIER = /^[A-Za-z0-9_.:/-]+$/u;
|
|
69
|
+
const IDENTIFIER_UNSAFE = /[^A-Za-z0-9_.:/-]+/gu;
|
|
70
|
+
function record(value) {
|
|
71
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
|
|
72
|
+
}
|
|
73
|
+
function int32(value, floor = 0) {
|
|
74
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
75
|
+
return undefined;
|
|
76
|
+
const rounded = Math.round(value);
|
|
77
|
+
if (rounded < floor)
|
|
78
|
+
return undefined;
|
|
79
|
+
return Math.min(rounded, MAX_INT32);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Redact, then normalize, then clip — in that order. Clipping first could
|
|
83
|
+
* leave the head of a secret standing; normalizing first would let a
|
|
84
|
+
* multi-character replacement push the result back over the cap.
|
|
85
|
+
*/
|
|
86
|
+
export function identifier(value, env, maxChars = IDENTIFIER_MAX_CHARS) {
|
|
87
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
88
|
+
return undefined;
|
|
89
|
+
const clipped = redact(value, env).replace(IDENTIFIER_UNSAFE, '_').slice(0, Math.max(1, maxChars));
|
|
90
|
+
return IDENTIFIER.test(clipped) ? clipped : undefined;
|
|
91
|
+
}
|
|
92
|
+
/** Free text, redacted then bounded by code points. Empty becomes undefined. */
|
|
93
|
+
export function text(value, env, maxChars) {
|
|
94
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
95
|
+
return undefined;
|
|
96
|
+
const cleaned = redact(value, env);
|
|
97
|
+
const bounded = [...cleaned].slice(0, maxChars).join('');
|
|
98
|
+
return bounded.length === 0 ? undefined : bounded;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* A step label as `workflow_steps.display_name` accepts it: control characters
|
|
102
|
+
* become spaces, whitespace runs collapse, the result is trimmed and clipped.
|
|
103
|
+
*/
|
|
104
|
+
export function label(value, env) {
|
|
105
|
+
if (typeof value !== 'string')
|
|
106
|
+
return undefined;
|
|
107
|
+
const normalized = redact(value, env)
|
|
108
|
+
.replace(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]+/gu, ' ')
|
|
109
|
+
.replace(/\s+/gu, ' ')
|
|
110
|
+
.trim();
|
|
111
|
+
if (normalized.length === 0)
|
|
112
|
+
return undefined;
|
|
113
|
+
return [...normalized].slice(0, LABEL_MAX_CHARS).join('').trimEnd();
|
|
114
|
+
}
|
|
115
|
+
function snapshotState(state) {
|
|
116
|
+
// `pending` and `runnable` are states, but not publishable ones: a step that
|
|
117
|
+
// has not begun is neither completed nor running.
|
|
118
|
+
return state === 'pending' || state === 'runnable' ? undefined : state;
|
|
119
|
+
}
|
|
120
|
+
/** Cloud's own vocabulary for a live step, derived rather than carried. */
|
|
121
|
+
export function snapshotStepStatus(step) {
|
|
122
|
+
if (step.state !== 'done')
|
|
123
|
+
return 'running';
|
|
124
|
+
return step.completionReason === SUCCESS_COMPLETION_REASON ? 'completed' : 'failed';
|
|
125
|
+
}
|
|
126
|
+
function snapshotStep(journalRunId, step, env) {
|
|
127
|
+
const state = snapshotState(step.state);
|
|
128
|
+
if (state === undefined)
|
|
129
|
+
return undefined;
|
|
130
|
+
const stepName = identifier(step.id, env);
|
|
131
|
+
const journal = identifier(journalRunId, env);
|
|
132
|
+
const stepType = identifier(step.type, env);
|
|
133
|
+
if (stepName === undefined || journal === undefined || stepType === undefined)
|
|
134
|
+
return undefined;
|
|
135
|
+
const transcript = step.last_attempt?.transcript ?? null;
|
|
136
|
+
const verification = step.last_attempt?.verification ?? null;
|
|
137
|
+
const gateName = verification === null ? undefined : identifier(verification.gate, env);
|
|
138
|
+
const gateVerdict = verification === null ? undefined : identifier(verification.verdict, env);
|
|
139
|
+
const paths = step.artifacts.paths
|
|
140
|
+
.slice(0, SNAPSHOT_ARTIFACTS_MAX)
|
|
141
|
+
.map(path => identifier(path, env, SNAPSHOT_ARTIFACT_MAX_CHARS))
|
|
142
|
+
.filter((path) => path !== undefined);
|
|
143
|
+
const completionReason = identifier(step.completion_reason ?? step.last_attempt?.completion_reason, env);
|
|
144
|
+
const cost = transcript?.total_cost_usd;
|
|
145
|
+
return {
|
|
146
|
+
stepName,
|
|
147
|
+
journalRunId: journal,
|
|
148
|
+
stepType,
|
|
149
|
+
state,
|
|
150
|
+
attempt: int32(step.attempt) ?? 0,
|
|
151
|
+
elapsedMs: int32(step.elapsed_ms) ?? 0,
|
|
152
|
+
...(completionReason === undefined ? {} : { completionReason }),
|
|
153
|
+
...(gateName === undefined || gateVerdict === undefined ? {} : { gate: { name: gateName, verdict: gateVerdict } }),
|
|
154
|
+
...(identifier(transcript?.model, env) === undefined ? {} : { model: identifier(transcript?.model, env) }),
|
|
155
|
+
...(int32(transcript?.num_turns) === undefined ? {} : { turns: int32(transcript?.num_turns) }),
|
|
156
|
+
...(int32(transcript?.tool_calls) === undefined ? {} : { toolCalls: int32(transcript?.tool_calls) }),
|
|
157
|
+
...(typeof cost === 'number' && Number.isFinite(cost) && cost >= 0 ? { costUsd: cost } : {}),
|
|
158
|
+
...(step.artifacts.journaled ? { artifactCount: int32(step.artifacts.paths.length) ?? 0 } : {}),
|
|
159
|
+
...(paths.length === 0 ? {} : { artifacts: paths }),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function isoAt(ms) {
|
|
163
|
+
if (typeof ms !== 'number' || !Number.isFinite(ms))
|
|
164
|
+
return '';
|
|
165
|
+
const at = new Date(ms);
|
|
166
|
+
return Number.isNaN(at.getTime()) ? '' : at.toISOString();
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The bounded `workflow_steps.detail` for one step: the attempt's journaled
|
|
170
|
+
* transcript digest, plus the attempt roster. The digest is already redacted
|
|
171
|
+
* and bounded where the worker wrote it (`agent-transcript.ts`); it is
|
|
172
|
+
* re-bounded here because this process, not that one, is what Cloud's parser
|
|
173
|
+
* will judge.
|
|
174
|
+
*/
|
|
175
|
+
function stepDetail(attempts, env) {
|
|
176
|
+
const last = attempts.at(-1);
|
|
177
|
+
const digest = record(record(last?.trajectoryTail)?.['transcript']);
|
|
178
|
+
const roster = attempts.slice(-DETAIL_MAX_ATTEMPTS).map(entry => ({
|
|
179
|
+
attempt: entry.attempt,
|
|
180
|
+
atMs: entry.atMs,
|
|
181
|
+
completionReason: identifier(entry.completionReason, env) ?? 'unknown',
|
|
182
|
+
...(identifier(entry.disposition, env) === undefined ? {} : { disposition: identifier(entry.disposition, env) }),
|
|
183
|
+
...(entry.transcriptBytes === undefined ? {} : { transcriptBytes: entry.transcriptBytes }),
|
|
184
|
+
}));
|
|
185
|
+
if (digest === undefined && roster.length <= 1)
|
|
186
|
+
return {};
|
|
187
|
+
// The digest carries a sandbox-free copy of the transcript's facts. `file`
|
|
188
|
+
// names a path on *this* machine, which is neither useful to a reader of the
|
|
189
|
+
// dashboard nor something to publish; the byte counts beside it are.
|
|
190
|
+
const file = record(digest?.['file']);
|
|
191
|
+
const detail = {
|
|
192
|
+
...(digest === undefined ? {} : {
|
|
193
|
+
transcript: {
|
|
194
|
+
...digest,
|
|
195
|
+
...(file === undefined ? {} : {
|
|
196
|
+
file: Object.fromEntries(Object.entries(file).filter(([key]) => key !== 'path')),
|
|
197
|
+
}),
|
|
198
|
+
},
|
|
199
|
+
}),
|
|
200
|
+
...(roster.length === 0 ? {} : { attempts: roster }),
|
|
201
|
+
...(attempts.length > roster.length ? { attemptsOmitted: attempts.length - roster.length } : {}),
|
|
202
|
+
};
|
|
203
|
+
if (Buffer.byteLength(JSON.stringify(detail), 'utf8') <= DETAIL_MAX_BYTES)
|
|
204
|
+
return { detail };
|
|
205
|
+
// Over the cap: drop the transcript's free text and its tool roster — the
|
|
206
|
+
// largest fields by far — and say the detail was cut rather than dropping it
|
|
207
|
+
// whole, which would take the attempt history with it.
|
|
208
|
+
const transcript = record(detail['transcript']);
|
|
209
|
+
const reduced = {
|
|
210
|
+
...(transcript === undefined ? {} : {
|
|
211
|
+
transcript: Object.fromEntries(Object.entries(transcript).filter(([key]) => key === 'attempt' || key === 'exit_code'
|
|
212
|
+
|| key === 'file' || key === 'result')),
|
|
213
|
+
}),
|
|
214
|
+
...(roster.length === 0 ? {} : { attempts: roster }),
|
|
215
|
+
};
|
|
216
|
+
if (Buffer.byteLength(JSON.stringify(reduced), 'utf8') <= DETAIL_MAX_BYTES) {
|
|
217
|
+
return { detail: reduced, truncated: true };
|
|
218
|
+
}
|
|
219
|
+
return { detail: { attempts: roster.slice(-1) }, truncated: true };
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Every `step.completed` the journal holds, in order, by step id.
|
|
223
|
+
*
|
|
224
|
+
* `foldRunState` keeps only the *last* attempt, because that is what a status
|
|
225
|
+
* view shows. The final report's `detail.attempts` is the whole roster, and
|
|
226
|
+
* its token totals are the sum across attempts, so both need the raw entries.
|
|
227
|
+
*/
|
|
228
|
+
function attemptsByStep(events) {
|
|
229
|
+
const byStep = new Map();
|
|
230
|
+
for (const event of events) {
|
|
231
|
+
if (event.entry_type !== 'step.completed' || event.step_id === null)
|
|
232
|
+
continue;
|
|
233
|
+
const payload = record(event.payload) ?? {};
|
|
234
|
+
const budget = record(payload['budget']) ?? {};
|
|
235
|
+
const digest = record(record(payload['trajectory_tail'])?.['transcript']);
|
|
236
|
+
const file = record(digest?.['file']);
|
|
237
|
+
const result = record(digest?.['result']);
|
|
238
|
+
const entries = byStep.get(event.step_id) ?? [];
|
|
239
|
+
entries.push({
|
|
240
|
+
attempt: event.attempt ?? entries.length + 1,
|
|
241
|
+
atMs: event.at_ms,
|
|
242
|
+
completionReason: typeof payload['completionReason'] === 'string' ? payload['completionReason'] : 'unknown',
|
|
243
|
+
disposition: typeof payload['disposition'] === 'string' ? payload['disposition'] : 'unknown',
|
|
244
|
+
trajectoryTail: payload['trajectory_tail'],
|
|
245
|
+
...(int32(file?.['bytes_kept']) === undefined ? {} : { transcriptBytes: int32(file?.['bytes_kept']) }),
|
|
246
|
+
...(typeof file?.['path'] === 'string' ? { transcriptPath: file['path'] } : {}),
|
|
247
|
+
...(int32(budget['tokens_in']) === undefined ? {} : { tokensIn: int32(budget['tokens_in']) }),
|
|
248
|
+
...(int32(budget['tokens_out']) === undefined ? {} : { tokensOut: int32(budget['tokens_out']) }),
|
|
249
|
+
...(typeof result?.['total_cost_usd'] === 'number' && Number.isFinite(result['total_cost_usd'])
|
|
250
|
+
&& result['total_cost_usd'] >= 0
|
|
251
|
+
? { costUsd: result['total_cost_usd'] } : {}),
|
|
252
|
+
...(budget['dollars_unmetered'] === true ? { costUnmetered: true } : {}),
|
|
253
|
+
});
|
|
254
|
+
byStep.set(event.step_id, entries);
|
|
255
|
+
}
|
|
256
|
+
return byStep;
|
|
257
|
+
}
|
|
258
|
+
function finalStep(step, attempts, env) {
|
|
259
|
+
const stepName = identifier(step.id, env);
|
|
260
|
+
const stepType = identifier(step.type, env);
|
|
261
|
+
if (stepName === undefined || stepType === undefined)
|
|
262
|
+
return undefined;
|
|
263
|
+
const completionReason = step.completion_reason ?? step.last_attempt?.completion_reason ?? 'unknown';
|
|
264
|
+
const succeeded = completionReason === SUCCESS_COMPLETION_REASON;
|
|
265
|
+
const transcript = step.last_attempt?.transcript ?? null;
|
|
266
|
+
const startMs = step.started_at_ms;
|
|
267
|
+
const endMs = step.last_attempt?.ended_at_ms ?? null;
|
|
268
|
+
const duration = startMs !== null && endMs !== null ? Math.max(0, endMs - startMs) : (step.elapsed_ms ?? 0);
|
|
269
|
+
const tokensIn = attempts.reduce((total, entry) => total + (entry.tokensIn ?? 0), 0);
|
|
270
|
+
const tokensOut = attempts.reduce((total, entry) => total + (entry.tokensOut ?? 0), 0);
|
|
271
|
+
const failure = transcript?.failure ?? null;
|
|
272
|
+
// Summed across attempts, exactly as the tokens above are. Taking the last
|
|
273
|
+
// attempt's figure while summing its tokens was inconsistent in itself, and
|
|
274
|
+
// Cloud totals these rows for the run's spend — so a retried agent's earlier
|
|
275
|
+
// charges simply vanished from the run.
|
|
276
|
+
const spentUsd = attempts.reduce((total, entry) => total + (entry.costUsd ?? 0), 0);
|
|
277
|
+
const priced = attempts.some(entry => entry.costUsd !== undefined);
|
|
278
|
+
/**
|
|
279
|
+
* Any unpriced attempt makes the step's cost unknown, even when another
|
|
280
|
+
* attempt reported one.
|
|
281
|
+
*
|
|
282
|
+
* The first cut suppressed the flag whenever `spentUsd > 0`, which published
|
|
283
|
+
* a partial subtotal as though it were the whole cost: a step that spent
|
|
284
|
+
* $0.02 on attempt 1 and an unpriced amount on attempt 2 reported exactly
|
|
285
|
+
* $0.02. The two facts are not exclusive — `costUsd` is then a *lower bound*
|
|
286
|
+
* and the flag says so. `run-state.ts`'s `addSpend` keeps them together for
|
|
287
|
+
* the same reason.
|
|
288
|
+
*
|
|
289
|
+
* Presence, not a positive sum: an attempt reporting `total_cost_usd: 0` did
|
|
290
|
+
* produce a price, and testing `spentUsd === 0` would have called that step
|
|
291
|
+
* unpriced.
|
|
292
|
+
*/
|
|
293
|
+
const unmetered = attempts.some(entry => entry.costUnmetered === true);
|
|
294
|
+
const detail = stepDetail(attempts, env);
|
|
295
|
+
const verification = step.last_attempt?.verification ?? null;
|
|
296
|
+
// What the step said about itself. A gate's verdict detail is the nearest
|
|
297
|
+
// thing a deterministic step has to an agent's final message; an agent step
|
|
298
|
+
// has neither in the status view, so the completion reason stands alone
|
|
299
|
+
// rather than being invented.
|
|
300
|
+
const summary = text(verification?.detail, env, OUTPUT_SUMMARY_MAX_CHARS)
|
|
301
|
+
?? `step ${succeeded ? 'completed' : 'ended'}: ${identifier(completionReason, env) ?? 'unknown'}`;
|
|
302
|
+
const model = identifier(transcript?.model, env);
|
|
303
|
+
const error = succeeded ? undefined : text(failure?.excerpt, env, ERROR_MAX_CHARS);
|
|
304
|
+
return {
|
|
305
|
+
stepName,
|
|
306
|
+
stepType,
|
|
307
|
+
// Cloud's legacy v1 columns. The kernel has no agent/preset/CLI identity
|
|
308
|
+
// per step, and an empty string is the honest answer the hosted v2
|
|
309
|
+
// executor gives too — never a guess that would render as a real name.
|
|
310
|
+
agent: '',
|
|
311
|
+
preset: '',
|
|
312
|
+
cli: '',
|
|
313
|
+
// Named after the uploaded transcript object once one is written, exactly
|
|
314
|
+
// as the sandbox does; empty until then, never a fabricated sandbox id.
|
|
315
|
+
sandboxId: '',
|
|
316
|
+
startTime: isoAt(startMs),
|
|
317
|
+
endTime: isoAt(endMs),
|
|
318
|
+
durationMs: int32(duration) ?? 0,
|
|
319
|
+
exitCode: succeeded ? 0 : 1,
|
|
320
|
+
outputSummary: summary,
|
|
321
|
+
status: succeeded ? 'completed' : 'failed',
|
|
322
|
+
completionReason: identifier(completionReason, env) ?? 'unknown',
|
|
323
|
+
retryCount: Math.max(0, attempts.length - 1),
|
|
324
|
+
...(model === undefined ? {} : { model }),
|
|
325
|
+
...(tokensIn > 0 ? { tokensInput: Math.min(tokensIn, MAX_INT32) } : {}),
|
|
326
|
+
...(tokensOut > 0 ? { tokensOutput: Math.min(tokensOut, MAX_INT32) } : {}),
|
|
327
|
+
...(priced ? { costUsd: spentUsd } : {}),
|
|
328
|
+
...(unmetered ? { costUnmetered: true } : {}),
|
|
329
|
+
...(error === undefined ? {} : { error }),
|
|
330
|
+
...(detail.detail === undefined ? {} : { detail: detail.detail }),
|
|
331
|
+
...(detail.truncated === undefined ? {} : { detailTruncated: detail.truncated }),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
/** Per-attempt transcript files this step left on disk, in attempt order. */
|
|
335
|
+
function transcriptRef(stepName, attempts) {
|
|
336
|
+
const files = attempts
|
|
337
|
+
.filter((entry) => entry.transcriptPath !== undefined)
|
|
338
|
+
.map(entry => ({ attempt: entry.attempt, path: entry.transcriptPath }));
|
|
339
|
+
return files.length === 0 ? undefined : { stepName, attempts: files };
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Fold one journal into everything the mirror can say about it.
|
|
343
|
+
*
|
|
344
|
+
* The authored root is deliberately not published as a step: it spans the
|
|
345
|
+
* whole flow, so a snapshot carrying it would show one node called
|
|
346
|
+
* `authored-root` sitting at 100% for the run's entire duration beside the
|
|
347
|
+
* steps that actually did the work. Its journal is still read, for the step
|
|
348
|
+
* index that names the child journals and their graph edges.
|
|
349
|
+
*/
|
|
350
|
+
export function mirrorJournal(runId, events, nowMs, env = process.env) {
|
|
351
|
+
const view = foldRunState(events, nowMs);
|
|
352
|
+
const attempts = attemptsByStep(events);
|
|
353
|
+
const steps = [];
|
|
354
|
+
const finals = [];
|
|
355
|
+
const transcripts = [];
|
|
356
|
+
for (const step of view.steps) {
|
|
357
|
+
if (step.id === AUTHORED_ROOT_STEP)
|
|
358
|
+
continue;
|
|
359
|
+
const live = snapshotStep(runId, step, env);
|
|
360
|
+
if (live !== undefined)
|
|
361
|
+
steps.push(live);
|
|
362
|
+
const stepAttempts = attempts.get(step.id) ?? [];
|
|
363
|
+
if (step.state === 'done') {
|
|
364
|
+
const row = finalStep(step, stepAttempts, env);
|
|
365
|
+
if (row !== undefined) {
|
|
366
|
+
finals.push(row);
|
|
367
|
+
const ref = transcriptRef(row.stepName, stepAttempts);
|
|
368
|
+
if (ref !== undefined)
|
|
369
|
+
transcripts.push(ref);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const index = authoredIndex(events, env);
|
|
374
|
+
// A declarative flow declares its edges in the spec, not in an authored-step
|
|
375
|
+
// stream — so a YAML run had no hints at all and drew every node
|
|
376
|
+
// unconnected. Read them from `run.spawned`, keyed the same way, and let the
|
|
377
|
+
// authored index win where both exist (an authored root's index is the
|
|
378
|
+
// richer record, and carries labels too).
|
|
379
|
+
const declared = declaredEdges(runId, events, env);
|
|
380
|
+
for (const [key, hint] of declared) {
|
|
381
|
+
if (!index.hints.has(key))
|
|
382
|
+
index.hints.set(key, hint);
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
runId,
|
|
386
|
+
status: view.status,
|
|
387
|
+
terminal: view.status === 'completed' || view.status === 'failed' || view.status === 'cancelled',
|
|
388
|
+
steps,
|
|
389
|
+
finals,
|
|
390
|
+
transcripts,
|
|
391
|
+
children: index.children,
|
|
392
|
+
hints: index.hints,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* An authored root's step index: which child journal runs each authored step,
|
|
397
|
+
* what the author called it, and what it came after.
|
|
398
|
+
*
|
|
399
|
+
* This is the only place those facts exist. A child journal's own view knows
|
|
400
|
+
* its kernel step ids and nothing about the authored graph above it, so
|
|
401
|
+
* without the root's index a mirrored authored run would show its steps with
|
|
402
|
+
* no names and no edges — which is exactly what the run graph draws from.
|
|
403
|
+
*/
|
|
404
|
+
function authoredIndex(events, env) {
|
|
405
|
+
const messages = [];
|
|
406
|
+
for (const event of events) {
|
|
407
|
+
if (event.entry_type !== 'stream.appended')
|
|
408
|
+
continue;
|
|
409
|
+
const payload = record(event.payload);
|
|
410
|
+
if (payload?.['stream'] === AUTHORED_STEP_STREAM)
|
|
411
|
+
messages.push(payload['message']);
|
|
412
|
+
}
|
|
413
|
+
const children = [];
|
|
414
|
+
const hints = new Map();
|
|
415
|
+
for (const entry of foldAuthoredStepRecords(messages).values()) {
|
|
416
|
+
if (/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(entry.runId))
|
|
417
|
+
children.push(entry.runId);
|
|
418
|
+
const name = label(entry.label, env);
|
|
419
|
+
const after = entry.after === undefined
|
|
420
|
+
? undefined
|
|
421
|
+
: [...entry.after]
|
|
422
|
+
.slice(0, DEPENDS_ON_MAX_ENTRIES)
|
|
423
|
+
.map(value => identifier(value, env))
|
|
424
|
+
.filter((value) => value !== undefined);
|
|
425
|
+
if (name === undefined && after === undefined)
|
|
426
|
+
continue;
|
|
427
|
+
hints.set(`${entry.runId}/${entry.step}`, {
|
|
428
|
+
...(name === undefined ? {} : { label: name }),
|
|
429
|
+
...(after === undefined ? {} : { after }),
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
return { children, hints };
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* The `depends_on` a declarative spec declares, as graph hints.
|
|
436
|
+
*
|
|
437
|
+
* `foldRunState` reads these to decide readiness but does not surface them on
|
|
438
|
+
* `StepView`, and deliberately: `flows status --json` is a pinned shape. So
|
|
439
|
+
* they are read here, straight off the `run.spawned` payload this fold already
|
|
440
|
+
* has in hand, rather than by widening a view other readers depend on.
|
|
441
|
+
*/
|
|
442
|
+
function declaredEdges(runId, events, env) {
|
|
443
|
+
const hints = new Map();
|
|
444
|
+
const spawned = events.find(event => event.entry_type === 'run.spawned');
|
|
445
|
+
const steps = record(spawned?.payload)?.['spec'];
|
|
446
|
+
const declared = record(steps)?.['steps'];
|
|
447
|
+
if (!Array.isArray(declared))
|
|
448
|
+
return hints;
|
|
449
|
+
for (const entry of declared) {
|
|
450
|
+
const step = record(entry);
|
|
451
|
+
const id = identifier(step?.['id'], env);
|
|
452
|
+
if (id === undefined)
|
|
453
|
+
continue;
|
|
454
|
+
const raw = step?.['depends_on'] ?? step?.['dependsOn'];
|
|
455
|
+
if (!Array.isArray(raw))
|
|
456
|
+
continue;
|
|
457
|
+
const after = raw
|
|
458
|
+
.slice(0, DEPENDS_ON_MAX_ENTRIES)
|
|
459
|
+
.map(value => identifier(value, env))
|
|
460
|
+
.filter((value) => value !== undefined);
|
|
461
|
+
hints.set(`${runId}/${id}`, { after });
|
|
462
|
+
}
|
|
463
|
+
return hints;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Build a snapshot envelope that actually fits both bounds.
|
|
467
|
+
*
|
|
468
|
+
* The count cap applies unconditionally — 65 tiny steps are 65 steps. Only
|
|
469
|
+
* then does the byte cap bite: first the artifact *names* go (their count
|
|
470
|
+
* survives), then the `dependsOn` edges, then whole entries from the head of
|
|
471
|
+
* the display order, because the tail is the newest work and that is what a
|
|
472
|
+
* live view exists to show. A capped view announces itself as incomplete;
|
|
473
|
+
* silently showing fewer steps than ran is the one thing it must not do.
|
|
474
|
+
*/
|
|
475
|
+
export function fitSnapshot(steps, envelope) {
|
|
476
|
+
let kept = [...steps];
|
|
477
|
+
let omitted = envelope.alreadyOmitted ?? 0;
|
|
478
|
+
let truncated = omitted > 0;
|
|
479
|
+
if (kept.length > SNAPSHOT_MAX_STEPS) {
|
|
480
|
+
omitted += kept.length - SNAPSHOT_MAX_STEPS;
|
|
481
|
+
kept = kept.slice(kept.length - SNAPSHOT_MAX_STEPS);
|
|
482
|
+
truncated = true;
|
|
483
|
+
}
|
|
484
|
+
const build = () => ({
|
|
485
|
+
sequence: envelope.sequence,
|
|
486
|
+
capturedAt: envelope.capturedAt,
|
|
487
|
+
...(truncated ? { truncated: true } : {}),
|
|
488
|
+
...(omitted > 0 ? { omittedStepCount: Math.min(omitted, MAX_INT32) } : {}),
|
|
489
|
+
steps: kept,
|
|
490
|
+
});
|
|
491
|
+
const bytes = () => Buffer.byteLength(JSON.stringify(build()), 'utf8');
|
|
492
|
+
if (bytes() <= SNAPSHOT_MAX_BYTES)
|
|
493
|
+
return build();
|
|
494
|
+
kept = kept.map(({ artifacts: _artifacts, ...step }) => step);
|
|
495
|
+
truncated = true;
|
|
496
|
+
if (bytes() <= SNAPSHOT_MAX_BYTES)
|
|
497
|
+
return build();
|
|
498
|
+
kept = kept.map(({ dependsOn: _dependsOn, ...step }) => step);
|
|
499
|
+
if (bytes() <= SNAPSHOT_MAX_BYTES)
|
|
500
|
+
return build();
|
|
501
|
+
while (kept.length > 1 && bytes() > SNAPSHOT_MAX_BYTES) {
|
|
502
|
+
kept = kept.slice(1);
|
|
503
|
+
omitted += 1;
|
|
504
|
+
}
|
|
505
|
+
return build();
|
|
506
|
+
}
|
|
507
|
+
/** Apply an authored root's graph hints to a step, bounded for the live view. */
|
|
508
|
+
export function withGraphHints(step, hints, journalRunId, maxDependsOn, knownSteps) {
|
|
509
|
+
const hint = hints.get(`${journalRunId}/${step.stepName}`);
|
|
510
|
+
if (hint === undefined)
|
|
511
|
+
return step;
|
|
512
|
+
// Only predecessors that are themselves steps of this report: an edge to a
|
|
513
|
+
// node the graph does not contain draws nothing and reads as data loss.
|
|
514
|
+
const after = hint.after
|
|
515
|
+
?.filter(name => name !== step.stepName && knownSteps.has(name))
|
|
516
|
+
.slice(0, maxDependsOn);
|
|
517
|
+
return {
|
|
518
|
+
...step,
|
|
519
|
+
...(hint.label === undefined ? {} : { label: hint.label }),
|
|
520
|
+
...(after === undefined ? {} : { dependsOn: after }),
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
//# sourceMappingURL=cloud-mirror-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-mirror-step.js","sourceRoot":"","sources":["../src/cloud-mirror-step.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type CloudConnectionOptions } from './cloud-http.js';
|
|
2
|
+
import type { FinalStep, SnapshotStep } from './cloud-mirror-step.js';
|
|
3
|
+
/** What registration returns: the run, and the credential that may report on it. */
|
|
4
|
+
export interface MirrorRegistration {
|
|
5
|
+
runId: string;
|
|
6
|
+
/** The run-bound token every later call authenticates with. */
|
|
7
|
+
token: string;
|
|
8
|
+
/** Proves the terminal callback came from this run's executor. */
|
|
9
|
+
callbackToken: string;
|
|
10
|
+
/** The dashboard page for this run, as Cloud named it. */
|
|
11
|
+
runUrl: string;
|
|
12
|
+
/**
|
|
13
|
+
* The deployment that issued the credential, pinned.
|
|
14
|
+
*
|
|
15
|
+
* Load-bearing, not bookkeeping. `cloudConnection` resolves the base URL
|
|
16
|
+
* from the *login store* only while no explicit token is given — and every
|
|
17
|
+
* call after registration gives one. Without pinning it here, a CLI signed
|
|
18
|
+
* in to a staging deployment would register there and then send that
|
|
19
|
+
* deployment's run token to the production default.
|
|
20
|
+
*/
|
|
21
|
+
apiUrl: string;
|
|
22
|
+
}
|
|
23
|
+
export interface MirrorRunSource {
|
|
24
|
+
/** The exact source bytes that ran: YAML/JSON text, or authored `.flow.ts`. */
|
|
25
|
+
workflow: string;
|
|
26
|
+
fileType: 'yaml' | 'ts';
|
|
27
|
+
/** Authored runs only: the input the flow was invoked with. */
|
|
28
|
+
inputs?: unknown;
|
|
29
|
+
/**
|
|
30
|
+
* The Cloud run of the attempt this one continues, for a `flows resume`.
|
|
31
|
+
*
|
|
32
|
+
* Cloud models a resume as a new attempt row — its own hosted resume mints a
|
|
33
|
+
* fresh run id too — so one parked-then-resumed flow is two rows either way.
|
|
34
|
+
* Naming the predecessor is what stops those two rows reading as two
|
|
35
|
+
* unrelated pieces of work: the run page links them, and a reader of the
|
|
36
|
+
* red "Needs review" row can see it was answered.
|
|
37
|
+
*/
|
|
38
|
+
resumedFromRunId?: string;
|
|
39
|
+
}
|
|
40
|
+
/** One lifecycle event, in the vocabulary Cloud's session event stream uses. */
|
|
41
|
+
export interface MirrorEvent {
|
|
42
|
+
eventType: string;
|
|
43
|
+
stepName?: string;
|
|
44
|
+
payload?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Register the run and take its credential.
|
|
48
|
+
*
|
|
49
|
+
* The only call here that throws. Everything the mirror does afterwards
|
|
50
|
+
* depends on this receipt, so a caller has to be able to tell "Cloud refused"
|
|
51
|
+
* from "Cloud accepted" — and the CLI turns that difference into one line on
|
|
52
|
+
* stderr rather than a failed run.
|
|
53
|
+
*/
|
|
54
|
+
export declare function registerLocalRun(source: MirrorRunSource, options?: CloudConnectionOptions): Promise<MirrorRegistration>;
|
|
55
|
+
/** A mirror's authenticated view of one run. Built once, from the registration. */
|
|
56
|
+
export declare class MirrorClient {
|
|
57
|
+
private readonly registration;
|
|
58
|
+
/** Connection options with the run's credential and its deployment pinned. */
|
|
59
|
+
private readonly bound;
|
|
60
|
+
constructor(registration: MirrorRegistration, options?: CloudConnectionOptions);
|
|
61
|
+
get runId(): string;
|
|
62
|
+
get runUrl(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Every call but registration goes through here. The run token replaces the
|
|
65
|
+
* operator credential, the outcome collapses to a boolean, and nothing —
|
|
66
|
+
* not a refusal, not a timeout, not a thrown transport error — escapes.
|
|
67
|
+
*/
|
|
68
|
+
private post;
|
|
69
|
+
publishEvent(event: MirrorEvent, signal?: AbortSignal): Promise<boolean>;
|
|
70
|
+
publishSnapshot(snapshot: {
|
|
71
|
+
sequence: number;
|
|
72
|
+
capturedAt: string;
|
|
73
|
+
truncated?: true;
|
|
74
|
+
omittedStepCount?: number;
|
|
75
|
+
steps: SnapshotStep[];
|
|
76
|
+
}, limits?: {
|
|
77
|
+
signal?: AbortSignal;
|
|
78
|
+
timeoutMs?: number;
|
|
79
|
+
}): Promise<boolean>;
|
|
80
|
+
publishSteps(steps: readonly FinalStep[], omittedStepCount: number, signal?: AbortSignal, timeoutMs?: number): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Write one object under the run's storage prefix. The keys are the ones the
|
|
83
|
+
* `/logs` route already reads: `runner.log` for the run, and
|
|
84
|
+
* `<stepName>/agent.log` for a step's assembled transcript.
|
|
85
|
+
*/
|
|
86
|
+
putObject(key: string, bytes: Uint8Array, signal?: AbortSignal, timeoutMs?: number): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* The terminal status. Authenticated by the callback token rather than the
|
|
89
|
+
* run token, because that is the credential this route checks — and because
|
|
90
|
+
* the run token is revoked by the transition this very call performs.
|
|
91
|
+
*/
|
|
92
|
+
reportTerminal(status: 'completed' | 'failed' | 'cancelled', result: Record<string, unknown>, error?: string, signal?: AbortSignal, timeoutMs?: number): Promise<boolean>;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=cloud-mirror-transport.d.ts.map
|