@tangle-network/agent-eval 0.126.0 → 0.126.2

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.
@@ -95,11 +95,22 @@ function finiteOrZero(value) {
95
95
  return Number.isFinite(value) ? value : 0;
96
96
  }
97
97
 
98
+ // src/abort-signal.ts
99
+ function combineAbortSignals(...signals) {
100
+ const active = [
101
+ ...new Set(signals.filter((signal) => signal !== void 0))
102
+ ];
103
+ if (active.length === 0) return void 0;
104
+ if (active.length === 1) return active[0];
105
+ return AbortSignal.any(active);
106
+ }
107
+
98
108
  export {
109
+ combineAbortSignals,
99
110
  Mutex,
100
111
  mapConcurrent,
101
112
  DEFAULT_RUN_SCORE_WEIGHTS,
102
113
  aggregateRunScore,
103
114
  clamp01
104
115
  };
105
- //# sourceMappingURL=chunk-UI4YMIN2.js.map
116
+ //# sourceMappingURL=chunk-WGXIEX7P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/concurrency.ts","../src/run-score.ts","../src/abort-signal.ts"],"sourcesContent":["/**\n * concurrency — small primitives the evolution loop needs.\n *\n * `Mutex` is a zero-dep async lock with FIFO fairness. The evolution loop\n * uses it to serialise checkout/build/commit sequences inside a single\n * pool slot, and to gate concurrent JSONL writers (see\n * `lockedJsonlReferenceReplayStore`).\n *\n * Deliberately minimal — no priority queue, no timeouts. If you need\n * those, swap to `async-mutex` at the call site.\n */\n\nexport class Mutex {\n private locked = false\n private readonly waiters: Array<() => void> = []\n\n async acquire(): Promise<() => void> {\n if (!this.locked) {\n this.locked = true\n return () => this.release()\n }\n return new Promise<() => void>((resolve) => {\n this.waiters.push(() => {\n resolve(() => this.release())\n })\n })\n }\n\n private release(): void {\n const next = this.waiters.shift()\n if (next) {\n next()\n } else {\n this.locked = false\n }\n }\n\n async runExclusive<T>(fn: () => Promise<T> | T): Promise<T> {\n const release = await this.acquire()\n try {\n return await fn()\n } finally {\n release()\n }\n }\n\n /** True iff someone holds the lock right now. Diagnostics only. */\n get isLocked(): boolean {\n return this.locked\n }\n\n /** Pending waiter count. Diagnostics only. */\n get pending(): number {\n return this.waiters.length\n }\n}\n\n/**\n * Map independent work with a fixed worker count while preserving input order.\n * After the first rejection, no new items start; already-running work is allowed\n * to settle before the returned promise rejects. Partial results are discarded.\n */\nexport async function mapConcurrent<T, R>(\n items: readonly T[],\n concurrency: number,\n map: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n if (!Number.isInteger(concurrency) || concurrency < 1) {\n throw new Error(`mapConcurrent: concurrency must be a positive integer, got ${concurrency}`)\n }\n if (items.length === 0) return []\n\n const results = new Array<R>(items.length)\n let nextIndex = 0\n let stopped = false\n let failed = false\n let failure: unknown\n\n const worker = async (): Promise<void> => {\n while (!stopped) {\n const index = nextIndex\n nextIndex += 1\n if (index >= items.length) return\n\n try {\n results[index] = await map(items[index]!, index)\n } catch (error) {\n stopped = true\n if (!failed) {\n failed = true\n failure = error\n }\n }\n }\n }\n\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()))\n if (failed) throw failure\n return results\n}\n","export interface RunScore {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n notes?: string[]\n}\n\nexport interface RunScoreWeights {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n}\n\nexport const DEFAULT_RUN_SCORE_WEIGHTS: RunScoreWeights = {\n success: 4,\n goalProgress: 2,\n repoGroundedness: 1.5,\n driftPenalty: -1.5,\n toolUseQuality: 1,\n patchQuality: 1.25,\n testReality: 1.5,\n finalGate: 3,\n reviewerBlockers: -2,\n costUsd: -0.2,\n wallSeconds: -0.1,\n}\n\nexport function aggregateRunScore(score: RunScore, weights: Partial<RunScoreWeights> = {}): number {\n const w = { ...DEFAULT_RUN_SCORE_WEIGHTS, ...weights }\n return (\n w.success * clamp01(score.success) +\n w.goalProgress * clamp01(score.goalProgress) +\n w.repoGroundedness * clamp01(score.repoGroundedness) +\n w.driftPenalty * clamp01(score.driftPenalty) +\n w.toolUseQuality * clamp01(score.toolUseQuality) +\n w.patchQuality * clamp01(score.patchQuality) +\n w.testReality * clamp01(score.testReality) +\n w.finalGate * clamp01(score.finalGate) +\n w.reviewerBlockers * clamp01(score.reviewerBlockers) +\n w.costUsd * Math.max(0, finiteOrZero(score.costUsd)) +\n w.wallSeconds * Math.max(0, finiteOrZero(score.wallSeconds) / 60)\n )\n}\n\nexport function clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction finiteOrZero(value: number): number {\n return Number.isFinite(value) ? value : 0\n}\n","/** Combine active cancellation sources without wrapping a single source. */\nexport function combineAbortSignals(\n ...signals: Array<AbortSignal | undefined>\n): AbortSignal | undefined {\n const active = [\n ...new Set(signals.filter((signal): signal is AbortSignal => signal !== undefined)),\n ]\n if (active.length === 0) return undefined\n if (active.length === 1) return active[0]\n return AbortSignal.any(active)\n}\n"],"mappings":"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","names":[]}
@@ -7,7 +7,7 @@ import {
7
7
  pairHoldout,
8
8
  recoverTruncatedJson,
9
9
  surfaceContentHash
10
- } from "./chunk-NTOV7RU5.js";
10
+ } from "./chunk-7AN2E7BU.js";
11
11
  import {
12
12
  SearchLedgerConflictError,
13
13
  SearchLedgerError,
@@ -22,7 +22,7 @@ import {
22
22
  } from "./chunk-UCLVDLCH.js";
23
23
  import {
24
24
  Mutex
25
- } from "./chunk-UI4YMIN2.js";
25
+ } from "./chunk-WGXIEX7P.js";
26
26
  import {
27
27
  eProcess,
28
28
  mcnemar,
@@ -4634,4 +4634,4 @@ export {
4634
4634
  verifyCodeSurface,
4635
4635
  resolveWorktreePath
4636
4636
  };
4637
- //# sourceMappingURL=chunk-KO2PZOGP.js.map
4637
+ //# sourceMappingURL=chunk-Y5CLI4PY.js.map
@@ -1477,6 +1477,24 @@ interface RunOptimizationBaseOptions<TScenario extends Scenario$1, TArtifact> ex
1477
1477
  costLedger?: CostLedgerHandle;
1478
1478
  costPhase?: string;
1479
1479
  }) => Promise<unknown[]>;
