@langchain/langgraph-sdk 1.12.3 → 1.12.5

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 (77) hide show
  1. package/dist/client/stream/handles/subagents.cjs +9 -2
  2. package/dist/client/stream/handles/subagents.cjs.map +1 -1
  3. package/dist/client/stream/handles/subagents.d.cts.map +1 -1
  4. package/dist/client/stream/handles/subagents.d.ts.map +1 -1
  5. package/dist/client/stream/handles/subagents.js +10 -3
  6. package/dist/client/stream/handles/subagents.js.map +1 -1
  7. package/dist/client/stream/handles/subgraphs.cjs +24 -2
  8. package/dist/client/stream/handles/subgraphs.cjs.map +1 -1
  9. package/dist/client/stream/handles/subgraphs.d.cts.map +1 -1
  10. package/dist/client/stream/handles/subgraphs.d.ts.map +1 -1
  11. package/dist/client/stream/handles/subgraphs.js +24 -3
  12. package/dist/client/stream/handles/subgraphs.js.map +1 -1
  13. package/dist/client/stream/index.cjs +17 -7
  14. package/dist/client/stream/index.cjs.map +1 -1
  15. package/dist/client/stream/index.d.cts.map +1 -1
  16. package/dist/client/stream/index.d.ts.map +1 -1
  17. package/dist/client/stream/index.js +17 -7
  18. package/dist/client/stream/index.js.map +1 -1
  19. package/dist/client/stream/messages.cjs +43 -0
  20. package/dist/client/stream/messages.cjs.map +1 -1
  21. package/dist/client/stream/messages.d.cts +8 -0
  22. package/dist/client/stream/messages.d.cts.map +1 -1
  23. package/dist/client/stream/messages.d.ts +8 -0
  24. package/dist/client/stream/messages.d.ts.map +1 -1
  25. package/dist/client/stream/messages.js +43 -0
  26. package/dist/client/stream/messages.js.map +1 -1
  27. package/dist/client/stream/transport/http.cjs +1 -12
  28. package/dist/client/stream/transport/http.cjs.map +1 -1
  29. package/dist/client/stream/transport/http.d.cts.map +1 -1
  30. package/dist/client/stream/transport/http.d.ts.map +1 -1
  31. package/dist/client/stream/transport/http.js +1 -12
  32. package/dist/client/stream/transport/http.js.map +1 -1
  33. package/dist/client/stream/transport/utils.cjs +12 -0
  34. package/dist/client/stream/transport/utils.cjs.map +1 -1
  35. package/dist/client/stream/transport/utils.js +12 -1
  36. package/dist/client/stream/transport/utils.js.map +1 -1
  37. package/dist/client/stream/transport/websocket.cjs +33 -3
  38. package/dist/client/stream/transport/websocket.cjs.map +1 -1
  39. package/dist/client/stream/transport/websocket.d.cts +4 -1
  40. package/dist/client/stream/transport/websocket.d.cts.map +1 -1
  41. package/dist/client/stream/transport/websocket.d.ts +4 -1
  42. package/dist/client/stream/transport/websocket.d.ts.map +1 -1
  43. package/dist/client/stream/transport/websocket.js +34 -4
  44. package/dist/client/stream/transport/websocket.js.map +1 -1
  45. package/dist/stream/controller.cjs +94 -3
  46. package/dist/stream/controller.cjs.map +1 -1
  47. package/dist/stream/controller.d.cts.map +1 -1
  48. package/dist/stream/controller.d.ts.map +1 -1
  49. package/dist/stream/controller.js +94 -3
  50. package/dist/stream/controller.js.map +1 -1
  51. package/dist/stream/discovery/namespace-from-history.cjs +1 -1
  52. package/dist/stream/discovery/namespace-from-history.cjs.map +1 -1
  53. package/dist/stream/discovery/namespace-from-history.js +1 -1
  54. package/dist/stream/discovery/namespace-from-history.js.map +1 -1
  55. package/dist/stream/lifecycle-loading-tracker.cjs +5 -0
  56. package/dist/stream/lifecycle-loading-tracker.cjs.map +1 -1
  57. package/dist/stream/lifecycle-loading-tracker.js +5 -0
  58. package/dist/stream/lifecycle-loading-tracker.js.map +1 -1
  59. package/dist/stream/projections/messages.cjs +45 -12
  60. package/dist/stream/projections/messages.cjs.map +1 -1
  61. package/dist/stream/projections/messages.js +45 -12
  62. package/dist/stream/projections/messages.js.map +1 -1
  63. package/dist/stream/root-message-projection.cjs +71 -8
  64. package/dist/stream/root-message-projection.cjs.map +1 -1
  65. package/dist/stream/root-message-projection.js +71 -8
  66. package/dist/stream/root-message-projection.js.map +1 -1
  67. package/dist/stream/submit-coordinator.cjs +7 -2
  68. package/dist/stream/submit-coordinator.cjs.map +1 -1
  69. package/dist/stream/submit-coordinator.js +7 -2
  70. package/dist/stream/submit-coordinator.js.map +1 -1
  71. package/dist/ui/manager.cjs +1 -1
  72. package/dist/ui/manager.cjs.map +1 -1
  73. package/dist/ui/manager.d.cts.map +1 -1
  74. package/dist/ui/manager.d.ts.map +1 -1
  75. package/dist/ui/manager.js +1 -1
  76. package/dist/ui/manager.js.map +1 -1
  77. package/package.json +1 -1
