darwin-langgraph 0.2.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.
- package/CHANGELOG.md +348 -0
- package/README.md +108 -3
- package/dist/create-darwin-node.d.ts +55 -0
- package/dist/create-darwin-node.d.ts.map +1 -1
- package/dist/create-darwin-node.js +56 -1
- package/dist/create-darwin-node.js.map +1 -1
- package/dist/darwin-accumulating-annotation.d.ts +81 -0
- package/dist/darwin-accumulating-annotation.d.ts.map +1 -0
- package/dist/darwin-accumulating-annotation.js +144 -0
- package/dist/darwin-accumulating-annotation.js.map +1 -0
- package/dist/darwin-callback-handler.d.ts +161 -2
- package/dist/darwin-callback-handler.d.ts.map +1 -1
- package/dist/darwin-callback-handler.js +417 -25
- package/dist/darwin-callback-handler.js.map +1 -1
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/to-otel-attributes.d.ts +49 -0
- package/dist/to-otel-attributes.d.ts.map +1 -1
- package/dist/to-otel-attributes.js +38 -2
- package/dist/to-otel-attributes.js.map +1 -1
- package/dist/to-w3c-trace-context.d.ts +81 -0
- package/dist/to-w3c-trace-context.d.ts.map +1 -0
- package/dist/to-w3c-trace-context.js +134 -0
- package/dist/to-w3c-trace-context.js.map +1 -0
- package/dist/token-budget.d.ts +141 -0
- package/dist/token-budget.d.ts.map +1 -0
- package/dist/token-budget.js +225 -0
- package/dist/token-budget.js.map +1 -0
- package/dist/with-darwin-evolution.d.ts +40 -0
- package/dist/with-darwin-evolution.d.ts.map +1 -1
- package/dist/with-darwin-evolution.js +55 -1
- package/dist/with-darwin-evolution.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,354 @@
|
|
|
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
|
+
|
|
249
|
+
## [0.3.0-alpha.1] — 2026-05-25
|
|
250
|
+
|
|
251
|
+
V0.3 closes the three deferred items from V0.2's R2 review (parent-run
|
|
252
|
+
propagation, double-wrap detection, hung-invoke guard) and lifts the
|
|
253
|
+
repository to the StudioMeyer open-source-standard documentation layout
|
|
254
|
+
(CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, ECOSYSTEM, issue + PR
|
|
255
|
+
templates, GitHub Actions CI matrix on Node 20 + 22).
|
|
256
|
+
|
|
257
|
+
### Added — three new behaviours + one new option
|
|
258
|
+
|
|
259
|
+
- **`DarwinTrajectoryEvent.runId` + `.parentRunId`** — propagated by
|
|
260
|
+
`DarwinCallbackHandler` from the LangChain callback contract. Lets
|
|
261
|
+
downstream consumers (OTEL exporters, Langfuse, LangSmith, custom
|
|
262
|
+
span-tree loggers) rebuild the chain hierarchy from the event payload
|
|
263
|
+
alone without a separate runId-tracking side-channel. `runId` is
|
|
264
|
+
always present on V0.2+ handler events; `parentRunId` is present
|
|
265
|
+
only when the chain has a parent (omitted for top-level invokes).
|
|
266
|
+
- **`withDarwinEvolution` double-wrap warning** — a `Symbol.for(...)`
|
|
267
|
+
sentinel is stamped on each wrapped graph. A second wrap of the same
|
|
268
|
+
graph instance now emits a one-shot `console.warn` flagging the
|
|
269
|
+
duplicate-hook footgun. The wrap still succeeds (some users legitimately
|
|
270
|
+
layer multiple `nodeMap` slices), but the silent-double-fire case
|
|
271
|
+
is now visible in logs.
|
|
272
|
+
- **`DarwinCallbackHandler` hung-invoke guard** — new option
|
|
273
|
+
`maxInFlightRuns?: number` on `DarwinCallbackHandlerOptions`. Caps the
|
|
274
|
+
internal `runId → InFlightRun` map. When the cap is exceeded the
|
|
275
|
+
oldest entry is evicted (LRU via Map insertion order) and a
|
|
276
|
+
one-shot warning fires. Defaults to 1024 — small enough to surface
|
|
277
|
+
real leaks within minutes, large enough for typical fan-out. Set to
|
|
278
|
+
`Infinity` to opt out.
|
|
279
|
+
|
|
280
|
+
### Changed
|
|
281
|
+
|
|
282
|
+
- **`DarwinCallbackHandlerOptions` type exported** alongside
|
|
283
|
+
`DarwinCallbackHandler`. Was internal in V0.2; now a public type so
|
|
284
|
+
consumers can build wrapper handlers without re-declaring the shape.
|
|
285
|
+
- **`InFlightRun` shape** — internal change in `DarwinCallbackHandler`:
|
|
286
|
+
the `runIdToName` map now stores `{ nodeName, parentRunId }` rather
|
|
287
|
+
than just the name string, to carry parentRunId through to
|
|
288
|
+
`handleChainEnd`. Non-breaking — only the internal field type changed.
|
|
289
|
+
- **VERSION constant bumped** to `0.3.0-alpha.1` in both `package.json`
|
|
290
|
+
and `src/index.ts` (verified by `prepublishOnly` script).
|
|
291
|
+
|
|
292
|
+
### Added — open-source documentation standard
|
|
293
|
+
|
|
294
|
+
The repo now matches the
|
|
295
|
+
[`temporal-memory-workflows`](https://github.com/studiomeyer-io/temporal-memory-workflows)
|
|
296
|
+
OS-standard layout. New top-level files:
|
|
297
|
+
|
|
298
|
+
- **`CONTRIBUTING.md`** — folder layout, code-review expectations, PR
|
|
299
|
+
format, Conventional Commits convention, deprecation contract on
|
|
300
|
+
`withDarwinEvolution`, adapter-vs-upstream-bugs separation.
|
|
301
|
+
- **`CODE_OF_CONDUCT.md`** — adapted from Contributor Covenant 2.1.
|
|
302
|
+
- **`SECURITY.md`** — disclosure policy, supported versions
|
|
303
|
+
(`0.3.x` + `0.2.x` security-only), supply-chain stance (no
|
|
304
|
+
postinstall scripts), defense-in-depth layer breakdown.
|
|
305
|
+
- **`ECOSYSTEM.md`** — where the adapter sits in the StudioMeyer
|
|
306
|
+
toolkit, pairing notes with `darwin-agents` /
|
|
307
|
+
`@langchain/langgraph` / `temporal-memory-workflows`, when-to-use-what
|
|
308
|
+
decision table, sibling-repo links.
|
|
309
|
+
- **`.github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml`**
|
|
310
|
+
— surface-aware bug template, problem-first feature template, contact
|
|
311
|
+
links routing to upstream where appropriate.
|
|
312
|
+
- **`.github/PULL_REQUEST_TEMPLATE.md`** — surface checklist,
|
|
313
|
+
zero-hard-dep check, deprecation-contract check, R1/R2 code-review
|
|
314
|
+
trail field for maintainers.
|
|
315
|
+
- **`.github/workflows/ci.yml`** — Node 20 + 22 matrix, runs
|
|
316
|
+
`npm ci` → `verify-version-sync` → `typecheck` → `examples:check` →
|
|
317
|
+
`test` → `build` on every push to `main` and every PR.
|
|
318
|
+
|
|
319
|
+
### Test coverage
|
|
320
|
+
|
|
321
|
+
- **132/132 vitest tests green** (was 116 in V0.2, **+16 V0.3 tests**).
|
|
322
|
+
- New test file: `tests/v03-features.test.ts` (16 tests across 4 groups:
|
|
323
|
+
parent-run propagation, double-wrap warning, hung-invoke timeout
|
|
324
|
+
guard, `vi.resetModules()` pattern for module-level flag tests).
|
|
325
|
+
- tsc strict + examples typecheck + version-sync + build all clean.
|
|
326
|
+
- No regressions: all V0.1 + V0.2 surface tests + R1 + R2 fixes still
|
|
327
|
+
green.
|
|
328
|
+
|
|
329
|
+
### Migration notes
|
|
330
|
+
|
|
331
|
+
- **From V0.2.x → V0.3.x:** No code changes required. The
|
|
332
|
+
`runId`/`parentRunId` fields on `DarwinTrajectoryEvent` are optional
|
|
333
|
+
additions; existing callbacks ignore them. The double-wrap warning
|
|
334
|
+
only fires if you actually double-wrap (most users do not). The
|
|
335
|
+
default `maxInFlightRuns: 1024` cap is invisible in normal use.
|
|
336
|
+
- **From V0.1.x → V0.3.x:** Still recommended to migrate from
|
|
337
|
+
`withDarwinEvolution` to `DarwinCallbackHandler` — see V0.2
|
|
338
|
+
migration notes in this changelog.
|
|
339
|
+
|
|
340
|
+
### V0.4 Roadmap (deferred)
|
|
341
|
+
|
|
342
|
+
- **`reflectionRunPrompt` override on `darwin-agents` (paper-fidelity).**
|
|
343
|
+
The GEPA paper uses a stronger reflection LM than the task LM. Currently
|
|
344
|
+
the adapter inherits `darwin-agents@0.5.0-alpha.2`'s single-`runPrompt`
|
|
345
|
+
implementation. Defer to a paired bump.
|
|
346
|
+
- **OTEL exporter binding helper** — turn the pure `toOtelAttributes`
|
|
347
|
+
mapping into a one-liner that registers a span per trajectory with
|
|
348
|
+
a configured tracer.
|
|
349
|
+
- **Langfuse handler subclass** — `DarwinLangfuseHandler` that extends
|
|
350
|
+
`DarwinCallbackHandler` and emits Langfuse traces directly.
|
|
351
|
+
- **LangSmith trace correlation** — propagate `runId`/`parentRunId`
|
|
352
|
+
into a LangSmith-compatible attribute set.
|
|
353
|
+
|
|
6
354
|
## [0.2.0-alpha.1] — 2026-05-25
|
|
7
355
|
|
|
8
356
|
### Added — three new surfaces (V0.1 roadmap → LIVE)
|
package/README.md
CHANGED
|
@@ -72,7 +72,24 @@ console.log(result.output);
|
|
|
72
72
|
console.log("trajectory:", result.darwinTrajectory);
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
##
|
|
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
|
|
|
@@ -202,7 +219,8 @@ The [`examples/`](./examples/) directory ships three runnable scripts:
|
|
|
202
219
|
|
|
203
220
|
| `darwin-langgraph` | `darwin-agents` | `@langchain/langgraph` | Status |
|
|
204
221
|
|---|---|---|---|
|
|
205
|
-
| `0.
|
|
222
|
+
| `0.3.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | alpha (this release) |
|
|
223
|
+
| `0.2.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | superseded |
|
|
206
224
|
| `0.1.0-alpha.x` | `^0.5.0-alpha.1` | `^1.3.0` | superseded |
|
|
207
225
|
|
|
208
226
|
The peer-dep range `darwin-agents: "^0.5.0-alpha.1"` follows npm's
|
|
@@ -210,7 +228,83 @@ prerelease semver rules — `0.5.0-alpha.N` and `0.5.0` final satisfy it,
|
|
|
210
228
|
but `0.5.1-alpha.0` does NOT. A patch release of this adapter will be
|
|
211
229
|
required when `darwin-agents` bumps past `0.5.x`.
|
|
212
230
|
|
|
213
|
-
## V0.
|
|
231
|
+
## V0.3 — observability + safety (LIVE this release)
|
|
232
|
+
|
|
233
|
+
V0.3 closes the three deferred items from V0.2's R2 review. Backwards
|
|
234
|
+
compatible — no consumer code changes required.
|
|
235
|
+
|
|
236
|
+
### Parent-run propagation on `DarwinTrajectoryEvent`
|
|
237
|
+
|
|
238
|
+
`DarwinCallbackHandler` now populates two new fields on every emitted
|
|
239
|
+
event:
|
|
240
|
+
|
|
241
|
+
- **`runId: string`** — the LangChain runId of the node-chain that
|
|
242
|
+
produced the trajectory. Stable identifier suitable for correlation
|
|
243
|
+
with OTEL spans, Langfuse traces, LangSmith runs.
|
|
244
|
+
- **`parentRunId?: string`** — the runId of the chain that invoked
|
|
245
|
+
this node-chain. Omitted for top-level invokes. Use it to build the
|
|
246
|
+
full span hierarchy in OTEL exporters.
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
const handler = new DarwinCallbackHandler({
|
|
250
|
+
nodeMap: { research: "researcher" },
|
|
251
|
+
onTrajectory: (event) => {
|
|
252
|
+
const attrs = toOtelAttributes(event.trajectory);
|
|
253
|
+
const span = tracer.startSpan(event.nodeName, {
|
|
254
|
+
attributes: { ...attrs, "darwin.run.id": event.runId },
|
|
255
|
+
});
|
|
256
|
+
// event.parentRunId can be used as the parent context for span linking
|
|
257
|
+
span.end();
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`withDarwinEvolution` legacy events do NOT carry the runId fields (no
|
|
263
|
+
runId exists in the monkey-patch path). Migrate to
|
|
264
|
+
`DarwinCallbackHandler` if you need them.
|
|
265
|
+
|
|
266
|
+
### Double-wrap warning on `withDarwinEvolution`
|
|
267
|
+
|
|
268
|
+
A `Symbol.for("darwin-langgraph.evolution.wrapped")` sentinel is now
|
|
269
|
+
stamped on each wrapped graph. A second `withDarwinEvolution(graph, …)`
|
|
270
|
+
call on the same graph instance emits a one-shot `console.warn`:
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
[darwin-langgraph] withDarwinEvolution(): graph appears to be wrapped twice
|
|
274
|
+
— both hooks will fire per run, producing duplicate trajectories.
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Some users legitimately layer multiple `nodeMap` slices on one graph,
|
|
278
|
+
so the wrap still succeeds — but the silent-double-fire footgun is now
|
|
279
|
+
visible in logs. To layer cleanly, prefer multiple
|
|
280
|
+
`DarwinCallbackHandler` instances via `callbacks: [h1, h2]`.
|
|
281
|
+
|
|
282
|
+
### Hung-invoke guard on `DarwinCallbackHandler`
|
|
283
|
+
|
|
284
|
+
New option `maxInFlightRuns?: number` on
|
|
285
|
+
`DarwinCallbackHandlerOptions`. Caps the internal `runId → InFlightRun`
|
|
286
|
+
map at the configured size. When the cap is exceeded, the oldest
|
|
287
|
+
entry is evicted (Map insertion order) and a one-shot warning fires.
|
|
288
|
+
Defaults to **1024** — large enough for typical fan-out, small enough
|
|
289
|
+
to surface a real leak within minutes of an incident.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
const handler = new DarwinCallbackHandler({
|
|
293
|
+
nodeMap: { research: "researcher" },
|
|
294
|
+
onTrajectory: (event) => { /* ... */ },
|
|
295
|
+
maxInFlightRuns: 500, // tighter for memory-constrained workers
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Set `maxInFlightRuns: Infinity` to opt out (discouraged in production).
|
|
300
|
+
|
|
301
|
+
This defends against the failure mode where `handleChainEnd` /
|
|
302
|
+
`handleChainError` never fires (LangGraph internal bug, OS-level kill
|
|
303
|
+
of the worker mid-invoke, parent invoke aborted mid-flight). Without
|
|
304
|
+
the cap, the map grows without bound and leaks memory in long-running
|
|
305
|
+
processes (server singletons, schedulers, Temporal Workers).
|
|
306
|
+
|
|
307
|
+
### V0.2 — new surfaces (still LIVE)
|
|
214
308
|
|
|
215
309
|
V0.2 ships the three items from the V0.1 V0.2-roadmap, plus runtime
|
|
216
310
|
deprecation warnings on the legacy wrapper:
|
|
@@ -256,6 +350,17 @@ Two lines:
|
|
|
256
350
|
`DarwinTrajectoryEvent` shape passed to `onTrajectory` are 100% identical
|
|
257
351
|
between both APIs — no other code changes required.
|
|
258
352
|
|
|
353
|
+
## Migration from v0.2.x to v0.3.x
|
|
354
|
+
|
|
355
|
+
**No code changes required.** V0.3 is purely additive:
|
|
356
|
+
|
|
357
|
+
- `event.runId` and `event.parentRunId` are new optional fields — existing
|
|
358
|
+
callbacks that don't read them keep working untouched.
|
|
359
|
+
- The double-wrap warning only fires if you actually double-wrap (most
|
|
360
|
+
users do not).
|
|
361
|
+
- The default `maxInFlightRuns: 1024` is invisible in normal use. Override
|
|
362
|
+
only if you have memory pressure or want to opt out via `Infinity`.
|
|
363
|
+
|
|
259
364
|
The adapter releases follow `darwin-agents` major bumps. When
|
|
260
365
|
`@langchain/langgraph` 2.x lands, the adapter ships a new major within
|
|
261
366
|
the same minor of the underlying Darwin release.
|
|
@@ -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;
|
|
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
|
-
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"create-darwin-node.js","sourceRoot":"","sources":["../src/create-darwin-node.ts"],"names":[],"mappings":"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"}
|