@langchain/langgraph-sdk 0.0.38 → 0.0.40
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/client.cjs +10 -67
- package/dist/client.d.ts +18 -23
- package/dist/client.js +10 -67
- package/dist/index.d.ts +3 -0
- package/dist/react/debug.cjs +32 -0
- package/dist/react/debug.d.ts +23 -0
- package/dist/react/debug.js +28 -0
- package/dist/react/index.cjs +5 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/react/stream.cjs +411 -0
- package/dist/react/stream.d.ts +46 -0
- package/dist/react/stream.js +407 -0
- package/dist/types.d.ts +6 -16
- package/dist/types.messages.d.ts +88 -0
- package/dist/types.stream.cjs +2 -0
- package/dist/types.stream.d.ts +156 -0
- package/dist/types.stream.js +1 -0
- package/dist/utils/async_caller.cjs +2 -1
- package/dist/utils/async_caller.js +2 -1
- package/dist/utils/sse.cjs +157 -0
- package/dist/utils/sse.d.ts +11 -0
- package/dist/utils/sse.js +152 -0
- package/package.json +23 -3
- package/react.cjs +1 -0
- package/react.d.cts +1 -0
- package/react.d.ts +1 -0
- package/react.js +1 -0
- package/dist/utils/eventsource-parser/index.cjs +0 -7
- package/dist/utils/eventsource-parser/index.d.ts +0 -2
- package/dist/utils/eventsource-parser/index.js +0 -3
- package/dist/utils/eventsource-parser/parse.cjs +0 -150
- package/dist/utils/eventsource-parser/parse.d.ts +0 -18
- package/dist/utils/eventsource-parser/parse.js +0 -146
- package/dist/utils/eventsource-parser/stream.cjs +0 -34
- package/dist/utils/eventsource-parser/stream.d.ts +0 -17
- package/dist/utils/eventsource-parser/stream.js +0 -30
- package/dist/utils/eventsource-parser/types.d.ts +0 -81
- /package/dist/{utils/eventsource-parser/types.cjs → types.messages.cjs} +0 -0
- /package/dist/{utils/eventsource-parser/types.js → types.messages.js} +0 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */
|
|
2
|
+
"use client";
|
|
3
|
+
import { Client } from "../client.js";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
5
|
+
import { coerceMessageLikeToMessage, convertToChunk, } from "@langchain/core/messages";
|
|
6
|
+
class StreamError extends Error {
|
|
7
|
+
constructor(data) {
|
|
8
|
+
super(data.message);
|
|
9
|
+
this.name = data.name ?? data.error ?? "StreamError";
|
|
10
|
+
}
|
|
11
|
+
static isStructuredError(error) {
|
|
12
|
+
return typeof error === "object" && error != null && "message" in error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class MessageTupleManager {
|
|
16
|
+
constructor() {
|
|
17
|
+
Object.defineProperty(this, "chunks", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: {}
|
|
22
|
+
});
|
|
23
|
+
this.chunks = {};
|
|
24
|
+
}
|
|
25
|
+
add(serialized) {
|
|
26
|
+
const chunk = convertToChunk(coerceMessageLikeToMessage(serialized));
|
|
27
|
+
const id = chunk.id;
|
|
28
|
+
if (!id)
|
|
29
|
+
return null;
|
|
30
|
+
this.chunks[id] ??= {};
|
|
31
|
+
this.chunks[id].chunk = this.chunks[id]?.chunk?.concat(chunk) ?? chunk;
|
|
32
|
+
return id;
|
|
33
|
+
}
|
|
34
|
+
clear() {
|
|
35
|
+
this.chunks = {};
|
|
36
|
+
}
|
|
37
|
+
get(id, defaultIndex) {
|
|
38
|
+
if (this.chunks[id] == null)
|
|
39
|
+
return null;
|
|
40
|
+
this.chunks[id].index ??= defaultIndex;
|
|
41
|
+
return this.chunks[id];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const toMessageDict = (chunk) => {
|
|
45
|
+
const { type, data } = chunk.toDict();
|
|
46
|
+
return { ...data, type };
|
|
47
|
+
};
|
|
48
|
+
function unique(array) {
|
|
49
|
+
return [...new Set(array)];
|
|
50
|
+
}
|
|
51
|
+
function findLastIndex(array, predicate) {
|
|
52
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
53
|
+
if (predicate(array[i]))
|
|
54
|
+
return i;
|
|
55
|
+
}
|
|
56
|
+
return -1;
|
|
57
|
+
}
|
|
58
|
+
function fetchHistory(client, threadId) {
|
|
59
|
+
return client.threads.getHistory(threadId, { limit: 1000 });
|
|
60
|
+
}
|
|
61
|
+
function useThreadHistory(threadId, client, clearCallbackRef, submittingRef) {
|
|
62
|
+
const [history, setHistory] = useState([]);
|
|
63
|
+
const fetcher = useCallback((threadId) => {
|
|
64
|
+
if (threadId != null) {
|
|
65
|
+
return fetchHistory(client, threadId).then((history) => {
|
|
66
|
+
setHistory(history);
|
|
67
|
+
return history;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
setHistory([]);
|
|
71
|
+
clearCallbackRef.current?.();
|
|
72
|
+
return Promise.resolve([]);
|
|
73
|
+
}, []);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (submittingRef.current)
|
|
76
|
+
return;
|
|
77
|
+
fetcher(threadId);
|
|
78
|
+
}, [fetcher, submittingRef, threadId]);
|
|
79
|
+
return {
|
|
80
|
+
data: history,
|
|
81
|
+
mutate: (mutateId) => fetcher(mutateId ?? threadId),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function useStream(options) {
|
|
85
|
+
const { assistantId, threadId, withMessages, onError, onFinish } = options;
|
|
86
|
+
const client = useMemo(() => new Client({ apiUrl: options.apiUrl, apiKey: options.apiKey }), [options.apiKey, options.apiUrl]);
|
|
87
|
+
const [branchPath, setBranchPath] = useState([]);
|
|
88
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
89
|
+
const [_, setEvents] = useState([]);
|
|
90
|
+
const [streamError, setStreamError] = useState(undefined);
|
|
91
|
+
const [streamValues, setStreamValues] = useState(null);
|
|
92
|
+
const messageManagerRef = useRef(new MessageTupleManager());
|
|
93
|
+
const submittingRef = useRef(false);
|
|
94
|
+
const abortRef = useRef(null);
|
|
95
|
+
const trackStreamModeRef = useRef(["values", "messages-tuple"]);
|
|
96
|
+
const trackStreamMode = useCallback((mode) => {
|
|
97
|
+
if (!trackStreamModeRef.current.includes(mode))
|
|
98
|
+
trackStreamModeRef.current.push(mode);
|
|
99
|
+
}, []);
|
|
100
|
+
const hasUpdateListener = options.onUpdateEvent != null;
|
|
101
|
+
const hasCustomListener = options.onCustomEvent != null;
|
|
102
|
+
const callbackStreamMode = useMemo(() => {
|
|
103
|
+
const modes = [];
|
|
104
|
+
if (hasUpdateListener)
|
|
105
|
+
modes.push("updates");
|
|
106
|
+
if (hasCustomListener)
|
|
107
|
+
modes.push("custom");
|
|
108
|
+
return modes;
|
|
109
|
+
}, [hasUpdateListener, hasCustomListener]);
|
|
110
|
+
const clearCallbackRef = useRef(null);
|
|
111
|
+
clearCallbackRef.current = () => {
|
|
112
|
+
setStreamError(undefined);
|
|
113
|
+
setStreamValues(null);
|
|
114
|
+
};
|
|
115
|
+
// TODO: this should be done on the server to avoid pagination
|
|
116
|
+
// TODO: should we permit adapter? SWR / React Query?
|
|
117
|
+
const history = useThreadHistory(threadId, client, clearCallbackRef, submittingRef);
|
|
118
|
+
const getMessages = useMemo(() => {
|
|
119
|
+
if (withMessages == null)
|
|
120
|
+
return undefined;
|
|
121
|
+
return (value) => Array.isArray(value[withMessages])
|
|
122
|
+
? value[withMessages]
|
|
123
|
+
: [];
|
|
124
|
+
}, [withMessages]);
|
|
125
|
+
const [sequence, pathMap] = (() => {
|
|
126
|
+
const childrenMap = {};
|
|
127
|
+
// First pass - collect nodes for each checkpoint
|
|
128
|
+
history.data.forEach((state) => {
|
|
129
|
+
const checkpointId = state.parent_checkpoint?.checkpoint_id ?? "$";
|
|
130
|
+
childrenMap[checkpointId] ??= [];
|
|
131
|
+
childrenMap[checkpointId].push(state);
|
|
132
|
+
});
|
|
133
|
+
const rootSequence = { type: "sequence", items: [] };
|
|
134
|
+
const queue = [{ id: "$", sequence: rootSequence, path: [] }];
|
|
135
|
+
const paths = [];
|
|
136
|
+
const visited = new Set();
|
|
137
|
+
while (queue.length > 0) {
|
|
138
|
+
const task = queue.shift();
|
|
139
|
+
if (visited.has(task.id))
|
|
140
|
+
continue;
|
|
141
|
+
visited.add(task.id);
|
|
142
|
+
const children = childrenMap[task.id];
|
|
143
|
+
if (children == null || children.length === 0)
|
|
144
|
+
continue;
|
|
145
|
+
// If we've encountered a fork (2+ children), push the fork
|
|
146
|
+
// to the sequence and add a new sequence for each child
|
|
147
|
+
let fork;
|
|
148
|
+
if (children.length > 1) {
|
|
149
|
+
fork = { type: "fork", items: [] };
|
|
150
|
+
task.sequence.items.push(fork);
|
|
151
|
+
}
|
|
152
|
+
for (const value of children) {
|
|
153
|
+
const id = value.checkpoint.checkpoint_id;
|
|
154
|
+
let sequence = task.sequence;
|
|
155
|
+
let path = task.path;
|
|
156
|
+
if (fork != null) {
|
|
157
|
+
sequence = { type: "sequence", items: [] };
|
|
158
|
+
fork.items.unshift(sequence);
|
|
159
|
+
path = path.slice();
|
|
160
|
+
path.push(id);
|
|
161
|
+
paths.push(path);
|
|
162
|
+
}
|
|
163
|
+
sequence.items.push({ type: "node", value, path });
|
|
164
|
+
queue.push({ id, sequence, path });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Third pass, create a map for available forks
|
|
168
|
+
const pathMap = {};
|
|
169
|
+
for (const path of paths) {
|
|
170
|
+
const parent = path.at(-2) ?? "$";
|
|
171
|
+
pathMap[parent] ??= [];
|
|
172
|
+
pathMap[parent].unshift(path);
|
|
173
|
+
}
|
|
174
|
+
return [rootSequence, pathMap];
|
|
175
|
+
})();
|
|
176
|
+
const [flatValues, flatPaths] = (() => {
|
|
177
|
+
const result = [];
|
|
178
|
+
const flatPaths = {};
|
|
179
|
+
const forkStack = branchPath.slice();
|
|
180
|
+
const queue = [...sequence.items];
|
|
181
|
+
while (queue.length > 0) {
|
|
182
|
+
const item = queue.shift();
|
|
183
|
+
if (item.type === "node") {
|
|
184
|
+
result.push(item.value);
|
|
185
|
+
flatPaths[item.value.checkpoint.checkpoint_id] = {
|
|
186
|
+
current: item.path,
|
|
187
|
+
branches: item.path.length > 0 ? pathMap[item.path.at(-2) ?? "$"] ?? [] : [],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
if (item.type === "fork") {
|
|
191
|
+
const forkId = forkStack.shift();
|
|
192
|
+
const index = forkId != null
|
|
193
|
+
? item.items.findIndex((value) => {
|
|
194
|
+
const firstItem = value.items.at(0);
|
|
195
|
+
if (!firstItem || firstItem.type !== "node")
|
|
196
|
+
return false;
|
|
197
|
+
return firstItem.value.checkpoint.checkpoint_id === forkId;
|
|
198
|
+
})
|
|
199
|
+
: -1;
|
|
200
|
+
const nextItems = item.items.at(index)?.items ?? [];
|
|
201
|
+
queue.push(...nextItems);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return [result, flatPaths];
|
|
205
|
+
})();
|
|
206
|
+
const threadHead = flatValues.at(-1);
|
|
207
|
+
const historyValues = threadHead?.values ?? {};
|
|
208
|
+
const historyError = (() => {
|
|
209
|
+
const error = threadHead?.tasks?.at(-1)?.error;
|
|
210
|
+
if (error == null)
|
|
211
|
+
return undefined;
|
|
212
|
+
try {
|
|
213
|
+
const parsed = JSON.parse(error);
|
|
214
|
+
if (StreamError.isStructuredError(parsed)) {
|
|
215
|
+
return new StreamError(parsed);
|
|
216
|
+
}
|
|
217
|
+
return parsed;
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// do nothing
|
|
221
|
+
}
|
|
222
|
+
return error;
|
|
223
|
+
})();
|
|
224
|
+
const messageMetadata = (() => {
|
|
225
|
+
if (getMessages == null)
|
|
226
|
+
return undefined;
|
|
227
|
+
const alreadyShown = new Set();
|
|
228
|
+
return getMessages(historyValues).map((message, idx) => {
|
|
229
|
+
const messageId = message.id ?? idx;
|
|
230
|
+
const firstSeenIdx = findLastIndex(history.data, (state) => getMessages(state.values)
|
|
231
|
+
.map((m, idx) => m.id ?? idx)
|
|
232
|
+
.includes(messageId));
|
|
233
|
+
const firstSeen = history.data[firstSeenIdx];
|
|
234
|
+
let branch = firstSeen
|
|
235
|
+
? flatPaths[firstSeen.checkpoint.checkpoint_id]
|
|
236
|
+
: undefined;
|
|
237
|
+
if (!branch?.current?.length)
|
|
238
|
+
branch = undefined;
|
|
239
|
+
// serialize branches
|
|
240
|
+
const optionsShown = branch?.branches?.flat(2).join(",");
|
|
241
|
+
if (optionsShown) {
|
|
242
|
+
if (alreadyShown.has(optionsShown))
|
|
243
|
+
branch = undefined;
|
|
244
|
+
alreadyShown.add(optionsShown);
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
messageId: messageId.toString(),
|
|
248
|
+
firstSeenState: firstSeen,
|
|
249
|
+
branch: branch?.current?.join(">"),
|
|
250
|
+
branchOptions: branch?.branches?.map((b) => b.join(">")),
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
})();
|
|
254
|
+
const stop = useCallback(() => {
|
|
255
|
+
if (abortRef.current != null)
|
|
256
|
+
abortRef.current.abort();
|
|
257
|
+
abortRef.current = null;
|
|
258
|
+
}, []);
|
|
259
|
+
const submit = async (values, submitOptions) => {
|
|
260
|
+
try {
|
|
261
|
+
setIsLoading(true);
|
|
262
|
+
setStreamError(undefined);
|
|
263
|
+
submittingRef.current = true;
|
|
264
|
+
abortRef.current = new AbortController();
|
|
265
|
+
let usableThreadId = threadId;
|
|
266
|
+
if (!usableThreadId) {
|
|
267
|
+
const thread = await client.threads.create();
|
|
268
|
+
options?.onThreadId?.(thread.thread_id);
|
|
269
|
+
usableThreadId = thread.thread_id;
|
|
270
|
+
}
|
|
271
|
+
const streamMode = unique([
|
|
272
|
+
...(submitOptions?.streamMode ?? []),
|
|
273
|
+
...trackStreamModeRef.current,
|
|
274
|
+
...callbackStreamMode,
|
|
275
|
+
]);
|
|
276
|
+
const checkpoint = submitOptions?.checkpoint ?? threadHead?.checkpoint ?? undefined;
|
|
277
|
+
// @ts-expect-error
|
|
278
|
+
if (checkpoint != null)
|
|
279
|
+
delete checkpoint.thread_id;
|
|
280
|
+
const run = (await client.runs.stream(usableThreadId, assistantId, {
|
|
281
|
+
input: values,
|
|
282
|
+
config: submitOptions?.config,
|
|
283
|
+
command: submitOptions?.command,
|
|
284
|
+
interruptBefore: submitOptions?.interruptBefore,
|
|
285
|
+
interruptAfter: submitOptions?.interruptAfter,
|
|
286
|
+
metadata: submitOptions?.metadata,
|
|
287
|
+
multitaskStrategy: submitOptions?.multitaskStrategy,
|
|
288
|
+
onCompletion: submitOptions?.onCompletion,
|
|
289
|
+
onDisconnect: submitOptions?.onDisconnect ?? "cancel",
|
|
290
|
+
signal: abortRef.current.signal,
|
|
291
|
+
checkpoint,
|
|
292
|
+
streamMode,
|
|
293
|
+
}));
|
|
294
|
+
// Unbranch things
|
|
295
|
+
const newPath = submitOptions?.checkpoint?.checkpoint_id
|
|
296
|
+
? flatPaths[submitOptions?.checkpoint?.checkpoint_id]?.current
|
|
297
|
+
: undefined;
|
|
298
|
+
if (newPath != null)
|
|
299
|
+
setBranchPath(newPath ?? []);
|
|
300
|
+
// Assumption: we're setting the initial value
|
|
301
|
+
// Used for instant feedback
|
|
302
|
+
setStreamValues(() => {
|
|
303
|
+
const values = { ...historyValues };
|
|
304
|
+
if (submitOptions?.optimisticValues != null) {
|
|
305
|
+
return {
|
|
306
|
+
...values,
|
|
307
|
+
...(typeof submitOptions.optimisticValues === "function"
|
|
308
|
+
? submitOptions.optimisticValues(values)
|
|
309
|
+
: submitOptions.optimisticValues),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
return values;
|
|
313
|
+
});
|
|
314
|
+
let streamError;
|
|
315
|
+
for await (const { event, data } of run) {
|
|
316
|
+
setEvents((events) => [...events, { event, data }]);
|
|
317
|
+
if (event === "error") {
|
|
318
|
+
streamError = new StreamError(data);
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
if (event === "updates") {
|
|
322
|
+
options.onUpdateEvent?.(data);
|
|
323
|
+
}
|
|
324
|
+
if (event === "custom") {
|
|
325
|
+
options.onCustomEvent?.(data);
|
|
326
|
+
}
|
|
327
|
+
if (event === "metadata") {
|
|
328
|
+
options.onMetadataEvent?.(data);
|
|
329
|
+
}
|
|
330
|
+
if (event === "values") {
|
|
331
|
+
setStreamValues(data);
|
|
332
|
+
}
|
|
333
|
+
if (event === "messages") {
|
|
334
|
+
if (!getMessages)
|
|
335
|
+
continue;
|
|
336
|
+
const [serialized] = data;
|
|
337
|
+
const messageId = messageManagerRef.current.add(serialized);
|
|
338
|
+
if (!messageId) {
|
|
339
|
+
console.warn("Failed to add message to manager, no message ID found");
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
setStreamValues((streamValues) => {
|
|
343
|
+
const values = { ...historyValues, ...streamValues };
|
|
344
|
+
// Assumption: we're concatenating the message
|
|
345
|
+
const messages = getMessages(values).slice();
|
|
346
|
+
const { chunk, index } = messageManagerRef.current.get(messageId, messages.length) ?? {};
|
|
347
|
+
if (!chunk || index == null)
|
|
348
|
+
return values;
|
|
349
|
+
messages[index] = toMessageDict(chunk);
|
|
350
|
+
return { ...values, [withMessages]: messages };
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// TODO: stream created checkpoints to avoid an unnecessary network request
|
|
355
|
+
const result = await history.mutate(usableThreadId);
|
|
356
|
+
// TODO: write tests verifying that stream values are properly handled lifecycle-wise
|
|
357
|
+
setStreamValues(null);
|
|
358
|
+
if (streamError != null)
|
|
359
|
+
throw streamError;
|
|
360
|
+
const lastHead = result.at(0);
|
|
361
|
+
if (lastHead)
|
|
362
|
+
onFinish?.(lastHead);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
if (!(error instanceof Error &&
|
|
366
|
+
(error.name === "AbortError" || error.name === "TimeoutError"))) {
|
|
367
|
+
setStreamError(error);
|
|
368
|
+
onError?.(error);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
finally {
|
|
372
|
+
setIsLoading(false);
|
|
373
|
+
// Assumption: messages are already handled, we can clear the manager
|
|
374
|
+
messageManagerRef.current.clear();
|
|
375
|
+
submittingRef.current = false;
|
|
376
|
+
abortRef.current = null;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
const error = isLoading ? streamError : historyError;
|
|
380
|
+
const values = streamValues ?? historyValues;
|
|
381
|
+
const setBranch = useCallback((path) => setBranchPath(path.split(">")), [setBranchPath]);
|
|
382
|
+
return {
|
|
383
|
+
get values() {
|
|
384
|
+
trackStreamMode("values");
|
|
385
|
+
return values;
|
|
386
|
+
},
|
|
387
|
+
error,
|
|
388
|
+
isLoading,
|
|
389
|
+
stop,
|
|
390
|
+
submit,
|
|
391
|
+
setBranch,
|
|
392
|
+
get messages() {
|
|
393
|
+
trackStreamMode("messages-tuple");
|
|
394
|
+
if (getMessages == null) {
|
|
395
|
+
throw new Error("No messages key provided. Make sure that `useStream` contains the `messagesKey` property.");
|
|
396
|
+
}
|
|
397
|
+
return getMessages(values);
|
|
398
|
+
},
|
|
399
|
+
getMessagesMetadata(message, index) {
|
|
400
|
+
trackStreamMode("messages-tuple");
|
|
401
|
+
if (getMessages == null) {
|
|
402
|
+
throw new Error("No messages key provided. Make sure that `useStream` contains the `messagesKey` property.");
|
|
403
|
+
}
|
|
404
|
+
return messageMetadata?.find((m) => m.messageId === (message.id ?? index));
|
|
405
|
+
},
|
|
406
|
+
};
|
|
407
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import { Checkpoint, Config, Metadata } from "./schema.js";
|
|
2
|
-
|
|
3
|
-
* Stream modes
|
|
4
|
-
* - "values": Stream only the state values.
|
|
5
|
-
* - "messages": Stream complete messages.
|
|
6
|
-
* - "messages-tuple": Stream (message chunk, metadata) tuples.
|
|
7
|
-
* - "updates": Stream updates to the state.
|
|
8
|
-
* - "events": Stream events occurring during execution.
|
|
9
|
-
* - "debug": Stream detailed debug information.
|
|
10
|
-
* - "custom": Stream custom events.
|
|
11
|
-
*/
|
|
12
|
-
export type StreamMode = "values" | "messages" | "updates" | "events" | "debug" | "custom" | "messages-tuple";
|
|
2
|
+
import { StreamMode } from "./types.stream.js";
|
|
13
3
|
export type MultitaskStrategy = "reject" | "interrupt" | "rollback" | "enqueue";
|
|
14
4
|
export type OnConflictBehavior = "raise" | "do_nothing";
|
|
15
5
|
export type OnCompletionBehavior = "complete" | "continue";
|
|
16
6
|
export type DisconnectMode = "cancel" | "continue";
|
|
17
|
-
export type StreamEvent = "events" | "metadata" | "debug" | "updates" | "values" | "messages/partial" | "messages/metadata" | "messages/complete" | (string & {});
|
|
7
|
+
export type StreamEvent = "events" | "metadata" | "debug" | "updates" | "values" | "messages/partial" | "messages/metadata" | "messages/complete" | "messages" | (string & {});
|
|
18
8
|
export interface Send {
|
|
19
9
|
node: string;
|
|
20
10
|
input: Record<string, unknown> | null;
|
|
@@ -23,7 +13,7 @@ export interface Command {
|
|
|
23
13
|
/**
|
|
24
14
|
* An object to update the thread state with.
|
|
25
15
|
*/
|
|
26
|
-
update?: Record<string, unknown> | [string, unknown][];
|
|
16
|
+
update?: Record<string, unknown> | [string, unknown][] | null;
|
|
27
17
|
/**
|
|
28
18
|
* The value to return from an `interrupt` function call.
|
|
29
19
|
*/
|
|
@@ -111,15 +101,15 @@ interface RunsInvokePayload {
|
|
|
111
101
|
*/
|
|
112
102
|
command?: Command;
|
|
113
103
|
}
|
|
114
|
-
export interface RunsStreamPayload extends RunsInvokePayload {
|
|
104
|
+
export interface RunsStreamPayload<TStreamMode extends StreamMode | StreamMode[] = [], TSubgraphs extends boolean = false> extends RunsInvokePayload {
|
|
115
105
|
/**
|
|
116
106
|
* One of `"values"`, `"messages"`, `"messages-tuple"`, `"updates"`, `"events"`, `"debug"`, `"custom"`.
|
|
117
107
|
*/
|
|
118
|
-
streamMode?:
|
|
108
|
+
streamMode?: TStreamMode;
|
|
119
109
|
/**
|
|
120
110
|
* Stream output from subgraphs. By default, streams only the top graph.
|
|
121
111
|
*/
|
|
122
|
-
streamSubgraphs?:
|
|
112
|
+
streamSubgraphs?: TSubgraphs;
|
|
123
113
|
/**
|
|
124
114
|
* Pass one or more feedbackKeys if you want to request short-lived signed URLs
|
|
125
115
|
* for submitting feedback to LangSmith with this key for this run.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
type ImageDetail = "auto" | "low" | "high";
|
|
2
|
+
type MessageContentImageUrl = {
|
|
3
|
+
type: "image_url";
|
|
4
|
+
image_url: string | {
|
|
5
|
+
url: string;
|
|
6
|
+
detail?: ImageDetail | undefined;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
type MessageContentText = {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
};
|
|
13
|
+
type MessageContentComplex = MessageContentText | MessageContentImageUrl;
|
|
14
|
+
type MessageContent = string | MessageContentComplex[];
|
|
15
|
+
/**
|
|
16
|
+
* Model-specific additional kwargs, which is passed back to the underlying LLM.
|
|
17
|
+
*/
|
|
18
|
+
type MessageAdditionalKwargs = Record<string, unknown>;
|
|
19
|
+
export type HumanMessage = {
|
|
20
|
+
type: "human";
|
|
21
|
+
id?: string | undefined;
|
|
22
|
+
content: MessageContent;
|
|
23
|
+
};
|
|
24
|
+
export type AIMessage = {
|
|
25
|
+
type: "ai";
|
|
26
|
+
id?: string | undefined;
|
|
27
|
+
content: MessageContent;
|
|
28
|
+
tool_calls?: {
|
|
29
|
+
name: string;
|
|
30
|
+
args: {
|
|
31
|
+
[x: string]: {
|
|
32
|
+
[x: string]: any;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
id?: string | undefined;
|
|
36
|
+
type?: "tool_call" | undefined;
|
|
37
|
+
}[] | undefined;
|
|
38
|
+
invalid_tool_calls?: {
|
|
39
|
+
name?: string | undefined;
|
|
40
|
+
args?: string | undefined;
|
|
41
|
+
id?: string | undefined;
|
|
42
|
+
error?: string | undefined;
|
|
43
|
+
type?: "invalid_tool_call" | undefined;
|
|
44
|
+
}[] | undefined;
|
|
45
|
+
usage_metadata?: {
|
|
46
|
+
input_tokens: number;
|
|
47
|
+
output_tokens: number;
|
|
48
|
+
total_tokens: number;
|
|
49
|
+
input_token_details?: {
|
|
50
|
+
audio?: number | undefined;
|
|
51
|
+
cache_read?: number | undefined;
|
|
52
|
+
cache_creation?: number | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
output_token_details?: {
|
|
55
|
+
audio?: number | undefined;
|
|
56
|
+
reasoning?: number | undefined;
|
|
57
|
+
} | undefined;
|
|
58
|
+
} | undefined;
|
|
59
|
+
additional_kwargs?: MessageAdditionalKwargs | undefined;
|
|
60
|
+
response_metadata?: Record<string, unknown> | undefined;
|
|
61
|
+
};
|
|
62
|
+
export type ToolMessage = {
|
|
63
|
+
type: "tool";
|
|
64
|
+
name?: string | undefined;
|
|
65
|
+
id?: string | undefined;
|
|
66
|
+
content: MessageContent;
|
|
67
|
+
status?: "error" | "success" | undefined;
|
|
68
|
+
tool_call_id: string;
|
|
69
|
+
additional_kwargs?: MessageAdditionalKwargs | undefined;
|
|
70
|
+
response_metadata?: Record<string, unknown> | undefined;
|
|
71
|
+
};
|
|
72
|
+
export type SystemMessage = {
|
|
73
|
+
type: "system";
|
|
74
|
+
id?: string | undefined;
|
|
75
|
+
content: MessageContent;
|
|
76
|
+
};
|
|
77
|
+
export type FunctionMessage = {
|
|
78
|
+
type: "function";
|
|
79
|
+
id?: string | undefined;
|
|
80
|
+
content: MessageContent;
|
|
81
|
+
};
|
|
82
|
+
export type RemoveMessage = {
|
|
83
|
+
type: "remove";
|
|
84
|
+
id: string;
|
|
85
|
+
content: MessageContent;
|
|
86
|
+
};
|
|
87
|
+
export type Message = HumanMessage | AIMessage | ToolMessage | SystemMessage | FunctionMessage | RemoveMessage;
|
|
88
|
+
export {};
|