@@ -172,6 +172,14 @@ var StreamController = class {
172
172
  */
173
173
  #hydratedActiveInterruptIds = null;
174
174
  /**
175
+ * Creation time of the checkpoint the latest {@link hydrate} seeded
176
+ * from. A new stream subscription replays the thread's retained
177
+ * history, and events produced before this moment are already part of
178
+ * the seed: applying them again rewinds `messages`, `values` and
179
+ * `toolCalls` to older turns and then rebuilds them.
180
+ */
181
+ #hydratedCheckpointTime;
182
+ /**
175
183
  * Highest event sequence already applied when the latest run command
176
184
  * was accepted. Interrupts outside the hydrate-time allowlist remain
177
185
  * filtered through this sequence, while newer events are live output
@@ -243,6 +251,16 @@ var StreamController = class {
243
251
  #rootEventListeners = /* @__PURE__ */ new Set();
244
252
  #rootBus;
245
253
  #activeRunId;
254
+ /**
255
+ * Run id `run.start` returned for the in-flight local `submit()`. Kept
256
+ * apart from {@link #activeRunId}, which a rolled-back submit's late
257
+ * response can still overwrite.
258
+ */
259
+ #submittedRunId;
260
+ /** `true` from a local run's dispatch until its `run.start` answers. */
261
+ #submittedRunIdPending = false;
262
+ /** One per armed terminal wait: re-runs the lifecycle events it held until `run.start` answered. */
263
+ #heldLifecycleReleases = /* @__PURE__ */ new Set();
246
264
  #localRunDepth = 0;
247
265
  /**
248
266
  * `true` once a root `values` event has been applied for the current
@@ -302,7 +320,8 @@ var StreamController = class {
302
320
  this.#lifecycleLoading = new require_lifecycle_loading_tracker.LifecycleLoadingTracker({
303
321
  store: this.rootStore,
304
322
  isDisposed: () => this.#disposed,
305
- onSettled: () => this.#submitter.scheduleQueueDrainOnObservedIdle()
323
+ onSettled: () => this.#submitter.scheduleQueueDrainOnObservedIdle(),
324
+ ignore: (event) => this.#submittedRunMatch(event) != null
306
325
  });
307
326
  this.messageMetadataStore = this.#messageMetadata.store;
308
327
  this.queueStore = new require_store.StreamStore(require_queue_adapter.EMPTY_QUEUE);
@@ -337,6 +356,11 @@ var StreamController = class {
337
356
  this.#pendingHydrationInterruptEvents = [];
338
357
  },
339
358
  onRunStart: () => this.#markLocalRunStart(),
359
+ onRunStartReturned: (runId) => {
360
+ this.#submittedRunId = runId;
361
+ this.#submittedRunIdPending = false;
362
+ for (const release of [...this.#heldLifecycleReleases]) release();
363
+ },
340
364
  onRunCreated: (runId) => {
341
365
  this.#advanceInterruptReplayBarrier();
342
366
  this.#notifyCreated(runId);
@@ -496,6 +520,8 @@ var StreamController = class {
496
520
  if (this.#disposed || this.#currentThreadId !== hydratedThreadId) return;
497
521
  threadExists = state != null;
498
522
  threadActive = isThreadStateActive(state);
523
+ const checkpointTime = Date.parse(state?.created_at ?? "");
524
+ this.#hydratedCheckpointTime = Number.isNaN(checkpointTime) ? void 0 : checkpointTime;
499
525
  this.#missingThreadIds.delete(hydratedThreadId);
500
526
  if (state?.values != null) {
501
527
  /**
@@ -534,6 +560,11 @@ var StreamController = class {
534
560
  const seedMessages = state.values[this.#messagesKey];
535
561
  if (Array.isArray(seedMessages)) {
536
562
  this.#subagents.seedFromCheckpointMessages(seedMessages);
563
+ const finishedToolCalls = require_tool_calls.seedToolCallsFromMessages(ROOT_NAMESPACE, require_message_coercion.ensureMessageInstances(seedMessages)).filter((toolCall) => toolCall.status === "finished");
564
+ if (finishedToolCalls.length > 0) this.rootStore.setState((s) => ({
565
+ ...s,
566
+ toolCalls: finishedToolCalls.reduce((toolCalls, toolCall) => require_tool_calls.upsertToolCall(toolCalls, toolCall), s.toolCalls)
567
+ }));
537
568
  /**
538
569
  * An idle (finished) thread defers its root SSE pump; the first
539
570
  * `submit()` brings it up and the transport replays the finished
@@ -561,7 +592,7 @@ var StreamController = class {
561
592
  */
562
593
  const unpersisted = this.#messageMetadata.unpersistedOptimisticIds();
563
594
  if (unpersisted.size > 0) {
564
- this.#rootMessages.dropOptimisticMessages(unpersisted);
595
+ this.#rootMessages.dropMessages(unpersisted);
565
596
  this.#messageMetadata.forget(unpersisted);
566
597
  }
567
598
  /**
@@ -913,6 +944,13 @@ var StreamController = class {
913
944
  if (options?.cancel ?? true) {
914
945
  const threadId = this.#currentThreadId;
915
946
  const runId = this.#activeRunId;
947
+ if (runId != null && this.rootStore.getSnapshot().isLoading) {
948
+ const dropped = this.#rootMessages.closeRun({
949
+ sync: true,
950
+ unfinishedOnly: true
951
+ });
952
+ if (dropped.size > 0) this.#messageMetadata.forget(dropped);
953
+ }
916
954
  if (threadId != null && runId != null) try {
917
955
  await this.#options.client.runs.cancel(threadId, runId);
918
956
  } catch {}
@@ -928,9 +966,12 @@ var StreamController = class {
928
966
  }
929
967
  #markLocalRunStart() {
930
968
  this.#localRunDepth += 1;
969
+ this.#submittedRunId = void 0;
970
+ this.#submittedRunIdPending = true;
931
971
  }
932
972
  #markLocalRunEnd() {
933
973
  this.#localRunDepth = Math.max(0, this.#localRunDepth - 1);
974
+ if (this.#localRunDepth === 0) this.#submittedRunIdPending = false;
934
975
  }
935
976
  #notifyCreated(runId) {
936
977
  this.#activeRunId = runId;
@@ -1348,6 +1389,7 @@ var StreamController = class {
1348
1389
  this.#localRunDepth = 0;
1349
1390
  this.#messageMetadata.reset();
1350
1391
  this.#hydratedActiveInterruptIds = null;
1392
+ this.#hydratedCheckpointTime = void 0;
1351
1393
  this.#interruptReplayThroughSeq = void 0;
1352
1394
  this.#pendingHydrationInterruptEvents = [];
1353
1395
  this.#discardPendingInterruptEvents();
@@ -1587,6 +1629,8 @@ var StreamController = class {
1587
1629
  if (this.#rootEventListeners.size > 0) for (const listener of this.#rootEventListeners) try {
1588
1630
  listener(event);
1589
1631
  } catch {}
1632
+ const floor = this.#hydratedCheckpointTime;
1633
+ if (floor != null && event.params.timestamp < floor) return;
1590
1634
  /**
1591
1635
  * `messages` and `tools` events are emitted under a node's
1592
1636
  * namespace — for a typical StateGraph the LLM's token deltas
@@ -1662,7 +1706,32 @@ var StreamController = class {
1662
1706
  this.#recordInterrupt(event);
1663
1707
  return;
1664
1708
  }
1665
- if (event.method === "lifecycle") event.params.data;
1709
+ if (event.method === "lifecycle") {
1710
+ /**
1711
+ * Root lifecycle transitions are observed elsewhere
1712
+ * (#awaitTerminal) to unblock `submit`. Here they drop a closed
1713
+ * run's never-checkpointed messages.
1714
+ */
1715
+ const lifecycle = event.params.data;
1716
+ const dropped = this.#rootMessages.applyLifecycle(lifecycle?.event);
1717
+ if (dropped.size > 0) this.#messageMetadata.forget(dropped);
1718
+ }
1719
+ }
1720
+ /**
1721
+ * How a lifecycle event relates to the run a local `submit()` started.
1722
+ * New subscriptions replay earlier runs' terminals, and accepting one
1723
+ * would end the submitted run early: `"other"` marks those, `"pending"`
1724
+ * an event that names a run before `run.start` has answered. `undefined`
1725
+ * when it can't be told apart (no submit in flight, no run named, or no
1726
+ * run id returned).
1727
+ */
1728
+ #submittedRunMatch(event) {
1729
+ if (event.method !== "lifecycle" || this.#localRunDepth === 0) return;
1730
+ const runId = synthesizedEventRunId(event.event_id);
1731
+ if (runId == null) return void 0;
1732
+ if (this.#submittedRunIdPending) return "pending";
1733
+ if (this.#submittedRunId == null) return void 0;
1734
+ return runId === this.#submittedRunId ? void 0 : "other";
1666
1735
  }
1667
1736
  /**
1668
1737
  * Merge a `values` payload into root values and root messages.
@@ -2008,9 +2077,12 @@ var StreamController = class {
2008
2077
  return new Promise((resolve) => {
2009
2078
  let settled = false;
2010
2079
  let sawRunning = false;
2080
+ const held = [];
2081
+ const heldReleases = this.#heldLifecycleReleases;
2011
2082
  function finish(result) {
2012
2083
  if (settled) return;
2013
2084
  settled = true;
2085
+ heldReleases.delete(releaseHeld);
2014
2086
  unsubscribeRoot?.();
2015
2087
  unsubscribeThread?.();
2016
2088
  unsubscribeError?.();
@@ -2022,6 +2094,12 @@ var StreamController = class {
2022
2094
  if (settled) return;
2023
2095
  if (event.method !== "lifecycle") return;
2024
2096
  if (!require_namespace.isRootNamespace(event.params.namespace)) return;
2097
+ const match = this.#submittedRunMatch(event);
2098
+ if (match === "other") return;
2099
+ if (match === "pending") {
2100
+ held.push(event);
2101
+ return;
2102
+ }
2025
2103
  const lifecycle = event.params.data;
2026
2104
  if (lifecycle?.event === "running") {
2027
2105
  sawRunning = true;
@@ -2037,6 +2115,10 @@ var StreamController = class {
2037
2115
  setTimeout(() => finish({ event: "interrupted" }), 0);
2038
2116
  }
2039
2117
  };
2118
+ const releaseHeld = () => {
2119
+ for (const event of held.splice(0)) onEvent(event);
2120
+ };
2121
+ heldReleases.add(releaseHeld);
2040
2122
  const unsubscribeRoot = this.#rootBus.subscribe(onEvent);
2041
2123
  const unsubscribeThread = this.#thread?.onEvent(onEvent);
2042
2124
  const unsubscribeError = this.#thread?.onError((error) => finish({
@@ -2131,6 +2213,15 @@ function collectActiveInterruptsFromTasks(tasks) {
2131
2213
  activeIds
2132
2214
  };
2133
2215
  }
2216
+ /**
2217
+ * Run id from a `synth:<run_id>:...` event id, the form the agent server
2218
+ * uses for events it synthesizes such as root `lifecycle`. Events carry no
2219
+ * run id field.
2220
+ */
2221
+ function synthesizedEventRunId(eventId) {
2222
+ if (eventId == null || !eventId.startsWith("synth:")) return void 0;
2223
+ return eventId.split(":")[1] || void 0;
2224
+ }
2134
2225
  //#endregion
2135
2226
  exports.ROOT_PUMP_CHANNELS = ROOT_PUMP_CHANNELS;
2136
2227
  exports.StreamController = StreamController;