darwin-langgraph 0.1.0-alpha.1 → 0.2.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 CHANGED
@@ -3,6 +3,107 @@
3
3
  All notable changes to `darwin-langgraph` are documented here.
4
4
  The project adheres to [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [0.2.0-alpha.1] — 2026-05-25
7
+
8
+ ### Added — three new surfaces (V0.1 roadmap → LIVE)
9
+
10
+ - **Surface 4: `DarwinCallbackHandler`** — LangChain-native replacement
11
+ for `withDarwinEvolution`. Subclass of `BaseCallbackHandler` from
12
+ `@langchain/core/callbacks/base`. Pass via
13
+ `graph.invoke(input, { callbacks: [new DarwinCallbackHandler({ nodeMap,
14
+ onTrajectory }) ] })`. No monkey-patching of `invoke` / `stream`,
15
+ no `Set<symbol>` race-fix needed, no `streamMode` warn — works
16
+ identically across `invoke`, `stream` (any `streamMode`), and
17
+ `streamEvents`. Uses `metadata.langgraph_node` as the primary
18
+ node-name source (live-verified against `@langchain/langgraph@1.3.x`)
19
+ with the `runName` parameter as fallback for non-LangGraph chains.
20
+ - **Surface 5: `toOtelAttributes(trajectory, opts?)` +
21
+ `toolCallToOtelAttributes(call, opts?)`** — pure mappers from Darwin's
22
+ `ExecutionTrace` to flat `Record<string, string|number|boolean>` keyed
23
+ by [OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/).
24
+ Spec-compliant cache attribute names
25
+ (`gen_ai.usage.cache_read.input_tokens` /
26
+ `gen_ai.usage.cache_creation.input_tokens`). MCP tools correctly map
27
+ to `gen_ai.tool.type = "extension"` (server-side, calls external APIs)
28
+ vs `"function"` for builtins. Sensitive `arguments` / `result` fields
29
+ are opt-in per OTEL spec. NaN/Infinity values dropped from output
30
+ (OTEL exporter compliance).
31
+ - **Surface 6: `darwinMessagesAnnotation(extra?)`** — variant of
32
+ `darwinAnnotation` that also includes LangGraph's canonical `messages`
33
+ channel (`messagesStateReducer`). Use it when your graph mixes Darwin
34
+ agents with `createReactAgent` / `MessagesAnnotation`-based prebuilt
35
+ agents. Power-user escape hatch `getMessagesChannelSpec()` exposed
36
+ for manual `Annotation.Root` composition.
37
+
38
+ ### Changed
39
+
40
+ - **`withDarwinEvolution` is `@deprecated` since v0.2.0** — JSDoc tag
41
+ plus a one-shot `console.warn` on first call (process-level, never
42
+ spam). Will be **removed in v1.0.0**. Migration is two lines (see
43
+ README "Migration from v0.1.x to v0.2.x").
44
+ - **VERSION constant bumped** to `0.2.0-alpha.1` in both `package.json`
45
+ and `src/index.ts` (verified by `prepublishOnly` script).
46
+
47
+ ### Fixed (R1 + R2 V0.2 code-review findings, all in-place pre-publish)
48
+
49
+ The 3-Agent code-review loop ran twice on V0.2. R1 surfaced 10 findings,
50
+ R2 caught 1 HIGH that R1 missed. All addressed before this release.
51
+
52
+ **R1 — 6 MUST-FIX (S1185):**
53
+
54
+ 1. **CRITICAL (Critic 1):** `firedRuns: Set<string>` in
55
+ `DarwinCallbackHandler` was an unbounded memory leak for long-lived
56
+ handlers (e.g. server singletons). Removed — `runIdToName.delete` is
57
+ the sole dedup and LangGraph guarantees one `handleChainEnd` per
58
+ `runId`.
59
+ 2. **HIGH (Critic 2):** `isExecutionTrace` only checked `version === 1`
60
+ — a malformed trajectory could pass and crash downstream
61
+ `toOtelAttributes(trajectory.toolCalls.length)`. Guard now also
62
+ requires `Array.isArray(toolCalls)` + `Array.isArray(errors)`.
63
+ `toOtelAttributes` got defensive fallbacks too.
64
+ 3. **HIGH (Critic 3 + 7):** `typeof === "number"` passed `NaN` and
65
+ `Infinity` through to OTEL exporters (silent span drop). All numeric
66
+ attributes (token usage, durationMs, turn, textBlockCount, turnCount,
67
+ mcpInvocations) now use `Number.isFinite`.
68
+ 4. **HIGH (Research 1):** OTEL spec uses
69
+ `gen_ai.usage.cache_read.input_tokens` /
70
+ `cache_creation.input_tokens` per the official attribute registry,
71
+ not the short `cache_*_tokens` form we initially emitted. Fixed
72
+ pre-release (zero-cost rename in alpha).
73
+ 5. **HIGH (Research 3):** MCP tools execute server-side and call
74
+ external APIs — `gen_ai.tool.type` must be `"extension"`, not
75
+ `"function"`. Adapter now routes on the existing `is_mcp` heuristic.
76
+ 6. **MED (Critic 5):** `swallow(err)` used `if (warned || !err)` which
77
+ silently dropped falsy throws (`throw null` etc). Fixed in
78
+ `DarwinCallbackHandler.swallow`.
79
+
80
+ **R2 — 1 HIGH (caught what R1 missed, S1185):**
81
+
82
+ 7. **HIGH (R2 Critic R2-1):** R1's fix #6 was applied to
83
+ `DarwinCallbackHandler.swallow` but NOT to the parallel `swallow`
84
+ inside `withDarwinEvolution`. Both now consistent.
85
+
86
+ ### Known limitations carried to V0.3
87
+
88
+ - **`withDarwinEvolution` module-level deprecation flag** is not reset
89
+ across tests in the same process (R2 Critic R2-2). Acceptable for
90
+ one-shot warn semantics; testing the contract requires
91
+ `vi.resetModules()`.
92
+ - **Double-wrapping `withDarwinEvolution` on the same graph instance**
93
+ is unsupported and produces no clear error (R2 Critic R2-3). Use
94
+ `DarwinCallbackHandler` instead — composable by default.
95
+ - **Parent-run propagation** on `DarwinTrajectoryEvent` not exposed
96
+ yet (R1 Research 5). Planned for V0.3 — needs use-case validation.
97
+
98
+ ### Test coverage
99
+
100
+ - **116/116 vitest tests green** (was 63 in V0.1).
101
+ - New test files: `tests/darwin-callback-handler.test.ts` (14),
102
+ `tests/to-otel-attributes.test.ts` (18),
103
+ `tests/darwin-messages-annotation.test.ts` (7),
104
+ `tests/r2-v02-fixes.test.ts` (10 R1+R2 regression).
105
+ - tsc strict + examples typecheck + version-sync + build all clean.
106
+
6
107
  ## [0.1.0-alpha.1] — 2026-05-24
7
108
 
8
109
  ### Added
@@ -37,9 +138,12 @@ controls the installed versions and the adapter never pins them.
37
138
 
38
139
  - Released under the `alpha` npm dist-tag in parallel with
39
140
  `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`.
141
+ `ExecutionTrace` capture). Because `0.1.0-alpha.1` is the very
142
+ first publish of this package, npm assigns BOTH `alpha` and
143
+ `latest` to it (npm rule: `latest` always exists), so
144
+ `npm install darwin-langgraph` resolves to the alpha version
145
+ until `0.1.0` final ships. Prefer the explicit
146
+ `npm install darwin-langgraph@alpha` form for clarity.
43
147
  - The adapter never touches `ANTHROPIC_API_KEY`. If you run Darwin on a
44
148
  Claude Max subscription via the Claude Code CLI, set `delete
45
149
  process.env.ANTHROPIC_API_KEY` in your own bootstrap.
package/README.md CHANGED
@@ -202,26 +202,59 @@ The [`examples/`](./examples/) directory ships three runnable scripts:
202
202
 
203
203
  | `darwin-langgraph` | `darwin-agents` | `@langchain/langgraph` | Status |
204
204
  |---|---|---|---|
