@langchain/langgraph-sdk 0.0.43 → 0.0.45
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/dist/react/stream.cjs +42 -6
- package/dist/react/stream.d.ts +39 -9
- package/dist/react/stream.js +43 -7
- package/dist/schema.d.ts +2 -2
- package/package.json +1 -1
package/dist/react/stream.cjs
CHANGED
|
@@ -15,6 +15,14 @@ class StreamError extends Error {
|
|
|
15
15
|
return typeof error === "object" && error != null && "message" in error;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
function tryConvertToChunk(message) {
|
|
19
|
+
try {
|
|
20
|
+
return (0, messages_1.convertToChunk)(message);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
18
26
|
class MessageTupleManager {
|
|
19
27
|
constructor() {
|
|
20
28
|
Object.defineProperty(this, "chunks", {
|
|
@@ -26,12 +34,29 @@ class MessageTupleManager {
|
|
|
26
34
|
this.chunks = {};
|
|
27
35
|
}
|
|
28
36
|
add(serialized) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
37
|
+
// TODO: this is sometimes sent from the API
|
|
38
|
+
// figure out how to prevent this or move this to LC.js
|
|
39
|
+
if (serialized.type.endsWith("MessageChunk")) {
|
|
40
|
+
serialized.type = serialized.type
|
|
41
|
+
.slice(0, -"MessageChunk".length)
|
|
42
|
+
.toLowerCase();
|
|
43
|
+
}
|
|
44
|
+
const message = (0, messages_1.coerceMessageLikeToMessage)(serialized);
|
|
45
|
+
const chunk = tryConvertToChunk(message);
|
|
46
|
+
const id = (chunk ?? message).id;
|
|
47
|
+
if (!id) {
|
|
48
|
+
console.warn("No message ID found for chunk, ignoring in state", serialized);
|
|
32
49
|
return null;
|
|
50
|
+
}
|
|
33
51
|
this.chunks[id] ??= {};
|
|
34
|
-
|
|
52
|
+
if (chunk) {
|
|
53
|
+
const prev = this.chunks[id].chunk;
|
|
54
|
+
this.chunks[id].chunk =
|
|
55
|
+
((0, messages_1.isBaseMessageChunk)(prev) ? prev : null)?.concat(chunk) ?? chunk;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.chunks[id].chunk = message;
|
|
59
|
+
}
|
|
35
60
|
return id;
|
|
36
61
|
}
|
|
37
62
|
clear() {
|
|
@@ -195,7 +220,7 @@ function useStream(options) {
|
|
|
195
220
|
const messageManagerRef = (0, react_1.useRef)(new MessageTupleManager());
|
|
196
221
|
const submittingRef = (0, react_1.useRef)(false);
|
|
197
222
|
const abortRef = (0, react_1.useRef)(null);
|
|
198
|
-
const trackStreamModeRef = (0, react_1.useRef)(["values"
|
|
223
|
+
const trackStreamModeRef = (0, react_1.useRef)(["values"]);
|
|
199
224
|
const trackStreamMode = (0, react_1.useCallback)((mode) => {
|
|
200
225
|
if (!trackStreamModeRef.current.includes(mode))
|
|
201
226
|
trackStreamModeRef.current.push(mode);
|
|
@@ -376,6 +401,7 @@ function useStream(options) {
|
|
|
376
401
|
catch (error) {
|
|
377
402
|
if (!(error instanceof Error &&
|
|
378
403
|
(error.name === "AbortError" || error.name === "TimeoutError"))) {
|
|
404
|
+
console.error(error);
|
|
379
405
|
setStreamError(error);
|
|
380
406
|
onError?.(error);
|
|
381
407
|
}
|
|
@@ -388,7 +414,7 @@ function useStream(options) {
|
|
|
388
414
|
abortRef.current = null;
|
|
389
415
|
}
|
|
390
416
|
};
|
|
391
|
-
const error =
|
|
417
|
+
const error = streamError ?? historyError;
|
|
392
418
|
const values = streamValues ?? historyValues;
|
|
393
419
|
return {
|
|
394
420
|
get values() {
|
|
@@ -403,6 +429,16 @@ function useStream(options) {
|
|
|
403
429
|
setBranch,
|
|
404
430
|
history: flatHistory,
|
|
405
431
|
experimental_branchTree: rootSequence,
|
|
432
|
+
get interrupt() {
|
|
433
|
+
// Don't show the interrupt if the stream is loading
|
|
434
|
+
if (isLoading)
|
|
435
|
+
return undefined;
|
|
436
|
+
const interrupts = threadHead?.tasks?.at(-1)?.interrupts;
|
|
437
|
+
if (interrupts == null || interrupts.length === 0)
|
|
438
|
+
return undefined;
|
|
439
|
+
// Return only the current interrupt
|
|
440
|
+
return interrupts.at(-1);
|
|
441
|
+
},
|
|
406
442
|
get messages() {
|
|
407
443
|
trackStreamMode("messages-tuple");
|
|
408
444
|
return getMessages(values);
|
package/dist/react/stream.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ClientConfig } from "../client.js";
|
|
2
2
|
import type { Command, DisconnectMode, MultitaskStrategy, OnCompletionBehavior } from "../types.js";
|
|
3
3
|
import type { Message } from "../types.messages.js";
|
|
4
|
-
import type { Checkpoint, Config, Metadata, ThreadState } from "../schema.js";
|
|
4
|
+
import type { Checkpoint, Config, Interrupt, Metadata, ThreadState } from "../schema.js";
|
|
5
5
|
import type { CustomStreamEvent, MetadataStreamEvent, StreamMode, UpdatesStreamEvent } from "../types.stream.js";
|
|
6
6
|
interface Node<StateType = any> {
|
|
7
7
|
type: "node";
|
|
@@ -35,7 +35,25 @@ export type MessageMetadata<StateType extends Record<string, unknown>> = {
|
|
|
35
35
|
*/
|
|
36
36
|
branchOptions: string[] | undefined;
|
|
37
37
|
};
|
|
38
|
-
|
|
38
|
+
type BagTemplate = {
|
|
39
|
+
ConfigurableType?: Record<string, unknown>;
|
|
40
|
+
InterruptType?: unknown;
|
|
41
|
+
CustomEventType?: unknown;
|
|
42
|
+
UpdateType?: unknown;
|
|
43
|
+
};
|
|
44
|
+
type GetUpdateType<Bag extends BagTemplate, StateType extends Record<string, unknown>> = Bag extends {
|
|
45
|
+
UpdateType: unknown;
|
|
46
|
+
} ? Bag["UpdateType"] : Partial<StateType>;
|
|
47
|
+
type GetConfigurableType<Bag extends BagTemplate> = Bag extends {
|
|
48
|
+
ConfigurableType: Record<string, unknown>;
|
|
49
|
+
} ? Bag["ConfigurableType"] : Record<string, unknown>;
|
|
50
|
+
type GetInterruptType<Bag extends BagTemplate> = Bag extends {
|
|
51
|
+
InterruptType: unknown;
|
|
52
|
+
} ? Bag["InterruptType"] : unknown;
|
|
53
|
+
type GetCustomEventType<Bag extends BagTemplate> = Bag extends {
|
|
54
|
+
CustomEventType: unknown;
|
|
55
|
+
} ? Bag["CustomEventType"] : unknown;
|
|
56
|
+
interface UseStreamOptions<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> {
|
|
39
57
|
/**
|
|
40
58
|
* The ID of the assistant to use.
|
|
41
59
|
*/
|
|
@@ -66,11 +84,11 @@ interface UseStreamOptions<StateType extends Record<string, unknown> = Record<st
|
|
|
66
84
|
/**
|
|
67
85
|
* Callback that is called when an update event is received.
|
|
68
86
|
*/
|
|
69
|
-
onUpdateEvent?: (data: UpdatesStreamEvent<
|
|
87
|
+
onUpdateEvent?: (data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>["data"]) => void;
|
|
70
88
|
/**
|
|
71
89
|
* Callback that is called when a custom event is received.
|
|
72
90
|
*/
|
|
73
|
-
onCustomEvent?: (data: CustomStreamEvent<
|
|
91
|
+
onCustomEvent?: (data: CustomStreamEvent<GetCustomEventType<Bag>>["data"]) => void;
|
|
74
92
|
/**
|
|
75
93
|
* Callback that is called when a metadata event is received.
|
|
76
94
|
*/
|
|
@@ -84,7 +102,7 @@ interface UseStreamOptions<StateType extends Record<string, unknown> = Record<st
|
|
|
84
102
|
*/
|
|
85
103
|
onThreadId?: (threadId: string) => void;
|
|
86
104
|
}
|
|
87
|
-
interface UseStream<StateType extends Record<string, unknown> = Record<string, unknown>,
|
|
105
|
+
interface UseStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> {
|
|
88
106
|
/**
|
|
89
107
|
* The current values of the thread.
|
|
90
108
|
*/
|
|
@@ -104,7 +122,7 @@ interface UseStream<StateType extends Record<string, unknown> = Record<string, u
|
|
|
104
122
|
/**
|
|
105
123
|
* Create and stream a run to the thread.
|
|
106
124
|
*/
|
|
107
|
-
submit: (values:
|
|
125
|
+
submit: (values: GetUpdateType<Bag, StateType> | null | undefined, options?: SubmitOptions<StateType, GetConfigurableType<Bag>>) => void;
|
|
108
126
|
/**
|
|
109
127
|
* The current branch of the thread.
|
|
110
128
|
*/
|
|
@@ -122,6 +140,10 @@ interface UseStream<StateType extends Record<string, unknown> = Record<string, u
|
|
|
122
140
|
* @experimental
|
|
123
141
|
*/
|
|
124
142
|
experimental_branchTree: Sequence<StateType>;
|
|
143
|
+
/**
|
|
144
|
+
* Get the interrupt value for the stream if interrupted.
|
|
145
|
+
*/
|
|
146
|
+
interrupt: Interrupt<GetInterruptType<Bag>> | undefined;
|
|
125
147
|
/**
|
|
126
148
|
* Messages inferred from the thread.
|
|
127
149
|
* Will automatically update with incoming message chunks.
|
|
@@ -137,8 +159,11 @@ interface UseStream<StateType extends Record<string, unknown> = Record<string, u
|
|
|
137
159
|
*/
|
|
138
160
|
getMessagesMetadata: (message: Message, index?: number) => MessageMetadata<StateType> | undefined;
|
|
139
161
|
}
|
|
140
|
-
|
|
141
|
-
|
|
162
|
+
type ConfigWithConfigurable<ConfigurableType extends Record<string, unknown>> = Config & {
|
|
163
|
+
configurable?: ConfigurableType;
|
|
164
|
+
};
|
|
165
|
+
interface SubmitOptions<StateType extends Record<string, unknown> = Record<string, unknown>, ConfigurableType extends Record<string, unknown> = Record<string, unknown>> {
|
|
166
|
+
config?: ConfigWithConfigurable<ConfigurableType>;
|
|
142
167
|
checkpoint?: Omit<Checkpoint, "thread_id"> | null;
|
|
143
168
|
command?: Command;
|
|
144
169
|
interruptBefore?: "*" | string[];
|
|
@@ -151,5 +176,10 @@ interface SubmitOptions<StateType extends Record<string, unknown> = Record<strin
|
|
|
151
176
|
streamMode?: Array<StreamMode>;
|
|
152
177
|
optimisticValues?: Partial<StateType> | ((prev: StateType) => Partial<StateType>);
|
|
153
178
|
}
|
|
154
|
-
export declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>,
|
|
179
|
+
export declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {
|
|
180
|
+
ConfigurableType?: Record<string, unknown>;
|
|
181
|
+
InterruptType?: unknown;
|
|
182
|
+
CustomEventType?: unknown;
|
|
183
|
+
UpdateType?: unknown;
|
|
184
|
+
} = BagTemplate>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;
|
|
155
185
|
export {};
|
package/dist/react/stream.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
import { Client } from "../client.js";
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
5
|
-
import { coerceMessageLikeToMessage, convertToChunk, } from "@langchain/core/messages";
|
|
5
|
+
import { coerceMessageLikeToMessage, convertToChunk, isBaseMessageChunk, } from "@langchain/core/messages";
|
|
6
6
|
class StreamError extends Error {
|
|
7
7
|
constructor(data) {
|
|
8
8
|
super(data.message);
|
|
@@ -12,6 +12,14 @@ class StreamError extends Error {
|
|
|
12
12
|
return typeof error === "object" && error != null && "message" in error;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
function tryConvertToChunk(message) {
|
|
16
|
+
try {
|
|
17
|
+
return convertToChunk(message);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
15
23
|
class MessageTupleManager {
|
|
16
24
|
constructor() {
|
|
17
25
|
Object.defineProperty(this, "chunks", {
|
|
@@ -23,12 +31,29 @@ class MessageTupleManager {
|
|
|
23
31
|
this.chunks = {};
|
|
24
32
|
}
|
|
25
33
|
add(serialized) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (
|
|
34
|
+
// TODO: this is sometimes sent from the API
|
|
35
|
+
// figure out how to prevent this or move this to LC.js
|
|
36
|
+
if (serialized.type.endsWith("MessageChunk")) {
|
|
37
|
+
serialized.type = serialized.type
|
|
38
|
+
.slice(0, -"MessageChunk".length)
|
|
39
|
+
.toLowerCase();
|
|
40
|
+
}
|
|
41
|
+
const message = coerceMessageLikeToMessage(serialized);
|
|
42
|
+
const chunk = tryConvertToChunk(message);
|
|
43
|
+
const id = (chunk ?? message).id;
|
|
44
|
+
if (!id) {
|
|
45
|
+
console.warn("No message ID found for chunk, ignoring in state", serialized);
|
|
29
46
|
return null;
|
|
47
|
+
}
|
|
30
48
|
this.chunks[id] ??= {};
|
|
31
|
-
|
|
49
|
+
if (chunk) {
|
|
50
|
+
const prev = this.chunks[id].chunk;
|
|
51
|
+
this.chunks[id].chunk =
|
|
52
|
+
(isBaseMessageChunk(prev) ? prev : null)?.concat(chunk) ?? chunk;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
this.chunks[id].chunk = message;
|
|
56
|
+
}
|
|
32
57
|
return id;
|
|
33
58
|
}
|
|
34
59
|
clear() {
|
|
@@ -192,7 +217,7 @@ export function useStream(options) {
|
|
|
192
217
|
const messageManagerRef = useRef(new MessageTupleManager());
|
|
193
218
|
const submittingRef = useRef(false);
|
|
194
219
|
const abortRef = useRef(null);
|
|
195
|
-
const trackStreamModeRef = useRef(["values"
|
|
220
|
+
const trackStreamModeRef = useRef(["values"]);
|
|
196
221
|
const trackStreamMode = useCallback((mode) => {
|
|
197
222
|
if (!trackStreamModeRef.current.includes(mode))
|
|
198
223
|
trackStreamModeRef.current.push(mode);
|
|
@@ -373,6 +398,7 @@ export function useStream(options) {
|
|
|
373
398
|
catch (error) {
|
|
374
399
|
if (!(error instanceof Error &&
|
|
375
400
|
(error.name === "AbortError" || error.name === "TimeoutError"))) {
|
|
401
|
+
console.error(error);
|
|
376
402
|
setStreamError(error);
|
|
377
403
|
onError?.(error);
|
|
378
404
|
}
|
|
@@ -385,7 +411,7 @@ export function useStream(options) {
|
|
|
385
411
|
abortRef.current = null;
|
|
386
412
|
}
|
|
387
413
|
};
|
|
388
|
-
const error =
|
|
414
|
+
const error = streamError ?? historyError;
|
|
389
415
|
const values = streamValues ?? historyValues;
|
|
390
416
|
return {
|
|
391
417
|
get values() {
|
|
@@ -400,6 +426,16 @@ export function useStream(options) {
|
|
|
400
426
|
setBranch,
|
|
401
427
|
history: flatHistory,
|
|
402
428
|
experimental_branchTree: rootSequence,
|
|
429
|
+
get interrupt() {
|
|
430
|
+
// Don't show the interrupt if the stream is loading
|
|
431
|
+
if (isLoading)
|
|
432
|
+
return undefined;
|
|
433
|
+
const interrupts = threadHead?.tasks?.at(-1)?.interrupts;
|
|
434
|
+
if (interrupts == null || interrupts.length === 0)
|
|
435
|
+
return undefined;
|
|
436
|
+
// Return only the current interrupt
|
|
437
|
+
return interrupts.at(-1);
|
|
438
|
+
},
|
|
403
439
|
get messages() {
|
|
404
440
|
trackStreamMode("messages-tuple");
|
|
405
441
|
return getMessages(values);
|
package/dist/schema.d.ts
CHANGED
|
@@ -103,8 +103,8 @@ export interface AssistantGraph {
|
|
|
103
103
|
/**
|
|
104
104
|
* An interrupt thrown inside a thread.
|
|
105
105
|
*/
|
|
106
|
-
export interface Interrupt {
|
|
107
|
-
value:
|
|
106
|
+
export interface Interrupt<TValue = unknown> {
|
|
107
|
+
value: TValue;
|
|
108
108
|
when: "during";
|
|
109
109
|
resumable: boolean;
|
|
110
110
|
ns?: string[];
|