@rulvar/core 1.230.0 → 1.232.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +272 -4
- package/dist/index.js +1310 -887
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8794,11 +8794,25 @@ function readRejectedFinishCandidates(raw) {
|
|
|
8794
8794
|
*
|
|
8795
8795
|
* The twenty-fifth comparison run was killed and resumed, and its two
|
|
8796
8796
|
* terminals mixed both kinds with nothing marking which was which: the
|
|
8797
|
-
* money was cumulative, the
|
|
8797
|
+
* money was cumulative, the live-only counters were not,
|
|
8798
8798
|
* and reconciling them into one honest account of the logical run was
|
|
8799
8799
|
* hand work over a joined journal. Keys are field paths as a consumer
|
|
8800
|
-
* reads them off `RunOutcome` (`cost.orchestrator.wakes`)
|
|
8801
|
-
*
|
|
8800
|
+
* reads them off `RunOutcome` (`cost.orchestrator.wakes`): the type
|
|
8801
|
+
* requires every field of the outcome, and the `satisfies` below
|
|
8802
|
+
* requires every counted leaf under `cost` (RV2801), because an index
|
|
8803
|
+
* signature admits nested paths and demands none, so the five that were
|
|
8804
|
+
* declared were declared by hand and by luck while four
|
|
8805
|
+
* (`cost.usageApprox`, `cost.abandoned.usd`, `cost.abandoned.usageApprox`,
|
|
8806
|
+
* `cost.orchestrator.share`) were simply missing. That is the RV2701
|
|
8807
|
+
* blindness one level down: a gate whose subject is nested figures
|
|
8808
|
+
* cannot stop at the top level.
|
|
8809
|
+
*
|
|
8810
|
+
* What neither can decide is whether a declared scope is TRUE, and a
|
|
8811
|
+
* wrong scope is worse than a missing one: a missing one is noticed, a
|
|
8812
|
+
* wrong one is believed. The doctrine test suspends a real run, resumes
|
|
8813
|
+
* it, and holds every declared figure against its own claim (RV2801),
|
|
8814
|
+
* which is how three `cost.orchestrator.*` paths were found calling
|
|
8815
|
+
* themselves `'segment'` while the terminal folded them cumulatively.
|
|
8802
8816
|
*/
|
|
8803
8817
|
const TERMINAL_TELEMETRY_SCOPE = Object.freeze({
|
|
8804
8818
|
status: "terminal",
|
|
@@ -8827,10 +8841,14 @@ const TERMINAL_TELEMETRY_SCOPE = Object.freeze({
|
|
|
8827
8841
|
"cost.totalUsd": "cumulative",
|
|
8828
8842
|
"cost.grossUsd": "cumulative",
|
|
8829
8843
|
"cost.wireRequests": "cumulative",
|
|
8844
|
+
"cost.usageApprox": "cumulative",
|
|
8845
|
+
"cost.abandoned.usd": "cumulative",
|
|
8846
|
+
"cost.abandoned.usageApprox": "cumulative",
|
|
8830
8847
|
"cost.orchestrator.spentUsd": "cumulative",
|
|
8831
|
-
"cost.orchestrator.
|
|
8832
|
-
"cost.orchestrator.
|
|
8833
|
-
"cost.orchestrator.
|
|
8848
|
+
"cost.orchestrator.share": "cumulative",
|
|
8849
|
+
"cost.orchestrator.wakes": "cumulative",
|
|
8850
|
+
"cost.orchestrator.forcedFinish": "cumulative",
|
|
8851
|
+
"cost.orchestrator.reserveUsedUsd": "cumulative",
|
|
8834
8852
|
transportRetries: "segment",
|
|
8835
8853
|
schemaRejectedFinishExchanges: "segment",
|
|
8836
8854
|
schemaRecoveredFinishExchanges: "segment"
|
|
@@ -8905,6 +8923,7 @@ function logicalRunTelemetry(entries) {
|
|
|
8905
8923
|
function childRostersFromJournal(entries) {
|
|
8906
8924
|
const rosters = /* @__PURE__ */ new Map();
|
|
8907
8925
|
const ordered = [...entries].sort((a, b) => a.seq - b.seq);
|
|
8926
|
+
const abandoned = buildAbandonFold(ordered);
|
|
8908
8927
|
const dispatchesByScope = /* @__PURE__ */ new Map();
|
|
8909
8928
|
const terminalsByScopeKey = /* @__PURE__ */ new Map();
|
|
8910
8929
|
for (const entry of ordered) {
|
|
@@ -8950,6 +8969,7 @@ function childRostersFromJournal(entries) {
|
|
|
8950
8969
|
const terminal = terminalsByScopeKey.get(JSON.stringify([childScope, dispatch.key]))?.find((candidate) => candidate.seq > dispatch.seq);
|
|
8951
8970
|
roster.children.push({
|
|
8952
8971
|
handle: dispatch.seq,
|
|
8972
|
+
...abandoned.isAbandoned(dispatch.seq) ? { abandoned: true } : {},
|
|
8953
8973
|
...terminal?.costAttribution?.agentType === void 0 ? {} : { agentType: terminal.costAttribution.agentType },
|
|
8954
8974
|
...terminal === void 0 ? {} : { status: terminal.status },
|
|
8955
8975
|
...terminal?.evidence === void 0 ? {} : { evidence: { ...terminal.evidence } }
|
|
@@ -9071,455 +9091,1021 @@ async function reconcileRunMeta(store, runId, opts) {
|
|
|
9071
9091
|
};
|
|
9072
9092
|
}
|
|
9073
9093
|
//#endregion
|
|
9074
|
-
//#region src/
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
* Contract (DEF-4 tightening):
|
|
9082
|
-
* - A1 atomicity: a torn trailing line (crash mid-append) is never
|
|
9083
|
-
* visible in load; the incomplete fragment is dropped and overwritten
|
|
9084
|
-
* by the next append. Whole records on that line are data, never
|
|
9085
|
-
* fragment (RV701): a crash that persisted every JSON byte but not
|
|
9086
|
-
* the '\n' leaves a parseable tail that load serves and append
|
|
9087
|
-
* terminates before writing, and repair salvages complete records a
|
|
9088
|
-
* glued line carries instead of discarding the line, so an entry a
|
|
9089
|
-
* load has served can never be un-served by a later repair.
|
|
9090
|
-
* - A2 total per-run order: load returns append order, stable across
|
|
9091
|
-
* calls (the kernel's per-run queue serializes appends).
|
|
9092
|
-
* - A3 read-your-writes: append resolves after the line is written.
|
|
9093
|
-
* - A4 opaque payload: entries round-trip byte-for-byte as JSON; unknown
|
|
9094
|
-
* kinds and fields pass through untouched.
|
|
9095
|
-
*
|
|
9096
|
-
* Leasing is NOT implemented here: LeasableStore ships with
|
|
9097
|
-
* @rulvar/store-sqlite (M5); JsonlFileStore is single-writer by
|
|
9098
|
-
* convention.
|
|
9099
|
-
*/
|
|
9100
|
-
const JOURNAL_SUFFIX = ".jsonl";
|
|
9101
|
-
const META_SUFFIX = ".meta.json";
|
|
9102
|
-
function safeName(runId) {
|
|
9103
|
-
if (!/^[A-Za-z0-9._-]+$/.test(runId)) throw new JournalOrderViolation(`JsonlFileStore: runId '${runId}' is not filesystem-safe ([A-Za-z0-9._-] only)`);
|
|
9104
|
-
return runId;
|
|
9105
|
-
}
|
|
9094
|
+
//#region src/l0/telemetry-reduce.ts
|
|
9095
|
+
const ZERO = {
|
|
9096
|
+
inputTokens: 0,
|
|
9097
|
+
outputTokens: 0,
|
|
9098
|
+
cacheReadTokens: 0,
|
|
9099
|
+
cacheWriteTokens: 0
|
|
9100
|
+
};
|
|
9106
9101
|
/**
|
|
9107
|
-
*
|
|
9108
|
-
*
|
|
9109
|
-
*
|
|
9110
|
-
* clean concatenation from its first byte salvages its whole prefix
|
|
9111
|
-
* values and returns everything after them as the torn fragment, so the
|
|
9112
|
-
* caller keeps accepted records and drops exactly the unacknowledged
|
|
9113
|
-
* tail a crash tore.
|
|
9102
|
+
* Reduces one run's event stream (or any slice of it) to the invocation
|
|
9103
|
+
* table. Feed it the events in emission order; both a live stream and a
|
|
9104
|
+
* replayed one produce the same usage and cost columns.
|
|
9114
9105
|
*/
|
|
9115
|
-
function
|
|
9116
|
-
const
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
let
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
if (
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9106
|
+
function reduceInvocationTable(events) {
|
|
9107
|
+
const rows = /* @__PURE__ */ new Map();
|
|
9108
|
+
const order = [];
|
|
9109
|
+
const openPhases = /* @__PURE__ */ new Map();
|
|
9110
|
+
const byRole = {};
|
|
9111
|
+
let totalCostUsd = 0;
|
|
9112
|
+
const rowFor = (event) => {
|
|
9113
|
+
let row = rows.get(event.spanId);
|
|
9114
|
+
if (row === void 0) {
|
|
9115
|
+
row = {
|
|
9116
|
+
spanId: event.spanId,
|
|
9117
|
+
agentType: event.agentType,
|
|
9118
|
+
...event.label === void 0 ? {} : { label: event.label },
|
|
9119
|
+
usage: ZERO,
|
|
9120
|
+
costUsd: 0,
|
|
9121
|
+
costBasis: "aggregate-estimate",
|
|
9122
|
+
usageApprox: false,
|
|
9123
|
+
retryCount: 0,
|
|
9124
|
+
replayed: event.replayed === true,
|
|
9125
|
+
open: true,
|
|
9126
|
+
phases: []
|
|
9127
|
+
};
|
|
9128
|
+
rows.set(event.spanId, row);
|
|
9129
|
+
order.push(row);
|
|
9132
9130
|
}
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9131
|
+
return row;
|
|
9132
|
+
};
|
|
9133
|
+
for (const event of events) switch (event.type) {
|
|
9134
|
+
case "agent:start": {
|
|
9135
|
+
const row = rowFor(event);
|
|
9136
|
+
row.role = event.role;
|
|
9137
|
+
break;
|
|
9136
9138
|
}
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9139
|
+
case "agent:phase:start": {
|
|
9140
|
+
const row = rowFor(event);
|
|
9141
|
+
const phase = {
|
|
9142
|
+
invocation: event.invocation,
|
|
9143
|
+
role: event.role,
|
|
9144
|
+
model: event.model,
|
|
9145
|
+
durationMs: 0,
|
|
9146
|
+
usage: ZERO,
|
|
9147
|
+
costUsd: 0,
|
|
9148
|
+
costBasis: "aggregate-estimate",
|
|
9149
|
+
retries: 0,
|
|
9150
|
+
replayed: event.replayed === true,
|
|
9151
|
+
open: true
|
|
9142
9152
|
};
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9153
|
+
row.phases.push(phase);
|
|
9154
|
+
openPhases.set(`${event.spanId}#${event.invocation}`, phase);
|
|
9155
|
+
break;
|
|
9156
|
+
}
|
|
9157
|
+
case "agent:phase:end": {
|
|
9158
|
+
const key = `${event.spanId}#${event.invocation}`;
|
|
9159
|
+
let phase = openPhases.get(key);
|
|
9160
|
+
if (phase === void 0) {
|
|
9161
|
+
phase = {
|
|
9162
|
+
invocation: event.invocation,
|
|
9163
|
+
role: event.role,
|
|
9164
|
+
model: event.model,
|
|
9165
|
+
durationMs: 0,
|
|
9166
|
+
usage: ZERO,
|
|
9167
|
+
costUsd: 0,
|
|
9168
|
+
costBasis: "aggregate-estimate",
|
|
9169
|
+
retries: 0,
|
|
9170
|
+
replayed: event.replayed === true,
|
|
9171
|
+
open: true
|
|
9172
|
+
};
|
|
9173
|
+
rowFor(event).phases.push(phase);
|
|
9154
9174
|
}
|
|
9175
|
+
openPhases.delete(key);
|
|
9176
|
+
phase.open = false;
|
|
9177
|
+
phase.role = event.role;
|
|
9178
|
+
phase.model = event.model;
|
|
9179
|
+
phase.durationMs = event.durationMs;
|
|
9180
|
+
phase.usage = event.usage;
|
|
9181
|
+
phase.costUsd = event.costUsd;
|
|
9182
|
+
phase.costBasis = event.costBasis ?? "aggregate-estimate";
|
|
9183
|
+
phase.outcome = event.outcome;
|
|
9184
|
+
phase.retries = event.retries ?? 0;
|
|
9185
|
+
const bucket = byRole[event.role] ??= {
|
|
9186
|
+
usage: ZERO,
|
|
9187
|
+
costUsd: 0,
|
|
9188
|
+
costBasis: "per-call"
|
|
9189
|
+
};
|
|
9190
|
+
bucket.usage = sumUsage(bucket.usage, event.usage);
|
|
9191
|
+
bucket.costUsd += event.costUsd;
|
|
9192
|
+
if (phase.costBasis === "aggregate-estimate") bucket.costBasis = "aggregate-estimate";
|
|
9193
|
+
break;
|
|
9194
|
+
}
|
|
9195
|
+
case "agent:end": {
|
|
9196
|
+
const row = rowFor(event);
|
|
9197
|
+
row.open = false;
|
|
9198
|
+
row.status = event.status;
|
|
9199
|
+
row.usage = event.usage;
|
|
9200
|
+
row.costUsd = event.costUsd;
|
|
9201
|
+
row.costBasis = event.costBasis ?? "aggregate-estimate";
|
|
9202
|
+
row.usageApprox = event.usageApprox === true;
|
|
9203
|
+
row.retryCount = event.retryCount ?? 0;
|
|
9204
|
+
if (event.toolBudget !== void 0) row.toolBudget = event.toolBudget;
|
|
9205
|
+
totalCostUsd += event.costUsd;
|
|
9206
|
+
break;
|
|
9155
9207
|
}
|
|
9208
|
+
default: break;
|
|
9156
9209
|
}
|
|
9157
9210
|
return {
|
|
9158
|
-
|
|
9159
|
-
|
|
9211
|
+
agents: order,
|
|
9212
|
+
byRole,
|
|
9213
|
+
totalCostUsd
|
|
9160
9214
|
};
|
|
9161
9215
|
}
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9216
|
+
/**
|
|
9217
|
+
* The label the claim-consistency judge invocation dispatches under
|
|
9218
|
+
* (RV1502; named here since RV1604 so the critical-path reducer and the
|
|
9219
|
+
* orchestrator share one constant): the judge rides role 'synthesize',
|
|
9220
|
+
* and this label is what tells its wall apart from a real final
|
|
9221
|
+
* composition in {@link reduceCriticalPath}.
|
|
9222
|
+
*/
|
|
9223
|
+
const CLAIM_JUDGE_LABEL = "claim-consistency-judge";
|
|
9224
|
+
/**
|
|
9225
|
+
* The label the final synthesis (composition) invocation dispatches
|
|
9226
|
+
* under (RV2901). The engine labelling its OWN dispatches is what lets
|
|
9227
|
+
* `criticalPathFromJournal` split the synthesize bucket offline: the
|
|
9228
|
+
* split demands a label on EVERY synthesize span, and the comparison
|
|
9229
|
+
* run that shipped the journal fold still refused it because this one
|
|
9230
|
+
* dispatch stayed anonymous while the claim judge was labelled.
|
|
9231
|
+
*/
|
|
9232
|
+
const FINAL_COMPOSITION_LABEL = "final-composition";
|
|
9233
|
+
/**
|
|
9234
|
+
* The label an incremental synthesis note dispatches under (RV2901).
|
|
9235
|
+
* Notes ride role 'synthesize' and are composition-side work, so both
|
|
9236
|
+
* reducers count them toward the composition half of the split; the
|
|
9237
|
+
* label exists so a journal reader can tell WHICH composition spans
|
|
9238
|
+
* were notes without guessing from their size.
|
|
9239
|
+
*/
|
|
9240
|
+
const SYNTHESIS_NOTE_LABEL = "synthesis-note";
|
|
9241
|
+
/** Total length of the union of possibly overlapping intervals. */
|
|
9242
|
+
function unionLength(intervals) {
|
|
9243
|
+
const positive = intervals.filter((interval) => interval.to > interval.from);
|
|
9244
|
+
if (positive.length === 0) return 0;
|
|
9245
|
+
const sorted = [...positive].sort((a, b) => a.from - b.from);
|
|
9246
|
+
let total = 0;
|
|
9247
|
+
let from = sorted[0]?.from ?? 0;
|
|
9248
|
+
let to = sorted[0]?.to ?? 0;
|
|
9249
|
+
for (const interval of sorted.slice(1)) if (interval.from > to) {
|
|
9250
|
+
total += to - from;
|
|
9251
|
+
from = interval.from;
|
|
9252
|
+
to = interval.to;
|
|
9253
|
+
} else if (interval.to > to) to = interval.to;
|
|
9254
|
+
return total + (to - from);
|
|
9255
|
+
}
|
|
9256
|
+
function reduceCriticalPath(events) {
|
|
9257
|
+
let runStart;
|
|
9258
|
+
let runEnd;
|
|
9259
|
+
const startBySpan = /* @__PURE__ */ new Map();
|
|
9260
|
+
let lastWorkerEnd;
|
|
9261
|
+
let workerSpans = 0;
|
|
9262
|
+
let synthesisMs = 0;
|
|
9263
|
+
let finalCompositionMs = 0;
|
|
9264
|
+
let semanticJudgeMs = 0;
|
|
9265
|
+
const coordinationModel = [];
|
|
9266
|
+
const coordinationTools = [];
|
|
9267
|
+
const synthesisSpans = [];
|
|
9268
|
+
const spanOf = (durationMs) => Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;
|
|
9269
|
+
for (const event of events) {
|
|
9270
|
+
const at = Date.parse(event.ts);
|
|
9271
|
+
if (!Number.isFinite(at)) continue;
|
|
9272
|
+
switch (event.type) {
|
|
9273
|
+
case "run:start":
|
|
9274
|
+
runStart ??= at;
|
|
9275
|
+
break;
|
|
9276
|
+
case "run:end":
|
|
9277
|
+
runEnd = at;
|
|
9278
|
+
break;
|
|
9279
|
+
case "agent:start":
|
|
9280
|
+
startBySpan.set(event.spanId, {
|
|
9281
|
+
role: event.role,
|
|
9282
|
+
at,
|
|
9283
|
+
...event.label === void 0 ? {} : { label: event.label }
|
|
9284
|
+
});
|
|
9285
|
+
break;
|
|
9286
|
+
case "agent:phase:end":
|
|
9287
|
+
if (startBySpan.get(event.spanId)?.role === "orchestrate") coordinationModel.push({
|
|
9288
|
+
phase: event.role,
|
|
9289
|
+
from: at - spanOf(event.durationMs),
|
|
9290
|
+
to: at
|
|
9291
|
+
});
|
|
9292
|
+
break;
|
|
9293
|
+
case "tool:end":
|
|
9294
|
+
if (startBySpan.get(event.spanId)?.role === "orchestrate") coordinationTools.push({
|
|
9295
|
+
name: event.toolName,
|
|
9296
|
+
from: at - spanOf(event.durationMs),
|
|
9297
|
+
to: at
|
|
9298
|
+
});
|
|
9299
|
+
break;
|
|
9300
|
+
case "agent:end": {
|
|
9301
|
+
const started = startBySpan.get(event.spanId);
|
|
9302
|
+
if (started === void 0) break;
|
|
9303
|
+
if (started.role === "synthesize") {
|
|
9304
|
+
const wall = Math.max(0, at - started.at);
|
|
9305
|
+
const judge = started.label === CLAIM_JUDGE_LABEL;
|
|
9306
|
+
synthesisMs += wall;
|
|
9307
|
+
if (judge) semanticJudgeMs += wall;
|
|
9308
|
+
else finalCompositionMs += wall;
|
|
9309
|
+
synthesisSpans.push({
|
|
9310
|
+
from: started.at,
|
|
9311
|
+
to: at,
|
|
9312
|
+
judge
|
|
9313
|
+
});
|
|
9314
|
+
} else if (started.role !== "orchestrate") {
|
|
9315
|
+
workerSpans += 1;
|
|
9316
|
+
lastWorkerEnd = lastWorkerEnd === void 0 ? at : Math.max(lastWorkerEnd, at);
|
|
9317
|
+
}
|
|
9318
|
+
break;
|
|
9253
9319
|
}
|
|
9254
|
-
|
|
9255
|
-
closeSync(fd);
|
|
9320
|
+
default: break;
|
|
9256
9321
|
}
|
|
9257
|
-
if (needsNewline) appendFileSync(path, "\n", "utf8");
|
|
9258
|
-
}
|
|
9259
|
-
repairTornTail(runId, whole) {
|
|
9260
|
-
const path = this.journalPath(runId);
|
|
9261
|
-
const temp = `${path}.tmp`;
|
|
9262
|
-
writeFileSync(temp, whole.map((entry) => JSON.stringify(entry)).join("\n") + (whole.length > 0 ? "\n" : ""), "utf8");
|
|
9263
|
-
renameSync(temp, path);
|
|
9264
|
-
}
|
|
9265
|
-
async putMeta(m) {
|
|
9266
|
-
const path = this.metaPath(m.runId);
|
|
9267
|
-
const temp = `${path}.tmp`;
|
|
9268
|
-
writeFileSync(temp, JSON.stringify(m, null, 2), "utf8");
|
|
9269
|
-
renameSync(temp, path);
|
|
9270
9322
|
}
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9323
|
+
const path = {
|
|
9324
|
+
synthesisMs,
|
|
9325
|
+
finalCompositionMs,
|
|
9326
|
+
semanticJudgeMs,
|
|
9327
|
+
workerSpans
|
|
9328
|
+
};
|
|
9329
|
+
if (runStart !== void 0 && runEnd !== void 0) path.runWallMs = Math.max(0, runEnd - runStart);
|
|
9330
|
+
if (runEnd !== void 0 && lastWorkerEnd !== void 0) {
|
|
9331
|
+
path.postFanInMs = Math.max(0, runEnd - lastWorkerEnd);
|
|
9332
|
+
const windowFrom = Math.min(lastWorkerEnd, runEnd);
|
|
9333
|
+
const windowTo = runEnd;
|
|
9334
|
+
const clip = (interval) => {
|
|
9335
|
+
if (interval.to < windowFrom || interval.from > windowTo) return;
|
|
9336
|
+
return {
|
|
9337
|
+
from: Math.max(interval.from, windowFrom),
|
|
9338
|
+
to: Math.min(interval.to, windowTo)
|
|
9339
|
+
};
|
|
9340
|
+
};
|
|
9341
|
+
const byPhase = {};
|
|
9342
|
+
const modelClipped = [];
|
|
9343
|
+
for (const interval of coordinationModel) {
|
|
9344
|
+
const clipped = clip(interval);
|
|
9345
|
+
if (clipped === void 0) continue;
|
|
9346
|
+
byPhase[interval.phase] = (byPhase[interval.phase] ?? 0) + (clipped.to - clipped.from);
|
|
9347
|
+
modelClipped.push(clipped);
|
|
9276
9348
|
}
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
for (const
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9349
|
+
const synthesisClipped = [];
|
|
9350
|
+
let judgeClippedMs = 0;
|
|
9351
|
+
let compositionClippedMs = 0;
|
|
9352
|
+
for (const span of synthesisSpans) {
|
|
9353
|
+
const clipped = clip(span);
|
|
9354
|
+
if (clipped === void 0) continue;
|
|
9355
|
+
synthesisClipped.push(clipped);
|
|
9356
|
+
if (span.judge) judgeClippedMs += clipped.to - clipped.from;
|
|
9357
|
+
else compositionClippedMs += clipped.to - clipped.from;
|
|
9285
9358
|
}
|
|
9286
|
-
|
|
9359
|
+
const byName = {};
|
|
9360
|
+
const callsByName = {};
|
|
9361
|
+
const toolsClipped = [];
|
|
9362
|
+
for (const interval of coordinationTools) {
|
|
9363
|
+
const clipped = clip(interval);
|
|
9364
|
+
if (clipped === void 0) continue;
|
|
9365
|
+
byName[interval.name] = (byName[interval.name] ?? 0) + (clipped.to - clipped.from);
|
|
9366
|
+
callsByName[interval.name] = (callsByName[interval.name] ?? 0) + 1;
|
|
9367
|
+
toolsClipped.push(clipped);
|
|
9368
|
+
}
|
|
9369
|
+
const lengthOf = (intervals) => intervals.reduce((sum, interval) => sum + (interval.to - interval.from), 0);
|
|
9370
|
+
const coveredMs = unionLength([
|
|
9371
|
+
...modelClipped,
|
|
9372
|
+
...toolsClipped,
|
|
9373
|
+
...synthesisClipped
|
|
9374
|
+
]);
|
|
9375
|
+
const modelOnlyMs = unionLength([...modelClipped, ...toolsClipped]) - unionLength(toolsClipped);
|
|
9376
|
+
const breakdown = {
|
|
9377
|
+
coordinationModelMs: lengthOf(modelClipped),
|
|
9378
|
+
coordinationModelMsByPhase: byPhase,
|
|
9379
|
+
coordinationModelOnlyMs: modelOnlyMs,
|
|
9380
|
+
coordinationToolMs: lengthOf(toolsClipped),
|
|
9381
|
+
coordinationToolMsByName: byName,
|
|
9382
|
+
coordinationToolCallsByName: callsByName,
|
|
9383
|
+
synthesisMs: lengthOf(synthesisClipped),
|
|
9384
|
+
finalCompositionMs: compositionClippedMs,
|
|
9385
|
+
semanticJudgeMs: judgeClippedMs,
|
|
9386
|
+
coveredMs,
|
|
9387
|
+
residueMs: Math.max(0, path.postFanInMs - coveredMs)
|
|
9388
|
+
};
|
|
9389
|
+
if (path.postFanInMs > 0) breakdown.residueShare = breakdown.residueMs / path.postFanInMs;
|
|
9390
|
+
path.postFanIn = breakdown;
|
|
9287
9391
|
}
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
this.lastSeq.delete(runId);
|
|
9392
|
+
if (path.runWallMs !== void 0 && path.runWallMs > 0) {
|
|
9393
|
+
if (path.postFanInMs !== void 0) path.postFanInShare = path.postFanInMs / path.runWallMs;
|
|
9394
|
+
path.synthesisShare = synthesisMs / path.runWallMs;
|
|
9292
9395
|
}
|
|
9396
|
+
return path;
|
|
9397
|
+
}
|
|
9398
|
+
//#endregion
|
|
9399
|
+
//#region src/stores/critical-path.ts
|
|
9400
|
+
const parse$1 = (at) => {
|
|
9401
|
+
if (at === void 0) return;
|
|
9402
|
+
const ms = Date.parse(at);
|
|
9403
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
9293
9404
|
};
|
|
9294
|
-
const TRANSCRIPT_SUFFIX = ".bin";
|
|
9295
9405
|
/**
|
|
9296
|
-
*
|
|
9297
|
-
* persisted CompiledWorkflow sources) as one file per ref under `dir`,
|
|
9298
|
-
* so compiled runs resume across processes. Refs follow the
|
|
9299
|
-
* `<runId>/<name>` convention; nested segments become directories.
|
|
9406
|
+
* Fold a run's critical path out of its journal.
|
|
9300
9407
|
*
|
|
9301
|
-
*
|
|
9302
|
-
* segment must match `[A-Za-z0-9._-]` and be neither empty, '.', nor
|
|
9303
|
-
* '..', and the resolved path must stay under the resolved root. A '..'
|
|
9304
|
-
* segment used to pass the per-segment alphabet (dots are in it) and, via
|
|
9305
|
-
* `join`, escape the root; a caller passing an untrusted ref (or an
|
|
9306
|
-
* untrusted runId, which prefixes checkpoint and workflow-source refs)
|
|
9307
|
-
* could read, write, or delete `.bin` files outside `dir`.
|
|
9408
|
+
* @param entries the journal of one run, in any order
|
|
9308
9409
|
*/
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9410
|
+
function criticalPathFromJournal(entries) {
|
|
9411
|
+
const ordered = [...entries].sort((a, b) => a.seq - b.seq);
|
|
9412
|
+
let runStart;
|
|
9413
|
+
let runEnd;
|
|
9414
|
+
let lastWorkerEnd;
|
|
9415
|
+
let workerSpans = 0;
|
|
9416
|
+
let unclassifiedSpans = 0;
|
|
9417
|
+
let synthesisMs = 0;
|
|
9418
|
+
let finalCompositionMs = 0;
|
|
9419
|
+
let semanticJudgeMs = 0;
|
|
9420
|
+
let labelledSynthesis = false;
|
|
9421
|
+
let unlabelledSynthesis = false;
|
|
9422
|
+
for (const entry of ordered) {
|
|
9423
|
+
const startedAt = parse$1(entry.startedAt);
|
|
9424
|
+
const endedAt = parse$1(entry.endedAt);
|
|
9425
|
+
if (startedAt !== void 0) runStart = runStart === void 0 ? startedAt : Math.min(runStart, startedAt);
|
|
9426
|
+
const last = endedAt ?? startedAt;
|
|
9427
|
+
if (last !== void 0) runEnd = runEnd === void 0 ? last : Math.max(runEnd, last);
|
|
9428
|
+
if (entry.kind !== "agent" || entry.status === "running" || entry.status === "suspended") continue;
|
|
9429
|
+
const role = entry.costAttribution?.role;
|
|
9430
|
+
if (role === void 0) {
|
|
9431
|
+
unclassifiedSpans += 1;
|
|
9432
|
+
continue;
|
|
9433
|
+
}
|
|
9434
|
+
if (role === "orchestrate") continue;
|
|
9435
|
+
if (role !== "synthesize") {
|
|
9436
|
+
workerSpans += 1;
|
|
9437
|
+
if (endedAt !== void 0) lastWorkerEnd = lastWorkerEnd === void 0 ? endedAt : Math.max(lastWorkerEnd, endedAt);
|
|
9438
|
+
continue;
|
|
9439
|
+
}
|
|
9440
|
+
if (startedAt === void 0 || endedAt === void 0) continue;
|
|
9441
|
+
const wall = Math.max(0, endedAt - startedAt);
|
|
9442
|
+
synthesisMs += wall;
|
|
9443
|
+
const label = entry.costAttribution?.label;
|
|
9444
|
+
if (label === void 0) {
|
|
9445
|
+
unlabelledSynthesis = true;
|
|
9446
|
+
continue;
|
|
9447
|
+
}
|
|
9448
|
+
labelledSynthesis = true;
|
|
9449
|
+
if (label === "claim-consistency-judge" || label.startsWith(`claim-consistency-judge-`)) semanticJudgeMs += wall;
|
|
9450
|
+
else finalCompositionMs += wall;
|
|
9314
9451
|
}
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
|
|
9452
|
+
const segments = logicalRunTelemetry(ordered).segments;
|
|
9453
|
+
const path = {
|
|
9454
|
+
workerSpans,
|
|
9455
|
+
synthesisMs,
|
|
9456
|
+
unclassifiedSpans,
|
|
9457
|
+
segments
|
|
9458
|
+
};
|
|
9459
|
+
if (labelledSynthesis && !unlabelledSynthesis) {
|
|
9460
|
+
path.finalCompositionMs = finalCompositionMs;
|
|
9461
|
+
path.semanticJudgeMs = semanticJudgeMs;
|
|
9462
|
+
}
|
|
9463
|
+
if (segments > 1 || runStart === void 0 || runEnd === void 0) return path;
|
|
9464
|
+
path.runWallMs = Math.max(0, runEnd - runStart);
|
|
9465
|
+
if (lastWorkerEnd !== void 0) path.postFanInMs = Math.max(0, runEnd - lastWorkerEnd);
|
|
9466
|
+
if (path.runWallMs > 0) {
|
|
9467
|
+
if (path.postFanInMs !== void 0) path.postFanInShare = path.postFanInMs / path.runWallMs;
|
|
9468
|
+
path.synthesisShare = synthesisMs / path.runWallMs;
|
|
9324
9469
|
}
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9470
|
+
return path;
|
|
9471
|
+
}
|
|
9472
|
+
//#endregion
|
|
9473
|
+
//#region src/stores/synthesis-candidates.ts
|
|
9474
|
+
const parse = (at) => {
|
|
9475
|
+
if (at === void 0) return;
|
|
9476
|
+
const ms = Date.parse(at);
|
|
9477
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
9478
|
+
};
|
|
9479
|
+
const VERDICTS = /* @__PURE__ */ new Set([
|
|
9480
|
+
"accepted",
|
|
9481
|
+
"repair",
|
|
9482
|
+
"rejected"
|
|
9483
|
+
]);
|
|
9484
|
+
const OPTIONAL_USAGE_KEYS = [
|
|
9485
|
+
"reasoningTokens",
|
|
9486
|
+
"cacheWrite5mTokens",
|
|
9487
|
+
"cacheWrite1hTokens"
|
|
9488
|
+
];
|
|
9489
|
+
function sumUsage$1(rows) {
|
|
9490
|
+
const total = {
|
|
9491
|
+
inputTokens: 0,
|
|
9492
|
+
outputTokens: 0,
|
|
9493
|
+
cacheReadTokens: 0,
|
|
9494
|
+
cacheWriteTokens: 0
|
|
9495
|
+
};
|
|
9496
|
+
for (const row of rows) {
|
|
9497
|
+
if (row.usage === void 0) continue;
|
|
9498
|
+
total.inputTokens += row.usage.inputTokens;
|
|
9499
|
+
total.outputTokens += row.usage.outputTokens;
|
|
9500
|
+
total.cacheReadTokens += row.usage.cacheReadTokens;
|
|
9501
|
+
total.cacheWriteTokens += row.usage.cacheWriteTokens;
|
|
9502
|
+
for (const key of OPTIONAL_USAGE_KEYS) {
|
|
9503
|
+
const share = row.usage[key];
|
|
9504
|
+
if (share !== void 0) total[key] = (total[key] ?? 0) + share;
|
|
9505
|
+
}
|
|
9506
|
+
}
|
|
9507
|
+
return total;
|
|
9508
|
+
}
|
|
9509
|
+
const usageUnknown = (row) => {
|
|
9510
|
+
if (row.outcome === "ok") return false;
|
|
9511
|
+
const usage = row.usage;
|
|
9512
|
+
if (usage === void 0) return true;
|
|
9513
|
+
return usage.inputTokens === 0 && usage.outputTokens === 0 && usage.cacheReadTokens === 0 && usage.cacheWriteTokens === 0 && (usage.reasoningTokens ?? 0) === 0;
|
|
9514
|
+
};
|
|
9515
|
+
/**
|
|
9516
|
+
* Fold the finish candidates (RV2902) out of a run's journal: each
|
|
9517
|
+
* journaled validation verdict with the window of wall, wires, usage,
|
|
9518
|
+
* and priced cost that produced the candidate it judged.
|
|
9519
|
+
*
|
|
9520
|
+
* @param entries the journal of one run, in any order
|
|
9521
|
+
* @param priceUsd prices one call's usage at its serving model, the
|
|
9522
|
+
* same shape `invoiceFromJournal` takes; omit to fold without money
|
|
9523
|
+
*/
|
|
9524
|
+
function synthesisCandidatesFromJournal(entries, priceUsd) {
|
|
9525
|
+
const ordered = [...entries].sort((a, b) => a.seq - b.seq);
|
|
9526
|
+
const spans = [];
|
|
9527
|
+
for (const entry of ordered) {
|
|
9528
|
+
if (entry.kind !== "agent" || entry.status === "running" || entry.status === "suspended" || entry.costAttribution?.role !== "synthesize" || typeof entry.ref !== "number") continue;
|
|
9529
|
+
spans.push({
|
|
9530
|
+
runningSeq: entry.ref,
|
|
9531
|
+
terminalSeq: entry.seq,
|
|
9532
|
+
startedAt: parse(entry.startedAt),
|
|
9533
|
+
...entry.costAttribution.label === void 0 ? {} : { label: entry.costAttribution.label },
|
|
9534
|
+
records: entry.providerCalls,
|
|
9535
|
+
wires: [],
|
|
9536
|
+
verdictSeqs: []
|
|
9537
|
+
});
|
|
9331
9538
|
}
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9539
|
+
const bySeqOpen = /* @__PURE__ */ new Map();
|
|
9540
|
+
for (const span of spans) bySeqOpen.set(span.runningSeq, span);
|
|
9541
|
+
const verdicts = [];
|
|
9542
|
+
for (const entry of ordered) {
|
|
9543
|
+
if (entry.kind !== "decision") continue;
|
|
9544
|
+
const value = entry.value;
|
|
9545
|
+
if (value === void 0) continue;
|
|
9546
|
+
if (value.decisionType === "provider-call") {
|
|
9547
|
+
const wire = value;
|
|
9548
|
+
if (typeof wire.agentRef !== "number") continue;
|
|
9549
|
+
const span = bySeqOpen.get(wire.agentRef);
|
|
9550
|
+
const record = wire.record;
|
|
9551
|
+
if (span === void 0 || record === void 0 || typeof record.ordinal !== "number") continue;
|
|
9552
|
+
span.wires.push({
|
|
9553
|
+
seq: entry.seq,
|
|
9554
|
+
ordinal: record.ordinal,
|
|
9555
|
+
...typeof record.servedBy === "string" ? { servedBy: record.servedBy } : {},
|
|
9556
|
+
outcome: typeof record.outcome === "string" ? record.outcome : "ok",
|
|
9557
|
+
...record.usage === void 0 ? {} : { usage: record.usage },
|
|
9558
|
+
wireRequests: typeof record.wireRequests === "number" ? record.wireRequests : 1
|
|
9559
|
+
});
|
|
9560
|
+
continue;
|
|
9561
|
+
}
|
|
9562
|
+
if (value.decisionType !== "orchestrator_finish_validation") continue;
|
|
9563
|
+
const verdictValue = value;
|
|
9564
|
+
if (typeof verdictValue.verdict !== "string" || !VERDICTS.has(verdictValue.verdict)) continue;
|
|
9565
|
+
let host;
|
|
9566
|
+
for (const span of spans) if (entry.seq > span.runningSeq && entry.seq < span.terminalSeq) {
|
|
9567
|
+
if (host === void 0 || span.runningSeq > host.runningSeq) host = span;
|
|
9338
9568
|
}
|
|
9569
|
+
if (host !== void 0) host.verdictSeqs.push(entry.seq);
|
|
9570
|
+
verdicts.push({
|
|
9571
|
+
seq: entry.seq,
|
|
9572
|
+
...entry.startedAt === void 0 ? {} : { at: entry.startedAt },
|
|
9573
|
+
value: verdictValue,
|
|
9574
|
+
...host === void 0 ? {} : { span: host }
|
|
9575
|
+
});
|
|
9339
9576
|
}
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
const
|
|
9344
|
-
const
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
else if (name.endsWith(TRANSCRIPT_SUFFIX)) refs.push(`${prefix}${name.slice(0, -4)}`);
|
|
9355
|
-
}
|
|
9356
|
-
};
|
|
9357
|
-
walk(root, `${runId}/`);
|
|
9358
|
-
return refs.sort();
|
|
9577
|
+
const attributable = /* @__PURE__ */ new Set();
|
|
9578
|
+
let unattributedSpans = 0;
|
|
9579
|
+
for (const span of spans) {
|
|
9580
|
+
const recorded = (span.records ?? []).map((record) => record.ordinal).sort((a, b) => a - b);
|
|
9581
|
+
const rows = [...span.wires].map((wire) => wire.ordinal).sort((a, b) => a - b);
|
|
9582
|
+
if (span.records !== void 0 && recorded.length === rows.length && recorded.every((ordinal, index) => ordinal === rows[index])) attributable.add(span);
|
|
9583
|
+
else unattributedSpans += 1;
|
|
9584
|
+
}
|
|
9585
|
+
let tailWires = 0;
|
|
9586
|
+
for (const span of spans) {
|
|
9587
|
+
if (!attributable.has(span)) continue;
|
|
9588
|
+
const lastVerdict = span.verdictSeqs.length === 0 ? void 0 : Math.max(...span.verdictSeqs);
|
|
9589
|
+
if (lastVerdict === void 0) continue;
|
|
9590
|
+
for (const wire of span.wires) if (wire.seq > lastVerdict) tailWires += wire.wireRequests;
|
|
9359
9591
|
}
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9592
|
+
const candidates = [];
|
|
9593
|
+
let unhostedVerdicts = 0;
|
|
9594
|
+
const previousBoundary = /* @__PURE__ */ new Map();
|
|
9595
|
+
for (const verdict of verdicts) {
|
|
9596
|
+
const value = verdict.value;
|
|
9597
|
+
if (verdict.span === void 0) {
|
|
9598
|
+
unhostedVerdicts += 1;
|
|
9599
|
+
continue;
|
|
9365
9600
|
}
|
|
9601
|
+
const span = verdict.span;
|
|
9602
|
+
const boundary = previousBoundary.get(span) ?? {
|
|
9603
|
+
seq: span.runningSeq,
|
|
9604
|
+
...span.startedAt === void 0 ? {} : { at: span.startedAt }
|
|
9605
|
+
};
|
|
9606
|
+
const verdictAtMs = parse(verdict.at);
|
|
9607
|
+
previousBoundary.set(span, {
|
|
9608
|
+
seq: verdict.seq,
|
|
9609
|
+
...verdictAtMs === void 0 ? {} : { at: verdictAtMs }
|
|
9610
|
+
});
|
|
9611
|
+
const candidate = {
|
|
9612
|
+
verdict: value.verdict,
|
|
9613
|
+
verdictSeq: verdict.seq,
|
|
9614
|
+
...verdict.at === void 0 ? {} : { verdictAt: verdict.at },
|
|
9615
|
+
...typeof value.callId === "string" ? { callId: value.callId } : {},
|
|
9616
|
+
...typeof value.repairsUsed === "number" ? { repairsUsed: value.repairsUsed } : {},
|
|
9617
|
+
...typeof value.maxRepairs === "number" ? { maxRepairs: value.maxRepairs } : {},
|
|
9618
|
+
...typeof value.contractHash === "string" ? { contractHash: value.contractHash } : {},
|
|
9619
|
+
...typeof value.candidateHash === "string" ? { candidateHash: value.candidateHash } : {},
|
|
9620
|
+
...typeof value.candidateChars === "number" ? { candidateChars: value.candidateChars } : {},
|
|
9621
|
+
...typeof value.candidateRef === "string" ? { candidateRef: value.candidateRef } : {},
|
|
9622
|
+
failed: Array.isArray(value.failed) ? value.failed.filter((failure) => typeof failure.name === "string").map((failure) => ({
|
|
9623
|
+
name: failure.name,
|
|
9624
|
+
reasons: Array.isArray(failure.reasons) ? failure.reasons.filter((reason) => typeof reason === "string") : []
|
|
9625
|
+
})) : [],
|
|
9626
|
+
...span.label === void 0 ? {} : { spanLabel: span.label }
|
|
9627
|
+
};
|
|
9628
|
+
if (boundary.at !== void 0 && verdictAtMs !== void 0) candidate.windowMs = Math.max(0, verdictAtMs - boundary.at);
|
|
9629
|
+
if (attributable.has(span)) {
|
|
9630
|
+
const window = span.wires.filter((wire) => wire.seq > boundary.seq && wire.seq < verdict.seq);
|
|
9631
|
+
candidate.wires = window.reduce((sum, wire) => sum + wire.wireRequests, 0);
|
|
9632
|
+
candidate.usage = sumUsage$1(window);
|
|
9633
|
+
const unknown = window.filter((wire) => usageUnknown(wire)).length;
|
|
9634
|
+
if (unknown > 0) candidate.usageUnknownWires = unknown;
|
|
9635
|
+
if (priceUsd !== void 0) {
|
|
9636
|
+
let priced = 0;
|
|
9637
|
+
let complete = true;
|
|
9638
|
+
for (const wire of window) {
|
|
9639
|
+
const usd = wire.servedBy === void 0 || wire.usage === void 0 ? void 0 : priceUsd(wire.servedBy, wire.usage);
|
|
9640
|
+
if (usd === void 0) {
|
|
9641
|
+
complete = false;
|
|
9642
|
+
break;
|
|
9643
|
+
}
|
|
9644
|
+
priced += usd;
|
|
9645
|
+
}
|
|
9646
|
+
if (complete) candidate.costUsd = priced;
|
|
9647
|
+
}
|
|
9648
|
+
}
|
|
9649
|
+
candidates.push(candidate);
|
|
9366
9650
|
}
|
|
9367
|
-
|
|
9651
|
+
return {
|
|
9652
|
+
candidates,
|
|
9653
|
+
synthesisSpans: spans.length,
|
|
9654
|
+
unhostedVerdicts,
|
|
9655
|
+
unattributedSpans,
|
|
9656
|
+
tailWires
|
|
9657
|
+
};
|
|
9658
|
+
}
|
|
9368
9659
|
//#endregion
|
|
9369
|
-
//#region src/
|
|
9660
|
+
//#region src/stores/jsonl.ts
|
|
9370
9661
|
/**
|
|
9371
|
-
*
|
|
9372
|
-
*
|
|
9373
|
-
*
|
|
9662
|
+
* JsonlFileStore (M2-T01): the durable file store. One JSON entry per
|
|
9663
|
+
* line per run; the journal doubles as an event log. Meta records live
|
|
9664
|
+
* beside the journal and are replaced atomically, so listRuns never
|
|
9665
|
+
* parses payloads.
|
|
9666
|
+
*
|
|
9667
|
+
* Contract (DEF-4 tightening):
|
|
9668
|
+
* - A1 atomicity: a torn trailing line (crash mid-append) is never
|
|
9669
|
+
* visible in load; the incomplete fragment is dropped and overwritten
|
|
9670
|
+
* by the next append. Whole records on that line are data, never
|
|
9671
|
+
* fragment (RV701): a crash that persisted every JSON byte but not
|
|
9672
|
+
* the '\n' leaves a parseable tail that load serves and append
|
|
9673
|
+
* terminates before writing, and repair salvages complete records a
|
|
9674
|
+
* glued line carries instead of discarding the line, so an entry a
|
|
9675
|
+
* load has served can never be un-served by a later repair.
|
|
9676
|
+
* - A2 total per-run order: load returns append order, stable across
|
|
9677
|
+
* calls (the kernel's per-run queue serializes appends).
|
|
9678
|
+
* - A3 read-your-writes: append resolves after the line is written.
|
|
9679
|
+
* - A4 opaque payload: entries round-trip byte-for-byte as JSON; unknown
|
|
9680
|
+
* kinds and fields pass through untouched.
|
|
9681
|
+
*
|
|
9682
|
+
* Leasing is NOT implemented here: LeasableStore ships with
|
|
9683
|
+
* @rulvar/store-sqlite (M5); JsonlFileStore is single-writer by
|
|
9684
|
+
* convention.
|
|
9374
9685
|
*/
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
let tier;
|
|
9381
|
-
for (const candidate of pricing.tiers ?? []) if (inputTokens > candidate.aboveInputTokens && (tier === void 0 || candidate.aboveInputTokens > tier.aboveInputTokens)) tier = candidate;
|
|
9382
|
-
return tier;
|
|
9686
|
+
const JOURNAL_SUFFIX = ".jsonl";
|
|
9687
|
+
const META_SUFFIX = ".meta.json";
|
|
9688
|
+
function safeName(runId) {
|
|
9689
|
+
if (!/^[A-Za-z0-9._-]+$/.test(runId)) throw new JournalOrderViolation(`JsonlFileStore: runId '${runId}' is not filesystem-safe ([A-Za-z0-9._-] only)`);
|
|
9690
|
+
return runId;
|
|
9383
9691
|
}
|
|
9384
9692
|
/**
|
|
9385
|
-
*
|
|
9386
|
-
*
|
|
9387
|
-
*
|
|
9388
|
-
*
|
|
9389
|
-
*
|
|
9390
|
-
*
|
|
9391
|
-
*
|
|
9392
|
-
* prompt re-prices the ENTIRE request (input-side rates scale by
|
|
9393
|
-
* inputMultiplier, the output rate by outputMultiplier). Cache writes
|
|
9394
|
-
* price at the 5m premium rate by default; when the usage carries the
|
|
9395
|
-
* TTL split (RV810: `cacheWrite5mTokens` and `cacheWrite1hTokens`,
|
|
9396
|
-
* filled by adapters whose provider distinguishes write TTLs), the 1h
|
|
9397
|
-
* share prices at `cacheWrite1hUsdPerMTok` (falling back to the plain
|
|
9398
|
-
* write rate when the row lacks it) and everything the 1h share does
|
|
9399
|
-
* not claim, the 5m share plus any unattributed remainder an upstream
|
|
9400
|
-
* invariant violation left, bills at the write rate, never silently
|
|
9401
|
-
* for free. The component's `tokens` stays the WHOLE
|
|
9402
|
-
* `cacheWriteTokens` either way, so statement reconciliation keys are
|
|
9403
|
-
* unchanged.
|
|
9693
|
+
* Whole JSON values glued on one line, split apart without parser
|
|
9694
|
+
* ambiguity (RV701): depth is tracked outside string literals only, and
|
|
9695
|
+
* every candidate must still round-trip JSON.parse. A line that is not a
|
|
9696
|
+
* clean concatenation from its first byte salvages its whole prefix
|
|
9697
|
+
* values and returns everything after them as the torn fragment, so the
|
|
9698
|
+
* caller keeps accepted records and drops exactly the unacknowledged
|
|
9699
|
+
* tail a crash tore.
|
|
9404
9700
|
*/
|
|
9405
|
-
function
|
|
9406
|
-
const
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
}
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
}
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
}
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9701
|
+
function splitConcatenatedJson(line) {
|
|
9702
|
+
const whole = [];
|
|
9703
|
+
let start = 0;
|
|
9704
|
+
let depth = 0;
|
|
9705
|
+
let inString = false;
|
|
9706
|
+
let escaped = false;
|
|
9707
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
9708
|
+
const ch = line[i];
|
|
9709
|
+
if (inString) {
|
|
9710
|
+
if (escaped) escaped = false;
|
|
9711
|
+
else if (ch === "\\") escaped = true;
|
|
9712
|
+
else if (ch === "\"") inString = false;
|
|
9713
|
+
continue;
|
|
9714
|
+
}
|
|
9715
|
+
if (ch === "\"") {
|
|
9716
|
+
inString = true;
|
|
9717
|
+
continue;
|
|
9718
|
+
}
|
|
9719
|
+
if (ch === "{" || ch === "[") {
|
|
9720
|
+
depth += 1;
|
|
9721
|
+
continue;
|
|
9722
|
+
}
|
|
9723
|
+
if (ch === "}" || ch === "]") {
|
|
9724
|
+
depth -= 1;
|
|
9725
|
+
if (depth < 0) return {
|
|
9726
|
+
whole,
|
|
9727
|
+
fragment: line.slice(start)
|
|
9728
|
+
};
|
|
9729
|
+
if (depth === 0) {
|
|
9730
|
+
const candidate = line.slice(start, i + 1);
|
|
9731
|
+
try {
|
|
9732
|
+
whole.push(JSON.parse(candidate));
|
|
9733
|
+
} catch {
|
|
9734
|
+
return {
|
|
9735
|
+
whole,
|
|
9736
|
+
fragment: line.slice(start)
|
|
9737
|
+
};
|
|
9738
|
+
}
|
|
9739
|
+
start = i + 1;
|
|
9740
|
+
}
|
|
9430
9741
|
}
|
|
9742
|
+
}
|
|
9743
|
+
return {
|
|
9744
|
+
whole,
|
|
9745
|
+
fragment: line.slice(start)
|
|
9431
9746
|
};
|
|
9432
9747
|
}
|
|
9748
|
+
var JsonlFileStore = class {
|
|
9749
|
+
dir;
|
|
9750
|
+
/**
|
|
9751
|
+
* The stored tail seq per run, lazily initialized from the file on the
|
|
9752
|
+
* first append this instance performs (obligation A5). Per instance by
|
|
9753
|
+
* design: cross-process writers are the lease seam's job.
|
|
9754
|
+
*/
|
|
9755
|
+
lastSeq = /* @__PURE__ */ new Map();
|
|
9756
|
+
/**
|
|
9757
|
+
* The verify-only load switch (RV1512): with `repairOnLoad: false`,
|
|
9758
|
+
* `load` serves the salvageable records WITHOUT rewriting the file,
|
|
9759
|
+
* so an auditor's "verification" read never destroys the evidence
|
|
9760
|
+
* of a tear it found. The default keeps the owner semantics byte
|
|
9761
|
+
* for byte: a torn tail repairs on load exactly as documented in
|
|
9762
|
+
* the A1 model above. Mutations (`append`, `putMeta`, `delete`)
|
|
9763
|
+
* are unaffected by the flag; an auditor that must not write simply
|
|
9764
|
+
* does not call them.
|
|
9765
|
+
*/
|
|
9766
|
+
repairOnLoad;
|
|
9767
|
+
constructor(options) {
|
|
9768
|
+
this.dir = options.dir;
|
|
9769
|
+
this.repairOnLoad = options.repairOnLoad !== false;
|
|
9770
|
+
mkdirSync(this.dir, { recursive: true });
|
|
9771
|
+
}
|
|
9772
|
+
journalPath(runId) {
|
|
9773
|
+
return join(this.dir, `${safeName(runId)}${JOURNAL_SUFFIX}`);
|
|
9774
|
+
}
|
|
9775
|
+
metaPath(runId) {
|
|
9776
|
+
return join(this.dir, `${safeName(runId)}${META_SUFFIX}`);
|
|
9777
|
+
}
|
|
9778
|
+
async append(runId, e) {
|
|
9779
|
+
let tail = this.lastSeq.get(runId);
|
|
9780
|
+
if (tail === void 0) {
|
|
9781
|
+
const existing = await this.load(runId);
|
|
9782
|
+
this.terminateUnterminatedTail(runId);
|
|
9783
|
+
const last = existing[existing.length - 1];
|
|
9784
|
+
tail = last !== void 0 && Number.isFinite(last.seq) ? last.seq : Number.NEGATIVE_INFINITY;
|
|
9785
|
+
this.lastSeq.set(runId, tail);
|
|
9786
|
+
}
|
|
9787
|
+
if (Number.isFinite(e.seq) && e.seq <= tail) throw new JournalOrderViolation(`JsonlFileStore: append of seq ${e.seq} to run '${runId}' is not after the stored tail seq ${tail}; a concurrent writer raced this journal from a stale tail`);
|
|
9788
|
+
appendFileSync(this.journalPath(runId), `${JSON.stringify(e)}\n`, "utf8");
|
|
9789
|
+
if (Number.isFinite(e.seq)) this.lastSeq.set(runId, e.seq);
|
|
9790
|
+
}
|
|
9791
|
+
async load(runId) {
|
|
9792
|
+
let raw;
|
|
9793
|
+
try {
|
|
9794
|
+
raw = readFileSync(this.journalPath(runId), "utf8");
|
|
9795
|
+
} catch (thrown) {
|
|
9796
|
+
if (thrown.code === "ENOENT") return [];
|
|
9797
|
+
throw thrown;
|
|
9798
|
+
}
|
|
9799
|
+
const lines = raw.split("\n");
|
|
9800
|
+
const entries = [];
|
|
9801
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
9802
|
+
const line = lines[i] ?? "";
|
|
9803
|
+
if (line === "") continue;
|
|
9804
|
+
try {
|
|
9805
|
+
entries.push(JSON.parse(line));
|
|
9806
|
+
} catch (thrown) {
|
|
9807
|
+
if (lines.slice(i + 1).every((rest) => rest === "")) {
|
|
9808
|
+
for (const value of splitConcatenatedJson(line).whole) entries.push(value);
|
|
9809
|
+
if (this.repairOnLoad) this.repairTornTail(runId, entries);
|
|
9810
|
+
break;
|
|
9811
|
+
}
|
|
9812
|
+
throw new JournalOrderViolation(`JsonlFileStore: corrupt journal line ${i + 1} of run '${runId}' (not the trailing line, so this is not a torn append)`, { cause: thrown });
|
|
9813
|
+
}
|
|
9814
|
+
}
|
|
9815
|
+
return entries;
|
|
9816
|
+
}
|
|
9817
|
+
/**
|
|
9818
|
+
* Restores the trailing '\n' of a parseable-but-unterminated tail
|
|
9819
|
+
* (RV701). One byte appended in place terminates the record exactly
|
|
9820
|
+
* where the crash left it; the file's bytes before it stay untouched.
|
|
9821
|
+
* No-op on a missing, empty, or already-terminated journal.
|
|
9822
|
+
*/
|
|
9823
|
+
terminateUnterminatedTail(runId) {
|
|
9824
|
+
const path = this.journalPath(runId);
|
|
9825
|
+
let fd;
|
|
9826
|
+
try {
|
|
9827
|
+
fd = openSync(path, "r");
|
|
9828
|
+
} catch (thrown) {
|
|
9829
|
+
if (thrown.code === "ENOENT") return;
|
|
9830
|
+
throw thrown;
|
|
9831
|
+
}
|
|
9832
|
+
let needsNewline = false;
|
|
9833
|
+
try {
|
|
9834
|
+
const size = fstatSync(fd).size;
|
|
9835
|
+
if (size > 0) {
|
|
9836
|
+
const lastByte = /* @__PURE__ */ new Uint8Array(1);
|
|
9837
|
+
readSync(fd, lastByte, 0, 1, size - 1);
|
|
9838
|
+
needsNewline = lastByte[0] !== 10;
|
|
9839
|
+
}
|
|
9840
|
+
} finally {
|
|
9841
|
+
closeSync(fd);
|
|
9842
|
+
}
|
|
9843
|
+
if (needsNewline) appendFileSync(path, "\n", "utf8");
|
|
9844
|
+
}
|
|
9845
|
+
repairTornTail(runId, whole) {
|
|
9846
|
+
const path = this.journalPath(runId);
|
|
9847
|
+
const temp = `${path}.tmp`;
|
|
9848
|
+
writeFileSync(temp, whole.map((entry) => JSON.stringify(entry)).join("\n") + (whole.length > 0 ? "\n" : ""), "utf8");
|
|
9849
|
+
renameSync(temp, path);
|
|
9850
|
+
}
|
|
9851
|
+
async putMeta(m) {
|
|
9852
|
+
const path = this.metaPath(m.runId);
|
|
9853
|
+
const temp = `${path}.tmp`;
|
|
9854
|
+
writeFileSync(temp, JSON.stringify(m, null, 2), "utf8");
|
|
9855
|
+
renameSync(temp, path);
|
|
9856
|
+
}
|
|
9857
|
+
async getMeta(runId) {
|
|
9858
|
+
try {
|
|
9859
|
+
return JSON.parse(readFileSync(this.metaPath(runId), "utf8"));
|
|
9860
|
+
} catch {
|
|
9861
|
+
return;
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
async listRuns(f) {
|
|
9865
|
+
const metas = [];
|
|
9866
|
+
for (const file of readdirSync(this.dir)) {
|
|
9867
|
+
if (!file.endsWith(META_SUFFIX)) continue;
|
|
9868
|
+
try {
|
|
9869
|
+
metas.push(JSON.parse(readFileSync(join(this.dir, file), "utf8")));
|
|
9870
|
+
} catch {}
|
|
9871
|
+
}
|
|
9872
|
+
return metas.filter((meta) => metaMatchesFilter(meta, f));
|
|
9873
|
+
}
|
|
9874
|
+
async delete(runId) {
|
|
9875
|
+
rmSync(this.journalPath(runId), { force: true });
|
|
9876
|
+
rmSync(this.metaPath(runId), { force: true });
|
|
9877
|
+
this.lastSeq.delete(runId);
|
|
9878
|
+
}
|
|
9879
|
+
};
|
|
9880
|
+
const TRANSCRIPT_SUFFIX = ".bin";
|
|
9433
9881
|
/**
|
|
9434
|
-
*
|
|
9435
|
-
*
|
|
9436
|
-
*
|
|
9437
|
-
*
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
*
|
|
9445
|
-
*
|
|
9446
|
-
* the same tier rules as settlement (the tier is selected by the
|
|
9447
|
-
* estimated prompt). Floored to whole tokens; zero or negative means not
|
|
9448
|
-
* even one output token fits, so the turn must not be dispatched.
|
|
9449
|
-
* Undefined when the row prices output at zero (a free model needs no
|
|
9450
|
-
* output bound).
|
|
9451
|
-
*/
|
|
9452
|
-
function affordableOutputTokens(pricing, remainingUsd, estimatedInputTokens) {
|
|
9453
|
-
const tier = tierFor(pricing, estimatedInputTokens);
|
|
9454
|
-
const outputRate = pricing.outputUsdPerMTok * (tier?.outputMultiplier ?? 1);
|
|
9455
|
-
if (outputRate <= 0) return;
|
|
9456
|
-
const inputUsd = priceUsdOf(pricing, {
|
|
9457
|
-
inputTokens: estimatedInputTokens,
|
|
9458
|
-
outputTokens: 0,
|
|
9459
|
-
cacheReadTokens: 0,
|
|
9460
|
-
cacheWriteTokens: 0
|
|
9461
|
-
});
|
|
9462
|
-
return Math.floor((remainingUsd - inputUsd) / outputRate * 1e6);
|
|
9463
|
-
}
|
|
9464
|
-
const RATE_FIELDS = [
|
|
9465
|
-
"inputUsdPerMTok",
|
|
9466
|
-
"outputUsdPerMTok",
|
|
9467
|
-
"cacheReadUsdPerMTok",
|
|
9468
|
-
"cacheWriteUsdPerMTok",
|
|
9469
|
-
"cacheWrite1hUsdPerMTok"
|
|
9470
|
-
];
|
|
9471
|
-
const TIER_FIELDS = [
|
|
9472
|
-
"aboveInputTokens",
|
|
9473
|
-
"inputMultiplier",
|
|
9474
|
-
"outputMultiplier"
|
|
9475
|
-
];
|
|
9476
|
-
/**
|
|
9477
|
-
* Compares a pricing seed against rates extracted from the provider's
|
|
9478
|
-
* documented pricing page, in BOTH directions (RV902): a seed rate the
|
|
9479
|
-
* page moved or dropped is a finding, and so is a documented billable
|
|
9480
|
-
* rate the seed never declared, because a billable column missing from
|
|
9481
|
-
* the seed is a silent underpricing channel (the 1h cache-write premium
|
|
9482
|
-
* hid exactly there). Declared long-context tiers compare field by
|
|
9483
|
-
* field. Returns human-readable findings, empty when the sides agree;
|
|
9484
|
-
* the weekly rates audit (scripts/rates-audit.mjs) runs this exact
|
|
9485
|
-
* comparator over the live pages, and the fault-injection kit drives it
|
|
9486
|
-
* as a permanent gate (RV909). It verifies DOCUMENTATION, not billing:
|
|
9487
|
-
* only a statement reconciliation over saved exports settles what the
|
|
9488
|
-
* provider's meter actually charges.
|
|
9882
|
+
* File-backed TranscriptStore (M6-T02): blobs (transcripts, checkpoints,
|
|
9883
|
+
* persisted CompiledWorkflow sources) as one file per ref under `dir`,
|
|
9884
|
+
* so compiled runs resume across processes. Refs follow the
|
|
9885
|
+
* `<runId>/<name>` convention; nested segments become directories.
|
|
9886
|
+
*
|
|
9887
|
+
* Every ref is contained under `dir` (v1.36.0 review SEC-P1): each
|
|
9888
|
+
* segment must match `[A-Za-z0-9._-]` and be neither empty, '.', nor
|
|
9889
|
+
* '..', and the resolved path must stay under the resolved root. A '..'
|
|
9890
|
+
* segment used to pass the per-segment alphabet (dots are in it) and, via
|
|
9891
|
+
* `join`, escape the root; a caller passing an untrusted ref (or an
|
|
9892
|
+
* untrusted runId, which prefixes checkpoint and workflow-source refs)
|
|
9893
|
+
* could read, write, or delete `.bin` files outside `dir`.
|
|
9489
9894
|
*/
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9895
|
+
var FileTranscriptStore = class {
|
|
9896
|
+
dir;
|
|
9897
|
+
constructor(options) {
|
|
9898
|
+
this.dir = options.dir;
|
|
9899
|
+
mkdirSync(this.dir, { recursive: true });
|
|
9900
|
+
}
|
|
9901
|
+
blobPath(ref) {
|
|
9902
|
+
const segments = ref.split("/");
|
|
9903
|
+
for (const segment of segments) if (segment === "" || segment === "." || segment === ".." || !/^[A-Za-z0-9._-]+$/.test(segment)) throw new JournalOrderViolation(`FileTranscriptStore: ref segment '${segment}' is not filesystem-safe`);
|
|
9904
|
+
const name = segments.pop() ?? "";
|
|
9905
|
+
const path = join(this.dir, ...segments, `${name}${TRANSCRIPT_SUFFIX}`);
|
|
9906
|
+
const root = resolve(this.dir);
|
|
9907
|
+
const resolved = resolve(path);
|
|
9908
|
+
if (resolved !== root && !resolved.startsWith(`${root}${sep}`)) throw new JournalOrderViolation(`FileTranscriptStore: ref '${ref}' resolves outside the configured root`);
|
|
9909
|
+
return path;
|
|
9910
|
+
}
|
|
9911
|
+
async put(ref, blob) {
|
|
9912
|
+
const path = this.blobPath(ref);
|
|
9913
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
9914
|
+
const temp = `${path}.tmp`;
|
|
9915
|
+
writeFileSync(temp, blob);
|
|
9916
|
+
renameSync(temp, path);
|
|
9917
|
+
}
|
|
9918
|
+
async get(ref) {
|
|
9919
|
+
try {
|
|
9920
|
+
return new Uint8Array(readFileSync(this.blobPath(ref)));
|
|
9921
|
+
} catch (error) {
|
|
9922
|
+
if (error.code === "ENOENT") return null;
|
|
9923
|
+
throw error;
|
|
9498
9924
|
}
|
|
9499
|
-
if (pageValue === void 0) findings.push(`${field}: seed ${String(seedValue)} but the page shows no such rate`);
|
|
9500
|
-
else if (!(Math.abs(seedValue - pageValue) <= 1e-9)) findings.push(`${field}: seed ${String(seedValue)} vs page ${String(pageValue)}`);
|
|
9501
9925
|
}
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9926
|
+
async list(runId) {
|
|
9927
|
+
if (runId === "." || runId === "..") throw new JournalOrderViolation(`FileTranscriptStore: runId '${runId}' is not filesystem-safe`);
|
|
9928
|
+
const root = join(this.dir, safeName(runId));
|
|
9929
|
+
const refs = [];
|
|
9930
|
+
const walk = (dir, prefix) => {
|
|
9931
|
+
let names;
|
|
9932
|
+
try {
|
|
9933
|
+
names = readdirSync(dir);
|
|
9934
|
+
} catch {
|
|
9935
|
+
return;
|
|
9936
|
+
}
|
|
9937
|
+
for (const name of names) {
|
|
9938
|
+
const path = join(dir, name);
|
|
9939
|
+
if (statSync(path).isDirectory()) walk(path, `${prefix}${name}/`);
|
|
9940
|
+
else if (name.endsWith(TRANSCRIPT_SUFFIX)) refs.push(`${prefix}${name.slice(0, -4)}`);
|
|
9941
|
+
}
|
|
9942
|
+
};
|
|
9943
|
+
walk(root, `${runId}/`);
|
|
9944
|
+
return refs.sort();
|
|
9511
9945
|
}
|
|
9512
|
-
|
|
9513
|
-
|
|
9946
|
+
async delete(ref) {
|
|
9947
|
+
try {
|
|
9948
|
+
rmSync(this.blobPath(ref));
|
|
9949
|
+
} catch (error) {
|
|
9950
|
+
if (error.code !== "ENOENT") throw error;
|
|
9951
|
+
}
|
|
9952
|
+
}
|
|
9953
|
+
};
|
|
9514
9954
|
//#endregion
|
|
9515
|
-
//#region src/model/
|
|
9955
|
+
//#region src/model/pricing.ts
|
|
9516
9956
|
/**
|
|
9517
|
-
*
|
|
9518
|
-
*
|
|
9519
|
-
* (
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9957
|
+
* Resolves the pricing for a model: the versioned table wins; the
|
|
9958
|
+
* adapter-reported caps.pricing is the fallback; undefined means
|
|
9959
|
+
* unpriced (the CostReport surfaces it, never a silent zero).
|
|
9960
|
+
*/
|
|
9961
|
+
function resolvePricing(ref, table, capsPricing) {
|
|
9962
|
+
return table?.models[ref] ?? capsPricing;
|
|
9963
|
+
}
|
|
9964
|
+
/** The tier a full prompt lands in: the highest threshold strictly below it. */
|
|
9965
|
+
function tierFor(pricing, inputTokens) {
|
|
9966
|
+
let tier;
|
|
9967
|
+
for (const candidate of pricing.tiers ?? []) if (inputTokens > candidate.aboveInputTokens && (tier === void 0 || candidate.aboveInputTokens > tier.aboveInputTokens)) tier = candidate;
|
|
9968
|
+
return tier;
|
|
9969
|
+
}
|
|
9970
|
+
/**
|
|
9971
|
+
* Decomposes one usage against one pricing row into the four billing
|
|
9972
|
+
* components. Under the Usage invariant inputTokens is the FULL prompt
|
|
9973
|
+
* including cache reads and writes, so the input rate bills only the
|
|
9974
|
+
* uncached remainder and cache tokens bill at their own rates, never
|
|
9975
|
+
* twice; a row that omits a cache rate bills those tokens at the plain
|
|
9976
|
+
* input rate rather than silently for free. A row may carry
|
|
9977
|
+
* long-context tiers: the highest threshold strictly below the full
|
|
9978
|
+
* prompt re-prices the ENTIRE request (input-side rates scale by
|
|
9979
|
+
* inputMultiplier, the output rate by outputMultiplier). Cache writes
|
|
9980
|
+
* price at the 5m premium rate by default; when the usage carries the
|
|
9981
|
+
* TTL split (RV810: `cacheWrite5mTokens` and `cacheWrite1hTokens`,
|
|
9982
|
+
* filled by adapters whose provider distinguishes write TTLs), the 1h
|
|
9983
|
+
* share prices at `cacheWrite1hUsdPerMTok` (falling back to the plain
|
|
9984
|
+
* write rate when the row lacks it) and everything the 1h share does
|
|
9985
|
+
* not claim, the 5m share plus any unattributed remainder an upstream
|
|
9986
|
+
* invariant violation left, bills at the write rate, never silently
|
|
9987
|
+
* for free. The component's `tokens` stays the WHOLE
|
|
9988
|
+
* `cacheWriteTokens` either way, so statement reconciliation keys are
|
|
9989
|
+
* unchanged.
|
|
9990
|
+
*/
|
|
9991
|
+
function priceComponentsOf(pricing, usage) {
|
|
9992
|
+
const tier = tierFor(pricing, usage.inputTokens);
|
|
9993
|
+
const inputMul = tier?.inputMultiplier ?? 1;
|
|
9994
|
+
const outputMul = tier?.outputMultiplier ?? 1;
|
|
9995
|
+
const uncachedInputTokens = Math.max(0, usage.inputTokens - usage.cacheReadTokens - usage.cacheWriteTokens);
|
|
9996
|
+
const writeRate = pricing.cacheWriteUsdPerMTok ?? pricing.inputUsdPerMTok;
|
|
9997
|
+
const write1hRate = pricing.cacheWrite1hUsdPerMTok ?? writeRate;
|
|
9998
|
+
const write1hTokens = usage.cacheWrite5mTokens !== void 0 || usage.cacheWrite1hTokens !== void 0 ? usage.cacheWrite1hTokens ?? 0 : 0;
|
|
9999
|
+
const writeDefaultTokens = Math.max(0, usage.cacheWriteTokens - write1hTokens);
|
|
10000
|
+
return {
|
|
10001
|
+
input: {
|
|
10002
|
+
tokens: uncachedInputTokens,
|
|
10003
|
+
usd: uncachedInputTokens / 1e6 * pricing.inputUsdPerMTok * inputMul
|
|
10004
|
+
},
|
|
10005
|
+
output: {
|
|
10006
|
+
tokens: usage.outputTokens,
|
|
10007
|
+
usd: usage.outputTokens / 1e6 * pricing.outputUsdPerMTok * outputMul
|
|
10008
|
+
},
|
|
10009
|
+
cachedInput: {
|
|
10010
|
+
tokens: usage.cacheReadTokens,
|
|
10011
|
+
usd: usage.cacheReadTokens / 1e6 * (pricing.cacheReadUsdPerMTok ?? pricing.inputUsdPerMTok) * inputMul
|
|
10012
|
+
},
|
|
10013
|
+
cacheWrite: {
|
|
10014
|
+
tokens: usage.cacheWriteTokens,
|
|
10015
|
+
usd: (writeDefaultTokens / 1e6 * writeRate + write1hTokens / 1e6 * write1hRate) * inputMul
|
|
10016
|
+
}
|
|
10017
|
+
};
|
|
10018
|
+
}
|
|
10019
|
+
/**
|
|
10020
|
+
* Dollars from normalized usage against one pricing row: the sum of the
|
|
10021
|
+
* {@link priceComponentsOf} terms in their declared order, byte for
|
|
10022
|
+
* byte the historical expression (uncached input, output, cached input,
|
|
10023
|
+
* cache writes).
|
|
10024
|
+
*/
|
|
10025
|
+
function priceUsdOf(pricing, usage) {
|
|
10026
|
+
const parts = priceComponentsOf(pricing, usage);
|
|
10027
|
+
return parts.input.usd + parts.output.usd + parts.cachedInput.usd + parts.cacheWrite.usd;
|
|
10028
|
+
}
|
|
10029
|
+
/**
|
|
10030
|
+
* The output tokens `remainingUsd` still buys from one pricing row after
|
|
10031
|
+
* paying for an estimated prompt of `estimatedInputTokens`, priced with
|
|
10032
|
+
* the same tier rules as settlement (the tier is selected by the
|
|
10033
|
+
* estimated prompt). Floored to whole tokens; zero or negative means not
|
|
10034
|
+
* even one output token fits, so the turn must not be dispatched.
|
|
10035
|
+
* Undefined when the row prices output at zero (a free model needs no
|
|
10036
|
+
* output bound).
|
|
10037
|
+
*/
|
|
10038
|
+
function affordableOutputTokens(pricing, remainingUsd, estimatedInputTokens) {
|
|
10039
|
+
const tier = tierFor(pricing, estimatedInputTokens);
|
|
10040
|
+
const outputRate = pricing.outputUsdPerMTok * (tier?.outputMultiplier ?? 1);
|
|
10041
|
+
if (outputRate <= 0) return;
|
|
10042
|
+
const inputUsd = priceUsdOf(pricing, {
|
|
10043
|
+
inputTokens: estimatedInputTokens,
|
|
10044
|
+
outputTokens: 0,
|
|
10045
|
+
cacheReadTokens: 0,
|
|
10046
|
+
cacheWriteTokens: 0
|
|
10047
|
+
});
|
|
10048
|
+
return Math.floor((remainingUsd - inputUsd) / outputRate * 1e6);
|
|
10049
|
+
}
|
|
10050
|
+
const RATE_FIELDS = [
|
|
10051
|
+
"inputUsdPerMTok",
|
|
10052
|
+
"outputUsdPerMTok",
|
|
10053
|
+
"cacheReadUsdPerMTok",
|
|
10054
|
+
"cacheWriteUsdPerMTok",
|
|
10055
|
+
"cacheWrite1hUsdPerMTok"
|
|
10056
|
+
];
|
|
10057
|
+
const TIER_FIELDS = [
|
|
10058
|
+
"aboveInputTokens",
|
|
10059
|
+
"inputMultiplier",
|
|
10060
|
+
"outputMultiplier"
|
|
10061
|
+
];
|
|
10062
|
+
/**
|
|
10063
|
+
* Compares a pricing seed against rates extracted from the provider's
|
|
10064
|
+
* documented pricing page, in BOTH directions (RV902): a seed rate the
|
|
10065
|
+
* page moved or dropped is a finding, and so is a documented billable
|
|
10066
|
+
* rate the seed never declared, because a billable column missing from
|
|
10067
|
+
* the seed is a silent underpricing channel (the 1h cache-write premium
|
|
10068
|
+
* hid exactly there). Declared long-context tiers compare field by
|
|
10069
|
+
* field. Returns human-readable findings, empty when the sides agree;
|
|
10070
|
+
* the weekly rates audit (scripts/rates-audit.mjs) runs this exact
|
|
10071
|
+
* comparator over the live pages, and the fault-injection kit drives it
|
|
10072
|
+
* as a permanent gate (RV909). It verifies DOCUMENTATION, not billing:
|
|
10073
|
+
* only a statement reconciliation over saved exports settles what the
|
|
10074
|
+
* provider's meter actually charges.
|
|
10075
|
+
*/
|
|
10076
|
+
function compareRates(seed, page) {
|
|
10077
|
+
const findings = [];
|
|
10078
|
+
for (const field of RATE_FIELDS) {
|
|
10079
|
+
const seedValue = seed[field];
|
|
10080
|
+
const pageValue = page[field];
|
|
10081
|
+
if (seedValue === void 0) {
|
|
10082
|
+
if (pageValue !== void 0) findings.push(`${field}: the page shows ${String(pageValue)} but the seed declares no such rate`);
|
|
10083
|
+
continue;
|
|
10084
|
+
}
|
|
10085
|
+
if (pageValue === void 0) findings.push(`${field}: seed ${String(seedValue)} but the page shows no such rate`);
|
|
10086
|
+
else if (!(Math.abs(seedValue - pageValue) <= 1e-9)) findings.push(`${field}: seed ${String(seedValue)} vs page ${String(pageValue)}`);
|
|
10087
|
+
}
|
|
10088
|
+
const seedTiers = seed.tiers;
|
|
10089
|
+
const pageTiers = page.tiers;
|
|
10090
|
+
if (!Array.isArray(seedTiers)) {
|
|
10091
|
+
if (Array.isArray(pageTiers) && pageTiers.length > 0) findings.push(`tiers: the page shows ${String(pageTiers.length)} but the seed declares none`);
|
|
10092
|
+
} else if (!Array.isArray(pageTiers) || pageTiers.length !== seedTiers.length) findings.push(`tiers: seed declares ${String(seedTiers.length)}, page shows ${Array.isArray(pageTiers) ? String(pageTiers.length) : "none"}`);
|
|
10093
|
+
else for (let i = 0; i < seedTiers.length; i += 1) for (const field of TIER_FIELDS) {
|
|
10094
|
+
const seedValue = seedTiers[i]?.[field] ?? NaN;
|
|
10095
|
+
const pageValue = pageTiers[i]?.[field] ?? NaN;
|
|
10096
|
+
if (!(Math.abs(seedValue - pageValue) <= 1e-9)) findings.push(`tiers[${String(i)}].${field}: seed ${String(seedValue)} vs page ${String(pageValue)}`);
|
|
10097
|
+
}
|
|
10098
|
+
return findings;
|
|
10099
|
+
}
|
|
10100
|
+
//#endregion
|
|
10101
|
+
//#region src/model/quota.ts
|
|
10102
|
+
/**
|
|
10103
|
+
* Quota rules and the in-process reference QuotaLimiter (RV-215).
|
|
10104
|
+
* The rule model is shared by every reference implementation
|
|
10105
|
+
* (memoryQuotaLimiter here, SqliteQuotaLimiter in
|
|
10106
|
+
* @rulvar/store-sqlite): fixed one-minute windows aligned to the
|
|
10107
|
+
* epoch, admission at reservation time, reconciliation to actual
|
|
10108
|
+
* usage inside the same window. The hard guarantee is on
|
|
9523
10109
|
* `requestsPerMinute` (every wire attempt is exactly one request);
|
|
9524
10110
|
* `tokensPerMinute` admits on the heuristic estimate and settles to
|
|
9525
10111
|
* actual usage, so token windows are approximate at admission and
|
|
@@ -15743,6 +16329,94 @@ function statementFromRows(input) {
|
|
|
15743
16329
|
})
|
|
15744
16330
|
};
|
|
15745
16331
|
}
|
|
16332
|
+
/**
|
|
16333
|
+
* Parses a delimited billing export (the CSV/TSV a provider console
|
|
16334
|
+
* hands a host) into the header-keyed rows {@link statementFromRows}
|
|
16335
|
+
* consumes (RV2908). The library deliberately hard-codes NO provider's
|
|
16336
|
+
* export format: the host owns the column map, this owns only the
|
|
16337
|
+
* delimited grammar, and the pair closes the last manual step between
|
|
16338
|
+
* a downloaded export and {@link reconcileStatement}.
|
|
16339
|
+
*
|
|
16340
|
+
* Fail-closed at the record, like the rest of this module: a data row
|
|
16341
|
+
* whose cell count differs from the header, a quote opened and never
|
|
16342
|
+
* closed, a stray quote inside an unquoted cell, an empty or duplicate
|
|
16343
|
+
* header name, all refuse typed with the line instead of flowing a
|
|
16344
|
+
* shifted column into a reconciliation, because a column shifted one
|
|
16345
|
+
* to the left prices `outputTokens` as dollars and calls it evidence.
|
|
16346
|
+
* RFC 4180 quoting is honored (quoted cells may carry the delimiter,
|
|
16347
|
+
* doubled quotes, and line breaks); CRLF and lone LF both delimit
|
|
16348
|
+
* records; one trailing empty line is an artifact of every exporter
|
|
16349
|
+
* and is ignored. Cells come back as raw strings, so an empty cell
|
|
16350
|
+
* reads as "the export does not carry this figure" downstream, exactly
|
|
16351
|
+
* the absence contract `statementFromRows` documents.
|
|
16352
|
+
*/
|
|
16353
|
+
function statementRowsFromDelimited(text, options) {
|
|
16354
|
+
const delimiter = options?.delimiter ?? ",";
|
|
16355
|
+
const records = [];
|
|
16356
|
+
let cells = [];
|
|
16357
|
+
let cell = "";
|
|
16358
|
+
let quoted = false;
|
|
16359
|
+
let cellHadQuote = false;
|
|
16360
|
+
let line = 1;
|
|
16361
|
+
const endCell = () => {
|
|
16362
|
+
cells.push(cell);
|
|
16363
|
+
cell = "";
|
|
16364
|
+
cellHadQuote = false;
|
|
16365
|
+
};
|
|
16366
|
+
const endRecord = () => {
|
|
16367
|
+
endCell();
|
|
16368
|
+
records.push(cells);
|
|
16369
|
+
cells = [];
|
|
16370
|
+
};
|
|
16371
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
16372
|
+
const char = text[index];
|
|
16373
|
+
if (quoted) {
|
|
16374
|
+
if (char === "\"") {
|
|
16375
|
+
if (text[index + 1] === "\"") {
|
|
16376
|
+
cell += "\"";
|
|
16377
|
+
index += 1;
|
|
16378
|
+
continue;
|
|
16379
|
+
}
|
|
16380
|
+
quoted = false;
|
|
16381
|
+
continue;
|
|
16382
|
+
}
|
|
16383
|
+
if (char === "\n") line += 1;
|
|
16384
|
+
cell += char;
|
|
16385
|
+
continue;
|
|
16386
|
+
}
|
|
16387
|
+
if (char === "\"") {
|
|
16388
|
+
if (cell.length > 0 || cellHadQuote) throw new ConfigError(`statementRowsFromDelimited: line ${String(line)} carries a quote inside an unquoted cell; quote the whole cell (RFC 4180) or fix the export`);
|
|
16389
|
+
quoted = true;
|
|
16390
|
+
cellHadQuote = true;
|
|
16391
|
+
continue;
|
|
16392
|
+
}
|
|
16393
|
+
if (char === delimiter) {
|
|
16394
|
+
endCell();
|
|
16395
|
+
continue;
|
|
16396
|
+
}
|
|
16397
|
+
if (char === "\r" && text[index + 1] === "\n") continue;
|
|
16398
|
+
if (char === "\n") {
|
|
16399
|
+
endRecord();
|
|
16400
|
+
line += 1;
|
|
16401
|
+
continue;
|
|
16402
|
+
}
|
|
16403
|
+
cell += char;
|
|
16404
|
+
}
|
|
16405
|
+
if (quoted) throw new ConfigError(`statementRowsFromDelimited: a quoted cell opened on line ${String(line)} never closes; the export is torn`);
|
|
16406
|
+
if (cell.length > 0 || cellHadQuote || cells.length > 0) endRecord();
|
|
16407
|
+
if (records.length === 0) throw new ConfigError("statementRowsFromDelimited: the export carries no header record");
|
|
16408
|
+
const header = records[0];
|
|
16409
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16410
|
+
header.forEach((name, index) => {
|
|
16411
|
+
if (name.length === 0) throw new ConfigError(`statementRowsFromDelimited: header column ${String(index)} is empty; every column needs a name for the map to address`);
|
|
16412
|
+
if (seen.has(name)) throw new ConfigError(`statementRowsFromDelimited: header names column '${name}' twice; an ambiguous address cannot be mapped`);
|
|
16413
|
+
seen.add(name);
|
|
16414
|
+
});
|
|
16415
|
+
return records.slice(1).map((record, index) => {
|
|
16416
|
+
if (record.length !== header.length) throw new ConfigError(`statementRowsFromDelimited: data record ${String(index)} carries ${String(record.length)} cell(s) against ${String(header.length)} header column(s); a shifted column prices the wrong figure, so a ragged export refuses instead`);
|
|
16417
|
+
return Object.fromEntries(header.map((name, column) => [name, record[column]]));
|
|
16418
|
+
});
|
|
16419
|
+
}
|
|
15746
16420
|
//#endregion
|
|
15747
16421
|
//#region src/engine/persisted-terminal.ts
|
|
15748
16422
|
const REFUSAL_MESSAGES = {
|
|
@@ -16488,484 +17162,196 @@ var AdmissionController = class {
|
|
|
16488
17162
|
depth,
|
|
16489
17163
|
...evaluated.statsBefore === void 0 ? {} : { lineage: evaluated.statsBefore }
|
|
16490
17164
|
};
|
|
16491
|
-
if (evaluated.decision.kind === "reject") return {
|
|
16492
|
-
verdict: {
|
|
16493
|
-
kind: "reject",
|
|
16494
|
-
reason: evaluated.decision.reason
|
|
16495
|
-
},
|
|
16496
|
-
statsBefore
|
|
16497
|
-
};
|
|
16498
|
-
if (this.terminationAccount !== void 0) {
|
|
16499
|
-
if ((spec.ladderLength ?? 1) > this.terminationAccount.limits.kMax) return {
|
|
16500
|
-
verdict: {
|
|
16501
|
-
kind: "reject",
|
|
16502
|
-
reason: { code: "ladder_exceeds_frozen" }
|
|
16503
|
-
},
|
|
16504
|
-
statsBefore
|
|
16505
|
-
};
|
|
16506
|
-
if (this.terminationAccount.spawnUnitsExhausted) return {
|
|
16507
|
-
verdict: {
|
|
16508
|
-
kind: "reject",
|
|
16509
|
-
reason: { code: "termination_exhausted" }
|
|
16510
|
-
},
|
|
16511
|
-
statsBefore
|
|
16512
|
-
};
|
|
16513
|
-
}
|
|
16514
|
-
if (depth > this.maxDepth) return {
|
|
16515
|
-
verdict: {
|
|
16516
|
-
kind: "reject",
|
|
16517
|
-
reason: { code: "depth" }
|
|
16518
|
-
},
|
|
16519
|
-
statsBefore
|
|
16520
|
-
};
|
|
16521
|
-
if (childrenBefore >= this.maxChildrenPerNode) return {
|
|
16522
|
-
verdict: {
|
|
16523
|
-
kind: "reject",
|
|
16524
|
-
reason: { code: "quota" }
|
|
16525
|
-
},
|
|
16526
|
-
statsBefore
|
|
16527
|
-
};
|
|
16528
|
-
if (this.maxTotalSpawns !== void 0 && this.admittedTotal >= this.maxTotalSpawns) return {
|
|
16529
|
-
verdict: {
|
|
16530
|
-
kind: "reject",
|
|
16531
|
-
reason: { code: "lifetime" }
|
|
16532
|
-
},
|
|
16533
|
-
statsBefore
|
|
16534
|
-
};
|
|
16535
|
-
if (spec.roster !== void 0) {
|
|
16536
|
-
const seatsRemaining = spec.roster.floor - spec.roster.admittedChildren;
|
|
16537
|
-
if (seatsRemaining > 0) {
|
|
16538
|
-
const perSeatProjectionUsd = this.projectedDispatchReserveUsd(spec);
|
|
16539
|
-
const remainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
16540
|
-
if (remainder !== void 0 && remainder < seatsRemaining * perSeatProjectionUsd + spec.roster.liveExposureUsd) return {
|
|
16541
|
-
verdict: {
|
|
16542
|
-
kind: "reject",
|
|
16543
|
-
reason: {
|
|
16544
|
-
code: "roster_floor",
|
|
16545
|
-
floor: spec.roster.floor,
|
|
16546
|
-
admittedChildren: spec.roster.admittedChildren,
|
|
16547
|
-
seatsRemaining,
|
|
16548
|
-
perSeatProjectionUsd,
|
|
16549
|
-
liveExposureUsd: spec.roster.liveExposureUsd,
|
|
16550
|
-
remainderUsd: remainder
|
|
16551
|
-
}
|
|
16552
|
-
},
|
|
16553
|
-
statsBefore
|
|
16554
|
-
};
|
|
16555
|
-
}
|
|
16556
|
-
}
|
|
16557
|
-
const spawnToolOrigin = spec.origin === "spawn_agent" || spec.origin === "parallel_agents";
|
|
16558
|
-
let childCeilingUsd;
|
|
16559
|
-
const parentRemainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
16560
|
-
if (spawnToolOrigin) {
|
|
16561
|
-
if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
16562
|
-
} else if (parentRemainder !== void 0) {
|
|
16563
|
-
const fractionCap = this.childBudgetFraction * parentRemainder;
|
|
16564
|
-
childCeilingUsd = spec.budgetUsd === void 0 ? fractionCap : Math.min(spec.budgetUsd, fractionCap);
|
|
16565
|
-
} else if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
16566
|
-
let reserveUsd = spec.estCostUsd ?? this.flatReserveUsd;
|
|
16567
|
-
const source = spec.estCostUsd === void 0 ? "default" : "estCost";
|
|
16568
|
-
let clampedBy;
|
|
16569
|
-
if (childCeilingUsd !== void 0 && reserveUsd > childCeilingUsd) {
|
|
16570
|
-
clampedBy = spec.budgetUsd !== void 0 && childCeilingUsd === spec.budgetUsd ? "explicit-budget" : "fraction-ceiling";
|
|
16571
|
-
reserveUsd = childCeilingUsd;
|
|
16572
|
-
}
|
|
16573
|
-
const reserve = {
|
|
16574
|
-
reserveUsd,
|
|
16575
|
-
source
|
|
16576
|
-
};
|
|
16577
|
-
if (clampedBy !== void 0) reserve.clampedBy = clampedBy;
|
|
16578
|
-
if (childCeilingUsd !== void 0) reserve.childCeilingUsd = childCeilingUsd;
|
|
16579
|
-
if (this.budget.spawnHeadroom <= 0) return {
|
|
16580
|
-
verdict: {
|
|
16581
|
-
kind: "reject",
|
|
16582
|
-
reason: { code: "lifetime" }
|
|
16583
|
-
},
|
|
16584
|
-
statsBefore
|
|
16585
|
-
};
|
|
16586
|
-
if (commitReserve) try {
|
|
16587
|
-
this.budget.admitSpawn(reserveUsd, spec.parentAccountScope);
|
|
16588
|
-
} catch {
|
|
16589
|
-
return {
|
|
16590
|
-
verdict: {
|
|
16591
|
-
kind: "reject",
|
|
16592
|
-
reason: { code: "budget" }
|
|
16593
|
-
},
|
|
16594
|
-
statsBefore
|
|
16595
|
-
};
|
|
16596
|
-
}
|
|
16597
|
-
else {
|
|
16598
|
-
const remainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
16599
|
-
const projection = this.projectedDispatchReserveUsd(spec);
|
|
16600
|
-
if (remainder !== void 0 && (remainder <= 0 || remainder < projection + (spec.pendingReserveUsd ?? 0))) return {
|
|
16601
|
-
verdict: {
|
|
16602
|
-
kind: "reject",
|
|
16603
|
-
reason: { code: "budget" }
|
|
16604
|
-
},
|
|
16605
|
-
statsBefore
|
|
16606
|
-
};
|
|
16607
|
-
}
|
|
16608
|
-
this.childrenOf.set(nodeKey, childrenBefore + 1);
|
|
16609
|
-
this.admittedTotal += 1;
|
|
16610
|
-
const lineage = evaluated.decision.lineage;
|
|
16611
|
-
this.registerLineageAdmit(lineage.logicalTaskId);
|
|
16612
|
-
let spawnUnitsAfter = this.budget.spawnHeadroom;
|
|
16613
|
-
if (this.terminationAccount !== void 0) {
|
|
16614
|
-
const debited = this.terminationAccount.debitSpawn({
|
|
16615
|
-
logicalTaskId: lineage.logicalTaskId,
|
|
16616
|
-
isNew: spec.lineage === void 0,
|
|
16617
|
-
ladderLength: spec.ladderLength ?? 1
|
|
16618
|
-
});
|
|
16619
|
-
if (!debited.ok) return {
|
|
16620
|
-
verdict: {
|
|
16621
|
-
kind: "reject",
|
|
16622
|
-
reason: { code: "termination_exhausted" }
|
|
16623
|
-
},
|
|
16624
|
-
statsBefore
|
|
16625
|
-
};
|
|
16626
|
-
spawnUnitsAfter = debited.spawnUnitsAfter;
|
|
16627
|
-
}
|
|
16628
|
-
return {
|
|
16629
|
-
verdict: {
|
|
16630
|
-
kind: "admit",
|
|
16631
|
-
reserve,
|
|
16632
|
-
spawnUnitsAfter,
|
|
16633
|
-
lineage: {
|
|
16634
|
-
logicalTaskId: lineage.logicalTaskId,
|
|
16635
|
-
isNew: spec.lineage === void 0,
|
|
16636
|
-
depth
|
|
16637
|
-
}
|
|
16638
|
-
},
|
|
16639
|
-
statsBefore,
|
|
16640
|
-
nodeId: this.mintId(),
|
|
16641
|
-
lineage,
|
|
16642
|
-
...this.terminationAccount === void 0 ? {} : { ladderLength: spec.ladderLength ?? 1 }
|
|
16643
|
-
};
|
|
16644
|
-
}
|
|
16645
|
-
/**
|
|
16646
|
-
* Resume roll-forward for an orchestrator child (M6-T07): restores the
|
|
16647
|
-
* children-quota counter only. The budget seed already counts settled
|
|
16648
|
-
* agent dispatches, and an in-flight child re-commits its reserve
|
|
16649
|
-
* through the ctx.agent dispatch path.
|
|
16650
|
-
*/
|
|
16651
|
-
recoverChild(nodeKey) {
|
|
16652
|
-
this.childrenOf.set(nodeKey, (this.childrenOf.get(nodeKey) ?? 0) + 1);
|
|
16653
|
-
this.admittedTotal += 1;
|
|
16654
|
-
}
|
|
16655
|
-
/**
|
|
16656
|
-
* Resume roll-forward for a child that already SETTLED before the
|
|
16657
|
-
* resume: re-registers the counters (maxChildrenPerNode, the lifetime
|
|
16658
|
-
* cap, statsBefore fidelity) without committing any reserve; the spend
|
|
16659
|
-
* itself sits in the root ledger seed.
|
|
16660
|
-
*/
|
|
16661
|
-
recoverSettled(parentAccountScope) {
|
|
16662
|
-
this.budget.admitRecovered(0, parentAccountScope);
|
|
16663
|
-
this.childrenOf.set(parentAccountScope, (this.childrenOf.get(parentAccountScope) ?? 0) + 1);
|
|
16664
|
-
this.admittedTotal += 1;
|
|
16665
|
-
}
|
|
16666
|
-
/**
|
|
16667
|
-
* Resume roll-forward for an admission whose decision entry exists but
|
|
16668
|
-
* whose child has NOT settled: re-applies the recorded reserve and
|
|
16669
|
-
* counters without re-evaluating any limit (replay never
|
|
16670
|
-
* re-evaluates admission; reserves are recovered, never
|
|
16671
|
-
* re-estimated).
|
|
16672
|
-
*/
|
|
16673
|
-
recoverInFlight(parentAccountScope, verdict) {
|
|
16674
|
-
if (verdict.kind === "reject") return;
|
|
16675
|
-
const reserveUsd = verdict.kind === "reuse_full" ? 0 : verdict.reserve.reserveUsd;
|
|
16676
|
-
this.budget.admitRecovered(reserveUsd, parentAccountScope);
|
|
16677
|
-
this.childrenOf.set(parentAccountScope, (this.childrenOf.get(parentAccountScope) ?? 0) + 1);
|
|
16678
|
-
this.admittedTotal += 1;
|
|
16679
|
-
}
|
|
16680
|
-
};
|
|
16681
|
-
//#endregion
|
|
16682
|
-
//#region src/l0/telemetry-reduce.ts
|
|
16683
|
-
const ZERO = {
|
|
16684
|
-
inputTokens: 0,
|
|
16685
|
-
outputTokens: 0,
|
|
16686
|
-
cacheReadTokens: 0,
|
|
16687
|
-
cacheWriteTokens: 0
|
|
16688
|
-
};
|
|
16689
|
-
/**
|
|
16690
|
-
* Reduces one run's event stream (or any slice of it) to the invocation
|
|
16691
|
-
* table. Feed it the events in emission order; both a live stream and a
|
|
16692
|
-
* replayed one produce the same usage and cost columns.
|
|
16693
|
-
*/
|
|
16694
|
-
function reduceInvocationTable(events) {
|
|
16695
|
-
const rows = /* @__PURE__ */ new Map();
|
|
16696
|
-
const order = [];
|
|
16697
|
-
const openPhases = /* @__PURE__ */ new Map();
|
|
16698
|
-
const byRole = {};
|
|
16699
|
-
let totalCostUsd = 0;
|
|
16700
|
-
const rowFor = (event) => {
|
|
16701
|
-
let row = rows.get(event.spanId);
|
|
16702
|
-
if (row === void 0) {
|
|
16703
|
-
row = {
|
|
16704
|
-
spanId: event.spanId,
|
|
16705
|
-
agentType: event.agentType,
|
|
16706
|
-
...event.label === void 0 ? {} : { label: event.label },
|
|
16707
|
-
usage: ZERO,
|
|
16708
|
-
costUsd: 0,
|
|
16709
|
-
costBasis: "aggregate-estimate",
|
|
16710
|
-
usageApprox: false,
|
|
16711
|
-
retryCount: 0,
|
|
16712
|
-
replayed: event.replayed === true,
|
|
16713
|
-
open: true,
|
|
16714
|
-
phases: []
|
|
16715
|
-
};
|
|
16716
|
-
rows.set(event.spanId, row);
|
|
16717
|
-
order.push(row);
|
|
16718
|
-
}
|
|
16719
|
-
return row;
|
|
16720
|
-
};
|
|
16721
|
-
for (const event of events) switch (event.type) {
|
|
16722
|
-
case "agent:start": {
|
|
16723
|
-
const row = rowFor(event);
|
|
16724
|
-
row.role = event.role;
|
|
16725
|
-
break;
|
|
16726
|
-
}
|
|
16727
|
-
case "agent:phase:start": {
|
|
16728
|
-
const row = rowFor(event);
|
|
16729
|
-
const phase = {
|
|
16730
|
-
invocation: event.invocation,
|
|
16731
|
-
role: event.role,
|
|
16732
|
-
model: event.model,
|
|
16733
|
-
durationMs: 0,
|
|
16734
|
-
usage: ZERO,
|
|
16735
|
-
costUsd: 0,
|
|
16736
|
-
costBasis: "aggregate-estimate",
|
|
16737
|
-
retries: 0,
|
|
16738
|
-
replayed: event.replayed === true,
|
|
16739
|
-
open: true
|
|
16740
|
-
};
|
|
16741
|
-
row.phases.push(phase);
|
|
16742
|
-
openPhases.set(`${event.spanId}#${event.invocation}`, phase);
|
|
16743
|
-
break;
|
|
16744
|
-
}
|
|
16745
|
-
case "agent:phase:end": {
|
|
16746
|
-
const key = `${event.spanId}#${event.invocation}`;
|
|
16747
|
-
let phase = openPhases.get(key);
|
|
16748
|
-
if (phase === void 0) {
|
|
16749
|
-
phase = {
|
|
16750
|
-
invocation: event.invocation,
|
|
16751
|
-
role: event.role,
|
|
16752
|
-
model: event.model,
|
|
16753
|
-
durationMs: 0,
|
|
16754
|
-
usage: ZERO,
|
|
16755
|
-
costUsd: 0,
|
|
16756
|
-
costBasis: "aggregate-estimate",
|
|
16757
|
-
retries: 0,
|
|
16758
|
-
replayed: event.replayed === true,
|
|
16759
|
-
open: true
|
|
16760
|
-
};
|
|
16761
|
-
rowFor(event).phases.push(phase);
|
|
16762
|
-
}
|
|
16763
|
-
openPhases.delete(key);
|
|
16764
|
-
phase.open = false;
|
|
16765
|
-
phase.role = event.role;
|
|
16766
|
-
phase.model = event.model;
|
|
16767
|
-
phase.durationMs = event.durationMs;
|
|
16768
|
-
phase.usage = event.usage;
|
|
16769
|
-
phase.costUsd = event.costUsd;
|
|
16770
|
-
phase.costBasis = event.costBasis ?? "aggregate-estimate";
|
|
16771
|
-
phase.outcome = event.outcome;
|
|
16772
|
-
phase.retries = event.retries ?? 0;
|
|
16773
|
-
const bucket = byRole[event.role] ??= {
|
|
16774
|
-
usage: ZERO,
|
|
16775
|
-
costUsd: 0,
|
|
16776
|
-
costBasis: "per-call"
|
|
16777
|
-
};
|
|
16778
|
-
bucket.usage = sumUsage(bucket.usage, event.usage);
|
|
16779
|
-
bucket.costUsd += event.costUsd;
|
|
16780
|
-
if (phase.costBasis === "aggregate-estimate") bucket.costBasis = "aggregate-estimate";
|
|
16781
|
-
break;
|
|
16782
|
-
}
|
|
16783
|
-
case "agent:end": {
|
|
16784
|
-
const row = rowFor(event);
|
|
16785
|
-
row.open = false;
|
|
16786
|
-
row.status = event.status;
|
|
16787
|
-
row.usage = event.usage;
|
|
16788
|
-
row.costUsd = event.costUsd;
|
|
16789
|
-
row.costBasis = event.costBasis ?? "aggregate-estimate";
|
|
16790
|
-
row.usageApprox = event.usageApprox === true;
|
|
16791
|
-
row.retryCount = event.retryCount ?? 0;
|
|
16792
|
-
if (event.toolBudget !== void 0) row.toolBudget = event.toolBudget;
|
|
16793
|
-
totalCostUsd += event.costUsd;
|
|
16794
|
-
break;
|
|
16795
|
-
}
|
|
16796
|
-
default: break;
|
|
16797
|
-
}
|
|
16798
|
-
return {
|
|
16799
|
-
agents: order,
|
|
16800
|
-
byRole,
|
|
16801
|
-
totalCostUsd
|
|
16802
|
-
};
|
|
16803
|
-
}
|
|
16804
|
-
/**
|
|
16805
|
-
* The label the claim-consistency judge invocation dispatches under
|
|
16806
|
-
* (RV1502; named here since RV1604 so the critical-path reducer and the
|
|
16807
|
-
* orchestrator share one constant): the judge rides role 'synthesize',
|
|
16808
|
-
* and this label is what tells its wall apart from a real final
|
|
16809
|
-
* composition in {@link reduceCriticalPath}.
|
|
16810
|
-
*/
|
|
16811
|
-
const CLAIM_JUDGE_LABEL = "claim-consistency-judge";
|
|
16812
|
-
/** Total length of the union of possibly overlapping intervals. */
|
|
16813
|
-
function unionLength(intervals) {
|
|
16814
|
-
const positive = intervals.filter((interval) => interval.to > interval.from);
|
|
16815
|
-
if (positive.length === 0) return 0;
|
|
16816
|
-
const sorted = [...positive].sort((a, b) => a.from - b.from);
|
|
16817
|
-
let total = 0;
|
|
16818
|
-
let from = sorted[0]?.from ?? 0;
|
|
16819
|
-
let to = sorted[0]?.to ?? 0;
|
|
16820
|
-
for (const interval of sorted.slice(1)) if (interval.from > to) {
|
|
16821
|
-
total += to - from;
|
|
16822
|
-
from = interval.from;
|
|
16823
|
-
to = interval.to;
|
|
16824
|
-
} else if (interval.to > to) to = interval.to;
|
|
16825
|
-
return total + (to - from);
|
|
16826
|
-
}
|
|
16827
|
-
function reduceCriticalPath(events) {
|
|
16828
|
-
let runStart;
|
|
16829
|
-
let runEnd;
|
|
16830
|
-
const startBySpan = /* @__PURE__ */ new Map();
|
|
16831
|
-
let lastWorkerEnd;
|
|
16832
|
-
let workerSpans = 0;
|
|
16833
|
-
let synthesisMs = 0;
|
|
16834
|
-
let finalCompositionMs = 0;
|
|
16835
|
-
let semanticJudgeMs = 0;
|
|
16836
|
-
const coordinationModel = [];
|
|
16837
|
-
const coordinationTools = [];
|
|
16838
|
-
const synthesisSpans = [];
|
|
16839
|
-
const spanOf = (durationMs) => Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;
|
|
16840
|
-
for (const event of events) {
|
|
16841
|
-
const at = Date.parse(event.ts);
|
|
16842
|
-
if (!Number.isFinite(at)) continue;
|
|
16843
|
-
switch (event.type) {
|
|
16844
|
-
case "run:start":
|
|
16845
|
-
runStart ??= at;
|
|
16846
|
-
break;
|
|
16847
|
-
case "run:end":
|
|
16848
|
-
runEnd = at;
|
|
16849
|
-
break;
|
|
16850
|
-
case "agent:start":
|
|
16851
|
-
startBySpan.set(event.spanId, {
|
|
16852
|
-
role: event.role,
|
|
16853
|
-
at,
|
|
16854
|
-
...event.label === void 0 ? {} : { label: event.label }
|
|
16855
|
-
});
|
|
16856
|
-
break;
|
|
16857
|
-
case "agent:phase:end":
|
|
16858
|
-
if (startBySpan.get(event.spanId)?.role === "orchestrate") coordinationModel.push({
|
|
16859
|
-
phase: event.role,
|
|
16860
|
-
from: at - spanOf(event.durationMs),
|
|
16861
|
-
to: at
|
|
16862
|
-
});
|
|
16863
|
-
break;
|
|
16864
|
-
case "tool:end":
|
|
16865
|
-
if (startBySpan.get(event.spanId)?.role === "orchestrate") coordinationTools.push({
|
|
16866
|
-
name: event.toolName,
|
|
16867
|
-
from: at - spanOf(event.durationMs),
|
|
16868
|
-
to: at
|
|
16869
|
-
});
|
|
16870
|
-
break;
|
|
16871
|
-
case "agent:end": {
|
|
16872
|
-
const started = startBySpan.get(event.spanId);
|
|
16873
|
-
if (started === void 0) break;
|
|
16874
|
-
if (started.role === "synthesize") {
|
|
16875
|
-
const wall = Math.max(0, at - started.at);
|
|
16876
|
-
const judge = started.label === CLAIM_JUDGE_LABEL;
|
|
16877
|
-
synthesisMs += wall;
|
|
16878
|
-
if (judge) semanticJudgeMs += wall;
|
|
16879
|
-
else finalCompositionMs += wall;
|
|
16880
|
-
synthesisSpans.push({
|
|
16881
|
-
from: started.at,
|
|
16882
|
-
to: at,
|
|
16883
|
-
judge
|
|
16884
|
-
});
|
|
16885
|
-
} else if (started.role !== "orchestrate") {
|
|
16886
|
-
workerSpans += 1;
|
|
16887
|
-
lastWorkerEnd = lastWorkerEnd === void 0 ? at : Math.max(lastWorkerEnd, at);
|
|
16888
|
-
}
|
|
16889
|
-
break;
|
|
17165
|
+
if (evaluated.decision.kind === "reject") return {
|
|
17166
|
+
verdict: {
|
|
17167
|
+
kind: "reject",
|
|
17168
|
+
reason: evaluated.decision.reason
|
|
17169
|
+
},
|
|
17170
|
+
statsBefore
|
|
17171
|
+
};
|
|
17172
|
+
if (this.terminationAccount !== void 0) {
|
|
17173
|
+
if ((spec.ladderLength ?? 1) > this.terminationAccount.limits.kMax) return {
|
|
17174
|
+
verdict: {
|
|
17175
|
+
kind: "reject",
|
|
17176
|
+
reason: { code: "ladder_exceeds_frozen" }
|
|
17177
|
+
},
|
|
17178
|
+
statsBefore
|
|
17179
|
+
};
|
|
17180
|
+
if (this.terminationAccount.spawnUnitsExhausted) return {
|
|
17181
|
+
verdict: {
|
|
17182
|
+
kind: "reject",
|
|
17183
|
+
reason: { code: "termination_exhausted" }
|
|
17184
|
+
},
|
|
17185
|
+
statsBefore
|
|
17186
|
+
};
|
|
17187
|
+
}
|
|
17188
|
+
if (depth > this.maxDepth) return {
|
|
17189
|
+
verdict: {
|
|
17190
|
+
kind: "reject",
|
|
17191
|
+
reason: { code: "depth" }
|
|
17192
|
+
},
|
|
17193
|
+
statsBefore
|
|
17194
|
+
};
|
|
17195
|
+
if (childrenBefore >= this.maxChildrenPerNode) return {
|
|
17196
|
+
verdict: {
|
|
17197
|
+
kind: "reject",
|
|
17198
|
+
reason: { code: "quota" }
|
|
17199
|
+
},
|
|
17200
|
+
statsBefore
|
|
17201
|
+
};
|
|
17202
|
+
if (this.maxTotalSpawns !== void 0 && this.admittedTotal >= this.maxTotalSpawns) return {
|
|
17203
|
+
verdict: {
|
|
17204
|
+
kind: "reject",
|
|
17205
|
+
reason: { code: "lifetime" }
|
|
17206
|
+
},
|
|
17207
|
+
statsBefore
|
|
17208
|
+
};
|
|
17209
|
+
if (spec.roster !== void 0) {
|
|
17210
|
+
const seatsRemaining = spec.roster.floor - spec.roster.admittedChildren;
|
|
17211
|
+
if (seatsRemaining > 0) {
|
|
17212
|
+
const perSeatProjectionUsd = this.projectedDispatchReserveUsd(spec);
|
|
17213
|
+
const remainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
17214
|
+
if (remainder !== void 0 && remainder < seatsRemaining * perSeatProjectionUsd + spec.roster.liveExposureUsd) return {
|
|
17215
|
+
verdict: {
|
|
17216
|
+
kind: "reject",
|
|
17217
|
+
reason: {
|
|
17218
|
+
code: "roster_floor",
|
|
17219
|
+
floor: spec.roster.floor,
|
|
17220
|
+
admittedChildren: spec.roster.admittedChildren,
|
|
17221
|
+
seatsRemaining,
|
|
17222
|
+
perSeatProjectionUsd,
|
|
17223
|
+
liveExposureUsd: spec.roster.liveExposureUsd,
|
|
17224
|
+
remainderUsd: remainder
|
|
17225
|
+
}
|
|
17226
|
+
},
|
|
17227
|
+
statsBefore
|
|
17228
|
+
};
|
|
16890
17229
|
}
|
|
16891
|
-
default: break;
|
|
16892
17230
|
}
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
|
|
16898
|
-
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
|
|
16903
|
-
const
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
17231
|
+
const spawnToolOrigin = spec.origin === "spawn_agent" || spec.origin === "parallel_agents";
|
|
17232
|
+
let childCeilingUsd;
|
|
17233
|
+
const parentRemainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
17234
|
+
if (spawnToolOrigin) {
|
|
17235
|
+
if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
17236
|
+
} else if (parentRemainder !== void 0) {
|
|
17237
|
+
const fractionCap = this.childBudgetFraction * parentRemainder;
|
|
17238
|
+
childCeilingUsd = spec.budgetUsd === void 0 ? fractionCap : Math.min(spec.budgetUsd, fractionCap);
|
|
17239
|
+
} else if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
17240
|
+
let reserveUsd = spec.estCostUsd ?? this.flatReserveUsd;
|
|
17241
|
+
const source = spec.estCostUsd === void 0 ? "default" : "estCost";
|
|
17242
|
+
let clampedBy;
|
|
17243
|
+
if (childCeilingUsd !== void 0 && reserveUsd > childCeilingUsd) {
|
|
17244
|
+
clampedBy = spec.budgetUsd !== void 0 && childCeilingUsd === spec.budgetUsd ? "explicit-budget" : "fraction-ceiling";
|
|
17245
|
+
reserveUsd = childCeilingUsd;
|
|
17246
|
+
}
|
|
17247
|
+
const reserve = {
|
|
17248
|
+
reserveUsd,
|
|
17249
|
+
source
|
|
17250
|
+
};
|
|
17251
|
+
if (clampedBy !== void 0) reserve.clampedBy = clampedBy;
|
|
17252
|
+
if (childCeilingUsd !== void 0) reserve.childCeilingUsd = childCeilingUsd;
|
|
17253
|
+
if (this.budget.spawnHeadroom <= 0) return {
|
|
17254
|
+
verdict: {
|
|
17255
|
+
kind: "reject",
|
|
17256
|
+
reason: { code: "lifetime" }
|
|
17257
|
+
},
|
|
17258
|
+
statsBefore
|
|
17259
|
+
};
|
|
17260
|
+
if (commitReserve) try {
|
|
17261
|
+
this.budget.admitSpawn(reserveUsd, spec.parentAccountScope);
|
|
17262
|
+
} catch {
|
|
16907
17263
|
return {
|
|
16908
|
-
|
|
16909
|
-
|
|
17264
|
+
verdict: {
|
|
17265
|
+
kind: "reject",
|
|
17266
|
+
reason: { code: "budget" }
|
|
17267
|
+
},
|
|
17268
|
+
statsBefore
|
|
16910
17269
|
};
|
|
16911
|
-
};
|
|
16912
|
-
const byPhase = {};
|
|
16913
|
-
const modelClipped = [];
|
|
16914
|
-
for (const interval of coordinationModel) {
|
|
16915
|
-
const clipped = clip(interval);
|
|
16916
|
-
if (clipped === void 0) continue;
|
|
16917
|
-
byPhase[interval.phase] = (byPhase[interval.phase] ?? 0) + (clipped.to - clipped.from);
|
|
16918
|
-
modelClipped.push(clipped);
|
|
16919
17270
|
}
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
|
|
16927
|
-
|
|
16928
|
-
|
|
17271
|
+
else {
|
|
17272
|
+
const remainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
17273
|
+
const projection = this.projectedDispatchReserveUsd(spec);
|
|
17274
|
+
if (remainder !== void 0 && (remainder <= 0 || remainder < projection + (spec.pendingReserveUsd ?? 0))) return {
|
|
17275
|
+
verdict: {
|
|
17276
|
+
kind: "reject",
|
|
17277
|
+
reason: { code: "budget" }
|
|
17278
|
+
},
|
|
17279
|
+
statsBefore
|
|
17280
|
+
};
|
|
16929
17281
|
}
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
const
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
17282
|
+
this.childrenOf.set(nodeKey, childrenBefore + 1);
|
|
17283
|
+
this.admittedTotal += 1;
|
|
17284
|
+
const lineage = evaluated.decision.lineage;
|
|
17285
|
+
this.registerLineageAdmit(lineage.logicalTaskId);
|
|
17286
|
+
let spawnUnitsAfter = this.budget.spawnHeadroom;
|
|
17287
|
+
if (this.terminationAccount !== void 0) {
|
|
17288
|
+
const debited = this.terminationAccount.debitSpawn({
|
|
17289
|
+
logicalTaskId: lineage.logicalTaskId,
|
|
17290
|
+
isNew: spec.lineage === void 0,
|
|
17291
|
+
ladderLength: spec.ladderLength ?? 1
|
|
17292
|
+
});
|
|
17293
|
+
if (!debited.ok) return {
|
|
17294
|
+
verdict: {
|
|
17295
|
+
kind: "reject",
|
|
17296
|
+
reason: { code: "termination_exhausted" }
|
|
17297
|
+
},
|
|
17298
|
+
statsBefore
|
|
17299
|
+
};
|
|
17300
|
+
spawnUnitsAfter = debited.spawnUnitsAfter;
|
|
16939
17301
|
}
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16945
|
-
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16954
|
-
|
|
16955
|
-
finalCompositionMs: compositionClippedMs,
|
|
16956
|
-
semanticJudgeMs: judgeClippedMs,
|
|
16957
|
-
coveredMs,
|
|
16958
|
-
residueMs: Math.max(0, path.postFanInMs - coveredMs)
|
|
17302
|
+
return {
|
|
17303
|
+
verdict: {
|
|
17304
|
+
kind: "admit",
|
|
17305
|
+
reserve,
|
|
17306
|
+
spawnUnitsAfter,
|
|
17307
|
+
lineage: {
|
|
17308
|
+
logicalTaskId: lineage.logicalTaskId,
|
|
17309
|
+
isNew: spec.lineage === void 0,
|
|
17310
|
+
depth
|
|
17311
|
+
}
|
|
17312
|
+
},
|
|
17313
|
+
statsBefore,
|
|
17314
|
+
nodeId: this.mintId(),
|
|
17315
|
+
lineage,
|
|
17316
|
+
...this.terminationAccount === void 0 ? {} : { ladderLength: spec.ladderLength ?? 1 }
|
|
16959
17317
|
};
|
|
16960
|
-
if (path.postFanInMs > 0) breakdown.residueShare = breakdown.residueMs / path.postFanInMs;
|
|
16961
|
-
path.postFanIn = breakdown;
|
|
16962
17318
|
}
|
|
16963
|
-
|
|
16964
|
-
|
|
16965
|
-
|
|
17319
|
+
/**
|
|
17320
|
+
* Resume roll-forward for an orchestrator child (M6-T07): restores the
|
|
17321
|
+
* children-quota counter only. The budget seed already counts settled
|
|
17322
|
+
* agent dispatches, and an in-flight child re-commits its reserve
|
|
17323
|
+
* through the ctx.agent dispatch path.
|
|
17324
|
+
*/
|
|
17325
|
+
recoverChild(nodeKey) {
|
|
17326
|
+
this.childrenOf.set(nodeKey, (this.childrenOf.get(nodeKey) ?? 0) + 1);
|
|
17327
|
+
this.admittedTotal += 1;
|
|
16966
17328
|
}
|
|
16967
|
-
|
|
16968
|
-
|
|
17329
|
+
/**
|
|
17330
|
+
* Resume roll-forward for a child that already SETTLED before the
|
|
17331
|
+
* resume: re-registers the counters (maxChildrenPerNode, the lifetime
|
|
17332
|
+
* cap, statsBefore fidelity) without committing any reserve; the spend
|
|
17333
|
+
* itself sits in the root ledger seed.
|
|
17334
|
+
*/
|
|
17335
|
+
recoverSettled(parentAccountScope) {
|
|
17336
|
+
this.budget.admitRecovered(0, parentAccountScope);
|
|
17337
|
+
this.childrenOf.set(parentAccountScope, (this.childrenOf.get(parentAccountScope) ?? 0) + 1);
|
|
17338
|
+
this.admittedTotal += 1;
|
|
17339
|
+
}
|
|
17340
|
+
/**
|
|
17341
|
+
* Resume roll-forward for an admission whose decision entry exists but
|
|
17342
|
+
* whose child has NOT settled: re-applies the recorded reserve and
|
|
17343
|
+
* counters without re-evaluating any limit (replay never
|
|
17344
|
+
* re-evaluates admission; reserves are recovered, never
|
|
17345
|
+
* re-estimated).
|
|
17346
|
+
*/
|
|
17347
|
+
recoverInFlight(parentAccountScope, verdict) {
|
|
17348
|
+
if (verdict.kind === "reject") return;
|
|
17349
|
+
const reserveUsd = verdict.kind === "reuse_full" ? 0 : verdict.reserve.reserveUsd;
|
|
17350
|
+
this.budget.admitRecovered(reserveUsd, parentAccountScope);
|
|
17351
|
+
this.childrenOf.set(parentAccountScope, (this.childrenOf.get(parentAccountScope) ?? 0) + 1);
|
|
17352
|
+
this.admittedTotal += 1;
|
|
17353
|
+
}
|
|
17354
|
+
};
|
|
16969
17355
|
//#endregion
|
|
16970
17356
|
//#region src/model/profile-card.ts
|
|
16971
17357
|
function toolNamesOf(profile) {
|
|
@@ -18708,6 +19094,7 @@ function createCtx(internals, rootWorkflow) {
|
|
|
18708
19094
|
agentType,
|
|
18709
19095
|
role: primaryRole,
|
|
18710
19096
|
budgetAccount: state.budgetScope ?? "run",
|
|
19097
|
+
...opts.label === void 0 ? {} : { label: opts.label },
|
|
18711
19098
|
...opts[kFinalizeReserve] === true ? { finalizeReserve: true } : {}
|
|
18712
19099
|
},
|
|
18713
19100
|
transcriptRef: result.transcriptRef
|
|
@@ -21106,6 +21493,8 @@ function pairDraftClaims(draftText, rows, options) {
|
|
|
21106
21493
|
const max = requirePositiveInteger(options?.max ?? 40, "pairDraftClaims max");
|
|
21107
21494
|
const maxPoolPerPair = requirePositiveInteger(options?.maxPoolPerPair ?? 3, "pairDraftClaims maxPoolPerPair");
|
|
21108
21495
|
const maxExcerptChars = requirePositiveInteger(options?.maxExcerptChars ?? 400, "pairDraftClaims maxExcerptChars");
|
|
21496
|
+
const targetShare = options?.targetCoverageShare;
|
|
21497
|
+
if (targetShare !== void 0 && (typeof targetShare !== "number" || !Number.isFinite(targetShare) || targetShare <= 0 || targetShare > 1)) throw new ConfigError(`pairDraftClaims targetCoverageShare must be a number in (0, 1]; got ` + JSON.stringify(targetShare));
|
|
21109
21498
|
const poolByPath = /* @__PURE__ */ new Map();
|
|
21110
21499
|
for (const row of rows) for (const sentence of sentencesOf(row.text)) {
|
|
21111
21500
|
const anchors = anchorsOf(sentence, pattern);
|
|
@@ -21197,13 +21586,37 @@ function pairDraftClaims(draftText, rows, options) {
|
|
|
21197
21586
|
});
|
|
21198
21587
|
}
|
|
21199
21588
|
}
|
|
21200
|
-
const
|
|
21589
|
+
const ordered = critical === void 0 ? candidates : [...candidates.filter((candidate) => candidate.critical), ...candidates.filter((candidate) => !candidate.critical)];
|
|
21590
|
+
let reported;
|
|
21591
|
+
let maxCut;
|
|
21592
|
+
let targetSentences;
|
|
21593
|
+
if (targetShare === void 0) {
|
|
21594
|
+
reported = ordered.slice(0, max);
|
|
21595
|
+
maxCut = candidates.length > reported.length;
|
|
21596
|
+
} else {
|
|
21597
|
+
targetSentences = Math.min(draftCitingSentences, Math.ceil(targetShare * draftCitingSentences));
|
|
21598
|
+
const covering = /* @__PURE__ */ new Set();
|
|
21599
|
+
const wanted = [];
|
|
21600
|
+
for (const candidate of ordered) {
|
|
21601
|
+
if (candidate.critical) {
|
|
21602
|
+
wanted.push(candidate);
|
|
21603
|
+
covering.add(candidate.sentence);
|
|
21604
|
+
continue;
|
|
21605
|
+
}
|
|
21606
|
+
if (covering.size >= targetSentences || covering.has(candidate.sentence)) continue;
|
|
21607
|
+
wanted.push(candidate);
|
|
21608
|
+
covering.add(candidate.sentence);
|
|
21609
|
+
}
|
|
21610
|
+
reported = wanted.slice(0, max);
|
|
21611
|
+
maxCut = wanted.length > reported.length;
|
|
21612
|
+
}
|
|
21201
21613
|
const coveredSentences = new Set(reported.map((candidate) => candidate.sentence));
|
|
21202
21614
|
const fold = {
|
|
21203
21615
|
pairs: reported.map((candidate) => candidate.pair),
|
|
21204
|
-
truncated:
|
|
21616
|
+
truncated: maxCut,
|
|
21205
21617
|
draftCitingSentences,
|
|
21206
|
-
coveredCitingSentences: coveredSentences.size
|
|
21618
|
+
coveredCitingSentences: coveredSentences.size,
|
|
21619
|
+
...targetSentences === void 0 ? {} : { targetCoveredSentences: targetSentences }
|
|
21207
21620
|
};
|
|
21208
21621
|
if (critical !== void 0) {
|
|
21209
21622
|
const reportedAnchors = new Set(reported.map((candidate) => candidate.pair.anchor));
|
|
@@ -22010,10 +22423,14 @@ function validateOrchestrateOptions(opts) {
|
|
|
22010
22423
|
if (consistency.runFacts !== true) throw new ConfigError("orchestrate claimConsistency.runFactTerms rides the runFacts pass; set claimConsistency.runFacts true");
|
|
22011
22424
|
if (!Array.isArray(consistency.runFactTerms) || consistency.runFactTerms.some((term) => typeof term !== "string" || term.length === 0)) throw new ConfigError("orchestrate claimConsistency.runFactTerms must be an array of nonempty strings; got " + JSON.stringify(consistency.runFactTerms));
|
|
22012
22425
|
}
|
|
22013
|
-
for (const [label, ratio] of [
|
|
22426
|
+
for (const [label, ratio] of [
|
|
22427
|
+
["minimumCoverageRatio", consistency.minimumCoverageRatio],
|
|
22428
|
+
["runFactCoverageRatio", consistency.runFactCoverageRatio],
|
|
22429
|
+
["coverageTarget", consistency.coverageTarget]
|
|
22430
|
+
]) if (ratio !== void 0 && (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio <= 0 || ratio > 1)) throw new ConfigError(`orchestrate claimConsistency.${label} must be a number in (0, 1]; got ` + JSON.stringify(ratio));
|
|
22014
22431
|
if (consistency.runFactCoverageRatio !== void 0 && consistency.runFacts !== true) throw new ConfigError("orchestrate claimConsistency.runFactCoverageRatio rides the runFacts pass; set claimConsistency.runFacts true");
|
|
22015
22432
|
if (consistency.onLowCoverage !== void 0 && consistency.onLowCoverage !== "report" && consistency.onLowCoverage !== "fail") throw new ConfigError("orchestrate claimConsistency.onLowCoverage must be 'report' or 'fail'; got " + JSON.stringify(consistency.onLowCoverage));
|
|
22016
|
-
if (consistency.onLowCoverage !== void 0 && consistency.minimumCoverageRatio === void 0 && consistency.runFactCoverageRatio === void 0) throw new ConfigError("orchestrate claimConsistency.onLowCoverage needs a declared floor; set minimumCoverageRatio or
|
|
22433
|
+
if (consistency.onLowCoverage !== void 0 && consistency.minimumCoverageRatio === void 0 && consistency.runFactCoverageRatio === void 0 && consistency.coverageTarget === void 0) throw new ConfigError("orchestrate claimConsistency.onLowCoverage needs a declared floor; set minimumCoverageRatio, runFactCoverageRatio, or coverageTarget");
|
|
22017
22434
|
if (consistency.judge !== void 0) {
|
|
22018
22435
|
const judge = consistency.judge;
|
|
22019
22436
|
if (typeof judge !== "object" || judge === null || Array.isArray(judge)) throw new ConfigError(`orchestrate claimConsistency.judge must be an object; got ${JSON.stringify(consistency.judge)}`);
|
|
@@ -23685,6 +24102,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
23685
24102
|
const noteOpts = {
|
|
23686
24103
|
role: "synthesize",
|
|
23687
24104
|
result: "full",
|
|
24105
|
+
label: SYNTHESIS_NOTE_LABEL,
|
|
23688
24106
|
tools: finishOnly,
|
|
23689
24107
|
limits: spec.noteLimits ?? { maxTurns: 2 },
|
|
23690
24108
|
...spec.model === void 0 ? {} : { model: spec.model },
|
|
@@ -24021,7 +24439,8 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24021
24439
|
max: spec.max ?? 40,
|
|
24022
24440
|
...spec.maxPoolPerPair === void 0 ? {} : { maxPoolPerPair: spec.maxPoolPerPair },
|
|
24023
24441
|
...spec.maxExcerptChars === void 0 ? {} : { maxExcerptChars: spec.maxExcerptChars },
|
|
24024
|
-
...spec.critical === void 0 ? {} : { critical: spec.critical }
|
|
24442
|
+
...spec.critical === void 0 ? {} : { critical: spec.critical },
|
|
24443
|
+
...spec.coverageTarget === void 0 ? {} : { targetCoverageShare: spec.coverageTarget }
|
|
24025
24444
|
});
|
|
24026
24445
|
const runFold = spec.runFacts === true ? pairRunFactClaims(draftText, {
|
|
24027
24446
|
text: `The run ${internals.runId} made ${String(factWires)} provider wire requests across ${String(poolChildren)} accepted children, with token totals ${String(factInput)} input and ${String(factOutput)} output (the run's own recorded execution facts; harness-observed, not production evidence). ${factRows.join(" ")}`,
|
|
@@ -24034,7 +24453,8 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24034
24453
|
]
|
|
24035
24454
|
}, {
|
|
24036
24455
|
...spec.runFactTerms === void 0 ? {} : { terms: spec.runFactTerms },
|
|
24037
|
-
...spec.maxExcerptChars === void 0 ? {} : { maxExcerptChars: spec.maxExcerptChars }
|
|
24456
|
+
...spec.maxExcerptChars === void 0 ? {} : { maxExcerptChars: spec.maxExcerptChars },
|
|
24457
|
+
...spec.coverageTarget === void 0 ? {} : { max: Number.MAX_SAFE_INTEGER }
|
|
24038
24458
|
}) : void 0;
|
|
24039
24459
|
const allPairs = runFold === void 0 ? fold.pairs : [...fold.pairs, ...runFold.pairs];
|
|
24040
24460
|
const onFound = spec.onFound ?? "report";
|
|
@@ -24044,6 +24464,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24044
24464
|
pairs: allPairs.length,
|
|
24045
24465
|
truncated: fold.truncated,
|
|
24046
24466
|
coveredCitingSentences: fold.coveredCitingSentences,
|
|
24467
|
+
...spec.coverageTarget === void 0 ? {} : { coverageTarget: spec.coverageTarget },
|
|
24047
24468
|
...fold.criticalUncovered === void 0 ? {} : {
|
|
24048
24469
|
criticalUncovered: fold.criticalUncovered,
|
|
24049
24470
|
criticalUncoveredTotal: fold.criticalUncoveredTotal ?? 0
|
|
@@ -24054,14 +24475,15 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24054
24475
|
runFactCandidates: runFold.candidates
|
|
24055
24476
|
},
|
|
24056
24477
|
...(() => {
|
|
24478
|
+
const coverageFloor = spec.minimumCoverageRatio ?? spec.coverageTarget;
|
|
24057
24479
|
const coverageRatio = fold.draftCitingSentences === 0 ? 1 : fold.coveredCitingSentences / fold.draftCitingSentences;
|
|
24058
24480
|
const runFactRatio = runFold === void 0 || runFold.candidates === 0 ? void 0 : runFold.pairs.length / runFold.candidates;
|
|
24059
|
-
const belowCoverage =
|
|
24481
|
+
const belowCoverage = coverageFloor !== void 0 && fold.draftCitingSentences > 0 && coverageRatio < coverageFloor;
|
|
24060
24482
|
const belowRunFacts = spec.runFactCoverageRatio !== void 0 && runFactRatio !== void 0 && runFactRatio < spec.runFactCoverageRatio;
|
|
24061
24483
|
if (!belowCoverage && !belowRunFacts) return {};
|
|
24062
24484
|
return { lowCoverage: {
|
|
24063
24485
|
coverageRatio,
|
|
24064
|
-
...
|
|
24486
|
+
...coverageFloor === void 0 ? {} : { coverageFloor },
|
|
24065
24487
|
...runFactRatio === void 0 ? {} : { runFactRatio },
|
|
24066
24488
|
...spec.runFactCoverageRatio === void 0 ? {} : { runFactFloor: spec.runFactCoverageRatio }
|
|
24067
24489
|
} };
|
|
@@ -24558,6 +24980,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24558
24980
|
const synthesisOpts = {
|
|
24559
24981
|
role: "synthesize",
|
|
24560
24982
|
result: "full",
|
|
24983
|
+
label: FINAL_COMPOSITION_LABEL,
|
|
24561
24984
|
tools: synthesisTools,
|
|
24562
24985
|
[kExposureWait]: true,
|
|
24563
24986
|
limits: spec.limits ?? { maxTurns: 4 },
|
|
@@ -28316,4 +28739,4 @@ function createSandboxBridge(ctx, options) {
|
|
|
28316
28739
|
};
|
|
28317
28740
|
}
|
|
28318
28741
|
//#endregion
|
|
28319
|
-
export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_JUDGE_LABEL, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DECISION_CHAIN_KINDS, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_RUN_FACT_PAIRS, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DedupIndex, DeterminismError, EMIT_RESULT_TOOL, EMPTY_AUTHORITY_HASH, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EXPOSURE_WAIT_SWEEP_MS, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FUTURE_RATES_TOLERANCE_MS, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GET_SETTLED_CHILD_RESULTS_SCHEMA, GET_SETTLED_CHILD_RESULTS_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, JournalCompatibilityError, JournalMatcher, JournalMissError, JournalOrderViolation, JournalSealedError, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_CRITICAL_UNCOVERED, MAX_DEPTH_CEILING, MAX_RUN_FACTS_SHEET_CHARS, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_FACTS_ANCHOR, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_ADMISSION_DECISION_TYPE, SPAWN_AGENT_SCHEMA, SandboxError, ScriptRejected, Semaphore, SettlementError, SpanRegistry, SupersededError, TERMINAL_TELEMETRY_SCOPE, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, childRostersFromJournal, citationTargetsValidator, citedValueValidator, claimCoverageOf, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, logicalRunTelemetry, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, pairRunFactClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pilotAgentProfile, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reconcileStatement, reduceAuditTrail, reduceCriticalPath, reduceDecisionChain, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, sectionPatternCountValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, statementFromRows, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolAuthority, toolContract, toolContractHash, toolsetAuthorityHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
|
|
28742
|
+
export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_JUDGE_LABEL, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DECISION_CHAIN_KINDS, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_RUN_FACT_PAIRS, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DedupIndex, DeterminismError, EMIT_RESULT_TOOL, EMPTY_AUTHORITY_HASH, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EXPOSURE_WAIT_SWEEP_MS, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINAL_COMPOSITION_LABEL, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FUTURE_RATES_TOLERANCE_MS, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GET_SETTLED_CHILD_RESULTS_SCHEMA, GET_SETTLED_CHILD_RESULTS_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, JournalCompatibilityError, JournalMatcher, JournalMissError, JournalOrderViolation, JournalSealedError, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_CRITICAL_UNCOVERED, MAX_DEPTH_CEILING, MAX_RUN_FACTS_SHEET_CHARS, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_FACTS_ANCHOR, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_ADMISSION_DECISION_TYPE, SPAWN_AGENT_SCHEMA, SYNTHESIS_NOTE_LABEL, SandboxError, ScriptRejected, Semaphore, SettlementError, SpanRegistry, SupersededError, TERMINAL_TELEMETRY_SCOPE, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, childRostersFromJournal, citationTargetsValidator, citedValueValidator, claimCoverageOf, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, criticalPathFromJournal, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, logicalRunTelemetry, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, pairRunFactClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pilotAgentProfile, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reconcileStatement, reduceAuditTrail, reduceCriticalPath, reduceDecisionChain, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, sectionPatternCountValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, statementFromRows, statementRowsFromDelimited, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, synthesisCandidatesFromJournal, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolAuthority, toolContract, toolContractHash, toolsetAuthorityHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
|