@langchain/svelte 0.2.0 → 0.3.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/dist/index.cjs +144 -438
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -30
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +54 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +144 -438
- package/dist/index.js.map +1 -1
- package/dist/stream.custom.cjs +34 -160
- package/dist/stream.custom.cjs.map +1 -1
- package/dist/stream.custom.js +36 -162
- package/dist/stream.custom.js.map +1 -1
- package/package.json +3 -3
- package/dist/context.cjs +0 -86
- package/dist/context.cjs.map +0 -1
- package/dist/context.d.cts +0 -77
- package/dist/context.d.cts.map +0 -1
- package/dist/context.d.ts +0 -77
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -85
- package/dist/context.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { useStreamCustom } from "./stream.custom.js";
|
|
2
|
-
import {
|
|
3
|
-
import { derived, fromStore, get, writable } from "svelte/store";
|
|
2
|
+
import { derived, fromStore, writable } from "svelte/store";
|
|
4
3
|
import { getContext, onDestroy, onMount, setContext } from "svelte";
|
|
5
|
-
import { FetchStreamTransport,
|
|
4
|
+
import { FetchStreamTransport, StreamOrchestrator, SubagentManager, calculateDepthFromNamespace, ensureMessageInstances, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "@langchain/langgraph-sdk/ui";
|
|
6
5
|
import { Client } from "@langchain/langgraph-sdk";
|
|
7
|
-
import { getToolCallsWithResults } from "@langchain/langgraph-sdk/utils";
|
|
8
6
|
//#region src/index.ts
|
|
9
7
|
const STREAM_CONTEXT_KEY = Symbol.for("langchain:stream-context");
|
|
10
8
|
/**
|
|
@@ -30,8 +28,8 @@ function setStreamContext(stream) {
|
|
|
30
28
|
}
|
|
31
29
|
/**
|
|
32
30
|
* Retrieves the `useStream` instance previously provided by a parent
|
|
33
|
-
* component via {@link setStreamContext}
|
|
34
|
-
* initialisation.
|
|
31
|
+
* component via {@link setStreamContext} or {@link provideStream}.
|
|
32
|
+
* Must be called during component initialisation.
|
|
35
33
|
*
|
|
36
34
|
* @throws If no stream context has been set by an ancestor component.
|
|
37
35
|
*
|
|
@@ -49,436 +47,154 @@ function getStreamContext() {
|
|
|
49
47
|
if (!ctx) throw new Error("getStreamContext must be used within a component that has called setStreamContext");
|
|
50
48
|
return ctx;
|
|
51
49
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Creates a shared `useStream` instance and makes it available to all
|
|
52
|
+
* descendant components via Svelte's `setContext`/`getContext`.
|
|
53
|
+
*
|
|
54
|
+
* Call this in a parent component's `<script>` block. Children access
|
|
55
|
+
* the shared stream via {@link getStream}.
|
|
56
|
+
*
|
|
57
|
+
* Uses the same context key as {@link setStreamContext}/{@link getStreamContext},
|
|
58
|
+
* so both retrieval functions work interchangeably.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```svelte
|
|
62
|
+
* <!-- ChatContainer.svelte -->
|
|
63
|
+
* <script lang="ts">
|
|
64
|
+
* import { provideStream } from "@langchain/svelte";
|
|
65
|
+
*
|
|
66
|
+
* provideStream({
|
|
67
|
+
* assistantId: "agent",
|
|
68
|
+
* apiUrl: "http://localhost:2024",
|
|
69
|
+
* });
|
|
70
|
+
* <\/script>
|
|
71
|
+
*
|
|
72
|
+
* <ChatHeader />
|
|
73
|
+
* <MessageList />
|
|
74
|
+
* <MessageInput />
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @returns The stream instance (same as calling `useStream` directly).
|
|
78
|
+
*/
|
|
79
|
+
function provideStream(options) {
|
|
80
|
+
const stream = useStream(options);
|
|
81
|
+
setContext(STREAM_CONTEXT_KEY, stream);
|
|
82
|
+
return stream;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Retrieves the shared stream instance from the nearest ancestor that
|
|
86
|
+
* called {@link provideStream} or {@link setStreamContext}.
|
|
87
|
+
*
|
|
88
|
+
* Throws if no ancestor has provided a stream.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```svelte
|
|
92
|
+
* <!-- MessageList.svelte -->
|
|
93
|
+
* <script lang="ts">
|
|
94
|
+
* import { getStream } from "@langchain/svelte";
|
|
95
|
+
*
|
|
96
|
+
* const stream = getStream();
|
|
97
|
+
* <\/script>
|
|
98
|
+
*
|
|
99
|
+
* {#each stream.messages as msg (msg.id)}
|
|
100
|
+
* <div>{msg.content}</div>
|
|
101
|
+
* {/each}
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
function getStream() {
|
|
105
|
+
const context = getContext(STREAM_CONTEXT_KEY);
|
|
106
|
+
if (context == null) throw new Error("getStream() requires a parent component to call provideStream(). Add provideStream({ assistantId: '...' }) in an ancestor component.");
|
|
107
|
+
return context;
|
|
59
108
|
}
|
|
60
109
|
function useStream(options) {
|
|
61
110
|
if ("transport" in options) return useStreamCustom(options);
|
|
62
111
|
return useStreamLGP(options);
|
|
63
112
|
}
|
|
64
113
|
function useStreamLGP(options) {
|
|
65
|
-
const runMetadataStorage = (() => {
|
|
66
|
-
if (typeof window === "undefined") return null;
|
|
67
|
-
const storage = options.reconnectOnMount;
|
|
68
|
-
if (storage === true) return window.sessionStorage;
|
|
69
|
-
if (typeof storage === "function") return storage();
|
|
70
|
-
return null;
|
|
71
|
-
})();
|
|
72
|
-
const getMessages = (value) => {
|
|
73
|
-
const messagesKey = options.messagesKey ?? "messages";
|
|
74
|
-
return Array.isArray(value[messagesKey]) ? value[messagesKey] : [];
|
|
75
|
-
};
|
|
76
|
-
const setMessages = (current, messages) => {
|
|
77
|
-
const messagesKey = options.messagesKey ?? "messages";
|
|
78
|
-
return {
|
|
79
|
-
...current,
|
|
80
|
-
[messagesKey]: messages
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
const historyLimit = typeof options.fetchStateHistory === "object" && options.fetchStateHistory != null ? options.fetchStateHistory.limit ?? false : options.fetchStateHistory ?? false;
|
|
84
|
-
const threadId = writable(void 0);
|
|
85
|
-
let threadIdPromise = null;
|
|
86
114
|
const client = options.client ?? new Client({ apiUrl: options.apiUrl });
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
mutate: async () => void 0
|
|
92
|
-
});
|
|
93
|
-
async function mutate(mutateId) {
|
|
94
|
-
const tid = mutateId ?? get(threadId);
|
|
95
|
-
if (!tid) return void 0;
|
|
96
|
-
try {
|
|
97
|
-
const data = await fetchHistory(client, tid, { limit: historyLimit });
|
|
98
|
-
history.set({
|
|
99
|
-
data,
|
|
100
|
-
error: void 0,
|
|
101
|
-
isLoading: false,
|
|
102
|
-
mutate
|
|
103
|
-
});
|
|
104
|
-
return data;
|
|
105
|
-
} catch (err) {
|
|
106
|
-
history.update((prev) => ({
|
|
107
|
-
...prev,
|
|
108
|
-
error: err,
|
|
109
|
-
isLoading: false
|
|
110
|
-
}));
|
|
111
|
-
options.onError?.(err, void 0);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
history.update((prev) => ({
|
|
116
|
-
...prev,
|
|
117
|
-
mutate
|
|
118
|
-
}));
|
|
119
|
-
const branch = writable("");
|
|
120
|
-
const branchContext = derived([branch, history], ([$branch, $history]) => getBranchContext($branch, $history.data ?? void 0));
|
|
121
|
-
const messageManager = new MessageTupleManager();
|
|
122
|
-
const stream = new StreamManager(messageManager, {
|
|
123
|
-
throttle: options.throttle ?? false,
|
|
124
|
-
subagentToolNames: options.subagentToolNames,
|
|
125
|
-
filterSubagentMessages: options.filterSubagentMessages,
|
|
126
|
-
toMessage: toMessageClass
|
|
127
|
-
});
|
|
128
|
-
const pendingRuns = new PendingRunsTracker();
|
|
129
|
-
const historyValues = derived([branchContext], ([$branchContext]) => $branchContext.threadHead?.values ?? options.initialValues ?? {});
|
|
130
|
-
const historyError = derived([branchContext], ([$branchContext]) => {
|
|
131
|
-
const error = $branchContext.threadHead?.tasks?.at(-1)?.error;
|
|
132
|
-
if (error == null) return void 0;
|
|
133
|
-
try {
|
|
134
|
-
const parsed = JSON.parse(error);
|
|
135
|
-
if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);
|
|
136
|
-
return parsed;
|
|
137
|
-
} catch {}
|
|
138
|
-
return error;
|
|
139
|
-
});
|
|
140
|
-
const streamValues = writable(stream.values);
|
|
141
|
-
const streamError = writable(stream.error);
|
|
142
|
-
const isLoading = writable(stream.isLoading);
|
|
143
|
-
const queueEntries = writable(pendingRuns.entries);
|
|
144
|
-
const queueSize = writable(pendingRuns.size);
|
|
145
|
-
const values = derived([streamValues, historyValues], ([$streamValues, $historyValues]) => $streamValues ?? $historyValues);
|
|
146
|
-
const error = derived([
|
|
147
|
-
streamError,
|
|
148
|
-
historyError,
|
|
149
|
-
history
|
|
150
|
-
], ([$streamError, $historyError, $history]) => $streamError ?? $historyError ?? $history.error);
|
|
151
|
-
const messageMetadata = derived([history, branchContext], ([$history, $branchContext]) => getMessagesMetadataMap({
|
|
152
|
-
initialValues: options.initialValues,
|
|
153
|
-
history: $history.data,
|
|
154
|
-
getMessages,
|
|
155
|
-
branchContext: $branchContext
|
|
156
|
-
}));
|
|
157
|
-
const subagentVersion = writable(0);
|
|
158
|
-
const unsubscribe = stream.subscribe(() => {
|
|
159
|
-
streamValues.set(stream.values);
|
|
160
|
-
streamError.set(stream.error);
|
|
161
|
-
isLoading.set(stream.isLoading);
|
|
162
|
-
subagentVersion.update((v) => v + 1);
|
|
163
|
-
});
|
|
164
|
-
const unsubQueue = pendingRuns.subscribe(() => {
|
|
165
|
-
queueEntries.set(pendingRuns.entries);
|
|
166
|
-
queueSize.set(pendingRuns.size);
|
|
115
|
+
const orchestrator = new StreamOrchestrator(options, {
|
|
116
|
+
getClient: () => client,
|
|
117
|
+
getAssistantId: () => options.assistantId,
|
|
118
|
+
getMessagesKey: () => options.messagesKey ?? "messages"
|
|
167
119
|
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
120
|
+
orchestrator.initThreadId(options.threadId ?? void 0);
|
|
121
|
+
const version = writable(0);
|
|
122
|
+
const unsubscribe = orchestrator.subscribe(() => {
|
|
123
|
+
version.update((v) => v + 1);
|
|
172
124
|
});
|
|
173
125
|
let fetchController = null;
|
|
174
|
-
const unsubReconstruct =
|
|
126
|
+
const unsubReconstruct = derived(version, () => {
|
|
127
|
+
const hvMessages = orchestrator.messages;
|
|
128
|
+
if (!options.filterSubagentMessages) return false;
|
|
129
|
+
if (orchestrator.isLoading || orchestrator.historyData.isLoading) return false;
|
|
130
|
+
return hvMessages.length > 0;
|
|
131
|
+
}).subscribe(($should) => {
|
|
175
132
|
if ($should) {
|
|
176
|
-
const hvMessages = getMessages(get(historyValues));
|
|
177
|
-
stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });
|
|
178
133
|
fetchController?.abort();
|
|
179
|
-
fetchController =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
134
|
+
fetchController = orchestrator.reconstructSubagentsIfNeeded();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const unsubDrain = derived(version, () => orchestrator.isLoading).subscribe(() => {
|
|
138
|
+
orchestrator.drainQueue();
|
|
139
|
+
});
|
|
140
|
+
let { shouldReconnect } = orchestrator;
|
|
141
|
+
onMount(() => {
|
|
142
|
+
if (shouldReconnect) {
|
|
143
|
+
if (orchestrator.tryReconnect()) shouldReconnect = false;
|
|
185
144
|
}
|
|
186
145
|
});
|
|
187
146
|
onDestroy(() => {
|
|
188
147
|
fetchController?.abort();
|
|
189
148
|
unsubscribe();
|
|
190
149
|
unsubReconstruct();
|
|
191
|
-
|
|
150
|
+
unsubDrain();
|
|
151
|
+
orchestrator.dispose();
|
|
192
152
|
});
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (runMetadataStorage && tid) {
|
|
197
|
-
const runId = runMetadataStorage.getItem(`lg:stream:${tid}`);
|
|
198
|
-
if (runId) client.runs.cancel(tid, runId);
|
|
199
|
-
runMetadataStorage.removeItem(`lg:stream:${tid}`);
|
|
200
|
-
}
|
|
201
|
-
options.onStop?.(args);
|
|
202
|
-
} });
|
|
203
|
-
}
|
|
204
|
-
function setBranch(value) {
|
|
205
|
-
branch.set(value);
|
|
206
|
-
}
|
|
207
|
-
function submitDirect(values, submitOptions) {
|
|
208
|
-
const currentBranchContext = get(branchContext);
|
|
209
|
-
const checkpointId = submitOptions?.checkpoint?.checkpoint_id;
|
|
210
|
-
branch.set(checkpointId != null ? currentBranchContext.branchByCheckpoint[checkpointId]?.branch ?? "" : "");
|
|
211
|
-
const includeImplicitBranch = historyLimit === true || typeof historyLimit === "number";
|
|
212
|
-
const shouldRefetch = options.onFinish != null || includeImplicitBranch;
|
|
213
|
-
let checkpoint = submitOptions?.checkpoint ?? (includeImplicitBranch ? currentBranchContext.threadHead?.checkpoint : void 0) ?? void 0;
|
|
214
|
-
if (submitOptions?.checkpoint === null) checkpoint = void 0;
|
|
215
|
-
if (checkpoint != null) delete checkpoint.thread_id;
|
|
216
|
-
let callbackMeta;
|
|
217
|
-
let rejoinKey;
|
|
218
|
-
let usableThreadId;
|
|
219
|
-
return stream.start(async (signal) => {
|
|
220
|
-
usableThreadId = get(threadId);
|
|
221
|
-
if (!usableThreadId) {
|
|
222
|
-
const threadPromise = client.threads.create({
|
|
223
|
-
threadId: submitOptions?.threadId,
|
|
224
|
-
metadata: submitOptions?.metadata
|
|
225
|
-
});
|
|
226
|
-
threadIdPromise = threadPromise.then((t) => t.thread_id);
|
|
227
|
-
usableThreadId = (await threadPromise).thread_id;
|
|
228
|
-
threadId.set(usableThreadId);
|
|
229
|
-
options.onThreadId?.(usableThreadId);
|
|
230
|
-
}
|
|
231
|
-
const streamMode = [
|
|
232
|
-
"values",
|
|
233
|
-
"messages-tuple",
|
|
234
|
-
"updates",
|
|
235
|
-
...submitOptions?.streamMode ?? []
|
|
236
|
-
];
|
|
237
|
-
if (options.onUpdateEvent && !streamMode.includes("updates")) streamMode.push("updates");
|
|
238
|
-
if (options.onCustomEvent && !streamMode.includes("custom")) streamMode.push("custom");
|
|
239
|
-
if (options.onCheckpointEvent && !streamMode.includes("checkpoints")) streamMode.push("checkpoints");
|
|
240
|
-
if (options.onTaskEvent && !streamMode.includes("tasks")) streamMode.push("tasks");
|
|
241
|
-
if ("onDebugEvent" in options && options.onDebugEvent && !streamMode.includes("debug")) streamMode.push("debug");
|
|
242
|
-
if ("onLangChainEvent" in options && options.onLangChainEvent && !streamMode.includes("events")) streamMode.push("events");
|
|
243
|
-
stream.setStreamValues(() => {
|
|
244
|
-
const prev = {
|
|
245
|
-
...get(historyValues),
|
|
246
|
-
...stream.values
|
|
247
|
-
};
|
|
248
|
-
if (submitOptions?.optimisticValues != null) return {
|
|
249
|
-
...prev,
|
|
250
|
-
...typeof submitOptions.optimisticValues === "function" ? submitOptions.optimisticValues(prev) : submitOptions.optimisticValues
|
|
251
|
-
};
|
|
252
|
-
return { ...prev };
|
|
253
|
-
});
|
|
254
|
-
const streamResumable = submitOptions?.streamResumable ?? !!runMetadataStorage;
|
|
255
|
-
return client.runs.stream(usableThreadId, options.assistantId, {
|
|
256
|
-
input: values,
|
|
257
|
-
config: submitOptions?.config,
|
|
258
|
-
context: submitOptions?.context,
|
|
259
|
-
command: submitOptions?.command,
|
|
260
|
-
interruptBefore: submitOptions?.interruptBefore,
|
|
261
|
-
interruptAfter: submitOptions?.interruptAfter,
|
|
262
|
-
metadata: submitOptions?.metadata,
|
|
263
|
-
multitaskStrategy: submitOptions?.multitaskStrategy,
|
|
264
|
-
onCompletion: submitOptions?.onCompletion,
|
|
265
|
-
onDisconnect: submitOptions?.onDisconnect ?? (streamResumable ? "continue" : "cancel"),
|
|
266
|
-
signal,
|
|
267
|
-
checkpoint,
|
|
268
|
-
streamMode,
|
|
269
|
-
streamSubgraphs: submitOptions?.streamSubgraphs,
|
|
270
|
-
streamResumable,
|
|
271
|
-
durability: submitOptions?.durability,
|
|
272
|
-
onRunCreated(params) {
|
|
273
|
-
callbackMeta = {
|
|
274
|
-
run_id: params.run_id,
|
|
275
|
-
thread_id: params.thread_id ?? usableThreadId
|
|
276
|
-
};
|
|
277
|
-
if (runMetadataStorage) {
|
|
278
|
-
rejoinKey = `lg:stream:${usableThreadId}`;
|
|
279
|
-
runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);
|
|
280
|
-
}
|
|
281
|
-
options.onCreated?.(callbackMeta);
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
}, {
|
|
285
|
-
getMessages,
|
|
286
|
-
setMessages,
|
|
287
|
-
initialValues: get(historyValues),
|
|
288
|
-
callbacks: options,
|
|
289
|
-
async onSuccess() {
|
|
290
|
-
if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);
|
|
291
|
-
if (shouldRefetch && usableThreadId) {
|
|
292
|
-
const lastHead = (await mutate(usableThreadId))?.at(0);
|
|
293
|
-
if (lastHead) {
|
|
294
|
-
options.onFinish?.(lastHead, callbackMeta);
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
onError(error) {
|
|
300
|
-
options.onError?.(error, callbackMeta);
|
|
301
|
-
submitOptions?.onError?.(error, callbackMeta);
|
|
302
|
-
},
|
|
303
|
-
onFinish: () => {}
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
let submitting = false;
|
|
307
|
-
function drainQueue() {
|
|
308
|
-
if (!get(isLoading) && !submitting && pendingRuns.size > 0) {
|
|
309
|
-
const next = pendingRuns.shift();
|
|
310
|
-
if (next) {
|
|
311
|
-
submitting = true;
|
|
312
|
-
joinStream(next.id).finally(() => {
|
|
313
|
-
submitting = false;
|
|
314
|
-
drainQueue();
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
isLoading.subscribe(() => {
|
|
320
|
-
drainQueue();
|
|
153
|
+
const valuesStore = derived(version, () => {
|
|
154
|
+
orchestrator.trackStreamMode("values");
|
|
155
|
+
return orchestrator.values;
|
|
321
156
|
});
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
} finally {
|
|
329
|
-
submitting = false;
|
|
330
|
-
}
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
let usableThreadId = get(threadId);
|
|
334
|
-
if (!usableThreadId && threadIdPromise) usableThreadId = await threadIdPromise;
|
|
335
|
-
if (usableThreadId) {
|
|
336
|
-
try {
|
|
337
|
-
const run = await client.runs.create(usableThreadId, options.assistantId, {
|
|
338
|
-
input: values,
|
|
339
|
-
config: submitOptions?.config,
|
|
340
|
-
context: submitOptions?.context,
|
|
341
|
-
command: submitOptions?.command,
|
|
342
|
-
interruptBefore: submitOptions?.interruptBefore,
|
|
343
|
-
interruptAfter: submitOptions?.interruptAfter,
|
|
344
|
-
metadata: submitOptions?.metadata,
|
|
345
|
-
multitaskStrategy: "enqueue",
|
|
346
|
-
streamResumable: true,
|
|
347
|
-
streamSubgraphs: submitOptions?.streamSubgraphs,
|
|
348
|
-
durability: submitOptions?.durability
|
|
349
|
-
});
|
|
350
|
-
pendingRuns.add({
|
|
351
|
-
id: run.run_id,
|
|
352
|
-
values,
|
|
353
|
-
options: submitOptions,
|
|
354
|
-
createdAt: new Date(run.created_at)
|
|
355
|
-
});
|
|
356
|
-
} catch (error) {
|
|
357
|
-
options.onError?.(error, void 0);
|
|
358
|
-
submitOptions?.onError?.(error, void 0);
|
|
359
|
-
}
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
submitting = true;
|
|
364
|
-
const result = submitDirect(values, submitOptions);
|
|
365
|
-
Promise.resolve(result).finally(() => {
|
|
366
|
-
submitting = false;
|
|
367
|
-
drainQueue();
|
|
368
|
-
});
|
|
369
|
-
return result;
|
|
370
|
-
}
|
|
371
|
-
async function joinStream(runId, lastEventId, joinOptions) {
|
|
372
|
-
lastEventId ??= "-1";
|
|
373
|
-
const tid = get(threadId);
|
|
374
|
-
if (!tid) return;
|
|
375
|
-
const callbackMeta = {
|
|
376
|
-
thread_id: tid,
|
|
377
|
-
run_id: runId
|
|
378
|
-
};
|
|
379
|
-
await stream.start(async (signal) => {
|
|
380
|
-
const rawStream = client.runs.joinStream(tid, runId, {
|
|
381
|
-
signal,
|
|
382
|
-
lastEventId,
|
|
383
|
-
streamMode: joinOptions?.streamMode
|
|
384
|
-
});
|
|
385
|
-
return joinOptions?.filter != null ? filterStream(rawStream, joinOptions.filter) : rawStream;
|
|
386
|
-
}, {
|
|
387
|
-
getMessages,
|
|
388
|
-
setMessages,
|
|
389
|
-
initialValues: get(historyValues),
|
|
390
|
-
callbacks: options,
|
|
391
|
-
async onSuccess() {
|
|
392
|
-
runMetadataStorage?.removeItem(`lg:stream:${tid}`);
|
|
393
|
-
const lastHead = (await mutate(tid))?.at(0);
|
|
394
|
-
if (lastHead) options.onFinish?.(lastHead, callbackMeta);
|
|
395
|
-
},
|
|
396
|
-
onError(error) {
|
|
397
|
-
options.onError?.(error, callbackMeta);
|
|
398
|
-
},
|
|
399
|
-
onFinish: () => {}
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
let shouldReconnect = !!runMetadataStorage;
|
|
403
|
-
onMount(() => {
|
|
404
|
-
const tid = get(threadId);
|
|
405
|
-
if (shouldReconnect && runMetadataStorage && tid) {
|
|
406
|
-
const runId = runMetadataStorage.getItem(`lg:stream:${tid}`);
|
|
407
|
-
if (runId) {
|
|
408
|
-
shouldReconnect = false;
|
|
409
|
-
joinStream(runId);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
157
|
+
const errorStore = derived(version, () => orchestrator.error);
|
|
158
|
+
const isLoadingStore = derived(version, () => orchestrator.isLoading);
|
|
159
|
+
const branchStore = derived(version, () => orchestrator.branch);
|
|
160
|
+
const messagesStore = derived(version, () => {
|
|
161
|
+
orchestrator.trackStreamMode("messages-tuple", "values");
|
|
162
|
+
return ensureMessageInstances(orchestrator.messages);
|
|
412
163
|
});
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
streamError,
|
|
417
|
-
branchContext,
|
|
418
|
-
isLoading
|
|
419
|
-
], ([$streamValues, $streamError, $branchContext, $isLoading]) => {
|
|
420
|
-
return extractInterrupts($streamValues, {
|
|
421
|
-
isLoading: $isLoading,
|
|
422
|
-
threadState: $branchContext.threadHead,
|
|
423
|
-
error: $streamError
|
|
424
|
-
});
|
|
164
|
+
const toolCallsStore = derived(version, () => {
|
|
165
|
+
orchestrator.trackStreamMode("messages-tuple", "values");
|
|
166
|
+
return orchestrator.toolCalls;
|
|
425
167
|
});
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
const valueInterrupts = vals.__interrupt__;
|
|
435
|
-
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
436
|
-
return valueInterrupts;
|
|
437
|
-
}
|
|
438
|
-
if ($isLoading) return [];
|
|
439
|
-
const allInterrupts = ($branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
|
|
440
|
-
if (allInterrupts.length > 0) return allInterrupts;
|
|
441
|
-
if (!($branchContext.threadHead?.next ?? []).length || $streamError != null) return [];
|
|
442
|
-
return [{ when: "breakpoint" }];
|
|
443
|
-
});
|
|
444
|
-
const toolCalls = derived([streamValues, historyValues], ([$streamValues, $historyValues]) => getToolCallsWithResults(getMessages($streamValues ?? $historyValues)));
|
|
445
|
-
function getToolCalls(message) {
|
|
446
|
-
return getToolCallsWithResults(getMessages(get(streamValues) ?? get(historyValues))).filter((tc) => tc.aiMessage.id === message.id);
|
|
447
|
-
}
|
|
448
|
-
const historyList = derived([branchContext], ([$branchContext]) => {
|
|
449
|
-
if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `history`");
|
|
450
|
-
return ensureHistoryMessageInstances($branchContext.flatHistory, options.messagesKey ?? "messages");
|
|
168
|
+
const interruptStore = derived(version, () => orchestrator.interrupt);
|
|
169
|
+
const interruptsStore = derived(version, () => orchestrator.interrupts);
|
|
170
|
+
const historyListStore = derived(version, () => orchestrator.flatHistory);
|
|
171
|
+
const isThreadLoadingStore = derived(version, () => orchestrator.isThreadLoading);
|
|
172
|
+
const experimentalBranchTreeStore = derived(version, () => orchestrator.experimental_branchTree);
|
|
173
|
+
const subagentsStore = derived(version, () => {
|
|
174
|
+
orchestrator.trackStreamMode("updates", "messages-tuple");
|
|
175
|
+
return orchestrator.subagents;
|
|
451
176
|
});
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return $branchContext.branchTree;
|
|
177
|
+
const activeSubagentsStore = derived(version, () => {
|
|
178
|
+
orchestrator.trackStreamMode("updates", "messages-tuple");
|
|
179
|
+
return orchestrator.activeSubagents;
|
|
456
180
|
});
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
const
|
|
467
|
-
const
|
|
468
|
-
const
|
|
469
|
-
const
|
|
470
|
-
const isThreadLoadingRef = fromStore(isThreadLoading);
|
|
471
|
-
const branchRef = fromStore(branch);
|
|
472
|
-
const messagesRef = fromStore(messages);
|
|
473
|
-
const toolCallsRef = fromStore(toolCalls);
|
|
474
|
-
const interruptRef = fromStore(interrupt);
|
|
475
|
-
const interruptsRef = fromStore(interrupts);
|
|
476
|
-
const historyListRef = fromStore(historyList);
|
|
477
|
-
const experimentalBranchTreeRef = fromStore(experimentalBranchTree);
|
|
181
|
+
const queueEntriesStore = derived(version, () => orchestrator.queueEntries);
|
|
182
|
+
const queueSizeStore = derived(version, () => orchestrator.queueSize);
|
|
183
|
+
const valuesRef = fromStore(valuesStore);
|
|
184
|
+
const errorRef = fromStore(errorStore);
|
|
185
|
+
const isLoadingRef = fromStore(isLoadingStore);
|
|
186
|
+
const branchRef = fromStore(branchStore);
|
|
187
|
+
const messagesRef = fromStore(messagesStore);
|
|
188
|
+
const toolCallsRef = fromStore(toolCallsStore);
|
|
189
|
+
const interruptRef = fromStore(interruptStore);
|
|
190
|
+
const interruptsRef = fromStore(interruptsStore);
|
|
191
|
+
const historyListRef = fromStore(historyListStore);
|
|
192
|
+
const isThreadLoadingRef = fromStore(isThreadLoadingStore);
|
|
193
|
+
const experimentalBranchTreeRef = fromStore(experimentalBranchTreeStore);
|
|
478
194
|
const subagentsRef = fromStore(subagentsStore);
|
|
479
195
|
const activeSubagentsRef = fromStore(activeSubagentsStore);
|
|
480
|
-
const queueEntriesRef = fromStore(
|
|
481
|
-
const queueSizeRef = fromStore(
|
|
196
|
+
const queueEntriesRef = fromStore(queueEntriesStore);
|
|
197
|
+
const queueSizeRef = fromStore(queueSizeStore);
|
|
482
198
|
return {
|
|
483
199
|
assistantId: options.assistantId,
|
|
484
200
|
client,
|
|
@@ -497,14 +213,18 @@ function useStreamLGP(options) {
|
|
|
497
213
|
get branch() {
|
|
498
214
|
return branchRef.current;
|
|
499
215
|
},
|
|
500
|
-
setBranch
|
|
216
|
+
setBranch(value) {
|
|
217
|
+
orchestrator.setBranch(value);
|
|
218
|
+
},
|
|
501
219
|
get messages() {
|
|
502
220
|
return messagesRef.current;
|
|
503
221
|
},
|
|
504
222
|
get toolCalls() {
|
|
505
223
|
return toolCallsRef.current;
|
|
506
224
|
},
|
|
507
|
-
getToolCalls
|
|
225
|
+
getToolCalls(message) {
|
|
226
|
+
return orchestrator.getToolCalls(message);
|
|
227
|
+
},
|
|
508
228
|
get interrupt() {
|
|
509
229
|
return interruptRef.current;
|
|
510
230
|
},
|
|
@@ -517,10 +237,12 @@ function useStreamLGP(options) {
|
|
|
517
237
|
get experimental_branchTree() {
|
|
518
238
|
return experimentalBranchTreeRef.current;
|
|
519
239
|
},
|
|
520
|
-
getMessagesMetadata,
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
240
|
+
getMessagesMetadata(message, index) {
|
|
241
|
+
return orchestrator.getMessagesMetadata(message, index);
|
|
242
|
+
},
|
|
243
|
+
submit: (...args) => orchestrator.submit(...args),
|
|
244
|
+
stop: () => orchestrator.stop(),
|
|
245
|
+
joinStream: (...args) => orchestrator.joinStream(...args),
|
|
524
246
|
queue: {
|
|
525
247
|
get entries() {
|
|
526
248
|
return queueEntriesRef.current;
|
|
@@ -528,27 +250,11 @@ function useStreamLGP(options) {
|
|
|
528
250
|
get size() {
|
|
529
251
|
return queueSizeRef.current;
|
|
530
252
|
},
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const removed = pendingRuns.remove(id);
|
|
534
|
-
if (removed && tid) await client.runs.cancel(tid, id);
|
|
535
|
-
return removed;
|
|
536
|
-
},
|
|
537
|
-
async clear() {
|
|
538
|
-
const tid = get(threadId);
|
|
539
|
-
const removed = pendingRuns.removeAll();
|
|
540
|
-
if (tid && removed.length > 0) await Promise.all(removed.map((e) => client.runs.cancel(tid, e.id)));
|
|
541
|
-
}
|
|
253
|
+
cancel: (id) => orchestrator.cancelQueueItem(id),
|
|
254
|
+
clear: () => orchestrator.clearQueue()
|
|
542
255
|
},
|
|
543
256
|
switchThread(newThreadId) {
|
|
544
|
-
|
|
545
|
-
const prevThreadId = get(threadId);
|
|
546
|
-
threadId.set(newThreadId ?? void 0);
|
|
547
|
-
stream.clear();
|
|
548
|
-
const removed = pendingRuns.removeAll();
|
|
549
|
-
if (prevThreadId && removed.length > 0) Promise.all(removed.map((e) => client.runs.cancel(prevThreadId, e.id)));
|
|
550
|
-
if (newThreadId != null) options.onThreadId?.(newThreadId);
|
|
551
|
-
}
|
|
257
|
+
orchestrator.switchThread(newThreadId);
|
|
552
258
|
},
|
|
553
259
|
get subagents() {
|
|
554
260
|
return subagentsRef.current;
|
|
@@ -557,13 +263,13 @@ function useStreamLGP(options) {
|
|
|
557
263
|
return activeSubagentsRef.current;
|
|
558
264
|
},
|
|
559
265
|
getSubagent(toolCallId) {
|
|
560
|
-
return
|
|
266
|
+
return orchestrator.getSubagent(toolCallId);
|
|
561
267
|
},
|
|
562
268
|
getSubagentsByType(type) {
|
|
563
|
-
return
|
|
269
|
+
return orchestrator.getSubagentsByType(type);
|
|
564
270
|
},
|
|
565
271
|
getSubagentsByMessage(messageId) {
|
|
566
|
-
return
|
|
272
|
+
return orchestrator.getSubagentsByMessage(messageId);
|
|
567
273
|
}
|
|
568
274
|
};
|
|
569
275
|
}
|