@rulvar/core 1.78.0 → 1.80.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 +72 -1
- package/dist/index.js +135 -33
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3476,6 +3476,16 @@ type CoreEvents = {
|
|
|
3476
3476
|
* nonnegative integers. Absent otherwise.
|
|
3477
3477
|
*/
|
|
3478
3478
|
childStatusCounts?: Record<string, number>;
|
|
3479
|
+
/**
|
|
3480
|
+
* Per-child degradation notes, lifted from the same envelope (or
|
|
3481
|
+
* typed error data) when it carries a valid string array (the
|
|
3482
|
+
* fifth experiment, cycle 75). An empty array is the workflow's
|
|
3483
|
+
* claim of zero degradation; absence means no claim. The outcome
|
|
3484
|
+
* mirror spreads the SAME lift, so the surfaces cannot disagree.
|
|
3485
|
+
*/
|
|
3486
|
+
degradedReasons?: string[]; /** Children accepted by acceptPartialChildren; same lift. */
|
|
3487
|
+
salvagedPartialChildren?: string[]; /** Children accepted through validated terminal output salvage on 'limit'; same lift. */
|
|
3488
|
+
salvagedTerminalOutputChildren?: string[];
|
|
3479
3489
|
} | {
|
|
3480
3490
|
type: "phase:start";
|
|
3481
3491
|
phase: string;
|
|
@@ -4915,6 +4925,8 @@ interface BudgetAccountView {
|
|
|
4915
4925
|
spentUsd: number;
|
|
4916
4926
|
committedReserveUsd: number;
|
|
4917
4927
|
finalizeReserveUsd: number;
|
|
4928
|
+
/** The synthesis payload hold (cycle 76); zero when none is committed. */
|
|
4929
|
+
synthesisReserveUsd: number;
|
|
4918
4930
|
parentScope?: string;
|
|
4919
4931
|
}
|
|
4920
4932
|
/**
|
|
@@ -5071,6 +5083,21 @@ declare class RunBudget {
|
|
|
5071
5083
|
* frozen past the cap, so nothing else can take it.
|
|
5072
5084
|
*/
|
|
5073
5085
|
releaseFinalizeReserve(scope: string): void;
|
|
5086
|
+
/**
|
|
5087
|
+
* Registers the synthesis payload reserve (the sixth comparison
|
|
5088
|
+
* experiment, cycle 76): absolute dollars held on the orchestrator
|
|
5089
|
+
* account AND the run root, so neither spawn admission nor the
|
|
5090
|
+
* per-turn output clamp lets the coordination prefix eat the money
|
|
5091
|
+
* the synthesis finish needs. Unlike the finalize reserve it is
|
|
5092
|
+
* released BEFORE the synthesis invocation dispatches (the held
|
|
5093
|
+
* money is exactly what that invocation is meant to spend), and it
|
|
5094
|
+
* never joins the severing check: a coordination running against the
|
|
5095
|
+
* hold is clamped smaller, never aborted. Idempotent per account:
|
|
5096
|
+
* re-registering adjusts the root by the delta.
|
|
5097
|
+
*/
|
|
5098
|
+
commitSynthesisReserve(scope: string, reserveUsd: number): void;
|
|
5099
|
+
/** The synthesis dispatch consumes its reserve; see commitSynthesisReserve. */
|
|
5100
|
+
releaseSynthesisReserve(scope: string): void;
|
|
5074
5101
|
/** The reserve is replaced by real spend when the spawn settles. */
|
|
5075
5102
|
releaseReserve(reserveUsd: number, accountScope?: string): void;
|
|
5076
5103
|
/** Layer 2: the per-turn guard. A turn that would cross any ceiling in the chain is not dispatched. */
|
|
@@ -5682,7 +5709,23 @@ type RunOutcome<R> = {
|
|
|
5682
5709
|
* nonnegative integers; the mirror of the `run:end` field. Absent
|
|
5683
5710
|
* otherwise.
|
|
5684
5711
|
*/
|
|
5685
|
-
childStatusCounts?: Record<string, number>;
|
|
5712
|
+
childStatusCounts?: Record<string, number>;
|
|
5713
|
+
/**
|
|
5714
|
+
* Per-child degradation notes, lifted from the same envelope (or
|
|
5715
|
+
* typed error data) when it carries a valid string array (the fifth
|
|
5716
|
+
* experiment, cycle 75): the facts the orchestrator acceptance path
|
|
5717
|
+
* has always emitted beside completion, now on the outcome itself so
|
|
5718
|
+
* a host stops digging error.data on the rejected path. An empty
|
|
5719
|
+
* array is the workflow's claim of zero degradation; absence means no
|
|
5720
|
+
* claim was made.
|
|
5721
|
+
*/
|
|
5722
|
+
degradedReasons?: string[]; /** Children accepted by acceptPartialChildren; same lift and posture. */
|
|
5723
|
+
salvagedPartialChildren?: string[];
|
|
5724
|
+
/**
|
|
5725
|
+
* Children accepted through validated terminal output salvage on
|
|
5726
|
+
* 'limit'; same lift and posture.
|
|
5727
|
+
*/
|
|
5728
|
+
salvagedTerminalOutputChildren?: string[]; /** Pipeline drops and onError:'null' losses; silent losses are forbidden. */
|
|
5686
5729
|
dropped: DroppedItem[]; /** Suspensions open at settle time (M2). */
|
|
5687
5730
|
pending: PendingExternal[];
|
|
5688
5731
|
usage: Usage;
|
|
@@ -7098,6 +7141,21 @@ interface OrchestratorBudgetSpec {
|
|
|
7098
7141
|
*/
|
|
7099
7142
|
finalizeReserveUsd?: number;
|
|
7100
7143
|
/**
|
|
7144
|
+
* The synthesis payload reserve (the sixth comparison experiment,
|
|
7145
|
+
* cycle 76): absolute USD held out of the orchestrator sub account
|
|
7146
|
+
* while the coordination loop runs, released to the synthesis
|
|
7147
|
+
* invocation just before it dispatches. Without it a pricey
|
|
7148
|
+
* coordination can leave the synthesis turns a remainder the budget
|
|
7149
|
+
* clamp shrinks below the contract's minimal accepting payload: the
|
|
7150
|
+
* finish is then cut at the output allowance before any tool call,
|
|
7151
|
+
* the invocation dies at maxTurns, and a validator-bound run fails
|
|
7152
|
+
* closed (the rematch run 1 lost an entire paid run exactly there).
|
|
7153
|
+
* Requires the `synthesis` option (single mode); must stay below the
|
|
7154
|
+
* effective cap. Declaring it changes budget arithmetic only; absent
|
|
7155
|
+
* keeps every account byte identical.
|
|
7156
|
+
*/
|
|
7157
|
+
synthesisReserveUsd?: number;
|
|
7158
|
+
/**
|
|
7101
7159
|
* A positive integer, validated before any journal entry or dispatch:
|
|
7102
7160
|
* the turn limit of the reserved final wake.
|
|
7103
7161
|
*/
|
|
@@ -9112,6 +9170,19 @@ interface PreflightInput {
|
|
|
9112
9170
|
* the repair-reserve-unfunded warning stays silent.
|
|
9113
9171
|
*/
|
|
9114
9172
|
maxRepairs?: number;
|
|
9173
|
+
/**
|
|
9174
|
+
* Mirrors FinishValidationSpec.draftPolicy (the fifth experiment,
|
|
9175
|
+
* cycle 75): declaring it lets the estimator compare the draft
|
|
9176
|
+
* gate's word floor against the contract's own word minimum. The
|
|
9177
|
+
* experiment gated drafts at 3200 words under a 4500 word contract,
|
|
9178
|
+
* so the gate admitted a draft the final validators had to reject
|
|
9179
|
+
* and the synthesis started from an underlength base; the
|
|
9180
|
+
* draft-gate-below-contract warning names exactly that shape.
|
|
9181
|
+
*/
|
|
9182
|
+
draftPolicy?: {
|
|
9183
|
+
minWords?: number;
|
|
9184
|
+
requireSections?: string[];
|
|
9185
|
+
};
|
|
9115
9186
|
};
|
|
9116
9187
|
}
|
|
9117
9188
|
/** One linter verdict; `spawn` names the wave entry it is about. */
|
package/dist/index.js
CHANGED
|
@@ -10740,24 +10740,35 @@ async function runAgent(options) {
|
|
|
10740
10740
|
skipped: true
|
|
10741
10741
|
}));
|
|
10742
10742
|
};
|
|
10743
|
+
let terminalAdmitted = false;
|
|
10743
10744
|
for (const [index, call] of calls.entries()) {
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10745
|
+
const expiredLimiter = limits.maxToolCalls !== void 0 && toolCallsUsed >= limits.maxToolCalls ? "maxToolCalls" : guard !== void 0 && guard.unitsExhausted() ? "toolUnits" : void 0;
|
|
10746
|
+
if (expiredLimiter !== void 0) {
|
|
10747
|
+
const tail = calls.slice(index);
|
|
10748
|
+
const terminalName = options.terminalTool?.name;
|
|
10749
|
+
if (!(terminalName !== void 0 && (terminalAdmitted || tail.some((candidate) => candidate.name === terminalName)))) {
|
|
10750
|
+
closeSkippedTail(tail, expiredLimiter);
|
|
10751
|
+
return {
|
|
10752
|
+
parts,
|
|
10753
|
+
limitHit: true,
|
|
10754
|
+
limiter: expiredLimiter,
|
|
10755
|
+
skipped: calls.length - index
|
|
10756
|
+
};
|
|
10757
|
+
}
|
|
10758
|
+
if (call.name !== terminalName) {
|
|
10759
|
+
parts.push(errorPart(call, {
|
|
10760
|
+
error: "skipped: the tool budget is exhausted; the call was not executed",
|
|
10761
|
+
limiter: expiredLimiter,
|
|
10762
|
+
skipped: true
|
|
10763
|
+
}));
|
|
10764
|
+
continue;
|
|
10765
|
+
}
|
|
10766
|
+
terminalAdmitted = true;
|
|
10767
|
+
events?.emit({
|
|
10768
|
+
type: "log",
|
|
10769
|
+
level: "warn",
|
|
10770
|
+
msg: `terminal tool '${call.name}' admitted at the exhausted tool budget (${expiredLimiter}): terminal calls do not consume the budget`
|
|
10771
|
+
});
|
|
10761
10772
|
}
|
|
10762
10773
|
const def = runtime.defs.find((candidate) => candidate.name === call.name);
|
|
10763
10774
|
events?.emit({
|
|
@@ -12130,6 +12141,7 @@ var RunBudget = class {
|
|
|
12130
12141
|
spentUsd: 0,
|
|
12131
12142
|
committedReserveUsd: 0,
|
|
12132
12143
|
finalizeReserveUsd: 0,
|
|
12144
|
+
synthesisReserveUsd: 0,
|
|
12133
12145
|
controller: new AbortController()
|
|
12134
12146
|
};
|
|
12135
12147
|
if (options.ceilingUsd !== void 0) root.ceilingUsd = options.ceilingUsd;
|
|
@@ -12174,6 +12186,7 @@ var RunBudget = class {
|
|
|
12174
12186
|
spentUsd: 0,
|
|
12175
12187
|
committedReserveUsd: 0,
|
|
12176
12188
|
finalizeReserveUsd: options.finalizeReserveUsd ?? 0,
|
|
12189
|
+
synthesisReserveUsd: 0,
|
|
12177
12190
|
parentScope,
|
|
12178
12191
|
controller: new AbortController()
|
|
12179
12192
|
};
|
|
@@ -12225,7 +12238,8 @@ var RunBudget = class {
|
|
|
12225
12238
|
scope: account.scope,
|
|
12226
12239
|
spentUsd: account.spentUsd,
|
|
12227
12240
|
committedReserveUsd: account.committedReserveUsd,
|
|
12228
|
-
finalizeReserveUsd: account.finalizeReserveUsd
|
|
12241
|
+
finalizeReserveUsd: account.finalizeReserveUsd,
|
|
12242
|
+
synthesisReserveUsd: account.synthesisReserveUsd
|
|
12229
12243
|
};
|
|
12230
12244
|
if (account.ceilingUsd !== void 0) view.ceilingUsd = account.ceilingUsd;
|
|
12231
12245
|
if (account.parentScope !== void 0) view.parentScope = account.parentScope;
|
|
@@ -12239,7 +12253,7 @@ var RunBudget = class {
|
|
|
12239
12253
|
remainderOf(scope) {
|
|
12240
12254
|
const account = this.accounts.get(scope);
|
|
12241
12255
|
if (account?.ceilingUsd === void 0) return;
|
|
12242
|
-
return Math.max(0, account.ceilingUsd - account.spentUsd - account.committedReserveUsd - account.finalizeReserveUsd);
|
|
12256
|
+
return Math.max(0, account.ceilingUsd - account.spentUsd - account.committedReserveUsd - account.finalizeReserveUsd - account.synthesisReserveUsd);
|
|
12243
12257
|
}
|
|
12244
12258
|
/**
|
|
12245
12259
|
* The tightest allowance headroom on the chain of `scope`: the minimum
|
|
@@ -12309,7 +12323,7 @@ var RunBudget = class {
|
|
|
12309
12323
|
const chain = this.chainOf(accountScope);
|
|
12310
12324
|
for (const account of chain) {
|
|
12311
12325
|
if (account.ceilingUsd === void 0) continue;
|
|
12312
|
-
const committed = account.spentUsd + account.committedReserveUsd + account.finalizeReserveUsd;
|
|
12326
|
+
const committed = account.spentUsd + account.committedReserveUsd + account.finalizeReserveUsd + account.synthesisReserveUsd;
|
|
12313
12327
|
if (committed >= account.ceilingUsd || committed + reserveUsd > account.ceilingUsd) {
|
|
12314
12328
|
if (account.scope === "run") this.exhaustedInternal = true;
|
|
12315
12329
|
throw new BudgetExhaustedError(`budget ceiling reached on account '${account.scope}': spent ${account.spentUsd.toFixed(4)} USD plus committed reserves ${(account.committedReserveUsd + account.finalizeReserveUsd).toFixed(4)} USD plus the proposed reserve ${reserveUsd.toFixed(4)} USD does not fit the ceiling ${account.ceilingUsd.toFixed(4)} USD`, { data: {
|
|
@@ -12364,6 +12378,34 @@ var RunBudget = class {
|
|
|
12364
12378
|
this.root.finalizeReserveUsd = 0;
|
|
12365
12379
|
this.emitUpdate();
|
|
12366
12380
|
}
|
|
12381
|
+
/**
|
|
12382
|
+
* Registers the synthesis payload reserve (the sixth comparison
|
|
12383
|
+
* experiment, cycle 76): absolute dollars held on the orchestrator
|
|
12384
|
+
* account AND the run root, so neither spawn admission nor the
|
|
12385
|
+
* per-turn output clamp lets the coordination prefix eat the money
|
|
12386
|
+
* the synthesis finish needs. Unlike the finalize reserve it is
|
|
12387
|
+
* released BEFORE the synthesis invocation dispatches (the held
|
|
12388
|
+
* money is exactly what that invocation is meant to spend), and it
|
|
12389
|
+
* never joins the severing check: a coordination running against the
|
|
12390
|
+
* hold is clamped smaller, never aborted. Idempotent per account:
|
|
12391
|
+
* re-registering adjusts the root by the delta.
|
|
12392
|
+
*/
|
|
12393
|
+
commitSynthesisReserve(scope, reserveUsd) {
|
|
12394
|
+
const account = this.accounts.get(scope);
|
|
12395
|
+
if (account === void 0) throw new ConfigError(`unknown budget account '${scope}' for the synthesis reserve`);
|
|
12396
|
+
const previous = account.synthesisReserveUsd;
|
|
12397
|
+
account.synthesisReserveUsd = reserveUsd;
|
|
12398
|
+
if (account.scope !== "run") this.root.synthesisReserveUsd = Math.max(0, this.root.synthesisReserveUsd + reserveUsd - previous);
|
|
12399
|
+
this.emitUpdate();
|
|
12400
|
+
}
|
|
12401
|
+
/** The synthesis dispatch consumes its reserve; see commitSynthesisReserve. */
|
|
12402
|
+
releaseSynthesisReserve(scope) {
|
|
12403
|
+
const account = this.accounts.get(scope);
|
|
12404
|
+
if (account === void 0 || account.synthesisReserveUsd === 0) return;
|
|
12405
|
+
if (account.scope !== "run") this.root.synthesisReserveUsd = Math.max(0, this.root.synthesisReserveUsd - account.synthesisReserveUsd);
|
|
12406
|
+
account.synthesisReserveUsd = 0;
|
|
12407
|
+
this.emitUpdate();
|
|
12408
|
+
}
|
|
12367
12409
|
/** The reserve is replaced by real spend when the spawn settles. */
|
|
12368
12410
|
releaseReserve(reserveUsd, accountScope = "run") {
|
|
12369
12411
|
for (const account of this.chainOf(accountScope)) account.committedReserveUsd = Math.max(0, account.committedReserveUsd - reserveUsd);
|
|
@@ -12396,7 +12438,7 @@ var RunBudget = class {
|
|
|
12396
12438
|
let remainingUsd;
|
|
12397
12439
|
for (const account of this.chainOf(accountScope)) {
|
|
12398
12440
|
if (account.ceilingUsd === void 0) continue;
|
|
12399
|
-
const headroom = account.ceilingUsd - account.spentUsd;
|
|
12441
|
+
const headroom = account.ceilingUsd - account.spentUsd - account.synthesisReserveUsd;
|
|
12400
12442
|
remainingUsd = remainingUsd === void 0 ? headroom : Math.min(remainingUsd, headroom);
|
|
12401
12443
|
}
|
|
12402
12444
|
if (remainingUsd === void 0) return;
|
|
@@ -16148,6 +16190,11 @@ function validateOrchestrateOptions(opts) {
|
|
|
16148
16190
|
if (spec.capUsd !== void 0) requireNonNegativeNumber(spec.capUsd, "orchestrate budget.capUsd");
|
|
16149
16191
|
if (spec.capFraction !== void 0) requireFraction(spec.capFraction, "orchestrate budget.capFraction");
|
|
16150
16192
|
if (spec.finalizeReserveUsd !== void 0) requireNonNegativeNumber(spec.finalizeReserveUsd, "orchestrate budget.finalizeReserveUsd");
|
|
16193
|
+
if (spec.synthesisReserveUsd !== void 0) {
|
|
16194
|
+
requireNonNegativeNumber(spec.synthesisReserveUsd, "orchestrate budget.synthesisReserveUsd");
|
|
16195
|
+
if (opts.synthesis === void 0) throw new ConfigError("orchestrate budget.synthesisReserveUsd requires the synthesis option: the reserve holds sub account money for the separate synthesis invocation");
|
|
16196
|
+
if (opts.synthesis.mode === "incremental") throw new ConfigError("orchestrate budget.synthesisReserveUsd is incompatible with synthesis.mode 'incremental': the reserve protects the single post-fan-in invocation");
|
|
16197
|
+
}
|
|
16151
16198
|
if (spec.finalizeTurns !== void 0) requirePositiveInteger(spec.finalizeTurns, "orchestrate budget.finalizeTurns");
|
|
16152
16199
|
if (spec.atCap !== void 0 && spec.atCap !== "finish-with-partial" && spec.atCap !== "fail-run") throw new ConfigError(`orchestrate budget.atCap must be 'finish-with-partial' or 'fail-run'; got ${String(spec.atCap)}`);
|
|
16153
16200
|
}
|
|
@@ -16297,12 +16344,14 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16297
16344
|
liveValue: internals.pricingVersion ?? "unpriced"
|
|
16298
16345
|
}] : []);
|
|
16299
16346
|
orchestratorAccount = callingState.scope === "" ? "orchestrator" : `${callingState.scope}/orchestrator`;
|
|
16347
|
+
if (spec?.synthesisReserveUsd !== void 0 && frozen.capUsd <= spec.synthesisReserveUsd) throw new OrchestratorCapConfigError(`effectiveCap ${frozen.capUsd.toFixed(4)} USD is not above the synthesis reserve ${spec.synthesisReserveUsd.toFixed(4)} USD`);
|
|
16300
16348
|
internals.budget.openAccount(orchestratorAccount, {
|
|
16301
16349
|
parentScope: callingState.budgetScope ?? "run",
|
|
16302
16350
|
ceilingUsd: frozen.capUsd,
|
|
16303
16351
|
kind: "orchestrator-cap"
|
|
16304
16352
|
});
|
|
16305
16353
|
if (extension !== void 0) internals.budget.commitFinalizeReserve(orchestratorAccount, frozen.finalizeReserveUsd);
|
|
16354
|
+
if (spec?.synthesisReserveUsd !== void 0 && spec.synthesisReserveUsd > 0) internals.budget.commitSynthesisReserve(orchestratorAccount, spec.synthesisReserveUsd);
|
|
16306
16355
|
capState = {
|
|
16307
16356
|
effectiveCapUsd: frozen.capUsd,
|
|
16308
16357
|
finalizeReserveUsd: frozen.finalizeReserveUsd,
|
|
@@ -16324,6 +16373,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16324
16373
|
level: "warn",
|
|
16325
16374
|
msg: `orchestrator budget.capUsd ${spec.capUsd.toFixed(4)} USD is bounded to ${effectiveCapUsd.toFixed(4)} USD by the default capFraction 0.2 of the run ceiling (effectiveCap = min(capUsd, capFraction * ceiling)); pass capFraction: 1.0 to make capUsd the sole bound`
|
|
16326
16375
|
}, callingState.spanId);
|
|
16376
|
+
if (spec?.synthesisReserveUsd !== void 0 && effectiveCapUsd <= spec.synthesisReserveUsd) throw new OrchestratorCapConfigError(`effectiveCap ${effectiveCapUsd.toFixed(4)} USD is not above the synthesis reserve ${spec.synthesisReserveUsd.toFixed(4)} USD: the coordination loop would have no money at all`);
|
|
16327
16377
|
orchestratorAccount = callingState.scope === "" ? "orchestrator" : `${callingState.scope}/orchestrator`;
|
|
16328
16378
|
internals.budget.openAccount(orchestratorAccount, {
|
|
16329
16379
|
parentScope: callingState.budgetScope ?? "run",
|
|
@@ -16331,6 +16381,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
16331
16381
|
kind: "orchestrator-cap"
|
|
16332
16382
|
});
|
|
16333
16383
|
if (extension !== void 0) internals.budget.commitFinalizeReserve(orchestratorAccount, finalizeReserveUsd);
|
|
16384
|
+
if (spec?.synthesisReserveUsd !== void 0 && spec.synthesisReserveUsd > 0) internals.budget.commitSynthesisReserve(orchestratorAccount, spec.synthesisReserveUsd);
|
|
16334
16385
|
capState = {
|
|
16335
16386
|
effectiveCapUsd,
|
|
16336
16387
|
finalizeReserveUsd,
|
|
@@ -17257,7 +17308,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17257
17308
|
role: "orchestrate",
|
|
17258
17309
|
result: "full",
|
|
17259
17310
|
tools,
|
|
17260
|
-
...capState === void 0 ? {} : { estCost: orchestratorAdmissionEstCostUsd(capState.effectiveCapUsd, orchestratorAccount === void 0 ? 0 : internals.budget.accountView(orchestratorAccount)?.finalizeReserveUsd ?? 0) },
|
|
17311
|
+
...capState === void 0 ? {} : { estCost: orchestratorAdmissionEstCostUsd(capState.effectiveCapUsd, orchestratorAccount === void 0 ? 0 : (internals.budget.accountView(orchestratorAccount)?.finalizeReserveUsd ?? 0) + (internals.budget.accountView(orchestratorAccount)?.synthesisReserveUsd ?? 0)) },
|
|
17261
17312
|
...opts?.model === void 0 ? {} : { model: opts.model },
|
|
17262
17313
|
...opts?.limits === void 0 ? {} : { limits: opts.limits },
|
|
17263
17314
|
[kOnRunning]: (seq) => {
|
|
@@ -17573,7 +17624,10 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
17573
17624
|
}
|
|
17574
17625
|
}, callingState.spanId);
|
|
17575
17626
|
const synthesisState = { ...callingState };
|
|
17576
|
-
if (orchestratorAccount !== void 0)
|
|
17627
|
+
if (orchestratorAccount !== void 0) {
|
|
17628
|
+
synthesisState.budgetScope = orchestratorAccount;
|
|
17629
|
+
internals.budget.releaseSynthesisReserve(orchestratorAccount);
|
|
17630
|
+
}
|
|
17577
17631
|
const synthesisBreak = validationSpec === void 0 ? void 0 : validationAbort.signal;
|
|
17578
17632
|
if (synthesisBreak !== void 0) synthesisState.signal = callingState.signal === void 0 ? synthesisBreak : AbortSignal.any([callingState.signal, synthesisBreak]);
|
|
17579
17633
|
const synthesisOpts = {
|
|
@@ -18226,7 +18280,7 @@ function preflightEstimate(input) {
|
|
|
18226
18280
|
turns: projectedProviderTurnsOf(orchLimits, overallExecutedCeiling(orchLimits, toolCeilingsOf(orchLimits))) + coordinationRepairReserve,
|
|
18227
18281
|
count: 1
|
|
18228
18282
|
});
|
|
18229
|
-
if (effectiveCapUsd !== void 0) orchestratorReserveUsd = Math.max(0, orchestratorAdmissionEstCostUsd(effectiveCapUsd, reservedForFinalizationUsd));
|
|
18283
|
+
if (effectiveCapUsd !== void 0) orchestratorReserveUsd = Math.max(0, orchestratorAdmissionEstCostUsd(effectiveCapUsd, reservedForFinalizationUsd + (input.orchestrator.budget?.synthesisReserveUsd ?? 0)));
|
|
18230
18284
|
else if (pricing === void 0) orchestratorReserveUsd = 0;
|
|
18231
18285
|
else orchestratorReserveUsd = admissionReserveUsd({
|
|
18232
18286
|
...input.orchestrator.estInputTokens === void 0 ? {} : { inputTokens: input.orchestrator.estInputTokens },
|
|
@@ -18254,6 +18308,16 @@ function preflightEstimate(input) {
|
|
|
18254
18308
|
spawn: "synthesis"
|
|
18255
18309
|
});
|
|
18256
18310
|
}
|
|
18311
|
+
{
|
|
18312
|
+
const synthesisToolCap = synthesis.limits?.maxToolCalls;
|
|
18313
|
+
const expectedReads = input.orchestrator?.maxSpawns ?? 1;
|
|
18314
|
+
if (synthesis.exposeChildResultTools === true && synthesisToolCap !== void 0 && synthesisToolCap < expectedReads) say({
|
|
18315
|
+
severity: "warning",
|
|
18316
|
+
code: "synthesis-terminal-tool-headroom",
|
|
18317
|
+
message: `synthesis.limits.maxToolCalls ${String(synthesisToolCap)} cannot cover one get_child_result read per child (${input.orchestrator?.maxSpawns === void 0 ? "at least 1 read" : `maxSpawns ${String(expectedReads)}`}): the reads exhaust the tool budget and the synthesis loses evidence access (the terminal finish is admitted budget free and needs no slot); raise the cap to at least the child count plus paging margin, or use context 'full' without the read tools`,
|
|
18318
|
+
spawn: "synthesis"
|
|
18319
|
+
});
|
|
18320
|
+
}
|
|
18257
18321
|
const servedBy = resolveServing(synthesis.model) ?? resolveServing(defaults.routing?.synthesize);
|
|
18258
18322
|
if (servedBy === void 0) say({
|
|
18259
18323
|
severity: "error",
|
|
@@ -18272,6 +18336,21 @@ function preflightEstimate(input) {
|
|
|
18272
18336
|
spawn: "synthesis"
|
|
18273
18337
|
});
|
|
18274
18338
|
contractFeasibilityFindings(outputBound, "synthesis", servedBy);
|
|
18339
|
+
{
|
|
18340
|
+
const contract = input.finishValidation?.contract;
|
|
18341
|
+
const pricing = pricingOf(servedBy);
|
|
18342
|
+
if (contract !== void 0 && pricing !== void 0 && pricing.outputUsdPerMTok > 0) {
|
|
18343
|
+
const minTokens = Math.ceil(JSON.stringify({ result: contract.goldenAccept.text }).length / 4);
|
|
18344
|
+
const payloadUsd = minTokens / 1e6 * pricing.outputUsdPerMTok;
|
|
18345
|
+
const declared = input.orchestrator?.budget?.synthesisReserveUsd;
|
|
18346
|
+
if (declared === void 0 || declared < payloadUsd) say({
|
|
18347
|
+
severity: "warning",
|
|
18348
|
+
code: "synthesis-reserve-unfunded",
|
|
18349
|
+
message: `the contract's minimal accepting payload is about ${String(minTokens)} output tokens, about ${payloadUsd.toFixed(4)} USD at the output rate of '${servedBy}', and the orchestrator sub account holds ${declared === void 0 ? "no synthesis reserve" : `only ${declared.toFixed(4)} USD`} for it: a pricey coordination prefix can leave the synthesis turns a remainder the budget clamp shrinks below the payload, cutting the finish before any tool call; declare budget.synthesisReserveUsd at or above the payload price`,
|
|
18350
|
+
spawn: "synthesis"
|
|
18351
|
+
});
|
|
18352
|
+
}
|
|
18353
|
+
}
|
|
18275
18354
|
const projected = projectedProviderTurnsOf(merged, overallExecutedCeiling(merged, toolCeilingsOf(merged))) + finishRepairReserve;
|
|
18276
18355
|
if (orchestratorEcho !== void 0) orchestratorEcho.synthesis = {
|
|
18277
18356
|
projectedProviderTurns: projected,
|
|
@@ -18294,10 +18373,12 @@ function preflightEstimate(input) {
|
|
|
18294
18373
|
let committed = 0;
|
|
18295
18374
|
let spawned = 0;
|
|
18296
18375
|
let children = 0;
|
|
18297
|
-
const admitAgainstRoot = (reserveUsd) => {
|
|
18376
|
+
const admitAgainstRoot = (reserveUsd, strictAtFill = false) => {
|
|
18298
18377
|
if (ceilingUsd === void 0) return true;
|
|
18299
18378
|
const held = committed + reservedForFinalizationUsd;
|
|
18300
|
-
|
|
18379
|
+
if (held >= ceilingUsd) return false;
|
|
18380
|
+
const fill = held + reserveUsd;
|
|
18381
|
+
return strictAtFill ? fill < ceilingUsd : fill <= ceilingUsd;
|
|
18301
18382
|
};
|
|
18302
18383
|
if (input.orchestrator !== void 0) {
|
|
18303
18384
|
const reserveUsd = orchestratorReserveUsd ?? flatReserveUsd;
|
|
@@ -18329,9 +18410,9 @@ function preflightEstimate(input) {
|
|
|
18329
18410
|
if (orchestrateWave && ceilingUsd !== void 0) {
|
|
18330
18411
|
const remainder = ceilingUsd - committed - reservedForFinalizationUsd;
|
|
18331
18412
|
const projection = dispatchProjectionReserveUsd(gate, flatReserveUsd);
|
|
18332
|
-
if (remainder <= 0 || remainder
|
|
18413
|
+
if (remainder <= 0 || remainder <= projection) deniedBy = "budget";
|
|
18333
18414
|
}
|
|
18334
|
-
if (deniedBy === void 0 && !admitAgainstRoot(reserveUsd)) deniedBy = "budget";
|
|
18415
|
+
if (deniedBy === void 0 && !admitAgainstRoot(reserveUsd, orchestrateWave)) deniedBy = "budget";
|
|
18335
18416
|
}
|
|
18336
18417
|
wave.push({
|
|
18337
18418
|
label,
|
|
@@ -18505,6 +18586,16 @@ function preflightEstimate(input) {
|
|
|
18505
18586
|
message: `finishValidation grants up to ${String(grantedRepairs)} repair exchange(s) but declares no repairTurnReserve: a rejected finish burns an ordinary turn and a window at maxTurns settles 'limit' with the repair unspent; set finishValidation.repairTurnReserve to fund the repair exchanges`
|
|
18506
18587
|
});
|
|
18507
18588
|
}
|
|
18589
|
+
{
|
|
18590
|
+
const draftMinWords = fv.draftPolicy?.minWords;
|
|
18591
|
+
if (draftMinWords !== void 0) requireNonNegativeInteger(draftMinWords, "preflight finishValidation.draftPolicy.minWords");
|
|
18592
|
+
const contractMinWords = fv.contract?.manifest.words?.min;
|
|
18593
|
+
if (draftMinWords !== void 0 && contractMinWords !== void 0 && draftMinWords < contractMinWords) findings.push({
|
|
18594
|
+
severity: "warning",
|
|
18595
|
+
code: "draft-gate-below-contract",
|
|
18596
|
+
message: `draftPolicy.minWords ${String(draftMinWords)} sits below the contract word minimum ${String(contractMinWords)}: the draft gate admits drafts the final validators must reject, so the synthesis starts from an underlength base; raise draftPolicy.minWords to the contract minimum or above`
|
|
18597
|
+
});
|
|
18598
|
+
}
|
|
18508
18599
|
if (fv.contract !== void 0) {
|
|
18509
18600
|
for (const contractValidator of fv.contract.validators) if (!names.has(contractValidator.name)) findings.push({
|
|
18510
18601
|
severity: "error",
|
|
@@ -19325,15 +19416,23 @@ function liftRunCompletion(candidate) {
|
|
|
19325
19416
|
if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) return;
|
|
19326
19417
|
const completion = candidate.completion;
|
|
19327
19418
|
if (completion !== "complete" && completion !== "partial" && completion !== "rejected") return;
|
|
19419
|
+
const lifted = { completion };
|
|
19328
19420
|
const counts = candidate.childStatusCounts;
|
|
19329
19421
|
if (typeof counts === "object" && counts !== null && !Array.isArray(counts)) {
|
|
19330
19422
|
const entries = Object.entries(counts);
|
|
19331
|
-
if (entries.every(([, value]) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0))
|
|
19332
|
-
completion,
|
|
19333
|
-
childStatusCounts: Object.fromEntries(entries)
|
|
19334
|
-
};
|
|
19423
|
+
if (entries.every(([, value]) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0)) lifted.childStatusCounts = Object.fromEntries(entries);
|
|
19335
19424
|
}
|
|
19336
|
-
|
|
19425
|
+
const liftStringList = (key) => {
|
|
19426
|
+
const value = candidate[key];
|
|
19427
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? [...value] : void 0;
|
|
19428
|
+
};
|
|
19429
|
+
const degradedReasons = liftStringList("degradedReasons");
|
|
19430
|
+
if (degradedReasons !== void 0) lifted.degradedReasons = degradedReasons;
|
|
19431
|
+
const salvagedPartialChildren = liftStringList("salvagedPartialChildren");
|
|
19432
|
+
if (salvagedPartialChildren !== void 0) lifted.salvagedPartialChildren = salvagedPartialChildren;
|
|
19433
|
+
const salvagedTerminalOutputChildren = liftStringList("salvagedTerminalOutputChildren");
|
|
19434
|
+
if (salvagedTerminalOutputChildren !== void 0) lifted.salvagedTerminalOutputChildren = salvagedTerminalOutputChildren;
|
|
19435
|
+
return lifted;
|
|
19337
19436
|
}
|
|
19338
19437
|
/**
|
|
19339
19438
|
* sha256 hex over the JCS canonical serialization of a run's args: the
|
|
@@ -19788,6 +19887,9 @@ function createEngine(options) {
|
|
|
19788
19887
|
if (lifted !== void 0) {
|
|
19789
19888
|
outcome.completion = lifted.completion;
|
|
19790
19889
|
if (lifted.childStatusCounts !== void 0) outcome.childStatusCounts = lifted.childStatusCounts;
|
|
19890
|
+
if (lifted.degradedReasons !== void 0) outcome.degradedReasons = lifted.degradedReasons;
|
|
19891
|
+
if (lifted.salvagedPartialChildren !== void 0) outcome.salvagedPartialChildren = lifted.salvagedPartialChildren;
|
|
19892
|
+
if (lifted.salvagedTerminalOutputChildren !== void 0) outcome.salvagedTerminalOutputChildren = lifted.salvagedTerminalOutputChildren;
|
|
19791
19893
|
}
|
|
19792
19894
|
let settlementFailure;
|
|
19793
19895
|
if (resumeCtx?.strict !== true) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.80.0",
|
|
4
4
|
"description": "Rulvar core: L0 contracts, journal kernel, ctx primitives, agent runtime, model router, tool system, dynamic orchestrator, InMemory and JSONL stores, event stream.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|