1480
+ /**
1481
+ * Optional override for how the WINNER is selected among coverage-complete
1482
+ * candidates (and how the incumbent bar is set). Returns a lexicographic rank
1483
+ * key — each element higher-is-better; candidates are ranked by descending key
1484
+ * (`compareRankKeys`) and the top must STRICTLY beat the incumbent's key to
1485
+ * promote. Defaults to `[campaignMeanComposite(campaign)]`, i.e. the historical
1486
+ * scalar-mean ranking (single-element key ⇒ identical behavior).
1487
+ *
1488
+ * A binary-with-replicates consumer (e.g. swe-arena, whose ship-gate counts an
1489
+ * instance resolved only when EVERY replicate resolved) passes a fail-closed
1490
+ * key built from the SAME reduction its gate uses, so winner-selection and the
1491
+ * ship-gate rank on the identical metric and can never invert — the selector
1492
+ * cannot promote a flaky per-cell-mean candidate the gate would reject over a
1493
+ * fail-closed candidate the gate would accept. Only the winner CHOICE changes;
1494
+ * the descriptive `composite` (mean) on every record and the Pareto objective
1495
+ * vectors are untouched, so proposer diversity and reporting are unaffected.
1496
+ */
1497
+ selectionRankKey?: (campaign: CampaignResult<TArtifact, TScenario>) => number[];
1480
1498
  }
1481
1499
  type RunOptimizationOptions<TScenario extends Scenario$1, TArtifact> = RunOptimizationBaseOptions<TScenario, TArtifact>;
