@rulvar/core 1.199.0 → 1.201.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 CHANGED
@@ -9421,6 +9421,24 @@ interface OrchestrateOptions {
9421
9421
  */
9422
9422
  onUnsettledAtExit?: "cancel" | "drain";
9423
9423
  /**
9424
+ * The parallel_agents admission policy (RV1908). 'fail-fast' (the
9425
+ * default, the RV805 shape) admits in submission order and stops at
9426
+ * the first refusal, tasks after it never attempted. 'try-all'
9427
+ * attempts every task and reports every refusal, so one refused
9428
+ * sibling no longer hides whether the rest would seat. 'all-or-none'
9429
+ * projects the WHOLE batch against the live remainder first and
9430
+ * refuses it typed with zero admissions when it cannot seat
9431
+ * entirely; a non-budget failure mid-batch cancels the admitted
9432
+ * siblings, best-effort atomicity over a machinery that cannot
9433
+ * un-admit. Independent of the policy, a declared
9434
+ * acceptance.minSpawnedChildren arms the roster pre-check: a batch
9435
+ * large enough to seat the floor whose feasible count cannot reach
9436
+ * it is refused before paying for the first child, the four-role
9437
+ * benchmark's primary arm shape, where two workers were paid in
9438
+ * full and the settle verdict was bound to reject them.
9439
+ */
9440
+ parallelAdmission?: "fail-fast" | "try-all" | "all-or-none";
9441
+ /**
9424
9442
  * The opt in deterministic host validation of the finish result, with
9425
9443
  * bounded repair; see {@link FinishValidationSpec}.
9426
9444
  */
@@ -13331,7 +13349,21 @@ declare function buildOrchestratorTools(runtime: OrchestratorRuntime, profileCar
13331
13349
  * opted-in run's toolset hash and re-key their resumes, so the new
13332
13350
  * tool re-keys only runs that opt into IT.
13333
13351
  */
13334
- settledResultsTool?: boolean;
13352
+ settledResultsTool?: boolean; /** The parallel_agents admission policy (RV1908); default 'fail-fast'. */
13353
+ parallelAdmission?: "fail-fast" | "try-all" | "all-or-none";
13354
+ /**
13355
+ * The batch projection seam (RV1908): the live remainder and the
13356
+ * per-task dispatch projection the embedded gate itself uses, plus
13357
+ * the run's admitted-children count and the declared acceptance
13358
+ * roster floor. Runtime behavior only, never part of the tool
13359
+ * schema or description, so toolset hashes stay byte identical.
13360
+ */
13361
+ batchGate?: {
13362
+ rosterFloor?: number;
13363
+ admittedChildren: () => number;
13364
+ projectionUsd: (task: SpawnAgentParams) => number;
13365
+ remainderUsd: () => number | undefined;
13366
+ };
13335
13367
  }): ToolDef[];
13336
13368
  //#endregion
13337
13369
  //#region src/engine/events.d.ts
package/dist/index.js CHANGED
@@ -19058,23 +19058,77 @@ function buildOrchestratorTools(runtime, profileCardText, options) {
19058
19058
  parameters: PARALLEL_AGENTS_SCHEMA,
19059
19059
  execute: async (input) => {
19060
19060
  const tasks = input.tasks;
19061
+ const policy = options?.parallelAdmission ?? "fail-fast";
19062
+ const gate = options?.batchGate;
19063
+ if (gate !== void 0) {
19064
+ const remainder = gate.remainderUsd();
19065
+ if (remainder !== void 0) {
19066
+ let accumulated = 0;
19067
+ let feasible = 0;
19068
+ for (const task of tasks) {
19069
+ const projection = gate.projectionUsd(task);
19070
+ if (remainder < accumulated + projection) break;
19071
+ accumulated += projection;
19072
+ feasible += 1;
19073
+ }
19074
+ const admittedSoFar = gate.admittedChildren();
19075
+ const floor = gate.rosterFloor;
19076
+ if (floor !== void 0 && admittedSoFar + tasks.length >= floor && admittedSoFar + feasible < floor) return {
19077
+ handles: [],
19078
+ refused: {
19079
+ index: feasible,
19080
+ code: "roster_floor",
19081
+ reason: `the batch can seat ${String(feasible)} of its ${String(tasks.length)} tasks under the live remainder, and the ${String(admittedSoFar)} already admitted cannot reach acceptance.minSpawnedChildren ${String(floor)}: refused before paying for a roster the settle verdict is bound to reject`
19082
+ }
19083
+ };
19084
+ if (policy === "all-or-none" && feasible < tasks.length) return {
19085
+ handles: [],
19086
+ refused: {
19087
+ index: feasible,
19088
+ code: "batch_atomic",
19089
+ reason: `all-or-none: the batch's ${String(tasks.length)} reserves do not fit the live remainder ${remainder.toFixed(4)} USD (${String(feasible)} would seat); nothing was admitted and nothing was paid`
19090
+ }
19091
+ };
19092
+ }
19093
+ }
19061
19094
  const handles = [];
19095
+ const refusals = [];
19062
19096
  for (const [index, task] of tasks.entries()) {
19063
19097
  let spawned;
19064
19098
  try {
19065
19099
  spawned = await runtime.spawn(task);
19066
19100
  } catch (thrown) {
19101
+ const failure = {
19102
+ index,
19103
+ ...thrown instanceof RulvarError ? { code: thrown.code } : {},
19104
+ reason: thrown instanceof Error ? thrown.message : String(thrown)
19105
+ };
19106
+ if (policy === "try-all") {
19107
+ refusals.push(failure);
19108
+ continue;
19109
+ }
19110
+ if (policy === "all-or-none" && handles.length > 0) {
19111
+ for (const handle of handles) await runtime.cancel(handle, "rulvar:batch-atomic-rollback");
19112
+ return {
19113
+ handles: [],
19114
+ refused: {
19115
+ ...failure,
19116
+ reason: `all-or-none: task ${String(index)} failed after ${String(handles.length)} sibling(s) were admitted; the siblings were cancelled (${failure.reason})`
19117
+ }
19118
+ };
19119
+ }
19067
19120
  return {
19068
19121
  handles,
19069
- refused: {
19070
- index,
19071
- ...thrown instanceof RulvarError ? { code: thrown.code } : {},
19072
- reason: thrown instanceof Error ? thrown.message : String(thrown)
19073
- }
19122
+ refused: failure
19074
19123
  };
19075
19124
  }
19076
19125
  handles.push(spawned.handle);
19077
19126
  }
19127
+ if (refusals.length > 0) return {
19128
+ handles,
19129
+ refused: refusals[0],
19130
+ refusals
19131
+ };
19078
19132
  return { handles };
19079
19133
  }
19080
19134
  });
