@orcareplay/core 0.1.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.
@@ -0,0 +1,21 @@
1
+ import type { BlobRef } from '@orcareplay/schema';
2
+ /**
3
+ * Content-addressed blob store, laid out as `<dir>/<first two hex>/<full hex>` (spec §2.2).
4
+ *
5
+ * Every model turn resends the whole conversation, so identical content arrives over and over.
6
+ * Addressing by digest is what keeps a trace O(n) in new content instead of O(n²) in turns —
7
+ * hence `put` of existing content must not touch the file at all.
8
+ */
9
+ export declare class BlobStore {
10
+ #private;
11
+ /** @param dir The blob root, conventionally `<runDir>/blobs`. */
12
+ constructor(dir: string);
13
+ get dir(): string;
14
+ put(data: Uint8Array | string, mediaType?: string): Promise<BlobRef>;
15
+ get(ref: BlobRef | string): Promise<Uint8Array>;
16
+ has(digest: BlobRef | string): Promise<boolean>;
17
+ count(): Promise<number>;
18
+ }
19
+ /** SHA-256 of a whole file, streamed — this is the integrity root of a run (spec §6). */
20
+ export declare function sha256File(path: string): Promise<string>;
21
+ //# sourceMappingURL=blobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAqBlD;;;;;;GAMG;AACH,qBAAa,SAAS;;IAGpB,iEAAiE;gBACrD,GAAG,EAAE,MAAM;IAIvB,IAAI,GAAG,IAAI,MAAM,CAEhB;IAEK,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBpE,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAY/C,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;CAS/B;AAED,yFAAyF;AACzF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9D"}
package/dist/blobs.js ADDED
@@ -0,0 +1,97 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { createReadStream } from 'node:fs';
3
+ import { mkdir, readFile, readdir, rename, stat, writeFile } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ /** Traces are sensitive material (design §7), so nothing is group- or world-readable. */
6
+ const FILE_MODE = 0o600;
7
+ const DIR_MODE = 0o700;
8
+ const HEX64 = /^[0-9a-f]{64}$/;
9
+ const PREFIX = 'sha256:';
10
+ /** Accepts `sha256:<hex>` or a bare hex digest and returns the bare hex. */
11
+ function bareDigest(ref) {
12
+ const raw = typeof ref === 'string' ? ref : ref.$blob;
13
+ const hex = raw.startsWith(PREFIX) ? raw.slice(PREFIX.length) : raw;
14
+ if (!HEX64.test(hex))
15
+ throw new Error(`invalid blob digest: ${JSON.stringify(raw)}`);
16
+ return hex;
17
+ }
18
+ function toBytes(data) {
19
+ return typeof data === 'string' ? new Uint8Array(Buffer.from(data, 'utf8')) : data;
20
+ }
21
+ /**
22
+ * Content-addressed blob store, laid out as `<dir>/<first two hex>/<full hex>` (spec §2.2).
23
+ *
24
+ * Every model turn resends the whole conversation, so identical content arrives over and over.
25
+ * Addressing by digest is what keeps a trace O(n) in new content instead of O(n²) in turns —
26
+ * hence `put` of existing content must not touch the file at all.
27
+ */
28
+ export class BlobStore {
29
+ #dir;
30
+ /** @param dir The blob root, conventionally `<runDir>/blobs`. */
31
+ constructor(dir) {
32
+ this.#dir = dir;
33
+ }
34
+ get dir() {
35
+ return this.#dir;
36
+ }
37
+ async put(data, mediaType) {
38
+ const bytes = toBytes(data);
39
+ const hex = createHash('sha256').update(bytes).digest('hex');
40
+ const ref = { $blob: `${PREFIX}${hex}`, bytes: bytes.byteLength };
41
+ if (mediaType !== undefined)
42
+ ref.media_type = mediaType;
43
+ const shard = join(this.#dir, hex.slice(0, 2));
44
+ const path = join(shard, hex);
45
+ if (await exists(path))
46
+ return ref;
47
+ await mkdir(shard, { recursive: true, mode: DIR_MODE });
48
+ // Write then rename so a reader never sees a half-written blob under its final digest.
49
+ const tmp = `${path}.${randomBytes(6).toString('hex')}.tmp`;
50
+ await writeFile(tmp, bytes, { mode: FILE_MODE });
51
+ await rename(tmp, path);
52
+ return ref;
53
+ }
54
+ async get(ref) {
55
+ const hex = bareDigest(ref);
56
+ const path = join(this.#dir, hex.slice(0, 2), hex);
57
+ let buf;
58
+ try {
59
+ buf = await readFile(path);
60
+ }
61
+ catch {
62
+ throw new Error(`blob not found: ${PREFIX}${hex} (looked in ${path})`);
63
+ }
64
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
65
+ }
66
+ async has(digest) {
67
+ const hex = bareDigest(digest);
68
+ return exists(join(this.#dir, hex.slice(0, 2), hex));
69
+ }
70
+ async count() {
71
+ let n = 0;
72
+ for (const shard of await readdir(this.#dir, { withFileTypes: true }).catch(() => [])) {
73
+ if (!shard.isDirectory())
74
+ continue;
75
+ const files = await readdir(join(this.#dir, shard.name)).catch(() => []);
76
+ n += files.filter((f) => HEX64.test(f)).length;
77
+ }
78
+ return n;
79
+ }
80
+ }
81
+ /** SHA-256 of a whole file, streamed — this is the integrity root of a run (spec §6). */
82
+ export async function sha256File(path) {
83
+ const hash = createHash('sha256');
84
+ for await (const chunk of createReadStream(path))
85
+ hash.update(chunk);
86
+ return hash.digest('hex');
87
+ }
88
+ async function exists(path) {
89
+ try {
90
+ await stat(path);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ //# sourceMappingURL=blobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import type { TraceEvent } from '@orcareplay/schema';
2
+ /** A forkable point in a run. Derived from the log, never recorded (spec §3). */
3
+ export interface Checkpoint {
4
+ seq: number;
5
+ turn: number;
6
+ /** Tree id from the governing `fs.snapshot`, when it recorded one. */
7
+ fsTree?: string;
8
+ }
9
+ export interface Turn {
10
+ turn: number;
11
+ startSeq: number;
12
+ endSeq: number;
13
+ events: TraceEvent[];
14
+ }
15
+ export interface SnapResult {
16
+ checkpoint: Checkpoint;
17
+ /** True when the target was not itself a checkpoint and had to move back. */
18
+ snapped: boolean;
19
+ }
20
+ /**
21
+ * Every seq that satisfies both checkpoint conditions of spec §3: an `fs.snapshot` at or before it
22
+ * in the same turn, and a complete conversation prefix.
23
+ */
24
+ export declare function deriveCheckpoints(events: TraceEvent[]): Checkpoint[];
25
+ /**
26
+ * The checkpoint a fork of `target` must actually start from — the nearest preceding one.
27
+ *
28
+ * Never rounds forward. Forking from state the run had not reached yet would produce a child run
29
+ * that silently disagrees with its parent, which is worse than refusing outright.
30
+ */
31
+ export declare function snapToCheckpoint(cps: Checkpoint[], target: number): SnapResult;
32
+ /** The events of a run grouped into model turns, in turn order. */
33
+ export declare function turnsOf(events: TraceEvent[]): Turn[];
34
+ /** The event at `seq` and everything transitively named by `causes`, oldest first. */
35
+ export declare function causalChain(events: TraceEvent[], seq: number): TraceEvent[];
36
+ /** Where an edge came from. The distinction is the whole honesty mechanism — see `runGraph`. */
37
+ export type EdgeKind = 'recorded' | 'inferred';
38
+ export interface GraphNode {
39
+ seq: number;
40
+ turn: number;
41
+ type: TraceEvent['type'];
42
+ attrs?: Record<string, unknown>;
43
+ }
44
+ export interface GraphEdge {
45
+ /** The cause. Always less than `to`, as spec §2.1 requires of `causes`. */
46
+ from: number;
47
+ to: number;
48
+ kind: EdgeKind;
49
+ /** Why this edge exists. For an inferred edge, the rule that produced it. */
50
+ rule: string;
51
+ }
52
+ export interface RunGraph {
53
+ nodes: GraphNode[];
54
+ edges: GraphEdge[];
55
+ }
56
+ /**
57
+ * A run as nodes and edges, with every edge saying whether the trace vouches for it.
58
+ *
59
+ * Two kinds, and they are not interchangeable. A `recorded` edge came out of `causes`, which the
60
+ * recorder wrote because it watched the relationship happen. An `inferred` edge was derived here,
61
+ * just now, by the named rule — a filesystem snapshot is taken once per turn rather than once per
62
+ * tool call, and shell frames are bucketed into turns by wall clock, so attributing an effect to a
63
+ * *particular* call is a guess however good the heuristic is.
64
+ *
65
+ * Inferred edges are therefore never written back to the trace. That is the same discipline spec
66
+ * §3 applies to checkpoints, which are derived and never recorded, and it exists so that a field
67
+ * a third-party reader trusts never contains something orca made up.
68
+ */
69
+ export declare function runGraph(events: TraceEvent[]): RunGraph;
70
+ /**
71
+ * The sub-graph that produced `seq`: that event and everything transitively behind it.
72
+ *
73
+ * `causalChain` walks `causes` alone and so stops at the first inferred hop, which in a real run
74
+ * is the hop from a tool call to the shell command it ran — exactly the one a person following a
75
+ * failure backwards needs. This walks the derived graph instead, so it crosses both kinds.
76
+ */
77
+ export declare function chainTo(graph: RunGraph, seq: number): RunGraph;
78
+ /**
79
+ * The event a card about this run should be about, or undefined when nothing stands out.
80
+ *
81
+ * Which chain to draw *is* the feature. A card gets screenshotted whether or not it happens to be
82
+ * the interesting one, so an arbitrary pick travels further than no card at all — hence a run with
83
+ * nothing notable returns undefined and the caller refuses rather than drawing something.
84
+ *
85
+ * The order is failure first, then the largest visible effect: a command that exited non-zero, a
86
+ * tool that reported an error, an error orca itself recorded, a replay divergence, and only then
87
+ * the last file the run changed. Within a kind the last one wins, since that is where the run
88
+ * ended up.
89
+ */
90
+ export declare function pickChainTarget(events: TraceEvent[]): number | undefined;
91
+ /** Tool calls that hand work to another agent, by the argument every harness gives them. */
92
+ export declare function isDelegation(event: TraceEvent): boolean;
93
+ /**
94
+ * The delegation whose span encloses `seq`, if any.
95
+ *
96
+ * A replay that halts inside one is the hardest kind of miss to read: the distance is small, the
97
+ * trace is intact, and nothing on the line says why the same run asked a different question. The
98
+ * answer is that the harness wrote the delegate's prompt itself and writes a fresh one every time,
99
+ * so that request genuinely was not the recorded one. Naming the delegation turns a number into
100
+ * that sentence.
101
+ */
102
+ export declare function enclosingDelegation(events: TraceEvent[], seq: number): {
103
+ seq: number;
104
+ subagent: string;
105
+ } | undefined;
106
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;CAClB;AAyBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAmBpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAkB9E;AAED,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,CAepD;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAsB3E;AAED,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AA6GD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAgDvD;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CA8B9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,SAAS,CAiBxE;AAOD,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAMvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAAE,EACpB,GAAG,EAAE,MAAM,GACV;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAkB/C"}
package/dist/graph.js ADDED
@@ -0,0 +1,393 @@
1
+ function bySeq(events) {
2
+ return [...events].sort((a, b) => a.seq - b.seq);
3
+ }
4
+ /**
5
+ * The seq of the first `model.request` with no reply, or Infinity when the conversation is whole.
6
+ *
7
+ * Requests and responses are paired in order, so a second request that is still in flight is not
8
+ * excused by the first one's reply. Everything after an unanswered request is un-forkable: the
9
+ * model's effect on the run is unknown there.
10
+ */
11
+ function firstUnansweredRequest(events) {
12
+ const requests = events.filter((e) => e.type === 'model.request');
13
+ const responses = events.filter((e) => e.type === 'model.response');
14
+ for (let i = 0; i < requests.length; i++) {
15
+ const request = requests[i];
16
+ const response = responses[i];
17
+ if (!request)
18
+ continue;
19
+ if (!response || response.seq <= request.seq)
20
+ return request.seq;
21
+ }
22
+ return Number.POSITIVE_INFINITY;
23
+ }
24
+ /**
25
+ * Every seq that satisfies both checkpoint conditions of spec §3: an `fs.snapshot` at or before it
26
+ * in the same turn, and a complete conversation prefix.
27
+ */
28
+ export function deriveCheckpoints(events) {
29
+ const ordered = bySeq(events);
30
+ const cutoff = firstUnansweredRequest(ordered);
31
+ const checkpoints = [];
32
+ let snapshot;
33
+ for (const e of ordered) {
34
+ if (e.seq > cutoff)
35
+ break;
36
+ if (e.type === 'fs.snapshot') {
37
+ const tree = e.attrs?.['tree'];
38
+ snapshot = { turn: e.turn, tree: typeof tree === 'string' ? tree : undefined };
39
+ }
40
+ // A snapshot only vouches for the state of its own turn; work in a later turn has moved on.
41
+ if (!snapshot || snapshot.turn !== e.turn)
42
+ continue;
43
+ const checkpoint = { seq: e.seq, turn: e.turn };
44
+ if (snapshot.tree !== undefined)
45
+ checkpoint.fsTree = snapshot.tree;
46
+ checkpoints.push(checkpoint);
47
+ }
48
+ return checkpoints;
49
+ }
50
+ /**
51
+ * The checkpoint a fork of `target` must actually start from — the nearest preceding one.
52
+ *
53
+ * Never rounds forward. Forking from state the run had not reached yet would produce a child run
54
+ * that silently disagrees with its parent, which is worse than refusing outright.
55
+ */
56
+ export function snapToCheckpoint(cps, target) {
57
+ const ordered = [...cps].sort((a, b) => a.seq - b.seq);
58
+ if (ordered.length === 0) {
59
+ throw new Error(`cannot fork at seq ${target}: this run has no checkpoints — it recorded no fs.snapshot`);
60
+ }
61
+ let found;
62
+ for (const cp of ordered) {
63
+ if (cp.seq > target)
64
+ break;
65
+ found = cp;
66
+ }
67
+ if (!found) {
68
+ throw new Error(`no checkpoint at or before ${target}: the earliest forkable seq is ${ordered[0]?.seq}`);
69
+ }
70
+ return { checkpoint: found, snapped: found.seq !== target };
71
+ }
72
+ /** The events of a run grouped into model turns, in turn order. */
73
+ export function turnsOf(events) {
74
+ const byTurn = new Map();
75
+ for (const e of bySeq(events)) {
76
+ const bucket = byTurn.get(e.turn);
77
+ if (bucket)
78
+ bucket.push(e);
79
+ else
80
+ byTurn.set(e.turn, [e]);
81
+ }
82
+ return [...byTurn.entries()]
83
+ .sort((a, b) => a[0] - b[0])
84
+ .map(([turn, group]) => ({
85
+ turn,
86
+ startSeq: group[0]?.seq ?? 0,
87
+ endSeq: group[group.length - 1]?.seq ?? 0,
88
+ events: group,
89
+ }));
90
+ }
91
+ /** The event at `seq` and everything transitively named by `causes`, oldest first. */
92
+ export function causalChain(events, seq) {
93
+ const index = new Map(events.map((e) => [e.seq, e]));
94
+ const start = index.get(seq);
95
+ if (!start)
96
+ throw new Error(`no event with seq ${seq} in this trace`);
97
+ const seen = new Set([seq]);
98
+ const queue = [start];
99
+ const chain = [];
100
+ while (queue.length > 0) {
101
+ const event = queue.shift();
102
+ if (!event)
103
+ break;
104
+ chain.push(event);
105
+ for (const cause of event.causes ?? []) {
106
+ // A cycle is malformed, and an ancestor may be missing because the reader skipped an
107
+ // unknown event type. Neither may stop the walk.
108
+ if (seen.has(cause))
109
+ continue;
110
+ seen.add(cause);
111
+ const parent = index.get(cause);
112
+ if (parent)
113
+ queue.push(parent);
114
+ }
115
+ }
116
+ return chain.sort((a, b) => a.seq - b.seq);
117
+ }
118
+ /**
119
+ * What a recorded pair means, when the pair is one orca itself writes.
120
+ *
121
+ * `causes` says *that* one event caused another and never *why*, so this is a post-hoc reading of
122
+ * the type pair rather than anything the trace claims. An unrecognised pair says `causes` and
123
+ * stops there, which is the honest answer for an edge written by a reader we do not know.
124
+ */
125
+ const RECORDED_RULES = {
126
+ 'tool.call→tool.result': 'tool result answers its call',
127
+ 'shell.exec→shell.result': 'shell result answers its exec',
128
+ 'net.request→net.response': 'network response answers its request',
129
+ 'model.response→tool.call': 'tool_use block in the response',
130
+ 'tool.result→model.request': 'tool_result block in the request',
131
+ };
132
+ const ARGV_RULE = 'argv matches tool input, same or previous turn';
133
+ const PATH_RULE = 'changed path appears in tool input, same or previous turn';
134
+ /**
135
+ * How many turns back an effect may reach for the call that caused it.
136
+ *
137
+ * One, not zero. A snapshot is taken when the turn's exchange is persisted, which races the agent
138
+ * actually running the tool — an end-to-end recording produced the edit in the turn's own snapshot
139
+ * on one run and in the next turn's on another. A same-turn rule therefore made the graph differ
140
+ * between two identical runs. Not more than one either: an effect two turns later would have been
141
+ * reported by the snapshot in between.
142
+ */
143
+ const TURN_REACH = 1;
144
+ /** The longest string in an argv array — in practice the command, not the shell that ran it. */
145
+ function commandOf(argv) {
146
+ if (!Array.isArray(argv))
147
+ return '';
148
+ let longest = '';
149
+ for (const part of argv) {
150
+ if (typeof part === 'string' && part.length > longest.length)
151
+ longest = part;
152
+ }
153
+ return longest;
154
+ }
155
+ function inputText(call) {
156
+ const input = (call.attrs ?? {})['input'];
157
+ if (input === undefined)
158
+ return '';
159
+ try {
160
+ return typeof input === 'string' ? input : (JSON.stringify(input) ?? '');
161
+ }
162
+ catch {
163
+ return '';
164
+ }
165
+ }
166
+ /**
167
+ * The one tool call that can be said to have caused `effect`, or undefined when that is not
168
+ * exactly one call.
169
+ *
170
+ * Candidates are calls whose input names `needle`, that happened first, and that are within
171
+ * `TURN_REACH` turns. Of those, only the nearest turn is considered: a later call supersedes an
172
+ * earlier one, since a file edited twice was last edited by the most recent call to name it.
173
+ *
174
+ * Two calls in that nearest turn is the case worth dwelling on. Picking either would produce an
175
+ * edge indistinguishable from a true one and wrong half the time, and a wrong edge is worse than
176
+ * a missing one because the missing one is visible. So ambiguity yields nothing.
177
+ */
178
+ function soleMatchingCall(calls, effect, needle) {
179
+ if (needle === '')
180
+ return undefined;
181
+ const candidates = calls.filter((call) => call.seq < effect.seq &&
182
+ effect.turn - call.turn >= 0 &&
183
+ effect.turn - call.turn <= TURN_REACH &&
184
+ inputText(call).includes(needle));
185
+ if (candidates.length === 0)
186
+ return undefined;
187
+ const nearest = Math.max(...candidates.map((c) => c.turn));
188
+ const inNearest = candidates.filter((c) => c.turn === nearest);
189
+ return inNearest.length === 1 ? inNearest[0] : undefined;
190
+ }
191
+ /**
192
+ * The longest string a graph node carries. A graph is about structure, not payloads.
193
+ *
194
+ * `orca_graph` answers an agent, and the answer lands in its context — so a `tool.call` whose
195
+ * `input` holds a whole file body would spend that context on something the graph never uses. The
196
+ * shape survives so a label can still read `input.path`; the bulk does not. `orca events` is one
197
+ * command away when the full value is what you want.
198
+ */
199
+ const ATTR_MAX = 200;
200
+ function clampValue(value, depth = 0) {
201
+ if (typeof value === 'string') {
202
+ return value.length <= ATTR_MAX ? value : `${value.slice(0, ATTR_MAX)}…`;
203
+ }
204
+ if (depth >= 4 || value === null || typeof value !== 'object')
205
+ return value;
206
+ if (Array.isArray(value))
207
+ return value.slice(0, 20).map((v) => clampValue(v, depth + 1));
208
+ const out = {};
209
+ for (const [key, v] of Object.entries(value)) {
210
+ out[key] = clampValue(v, depth + 1);
211
+ }
212
+ return out;
213
+ }
214
+ function clampAttrs(attrs) {
215
+ return clampValue(attrs);
216
+ }
217
+ /**
218
+ * A run as nodes and edges, with every edge saying whether the trace vouches for it.
219
+ *
220
+ * Two kinds, and they are not interchangeable. A `recorded` edge came out of `causes`, which the
221
+ * recorder wrote because it watched the relationship happen. An `inferred` edge was derived here,
222
+ * just now, by the named rule — a filesystem snapshot is taken once per turn rather than once per
223
+ * tool call, and shell frames are bucketed into turns by wall clock, so attributing an effect to a
224
+ * *particular* call is a guess however good the heuristic is.
225
+ *
226
+ * Inferred edges are therefore never written back to the trace. That is the same discipline spec
227
+ * §3 applies to checkpoints, which are derived and never recorded, and it exists so that a field
228
+ * a third-party reader trusts never contains something orca made up.
229
+ */
230
+ export function runGraph(events) {
231
+ const ordered = bySeq(events);
232
+ const present = new Set(ordered.map((e) => e.seq));
233
+ const nodes = ordered.map((e) => ({
234
+ seq: e.seq,
235
+ turn: e.turn,
236
+ type: e.type,
237
+ ...(e.attrs === undefined ? {} : { attrs: clampAttrs(e.attrs) }),
238
+ }));
239
+ const byType = new Map(ordered.map((e) => [e.seq, e.type]));
240
+ const edges = [];
241
+ for (const event of ordered) {
242
+ for (const cause of event.causes ?? []) {
243
+ // A reader may have dropped an event type it did not know (spec §2.3), so an edge can name
244
+ // an ancestor that is not here. Naming a node that does not exist is worse than no edge.
245
+ if (!present.has(cause))
246
+ continue;
247
+ const pair = `${byType.get(cause)}→${event.type}`;
248
+ edges.push({
249
+ from: cause,
250
+ to: event.seq,
251
+ kind: 'recorded',
252
+ rule: RECORDED_RULES[pair] ?? 'causes',
253
+ });
254
+ }
255
+ }
256
+ const calls = ordered.filter((e) => e.type === 'tool.call');
257
+ if (calls.length > 0) {
258
+ for (const event of ordered) {
259
+ const attrs = event.attrs ?? {};
260
+ let match;
261
+ let rule = '';
262
+ if (event.type === 'shell.exec') {
263
+ match = soleMatchingCall(calls, event, commandOf(attrs['argv']));
264
+ rule = ARGV_RULE;
265
+ }
266
+ else if (event.type === 'fs.change') {
267
+ const path = attrs['path'];
268
+ match = soleMatchingCall(calls, event, typeof path === 'string' ? path : '');
269
+ rule = PATH_RULE;
270
+ }
271
+ if (match)
272
+ edges.push({ from: match.seq, to: event.seq, kind: 'inferred', rule });
273
+ }
274
+ }
275
+ edges.sort((a, b) => a.to - b.to || a.from - b.from);
276
+ return { nodes, edges };
277
+ }
278
+ /**
279
+ * The sub-graph that produced `seq`: that event and everything transitively behind it.
280
+ *
281
+ * `causalChain` walks `causes` alone and so stops at the first inferred hop, which in a real run
282
+ * is the hop from a tool call to the shell command it ran — exactly the one a person following a
283
+ * failure backwards needs. This walks the derived graph instead, so it crosses both kinds.
284
+ */
285
+ export function chainTo(graph, seq) {
286
+ if (!graph.nodes.some((n) => n.seq === seq)) {
287
+ throw new Error(`no event with seq ${seq} in this graph`);
288
+ }
289
+ const incoming = new Map();
290
+ for (const edge of graph.edges) {
291
+ const bucket = incoming.get(edge.to);
292
+ if (bucket)
293
+ bucket.push(edge);
294
+ else
295
+ incoming.set(edge.to, [edge]);
296
+ }
297
+ const kept = new Set([seq]);
298
+ const edges = [];
299
+ const queue = [seq];
300
+ while (queue.length > 0) {
301
+ const at = queue.shift();
302
+ if (at === undefined)
303
+ break;
304
+ for (const edge of incoming.get(at) ?? []) {
305
+ edges.push(edge);
306
+ // A cycle is malformed rather than impossible, and it must not hang the walk.
307
+ if (kept.has(edge.from))
308
+ continue;
309
+ kept.add(edge.from);
310
+ queue.push(edge.from);
311
+ }
312
+ }
313
+ return {
314
+ nodes: graph.nodes.filter((n) => kept.has(n.seq)),
315
+ edges: edges.sort((a, b) => a.to - b.to || a.from - b.from),
316
+ };
317
+ }
318
+ /**
319
+ * The event a card about this run should be about, or undefined when nothing stands out.
320
+ *
321
+ * Which chain to draw *is* the feature. A card gets screenshotted whether or not it happens to be
322
+ * the interesting one, so an arbitrary pick travels further than no card at all — hence a run with
323
+ * nothing notable returns undefined and the caller refuses rather than drawing something.
324
+ *
325
+ * The order is failure first, then the largest visible effect: a command that exited non-zero, a
326
+ * tool that reported an error, an error orca itself recorded, a replay divergence, and only then
327
+ * the last file the run changed. Within a kind the last one wins, since that is where the run
328
+ * ended up.
329
+ */
330
+ export function pickChainTarget(events) {
331
+ const ordered = bySeq(events);
332
+ const last = (match) => {
333
+ for (let i = ordered.length - 1; i >= 0; i--) {
334
+ const event = ordered[i];
335
+ if (event && match(event))
336
+ return event.seq;
337
+ }
338
+ return undefined;
339
+ };
340
+ return (last((e) => e.type === 'shell.result' && (e.attrs?.['exit_code'] ?? 0) !== 0) ??
341
+ last((e) => e.type === 'tool.result' && e.attrs?.['is_error'] === true) ??
342
+ last((e) => e.type === 'error') ??
343
+ last((e) => e.type === 'divergence') ??
344
+ last((e) => e.type === 'fs.change'));
345
+ }
346
+ /** Attributes as a plain record, since the envelope leaves them optional. */
347
+ function toAttrs(event) {
348
+ return event.attrs ?? {};
349
+ }
350
+ /** Tool calls that hand work to another agent, by the argument every harness gives them. */
351
+ export function isDelegation(event) {
352
+ if (event.type !== 'tool.call')
353
+ return false;
354
+ const input = toAttrs(event)['input'];
355
+ if (input === null || typeof input !== 'object')
356
+ return false;
357
+ const shape = input;
358
+ return typeof shape['subagent_type'] === 'string' || typeof shape['agent'] === 'string';
359
+ }
360
+ /**
361
+ * The delegation whose span encloses `seq`, if any.
362
+ *
363
+ * A replay that halts inside one is the hardest kind of miss to read: the distance is small, the
364
+ * trace is intact, and nothing on the line says why the same run asked a different question. The
365
+ * answer is that the harness wrote the delegate's prompt itself and writes a fresh one every time,
366
+ * so that request genuinely was not the recorded one. Naming the delegation turns a number into
367
+ * that sentence.
368
+ */
369
+ export function enclosingDelegation(events, seq) {
370
+ const closesAt = new Map();
371
+ for (const event of events) {
372
+ if (event.type !== 'tool.result')
373
+ continue;
374
+ for (const cause of event.causes ?? [])
375
+ closesAt.set(cause, event.seq);
376
+ }
377
+ let found;
378
+ for (const event of events) {
379
+ if (event.seq > seq)
380
+ break;
381
+ if (!isDelegation(event))
382
+ continue;
383
+ const closes = closesAt.get(event.seq);
384
+ // Still open at `seq`: an unclosed delegation ran to the end of the trace.
385
+ if (closes !== undefined && closes < seq)
386
+ continue;
387
+ const input = toAttrs(event)['input'];
388
+ const subagent = String(input?.['subagent_type'] ?? input?.['agent'] ?? 'sub-agent');
389
+ found = { seq: event.seq, subagent };
390
+ }
391
+ return found;
392
+ }
393
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}