darwin-agents 0.5.0-alpha.2 → 0.5.1-alpha.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,119 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.5.1-alpha.2] — 2026-06-06
6
+
7
+ ### Fixed
8
+
9
+ - **CI green again on Node 20/22** (red since v0.5.0-alpha.2). The `better-sqlite3`
10
+ peer dependency was pinned to `^11.0.0`, which ships no prebuilt binary for newer
11
+ Node ABIs — `new Database()` in the test `before` hook crashed with a
12
+ `NODE_MODULE_VERSION` mismatch (127 vs 137), which `node:test` reported as the
13
+ whole trajectory suite being "cancelled by parent". Widened the peer range to
14
+ `^11.0.0 || ^12.0.0` (consumers may use either major) and added
15
+ `better-sqlite3@^12.10.0` as a devDependency so the test suite runs against the
16
+ full Node 20–26 ABI matrix. Verified on Node 22 + 24 (336/336 tests green), tsc clean.
17
+
18
+ ## [0.5.1-alpha.1] — 2026-05-29
19
+
20
+ **GEPA Polish-Welle.** Closes the three deliberate paper deviations
21
+ documented in `optimizer-gepa.ts` as V0.6 backlog from V0.5.0-alpha.2.
22
+ **Zero breaking changes** — every V0.5.0 callsite keeps working unchanged.
23
+ **R1 + R2 + R3 code-review-loop GO**, **336/337 vitest tests grün** (+29
24
+ V0.5.1 regression tests). tsc strict clean, build clean.
25
+
26
+ ### Added — three new surfaces
27
+
28
+ - **`crowdingDistance(variants, objectives)`** in `src/evolution/pareto.ts` —
29
+ pure NSGA-II Deb 2002 density-estimator. Returns one distance per
30
+ variant: per-objective min-max-normalised neighbour gap, summed across
31
+ objectives, with `+Infinity` for boundary variants so they always
32
+ survive truncation. Scale-safe through per-objective normalisation
33
+ (unlike `scalarise` which is scale-sensitive).
34
+ - **`ParetoTruncationStrategy`** type + new 4th parameter to
35
+ `paretoSelect(variants, objectives, maxKeep, truncationStrategy)`.
36
+ Two strategies: `"scalarised"` (V0.5.0 default, kept) and `"crowding"`
37
+ (NSGA-II density-preserving). Backward-compatible default.
38
+ - **`GepaOptimizerOptions`** interface + new constructor option
39
+ `reflectionRunPrompt?: RunPromptFn`. When supplied, reflection AND
40
+ merge route through the override — matches GEPA paper guidance
41
+ (stronger LM for reflection than for task execution). Falls back to
42
+ the main `runPrompt` when omitted. Closes V0.5.0 R1 Research F7.
43
+ - **`GepaOptimizer.merge(parents, opts)`** — GEPA Paper Appendix F
44
+ system-aware merge. Takes two distinct Pareto-front parents, asks the
45
+ reflection LM to combine their strongest aspects into one mutated
46
+ prompt. Returns `{ id: "gepa-merge-<a>+<b>", prompt }`. Validations:
47
+ exactly 2 parents, distinct ids, non-empty prompts. Output is
48
+ fence-stripped + sentence-boundary capped to
49
+ `max(longerParent.length * 1.3, 3500)`. Paper reports ~5% lift when
50
+ run every K-th generation.
51
+ - **`GepaOptimizer.nextGeneration.truncationStrategy` passthrough** —
52
+ forwards the new `paretoSelect` parameter from `NextGenerationOptions`.
53
+ Default `"scalarised"` matches V0.5.0 byte-for-byte.
54
+
55
+ ### Fixed — R1 + R2 + R3 code-review-loop
56
+
57
+ R1 critic reported a P1 template-injection in `merge` (claimed `{SCORE_A}`
58
+ / `{SCORE_B}` placeholders inside parent prompts were double-substituted
59
+ because they ran before `{PROMPT_A}` / `{PROMPT_B}`). On R2 verification
60
+ the V1 ordering (ID + SCORE first, PROMPT last) was confirmed CORRECT —
61
+ `String.prototype.replace` only finds matches in the current working
62
+ string, and user content does not enter the working string until the
63
+ final two replacements. **Net effect:** code unchanged, but
64
+ `tests/v0.5.1-features.test.ts` now explicitly regression-tests BOTH
65
+ `{ID_B}` AND `{SCORE_A}` + `{SCORE_B}` literals inside parent prompts —
66
+ the test coverage gap was the real R1 finding, not the substitution order.
67
+
68
+ R1 Analyst documentation-drift fixes:
69
+
70
+ - `src/evolution/optimizer-gepa.ts` header — V0.6 deferrals updated to
71
+ reflect V0.5.1 shipping `truncationStrategy` + `merge` +
72
+ `reflectionRunPrompt`. Instance-coverage sampling remains V0.6
73
+ backlog.
74
+ - `src/evolution/reflector.ts` — "deferred to V0.5.1" wording replaced
75
+ with "SHIPPED in V0.5.1".
76
+ - `src/evolution/pareto.ts` — `"coverage"` mention removed from the
77
+ `paretoSelect` docstring; type carries only `"scalarised" | "crowding"`,
78
+ no type/doc mismatch remains.
79
+
80
+ ### Test coverage
81
+
82
+ - **336/337 vitest tests grün** (was 307/308 baseline + 29 new tests
83
+ in `tests/v0.5.1-features.test.ts`). 1 pre-existing skip carried over.
84
+ - New tests cover: `crowdingDistance` (4 boundary + 4 three-variant
85
+ scale-safe + non-finite defense), `paretoSelect` (default vs explicit
86
+ scalarised parity + crowding boundary preservation), `GepaOptimizer`
87
+ reflection-LM routing + fallback + invalid-type guard, `merge`
88
+ (template-injection for ID + SCORE, tuple validation, same-id
89
+ rejection, empty-prompt rejection, reflection-LM routing, fence-strip,
90
+ length cap, rejection propagation), `nextGeneration`
91
+ truncationStrategy passthrough + backward-compat byte-equivalence.
92
+
93
+ ### V0.6 backlog (carried over from V0.5.1 deferrals)
94
+
95
+ - `"coverage"` strategy on `ParetoTruncationStrategy` (GEPA Algorithm 2
96
+ instance-proportional sampling)
97
+ - Extract `cleanOutput` + `truncateAtSentenceBoundary` to shared
98
+ `src/evolution/text-utils.ts` (currently byte-identical in `Reflector`
99
+ + `GepaOptimizer`)
100
+ - Collision-safe `makeMergeId` separator (current `+` collides if
101
+ caller-side ids contain `+` literally — unlikely with default
102
+ `gepa-cand-${i}` ids)
103
+ - More edge tests: `merge` with non-finite metrics, `crowdingDistance`
104
+ with all-Infinity inputs
105
+
106
+ ### Migration from V0.5.0
107
+
108
+ None required. V0.5.1 is additive. Adopt new surfaces incrementally:
109
+
110
+ - Switch `nextGeneration` to `truncationStrategy: "crowding"` for
111
+ diversity-critical workloads
112
+ - Pass a stronger Opus model as `reflectionRunPrompt` while keeping a
113
+ cheaper Haiku as the main task LM
114
+ - Invoke `optimizer.merge([survivors[0], survivors[1]])` every K-th
115
+ generation for the Paper Appendix F lift
116
+
3
117
  ## [0.5.0-alpha.2] — 2026-05-25
4
118
 