@@ -20817,6 +20871,7 @@ function validateOrchestrateOptions(opts) {
20817
20871
  if (opts.maxSpawns !== void 0) requireNonNegativeInteger(opts.maxSpawns, "orchestrate maxSpawns");
20818
20872
  if (opts.renderBudgetChars !== void 0) requireNonNegativeInteger(opts.renderBudgetChars, "orchestrate renderBudgetChars");
20819
20873
  if (opts.onUnsettledAtExit !== void 0 && opts.onUnsettledAtExit !== "cancel" && opts.onUnsettledAtExit !== "drain") throw new ConfigError(`orchestrate onUnsettledAtExit must be 'cancel' or 'drain'; got ${String(opts.onUnsettledAtExit)}`);
20874
+ if (opts.parallelAdmission !== void 0 && opts.parallelAdmission !== "fail-fast" && opts.parallelAdmission !== "try-all" && opts.parallelAdmission !== "all-or-none") throw new ConfigError(`orchestrate parallelAdmission must be 'fail-fast', 'try-all' or 'all-or-none'; got ${String(opts.parallelAdmission)}`);
20820
20875
  if (opts.acceptance !== void 0) {
20821
20876
  const policy = opts.acceptance.childPolicy;
20822
20877
  const minSuccessful = typeof policy === "object" && policy !== null && !Array.isArray(policy) ? policy.minSuccessful : void 0;
@@ -22036,7 +22091,20 @@ function makeOrchestratorWorkflow(goal, opts) {
22036
22091
  const tools = [...buildOrchestratorTools(orchestratorRuntime, fullCardText, {
22037
22092
  childResultTools: opts?.exposeChildResultTools === true,
22038
22093
  settledResultsTool: opts?.exposeSettledResultsTool === true,
22039
- sectionalFinish: coordSectionalFinish
22094
+ sectionalFinish: coordSectionalFinish,
22095
+ ...opts?.parallelAdmission === void 0 ? {} : { parallelAdmission: opts.parallelAdmission },
22096
+ batchGate: {
22097
+ ...(opts?.acceptance)?.minSpawnedChildren === void 0 ? {} : { rosterFloor: (opts?.acceptance)?.minSpawnedChildren },
22098
+ admittedChildren: () => admittedSpawnCount,
22099
+ projectionUsd: (task) => {
22100
+ const profile = internals.defaults.profiles?.[task.agentType];
22101
+ return admission.projectedDispatchReserveUsd({
22102
+ ...profile?.estCost === void 0 ? {} : { estCostUsd: profile.estCost },
22103
+ ...task.budgetUsd === void 0 ? {} : { budgetUsd: task.budgetUsd }
22104
+ });
22105
+ },
22106
+ remainderUsd: () => internals.budget.remainderOf(callingState.budgetScope ?? "run")
22107
+ }
22040
22108
  }), ...extension?.tools(io) ?? []];
22041
22109
  /**
22042
22110
  * The RV-204 finish validation hook, installed on the terminal tool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.199.0",
3
+ "version": "1.201.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",