darwin-langgraph 0.1.0-alpha.1

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 ADDED
@@ -0,0 +1,119 @@
1
+ # Changelog
2
+
3
+ All notable changes to `darwin-langgraph` are documented here.
4
+ The project adheres to [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [0.1.0-alpha.1] — 2026-05-24
7
+
8
+ ### Added
9
+
10
+ - **Surface 1: `createDarwinNode(agent, opts?)`** — wraps a Darwin
11
+ `AgentDefinition` as a LangGraph `NodeAction`. Reads the task from state,
12
+ runs the agent via `darwin-agents.runAgent()`, writes `output` and (opt-in)
13
+ the captured `ExecutionTrace` back to state.
14
+ - **Surface 2: `darwinAnnotation(extra?)`** — `Annotation.Root` helper with
15
+ three pre-defined channels (`task`, `output`, `darwinTrajectory`).
16
+ Composable via `extra` for user channels.
17
+ - **Surface 3: `withDarwinEvolution(graph, opts)`** — wraps a compiled
18
+ `StateGraph`'s `invoke` / `stream` methods with a fire-and-forget post-run
19
+ hook that forwards each node's trajectory to a user-supplied callback,
20
+ enabling Darwin's closed-loop A/B evolution without changing graph code.
21
+ - **Custom errors:** `DarwinNodeError`, `DarwinEvolutionHookError` — subclass
22
+ `Error` for `instanceof` checks.
23
+ - **Types:** Re-export of `AgentDefinition`, `ExecutionTrace`, `RunResult`,
24
+ `MemoryProvider`, `TraceToolCall`, `TraceTokenUsage`, `TraceTurnError`
25
+ from `darwin-agents` for ergonomic single-import.
26
+
27
+ ### Compatibility
28
+
29
+ | `darwin-langgraph` | `darwin-agents` | `@langchain/langgraph` |
30
+ |---|---|---|
31
+ | `0.1.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` |
32
+
33
+ Both upstream packages are declared as **peer-dependencies** — the consumer
34
+ controls the installed versions and the adapter never pins them.
35
+
36
+ ### Notes
37
+
38
+ - Released under the `alpha` npm dist-tag in parallel with
39
+ `darwin-agents@0.5.0-alpha.1` (the first release that ships
40
+ `ExecutionTrace` capture). Default `npm install darwin-langgraph`
41
+ refuses to resolve until `0.1.0` final ships — explicit opt-in via
42
+ `npm install darwin-langgraph@alpha`.
43
+ - The adapter never touches `ANTHROPIC_API_KEY`. If you run Darwin on a
44
+ Claude Max subscription via the Claude Code CLI, set `delete
45
+ process.env.ANTHROPIC_API_KEY` in your own bootstrap.
46
+ - **Peer-dep semver caveat:** `darwin-agents: "^0.5.0-alpha.1"` follows
47
+ npm's prerelease semver rules — `0.5.0-alpha.N` and `0.5.0` final
48
+ satisfy it, but `0.5.1-alpha.0` does NOT. A patch release of this
49
+ adapter will be required when `darwin-agents` bumps past `0.5.x`.
50
+
51
+ ### R1 + R2 Code-Review Loop Pre-Publish
52
+
53
+ The 3-Agent code-review loop (Critic + Analyst + Research, in parallel)
54
+ ran twice before this release. R1 surfaced 8 findings, all fixed
55
+ in-place. R2 surfaced 1 HIGH must-fix + 4 LOW deferrals, the must-fix
56
+ landed in this release. The 9 R1 + 4 R2 regression tests live in
57
+ [`tests/r1-fixes.test.ts`](./tests/r1-fixes.test.ts).
58
+
59
+ **R2 MUST-FIX (S1185):**
60
+
61
+ - **HIGH (R2 Research 1):** the R1 hand-rolled `isGraphInterrupt`
62
+ duck-type missed `NodeInterrupt` (a `GraphInterrupt` subclass that
63
+ is the ACTUAL error thrown by `interrupt()` inside a node) AND broke
64
+ under bundler minification when `keep_classnames` was off. Fix:
65
+ import `isGraphInterrupt` directly from `@langchain/langgraph`'s
66
+ main entry (a stable public export that uses LangGraph's internal
67
+ `unminifiable_name` static-getter pattern). 12 LOC of hand-rolled
68
+ helper deleted, 1 line of named import added. Tests now use real
69
+ `GraphInterrupt` + `NodeInterrupt` instances.
70
+ - **LOW (R2 Critic 3):** added a comment block in `wrappedStream`
71
+ explaining the `activeInvokeMarkers.size > 0` ordering invariant
72
+ so future maintainers don't misread the race-free pattern.
73
+ - **LOW (R2 Analyst):** fixed stale README design-note line that still
74
+ said "counter" instead of "`Set<symbol>`".
75
+
76
+ **R1-Fixes (8 findings):**
77
+
78
+ 1. **CRITICAL (Critic 1):** `withDarwinEvolution` shared-counter race —
79
+ replaced `let invokesInFlight = 0` with `Set<symbol>` so concurrent
80
+ `Promise.all([graph.invoke, graph.invoke])` calls fire `onTrajectory`
81
+ exactly once each instead of double-firing. Regression test in
82
+ `tests/r1-fixes.test.ts`.
83
+ 2. **HIGH (Critic 2):** `stream({ streamMode: "updates" })` silently
84
+ skipped hook — adapter now `console.warn`s once when streamMode is
85
+ not `"values"`, surfacing the contract gap to users.
86
+ 3. **HIGH (Research 5):** `runAgent`-throws of `GraphInterrupt`
87
+ (LangGraph HITL signal) were getting wrapped in `DarwinNodeError`,
88
+ breaking the resume protocol. `createDarwinNode` now duck-types the
89
+ `name` / `constructor.name` field and re-throws untouched.
90
+ 4. **MEDIUM (Critic 4):** `Object.freeze({...stateObj})` is shallow.
91
+ JSDoc on `DarwinTrajectoryEvent.finalState` now says so explicitly
92
+ and points to "treat nested values as immutable by convention."
93
+ 5. **MEDIUM (Critic 6):** Added explicit test for
94
+ `result.experiment.trajectory === null` (not just `undefined`).
95
+ 6. **MEDIUM (Critic 7):** Added `verify:version-sync` script that the
96
+ `prepublishOnly` step runs — refuses to publish when `package.json`
97
+ and `src/index.ts` `VERSION` constant drift.
98
+ 7. **MEDIUM (Critic 8, Analyst 4):** Example 02 + 03 now warn about
99
+ `taskKey` shadowing and `MemorySaver` being dev-only.
100
+ 8. **LOW (Research 6):** `peerDependenciesMeta` stanza added
101
+ (both peers marked `optional: false` explicitly).
102
+
103
+ ### V0.2 Roadmap (deferred from R1 review)
104
+
105
+ - **`DarwinCallbackHandler` migration** (Research 2): drop the
106
+ `invoke`/`stream` monkey-patch in `withDarwinEvolution` in favour of
107
+ LangChain's `BaseCallbackHandler` registered via `graph.invoke(input,
108
+ { callbacks: [...] })`. Outlives any LangGraph-internal API shuffle.
109
+ - **`toOtelAttributes(trajectory)` helper** (Research 3): map Darwin's
110
+ `ExecutionTrace` to OpenTelemetry GenAI Semantic Conventions
111
+ (`gen_ai.usage.input_tokens`, `gen_ai.agent.name`, etc.) so Langfuse /
112
+ Braintrust / Datadog integrate out-of-the-box.
113
+ - **`darwinMessagesAnnotation()`** (Research 7): variant that merges
114
+ Darwin's three channels with LangGraph's `MessagesAnnotation.spec` so
115
+ mixing `createReactAgent` and `createDarwinNode` in one graph works
116
+ without channel-name conflicts.
117
+ - **`onResult` vs `onTrajectory` README paragraph** (Analyst 2):
118
+ explicit "when to pick which" guidance. Currently covered in JSDoc
119
+ only.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 StudioMeyer (Matthias Meyer)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,276 @@
1
+ # darwin-langgraph
2
+
3
+ > **LangGraph.js adapter for [`darwin-agents`](https://www.npmjs.com/package/darwin-agents).**
4
+ > Wrap self-evolving Darwin agents as `StateGraph` nodes — with zero hard deps.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/darwin-langgraph/alpha.svg)](https://www.npmjs.com/package/darwin-langgraph)
7
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
8
+
9
+ `darwin-langgraph` is a thin, peer-dependency-only bridge between two
10
+ independent libraries:
11
+
12
+ - **[`darwin-agents`](https://www.npmjs.com/package/darwin-agents)** — Darwin
13
+ is an agent framework where prompts evolve themselves via A/B testing,
14
+ multi-model critics, safety gates, and (since `v0.5.0-alpha.1`) full
15
+ execution-trace capture for GEPA-style reflective optimizers.
16
+ - **[`@langchain/langgraph`](https://www.npmjs.com/package/@langchain/langgraph)** —
17
+ LangGraph is the state-graph orchestration runtime used by Uber,
18
+ LinkedIn, Klarna, Replit, and others to build multi-step, multi-agent
19
+ workflows with durable execution and human-in-the-loop.
20
+
21
+ If you use **only Darwin**, you install nothing extra — Darwin itself has
22
+ zero LangChain dependency. If you use **only LangGraph**, the same.
23
+ If you want to combine the two — let LangGraph orchestrate, let Darwin
24
+ evolve — install this adapter.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ npm install darwin-langgraph@alpha @langchain/langgraph darwin-agents@alpha
30
+ ```
31
+
32
+ Both `@langchain/langgraph` and `darwin-agents` are declared as
33
+ **peer-dependencies** — you control the installed versions, the adapter
34
+ never pins them.
35
+
36
+ ## Quick start
37
+
38
+ ```ts
39
+ import { StateGraph } from "@langchain/langgraph";
40
+ import { defineAgent } from "darwin-agents";
41
+ import {
42
+ createDarwinNode,
43
+ darwinAnnotation,
44
+ withDarwinEvolution,
45
+ } from "darwin-langgraph";
46
+
47
+ const researcher = defineAgent({
48
+ name: "researcher",
49
+ role: "Topic Researcher",
50
+ description: "Five bullets on a topic.",
51
+ systemPrompt: "Return exactly 5 bullet points.",
52
+ });
53
+
54
+ const graph = withDarwinEvolution(
55
+ new StateGraph(darwinAnnotation())
56
+ .addNode("research", createDarwinNode(researcher))
57
+ .addEdge("__start__", "research")
58
+ .compile(),
59
+ {
60
+ nodeMap: { research: "researcher" },
61
+ onTrajectory: (event) => {
62
+ console.log(
63
+ `${event.nodeName} ran in ${event.trajectory.turnCount} turns ` +
64
+ `with ${event.trajectory.toolCalls.length} tool calls.`,
65
+ );
66
+ },
67
+ },
68
+ );
69
+
70
+ const result = await graph.invoke({ task: "What is GEPA?" });
71
+ console.log(result.output);
72
+ console.log("trajectory:", result.darwinTrajectory);
73
+ ```
74
+
75
+ ## Three surfaces
76
+
77
+ ### 1. `createDarwinNode(agent, opts?)`
78
+
79
+ Wraps a Darwin `AgentDefinition` as a LangGraph node action. The returned
80
+ function:
81
+
82
+ 1. Reads the task from `state[opts.taskKey ?? "task"]`.
83
+ 2. Calls `runAgent(agent, task, opts.runOptions)` from `darwin-agents`.
84
+ 3. Writes the agent's output to `state[opts.outputKey ?? "output"]`.
85
+ 4. Optionally writes the captured `ExecutionTrace` to
86
+ `state[opts.trajectoryKey ?? "darwinTrajectory"]`.
87
+
88
+ | Option | Type | Default | Description |
89
+ |---|---|---|---|
90
+ | `taskKey` | `string` | `"task"` | State property to read the task from. |
91
+ | `outputKey` | `string` | `"output"` | State property the output is written to. |
92
+ | `trajectoryKey` | `string` | `"darwinTrajectory"` | State property the trace is written to. |
93
+ | `runOptions` | object | `{}` | Passthrough for `model`, `maxTurns`, `timeout`, `cwd`, `autonomous`, `config`. |
94
+ | `captureTrace` | `boolean` | `true` | Set `false` to skip trajectory propagation. |
95
+ | `onResult` | function | — | Fire-and-forget side-effect after each run. Errors are swallowed. |
96
+
97
+ ### 2. `darwinAnnotation(extra?)`
98
+
99
+ Returns an `Annotation.Root` with three pre-defined channels
100
+ (`task` / `output` / `darwinTrajectory`) plus any extra channels you pass
101
+ in. Composable:
102
+
103
+ ```ts
104
+ const State = darwinAnnotation({
105
+ reviewNotes: Annotation<string[]>({
106
+ reducer: (a, b) => a.concat(b),
107
+ default: () => [],
108
+ }),
109
+ });
110
+ ```
111
+
112
+ Power-users can spread `getDarwinChannelSpec()` directly into their own
113
+ `Annotation.Root({...})` when the helper doesn't fit.
114
+
115
+ ### 3. `withDarwinEvolution(graph, opts)`
116
+
117
+ Wraps a compiled `StateGraph` with a post-run hook that fires `onTrajectory`
118
+ for each node listed in `nodeMap` after every `invoke` / `stream` run.
119
+ Errors inside the hook are swallowed — the graph result is always
120
+ returned unchanged.
121
+
122
+ ```ts
123
+ withDarwinEvolution(graph, {
124
+ nodeMap: {
125
+ research: "researcher",
126
+ critique: { agentName: "critic", trajectoryKey: "critiqueTrace" },
127
+ },
128
+ onTrajectory: (event) => {
129
+ // event.nodeName, event.agentName, event.trajectory, event.finalState
130
+ },
131
+ });
132
+ ```
133
+
134
+ ### Custom errors
135
+
136
+ ```ts
137
+ import { DarwinNodeError, DarwinEvolutionHookError } from "darwin-langgraph";
138
+
139
+ try { await graph.invoke({ task: "..." }); }
140
+ catch (err) {
141
+ if (err instanceof DarwinNodeError) {
142
+ console.error(`Node "${err.agentName}" failed:`, err.cause);
143
+ }
144
+ }
145
+ ```
146
+
147
+ > **GraphInterrupt is re-thrown un-wrapped.** When a downstream node
148
+ > calls LangGraph's `interrupt()` for human-in-the-loop, the resulting
149
+ > `GraphInterrupt` is surfaced through `createDarwinNode` un-touched so
150
+ > the resume protocol (`Command({ resume: ... })`) works. Only non-HITL
151
+ > errors get wrapped in `DarwinNodeError`.
152
+
153
+ ### `onResult` vs `onTrajectory` — when to pick which
154
+
155
+ Both hooks fire after a Darwin agent finishes, but at different layers:
156
+
157
+ - **`onResult`** (per-node, on `createDarwinNode`) receives the **full
158
+ raw `RunResult`** — including `experiment`, `evolution`, `reportPath`,
159
+ and the raw output. Use it for **per-agent side-effects** that don't
160
+ care about graph structure (e.g. writing to a database, logging the
161
+ full result).
162
+ - **`onTrajectory`** (graph-wide, on `withDarwinEvolution`) receives a
163
+ **normalised `DarwinTrajectoryEvent`** with `nodeName`, `agentName`,
164
+ trajectory, and a frozen final-state snapshot. Use it for
165
+ **cross-node observability** that needs to know which LangGraph node
166
+ produced which trace (cost tracking, A/B telemetry, evolution loops).
167
+
168
+ If you only need per-agent side-effects, use `onResult`. If you need
169
+ node-aware telemetry, use `onTrajectory`. They are **not redundant** —
170
+ combining both is fine, just be aware they fire at slightly different
171
+ points (node-completion vs graph-completion).
172
+
173
+ ### `streamMode` and the trajectory hook
174
+
175
+ `withDarwinEvolution` wraps both `invoke()` and `stream()`. The hook
176
+ reliably fires when:
177
+
178
+ - You call `graph.invoke({...})` — always works. Internally
179
+ `streamMode: "values"`.
180
+ - You call `graph.stream({...})` or `graph.stream({...}, { streamMode:
181
+ "values" })` — works.
182
+ - You include `"values"` in a multi-mode array
183
+ (`streamMode: ["values", "updates"]`) — works.
184
+
185
+ It does **not** fire on `streamMode: "updates"` / `"messages"` /
186
+ `"debug"` (without `"values"`) — the last chunk in those modes is a
187
+ node-update dict, not the final state, so the trajectory key lookup
188
+ silently misses. The adapter logs a `console.warn` (once per process)
189
+ the first time it detects a non-`values` stream so you don't silently
190
+ lose telemetry. V0.2 will migrate to the LangChain `CallbackHandler`
191
+ mechanism which fires regardless of stream mode.
192
+
193
+ ## Examples
194
+
195
+ The [`examples/`](./examples/) directory ships three runnable scripts:
196
+
197
+ - [`01-basic-node.ts`](./examples/01-basic-node.ts) — single Darwin node in a 1-edge graph.
198
+ - [`02-multi-agent-research.ts`](./examples/02-multi-agent-research.ts) — researcher → critic → writer pipeline with per-node trajectories.
199
+ - [`03-hitl-with-darwin.ts`](./examples/03-hitl-with-darwin.ts) — LangGraph `interrupt()` before a Darwin agent runs, with `Command({ resume: ... })` to continue.
200
+
201
+ ## Compatibility matrix
202
+
203
+ | `darwin-langgraph` | `darwin-agents` | `@langchain/langgraph` | Status |
204
+ |---|---|---|---|
205
+ | `0.1.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | alpha (this release) |
206
+
207
+ The peer-dep range `darwin-agents: "^0.5.0-alpha.1"` follows npm's
208
+ prerelease semver rules — `0.5.0-alpha.N` and `0.5.0` final satisfy it,
209
+ but `0.5.1-alpha.0` does NOT. A patch release of this adapter will be
210
+ required when `darwin-agents` bumps past `0.5.x`.
211
+
212
+ ## Known limitations (will be addressed in v0.2)
213
+
214
+ - **`withDarwinEvolution` monkey-patches `invoke`/`stream`** — V0.2
215
+ will migrate to a `DarwinCallbackHandler` you pass via
216
+ `graph.invoke(input, { callbacks: [...] })`, which is the canonical
217
+ LangChain pattern (matches Langfuse, Braintrust, LangSmith handlers).
218
+ - **No `gen_ai.*` OTEL attribute helper** — V0.2 will ship
219
+ `toOtelAttributes(trajectory)` so traces forward to Langfuse /
220
+ Braintrust / Datadog with OpenTelemetry GenAI Semantic Conventions.
221
+ - **No bundled `messages` channel** — V0.2 will add
222
+ `darwinMessagesAnnotation()` for graphs that mix `createReactAgent`
223
+ with `createDarwinNode`. Until then, you can pass
224
+ `darwinAnnotation({ ...MessagesAnnotation.spec })` manually.
225
+
226
+ The adapter releases follow `darwin-agents` major bumps. When
227
+ `@langchain/langgraph` 2.x lands, the adapter ships a new major within
228
+ the same minor of the underlying Darwin release.
229
+
230
+ ## Subscription / API key handling
231
+
232
+ The adapter NEVER touches `ANTHROPIC_API_KEY`. If you run Darwin on a
233
+ Claude Max subscription via the Claude Code CLI, your bootstrap must
234
+ `delete process.env.ANTHROPIC_API_KEY` BEFORE invoking the graph —
235
+ otherwise Darwin's `ClaudeCliProvider` will hit the metered API and you
236
+ pay per request instead of the flat subscription.
237
+
238
+ ```ts
239
+ // bootstrap.ts
240
+ import "dotenv/config";
241
+ delete process.env.ANTHROPIC_API_KEY; // enforce Max-Plan subscription
242
+ ```
243
+
244
+ ## Design notes
245
+
246
+ - **Zero runtime deps.** Both `darwin-agents` and `@langchain/langgraph`
247
+ are peer-dependencies. The adapter itself is a couple of hundred lines
248
+ of TypeScript that re-exports a handful of types.
249
+ - **`invoke()` calls `stream()` internally.** LangGraph v1.x implements
250
+ `invoke` on top of `stream`. The adapter tracks in-flight invokes
251
+ with a per-call `Symbol` marker stored in a `Set` so the trajectory
252
+ hook fires exactly once per logical run, even under concurrent
253
+ `Promise.all([graph.invoke(...), graph.invoke(...)])`.
254
+ - **`GraphInterrupt` re-throw.** The adapter imports `isGraphInterrupt`
255
+ directly from `@langchain/langgraph` so LangGraph's HITL exceptions
256
+ (both `GraphInterrupt` and `NodeInterrupt`) propagate untouched —
257
+ `Command({ resume })` works as expected.
258
+ - **Hook errors never propagate.** Both `opts.onResult` (on
259
+ `createDarwinNode`) and `opts.onTrajectory` (on `withDarwinEvolution`)
260
+ use a fire-and-forget pattern with one-shot `console.warn` for the
261
+ first swallowed throw per process.
262
+ - **No memory provider construction.** Memory backends (Postgres,
263
+ SQLite) are resolved by `darwin-agents` itself — set
264
+ `DARWIN_POSTGRES_URL` / `DARWIN_SQLITE_PATH` env vars or pass
265
+ `runOptions.config.dataDir`.
266
+
267
+ ## Versioning
268
+
269
+ Released under the `alpha` npm dist-tag in parallel with
270
+ `darwin-agents@0.5.0-alpha.1`. Default `npm install darwin-langgraph`
271
+ will NOT resolve until `0.1.0` final ships. Explicit opt-in via
272
+ `npm install darwin-langgraph@alpha`.
273
+
274
+ ## License
275
+
276
+ MIT © 2026 StudioMeyer
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Surface 1 — `createDarwinNode(agent, opts?)`.
3
+ *
4
+ * Wraps a Darwin `AgentDefinition` as a LangGraph node action. The
5
+ * returned function:
6
+ * 1. Reads the task from `state[opts.taskKey ?? "task"]`.
7
+ * 2. Invokes `runAgent(agent, task, { memory })` from `darwin-agents`.
8
+ * 3. Writes the agent output to `state[opts.outputKey ?? "output"]`.
9
+ * 4. Optionally writes the captured `ExecutionTrace` to
10
+ * `state[opts.trajectoryKey ?? "darwinTrajectory"]` so downstream
11
+ * nodes (or the evolution hook) can read it.
12
+ *
13
+ * Design notes (S1185):
14
+ * - **Non-generic return type.** The adapter returns `(state, config?) =>
15
+ * Promise<Record<string, unknown>>`. LangGraph accepts any function
16
+ * with the shape `(state, config?) => Partial<State>` as a NodeAction;
17
+ * leaving the return type generic-free keeps the public API trivial
18
+ * to consume from JS and TS alike. Strong typing is recovered via
19
+ * `darwinAnnotation()` on the StateGraph side.
20
+ * - **`runAgent` errors are wrapped** in `DarwinNodeError` so consumers
21
+ * can `instanceof`-check adapter failures vs upstream failures.
22
+ * - **`opts.onResult` is fire-and-forget swallowed.** A user callback
23
+ * must NEVER break the graph; we await it, but suppress any throw
24
+ * and surface it via `console.warn` once per Node. Mirrors the
25
+ * `darwinPostRun` no-throw guarantee from `agents/lib/darwin-hook.ts`.
26
+ * - **No `ANTHROPIC_API_KEY` manipulation.** `runAgent` makes its own
27
+ * subprocess/provider decisions; consumers running on Claude Max
28
+ * subscriptions must `delete process.env.ANTHROPIC_API_KEY` in
29
+ * their own bootstrap (documented in README).
30
+ */
31
+ import type { AgentDefinition, DarwinConfig, RunResult } from "darwin-agents";
32
+ /**
33
+ * LangGraph HITL detector (R1 Research Finding 5, refined by R2 Research
34
+ * Finding 1, S1185).
35
+ *
36
+ * When `interrupt()` is called inside a downstream node during a
37
+ * `runAgent` run, LangGraph throws a typed error to surface the HITL
38
+ * pause. The adapter MUST re-throw that error untouched — wrapping it
39
+ * in `DarwinNodeError` would swallow the interrupt and break the
40
+ * `Command({ resume })` protocol.
41
+ *
42
+ * Initially (R1) we hand-rolled a `name === "GraphInterrupt"` duck-type.
43
+ * R2 surfaced two issues with that approach:
44
+ * 1. Production minifiers (esbuild/Terser/SWC) rewrite class.name
45
+ * and constructor.name unless `keep_classnames` is set — breaking
46
+ * the constructor-name fallback for bundled consumers.
47
+ * 2. The real-world case throws `NodeInterrupt` (a `GraphInterrupt`
48
+ * subclass), NOT raw `GraphInterrupt`. The hand-rolled string
49
+ * check missed it.
50
+ *
51
+ * Fix: import `isGraphInterrupt` from `@langchain/langgraph`'s main
52
+ * entry — it is a stable PUBLIC export and uses LangGraph's internal
53
+ * `unminifiable_name` static-getter pattern that survives minification
54
+ * AND covers both `GraphInterrupt` and `NodeInterrupt`. The previous
55
+ * concern about "internal-ish module paths" was wrong — it lives in the
56
+ * top-level barrel.
57
+ */
58
+ /**
59
+ * Mirror of `darwin-agents` `RunOptions` — narrower because the adapter
60
+ * sets `taskType` and `promptVersion` implicitly. Exposed as `runOptions`
61
+ * on {@link CreateDarwinNodeOptions} so consumers can forward
62
+ * `model` / `maxTurns` / `timeout` / `autonomous` flags to `runAgent`
63
+ * without re-importing `darwin-agents`.
64
+ *
65
+ * If the upstream `RunOptions` shape changes in a future `darwin-agents`
66
+ * release, the build will break here on purpose — peer-dep semver
67
+ * guarantees additive-only changes inside the alpha range, but real
68
+ * drift happens (see `nex_learn fcfc928f`).
69
+ */
70
+ export interface DarwinRunOptionsPassthrough {
71
+ model?: string;
72
+ maxTurns?: number;
73
+ taskType?: string;
74
+ config?: DarwinConfig;
75
+ promptVersion?: string;
76
+ cwd?: string;
77
+ timeout?: number;
78
+ autonomous?: boolean;
79
+ }
80
+ /**
81
+ * Options accepted by {@link createDarwinNode}.
82
+ *
83
+ * All keys are optional. Defaults match the channel names returned by
84
+ * {@link darwinAnnotation} so the most common case (`createDarwinNode(myAgent)`
85
+ * inside `darwinAnnotation()`) needs zero configuration.
86
+ */
87
+ export interface CreateDarwinNodeOptions {
88
+ /** State property to read the task from. Default: `"task"`. */
89
+ taskKey?: string;
90
+ /** State property to write the agent output to. Default: `"output"`. */
91
+ outputKey?: string;
92
+ /** State property to write the captured trajectory to. Default: `"darwinTrajectory"`. */
93
+ trajectoryKey?: string;
94
+ /**
95
+ * Passthrough options forwarded to `darwin-agents.runAgent()`. Use this
96
+ * to override `model`, `maxTurns`, `timeout`, `cwd`, `autonomous`, or to
97
+ * provide a custom `DarwinConfig` (data dir, MCP servers, etc.).
98
+ *
99
+ * Memory resolution lives inside `darwin-agents` itself — set
100
+ * `DARWIN_POSTGRES_URL` / `DARWIN_SQLITE_PATH` env vars or pass a
101
+ * `config.dataDir` here. The adapter never instantiates a memory
102
+ * provider on its own.
103
+ */
104
+ runOptions?: DarwinRunOptionsPassthrough;
105
+ /**
106
+ * Persist the captured `ExecutionTrace` in graph state. Default `true`.
107
+ * Set `false` to skip trajectory propagation when memory pressure is a
108
+ * concern (long-running streams) or when the consumer reads
109
+ * trajectories from Darwin's own memory backend.
110
+ */
111
+ captureTrace?: boolean;
112
+ /**
113
+ * Fire-and-forget side-effect after every successful run. Receives the
114
+ * full `RunResult`. **Errors are swallowed** — never let a callback
115
+ * break the LangGraph node.
116
+ */
117
+ onResult?: (result: RunResult) => void | Promise<void>;
118
+ }
119
+ /**
120
+ * Type alias for the function returned by {@link createDarwinNode}.
121
+ * Matches the loose `NodeAction` contract from `@langchain/langgraph`:
122
+ * `(state, config?) => Promise<Partial<State>>`.
123
+ */
124
+ export type DarwinNodeFn = (state: Record<string, unknown>, config?: unknown) => Promise<Record<string, unknown>>;
125
+ /**
126
+ * Build a LangGraph node from a Darwin agent.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * import { StateGraph } from "@langchain/langgraph";
131
+ * import { createDarwinNode, darwinAnnotation } from "darwin-langgraph";
132
+ * import { defineAgent } from "darwin-agents";
133
+ *
134
+ * const researcher = defineAgent({
135
+ * name: "researcher",
136
+ * role: "Topic Researcher",
137
+ * description: "Researches a topic and returns 5 bullet points.",
138
+ * systemPrompt: "Return exactly 5 bullets.",
139
+ * });
140
+ *
141
+ * const graph = new StateGraph(darwinAnnotation())
142
+ * .addNode("research", createDarwinNode(researcher))
143
+ * .addEdge("__start__", "research")
144
+ * .compile();
145
+ *
146
+ * const result = await graph.invoke({ task: "What is GEPA?" });
147
+ * console.log(result.output);
148
+ * ```
149
+ */
150
+ export declare function createDarwinNode(agent: AgentDefinition, opts?: CreateDarwinNodeOptions): DarwinNodeFn;
151
+ //# sourceMappingURL=create-darwin-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-darwin-node.d.ts","sourceRoot":"","sources":["../src/create-darwin-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;AAIvB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,CAAC,EAAE,OAAO,KACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE,uBAA4B,GACjC,YAAY,CAiFd"}