@langchain/langgraph-sdk 1.7.1 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/index.cjs +10 -46
- package/dist/react/index.d.cts +11 -14
- package/dist/react/index.d.ts +11 -14
- package/dist/react/index.js +3 -13
- package/dist/react/stream.cjs +17 -0
- package/dist/react/stream.cjs.map +1 -0
- package/dist/react/stream.custom.cjs +162 -0
- package/dist/react/stream.custom.cjs.map +1 -0
- package/dist/react/stream.custom.d.cts +40 -0
- package/dist/react/stream.custom.d.cts.map +1 -0
- package/dist/react/stream.custom.d.ts +39 -0
- package/dist/react/stream.custom.d.ts.map +1 -0
- package/dist/react/stream.custom.js +160 -0
- package/dist/react/stream.custom.js.map +1 -0
- package/dist/react/stream.d.cts +10 -0
- package/dist/react/stream.d.cts.map +1 -0
- package/dist/react/stream.d.ts +9 -0
- package/dist/react/stream.d.ts.map +1 -0
- package/dist/react/stream.js +16 -0
- package/dist/react/stream.js.map +1 -0
- package/dist/react/stream.lgp.cjs +550 -0
- package/dist/react/stream.lgp.cjs.map +1 -0
- package/dist/react/stream.lgp.js +549 -0
- package/dist/react/stream.lgp.js.map +1 -0
- package/dist/react/thread.cjs +19 -0
- package/dist/react/thread.cjs.map +1 -0
- package/dist/react/thread.js +18 -0
- package/dist/react/thread.js.map +1 -0
- package/dist/react/types.d.cts +79 -0
- package/dist/react/types.d.cts.map +1 -0
- package/dist/react/types.d.ts +79 -0
- package/dist/react/types.d.ts.map +1 -0
- package/dist/react-ui/client.cjs +136 -0
- package/dist/react-ui/client.cjs.map +1 -0
- package/dist/react-ui/client.d.cts +67 -0
- package/dist/react-ui/client.d.cts.map +1 -0
- package/dist/react-ui/client.d.ts +67 -0
- package/dist/react-ui/client.d.ts.map +1 -0
- package/dist/react-ui/client.js +130 -0
- package/dist/react-ui/client.js.map +1 -0
- package/dist/react-ui/index.cjs +13 -38
- package/dist/react-ui/index.cjs.map +1 -0
- package/dist/react-ui/index.d.cts +2 -1
- package/dist/react-ui/index.d.ts +2 -1
- package/dist/react-ui/index.js +7 -1
- package/dist/react-ui/index.js.map +1 -0
- package/dist/react-ui/server/index.cjs +4 -14
- package/dist/react-ui/server/index.d.cts +2 -1
- package/dist/react-ui/server/index.d.ts +2 -1
- package/dist/react-ui/server/index.js +2 -1
- package/dist/react-ui/server/server.cjs +56 -0
- package/dist/react-ui/server/server.cjs.map +1 -0
- package/dist/react-ui/server/server.d.cts +54 -0
- package/dist/react-ui/server/server.d.cts.map +1 -0
- package/dist/react-ui/server/server.d.ts +54 -0
- package/dist/react-ui/server/server.d.ts.map +1 -0
- package/dist/react-ui/server/server.js +55 -0
- package/dist/react-ui/server/server.js.map +1 -0
- package/dist/react-ui/types.cjs +37 -0
- package/dist/react-ui/types.cjs.map +1 -0
- package/dist/react-ui/types.d.cts +25 -0
- package/dist/react-ui/types.d.cts.map +1 -0
- package/dist/react-ui/types.d.ts +25 -0
- package/dist/react-ui/types.d.ts.map +1 -0
- package/dist/react-ui/types.js +35 -0
- package/dist/react-ui/types.js.map +1 -0
- package/dist/ui/index.d.cts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +11 -3
- package/dist/react/index.cjs.map +0 -1
- package/dist/react/index.d.cts.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.custom.js","names":[],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { Interrupt } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> implements UseStreamTransport<StateType, Bag>\n{\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n // generate random thread id\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => undefined,\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\n };\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return valueInterrupts;\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BagTemplate } from "../types.template.cjs";
|
|
2
|
+
import { UseStreamCustomOptions } from "../ui/types.cjs";
|
|
3
|
+
import { InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.cjs";
|
|
4
|
+
|
|
5
|
+
//#region src/react/stream.d.ts
|
|
6
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: ResolveStreamOptions<T, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
7
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useStream };
|
|
10
|
+
//# sourceMappingURL=stream.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.cts","names":[],"sources":["../../src/react/stream.tsx"],"mappings":";;;;;iBAwBgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;AAAA,iBAEzB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,sBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BagTemplate } from "../types.template.js";
|
|
2
|
+
import { UseStreamCustomOptions } from "../ui/types.js";
|
|
3
|
+
import { InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.js";
|
|
4
|
+
//#region src/react/stream.d.ts
|
|
5
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: ResolveStreamOptions<T, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
6
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { useStream };
|
|
9
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","names":[],"sources":["../../src/react/stream.tsx"],"mappings":";;;;iBAwBgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;AAAA,iBAEzB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,sBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useStreamLGP } from "./stream.lgp.js";
|
|
2
|
+
import { useStreamCustom } from "./stream.custom.js";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
//#region src/react/stream.tsx
|
|
5
|
+
function isCustomOptions(options) {
|
|
6
|
+
return "transport" in options;
|
|
7
|
+
}
|
|
8
|
+
function useStream(options) {
|
|
9
|
+
const [isCustom] = useState(isCustomOptions(options));
|
|
10
|
+
if (isCustom) return useStreamCustom(options);
|
|
11
|
+
return useStreamLGP(options);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useStream };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","names":[],"sources":["../../src/react/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamOptions } from \"../ui/types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\nimport type {\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n} from \"../ui/stream/index.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>\n): ResolveStreamInterface<T, InferBag<T, Bag>>;\n\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>\n): ResolveStreamInterface<T, InferBag<T, Bag>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Store this in useState to make sure we're not changing the implementation in re-renders\n const [isCustom] = useState(isCustomOptions(options));\n\n if (isCustom) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamCustom(options);\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamLGP(options);\n}\n"],"mappings":";;;;AAaA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AAkBxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,YAAY,SAAS,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAO,gBAAgB,QAAQ;AAIjC,QAAO,aAAa,QAAQ"}
|
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_client = require("../client.cjs");
|
|
4
|
+
const require_errors = require("../ui/errors.cjs");
|
|
5
|
+
const require_messages = require("../ui/messages.cjs");
|
|
6
|
+
const require_tools = require("../utils/tools.cjs");
|
|
7
|
+
const require_manager = require("../ui/manager.cjs");
|
|
8
|
+
const require_utils = require("../ui/utils.cjs");
|
|
9
|
+
const require_branching = require("../ui/branching.cjs");
|
|
10
|
+
const require_thread = require("./thread.cjs");
|
|
11
|
+
let react = require("react");
|
|
12
|
+
//#region src/react/stream.lgp.tsx
|
|
13
|
+
function getFetchHistoryKey(client, threadId, limit) {
|
|
14
|
+
return [
|
|
15
|
+
require_client.getClientConfigHash(client),
|
|
16
|
+
threadId,
|
|
17
|
+
limit
|
|
18
|
+
].join(":");
|
|
19
|
+
}
|
|
20
|
+
function fetchHistory(client, threadId, options) {
|
|
21
|
+
if (options?.limit === false) return client.threads.getState(threadId).then((state) => {
|
|
22
|
+
if (state.checkpoint == null) return [];
|
|
23
|
+
return [state];
|
|
24
|
+
});
|
|
25
|
+
const limit = typeof options?.limit === "number" ? options.limit : 10;
|
|
26
|
+
return client.threads.getHistory(threadId, { limit });
|
|
27
|
+
}
|
|
28
|
+
function useThreadHistory(client, threadId, limit, options) {
|
|
29
|
+
const key = getFetchHistoryKey(client, threadId, limit);
|
|
30
|
+
const [state, setState] = (0, react.useState)(() => ({
|
|
31
|
+
key: void 0,
|
|
32
|
+
data: void 0,
|
|
33
|
+
error: void 0,
|
|
34
|
+
isLoading: threadId != null
|
|
35
|
+
}));
|
|
36
|
+
const clientRef = (0, react.useRef)(client);
|
|
37
|
+
clientRef.current = client;
|
|
38
|
+
const onErrorRef = (0, react.useRef)(options?.onError);
|
|
39
|
+
onErrorRef.current = options?.onError;
|
|
40
|
+
const fetcher = (0, react.useCallback)((threadId, limit) => {
|
|
41
|
+
if (options.passthrough) return Promise.resolve([]);
|
|
42
|
+
const client = clientRef.current;
|
|
43
|
+
const key = getFetchHistoryKey(client, threadId, limit);
|
|
44
|
+
if (threadId != null) {
|
|
45
|
+
setState((state) => {
|
|
46
|
+
if (state.key === key) return {
|
|
47
|
+
...state,
|
|
48
|
+
isLoading: true
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
key,
|
|
52
|
+
data: void 0,
|
|
53
|
+
error: void 0,
|
|
54
|
+
isLoading: true
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
return fetchHistory(client, threadId, { limit }).then((data) => {
|
|
58
|
+
setState((state) => {
|
|
59
|
+
if (state.key !== key) return state;
|
|
60
|
+
return {
|
|
61
|
+
key,
|
|
62
|
+
data,
|
|
63
|
+
error: void 0,
|
|
64
|
+
isLoading: false
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
return data;
|
|
68
|
+
}, (error) => {
|
|
69
|
+
setState((state) => {
|
|
70
|
+
if (state.key !== key) return state;
|
|
71
|
+
return {
|
|
72
|
+
key,
|
|
73
|
+
data: state.data,
|
|
74
|
+
error,
|
|
75
|
+
isLoading: false
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
onErrorRef.current?.(error);
|
|
79
|
+
return Promise.reject(error);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
setState({
|
|
83
|
+
key,
|
|
84
|
+
data: void 0,
|
|
85
|
+
error: void 0,
|
|
86
|
+
isLoading: false
|
|
87
|
+
});
|
|
88
|
+
return Promise.resolve([]);
|
|
89
|
+
}, [options.passthrough]);
|
|
90
|
+
(0, react.useEffect)(() => {
|
|
91
|
+
if (options.submittingRef.current != null && options.submittingRef.current === threadId) return;
|
|
92
|
+
fetcher(threadId, limit);
|
|
93
|
+
}, [fetcher, key]);
|
|
94
|
+
return {
|
|
95
|
+
data: state.data,
|
|
96
|
+
error: state.error,
|
|
97
|
+
isLoading: state.isLoading,
|
|
98
|
+
mutate: (mutateId) => fetcher(mutateId ?? threadId, limit)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function useStreamLGP(options) {
|
|
102
|
+
const reconnectOnMountRef = (0, react.useRef)(options.reconnectOnMount);
|
|
103
|
+
const runMetadataStorage = (0, react.useMemo)(() => {
|
|
104
|
+
if (typeof window === "undefined") return null;
|
|
105
|
+
const storage = reconnectOnMountRef.current;
|
|
106
|
+
if (storage === true) return window.sessionStorage;
|
|
107
|
+
if (typeof storage === "function") return storage();
|
|
108
|
+
return null;
|
|
109
|
+
}, []);
|
|
110
|
+
const client = (0, react.useMemo)(() => options.client ?? new require_client.Client({
|
|
111
|
+
apiUrl: options.apiUrl,
|
|
112
|
+
apiKey: options.apiKey,
|
|
113
|
+
callerOptions: options.callerOptions,
|
|
114
|
+
defaultHeaders: options.defaultHeaders
|
|
115
|
+
}), [
|
|
116
|
+
options.client,
|
|
117
|
+
options.apiKey,
|
|
118
|
+
options.apiUrl,
|
|
119
|
+
options.callerOptions,
|
|
120
|
+
options.defaultHeaders
|
|
121
|
+
]);
|
|
122
|
+
const [messageManager] = (0, react.useState)(() => new require_messages.MessageTupleManager());
|
|
123
|
+
const [stream] = (0, react.useState)(() => new require_manager.StreamManager(messageManager, {
|
|
124
|
+
throttle: options.throttle ?? false,
|
|
125
|
+
subagentToolNames: options.subagentToolNames,
|
|
126
|
+
filterSubagentMessages: options.filterSubagentMessages
|
|
127
|
+
}));
|
|
128
|
+
(0, react.useSyncExternalStore)(stream.subscribe, stream.getSnapshot, stream.getSnapshot);
|
|
129
|
+
const [threadId, onThreadId] = require_thread.useControllableThreadId(options);
|
|
130
|
+
const trackStreamModeRef = (0, react.useRef)([]);
|
|
131
|
+
const trackStreamMode = (0, react.useCallback)((...mode) => {
|
|
132
|
+
const ref = trackStreamModeRef.current;
|
|
133
|
+
for (const m of mode) if (!ref.includes(m)) ref.push(m);
|
|
134
|
+
}, []);
|
|
135
|
+
const hasUpdateListener = options.onUpdateEvent != null;
|
|
136
|
+
const hasCustomListener = options.onCustomEvent != null;
|
|
137
|
+
const hasLangChainListener = options.onLangChainEvent != null;
|
|
138
|
+
const hasDebugListener = options.onDebugEvent != null;
|
|
139
|
+
const hasCheckpointListener = options.onCheckpointEvent != null;
|
|
140
|
+
const hasTaskListener = options.onTaskEvent != null;
|
|
141
|
+
const hasToolListener = options.onToolEvent != null;
|
|
142
|
+
const callbackStreamMode = (0, react.useMemo)(() => {
|
|
143
|
+
const modes = [];
|
|
144
|
+
if (hasUpdateListener) modes.push("updates");
|
|
145
|
+
if (hasCustomListener) modes.push("custom");
|
|
146
|
+
if (hasLangChainListener) modes.push("events");
|
|
147
|
+
if (hasDebugListener) modes.push("debug");
|
|
148
|
+
if (hasCheckpointListener) modes.push("checkpoints");
|
|
149
|
+
if (hasTaskListener) modes.push("tasks");
|
|
150
|
+
if (hasToolListener) modes.push("tools");
|
|
151
|
+
return modes;
|
|
152
|
+
}, [
|
|
153
|
+
hasUpdateListener,
|
|
154
|
+
hasCustomListener,
|
|
155
|
+
hasLangChainListener,
|
|
156
|
+
hasDebugListener,
|
|
157
|
+
hasCheckpointListener,
|
|
158
|
+
hasTaskListener,
|
|
159
|
+
hasToolListener
|
|
160
|
+
]);
|
|
161
|
+
const threadIdRef = (0, react.useRef)(threadId);
|
|
162
|
+
const threadIdStreamingRef = (0, react.useRef)(null);
|
|
163
|
+
(0, react.useEffect)(() => {
|
|
164
|
+
if (threadIdRef.current !== threadId) {
|
|
165
|
+
threadIdRef.current = threadId;
|
|
166
|
+
stream.clear();
|
|
167
|
+
}
|
|
168
|
+
}, [threadId, stream]);
|
|
169
|
+
const switchThread = (0, react.useCallback)((newThreadId) => {
|
|
170
|
+
if (newThreadId !== threadIdRef.current) {
|
|
171
|
+
threadIdRef.current = newThreadId;
|
|
172
|
+
stream.clear();
|
|
173
|
+
onThreadId(newThreadId);
|
|
174
|
+
}
|
|
175
|
+
}, [stream, onThreadId]);
|
|
176
|
+
const historyLimit = typeof options.fetchStateHistory === "object" && options.fetchStateHistory != null ? options.fetchStateHistory.limit ?? false : options.fetchStateHistory ?? false;
|
|
177
|
+
const builtInHistory = useThreadHistory(client, threadId, historyLimit, {
|
|
178
|
+
passthrough: options.thread != null,
|
|
179
|
+
submittingRef: threadIdStreamingRef,
|
|
180
|
+
onError: options.onError
|
|
181
|
+
});
|
|
182
|
+
const history = options.thread ?? builtInHistory;
|
|
183
|
+
const getMessages = (value) => {
|
|
184
|
+
const messagesKey = options.messagesKey ?? "messages";
|
|
185
|
+
return Array.isArray(value[messagesKey]) ? value[messagesKey] : [];
|
|
186
|
+
};
|
|
187
|
+
const setMessages = (current, messages) => {
|
|
188
|
+
const messagesKey = options.messagesKey ?? "messages";
|
|
189
|
+
return {
|
|
190
|
+
...current,
|
|
191
|
+
[messagesKey]: messages
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const [branch, setBranch] = (0, react.useState)("");
|
|
195
|
+
const branchContext = require_branching.getBranchContext(branch, history.data ?? void 0);
|
|
196
|
+
const [toolProgressMap, setToolProgressMap] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
197
|
+
const handleToolEvent = (0, react.useCallback)((data) => {
|
|
198
|
+
setToolProgressMap((prev) => {
|
|
199
|
+
const next = new Map(prev);
|
|
200
|
+
const key = data.toolCallId ?? data.name;
|
|
201
|
+
const existing = next.get(key);
|
|
202
|
+
switch (data.event) {
|
|
203
|
+
case "on_tool_start":
|
|
204
|
+
next.set(key, {
|
|
205
|
+
toolCallId: data.toolCallId,
|
|
206
|
+
name: data.name,
|
|
207
|
+
state: "starting",
|
|
208
|
+
input: data.input
|
|
209
|
+
});
|
|
210
|
+
break;
|
|
211
|
+
case "on_tool_event":
|
|
212
|
+
if (existing) next.set(key, {
|
|
213
|
+
...existing,
|
|
214
|
+
state: "running",
|
|
215
|
+
data: data.data
|
|
216
|
+
});
|
|
217
|
+
break;
|
|
218
|
+
case "on_tool_end":
|
|
219
|
+
if (existing) next.set(key, {
|
|
220
|
+
...existing,
|
|
221
|
+
state: "completed",
|
|
222
|
+
result: data.output
|
|
223
|
+
});
|
|
224
|
+
break;
|
|
225
|
+
case "on_tool_error":
|
|
226
|
+
if (existing) next.set(key, {
|
|
227
|
+
...existing,
|
|
228
|
+
state: "error",
|
|
229
|
+
error: data.error
|
|
230
|
+
});
|
|
231
|
+
break;
|
|
232
|
+
default: throw new Error(`Unexpected tool event: ${data.event}`);
|
|
233
|
+
}
|
|
234
|
+
return next;
|
|
235
|
+
});
|
|
236
|
+
}, []);
|
|
237
|
+
const historyValues = branchContext.threadHead?.values ?? options.initialValues ?? {};
|
|
238
|
+
const historyMessages = getMessages(historyValues);
|
|
239
|
+
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && !history.isLoading && historyMessages.length > 0;
|
|
240
|
+
(0, react.useEffect)(() => {
|
|
241
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
242
|
+
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
243
|
+
const historyError = (() => {
|
|
244
|
+
const error = branchContext.threadHead?.tasks?.at(-1)?.error;
|
|
245
|
+
if (error == null) return void 0;
|
|
246
|
+
try {
|
|
247
|
+
const parsed = JSON.parse(error);
|
|
248
|
+
if (require_errors.StreamError.isStructuredError(parsed)) return new require_errors.StreamError(parsed);
|
|
249
|
+
return parsed;
|
|
250
|
+
} catch {}
|
|
251
|
+
return error;
|
|
252
|
+
})();
|
|
253
|
+
const messageMetadata = (() => {
|
|
254
|
+
const alreadyShown = /* @__PURE__ */ new Set();
|
|
255
|
+
return getMessages(historyValues).map((message, idx) => {
|
|
256
|
+
const messageId = message.id ?? idx;
|
|
257
|
+
const firstSeenState = require_utils.findLast(history.data ?? [], (state) => getMessages(state.values).map((m, idx) => m.id ?? idx).includes(messageId));
|
|
258
|
+
const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;
|
|
259
|
+
let branch = checkpointId != null ? branchContext.branchByCheckpoint[checkpointId] : void 0;
|
|
260
|
+
if (!branch?.branch?.length) branch = void 0;
|
|
261
|
+
const optionsShown = branch?.branchOptions?.flat(2).join(",");
|
|
262
|
+
if (optionsShown) {
|
|
263
|
+
if (alreadyShown.has(optionsShown)) branch = void 0;
|
|
264
|
+
alreadyShown.add(optionsShown);
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
messageId: messageId.toString(),
|
|
268
|
+
firstSeenState,
|
|
269
|
+
branch: branch?.branch,
|
|
270
|
+
branchOptions: branch?.branchOptions
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
})();
|
|
274
|
+
const stop = () => stream.stop(historyValues, { onStop: (args) => {
|
|
275
|
+
if (runMetadataStorage && threadId) {
|
|
276
|
+
const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);
|
|
277
|
+
if (runId) client.runs.cancel(threadId, runId);
|
|
278
|
+
runMetadataStorage.removeItem(`lg:stream:${threadId}`);
|
|
279
|
+
}
|
|
280
|
+
options.onStop?.(args);
|
|
281
|
+
} });
|
|
282
|
+
const submit = async (values, submitOptions) => {
|
|
283
|
+
setToolProgressMap(/* @__PURE__ */ new Map());
|
|
284
|
+
const checkpointId = submitOptions?.checkpoint?.checkpoint_id;
|
|
285
|
+
setBranch(checkpointId != null ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? "" : "");
|
|
286
|
+
const includeImplicitBranch = historyLimit === true || typeof historyLimit === "number";
|
|
287
|
+
const shouldRefetch = options.onFinish != null || includeImplicitBranch;
|
|
288
|
+
let callbackMeta;
|
|
289
|
+
let rejoinKey;
|
|
290
|
+
let usableThreadId = threadId;
|
|
291
|
+
const shouldAbortPrevious = (submitOptions?.multitaskStrategy === "interrupt" || submitOptions?.multitaskStrategy === "rollback") && stream.isLoading;
|
|
292
|
+
await stream.start(async (signal) => {
|
|
293
|
+
stream.setStreamValues((values) => {
|
|
294
|
+
const prev = {
|
|
295
|
+
...historyValues,
|
|
296
|
+
...values
|
|
297
|
+
};
|
|
298
|
+
if (submitOptions?.optimisticValues != null) return {
|
|
299
|
+
...prev,
|
|
300
|
+
...typeof submitOptions.optimisticValues === "function" ? submitOptions.optimisticValues(prev) : submitOptions.optimisticValues
|
|
301
|
+
};
|
|
302
|
+
return { ...prev };
|
|
303
|
+
});
|
|
304
|
+
if (!usableThreadId) {
|
|
305
|
+
usableThreadId = (await client.threads.create({
|
|
306
|
+
threadId: submitOptions?.threadId,
|
|
307
|
+
metadata: submitOptions?.metadata,
|
|
308
|
+
signal
|
|
309
|
+
})).thread_id;
|
|
310
|
+
threadIdRef.current = usableThreadId;
|
|
311
|
+
threadIdStreamingRef.current = usableThreadId;
|
|
312
|
+
onThreadId(usableThreadId);
|
|
313
|
+
}
|
|
314
|
+
if (!usableThreadId) throw new Error("Failed to obtain valid thread ID.");
|
|
315
|
+
threadIdStreamingRef.current = usableThreadId;
|
|
316
|
+
const streamMode = require_utils.unique([
|
|
317
|
+
...submitOptions?.streamMode ?? [],
|
|
318
|
+
...trackStreamModeRef.current,
|
|
319
|
+
...callbackStreamMode
|
|
320
|
+
]);
|
|
321
|
+
let checkpoint = submitOptions?.checkpoint ?? (includeImplicitBranch ? branchContext.threadHead?.checkpoint : void 0) ?? void 0;
|
|
322
|
+
if (submitOptions?.checkpoint === null) checkpoint = void 0;
|
|
323
|
+
if (checkpoint != null) delete checkpoint.thread_id;
|
|
324
|
+
const streamResumable = submitOptions?.streamResumable ?? !!runMetadataStorage;
|
|
325
|
+
return client.runs.stream(usableThreadId, options.assistantId, {
|
|
326
|
+
input: values,
|
|
327
|
+
config: submitOptions?.config,
|
|
328
|
+
context: submitOptions?.context,
|
|
329
|
+
command: submitOptions?.command,
|
|
330
|
+
interruptBefore: submitOptions?.interruptBefore,
|
|
331
|
+
interruptAfter: submitOptions?.interruptAfter,
|
|
332
|
+
metadata: submitOptions?.metadata,
|
|
333
|
+
multitaskStrategy: submitOptions?.multitaskStrategy,
|
|
334
|
+
onCompletion: submitOptions?.onCompletion,
|
|
335
|
+
onDisconnect: submitOptions?.onDisconnect ?? (streamResumable ? "continue" : "cancel"),
|
|
336
|
+
signal,
|
|
337
|
+
checkpoint,
|
|
338
|
+
streamMode,
|
|
339
|
+
streamSubgraphs: submitOptions?.streamSubgraphs,
|
|
340
|
+
streamResumable,
|
|
341
|
+
durability: submitOptions?.durability,
|
|
342
|
+
onRunCreated(params) {
|
|
343
|
+
callbackMeta = {
|
|
344
|
+
run_id: params.run_id,
|
|
345
|
+
thread_id: params.thread_id ?? usableThreadId
|
|
346
|
+
};
|
|
347
|
+
if (runMetadataStorage) {
|
|
348
|
+
rejoinKey = `lg:stream:${usableThreadId}`;
|
|
349
|
+
runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);
|
|
350
|
+
}
|
|
351
|
+
options.onCreated?.(callbackMeta);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}, {
|
|
355
|
+
getMessages,
|
|
356
|
+
setMessages,
|
|
357
|
+
initialValues: historyValues,
|
|
358
|
+
callbacks: {
|
|
359
|
+
...options,
|
|
360
|
+
onToolEvent: (data, opts) => {
|
|
361
|
+
handleToolEvent(data);
|
|
362
|
+
options.onToolEvent?.(data, opts);
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
async onSuccess() {
|
|
366
|
+
if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);
|
|
367
|
+
if (shouldRefetch) {
|
|
368
|
+
const lastHead = (await history.mutate(usableThreadId))?.at(0);
|
|
369
|
+
if (lastHead) {
|
|
370
|
+
options.onFinish?.(lastHead, callbackMeta);
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
onError(error) {
|
|
376
|
+
options.onError?.(error, callbackMeta);
|
|
377
|
+
},
|
|
378
|
+
onFinish() {
|
|
379
|
+
threadIdStreamingRef.current = null;
|
|
380
|
+
}
|
|
381
|
+
}, { abortPrevious: shouldAbortPrevious });
|
|
382
|
+
};
|
|
383
|
+
const joinStream = async (runId, lastEventId, joinOptions) => {
|
|
384
|
+
setToolProgressMap(/* @__PURE__ */ new Map());
|
|
385
|
+
lastEventId ??= "-1";
|
|
386
|
+
if (!threadId) return;
|
|
387
|
+
const callbackMeta = {
|
|
388
|
+
thread_id: threadId,
|
|
389
|
+
run_id: runId
|
|
390
|
+
};
|
|
391
|
+
await stream.start(async (signal) => {
|
|
392
|
+
threadIdStreamingRef.current = threadId;
|
|
393
|
+
const stream = client.runs.joinStream(threadId, runId, {
|
|
394
|
+
signal,
|
|
395
|
+
lastEventId,
|
|
396
|
+
streamMode: joinOptions?.streamMode
|
|
397
|
+
});
|
|
398
|
+
return joinOptions?.filter != null ? require_utils.filterStream(stream, joinOptions.filter) : stream;
|
|
399
|
+
}, {
|
|
400
|
+
getMessages,
|
|
401
|
+
setMessages,
|
|
402
|
+
initialValues: historyValues,
|
|
403
|
+
callbacks: {
|
|
404
|
+
...options,
|
|
405
|
+
onToolEvent: (data, opts) => {
|
|
406
|
+
handleToolEvent(data);
|
|
407
|
+
options.onToolEvent?.(data, opts);
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
async onSuccess() {
|
|
411
|
+
runMetadataStorage?.removeItem(`lg:stream:${threadId}`);
|
|
412
|
+
const lastHead = (await history.mutate(threadId))?.at(0);
|
|
413
|
+
if (lastHead) options.onFinish?.(lastHead, callbackMeta);
|
|
414
|
+
},
|
|
415
|
+
onError(error) {
|
|
416
|
+
options.onError?.(error, callbackMeta);
|
|
417
|
+
},
|
|
418
|
+
onFinish() {
|
|
419
|
+
threadIdStreamingRef.current = null;
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
};
|
|
423
|
+
const reconnectKey = (0, react.useMemo)(() => {
|
|
424
|
+
if (!runMetadataStorage || stream.isLoading) return void 0;
|
|
425
|
+
if (typeof window === "undefined") return void 0;
|
|
426
|
+
const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);
|
|
427
|
+
if (!runId) return void 0;
|
|
428
|
+
return {
|
|
429
|
+
runId,
|
|
430
|
+
threadId
|
|
431
|
+
};
|
|
432
|
+
}, [
|
|
433
|
+
runMetadataStorage,
|
|
434
|
+
stream.isLoading,
|
|
435
|
+
threadId
|
|
436
|
+
]);
|
|
437
|
+
const shouldReconnect = !!runMetadataStorage;
|
|
438
|
+
const reconnectRef = (0, react.useRef)({
|
|
439
|
+
threadId,
|
|
440
|
+
shouldReconnect
|
|
441
|
+
});
|
|
442
|
+
const joinStreamRef = (0, react.useRef)(joinStream);
|
|
443
|
+
joinStreamRef.current = joinStream;
|
|
444
|
+
(0, react.useEffect)(() => {
|
|
445
|
+
if (reconnectRef.current.threadId !== threadId) reconnectRef.current = {
|
|
446
|
+
threadId,
|
|
447
|
+
shouldReconnect
|
|
448
|
+
};
|
|
449
|
+
}, [threadId, shouldReconnect]);
|
|
450
|
+
(0, react.useEffect)(() => {
|
|
451
|
+
if (reconnectKey && reconnectRef.current.shouldReconnect) {
|
|
452
|
+
reconnectRef.current.shouldReconnect = false;
|
|
453
|
+
joinStreamRef.current?.(reconnectKey.runId);
|
|
454
|
+
}
|
|
455
|
+
}, [reconnectKey]);
|
|
456
|
+
const error = stream.error ?? historyError ?? history.error;
|
|
457
|
+
const values = stream.values ?? historyValues;
|
|
458
|
+
return {
|
|
459
|
+
get values() {
|
|
460
|
+
trackStreamMode("values");
|
|
461
|
+
return values;
|
|
462
|
+
},
|
|
463
|
+
client,
|
|
464
|
+
assistantId: options.assistantId,
|
|
465
|
+
error,
|
|
466
|
+
isLoading: stream.isLoading,
|
|
467
|
+
stop,
|
|
468
|
+
submit,
|
|
469
|
+
switchThread,
|
|
470
|
+
joinStream,
|
|
471
|
+
branch,
|
|
472
|
+
setBranch,
|
|
473
|
+
get history() {
|
|
474
|
+
if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `history`");
|
|
475
|
+
return branchContext.flatHistory;
|
|
476
|
+
},
|
|
477
|
+
isThreadLoading: history.isLoading && history.data == null,
|
|
478
|
+
get experimental_branchTree() {
|
|
479
|
+
if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `experimental_branchTree`");
|
|
480
|
+
return branchContext.branchTree;
|
|
481
|
+
},
|
|
482
|
+
get interrupts() {
|
|
483
|
+
if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__)) {
|
|
484
|
+
const valueInterrupts = values.__interrupt__;
|
|
485
|
+
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
486
|
+
return valueInterrupts;
|
|
487
|
+
}
|
|
488
|
+
if (stream.isLoading) return [];
|
|
489
|
+
const allInterrupts = (branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
|
|
490
|
+
if (allInterrupts.length > 0) return allInterrupts;
|
|
491
|
+
if (!(branchContext.threadHead?.next ?? []).length || error != null) return [];
|
|
492
|
+
return [{ when: "breakpoint" }];
|
|
493
|
+
},
|
|
494
|
+
get interrupt() {
|
|
495
|
+
const all = this.interrupts;
|
|
496
|
+
if (all.length === 0) return void 0;
|
|
497
|
+
if (all.length === 1) return all[0];
|
|
498
|
+
return all;
|
|
499
|
+
},
|
|
500
|
+
get messages() {
|
|
501
|
+
trackStreamMode("messages-tuple", "values");
|
|
502
|
+
return getMessages(values);
|
|
503
|
+
},
|
|
504
|
+
get toolCalls() {
|
|
505
|
+
trackStreamMode("messages-tuple", "values");
|
|
506
|
+
return require_tools.getToolCallsWithResults(getMessages(values));
|
|
507
|
+
},
|
|
508
|
+
get toolProgress() {
|
|
509
|
+
trackStreamMode("tools");
|
|
510
|
+
return Array.from(toolProgressMap.values());
|
|
511
|
+
},
|
|
512
|
+
getToolCalls(message) {
|
|
513
|
+
trackStreamMode("messages-tuple", "values");
|
|
514
|
+
return require_tools.getToolCallsWithResults(getMessages(values)).filter((tc) => tc.aiMessage.id === message.id);
|
|
515
|
+
},
|
|
516
|
+
getMessagesMetadata(message, index) {
|
|
517
|
+
trackStreamMode("values");
|
|
518
|
+
const streamMetadata = messageManager.get(message.id)?.metadata;
|
|
519
|
+
const historyMetadata = messageMetadata?.find((m) => m.messageId === (message.id ?? index));
|
|
520
|
+
if (streamMetadata != null || historyMetadata != null) return {
|
|
521
|
+
...historyMetadata,
|
|
522
|
+
streamMetadata
|
|
523
|
+
};
|
|
524
|
+
},
|
|
525
|
+
get subagents() {
|
|
526
|
+
trackStreamMode("updates", "messages-tuple");
|
|
527
|
+
return stream.getSubagents();
|
|
528
|
+
},
|
|
529
|
+
get activeSubagents() {
|
|
530
|
+
trackStreamMode("updates", "messages-tuple");
|
|
531
|
+
return stream.getActiveSubagents();
|
|
532
|
+
},
|
|
533
|
+
getSubagent(toolCallId) {
|
|
534
|
+
trackStreamMode("updates", "messages-tuple");
|
|
535
|
+
return stream.getSubagent(toolCallId);
|
|
536
|
+
},
|
|
537
|
+
getSubagentsByType(type) {
|
|
538
|
+
trackStreamMode("updates", "messages-tuple");
|
|
539
|
+
return stream.getSubagentsByType(type);
|
|
540
|
+
},
|
|
541
|
+
getSubagentsByMessage(messageId) {
|
|
542
|
+
trackStreamMode("updates", "messages-tuple");
|
|
543
|
+
return stream.getSubagentsByMessage(messageId);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
//#endregion
|
|
548
|
+
exports.useStreamLGP = useStreamLGP;
|
|
549
|
+
|
|
550
|
+
//# sourceMappingURL=stream.lgp.cjs.map
|