@lloyal-labs/dev-tools 0.4.3 → 0.5.0-alpha.10
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 +143 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +214 -21
- package/dist/index.js.map +1 -1
- package/dist/ink.d.ts +20 -1
- package/dist/ink.d.ts.map +1 -1
- package/dist/ink.js +51 -11
- package/dist/ink.js.map +1 -1
- package/dist/react.d.ts +8 -6
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +267 -83
- package/dist/react.js.map +1 -1
- package/dist/store.d.ts +5 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/package.json +3 -7
- package/dist/node.d.ts +0 -6
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -78
- package/dist/node.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The dev pane's node-free core: the event fold that turns a harness's bus
|
|
3
|
-
* stream into renderable pane state, the
|
|
4
|
-
*
|
|
3
|
+
* stream into renderable pane state, the settings rows derived from an
|
|
4
|
+
* application's config table, and the provenance vocabulary.
|
|
5
5
|
*
|
|
6
6
|
* Everything here is DERIVED from events the harness already emits — the pane
|
|
7
7
|
* never asks the harness for anything it doesn't already say. Events arrive
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @category DevTools
|
|
13
13
|
*/
|
|
14
|
-
import type { ConfigOriginValue } from '@lloyal-labs/rig';
|
|
15
|
-
export type { ConfigOriginValue } from '@lloyal-labs/rig';
|
|
14
|
+
import type { ConfigOriginValue, ConfigTable, ConfigTier } from '@lloyal-labs/rig';
|
|
15
|
+
export type { ConfigOriginValue, ConfigTable, ConfigTier } from '@lloyal-labs/rig';
|
|
16
16
|
/** A structural bus event — the pane subscribes to the SAME stream the app
|
|
17
17
|
* view folds, and narrows by `type` per field it reads. */
|
|
18
18
|
export type DevEvent = {
|
|
@@ -21,30 +21,6 @@ export type DevEvent = {
|
|
|
21
21
|
/** The pane's tabs. `prompt` arrives with the trace transport — the model
|
|
22
22
|
* knows the name so the tab strip can reserve it, but v1 never activates it. */
|
|
23
23
|
export type PaneTab = 'timeline' | 'sources' | 'settings';
|
|
24
|
-
/**
|
|
25
|
-
* One template-contributed Settings control — pure DATA, no components. The
|
|
26
|
-
* pane renders a segmented control and dispatches
|
|
27
|
-
* `{ type: command, [field]: value }` on click; the template's reducer and
|
|
28
|
-
* handlers already know that command (it is the same one its composer sends).
|
|
29
|
-
*/
|
|
30
|
-
export interface DevControl {
|
|
31
|
-
/** The config path this control edits (display + provenance lookup),
|
|
32
|
-
* e.g. `defaults.effort`. */
|
|
33
|
-
key: string;
|
|
34
|
-
/** The `ConfigOrigin` field carrying this key's provenance, e.g. `effort`
|
|
35
|
-
* is not tracked — use the origin key that is (`reasoningMode`), or omit. */
|
|
36
|
-
originKey?: string;
|
|
37
|
-
/** The values the segmented control offers, in display order. */
|
|
38
|
-
values: readonly string[];
|
|
39
|
-
/** The command `type` dispatched on selection. */
|
|
40
|
-
command: string;
|
|
41
|
-
/** The command field carrying the selected value. */
|
|
42
|
-
field: string;
|
|
43
|
-
/** One clause shown beside the control, e.g. `applies next run`. */
|
|
44
|
-
note?: string;
|
|
45
|
-
/** Read the current value out of the live config object. */
|
|
46
|
-
read: (config: Record<string, unknown>) => string | undefined;
|
|
47
|
-
}
|
|
48
24
|
/** A clarify exchange on the planner's lane — the planner waiting on the
|
|
49
25
|
* USER, rendered with the same call/wait/answer grammar a tool wait uses. */
|
|
50
26
|
export interface ClarifyExchange {
|
|
@@ -60,6 +36,16 @@ export interface AgentLane {
|
|
|
60
36
|
* {@link RunFraming} declaration; null when its wire marks nothing.
|
|
61
37
|
* Never guessed. */
|
|
62
38
|
role: string | null;
|
|
39
|
+
/** Agent ids whose completion gated this spawn — the DAG's dependency
|
|
40
|
+
* edges, from the orchestrator via `agent:spawn.after`. Never inferred. */
|
|
41
|
+
after?: number[];
|
|
42
|
+
/** Tokens already resident on this lane's prefix at its fork — snapshotted
|
|
43
|
+
* the moment the spawn folds, never reconstructed. Top-level: the trunk
|
|
44
|
+
* inheritance + spine growth so far. Recursive: the parent lane's own
|
|
45
|
+
* inheritance + what it had produced by then (its suffix is not counted —
|
|
46
|
+
* an honest undercount). Absent when the pane cannot attribute the fork
|
|
47
|
+
* (a pre-spine spawn such as a planner). */
|
|
48
|
+
inherited?: number;
|
|
63
49
|
spawnedAt: number;
|
|
64
50
|
doneAt: number | null;
|
|
65
51
|
/** Terminal outcome, when known. `failed` carries the reason. */
|
|
@@ -99,25 +85,10 @@ export interface AgentLane {
|
|
|
99
85
|
nllSum: number;
|
|
100
86
|
nllCount: number;
|
|
101
87
|
}
|
|
88
|
+
/** One host-resources sample on the wire — rig's, produced by its sampler
|
|
89
|
+
* (`startHostResources` in `@lloyal-labs/rig/node`), folded into {@link PaneModel.host}. */
|
|
90
|
+
export type { HostResourcesEvent } from '@lloyal-labs/rig';
|
|
102
91
|
/** One per-token epistemics sample, stamped at fold time. */
|
|
103
|
-
/** One host-resources sample on the wire — produced by the node entry's
|
|
104
|
-
* sampler (`@lloyal-labs/dev-tools/node`), folded into {@link PaneModel.host}.
|
|
105
|
-
* Declared here so a node-free protocol can name it type-only. */
|
|
106
|
-
export interface HostResourcesEvent {
|
|
107
|
-
type: 'host:resources';
|
|
108
|
-
/** The harness process's CPU use since the last sample, as % of the
|
|
109
|
-
* whole machine (all cores). */
|
|
110
|
-
cpuPct: number;
|
|
111
|
-
/** The process's resident set, MB — on a model host this is effectively
|
|
112
|
-
* weights + KV + runtime. */
|
|
113
|
-
rssMb: number;
|
|
114
|
-
/** System-wide memory in use, MB — honest per-platform accounting
|
|
115
|
-
* (darwin: vm_stat active+wired+compressed; linux: total − MemAvailable).
|
|
116
|
-
* Absent where no honest read exists. */
|
|
117
|
-
sysMemUsedMb?: number;
|
|
118
|
-
/** Total machine memory, MB. */
|
|
119
|
-
sysMemTotalMb?: number;
|
|
120
|
-
}
|
|
121
92
|
export interface EpiSample {
|
|
122
93
|
at: number;
|
|
123
94
|
h: number;
|
|
@@ -221,19 +192,64 @@ export interface AbilityInfo {
|
|
|
221
192
|
/** The run's framing, declared by the HARNESS as data — the pane knows no
|
|
222
193
|
* pipeline's event names. `phases` maps a marker event to the label every
|
|
223
194
|
* agent spawned under it wears; `open` events reset the run (the timeline
|
|
224
|
-
* anchor); `close` events end it.
|
|
225
|
-
*
|
|
226
|
-
* the default covers the stock templates. */
|
|
195
|
+
* anchor); `close` events end it. An application declares its own and edits
|
|
196
|
+
* it when a stage is added or renamed. */
|
|
227
197
|
export interface RunFraming {
|
|
228
198
|
phases: Record<string, string>;
|
|
229
|
-
/** The submission's start markers IN
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
199
|
+
/** The submission's start markers IN THE ORDER THE WIRE SAYS THEM. Within
|
|
200
|
+
* one run they only advance; a marker at or before the last one seen is a
|
|
201
|
+
* NEW submission superseding an unclosed run — the halt-and-resubmit path
|
|
202
|
+
* emits no close event. Declared out of order, a run resets itself
|
|
203
|
+
* mid-flight, so the application's own tests should fold a real run. */
|
|
233
204
|
open: readonly string[];
|
|
234
205
|
close: readonly string[];
|
|
206
|
+
/** Where the user's instruction lives on THIS harness's wire — the event
|
|
207
|
+
* type and the field carrying its text (and optionally the field carrying
|
|
208
|
+
* its media descriptors). Declared, never guessed: undeclared harnesses
|
|
209
|
+
* get a spine row folded from runtime events alone, with no instruction
|
|
210
|
+
* shown. */
|
|
211
|
+
instruction?: {
|
|
212
|
+
event: string;
|
|
213
|
+
field: string;
|
|
214
|
+
attachments?: string;
|
|
215
|
+
};
|
|
235
216
|
}
|
|
217
|
+
/** What the pane assumes of a harness that declares nothing: no event opens or closes a run, no lane wears a
|
|
218
|
+
* phase, and no instruction is read. Lanes, retrievals, pressure and the trunk still fold, because those come
|
|
219
|
+
* from the runtime's own events; the run axis simply never resets. */
|
|
236
220
|
export declare const DEFAULT_FRAMING: RunFraming;
|
|
221
|
+
/** One session-trunk turn (`branch:prefill role='warmDelta'` mirror) — the
|
|
222
|
+
* verbatim conversation delta the spine accreted, with what it cost. */
|
|
223
|
+
export interface TrunkTurn {
|
|
224
|
+
at: number;
|
|
225
|
+
/** Which conversation side — from the Session's own prefill call, never
|
|
226
|
+
* inferred from the text. `turn` is a committed whole exchange. */
|
|
227
|
+
speaker?: 'user' | 'assistant' | 'tool' | 'turn';
|
|
228
|
+
/** Verbatim prefilled text (the trunk conversation turn). */
|
|
229
|
+
content: string;
|
|
230
|
+
/** A committed exchange's halves (`speaker: 'turn'`) — never re-split
|
|
231
|
+
* from `content`. */
|
|
232
|
+
query?: string;
|
|
233
|
+
response?: string;
|
|
234
|
+
/** KV cells the prefill added. */
|
|
235
|
+
cells: number;
|
|
236
|
+
/** The trunk branch this turn accreted onto — the key the release fold
|
|
237
|
+
* deletes by when that branch leaves the KV. */
|
|
238
|
+
branchHandle?: number;
|
|
239
|
+
/** The images that entered with it — roots, resolvable to bytes through
|
|
240
|
+
* the bridge's `representationUrl` when the harness exposes one. */
|
|
241
|
+
attachments: {
|
|
242
|
+
digest: string;
|
|
243
|
+
mediaType?: string;
|
|
244
|
+
}[];
|
|
245
|
+
/** Wall time of the run this delta settled out of — folded from the run
|
|
246
|
+
* anchor at arrival. Absent when no run was open. */
|
|
247
|
+
wallMs?: number;
|
|
248
|
+
/** What the run's agents spent (sum of its lanes' cumulative counters) to
|
|
249
|
+
* produce this delta — the numerator of the distillation ratio whose
|
|
250
|
+
* denominator is `cells`. Absent with `wallMs`. */
|
|
251
|
+
agentTokens?: number;
|
|
252
|
+
}
|
|
237
253
|
export interface PaneModel {
|
|
238
254
|
/** The current run's phase cursor — set by the framing's marker events;
|
|
239
255
|
* tags each spawn with a role. */
|
|
@@ -285,6 +301,53 @@ export interface PaneModel {
|
|
|
285
301
|
* "applied for this session"). Undefined until a save happens. */
|
|
286
302
|
lastSavedTo: string | null | undefined;
|
|
287
303
|
lanes: Map<number, AgentLane>;
|
|
304
|
+
/** The RESIDENT conversation — the turns of the trunk the model can
|
|
305
|
+
* currently attend. Not cleared by `resetRun` (the next run rides the
|
|
306
|
+
* live trunk), but a released trunk's turns are REMOVED when its
|
|
307
|
+
* `branch:prune` folds: dead cells feed nothing, so the feed never
|
|
308
|
+
* shows them. History across trunks is the harness's concern. */
|
|
309
|
+
trunk: TrunkTurn[];
|
|
310
|
+
/** The run's SPINE, run-scoped: the shared root every agent forks from.
|
|
311
|
+
* Folded from runtime events alone (`branch:prefill role='spineHeader'`,
|
|
312
|
+
* `prompt:format role='spine'`) — universal to any pool harness — plus,
|
|
313
|
+
* when the harness DECLARES it ({@link RunFraming.instruction}), the
|
|
314
|
+
* user's instruction verbatim. This is the prompt's home in the pane
|
|
315
|
+
* even when a run later fails. Cleared by `resetRun`. */
|
|
316
|
+
spine: {
|
|
317
|
+
/** The user's instruction, as submitted — null until (unless) the
|
|
318
|
+
* harness's declared instruction event arrives. Never guessed. */
|
|
319
|
+
query: string | null;
|
|
320
|
+
attachments: {
|
|
321
|
+
digest: string;
|
|
322
|
+
}[];
|
|
323
|
+
/** First-seen moment (instruction arrival or first header prefill). */
|
|
324
|
+
at: number;
|
|
325
|
+
/** KV cells the spine header prefills added (outer + inner pools). */
|
|
326
|
+
spineCells: number;
|
|
327
|
+
/** The compiled spine header (system + tools), verbatim. */
|
|
328
|
+
headerText: string | null;
|
|
329
|
+
headerTokens: number;
|
|
330
|
+
spineAt: number | null;
|
|
331
|
+
/** Every moment the spine grew, with what it grew by — the seed first,
|
|
332
|
+
* then each extension (a chain step, a fanout widening). The bar's
|
|
333
|
+
* tick marks. */
|
|
334
|
+
growth: {
|
|
335
|
+
at: number;
|
|
336
|
+
tokens: number;
|
|
337
|
+
}[];
|
|
338
|
+
/** Positions inherited at fork — 0 on a cold start, the trunk's length
|
|
339
|
+
* on a warm one. From `branch:create role='spine'` position; first
|
|
340
|
+
* spine only (the inner pool's spine forks from the outer). */
|
|
341
|
+
inherited?: number;
|
|
342
|
+
/** Parsed from the STRUCTURED `tools` field the runtime emits on
|
|
343
|
+
* `prompt:format role='spine'` — reading data, not scraping markup. */
|
|
344
|
+
tools?: {
|
|
345
|
+
name: string;
|
|
346
|
+
description: string;
|
|
347
|
+
}[];
|
|
348
|
+
/** The system message text, from the structured `messages` field. */
|
|
349
|
+
systemText?: string | null;
|
|
350
|
+
} | null;
|
|
288
351
|
retrievals: Retrieval[];
|
|
289
352
|
pressure: PressurePoint[];
|
|
290
353
|
/** Host samples (`host:resources`, dev-gated boots only): the harness
|
|
@@ -342,10 +405,33 @@ export declare const PROVENANCE_RUNGS: readonly {
|
|
|
342
405
|
rung: ConfigOriginValue;
|
|
343
406
|
means: string;
|
|
344
407
|
}[];
|
|
345
|
-
/**
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
408
|
+
/** One row of the Settings inspector, derived from the application's config table. */
|
|
409
|
+
export interface ConfigRow {
|
|
410
|
+
/** The config path, e.g. `defaults.effort`. */
|
|
411
|
+
key: string;
|
|
412
|
+
/** When a change takes effect — the key's own declaration, `session` when it says nothing. */
|
|
413
|
+
applies: ConfigTier;
|
|
414
|
+
/** The values the row offers, or null when it offers none: the key lists no values, it is fixed at boot,
|
|
415
|
+
* or it is not a `family.leaf` path, which is all a settings patch can name. */
|
|
416
|
+
values: readonly string[] | null;
|
|
417
|
+
/** What the key is, in the declaration's own words; absent when it said nothing. */
|
|
418
|
+
describe?: string;
|
|
419
|
+
/** Where `harness.yml` sets it, and the environment variable that outranks the files — for saying how to change it. */
|
|
420
|
+
yml?: string;
|
|
421
|
+
env?: string;
|
|
422
|
+
}
|
|
423
|
+
export declare function configRows(table: ConfigTable): ConfigRow[];
|
|
424
|
+
/** How a row is changed, said from its declaration: the tier says when, `yml` and `env` say where. */
|
|
425
|
+
export declare function changing(row: ConfigRow): string;
|
|
426
|
+
/** The command that makes a row's choice: rig's own, for the row's tier, carrying a real patch. Null when the
|
|
427
|
+
* row offers no such choice. */
|
|
428
|
+
export declare function configCommand(row: ConfigRow, value: string): {
|
|
429
|
+
type: 'set_config' | 'reload_runtime';
|
|
430
|
+
patch: Record<string, Record<string, string>>;
|
|
431
|
+
} | null;
|
|
432
|
+
/** Every path the live config carries — a top-level key, or a `family.leaf` under one — as the rows of a harness
|
|
433
|
+
* that handed the pane no table. The keys rig owns (`version`, the `abilities` family) are not the app's. */
|
|
434
|
+
export declare function liveConfigKeys(config: Record<string, unknown> | null): string[];
|
|
349
435
|
/** Read a dotted config path off the live config object. */
|
|
350
436
|
export declare function readConfigPath(config: Record<string, unknown> | null, path: string): unknown;
|
|
351
437
|
//# sourceMappingURL=index.d.ts.map
|
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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,16 +4,10 @@
|
|
|
4
4
|
export function lanePpl(lane) {
|
|
5
5
|
return lane.nllCount === 0 ? null : Math.exp(lane.nllSum / lane.nllCount);
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
'research:start': 'research',
|
|
12
|
-
'synthesize:start': 'synth',
|
|
13
|
-
},
|
|
14
|
-
open: ['preflight:start', 'plan:start', 'query'],
|
|
15
|
-
close: ['complete', 'ui:error', 'ui:composer'],
|
|
16
|
-
};
|
|
7
|
+
/** What the pane assumes of a harness that declares nothing: no event opens or closes a run, no lane wears a
|
|
8
|
+
* phase, and no instruction is read. Lanes, retrievals, pressure and the trunk still fold, because those come
|
|
9
|
+
* from the runtime's own events; the run axis simply never resets. */
|
|
10
|
+
export const DEFAULT_FRAMING = { phases: {}, open: [], close: [] };
|
|
17
11
|
export function createPaneModel() {
|
|
18
12
|
return {
|
|
19
13
|
runPhase: null,
|
|
@@ -30,6 +24,8 @@ export function createPaneModel() {
|
|
|
30
24
|
origin: null,
|
|
31
25
|
lastSavedTo: undefined,
|
|
32
26
|
lanes: new Map(),
|
|
27
|
+
trunk: [],
|
|
28
|
+
spine: null,
|
|
33
29
|
retrievals: [],
|
|
34
30
|
pressure: [],
|
|
35
31
|
host: [],
|
|
@@ -47,6 +43,7 @@ export function createPaneModel() {
|
|
|
47
43
|
const MAX_PRESSURE_POINTS = 20_000;
|
|
48
44
|
const MAX_RETRIEVALS = 500;
|
|
49
45
|
const MAX_INTERVENTIONS = 200;
|
|
46
|
+
const MAX_TRUNK = 200;
|
|
50
47
|
const MAX_EPISTEMICS = 4096;
|
|
51
48
|
const MAX_HOST = 600;
|
|
52
49
|
/**
|
|
@@ -81,11 +78,21 @@ function resetRun(m, now) {
|
|
|
81
78
|
m.host = [];
|
|
82
79
|
m.interventions = [];
|
|
83
80
|
m.plan = null;
|
|
81
|
+
m.spine = null;
|
|
84
82
|
m.runStartAt = now;
|
|
85
83
|
m.runEndedAt = null;
|
|
86
84
|
m.pausedAt = null;
|
|
87
85
|
m.windingDownAt = null;
|
|
88
86
|
}
|
|
87
|
+
/** The spine record, created by whichever signal arrives first — the
|
|
88
|
+
* harness's declared instruction event or the runtime's own header
|
|
89
|
+
* prefill. Runtime-only harnesses still get a spine row. */
|
|
90
|
+
function ensureSpine(m, now) {
|
|
91
|
+
if (!m.spine) {
|
|
92
|
+
m.spine = { query: null, attachments: [], at: now, spineCells: 0, headerText: null, headerTokens: 0, spineAt: null, growth: [] };
|
|
93
|
+
}
|
|
94
|
+
return m.spine;
|
|
95
|
+
}
|
|
89
96
|
/** The retrieval a mirrored trace event belongs to: by callId WITHIN the
|
|
90
97
|
* agent (callIds are per-agent counters — call_0 exists in every agent, so
|
|
91
98
|
* a global match attaches one agent's funnel to another's call), else the
|
|
@@ -128,6 +135,25 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
128
135
|
const phaseLabel = framing.phases[ev.type];
|
|
129
136
|
if (phaseLabel !== undefined)
|
|
130
137
|
m.runPhase = phaseLabel;
|
|
138
|
+
// The user's instruction — read only where the harness DECLARED it lives
|
|
139
|
+
// (framing.instruction), never guessed from event shapes. First one per
|
|
140
|
+
// run wins: a re-plan re-emits the same event and must not reseed.
|
|
141
|
+
const instr = framing.instruction;
|
|
142
|
+
if (instr && ev.type === instr.event && (m.spine === null || m.spine.query === null)) {
|
|
143
|
+
const s = ensureSpine(m, now);
|
|
144
|
+
const q = ev[instr.field];
|
|
145
|
+
if (typeof q === 'string')
|
|
146
|
+
s.query = q;
|
|
147
|
+
if (instr.attachments) {
|
|
148
|
+
const a = ev[instr.attachments];
|
|
149
|
+
if (Array.isArray(a)) {
|
|
150
|
+
s.attachments = a.flatMap((x) => {
|
|
151
|
+
const r = x;
|
|
152
|
+
return typeof r.digest === 'string' ? [{ digest: r.digest }] : [];
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
131
157
|
switch (ev.type) {
|
|
132
158
|
case 'plan': {
|
|
133
159
|
const intent = typeof ev.intent === 'string' ? ev.intent : 'research';
|
|
@@ -201,6 +227,21 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
201
227
|
return;
|
|
202
228
|
}
|
|
203
229
|
case 'agent:spawn': {
|
|
230
|
+
const afterIds = Array.isArray(ev.after)
|
|
231
|
+
? ev.after.filter((x) => typeof x === 'number')
|
|
232
|
+
: [];
|
|
233
|
+
// Inherited-at-fork, snapshotted NOW: a recursive fork carries its
|
|
234
|
+
// parent's attention state; a top-level fork carries trunk + the spine
|
|
235
|
+
// as grown so far. Pre-spine forks get nothing — no guessed parentage.
|
|
236
|
+
const parentLane = typeof ev.parentAgentId === 'number' ? m.lanes.get(ev.parentAgentId) : undefined;
|
|
237
|
+
let inheritedAtFork;
|
|
238
|
+
if (parentLane) {
|
|
239
|
+
inheritedAtFork = (parentLane.inherited ?? 0) + parentLane.tokenCount;
|
|
240
|
+
}
|
|
241
|
+
else if (m.spine && m.spine.spineAt !== null && now + 250 >= m.spine.spineAt) {
|
|
242
|
+
inheritedAtFork = (m.spine.inherited ?? 0)
|
|
243
|
+
+ m.spine.growth.reduce((n2, g) => (g.at <= now + 250 ? n2 + g.tokens : n2), 0);
|
|
244
|
+
}
|
|
204
245
|
if (typeof ev.agentId !== 'number')
|
|
205
246
|
return; // type-only frame — never corrupt the lane map
|
|
206
247
|
const id = ev.agentId;
|
|
@@ -212,6 +253,8 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
212
253
|
doneAt: null,
|
|
213
254
|
outcome: 'running',
|
|
214
255
|
tokenCount: 0,
|
|
256
|
+
...(afterIds.length > 0 ? { after: afterIds } : {}),
|
|
257
|
+
...(inheritedAtFork !== undefined ? { inherited: inheritedAtFork } : {}),
|
|
215
258
|
inflightTool: null,
|
|
216
259
|
report: null,
|
|
217
260
|
reportSource: null,
|
|
@@ -351,6 +394,78 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
351
394
|
if (!te)
|
|
352
395
|
return;
|
|
353
396
|
switch (te.type) {
|
|
397
|
+
case 'branch:create': {
|
|
398
|
+
// Cold vs warm, from the run's own record: the FIRST spine's fork
|
|
399
|
+
// position. The inner pool's spine forks from the outer — skip it.
|
|
400
|
+
if (te.role !== 'spine')
|
|
401
|
+
return;
|
|
402
|
+
{
|
|
403
|
+
const s = ensureSpine(m, now);
|
|
404
|
+
if (s.inherited === undefined && typeof te.position === 'number')
|
|
405
|
+
s.inherited = te.position;
|
|
406
|
+
}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
case 'spine:extend': {
|
|
410
|
+
// A settled contribution committed onto the spine mid-run (chain
|
|
411
|
+
// steps). Later forks inherit it — the growth entry is what makes
|
|
412
|
+
// their inherited-at-fork snapshot and the paid-once sum honest.
|
|
413
|
+
const s = ensureSpine(m, now);
|
|
414
|
+
const grew = typeof te.deltaTokens === 'number' ? te.deltaTokens : 0;
|
|
415
|
+
s.spineCells += grew;
|
|
416
|
+
if (grew > 0)
|
|
417
|
+
s.growth.push({ at: now, tokens: grew });
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
case 'branch:prefill': {
|
|
421
|
+
// The spine's seed — runtime truth, no harness assumption.
|
|
422
|
+
if (te.role === 'spineHeader') {
|
|
423
|
+
const s = ensureSpine(m, now);
|
|
424
|
+
const grew = typeof te.cells === 'number' ? te.cells : 0;
|
|
425
|
+
s.spineCells += grew;
|
|
426
|
+
if (grew > 0)
|
|
427
|
+
s.growth.push({ at: now, tokens: grew });
|
|
428
|
+
if (s.spineAt === null)
|
|
429
|
+
s.spineAt = now;
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
// The session trunk's own turns (role warmDelta) — visible beside
|
|
433
|
+
// the runs they feed. Session-lived: resetRun leaves m.trunk alone.
|
|
434
|
+
if (te.role !== 'warmDelta')
|
|
435
|
+
return;
|
|
436
|
+
const speaker = te.speaker;
|
|
437
|
+
// Run-derived stats ride the response side: how long the run took
|
|
438
|
+
// and what its agents spent to produce what the trunk kept.
|
|
439
|
+
const responseSide = speaker === 'assistant' || speaker === 'turn' || speaker === undefined;
|
|
440
|
+
const stats = responseSide && m.runStartAt !== null
|
|
441
|
+
? {
|
|
442
|
+
wallMs: Math.max(0, now - m.runStartAt),
|
|
443
|
+
agentTokens: [...m.lanes.values()].reduce((n, l) => n + l.tokenCount, 0),
|
|
444
|
+
}
|
|
445
|
+
: {};
|
|
446
|
+
m.trunk.push({
|
|
447
|
+
at: now,
|
|
448
|
+
...stats,
|
|
449
|
+
...(speaker === 'user' || speaker === 'assistant' || speaker === 'tool' || speaker === 'turn'
|
|
450
|
+
? { speaker } : {}),
|
|
451
|
+
...(typeof te.query === 'string' ? { query: te.query } : {}),
|
|
452
|
+
...(typeof te.response === 'string' ? { response: te.response } : {}),
|
|
453
|
+
content: typeof te.content === 'string' ? te.content : '',
|
|
454
|
+
cells: typeof te.cells === 'number' ? te.cells : 0,
|
|
455
|
+
...(typeof te.branchHandle === 'number' ? { branchHandle: te.branchHandle } : {}),
|
|
456
|
+
attachments: Array.isArray(te.attachments)
|
|
457
|
+
? te.attachments.flatMap((a) => {
|
|
458
|
+
const r = a;
|
|
459
|
+
return typeof r.digest === 'string'
|
|
460
|
+
? [{ digest: r.digest, ...(typeof r.mediaType === 'string' ? { mediaType: r.mediaType } : {}) }]
|
|
461
|
+
: [];
|
|
462
|
+
})
|
|
463
|
+
: [],
|
|
464
|
+
});
|
|
465
|
+
if (m.trunk.length > MAX_TRUNK)
|
|
466
|
+
m.trunk.shift();
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
354
469
|
case 'pool:agentNudge': {
|
|
355
470
|
m.interventions.push({
|
|
356
471
|
kind: typeof te.guard === 'string' ? 'guard' : 'nudge',
|
|
@@ -381,6 +496,40 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
381
496
|
return;
|
|
382
497
|
}
|
|
383
498
|
case 'prompt:format': {
|
|
499
|
+
// The compiled spine header — what position 0 actually holds.
|
|
500
|
+
if (te.role === 'spine') {
|
|
501
|
+
const s = ensureSpine(m, now);
|
|
502
|
+
if (typeof te.promptText === 'string')
|
|
503
|
+
s.headerText = te.promptText;
|
|
504
|
+
if (typeof te.tokenCount === 'number')
|
|
505
|
+
s.headerTokens = te.tokenCount;
|
|
506
|
+
if (typeof te.tools === 'string') {
|
|
507
|
+
try {
|
|
508
|
+
const arr = JSON.parse(te.tools);
|
|
509
|
+
if (Array.isArray(arr)) {
|
|
510
|
+
s.tools = arr.flatMap((x) => {
|
|
511
|
+
const f = x.function ?? x;
|
|
512
|
+
const g = f;
|
|
513
|
+
return g && typeof g.name === 'string'
|
|
514
|
+
? [{ name: g.name, description: typeof g.description === 'string' ? g.description : '' }]
|
|
515
|
+
: [];
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
catch { /* not JSON — leave unparsed */ }
|
|
520
|
+
}
|
|
521
|
+
if (typeof te.messages === 'string') {
|
|
522
|
+
try {
|
|
523
|
+
const ms = JSON.parse(te.messages);
|
|
524
|
+
if (Array.isArray(ms)) {
|
|
525
|
+
const sys = ms.find((mm) => mm && mm.role === 'system' && typeof mm.content === 'string');
|
|
526
|
+
s.systemText = sys ? sys.content : null;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
catch { /* not JSON */ }
|
|
530
|
+
}
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
384
533
|
const lane = m.lanes.get(agentId);
|
|
385
534
|
if (lane && typeof te.promptText === 'string') {
|
|
386
535
|
lane.prompt = {
|
|
@@ -396,6 +545,13 @@ export function foldEvent(m, ev, now, framing = DEFAULT_FRAMING) {
|
|
|
396
545
|
const lane = m.lanes.get(handle);
|
|
397
546
|
if (lane)
|
|
398
547
|
lane.prunedAt = now;
|
|
548
|
+
// The same prune, seen by the trunk feed: this handle's turns
|
|
549
|
+
// left the KV with it, so they leave the feed — the feed shows
|
|
550
|
+
// the resident conversation, nothing else. Handle-matched (never
|
|
551
|
+
// a blanket clear): an agent branch's prune must not touch the
|
|
552
|
+
// trunk, and the match is order-independent with the next
|
|
553
|
+
// generation's first commit.
|
|
554
|
+
m.trunk = m.trunk.filter((t) => t.branchHandle !== handle);
|
|
399
555
|
return;
|
|
400
556
|
}
|
|
401
557
|
case 'tool:dispatch': {
|
|
@@ -559,17 +715,54 @@ export const PROVENANCE_RUNGS = [
|
|
|
559
715
|
{ rung: 'session', means: 'this session only — no file remembers it' },
|
|
560
716
|
{ rung: 'default', means: 'nothing set it' },
|
|
561
717
|
];
|
|
562
|
-
export
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
};
|
|
718
|
+
export function configRows(table) {
|
|
719
|
+
return Object.entries(table).map(([key, decl]) => {
|
|
720
|
+
const applies = decl.applies ?? 'session';
|
|
721
|
+
const offered = decl.oneOf && applies !== 'boot' && key.split('.').length === 2;
|
|
722
|
+
return {
|
|
723
|
+
key, applies, values: offered ? decl.oneOf : null,
|
|
724
|
+
...(decl.describe !== undefined ? { describe: decl.describe } : {}),
|
|
725
|
+
...(decl.yml !== undefined ? { yml: decl.yml } : {}),
|
|
726
|
+
...(decl.env !== undefined ? { env: decl.env } : {}),
|
|
727
|
+
};
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
/** How a row is changed, said from its declaration: the tier says when, `yml` and `env` say where. */
|
|
731
|
+
export function changing(row) {
|
|
732
|
+
const committed = row.yml ? `harness.yml → ${row.yml}` : null;
|
|
733
|
+
switch (row.applies) {
|
|
734
|
+
case 'session':
|
|
735
|
+
return `Change it here: it applies to the next run and is remembered locally.${committed ? ` The committed default is ${committed}.` : ''}`;
|
|
736
|
+
case 'reload':
|
|
737
|
+
return `Saved now; the next start loads it.${committed ? ` Committed in ${committed}.` : ''}`;
|
|
738
|
+
case 'boot':
|
|
739
|
+
return `Fixed for this run.${committed ? ` Set ${committed}${row.env ? ` (or ${row.env})` : ''}, then restart.` : ''}`;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/** The command that makes a row's choice: rig's own, for the row's tier, carrying a real patch. Null when the
|
|
743
|
+
* row offers no such choice. */
|
|
744
|
+
export function configCommand(row, value) {
|
|
745
|
+
if (!row.values?.includes(value))
|
|
746
|
+
return null;
|
|
747
|
+
const [family, leaf] = row.key.split('.');
|
|
748
|
+
return { type: row.applies === 'reload' ? 'reload_runtime' : 'set_config', patch: { [family]: { [leaf]: value } } };
|
|
749
|
+
}
|
|
750
|
+
/** Every path the live config carries — a top-level key, or a `family.leaf` under one — as the rows of a harness
|
|
751
|
+
* that handed the pane no table. The keys rig owns (`version`, the `abilities` family) are not the app's. */
|
|
752
|
+
export function liveConfigKeys(config) {
|
|
753
|
+
const keys = [];
|
|
754
|
+
for (const [key, node] of Object.entries(config ?? {})) {
|
|
755
|
+
if (key === 'version' || key === 'abilities')
|
|
756
|
+
continue;
|
|
757
|
+
if (node !== null && typeof node === 'object' && !Array.isArray(node)) {
|
|
758
|
+
for (const leaf of Object.keys(node))
|
|
759
|
+
keys.push(`${key}.${leaf}`);
|
|
760
|
+
}
|
|
761
|
+
else
|
|
762
|
+
keys.push(key);
|
|
763
|
+
}
|
|
764
|
+
return keys;
|
|
765
|
+
}
|
|
573
766
|
/** Read a dotted config path off the live config object. */
|
|
574
767
|
export function readConfigPath(config, path) {
|
|
575
768
|
if (!config)
|