darwin-langgraph 0.3.0-alpha.1 → 0.4.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +243 -0
  2. package/README.md +18 -1
  3. package/dist/create-darwin-node.d.ts +55 -0
  4. package/dist/create-darwin-node.d.ts.map +1 -1
  5. package/dist/create-darwin-node.js +56 -1
  6. package/dist/create-darwin-node.js.map +1 -1
  7. package/dist/darwin-accumulating-annotation.d.ts +81 -0
  8. package/dist/darwin-accumulating-annotation.d.ts.map +1 -0
  9. package/dist/darwin-accumulating-annotation.js +144 -0
  10. package/dist/darwin-accumulating-annotation.js.map +1 -0
  11. package/dist/darwin-callback-handler.d.ts +131 -1
  12. package/dist/darwin-callback-handler.d.ts.map +1 -1
  13. package/dist/darwin-callback-handler.js +360 -18
  14. package/dist/darwin-callback-handler.js.map +1 -1
  15. package/dist/errors.d.ts +16 -0
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +19 -0
  18. package/dist/errors.js.map +1 -1
  19. package/dist/index.d.ts +7 -3
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +11 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/to-otel-attributes.d.ts +49 -0
  24. package/dist/to-otel-attributes.d.ts.map +1 -1
  25. package/dist/to-otel-attributes.js +38 -2
  26. package/dist/to-otel-attributes.js.map +1 -1
  27. package/dist/to-w3c-trace-context.d.ts +81 -0
  28. package/dist/to-w3c-trace-context.d.ts.map +1 -0
  29. package/dist/to-w3c-trace-context.js +134 -0
  30. package/dist/to-w3c-trace-context.js.map +1 -0
  31. package/dist/token-budget.d.ts +141 -0
  32. package/dist/token-budget.d.ts.map +1 -0
  33. package/dist/token-budget.js +225 -0
  34. package/dist/token-budget.js.map +1 -0
  35. package/dist/with-darwin-evolution.d.ts +16 -0
  36. package/dist/with-darwin-evolution.d.ts.map +1 -1
  37. package/dist/with-darwin-evolution.js +9 -1
  38. package/dist/with-darwin-evolution.js.map +1 -1
  39. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,249 @@
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.4.0-alpha.1] — 2026-05-29
7
+
8
+ V0.4 is an additive release that closes the V0.3 R2 deferrals and lands
9
+ nine new surfaces driven by a research sweep across LangGraph 1.3, the
10
+ OpenTelemetry GenAI Semantic Conventions registry, and the LangGraph
11
+ TypeScript Production Guide. **Zero breaking changes** — every existing
12
+ V0.3 consumer keeps working unchanged.
13
+
14
+ ### Added — nine new surfaces
15
+
16
+ - **`DarwinCallbackHandler.onToolEvent`** — new option that fires for
17
+ every LangGraph tool-chain start / end / error inside a tracked node.
18
+ Emits a `DarwinToolEvent` (`phase: "start" | "end" | "error"`) with
19
+ `toolName`, `runId`, `parentRunId`, plus `input` / `output` / `error`
20
+ depending on phase. Use it to emit per-tool OTEL spans, drive progress
21
+ UIs, or wire abort-on-tool-failure logic. The handler now also caches
22
+ tool names internally so end / error events get the same name the
23
+ start event reported, even when the LangChain tool-end signature does
24
+ not carry the name (LangChain 0.3 quirk).
25
+ - **`DarwinCallbackHandler` `maxTrajectoryBytes`** — soft cap (default
26
+ `262_144` = 256 KiB) on the serialised trajectory size emitted via
27
+ `onTrajectory`. Oversized trajectories are replaced with a
28
+ structurally-compatible BUT minimal stub (counts + `capturedAt` +
29
+ `tokenUsage` preserved, `toolCalls` / `errors` replaced with empty
30
+ arrays). The event payload gains a new `trajectoryTruncated: true`
31
+ field so consumers can branch. Circular-reference trajectories are
32
+ caught defensively and treated as oversized. `tokenUsage` is shallow-
33
+ copied and `bigint` token counters are coerced to `number` so
34
+ downstream `JSON.stringify` never trips.
35
+ - **`MAX_KNOWN_TRACE_VERSION` + forward-compat `isExecutionTrace`** —
36
+ the handler now accepts `version >= 1` and warns once per process when
37
+ a higher-than-known version is observed. The accumulator reducer,
38
+ `withDarwinEvolution`, and `toOtelAttributes` all share the same
39
+ widening so a future `darwin-agents` schema bump does not silently
40
+ drop trajectories anywhere on the pipeline.
41
+ - **`toOtelAttributes` LangGraph + OTel cross-cutting attributes** —
42
+ four new options. `langGraphNode` and `langGraphStep` emit
43
+ `gen_ai.langgraph.node` / `gen_ai.langgraph.step` per the Coralogix /
44
+ Last9 / Honeycomb LangGraph instrumentation convention. `userId` emits
45
+ BOTH the OTel-spec-canonical `enduser.id` (cross-cutting) AND the
46
+ historical alias `gen_ai.request.user` so dashboards on either
47
+ convention keep working. `conversationId` emits the spec-correct
48
+ `gen_ai.conversation.id` (typically the LangGraph `thread_id`).
49
+ `requestId` emits `gen_ai.request.id`.
50
+ - **`createDarwinNode.onAttempt`** — config-aware passthrough that
51
+ fires before `runAgent` with the runtime info LangGraph surfaces.
52
+ Reads `nodeAttempt` from `config.runtime.executionInfo` (per
53
+ LangGraph PR #7363, surfacing `1` on first execution and incrementing
54
+ per retry under an `addNode(name, fn, { retryPolicy })` policy),
55
+ `nodeFirstAttemptTime` from the same source (per PR #7363 for
56
+ retry-latency computation), `langGraphStep` from
57
+ `config.metadata.langgraph_step` (the canonical LangGraph 1.3 source —
58
+ NOT `executionInfo`), and `threadId` from `config.configurable.thread_id`.
59
+ Pairs naturally with LangGraph's native `retryPolicy` without adding
60
+ a competing retry layer.
61
+ - **`darwinAccumulatingAnnotation`** + **`darwinTrajectoryAccumulatorReducer`**
62
+ + **`getDarwinAccumulatingChannelSpec`** — variant of `darwinAnnotation`
63
+ that replaces the singleton `darwinTrajectory: ExecutionTrace | undefined`
64
+ channel with an accumulating `darwinTrajectories: ExecutionTrace[]`
65
+ channel. Use it when you orchestrate multiple Darwin nodes in a graph
66
+ (fan-out, sequential pipeline, supervisor) and want every trajectory
67
+ preserved in state without declaring a per-node trace channel by
68
+ hand. The reducer accepts a single `ExecutionTrace` (matching the
69
+ bare `createDarwinNode` contract) or `ExecutionTrace[]` (batch
70
+ append) and drops non-`version >= 1` shapes defensively. The
71
+ annotation throws when the optional `extra` argument tries to redefine
72
+ one of the Darwin-managed channels (`task`, `output`,
73
+ `darwinTrajectories`) — a previously silent contract footgun.
74
+ - **`createTokenBudgetCallbacks(opts)`** + **`TokenBudgetCallbackHandler`**
75
+ + **`DarwinTokenBudgetExceededError`** — production-pattern from the
76
+ LangGraph TypeScript Production Guide. Enforces a per-invocation
77
+ token budget across all LLM calls inside the graph. Extracts tokens
78
+ from `output.llmOutput.tokenUsage.totalTokens` (LangChain canonical
79
+ for ChatOpenAI / ChatAnthropic) and falls back to summing per-message
80
+ `generations[][].message.usage_metadata` (Anthropic native + others).
81
+ Throws the typed `DarwinTokenBudgetExceededError` on breach so
82
+ callers can `instanceof`-check without parsing message text.
83
+ `awaitHandlers = true` so LangChain awaits the handler and the
84
+ synchronous throw reliably reaches the `graph.invoke` caller.
85
+ Constructor validates the budget is a finite positive integer
86
+ (NaN / Infinity / 0 / negative / non-integer all throw eagerly).
87
+ - **`toW3CTraceContext(event, opts?)`** — pure mapper from
88
+ `DarwinTrajectoryEvent` to a [W3C Trace Context](https://www.w3.org/TR/trace-context/)
89
+ `traceparent` header value (`00-<32hex>-<16hex>-(00|01)`). When the
90
+ event has no `parentRunId`, the spanId is taken from the SECOND 16
91
+ hex of the runId so it is never a prefix of the traceId — several
92
+ OTEL backends (Datadog APM, Honeycomb classic) reject or misroute
93
+ spans whose ids look like self-parents. When the event has a valid
94
+ `parentRunId`, the traceId is taken from the parent and the spanId
95
+ from the first 16 hex of the runId. Returns `undefined` for malformed
96
+ / non-UUID runIds and for the all-zero strings the W3C spec forbids.
97
+ - **Example 04 — OTEL + W3C + token budget**
98
+ (`examples/04-otel-and-budget.ts`). End-to-end wiring of every new
99
+ V0.4 surface against a console-only span emitter so the example
100
+ runs without external services; swap in a real OTLP exporter or
101
+ Langfuse SDK at the marked line.
102
+
103
+ ### Added — error class
104
+
105
+ - **`DarwinTokenBudgetExceededError`** — thrown by
106
+ `TokenBudgetCallbackHandler` on breach AND eagerly on construction
107
+ when the configured budget is invalid. Exposes `budget`, `totalTokens`,
108
+ and `providerHint` (`modelName` / `model_name` extracted from the
109
+ LLMResult when present) so callers can branch on cost / provider.
110
+
111
+ ### Changed
112
+
113
+ - **`DarwinTrajectoryEvent` extended** with optional `trajectoryTruncated`
114
+ field — set to `true` when `DarwinCallbackHandler.maxTrajectoryBytes`
115
+ replaces the trajectory with a stub. Omitted (not `false`) when the
116
+ trajectory passed through unchanged.
117
+ - **`InFlightRun` shape** in `DarwinCallbackHandler` — internal change,
118
+ the `runIdToName` map now stores `{ nodeName, parentRunId, pendingTools,
119
+ finalized }`. The two new fields drive the R1 P1-4 fix that keeps
120
+ chain entries alive past `handleChainEnd` until pending tool events
121
+ have surfaced so `onToolEvent` callbacks for late-completing tools
122
+ are no longer silently dropped.
123
+ - **VERSION constant bumped** to `0.4.0-alpha.1` in both `package.json`
124
+ and `src/index.ts` (verified by `prepublishOnly` script).
125
+
126
+ ### Fixed (R1 + R2 code-review-loop pre-publish)
127
+
128
+ A three-agent R1 review (Critic + Analyst + Research) followed by an
129
+ R2 critic verification + R3 grep self-check surfaced and closed ten
130
+ issues before publish:
131
+
132
+ - **P0-1 — W3C trace context self-parent collision.** Top-level
133
+ invokes derived BOTH `traceId` and `spanId` from the first 16 chars
134
+ of the same UUID, producing `traceparent` headers where the spanId
135
+ was a prefix of the traceId. Several OTEL backends reject those as
136
+ self-parents. Fix: when no `parentRunId`, `spanId = runHex.slice(16, 32)`.
137
+ - **P0-2 — Forward-compat version drift.** The accumulator reducer
138
+ strict-equality-checked `version === 1` while `isExecutionTrace`
139
+ accepted `version >= 1`. The same widening was also missed in
140
+ `toOtelAttributes` and the legacy `withDarwinEvolution` wrapper.
141
+ All four sites now share the same `version >= 1 && Number.isFinite`
142
+ gate so a v=2 trajectory flows through every code path consistently.
143
+ - **P1-1 — Tool name lost between start and end.** `handleToolEnd`
144
+ tried to read `output.name`, which is absent for the common
145
+ `ToolNode` case (output is a plain string). Fix: cache the name
146
+ from `handleToolStart` keyed by tool runId; consume it in
147
+ `handleToolEnd` / `handleToolError`. Falls back to `output.name`
148
+ when the start was missed.
149
+ - **P1-2 — `buildTruncatedTrace` aliased original `tokenUsage`.**
150
+ The stub kept a reference to the original (potentially `bigint`-
151
+ carrying) `tokenUsage` object, breaking downstream `JSON.stringify`.
152
+ Fix: shallow copy via `Object.fromEntries(Object.entries(...))` and
153
+ coerce `bigint` values to `number`.
154
+ - **P1-4 — Pending tool events vs `handleChainEnd` race.** Chains
155
+ with long-running tools sometimes saw `handleChainEnd` synchronously
156
+ delete the `runIdToName` entry before the matching
157
+ `handleToolEnd` / `handleToolError` arrived. Fix: reference-count
158
+ pending tools per chain (`InFlightRun.pendingTools`). `handleChainEnd`
159
+ marks the entry `finalized` instead of deleting it; the last tool
160
+ callback drains a deferred trajectory dispatch and cleans up.
161
+ - **Research-1 — `gen_ai.request.user` is not OTel-canonical.** The
162
+ GenAI semconv registry defines `gen_ai.conversation.id` and the
163
+ cross-cutting `enduser.id` for user / session identity, not
164
+ `gen_ai.request.user`. Fix: emit both the canonical `enduser.id`
165
+ AND the historical alias `gen_ai.request.user` (older Coralogix /
166
+ Last9 dashboards key off the alias). New `conversationId` option
167
+ emits the spec-correct `gen_ai.conversation.id`.
168
+ - **Research-2 — `langGraphStep` source path corrected.** LangGraph
169
+ 1.3 surfaces the step counter in `config.metadata.langgraph_step`,
170
+ not `executionInfo.langGraphStep`. Fix: `createDarwinNode` reads
171
+ from the correct path and additionally surfaces
172
+ `nodeFirstAttemptTime` from `executionInfo` (per LangGraph PR
173
+ #7363) for retry-latency math.
174
+ - **P2-2 — `darwinAccumulatingAnnotation` reserved-key silent
175
+ overwrite.** Passing `extra = { darwinTrajectories: customAnnotation }`
176
+ silently replaced the accumulator channel with no warning. Fix:
177
+ throws on any `extra` key that conflicts with `task` / `output` /
178
+ `darwinTrajectories`.
179
+ - **P2-3 — `TokenBudgetCallbackHandler.awaitHandlers = false`.**
180
+ With `awaitHandlers = false` LangChain may not await the handler;
181
+ the synchronous throw inside `handleLLMEnd` could surface as an
182
+ unhandled rejection rather than aborting the graph. Fix:
183
+ `awaitHandlers = true` (the throw IS the abort signal).
184
+ - **R2 MUST-FIX — `toOtelAttributes` strict version guard.** The R1
185
+ P0-2 widening was applied to the accumulator reducer and the
186
+ callback-handler `isExecutionTrace` but missed in `toOtelAttributes`
187
+ (which still threw `TypeError` on v=2 trajectories). The R2 critic
188
+ caught it; the same forward-compat guard now lives in all four
189
+ trajectory consumers.
190
+
191
+ ### Test coverage
192
+
193
+ - **241/241 vitest tests green** (was 132 in V0.3, **+109 V0.4 tests**
194
+ across `tests/token-budget.test.ts`, `tests/to-w3c-trace-context.test.ts`,
195
+ `tests/darwin-accumulating-annotation.test.ts`, `tests/v04-features.test.ts`,
196
+ `tests/r1-v04-fixes.test.ts`).
197
+ - New regression-test file `tests/r1-v04-fixes.test.ts` (28 tests across
198
+ 10 R1+R2 fix groups) pins each fix so a future patch cannot regress
199
+ the corrected behaviour silently.
200
+ - `tsc --strict --noEmit` clean (src + examples).
201
+ - `npm run build` clean — all V0.4 surface additions ship in `dist/`.
202
+
203
+ ### V0.5 backlog (deferred from R1 + R2)
204
+
205
+ - **Per-tool size cap** alongside `maxTrajectoryBytes` (instead of the
206
+ per-trajectory level — surgical truncation of one fat tool result
207
+ rather than the whole agent).
208
+ - **`gen_ai.provider.name` + `gen_ai.request.model` + `gen_ai.response.model`
209
+ + `gen_ai.response.finish_reasons`** — spec-required OTel GenAI
210
+ attributes V0.4 does not yet emit.
211
+ - **`gen_ai.workflow.*` parallel emission** — Traceloop RFC #3460
212
+ proposes `gen_ai.workflow.current_node` as the canonical successor
213
+ to `gen_ai.langgraph.node`. Emit both during the transition.
214
+ - **`gen_ai.usage.reasoning.output_tokens`** for Claude extended
215
+ thinking / Opus 4.x reasoning models.
216
+ - **`gen_ai.usage.cache_*` rollup into the token-budget total** with
217
+ an `countCacheTokens?: boolean` flag — Anthropic prompt caching can
218
+ shift 90% of effective tokens into the cache bucket.
219
+ - **Bedrock LLMResult shape** in `extractTokenDelta` (third branch
220
+ alongside ChatOpenAI canonical + per-message `usage_metadata`).
221
+ - **`getMessagesAccumulatingChannelSpec`** + companion
222
+ `darwinMessagesAccumulatingAnnotation` for graphs mixing
223
+ `createReactAgent` with multi-Darwin fan-out.
224
+ - **Explicit `@langchain/core` peer dep declaration** in `package.json`
225
+ (currently implicit via `@langchain/langgraph` peer dep).
226
+ - **`MAX_KNOWN_TRACE_VERSION` migration to `darwin-agents`** — let the
227
+ upstream library own the constant so the adapter dependency drift
228
+ becomes a peer-dep semver failure rather than a runtime warn.
229
+ - **`tools/list` notification handler** in `streamEvents` v3 — separate
230
+ V0.5 surface that fires on tool-list changes without polling.
231
+ - **`tool_result` content-block streaming events** when LangGraph 1.4
232
+ surfaces them through the callback contract.
233
+
234
+ ### Migration from V0.3
235
+
236
+ None required. V0.4 is additive. Existing consumers can adopt the new
237
+ surfaces incrementally:
238
+
239
+ - Adopt `DarwinCallbackHandler.onToolEvent` to emit per-tool spans.
240
+ - Wrap `graph.invoke` with `createTokenBudgetCallbacks(...)` to enforce
241
+ a cost ceiling.
242
+ - Pass `event` through `toW3CTraceContext(event)` and attach the
243
+ `traceparent` header to outgoing HTTP calls for cross-process span
244
+ correlation.
245
+ - Swap `darwinAnnotation()` for `darwinAccumulatingAnnotation()` when
246
+ you orchestrate more than one Darwin node and want every trajectory
247
+ preserved.
248
+
6
249
  ## [0.3.0-alpha.1] — 2026-05-25
7
250
 
8
251
  V0.3 closes the three deferred items from V0.2's R2 review (parent-run
package/README.md CHANGED
@@ -72,7 +72,24 @@ console.log(result.output);
72
72
  console.log("trajectory:", result.darwinTrajectory);
73
73
  ```
74
74
 
75
- ## Three surfaces
75
+ ## Surfaces (V0.4 — 11 total)
76
+
77
+ V0.4 adds six new surfaces on top of the V0.3 baseline. Every addition
78
+ is additive — existing V0.3 code keeps working. The full list:
79
+
80
+ | # | Name | When to use |
81
+ |---|---|---|
82
+ | 1 | `createDarwinNode(agent, opts?)` | Wrap one Darwin agent as a `StateGraph` node. |
83
+ | 2 | `darwinAnnotation(extra?)` | Annotation with `task` + `output` + singleton `darwinTrajectory` channel. |
84
+ | 3 | `withDarwinEvolution(graph, opts)` *(deprecated since V0.2)* | Legacy monkey-patch wrapper — migrate to `DarwinCallbackHandler`. |
85
+ | 4 | `DarwinCallbackHandler` *(V0.2)* | LangChain-native callback handler with `onTrajectory` + V0.4 `onToolEvent` + V0.4 `maxTrajectoryBytes`. |
86
+ | 5 | `toOtelAttributes(trajectory, opts?)` *(V0.2)* | Map an `ExecutionTrace` to OpenTelemetry GenAI Semantic Conventions attributes. V0.4 adds `langGraphNode` / `langGraphStep` / `userId` / `conversationId` / `requestId`. |
87
+ | 6 | `darwinMessagesAnnotation(extra?)` *(V0.2)* | Annotation with a `messages` channel for `createReactAgent` interop. |
88
+ | 7 | `darwinAccumulatingAnnotation(extra?)` *(V0.4)* | Annotation with an accumulating `darwinTrajectories: ExecutionTrace[]` channel — every node write appends instead of overwriting. |
89
+ | 8 | `createTokenBudgetCallbacks(opts)` *(V0.4)* | Production guard — throws `DarwinTokenBudgetExceededError` when a per-invocation token budget is breached. |
90
+ | 9 | `toW3CTraceContext(event, opts?)` *(V0.4)* | Pure mapper to a W3C `traceparent` header value for cross-process span correlation. |
91
+ | 10 | `MAX_KNOWN_TRACE_VERSION` *(V0.4 const)* | Highest `ExecutionTrace.version` this adapter natively understands; `isExecutionTrace` warns once on higher versions but emits them anyway. |
92
+ | 11 | Error classes | `DarwinNodeError` + `DarwinEvolutionHookError` + V0.4 `DarwinTokenBudgetExceededError`. |
76
93
 
77
94
  ### 1. `createDarwinNode(agent, opts?)`
78
95
 
@@ -77,6 +77,43 @@ export interface DarwinRunOptionsPassthrough {
77
77
  timeout?: number;
78
78
  autonomous?: boolean;
79
79
  }
80
+ /**
81
+ * V0.4 (S1235) — runtime info surfaced from the LangGraph `RunnableConfig`
82
+ * for the `onAttempt` callback. Lets consumers branch on retries (e.g.
83
+ * fall back to a cheaper model after the first attempt fails — the
84
+ * canonical LangGraph retryPolicy pattern from
85
+ * langchain.com/oss/javascript/langgraph/use-graph-api#access-execution-info-inside-a-node).
86
+ *
87
+ * `nodeAttempt` is `1` for the first execution; if a retry policy is
88
+ * attached via `addNode("name", fn, { retryPolicy })` and the node
89
+ * throws, LangGraph re-fires with `nodeAttempt = 2`, etc.
90
+ *
91
+ * NEW V0.4 (S1235).
92
+ */
93
+ export interface DarwinNodeAttemptInfo {
94
+ /** Current attempt number (1-indexed, increments per retry). */
95
+ nodeAttempt: number;
96
+ /**
97
+ * LangGraph step counter for this node execution within the graph
98
+ * run. Read from `config.metadata.langgraph_step` (the canonical
99
+ * 1.3.x source) — R1 Research Finding 2 (S1235) corrected the
100
+ * source: it is metadata, NOT `executionInfo`.
101
+ */
102
+ langGraphStep?: number;
103
+ /**
104
+ * V0.4 (R1 Research Finding 2, S1235) — first-attempt timestamp as
105
+ * ISO 8601 string when LangGraph surfaces it. Useful to compute
106
+ * retry-attempt latency in fallback paths. Read from
107
+ * `config.runtime.executionInfo.nodeFirstAttemptTime` per
108
+ * LangGraph PR #7363 — value may be `null` on Platform-managed
109
+ * graphs (PR #7406 workaround).
110
+ */
111
+ nodeFirstAttemptTime?: string;
112
+ /** LangGraph thread id (from `config.configurable.thread_id`). */
113
+ threadId?: string;
114
+ /** Raw runtime info object — passed through for power-users. */
115
+ raw: Record<string, unknown> | undefined;
116
+ }
80
117
  /**
81
118
  * Options accepted by {@link createDarwinNode}.
82
119
  *
@@ -115,6 +152,24 @@ export interface CreateDarwinNodeOptions {
115
152
  * break the LangGraph node.
116
153
  */
117
154
  onResult?: (result: RunResult) => void | Promise<void>;
155
+ /**
156
+ * V0.4 — Fired before `runAgent` with the runtime info LangGraph
157
+ * surfaces via `config.runtime.executionInfo`. Use this to:
158
+ * - Log retry behaviour (`nodeAttempt > 1` means LangGraph's
159
+ * retryPolicy decided to retry).
160
+ * - Switch to a cheaper / faster fallback model on retries
161
+ * (mutate `runOptions` via closure capture).
162
+ * - Forward step / thread context to upstream tracing systems.
163
+ *
164
+ * Pairs naturally with LangGraph's `addNode(name, fn, { retryPolicy })`
165
+ * — the adapter does NOT add its own retry layer (would conflict).
166
+ *
167
+ * **Errors are swallowed** with a one-shot warn per node, same contract
168
+ * as `onResult`.
169
+ *
170
+ * NEW V0.4 (S1235).
171
+ */
172
+ onAttempt?: (info: DarwinNodeAttemptInfo) => void | Promise<void>;
118
173
  }
119
174
  /**
120
175
  * Type alias for the function returned by {@link createDarwinNode}.
@@ -1 +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"}
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;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC1C;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;IACvD;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;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,CAqJd"}
@@ -68,11 +68,13 @@ export function createDarwinNode(agent, opts = {}) {
68
68
  const captureTrace = opts.captureTrace !== false;
69
69
  const agentName = agent.name;
70
70
  const onResult = opts.onResult;
71
+ const onAttempt = opts.onAttempt;
71
72
  const runOptions = opts.runOptions ?? {};
72
73
  // Track whether we already warned about a swallowed callback so the
73
74
  // log stays at most one line per node, not one per invocation.
74
75
  let onResultWarned = false;
75
- return async function darwinNode(state) {
76
+ let onAttemptWarned = false;
77
+ return async function darwinNode(state, config) {
76
78
  if (state === null || typeof state !== "object") {
77
79
  throw new DarwinNodeError(`createDarwinNode(${agentName}): state must be an object, got ${typeof state}.`, agentName);
78
80
  }
@@ -81,6 +83,59 @@ export function createDarwinNode(agent, opts = {}) {
81
83
  throw new DarwinNodeError(`createDarwinNode(${agentName}): state["${taskKey}"] must be a non-empty string, ` +
82
84
  `got ${rawTask === undefined ? "undefined" : typeof rawTask}.`, agentName);
83
85
  }
86
+ // V0.4 (S1235): surface LangGraph runtime info to the optional
87
+ // onAttempt callback. The shape of `config.runtime.executionInfo` is
88
+ // defined in @langchain/langgraph 1.3+ via PR #7363 (2026-03-31).
89
+ //
90
+ // R1 Research Finding 2 fix (S1235): `langGraphStep` does NOT live
91
+ // on `executionInfo` — it is in `config.metadata.langgraph_step`.
92
+ // `executionInfo` carries `nodeAttempt` and `nodeFirstAttemptTime`
93
+ // among other identifiers. We read both defensively so older
94
+ // LangGraph versions don't crash this node.
95
+ if (onAttempt && config && typeof config === "object") {
96
+ const c = config;
97
+ const runtime = c.runtime;
98
+ const executionInfo = runtime?.executionInfo;
99
+ const metadata = c.metadata;
100
+ const configurable = c.configurable;
101
+ const nodeAttempt = typeof executionInfo?.nodeAttempt === "number" &&
102
+ Number.isFinite(executionInfo.nodeAttempt) &&
103
+ executionInfo.nodeAttempt >= 1
104
+ ? executionInfo.nodeAttempt
105
+ : 1;
106
+ // R1 Research Finding 2: langgraph_step lives in metadata.
107
+ const rawStep = metadata?.["langgraph_step"];
108
+ const langGraphStep = typeof rawStep === "number" && Number.isFinite(rawStep)
109
+ ? rawStep
110
+ : undefined;
111
+ // R1 Research Finding 2: nodeFirstAttemptTime from executionInfo.
112
+ const rawFirstAttempt = executionInfo?.nodeFirstAttemptTime;
113
+ const nodeFirstAttemptTime = typeof rawFirstAttempt === "string" && rawFirstAttempt.length > 0
114
+ ? rawFirstAttempt
115
+ : undefined;
116
+ const threadId = typeof configurable?.thread_id === "string"
117
+ ? configurable.thread_id
118
+ : undefined;
119
+ try {
120
+ await onAttempt({
121
+ nodeAttempt,
122
+ ...(langGraphStep !== undefined ? { langGraphStep } : {}),
123
+ ...(nodeFirstAttemptTime !== undefined
124
+ ? { nodeFirstAttemptTime }
125
+ : {}),
126
+ ...(threadId !== undefined ? { threadId } : {}),
127
+ raw: runtime,
128
+ });
129
+ }
130
+ catch (err) {
131
+ if (!onAttemptWarned) {
132
+ onAttemptWarned = true;
133
+ console.warn(`[darwin-langgraph] onAttempt callback for "${agentName}" threw — ` +
134
+ `swallowed. Subsequent throws will be silent. Original error: ` +
135
+ `${err?.message ?? String(err)}`);
136
+ }
137
+ }
138
+ }
84
139
  let result;
85
140
  try {
86
141
  result = await runAgent(agent, rawTask, runOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"create-darwin-node.js","sourceRoot":"","sources":["../src/create-darwin-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-darwin-node.js","sourceRoot":"","sources":["../src/create-darwin-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Surface 9 (V0.4) — `darwinAccumulatingAnnotation(extra?)`.
3
+ *
4
+ * Variant of {@link darwinAnnotation} that REPLACES the singleton
5
+ * `darwinTrajectory: ExecutionTrace | undefined` channel with an
6
+ * accumulating `darwinTrajectories: ExecutionTrace[]` channel — every
7
+ * node write appends, the channel never overwrites.
8
+ *
9
+ * Use this when you orchestrate multiple Darwin nodes in a single graph
10
+ * (fan-out, sequential pipeline, supervisor pattern) and want ALL
11
+ * trajectories preserved in graph state for end-of-run analysis without
12
+ * having to declare a separate `*Trace` channel per node manually.
13
+ *
14
+ * The matching `trajectoryKey` you pass to each `createDarwinNode(...)`
15
+ * call is `"darwinTrajectories"`. The reducer accepts EITHER a single
16
+ * `ExecutionTrace` (matching the bare {@link createDarwinNode} contract)
17
+ * OR an `ExecutionTrace[]` (lets advanced users batch-append from a
18
+ * worker). Both paths flatten into the same accumulator array.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import {
23
+ * createDarwinNode,
24
+ * darwinAccumulatingAnnotation,
25
+ * } from "darwin-langgraph";
26
+ * import { StateGraph } from "@langchain/langgraph";
27
+ *
28
+ * const State = darwinAccumulatingAnnotation();
29
+ *
30
+ * const graph = new StateGraph(State)
31
+ * .addNode("research", createDarwinNode(researcher, {
32
+ * trajectoryKey: "darwinTrajectories",
33
+ * }))
34
+ * .addNode("critique", createDarwinNode(critic, {
35
+ * trajectoryKey: "darwinTrajectories",
36
+ * taskKey: "output",
37
+ * }))
38
+ * .addEdge("__start__", "research")
39
+ * .addEdge("research", "critique")
40
+ * .compile();
41
+ *
42
+ * const result = await graph.invoke({ task: "What is GEPA?" });
43
+ * console.log(`captured ${result.darwinTrajectories.length} trajectories`);
44
+ * // → captured 2 trajectories
45
+ * ```
46
+ *
47
+ * NEW V0.4 (S1235).
48
+ */
49
+ import type { ExecutionTrace } from "darwin-agents";
50
+ /**
51
+ * Tolerant accumulator reducer — accepts either a single
52
+ * `ExecutionTrace` (the shape `createDarwinNode` actually emits) or an
53
+ * `ExecutionTrace[]` (lets advanced users batch-append from a worker
54
+ * graph). Both paths flatten into the previous array.
55
+ *
56
+ * Pure, exported for testability and so advanced users can hand-roll
57
+ * their own `Annotation.Root` with the same semantics.
58
+ */
59
+ export declare function darwinTrajectoryAccumulatorReducer(prev: ExecutionTrace[] | undefined, next: ExecutionTrace | ExecutionTrace[] | undefined): ExecutionTrace[];
60
+ /**
61
+ * Channel spec for the accumulating trajectory variant — re-exported for
62
+ * power-users who want to spread it into their own `Annotation.Root`
63
+ * call manually. Mirrors the {@link getDarwinChannelSpec} pattern.
64
+ *
65
+ * NEW V0.4 (S1235).
66
+ */
67
+ export declare function getDarwinAccumulatingChannelSpec(): {
68
+ task: import("@langchain/langgraph").LastValue<string>;
69
+ output: import("@langchain/langgraph").LastValue<string>;
70
+ darwinTrajectories: import("@langchain/langgraph").BaseChannel<ExecutionTrace[], ExecutionTrace[] | import("@langchain/langgraph").OverwriteValue<ExecutionTrace[]>, unknown>;
71
+ };
72
+ /**
73
+ * Build an `Annotation.Root` with `task` + `output` + accumulating
74
+ * `darwinTrajectories: ExecutionTrace[]` plus any extra channels.
75
+ */
76
+ export declare function darwinAccumulatingAnnotation<Extra extends Record<string, any> = {}>(extra?: Extra): import("@langchain/langgraph").AnnotationRoot<{
77
+ task: import("@langchain/langgraph").LastValue<string>;
78
+ output: import("@langchain/langgraph").LastValue<string>;
79
+ darwinTrajectories: import("@langchain/langgraph").BaseChannel<ExecutionTrace[], ExecutionTrace[] | import("@langchain/langgraph").OverwriteValue<ExecutionTrace[]>, unknown>;
80
+ } & Extra>;
81
+ //# sourceMappingURL=darwin-accumulating-annotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-accumulating-annotation.d.ts","sourceRoot":"","sources":["../src/darwin-accumulating-annotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD;;;;;;;;GAQG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,cAAc,EAAE,GAAG,SAAS,EAClC,IAAI,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,SAAS,GAClD,cAAc,EAAE,CAoBlB;AAeD;;;;;;GAMG;AACH,wBAAgB,gCAAgC;;;;EAe/C;AAED;;;GAGG;AAEH,wBAAgB,4BAA4B,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,EACjF,KAAK,CAAC,EAAE,KAAK;;;;WAsBd"}