darwin-agents 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +62 -1
- package/dist/src/cli/canary.d.ts +13 -0
- package/dist/src/cli/canary.d.ts.map +1 -0
- package/dist/src/cli/canary.js +66 -0
- package/dist/src/cli/canary.js.map +1 -0
- package/dist/src/cli/evolution-flags.d.ts +40 -0
- package/dist/src/cli/evolution-flags.d.ts.map +1 -0
- package/dist/src/cli/evolution-flags.js +106 -0
- package/dist/src/cli/evolution-flags.js.map +1 -0
- package/dist/src/cli/evolve.d.ts +10 -1
- package/dist/src/cli/evolve.d.ts.map +1 -1
- package/dist/src/cli/evolve.js +93 -8
- package/dist/src/cli/evolve.js.map +1 -1
- package/dist/src/cli/index.js +18 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/run.d.ts.map +1 -1
- package/dist/src/cli/run.js +54 -70
- package/dist/src/cli/run.js.map +1 -1
- package/dist/src/evolution/build-loop.d.ts +20 -0
- package/dist/src/evolution/build-loop.d.ts.map +1 -0
- package/dist/src/evolution/build-loop.js +67 -0
- package/dist/src/evolution/build-loop.js.map +1 -0
- package/dist/src/evolution/canary.d.ts +164 -0
- package/dist/src/evolution/canary.d.ts.map +1 -0
- package/dist/src/evolution/canary.js +244 -0
- package/dist/src/evolution/canary.js.map +1 -0
- package/dist/src/evolution/critic-families.d.ts +51 -0
- package/dist/src/evolution/critic-families.d.ts.map +1 -0
- package/dist/src/evolution/critic-families.js +51 -0
- package/dist/src/evolution/critic-families.js.map +1 -0
- package/dist/src/evolution/enabled-state.d.ts +59 -0
- package/dist/src/evolution/enabled-state.d.ts.map +1 -0
- package/dist/src/evolution/enabled-state.js +122 -0
- package/dist/src/evolution/enabled-state.js.map +1 -0
- package/dist/src/evolution/loop.d.ts +46 -0
- package/dist/src/evolution/loop.d.ts.map +1 -1
- package/dist/src/evolution/loop.js +119 -1
- package/dist/src/evolution/loop.js.map +1 -1
- package/dist/src/evolution/parse-score.d.ts +35 -0
- package/dist/src/evolution/parse-score.d.ts.map +1 -0
- package/dist/src/evolution/parse-score.js +115 -0
- package/dist/src/evolution/parse-score.js.map +1 -0
- package/dist/src/evolution/tracker.d.ts +13 -0
- package/dist/src/evolution/tracker.d.ts.map +1 -1
- package/dist/src/evolution/tracker.js +34 -0
- package/dist/src/evolution/tracker.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/memory/postgres-memory.d.ts.map +1 -1
- package/dist/src/memory/postgres-memory.js +1 -0
- package/dist/src/memory/postgres-memory.js.map +1 -1
- package/dist/src/memory/sqlite-memory.d.ts.map +1 -1
- package/dist/src/memory/sqlite-memory.js +1 -0
- package/dist/src/memory/sqlite-memory.js.map +1 -1
- package/dist/src/types.d.ts +45 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/agents/analyst.d.ts +0 -11
- package/dist/agents/analyst.d.ts.map +0 -1
- package/dist/agents/analyst.js +0 -78
- package/dist/agents/analyst.js.map +0 -1
- package/dist/agents/blog-writer.d.ts +0 -13
- package/dist/agents/blog-writer.d.ts.map +0 -1
- package/dist/agents/blog-writer.js +0 -59
- package/dist/agents/blog-writer.js.map +0 -1
- package/dist/agents/critic.d.ts +0 -11
- package/dist/agents/critic.d.ts.map +0 -1
- package/dist/agents/critic.js +0 -57
- package/dist/agents/critic.js.map +0 -1
- package/dist/agents/index.d.ts +0 -15
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -31
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/investigator-critic.d.ts +0 -10
- package/dist/agents/investigator-critic.d.ts.map +0 -1
- package/dist/agents/investigator-critic.js +0 -78
- package/dist/agents/investigator-critic.js.map +0 -1
- package/dist/agents/investigator.d.ts +0 -13
- package/dist/agents/investigator.d.ts.map +0 -1
- package/dist/agents/investigator.js +0 -105
- package/dist/agents/investigator.js.map +0 -1
- package/dist/agents/marketing.d.ts +0 -13
- package/dist/agents/marketing.d.ts.map +0 -1
- package/dist/agents/marketing.js +0 -59
- package/dist/agents/marketing.js.map +0 -1
- package/dist/agents/researcher.d.ts +0 -11
- package/dist/agents/researcher.d.ts.map +0 -1
- package/dist/agents/researcher.js +0 -68
- package/dist/agents/researcher.js.map +0 -1
- package/dist/agents/writer.d.ts +0 -9
- package/dist/agents/writer.d.ts.map +0 -1
- package/dist/agents/writer.js +0 -47
- package/dist/agents/writer.js.map +0 -1
- package/dist/cli/create.d.ts +0 -11
- package/dist/cli/create.d.ts.map +0 -1
- package/dist/cli/create.js +0 -104
- package/dist/cli/create.js.map +0 -1
- package/dist/cli/evolve.d.ts +0 -13
- package/dist/cli/evolve.d.ts.map +0 -1
- package/dist/cli/evolve.js +0 -69
- package/dist/cli/evolve.js.map +0 -1
- package/dist/cli/index.d.ts +0 -13
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -84
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/init.d.ts +0 -12
- package/dist/cli/init.d.ts.map +0 -1
- package/dist/cli/init.js +0 -68
- package/dist/cli/init.js.map +0 -1
- package/dist/cli/run.d.ts +0 -7
- package/dist/cli/run.d.ts.map +0 -1
- package/dist/cli/run.js +0 -371
- package/dist/cli/run.js.map +0 -1
- package/dist/cli/status.d.ts +0 -7
- package/dist/cli/status.d.ts.map +0 -1
- package/dist/cli/status.js +0 -123
- package/dist/cli/status.js.map +0 -1
- package/dist/core/agent.d.ts +0 -53
- package/dist/core/agent.d.ts.map +0 -1
- package/dist/core/agent.js +0 -172
- package/dist/core/agent.js.map +0 -1
- package/dist/core/runner.d.ts +0 -75
- package/dist/core/runner.d.ts.map +0 -1
- package/dist/core/runner.js +0 -255
- package/dist/core/runner.js.map +0 -1
- package/dist/evolution/loop.d.ts +0 -100
- package/dist/evolution/loop.d.ts.map +0 -1
- package/dist/evolution/loop.js +0 -424
- package/dist/evolution/loop.js.map +0 -1
- package/dist/evolution/multi-critic.d.ts +0 -58
- package/dist/evolution/multi-critic.d.ts.map +0 -1
- package/dist/evolution/multi-critic.js +0 -326
- package/dist/evolution/multi-critic.js.map +0 -1
- package/dist/evolution/notifications.d.ts +0 -32
- package/dist/evolution/notifications.d.ts.map +0 -1
- package/dist/evolution/notifications.js +0 -92
- package/dist/evolution/notifications.js.map +0 -1
- package/dist/evolution/optimizer.d.ts +0 -64
- package/dist/evolution/optimizer.d.ts.map +0 -1
- package/dist/evolution/optimizer.js +0 -223
- package/dist/evolution/optimizer.js.map +0 -1
- package/dist/evolution/patterns.d.ts +0 -63
- package/dist/evolution/patterns.d.ts.map +0 -1
- package/dist/evolution/patterns.js +0 -297
- package/dist/evolution/patterns.js.map +0 -1
- package/dist/evolution/safety.d.ts +0 -76
- package/dist/evolution/safety.d.ts.map +0 -1
- package/dist/evolution/safety.js +0 -182
- package/dist/evolution/safety.js.map +0 -1
- package/dist/evolution/tracker.d.ts +0 -48
- package/dist/evolution/tracker.d.ts.map +0 -1
- package/dist/evolution/tracker.js +0 -163
- package/dist/evolution/tracker.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -35
- package/dist/index.js.map +0 -1
- package/dist/memory/index.d.ts +0 -32
- package/dist/memory/index.d.ts.map +0 -1
- package/dist/memory/index.js +0 -49
- package/dist/memory/index.js.map +0 -1
- package/dist/memory/postgres-memory.d.ts +0 -52
- package/dist/memory/postgres-memory.d.ts.map +0 -1
- package/dist/memory/postgres-memory.js +0 -515
- package/dist/memory/postgres-memory.js.map +0 -1
- package/dist/memory/sqlite-memory.d.ts +0 -36
- package/dist/memory/sqlite-memory.d.ts.map +0 -1
- package/dist/memory/sqlite-memory.js +0 -380
- package/dist/memory/sqlite-memory.js.map +0 -1
- package/dist/providers/anthropic.d.ts +0 -20
- package/dist/providers/anthropic.d.ts.map +0 -1
- package/dist/providers/anthropic.js +0 -82
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/claude-cli.d.ts +0 -35
- package/dist/providers/claude-cli.d.ts.map +0 -1
- package/dist/providers/claude-cli.js +0 -153
- package/dist/providers/claude-cli.js.map +0 -1
- package/dist/providers/index.d.ts +0 -39
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -58
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/ollama.d.ts +0 -17
- package/dist/providers/ollama.d.ts.map +0 -1
- package/dist/providers/ollama.js +0 -64
- package/dist/providers/ollama.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -19
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/providers/openai.js +0 -75
- package/dist/providers/openai.js.map +0 -1
- package/dist/providers/types.d.ts +0 -62
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/providers/types.js +0 -9
- package/dist/providers/types.js.map +0 -1
- package/dist/types.d.ts +0 -221
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -19
- package/dist/types.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.0] — 2026-06-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Validate-by-reproduce drift-detection canary** (Phase 2 A5) — new
|
|
10
|
+
`src/evolution/canary.ts` + a `darwin canary <agent>` command. The A/B gate
|
|
11
|
+
guards prompt *quality*; the canary guards *behaviour*. It compares an agent's
|
|
12
|
+
recent execution trajectories (captured in A1) against a frozen baseline using
|
|
13
|
+
tolerance-based metrics — unordered tool-set Jaccard, ordered tool-sequence
|
|
14
|
+
similarity, turn-count ratio, error-rate delta — and flags drift the score can
|
|
15
|
+
miss (a model update or a broken tool changing *how* the agent works while the
|
|
16
|
+
quality score stays flat). Exact-hash equivalence is deliberately avoided (LLM
|
|
17
|
+
runs are non-deterministic). Drift requires a *pattern* (default ≥2 of N runs),
|
|
18
|
+
and the baseline is pinned to the active prompt version so an intentional
|
|
19
|
+
evolution reports `insufficient-data` (re-baseline) rather than a false alarm.
|
|
20
|
+
Pure and zero-dep; `--json` + `--exit-on-drift` for CI. The metrics and the
|
|
21
|
+
`runCanaryOverExperiments` orchestrator are exported from the package root so
|
|
22
|
+
consumers can run the same check on their own captured trajectories.
|
|
23
|
+
|
|
24
|
+
- **Cross-family critic diversity check** (`src/evolution/critic-families.ts`).
|
|
25
|
+
Multi-critic evaluation spreads critics across model families to reduce
|
|
26
|
+
LLM-as-judge bias — but only when more than one provider key is present.
|
|
27
|
+
Otherwise all three critics collapse onto a single family (`claude-cli` and
|
|
28
|
+
`anthropic-api` are the *same* family, differing only in latency) with no
|
|
29
|
+
signal to the operator. The run path now warns when the critics share one
|
|
30
|
+
family, and hard-fails when `DARWIN_REQUIRE_CROSS_FAMILY` is set (CI / strict
|
|
31
|
+
setups). Default behaviour is unchanged apart from the new warning.
|
|
32
|
+
|
|
33
|
+
## [0.8.0] — 2026-06-21
|
|
34
|
+
|
|
35
|
+
**Evolution wired end-to-end through the CLI, plus three correctness fixes.** The
|
|
36
|
+
v0.7 evolution surfaces existed but the `darwin evolve` command couldn't fully
|
|
37
|
+
drive them; this release closes that gap and hardens score parsing. The
|
|
38
|
+
automatic loop is behaviour-preserving — the gated path still passes the
|
|
39
|
+
existing loop/GEPA suites unchanged.
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **`darwin evolve <agent> --force`** now runs the loop's real
|
|
44
|
+
variant-generation + A/B-start path on demand (`DarwinLoop.forceEvolve()`),
|
|
45
|
+
bypassing the automatic "enough runs / actionable patterns / data quality"
|
|
46
|
+
gates while still refusing the impossible cases (no active prompt, no recorded
|
|
47
|
+
experiments, an A/B test already running). It was previously a stub that
|
|
48
|
+
printed "not yet available" while the help text advertised it.
|
|
49
|
+
- **`src/evolution/build-loop.ts`** — shared loop wiring (legacy optimizer +
|
|
50
|
+
opt-in GEPA) used by both `cli/run.ts` and the new `--force` command.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **`darwin evolve <agent> --enable|--disable` now persists.** The flag mutated
|
|
55
|
+
only the in-memory agent singleton, so it was lost on process exit and `darwin
|
|
56
|
+
run` read the static source default again. A new `DarwinState.evolutionEnabled`
|
|
57
|
+
override map (round-tripped by every backend's existing JSON state blob) is set
|
|
58
|
+
atomically by the evolve command and wins over the static default in the run
|
|
59
|
+
path. Persisting an enable on an agent with no evolution config is a no-op, not
|
|
60
|
+
a crash; the field is read defensively so pre-existing state rows keep their
|
|
61
|
+
prior behaviour. New shared helper `src/evolution/enabled-state.ts`.
|
|
62
|
+
- **Robust critic-score parsing** via a shared `parseCriticScore` helper —
|
|
63
|
+
handles `===SCORE===`, `N/10`, "N out of 10", "rating: N", "I'd rate this N", …
|
|
64
|
+
(clamped 1–10). Previously only `===SCORE===` and a bare `N/10` were read,
|
|
65
|
+
silently dropping every other phrasing from evolution.
|
|
66
|
+
|
|
5
67
|
## [0.7.1] — 2026-06-20
|
|
6
68
|
|
|
7
69
|
**Documentation honesty + a reproducible evolution benchmark.** No library code
|
package/README.md
CHANGED
|
@@ -195,6 +195,33 @@ const loop = new DarwinLoop({
|
|
|
195
195
|
- **Style-bias-free judging** (`normalizeForJudging`) — strip markdown before the
|
|
196
196
|
critic scores, so it measures content not formatting.
|
|
197
197
|
|
|
198
|
+
### Drift detection — validate-by-reproduce canary (v0.9)
|
|
199
|
+
|
|
200
|
+
The A/B gate guards prompt *quality*. The canary guards *behaviour*: a model
|
|
201
|
+
update or a broken tool can change *how* an agent reaches its answer (different
|
|
202
|
+
tools, more turns, more errors) while the quality score stays flat. `darwin
|
|
203
|
+
canary` re-checks recent runs against a frozen baseline and flags that drift.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
darwin canary writer # Stable / drift / insufficient-data report
|
|
207
|
+
darwin canary writer --json # Machine-readable, for dashboards
|
|
208
|
+
darwin canary writer --exit-on-drift # Non-zero exit on drift, for CI
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
It compares execution *trajectories* (captured opt-in since v0.5) with
|
|
212
|
+
tolerance-based metrics — unordered tool-set Jaccard, ordered sequence
|
|
213
|
+
similarity, turn-count ratio, error-rate delta — never an exact hash (LLM runs
|
|
214
|
+
are non-deterministic). Drift has to be a *pattern* (≥2 of N runs), and the
|
|
215
|
+
baseline is pinned to the active prompt version, so an intentional evolution
|
|
216
|
+
reports `insufficient-data` (re-baseline), not a false alarm. The metrics and
|
|
217
|
+
the `runCanaryOverExperiments` orchestrator are exported for your own pipelines.
|
|
218
|
+
|
|
219
|
+
**Cross-family judging:** with more than one provider key present, Darwin
|
|
220
|
+
already spreads the three critics across model families to cut LLM-as-judge
|
|
221
|
+
bias. With only one key they collapse onto a single family (note: `claude-cli`
|
|
222
|
+
and `anthropic-api` are the *same* family) — Darwin now warns, and hard-fails
|
|
223
|
+
under `DARWIN_REQUIRE_CROSS_FAMILY=1` for strict / CI setups.
|
|
224
|
+
|
|
198
225
|
## Built-in Agents
|
|
199
226
|
|
|
200
227
|
| Agent | What it does | Needs |
|
|
@@ -329,6 +356,11 @@ Actual numbers from **419 runs across 19 agents** in our internal `darwin_db`
|
|
|
329
356
|
not synthetic benchmarks. "Success" means the run completed and produced valid
|
|
330
357
|
output (100% across 419 runs); "quality" is the critic's separate 1–10 score.
|
|
331
358
|
|
|
359
|
+
> Those 19 are our own internal + custom agents; the package ships **8 built-in
|
|
360
|
+
> agents** by default (`writer`, `researcher`, `critic`, `analyst`,
|
|
361
|
+
> `investigator`, `investigator-critic`, `marketing`, `blog-writer`) — the table
|
|
362
|
+
> below shows the four with enough runs to report.
|
|
363
|
+
|
|
332
364
|
```
|
|
333
365
|
Agent Runs Avg quality
|
|
334
366
|
writer 172 6.94 / 10
|
|
@@ -402,12 +434,41 @@ darwin run analyst --path ./src # Analyze a codebase
|
|
|
402
434
|
darwin status # Overview of all agents
|
|
403
435
|
darwin status writer # Detailed agent stats + evolution history
|
|
404
436
|
|
|
405
|
-
darwin
|
|
437
|
+
darwin canary writer # Behavioural drift vs a frozen baseline (--json, --exit-on-drift)
|
|
438
|
+
|
|
439
|
+
darwin evolve writer --enable # Enable self-evolution (persisted)
|
|
440
|
+
darwin evolve writer --disable # Disable self-evolution (persisted)
|
|
406
441
|
darwin evolve writer --reset # Reset to v1
|
|
442
|
+
darwin evolve writer --force # Force one optimization cycle now
|
|
407
443
|
|
|
408
444
|
darwin create my-agent # Scaffold a new agent
|
|
409
445
|
```
|
|
410
446
|
|
|
447
|
+
### Advanced evolution flags
|
|
448
|
+
|
|
449
|
+
The v0.6/v0.7 evolution strategies are reachable from the CLI. `darwin evolve`
|
|
450
|
+
**persists** them onto the agent (they survive process exit); `darwin run`
|
|
451
|
+
accepts the same flags as a one-off override for a single run.
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# Persist: reflect with GEPA + a stronger reflection model, pick parents by coverage
|
|
455
|
+
darwin evolve writer --gepa --reflection-model claude-opus-4-8 --coverage
|
|
456
|
+
|
|
457
|
+
# One-off for a single run
|
|
458
|
+
darwin run writer "Explain consensus" --gepa --pareto-gate
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
| Flag | What it does |
|
|
462
|
+
|------|--------------|
|
|
463
|
+
| `--gepa` / `--no-gepa` | GEPA-style reflective prompt mutation (vs. the legacy stats optimizer) |
|
|
464
|
+
| `--merge` / `--no-merge` | GEPA system-aware merge of two Pareto-front prompts as a challenger source |
|
|
465
|
+
| `--pareto-gate` / `--no-pareto-gate` | Reject an A/B winner that regressed on any objective |
|
|
466
|
+
| `--coverage` / `--no-coverage` | Pick the reflection parent by per-task-type coverage breadth (GEPA Algorithm 2) |
|
|
467
|
+
| `--reflection-model <id>` | Use a stronger model for GEPA reflection (the documented leverage point) |
|
|
468
|
+
|
|
469
|
+
All default to **off** — the baseline single-objective evolution loop is
|
|
470
|
+
unchanged unless you opt in.
|
|
471
|
+
|
|
411
472
|
## Storage: SQLite or PostgreSQL — both free, both MIT
|
|
412
473
|
|
|
413
474
|
Darwin runs on SQLite by default (zero config, single file) and on PostgreSQL
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* darwin canary <agent> [--json] [--exit-on-drift]
|
|
3
|
+
*
|
|
4
|
+
* Validate-by-reproduce drift check (Phase 2 A5). Loads the agent's recent
|
|
5
|
+
* experiments, baselines within the active prompt version, and reports whether
|
|
6
|
+
* the recent trajectories have drifted from that baseline (different tools,
|
|
7
|
+
* more turns, more errors) — behavioural drift the A/B *quality* gate can miss.
|
|
8
|
+
*
|
|
9
|
+
* Read-only. Exits 0 by default even on drift (the signal is the printed report
|
|
10
|
+
* / JSON, mirroring the staleness monitor); pass `--exit-on-drift` for CI.
|
|
11
|
+
*/
|
|
12
|
+
export declare function canaryCommand(args: string[]): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=canary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canary.d.ts","sourceRoot":"","sources":["../../../src/cli/canary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BjE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* darwin canary <agent> [--json] [--exit-on-drift]
|
|
3
|
+
*
|
|
4
|
+
* Validate-by-reproduce drift check (Phase 2 A5). Loads the agent's recent
|
|
5
|
+
* experiments, baselines within the active prompt version, and reports whether
|
|
6
|
+
* the recent trajectories have drifted from that baseline (different tools,
|
|
7
|
+
* more turns, more errors) — behavioural drift the A/B *quality* gate can miss.
|
|
8
|
+
*
|
|
9
|
+
* Read-only. Exits 0 by default even on drift (the signal is the printed report
|
|
10
|
+
* / JSON, mirroring the staleness monitor); pass `--exit-on-drift` for CI.
|
|
11
|
+
*/
|
|
12
|
+
import { createMemory } from '../memory/index.js';
|
|
13
|
+
import { loadConfig } from '../core/agent.js';
|
|
14
|
+
import { runCanaryOverExperiments } from '../evolution/canary.js';
|
|
15
|
+
/** How many recent experiments to pull for the drift window — wide enough that
|
|
16
|
+
* several same-version runs land in it after an evolution. */
|
|
17
|
+
const CANARY_WINDOW = 100;
|
|
18
|
+
export async function canaryCommand(args) {
|
|
19
|
+
const agentName = args.find((a) => !a.startsWith('--'));
|
|
20
|
+
if (!agentName) {
|
|
21
|
+
throw new Error('Usage: darwin canary <agent> [--json] [--exit-on-drift]');
|
|
22
|
+
}
|
|
23
|
+
const asJson = args.includes('--json');
|
|
24
|
+
const exitOnDrift = args.includes('--exit-on-drift');
|
|
25
|
+
const config = await loadConfig();
|
|
26
|
+
const memory = createMemory(config);
|
|
27
|
+
await memory.init();
|
|
28
|
+
try {
|
|
29
|
+
const state = await memory.getState();
|
|
30
|
+
const activeVersion = state.activeVersions[agentName] ?? null;
|
|
31
|
+
const experiments = await memory.loadExperiments(agentName, CANARY_WINDOW);
|
|
32
|
+
const report = runCanaryOverExperiments(agentName, experiments, activeVersion);
|
|
33
|
+
if (asJson) {
|
|
34
|
+
console.log(JSON.stringify(report, null, 2));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
printReport(report);
|
|
38
|
+
}
|
|
39
|
+
if (exitOnDrift && report.status === 'drift') {
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await memory.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function printReport(report) {
|
|
48
|
+
const icon = report.status === 'drift' ? '⚠' : report.status === 'ok' ? '✓' : '·';
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(`[darwin] Canary: ${report.agentName}${report.promptVersion ? ` / ${report.promptVersion}` : ''}`);
|
|
51
|
+
if (report.baselineId)
|
|
52
|
+
console.log(` Baseline: ${report.baselineId}`);
|
|
53
|
+
console.log(` Evaluated: ${report.evaluated} candidate run(s)`);
|
|
54
|
+
console.log(` Status: ${icon} ${report.status.toUpperCase()}`);
|
|
55
|
+
if (report.result) {
|
|
56
|
+
const r = report.result;
|
|
57
|
+
console.log(` Drifted: ${r.driftedCount}/${r.total} runs`);
|
|
58
|
+
console.log(` Medians: tool-Jaccard ${r.medianToolJaccard.toFixed(2)} | turn-ratio ${r.medianTurnRatio.toFixed(2)}`);
|
|
59
|
+
if (r.reasons.length > 0) {
|
|
60
|
+
console.log(` Reasons: ${r.reasons.join('; ')}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.log(` ${report.message}`);
|
|
64
|
+
console.log('');
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=canary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canary.js","sourceRoot":"","sources":["../../../src/cli/canary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Darwin CLI — shared parser for the advanced evolution-config flags.
|
|
3
|
+
*
|
|
4
|
+
* Both `darwin run` and `darwin evolve` accept the same knobs that toggle the
|
|
5
|
+
* v0.6/v0.7 evolution config (GEPA reflective optimizer, system-aware merge,
|
|
6
|
+
* Pareto activation gate, instance-wise coverage selection, and the reflection
|
|
7
|
+
* model). This module centralises the flag spelling + parsing so the two
|
|
8
|
+
* commands stay in sync.
|
|
9
|
+
*
|
|
10
|
+
* --gepa / --no-gepa
|
|
11
|
+
* --merge / --no-merge
|
|
12
|
+
* --pareto-gate / --no-pareto-gate
|
|
13
|
+
* --coverage / --no-coverage
|
|
14
|
+
* --reflection-model <model-id>
|
|
15
|
+
*/
|
|
16
|
+
import type { EvolutionConfigOverride } from '../types.js';
|
|
17
|
+
/** True when `arg` is one of the evolution-config flags this module handles. */
|
|
18
|
+
export declare function isEvolutionConfigFlag(arg: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Apply a single recognised evolution flag to `target`, mutating it in place.
|
|
21
|
+
*
|
|
22
|
+
* Returns the number of EXTRA argv tokens consumed (1 for `--reflection-model`
|
|
23
|
+
* which takes a value, 0 for the boolean flags). Callers that walk argv use the
|
|
24
|
+
* return value to advance their index. Unknown flags are ignored (return 0) —
|
|
25
|
+
* use {@link isEvolutionConfigFlag} to gate first.
|
|
26
|
+
*/
|
|
27
|
+
export declare function applyEvolutionFlag(arg: string, nextArg: string | undefined, target: EvolutionConfigOverride): number;
|
|
28
|
+
/**
|
|
29
|
+
* Parse an argv slice into an {@link EvolutionConfigOverride}, returning the
|
|
30
|
+
* override plus the tokens that were NOT consumed (so the caller can keep
|
|
31
|
+
* parsing its own flags / positionals). Only the evolution-config flags above
|
|
32
|
+
* are recognised; everything else is passed through untouched.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseEvolutionConfigFlags(args: string[]): {
|
|
35
|
+
override: EvolutionConfigOverride;
|
|
36
|
+
rest: string[];
|
|
37
|
+
};
|
|
38
|
+
/** True when the override carries at least one set flag. */
|
|
39
|
+
export declare function hasAnyEvolutionFlag(override: EvolutionConfigOverride): boolean;
|
|
40
|
+
//# sourceMappingURL=evolution-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evolution-flags.d.ts","sourceRoot":"","sources":["../../../src/cli/evolution-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAe1D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,MAAM,EAAE,uBAAuB,GAC9B,MAAM,CAmCR;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IACzD,QAAQ,EAAE,uBAAuB,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAaA;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAQ9E"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Darwin CLI — shared parser for the advanced evolution-config flags.
|
|
3
|
+
*
|
|
4
|
+
* Both `darwin run` and `darwin evolve` accept the same knobs that toggle the
|
|
5
|
+
* v0.6/v0.7 evolution config (GEPA reflective optimizer, system-aware merge,
|
|
6
|
+
* Pareto activation gate, instance-wise coverage selection, and the reflection
|
|
7
|
+
* model). This module centralises the flag spelling + parsing so the two
|
|
8
|
+
* commands stay in sync.
|
|
9
|
+
*
|
|
10
|
+
* --gepa / --no-gepa
|
|
11
|
+
* --merge / --no-merge
|
|
12
|
+
* --pareto-gate / --no-pareto-gate
|
|
13
|
+
* --coverage / --no-coverage
|
|
14
|
+
* --reflection-model <model-id>
|
|
15
|
+
*/
|
|
16
|
+
/** True when `arg` is one of the evolution-config flags this module handles. */
|
|
17
|
+
export function isEvolutionConfigFlag(arg) {
|
|
18
|
+
switch (arg) {
|
|
19
|
+
case '--gepa':
|
|
20
|
+
case '--no-gepa':
|
|
21
|
+
case '--merge':
|
|
22
|
+
case '--no-merge':
|
|
23
|
+
case '--pareto-gate':
|
|
24
|
+
case '--no-pareto-gate':
|
|
25
|
+
case '--coverage':
|
|
26
|
+
case '--no-coverage':
|
|
27
|
+
case '--reflection-model':
|
|
28
|
+
return true;
|
|
29
|
+
default:
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Apply a single recognised evolution flag to `target`, mutating it in place.
|
|
35
|
+
*
|
|
36
|
+
* Returns the number of EXTRA argv tokens consumed (1 for `--reflection-model`
|
|
37
|
+
* which takes a value, 0 for the boolean flags). Callers that walk argv use the
|
|
38
|
+
* return value to advance their index. Unknown flags are ignored (return 0) —
|
|
39
|
+
* use {@link isEvolutionConfigFlag} to gate first.
|
|
40
|
+
*/
|
|
41
|
+
export function applyEvolutionFlag(arg, nextArg, target) {
|
|
42
|
+
switch (arg) {
|
|
43
|
+
case '--gepa':
|
|
44
|
+
target.useGepa = true;
|
|
45
|
+
return 0;
|
|
46
|
+
case '--no-gepa':
|
|
47
|
+
target.useGepa = false;
|
|
48
|
+
return 0;
|
|
49
|
+
case '--merge':
|
|
50
|
+
target.useMerge = true;
|
|
51
|
+
return 0;
|
|
52
|
+
case '--no-merge':
|
|
53
|
+
target.useMerge = false;
|
|
54
|
+
return 0;
|
|
55
|
+
case '--pareto-gate':
|
|
56
|
+
target.paretoGate = true;
|
|
57
|
+
return 0;
|
|
58
|
+
case '--no-pareto-gate':
|
|
59
|
+
target.paretoGate = false;
|
|
60
|
+
return 0;
|
|
61
|
+
case '--coverage':
|
|
62
|
+
target.useCoverage = true;
|
|
63
|
+
return 0;
|
|
64
|
+
case '--no-coverage':
|
|
65
|
+
target.useCoverage = false;
|
|
66
|
+
return 0;
|
|
67
|
+
case '--reflection-model':
|
|
68
|
+
if (nextArg !== undefined) {
|
|
69
|
+
target.reflectionModel = nextArg;
|
|
70
|
+
return 1;
|
|
71
|
+
}
|
|
72
|
+
return 0;
|
|
73
|
+
default:
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parse an argv slice into an {@link EvolutionConfigOverride}, returning the
|
|
79
|
+
* override plus the tokens that were NOT consumed (so the caller can keep
|
|
80
|
+
* parsing its own flags / positionals). Only the evolution-config flags above
|
|
81
|
+
* are recognised; everything else is passed through untouched.
|
|
82
|
+
*/
|
|
83
|
+
export function parseEvolutionConfigFlags(args) {
|
|
84
|
+
const override = {};
|
|
85
|
+
const rest = [];
|
|
86
|
+
for (let i = 0; i < args.length; i++) {
|
|
87
|
+
const arg = args[i];
|
|
88
|
+
if (isEvolutionConfigFlag(arg)) {
|
|
89
|
+
const consumed = applyEvolutionFlag(arg, args[i + 1], override);
|
|
90
|
+
i += consumed;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
rest.push(arg);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return { override, rest };
|
|
97
|
+
}
|
|
98
|
+
/** True when the override carries at least one set flag. */
|
|
99
|
+
export function hasAnyEvolutionFlag(override) {
|
|
100
|
+
return (override.useGepa !== undefined ||
|
|
101
|
+
override.useMerge !== undefined ||
|
|
102
|
+
override.paretoGate !== undefined ||
|
|
103
|
+
override.useCoverage !== undefined ||
|
|
104
|
+
override.reflectionModel !== undefined);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=evolution-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evolution-flags.js","sourceRoot":"","sources":["../../../src/cli/evolution-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,gFAAgF;AAChF,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,WAAW,CAAC;QACjB,KAAK,SAAS,CAAC;QACf,KAAK,YAAY,CAAC;QAClB,KAAK,eAAe,CAAC;QACrB,KAAK,kBAAkB,CAAC;QACxB,KAAK,YAAY,CAAC;QAClB,KAAK,eAAe,CAAC;QACrB,KAAK,oBAAoB;YACvB,OAAO,IAAI,CAAC;QACd;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,OAA2B,EAC3B,MAA+B;IAE/B,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,QAAQ;YACX,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YACtB,OAAO,CAAC,CAAC;QACX,KAAK,WAAW;YACd,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,OAAO,CAAC,CAAC;QACX,KAAK,SAAS;YACZ,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;YACvB,OAAO,CAAC,CAAC;QACX,KAAK,YAAY;YACf,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;YACxB,OAAO,CAAC,CAAC;QACX,KAAK,eAAe;YAClB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;YACzB,OAAO,CAAC,CAAC;QACX,KAAK,kBAAkB;YACrB,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,KAAK,YAAY;YACf,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,KAAK,eAAe;YAClB,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,KAAK,oBAAoB;YACvB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC;gBACjC,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,CAAC,CAAC;QACX;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAc;IAItD,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAChE,CAAC,IAAI,QAAQ,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,mBAAmB,CAAC,QAAiC;IACnE,OAAO,CACL,QAAQ,CAAC,OAAO,KAAK,SAAS;QAC9B,QAAQ,CAAC,QAAQ,KAAK,SAAS;QAC/B,QAAQ,CAAC,UAAU,KAAK,SAAS;QACjC,QAAQ,CAAC,WAAW,KAAK,SAAS;QAClC,QAAQ,CAAC,eAAe,KAAK,SAAS,CACvC,CAAC;AACJ,CAAC"}
|
package/dist/src/cli/evolve.d.ts
CHANGED
|
@@ -7,7 +7,16 @@
|
|
|
7
7
|
* darwin evolve researcher --enable
|
|
8
8
|
* darwin evolve researcher --disable
|
|
9
9
|
* darwin evolve researcher --reset
|
|
10
|
-
* darwin evolve researcher --force
|
|
10
|
+
* darwin evolve researcher --force (force one optimization now)
|
|
11
|
+
* darwin evolve researcher --gepa --coverage (persist advanced config flags)
|
|
12
|
+
* darwin evolve researcher --reflection-model claude-opus-4-8
|
|
13
|
+
*
|
|
14
|
+
* Advanced flags (persisted, also accepted by `darwin run`):
|
|
15
|
+
* --gepa / --no-gepa GEPA reflective optimizer
|
|
16
|
+
* --merge / --no-merge GEPA system-aware merge
|
|
17
|
+
* --pareto-gate / --no-pareto-gate multi-objective A/B activation gate
|
|
18
|
+
* --coverage / --no-coverage instance-wise coverage selection
|
|
19
|
+
* --reflection-model <id> stronger reflection model for GEPA
|
|
11
20
|
*/
|
|
12
21
|
export declare function evolveCommand(args: string[]): Promise<void>;
|
|
13
22
|
//# sourceMappingURL=evolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evolve.d.ts","sourceRoot":"","sources":["../../../src/cli/evolve.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"evolve.d.ts","sourceRoot":"","sources":["../../../src/cli/evolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAeH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGjE"}
|
package/dist/src/cli/evolve.js
CHANGED
|
@@ -7,28 +7,52 @@
|
|
|
7
7
|
* darwin evolve researcher --enable
|
|
8
8
|
* darwin evolve researcher --disable
|
|
9
9
|
* darwin evolve researcher --reset
|
|
10
|
-
* darwin evolve researcher --force
|
|
10
|
+
* darwin evolve researcher --force (force one optimization now)
|
|
11
|
+
* darwin evolve researcher --gepa --coverage (persist advanced config flags)
|
|
12
|
+
* darwin evolve researcher --reflection-model claude-opus-4-8
|
|
13
|
+
*
|
|
14
|
+
* Advanced flags (persisted, also accepted by `darwin run`):
|
|
15
|
+
* --gepa / --no-gepa GEPA reflective optimizer
|
|
16
|
+
* --merge / --no-merge GEPA system-aware merge
|
|
17
|
+
* --pareto-gate / --no-pareto-gate multi-objective A/B activation gate
|
|
18
|
+
* --coverage / --no-coverage instance-wise coverage selection
|
|
19
|
+
* --reflection-model <id> stronger reflection model for GEPA
|
|
11
20
|
*/
|
|
12
21
|
import { createMemory } from '../memory/index.js';
|
|
13
22
|
import { loadConfig } from '../core/agent.js';
|
|
14
23
|
import { builtinAgents } from '../agents/index.js';
|
|
24
|
+
import { resolveEvolutionEnabled, resolveEvolutionConfig, setEvolutionEnabled, setEvolutionConfigOverrides, } from '../evolution/enabled-state.js';
|
|
25
|
+
import { buildEvolutionLoop } from '../evolution/build-loop.js';
|
|
26
|
+
import { parseEvolutionConfigFlags, hasAnyEvolutionFlag } from './evolution-flags.js';
|
|
15
27
|
export async function evolveCommand(args) {
|
|
16
28
|
const agentName = args[0];
|
|
17
29
|
if (!agentName) {
|
|
18
|
-
throw new Error('Usage: darwin evolve <agent> [--enable|--disable|--reset|--force]');
|
|
30
|
+
throw new Error('Usage: darwin evolve <agent> [--enable|--disable|--reset|--force|--gepa|--coverage|…]');
|
|
19
31
|
}
|
|
20
32
|
const agent = builtinAgents[agentName];
|
|
21
33
|
if (!agent) {
|
|
22
34
|
throw new Error(`Unknown agent: "${agentName}". Available: ${Object.keys(builtinAgents).join(', ')}`);
|
|
23
35
|
}
|
|
24
|
-
|
|
36
|
+
// Separate the advanced evolution-config flags from the action flags.
|
|
37
|
+
const { override, rest: flags } = parseEvolutionConfigFlags(args.slice(1));
|
|
25
38
|
const config = await loadConfig();
|
|
26
39
|
const memory = createMemory(config);
|
|
27
40
|
await memory.init();
|
|
41
|
+
// Persist advanced-config flags FIRST (so e.g. `--force --gepa` forces with
|
|
42
|
+
// GEPA on, and `--gepa --coverage` alone just records the config).
|
|
43
|
+
if (hasAnyEvolutionFlag(override)) {
|
|
44
|
+
await setEvolutionConfigOverrides(memory, agentName, override);
|
|
45
|
+
console.log(`[darwin] Evolution config updated for ${agentName}: ${describeOverride(override)}`);
|
|
46
|
+
}
|
|
28
47
|
if (flags.includes('--enable')) {
|
|
48
|
+
// Persist the override into DarwinState so it survives process exit.
|
|
49
|
+
// (Mutating the in-memory singleton alone was the v0.7.1 bug — the flag
|
|
50
|
+
// was gone the moment the CLI process ended and `darwin run` read the
|
|
51
|
+
// static source default again.)
|
|
29
52
|
if (agent.evolution) {
|
|
30
53
|
agent.evolution.enabled = true;
|
|
31
54
|
}
|
|
55
|
+
await setEvolutionEnabled(memory, agentName, true);
|
|
32
56
|
console.log(`[darwin] Evolution ENABLED for ${agentName}`);
|
|
33
57
|
console.log(`[darwin] The critic will evaluate runs and Darwin will optimize prompts automatically.`);
|
|
34
58
|
}
|
|
@@ -36,6 +60,7 @@ export async function evolveCommand(args) {
|
|
|
36
60
|
if (agent.evolution) {
|
|
37
61
|
agent.evolution.enabled = false;
|
|
38
62
|
}
|
|
63
|
+
await setEvolutionEnabled(memory, agentName, false);
|
|
39
64
|
console.log(`[darwin] Evolution DISABLED for ${agentName}`);
|
|
40
65
|
}
|
|
41
66
|
else if (flags.includes('--reset')) {
|
|
@@ -47,23 +72,83 @@ export async function evolveCommand(args) {
|
|
|
47
72
|
console.log(`[darwin] Evolution RESET for ${agentName}. Back to v1.`);
|
|
48
73
|
}
|
|
49
74
|
else if (flags.includes('--force')) {
|
|
50
|
-
|
|
51
|
-
|
|
75
|
+
// On-demand manual trigger: run the loop's variant-generation + A/B-start
|
|
76
|
+
// path ONCE, bypassing the "enough runs / actionable patterns / data
|
|
77
|
+
// quality" gates of the automatic loop. Uses the experiments collected so
|
|
78
|
+
// far. Refuses cleanly when there is nothing to mutate from (no active
|
|
79
|
+
// prompt / no experiments) or a test is already running.
|
|
80
|
+
console.log(`[darwin] Forcing evolution for ${agentName}...`);
|
|
81
|
+
// Build the loop with the resolved advanced config (persisted overrides +
|
|
82
|
+
// any flags passed on this command line) so `--force --gepa` etc. take
|
|
83
|
+
// effect for the forced cycle.
|
|
84
|
+
const state = await memory.getState();
|
|
85
|
+
const resolvedEvolution = resolveEvolutionConfig(agent, state);
|
|
86
|
+
const evolutionAgent = resolvedEvolution
|
|
87
|
+
? { ...agent, evolution: resolvedEvolution }
|
|
88
|
+
: agent;
|
|
89
|
+
const loop = buildEvolutionLoop(evolutionAgent, config, memory);
|
|
90
|
+
const evoResult = await loop.forceEvolve(agentName);
|
|
91
|
+
if (evoResult.abTestStarted) {
|
|
92
|
+
console.log(`[darwin] EVOLVED: ${evoResult.message}`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.log(`[darwin] ${evoResult.message}`);
|
|
96
|
+
}
|
|
97
|
+
if (evoResult.patternsFound.length > 0) {
|
|
98
|
+
console.log(`[darwin] Patterns detected:`);
|
|
99
|
+
for (const p of evoResult.patternsFound.slice(0, 5)) {
|
|
100
|
+
console.log(` ${p.type}: ${p.description}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
52
103
|
}
|
|
53
|
-
else {
|
|
54
|
-
// Show current status
|
|
104
|
+
else if (!hasAnyEvolutionFlag(override)) {
|
|
105
|
+
// Show current status (only when no config flag was the whole command —
|
|
106
|
+
// a bare `--gepa` already printed its confirmation above).
|
|
55
107
|
const state = await memory.getState();
|
|
56
108
|
const version = state.activeVersions[agentName] ?? 'v1';
|
|
57
109
|
const runs = state.experimentCounts[agentName] ?? 0;
|
|
58
110
|
const abTest = state.abTests[agentName];
|
|
59
|
-
|
|
111
|
+
// Reflect the PERSISTED override (set by --enable/--disable) so `darwin
|
|
112
|
+
// evolve <agent>` reports the same enabled-state `darwin run` will act on.
|
|
113
|
+
const enabled = resolveEvolutionEnabled(agent, state);
|
|
114
|
+
const evo = resolveEvolutionConfig(agent, state);
|
|
60
115
|
console.log(`\n[darwin] Evolution for ${agentName}:`);
|
|
61
116
|
console.log(` Enabled: ${enabled ? 'yes' : 'no'}`);
|
|
62
117
|
console.log(` Version: ${version}`);
|
|
63
118
|
console.log(` Runs: ${runs}`);
|
|
64
119
|
console.log(` A/B Test: ${abTest ? `${abTest.versionA} vs ${abTest.versionB}` : 'none'}`);
|
|
65
120
|
console.log(` Min Runs: ${agent.evolution?.minRuns ?? 5}`);
|
|
121
|
+
console.log(` Advanced: ${describeConfig(evo)}`);
|
|
66
122
|
}
|
|
67
123
|
await memory.close();
|
|
68
124
|
}
|
|
125
|
+
/** One-line summary of which advanced flags an override set (for confirmation). */
|
|
126
|
+
function describeOverride(o) {
|
|
127
|
+
const parts = [];
|
|
128
|
+
if (o.useGepa !== undefined)
|
|
129
|
+
parts.push(`gepa=${o.useGepa}`);
|
|
130
|
+
if (o.useMerge !== undefined)
|
|
131
|
+
parts.push(`merge=${o.useMerge}`);
|
|
132
|
+
if (o.paretoGate !== undefined)
|
|
133
|
+
parts.push(`paretoGate=${o.paretoGate}`);
|
|
134
|
+
if (o.useCoverage !== undefined)
|
|
135
|
+
parts.push(`coverage=${o.useCoverage}`);
|
|
136
|
+
if (o.reflectionModel !== undefined)
|
|
137
|
+
parts.push(`reflectionModel=${o.reflectionModel}`);
|
|
138
|
+
return parts.length > 0 ? parts.join(', ') : '(none)';
|
|
139
|
+
}
|
|
140
|
+
/** One-line summary of the effective advanced config for the status view. */
|
|
141
|
+
function describeConfig(evo) {
|
|
142
|
+
if (!evo)
|
|
143
|
+
return '(no evolution config)';
|
|
144
|
+
const parts = [
|
|
145
|
+
`gepa=${evo.useGepa ?? false}`,
|
|
146
|
+
`merge=${evo.useMerge ?? false}`,
|
|
147
|
+
`paretoGate=${evo.paretoGate ?? false}`,
|
|
148
|
+
`coverage=${evo.useCoverage ?? false}`,
|
|
149
|
+
];
|
|
150
|
+
if (evo.reflectionModel)
|
|
151
|
+
parts.push(`reflectionModel=${evo.reflectionModel}`);
|
|
152
|
+
return parts.join(', ');
|
|
153
|
+
}
|
|
69
154
|
//# sourceMappingURL=evolve.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evolve.js","sourceRoot":"","sources":["../../../src/cli/evolve.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"evolve.js","sourceRoot":"","sources":["../../../src/cli/evolve.ts"],"names":[],"mappings":"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"}
|