@rulvar/core 1.219.0 → 1.221.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 +18 -1
- package/dist/index.js +159 -27
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2162,7 +2162,15 @@ type CoreEvents = {
|
|
|
2162
2162
|
ran: boolean;
|
|
2163
2163
|
reason?: string;
|
|
2164
2164
|
};
|
|
2165
|
-
};
|
|
2165
|
+
};
|
|
2166
|
+
/**
|
|
2167
|
+
* The claim-consistency pass meta, lifted from the same envelope
|
|
2168
|
+
* (or typed error data) when it carries a valid object (RV2203);
|
|
2169
|
+
* `judgeDeclined` rides here on the failed terminals that used to
|
|
2170
|
+
* read null while the journal held the verdict.
|
|
2171
|
+
*/
|
|
2172
|
+
claimConsistencyMeta?: Record<string, unknown>; /** The synthesis-skip marker from the same envelope; same lift (RV2203). */
|
|
2173
|
+
synthesisSkipped?: boolean | string; /** Children accepted through validated terminal output salvage on 'limit'; same lift. */
|
|
2166
2174
|
salvagedTerminalOutputChildren?: string[];
|
|
2167
2175
|
/**
|
|
2168
2176
|
* Children that settled 'ok' below their declared evidence floor
|
|
@@ -11305,6 +11313,15 @@ type RunOutcome<R> = {
|
|
|
11305
11313
|
salvagedPartialChildren?: string[]; /** The explicit semantic pass summaries (RV1906); same lift and posture. */
|
|
11306
11314
|
semanticPasses?: SemanticPassesSummary;
|
|
11307
11315
|
/**
|
|
11316
|
+
* The claim-consistency pass meta (`judgeInvoked`, `judgeDeclined`,
|
|
11317
|
+
* the pair counts), lifted from the same envelope or typed error
|
|
11318
|
+
* data (RV2203). The RV2106 mirror run journaled its declined judge
|
|
11319
|
+
* and the error terminal carried null: the truth now rides every
|
|
11320
|
+
* terminal that has it, ok and failed alike.
|
|
11321
|
+
*/
|
|
11322
|
+
claimConsistencyMeta?: Record<string, unknown>; /** The synthesis-skip marker from the same envelope; same lift and posture (RV2203). */
|
|
11323
|
+
synthesisSkipped?: boolean | string;
|
|
11324
|
+
/**
|
|
11308
11325
|
* Children accepted through validated terminal output salvage on
|
|
11309
11326
|
* 'limit'; same lift and posture.
|
|
11310
11327
|
*/
|
package/dist/index.js
CHANGED
|
@@ -12604,6 +12604,102 @@ async function runAgent(options) {
|
|
|
12604
12604
|
resolved: options.resolved
|
|
12605
12605
|
}, ...options.fallbacks ?? []];
|
|
12606
12606
|
const loopCursor = { index: 0 };
|
|
12607
|
+
/**
|
|
12608
|
+
* The drained-finalization grant (RV2204, the third parity rerun).
|
|
12609
|
+
* The exposure drain is terminal mid-work: spend only grows, so a
|
|
12610
|
+
* seat refused with no live holder left can never dispatch an
|
|
12611
|
+
* ordinary turn again. The third parity rerun killed three workers
|
|
12612
|
+
* ~30 turns into research with evidence pools of 17 and 22 under a
|
|
12613
|
+
* floor of 24 and a CONFIGURED finalization window: the drain came
|
|
12614
|
+
* before the window, and the window's play needs the very wire the
|
|
12615
|
+
* drain refuses. With `limits.finalizationReserve.maxOutputTokens`
|
|
12616
|
+
* declared, a drained seat that already did work now spends ONE
|
|
12617
|
+
* clamped finalization turn before its typed terminal: the output
|
|
12618
|
+
* clamp shrinks the turn's exposure estimate (the full estimate was
|
|
12619
|
+
* refused; the clamped one prices the summary allowance instead of
|
|
12620
|
+
* the whole per-turn cap), the finalization-window allowlist rides
|
|
12621
|
+
* as the turn's only tools so outstanding record_evidence calls can
|
|
12622
|
+
* land in parallel, and the executed calls persist through the
|
|
12623
|
+
* ordinary tool machinery. Best effort, exactly like the tool-budget
|
|
12624
|
+
* reserve turn: a refusal of even the clamped estimate warns and
|
|
12625
|
+
* keeps the typed drained terminal; a seat with NO completed turns
|
|
12626
|
+
* keeps dying free (the RV2002 zero-cost doctrine: nothing to
|
|
12627
|
+
* summarize, nothing paid).
|
|
12628
|
+
*/
|
|
12629
|
+
let drainFinalizationRan = false;
|
|
12630
|
+
const runDrainFinalization = async (refusal) => {
|
|
12631
|
+
const allow = limits.finalizationWindow?.allow;
|
|
12632
|
+
const allowedTools = allow === void 0 ? void 0 : options.tools?.contracts.filter((contract) => allow.includes(contract.name));
|
|
12633
|
+
const toolsRide = allowedTools !== void 0 && allowedTools.length > 0;
|
|
12634
|
+
const drainMessages = [...messages, {
|
|
12635
|
+
role: "user",
|
|
12636
|
+
parts: [{
|
|
12637
|
+
type: "text",
|
|
12638
|
+
text: `The run's in-flight exposure pool is drained; no further ordinary turns can dispatch (${refusal}). This is your single finalization turn` + (toolsRide ? ": record any outstanding evidence with the allowed tools IN THIS turn (parallel calls), then close" : `: close`) + ` with your best final summary of the work already done.`
|
|
12639
|
+
}]
|
|
12640
|
+
}];
|
|
12641
|
+
let grant;
|
|
12642
|
+
try {
|
|
12643
|
+
grant = await dispatchPhase({
|
|
12644
|
+
role: primaryRole,
|
|
12645
|
+
chain: loopChain,
|
|
12646
|
+
cursor: loopCursor,
|
|
12647
|
+
requestFor: (target) => {
|
|
12648
|
+
let req = buildRequest(target.resolved, projectHistory(drainMessages, providerOf(target.adapter)), limits, toolsRide ? allowedTools : void 0);
|
|
12649
|
+
const reserveMax = limits.finalizationReserve?.maxOutputTokens;
|
|
12650
|
+
if (reserveMax !== void 0) req = {
|
|
12651
|
+
...req,
|
|
12652
|
+
maxOutputTokens: Math.min(req.maxOutputTokens ?? reserveMax, reserveMax)
|
|
12653
|
+
};
|
|
12654
|
+
req = applyCachePolicy(req, target, options.cache);
|
|
12655
|
+
return applyOutputBudget(req, target, options.budget);
|
|
12656
|
+
},
|
|
12657
|
+
streamOptionsFor: (target) => {
|
|
12658
|
+
const drainStreamOptions = {
|
|
12659
|
+
idleTimeoutMs: limits.streamIdleTimeoutMs,
|
|
12660
|
+
signals: options.signal === void 0 ? [] : [options.signal],
|
|
12661
|
+
onUsage: (delta) => options.budget?.onUsage(delta, target.resolved.ref)
|
|
12662
|
+
};
|
|
12663
|
+
if (options.budget?.signal !== void 0) drainStreamOptions.budgetSignal = options.budget.signal;
|
|
12664
|
+
if (options.stream === true) drainStreamOptions.onDelta = (delta) => events?.emit({
|
|
12665
|
+
type: "agent:stream",
|
|
12666
|
+
delta
|
|
12667
|
+
});
|
|
12668
|
+
return drainStreamOptions;
|
|
12669
|
+
}
|
|
12670
|
+
});
|
|
12671
|
+
} catch (grantThrown) {
|
|
12672
|
+
if (!(grantThrown instanceof BudgetExhaustedError)) throw grantThrown;
|
|
12673
|
+
events?.emit({
|
|
12674
|
+
type: "log",
|
|
12675
|
+
level: "warn",
|
|
12676
|
+
msg: `the drained-finalization turn was skipped: ${grantThrown.message}`
|
|
12677
|
+
});
|
|
12678
|
+
return;
|
|
12679
|
+
}
|
|
12680
|
+
const { outcome: grantOutcome, target: grantTarget } = grant;
|
|
12681
|
+
servedBy = grantTarget.resolved.ref;
|
|
12682
|
+
usageApprox = usageApprox || grantOutcome.usageApprox;
|
|
12683
|
+
messages.push(assistantMsg(grantOutcome.turn, liftRetainedParts(grantOutcome.providerMetadata, grantTarget.adapter)));
|
|
12684
|
+
if (toolsRide && grantOutcome.turn.toolCalls.length > 0) try {
|
|
12685
|
+
await runToolCalls(grantOutcome.turn.toolCalls, []);
|
|
12686
|
+
} catch (toolThrown) {
|
|
12687
|
+
events?.emit({
|
|
12688
|
+
type: "log",
|
|
12689
|
+
level: "warn",
|
|
12690
|
+
msg: `a drained-finalization tool call failed: ${toolThrown instanceof Error ? toolThrown.message : String(toolThrown)}`
|
|
12691
|
+
});
|
|
12692
|
+
}
|
|
12693
|
+
events?.emit({
|
|
12694
|
+
type: "log",
|
|
12695
|
+
level: "info",
|
|
12696
|
+
msg: "the drained seat spent its finalization turn",
|
|
12697
|
+
data: {
|
|
12698
|
+
toolCalls: grantOutcome.turn.toolCalls.length,
|
|
12699
|
+
outputTokens: grantOutcome.usage.outputTokens
|
|
12700
|
+
}
|
|
12701
|
+
});
|
|
12702
|
+
};
|
|
12607
12703
|
loop: while (status === "ok" && !finishedViaTool) {
|
|
12608
12704
|
if (limits.timeoutMs !== void 0 && now() - startedAt >= limits.timeoutMs) {
|
|
12609
12705
|
status = "limit";
|
|
@@ -12657,8 +12753,12 @@ async function runAgent(options) {
|
|
|
12657
12753
|
});
|
|
12658
12754
|
} catch (thrown) {
|
|
12659
12755
|
if (!(thrown instanceof BudgetExhaustedError)) throw thrown;
|
|
12660
|
-
status = "error";
|
|
12661
12756
|
const typedReason = thrown.data?.reason;
|
|
12757
|
+
if (typedReason === "exposure-drained" && limits.finalizationReserve !== void 0 && turns > 1 && !drainFinalizationRan) {
|
|
12758
|
+
drainFinalizationRan = true;
|
|
12759
|
+
await runDrainFinalization(thrown.message);
|
|
12760
|
+
}
|
|
12761
|
+
status = "error";
|
|
12662
12762
|
agentError = {
|
|
12663
12763
|
kind: "budget",
|
|
12664
12764
|
retryable: false,
|
|
@@ -24100,7 +24200,41 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24100
24200
|
}
|
|
24101
24201
|
});
|
|
24102
24202
|
};
|
|
24203
|
+
/**
|
|
24204
|
+
* The pass summaries as one builder (RV2203): the ok envelope and
|
|
24205
|
+
* the failure enrichment must tell the same {ran, reason} story,
|
|
24206
|
+
* with only the synthesis arm differing by path.
|
|
24207
|
+
*/
|
|
24208
|
+
const semanticPassesSummary = (synthesis) => ({
|
|
24209
|
+
contradictions: opts?.contradictions === void 0 ? {
|
|
24210
|
+
ran: false,
|
|
24211
|
+
reason: "not-configured"
|
|
24212
|
+
} : contradictionsFound === void 0 ? {
|
|
24213
|
+
ran: false,
|
|
24214
|
+
reason: "not-run"
|
|
24215
|
+
} : { ran: true },
|
|
24216
|
+
claimConsistency: opts?.claimConsistency === void 0 ? {
|
|
24217
|
+
ran: false,
|
|
24218
|
+
reason: "not-configured"
|
|
24219
|
+
} : claimConsistencyMeta === void 0 ? {
|
|
24220
|
+
ran: false,
|
|
24221
|
+
reason: "not-run"
|
|
24222
|
+
} : { ran: true },
|
|
24223
|
+
synthesis
|
|
24224
|
+
});
|
|
24103
24225
|
const enrichSynthesisFailure = (thrown, snapshot) => {
|
|
24226
|
+
const passTruth = {
|
|
24227
|
+
...claimConsistencyMeta === void 0 ? {} : { claimConsistencyMeta },
|
|
24228
|
+
semanticPasses: semanticPassesSummary({
|
|
24229
|
+
ran: false,
|
|
24230
|
+
reason: "synthesis-failed"
|
|
24231
|
+
})
|
|
24232
|
+
};
|
|
24233
|
+
if (thrown instanceof BudgetExhaustedError) throw new BudgetExhaustedError(thrown.message, { data: {
|
|
24234
|
+
...thrown.data ?? {},
|
|
24235
|
+
...snapshot ?? {},
|
|
24236
|
+
...passTruth
|
|
24237
|
+
} });
|
|
24104
24238
|
if (!(thrown instanceof FailRunError)) throw thrown;
|
|
24105
24239
|
const base = thrown.data ?? {};
|
|
24106
24240
|
const spent = validationDecisions().filter((candidate) => candidate.verdict !== "accepted" && contractGenerationCurrent(candidate));
|
|
@@ -24110,6 +24244,7 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24110
24244
|
throw new FailRunError(thrown.message, { data: {
|
|
24111
24245
|
...base,
|
|
24112
24246
|
...snapshot ?? {},
|
|
24247
|
+
...passTruth,
|
|
24113
24248
|
...spent.length === 0 || base.repairsUsed !== void 0 ? {} : {
|
|
24114
24249
|
repairsUsed: spent.length,
|
|
24115
24250
|
maxRepairs: validationSpec?.maxRepairs ?? 1,
|
|
@@ -24368,29 +24503,13 @@ function makeOrchestratorWorkflow(goal, opts) {
|
|
|
24368
24503
|
...claimFindingsFound === void 0 ? {} : { claimContradictions: claimFindingsFound },
|
|
24369
24504
|
claimConsistencyMeta
|
|
24370
24505
|
},
|
|
24371
|
-
semanticPasses: {
|
|
24372
|
-
|
|
24373
|
-
|
|
24374
|
-
|
|
24375
|
-
|
|
24376
|
-
|
|
24377
|
-
|
|
24378
|
-
} : { ran: true },
|
|
24379
|
-
claimConsistency: opts?.claimConsistency === void 0 ? {
|
|
24380
|
-
ran: false,
|
|
24381
|
-
reason: "not-configured"
|
|
24382
|
-
} : claimConsistencyMeta === void 0 ? {
|
|
24383
|
-
ran: false,
|
|
24384
|
-
reason: "not-run"
|
|
24385
|
-
} : { ran: true },
|
|
24386
|
-
synthesis: opts?.synthesis === void 0 ? {
|
|
24387
|
-
ran: false,
|
|
24388
|
-
reason: "not-configured"
|
|
24389
|
-
} : synthesisSkippedByValidDraft ? {
|
|
24390
|
-
ran: false,
|
|
24391
|
-
reason: "valid-draft"
|
|
24392
|
-
} : { ran: true }
|
|
24393
|
-
}
|
|
24506
|
+
semanticPasses: semanticPassesSummary(opts?.synthesis === void 0 ? {
|
|
24507
|
+
ran: false,
|
|
24508
|
+
reason: "not-configured"
|
|
24509
|
+
} : synthesisSkippedByValidDraft ? {
|
|
24510
|
+
ran: false,
|
|
24511
|
+
reason: "valid-draft"
|
|
24512
|
+
} : { ran: true })
|
|
24394
24513
|
};
|
|
24395
24514
|
};
|
|
24396
24515
|
return defineWorkflow({ name: ORCHESTRATE_WORKFLOW_NAME }, async (ctx) => {
|
|
@@ -24773,10 +24892,16 @@ function preflightEstimate(input) {
|
|
|
24773
24892
|
spawn: label
|
|
24774
24893
|
});
|
|
24775
24894
|
}
|
|
24776
|
-
if (limits.finalizationReserve !== void 0 && limits.maxToolCalls === void 0 && limits.toolUnits === void 0) say({
|
|
24895
|
+
if (limits.finalizationReserve !== void 0 && limits.maxToolCalls === void 0 && limits.toolUnits === void 0 && input.run?.maxInFlightExposureUsd === void 0) say({
|
|
24777
24896
|
severity: "warning",
|
|
24778
24897
|
code: "inert-finalization-reserve",
|
|
24779
|
-
message: `spawn '${label}' sets finalizationReserve without maxToolCalls or toolUnits: no tool budget limiter exists for it to fire on`,
|
|
24898
|
+
message: `spawn '${label}' sets finalizationReserve without maxToolCalls or toolUnits: no tool budget limiter exists for it to fire on, and no in-flight exposure cap is declared for the drained-finalization grant (RV2204) to spend it at`,
|
|
24899
|
+
spawn: label
|
|
24900
|
+
});
|
|
24901
|
+
if (limits.finalizationWindow !== void 0 && limits.finalizationReserve?.maxOutputTokens === void 0 && input.run?.maxInFlightExposureUsd !== void 0) say({
|
|
24902
|
+
severity: "info",
|
|
24903
|
+
code: "drained-finalization-unfunded",
|
|
24904
|
+
message: `spawn '${label}' declares finalizationWindow under an in-flight exposure cap but no finalizationReserve.maxOutputTokens: a mid-work exposure drain refuses the wire the window needs, and without the reserve's clamped turn the seat dies with its window unplayed (RV2204); declare the reserve to fund one drained-finalization turn`,
|
|
24780
24905
|
spawn: label
|
|
24781
24906
|
});
|
|
24782
24907
|
if (limits.toolBudgetNotices === true && limits.maxToolCalls === void 0) say({
|
|
@@ -26026,6 +26151,10 @@ function liftRunCompletion(candidate) {
|
|
|
26026
26151
|
synthesis: { ...synthesis }
|
|
26027
26152
|
};
|
|
26028
26153
|
}
|
|
26154
|
+
const metaCandidate = candidate.claimConsistencyMeta;
|
|
26155
|
+
if (typeof metaCandidate === "object" && metaCandidate !== null && !Array.isArray(metaCandidate)) lifted.claimConsistencyMeta = { ...metaCandidate };
|
|
26156
|
+
const skippedCandidate = candidate.synthesisSkipped;
|
|
26157
|
+
if (typeof skippedCandidate === "boolean" || typeof skippedCandidate === "string") lifted.synthesisSkipped = skippedCandidate;
|
|
26029
26158
|
return lifted;
|
|
26030
26159
|
}
|
|
26031
26160
|
/**
|
|
@@ -26576,7 +26705,8 @@ function createEngine(options) {
|
|
|
26576
26705
|
};
|
|
26577
26706
|
if (value !== void 0 && (status === "ok" || status === "exhausted")) outcomeFacts.value = value;
|
|
26578
26707
|
if (wireError !== void 0) outcomeFacts.error = wireError;
|
|
26579
|
-
|
|
26708
|
+
let lifted = liftRunCompletion(status === "ok" || status === "exhausted" ? outcomeFacts.value : status === "error" ? wireError?.data : void 0);
|
|
26709
|
+
if (lifted === void 0 && status === "exhausted") lifted = liftRunCompletion(wireError?.data);
|
|
26580
26710
|
if (lifted !== void 0) {
|
|
26581
26711
|
outcomeFacts.completion = lifted.completion;
|
|
26582
26712
|
if (lifted.childStatusCounts !== void 0) outcomeFacts.childStatusCounts = lifted.childStatusCounts;
|
|
@@ -26586,6 +26716,8 @@ function createEngine(options) {
|
|
|
26586
26716
|
if (lifted.belowFloorOkChildren !== void 0) outcomeFacts.belowFloorOkChildren = lifted.belowFloorOkChildren;
|
|
26587
26717
|
if (lifted.acceptanceChildren !== void 0) outcomeFacts.acceptanceChildren = lifted.acceptanceChildren;
|
|
26588
26718
|
if (lifted.semanticPasses !== void 0) outcomeFacts.semanticPasses = lifted.semanticPasses;
|
|
26719
|
+
if (lifted.claimConsistencyMeta !== void 0) outcomeFacts.claimConsistencyMeta = lifted.claimConsistencyMeta;
|
|
26720
|
+
if (lifted.synthesisSkipped !== void 0) outcomeFacts.synthesisSkipped = lifted.synthesisSkipped;
|
|
26589
26721
|
}
|
|
26590
26722
|
let settlementFailure;
|
|
26591
26723
|
let supersededBy;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.221.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",
|