@langchain/langgraph-sdk 1.3.1 → 1.4.5

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.
Files changed (152) hide show
  1. package/dist/_virtual/rolldown_runtime.cjs +10 -6
  2. package/dist/auth/error.cjs.map +1 -1
  3. package/dist/auth/error.d.cts.map +1 -1
  4. package/dist/auth/error.d.ts.map +1 -1
  5. package/dist/auth/error.js.map +1 -1
  6. package/dist/auth/index.cjs.map +1 -1
  7. package/dist/auth/index.d.cts +1 -3
  8. package/dist/auth/index.d.cts.map +1 -1
  9. package/dist/auth/index.d.ts +1 -3
  10. package/dist/auth/index.d.ts.map +1 -1
  11. package/dist/auth/index.js.map +1 -1
  12. package/dist/auth/types.d.cts +1 -1
  13. package/dist/auth/types.d.cts.map +1 -1
  14. package/dist/auth/types.d.ts +1 -1
  15. package/dist/auth/types.d.ts.map +1 -1
  16. package/dist/client.cjs +15 -24
  17. package/dist/client.cjs.map +1 -1
  18. package/dist/client.d.cts +2 -6
  19. package/dist/client.d.cts.map +1 -1
  20. package/dist/client.d.ts +2 -6
  21. package/dist/client.d.ts.map +1 -1
  22. package/dist/client.js +15 -24
  23. package/dist/client.js.map +1 -1
  24. package/dist/index.d.cts +2 -1
  25. package/dist/index.d.ts +2 -1
  26. package/dist/logging/index.cjs.map +1 -1
  27. package/dist/logging/index.d.cts +0 -1
  28. package/dist/logging/index.d.cts.map +1 -1
  29. package/dist/logging/index.d.ts +0 -1
  30. package/dist/logging/index.d.ts.map +1 -1
  31. package/dist/logging/index.js.map +1 -1
  32. package/dist/react/index.d.cts +3 -2
  33. package/dist/react/index.d.ts +3 -2
  34. package/dist/react/stream.cjs +1 -1
  35. package/dist/react/stream.cjs.map +1 -1
  36. package/dist/react/stream.custom.cjs +12 -6
  37. package/dist/react/stream.custom.cjs.map +1 -1
  38. package/dist/react/stream.custom.d.cts +3 -2
  39. package/dist/react/stream.custom.d.cts.map +1 -1
  40. package/dist/react/stream.custom.d.ts +3 -2
  41. package/dist/react/stream.custom.d.ts.map +1 -1
  42. package/dist/react/stream.custom.js +11 -5
  43. package/dist/react/stream.custom.js.map +1 -1
  44. package/dist/react/stream.d.cts +116 -34
  45. package/dist/react/stream.d.cts.map +1 -1
  46. package/dist/react/stream.d.ts +116 -34
  47. package/dist/react/stream.d.ts.map +1 -1
  48. package/dist/react/stream.js.map +1 -1
  49. package/dist/react/stream.lgp.cjs +15 -13
  50. package/dist/react/stream.lgp.cjs.map +1 -1
  51. package/dist/react/stream.lgp.js +14 -12
  52. package/dist/react/stream.lgp.js.map +1 -1
  53. package/dist/react/thread.cjs +1 -2
  54. package/dist/react/thread.cjs.map +1 -1
  55. package/dist/react/thread.js +0 -1
  56. package/dist/react/thread.js.map +1 -1
  57. package/dist/react/types.d.cts +73 -284
  58. package/dist/react/types.d.cts.map +1 -1
  59. package/dist/react/types.d.ts +73 -284
  60. package/dist/react/types.d.ts.map +1 -1
  61. package/dist/react-ui/client.cjs +8 -7
  62. package/dist/react-ui/client.cjs.map +1 -1
  63. package/dist/react-ui/client.d.cts +4 -21
  64. package/dist/react-ui/client.d.cts.map +1 -1
  65. package/dist/react-ui/client.d.ts +4 -21
  66. package/dist/react-ui/client.d.ts.map +1 -1
  67. package/dist/react-ui/client.js +2 -4
  68. package/dist/react-ui/client.js.map +1 -1
  69. package/dist/react-ui/index.cjs.map +1 -1
  70. package/dist/react-ui/index.js.map +1 -1
  71. package/dist/react-ui/server/server.cjs +1 -1
  72. package/dist/react-ui/server/server.cjs.map +1 -1
  73. package/dist/react-ui/server/server.d.cts.map +1 -1
  74. package/dist/react-ui/server/server.d.ts.map +1 -1
  75. package/dist/react-ui/server/server.js.map +1 -1
  76. package/dist/react-ui/types.cjs.map +1 -1
  77. package/dist/react-ui/types.d.cts.map +1 -1
  78. package/dist/react-ui/types.d.ts.map +1 -1
  79. package/dist/react-ui/types.js.map +1 -1
  80. package/dist/schema.d.cts +6 -6
  81. package/dist/schema.d.cts.map +1 -1
  82. package/dist/schema.d.ts +6 -6
  83. package/dist/schema.d.ts.map +1 -1
  84. package/dist/singletons/fetch.cjs.map +1 -1
  85. package/dist/singletons/fetch.js.map +1 -1
  86. package/dist/types.d.cts +1 -1
  87. package/dist/types.d.cts.map +1 -1
  88. package/dist/types.d.ts +1 -1
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.messages.d.cts +207 -34
  91. package/dist/types.messages.d.cts.map +1 -1
  92. package/dist/types.messages.d.ts +207 -34
  93. package/dist/types.messages.d.ts.map +1 -1
  94. package/dist/types.stream.d.cts +1 -3
  95. package/dist/types.stream.d.cts.map +1 -1
  96. package/dist/types.stream.d.ts +1 -3
  97. package/dist/types.stream.d.ts.map +1 -1
  98. package/dist/types.template.d.cts +19 -0
  99. package/dist/types.template.d.cts.map +1 -0
  100. package/dist/types.template.d.ts +19 -0
  101. package/dist/types.template.d.ts.map +1 -0
  102. package/dist/ui/branching.cjs.map +1 -1
  103. package/dist/ui/branching.d.cts +0 -3
  104. package/dist/ui/branching.d.cts.map +1 -1
  105. package/dist/ui/branching.d.ts +0 -3
  106. package/dist/ui/branching.d.ts.map +1 -1
  107. package/dist/ui/branching.js.map +1 -1
  108. package/dist/ui/errors.cjs.map +1 -1
  109. package/dist/ui/errors.js.map +1 -1
  110. package/dist/ui/manager.cjs +8 -2
  111. package/dist/ui/manager.cjs.map +1 -1
  112. package/dist/ui/manager.js +8 -2
  113. package/dist/ui/manager.js.map +1 -1
  114. package/dist/ui/messages.cjs +10 -10
  115. package/dist/ui/messages.cjs.map +1 -1
  116. package/dist/ui/messages.js.map +1 -1
  117. package/dist/ui/types.d.cts +420 -0
  118. package/dist/ui/types.d.cts.map +1 -0
  119. package/dist/ui/types.d.ts +420 -0
  120. package/dist/ui/types.d.ts.map +1 -0
  121. package/dist/ui/utils.cjs +0 -1
  122. package/dist/ui/utils.cjs.map +1 -1
  123. package/dist/ui/utils.js +0 -1
  124. package/dist/ui/utils.js.map +1 -1
  125. package/dist/utils/async_caller.cjs +12 -4
  126. package/dist/utils/async_caller.cjs.map +1 -1
  127. package/dist/utils/async_caller.d.cts +1 -3
  128. package/dist/utils/async_caller.d.cts.map +1 -1
  129. package/dist/utils/async_caller.d.ts +1 -3
  130. package/dist/utils/async_caller.d.ts.map +1 -1
  131. package/dist/utils/async_caller.js +8 -2
  132. package/dist/utils/async_caller.js.map +1 -1
  133. package/dist/utils/env.cjs +1 -1
  134. package/dist/utils/env.cjs.map +1 -1
  135. package/dist/utils/env.js +1 -1
  136. package/dist/utils/env.js.map +1 -1
  137. package/dist/utils/error.cjs.map +1 -1
  138. package/dist/utils/error.js.map +1 -1
  139. package/dist/utils/signals.cjs.map +1 -1
  140. package/dist/utils/signals.js.map +1 -1
  141. package/dist/utils/sse.cjs.map +1 -1
  142. package/dist/utils/sse.js.map +1 -1
  143. package/dist/utils/stream.cjs +1 -3
  144. package/dist/utils/stream.cjs.map +1 -1
  145. package/dist/utils/stream.js +1 -3
  146. package/dist/utils/stream.js.map +1 -1
  147. package/dist/utils/tools.cjs +52 -0
  148. package/dist/utils/tools.cjs.map +1 -0
  149. package/dist/utils/tools.js +51 -0
  150. package/dist/utils/tools.js.map +1 -0
  151. package/package.json +5 -5
  152. package/CHANGELOG.md +0 -281
