@wrongstack/core 0.308.7 → 0.309.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.
@@ -11592,7 +11592,7 @@ function resolveReasoningForRequest(settings, rc, warnings) {
11592
11592
  const cfg = settings.reasoning;
11593
11593
  if (!cfg) return void 0;
11594
11594
  const capKnown = rc !== void 0;
11595
- const supportsReasoning = rc ? rc.default !== "disabled" || rc.disableSupported || rc.effortSupported : false;
11595
+ const supportsReasoning = rc ? rc.default !== "disabled" || rc.disableSupported || rc.effortSupported !== false : false;
11596
11596
  const out = {};
11597
11597
  if (cfg.mode === "off") {
11598
11598
  if (capKnown && rc?.disableSupported) {
@@ -11614,14 +11614,17 @@ function resolveReasoningForRequest(settings, rc, warnings) {
11614
11614
  }
11615
11615
  const effort = cfg.effort;
11616
11616
  if (effort !== void 0) {
11617
- if (capKnown && rc?.effortSupported && rc.effortLevels.includes(effort)) {
11618
- out.effort = effort;
11619
- } else if (capKnown && rc?.effortSupported) {
11617
+ if (!capKnown) {
11618
+ } else if (rc?.effortSupported === false) {
11619
+ warnings.push(
11620
+ `reasoning effort "${effort}" requested, but this model does not support effort control; the setting was omitted.`
11621
+ );
11622
+ } else if (rc?.effortSupported === true && rc.effortLevels.length > 0 && !rc.effortLevels.includes(effort)) {
11620
11623
  warnings.push(
11621
11624
  `reasoning effort "${effort}" not supported by this model (supported: ${rc.effortLevels.join(", ")}); the setting was omitted.`
11622
11625
  );
11623
- } else if (capKnown) {
11624
- warnings.push(`reasoning effort "${effort}" requested, but this model does not support effort; the setting was omitted.`);
11626
+ } else {
11627
+ out.effort = effort;
11625
11628
  }
11626
11629
  }
11627
11630
  if (cfg.preserve !== void 0) {
@@ -11973,6 +11976,46 @@ function asTextBlocks(system) {
11973
11976
  // src/execution/parallel-eternal-engine.ts
11974
11977
  import { randomUUID as randomUUID2 } from "node:crypto";
11975
11978
 
11979
+ // src/core/btw.ts
11980
+ var META_KEY2 = "_btwNotes";
11981
+ var MAX_PENDING = 20;
11982
+ function readQueue(ctx) {
11983
+ const raw = ctx.meta[META_KEY2];
11984
+ return Array.isArray(raw) ? raw : [];
11985
+ }
11986
+ function setBtwNote(ctx, text) {
11987
+ const trimmed = text.trim();
11988
+ if (!trimmed) return readQueue(ctx).length;
11989
+ const next = [...readQueue(ctx), trimmed].slice(-MAX_PENDING);
11990
+ ctx.meta[META_KEY2] = next;
11991
+ return next.length;
11992
+ }
11993
+
11994
+ // src/coordination/subagent-finish.ts
11995
+ var SUBAGENT_FINISH_REQUESTED_EVENT = "subagent.finish_requested";
11996
+ var DEFAULT_SUBAGENT_FINISH_GRACE_MS = 12e4;
11997
+ function resolveGracefulFinish(config) {
11998
+ const raw = config.gracefulFinish;
11999
+ if (raw === void 0 || raw === false) return void 0;
12000
+ if (raw === true) return { graceMs: DEFAULT_SUBAGENT_FINISH_GRACE_MS };
12001
+ const graceMs = typeof raw.graceMs === "number" && Number.isFinite(raw.graceMs) && raw.graceMs > 0 ? Math.floor(raw.graceMs) : DEFAULT_SUBAGENT_FINISH_GRACE_MS;
12002
+ return { graceMs };
12003
+ }
12004
+ function buildSubagentFinishNotice(input) {
12005
+ const localTime = new Date(input.deadlineMs).toISOString();
12006
+ const seconds = Math.max(1, Math.round(input.graceMs / 1e3));
12007
+ const timeLeft = input.graceMs > 0 ? `You have roughly ${seconds} seconds (until ${localTime}) of legitimate working time left.` : `Your working-time window is already spent (deadline was ${localTime}) \u2014 finish now.`;
12008
+ return [
12009
+ "[SUBAGENT FINISH] The leader agent has finished its work.",
12010
+ `Reason: ${input.reason}`,
12011
+ timeLeft,
12012
+ "Finish your task now, in this turn: complete the thought you are working on, stop",
12013
+ "starting new tool calls unless one is strictly required to finish, and write your",
12014
+ "final answer or report as your final output, then end your turn.",
12015
+ "Do not restart the task and do not begin new work."
12016
+ ].join("\n");
12017
+ }
12018
+
11976
12019
  // src/coordination/subagent-budget.ts
11977
12020
  var TIMEOUT_PREEMPT_FRACTION = 0.85;
11978
12021
  var DECISION_TIMEOUT_MS = 6e4;
@@ -12030,6 +12073,82 @@ var SubagentBudget = class _SubagentBudget {
12030
12073
  this.limits.idleTimeoutMs = ext.idleTimeoutMs;
12031
12074
  }
12032
12075
  }
12076
+ /**
12077
+ * Graceful-finish state (see coordination/subagent-finish.ts).
12078
+ * `_finishNotified` guards the single in-band emission; `_grace` records a
12079
+ * granted working-time extension past the original wall-clock deadline.
12080
+ * They are separate because the two callers want different semantics:
12081
+ * the watchdog grants grace at the deadline crossing (notify + extend),
12082
+ * while an explicit leader-finished request only notifies — a subagent
12083
+ * well inside its budget keeps its full legitimate working time and simply
12084
+ * accelerates.
12085
+ */
12086
+ _finishNotified = false;
12087
+ _grace = null;
12088
+ /** True once the in-band finish notification has been emitted. */
12089
+ get finishNotified() {
12090
+ return this._finishNotified;
12091
+ }
12092
+ /** True once a grace window has been granted past the original deadline. */
12093
+ get graceGranted() {
12094
+ return this._grace !== null;
12095
+ }
12096
+ /**
12097
+ * Notify the subagent in-band to finish its task in its own turn:
12098
+ * `subagent.finish_requested` is emitted on the wired EventBus and the
12099
+ * agent loop folds the notice into the conversation between tool batches.
12100
+ * Nothing aborts — this is a notification, never an interrupt.
12101
+ *
12102
+ * `opts.graceMs` additionally extends the wall-clock ceiling by that window
12103
+ * (used by the watchdog at a deadline crossing, so the model gets working
12104
+ * time instead of a kill). Omit it to notify without touching the budget —
12105
+ * the subagent keeps its existing time budget and just accelerates.
12106
+ *
12107
+ * Returns `true` when this call did something (emitted the notification
12108
+ * and/or granted grace); `false` when there was nothing to do (already
12109
+ * notified, grace already granted, no EventBus wired, budget not started).
12110
+ */
12111
+ notifyFinish(reason, opts, now = Date.now) {
12112
+ if (!this._events) return false;
12113
+ if (this.startTime === null) return false;
12114
+ const shouldEmit = !this._finishNotified;
12115
+ const rawGrace = opts?.graceMs;
12116
+ const shouldGrant = rawGrace !== void 0 && this._grace === null;
12117
+ if (!shouldEmit && !shouldGrant) return false;
12118
+ let grantedGraceMs = 0;
12119
+ let graceDeadlineMs;
12120
+ if (shouldGrant && rawGrace !== void 0) {
12121
+ grantedGraceMs = Number.isFinite(rawGrace) && rawGrace > 0 ? Math.floor(rawGrace) : DEFAULT_SUBAGENT_FINISH_GRACE_MS;
12122
+ graceDeadlineMs = now() + grantedGraceMs;
12123
+ this._grace = { deadlineMs: graceDeadlineMs, graceMs: grantedGraceMs };
12124
+ this.patchLimits({ timeoutMs: graceDeadlineMs - this.startTime });
12125
+ }
12126
+ if (shouldEmit) {
12127
+ this._finishNotified = true;
12128
+ const effectiveDeadlineMs = graceDeadlineMs ?? (this.limits.timeoutMs !== void 0 ? this.startTime + this.limits.timeoutMs : now() + DEFAULT_SUBAGENT_FINISH_GRACE_MS);
12129
+ const effectiveGraceMs = Math.max(0, effectiveDeadlineMs - now());
12130
+ const subagentId = this._subagentId;
12131
+ this._events.emit(SUBAGENT_FINISH_REQUESTED_EVENT, {
12132
+ // Omitted entirely when the budget was built without an id — an
12133
+ // empty string is an address that matches nothing.
12134
+ ...subagentId !== void 0 ? { subagentId } : {},
12135
+ reason,
12136
+ deadlineMs: effectiveDeadlineMs,
12137
+ graceMs: effectiveGraceMs,
12138
+ notice: buildSubagentFinishNotice({
12139
+ reason,
12140
+ deadlineMs: effectiveDeadlineMs,
12141
+ graceMs: effectiveGraceMs
12142
+ })
12143
+ });
12144
+ }
12145
+ return true;
12146
+ }
12147
+ /** Epoch ms by which the subagent should have produced its final output,
12148
+ * once a grace window was granted. Undefined before that. */
12149
+ get finishDeadlineMs() {
12150
+ return this._grace?.deadlineMs;
12151
+ }
12033
12152
  iterations = 0;
12034
12153
  toolCalls = 0;
12035
12154
  tokenInput = 0;
@@ -12045,6 +12164,10 @@ var SubagentBudget = class _SubagentBudget {
12045
12164
  lastActivityTime = null;
12046
12165
  _onThreshold;
12047
12166
  _sessionId;
12167
+ /** Owning subagent id — used to address the graceful-finish event. */
12168
+ _subagentId;
12169
+ /** True when only the coordinator watchdog may enforce wall-clock limits. */
12170
+ _wallClockWatchdogOwned;
12048
12171
  /**
12049
12172
  * Hard cap on how long `_negotiateExtension` waits for the coordinator to
12050
12173
  * respond before defaulting to 'stop'. Without this fallback an absent
@@ -12116,6 +12239,8 @@ var SubagentBudget = class _SubagentBudget {
12116
12239
  constructor(limits = {}, mode = "auto", options = {}) {
12117
12240
  this._mode = mode;
12118
12241
  this._sessionId = options.sessionId;
12242
+ this._subagentId = options.subagentId;
12243
+ this._wallClockWatchdogOwned = options.wallClockWatchdogOwned === true;
12119
12244
  this.limits = { ...limits };
12120
12245
  }
12121
12246
  currentSessionId() {
@@ -12194,7 +12319,7 @@ var SubagentBudget = class _SubagentBudget {
12194
12319
  if (this.limits.idleTimeoutMs !== void 0 && idle > this.limits.idleTimeoutMs) {
12195
12320
  exceeded.push({ kind: "idle_timeout", used: idle, limit: this.limits.idleTimeoutMs });
12196
12321
  }
12197
- const wallOwnedByWatchdog = this._onThreshold !== void 0 && this._watchdogActive === this.limits.timeoutMs;
12322
+ const wallOwnedByWatchdog = this._wallClockWatchdogOwned || this._onThreshold !== void 0 && this._watchdogActive === this.limits.timeoutMs;
12198
12323
  if (this.limits.timeoutMs !== void 0 && elapsedMs > this.limits.timeoutMs && !wallOwnedByWatchdog) {
12199
12324
  exceeded.push({ kind: "timeout", used: elapsedMs, limit: this.limits.timeoutMs });
12200
12325
  }
@@ -12393,7 +12518,7 @@ var SubagentBudget = class _SubagentBudget {
12393
12518
  if (timeoutMs === void 0 && idleTimeoutMs === void 0) return;
12394
12519
  const elapsed = Date.now() - this.startTime;
12395
12520
  const wallSkipped = this._onThreshold !== void 0 && this._watchdogActive !== void 0 && timeoutMs !== void 0 && this._watchdogActive === timeoutMs;
12396
- const wallTripped = wallSkipped ? false : timeoutMs !== void 0 && elapsed > timeoutMs;
12521
+ const wallTripped = this._wallClockWatchdogOwned || wallSkipped ? false : timeoutMs !== void 0 && elapsed > timeoutMs;
12397
12522
  const idleTripped = idleTimeoutMs !== void 0 && this.idleMs() > idleTimeoutMs;
12398
12523
  if (!wallTripped && !idleTripped) return;
12399
12524
  void this.checkLimits(elapsed);
@@ -12769,6 +12894,14 @@ function makeAgentSubagentRunner(opts) {
12769
12894
  );
12770
12895
  const onParentAbort = () => aborter.abort();
12771
12896
  ctx.signal.addEventListener("abort", onParentAbort);
12897
+ if (resolveGracefulFinish(ctx.config)) {
12898
+ unsub.push(
12899
+ events.on("subagent.finish_requested", (e) => {
12900
+ if (e.subagentId && e.subagentId !== ctx.subagentId) return;
12901
+ setBtwNote(agent.ctx, e.notice);
12902
+ })
12903
+ );
12904
+ }
12772
12905
  let result;
12773
12906
  try {
12774
12907
  result = await agent.run(format(task, ctx.config), { signal: aborter.signal });
@@ -16960,6 +17093,20 @@ var EXPLORE_COMPANION_AGENT = {
16960
17093
  textStream: "silent",
16961
17094
  toolStream: "silent"
16962
17095
  };
17096
+ var CHAOS_MONKEY_AGENT = {
17097
+ ...defineAgent("chaos-monkey", "Chaos Monkey"),
17098
+ tools: [...TOOLS.build],
17099
+ skillNames: ["testing", "typescript-strict"],
17100
+ spawnBudgetExempt: true,
17101
+ // Follow fleet worktree policy (NOT 'required'): mutation targets are
17102
+ // often freshly written and uncommitted — a worktree spawned from HEAD
17103
+ // would not contain them and every mutant would drift. Callers pass
17104
+ // `worktree: 'off'` in the mutation_test input for uncommitted targets.
17105
+ worktree: "auto",
17106
+ // Report travels via submit_result + final text, not the leader's stream.
17107
+ textStream: "silent",
17108
+ toolStream: "silent"
17109
+ };
16963
17110
  var CRITIC_AGENT = defineAgent("critic", "Critic");
16964
17111
  var GENERIC_AGENT = defineAgent("generic", "Generic Project Agent");
16965
17112
  function withDispatchMetadata(definition) {
@@ -16979,6 +17126,7 @@ var FLEET_ROSTER = {
16979
17126
  generic: GENERIC_AGENT,
16980
17127
  "shadow-agent": SHADOW_AGENT,
16981
17128
  "explore-companion": EXPLORE_COMPANION_AGENT,
17129
+ "chaos-monkey": CHAOS_MONKEY_AGENT,
16982
17130
  ...Object.fromEntries(
16983
17131
  ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, withDispatchMetadata(d)])
16984
17132
  )
@@ -17009,6 +17157,16 @@ var FLEET_ROSTER_BUDGETS = {
17009
17157
  maxTokens: 96e3,
17010
17158
  maxCostUsd: 0.5
17011
17159
  },
17160
+ "chaos-monkey": {
17161
+ // A mutation pass is many short apply/run/restore cycles — per-mutant
17162
+ // work is tiny, but a large plan (25 mutants/file × N files) needs
17163
+ // headroom. Idle-based reaping covers a stalled pass.
17164
+ idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
17165
+ maxIterations: 2e3,
17166
+ maxToolCalls: 6e3,
17167
+ maxTokens: 96e3,
17168
+ maxCostUsd: 0.5
17169
+ },
17012
17170
  ...Object.fromEntries(
17013
17171
  ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, d.budget])
17014
17172
  )
@@ -17178,7 +17336,8 @@ async function executeSubagentWithTimeout({
17178
17336
  budget,
17179
17337
  preemptFraction = TIMEOUT_PREEMPT_FRACTION,
17180
17338
  abortSubagent,
17181
- currentSessionId
17339
+ currentSessionId,
17340
+ gracefulFinish
17182
17341
  }) {
17183
17342
  const initialTimeoutMs = budget.limits.timeoutMs;
17184
17343
  const idleLimitMs = budget.limits.idleTimeoutMs;
@@ -17209,9 +17368,17 @@ async function executeSubagentWithTimeout({
17209
17368
  const scheduleNext = () => {
17210
17369
  const wallLimit = budget.limits.timeoutMs ?? initialTimeoutMs;
17211
17370
  const wallRemaining = initialTimeoutMs === void 0 ? Number.POSITIVE_INFINITY : wallLimit - (Date.now() - start);
17212
- const idleRemaining = idleLimitMs === void 0 ? Number.POSITIVE_INFINITY : (budget.limits.idleTimeoutMs ?? idleLimitMs) - budget.idleMs();
17213
- const preemptRemaining = initialTimeoutMs === void 0 || preemptedCeiling === wallLimit ? Number.POSITIVE_INFINITY : wallLimit * preemptFraction - (Date.now() - start);
17214
- armFor(Math.max(25, Math.min(wallRemaining, idleRemaining, preemptRemaining)));
17371
+ const idleRemaining = idleLimitMs === void 0 || gracefulFinish !== void 0 && initialTimeoutMs !== void 0 ? Number.POSITIVE_INFINITY : (budget.limits.idleTimeoutMs ?? idleLimitMs) - budget.idleMs();
17372
+ const preemptRemaining = initialTimeoutMs === void 0 || preemptedCeiling === wallLimit || gracefulFinish !== void 0 ? Number.POSITIVE_INFINITY : wallLimit * preemptFraction - (Date.now() - start);
17373
+ const next = Math.min(wallRemaining, idleRemaining, preemptRemaining);
17374
+ if (!Number.isFinite(next)) {
17375
+ if (timer) {
17376
+ clearTimeout(timer);
17377
+ timer = null;
17378
+ }
17379
+ return;
17380
+ }
17381
+ armFor(Math.max(25, next));
17215
17382
  };
17216
17383
  const negotiateTimeout = async (used, limit) => {
17217
17384
  const handler = budget.onThreshold;
@@ -17260,6 +17427,10 @@ async function executeSubagentWithTimeout({
17260
17427
  const wallExceeded = wallLimit !== void 0 && elapsed >= wallLimit;
17261
17428
  const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
17262
17429
  if (idleExceeded && !wallExceeded) {
17430
+ if (gracefulFinish !== void 0 && initialTimeoutMs !== void 0) {
17431
+ scheduleNext();
17432
+ return;
17433
+ }
17263
17434
  const sessionId = currentSessionId();
17264
17435
  budget._events?.emit("budget.threshold_reached", {
17265
17436
  ...sessionId ? { sessionId } : {},
@@ -17276,7 +17447,7 @@ async function executeSubagentWithTimeout({
17276
17447
  reject(new BudgetExceededError("idle_timeout", idleLimit ?? 0, budget.idleMs()));
17277
17448
  return;
17278
17449
  }
17279
- if (wallLimit !== void 0 && !wallExceeded && budget.onThreshold && preemptState === "active" /* ACTIVE */ && elapsed >= wallLimit * preemptFraction) {
17450
+ if (wallLimit !== void 0 && !wallExceeded && gracefulFinish === void 0 && budget.onThreshold && preemptState === "active" /* ACTIVE */ && elapsed >= wallLimit * preemptFraction) {
17280
17451
  const activityTs = Date.now() - budget.idleMs();
17281
17452
  if (activityTs <= lastGrantActivityTs) {
17282
17453
  preemptState = "locked" /* LOCKED */;
@@ -17310,6 +17481,22 @@ async function executeSubagentWithTimeout({
17310
17481
  return;
17311
17482
  }
17312
17483
  const limit = wallLimit ?? 0;
17484
+ if (gracefulFinish !== void 0) {
17485
+ if (!budget.graceGranted) {
17486
+ const reason = `wall-clock budget of ${Math.round(limit / 1e3)}s reached`;
17487
+ if (budget.notifyFinish(reason, { graceMs: gracefulFinish.graceMs })) {
17488
+ scheduleNext();
17489
+ return;
17490
+ }
17491
+ abortSubagent(ctx.subagentId);
17492
+ reject(new BudgetExceededError("timeout", limit, elapsed));
17493
+ return;
17494
+ } else {
17495
+ abortSubagent(ctx.subagentId);
17496
+ reject(new BudgetExceededError("timeout", limit, elapsed));
17497
+ return;
17498
+ }
17499
+ }
17313
17500
  if (!budget.onThreshold) {
17314
17501
  abortSubagent(ctx.subagentId);
17315
17502
  reject(new BudgetExceededError("timeout", limit, elapsed));
@@ -17694,6 +17881,32 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
17694
17881
  completeTask(result) {
17695
17882
  this.recordCompletion(result);
17696
17883
  }
17884
+ /**
17885
+ * Ask every RUNNING subagent that opted into `gracefulFinish` to finish its
17886
+ * task in its own turn (see coordination/subagent-finish.ts). This is the
17887
+ * leader-side entry point for "the leader agent has finished": it delivers
17888
+ * an in-band notification between tool batches — never an interrupt, never
17889
+ * an abort. Each notified subagent keeps its existing time budget and
17890
+ * accelerates; the watchdog still bounds the maximum lifetime.
17891
+ *
17892
+ * Subagents without the policy opted in are deliberately untouched — their
17893
+ * lifecycle remains the legacy watchdog contract.
17894
+ *
17895
+ * Returns the number of subagents actually notified.
17896
+ */
17897
+ requestFinish(reason) {
17898
+ let notified = 0;
17899
+ for (const subagent of this.subagents.values()) {
17900
+ if (subagent.status !== "running") continue;
17901
+ if (!resolveGracefulFinish(subagent.config)) continue;
17902
+ const budget = subagent.activeBudget;
17903
+ if (!budget) continue;
17904
+ const usage = budget.usage();
17905
+ if (usage.iterations === 0 && usage.toolCalls === 0) continue;
17906
+ if (budget.notifyFinish(reason)) notified++;
17907
+ }
17908
+ return notified;
17909
+ }
17697
17910
  // --- internal dispatching ---------------------------------------------
17698
17911
  tryDispatchNext() {
17699
17912
  while (this.canDispatch()) {
@@ -17867,7 +18080,14 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
17867
18080
  idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
17868
18081
  },
17869
18082
  "auto",
17870
- { sessionId: () => this.currentSessionId() }
18083
+ {
18084
+ sessionId: () => this.currentSessionId(),
18085
+ subagentId,
18086
+ // Graceful-finish runs own wall-clock enforcement to the watchdog so
18087
+ // the notify-then-bound lifecycle cannot be raced by tool.progress
18088
+ // heartbeats calling checkTimeout() (see subagent-budget.ts).
18089
+ ...resolveGracefulFinish(subagent.config) ? { wallClockWatchdogOwned: true } : {}
18090
+ }
17871
18091
  );
17872
18092
  subagent.activeBudget = budget;
17873
18093
  if (!this.runner) {
@@ -17900,7 +18120,8 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
17900
18120
  task,
17901
18121
  runCtx,
17902
18122
  budget,
17903
- subagent.config.preemptFraction
18123
+ subagent.config.preemptFraction,
18124
+ resolveGracefulFinish(subagent.config)
17904
18125
  );
17905
18126
  result = {
17906
18127
  subagentId,
@@ -17930,13 +18151,14 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
17930
18151
  }
17931
18152
  this.recordCompletion(result);
17932
18153
  }
17933
- async executeWithTimeout(runner, task, ctx, budget, preemptFraction) {
18154
+ async executeWithTimeout(runner, task, ctx, budget, preemptFraction, gracefulFinish) {
17934
18155
  return executeSubagentWithTimeout({
17935
18156
  runner,
17936
18157
  task,
17937
18158
  ctx,
17938
18159
  budget,
17939
18160
  preemptFraction,
18161
+ gracefulFinish,
17940
18162
  abortSubagent: (subagentId) => this.subagents.get(subagentId)?.abortController.abort(),
17941
18163
  currentSessionId: () => this.currentSessionId()
17942
18164
  });
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export { DEPENDENCY_FILE_PATTERNS, type DependencyWatcherConfig, type DepWatchEn
16
16
  export { attachDepWatcherBridge, type DepWatcherBridgeOptions, } from './coordination/dep-watcher-bridge.js';
17
17
  export { Director, FleetCostCapError, FleetSpawnBudgetError, FleetTokenCapError, type TaskResultNotification, } from './coordination/director.js';
18
18
  export { type DirectorSessionFactory, type DirectorSessionFactoryOptions, makeDirectorSessionFactory, } from './coordination/director-session.js';
19
- export { makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeFleetEmitTool, makeFleetTool, makeKanbanQueueTool, makeQualityGateTool, makeRollUpTool, makeSpawnTool, makeTerminateTool, } from './coordination/director-tools.js';
19
+ export { makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeFleetEmitTool, makeFleetTool, makeKanbanQueueTool, makeMutationTestTool, makeQualityGateTool, makeRollUpTool, makeSpawnTool, makeTerminateTool, } from './coordination/director-tools.js';
20
20
  export { DEFAULT_DISPATCH_ROLE, type DispatchCandidate, type DispatchClassifier, type DispatchMethod, type DispatchOptions, type DispatchResult, dispatchAgent, makeLLMClassifier, scoreAgents, } from './coordination/dispatcher.js';
21
21
  export { compactLog, type FileAuthorEntry, type FileAuthorLog, type FileAuthorTrackerOptions, getFileHistory, getFilesByAgent, getFullLog, getLastAuthor, recordFileAction, } from './coordination/file-author-tracker.js';
22
22
  export { ACP_AGENTS, ALL_FLEET_AGENTS, applyRosterBudget, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, type FleetRosterBudget, } from './coordination/fleet.js';