@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.js CHANGED
@@ -1,10 +1,8 @@
1
1
  import { useStreamCustom } from "./stream.custom.js";
2
- import { getStream, provideStream } from "./context.js";
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, MessageTupleManager, PendingRunsTracker, StreamError, StreamManager, SubagentManager, calculateDepthFromNamespace, ensureHistoryMessageInstances, ensureMessageInstances, extractInterrupts, extractParentIdFromNamespace, extractToolCallIdFromNamespace, filterStream, getBranchContext, getMessagesMetadataMap, isSubagentNamespace, toMessageClass } from "@langchain/langgraph-sdk/ui";
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}. Must be called during component
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
- function fetchHistory(client, threadId, options) {
53
- if (options?.limit === false) return client.threads.getState(threadId).then((state) => {
54
- if (state.checkpoint == null) return [];
55
- return [state];
56
- });
57
- const limit = typeof options?.limit === "number" ? options.limit : 10;
58
- return client.threads.getHistory(threadId, { limit });
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 history = writable({
88
- data: void 0,
89
- error: void 0,
90
- isLoading: false,
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
- const shouldReconstructSubagents = derived([isLoading, history], ([$isLoading, $history]) => {
169
- if (!options.filterSubagentMessages) return false;
170
- if ($isLoading || $history.isLoading) return false;
171
- return getMessages(get(historyValues)).length > 0;
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 = shouldReconstructSubagents.subscribe(($should) => {
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 = new AbortController();
180
- const tid = get(threadId);
181
- if (tid) stream.fetchSubagentHistory(client.threads, tid, {
182
- messagesKey: options.messagesKey ?? "messages",
183
- signal: fetchController.signal
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
- unsubQueue();
150
+ unsubDrain();
151
+ orchestrator.dispose();
192
152
  });
193
- function stop() {
194
- return stream.stop(get(historyValues), { onStop: (args) => {
195
- const tid = get(threadId);
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
- async function submit(values, submitOptions) {
323
- if (stream.isLoading || submitting) {
324
- if (submitOptions?.multitaskStrategy === "interrupt" || submitOptions?.multitaskStrategy === "rollback") {
325
- submitting = true;
326
- try {
327
- await submitDirect(values, submitOptions);
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 messages = derived([streamValues, historyValues], ([$streamValues, $historyValues]) => ensureMessageInstances(getMessages($streamValues ?? $historyValues)));
414
- const interrupt = derived([
415
- streamValues,
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 interrupts = derived([
427
- streamValues,
428
- streamError,
429
- branchContext,
430
- isLoading
431
- ], ([$streamValues, $streamError, $branchContext, $isLoading]) => {
432
- const vals = $streamValues ?? get(historyValues);
433
- if (vals != null && "__interrupt__" in vals && Array.isArray(vals.__interrupt__)) {
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 isThreadLoading = derived([history], ([$history]) => $history.isLoading && $history.data == null);
453
- const experimentalBranchTree = derived([branchContext], ([$branchContext]) => {
454
- if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `experimental_branchTree`");
455
- return $branchContext.branchTree;
177
+ const activeSubagentsStore = derived(version, () => {
178
+ orchestrator.trackStreamMode("updates", "messages-tuple");
179
+ return orchestrator.activeSubagents;
456
180
  });
457
- function getMessagesMetadata(message, index) {
458
- const streamMetadata = messageManager.get(message.id)?.metadata;
459
- const historyMetadata = get(messageMetadata)?.find((m) => m.messageId === (message.id ?? index));
460
- if (streamMetadata != null || historyMetadata != null) return {
461
- ...historyMetadata,
462
- streamMetadata
463
- };
464
- }
465
- const subagentsStore = derived(subagentVersion, () => stream.getSubagents());
466
- const activeSubagentsStore = derived(subagentVersion, () => stream.getActiveSubagents());
467
- const valuesRef = fromStore(values);
468
- const errorRef = fromStore(error);
469
- const isLoadingRef = fromStore(isLoading);
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(queueEntries);
481
- const queueSizeRef = fromStore(queueSize);
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
- submit,
522
- stop,
523
- joinStream,
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
- async cancel(id) {
532
- const tid = get(threadId);
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
- if (newThreadId !== (get(threadId) ?? null)) {
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 stream.getSubagent(toolCallId);
266
+ return orchestrator.getSubagent(toolCallId);
561
267
  },
562
268
  getSubagentsByType(type) {
563
- return stream.getSubagentsByType(type);
269
+ return orchestrator.getSubagentsByType(type);
564
270
  },
565
271
  getSubagentsByMessage(messageId) {
566
- return stream.getSubagentsByMessage(messageId);
272
+ return orchestrator.getSubagentsByMessage(messageId);
567
273
  }
568
274
  };
569
275
  }