@@ -1,7 +1,34 @@
1
- import { BagTemplate, UseStream, UseStreamCustom, UseStreamCustomOptions, UseStreamOptions } from "./types.js";
1
+ import { Message } from "../types.messages.js";
2
+ import { BagTemplate } from "../types.template.js";
3
+ import { InferAgentToolCalls, UseStreamCustomOptions, UseStreamOptions } from "../ui/types.js";
4
+ import { UseStream, UseStreamCustom } from "./types.js";
2
5
 
3
6
  //#region src/react/stream.d.ts
4
7
 
8
+ /**
9
+ * Helper type that infers StateType based on whether T is an agent-like type, a CompiledGraph/Pregel instance, or a state type.
10
+ * - If T has `~agentTypes`, returns a state with typed messages based on the agent's tools
11
+ * - If T has `~RunOutput` (CompiledGraph/CompiledStateGraph), returns the state type
12
+ * - If T has `~OutputType` (Pregel), returns the output type as state
13
+ * - Otherwise, returns T (direct state type)
14
+ */
15
+ type InferStateType<T> = T extends {
16
+ "~agentTypes": unknown;
17
+ } ? {
18
+ messages: Message<InferAgentToolCalls<T>>[];
19
+ } : T extends {
20
+ "~RunOutput": infer S;
21
+ } ? S extends Record<string, unknown> ? S : Record<string, unknown> : T extends {
22
+ "~OutputType": infer O;
23
+ } ? O extends Record<string, unknown> ? O : Record<string, unknown> : T extends Record<string, unknown> ? T : Record<string, unknown>;
24
+ /**
25
+ * Helper type that infers Bag based on whether T is an agent-like type.
26
+ * - If T has `~agentTypes`, extracts bag from the agent's tools
27
+ * - Otherwise, returns the default BagTemplate
28
+ */
29
+ type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {
30
+ "~agentTypes": unknown;
31
+ } ? BagTemplate : B;
5
32
  /**
6
33
  * A React hook that provides seamless integration with LangGraph streaming capabilities.
7
34
  *
@@ -9,29 +36,94 @@ import { BagTemplate, UseStream, UseStreamCustom, UseStreamCustomOptions, UseStr
9
36
  * letting you focus on building great chat experiences. It provides automatic state management for
10
37
  * messages, interrupts, loading states, and errors.
11
38
  *
12
- * @template StateType The type of the thread state (default: `Record<string, unknown>`)
13
- * @template Bag Type configuration bag containing:
14
- * - `ConfigurableType`: Type for the `config.configurable` property
15
- * - `InterruptType`: Type for interrupt values
16
- * - `CustomEventType`: Type for custom events
17
- * - `UpdateType`: Type for the submit function updates
39
+ * ## Usage with ReactAgent (recommended for createAgent users)
18
40
  *
19
- * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
20
- */
21
- declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {
22
- ConfigurableType?: Record<string, unknown>;
23
- InterruptType?: unknown;
24
- CustomEventType?: unknown;
25
- UpdateType?: unknown;
26
- } = BagTemplate>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;
27
- /**
28
- * A React hook that provides seamless integration with LangGraph streaming capabilities.
41
+ * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the
42
+ * type parameter to automatically infer tool call types:
29
43
  *
30
- * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,
31
- * letting you focus on building great chat experiences. It provides automatic state management for
32
- * messages, interrupts, loading states, and errors.
44
+ * @example
45
+ * ```typescript
46
+ * // In your agent file (e.g., agent.ts)
47
+ * import { createAgent, tool } from "@langchain/langgraph";
48
+ * import { z } from "zod";
49
+ *
50
+ * const getWeather = tool(
51
+ * async ({ location }) => `Weather in ${location}`,
52
+ * { name: "get_weather", schema: z.object({ location: z.string() }) }
53
+ * );
54
+ *
55
+ * export const agent = createAgent({
56
+ * model: "openai:gpt-4o",
57
+ * tools: [getWeather],
58
+ * });
59
+ *
60
+ * // In your React component
61
+ * import { agent } from "./agent";
62
+ *
63
+ * function Chat() {
64
+ * // Tool calls are automatically typed from the agent's tools!
65
+ * const stream = useStream<typeof agent>({
66
+ * assistantId: "agent",
67
+ * apiUrl: "http://localhost:2024",
68
+ * });
69
+ *
70
+ * // stream.toolCalls[0].call.name is typed as "get_weather"
71
+ * // stream.toolCalls[0].call.args is typed as { location: string }
72
+ * }
73
+ * ```
74
+ *
75
+ * ## Usage with StateGraph (for custom LangGraph applications)
76
+ *
77
+ * When building custom graphs with `StateGraph`, embed your tool call types directly
78
+ * in your state's messages property using `Message<MyToolCalls>`:
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * import { Message } from "@langchain/langgraph-sdk";
83
+ *
84
+ * // Define your tool call types as a discriminated union
85
+ * type MyToolCalls =
86
+ * | { name: "search"; args: { query: string }; id?: string }
87
+ * | { name: "calculate"; args: { expression: string }; id?: string };
88
+ *
89
+ * // Embed tool call types in your state's messages
90
+ * interface MyGraphState {
91
+ * messages: Message<MyToolCalls>[];
92
+ * context?: string;
93
+ * }
94
+ *
95
+ * function Chat() {
96
+ * const stream = useStream<MyGraphState>({
97
+ * assistantId: "my-graph",
98
+ * apiUrl: "http://localhost:2024",
99
+ * });
100
+ *
101
+ * // stream.values is typed as MyGraphState
102
+ * // stream.toolCalls[0].call.name is typed as "search" | "calculate"
103
+ * }
104
+ * ```
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // With additional type configuration (interrupts, configurable)
109
+ * interface MyGraphState {
110
+ * messages: Message<MyToolCalls>[];
111
+ * }
112
+ *
113
+ * function Chat() {
114
+ * const stream = useStream<MyGraphState, {
115
+ * InterruptType: { question: string };
116
+ * ConfigurableType: { userId: string };
117
+ * }>({
118
+ * assistantId: "my-graph",
119
+ * apiUrl: "http://localhost:2024",
120
+ * });
121
+ *
122
+ * // stream.interrupt is typed as { question: string } | undefined
123
+ * }
124
+ * ```
33
125
  *
34
- * @template StateType The type of the thread state (default: `Record<string, unknown>`)
126
+ * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)
35
127
  * @template Bag Type configuration bag containing:
36
128
  * - `ConfigurableType`: Type for the `config.configurable` property
37
129
  * - `InterruptType`: Type for interrupt values
@@ -40,12 +132,7 @@ declare function useStream<StateType extends Record<string, unknown> = Record<st
40
132
  *
41
133
  * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
42
134
  */
