@lloyal-labs/dev-tools 0.4.2 → 0.5.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +134 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +219 -32
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +7 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +280 -13
- package/dist/react.js.map +1 -1
- package/dist/store.d.ts +8 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +13 -10
- package/dist/store.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export interface DevControl {
|
|
|
40
40
|
command: string;
|
|
41
41
|
/** The command field carrying the selected value. */
|
|
42
42
|
field: string;
|
|
43
|
+
/** How to draw the choice. `segmented` (default) is the button row;
|
|
44
|
+
* `slider` is the same ordered `values`, stepped — right when they form a
|
|
45
|
+
* scale rather than a set, so the ordering is the information. Both
|
|
46
|
+
* dispatch the identical command, so this changes the picture only. */
|
|
47
|
+
render?: 'segmented' | 'slider';
|
|
43
48
|
/** One clause shown beside the control, e.g. `applies next run`. */
|
|
44
49
|
note?: string;
|
|
45
50
|
/** Read the current value out of the live config object. */
|
|
@@ -56,10 +61,20 @@ export interface ClarifyExchange {
|
|
|
56
61
|
export interface AgentLane {
|
|
57
62
|
agentId: number;
|
|
58
63
|
parentAgentId: number | null;
|
|
59
|
-
/** The
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
role:
|
|
64
|
+
/** The phase label current at spawn — from the harness's own
|
|
65
|
+
* {@link RunFraming} declaration; null when its wire marks nothing.
|
|
66
|
+
* Never guessed. */
|
|
67
|
+
role: string | null;
|
|
68
|
+
/** Agent ids whose completion gated this spawn — the DAG's dependency
|
|
69
|
+
* edges, from the orchestrator via `agent:spawn.after`. Never inferred. */
|
|
70
|
+
after?: number[];
|
|
71
|
+
/** Tokens already resident on this lane's prefix at its fork — snapshotted
|
|
72
|
+
* the moment the spawn folds, never reconstructed. Top-level: the trunk
|
|
73
|
+
* inheritance + spine growth so far. Recursive: the parent lane's own
|
|
74
|
+
* inheritance + what it had produced by then (its suffix is not counted —
|
|
75
|
+
* an honest undercount). Absent when the pane cannot attribute the fork
|
|
76
|
+
* (a pre-spine spawn such as a planner). */
|
|
77
|
+
inherited?: number;
|
|
63
78
|
spawnedAt: number;
|
|
64
79
|
doneAt: number | null;
|
|
65
80
|
/** Terminal outcome, when known. `failed` carries the reason. */
|
|
@@ -218,10 +233,75 @@ export interface AbilityInfo {
|
|
|
218
233
|
}
|
|
219
234
|
/** The folded pane state. Everything optional is honestly absent until its
|
|
220
235
|
* event arrives — the pane renders absence, never a placeholder value. */
|
|
236
|
+
/** The run's framing, declared by the HARNESS as data — the pane knows no
|
|
237
|
+
* pipeline's event names. `phases` maps a marker event to the label every
|
|
238
|
+
* agent spawned under it wears; `open` events reset the run (the timeline
|
|
239
|
+
* anchor); `close` events end it. A scaffold passes its own grammar beside
|
|
240
|
+
* the other DevPane wiring and EDITS it when a stage is added or renamed;
|
|
241
|
+
* the default covers the stock templates. */
|
|
242
|
+
export interface RunFraming {
|
|
243
|
+
phases: Record<string, string>;
|
|
244
|
+
/** The submission's start markers IN PIPELINE ORDER. Within one run they
|
|
245
|
+
* only advance (preflight → plan:start → query); a marker at or before
|
|
246
|
+
* the last one seen is a NEW submission superseding an unclosed run —
|
|
247
|
+
* the halt-and-resubmit path emits no close event. */
|
|
248
|
+
open: readonly string[];
|
|
249
|
+
close: readonly string[];
|
|
250
|
+
/** Where the user's instruction lives on THIS harness's wire — the event
|
|
251
|
+
* type and the field carrying its text (and optionally the field carrying
|
|
252
|
+
* its media descriptors). Declared, never guessed: undeclared harnesses
|
|
253
|
+
* get a spine row folded from runtime events alone, with no instruction
|
|
254
|
+
* shown. */
|
|
255
|
+
instruction?: {
|
|
256
|
+
event: string;
|
|
257
|
+
field: string;
|
|
258
|
+
attachments?: string;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
export declare const DEFAULT_FRAMING: RunFraming;
|
|
262
|
+
/** One session-trunk turn (`branch:prefill role='warmDelta'` mirror) — the
|
|
263
|
+
* verbatim conversation delta the spine accreted, with what it cost. */
|
|
264
|
+
export interface TrunkTurn {
|
|
265
|
+
at: number;
|
|
266
|
+
/** Which conversation side — from the Session's own prefill call, never
|
|
267
|
+
* inferred from the text. `turn` is a committed whole exchange. */
|
|
268
|
+
speaker?: 'user' | 'assistant' | 'tool' | 'turn';
|
|
269
|
+
/** Verbatim prefilled text (the trunk conversation turn). */
|
|
270
|
+
content: string;
|
|
271
|
+
/** A committed exchange's halves (`speaker: 'turn'`) — never re-split
|
|
272
|
+
* from `content`. */
|
|
273
|
+
query?: string;
|
|
274
|
+
response?: string;
|
|
275
|
+
/** KV cells the prefill added. */
|
|
276
|
+
cells: number;
|
|
277
|
+
/** The trunk branch this turn accreted onto — the key the release fold
|
|
278
|
+
* deletes by when that branch leaves the KV. */
|
|
279
|
+
branchHandle?: number;
|
|
280
|
+
/** The images that entered with it — roots, resolvable to bytes through
|
|
281
|
+
* the bridge's `representationUrl` when the harness exposes one. */
|
|
282
|
+
attachments: {
|
|
283
|
+
digest: string;
|
|
284
|
+
mediaType?: string;
|
|
285
|
+
}[];
|
|
286
|
+
/** Wall time of the run this delta settled out of — folded from the run
|
|
287
|
+
* anchor at arrival. Absent when no run was open. */
|
|
288
|
+
wallMs?: number;
|
|
289
|
+
/** What the run's agents spent (sum of its lanes' cumulative counters) to
|
|
290
|
+
* produce this delta — the numerator of the distillation ratio whose
|
|
291
|
+
* denominator is `cells`. Absent with `wallMs`. */
|
|
292
|
+
agentTokens?: number;
|
|
293
|
+
}
|
|
221
294
|
export interface PaneModel {
|
|
222
|
-
/** The current run's phase cursor — set by the
|
|
295
|
+
/** The current run's phase cursor — set by the framing's marker events;
|
|
223
296
|
* tags each spawn with a role. */
|
|
224
|
-
runPhase:
|
|
297
|
+
runPhase: string | null;
|
|
298
|
+
/** A run is OPEN from its first open-marker until a close-marker ends it —
|
|
299
|
+
* the reset guard, replacing the old 1.5s timing window (recon can hold
|
|
300
|
+
* the start markers apart for minutes). */
|
|
301
|
+
runOpen: boolean;
|
|
302
|
+
/** Position (in `framing.open`) of the last open-marker seen — the
|
|
303
|
+
* supersede detector: a marker at or before it starts a NEW run. */
|
|
304
|
+
lastOpenIdx: number;
|
|
225
305
|
/** When the current run began (`query` / `plan:start`) — the timeline's
|
|
226
306
|
* anchor. Null before the first run. */
|
|
227
307
|
runStartAt: number | null;
|
|
@@ -262,6 +342,53 @@ export interface PaneModel {
|
|
|
262
342
|
* "applied for this session"). Undefined until a save happens. */
|
|
263
343
|
lastSavedTo: string | null | undefined;
|
|
264
344
|
lanes: Map<number, AgentLane>;
|
|
345
|
+
/** The RESIDENT conversation — the turns of the trunk the model can
|
|
346
|
+
* currently attend. Not cleared by `resetRun` (the next run rides the
|
|
347
|
+
* live trunk), but a released trunk's turns are REMOVED when its
|
|
348
|
+
* `branch:prune` folds: dead cells feed nothing, so the feed never
|
|
349
|
+
* shows them. History across trunks is the harness's concern. */
|
|
350
|
+
trunk: TrunkTurn[];
|
|
351
|
+
/** The run's SPINE, run-scoped: the shared root every agent forks from.
|
|
352
|
+
* Folded from runtime events alone (`branch:prefill role='spineHeader'`,
|
|
353
|
+
* `prompt:format role='spine'`) — universal to any pool harness — plus,
|
|
354
|
+
* when the harness DECLARES it ({@link RunFraming.instruction}), the
|
|
355
|
+
* user's instruction verbatim. This is the prompt's home in the pane
|
|
356
|
+
* even when a run later fails. Cleared by `resetRun`. */
|
|
357
|
+
spine: {
|
|
358
|
+
/** The user's instruction, as submitted — null until (unless) the
|
|
359
|
+
* harness's declared instruction event arrives. Never guessed. */
|
|
360
|
+
query: string | null;
|
|
361
|
+
attachments: {
|
|
362
|
+
digest: string;
|
|
363
|
+
}[];
|
|
364
|
+
/** First-seen moment (instruction arrival or first header prefill). */
|
|
365
|
+
at: number;
|
|
366
|
+
/** KV cells the spine header prefills added (outer + inner pools). */
|
|
367
|
+
spineCells: number;
|
|
368
|
+
/** The compiled spine header (system + tools), verbatim. */
|
|
369
|
+
headerText: string | null;
|
|
370
|
+
headerTokens: number;
|
|
371
|
+
spineAt: number | null;
|
|
372
|
+
/** Every moment the spine grew, with what it grew by — the seed first,
|
|
373
|
+
* then each extension (a chain step, a fanout widening). The bar's
|
|
374
|
+
* tick marks. */
|
|
375
|
+
growth: {
|
|
376
|
+
at: number;
|
|
377
|
+
tokens: number;
|
|
378
|
+
}[];
|
|
379
|
+
/** Positions inherited at fork — 0 on a cold start, the trunk's length
|
|
380
|
+
* on a warm one. From `branch:create role='spine'` position; first
|
|
381
|
+
* spine only (the inner pool's spine forks from the outer). */
|
|
382
|
+
inherited?: number;
|
|
383
|
+
/** Parsed from the STRUCTURED `tools` field the runtime emits on
|
|
384
|
+
* `prompt:format role='spine'` — reading data, not scraping markup. */
|
|
385
|
+
tools?: {
|
|
386
|
+
name: string;
|
|
387
|
+
description: string;
|
|
388
|
+
}[];
|
|
389
|
+
/** The system message text, from the structured `messages` field. */
|
|
390
|
+
systemText?: string | null;
|
|
391
|
+
} | null;
|
|
265
392
|
retrievals: Retrieval[];
|
|
266
393
|
pressure: PressurePoint[];
|
|
267
394
|
/** Host samples (`host:resources`, dev-gated boots only): the harness
|
|
@@ -295,7 +422,7 @@ export interface PaneModel {
|
|
|
295
422
|
eventCount: number;
|
|
296
423
|
}
|
|
297
424
|
export declare function createPaneModel(): PaneModel;
|
|
298
|
-
export declare function foldEvent(m: PaneModel, ev: DevEvent, now: number): void;
|
|
425
|
+
export declare function foldEvent(m: PaneModel, ev: DevEvent, now: number, framing?: RunFraming): void;
|
|
299
426
|
/** Live when any lane is still open — the run is producing and the pane's
|
|
300
427
|
* clocks (elapsed, park countdowns) must keep advancing even between
|
|
301
428
|
* events. */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;4DAC4D;AAC5D,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElE;iFACiF;AACjF,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB;kCAC8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ;kFAC8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;CAC/D;AAED;8EAC8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,26 @@
|
|
|
4
4
|
export function lanePpl(lane) {
|
|
5
5
|
return lane.nllCount === 0 ? null : Math.exp(lane.nllSum / lane.nllCount);
|
|
6
6
|
}
|
|
7
|
+
export const DEFAULT_FRAMING = {
|
|
8
|
+
phases: {
|
|
9
|
+
'preflight:start': 'recon',
|
|
10
|
+
'plan:start': 'planner',
|
|
11
|
+
'research:start': 'research',
|
|
12
|
+
'synthesize:start': 'synth',
|
|
13
|
+
},
|
|
14
|
+
// Declared in WIRE order: preflight (when it runs) precedes the query
|
|
15
|
+
// event, which the pipeline sends before the planner phase marker. An
|
|
16
|
+
// out-of-order declaration makes the supersede heuristic fire a second
|
|
17
|
+
// resetRun on every run (query idx > plan idx), wiping run-scoped state.
|
|
18
|
+
open: ['preflight:start', 'query', 'plan:start'],
|
|
19
|
+
close: ['complete', 'ui:error', 'ui:composer'],
|
|
20
|
+
instruction: { event: 'query', field: 'query', attachments: 'attachments' },
|
|
21
|
+
};
|
|
7
22
|
export function createPaneModel() {
|
|
8
23
|
return {
|
|
9
24
|
runPhase: null,
|
|
25
|
+
runOpen: false,
|
|
26
|
+
lastOpenIdx: -1,
|
|
10
27
|
runStartAt: null,
|
|
11
28
|
runEndedAt: null,
|
|
12
29
|
pausedAt: null,
|
|
@@ -18,6 +35,8 @@ export function createPaneModel() {
|
|
|
18
35
|
origin: null,
|
|
19
36
|
lastSavedTo: undefined,
|
|
20
37
|
lanes: new Map(),
|
|
38
|
+
trunk: [],
|
|
39
|
+
spine: null,
|
|
21
40
|
retrievals: [],
|
|
22
41
|
pressure: [],
|
|
23
42
|
host: [],
|
|
@@ -35,6 +54,7 @@ export function createPaneModel() {
|
|
|
35
54
|
const MAX_PRESSURE_POINTS = 20_000;
|
|
36
55
|
const MAX_RETRIEVALS = 500;
|
|
37
56
|
const MAX_INTERVENTIONS = 200;
|
|
57
|
+
const MAX_TRUNK = 200;
|
|
38
58
|
const MAX_EPISTEMICS = 4096;
|
|
39
59
|
const MAX_HOST = 600;
|
|
40
60
|
/**
|
|
@@ -45,35 +65,45 @@ const MAX_HOST = 600;
|
|
|
45
65
|
/** A new run begins: the timeline shows THE RUN, not wall-clock since page
|
|
46
66
|
* load — clear the run-scoped collections and anchor the axis. Idempotent
|
|
47
67
|
* (research emits `plan:start` then `query` back-to-back). */
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
lane.clarify.answeredAt = now;
|
|
58
|
-
}
|
|
59
|
-
return;
|
|
68
|
+
/** A clarify answer re-enters planning WITHIN the same run: the planner
|
|
69
|
+
* asked, the user answered, the cycle continues — mark the exchange
|
|
70
|
+
* answered and keep everything. */
|
|
71
|
+
function continueRun(m, now) {
|
|
72
|
+
m.clarifying = false;
|
|
73
|
+
m.runContinuedAt = now;
|
|
74
|
+
for (const lane of m.lanes.values()) {
|
|
75
|
+
if (lane.clarify && lane.clarify.answeredAt === null)
|
|
76
|
+
lane.clarify.answeredAt = now;
|
|
60
77
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
}
|
|
79
|
+
function resetRun(m, now) {
|
|
80
|
+
// Idempotent across a run's OWN start markers — recon opens the run
|
|
81
|
+
// minutes before `plan:start`/`query` arrive, so this is a flag, not a
|
|
82
|
+
// timing window. A close-marker (or supersede) re-arms it.
|
|
83
|
+
if (m.runOpen)
|
|
65
84
|
return;
|
|
85
|
+
m.runOpen = true;
|
|
66
86
|
m.lanes = new Map();
|
|
67
87
|
m.retrievals = [];
|
|
68
88
|
m.pressure = [];
|
|
69
89
|
m.host = [];
|
|
70
90
|
m.interventions = [];
|
|
71
91
|
m.plan = null;
|
|
92
|
+
m.spine = null;
|
|
72
93
|
m.runStartAt = now;
|
|
73
94
|
m.runEndedAt = null;
|
|
74
95
|
m.pausedAt = null;
|
|
75
96
|
m.windingDownAt = null;
|
|
76
97
|
}
|
|
98
|
+
/** The spine record, created by whichever signal arrives first — the
|
|
99
|
+
* harness's declared instruction event or the runtime's own header
|
|
100
|
+
* prefill. Runtime-only harnesses still get a spine row. */
|
|
101
|
+
function ensureSpine(m, now) {
|
|
102
|
+
if (!m.spine) {
|
|
103
|
+
m.spine = { query: null, attachments: [], at: now, spineCells: 0, headerText: null, headerTokens: 0, spineAt: null, growth: [] };
|
|
104
|
+
}
|
|
105
|
+
return m.spine;
|
|
106
|
+
}
|
|
77
107
|
/** The retrieval a mirrored trace event belongs to: by callId WITHIN the
|
|
78
108
|
* agent (callIds are per-agent counters — call_0 exists in every agent, so
|
|
79
109
|
* a global match attaches one agent's funnel to another's call), else the
|
|
@@ -88,29 +118,54 @@ function findRetrieval(m, callId, agentId) {
|
|
|
88
118
|
}
|
|
89
119
|
return undefined;
|
|
90
120
|
}
|
|
91
|
-
export function foldEvent(m, ev, now) {
|
|
121
|
+
export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
92
122
|
m.eventCount++;
|
|
93
123
|
if (m.t0 === null)
|
|
94
124
|
m.t0 = now;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
125
|
+
// ── run framing: the harness's OWN declared markers, as data ──
|
|
126
|
+
if (framing.close.includes(ev.type)) {
|
|
127
|
+
m.runOpen = false;
|
|
128
|
+
m.lastOpenIdx = -1;
|
|
129
|
+
}
|
|
130
|
+
const openIdx = framing.open.indexOf(ev.type);
|
|
131
|
+
if (openIdx !== -1) {
|
|
132
|
+
if (m.clarifying) {
|
|
133
|
+
// An answered clarify CONTINUES this run — never a reset.
|
|
134
|
+
continueRun(m, now);
|
|
101
135
|
}
|
|
102
|
-
|
|
136
|
+
else {
|
|
137
|
+
// Same submission's markers only ADVANCE through `open`; at-or-before
|
|
138
|
+
// means a new submission superseded an unclosed run (halt-and-resubmit
|
|
139
|
+
// emits no close marker).
|
|
140
|
+
if (m.runOpen && openIdx <= m.lastOpenIdx)
|
|
141
|
+
m.runOpen = false;
|
|
103
142
|
resetRun(m, now);
|
|
104
|
-
return;
|
|
105
143
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
144
|
+
m.lastOpenIdx = openIdx;
|
|
145
|
+
}
|
|
146
|
+
const phaseLabel = framing.phases[ev.type];
|
|
147
|
+
if (phaseLabel !== undefined)
|
|
148
|
+
m.runPhase = phaseLabel;
|
|
149
|
+
// The user's instruction — read only where the harness DECLARED it lives
|
|
150
|
+
// (framing.instruction), never guessed from event shapes. First one per
|
|
151
|
+
// run wins: a re-plan re-emits the same event and must not reseed.
|
|
152
|
+
const instr = framing.instruction;
|
|
153
|
+
if (instr && ev.type === instr.event && (m.spine === null || m.spine.query === null)) {
|
|
154
|
+
const s = ensureSpine(m, now);
|
|
155
|
+
const q = ev[instr.field];
|
|
156
|
+
if (typeof q === 'string')
|
|
157
|
+
s.query = q;
|
|
158
|
+
if (instr.attachments) {
|
|
159
|
+
const a = ev[instr.attachments];
|
|
160
|
+
if (Array.isArray(a)) {
|
|
161
|
+
s.attachments = a.flatMap((x) => {
|
|
162
|
+
const r = x;
|
|
163
|
+
return typeof r.digest === 'string' ? [{ digest: r.digest }] : [];
|
|
164
|
+
});
|
|
165
|
+
}
|
|
113
166
|
}
|
|
167
|
+
}
|
|
168
|
+
switch (ev.type) {
|
|
114
169
|
case 'plan': {
|
|
115
170
|
const intent = typeof ev.intent === 'string' ? ev.intent : 'research';
|
|
116
171
|
if (intent === 'clarify') {
|
|
@@ -183,6 +238,21 @@ export function foldEvent(m, ev, now) {
|
|
|
183
238
|
return;
|
|
184
239
|
}
|
|
185
240
|
case 'agent:spawn': {
|
|
241
|
+
const afterIds = Array.isArray(ev.after)
|
|
242
|
+
? ev.after.filter((x) => typeof x === 'number')
|
|
243
|
+
: [];
|
|
244
|
+
// Inherited-at-fork, snapshotted NOW: a recursive fork carries its
|
|
245
|
+
// parent's attention state; a top-level fork carries trunk + the spine
|
|
246
|
+
// as grown so far. Pre-spine forks get nothing — no guessed parentage.
|
|
247
|
+
const parentLane = typeof ev.parentAgentId === 'number' ? m.lanes.get(ev.parentAgentId) : undefined;
|
|
248
|
+
let inheritedAtFork;
|
|
249
|
+
if (parentLane) {
|
|
250
|
+
inheritedAtFork = (parentLane.inherited ?? 0) + parentLane.tokenCount;
|
|
251
|
+
}
|
|
252
|
+
else if (m.spine && m.spine.spineAt !== null && now + 250 >= m.spine.spineAt) {
|
|
253
|
+
inheritedAtFork = (m.spine.inherited ?? 0)
|
|
254
|
+
+ m.spine.growth.reduce((n2, g) => (g.at <= now + 250 ? n2 + g.tokens : n2), 0);
|
|
255
|
+
}
|
|
186
256
|
if (typeof ev.agentId !== 'number')
|
|
187
257
|
return; // type-only frame — never corrupt the lane map
|
|
188
258
|
const id = ev.agentId;
|
|
@@ -194,6 +264,8 @@ export function foldEvent(m, ev, now) {
|
|
|
194
264
|
doneAt: null,
|
|
195
265
|
outcome: 'running',
|
|
196
266
|
tokenCount: 0,
|
|
267
|
+
...(afterIds.length > 0 ? { after: afterIds } : {}),
|
|
268
|
+
...(inheritedAtFork !== undefined ? { inherited: inheritedAtFork } : {}),
|
|
197
269
|
inflightTool: null,
|
|
198
270
|
report: null,
|
|
199
271
|
reportSource: null,
|
|
@@ -333,6 +405,78 @@ export function foldEvent(m, ev, now) {
|
|
|
333
405
|
if (!te)
|
|
334
406
|
return;
|
|
335
407
|
switch (te.type) {
|
|
408
|
+
case 'branch:create': {
|
|
409
|
+
// Cold vs warm, from the run's own record: the FIRST spine's fork
|
|
410
|
+
// position. The inner pool's spine forks from the outer — skip it.
|
|
411
|
+
if (te.role !== 'spine')
|
|
412
|
+
return;
|
|
413
|
+
{
|
|
414
|
+
const s = ensureSpine(m, now);
|
|
415
|
+
if (s.inherited === undefined && typeof te.position === 'number')
|
|
416
|
+
s.inherited = te.position;
|
|
417
|
+
}
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
case 'spine:extend': {
|
|
421
|
+
// A settled contribution committed onto the spine mid-run (chain
|
|
422
|
+
// steps). Later forks inherit it — the growth entry is what makes
|
|
423
|
+
// their inherited-at-fork snapshot and the paid-once sum honest.
|
|
424
|
+
const s = ensureSpine(m, now);
|
|
425
|
+
const grew = typeof te.deltaTokens === 'number' ? te.deltaTokens : 0;
|
|
426
|
+
s.spineCells += grew;
|
|
427
|
+
if (grew > 0)
|
|
428
|
+
s.growth.push({ at: now, tokens: grew });
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
case 'branch:prefill': {
|
|
432
|
+
// The spine's seed — runtime truth, no harness assumption.
|
|
433
|
+
if (te.role === 'spineHeader') {
|
|
434
|
+
const s = ensureSpine(m, now);
|
|
435
|
+
const grew = typeof te.cells === 'number' ? te.cells : 0;
|
|
436
|
+
s.spineCells += grew;
|
|
437
|
+
if (grew > 0)
|
|
438
|
+
s.growth.push({ at: now, tokens: grew });
|
|
439
|
+
if (s.spineAt === null)
|
|
440
|
+
s.spineAt = now;
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
// The session trunk's own turns (role warmDelta) — visible beside
|
|
444
|
+
// the runs they feed. Session-lived: resetRun leaves m.trunk alone.
|
|
445
|
+
if (te.role !== 'warmDelta')
|
|
446
|
+
return;
|
|
447
|
+
const speaker = te.speaker;
|
|
448
|
+
// Run-derived stats ride the response side: how long the run took
|
|
449
|
+
// and what its agents spent to produce what the trunk kept.
|
|
450
|
+
const responseSide = speaker === 'assistant' || speaker === 'turn' || speaker === undefined;
|
|
451
|
+
const stats = responseSide && m.runStartAt !== null
|
|
452
|
+
? {
|
|
453
|
+
wallMs: Math.max(0, now - m.runStartAt),
|
|
454
|
+
agentTokens: [...m.lanes.values()].reduce((n, l) => n + l.tokenCount, 0),
|
|
455
|
+
}
|
|
456
|
+
: {};
|
|
457
|
+
m.trunk.push({
|
|
458
|
+
at: now,
|
|
459
|
+
...stats,
|
|
460
|
+
...(speaker === 'user' || speaker === 'assistant' || speaker === 'tool' || speaker === 'turn'
|
|
461
|
+
? { speaker } : {}),
|
|
462
|
+
...(typeof te.query === 'string' ? { query: te.query } : {}),
|
|
463
|
+
...(typeof te.response === 'string' ? { response: te.response } : {}),
|
|
464
|
+
content: typeof te.content === 'string' ? te.content : '',
|
|
465
|
+
cells: typeof te.cells === 'number' ? te.cells : 0,
|
|
466
|
+
...(typeof te.branchHandle === 'number' ? { branchHandle: te.branchHandle } : {}),
|
|
467
|
+
attachments: Array.isArray(te.attachments)
|
|
468
|
+
? te.attachments.flatMap((a) => {
|
|
469
|
+
const r = a;
|
|
470
|
+
return typeof r.digest === 'string'
|
|
471
|
+
? [{ digest: r.digest, ...(typeof r.mediaType === 'string' ? { mediaType: r.mediaType } : {}) }]
|
|
472
|
+
: [];
|
|
473
|
+
})
|
|
474
|
+
: [],
|
|
475
|
+
});
|
|
476
|
+
if (m.trunk.length > MAX_TRUNK)
|
|
477
|
+
m.trunk.shift();
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
336
480
|
case 'pool:agentNudge': {
|
|
337
481
|
m.interventions.push({
|
|
338
482
|
kind: typeof te.guard === 'string' ? 'guard' : 'nudge',
|
|
@@ -363,6 +507,40 @@ export function foldEvent(m, ev, now) {
|
|
|
363
507
|
return;
|
|
364
508
|
}
|
|
365
509
|
case 'prompt:format': {
|
|
510
|
+
// The compiled spine header — what position 0 actually holds.
|
|
511
|
+
if (te.role === 'spine') {
|
|
512
|
+
const s = ensureSpine(m, now);
|
|
513
|
+
if (typeof te.promptText === 'string')
|
|
514
|
+
s.headerText = te.promptText;
|
|
515
|
+
if (typeof te.tokenCount === 'number')
|
|
516
|
+
s.headerTokens = te.tokenCount;
|
|
517
|
+
if (typeof te.tools === 'string') {
|
|
518
|
+
try {
|
|
519
|
+
const arr = JSON.parse(te.tools);
|
|
520
|
+
if (Array.isArray(arr)) {
|
|
521
|
+
s.tools = arr.flatMap((x) => {
|
|
522
|
+
const f = x.function ?? x;
|
|
523
|
+
const g = f;
|
|
524
|
+
return g && typeof g.name === 'string'
|
|
525
|
+
? [{ name: g.name, description: typeof g.description === 'string' ? g.description : '' }]
|
|
526
|
+
: [];
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
catch { /* not JSON — leave unparsed */ }
|
|
531
|
+
}
|
|
532
|
+
if (typeof te.messages === 'string') {
|
|
533
|
+
try {
|
|
534
|
+
const ms = JSON.parse(te.messages);
|
|
535
|
+
if (Array.isArray(ms)) {
|
|
536
|
+
const sys = ms.find((mm) => mm && mm.role === 'system' && typeof mm.content === 'string');
|
|
537
|
+
s.systemText = sys ? sys.content : null;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
catch { /* not JSON */ }
|
|
541
|
+
}
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
366
544
|
const lane = m.lanes.get(agentId);
|
|
367
545
|
if (lane && typeof te.promptText === 'string') {
|
|
368
546
|
lane.prompt = {
|
|
@@ -378,6 +556,13 @@ export function foldEvent(m, ev, now) {
|
|
|
378
556
|
const lane = m.lanes.get(handle);
|
|
379
557
|
if (lane)
|
|
380
558
|
lane.prunedAt = now;
|
|
559
|
+
// The same prune, seen by the trunk feed: this handle's turns
|
|
560
|
+
// left the KV with it, so they leave the feed — the feed shows
|
|
561
|
+
// the resident conversation, nothing else. Handle-matched (never
|
|
562
|
+
// a blanket clear): an agent branch's prune must not touch the
|
|
563
|
+
// trunk, and the match is order-independent with the next
|
|
564
|
+
// generation's first commit.
|
|
565
|
+
m.trunk = m.trunk.filter((t) => t.branchHandle !== handle);
|
|
381
566
|
return;
|
|
382
567
|
}
|
|
383
568
|
case 'tool:dispatch': {
|
|
@@ -548,6 +733,8 @@ export const KEY_TIERS = {
|
|
|
548
733
|
'model.path': 'reload',
|
|
549
734
|
'model.reranker': 'reload',
|
|
550
735
|
'model.gpu': 'reload',
|
|
736
|
+
'model.imageMinTokens': 'reload',
|
|
737
|
+
'model.imageMaxTokens': 'reload',
|
|
551
738
|
'model.nCtx': 'boot',
|
|
552
739
|
'model.branches': 'boot',
|
|
553
740
|
'model.kvCache': 'boot',
|