@rulvar/core 1.205.0 → 1.207.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 +76 -1
- package/dist/index.js +59 -9
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -6758,6 +6758,23 @@ interface BudgetReserve {
|
|
|
6758
6758
|
reserveUsd: number;
|
|
6759
6759
|
/** The child sub-account ceiling; absent when the parent is uncapped. */
|
|
6760
6760
|
childCeilingUsd?: number;
|
|
6761
|
+
/**
|
|
6762
|
+
* The reserve derivation (RV2004): where reserveUsd came from, so a
|
|
6763
|
+
* journal reader never reverse-engineers the arithmetic. 'estCost'
|
|
6764
|
+
* is the declared estimate (spawn opts or the agentType profile),
|
|
6765
|
+
* 'default' the engine flat reserve.
|
|
6766
|
+
*/
|
|
6767
|
+
source?: "estCost" | "default";
|
|
6768
|
+
/**
|
|
6769
|
+
* Set when the derived reserve was clamped DOWN to the child's
|
|
6770
|
+
* ceiling: 'explicit-budget' by a declared budgetUsd,
|
|
6771
|
+
* 'fraction-ceiling' by the childBudgetFraction allowance an ORIGIN
|
|
6772
|
+
* WITH a materialized allowance account enforces (ctx.workflow).
|
|
6773
|
+
* The spawn-tool path never carries 'fraction-ceiling': its
|
|
6774
|
+
* dispatch enforces no fraction account, and journaling that clamp
|
|
6775
|
+
* is exactly the parity rerun's 0.50-versus-0.70 lie (RV2004).
|
|
6776
|
+
*/
|
|
6777
|
+
clampedBy?: "explicit-budget" | "fraction-ceiling";
|
|
6761
6778
|
}
|
|
6762
6779
|
/** The lineage block every non-reject verdict carries (DEF-3). */
|
|
6763
6780
|
interface AdmitLineage {
|
|
@@ -6801,6 +6818,25 @@ type AdmitRejectReason = {
|
|
|
6801
6818
|
code: "osc_guard";
|
|
6802
6819
|
spawnKey: SpawnKey;
|
|
6803
6820
|
oscillationCount: number;
|
|
6821
|
+
} | {
|
|
6822
|
+
/**
|
|
6823
|
+
* The sequential roster feasibility refusal (RV2005): under a
|
|
6824
|
+
* declared acceptance.minSpawnedChildren, the whole remaining
|
|
6825
|
+
* roster (priced at this seat's own projection) plus the live
|
|
6826
|
+
* in-flight exposure does not fit the parent remainder, so the
|
|
6827
|
+
* FIRST infeasible seat refuses before any child is paid. The
|
|
6828
|
+
* batchGate symmetry (RV1908) on the seat-by-seat path the
|
|
6829
|
+
* parity rerun's model actually took, where three seats were
|
|
6830
|
+
* paid in full under a floor of four the money could never
|
|
6831
|
+
* reach.
|
|
6832
|
+
*/
|
|
6833
|
+
code: "roster_floor";
|
|
6834
|
+
floor: number;
|
|
6835
|
+
admittedChildren: number;
|
|
6836
|
+
seatsRemaining: number;
|
|
6837
|
+
perSeatProjectionUsd: number;
|
|
6838
|
+
liveExposureUsd: number;
|
|
6839
|
+
remainderUsd: number;
|
|
6804
6840
|
} | {
|
|
6805
6841
|
/**
|
|
6806
6842
|
* The declared estimate cannot fit the child's own ceiling: the
|
|
@@ -6842,6 +6878,20 @@ interface AdmitSpec {
|
|
|
6842
6878
|
*/
|
|
6843
6879
|
pendingReserveUsd?: number;
|
|
6844
6880
|
/**
|
|
6881
|
+
* The sequential roster feasibility inputs (RV2005), passed by the
|
|
6882
|
+
* SINGLE spawn_agent path when acceptance.minSpawnedChildren is
|
|
6883
|
+
* declared: the admission projects the whole REMAINING roster at
|
|
6884
|
+
* this seat's own dispatch projection, live in-flight exposure
|
|
6885
|
+
* included, and refuses the first infeasible seat typed
|
|
6886
|
+
* 'roster_floor' before any child is paid. Batch seats never carry
|
|
6887
|
+
* this: the RV1908 batchGate already judged their batch entire.
|
|
6888
|
+
*/
|
|
6889
|
+
roster?: {
|
|
6890
|
+
floor: number;
|
|
6891
|
+
admittedChildren: number;
|
|
6892
|
+
liveExposureUsd: number;
|
|
6893
|
+
};
|
|
6894
|
+
/**
|
|
6845
6895
|
* Lineage continuation (DEF-3); absence mints a fresh lineage root. A
|
|
6846
6896
|
* continuation demands a causeRef: the seq of the entry that caused the
|
|
6847
6897
|
* rebirth.
|
|
@@ -8734,7 +8784,7 @@ interface OrchestratorRuntime {
|
|
|
8734
8784
|
causeRef: number;
|
|
8735
8785
|
};
|
|
8736
8786
|
taskClass?: string;
|
|
8737
|
-
}): Promise<{
|
|
8787
|
+
}, origin?: "spawn_agent" | "parallel_agents"): Promise<{
|
|
8738
8788
|
handle: number;
|
|
8739
8789
|
}>;
|
|
8740
8790
|
awaitAny(handles: number[]): Promise<TaskDigest>;
|
|
@@ -9535,6 +9585,19 @@ interface OrchestrateOptions {
|
|
|
9535
9585
|
*/
|
|
9536
9586
|
parallelAdmission?: "fail-fast" | "try-all" | "all-or-none";
|
|
9537
9587
|
/**
|
|
9588
|
+
* The batch-spawn discipline (RV2005). The third parity rerun's
|
|
9589
|
+
* model ignored the instruction to spawn its roster in one
|
|
9590
|
+
* parallel_agents call and spawned seat by seat through spawn_agent,
|
|
9591
|
+
* so the RV1908 batchGate never saw a batch and the roster
|
|
9592
|
+
* feasibility rode on per-seat luck. 'reject-spawn-agent' refuses
|
|
9593
|
+
* every SINGLE spawn_agent call typed (code 'batch_required',
|
|
9594
|
+
* nothing journaled, nothing paid) so model disobedience cannot
|
|
9595
|
+
* split the policy: the model reads the refusal and re-issues the
|
|
9596
|
+
* wave as one parallel_agents batch. Absent, both tools behave as
|
|
9597
|
+
* documented.
|
|
9598
|
+
*/
|
|
9599
|
+
requireBatchSpawn?: "reject-spawn-agent";
|
|
9600
|
+
/**
|
|
9538
9601
|
* The opt in deterministic host validation of the finish result, with
|
|
9539
9602
|
* bounded repair; see {@link FinishValidationSpec}.
|
|
9540
9603
|
*/
|
|
@@ -13096,6 +13159,18 @@ interface PreflightReport {
|
|
|
13096
13159
|
* fourth workers. Present whenever the wave has rows.
|
|
13097
13160
|
*/
|
|
13098
13161
|
requiredMinimumCeilingUsd?: number;
|
|
13162
|
+
/**
|
|
13163
|
+
* The live-root-exposure term of the wave projection (RV2004): the
|
|
13164
|
+
* orchestrator's own worst-case turn floor, the money coordination
|
|
13165
|
+
* has ALWAYS already spent (and holds in flight) by the time any
|
|
13166
|
+
* spawn tool runs. The parity rerun's fourth seat fit the plain
|
|
13167
|
+
* wave (5.95 under 6.00) and was refused live by exactly this
|
|
13168
|
+
* term; the embedded spawn gate and requiredMinimumCeilingUsd now
|
|
13169
|
+
* carry it, so a seat that cannot admit live cannot admit in
|
|
13170
|
+
* preflight either. Present on orchestrate waves whose
|
|
13171
|
+
* coordination turn prices.
|
|
13172
|
+
*/
|
|
13173
|
+
liveRootExposureTermUsd?: number;
|
|
13099
13174
|
wave: PreflightAdmissionRow[];
|
|
13100
13175
|
admitted: number;
|
|
13101
13176
|
denied: number;
|
package/dist/index.js
CHANGED
|
@@ -16047,15 +16047,49 @@ var AdmissionController = class {
|
|
|
16047
16047
|
},
|
|
16048
16048
|
statsBefore
|
|
16049
16049
|
};
|
|
16050
|
+
if (spec.roster !== void 0) {
|
|
16051
|
+
const seatsRemaining = spec.roster.floor - spec.roster.admittedChildren;
|
|
16052
|
+
if (seatsRemaining > 0) {
|
|
16053
|
+
const perSeatProjectionUsd = this.projectedDispatchReserveUsd(spec);
|
|
16054
|
+
const remainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
16055
|
+
if (remainder !== void 0 && remainder < seatsRemaining * perSeatProjectionUsd + spec.roster.liveExposureUsd) return {
|
|
16056
|
+
verdict: {
|
|
16057
|
+
kind: "reject",
|
|
16058
|
+
reason: {
|
|
16059
|
+
code: "roster_floor",
|
|
16060
|
+
floor: spec.roster.floor,
|
|
16061
|
+
admittedChildren: spec.roster.admittedChildren,
|
|
16062
|
+
seatsRemaining,
|
|
16063
|
+
perSeatProjectionUsd,
|
|
16064
|
+
liveExposureUsd: spec.roster.liveExposureUsd,
|
|
16065
|
+
remainderUsd: remainder
|
|
16066
|
+
}
|
|
16067
|
+
},
|
|
16068
|
+
statsBefore
|
|
16069
|
+
};
|
|
16070
|
+
}
|
|
16071
|
+
}
|
|
16072
|
+
const spawnToolOrigin = spec.origin === "spawn_agent" || spec.origin === "parallel_agents";
|
|
16050
16073
|
let childCeilingUsd;
|
|
16051
16074
|
const parentRemainder = this.budget.remainderOf(spec.parentAccountScope);
|
|
16052
|
-
if (
|
|
16075
|
+
if (spawnToolOrigin) {
|
|
16076
|
+
if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
16077
|
+
} else if (parentRemainder !== void 0) {
|
|
16053
16078
|
const fractionCap = this.childBudgetFraction * parentRemainder;
|
|
16054
16079
|
childCeilingUsd = spec.budgetUsd === void 0 ? fractionCap : Math.min(spec.budgetUsd, fractionCap);
|
|
16055
16080
|
} else if (spec.budgetUsd !== void 0) childCeilingUsd = spec.budgetUsd;
|
|
16056
16081
|
let reserveUsd = spec.estCostUsd ?? this.flatReserveUsd;
|
|
16057
|
-
|
|
16058
|
-
|
|
16082
|
+
const source = spec.estCostUsd === void 0 ? "default" : "estCost";
|
|
16083
|
+
let clampedBy;
|
|
16084
|
+
if (childCeilingUsd !== void 0 && reserveUsd > childCeilingUsd) {
|
|
16085
|
+
clampedBy = spec.budgetUsd !== void 0 && childCeilingUsd === spec.budgetUsd ? "explicit-budget" : "fraction-ceiling";
|
|
16086
|
+
reserveUsd = childCeilingUsd;
|
|
16087
|
+
}
|
|
16088
|
+
const reserve = {
|
|
16089
|
+
reserveUsd,
|
|
16090
|
+
source
|
|
16091
|
+
};
|
|
16092
|
+
if (clampedBy !== void 0) reserve.clampedBy = clampedBy;
|
|
16059
16093
|
if (childCeilingUsd !== void 0) reserve.childCeilingUsd = childCeilingUsd;
|
|
16060
16094
|
if (this.budget.spawnHeadroom <= 0) return {
|
|
16061
16095
|
verdict: {
|
|
@@ -19235,7 +19269,7 @@ function buildOrchestratorTools(runtime, profileCardText, options) {
|
|
|
19235
19269
|
for (const [index, task] of tasks.entries()) {
|
|
19236
19270
|
let spawned;
|
|
19237
19271
|
try {
|
|
19238
|
-
spawned = await runtime.spawn(task);
|
|
19272
|
+
spawned = await runtime.spawn(task, "parallel_agents");
|
|
19239
19273
|
} catch (thrown) {
|
|
19240
19274
|
const failure = {
|
|
19241
19275
|
index,
|
|
@@ -21860,8 +21894,16 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
21860
21894
|
};
|
|
21861
21895
|
const executionFactsEnabled = opts?.executionFacts === true;
|
|
21862
21896
|
const orchestratorRuntime = {
|
|
21863
|
-
async spawn(params) {
|
|
21897
|
+
async spawn(params, origin = "spawn_agent") {
|
|
21864
21898
|
await recoveryDone;
|
|
21899
|
+
if (origin === "spawn_agent" && opts?.requireBatchSpawn === "reject-spawn-agent") {
|
|
21900
|
+
internals.events.emit({
|
|
21901
|
+
type: "spawn:rejected",
|
|
21902
|
+
code: "batch_required",
|
|
21903
|
+
agentType: params.agentType
|
|
21904
|
+
}, callingState.spanId);
|
|
21905
|
+
throw new AdmissionRejectedError("orchestrate requireBatchSpawn 'reject-spawn-agent': single spawn_agent calls are refused; submit the whole wave as ONE parallel_agents call so the batch roster feasibility gate sees it entire", { data: { reason: { code: "batch_required" } } });
|
|
21906
|
+
}
|
|
21865
21907
|
const specKey = jcsSerialize(params);
|
|
21866
21908
|
const recoveredOrdinal = unclaimedRecoveredBySpec.get(specKey)?.shift();
|
|
21867
21909
|
if (recoveredOrdinal !== void 0) {
|
|
@@ -21895,14 +21937,20 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
21895
21937
|
const profile = Object.hasOwn(advertisedProfiles, params.agentType) ? advertisedProfiles[params.agentType] : void 0;
|
|
21896
21938
|
const profileModel = profile?.model;
|
|
21897
21939
|
if (profileModel !== void 0 && typeof profileModel !== "string" && "ladder" in profileModel) throw new ConfigError(`agentType '${params.agentType}' declares a ladder; ladder execution is owned by the plan extension, which resolves each rung attempt to a concrete model override; spawn a concrete profile instead`);
|
|
21940
|
+
const rosterFloor = (opts?.acceptance)?.minSpawnedChildren;
|
|
21898
21941
|
const decision = admission.admit({
|
|
21899
|
-
origin
|
|
21942
|
+
origin,
|
|
21900
21943
|
name: params.agentType,
|
|
21901
21944
|
childScope: scope,
|
|
21902
21945
|
parentAccountScope: callingState.budgetScope ?? "run",
|
|
21903
21946
|
nodeKey: scope,
|
|
21904
21947
|
...params.budgetUsd === void 0 ? {} : { budgetUsd: params.budgetUsd },
|
|
21905
21948
|
...profile?.estCost === void 0 ? {} : { estCostUsd: profile.estCost },
|
|
21949
|
+
...origin === "spawn_agent" && rosterFloor !== void 0 ? { roster: {
|
|
21950
|
+
floor: rosterFloor,
|
|
21951
|
+
admittedChildren: admittedSpawnCount,
|
|
21952
|
+
liveExposureUsd: internals.budget.liveExposureUsd
|
|
21953
|
+
} } : {},
|
|
21906
21954
|
...params.lineage === void 0 ? {} : { lineage: {
|
|
21907
21955
|
continues: params.lineage.continues,
|
|
21908
21956
|
causeRef: params.lineage.causeRef,
|
|
@@ -21916,7 +21964,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
21916
21964
|
}, { commitReserve: false });
|
|
21917
21965
|
const admissionValue = {
|
|
21918
21966
|
decisionType: "spawn-admission",
|
|
21919
|
-
origin
|
|
21967
|
+
origin,
|
|
21920
21968
|
orchestratorScope: scope,
|
|
21921
21969
|
spawnOrdinal,
|
|
21922
21970
|
name: params.agentType,
|
|
@@ -24726,6 +24774,7 @@ function preflightEstimate(input) {
|
|
|
24726
24774
|
}
|
|
24727
24775
|
const maxSpawns = input.orchestrator?.maxSpawns;
|
|
24728
24776
|
const orchestrateWave = input.orchestrator !== void 0;
|
|
24777
|
+
const liveRootExposureTermUsd = orchestrateWave ? units.find((unit) => unit.label === "orchestrator")?.turnFloorUsd ?? 0 : 0;
|
|
24729
24778
|
for (const [reportIndex, report] of spawnReports.entries()) {
|
|
24730
24779
|
const gate = waveGateInputs[reportIndex] ?? {};
|
|
24731
24780
|
for (let i = 0; i < report.count; i += 1) {
|
|
@@ -24736,7 +24785,7 @@ function preflightEstimate(input) {
|
|
|
24736
24785
|
else if (maxSpawns !== void 0 && children >= maxSpawns) deniedBy = "orchestrator-max-spawns";
|
|
24737
24786
|
else {
|
|
24738
24787
|
if (orchestrateWave && ceilingUsd !== void 0) {
|
|
24739
|
-
const remainder = ceilingUsd - heldAgainstRoot();
|
|
24788
|
+
const remainder = ceilingUsd - heldAgainstRoot() - liveRootExposureTermUsd;
|
|
24740
24789
|
const projection = dispatchProjectionReserveUsd(gate, flatReserveUsd);
|
|
24741
24790
|
if (remainder <= 0 || remainder <= projection) deniedBy = "budget";
|
|
24742
24791
|
}
|
|
@@ -24758,7 +24807,7 @@ function preflightEstimate(input) {
|
|
|
24758
24807
|
}
|
|
24759
24808
|
const admitted = wave.filter((row) => row.admitted).length;
|
|
24760
24809
|
const denied = wave.length - admitted;
|
|
24761
|
-
const requiredMinimumCeilingUsd = wave.length === 0 ? void 0 : wave.reduce((sum, row) => sum + row.reserveUsd, 0) + reservedForFinalizationUsd + synthesisHoldUsd;
|
|
24810
|
+
const requiredMinimumCeilingUsd = wave.length === 0 ? void 0 : wave.reduce((sum, row) => sum + row.reserveUsd, 0) + reservedForFinalizationUsd + synthesisHoldUsd + liveRootExposureTermUsd;
|
|
24762
24811
|
if (wave.length > 0 && denied > 0) {
|
|
24763
24812
|
const deniedLabels = wave.filter((row) => !row.admitted).map((row) => row.label);
|
|
24764
24813
|
if (admitted === 0) say({
|
|
@@ -25016,6 +25065,7 @@ function preflightEstimate(input) {
|
|
|
25016
25065
|
reservedForFinalizationUsd,
|
|
25017
25066
|
synthesisReserveUsd: synthesisHoldUsd,
|
|
25018
25067
|
...requiredMinimumCeilingUsd === void 0 ? {} : { requiredMinimumCeilingUsd },
|
|
25068
|
+
...liveRootExposureTermUsd > 0 ? { liveRootExposureTermUsd } : {},
|
|
25019
25069
|
wave,
|
|
25020
25070
|
admitted,
|
|
25021
25071
|
denied
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.207.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",
|