1482
1500
  interface RunOptimizationResult<TArtifact, TScenario extends Scenario$1> {
@@ -1816,8 +1834,8 @@ interface ExternalOptimizerModelBudget {
1816
1834
  * data and compared with paired confidence intervals.
1817
1835
  */
1818
1836
 
1819
- /** Per-method campaign settings. Each method receives its own spend account. */
1820
- type OptimizationMethodRunOptions<TScenario extends Scenario$1, TArtifact> = Omit<RunCampaignOptions<TScenario, TArtifact>, 'costLedger' | 'dispatch' | 'judges' | 'runDir' | 'scenarios' | 'seed'>;
1837
+ /** Shared campaign settings applied to every optimization method. */
1838
+ type OptimizationMethodRunOptions<TScenario extends Scenario$1, TArtifact> = Omit<RunCampaignOptions<TScenario, TArtifact>, 'costCeiling' | 'costLedger' | 'dispatch' | 'judges' | 'runDir' | 'scenarios' | 'seed'>;
1821
1839
  /** Cost reported by a method or by final test scoring. */
1822
1840
  interface ComparisonCost {
1823
1841
  totalCostUsd: number;
@@ -1890,7 +1908,7 @@ interface OptimizationMethodInput<TScenario extends Scenario$1, TArtifact> {
1890
1908
  readonly seed: number;
1891
1909
  /** Shared defaults for every method. A method may override them explicitly. */
1892
1910
  readonly runOptions: Readonly<OptimizationMethodRunOptions<TScenario, TArtifact>>;
1893
- /** Durable spend account shared by the method's model and evaluation calls. */
1911
+ /** Durable spend account shared by every method and final scoring. */
1894
1912
  readonly costLedger: CostLedgerHandle;
1895
1913
  }
1896
1914
  interface OptimizationMethodResult {
@@ -1999,8 +2017,7 @@ interface CompareOptimizationMethodsOptions<TScenario extends Scenario$1, TArtif
1999
2017
  /** Simultaneous confidence across method-vs-baseline and method-vs-method contrasts.
2000
2018
  * Each bootstrap interval is Bonferroni-adjusted. Default 0.95. */
2001
2019
  confidence?: number;
2002
- /** Shared spend limit across baseline and winner scoring on the final test partition.
2003
- * Each method owns its optimization budget through `optimizationRunOptions.costCeiling`. */
2020
+ /** Shared spend limit across every method's optimizer and evaluation calls plus final scoring. */
2004
2021
  costCeiling?: number;
2005
2022
  }
2006
2023
  /**
@@ -3727,6 +3744,13 @@ interface SelfImproveOptions<TScenario extends Scenario$1, TArtifact> {
3727
3744
  /** Static findings forwarded to the proposer's `propose()` as `ctx.findings`
3728
3745
  * (a findings-grounded proposer consumes them). Default: none. */
3729
3746
  findings?: unknown[];
3747
+ /** Override how the WINNER is selected among coverage-complete candidates.
3748
+ * Defaults to the scalar mean composite (historical behavior). A binary-with-
3749
+ * replicates consumer whose ship-gate counts an instance resolved only when
3750
+ * every replicate resolved passes a fail-closed lexicographic key here so that
3751
+ * winner-selection and the ship-gate rank on the identical metric and cannot
3752
+ * invert. See `RunOptimizationOptions.selectionRankKey`. */
3753
+ selectionRankKey?: RunOptimizationOptions<TScenario, TArtifact>['selectionRankKey'];
3730
3754
  }
3731
3755
  interface SelfImproveResult<TScenario extends Scenario$1, TArtifact> {
3732
3756
  /** Composite mean across all scenarios, baseline run. When
@@ -40,7 +40,7 @@ import {
40
40
  skillOptOptimizationMethod,
41
41
  surfaceContentHash,
42
42
  surfaceHash
43
- } from "../chunk-NTOV7RU5.js";
43
+ } from "../chunk-7AN2E7BU.js";
44
44
  import {
45
45
  campaignSplitDigest,
46
46
  createRunCostLedger,
@@ -52,9 +52,9 @@ import {
52
52
  import {
53
53
  buildDefaultAnalystRegistry,
54
54
  createChatClient
55
- } from "../chunk-CM4OILD2.js";
55
+ } from "../chunk-LUNF2SEL.js";
56
56
  import "../chunk-HHWE3POT.js";
57
- import "../chunk-UI4YMIN2.js";
57
+ import "../chunk-WGXIEX7P.js";
58
58
  import {
59
59
  FileSystemOutcomeStore,
60
60
  InMemoryOutcomeStore
@@ -340,7 +340,8 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
340
340
  labeledStore: opts.labeledStore,
341
341
  captureSource: opts.captureSource,
342
342
  analyzeGeneration: opts.analyzeGeneration,
343
- findings: opts.findings
343
+ findings: opts.findings,
344
+ selectionRankKey: opts.selectionRankKey
344
345
  });
345
346
  const winnerSearch = holdoutDeferred ? winnerSearchCampaign(result) : void 0;
346
347
  const baseline = meanComposite(