205
- | `0.1.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | alpha (this release) |
205
+ | `0.2.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | alpha (this release) |
206
+ | `0.1.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | superseded |
206
207
 
207
208
  The peer-dep range `darwin-agents: "^0.5.0-alpha.1"` follows npm's
208
209
  prerelease semver rules — `0.5.0-alpha.N` and `0.5.0` final satisfy it,
209
210
  but `0.5.1-alpha.0` does NOT. A patch release of this adapter will be
210
211
  required when `darwin-agents` bumps past `0.5.x`.
211
212
 
212
- ## Known limitations (will be addressed in v0.2)
213
+ ## V0.2 new surfaces (LIVE this release)
214
+
215
+ V0.2 ships the three items from the V0.1 V0.2-roadmap, plus runtime
216
+ deprecation warnings on the legacy wrapper:
217
+
218
+ - **`DarwinCallbackHandler`** — LangChain-native replacement for
219
+ `withDarwinEvolution`. Pass it via `graph.invoke(input, { callbacks:
220
+ [new DarwinCallbackHandler({ nodeMap, onTrajectory }) ] })`. No more
221
+ monkey-patching `invoke`/`stream`, no more `Set<symbol>` race-fix,
222
+ no more `streamMode` gymnastics. Works identically with `invoke`,
223
+ `stream` (any `streamMode`), and `streamEvents` because LangChain's
224
+ callback mechanism fires regardless of how the consumer iterates.
225
+ - **`toOtelAttributes(trajectory, opts?)` + `toolCallToOtelAttributes(call, opts?)`** —
226
+ pure mappers from Darwin's `ExecutionTrace` to flat
227
+ `Record<string, string|number|boolean>` keyed by
228
+ [OpenTelemetry GenAI Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
229
+ (`gen_ai.operation.name`, `gen_ai.usage.input_tokens`, etc.) plus
230
+ Darwin-namespaced custom attrs. Drop straight into Langfuse,
231
+ Braintrust, Honeycomb, Datadog. Sensitive `arguments` / `result`
232
+ fields are opt-in per OTEL spec.
233
+ - **`darwinMessagesAnnotation(extra?)`** — variant of `darwinAnnotation`
234
+ that also includes LangGraph's canonical `messages` channel
235
+ (`messagesStateReducer`). Use it when your graph mixes Darwin agents
236
+ with `createReactAgent` / `MessagesAnnotation`-based prebuilt agents.
237
+ - **Runtime deprecation warning on `withDarwinEvolution`** — fires once
238
+ per process on first call. The function still works identically for
239
+ back-compat; it will be removed in v1.0. Migrate to
240
+ `DarwinCallbackHandler`.
241
+
242
+ ## Migration from v0.1.x to v0.2.x
243
+
244
+ Two lines:
245
+
246
+ ```diff
247
+ - import { withDarwinEvolution } from "darwin-langgraph";
248
+ + import { DarwinCallbackHandler } from "darwin-langgraph";
249
+ - const graph = withDarwinEvolution(compiledGraph, { nodeMap, onTrajectory });
250
+ - const result = await graph.invoke(input);
251
+ + const handler = new DarwinCallbackHandler({ nodeMap, onTrajectory });
252
+ + const result = await compiledGraph.invoke(input, { callbacks: [handler] });
253
+ ```
213
254
 
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.
255
+ `DarwinEvolutionOptions`, `DarwinNodeMapEntry`, and the
256
+ `DarwinTrajectoryEvent` shape passed to `onTrajectory` are 100% identical
257
+ between both APIs no other code changes required.
225
258
 
226
259
  The adapter releases follow `darwin-agents` major bumps. When
227
260
  `@langchain/langgraph` 2.x lands, the adapter ships a new major within
@@ -267,9 +300,20 @@ delete process.env.ANTHROPIC_API_KEY; // enforce Max-Plan subscription
267
300
  ## Versioning
268
301
 
269
302
  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`.
303
+ `darwin-agents@0.5.0-alpha.1`. Because `0.1.0-alpha.1` is the FIRST
304
+ publish, npm assigns BOTH `alpha` and `latest` to it (npm rule: a
305
+ package must always have a `latest` tag) — so `npm install
306
+ darwin-langgraph` and `npm install darwin-langgraph@alpha` resolve to
307
+ the same version right now. Once `0.1.0` final ships, `latest` will
308
+ point to the stable release and `alpha` will continue to track
309
+ pre-releases.
310
+
311
+ For maximum clarity in alpha-stage projects, prefer the explicit
312
+ opt-in form:
313
+
314
+ ```bash
315
+ npm install darwin-langgraph@alpha @langchain/langgraph darwin-agents@alpha
316
+ ```
273
317
 
274
318
  ## License