5
119
  **GEPA-Style Reflective Optimizer (Phase 2 A2).** Multi-objective Pareto
@@ -85,6 +199,138 @@ The 3-Agent code-review loop ran twice. R1 found 13 findings, R2 caught
85
199
  v0.5.0-alpha.1.
86
200
  - tsc strict + build clean.
87
201
 
202
+ ## [0.5.0-alpha.1] — 2026-05-24
203
+
204
+ **Phase 2 A1: Execution-Trace-Capture.** First pre-release of Darwin's
205
+ Phase 2 tech roadmap. Unblocks GEPA-style reflective optimizers (A2)
206
+ and validate-by-reproduce drift-detection (A5) by giving them a
207
+ structured trajectory to consume.
208
+
209
+ Industry-aligned with the 2026 agent-observability consensus (Braintrust,
210
+ Langfuse, Strands SDK, Microsoft Foundry, OTEL GenAI semantic conventions):
211
+ three span types — Tool / Reasoning / Turn-level errors — captured into a
212
+ single `ExecutionTrace` object, persisted as JSONB (Postgres) or TEXT
213
+ (SQLite), and tagged with a forward-compatible `version: 1` discriminator.
214
+
215
+ ### Added
216
+
217
+ - **`ExecutionTrace` schema** (`src/types.ts`) — versioned trajectory shape:
218
+ `toolCalls[]` (with OTEL-mappable `id` / `tool` / `args` / `resultSummary`
219
+ (2000-char cap) / `outcome` / `durationMs` / `retryCount?` / `errorClass?` /
220
+ `errorMessage?` / `turn`), `textBlockCount` (honest name — NOT a thinking-
221
+ block counter, V2 will add typed `reasoningBlocks`), `turnCount`,
222
+ `mcpInvocations`, `errors[]` (turn-level), `tokenUsage?` (OTEL `gen_ai.usage.*`
223
+ fields: input/output/cache_read/cache_creation tokens), `capturedAt`. Plus
224
+ optional `trajectory?: ExecutionTrace` on `DarwinExperiment` (additive —
225
+ pre-A1 callers unaffected).
226
+
227
+ - **`createTraceCapture()` factory** (`src/core/trace-capture.ts`) — pure,
228
+ transport-agnostic capturer. The runtime feeds tool events; the capturer
229
+ aggregates into a typed trajectory. API:
230
+
231
+ ```ts
232
+ const trace = createTraceCapture();
233
+ trace.startTurn();
234
+ trace.recordToolUse('toolu_01AB', 'mcp__nex__search', { query: 'x' });
235
+ trace.recordToolResult('toolu_01AB', 'success', { resultSummary: '3 hits' });
236
+ trace.recordTextBlock();
237
+ trace.addTokens({ inputTokens: 1200, outputTokens: 340 });
238
+ trace.recordError('parse_error', 'invalid JSON');
239
+ const trajectory = trace.finalize();
240
+ ```
241
+
242
+ Unpaired `recordToolUse` calls (no matching `recordToolResult` before
243
+ `finalize`) surface as `outcome: 'error', errorClass: 'unpaired_call'`
244
+ so silent SDK hangs remain visible in the trace. Customizable via
245
+ `TraceCaptureOptions`: `now?` (clock injection for tests),
246
+ `isMcpTool?` (predicate override for non-`mcp__`-prefixed servers).
247
+
248
+ - **`addTokens()` aggregator** — lossy-merge of per-turn LLM usage. Missing
249
+ fields (`NaN` / `Infinity` / `undefined`) skip silently rather than
250
+ defaulting to zero — preserves the distinction between "provider didn't
251
+ report" and "actually zero tokens".
252
+
253
+ - **JSONB persistence** in `darwin_experiments.trajectory` column +
254
+ `idx_darwin_exp_trajectory_gin` GIN index (Postgres) for `@>`
255
+ containment queries from A2 / A5 consumers. SQLite stores the same
256
+ shape as JSON-stringified TEXT.
257
+
258
+ - **`scripts/migrate-add-trajectory.ts`** — idempotent migration script.
259
+ Pre-checks column + index existence (filtered by `current_schema()`
260
+ for multi-schema-safe operation), runs `ALTER TABLE … ADD COLUMN IF
261
+ NOT EXISTS trajectory JSONB` + `CREATE INDEX IF NOT EXISTS`, then
262
+ verifies. Rollback path documented inline.
263
+
264
+ ```bash
265
+ DARWIN_POSTGRES_URL=postgresql://… npx tsx scripts/migrate-add-trajectory.ts
266
+ ```
267
+
268
+ - **Defensive parsing** in both memory backends — `parseTrajectory` /
269
+ `parseTrajectoryColumn` drop malformed values (wrong `version`,
270
+ non-object, invalid JSON) to `undefined` instead of crashing the
271
+ load. Future schema versions (`version !== 1`) are silently ignored
272
+ so v0.5 consumers don't break on v0.6 trajectories.
273
+
274
+ - **39 new tests** across two suites (all green):
275
+ - `tests/trace-capture.test.ts` (32 unit tests): basic flow,
276
+ defensive behaviour, truncation (2000-char `resultSummary`),
277
+ MCP-heuristic, schema invariants, tool_call_id passthrough,
278
+ `addTokens` aggregate semantics
279
+ - `tests/memory-trajectory.test.ts` (7 tests): SQLite roundtrip,
280
+ backward-compat with pre-A1 rows, defensive parsing, idempotent
281
+ migration, Postgres-gated JSONB roundtrip
282
+
283
+ ### Changed
284
+
285
+ - **DDL single-source-of-truth** — the trajectory column is defined
286
+ ONLY in the additive `ALTER TABLE … ADD COLUMN IF NOT EXISTS` path
287
+ (Postgres) / PRAGMA-guarded ALTER (SQLite), never inline in the
288
+ `CREATE TABLE`. Schema-evolution lives in one place; fresh installs
289
+ reach the same end-state as legacy installs.
290
+
291
+ - **Postgres `ON CONFLICT` preserves trajectory** on feedback-only
292
+ re-saves via `COALESCE(EXCLUDED.trajectory, darwin_experiments.trajectory)`.
293
+ This means a second `saveExperiment(exp)` call that omits trajectory
294
+ doesn't zero out the previously-stored trace.
295
+
296
+ **NOTE — SQLite asymmetry:** SQLite uses `INSERT OR REPLACE` which
297
+ drops + re-inserts the row, so callers wanting to preserve a prior
298
+ trajectory across re-saves MUST include it in the new payload. This
299
+ asymmetry is documented on `MemoryProvider.saveExperiment` in the
300
+ interface JSDoc.
301
+
302
+ ### Backwards compatibility
303
+
304
+ 100% backwards-compatible. The new `trajectory` field is optional, the
305
+ new column is nullable, the new methods on `MemoryProvider` are
306
+ additive. Existing v0.4.x consumers see no behavioural changes.
307
+
308
+ Verified on a live `darwin_db` with 341 experiments, 339 of which
309
+ pre-date A1 — all loaded cleanly with `trajectory: undefined`.
310
+
311
+ ### Why "alpha.1"
312
+
313
+ `textBlockCount` is honest but limited — V2 will replace it with a
314
+ typed `reasoningBlocks: ReasoningBlock[]` sequence carrying the actual
315
+ text content per reasoning step, which is what GEPA reflectors need
316
+ for per-decision blame attribution. Existing `textBlockCount` will stay
317
+ as a fast aggregate. The `alpha.1` tag signals the schema is subject to
318
+ this kind of additive evolution before `0.5.0` final.
319
+
320
+ Three known minor gaps (deferred to follow-up patches):
321
+
322
+ - Per-call cost attribution (token usage per tool invocation, not just
323
+ per-run aggregate)
324
+ - Trace-capture lazy-load flag stays permanent on transient import
325
+ failure (low impact: Darwin is either built or not)
326
+ - Token extraction in the SDK adapter is Anthropic-shaped (`message.usage`)
327
+ and may silently miss tokens for non-Anthropic providers — by design
328
+ (token usage is documented optional), but a debug-level log line in a
329
+ follow-up patch will make this easier to spot.
330
+
331
+ Install: `npm install darwin-agents@alpha`. The default `latest` tag
332
+ remains on `0.4.9` until `0.5.0` final ships.
333
+
88
334
  ## [0.4.9] — 2026-05-22