43
- declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {
44
- ConfigurableType?: Record<string, unknown>;
45
- InterruptType?: unknown;
46
- CustomEventType?: unknown;
47
- UpdateType?: unknown;
48
- } = BagTemplate>(options: UseStreamCustomOptions<StateType, Bag>): UseStreamCustom<StateType, Bag>;
135
+ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamOptions<InferStateType<T>, InferBag<T, Bag>>): UseStream<InferStateType<T>, InferBag<T, Bag>>;
49
136
  /**
50
137
  * A React hook that provides seamless integration with LangGraph streaming capabilities.
51
138
  *
@@ -53,7 +140,7 @@ declare function useStream<StateType extends Record<string, unknown> = Record<st
53
140
  * letting you focus on building great chat experiences. It provides automatic state management for
54
141
  * messages, interrupts, loading states, and errors.
55
142
  *
56
- * @template StateType The type of the thread state (default: `Record<string, unknown>`)
143
+ * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)
57
144
  * @template Bag Type configuration bag containing:
58
145
  * - `ConfigurableType`: Type for the `config.configurable` property
59
146
  * - `InterruptType`: Type for interrupt values
@@ -62,12 +149,7 @@ declare function useStream<StateType extends Record<string, unknown> = Record<st
62
149
  *
63
150
  * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
64
151
  */
65
- declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {
66
- ConfigurableType?: Record<string, unknown>;
67
- InterruptType?: unknown;
68
- CustomEventType?: unknown;
69
- UpdateType?: unknown;
70
- } = BagTemplate>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;
152
+ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): UseStreamCustom<InferStateType<T>, InferBag<T, Bag>>;
71
153
  //#endregion
72
154
  export { useStream };