275
319
 
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Surface 4 (V0.2) — `DarwinCallbackHandler`.
3
+ *
4
+ * Drop-in replacement for {@link withDarwinEvolution} that uses
5
+ * LangChain's canonical `BaseCallbackHandler` mechanism instead of
6
+ * monkey-patching `graph.invoke` / `graph.stream`. The same trajectory
7
+ * hook fires, the same `nodeMap` routing applies, but the integration
8
+ * is now LangGraph-native — no method overwrites, no concurrent-invoke
9
+ * Set<symbol> dance, no streamMode gymnastics.
10
+ *
11
+ * Usage:
12
+ * ```ts
13
+ * import { DarwinCallbackHandler } from "darwin-langgraph";
14
+ *
15
+ * const handler = new DarwinCallbackHandler({
16
+ * nodeMap: { research: "researcher" },
17
+ * onTrajectory: (event) => {
18
+ * console.log(event.nodeName, event.trajectory.toolCalls.length);
19
+ * },
20
+ * });
21
+ *
22
+ * const result = await graph.invoke(
23
+ * { task: "What is GEPA?" },
24
+ * { callbacks: [handler] },
25
+ * );
26
+ * ```
27
+ *
28
+ * Design notes (S1185 V0.2):
29
+ * - **runId → runName mapping.** LangChain invokes `handleChainStart`
30
+ * with the `runName` arg (the node name in LangGraph's case) and
31
+ * a unique `runId`. We cache that mapping. On `handleChainEnd` we
32
+ * look up the name, find the matching `nodeMap` entry, and dispatch
33
+ * `onTrajectory`.
34
+ * - **Fire-and-forget.** Like the v0.1 monkey-patch wrapper, hook
35
+ * errors are swallowed with one warn-once per handler instance.
36
+ * - **No mutation of LangGraph internals.** This handler never touches
37
+ * `graph.invoke` or `graph.stream` — registering it via the standard
38
+ * `{ callbacks: [...] }` option is the only side effect, which is
39
+ * LangChain's documented integration point (matches Langfuse,
40
+ * Braintrust, LangSmith handler patterns).
41
+ * - **Stream-mode-agnostic.** Works identically with `invoke`,
42
+ * `stream` (any streamMode), and `streamEvents` because the chain
43
+ * callbacks fire regardless of how the consumer iterates.
44
+ * - **Concurrent runs work natively.** LangChain's runId is unique
45
+ * per call — no shared-counter race condition is possible.
46
+ * - **Backwards compat.** `withDarwinEvolution` from v0.1 still works
47
+ * (marked `@deprecated`) and produces the same `DarwinTrajectoryEvent`
48
+ * payload shape. Migration is one line: replace
49
+ * `withDarwinEvolution(graph, opts)` with
50
+ * `graph.invoke(input, { callbacks: [new DarwinCallbackHandler(opts)] })`.
51
+ */
52
+ import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
53
+ import type { ChainValues } from "@langchain/core/utils/types";
54
+ import type { DarwinEvolutionOptions } from "./with-darwin-evolution.js";
55
+ /**
56
+ * LangChain `BaseCallbackHandler` that listens for LangGraph node-chain
57
+ * events and dispatches Darwin trajectory hooks. Pass it via the
58
+ * standard `{ callbacks: [...] }` option to any `invoke`/`stream`/`streamEvents`
59
+ * call on a compiled `StateGraph`.
60
+ */
61
+ export declare class DarwinCallbackHandler extends BaseCallbackHandler {
62
+ readonly name = "DarwinCallbackHandler";
63
+ readonly awaitHandlers = false;
64
+ private readonly resolved;
65
+ private readonly onTrajectory;
66
+ private readonly runIdToName;
67
+ private warned;
68
+ constructor(opts: DarwinEvolutionOptions);
69
+ /**
70
+ * Capture the run-id → node-name mapping.
71
+ *
72
+ * Implementation note (S1185 V0.2 — live-debug against @langchain/langgraph@1.3.x):
73
+ * `metadata.langgraph_node` is the stable, reliable source for the
74
+ * StateGraph node name. LangGraph populates it on every node-chain
75
+ * invocation. The `runName` parameter slot in `@langchain/core`'s
76
+ * `BaseCallbackHandler` d.ts is undefined for LangGraph chains at
77
+ * runtime — we keep it as a fallback for non-LangGraph chains.
78
+ */
79
+ handleChainStart(_chain: unknown, _inputs: ChainValues, runId: string, _runType?: string, _tags?: string[], metadata?: Record<string, unknown>, runName?: string, _parentRunId?: string, _extra?: Record<string, unknown>): void;
80
+ /**
81
+ * When a node-chain finishes, look up its name, locate the matching
82
+ * trajectory in `outputs`, and dispatch onTrajectory.
83
+ *
84
+ * `outputs` carries the state update the node returned — which may be
85
+ * a partial state (just the new keys). When the node was wrapped via
86
+ * {@link createDarwinNode}, the trajectoryKey lives directly on that
87
+ * partial state under its configured name.
88
+ */
89
+ handleChainEnd(outputs: ChainValues, runId: string, _parentRunId?: string, _tags?: string[], _kwargs?: {
90
+ inputs?: ChainValues;
91
+ }): void;
92
+ /**
93
+ * Forget the in-flight runId when a chain errors out. We don't fire
94
+ * the hook on error — the trajectory is by definition incomplete.
95
+ */
96
+ handleChainError(_err: Error, runId: string, _parentRunId?: string): void;
97
+ private swallow;
98
+ /**
99
+ * Helper for tests + debug introspection — returns how many in-flight
100
+ * chain runs we are currently tracking. Should be 0 between
101
+ * top-level invocations.
102
+ */
103
+ getInFlightCount(): number;
104
+ }
105
+ //# sourceMappingURL=darwin-callback-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-callback-handler.d.ts","sourceRoot":"","sources":["../src/darwin-callback-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAI/D,OAAO,KAAK,EACV,sBAAsB,EAGvB,MAAM,4BAA4B,CAAC;AAqDpC;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,SAAyB,IAAI,2BAA2B;IACxD,SAAyB,aAAa,SAAS;IAE/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,sBAAsB;IAYxC;;;;;;;;;OASG;IACM,gBAAgB,CACvB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI;IAoBP;;;;;;;;OAQG;IACM,cAAc,CACrB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,IAAI;IAmCP;;;OAGG;IACM,gBAAgB,CACvB,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI;IAIP,OAAO,CAAC,OAAO;IAaf;;;;OAIG;IACI,gBAAgB,IAAI,MAAM;CAGlC"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Surface 4 (V0.2) — `DarwinCallbackHandler`.
3
+ *
4
+ * Drop-in replacement for {@link withDarwinEvolution} that uses
5
+ * LangChain's canonical `BaseCallbackHandler` mechanism instead of
6
+ * monkey-patching `graph.invoke` / `graph.stream`. The same trajectory
7
+ * hook fires, the same `nodeMap` routing applies, but the integration
8
+ * is now LangGraph-native — no method overwrites, no concurrent-invoke
9
+ * Set<symbol> dance, no streamMode gymnastics.
10
+ *
11
+ * Usage:
12
+ * ```ts
13
+ * import { DarwinCallbackHandler } from "darwin-langgraph";
14
+ *
15
+ * const handler = new DarwinCallbackHandler({
16
+ * nodeMap: { research: "researcher" },
17
+ * onTrajectory: (event) => {
18
+ * console.log(event.nodeName, event.trajectory.toolCalls.length);
19
+ * },
20
+ * });
21
+ *
22
+ * const result = await graph.invoke(
23
+ * { task: "What is GEPA?" },
24
+ * { callbacks: [handler] },
25
+ * );
26
+ * ```
27
+ *
28
+ * Design notes (S1185 V0.2):
29
+ * - **runId → runName mapping.** LangChain invokes `handleChainStart`
30
+ * with the `runName` arg (the node name in LangGraph's case) and
31
+ * a unique `runId`. We cache that mapping. On `handleChainEnd` we
32
+ * look up the name, find the matching `nodeMap` entry, and dispatch
33
+ * `onTrajectory`.
34
+ * - **Fire-and-forget.** Like the v0.1 monkey-patch wrapper, hook
35
+ * errors are swallowed with one warn-once per handler instance.
36
+ * - **No mutation of LangGraph internals.** This handler never touches
37
+ * `graph.invoke` or `graph.stream` — registering it via the standard
38
+ * `{ callbacks: [...] }` option is the only side effect, which is
39
+ * LangChain's documented integration point (matches Langfuse,
40
+ * Braintrust, LangSmith handler patterns).
41
+ * - **Stream-mode-agnostic.** Works identically with `invoke`,
42
+ * `stream` (any streamMode), and `streamEvents` because the chain
43
+ * callbacks fire regardless of how the consumer iterates.
44
+ * - **Concurrent runs work natively.** LangChain's runId is unique
45
+ * per call — no shared-counter race condition is possible.
46
+ * - **Backwards compat.** `withDarwinEvolution` from v0.1 still works
47
+ * (marked `@deprecated`) and produces the same `DarwinTrajectoryEvent`
48
+ * payload shape. Migration is one line: replace
49
+ * `withDarwinEvolution(graph, opts)` with
50
+ * `graph.invoke(input, { callbacks: [new DarwinCallbackHandler(opts)] })`.
51
+ */
52
+ import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
53
+ import { DarwinEvolutionHookError } from "./errors.js";
54
+ function isExecutionTrace(value) {
55
+ if (!value || typeof value !== "object")
56
+ return false;
57
+ const v = value;
58
+ // R1 V0.2 Critic Finding 2 (S1185): require shape-tightness, not just
59
+ // version. Downstream consumers (e.g. toOtelAttributes) read
60
+ // `toolCalls.length` directly — a malformed trace with missing arrays
61
+ // would crash there. Guard explicitly.
62
+ return (v.version === 1 &&
63
+ Array.isArray(v.toolCalls) &&
64
+ Array.isArray(v.errors));
65
+ }
66
+ function normaliseNodeMap(nodeMap, defaultKey) {
67
+ const resolved = new Map();
68
+ for (const [nodeName, entry] of Object.entries(nodeMap)) {
69
+ if (typeof entry === "string") {
70
+ resolved.set(nodeName, { agentName: entry, trajectoryKey: defaultKey });
71
+ }
72
+ else if (entry !== null &&
73
+ typeof entry === "object" &&
74
+ typeof entry.agentName === "string" &&
75
+ typeof entry.trajectoryKey === "string") {
76
+ resolved.set(nodeName, {
77
+ agentName: entry.agentName,
78
+ trajectoryKey: entry.trajectoryKey,
79
+ });
80
+ }
81
+ else {
82
+ throw new DarwinEvolutionHookError(`DarwinCallbackHandler: nodeMap entry for "${nodeName}" must be a string or ` +
83
+ `{ agentName, trajectoryKey }, got ${typeof entry}.`);
84
+ }
85
+ }
86
+ return resolved;
87
+ }
88
+ /**
89
+ * LangChain `BaseCallbackHandler` that listens for LangGraph node-chain
90
+ * events and dispatches Darwin trajectory hooks. Pass it via the
91
+ * standard `{ callbacks: [...] }` option to any `invoke`/`stream`/`streamEvents`
92
+ * call on a compiled `StateGraph`.
93
+ */
94
+ export class DarwinCallbackHandler extends BaseCallbackHandler {
95
+ name = "DarwinCallbackHandler";
96
+ awaitHandlers = false;
97
+ resolved;
98
+ onTrajectory;
99
+ runIdToName = new Map();
100
+ warned = false;
101
+ constructor(opts) {
102
+ super();
103
+ if (!opts || !opts.nodeMap || Object.keys(opts.nodeMap).length === 0) {
104
+ throw new DarwinEvolutionHookError("DarwinCallbackHandler: opts.nodeMap is required and must contain at least one entry.");
105
+ }
106
+ const defaultKey = opts.defaultTrajectoryKey ?? "darwinTrajectory";
107
+ this.resolved = normaliseNodeMap(opts.nodeMap, defaultKey);
108
+ this.onTrajectory = opts.onTrajectory;
109
+ }
110
+ /**
111
+ * Capture the run-id → node-name mapping.
112
+ *
113
+ * Implementation note (S1185 V0.2 — live-debug against @langchain/langgraph@1.3.x):
114
+ * `metadata.langgraph_node` is the stable, reliable source for the
115
+ * StateGraph node name. LangGraph populates it on every node-chain
116
+ * invocation. The `runName` parameter slot in `@langchain/core`'s
117
+ * `BaseCallbackHandler` d.ts is undefined for LangGraph chains at
118
+ * runtime — we keep it as a fallback for non-LangGraph chains.
119
+ */
120
+ handleChainStart(_chain, _inputs, runId, _runType, _tags, metadata, runName, _parentRunId, _extra) {
121
+ // Primary source: metadata.langgraph_node (set by LangGraph internals).
122
+ let nodeName;
123
+ if (metadata && typeof metadata === "object") {
124
+ const m = metadata;
125
+ if (typeof m["langgraph_node"] === "string") {
126
+ nodeName = m["langgraph_node"];
127
+ }
128
+ }
129
+ // Fallback: runName parameter (for non-LangGraph integrations).
130
+ if (!nodeName && typeof runName === "string" && runName.length > 0) {
131
+ nodeName = runName;
132
+ }
133
+ if (!nodeName)
134
+ return;
135
+ // Only track names that map to a known node. Reduces memory and
136
+ // makes lookup in handleChainEnd a simple `.has()` check.
137
+ if (!this.resolved.has(nodeName))
138
+ return;
139
+ this.runIdToName.set(runId, nodeName);
140
+ }
141
+ /**
142
+ * When a node-chain finishes, look up its name, locate the matching
143
+ * trajectory in `outputs`, and dispatch onTrajectory.
144
+ *
145
+ * `outputs` carries the state update the node returned — which may be
146
+ * a partial state (just the new keys). When the node was wrapped via
147
+ * {@link createDarwinNode}, the trajectoryKey lives directly on that
148
+ * partial state under its configured name.
149
+ */
150
+ handleChainEnd(outputs, runId, _parentRunId, _tags, _kwargs) {
151
+ const runName = this.runIdToName.get(runId);
152
+ if (!runName)
153
+ return;
154
+ // One-shot cleanup of the mapping so completed runs don't leak.
155
+ // R1 V0.2 Critic Finding 1 (S1185): the `runIdToName.delete` here
156
+ // is the ONLY dedup we need — LangGraph guarantees `handleChainEnd`
157
+ // fires exactly once per `runId`, and after deletion any second
158
+ // call returns early at `if (!runName)`. The pre-V0.2 `firedRuns`
159
+ // Set was redundant AND leaked unbounded — removed.
160
+ this.runIdToName.delete(runId);
161
+ if (!this.onTrajectory)
162
+ return;
163
+ const entry = this.resolved.get(runName);
164
+ if (!entry)
165
+ return;
166
+ if (outputs === null || typeof outputs !== "object")
167
+ return;
168
+ const trajectory = outputs[entry.trajectoryKey];
169
+ if (!isExecutionTrace(trajectory))
170
+ return;
171
+ const frozen = Object.freeze({ ...outputs });
172
+ const event = {
173
+ nodeName: runName,
174
+ agentName: entry.agentName,
175
+ trajectory,
176
+ finalState: frozen,
177
+ };
178
+ // Fire-and-forget. The handler base class supports async returns
179
+ // but we don't want to block the chain end on slow user callbacks.
180
+ void Promise.resolve()
181
+ .then(() => this.onTrajectory(event))
182
+ .catch((err) => this.swallow(err));
183
+ }
184
+ /**
185
+ * Forget the in-flight runId when a chain errors out. We don't fire
186
+ * the hook on error — the trajectory is by definition incomplete.
187
+ */
188
+ handleChainError(_err, runId, _parentRunId) {
189
+ this.runIdToName.delete(runId);
190
+ }
191
+ swallow(err) {
192
+ // R1 V0.2 Critic Finding 5 (S1185): do NOT short-circuit on falsy
193
+ // `err` — `throw 0` / `throw ""` / `throw null` from user callbacks
194
+ // should still surface in logs (silent-failure is worse than noisy).
195
+ if (this.warned)
196
+ return;
197
+ this.warned = true;
198
+ console.warn(`[darwin-langgraph] DarwinCallbackHandler.onTrajectory threw — swallowed. ` +
199
+ `Subsequent throws will be silent. Original error: ` +
200
+ `${err instanceof Error ? err.message : String(err)}`);
201
+ }
202
+ /**
203
+ * Helper for tests + debug introspection — returns how many in-flight
204
+ * chain runs we are currently tracking. Should be 0 between
205
+ * top-level invocations.
206
+ */
207
+ getInFlightCount() {
208
+ return this.runIdToName.size;
209
+ }
210
+ }
211
+ //# sourceMappingURL=darwin-callback-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-callback-handler.js","sourceRoot":"","sources":["../src/darwin-callback-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Surface 6 (V0.2) — `darwinMessagesAnnotation(extra?)`.
3
+ *
4
+ * Variant of {@link darwinAnnotation} that also includes LangGraph's
5
+ * canonical `messages` channel (using `messagesStateReducer` from
6
+ * `@langchain/langgraph`). Use this when your graph mixes Darwin agents
7
+ * with `createReactAgent` / `MessagesAnnotation`-based prebuilt agents
8
+ * — they all read and write the same `messages` channel without
9
+ * channel-name conflicts.
10
+ *
11
+ * Layered channels:
12
+ * - `task` (string, last-write-wins) — Darwin agent task input
13
+ * - `output` (string, last-write-wins) — Darwin agent text output
14
+ * - `darwinTrajectory` (ExecutionTrace | undefined) — captured trace
15
+ * - `messages` (BaseMessage[], `messagesStateReducer`) — chat history
16
+ *
17
+ * Composable: any `extra` channels merge in.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { darwinMessagesAnnotation, createDarwinNode } from "darwin-langgraph";
22
+ * import { StateGraph } from "@langchain/langgraph";
23
+ * import { createReactAgent } from "@langchain/langgraph/prebuilt";
24
+ * import { ChatAnthropic } from "@langchain/anthropic";
25
+ *
26
+ * const State = darwinMessagesAnnotation();
27
+ *
28
+ * const planner = createReactAgent({
29
+ * llm: new ChatAnthropic({ model: "claude-haiku-4-5" }),
30
+ * tools: [],
31
+ * });
32
+ *
33
+ * const graph = new StateGraph(State)
34
+ * .addNode("plan", planner) // writes to messages
35
+ * .addNode("execute", createDarwinNode(myAgent)) // writes to output
36
+ * .addEdge("__start__", "plan")
37
+ * .addEdge("plan", "execute")
38
+ * .compile();
39
+ * ```
40
+ *
41
+ * Design notes:
42
+ * - **Same inference quirk as `darwinAnnotation`.** Return type is
43
+ * inferred from `Annotation.Root`; the internal `LastValue` vs
44
+ * `BaseChannel` union is opaque to it. Hand-typing triggers TS2741.
45
+ * - **`messages` default is `[]`** — graphs that don't seed messages
46
+ * in `invoke({ task: "..." })` still work.
47
+ */
48
+ import type { BaseMessage } from "@langchain/core/messages";
49
+ /**
50
+ * Spec for the `messages` channel — re-exported for power-users who want
51
+ * to spread it into their own `Annotation.Root` call manually.
52
+ *
53
+ * Return type inferred (same `LastValue<T>` vs `BaseChannel<T>` quirk
54
+ * documented on `getDarwinChannelSpec` — hand-typing triggers TS2741).
55
+ */
56
+ export declare function getMessagesChannelSpec(): {
57
+ messages: import("@langchain/langgraph").BaseChannel<BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[], BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[] | import("@langchain/langgraph").OverwriteValue<BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[]>, unknown>;
58
+ };
59
+ /**
60
+ * Build an `Annotation.Root` with the three Darwin channels PLUS the
61
+ * canonical `messages` channel for interop with `createReactAgent` /
62
+ * `MessagesAnnotation`-based prebuilt agents.
63
+ */
64
+ export declare function darwinMessagesAnnotation<Extra extends Record<string, any> = {}>(extra?: Extra): import("@langchain/langgraph").AnnotationRoot<{
65
+ messages: import("@langchain/langgraph").BaseChannel<BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[], BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[] | import("@langchain/langgraph").OverwriteValue<BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>[]>, unknown>;
66
+ task: import("@langchain/langgraph").LastValue<string>;
67
+ output: import("@langchain/langgraph").LastValue<string>;
68
+ darwinTrajectory: import("@langchain/langgraph").BaseChannel<import("darwin-agents").ExecutionTrace | undefined, import("darwin-agents").ExecutionTrace | import("@langchain/langgraph").OverwriteValue<import("darwin-agents").ExecutionTrace | undefined> | undefined, unknown>;
69
+ } & Extra>;
70
+ //# sourceMappingURL=darwin-messages-annotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-messages-annotation.d.ts","sourceRoot":"","sources":["../src/darwin-messages-annotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAI5D;;;;;;GAMG;AACH,wBAAgB,sBAAsB;;EAOrC;AAED;;;;GAIG;AAEH,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,EAC7E,KAAK,CAAC,EAAE,KAAK;;;;;WAOd"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Surface 6 (V0.2) — `darwinMessagesAnnotation(extra?)`.
3
+ *
4
+ * Variant of {@link darwinAnnotation} that also includes LangGraph's
5
+ * canonical `messages` channel (using `messagesStateReducer` from
6
+ * `@langchain/langgraph`). Use this when your graph mixes Darwin agents
7
+ * with `createReactAgent` / `MessagesAnnotation`-based prebuilt agents
8
+ * — they all read and write the same `messages` channel without
9
+ * channel-name conflicts.
10
+ *
11
+ * Layered channels:
12
+ * - `task` (string, last-write-wins) — Darwin agent task input
13
+ * - `output` (string, last-write-wins) — Darwin agent text output
14
+ * - `darwinTrajectory` (ExecutionTrace | undefined) — captured trace
15
+ * - `messages` (BaseMessage[], `messagesStateReducer`) — chat history
16
+ *
17
+ * Composable: any `extra` channels merge in.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { darwinMessagesAnnotation, createDarwinNode } from "darwin-langgraph";
22
+ * import { StateGraph } from "@langchain/langgraph";
23
+ * import { createReactAgent } from "@langchain/langgraph/prebuilt";
24
+ * import { ChatAnthropic } from "@langchain/anthropic";
25
+ *
26
+ * const State = darwinMessagesAnnotation();
27
+ *
28
+ * const planner = createReactAgent({
29
+ * llm: new ChatAnthropic({ model: "claude-haiku-4-5" }),
30
+ * tools: [],
31
+ * });
32
+ *
33
+ * const graph = new StateGraph(State)
34
+ * .addNode("plan", planner) // writes to messages
35
+ * .addNode("execute", createDarwinNode(myAgent)) // writes to output
36
+ * .addEdge("__start__", "plan")
37
+ * .addEdge("plan", "execute")
38
+ * .compile();
39
+ * ```
40
+ *
41
+ * Design notes:
42
+ * - **Same inference quirk as `darwinAnnotation`.** Return type is
43
+ * inferred from `Annotation.Root`; the internal `LastValue` vs
44
+ * `BaseChannel` union is opaque to it. Hand-typing triggers TS2741.
45
+ * - **`messages` default is `[]`** — graphs that don't seed messages
46
+ * in `invoke({ task: "..." })` still work.
47
+ */
48
+ import { Annotation, messagesStateReducer, } from "@langchain/langgraph";
49
+ import { getDarwinChannelSpec } from "./darwin-annotation.js";
50
+ /**
51
+ * Spec for the `messages` channel — re-exported for power-users who want
52
+ * to spread it into their own `Annotation.Root` call manually.
53
+ *
54
+ * Return type inferred (same `LastValue<T>` vs `BaseChannel<T>` quirk
55
+ * documented on `getDarwinChannelSpec` — hand-typing triggers TS2741).
56
+ */
57
+ export function getMessagesChannelSpec() {
58
+ return {
59
+ messages: Annotation({
60
+ reducer: messagesStateReducer,
61
+ default: () => [],
62
+ }),
63
+ };
64
+ }
65
+ /**
66
+ * Build an `Annotation.Root` with the three Darwin channels PLUS the
67
+ * canonical `messages` channel for interop with `createReactAgent` /
68
+ * `MessagesAnnotation`-based prebuilt agents.
69
+ */
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ export function darwinMessagesAnnotation(extra) {
72
+ return Annotation.Root({
73
+ ...getDarwinChannelSpec(),
74
+ ...getMessagesChannelSpec(),
75
+ ...(extra ?? {}),
76
+ });
77
+ }
78
+ //# sourceMappingURL=darwin-messages-annotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-messages-annotation.js","sourceRoot":"","sources":["../src/darwin-messages-annotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EACL,UAAU,EACV,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,QAAQ,EAAE,UAAU,CAAgB;YAClC,OAAO,EAAE,oBAAoB;YAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;SAClB,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,8DAA8D;AAC9D,MAAM,UAAU,wBAAwB,CACtC,KAAa;IAEb,OAAO,UAAU,CAAC,IAAI,CAAC;QACrB,GAAG,oBAAoB,EAAE;QACzB,GAAG,sBAAsB,EAAE;QAC3B,GAAG,CAAC,KAAK,IAAK,EAAY,CAAC;KAC5B,CAAC,CAAC;AACL,CAAC"}
package/dist/index.d.ts CHANGED
@@ -37,11 +37,14 @@
37
37
  * console.log(result.output);