89
335
 
90
336
  Polish on top of v0.4.8. Adds spec-compliance, error classification,
@@ -40,14 +40,18 @@
40
40
  * - **`feedbackStrategy: "split"` is OUR adaptation** — GEPA paper
41
41
  * does not partition feedback across offspring. We do it to force
42
42
  * mutation diversity in a single `Promise.all` batch.
43
- * - **paretoSelect truncation uses scalarised tie-break** — GEPA
44
- * Algorithm 2 samples Pareto candidates proportional to instance
45
- * coverage. We use a simpler weighted-sum tie-break. V0.6 will add
46
- * a `truncationStrategy` option for coverage-proportional +
47
- * NSGA-II crowding-distance.
43
+ * - **paretoSelect truncation has two strategies (V0.5.1):**
44
+ * `"scalarised"` (V0.5.0 default, weighted-sum tie-break) and
45
+ * `"crowding"` (NSGA-II Deb 2002 density-preserving truncation).
46
+ * GEPA Algorithm 2's instance-proportional coverage sampling is
47
+ * still NOT implemented — backlog for V0.6.
48
48
  * - **GEPA+Merge (system-aware crossover from two Pareto-pool
49
- * ancestors, paper Appendix F)** is NOT implemented. +5% reported
50
- * lift in the paper. Backlog for V0.6.
49
+ * ancestors, paper Appendix F)** SHIPPED in V0.5.1 via
50
+ * {@link GepaOptimizer#merge}. Paper reports ~5% lift when run on
51
+ * every K-th generation.
52
+ * - **Stronger reflection LM** SHIPPED in V0.5.1 via
53
+ * {@link GepaOptimizerOptions.reflectionRunPrompt}. Falls back to
54
+ * the main `runPrompt` when omitted.
51
55
  * - **Instance-wise coverage sampling** (paper Algorithm 2) is NOT
52
56
  * implemented. Backlog for V0.6.
53
57
  *
@@ -79,7 +83,7 @@
79
83
  * ```
80
84
  */
81
85
  import type { ReflectiveFeedback, RunPromptFn } from "./reflector.js";
82
- import { type ParetoObjective } from "./pareto.js";
86
+ import { type ParetoObjective, type ParetoTruncationStrategy } from "./pareto.js";
83
87
  /** One evaluated variant in a generation. */
84
88
  export interface ScoredVariant {
85
89
  /** Variant identifier (e.g. "v3-gen2-cand1"). */
@@ -118,10 +122,59 @@ export interface NextGenerationOptions extends GenerateOptions {
118
122
  * Max variants to keep on the Pareto front. Default 3.
119
123
  */
120
124
  maxCarry?: number;
125
+ /**
126
+ * V0.5.1 — strategy used when the Pareto front exceeds `maxCarry`
127
+ * and needs truncation. Default `"scalarised"` (preserves V0.5.0
128
+ * behaviour). Switch to `"crowding"` for NSGA-II density-preserving
129
+ * truncation that maintains diversity along the front.
130
+ *
131
+ * NEW V0.5.1 (S1235).
132
+ */
133
+ truncationStrategy?: ParetoTruncationStrategy;
134
+ }
135
+ /**
136
+ * V0.5.1 options for {@link GepaOptimizer} constructor.
137
+ *
138
+ * R1 Research Finding F7 (S1185) closure — `reflectionRunPrompt` lets
139
+ * callers route reflection / merge calls to a STRONGER LM than the task
140
+ * LM, matching GEPA's official `reflection_lm` parameter. When omitted,
141
+ * reflection and merge fall back to the main `runPrompt`. NEW V0.5.1.
142
+ */
143
+ export interface GepaOptimizerOptions {
144
+ /**
145
+ * Stronger LM for reflection / merge calls. Pass a higher-tier
146
+ * `RunPromptFn` (e.g. Claude Opus) here when your main task LM is a
147
+ * cheaper one. Per GEPA paper guidance reflection is the leverage
148
+ * point — a stronger reflector lifts mutation quality more than a
149
+ * stronger task LM.
150
+ *
151
+ * When omitted, reflection + merge use the main `runPrompt`.
152
+ *
153
+ * NEW V0.5.1 (S1235).
154
+ */
155
+ reflectionRunPrompt?: RunPromptFn;
156
+ }
157
+ /**
158
+ * V0.5.1 options for {@link GepaOptimizer#merge}.
159
+ */
160
+ export interface MergeOptions {
161
+ /**
162
+ * Override the merge prompt template. Default is the GEPA Appendix-F
163
+ * system-aware merge template. Use a custom template when you want
164
+ * different merge pressure (e.g. conservative-additive vs. selective).
165
+ */
166
+ mergePromptTemplate?: string;
167
+ /**
168
+ * Hard upper bound on the returned merged-prompt length. Default
169
+ * `Math.max(max(parents[].prompt.length) * 1.3, 3500)` — same growth
170
+ * ceiling as {@link Reflector}.
171
+ */
172
+ maxMergeLength?: number;
121
173
  }
122
174
  export declare class GepaOptimizer {
123
175
  private readonly reflector;
124
- constructor(runPrompt: RunPromptFn);
176
+ private readonly reflectionRunPrompt;
177
+ constructor(runPrompt: RunPromptFn, opts?: GepaOptimizerOptions);
125
178
  /**
126
179
  * Generate N variant mutations from the current prompt + feedback set.
127
180
  * Returns the raw mutated prompts — caller scores them (typically via
@@ -141,9 +194,44 @@ export declare class GepaOptimizer {
141
194
  * nextGeneration"). The actual selection logic lives in `pareto.ts`.
142
195
  */
143
196
  nextGeneration(scored: ReadonlyArray<ScoredVariant>, opts: NextGenerationOptions): ScoredVariant[];
197
+ /**
198
+ * V0.5.1 (S1235) — GEPA+Merge (Paper Appendix F).
199
+ *
200
+ * Combines the strongest aspects of TWO Pareto-front parents into a
201
+ * single mutated prompt via a reflection-LM call. The paper reports
202
+ * ~+5% lift over generation-only optimisation when this is run on
203
+ * every K-th generation (typically K=3-5). The merged prompt then
204
+ * competes alongside the regular generation outputs in the next
205
+ * `nextGeneration` Pareto-select step.
206
+ *
207
+ * Typical usage:
208
+ * ```ts
209
+ * // Every Kth generation, merge the top two Pareto-front members.
210
+ * if (gen % 3 === 0 && survivors.length >= 2) {
211
+ * const merged = await optimizer.merge(
212
+ * [survivors[0], survivors[1]],
213
+ * );
214
+ * // Score `merged.prompt` via your evaluator, then include the
215
+ * // scored variant in the next nextGeneration() pool.
216
+ * }
217
+ * ```
218
+ *
219
+ * Errors are thrown — `merge` is a deliberate optimisation step, the
220
+ * caller chooses when to invoke it. No swallowing.
221
+ */
222
+ merge(parents: readonly [ScoredVariant, ScoredVariant], opts?: MergeOptions): Promise<{
223
+ id: string;
224
+ prompt: string;
225
+ }>;
226
+ /** Strip markdown fences + leading/trailing whitespace — mirrors `Reflector.cleanOutput`. */
227
+ private cleanOutput;
228
+ /** Sentence-boundary truncation — mirrors `Reflector.truncateAtSentenceBoundary`. */
229
+ private truncateAtSentenceBoundary;
144
230
  /** Clamp variant count into the documented bounds. */
145
231
  private clampN;
146
232
  /** Stable variant id: `gepa-cand-${i}` (caller can re-namespace). */
147
233
  private makeId;
234
+ /** V0.5.1 — stable merged-variant id: `gepa-merge-${idA}+${idB}`. */
235
+ private makeMergeId;
148
236
  }
149
237
  //# sourceMappingURL=optimizer-gepa.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimizer-gepa.d.ts","sourceRoot":"","sources":["../../../src/evolution/optimizer-gepa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;CACrD;AAED,wDAAwD;AACxD,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D;;;;OAIG;IACH,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACnE;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,SAAS,EAAE,WAAW;IAIlC;;;;;OAKG;IACG,QAAQ,CACZ,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAC5C,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA0DjD;;;;;;;OAOG;IACH,cAAc,CACZ,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,EACpC,IAAI,EAAE,qBAAqB,GAC1B,aAAa,EAAE;IAyClB,sDAAsD;IACtD,OAAO,CAAC,MAAM;IAKd,qEAAqE;IACrE,OAAO,CAAC,MAAM;CAGf"}
1
+ {"version":3,"file":"optimizer-gepa.d.ts","sourceRoot":"","sources":["../../../src/evolution/optimizer-gepa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;CACrD;AAED,wDAAwD;AACxD,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D;;;;OAIG;IACH,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACnE;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;CAC/C;AAqCD;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,WAAW,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAc;gBAEtC,SAAS,EAAE,WAAW,EAAE,IAAI,GAAE,oBAAyB;IAoBnE;;;;;OAKG;IACG,QAAQ,CACZ,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAC5C,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA0DjD;;;;;;;OAOG;IACH,cAAc,CACZ,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,EACpC,IAAI,EAAE,qBAAqB,GAC1B,aAAa,EAAE;IAgDlB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,KAAK,CACT,OAAO,EAAE,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC,EAChD,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA6E1C,6FAA6F;IAC7F,OAAO,CAAC,WAAW;IAOnB,qFAAqF;IACrF,OAAO,CAAC,0BAA0B;IAWlC,sDAAsD;IACtD,OAAO,CAAC,MAAM;IAKd,qEAAqE;IACrE,OAAO,CAAC,MAAM;IAId,qEAAqE;IACrE,OAAO,CAAC,WAAW;CAGpB"}
@@ -40,14 +40,18 @@
40
40
  * - **`feedbackStrategy: "split"` is OUR adaptation** — GEPA paper
41
41
  * does not partition feedback across offspring. We do it to force
42
42
  * mutation diversity in a single `Promise.all` batch.
43
- * - **paretoSelect truncation uses scalarised tie-break** — GEPA
44
- * Algorithm 2 samples Pareto candidates proportional to instance
45
- * coverage. We use a simpler weighted-sum tie-break. V0.6 will add
46
- * a `truncationStrategy` option for coverage-proportional +
47
- * NSGA-II crowding-distance.
43
+ * - **paretoSelect truncation has two strategies (V0.5.1):**
44
+ * `"scalarised"` (V0.5.0 default, weighted-sum tie-break) and
45
+ * `"crowding"` (NSGA-II Deb 2002 density-preserving truncation).
46
+ * GEPA Algorithm 2's instance-proportional coverage sampling is
47
+ * still NOT implemented — backlog for V0.6.
48
48
  * - **GEPA+Merge (system-aware crossover from two Pareto-pool
49
- * ancestors, paper Appendix F)** is NOT implemented. +5% reported
50
- * lift in the paper. Backlog for V0.6.
49
+ * ancestors, paper Appendix F)** SHIPPED in V0.5.1 via
50
+ * {@link GepaOptimizer#merge}. Paper reports ~5% lift when run on
51
+ * every K-th generation.
52
+ * - **Stronger reflection LM** SHIPPED in V0.5.1 via
53
+ * {@link GepaOptimizerOptions.reflectionRunPrompt}. Falls back to
54
+ * the main `runPrompt` when omitted.
51
55
  * - **Instance-wise coverage sampling** (paper Algorithm 2) is NOT
52
56
  * implemented. Backlog for V0.6.
53
57
  *
@@ -84,10 +88,52 @@ const DEFAULT_NUM_VARIANTS = 3;
84
88
  const MIN_NUM_VARIANTS = 1;
85
89
  const MAX_NUM_VARIANTS = 10;
86
90
  const DEFAULT_MAX_CARRY = 3;
91
+ /**
92
+ * V0.5.1 — GEPA+Merge prompt template (Paper Appendix F).
93
+ *
94
+ * Asks the LLM to combine the best aspects of two Pareto-front parents
95
+ * into a single mutated prompt. Deliberately NOT a literal cross-over
96
+ * of token spans — the paper reports the "system-aware merge" variant
97
+ * (semantic combination via reflection LM) lifts task performance by
98
+ * roughly 5%. Token-span crossover (the alternative they tested) did
99
+ * not yield the same gain.
100
+ *
101
+ * NEW V0.5.1 (S1235).
102
+ */
103
+ const DEFAULT_MERGE_TEMPLATE = `
104
+ You are a prompt-engineering merger. Below are two instruction prompts from a Pareto-front of variants. Each has its own strengths and weaknesses on different evaluation dimensions.
105
+
106
+ PARENT A (id={ID_A}, score {SCORE_A}):
107
+ \`\`\`
108
+ {PROMPT_A}
109
+ \`\`\`
110
+
111
+ PARENT B (id={ID_B}, score {SCORE_B}):
112
+ \`\`\`
113
+ {PROMPT_B}
114
+ \`\`\`
115
+
116
+ Task: produce ONE merged instruction that combines the strongest aspects of BOTH parents. You may borrow phrasing from either, but the merge must preserve correct behavior from BOTH and not regress on any dimension either parent handles well. Keep the overall length envelope reasonable (no growth beyond ~30% of the longer parent).
117
+
118
+ Return ONLY the merged instruction text. No prose, no explanations, no markdown fences.
119
+ `.trim();
87
120
  export class GepaOptimizer {
88
121
  reflector;
89
- constructor(runPrompt) {
90
- this.reflector = new Reflector(runPrompt);
122
+ reflectionRunPrompt;
123
+ constructor(runPrompt, opts = {}) {
124
+ if (typeof runPrompt !== "function") {
125
+ throw new TypeError("GepaOptimizer: runPrompt must be a function");
126
+ }
127
+ // V0.5.1 (R1 Research F7 closure, S1235): if a stronger reflection LM
128
+ // is provided, route reflection + merge through it; otherwise fall
129
+ // back to the main runPrompt so existing V0.5.0 callsites keep
130
+ // working unchanged.
131
+ if (opts.reflectionRunPrompt !== undefined &&
132
+ typeof opts.reflectionRunPrompt !== "function") {
133
+ throw new TypeError("GepaOptimizer: opts.reflectionRunPrompt must be a function when supplied");
134
+ }
135
+ this.reflectionRunPrompt = opts.reflectionRunPrompt ?? runPrompt;
136
+ this.reflector = new Reflector(this.reflectionRunPrompt);
91
137
  }
92
138
  /**
93
139
  * Generate N variant mutations from the current prompt + feedback set.
@@ -174,7 +220,9 @@ export class GepaOptimizer {
174
220
  "`metrics` object reference — provide a distinct metrics object per variant.");
175
221
  }
176
222
  const objectives = opts.objectives;
177
- const survivorMetrics = paretoSelect(metricsArr, objectives, maxCarry);
223
+ // V0.5.1 (S1235) forward truncationStrategy. Default "scalarised"
224
+ // preserves V0.5.0 behaviour byte-for-byte.
225
+ const survivorMetrics = paretoSelect(metricsArr, objectives, maxCarry, opts.truncationStrategy ?? "scalarised");
178
226
  // Build "metrics-ref → index" map then look up each survivor's index.
179
227
  // Linear scan twice is O(N²) worst-case but N≤10 in practice.
180
228
  const metricsToIndex = new Map();
@@ -184,6 +232,113 @@ export class GepaOptimizer {
184
232
  .filter((i) => typeof i === "number"));
185
233
  return scored.filter((_, i) => survivorIndices.has(i));
186
234
  }
235
+ /**
236
+ * V0.5.1 (S1235) — GEPA+Merge (Paper Appendix F).
237
+ *
238
+ * Combines the strongest aspects of TWO Pareto-front parents into a
239
+ * single mutated prompt via a reflection-LM call. The paper reports
240
+ * ~+5% lift over generation-only optimisation when this is run on
241
+ * every K-th generation (typically K=3-5). The merged prompt then
242
+ * competes alongside the regular generation outputs in the next
243
+ * `nextGeneration` Pareto-select step.
244
+ *
245
+ * Typical usage:
246
+ * ```ts
247
+ * // Every Kth generation, merge the top two Pareto-front members.
248
+ * if (gen % 3 === 0 && survivors.length >= 2) {
249
+ * const merged = await optimizer.merge(
250
+ * [survivors[0], survivors[1]],
251
+ * );
252
+ * // Score `merged.prompt` via your evaluator, then include the
253
+ * // scored variant in the next nextGeneration() pool.
254
+ * }
255
+ * ```
256
+ *
257
+ * Errors are thrown — `merge` is a deliberate optimisation step, the
258
+ * caller chooses when to invoke it. No swallowing.
259
+ */
260
+ async merge(parents, opts = {}) {
261
+ if (!Array.isArray(parents) || parents.length !== 2) {
262
+ throw new TypeError("GepaOptimizer.merge: parents must be a tuple of exactly two ScoredVariants");
263
+ }
264
+ const [a, b] = parents;
265
+ if (!a || !b || typeof a.prompt !== "string" || typeof b.prompt !== "string") {
266
+ throw new TypeError("GepaOptimizer.merge: both parents must carry a non-empty `prompt` string");
267
+ }
268
+ if (a.prompt.length === 0 || b.prompt.length === 0) {
269
+ throw new TypeError("GepaOptimizer.merge: parent prompts must be non-empty");
270
+ }
271
+ // R1-self-check: emit a merge for two IDENTICAL parents would be a
272
+ // waste of an LLM call AND likely produce a near-identical mutation
273
+ // anyway. Fail loud so the caller fixes the pairing logic upstream
274
+ // rather than silently consume budget.
275
+ if (a.id === b.id) {
276
+ throw new TypeError(`GepaOptimizer.merge: both parents share id "${a.id}" — merge is only ` +
277
+ `meaningful between distinct Pareto-front members.`);
278
+ }
279
+ const template = opts.mergePromptTemplate ?? DEFAULT_MERGE_TEMPLATE;
280
+ // Scalar score for the prompt header — purely informational for the
281
+ // reflection LM. Sum of variant.metrics values (best-effort), zero
282
+ // for missing or non-finite. Caller can override via the template.
283
+ const scoreOf = (v) => {
284
+ let s = 0;
285
+ for (const val of Object.values(v.metrics)) {
286
+ if (typeof val === "number" && Number.isFinite(val))
287
+ s += val;
288
+ }
289
+ return s;
290
+ };
291
+ // Template-injection defense (S1235): all FOUR metadata placeholders
292
+ // (`{ID_A}` / `{ID_B}` / `{SCORE_A}` / `{SCORE_B}`) are substituted
293
+ // FIRST, then the user-controlled `{PROMPT_A}` / `{PROMPT_B}` slots
294
+ // LAST. After the metadata substitutions are done, any literal
295
+ // `{ID_*}` / `{SCORE_*}` strings INSIDE the parent prompts cannot be
296
+ // re-processed — `String.prototype.replace` only matches what's
297
+ // currently in the working string, and the user content does not
298
+ // enter the working string until the final two replacements.
299
+ //
300
+ // R1 V0.5.1 self-check (S1235): R1 critic suggested swapping the
301
+ // order, but that would BREAK the defense — putting PROMPT first
302
+ // would let the subsequent ID/SCORE replacements grab literal
303
+ // `{ID_A}` etc. inside the user content. The original ordering is
304
+ // correct; the test coverage for SCORE placeholders is what was
305
+ // genuinely missing, and is now added in `tests/v0.5.1-features.test.ts`.
306
+ const metaPrompt = template
307
+ .replace("{ID_A}", a.id)
308
+ .replace("{ID_B}", b.id)
309
+ .replace("{SCORE_A}", scoreOf(a).toFixed(2))
310
+ .replace("{SCORE_B}", scoreOf(b).toFixed(2))
311
+ .replace("{PROMPT_A}", a.prompt)
312
+ .replace("{PROMPT_B}", b.prompt);
313
+ let merged = await this.reflectionRunPrompt(metaPrompt);
314
+ merged = this.cleanOutput(merged);
315
+ const longerParent = a.prompt.length >= b.prompt.length ? a.prompt : b.prompt;
316
+ const maxLength = opts.maxMergeLength ?? Math.max(Math.round(longerParent.length * 1.3), 3500);
317
+ if (merged.length > maxLength) {
318
+ merged = this.truncateAtSentenceBoundary(merged, maxLength);
319
+ }
320
+ return { id: this.makeMergeId(a.id, b.id), prompt: merged };
321
+ }
322
+ /** Strip markdown fences + leading/trailing whitespace — mirrors `Reflector.cleanOutput`. */
323
+ cleanOutput(raw) {
324
+ let out = raw.trim();
325
+ const fence = out.match(/^```[a-z]*\n?([\s\S]*?)\n?```$/i);
326
+ if (fence)
327
+ out = fence[1].trim();
328
+ return out;
329
+ }
330
+ /** Sentence-boundary truncation — mirrors `Reflector.truncateAtSentenceBoundary`. */
331
+ truncateAtSentenceBoundary(text, maxLength) {
332
+ if (text.length <= maxLength)
333
+ return text;
334
+ const truncated = text.slice(0, maxLength);
335
+ const lastPeriod = truncated.lastIndexOf(".");
336
+ const lastNewline = truncated.lastIndexOf("\n");
337
+ const cutPoint = Math.max(lastPeriod, lastNewline);
338
+ return cutPoint > maxLength * 0.7
339
+ ? truncated.slice(0, cutPoint + 1)
340
+ : truncated;
341
+ }
187
342
  /** Clamp variant count into the documented bounds. */
188
343
  clampN(n) {
189
344
  if (!Number.isFinite(n))
@@ -194,5 +349,9 @@ export class GepaOptimizer {
194
349
  makeId(i) {
195
350
  return `gepa-cand-${i}`;
196
351
  }
352
+ /** V0.5.1 — stable merged-variant id: `gepa-merge-${idA}+${idB}`. */
353
+ makeMergeId(idA, idB) {
354
+ return `gepa-merge-${idA}+${idB}`;
355
+ }
197
356
  }
198
357
  //# sourceMappingURL=optimizer-gepa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimizer-gepa.js","sourceRoot":"","sources":["../../../src/evolution/optimizer-gepa.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"optimizer-gepa.js","sourceRoot":"","sources":["../../../src/evolution/optimizer-gepa.ts"],"names":[],"mappings":"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"}
@@ -105,12 +105,62 @@ export declare function scalarise<T extends Record<string, unknown>>(variant: T,
105
105
  * Pareto-select up to `maxKeep` variants:
106
106
  * 1. Compute non-dominated front.
107
107
  * 2. If front size ≤ maxKeep: return front.
108
- * 3. If front size > maxKeep: sort by scalarised score (descending),
109
- * keep top maxKeep.
108
+ * 3. If front size > maxKeep: truncate via the configured strategy
109
+ * (default `"scalarised"` — weighted-sum tie-break).
110
110
  *
111
111
  * Use this when the GEPA generation budget is fixed (e.g. carry exactly
112
112
  * 3 variants to the next round) but the Pareto front happens to be
113
113
  * larger.
114
+ *
115
+ * V0.5.1 (S1235) — `truncationStrategy` opens up two new modes that
116
+ * close R1 Research deferrals from V0.5.0-alpha.2:
117
+ * - `"scalarised"` (default, V0.5.0 behaviour): weighted-sum tie-break.
118
+ * Scale-sensitive — pre-normalise objectives if their value ranges
119
+ * differ (see `ParetoObjective.weight` docstring).
120
+ * - `"crowding"` (NSGA-II Deb 2002): density-estimator that favours
121
+ * variants in sparsely-populated regions of the front. Per-objective
122
+ * min-max normalisation makes it scale-safe. Boundary variants
123
+ * always survive (assigned Infinity). Recommended for diversity-
124
+ * critical workloads.
125
+
126
+ * GEPA Algorithm 2's instance-proportional coverage sampling is the
127
+ * third paper strategy and is NOT implemented in V0.5.1 — the caller-
128
+ * side coverage data needed to drive it varies enough across domains
129
+ * that a one-size-fits-all signature would mislead. Backlog for V0.6.
130
+ */
131
+ export type ParetoTruncationStrategy = "scalarised" | "crowding";
132
+ export declare function paretoSelect<T extends Record<string, unknown>>(variants: ReadonlyArray<T>, objectives: ReadonlyArray<ParetoObjective<T>>, maxKeep?: number, truncationStrategy?: ParetoTruncationStrategy): T[];
133
+ /**
134
+ * Compute the NSGA-II crowding distance for each variant in a
135
+ * non-dominated front. Returns an array of the same length as
136
+ * `variants`, indexed in input order.
137
+ *
138
+ * The classic Deb 2002 algorithm:
139
+ * 1. For each objective `m`: sort the front by `m`.
140
+ * 2. Boundary variants (lowest + highest `m`) get distance `+Infinity`
141
+ * so they always survive truncation.
142
+ * 3. Interior variants get the normalised gap between neighbours:
143
+ * `(f_m(x_{i+1}) - f_m(x_{i-1})) / (f_m_max - f_m_min)`
144
+ * 4. Sum across objectives.
145
+ *
146
+ * **Pure**, no I/O, deterministic. Safe to call from the hot path of
147
+ * paretoSelect. Returns `0` for any variant whose objective is non-finite
148
+ * — never returns NaN.
149
+ *
150
+ * NEW V0.5.1 (S1235).
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * import { crowdingDistance, DARWIN_DEFAULT_OBJECTIVES } from "darwin-agents";
155
+ *
156
+ * const front = [
157
+ * { id: "a", qualityScore: 8, sourceCount: 3, durationMs: 100, outputLength: 500 },
158
+ * { id: "b", qualityScore: 9, sourceCount: 2, durationMs: 200, outputLength: 400 },
159
+ * { id: "c", qualityScore: 7, sourceCount: 4, durationMs: 150, outputLength: 600 },
160
+ * ];
161
+ * const distances = crowdingDistance(front, DARWIN_DEFAULT_OBJECTIVES);
162
+ * // distances[i] = sum of per-objective normalised neighbour gaps for variant i
163
+ * ```
114
164
  */
115
- export declare function paretoSelect<T extends Record<string, unknown>>(variants: ReadonlyArray<T>, objectives: ReadonlyArray<ParetoObjective<T>>, maxKeep?: number): T[];
165
+ export declare function crowdingDistance<T extends Record<string, unknown>>(variants: ReadonlyArray<T>, objectives: ReadonlyArray<ParetoObjective<T>>): number[];
116
166
  //# sourceMappingURL=pareto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pareto.d.ts","sourceRoot":"","sources":["../../../src/evolution/pareto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC,CAAC;IACb;;;OAGG;IACH,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,eAAe,CAAC;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAKD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,OAAO,CAeT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,CAAC,EAAE,CAoBL;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,MAAM,CAUR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAC7C,OAAO,CAAC,EAAE,MAAM,GACf,CAAC,EAAE,CAML"}
1
+ {"version":3,"file":"pareto.d.ts","sourceRoot":"","sources":["../../../src/evolution/pareto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC,CAAC;IACb;;;OAGG;IACH,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,eAAe,CAAC;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAKD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,OAAO,CAeT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,CAAC,EAAE,CAoBL;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,MAAM,CAUR;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,UAAU,CAAC;AAEjE,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAC7C,OAAO,CAAC,EAAE,MAAM,EAChB,kBAAkB,GAAE,wBAAuC,GAC1D,CAAC,EAAE,CAkBL;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAC5C,MAAM,EAAE,CAoDV"}
@@ -118,23 +118,108 @@ export function scalarise(variant, objectives) {
118
118
  }
119
119
  return total;
120
120
  }
121
- /**
122
- * Pareto-select up to `maxKeep` variants:
123
- * 1. Compute non-dominated front.
124
- * 2. If front size ≤ maxKeep: return front.
125
- * 3. If front size > maxKeep: sort by scalarised score (descending),
126
- * keep top maxKeep.
127
- *
128
- * Use this when the GEPA generation budget is fixed (e.g. carry exactly
129
- * 3 variants to the next round) but the Pareto front happens to be
130
- * larger.
131
- */
132
- export function paretoSelect(variants, objectives, maxKeep) {
121
+ export function paretoSelect(variants, objectives, maxKeep, truncationStrategy = "scalarised") {
133
122
  const front = nonDominatedFront(variants, objectives);
134
123
  if (typeof maxKeep !== "number" || front.length <= maxKeep)
135
124
  return front;
125
+ if (truncationStrategy === "crowding") {
126
+ // NSGA-II crowding-distance truncation (Deb et al. 2002, IEEE TEVC).
127
+ // Per-objective min-max normalisation makes this scale-safe — the
128
+ // tie-break does NOT inherit `scalarise`'s scale-sensitivity.
129
+ const distances = crowdingDistance(front, objectives);
130
+ return [...front]
131
+ .map((v, i) => ({ v, cd: distances[i] }))
132
+ .sort((a, b) => b.cd - a.cd)
133
+ .slice(0, maxKeep)
134
+ .map((x) => x.v);
135
+ }
136
+ // Default "scalarised" — preserves V0.5.0 behaviour exactly.
136
137
  return [...front]
137
138
  .sort((a, b) => scalarise(b, objectives) - scalarise(a, objectives))
138
139
  .slice(0, maxKeep);
139
140
  }
141
+ /**
142
+ * Compute the NSGA-II crowding distance for each variant in a
143
+ * non-dominated front. Returns an array of the same length as
144
+ * `variants`, indexed in input order.
145
+ *
146
+ * The classic Deb 2002 algorithm:
147
+ * 1. For each objective `m`: sort the front by `m`.
148
+ * 2. Boundary variants (lowest + highest `m`) get distance `+Infinity`
149
+ * so they always survive truncation.
150
+ * 3. Interior variants get the normalised gap between neighbours:
151
+ * `(f_m(x_{i+1}) - f_m(x_{i-1})) / (f_m_max - f_m_min)`
152
+ * 4. Sum across objectives.
153
+ *
154
+ * **Pure**, no I/O, deterministic. Safe to call from the hot path of
155
+ * paretoSelect. Returns `0` for any variant whose objective is non-finite
156
+ * — never returns NaN.
157
+ *
158
+ * NEW V0.5.1 (S1235).
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * import { crowdingDistance, DARWIN_DEFAULT_OBJECTIVES } from "darwin-agents";
163
+ *
164
+ * const front = [
165
+ * { id: "a", qualityScore: 8, sourceCount: 3, durationMs: 100, outputLength: 500 },
166
+ * { id: "b", qualityScore: 9, sourceCount: 2, durationMs: 200, outputLength: 400 },
167
+ * { id: "c", qualityScore: 7, sourceCount: 4, durationMs: 150, outputLength: 600 },
168
+ * ];
169
+ * const distances = crowdingDistance(front, DARWIN_DEFAULT_OBJECTIVES);
170
+ * // distances[i] = sum of per-objective normalised neighbour gaps for variant i
171
+ * ```
172
+ */
173
+ export function crowdingDistance(variants, objectives) {
174
+ const n = variants.length;
175
+ if (n === 0)
176
+ return [];
177
+ if (n === 1)
178
+ return [Number.POSITIVE_INFINITY];
179
+ if (n === 2) {
180
+ // Both are boundaries on every objective — assign Infinity to both
181
+ // so truncation does not pick arbitrarily.
182
+ return [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY];
183
+ }
184
+ if (objectives.length === 0)
185
+ return Array(n).fill(0);
186
+ const distances = Array(n).fill(0);
187
+ for (const obj of objectives) {
188
+ // Build [origIndex, value] pairs so we can sort without losing the
189
+ // mapping back to the input order.
190
+ const indexed = [];
191
+ let allFinite = true;
192
+ for (let i = 0; i < n; i++) {
193
+ const raw = variants[i][obj.key];
194
+ if (typeof raw !== "number" || !Number.isFinite(raw)) {
195
+ allFinite = false;
196
+ break;
197
+ }
198
+ // Direction-normalise so "better" is always larger — keeps the
199
+ // boundary assignment symmetric for maximize / minimize.
200
+ indexed.push({ i, v: obj.direction === "maximize" ? raw : -raw });
201
+ }
202
+ if (!allFinite)
203
+ continue; // Skip objectives with non-finite values.
204
+ indexed.sort((a, b) => a.v - b.v);
205
+ const min = indexed[0].v;
206
+ const max = indexed[n - 1].v;
207
+ const range = max - min;
208
+ // Boundary variants get +Infinity — assigned BEFORE the range check
209
+ // so degenerate-range fronts still keep their boundaries unique.
210
+ distances[indexed[0].i] = Number.POSITIVE_INFINITY;
211
+ distances[indexed[n - 1].i] = Number.POSITIVE_INFINITY;
212
+ if (range === 0)
213
+ continue; // All variants identical on this objective.
214
+ for (let k = 1; k < n - 1; k++) {
215
+ // Skip if we already hit Infinity from a previous objective —
216
+ // adding to Infinity is still Infinity, so no work to do.
217
+ if (distances[indexed[k].i] === Number.POSITIVE_INFINITY)
218
+ continue;
219
+ const gap = (indexed[k + 1].v - indexed[k - 1].v) / range;
220
+ distances[indexed[k].i] += gap;
221
+ }
222
+ }
223
+ return distances;
224
+ }
140
225
  //# sourceMappingURL=pareto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pareto.js","sourceRoot":"","sources":["../../../src/evolution/pareto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAwCH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAKhC;IACJ,EAAE,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE;IAC3D,EAAE,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;IAC3D,EAAE,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE;IAC3D,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;CAC3D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,CAAI,EACJ,CAAI,EACJ,UAA6C;IAE7C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,uBAAuB,GAAG,KAAK,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/D,+DAA+D;QAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,GAAG,KAAK;YAAE,OAAO,KAAK,CAAC,CAAC,gDAAgD;QACjF,IAAI,KAAK,GAAG,KAAK;YAAE,uBAAuB,GAAG,IAAI,CAAC;IACpD,CAAC;IACD,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAA0B,EAC1B,UAA6C;IAE7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,gEAAgE;QAChE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QAC/B,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAS;YACtB,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;gBACnD,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,CAAC,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,OAAU,EACV,UAA6C;IAE7C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAC3D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;QAC/B,MAAM,iBAAiB,GAAG,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,KAAK,IAAI,iBAAiB,GAAG,MAAM,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA0B,EAC1B,UAA6C,EAC7C,OAAgB;IAEhB,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO;QAAE,OAAO,KAAK,CAAC;IACzE,OAAO,CAAC,GAAG,KAAK,CAAC;SACd,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;SACnE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"pareto.js","sourceRoot":"","sources":["../../../src/evolution/pareto.ts"],"names":[],"mappings":"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"}
@@ -28,13 +28,14 @@
28
28
  * deviations from Algorithm 1/2 of the GEPA paper (arxiv 2507.19457).
29
29
  * For a feature-complete GEPA experience use the upstream Python tool.
30
30
  *
31
- * **Single-LM design note (R1 Research Finding F7, S1185):** GEPA's
32
- * official guidance is to use a STRONGER LM for reflection than for
33
- * task execution (their `reflection_lm` parameter). This adapter
34
- * intentionally accepts only one injected `RunPromptFn` to keep the
35
- * V0.5 alpha surface minimal. Stronger-reflection-LM support
36
- * (`reflectionRunPrompt` override) is deferred to V0.5.1 pass a
37
- * higher-tier model in your single `runPrompt` callback as a workaround.
31
+ * **Stronger reflection LM (V0.5.1, S1235):** GEPA's official guidance
32
+ * is to use a STRONGER LM for reflection than for task execution
33
+ * (their `reflection_lm` parameter). Direct support shipped in V0.5.1
34
+ * via `GepaOptimizerOptions.reflectionRunPrompt` on `GepaOptimizer`'s
35
+ * constructor the override is wired into the internal Reflector so
36
+ * `reflect()` calls route through the stronger LM. The `Reflector`
37
+ * class itself remains single-LM by design (the override lives one
38
+ * layer up in `GepaOptimizer`).
38
39
  */
39
40
  import type { ExecutionTrace } from "../types.js";
40
41
  import type { RunPromptFn } from "./run-prompt-fn.js";
@@ -1 +1 @@
1
- {"version":3,"file":"reflector.d.ts","sourceRoot":"","sources":["../../../src/evolution/reflector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKtD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAsBD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,SAAS,EAAE,WAAW;IAOlC;;;;;;;OAOG;IACG,OAAO,CACX,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAC5C,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC;IA+ClB,iCAAiC;IACjC,OAAO,CAAC,cAAc;IA2BtB,6DAA6D;IAC7D,OAAO,CAAC,WAAW;IAQnB,yEAAyE;IACzE,OAAO,CAAC,0BAA0B;CAUnC"}
1
+ {"version":3,"file":"reflector.d.ts","sourceRoot":"","sources":["../../../src/evolution/reflector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKtD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAsBD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,SAAS,EAAE,WAAW;IAOlC;;;;;;;OAOG;IACG,OAAO,CACX,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAC5C,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC;IA+ClB,iCAAiC;IACjC,OAAO,CAAC,cAAc;IA2BtB,6DAA6D;IAC7D,OAAO,CAAC,WAAW;IAQnB,yEAAyE;IACzE,OAAO,CAAC,0BAA0B;CAUnC"}
@@ -28,13 +28,14 @@
28
28
  * deviations from Algorithm 1/2 of the GEPA paper (arxiv 2507.19457).
29
29
  * For a feature-complete GEPA experience use the upstream Python tool.
30
30
  *
31
- * **Single-LM design note (R1 Research Finding F7, S1185):** GEPA's
32
- * official guidance is to use a STRONGER LM for reflection than for
33
- * task execution (their `reflection_lm` parameter). This adapter
34
- * intentionally accepts only one injected `RunPromptFn` to keep the
35
- * V0.5 alpha surface minimal. Stronger-reflection-LM support
36
- * (`reflectionRunPrompt` override) is deferred to V0.5.1 pass a
37
- * higher-tier model in your single `runPrompt` callback as a workaround.
31
+ * **Stronger reflection LM (V0.5.1, S1235):** GEPA's official guidance
32
+ * is to use a STRONGER LM for reflection than for task execution
33
+ * (their `reflection_lm` parameter). Direct support shipped in V0.5.1
34
+ * via `GepaOptimizerOptions.reflectionRunPrompt` on `GepaOptimizer`'s
35
+ * constructor the override is wired into the internal Reflector so
36
+ * `reflect()` calls route through the stronger LM. The `Reflector`
37
+ * class itself remains single-LM by design (the override lives one
38
+ * layer up in `GepaOptimizer`).
38
39
  */
39
40
  const DEFAULT_FEEDBACK_CAP = 2000;
40
41
  const DEFAULT_REFLECTION_TEMPLATE = `
@@ -1 +1 @@
1
- {"version":3,"file":"reflector.js","sourceRoot":"","sources":["../../../src/evolution/reflector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reflector.js","sourceRoot":"","sources":["../../../src/evolution/reflector.ts"],"names":[],"mappings":"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"}
@@ -31,8 +31,8 @@ export { ClaudeCliProvider } from './providers/claude-cli.js';
31
31
  export { createMemory, SqliteMemoryProvider, PostgresMemoryProvider } from './memory/index.js';
32
32
  export { loadNotificationConfig } from './evolution/notifications.js';
33
33
  export type { NotificationConfig } from './evolution/notifications.js';
34
- export { dominates, nonDominatedFront, paretoSelect, scalarise, DARWIN_DEFAULT_OBJECTIVES, type ParetoObjective, } from './evolution/pareto.js';
34
+ export { dominates, nonDominatedFront, paretoSelect, scalarise, crowdingDistance, DARWIN_DEFAULT_OBJECTIVES, type ParetoObjective, type ParetoTruncationStrategy, } from './evolution/pareto.js';
35
35
  export { Reflector, type ReflectiveFeedback, type ReflectOptions, } from './evolution/reflector.js';
36
36
  export type { RunPromptFn } from './evolution/run-prompt-fn.js';
37
- export { GepaOptimizer, type ScoredVariant, type GenerateOptions as GepaGenerateOptions, type NextGenerationOptions as GepaNextGenerationOptions, } from './evolution/optimizer-gepa.js';
37
+ export { GepaOptimizer, type ScoredVariant, type GenerateOptions as GepaGenerateOptions, type NextGenerationOptions as GepaNextGenerationOptions, type GepaOptimizerOptions, type MergeOptions as GepaMergeOptions, } from './evolution/optimizer-gepa.js';
38
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGjF,YAAY,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG7D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,yBAAyB,EACzB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,qBAAqB,IAAI,yBAAyB,GACxD,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGjF,YAAY,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG7D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAIvE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,eAAe,EACpB,KAAK,wBAAwB,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,qBAAqB,IAAI,yBAAyB,EACvD,KAAK,oBAAoB,EACzB,KAAK,YAAY,IAAI,gBAAgB,GACtC,MAAM,+BAA+B,CAAC"}
package/dist/src/index.js CHANGED
@@ -35,7 +35,8 @@ export { createMemory, SqliteMemoryProvider, PostgresMemoryProvider } from './me
35
35
  // Notifications
36
36
  export { loadNotificationConfig } from './evolution/notifications.js';
37
37
  // V0.5.0-alpha.2 — GEPA-Style Reflective Optimizer (S1185 Phase 2 A2)
38
- export { dominates, nonDominatedFront, paretoSelect, scalarise, DARWIN_DEFAULT_OBJECTIVES, } from './evolution/pareto.js';
38
+ // V0.5.1 crowdingDistance + ParetoTruncationStrategy + GepaOptimizer.merge + reflectionRunPrompt
39
+ export { dominates, nonDominatedFront, paretoSelect, scalarise, crowdingDistance, DARWIN_DEFAULT_OBJECTIVES, } from './evolution/pareto.js';
39
40
  export { Reflector, } from './evolution/reflector.js';
40
41
  export { GepaOptimizer, } from './evolution/optimizer-gepa.js';
41
42
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,WAAW;AACX,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,8DAA8D;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AA2B7D,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,kBAAkB;AAClB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvF,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE/F,gBAAgB;AAChB,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,sEAAsE;AACtE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,yBAAyB,GAE1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,SAAS,GAGV,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,aAAa,GAId,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,WAAW;AACX,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,8DAA8D;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AA2B7D,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,kBAAkB;AAClB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvF,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE/F,gBAAgB;AAChB,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,sEAAsE;AACtE,mGAAmG;AACnG,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,yBAAyB,GAG1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,SAAS,GAGV,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,aAAa,GAMd,MAAM,+BAA+B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "darwin-agents",
3
- "version": "0.5.0-alpha.2",
3
+ "version": "0.5.1-alpha.2",
4
4
  "description": "AI agents that improve themselves. Self-evolving prompts via A/B testing, multi-model critics, safety gates, and pattern detection.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "dependencies": {},
60
60
  "peerDependencies": {
61
- "better-sqlite3": "^11.0.0",
61
+ "better-sqlite3": "^11.0.0 || ^12.0.0",
62
62
  "pg": "^8.0.0"
63
63
  },
64
64
  "peerDependenciesMeta": {
@@ -71,6 +71,7 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/better-sqlite3": "^7.6.13",
74
+ "better-sqlite3": "^12.10.0",
74
75
  "@types/node": "^25.6.0",
75
76
  "@types/pg": "^8.11.0",
76
77
  "tsx": "^4.19.0",