@assistant-ui/react-langgraph 0.1.17 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -63,25 +63,33 @@ type LangGraphSendMessageConfig = {
63
63
  runConfig?: unknown;
64
64
  };
65
65
  type LangGraphMessagesEvent<TMessage> = {
66
- event: "messages/partial" | "messages/complete" | string;
66
+ event: "messages/partial" | "messages/complete" | "metadata" | "updates" | string;
67
67
  data: TMessage[] | any;
68
68
  };
69
69
  type LangGraphStreamCallback<TMessage> = (messages: TMessage[], config: LangGraphSendMessageConfig & {
70
70
  abortSignal: AbortSignal;
71
71
  }) => Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>> | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;
72
+ type LangGraphInterruptState = {
73
+ value: any;
74
+ resumable: boolean;
75
+ when: string;
76
+ ns: string[];
77
+ };
72
78
  declare const useLangGraphMessages: <TMessage extends {
73
79
  id?: string;
74
80
  }>({ stream, }: {
75
81
  stream: LangGraphStreamCallback<TMessage>;
76
82
  }) => {
83
+ interrupt: LangGraphInterruptState | undefined;
77
84
  messages: TMessage[];
78
85
  sendMessage: (newMessages: TMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
79
86
  cancel: () => void;
80
87
  setMessages: react.Dispatch<react.SetStateAction<TMessage[]>>;
81
88
  };
82
89
 
83
- declare const useLangGraphRuntimeSend: () => (messages: LangChainMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
84
- declare const useLangGraphRuntimeSendCommand: (command: LangGraphCommand) => () => Promise<void>;
90
+ declare const useLangGraphInterruptState: () => LangGraphInterruptState | undefined;
91
+ declare const useLangGraphSend: () => (messages: LangChainMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
92
+ declare const useLangGraphSendCommand: (command: LangGraphCommand) => () => Promise<void>;
85
93
  declare const useLangGraphRuntime: ({ autoCancelPendingToolCalls, adapters: { attachments, feedback, speech }, unstable_allowImageAttachments, unstable_allowCancellation, stream, threadId, onSwitchToNewThread, onSwitchToThread, }: {
86
94
  /**
87
95
  * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.
@@ -110,4 +118,4 @@ declare const useLangGraphRuntime: ({ autoCancelPendingToolCalls, adapters: { at
110
118
 
111
119
  declare const convertLangchainMessages: useExternalMessageConverter.Callback<LangChainMessage>;
112
120
 
113
- export { type LangChainEvent, type LangChainMessage, type LangChainToolCall, type LangChainToolCallChunk, convertLangchainMessages, useLangGraphMessages, useLangGraphRuntime, useLangGraphRuntimeSend, useLangGraphRuntimeSendCommand };
121
+ export { type LangChainEvent, type LangChainMessage, type LangChainToolCall, type LangChainToolCallChunk, type LangGraphCommand, type LangGraphInterruptState, type LangGraphSendMessageConfig, type LangGraphStreamCallback, convertLangchainMessages, useLangGraphInterruptState, useLangGraphMessages, useLangGraphRuntime, useLangGraphSend, useLangGraphSendCommand };
package/dist/index.d.ts CHANGED
@@ -63,25 +63,33 @@ type LangGraphSendMessageConfig = {
63
63
  runConfig?: unknown;
64
64
  };
65
65
  type LangGraphMessagesEvent<TMessage> = {
66
- event: "messages/partial" | "messages/complete" | string;
66
+ event: "messages/partial" | "messages/complete" | "metadata" | "updates" | string;
67
67
  data: TMessage[] | any;
68
68
  };
69
69
  type LangGraphStreamCallback<TMessage> = (messages: TMessage[], config: LangGraphSendMessageConfig & {
70
70
  abortSignal: AbortSignal;
71
71
  }) => Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>> | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;
72
+ type LangGraphInterruptState = {
73
+ value: any;
74
+ resumable: boolean;
75
+ when: string;
76
+ ns: string[];
77
+ };
72
78
  declare const useLangGraphMessages: <TMessage extends {
73
79
  id?: string;
74
80
  }>({ stream, }: {
75
81
  stream: LangGraphStreamCallback<TMessage>;
76
82
  }) => {
83
+ interrupt: LangGraphInterruptState | undefined;
77
84
  messages: TMessage[];
78
85
  sendMessage: (newMessages: TMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
79
86
  cancel: () => void;
80
87
  setMessages: react.Dispatch<react.SetStateAction<TMessage[]>>;
81
88
  };
82
89
 
83
- declare const useLangGraphRuntimeSend: () => (messages: LangChainMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
84
- declare const useLangGraphRuntimeSendCommand: (command: LangGraphCommand) => () => Promise<void>;
90
+ declare const useLangGraphInterruptState: () => LangGraphInterruptState | undefined;
91
+ declare const useLangGraphSend: () => (messages: LangChainMessage[], config: LangGraphSendMessageConfig) => Promise<void>;
92
+ declare const useLangGraphSendCommand: (command: LangGraphCommand) => () => Promise<void>;
85
93
  declare const useLangGraphRuntime: ({ autoCancelPendingToolCalls, adapters: { attachments, feedback, speech }, unstable_allowImageAttachments, unstable_allowCancellation, stream, threadId, onSwitchToNewThread, onSwitchToThread, }: {
86
94
  /**
87
95
  * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.
@@ -110,4 +118,4 @@ declare const useLangGraphRuntime: ({ autoCancelPendingToolCalls, adapters: { at
110
118
 
111
119
  declare const convertLangchainMessages: useExternalMessageConverter.Callback<LangChainMessage>;
112
120
 
113
- export { type LangChainEvent, type LangChainMessage, type LangChainToolCall, type LangChainToolCallChunk, convertLangchainMessages, useLangGraphMessages, useLangGraphRuntime, useLangGraphRuntimeSend, useLangGraphRuntimeSendCommand };
121
+ export { type LangChainEvent, type LangChainMessage, type LangChainToolCall, type LangChainToolCallChunk, type LangGraphCommand, type LangGraphInterruptState, type LangGraphSendMessageConfig, type LangGraphStreamCallback, convertLangchainMessages, useLangGraphInterruptState, useLangGraphMessages, useLangGraphRuntime, useLangGraphSend, useLangGraphSendCommand };
package/dist/index.js CHANGED
@@ -21,16 +21,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  convertLangchainMessages: () => convertLangchainMessages,
24
+ useLangGraphInterruptState: () => useLangGraphInterruptState,
24
25
  useLangGraphMessages: () => useLangGraphMessages,
25
26
  useLangGraphRuntime: () => useLangGraphRuntime,
26
- useLangGraphRuntimeSend: () => useLangGraphRuntimeSend,
27
- useLangGraphRuntimeSendCommand: () => useLangGraphRuntimeSendCommand
27
+ useLangGraphSend: () => useLangGraphSend,
28
+ useLangGraphSendCommand: () => useLangGraphSendCommand
28
29
  });
29
30
  module.exports = __toCommonJS(index_exports);
30
31
 
31
32
  // src/useLangGraphRuntime.ts
32
- var import_react3 = require("react");
33
- var import_react4 = require("@assistant-ui/react");
33
+ var import_react2 = require("react");
34
+ var import_react3 = require("@assistant-ui/react");
34
35
 
35
36
  // src/convertLangchainMessages.ts
36
37
  var contentToParts = (content) => {
@@ -101,12 +102,11 @@ var convertLangchainMessages = (message) => {
101
102
 
102
103
  // src/useLangGraphMessages.ts
103
104
  var import_react = require("react");
104
- var import_react2 = require("@assistant-ui/react");
105
105
  var import_uuid = require("uuid");
106
- var { generateId } = import_react2.INTERNAL;
107
106
  var useLangGraphMessages = ({
108
107
  stream
109
108
  }) => {
109
+ const [interrupt, setInterrupt] = (0, import_react.useState)();
110
110
  const [messages, setMessages] = (0, import_react.useState)([]);
111
111
  const abortControllerRef = (0, import_react.useRef)(null);
112
112
  const sendMessage = (0, import_react.useCallback)(
@@ -116,7 +116,7 @@ var useLangGraphMessages = ({
116
116
  const addMessages = (newMessages2) => {
117
117
  if (newMessages2.length === 0) return;
118
118
  for (const message of newMessages2) {
119
- messagesMap.set(message.id ?? generateId(), message);
119
+ messagesMap.set(message.id ?? (0, import_uuid.v4)(), message);
120
120
  }
121
121
  setMessages([...messagesMap.values()]);
122
122
  };
@@ -130,6 +130,8 @@ var useLangGraphMessages = ({
130
130
  for await (const chunk of response) {
131
131
  if (chunk.event === "messages/partial" || chunk.event === "messages/complete") {
132
132
  addMessages(chunk.data);
133
+ } else if (chunk.event === "updates") {
134
+ setInterrupt(chunk.data.__interrupt__);
133
135
  }
134
136
  }
135
137
  },
@@ -140,11 +142,11 @@ var useLangGraphMessages = ({
140
142
  abortControllerRef.current.abort();
141
143
  }
142
144
  }, [abortControllerRef]);
143
- return { messages, sendMessage, cancel, setMessages };
145
+ return { interrupt, messages, sendMessage, cancel, setMessages };
144
146
  };
145
147
 
146
148
  // src/useLangGraphRuntime.ts
147
- var import_react5 = require("@assistant-ui/react");
149
+ var import_react4 = require("@assistant-ui/react");
148
150
  var getPendingToolCalls = (messages) => {
149
151
  const pendingToolCalls = /* @__PURE__ */ new Map();
150
152
  for (const message of messages) {
@@ -193,12 +195,16 @@ var asLangGraphRuntimeExtras = (extras) => {
193
195
  );
194
196
  return extras;
195
197
  };
196
- var useLangGraphRuntimeSend = () => {
197
- const { send } = (0, import_react4.useThread)((t) => asLangGraphRuntimeExtras(t.extras));
198
+ var useLangGraphInterruptState = () => {
199
+ const { interrupt } = (0, import_react3.useThread)((t) => asLangGraphRuntimeExtras(t.extras));
200
+ return interrupt;
201
+ };
202
+ var useLangGraphSend = () => {
203
+ const { send } = (0, import_react3.useThread)((t) => asLangGraphRuntimeExtras(t.extras));
198
204
  return send;
199
205
  };
200
- var useLangGraphRuntimeSendCommand = (command) => {
201
- const send = useLangGraphRuntimeSend();
206
+ var useLangGraphSendCommand = (command) => {
207
+ const send = useLangGraphSend();
202
208
  return () => send([], { command });
203
209
  };
204
210
  var useLangGraphRuntime = ({
@@ -211,10 +217,10 @@ var useLangGraphRuntime = ({
211
217
  onSwitchToNewThread,
212
218
  onSwitchToThread
213
219
  }) => {
214
- const { messages, sendMessage, cancel, setMessages } = useLangGraphMessages({
220
+ const { interrupt, messages, sendMessage, cancel, setMessages } = useLangGraphMessages({
215
221
  stream
216
222
  });
217
- const [isRunning, setIsRunning] = (0, import_react3.useState)(false);
223
+ const [isRunning, setIsRunning] = (0, import_react2.useState)(false);
218
224
  const handleSendMessage = async (messages2, config) => {
219
225
  try {
220
226
  setIsRunning(true);
@@ -225,7 +231,7 @@ var useLangGraphRuntime = ({
225
231
  setIsRunning(false);
226
232
  }
227
233
  };
228
- const threadMessages = (0, import_react4.useExternalMessageConverter)({
234
+ const threadMessages = (0, import_react3.useExternalMessageConverter)({
229
235
  callback: convertLangchainMessages,
230
236
  messages,
231
237
  isRunning
@@ -235,7 +241,7 @@ var useLangGraphRuntime = ({
235
241
  "Replace unstable_allowImageAttachments with `adapters: { attachments: new SimpleImageAttachmentAdapter() }`."
236
242
  );
237
243
  if (unstable_allowImageAttachments)
238
- attachments = new import_react5.SimpleImageAttachmentAdapter();
244
+ attachments = new import_react4.SimpleImageAttachmentAdapter();
239
245
  const switchToThread = !onSwitchToThread ? void 0 : async (externalId) => {
240
246
  const { messages: messages2 } = await onSwitchToThread(externalId);
241
247
  setMessages(messages2);
@@ -248,9 +254,9 @@ var useLangGraphRuntime = ({
248
254
  },
249
255
  onSwitchToThread: switchToThread
250
256
  };
251
- const loadingRef = (0, import_react3.useRef)(false);
252
- const threadListItemRuntime = (0, import_react4.useThreadListItemRuntime)({ optional: true });
253
- (0, import_react3.useEffect)(() => {
257
+ const loadingRef = (0, import_react2.useRef)(false);
258
+ const threadListItemRuntime = (0, import_react3.useThreadListItemRuntime)({ optional: true });
259
+ (0, import_react2.useEffect)(() => {
254
260
  if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;
255
261
  const externalId = threadListItemRuntime.getState().externalId;
256
262
  if (externalId) {
@@ -260,7 +266,7 @@ var useLangGraphRuntime = ({
260
266
  });
261
267
  }
262
268
  }, []);
263
- return (0, import_react4.useExternalStoreRuntime)({
269
+ return (0, import_react3.useExternalStoreRuntime)({
264
270
  isRunning,
265
271
  messages: threadMessages,
266
272
  adapters: {
@@ -271,6 +277,7 @@ var useLangGraphRuntime = ({
271
277
  },
272
278
  extras: {
273
279
  [symbolLangGraphRuntimeExtras]: true,
280
+ interrupt,
274
281
  send: handleSendMessage
275
282
  },
276
283
  onNew: (msg) => {
@@ -317,9 +324,10 @@ var useLangGraphRuntime = ({
317
324
  // Annotate the CommonJS export names for ESM import in node:
318
325
  0 && (module.exports = {
319
326
  convertLangchainMessages,
327
+ useLangGraphInterruptState,
320
328
  useLangGraphMessages,
321
329
  useLangGraphRuntime,
322
- useLangGraphRuntimeSend,
323
- useLangGraphRuntimeSendCommand
330
+ useLangGraphSend,
331
+ useLangGraphSendCommand
324
332
  });
325
333
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["export {\n useLangGraphRuntime,\n useLangGraphRuntimeSend,\n useLangGraphRuntimeSendCommand,\n} from \"./useLangGraphRuntime\";\n\nexport { useLangGraphMessages } from \"./useLangGraphMessages\";\nexport { convertLangchainMessages } from \"./convertLangchainMessages\";\nexport type {\n LangChainMessage,\n LangChainEvent,\n LangChainToolCall,\n LangChainToolCallChunk,\n} from \"./types\";\n","import { useEffect, useRef, useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n useThread,\n useThreadListItemRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport {\n LangGraphCommand,\n LangGraphSendMessageConfig,\n LangGraphStreamCallback,\n useLangGraphMessages,\n} from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } from \"@assistant-ui/react\";\nimport { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { AppendMessage } from \"@assistant-ui/react\";\nimport { ExternalStoreAdapter } from \"@assistant-ui/react\";\nimport { FeedbackAdapter } from \"@assistant-ui/react\";\nimport { SpeechSynthesisAdapter } from \"@assistant-ui/react\";\n\nconst getPendingToolCalls = (messages: LangChainMessage[]) => {\n const pendingToolCalls = new Map<string, LangChainToolCall>();\n for (const message of messages) {\n if (message.type === \"ai\") {\n for (const toolCall of message.tool_calls ?? []) {\n pendingToolCalls.set(toolCall.id, toolCall);\n }\n }\n if (message.type === \"tool\") {\n pendingToolCalls.delete(message.tool_call_id);\n }\n }\n\n return [...pendingToolCalls.values()];\n};\n\nconst getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...msg.attachments.flatMap((a) => a.content),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default:\n const _exhaustiveCheck: \"file\" | \"audio\" = type;\n throw new Error(\n `Unsupported append content part type: ${_exhaustiveCheck}`,\n );\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n\n return content;\n};\n\nconst symbolLangGraphRuntimeExtras = Symbol(\"langgraph-runtime-extras\");\ntype LangGraphRuntimeExtras = {\n [symbolLangGraphRuntimeExtras]: true;\n send: (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => Promise<void>;\n};\n\nconst asLangGraphRuntimeExtras = (extras: unknown): LangGraphRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolLangGraphRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useLangGraphRuntime\",\n );\n\n return extras as LangGraphRuntimeExtras;\n};\n\nexport const useLangGraphRuntimeSend = () => {\n const { send } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return send;\n};\n\nexport const useLangGraphRuntimeSendCommand = (command: LangGraphCommand) => {\n const send = useLangGraphRuntimeSend();\n return () => send([], { command });\n};\n\nexport const useLangGraphRuntime = ({\n autoCancelPendingToolCalls,\n adapters: { attachments, feedback, speech } = {},\n unstable_allowImageAttachments,\n unstable_allowCancellation,\n stream,\n threadId,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n /**\n * @deprecated Use `adapters: { attachments: new SimpleImageAttachmentAdapter() }` instead. This option will be removed in a future version.\n */\n unstable_allowImageAttachments?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n stream: LangGraphStreamCallback<LangChainMessage>;\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n}) => {\n const { messages, sendMessage, cancel, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(messages, config);\n } catch (error) {\n console.error(\"Error streaming messages:\", error);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertLangchainMessages,\n messages,\n isRunning,\n });\n\n if (attachments && unstable_allowImageAttachments)\n throw new Error(\n \"Replace unstable_allowImageAttachments with `adapters: { attachments: new SimpleImageAttachmentAdapter() }`.\",\n );\n if (unstable_allowImageAttachments)\n attachments = new SimpleImageAttachmentAdapter();\n\n const switchToThread = !onSwitchToThread\n ? undefined\n : async (externalId: string) => {\n const { messages } = await onSwitchToThread(externalId);\n setMessages(messages);\n };\n\n const threadList: NonNullable<\n ExternalStoreAdapter[\"adapters\"]\n >[\"threadList\"] = {\n threadId,\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: switchToThread,\n };\n\n const loadingRef = useRef(false);\n const threadListItemRuntime = useThreadListItemRuntime({ optional: true });\n useEffect(() => {\n if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;\n\n const externalId = threadListItemRuntime.getState().externalId;\n if (externalId) {\n loadingRef.current = true;\n switchToThread(externalId).finally(() => {\n loadingRef.current = false;\n });\n }\n }, []);\n\n return useExternalStoreRuntime({\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments,\n feedback,\n speech,\n threadList,\n },\n extras: {\n [symbolLangGraphRuntimeExtras]: true,\n send: handleSendMessage,\n } satisfies LangGraphRuntimeExtras,\n onNew: (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingToolCalls(messages).map(\n (t) =>\n ({\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n }) satisfies LangChainMessage & { type: \"tool\" },\n )\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n },\n );\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n // TODO parallel human in the loop calls\n await handleSendMessage(\n [\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ],\n // TODO reuse runconfig here!\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n};\n","\"use client\";\n\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { LangChainMessage } from \"./types\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { ThreadUserMessage } from \"@assistant-ui/react\";\n\nconst contentToParts = (\n content: LangChainMessage[\"content\"],\n) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n return content\n .map((part): ThreadUserMessage[\"content\"][number] | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image_url\":\n if (typeof part.image_url === \"string\") {\n return { type: \"image\", image: part.image_url };\n } else {\n return {\n type: \"image\",\n image: part.image_url.url,\n };\n }\n\n case \"tool_use\":\n return null;\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);\n }\n })\n .filter((a) => a !== null);\n};\n\nexport const convertLangchainMessages: useExternalMessageConverter.Callback<\n LangChainMessage\n> = (message) => {\n switch (message.type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: message.content }],\n };\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n case \"ai\":\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...contentToParts(message.content),\n ...(message.tool_calls?.map(\n (chunk): ToolCallContentPart => ({\n type: \"tool-call\",\n toolCallId: chunk.id,\n toolName: chunk.name,\n args: chunk.args,\n argsText:\n message.tool_call_chunks?.find((c) => c.id === chunk.id)\n ?.args ?? JSON.stringify(chunk.args),\n }),\n ) ?? []),\n ],\n };\n case \"tool\":\n return {\n role: \"tool\",\n toolName: message.name,\n toolCallId: message.tool_call_id,\n result: message.content,\n };\n }\n};\n","import { useState, useCallback, useRef } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nconst { generateId } = INTERNAL;\n\nexport type LangGraphCommand = {\n resume: string;\n};\n\nexport type LangGraphSendMessageConfig = {\n command?: LangGraphCommand;\n runConfig?: unknown;\n};\n\ntype LangGraphMessagesEvent<TMessage> = {\n event: \"messages/partial\" | \"messages/complete\" | string;\n data: TMessage[] | any;\n};\nexport type LangGraphStreamCallback<TMessage> = (\n messages: TMessage[],\n config: LangGraphSendMessageConfig & { abortSignal: AbortSignal },\n) =>\n | Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>>\n | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;\n\nexport const useLangGraphMessages = <TMessage extends { id?: string }>({\n stream,\n}: {\n stream: LangGraphStreamCallback<TMessage>;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[], config: LangGraphSendMessageConfig) => {\n // ensure all messages have an ID\n newMessages = newMessages.map((m) => (m.id ? m : { ...m, id: uuidv4() }));\n\n const messagesMap = new Map<string, TMessage>();\n const addMessages = (newMessages: TMessage[]) => {\n if (newMessages.length === 0) return;\n for (const message of newMessages) {\n messagesMap.set(message.id ?? generateId(), message);\n }\n setMessages([...messagesMap.values()]);\n };\n addMessages([...messages, ...newMessages]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n const response = await stream(newMessages, {\n ...config,\n abortSignal: abortController.signal,\n });\n\n for await (const chunk of response) {\n if (\n chunk.event === \"messages/partial\" ||\n chunk.event === \"messages/complete\"\n ) {\n // TODO verify bugfix - if there are messages without IDs, they appear duplicated\n addMessages(chunk.data);\n }\n }\n },\n [messages, stream],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, [abortControllerRef]);\n\n return { messages, sendMessage, cancel, setMessages };\n};\n"],"mappings":"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","names":["import_react","import_react","uuidv4","newMessages","import_react","messages"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["export {\n useLangGraphRuntime,\n useLangGraphSend,\n useLangGraphSendCommand,\n useLangGraphInterruptState,\n} from \"./useLangGraphRuntime\";\n\nexport {\n useLangGraphMessages,\n type LangGraphInterruptState,\n type LangGraphCommand,\n type LangGraphSendMessageConfig,\n type LangGraphStreamCallback,\n} from \"./useLangGraphMessages\";\nexport { convertLangchainMessages } from \"./convertLangchainMessages\";\n\nexport type {\n LangChainMessage,\n LangChainEvent,\n LangChainToolCall,\n LangChainToolCallChunk,\n} from \"./types\";\n","import { useEffect, useRef, useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n useThread,\n useThreadListItemRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport {\n LangGraphCommand,\n LangGraphInterruptState,\n LangGraphSendMessageConfig,\n LangGraphStreamCallback,\n useLangGraphMessages,\n} from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } from \"@assistant-ui/react\";\nimport { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { AppendMessage } from \"@assistant-ui/react\";\nimport { ExternalStoreAdapter } from \"@assistant-ui/react\";\nimport { FeedbackAdapter } from \"@assistant-ui/react\";\nimport { SpeechSynthesisAdapter } from \"@assistant-ui/react\";\n\nconst getPendingToolCalls = (messages: LangChainMessage[]) => {\n const pendingToolCalls = new Map<string, LangChainToolCall>();\n for (const message of messages) {\n if (message.type === \"ai\") {\n for (const toolCall of message.tool_calls ?? []) {\n pendingToolCalls.set(toolCall.id, toolCall);\n }\n }\n if (message.type === \"tool\") {\n pendingToolCalls.delete(message.tool_call_id);\n }\n }\n\n return [...pendingToolCalls.values()];\n};\n\nconst getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...msg.attachments.flatMap((a) => a.content),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default:\n const _exhaustiveCheck: \"file\" | \"audio\" = type;\n throw new Error(\n `Unsupported append content part type: ${_exhaustiveCheck}`,\n );\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n\n return content;\n};\n\nconst symbolLangGraphRuntimeExtras = Symbol(\"langgraph-runtime-extras\");\ntype LangGraphRuntimeExtras = {\n [symbolLangGraphRuntimeExtras]: true;\n send: (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => Promise<void>;\n interrupt: LangGraphInterruptState | undefined;\n};\n\nconst asLangGraphRuntimeExtras = (extras: unknown): LangGraphRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolLangGraphRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useLangGraphRuntime\",\n );\n\n return extras as LangGraphRuntimeExtras;\n};\n\nexport const useLangGraphInterruptState = () => {\n const { interrupt } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return interrupt;\n};\n\nexport const useLangGraphSend = () => {\n const { send } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return send;\n};\n\nexport const useLangGraphSendCommand = (command: LangGraphCommand) => {\n const send = useLangGraphSend();\n return () => send([], { command });\n};\n\nexport const useLangGraphRuntime = ({\n autoCancelPendingToolCalls,\n adapters: { attachments, feedback, speech } = {},\n unstable_allowImageAttachments,\n unstable_allowCancellation,\n stream,\n threadId,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n /**\n * @deprecated Use `adapters: { attachments: new SimpleImageAttachmentAdapter() }` instead. This option will be removed in a future version.\n */\n unstable_allowImageAttachments?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n stream: LangGraphStreamCallback<LangChainMessage>;\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n}) => {\n const { interrupt, messages, sendMessage, cancel, setMessages } =\n useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(messages, config);\n } catch (error) {\n console.error(\"Error streaming messages:\", error);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertLangchainMessages,\n messages,\n isRunning,\n });\n\n if (attachments && unstable_allowImageAttachments)\n throw new Error(\n \"Replace unstable_allowImageAttachments with `adapters: { attachments: new SimpleImageAttachmentAdapter() }`.\",\n );\n if (unstable_allowImageAttachments)\n attachments = new SimpleImageAttachmentAdapter();\n\n const switchToThread = !onSwitchToThread\n ? undefined\n : async (externalId: string) => {\n const { messages } = await onSwitchToThread(externalId);\n setMessages(messages);\n };\n\n const threadList: NonNullable<\n ExternalStoreAdapter[\"adapters\"]\n >[\"threadList\"] = {\n threadId,\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: switchToThread,\n };\n\n const loadingRef = useRef(false);\n const threadListItemRuntime = useThreadListItemRuntime({ optional: true });\n useEffect(() => {\n if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;\n\n const externalId = threadListItemRuntime.getState().externalId;\n if (externalId) {\n loadingRef.current = true;\n switchToThread(externalId).finally(() => {\n loadingRef.current = false;\n });\n }\n }, []);\n\n return useExternalStoreRuntime({\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments,\n feedback,\n speech,\n threadList,\n },\n extras: {\n [symbolLangGraphRuntimeExtras]: true,\n interrupt,\n send: handleSendMessage,\n } satisfies LangGraphRuntimeExtras,\n onNew: (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingToolCalls(messages).map(\n (t) =>\n ({\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n }) satisfies LangChainMessage & { type: \"tool\" },\n )\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n },\n );\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n // TODO parallel human in the loop calls\n await handleSendMessage(\n [\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ],\n // TODO reuse runconfig here!\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n};\n","\"use client\";\n\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { LangChainMessage } from \"./types\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { ThreadUserMessage } from \"@assistant-ui/react\";\n\nconst contentToParts = (\n content: LangChainMessage[\"content\"],\n) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n return content\n .map((part): ThreadUserMessage[\"content\"][number] | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image_url\":\n if (typeof part.image_url === \"string\") {\n return { type: \"image\", image: part.image_url };\n } else {\n return {\n type: \"image\",\n image: part.image_url.url,\n };\n }\n\n case \"tool_use\":\n return null;\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);\n }\n })\n .filter((a) => a !== null);\n};\n\nexport const convertLangchainMessages: useExternalMessageConverter.Callback<\n LangChainMessage\n> = (message) => {\n switch (message.type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: message.content }],\n };\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n case \"ai\":\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...contentToParts(message.content),\n ...(message.tool_calls?.map(\n (chunk): ToolCallContentPart => ({\n type: \"tool-call\",\n toolCallId: chunk.id,\n toolName: chunk.name,\n args: chunk.args,\n argsText:\n message.tool_call_chunks?.find((c) => c.id === chunk.id)\n ?.args ?? JSON.stringify(chunk.args),\n }),\n ) ?? []),\n ],\n };\n case \"tool\":\n return {\n role: \"tool\",\n toolName: message.name,\n toolCallId: message.tool_call_id,\n result: message.content,\n };\n }\n};\n","import { useState, useCallback, useRef } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport type LangGraphCommand = {\n resume: string;\n};\n\nexport type LangGraphSendMessageConfig = {\n command?: LangGraphCommand;\n runConfig?: unknown;\n};\n\ntype LangGraphMessagesEvent<TMessage> = {\n event:\n | \"messages/partial\"\n | \"messages/complete\"\n | \"metadata\"\n | \"updates\"\n | string;\n data: TMessage[] | any;\n};\nexport type LangGraphStreamCallback<TMessage> = (\n messages: TMessage[],\n config: LangGraphSendMessageConfig & { abortSignal: AbortSignal },\n) =>\n | Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>>\n | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;\n\nexport type LangGraphInterruptState = {\n value: any;\n resumable: boolean;\n when: string;\n ns: string[];\n};\n\nexport const useLangGraphMessages = <TMessage extends { id?: string }>({\n stream,\n}: {\n stream: LangGraphStreamCallback<TMessage>;\n}) => {\n const [interrupt, setInterrupt] = useState<\n LangGraphInterruptState | undefined\n >();\n const [messages, setMessages] = useState<TMessage[]>([]);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[], config: LangGraphSendMessageConfig) => {\n // ensure all messages have an ID\n newMessages = newMessages.map((m) => (m.id ? m : { ...m, id: uuidv4() }));\n\n const messagesMap = new Map<string, TMessage>();\n const addMessages = (newMessages: TMessage[]) => {\n if (newMessages.length === 0) return;\n for (const message of newMessages) {\n messagesMap.set(message.id ?? uuidv4(), message);\n }\n setMessages([...messagesMap.values()]);\n };\n addMessages([...messages, ...newMessages]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n const response = await stream(newMessages, {\n ...config,\n abortSignal: abortController.signal,\n });\n\n for await (const chunk of response) {\n if (\n chunk.event === \"messages/partial\" ||\n chunk.event === \"messages/complete\"\n ) {\n addMessages(chunk.data);\n } else if (chunk.event === \"updates\") {\n setInterrupt(chunk.data.__interrupt__);\n }\n }\n },\n [messages, stream],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, [abortControllerRef]);\n\n return { interrupt, messages, sendMessage, cancel, setMessages };\n};\n"],"mappings":"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","names":["import_react","uuidv4","newMessages","import_react","messages"]}
package/dist/index.mjs CHANGED
@@ -76,12 +76,11 @@ var convertLangchainMessages = (message) => {
76
76
 
77
77
  // src/useLangGraphMessages.ts
78
78
  import { useState, useCallback, useRef } from "react";
79
- import { INTERNAL } from "@assistant-ui/react";
80
79
  import { v4 as uuidv4 } from "uuid";
81
- var { generateId } = INTERNAL;
82
80
  var useLangGraphMessages = ({
83
81
  stream
84
82
  }) => {
83
+ const [interrupt, setInterrupt] = useState();
85
84
  const [messages, setMessages] = useState([]);
86
85
  const abortControllerRef = useRef(null);
87
86
  const sendMessage = useCallback(
@@ -91,7 +90,7 @@ var useLangGraphMessages = ({
91
90
  const addMessages = (newMessages2) => {
92
91
  if (newMessages2.length === 0) return;
93
92
  for (const message of newMessages2) {
94
- messagesMap.set(message.id ?? generateId(), message);
93
+ messagesMap.set(message.id ?? uuidv4(), message);
95
94
  }
96
95
  setMessages([...messagesMap.values()]);
97
96
  };
@@ -105,6 +104,8 @@ var useLangGraphMessages = ({
105
104
  for await (const chunk of response) {
106
105
  if (chunk.event === "messages/partial" || chunk.event === "messages/complete") {
107
106
  addMessages(chunk.data);
107
+ } else if (chunk.event === "updates") {
108
+ setInterrupt(chunk.data.__interrupt__);
108
109
  }
109
110
  }
110
111
  },
@@ -115,7 +116,7 @@ var useLangGraphMessages = ({
115
116
  abortControllerRef.current.abort();
116
117
  }
117
118
  }, [abortControllerRef]);
118
- return { messages, sendMessage, cancel, setMessages };
119
+ return { interrupt, messages, sendMessage, cancel, setMessages };
119
120
  };
120
121
 
121
122
  // src/useLangGraphRuntime.ts
@@ -168,12 +169,16 @@ var asLangGraphRuntimeExtras = (extras) => {
168
169
  );
169
170
  return extras;
170
171
  };
171
- var useLangGraphRuntimeSend = () => {
172
+ var useLangGraphInterruptState = () => {
173
+ const { interrupt } = useThread((t) => asLangGraphRuntimeExtras(t.extras));
174
+ return interrupt;
175
+ };
176
+ var useLangGraphSend = () => {
172
177
  const { send } = useThread((t) => asLangGraphRuntimeExtras(t.extras));
173
178
  return send;
174
179
  };
175
- var useLangGraphRuntimeSendCommand = (command) => {
176
- const send = useLangGraphRuntimeSend();
180
+ var useLangGraphSendCommand = (command) => {
181
+ const send = useLangGraphSend();
177
182
  return () => send([], { command });
178
183
  };
179
184
  var useLangGraphRuntime = ({
@@ -186,7 +191,7 @@ var useLangGraphRuntime = ({
186
191
  onSwitchToNewThread,
187
192
  onSwitchToThread
188
193
  }) => {
189
- const { messages, sendMessage, cancel, setMessages } = useLangGraphMessages({
194
+ const { interrupt, messages, sendMessage, cancel, setMessages } = useLangGraphMessages({
190
195
  stream
191
196
  });
192
197
  const [isRunning, setIsRunning] = useState2(false);
@@ -246,6 +251,7 @@ var useLangGraphRuntime = ({
246
251
  },
247
252
  extras: {
248
253
  [symbolLangGraphRuntimeExtras]: true,
254
+ interrupt,
249
255
  send: handleSendMessage
250
256
  },
251
257
  onNew: (msg) => {
@@ -291,9 +297,10 @@ var useLangGraphRuntime = ({
291
297
  };
292
298
  export {
293
299
  convertLangchainMessages,
300
+ useLangGraphInterruptState,
294
301
  useLangGraphMessages,
295
302
  useLangGraphRuntime,
296
- useLangGraphRuntimeSend,
297
- useLangGraphRuntimeSendCommand
303
+ useLangGraphSend,
304
+ useLangGraphSendCommand
298
305
  };
299
306
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n useThread,\n useThreadListItemRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport {\n LangGraphCommand,\n LangGraphSendMessageConfig,\n LangGraphStreamCallback,\n useLangGraphMessages,\n} from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } from \"@assistant-ui/react\";\nimport { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { AppendMessage } from \"@assistant-ui/react\";\nimport { ExternalStoreAdapter } from \"@assistant-ui/react\";\nimport { FeedbackAdapter } from \"@assistant-ui/react\";\nimport { SpeechSynthesisAdapter } from \"@assistant-ui/react\";\n\nconst getPendingToolCalls = (messages: LangChainMessage[]) => {\n const pendingToolCalls = new Map<string, LangChainToolCall>();\n for (const message of messages) {\n if (message.type === \"ai\") {\n for (const toolCall of message.tool_calls ?? []) {\n pendingToolCalls.set(toolCall.id, toolCall);\n }\n }\n if (message.type === \"tool\") {\n pendingToolCalls.delete(message.tool_call_id);\n }\n }\n\n return [...pendingToolCalls.values()];\n};\n\nconst getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...msg.attachments.flatMap((a) => a.content),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default:\n const _exhaustiveCheck: \"file\" | \"audio\" = type;\n throw new Error(\n `Unsupported append content part type: ${_exhaustiveCheck}`,\n );\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n\n return content;\n};\n\nconst symbolLangGraphRuntimeExtras = Symbol(\"langgraph-runtime-extras\");\ntype LangGraphRuntimeExtras = {\n [symbolLangGraphRuntimeExtras]: true;\n send: (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => Promise<void>;\n};\n\nconst asLangGraphRuntimeExtras = (extras: unknown): LangGraphRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolLangGraphRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useLangGraphRuntime\",\n );\n\n return extras as LangGraphRuntimeExtras;\n};\n\nexport const useLangGraphRuntimeSend = () => {\n const { send } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return send;\n};\n\nexport const useLangGraphRuntimeSendCommand = (command: LangGraphCommand) => {\n const send = useLangGraphRuntimeSend();\n return () => send([], { command });\n};\n\nexport const useLangGraphRuntime = ({\n autoCancelPendingToolCalls,\n adapters: { attachments, feedback, speech } = {},\n unstable_allowImageAttachments,\n unstable_allowCancellation,\n stream,\n threadId,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n /**\n * @deprecated Use `adapters: { attachments: new SimpleImageAttachmentAdapter() }` instead. This option will be removed in a future version.\n */\n unstable_allowImageAttachments?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n stream: LangGraphStreamCallback<LangChainMessage>;\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n}) => {\n const { messages, sendMessage, cancel, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(messages, config);\n } catch (error) {\n console.error(\"Error streaming messages:\", error);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertLangchainMessages,\n messages,\n isRunning,\n });\n\n if (attachments && unstable_allowImageAttachments)\n throw new Error(\n \"Replace unstable_allowImageAttachments with `adapters: { attachments: new SimpleImageAttachmentAdapter() }`.\",\n );\n if (unstable_allowImageAttachments)\n attachments = new SimpleImageAttachmentAdapter();\n\n const switchToThread = !onSwitchToThread\n ? undefined\n : async (externalId: string) => {\n const { messages } = await onSwitchToThread(externalId);\n setMessages(messages);\n };\n\n const threadList: NonNullable<\n ExternalStoreAdapter[\"adapters\"]\n >[\"threadList\"] = {\n threadId,\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: switchToThread,\n };\n\n const loadingRef = useRef(false);\n const threadListItemRuntime = useThreadListItemRuntime({ optional: true });\n useEffect(() => {\n if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;\n\n const externalId = threadListItemRuntime.getState().externalId;\n if (externalId) {\n loadingRef.current = true;\n switchToThread(externalId).finally(() => {\n loadingRef.current = false;\n });\n }\n }, []);\n\n return useExternalStoreRuntime({\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments,\n feedback,\n speech,\n threadList,\n },\n extras: {\n [symbolLangGraphRuntimeExtras]: true,\n send: handleSendMessage,\n } satisfies LangGraphRuntimeExtras,\n onNew: (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingToolCalls(messages).map(\n (t) =>\n ({\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n }) satisfies LangChainMessage & { type: \"tool\" },\n )\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n },\n );\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n // TODO parallel human in the loop calls\n await handleSendMessage(\n [\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ],\n // TODO reuse runconfig here!\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n};\n","\"use client\";\n\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { LangChainMessage } from \"./types\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { ThreadUserMessage } from \"@assistant-ui/react\";\n\nconst contentToParts = (\n content: LangChainMessage[\"content\"],\n) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n return content\n .map((part): ThreadUserMessage[\"content\"][number] | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image_url\":\n if (typeof part.image_url === \"string\") {\n return { type: \"image\", image: part.image_url };\n } else {\n return {\n type: \"image\",\n image: part.image_url.url,\n };\n }\n\n case \"tool_use\":\n return null;\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);\n }\n })\n .filter((a) => a !== null);\n};\n\nexport const convertLangchainMessages: useExternalMessageConverter.Callback<\n LangChainMessage\n> = (message) => {\n switch (message.type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: message.content }],\n };\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n case \"ai\":\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...contentToParts(message.content),\n ...(message.tool_calls?.map(\n (chunk): ToolCallContentPart => ({\n type: \"tool-call\",\n toolCallId: chunk.id,\n toolName: chunk.name,\n args: chunk.args,\n argsText:\n message.tool_call_chunks?.find((c) => c.id === chunk.id)\n ?.args ?? JSON.stringify(chunk.args),\n }),\n ) ?? []),\n ],\n };\n case \"tool\":\n return {\n role: \"tool\",\n toolName: message.name,\n toolCallId: message.tool_call_id,\n result: message.content,\n };\n }\n};\n","import { useState, useCallback, useRef } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nconst { generateId } = INTERNAL;\n\nexport type LangGraphCommand = {\n resume: string;\n};\n\nexport type LangGraphSendMessageConfig = {\n command?: LangGraphCommand;\n runConfig?: unknown;\n};\n\ntype LangGraphMessagesEvent<TMessage> = {\n event: \"messages/partial\" | \"messages/complete\" | string;\n data: TMessage[] | any;\n};\nexport type LangGraphStreamCallback<TMessage> = (\n messages: TMessage[],\n config: LangGraphSendMessageConfig & { abortSignal: AbortSignal },\n) =>\n | Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>>\n | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;\n\nexport const useLangGraphMessages = <TMessage extends { id?: string }>({\n stream,\n}: {\n stream: LangGraphStreamCallback<TMessage>;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[], config: LangGraphSendMessageConfig) => {\n // ensure all messages have an ID\n newMessages = newMessages.map((m) => (m.id ? m : { ...m, id: uuidv4() }));\n\n const messagesMap = new Map<string, TMessage>();\n const addMessages = (newMessages: TMessage[]) => {\n if (newMessages.length === 0) return;\n for (const message of newMessages) {\n messagesMap.set(message.id ?? generateId(), message);\n }\n setMessages([...messagesMap.values()]);\n };\n addMessages([...messages, ...newMessages]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n const response = await stream(newMessages, {\n ...config,\n abortSignal: abortController.signal,\n });\n\n for await (const chunk of response) {\n if (\n chunk.event === \"messages/partial\" ||\n chunk.event === \"messages/complete\"\n ) {\n // TODO verify bugfix - if there are messages without IDs, they appear duplicated\n addMessages(chunk.data);\n }\n }\n },\n [messages, stream],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, [abortControllerRef]);\n\n return { messages, sendMessage, cancel, setMessages };\n};\n"],"mappings":"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","names":["useRef","useState","newMessages","useState","messages","useRef"]}
1
+ {"version":3,"sources":["../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n useThread,\n useThreadListItemRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport {\n LangGraphCommand,\n LangGraphInterruptState,\n LangGraphSendMessageConfig,\n LangGraphStreamCallback,\n useLangGraphMessages,\n} from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } from \"@assistant-ui/react\";\nimport { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { AppendMessage } from \"@assistant-ui/react\";\nimport { ExternalStoreAdapter } from \"@assistant-ui/react\";\nimport { FeedbackAdapter } from \"@assistant-ui/react\";\nimport { SpeechSynthesisAdapter } from \"@assistant-ui/react\";\n\nconst getPendingToolCalls = (messages: LangChainMessage[]) => {\n const pendingToolCalls = new Map<string, LangChainToolCall>();\n for (const message of messages) {\n if (message.type === \"ai\") {\n for (const toolCall of message.tool_calls ?? []) {\n pendingToolCalls.set(toolCall.id, toolCall);\n }\n }\n if (message.type === \"tool\") {\n pendingToolCalls.delete(message.tool_call_id);\n }\n }\n\n return [...pendingToolCalls.values()];\n};\n\nconst getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...msg.attachments.flatMap((a) => a.content),\n ];\n const content = allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n\n default:\n const _exhaustiveCheck: \"file\" | \"audio\" = type;\n throw new Error(\n `Unsupported append content part type: ${_exhaustiveCheck}`,\n );\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n\n return content;\n};\n\nconst symbolLangGraphRuntimeExtras = Symbol(\"langgraph-runtime-extras\");\ntype LangGraphRuntimeExtras = {\n [symbolLangGraphRuntimeExtras]: true;\n send: (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => Promise<void>;\n interrupt: LangGraphInterruptState | undefined;\n};\n\nconst asLangGraphRuntimeExtras = (extras: unknown): LangGraphRuntimeExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolLangGraphRuntimeExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useLangGraphRuntime\",\n );\n\n return extras as LangGraphRuntimeExtras;\n};\n\nexport const useLangGraphInterruptState = () => {\n const { interrupt } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return interrupt;\n};\n\nexport const useLangGraphSend = () => {\n const { send } = useThread((t) => asLangGraphRuntimeExtras(t.extras));\n return send;\n};\n\nexport const useLangGraphSendCommand = (command: LangGraphCommand) => {\n const send = useLangGraphSend();\n return () => send([], { command });\n};\n\nexport const useLangGraphRuntime = ({\n autoCancelPendingToolCalls,\n adapters: { attachments, feedback, speech } = {},\n unstable_allowImageAttachments,\n unstable_allowCancellation,\n stream,\n threadId,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n /**\n * @deprecated Use `adapters: { attachments: new SimpleImageAttachmentAdapter() }` instead. This option will be removed in a future version.\n */\n unstable_allowImageAttachments?: boolean | undefined;\n unstable_allowCancellation?: boolean | undefined;\n stream: LangGraphStreamCallback<LangChainMessage>;\n /**\n * @deprecated For thread management use `useCloudThreadListRuntime` instead. This option will be removed in a future version.\n */\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n adapters?:\n | {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n feedback?: FeedbackAdapter;\n }\n | undefined;\n}) => {\n const { interrupt, messages, sendMessage, cancel, setMessages } =\n useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (\n messages: LangChainMessage[],\n config: LangGraphSendMessageConfig,\n ) => {\n try {\n setIsRunning(true);\n await sendMessage(messages, config);\n } catch (error) {\n console.error(\"Error streaming messages:\", error);\n } finally {\n setIsRunning(false);\n }\n };\n\n const threadMessages = useExternalMessageConverter({\n callback: convertLangchainMessages,\n messages,\n isRunning,\n });\n\n if (attachments && unstable_allowImageAttachments)\n throw new Error(\n \"Replace unstable_allowImageAttachments with `adapters: { attachments: new SimpleImageAttachmentAdapter() }`.\",\n );\n if (unstable_allowImageAttachments)\n attachments = new SimpleImageAttachmentAdapter();\n\n const switchToThread = !onSwitchToThread\n ? undefined\n : async (externalId: string) => {\n const { messages } = await onSwitchToThread(externalId);\n setMessages(messages);\n };\n\n const threadList: NonNullable<\n ExternalStoreAdapter[\"adapters\"]\n >[\"threadList\"] = {\n threadId,\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: switchToThread,\n };\n\n const loadingRef = useRef(false);\n const threadListItemRuntime = useThreadListItemRuntime({ optional: true });\n useEffect(() => {\n if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;\n\n const externalId = threadListItemRuntime.getState().externalId;\n if (externalId) {\n loadingRef.current = true;\n switchToThread(externalId).finally(() => {\n loadingRef.current = false;\n });\n }\n }, []);\n\n return useExternalStoreRuntime({\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments,\n feedback,\n speech,\n threadList,\n },\n extras: {\n [symbolLangGraphRuntimeExtras]: true,\n interrupt,\n send: handleSendMessage,\n } satisfies LangGraphRuntimeExtras,\n onNew: (msg) => {\n const cancellations =\n autoCancelPendingToolCalls !== false\n ? getPendingToolCalls(messages).map(\n (t) =>\n ({\n type: \"tool\",\n name: t.name,\n tool_call_id: t.id,\n content: JSON.stringify({ cancelled: true }),\n }) satisfies LangChainMessage & { type: \"tool\" },\n )\n : [];\n\n return handleSendMessage(\n [\n ...cancellations,\n {\n type: \"human\",\n content: getMessageContent(msg),\n },\n ],\n {\n runConfig: msg.runConfig,\n },\n );\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n // TODO parallel human in the loop calls\n await handleSendMessage(\n [\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ],\n // TODO reuse runconfig here!\n {},\n );\n },\n onCancel: unstable_allowCancellation\n ? async () => {\n cancel();\n }\n : undefined,\n });\n};\n","\"use client\";\n\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { LangChainMessage } from \"./types\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { ThreadUserMessage } from \"@assistant-ui/react\";\n\nconst contentToParts = (\n content: LangChainMessage[\"content\"],\n) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n return content\n .map((part): ThreadUserMessage[\"content\"][number] | null => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image_url\":\n if (typeof part.image_url === \"string\") {\n return { type: \"image\", image: part.image_url };\n } else {\n return {\n type: \"image\",\n image: part.image_url.url,\n };\n }\n\n case \"tool_use\":\n return null;\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);\n }\n })\n .filter((a) => a !== null);\n};\n\nexport const convertLangchainMessages: useExternalMessageConverter.Callback<\n LangChainMessage\n> = (message) => {\n switch (message.type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: message.content }],\n };\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n };\n case \"ai\":\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...contentToParts(message.content),\n ...(message.tool_calls?.map(\n (chunk): ToolCallContentPart => ({\n type: \"tool-call\",\n toolCallId: chunk.id,\n toolName: chunk.name,\n args: chunk.args,\n argsText:\n message.tool_call_chunks?.find((c) => c.id === chunk.id)\n ?.args ?? JSON.stringify(chunk.args),\n }),\n ) ?? []),\n ],\n };\n case \"tool\":\n return {\n role: \"tool\",\n toolName: message.name,\n toolCallId: message.tool_call_id,\n result: message.content,\n };\n }\n};\n","import { useState, useCallback, useRef } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport type LangGraphCommand = {\n resume: string;\n};\n\nexport type LangGraphSendMessageConfig = {\n command?: LangGraphCommand;\n runConfig?: unknown;\n};\n\ntype LangGraphMessagesEvent<TMessage> = {\n event:\n | \"messages/partial\"\n | \"messages/complete\"\n | \"metadata\"\n | \"updates\"\n | string;\n data: TMessage[] | any;\n};\nexport type LangGraphStreamCallback<TMessage> = (\n messages: TMessage[],\n config: LangGraphSendMessageConfig & { abortSignal: AbortSignal },\n) =>\n | Promise<AsyncGenerator<LangGraphMessagesEvent<TMessage>>>\n | AsyncGenerator<LangGraphMessagesEvent<TMessage>>;\n\nexport type LangGraphInterruptState = {\n value: any;\n resumable: boolean;\n when: string;\n ns: string[];\n};\n\nexport const useLangGraphMessages = <TMessage extends { id?: string }>({\n stream,\n}: {\n stream: LangGraphStreamCallback<TMessage>;\n}) => {\n const [interrupt, setInterrupt] = useState<\n LangGraphInterruptState | undefined\n >();\n const [messages, setMessages] = useState<TMessage[]>([]);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[], config: LangGraphSendMessageConfig) => {\n // ensure all messages have an ID\n newMessages = newMessages.map((m) => (m.id ? m : { ...m, id: uuidv4() }));\n\n const messagesMap = new Map<string, TMessage>();\n const addMessages = (newMessages: TMessage[]) => {\n if (newMessages.length === 0) return;\n for (const message of newMessages) {\n messagesMap.set(message.id ?? uuidv4(), message);\n }\n setMessages([...messagesMap.values()]);\n };\n addMessages([...messages, ...newMessages]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n const response = await stream(newMessages, {\n ...config,\n abortSignal: abortController.signal,\n });\n\n for await (const chunk of response) {\n if (\n chunk.event === \"messages/partial\" ||\n chunk.event === \"messages/complete\"\n ) {\n addMessages(chunk.data);\n } else if (chunk.event === \"updates\") {\n setInterrupt(chunk.data.__interrupt__);\n }\n }\n },\n [messages, stream],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, [abortControllerRef]);\n\n return { interrupt, messages, sendMessage, cancel, setMessages };\n};\n"],"mappings":";AAAA,SAAS,WAAW,UAAAA,SAAQ,YAAAC,iBAAgB;AAE5C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACAP,IAAM,iBAAiB,CACrB,YACG;AACH,MAAI,OAAO,YAAY;AACrB,WAAO,CAAC,EAAE,MAAM,QAAiB,MAAM,QAAQ,CAAC;AAClD,SAAO,QACJ,IAAI,CAAC,SAAsD;AAC1D,UAAM,OAAO,KAAK;AAClB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK;AAAA,MACzC,KAAK;AACH,YAAI,OAAO,KAAK,cAAc,UAAU;AACtC,iBAAO,EAAE,MAAM,SAAS,OAAO,KAAK,UAAU;AAAA,QAChD,OAAO;AACL,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,OAAO,KAAK,UAAU;AAAA,UACxB;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO;AAAA,MACT;AACE,cAAM,mBAA0B;AAChC,cAAM,IAAI,MAAM,8BAA8B,gBAAgB,EAAE;AAAA,IACpE;AAAA,EACF,CAAC,EACA,OAAO,CAAC,MAAM,MAAM,IAAI;AAC7B;AAEO,IAAM,2BAET,CAAC,YAAY;AACf,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACnD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,SAAS,eAAe,QAAQ,OAAO;AAAA,MACzC;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,SAAS;AAAA,UACP,GAAG,eAAe,QAAQ,OAAO;AAAA,UACjC,GAAI,QAAQ,YAAY;AAAA,YACtB,CAAC,WAAgC;AAAA,cAC/B,MAAM;AAAA,cACN,YAAY,MAAM;AAAA,cAClB,UAAU,MAAM;AAAA,cAChB,MAAM,MAAM;AAAA,cACZ,UACE,QAAQ,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,GACnD,QAAQ,KAAK,UAAU,MAAM,IAAI;AAAA,YACzC;AAAA,UACF,KAAK,CAAC;AAAA,QACR;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU,QAAQ;AAAA,QAClB,YAAY,QAAQ;AAAA,QACpB,QAAQ,QAAQ;AAAA,MAClB;AAAA,EACJ;AACF;;;ACjFA,SAAS,UAAU,aAAa,cAAc;AAC9C,SAAS,MAAM,cAAc;AAkCtB,IAAM,uBAAuB,CAAmC;AAAA,EACrE;AACF,MAEM;AACJ,QAAM,CAAC,WAAW,YAAY,IAAI,SAEhC;AACF,QAAM,CAAC,UAAU,WAAW,IAAI,SAAqB,CAAC,CAAC;AACvD,QAAM,qBAAqB,OAA+B,IAAI;AAE9D,QAAM,cAAc;AAAA,IAClB,OAAO,aAAyB,WAAuC;AAErE,oBAAc,YAAY,IAAI,CAAC,MAAO,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,IAAI,OAAO,EAAE,CAAE;AAExE,YAAM,cAAc,oBAAI,IAAsB;AAC9C,YAAM,cAAc,CAACC,iBAA4B;AAC/C,YAAIA,aAAY,WAAW,EAAG;AAC9B,mBAAW,WAAWA,cAAa;AACjC,sBAAY,IAAI,QAAQ,MAAM,OAAO,GAAG,OAAO;AAAA,QACjD;AACA,oBAAY,CAAC,GAAG,YAAY,OAAO,CAAC,CAAC;AAAA,MACvC;AACA,kBAAY,CAAC,GAAG,UAAU,GAAG,WAAW,CAAC;AAEzC,YAAM,kBAAkB,IAAI,gBAAgB;AAC5C,yBAAmB,UAAU;AAC7B,YAAM,WAAW,MAAM,OAAO,aAAa;AAAA,QACzC,GAAG;AAAA,QACH,aAAa,gBAAgB;AAAA,MAC/B,CAAC;AAED,uBAAiB,SAAS,UAAU;AAClC,YACE,MAAM,UAAU,sBAChB,MAAM,UAAU,qBAChB;AACA,sBAAY,MAAM,IAAI;AAAA,QACxB,WAAW,MAAM,UAAU,WAAW;AACpC,uBAAa,MAAM,KAAK,aAAa;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU,MAAM;AAAA,EACnB;AAEA,QAAM,SAAS,YAAY,MAAM;AAC/B,QAAI,mBAAmB,SAAS;AAC9B,yBAAmB,QAAQ,MAAM;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,kBAAkB,CAAC;AAEvB,SAAO,EAAE,WAAW,UAAU,aAAa,QAAQ,YAAY;AACjE;;;AFzEA,SAAS,oCAAoC;AAO7C,IAAM,sBAAsB,CAAC,aAAiC;AAC5D,QAAM,mBAAmB,oBAAI,IAA+B;AAC5D,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,SAAS,MAAM;AACzB,iBAAW,YAAY,QAAQ,cAAc,CAAC,GAAG;AAC/C,yBAAiB,IAAI,SAAS,IAAI,QAAQ;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,QAAQ;AAC3B,uBAAiB,OAAO,QAAQ,YAAY;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,iBAAiB,OAAO,CAAC;AACtC;AAEA,IAAM,oBAAoB,CAAC,QAAuB;AAChD,QAAM,aAAa;AAAA,IACjB,GAAG,IAAI;AAAA,IACP,GAAG,IAAI,YAAY,QAAQ,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7C;AACA,QAAM,UAAU,WAAW,IAAI,CAAC,SAAS;AACvC,UAAM,OAAO,KAAK;AAClB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,EAAE,MAAM,QAAiB,MAAM,KAAK,KAAK;AAAA,MAClD,KAAK;AACH,eAAO,EAAE,MAAM,aAAsB,WAAW,EAAE,KAAK,KAAK,MAAM,EAAE;AAAA,MAEtE,KAAK;AACH,cAAM,IAAI,MAAM,sCAAsC;AAAA,MAExD;AACE,cAAM,mBAAqC;AAC3C,cAAM,IAAI;AAAA,UACR,yCAAyC,gBAAgB;AAAA,QAC3D;AAAA,IACJ;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,GAAG,SAAS,QAAQ;AACvD,WAAO,QAAQ,CAAC,EAAE,QAAQ;AAAA,EAC5B;AAEA,SAAO;AACT;AAEA,IAAM,+BAA+B,OAAO,0BAA0B;AAUtE,IAAM,2BAA2B,CAAC,WAA4C;AAC5E,MACE,OAAO,WAAW,YAClB,UAAU,QACV,EAAE,gCAAgC;AAElC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAEF,SAAO;AACT;AAEO,IAAM,6BAA6B,MAAM;AAC9C,QAAM,EAAE,UAAU,IAAI,UAAU,CAAC,MAAM,yBAAyB,EAAE,MAAM,CAAC;AACzE,SAAO;AACT;AAEO,IAAM,mBAAmB,MAAM;AACpC,QAAM,EAAE,KAAK,IAAI,UAAU,CAAC,MAAM,yBAAyB,EAAE,MAAM,CAAC;AACpE,SAAO;AACT;AAEO,IAAM,0BAA0B,CAAC,YAA8B;AACpE,QAAM,OAAO,iBAAiB;AAC9B,SAAO,MAAM,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC;AACnC;AAEO,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA,UAAU,EAAE,aAAa,UAAU,OAAO,IAAI,CAAC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MA0BM;AACJ,QAAM,EAAE,WAAW,UAAU,aAAa,QAAQ,YAAY,IAC5D,qBAAqB;AAAA,IACnB;AAAA,EACF,CAAC;AAEH,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,oBAAoB,OACxBC,WACA,WACG;AACH,QAAI;AACF,mBAAa,IAAI;AACjB,YAAM,YAAYA,WAAU,MAAM;AAAA,IACpC,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAAA,IAClD,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,iBAAiB,4BAA4B;AAAA,IACjD,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,eAAe;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,MAAI;AACF,kBAAc,IAAI,6BAA6B;AAEjD,QAAM,iBAAiB,CAAC,mBACpB,SACA,OAAO,eAAuB;AAC5B,UAAM,EAAE,UAAAA,UAAS,IAAI,MAAM,iBAAiB,UAAU;AACtD,gBAAYA,SAAQ;AAAA,EACtB;AAEJ,QAAM,aAEY;AAAA,IAChB;AAAA,IACA,qBAAqB,CAAC,sBAClB,SACA,YAAY;AACV,YAAM,oBAAoB;AAC1B,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,IACJ,kBAAkB;AAAA,EACpB;AAEA,QAAM,aAAaC,QAAO,KAAK;AAC/B,QAAM,wBAAwB,yBAAyB,EAAE,UAAU,KAAK,CAAC;AACzE,YAAU,MAAM;AACd,QAAI,CAAC,yBAAyB,CAAC,kBAAkB,WAAW,QAAS;AAErE,UAAM,aAAa,sBAAsB,SAAS,EAAE;AACpD,QAAI,YAAY;AACd,iBAAW,UAAU;AACrB,qBAAe,UAAU,EAAE,QAAQ,MAAM;AACvC,mBAAW,UAAU;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,wBAAwB;AAAA,IAC7B;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,CAAC,4BAA4B,GAAG;AAAA,MAChC;AAAA,MACA,MAAM;AAAA,IACR;AAAA,IACA,OAAO,CAAC,QAAQ;AACd,YAAM,gBACJ,+BAA+B,QAC3B,oBAAoB,QAAQ,EAAE;AAAA,QAC5B,CAAC,OACE;AAAA,UACC,MAAM;AAAA,UACN,MAAM,EAAE;AAAA,UACR,cAAc,EAAE;AAAA,UAChB,SAAS,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,QAC7C;AAAA,MACJ,IACA,CAAC;AAEP,aAAO;AAAA,QACL;AAAA,UACE,GAAG;AAAA,UACH;AAAA,YACE,MAAM;AAAA,YACN,SAAS,kBAAkB,GAAG;AAAA,UAChC;AAAA,QACF;AAAA,QACA;AAAA,UACE,WAAW,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB,OAAO,EAAE,YAAY,UAAU,OAAO,MAAM;AAE3D,YAAM;AAAA,QACJ;AAAA,UACE;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,YACd,SAAS,KAAK,UAAU,MAAM;AAAA,UAChC;AAAA,QACF;AAAA;AAAA,QAEA,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,UAAU,6BACN,YAAY;AACV,aAAO;AAAA,IACT,IACA;AAAA,EACN,CAAC;AACH;","names":["useRef","useState","newMessages","useState","messages","useRef"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-langgraph",
3
- "version": "0.1.17",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -28,7 +28,7 @@
28
28
  "zod": "^3.24.1"
29
29
  },
30
30
  "peerDependencies": {
31
- "@assistant-ui/react": "^0.7.38",
31
+ "@assistant-ui/react": "^0.7.45",
32
32
  "@types/react": "*",
33
33
  "react": "^18 || ^19 || ^19.0.0-rc"
34
34
  },
@@ -38,10 +38,10 @@
38
38
  }
39
39
  },
40
40
  "devDependencies": {
41
- "eslint-config-next": "15.1.4",
41
+ "eslint-config-next": "15.1.5",
42
42
  "tsup": "8.3.5",
43
- "@assistant-ui/tsconfig": "0.0.0",
44
- "@assistant-ui/react": "0.7.38"
43
+ "@assistant-ui/react": "0.7.45",
44
+ "@assistant-ui/tsconfig": "0.0.0"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public",