@langchain/langgraph-sdk 1.9.31 → 1.10.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.cts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;AA6KA;;cAAa,kBAAA,WAA6B,OAAA;;AAkC1C;;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAqJ0B;;;;;EAA7C,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAszBF;;;;;;;EAAA,IA5rBvC,gBAAA,CAAA,GAAoB,OAAA;EAi2BS;;;;;;;;EAxyB3B,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EA0hCpB;;;;;;;;;;;;;;EA7pBf,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA1sB5B;;;;;;;;EA88BlB,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EA98B4B;;;;;;EAw9BzB,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EAt9BtB;;;;EA0+Bb,UAAA,CAAA,GAAc,OAAA;EA3tBhB;;;;;;;;;;;EA2xBE,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FW;;;EAsGrC,UAAA,CAAA,GAAc,OAAA;EA3FC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJf,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
1
+ {"version":3,"file":"controller.d.cts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;AA6KA;;cAAa,kBAAA,WAA6B,OAAA;;AAkC1C;;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EA+J0B;;;;;EAA7C,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAgyBF;;;;;;;EAAA,IAtqBvC,gBAAA,CAAA,GAAoB,OAAA;EA20BS;;;;;;;;EAlxB3B,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAogCpB;;;;;;;;;;;;;;EA7pBf,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA9rB5B;;;;;;;;EAk8BlB,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAl8B4B;;;;;;EA48BzB,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA18BtB;;;;EA89Bb,UAAA,CAAA,GAAc,OAAA;EArsBhB;;;;;;;;;;;EAqwBE,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FW;;;EAsGrC,UAAA,CAAA,GAAc,OAAA;EA3FC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJf,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;;AA6KA;cAAa,kBAAA,WAA6B,OAAA;;;AAkC1C;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAAA;;;;;EAqJnB,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAszBb;;;;;;;EAAA,IA5rB5B,gBAAA,CAAA,GAAoB,OAAA;EAkyBJ;;;;;;;;EAzuBd,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EA8gC5B;;;;;;;;;;;;;;EAjpBP,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA1sB3C;;;;;;;;EA88BH,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EA98BM;;;;;;EAw9BH,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EAt9BhC;;;;EA0+BH,UAAA,CAAA,GAAc,OAAA;EAr1BR;;;;;;;;;;;EAq5BN,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FA;;;EAsG1B,UAAA,CAAA,GAAc,OAAA;EA3Fd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJA,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
1
+ {"version":3,"file":"controller.d.ts","names":[],"sources":["../../src/stream/controller.ts"],"mappings":";;;;;;;;;;;;;;;AA6KA;cAAa,kBAAA,WAA6B,OAAA;;;AAkC1C;;;;;;;;;;;cAAa,gBAAA,4BACgB,MAAA,8EAEO,MAAA;EAAA;WAEzB,SAAA,EAAW,WAAA,CAAY,YAAA,CAAa,SAAA,EAAW,aAAA;EAAA,SAC/C,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,aAAA,EAAe,WAAA,CAAY,WAAA;EAAA,SAC3B,mBAAA,EAAqB,WAAA,CAAY,iBAAA;EAAA,SACjC,oBAAA,EAAsB,WAAA,CAAY,kBAAA;EAAA,SAClC,UAAA,EAAY,WAAA,CAAY,uBAAA,CAAwB,SAAA;EAAA,SAChD,QAAA,EAAU,eAAA;EAAA;;;;;EA+JnB,WAAA,CAAY,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAgyBb;;;;;;;EAAA,IAtqB5B,gBAAA,CAAA,GAAoB,OAAA;EA4wBJ;;;;;;;;EAntBd,OAAA,CAAQ,QAAA,mBAA2B,OAAA;EAw/B5B;;;;;;;;;;;;;;EAjpBP,wBAAA,CAAyB,UAAA,WAAqB,OAAA;EA9rB3C;;;;;;;;EAk8BH,MAAA,CACJ,KAAA,WACA,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EAl8BM;;;;;;EA48BH,IAAA,CAAK,OAAA,GAAU,iBAAA,GAAoB,OAAA;EA18BhC;;;;EA89BH,UAAA,CAAA,GAAc,OAAA;EA/zBR;;;;;;;;;;;EA+3BN,YAAA,CAAa,EAAA,WAAa,OAAA;EA/FA;;;EAsG1B,UAAA,CAAA,GAAc,OAAA;EA3Fd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJA,OAAA,CACJ,QAAA,WACA,OAAA,GAAU,oBAAA,CAAqB,gBAAA,IAC9B,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiHG,UAAA,CACJ,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,uBAAA,CAAwB,gBAAA,IACjC,OAAA;;;;EA4DG,OAAA,CAAA,GAAW,OAAA;;;;;;;;;;;;;;;;EAyBjB,QAAA,CAAA;;;;;;EA4BA,SAAA,CAAA,GAAa,YAAA;;;;;;;;EAWb,eAAA,CACE,QAAA,GAAW,MAAA,EAAQ,YAAA;AAAA"}
@@ -144,6 +144,16 @@ var StreamController = class {
144
144
  #threadEventUnsubscribe;
145
145
  #disposed = false;
146
146
  #pendingDisposeTimer = null;
147
+ /**
148
+ * Interrupt ids this controller has locally marked resolved via
149
+ * {@link respond} / {@link respondAll}. Used only to suppress
150
+ * *historical* SSE replay of those `input.requested` events (there
151
+ * is no `input.responded` protocol event). Live events after the
152
+ * resume barrier — or a post-resume reconcile against
153
+ * `state.tasks[].interrupts` — clear an id from this set so a
154
+ * still-pending server interrupt can reappear on
155
+ * `rootStore.interrupts`.
156
+ */
147
157
  #resolvedInterrupts = /* @__PURE__ */ new Set();
148
158
  /**
149
159
  * Set of interrupt IDs the server reports as currently *active* on
@@ -558,24 +568,8 @@ var StreamController = class {
558
568
  */
559
569
  if (Array.isArray(state?.tasks)) {
560
570
  const generationAtFetch = this.#submitGeneration;
561
- const activeInterrupts = [];
562
- const activeIds = /* @__PURE__ */ new Set();
563
- for (const task of state.tasks) {
564
- if (!Array.isArray(task?.interrupts)) continue;
565
- const checkpointNs = task?.checkpoint?.checkpoint_ns;
566
- const namespace = typeof checkpointNs === "string" && checkpointNs.length > 0 ? checkpointNs.split("|").filter((segment) => segment.length > 0) : [...ROOT_NAMESPACE];
567
- for (const interrupt of task.interrupts) {
568
- const typed = interrupt;
569
- const id = typed?.id;
570
- if (typeof id !== "string" || activeIds.has(id)) continue;
571
- activeIds.add(id);
572
- activeInterrupts.push(normalizeInterruptForClient({
573
- id,
574
- value: typed?.value,
575
- namespace: Array.isArray(typed?.namespace) ? [...typed.namespace] : namespace
576
- }));
577
- }
578
- }
571
+ const { activeInterrupts, activeIds } = collectActiveInterruptsFromTasks(state.tasks);
572
+ for (const id of activeIds) this.#resolvedInterrupts.delete(id);
579
573
  this.rootStore.setState((s) => ({
580
574
  ...s,
581
575
  interrupts: activeInterrupts,
@@ -1728,8 +1722,12 @@ var StreamController = class {
1728
1722
  if (event.method !== "input.requested") return;
1729
1723
  const data = event.params.data;
1730
1724
  const interruptId = data?.interrupt_id;
1731
- if (typeof interruptId !== "string" || this.#resolvedInterrupts.has(interruptId)) return;
1725
+ if (typeof interruptId !== "string") return;
1732
1726
  const eventSeq = typeof event.seq === "number" ? event.seq : void 0;
1727
+ if (this.#resolvedInterrupts.has(interruptId)) {
1728
+ if (!(this.#hydratedActiveInterruptIds == null || typeof this.#interruptReplayThroughSeq === "number" && eventSeq != null && eventSeq > this.#interruptReplayThroughSeq)) return;
1729
+ this.#resolvedInterrupts.delete(interruptId);
1730
+ }
1733
1731
  const isUnknownInterrupt = this.#hydratedActiveInterruptIds != null && !this.#hydratedActiveInterruptIds.has(interruptId);
1734
1732
  if (isUnknownInterrupt && this.#interruptCommandPending) {
1735
1733
  this.#pendingInterruptEvents.push(event);
@@ -1793,8 +1791,12 @@ var StreamController = class {
1793
1791
  return [...ROOT_NAMESPACE];
1794
1792
  }
1795
1793
  /**
1796
- * Mark an interrupt resolved for replay filtering and mirror the
1797
- * removal into the root snapshot the framework hooks read.
1794
+ * Mark an interrupt resolved for historical-replay filtering and
1795
+ * mirror the removal into the root snapshot the framework hooks read.
1796
+ *
1797
+ * Tombstones are not permanent: a live `input.requested` after the
1798
+ * resume barrier, or {@link #reconcilePendingInterruptsFromServer},
1799
+ * clears the id when the server still reports it as pending.
1798
1800
  */
1799
1801
  #markInterruptResolvedInRootStore(interruptId) {
1800
1802
  this.#resolvedInterrupts.add(interruptId);
@@ -1809,6 +1811,38 @@ var StreamController = class {
1809
1811
  });
1810
1812
  }
1811
1813
  /**
1814
+ * Re-sync `rootStore.interrupts` from the server's authoritative
1815
+ * `state.tasks[].interrupts` after a resumed run settles.
1816
+ *
1817
+ * Sequential `respond()` of parallel interrupts optimistically clears
1818
+ * each id client-side. When the server still has siblings pending and
1819
+ * does not re-emit `input.requested` for them (session map already
1820
+ * holds the id), this restore keeps `stream.interrupts` truthful so
1821
+ * callers do not free-text `submit()` into an ambiguous resume.
1822
+ *
1823
+ * Uses the same transport-aware state fetch as {@link hydrate}, and
1824
+ * drops the result if the thread swapped or a new submit/respond
1825
+ * started while the fetch was in flight.
1826
+ */
1827
+ async #reconcilePendingInterruptsFromServer() {
1828
+ const threadId = this.#currentThreadId;
1829
+ if (threadId == null || this.#disposed) return;
1830
+ const generationAtFetch = this.#submitGeneration;
1831
+ try {
1832
+ const state = await this.#fetchHydrationState();
1833
+ if (this.#disposed || this.#currentThreadId !== threadId || this.#submitGeneration !== generationAtFetch) return;
1834
+ if (!Array.isArray(state?.tasks)) return;
1835
+ const { activeInterrupts, activeIds } = collectActiveInterruptsFromTasks(state.tasks);
1836
+ for (const id of activeIds) this.#resolvedInterrupts.delete(id);
1837
+ this.rootStore.setState((s) => ({
1838
+ ...s,
1839
+ interrupts: activeInterrupts,
1840
+ interrupt: activeInterrupts[0]
1841
+ }));
1842
+ this.#hydratedActiveInterruptIds = activeIds;
1843
+ } catch {}
1844
+ }
1845
+ /**
1812
1846
  * Resolve on the next root-namespace terminal lifecycle event
1813
1847
  * (`completed` / `failed` / `interrupted`) or on abort.
1814
1848
  *
@@ -1833,9 +1867,15 @@ var StreamController = class {
1833
1867
  * but before `respondInput` calls `#prepareForNextRun`; accepting that
1834
1868
  * terminal would unsubscribe the watcher before the resumed run's `failed`
1835
1869
  * terminal arrives.
1870
+ *
1871
+ * On `interrupted` / `completed`, reconciles pending interrupts from
1872
+ * server state so optimistic clears from {@link respond} cannot leave
1873
+ * `stream.interrupts` empty while the checkpoint still has siblings.
1836
1874
  */
1837
- #awaitResumedRunTerminal(signal) {
1838
- return this.#awaitRootTerminal(signal, { skipInterruptedUntilRunning: true });
1875
+ async #awaitResumedRunTerminal(signal) {
1876
+ const terminal = await this.#awaitRootTerminal(signal, { skipInterruptedUntilRunning: true });
1877
+ if (!signal.aborted && !this.#disposed && (terminal.event === "interrupted" || terminal.event === "completed")) await this.#reconcilePendingInterruptsFromServer();
1878
+ return terminal;
1839
1879
  }
1840
1880
  #awaitRootTerminal(signal, options) {
1841
1881
  return new Promise((resolve) => {
@@ -1927,6 +1967,38 @@ function extractAndCoerceMessagesWithFallback(values, messagesKey) {
1927
1967
  if (!Array.isArray(raw)) return null;
1928
1968
  return ensureMessageInstances(raw);
1929
1969
  }
1970
+ /**
1971
+ * Collect pending interrupts from a `threads.getState()` `tasks` array.
1972
+ *
1973
+ * Shared by {@link StreamController.hydrate} and the post-resume
1974
+ * reconcile path so both stay aligned on namespace derivation and
1975
+ * id dedupe.
1976
+ */
1977
+ function collectActiveInterruptsFromTasks(tasks) {
1978
+ const activeInterrupts = [];
1979
+ const activeIds = /* @__PURE__ */ new Set();
1980
+ for (const task of tasks) {
1981
+ if (!Array.isArray(task?.interrupts)) continue;
1982
+ const typedTask = task;
1983
+ const checkpointNs = typedTask.checkpoint?.checkpoint_ns;
1984
+ const namespace = typeof checkpointNs === "string" && checkpointNs.length > 0 ? checkpointNs.split("|").filter((segment) => segment.length > 0) : [...ROOT_NAMESPACE];
1985
+ for (const interrupt of typedTask.interrupts) {
1986
+ const typed = interrupt;
1987
+ const id = typed?.id;
1988
+ if (typeof id !== "string" || activeIds.has(id)) continue;
1989
+ activeIds.add(id);
1990
+ activeInterrupts.push(normalizeInterruptForClient({
1991
+ id,
1992
+ value: typed?.value,
1993
+ namespace: Array.isArray(typed?.namespace) ? [...typed.namespace] : namespace
1994
+ }));
1995
+ }
1996
+ }
1997
+ return {
1998
+ activeInterrupts,
1999
+ activeIds
2000
+ };
2001
+ }
1930
2002
  //#endregion
1931
2003
  export { ROOT_PUMP_CHANNELS, StreamController };
1932
2004