38
38
  * ```
39
39
  */
40
- export { createDarwinNode, type CreateDarwinNodeOptions, type DarwinNodeFn, } from "./create-darwin-node.js";
40
+ export { createDarwinNode, type CreateDarwinNodeOptions, type DarwinNodeFn, type DarwinRunOptionsPassthrough, } from "./create-darwin-node.js";
41
41
  export { darwinAnnotation, getDarwinChannelSpec, lastWriteWinsTrajectoryReducer, } from "./darwin-annotation.js";
42
42
  export { withDarwinEvolution, type DarwinEvolutionOptions, type DarwinNodeMapEntry, type DarwinTrajectoryEvent, } from "./with-darwin-evolution.js";
43
+ export { DarwinCallbackHandler } from "./darwin-callback-handler.js";
44
+ export { toOtelAttributes, toolCallToOtelAttributes, type OtelAttributes, type ToOtelAttributesOptions, type ToolCallOtelOptions, } from "./to-otel-attributes.js";
45
+ export { darwinMessagesAnnotation, getMessagesChannelSpec, } from "./darwin-messages-annotation.js";
43
46
  export { DarwinNodeError, DarwinEvolutionHookError } from "./errors.js";
44
47
  export type { AgentDefinition, DarwinExperiment, ExecutionTrace, MemoryProvider, RunResult, TraceToolCall, TraceTokenUsage, TraceTurnError, } from "./types.js";
45
48
  /** Adapter version — sync with `package.json` on every release. */
46
- export declare const VERSION = "0.1.0-alpha.1";
49
+ export declare const VERSION = "0.2.0-alpha.1";
47
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,GAClB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAExE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,mEAAmE;AACnE,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,2BAA2B,GACjC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAExE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,mEAAmE;AACnE,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -40,7 +40,13 @@
40
40
  export { createDarwinNode, } from "./create-darwin-node.js";
41
41
  export { darwinAnnotation, getDarwinChannelSpec, lastWriteWinsTrajectoryReducer, } from "./darwin-annotation.js";
42
42
  export { withDarwinEvolution, } from "./with-darwin-evolution.js";
43
+ // V0.2 — LangChain-native callback handler (preferred over `withDarwinEvolution`)
44
+ export { DarwinCallbackHandler } from "./darwin-callback-handler.js";
45
+ // V0.2 — OTEL GenAI Semantic Conventions mapping
46
+ export { toOtelAttributes, toolCallToOtelAttributes, } from "./to-otel-attributes.js";
47
+ // V0.2 — MessagesAnnotation interop for graphs mixing createReactAgent + createDarwinNode
48
+ export { darwinMessagesAnnotation, getMessagesChannelSpec, } from "./darwin-messages-annotation.js";
43
49
  export { DarwinNodeError, DarwinEvolutionHookError } from "./errors.js";
44
50
  /** Adapter version — sync with `package.json` on every release. */
45
- export const VERSION = "0.1.0-alpha.1";
51
+ export const VERSION = "0.2.0-alpha.1";
46
52
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EACL,gBAAgB,GAGjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,GAIpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAaxE,mEAAmE;AACnE,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EACL,gBAAgB,GAIjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,GAIpB,MAAM,4BAA4B,CAAC;AAEpC,kFAAkF;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,iDAAiD;AACjD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,GAIzB,MAAM,yBAAyB,CAAC;AAEjC,0FAA0F;AAC1F,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAaxE,mEAAmE;AACnE,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Surface 5 (V0.2) — `toOtelAttributes(trajectory, opts?)`.
3
+ *
4
+ * Pure mapper from Darwin's `ExecutionTrace` to a flat
5
+ * `Record<string, string | number | boolean>` keyed by
6
+ * [OpenTelemetry GenAI Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md)
7
+ * attribute names — so any OTEL-compatible exporter (Langfuse,
8
+ * Braintrust, Honeycomb, Datadog, New Relic, Grafana) picks up the
9
+ * trace data without further mapping.
10
+ *
11
+ * Coverage:
12
+ * - `gen_ai.operation.name` = `"invoke_agent"` (constant per OTEL
13
+ * GenAI spec for agent-level operations).
14
+ * - `gen_ai.agent.name` = `opts.agentName` (callers passes the
15
+ * agent's logical name).
16
+ * - `gen_ai.agent.id` = `opts.agentId` (optional UUID/run id).
17
+ * - `gen_ai.usage.input_tokens` / `output_tokens` / `cache_read_tokens` /
18
+ * `cache_creation_tokens` — only emitted when the upstream
19
+ * trajectory captured token usage (i.e. provider reported it).
20
+ * - `darwin.trajectory.tool_calls.count` (custom, non-OTEL — namespaced
21
+ * under `darwin.*` to avoid colliding with future OTEL fields).
22
+ * - `darwin.trajectory.text_blocks` / `turns` / `mcp_invocations` /
23
+ * `errors.count` — same custom namespace.
24
+ * - `darwin.trajectory.captured_at` — ISO string for traceability.
25
+ *
26
+ * Per OTEL GenAI spec we DO NOT emit `gen_ai.tool.call.arguments` /
27
+ * `gen_ai.tool.call.result` here — those are span-level attributes
28
+ * meant to be attached to per-tool-call spans, not the aggregate
29
+ * trajectory. Callers who need them should iterate `trajectory.toolCalls`
30
+ * and emit one child span per call.
31
+ *
32
+ * Design notes:
33
+ * - **Sparse output.** Undefined fields stay out of the result rather
34
+ * than appearing as `null` — keeps OTEL exporters from over-counting
35
+ * missing-data buckets.
36
+ * - **No allocation on hot path.** The function builds a single
37
+ * object literal incrementally; no Map / Set / array intermediates.
38
+ * - **Pure.** No side effects, no I/O, no Date.now() — fully
39
+ * testable with deterministic inputs.
40
+ */
41
+ import type { ExecutionTrace } from "darwin-agents";
42
+ /** Options accepted by {@link toOtelAttributes}. */
43
+ export interface ToOtelAttributesOptions {
44
+ /** Logical agent name. Maps to `gen_ai.agent.name`. */
45
+ agentName?: string;
46
+ /** Optional agent id (e.g. uuid or experiment id). Maps to `gen_ai.agent.id`. */
47
+ agentId?: string;
48
+ /**
49
+ * Custom namespace for Darwin-specific attributes that have no OTEL
50
+ * equivalent. Default: `"darwin"` → emits `darwin.trajectory.*`.
51
+ * Override for organisation-wide naming conventions (e.g. `"company.darwin"`).
52
+ */
53
+ customNamespace?: string;
54
+ }
55
+ /** Flat attribute bag matching OTEL's primitive-only attribute types. */
56
+ export type OtelAttributes = Record<string, string | number | boolean>;
57
+ /**
58
+ * Build the OTEL attribute bag for an `ExecutionTrace`.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * import { toOtelAttributes } from "darwin-langgraph";
63
+ *
64
+ * const attrs = toOtelAttributes(event.trajectory, {
65
+ * agentName: event.agentName,
66
+ * agentId: someExperimentId,
67
+ * });
68
+ * // attrs = {
69
+ * // "gen_ai.operation.name": "invoke_agent",
70
+ * // "gen_ai.agent.name": "researcher",
71
+ * // "gen_ai.agent.id": "exp-2026-05-25-001",
72
+ * // "gen_ai.usage.input_tokens": 1200,
73
+ * // "gen_ai.usage.output_tokens": 340,
74
+ * // "darwin.trajectory.tool_calls.count": 3,
75
+ * // "darwin.trajectory.text_blocks": 2,
76
+ * // "darwin.trajectory.turns": 4,
77
+ * // "darwin.trajectory.mcp_invocations": 2,
78
+ * // "darwin.trajectory.errors.count": 0,
79
+ * // "darwin.trajectory.captured_at": "2026-05-25T08:00:00.000Z",
80
+ * // }
81
+ *
82
+ * // OTEL exporter usage (any tracer):
83
+ * span.setAttributes(attrs);
84
+ * ```
85
+ */
86
+ export declare function toOtelAttributes(trajectory: ExecutionTrace, opts?: ToOtelAttributesOptions): OtelAttributes;
87
+ /**
88
+ * Build per-tool-call OTEL attributes for each entry in
89
+ * `trajectory.toolCalls`. Use this to emit one child span per tool call
90
+ * under the parent agent span.
91
+ *
92
+ * Coverage:
93
+ * - `gen_ai.operation.name` = `"execute_tool"` (OTEL spec).
94
+ * - `gen_ai.tool.name` (OTEL spec).
95
+ * - `gen_ai.tool.call.id` (OTEL spec).
96
+ * - `gen_ai.tool.type` = `"function"` (default for MCP + builtins).
97
+ * - `darwin.tool.outcome` = `"success" | "error"` (custom).
98
+ * - `darwin.tool.duration_ms` (custom).
99
+ * - `darwin.tool.turn` (custom).
100
+ * - `darwin.tool.is_mcp` (boolean, custom).
101
+ * - `gen_ai.tool.call.arguments` (JSON-stringified) — opt-in via
102
+ * `opts.includeArguments`. Per OTEL spec this is OPT-IN because args
103
+ * can contain sensitive data.
104
+ * - `gen_ai.tool.call.result` — opt-in via `opts.includeResults` for
105
+ * the same reason.
106
+ * - `error.type` = `trajectory.toolCalls[i].errorClass` (when outcome=error).
107
+ */
108
+ export interface ToolCallOtelOptions {
109
+ customNamespace?: string;
110
+ /** Emit `gen_ai.tool.call.arguments` (OPT-IN, may contain PII). */
111
+ includeArguments?: boolean;
112
+ /** Emit `gen_ai.tool.call.result` (OPT-IN, may contain PII). */
113
+ includeResults?: boolean;
114
+ }
115
+ export declare function toolCallToOtelAttributes(call: ExecutionTrace["toolCalls"][number], opts?: ToolCallOtelOptions): OtelAttributes;
116
+ //# sourceMappingURL=to-otel-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-otel-attributes.d.ts","sourceRoot":"","sources":["../src/to-otel-attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,EAC1B,IAAI,GAAE,uBAA4B,GACjC,cAAc,CAmEhB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EACzC,IAAI,GAAE,mBAAwB,GAC7B,cAAc,CAoDhB"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Surface 5 (V0.2) — `toOtelAttributes(trajectory, opts?)`.
3
+ *
4
+ * Pure mapper from Darwin's `ExecutionTrace` to a flat
5
+ * `Record<string, string | number | boolean>` keyed by
6
+ * [OpenTelemetry GenAI Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md)
7
+ * attribute names — so any OTEL-compatible exporter (Langfuse,
8
+ * Braintrust, Honeycomb, Datadog, New Relic, Grafana) picks up the
9
+ * trace data without further mapping.
10
+ *
11
+ * Coverage:
12
+ * - `gen_ai.operation.name` = `"invoke_agent"` (constant per OTEL
13
+ * GenAI spec for agent-level operations).
14
+ * - `gen_ai.agent.name` = `opts.agentName` (callers passes the
15
+ * agent's logical name).
16
+ * - `gen_ai.agent.id` = `opts.agentId` (optional UUID/run id).
17
+ * - `gen_ai.usage.input_tokens` / `output_tokens` / `cache_read_tokens` /
18
+ * `cache_creation_tokens` — only emitted when the upstream
19
+ * trajectory captured token usage (i.e. provider reported it).
20
+ * - `darwin.trajectory.tool_calls.count` (custom, non-OTEL — namespaced
21
+ * under `darwin.*` to avoid colliding with future OTEL fields).
22
+ * - `darwin.trajectory.text_blocks` / `turns` / `mcp_invocations` /
23
+ * `errors.count` — same custom namespace.
24
+ * - `darwin.trajectory.captured_at` — ISO string for traceability.
25
+ *
26
+ * Per OTEL GenAI spec we DO NOT emit `gen_ai.tool.call.arguments` /
27
+ * `gen_ai.tool.call.result` here — those are span-level attributes
28
+ * meant to be attached to per-tool-call spans, not the aggregate
29
+ * trajectory. Callers who need them should iterate `trajectory.toolCalls`
30
+ * and emit one child span per call.
31
+ *
32
+ * Design notes:
33
+ * - **Sparse output.** Undefined fields stay out of the result rather
34
+ * than appearing as `null` — keeps OTEL exporters from over-counting
35
+ * missing-data buckets.
36
+ * - **No allocation on hot path.** The function builds a single
37
+ * object literal incrementally; no Map / Set / array intermediates.
38
+ * - **Pure.** No side effects, no I/O, no Date.now() — fully
39
+ * testable with deterministic inputs.
40
+ */
41
+ /**
42
+ * Build the OTEL attribute bag for an `ExecutionTrace`.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * import { toOtelAttributes } from "darwin-langgraph";
47
+ *
48
+ * const attrs = toOtelAttributes(event.trajectory, {
49
+ * agentName: event.agentName,
50
+ * agentId: someExperimentId,
51
+ * });
52
+ * // attrs = {
53
+ * // "gen_ai.operation.name": "invoke_agent",
54
+ * // "gen_ai.agent.name": "researcher",
55
+ * // "gen_ai.agent.id": "exp-2026-05-25-001",
56
+ * // "gen_ai.usage.input_tokens": 1200,
57
+ * // "gen_ai.usage.output_tokens": 340,
58
+ * // "darwin.trajectory.tool_calls.count": 3,
59
+ * // "darwin.trajectory.text_blocks": 2,
60
+ * // "darwin.trajectory.turns": 4,
61
+ * // "darwin.trajectory.mcp_invocations": 2,
62
+ * // "darwin.trajectory.errors.count": 0,
63
+ * // "darwin.trajectory.captured_at": "2026-05-25T08:00:00.000Z",
64
+ * // }
65
+ *
66
+ * // OTEL exporter usage (any tracer):
67
+ * span.setAttributes(attrs);
68
+ * ```
69
+ */
70
+ export function toOtelAttributes(trajectory, opts = {}) {
71
+ if (!trajectory || typeof trajectory !== "object" || trajectory.version !== 1) {
72
+ throw new TypeError(`toOtelAttributes: trajectory must be an ExecutionTrace with version=1, got ${trajectory === null ? "null" : typeof trajectory}`);
73
+ }
74
+ const ns = opts.customNamespace ?? "darwin";
75
+ const attrs = {
76
+ // OTEL GenAI required-style attributes
77
+ "gen_ai.operation.name": "invoke_agent",
78
+ };
79
+ if (opts.agentName)
80
+ attrs["gen_ai.agent.name"] = opts.agentName;
81
+ if (opts.agentId)
82
+ attrs["gen_ai.agent.id"] = opts.agentId;
83
+ // Token usage — only emit when provider reported FINITE numbers. NaN
84
+ // and Infinity pass `typeof === "number"` but OTEL exporters drop
85
+ // spans with non-finite numeric attrs silently (R1 V0.2 Critic
86
+ // Finding 3 + Finding 7, S1185).
87
+ //
88
+ // OTEL GenAI spec attribute names (R1 V0.2 Research Finding 1, S1185):
89
+ // cache fields are `gen_ai.usage.cache_read.input_tokens` /
90
+ // `cache_creation.input_tokens` per the official registry, NOT the
91
+ // shorter `cache_read_tokens` / `cache_creation_tokens` we had pre-fix.
92
+ const usage = trajectory.tokenUsage;
93
+ if (usage) {
94
+ if (typeof usage.inputTokens === "number" && Number.isFinite(usage.inputTokens)) {
95
+ attrs["gen_ai.usage.input_tokens"] = usage.inputTokens;
96
+ }
97
+ if (typeof usage.outputTokens === "number" && Number.isFinite(usage.outputTokens)) {
98
+ attrs["gen_ai.usage.output_tokens"] = usage.outputTokens;
99
+ }
100
+ if (typeof usage.cacheReadTokens === "number" && Number.isFinite(usage.cacheReadTokens)) {
101
+ attrs["gen_ai.usage.cache_read.input_tokens"] = usage.cacheReadTokens;
102
+ }
103
+ if (typeof usage.cacheCreationTokens === "number" &&
104
+ Number.isFinite(usage.cacheCreationTokens)) {
105
+ attrs["gen_ai.usage.cache_creation.input_tokens"] = usage.cacheCreationTokens;
106
+ }
107
+ }
108
+ // Darwin-namespaced aggregates (always emitted, even when 0, so
109
+ // dashboards can graph deltas correctly). Defensive `?? 0` fallback
110
+ // in case a future darwin-agents version makes a field optional.
111
+ const toolCallsCount = Array.isArray(trajectory.toolCalls)
112
+ ? trajectory.toolCalls.length
113
+ : 0;
114
+ const errorsCount = Array.isArray(trajectory.errors) ? trajectory.errors.length : 0;
115
+ attrs[`${ns}.trajectory.tool_calls.count`] = toolCallsCount;
116
+ attrs[`${ns}.trajectory.text_blocks`] =
117
+ Number.isFinite(trajectory.textBlockCount) ? trajectory.textBlockCount : 0;
118
+ attrs[`${ns}.trajectory.turns`] =
119
+ Number.isFinite(trajectory.turnCount) ? trajectory.turnCount : 0;
120
+ attrs[`${ns}.trajectory.mcp_invocations`] =
121
+ Number.isFinite(trajectory.mcpInvocations) ? trajectory.mcpInvocations : 0;
122
+ attrs[`${ns}.trajectory.errors.count`] = errorsCount;
123
+ if (typeof trajectory.capturedAt === "string" && trajectory.capturedAt.length > 0) {
124
+ attrs[`${ns}.trajectory.captured_at`] = trajectory.capturedAt;
125
+ }
126
+ return attrs;
127
+ }
128
+ export function toolCallToOtelAttributes(call, opts = {}) {
129
+ const ns = opts.customNamespace ?? "darwin";
130
+ // R1 V0.2 Research Finding 3 (S1185): per OTEL GenAI spec, `gen_ai.tool.type`
131
+ // takes one of `function` (client-side, agent generates params),
132
+ // `extension` (agent-side, calls external APIs), or `datastore`. MCP
133
+ // tools execute server-side via the agent and call external APIs —
134
+ // they map to `"extension"`, not `"function"`. We route on the
135
+ // existing `mcp__` prefix heuristic.
136
+ const isMcp = call.tool.startsWith("mcp__");
137
+ const toolType = isMcp ? "extension" : "function";
138
+ const attrs = {
139
+ "gen_ai.operation.name": "execute_tool",
140
+ "gen_ai.tool.name": call.tool,
141
+ "gen_ai.tool.type": toolType,
142
+ [`${ns}.tool.outcome`]: call.outcome,
143
+ [`${ns}.tool.duration_ms`]: Number.isFinite(call.durationMs) ? call.durationMs : 0,
144
+ [`${ns}.tool.turn`]: Number.isFinite(call.turn) ? call.turn : 0,
145
+ [`${ns}.tool.is_mcp`]: isMcp,
146
+ };
147
+ // `call.id` is optional on TraceToolCall — only emit when present so
148
+ // OTEL exporters don't see empty-string ids.
149
+ if (typeof call.id === "string" && call.id.length > 0) {
150
+ attrs["gen_ai.tool.call.id"] = call.id;
151
+ }
152
+ if (call.outcome === "error") {
153
+ if (typeof call.errorClass === "string" && call.errorClass.length > 0) {
154
+ attrs["error.type"] = call.errorClass;
155
+ }
156
+ if (typeof call.errorMessage === "string" && call.errorMessage.length > 0) {
157
+ attrs[`${ns}.tool.error.message`] = call.errorMessage;
158
+ }
159
+ }
160
+ if (typeof call.retryCount === "number" && call.retryCount > 0) {
161
+ attrs[`${ns}.tool.retry_count`] = call.retryCount;
162
+ }
163
+ if (opts.includeArguments && call.args !== undefined) {
164
+ try {
165
+ attrs["gen_ai.tool.call.arguments"] = JSON.stringify(call.args);
166
+ }
167
+ catch {
168
+ attrs["gen_ai.tool.call.arguments"] = "<unserialisable>";
169
+ }
170
+ }
171
+ if (opts.includeResults &&
172
+ typeof call.resultSummary === "string" &&
173
+ call.resultSummary.length > 0) {
174
+ attrs["gen_ai.tool.call.result"] = call.resultSummary;
175
+ }
176
+ return attrs;
177
+ }
178
+ //# sourceMappingURL=to-otel-attributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-otel-attributes.js","sourceRoot":"","sources":["../src/to-otel-attributes.ts"],"names":[],"mappings":"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"}
@@ -80,13 +80,6 @@ interface InvokableGraph {
80
80
  invoke(input: unknown, config?: unknown): Promise<unknown>;
81
81
  stream(input: unknown, config?: unknown): Promise<AsyncIterable<unknown>>;
82
82
  }
83
- /**
84
- * Wraps a compiled LangGraph so the supplied `onTrajectory` callback
85
- * fires for each node listed in `nodeMap` after every `invoke` / `stream`
86
- * run. Returns the same graph instance for chaining.
87
- *
88
- * @throws {DarwinEvolutionHookError} when `nodeMap` is empty or missing.
89
- */
90
83
  export declare function withDarwinEvolution<G extends InvokableGraph>(graph: G, opts: DarwinEvolutionOptions): G;
91
84
  export {};
92
85
  //# sourceMappingURL=with-darwin-evolution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"with-darwin-evolution.d.ts","sourceRoot":"","sources":["../src/with-darwin-evolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,gFAAgF;AAChF,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,UAAU,EAAE,cAAc,CAAC;IAC3B;;;;;;OAMG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/C;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,mGAAmG;IACnG,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,yEAAyE;AACzE,UAAU,cAAc;IACtB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CAC3E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,cAAc,EAC1D,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,sBAAsB,GAC3B,CAAC,CA+OH"}
1
+ {"version":3,"file":"with-darwin-evolution.d.ts","sourceRoot":"","sources":["../src/with-darwin-evolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,gFAAgF;AAChF,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,UAAU,EAAE,cAAc,CAAC;IAC3B;;;;;;OAMG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/C;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,mGAAmG;IACnG,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,yEAAyE;AACzE,UAAU,cAAc;IACtB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CAC3E;AAkCD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,cAAc,EAC1D,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,sBAAsB,GAC3B,CAAC,CA2PH"}
@@ -34,9 +34,39 @@ import { DarwinEvolutionHookError } from "./errors.js";
34
34
  * fires for each node listed in `nodeMap` after every `invoke` / `stream`
35
35
  * run. Returns the same graph instance for chaining.
36
36
  *
37
+ * @deprecated Since v0.2.0 — prefer {@link DarwinCallbackHandler} which uses
38
+ * LangChain's canonical callback mechanism instead of monkey-patching
39
+ * `graph.invoke` / `graph.stream`. This wrapper continues to work
40
+ * identically for back-compat but will be removed in v1.0. Migration:
41
+ *
42
+ * ```ts
43
+ * // Before (v0.1):
44
+ * const graph = withDarwinEvolution(compiledGraph, { nodeMap, onTrajectory });
45
+ * const r = await graph.invoke(input);
46
+ *
47
+ * // After (v0.2 — recommended):
48
+ * const handler = new DarwinCallbackHandler({ nodeMap, onTrajectory });
49
+ * const r = await compiledGraph.invoke(input, { callbacks: [handler] });
50
+ * ```
51
+ *
37
52
  * @throws {DarwinEvolutionHookError} when `nodeMap` is empty or missing.
38
53
  */
54
+ /**
55
+ * Process-wide deprecation warning flag for `withDarwinEvolution`. We
56
+ * emit one `console.warn` on the first call so CI runs (no IDE for
57
+ * `@deprecated` strikethrough) still see the migration hint. After the
58
+ * first warn we go silent — never spam.
59
+ *
60
+ * R1 V0.2 Research Finding 7 + Analyst Observation 2 (S1185).
61
+ */
62
+ let withDarwinEvolutionDeprecationWarned = false;
39
63
  export function withDarwinEvolution(graph, opts) {
64
+ if (!withDarwinEvolutionDeprecationWarned) {
65
+ withDarwinEvolutionDeprecationWarned = true;
66
+ console.warn("[darwin-langgraph] withDarwinEvolution() is deprecated since v0.2.0 " +
67
+ "and will be removed in v1.0.0. Migrate to DarwinCallbackHandler — " +
68
+ "see https://github.com/studiomeyer-io/darwin-langgraph#migration");
69
+ }
40
70
  if (!opts || !opts.nodeMap || Object.keys(opts.nodeMap).length === 0) {
41
71
  throw new DarwinEvolutionHookError("withDarwinEvolution: opts.nodeMap is required and must contain at least one entry.");
42
72
  }
@@ -65,12 +95,16 @@ export function withDarwinEvolution(graph, opts) {
65
95
  }
66
96
  let warned = false;
67
97
  const swallow = (err) => {
68
- if (warned || !err)
98
+ // R2 V0.2 Critic Finding R2-1 (S1185): do NOT short-circuit on
99
+ // falsy `err` — `throw 0` / `throw null` / `throw ""` from user
100
+ // callbacks must still surface in logs. Diverged from
101
+ // DarwinCallbackHandler.swallow until R2 caught it.
102
+ if (warned)
69
103
  return;
70
104
  warned = true;
71
105
  console.warn(`[darwin-langgraph] onTrajectory callback threw — swallowed. ` +
72
106
  `Subsequent throws will be silent. Original error: ` +
73
- `${err?.message ?? String(err)}`);
107
+ `${err instanceof Error ? err.message : String(err)}`);
74
108
  };
75
109
  const fireHook = async (finalState) => {
76
110
  if (!callback)
@@ -1 +1 @@
1
- {"version":3,"file":"with-darwin-evolution.js","sourceRoot":"","sources":["../src/with-darwin-evolution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"with-darwin-evolution.js","sourceRoot":"","sources":["../src/with-darwin-evolution.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "darwin-langgraph",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.2.0-alpha.1",
4
4
  "description": "LangGraph.js adapter for darwin-agents — wrap self-evolving Darwin agents as StateGraph nodes with zero hard deps.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",