73
155
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","names":["BagTemplate","UseStream","UseStreamCustom","UseStreamCustomOptions","UseStreamOptions","useStream","Record","StateType","Bag"],"sources":["../../src/react/stream.d.ts"],"sourcesContent":["import { BagTemplate, UseStream, UseStreamCustom, UseStreamCustomOptions, UseStreamOptions } from \"./types.js\";\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n} = BagTemplate>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n} = BagTemplate>(options: UseStreamCustomOptions<StateType, Bag>): UseStreamCustom<StateType, Bag>;\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport declare function useStream<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n} = BagTemplate>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;\n"],"mappings":";;;;;;AAiBA;;;;;;;;;;;;;AAsBA;AAAiC,iBAtBTK,SAsBS,CAAA,kBAtBmBC,MAsBnB,CAAA,MAAA,EAAA,OAAA,CAAA,GAtB6CA,MAsB7C,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,YAAA;kBAAmBA,CAAAA,EArB7BA,MAqB6BA,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA;eAA0BA,CAAAA,EAAAA,OAAAA;iBACvDA,CAAAA,EAAAA,OAAAA;YAInBN,CAAAA,EAAAA,OAAAA;IAtBAA,WAsB6CO,CAAAA,CAAAA,OAAAA,EAtBvBH,gBAsBuBG,CAtBNA,SAsBMA,EAtBKC,GAsBLD,CAAAA,CAAAA,EAtBYN,SAsBZM,CAtBsBA,SAsBtBA,EAtBiCC,GAsBjCD,CAAAA;;;;;;;AAiBjD;;;;;;;;;;AAKkFC,iBA3B1DH,SA2B0DG,CAAAA,kBA3B9BF,MA2B8BE,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GA3BJF,MA2BIE,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,EAAAA,YAAAA;kBAArBP,CAAAA,EA1BtCK,MA0BsCL,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA;;;;IAtBzDD,sBAAsBG,uBAAuBI,WAAWC,OAAON,gBAAgBK,WAAWC;;;;;;;;;;;;;;;;;iBAiBtEH,4BAA4BC,0BAA0BA;qBACvDA;;;;IAInBN,sBAAsBI,iBAAiBG,WAAWC,OAAOP,UAAUM,WAAWC"}
1
+ {"version":3,"file":"stream.d.ts","names":["UseStreamOptions","InferAgentToolCalls","Message","BagTemplate","UseStream","UseStreamCustom","UseStreamCustomOptions","InferStateType","T","S","Record","O","InferBag","B","useStream","Bag"],"sources":["../../src/react/stream.d.ts"],"sourcesContent":["import type { UseStreamOptions, InferAgentToolCalls } from \"../ui/types.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport type { UseStream, UseStreamCustom, UseStreamCustomOptions } from \"./types.js\";\n/**\n * Helper type that infers StateType based on whether T is an agent-like type, a CompiledGraph/Pregel instance, or a state type.\n * - If T has `~agentTypes`, returns a state with typed messages based on the agent's tools\n * - If T has `~RunOutput` (CompiledGraph/CompiledStateGraph), returns the state type\n * - If T has `~OutputType` (Pregel), returns the output type as state\n * - Otherwise, returns T (direct state type)\n */\ntype InferStateType<T> = T extends {\n \"~agentTypes\": unknown;\n} ? {\n messages: Message<InferAgentToolCalls<T>>[];\n} : T extends {\n \"~RunOutput\": infer S;\n} ? S extends Record<string, unknown> ? S : Record<string, unknown> : T extends {\n \"~OutputType\": infer O;\n} ? O extends Record<string, unknown> ? O : Record<string, unknown> : T extends Record<string, unknown> ? T : Record<string, unknown>;\n/**\n * Helper type that infers Bag based on whether T is an agent-like type.\n * - If T has `~agentTypes`, extracts bag from the agent's tools\n * - Otherwise, returns the default BagTemplate\n */\ntype InferBag<T, B extends BagTemplate = BagTemplate> = T extends {\n \"~agentTypes\": unknown;\n} ? BagTemplate : B;\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"@langchain/langgraph\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamOptions<InferStateType<T>, InferBag<T, Bag>>): UseStream<InferStateType<T>, InferBag<T, Bag>>;\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): UseStreamCustom<InferStateType<T>, InferBag<T, Bag>>;\nexport {};\n"],"mappings":";;;;;;;;;AAGqF;;;;;KAQhFO,cAGSL,CAAAA,CAAAA,CAAAA,GAHWM,CAGXN,SAAAA;eACVM,EAAAA,OAAAA;;UAEUE,EAHAR,OAGAQ,CAHQT,mBAGRS,CAH4BF,CAG5BE,CAAAA,CAAAA,EAAAA;IAFVF,UAEoCC;cAAIC,EAAAA,KAAAA,EAAAA;IAAxCD,UAAUC,MAAwDF,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAA9BC,CAA8BD,GAA1BE,MAA0BF,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAAAA,CAAAA,SAAAA;eAElEG,EAAAA,KAAAA,EAAAA;IAAAA,UAAUD,MAAAA,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAA0BC,CAA1BD,GAA8BA,MAA9BA,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAAwDF,CAAxDE,SAAkEA,MAAlEA,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAA4FF,CAA5FE,GAAgGA,MAAhGA,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA;;;;;;KAMTE,QANyGF,CAAAA,CAAAA,EAAAA,UAMnFP,WANmFO,GAMrEP,WANqEO,CAAAA,GAMtDF,CANsDE,SAAAA;EAAM,aAAA,EAAA,OAAA;AAAA,CAAA,GAQhHP,WAFS,GAEKU,CAFL;;;;;;;;AA0Gb;;;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAjBwBC,cAAcJ,qCAAqCP,cAAcA,sBAAsBH,iBAAiBO,eAAeC,IAAII,SAASJ,GAAGO,QAAQX,UAAUG,eAAeC,IAAII,SAASJ,GAAGO;;;;;;;;;;;;;;;;;iBAiBxLD,cAAcJ,qCAAqCP,cAAcA,sBAAsBG,uBAAuBC,eAAeC,IAAII,SAASJ,GAAGO,QAAQV,gBAAgBE,eAAeC,IAAII,SAASJ,GAAGO"}
@@ -1 +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 {\n BagTemplate,\n UseStream,\n UseStreamCustom,\n UseStreamCustomOptions,\n UseStreamOptions,\n} from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = 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\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = BagTemplate\n>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = BagTemplate\n>(\n options: UseStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template StateType The type of the thread state (default: `Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = BagTemplate\n>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag>;\n\nexport function useStream<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = BagTemplate\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>\n): UseStream<StateType, Bag> | UseStreamCustom<StateType, Bag> {\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 as UseStreamCustomOptions<StateType, Bag>);\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamLGP(options as UseStreamOptions<StateType, Bag>);\n}\n"],"mappings":";;;;;AAWA,SAAS,gBASP,SAGmD;AACnD,QAAO,eAAe;;AAmFxB,SAAgB,UASd,SAG6D;CAE7D,MAAM,CAAC,YAAY,SAAS,gBAAgB;AAE5C,KAAI,SAEF,QAAO,gBAAgB;AAIzB,QAAO,aAAa"}
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, InferAgentToolCalls } from \"../ui/types.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport type {\n UseStream,\n UseStreamCustom,\n UseStreamCustomOptions,\n} from \"./types.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\n/**\n * Helper type that infers StateType based on whether T is an agent-like type, a CompiledGraph/Pregel instance, or a state type.\n * - If T has `~agentTypes`, returns a state with typed messages based on the agent's tools\n * - If T has `~RunOutput` (CompiledGraph/CompiledStateGraph), returns the state type\n * - If T has `~OutputType` (Pregel), returns the output type as state\n * - Otherwise, returns T (direct state type)\n */\ntype InferStateType<T> = T extends { \"~agentTypes\": unknown }\n ? { messages: Message<InferAgentToolCalls<T>>[] }\n : T extends { \"~RunOutput\": infer S }\n ? S extends Record<string, unknown>\n ? S\n : Record<string, unknown>\n : T extends { \"~OutputType\": infer O }\n ? O extends Record<string, unknown>\n ? O\n : Record<string, unknown>\n : T extends Record<string, unknown>\n ? T\n : Record<string, unknown>;\n\n/**\n * Helper type that infers Bag based on whether T is an agent-like type.\n * - If T has `~agentTypes`, extracts bag from the agent's tools\n * - Otherwise, returns the default BagTemplate\n */\ntype InferBag<T, B extends BagTemplate = BagTemplate> = T extends {\n \"~agentTypes\": unknown;\n}\n ? BagTemplate\n : B;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"@langchain/langgraph\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: UseStreamOptions<InferStateType<T>, InferBag<T, Bag>>\n): UseStream<InferStateType<T>, InferBag<T, Bag>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>\n): UseStreamCustom<InferStateType<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":";;;;;AAYA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AAyKxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,YAAY,SAAS,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAO,gBAAgB,QAAQ;AAIjC,QAAO,aAAa,QAAQ"}
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
 
3
-
4
3
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
5
4
  const require_client = require('../client.cjs');
6
5
  const require_utils = require('../ui/utils.cjs');
@@ -8,8 +7,9 @@ const require_errors = require('../ui/errors.cjs');
8
7
  const require_branching = require('../ui/branching.cjs');
9
8
  const require_messages = require('../ui/messages.cjs');
10
9
  const require_manager = require('../ui/manager.cjs');
10
+ const require_tools = require('../utils/tools.cjs');
11
11
  const require_thread = require('./thread.cjs');
12
- const react = require_rolldown_runtime.__toESM(require("react"));
12
+ let react = require("react");
13
13
 
14
14
  //#region src/react/stream.lgp.tsx
15
15
  function getFetchHistoryKey(client, threadId, limit) {
@@ -242,12 +242,11 @@ function useStreamLGP(options) {
242
242
  return { ...prev };
243
243
  });
244
244
  if (!usableThreadId) {
245
- const thread = await client.threads.create({
245
+ usableThreadId = (await client.threads.create({
246
246
  threadId: submitOptions?.threadId,
247
247
  metadata: submitOptions?.metadata,
248
248
  signal
249
- });
250
- usableThreadId = thread.thread_id;
249
+ })).thread_id;
251
250
  threadIdRef.current = usableThreadId;
252
251
  threadIdStreamingRef.current = usableThreadId;
253
252
  onThreadId(usableThreadId);
@@ -300,14 +299,12 @@ function useStreamLGP(options) {
300
299
  async onSuccess() {
301
300
  if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);
302
301
  if (shouldRefetch) {
303
- const newHistory = await history.mutate(usableThreadId);
304
- const lastHead = newHistory?.at(0);
302
+ const lastHead = (await history.mutate(usableThreadId))?.at(0);
305
303
  if (lastHead) {
306
304
  options.onFinish?.(lastHead, callbackMeta);
307
305
  return null;
308
306
  }
309
307
  }
310
- return void 0;
311
308
  },
312
309
  onError(error$1) {
313
310
  options.onError?.(error$1, callbackMeta);
@@ -338,8 +335,7 @@ function useStreamLGP(options) {
338
335
  callbacks: options,
339
336
  async onSuccess() {
340
337
  runMetadataStorage?.removeItem(`lg:stream:${threadId}`);
341
- const newHistory = await history.mutate(threadId);
342
- const lastHead = newHistory?.at(0);
338
+ const lastHead = (await history.mutate(threadId))?.at(0);
343
339
  if (lastHead) options.onFinish?.(lastHead, callbackMeta);
344
340
  },
345
341
  onError(error$1) {
@@ -418,8 +414,7 @@ function useStreamLGP(options) {
418
414
  if (stream.isLoading) return void 0;
419
415
  const interrupts = branchContext.threadHead?.tasks?.at(-1)?.interrupts;
420
416
  if (interrupts == null || interrupts.length === 0) {
421
- const next = branchContext.threadHead?.next ?? [];
422
- if (!next.length || error != null) return void 0;
417
+ if (!(branchContext.threadHead?.next ?? []).length || error != null) return void 0;
423
418
  return { when: "breakpoint" };
424
419
  }
425
420
  return interrupts.at(-1);
@@ -428,6 +423,14 @@ function useStreamLGP(options) {
428
423
  trackStreamMode("messages-tuple", "values");
429
424
  return getMessages(values);
430
425
  },
426
+ get toolCalls() {
427
+ trackStreamMode("messages-tuple", "values");
428
+ return require_tools.getToolCallsWithResults(getMessages(values));
429
+ },
430
+ getToolCalls(message) {
431
+ trackStreamMode("messages-tuple", "values");
432
+ return require_tools.getToolCallsWithResults(getMessages(values)).filter((tc) => tc.aiMessage.id === message.id);
433
+ },
431
434
  getMessagesMetadata(message, index) {
432
435
  trackStreamMode("values");
433
436
  const streamMetadata = messageManager.get(message.id)?.metadata;
@@ -436,7 +439,6 @@ function useStreamLGP(options) {
436
439
  ...historyMetadata,
437
440
  streamMetadata
438
441
  };
439
- return void 0;
440
442
  }
441
443
  };
442
444
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","client","key","threadId","limit","state","Client","MessageTupleManager","StreamManager","useControllableThreadId","modes: Exclude<StreamMode, \"messages\">[]","getBranchContext","error","StreamError","findLast","idx","branch","callbackMeta: RunCallbackMeta | undefined","rejoinKey: `lg:stream:${string}` | undefined","values","unique","callbackMeta: RunCallbackMeta"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { findLast, unique } from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n BagTemplate,\n UseStreamOptions,\n UseStream,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n RunCallbackMeta,\n SubmitOptions,\n MessageMetadata,\n UseStreamThread,\n} from \"./types.js\";\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { useControllableThreadId } from \"./thread.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends {\n ConfigurableType?: Record<string, unknown>;\n InterruptType?: unknown;\n CustomEventType?: unknown;\n UpdateType?: unknown;\n } = BagTemplate\n>(options: UseStreamOptions<StateType, Bag>): UseStream<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n\n const reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\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 historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? options.fetchStateHistory.limit ?? false\n : options.fetchStateHistory ?? false;\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey]) ? value[messagesKey] : [];\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 [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(history.data ?? [], (state) =>\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\"\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n // We're expecting the whole thread state in onFinish\n options.onFinish != null ||\n // We're fetching history, thus we need the latest checkpoint\n // to ensure we're not accidentally submitting to a wrong branch\n includeImplicitBranch;\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...(values ?? {}) };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: { streamMode?: StreamMode | StreamMode[] }\n ) => {\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n return client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n return {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupt() {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n const valueInterrupts = values.__interrupt__;\n if (valueInterrupts.length === 0) return { when: \"breakpoint\" };\n if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts;\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return undefined;\n\n const interrupts = branchContext.threadHead?.tasks?.at(-1)?.interrupts;\n if (interrupts == null || interrupts.length === 0) {\n // check if there's a next task present\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return undefined;\n return { when: \"breakpoint\" };\n }\n\n // Return only the current interrupt\n return interrupts.at(-1) as Interrupt<InterruptType> | undefined;\n },\n\n get messages() {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n getMessagesMetadata(\n message: Message,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","client","key","threadId","limit","state","Client","MessageTupleManager","StreamManager","useControllableThreadId","getBranchContext","error","StreamError","findLast","idx","branch","values","unique","getToolCallsWithResults"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { findLast, unique } from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n UseStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(options: UseStreamOptions<StateType, Bag>): UseStream<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 reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\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 historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? options.fetchStateHistory.limit ?? false\n : options.fetchStateHistory ?? false;\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\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 [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(history.data ?? [], (state) =>\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\"\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n // We're expecting the whole thread state in onFinish\n options.onFinish != null ||\n // We're fetching history, thus we need the latest checkpoint\n // to ensure we're not accidentally submitting to a wrong branch\n includeImplicitBranch;\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...(values ?? {}) };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: { streamMode?: StreamMode | StreamMode[] }\n ) => {\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n return client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n return {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupt() {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n const valueInterrupts = values.__interrupt__;\n if (valueInterrupts.length === 0) return { when: \"breakpoint\" };\n if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts;\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return undefined;\n\n const interrupts = branchContext.threadHead?.tasks?.at(-1)?.interrupts;\n if (interrupts == null || interrupts.length === 0) {\n // check if there's a next task present\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return undefined;\n return { when: \"breakpoint\" };\n }\n\n // Return only the current interrupt\n return interrupts.at(-1) as Interrupt<InterruptType> | undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAsCA,SAAS,mBACP,QACA,UACA,OACA;AACA,QAAO;EAACA,mCAAoB,OAAO;EAAE;EAAU;EAAM,CAAC,KAAK,IAAI;;AAGjE,SAAS,aACP,QACA,UACA,SACA;AACA,KAAI,SAAS,UAAU,MACrB,QAAO,OAAO,QAAQ,SAAoB,SAAS,CAAC,MAAM,UAAU;AAClE,MAAI,MAAM,cAAc,KAAM,QAAO,EAAE;AACvC,SAAO,CAAC,MAAM;GACd;CAGJ,MAAM,QAAQ,OAAO,SAAS,UAAU,WAAW,QAAQ,QAAQ;AACnE,QAAO,OAAO,QAAQ,WAAsB,UAAU,EAAE,OAAO,CAAC;;AAGlE,SAAS,iBACP,QACA,UACA,OACA,SAK4B;CAC5B,MAAM,MAAM,mBAAmB,QAAQ,UAAU,MAAM;CACvD,MAAM,CAAC,OAAO,uCAKJ;EACR,KAAK;EACL,MAAM;EACN,OAAO;EACP,WAAW,YAAY;EACxB,EAAE;CAEH,MAAM,8BAAmB,OAAO;AAChC,WAAU,UAAU;CAEpB,MAAM,+BAAoB,SAAS,QAAQ;AAC3C,YAAW,UAAU,SAAS;CAE9B,MAAM,kCAEF,YACA,YACsC;AAEtC,MAAI,QAAQ,YAAa,QAAO,QAAQ,QAAQ,EAAE,CAAC;EAEnD,MAAMC,WAAS,UAAU;EACzB,MAAMC,QAAM,mBAAmBD,UAAQE,YAAUC,QAAM;AAEvD,MAAID,cAAY,MAAM;AACpB,aAAU,YAAU;AAClB,QAAIE,QAAM,QAAQH,MAAK,QAAO;KAAE,GAAGG;KAAO,WAAW;KAAM;AAC3D,WAAO;KAAE;KAAK,MAAM;KAAW,OAAO;KAAW,WAAW;KAAM;KAClE;AACF,UAAO,aAAwBJ,UAAQE,YAAU,EAAE,gBAAO,CAAC,CAAC,MACzD,SAAS;AACR,cAAU,YAAU;AAClB,SAAIE,QAAM,QAAQH,MAAK,QAAOG;AAC9B,YAAO;MAAE;MAAK;MAAM,OAAO;MAAW,WAAW;MAAO;MACxD;AACF,WAAO;OAER,UAAU;AACT,cAAU,YAAU;AAClB,SAAIA,QAAM,QAAQH,MAAK,QAAOG;AAC9B,YAAO;MAAE;MAAK,MAAMA,QAAM;MAAM;MAAO,WAAW;MAAO;MACzD;AACF,eAAW,UAAU,MAAM;AAC3B,WAAO,QAAQ,OAAO,MAAM;KAE/B;;AAGH,WAAS;GAAE;GAAK,MAAM;GAAW,OAAO;GAAW,WAAW;GAAO,CAAC;AACtE,SAAO,QAAQ,QAAQ,EAAE,CAAC;IAE5B,CAAC,QAAQ,YAAY,CACtB;AAED,4BAAgB;AAEd,MACE,QAAQ,cAAc,WAAW,QACjC,QAAQ,cAAc,YAAY,SAElC;AAGF,EAAK,QAAQ,UAAU,MAAM;IAI5B,CAAC,SAAS,IAAI,CAAC;AAElB,QAAO;EACL,MAAM,MAAM;EACZ,OAAO,MAAM;EACb,WAAW,MAAM;EACjB,SAAS,aAAsB,QAAQ,YAAY,UAAU,MAAM;EACpE;;AAGH,SAAgB,aAGd,SAAsE;CAOtE,MAAM,wCAA6B,QAAQ,iBAAiB;CAC5D,MAAM,8CAAmC;AACvC,MAAI,OAAO,WAAW,YAAa,QAAO;EAC1C,MAAM,UAAU,oBAAoB;AACpC,MAAI,YAAY,KAAM,QAAO,OAAO;AACpC,MAAI,OAAO,YAAY,WAAY,QAAO,SAAS;AACnD,SAAO;IACN,EAAE,CAAC;CAEN,MAAM,kCAEF,QAAQ,UACR,IAAIC,sBAAO;EACT,QAAQ,QAAQ;EAChB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,gBAAgB,QAAQ;EACzB,CAAC,EACJ;EACE,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACT,CACF;CAED,MAAM,CAAC,4CAAiC,IAAIC,sCAAqB,CAAC;CAClE,MAAM,CAAC,oCAEH,IAAIC,8BAA8B,gBAAgB,EAChD,UAAU,QAAQ,YAAY,OAC/B,CAAC,CACL;AAED,iCACE,OAAO,WACP,OAAO,aACP,OAAO,YACR;CAED,MAAM,CAAC,UAAU,cAAcC,uCAAwB,QAAQ;CAC/D,MAAM,uCAA+D,EAAE,CAAC;CAExE,MAAM,0CACH,GAAG,SAA4C;EAC9C,MAAM,MAAM,mBAAmB;AAC/B,OAAK,MAAM,KAAK,KACd,KAAI,CAAC,IAAI,SAAS,EAAE,CAAE,KAAI,KAAK,EAAE;IAGrC,EAAE,CACH;CAED,MAAM,oBAAoB,QAAQ,iBAAiB;CACnD,MAAM,oBAAoB,QAAQ,iBAAiB;CACnD,MAAM,uBAAuB,QAAQ,oBAAoB;CACzD,MAAM,mBAAmB,QAAQ,gBAAgB;CACjD,MAAM,wBAAwB,QAAQ,qBAAqB;CAC3D,MAAM,kBAAkB,QAAQ,eAAe;CAE/C,MAAM,8CAAmC;EACvC,MAAM,QAA2C,EAAE;AACnD,MAAI,kBAAmB,OAAM,KAAK,UAAU;AAC5C,MAAI,kBAAmB,OAAM,KAAK,SAAS;AAC3C,MAAI,qBAAsB,OAAM,KAAK,SAAS;AAC9C,MAAI,iBAAkB,OAAM,KAAK,QAAQ;AACzC,MAAI,sBAAuB,OAAM,KAAK,cAAc;AACpD,MAAI,gBAAiB,OAAM,KAAK,QAAQ;AACxC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,gCAAoC,SAAS;CACnD,MAAM,yCAA6C,KAAK;AAGxD,4BAAgB;AACd,MAAI,YAAY,YAAY,UAAU;AACpC,eAAY,UAAU;AACtB,UAAO,OAAO;;IAEf,CAAC,UAAU,OAAO,CAAC;CAEtB,MAAM,eACJ,OAAO,QAAQ,sBAAsB,YACrC,QAAQ,qBAAqB,OACzB,QAAQ,kBAAkB,SAAS,QACnC,QAAQ,qBAAqB;CAEnC,MAAM,iBAAiB,iBACrB,QACA,UACA,cACA;EACE,aAAa,QAAQ,UAAU;EAC/B,eAAe;EACf,SAAS,QAAQ;EAClB,CACF;CACD,MAAM,UAAU,QAAQ,UAAU;CAElC,MAAM,eAAe,UAAgC;EACnD,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO,MAAM,QAAQ,MAAM,aAAa,GACnC,MAAM,eACP,EAAE;;CAGR,MAAM,eAAe,SAAoB,aAAmC;EAC1E,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO;GAAE,GAAG;IAAU,cAAc;GAAU;;CAGhD,MAAM,CAAC,QAAQ,iCAA8B,GAAG;CAChD,MAAM,gBAAgBC,mCAAiB,QAAQ,QAAQ,QAAQ,OAAU;CAEzE,MAAM,gBACJ,cAAc,YAAY,UAC1B,QAAQ,iBACP,EAAE;CAEL,MAAM,sBAAsB;EAC1B,MAAMC,UAAQ,cAAc,YAAY,OAAO,GAAG,GAAG,EAAE;AACvD,MAAIA,WAAS,KAAM,QAAO;AAC1B,MAAI;GACF,MAAM,SAAS,KAAK,MAAMA,QAAM;AAChC,OAAIC,2BAAY,kBAAkB,OAAO,CAAE,QAAO,IAAIA,2BAAY,OAAO;AACzE,UAAO;UACD;AAGR,SAAOD;KACL;CAEJ,MAAM,yBAAyB;EAC7B,MAAM,+BAAe,IAAI,KAAa;AACtC,SAAO,YAAY,cAAc,CAAC,KAC/B,SAAS,QAA4D;GACpE,MAAM,YAAY,QAAQ,MAAM;GAGhC,MAAM,iBAAiBE,uBAAS,QAAQ,QAAQ,EAAE,GAAG,UACnD,YAAY,MAAM,OAAO,CACtB,KAAK,GAAG,UAAQ,EAAE,MAAMC,MAAI,CAC5B,SAAS,UAAU,CACvB;GAED,MAAM,eAAe,gBAAgB,YAAY;GACjD,IAAIC,WACF,gBAAgB,OACZ,cAAc,mBAAmB,gBACjC;AACN,OAAI,CAACA,UAAQ,QAAQ,OAAQ,YAAS;GAGtC,MAAM,eAAeA,UAAQ,eAAe,KAAK,EAAE,CAAC,KAAK,IAAI;AAC7D,OAAI,cAAc;AAChB,QAAI,aAAa,IAAI,aAAa,CAAE,YAAS;AAC7C,iBAAa,IAAI,aAAa;;AAGhC,UAAO;IACL,WAAW,UAAU,UAAU;IAC/B;IAEA,QAAQA,UAAQ;IAChB,eAAeA,UAAQ;IACxB;IAEJ;KACC;CAEJ,MAAM,aACJ,OAAO,KAAK,eAAe,EACzB,SAAS,SAAS;AAChB,MAAI,sBAAsB,UAAU;GAClC,MAAM,QAAQ,mBAAmB,QAAQ,aAAa,WAAW;AACjE,OAAI,MAAO,CAAK,OAAO,KAAK,OAAO,UAAU,MAAM;AACnD,sBAAmB,WAAW,aAAa,WAAW;;AAGxD,UAAQ,SAAS,KAAK;IAEzB,CAAC;CAGJ,MAAM,SAAS,OACb,UACA,kBACG;EAEH,MAAM,eAAe,eAAe,YAAY;AAChD,YACE,gBAAgB,OACZ,cAAc,mBAAmB,eAAe,UAAU,KAC1D,GACL;EAID,MAAM,wBACJ,iBAAiB,QAAQ,OAAO,iBAAiB;EAEnD,MAAM,gBAEJ,QAAQ,YAAY,QAGpB;EAEF,IAAI;EACJ,IAAI;EACJ,IAAI,iBAAiB;AAErB,QAAM,OAAO,MACX,OAAO,WAAwB;AAC7B,UAAO,iBAAiB,aAAW;IACjC,MAAM,OAAO;KAAE,GAAG;KAAe,GAAIC,YAAU,EAAE;KAAG;AACpD,QAAI,eAAe,oBAAoB,KACrC,QAAO;KACL,GAAG;KACH,GAAI,OAAO,cAAc,qBAAqB,aAC1C,cAAc,iBAAiB,KAAK,GACpC,cAAc;KACnB;AAGH,WAAO,EAAE,GAAG,MAAM;KAClB;AAEF,OAAI,CAAC,gBAAgB;AAOnB,sBANe,MAAM,OAAO,QAAQ,OAAO;KACzC,UAAU,eAAe;KACzB,UAAU,eAAe;KACzB;KACD,CAAC,EAEsB;AAKxB,gBAAY,UAAU;AACtB,yBAAqB,UAAU;AAE/B,eAAW,eAAe;;AAG5B,OAAI,CAAC,eACH,OAAM,IAAI,MAAM,oCAAoC;AAGtD,wBAAqB,UAAU;GAE/B,MAAM,aAAaC,qBAAO;IACxB,GAAI,eAAe,cAAc,EAAE;IACnC,GAAG,mBAAmB;IACtB,GAAG;IACJ,CAAC;GAEF,IAAI,aACF,eAAe,eACd,wBACG,cAAc,YAAY,aAC1B,WACJ;AAGF,OAAI,eAAe,eAAe,KAAM,cAAa;AAIrD,OAAI,cAAc,KAAM,QAAO,WAAW;GAC1C,MAAM,kBACJ,eAAe,mBAAmB,CAAC,CAAC;AAEtC,UAAO,OAAO,KAAK,OAAO,gBAAgB,QAAQ,aAAa;IAC7D,OAAOD;IACP,QAAQ,eAAe;IACvB,SAAS,eAAe;IACxB,SAAS,eAAe;IAExB,iBAAiB,eAAe;IAChC,gBAAgB,eAAe;IAC/B,UAAU,eAAe;IACzB,mBAAmB,eAAe;IAClC,cAAc,eAAe;IAC7B,cACE,eAAe,iBACd,kBAAkB,aAAa;IAElC;IAEA;IACA;IACA,iBAAiB,eAAe;IAChC;IACA,YAAY,eAAe;IAC3B,aAAa,QAAQ;AACnB,oBAAe;MACb,QAAQ,OAAO;MACf,WAAW,OAAO,aAAa;MAChC;AAED,SAAI,oBAAoB;AACtB,kBAAY,aAAa;AACzB,yBAAmB,QAAQ,WAAW,aAAa,OAAO;;AAG5D,aAAQ,YAAY,aAAa;;IAEpC,CAAC;KAIJ;GACE;GACA;GAEA,eAAe;GACf,WAAW;GAEX,MAAM,YAAY;AAChB,QAAI,UAAW,qBAAoB,WAAW,UAAU;AAExD,QAAI,eAAe;KAEjB,MAAM,YADa,MAAM,QAAQ,OAAO,eAAgB,GAC3B,GAAG,EAAE;AAClC,SAAI,UAAU;AAGZ,cAAQ,WAAW,UAAU,aAAa;AAC1C,aAAO;;;;GAMb,QAAQ,SAAO;AACb,YAAQ,UAAUL,SAAO,aAAa;;GAExC,WAAW;AACT,yBAAqB,UAAU;;GAElC,CACF;;CAGH,MAAM,aAAa,OACjB,OACA,aACA,gBACG;AAEH,kBAAgB;AAChB,MAAI,CAAC,SAAU;EAEf,MAAM,eAAgC;GACpC,WAAW;GACX,QAAQ;GACT;AAED,QAAM,OAAO,MACX,OAAO,WAAwB;AAC7B,wBAAqB,UAAU;AAC/B,UAAO,OAAO,KAAK,WAAW,UAAU,OAAO;IAC7C;IACA;IACA,YAAY,aAAa;IAC1B,CAAC;KAIJ;GACE;GACA;GAEA,eAAe;GACf,WAAW;GACX,MAAM,YAAY;AAChB,wBAAoB,WAAW,aAAa,WAAW;IAEvD,MAAM,YADa,MAAM,QAAQ,OAAO,SAAS,GACpB,GAAG,EAAE;AAClC,QAAI,SAAU,SAAQ,WAAW,UAAU,aAAa;;GAE1D,QAAQ,SAAO;AACb,YAAQ,UAAUA,SAAO,aAAa;;GAExC,WAAW;AACT,yBAAqB,UAAU;;GAElC,CACF;;CAGH,MAAM,wCAA6B;AACjC,MAAI,CAAC,sBAAsB,OAAO,UAAW,QAAO;AACpD,MAAI,OAAO,WAAW,YAAa,QAAO;EAC1C,MAAM,QAAQ,oBAAoB,QAAQ,aAAa,WAAW;AAClE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;GAAE;GAAO;GAAU;IACzB;EAAC;EAAoB,OAAO;EAAW;EAAS,CAAC;CAEpD,MAAM,kBAAkB,CAAC,CAAC;CAC1B,MAAM,iCAAsB;EAAE;EAAU;EAAiB,CAAC;CAE1D,MAAM,kCAA0C,WAAW;AAC3D,eAAc,UAAU;AAExB,4BAAgB;AAEd,MAAI,aAAa,QAAQ,aAAa,SACpC,cAAa,UAAU;GAAE;GAAU;GAAiB;IAErD,CAAC,UAAU,gBAAgB,CAAC;AAE/B,4BAAgB;AACd,MAAI,gBAAgB,aAAa,QAAQ,iBAAiB;AACxD,gBAAa,QAAQ,kBAAkB;AACvC,GAAK,cAAc,UAAU,aAAa,MAAM;;IAEjD,CAAC,aAAa,CAAC;CAElB,MAAM,QAAQ,OAAO,SAAS,gBAAgB,QAAQ;CACtD,MAAM,SAAS,OAAO,UAAU;AAEhC,QAAO;EACL,IAAI,SAAS;AACX,mBAAgB,SAAS;AACzB,UAAO;;EAGT;EACA,aAAa,QAAQ;EAErB;EACA,WAAW,OAAO;EAElB;EACA;EAEA;EAEA;EACA;EAEA,IAAI,UAAU;AACZ,OAAI,iBAAiB,MACnB,OAAM,IAAI,MACR,6DACD;AAGH,UAAO,cAAc;;EAGvB,iBAAiB,QAAQ,aAAa,QAAQ,QAAQ;EAEtD,IAAI,0BAA0B;AAC5B,OAAI,iBAAiB,MACnB,OAAM,IAAI,MACR,6EACD;AAGH,UAAO,cAAc;;EAGvB,IAAI,YAAY;AACd,OACE,UAAU,QACV,mBAAmB,UACnB,MAAM,QAAQ,OAAO,cAAc,EACnC;IACA,MAAM,kBAAkB,OAAO;AAC/B,QAAI,gBAAgB,WAAW,EAAG,QAAO,EAAE,MAAM,cAAc;AAC/D,QAAI,gBAAgB,WAAW,EAAG,QAAO,gBAAgB;AAGzD,WAAO;;AAIT,OAAI,OAAO,UAAW,QAAO;GAE7B,MAAM,aAAa,cAAc,YAAY,OAAO,GAAG,GAAG,EAAE;AAC5D,OAAI,cAAc,QAAQ,WAAW,WAAW,GAAG;AAGjD,QAAI,EADS,cAAc,YAAY,QAAQ,EAAE,EACvC,UAAU,SAAS,KAAM,QAAO;AAC1C,WAAO,EAAE,MAAM,cAAc;;AAI/B,UAAO,WAAW,GAAG,GAAG;;EAG1B,IAAI,WAAoC;AACtC,mBAAgB,kBAAkB,SAAS;AAC3C,UAAO,YAAY,OAAO;;EAG5B,IAAI,YAAY;AACd,mBAAgB,kBAAkB,SAAS;AAE3C,UAAOO,sCADM,YAAY,OAAO,CACkB;;EAGpD,aAAa,SAAS;AACpB,mBAAgB,kBAAkB,SAAS;AAG3C,UADqBA,sCADR,YAAY,OAAO,CACgC,CAC5C,QAAQ,OAAO,GAAG,UAAU,OAAO,QAAQ,GAAG;;EAGpE,oBACE,SACA,OACwC;AACxC,mBAAgB,SAAS;GAEzB,MAAM,iBAAiB,eAAe,IAAI,QAAQ,GAAG,EAAE;GACvD,MAAM,kBAAkB,iBAAiB,MACtC,MAAM,EAAE,eAAe,QAAQ,MAAM,OACvC;AAED,OAAI,kBAAkB,QAAQ,mBAAmB,KAC/C,QAAO;IACL,GAAG;IACH;IACD;;EAKN"}
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
 
3
-
4
3
  import { Client, getClientConfigHash } from "../client.js";
5
4
  import { findLast, unique } from "../ui/utils.js";
6
5
  import { StreamError } from "../ui/errors.js";
7
6
  import { getBranchContext } from "../ui/branching.js";
8
7
  import { MessageTupleManager } from "../ui/messages.js";
9
8
  import { StreamManager } from "../ui/manager.js";
9
+ import { getToolCallsWithResults } from "../utils/tools.js";
10
10
  import { useControllableThreadId } from "./thread.js";
11
11
  import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
12
12
 
@@ -241,12 +241,11 @@ function useStreamLGP(options) {
241
241
  return { ...prev };
242
242
  });
243
243
  if (!usableThreadId) {
244
- const thread = await client.threads.create({
244
+ usableThreadId = (await client.threads.create({
245
245
  threadId: submitOptions?.threadId,
246
246
  metadata: submitOptions?.metadata,
247
247
  signal
248
- });
249
- usableThreadId = thread.thread_id;
248
+ })).thread_id;
250
249
  threadIdRef.current = usableThreadId;
251
250
  threadIdStreamingRef.current = usableThreadId;
252
251
  onThreadId(usableThreadId);
@@ -299,14 +298,12 @@ function useStreamLGP(options) {
299
298
  async onSuccess() {
300
299
  if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);
301
300
  if (shouldRefetch) {
302
- const newHistory = await history.mutate(usableThreadId);
303
- const lastHead = newHistory?.at(0);
301
+ const lastHead = (await history.mutate(usableThreadId))?.at(0);
304
302
  if (lastHead) {
305
303
  options.onFinish?.(lastHead, callbackMeta);
306
304
  return null;
307
305
  }
308
306
  }
309
- return void 0;
310
307
  },
311
308
  onError(error$1) {
312
309
  options.onError?.(error$1, callbackMeta);
@@ -337,8 +334,7 @@ function useStreamLGP(options) {
337
334
  callbacks: options,
338
335
  async onSuccess() {
339
336
  runMetadataStorage?.removeItem(`lg:stream:${threadId}`);
340
- const newHistory = await history.mutate(threadId);
341
- const lastHead = newHistory?.at(0);
337
+ const lastHead = (await history.mutate(threadId))?.at(0);
342
338
  if (lastHead) options.onFinish?.(lastHead, callbackMeta);
343
339
  },
344
340
  onError(error$1) {
@@ -417,8 +413,7 @@ function useStreamLGP(options) {
417
413
  if (stream.isLoading) return void 0;
418
414
  const interrupts = branchContext.threadHead?.tasks?.at(-1)?.interrupts;
419
415
  if (interrupts == null || interrupts.length === 0) {
420
- const next = branchContext.threadHead?.next ?? [];
421
- if (!next.length || error != null) return void 0;
416
+ if (!(branchContext.threadHead?.next ?? []).length || error != null) return void 0;
422
417
  return { when: "breakpoint" };
423
418
  }
424
419
  return interrupts.at(-1);
@@ -427,6 +422,14 @@ function useStreamLGP(options) {
427
422
  trackStreamMode("messages-tuple", "values");
428
423
  return getMessages(values);
429
424
  },
425
+ get toolCalls() {
426
+ trackStreamMode("messages-tuple", "values");
427
+ return getToolCallsWithResults(getMessages(values));
428
+ },
429
+ getToolCalls(message) {
430
+ trackStreamMode("messages-tuple", "values");
431
+ return getToolCallsWithResults(getMessages(values)).filter((tc) => tc.aiMessage.id === message.id);
432
+ },
430
433
  getMessagesMetadata(message, index) {
431
434
  trackStreamMode("values");
432
435
  const streamMetadata = messageManager.get(message.id)?.metadata;
@@ -435,7 +438,6 @@ function useStreamLGP(options) {
435
438
  ...historyMetadata,
436
439
  streamMetadata
437
440
  };
438
- return void 0;
439
441
  }
440
442
  };
441
443
  }