@assistant-ui/react-langgraph 0.0.18 → 0.0.19

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
@@ -55,9 +55,10 @@ type LangChainEvent = {
55
55
  data: LangChainMessage[];
56
56
  };
57
57
 
58
- declare const useLangGraphRuntime: ({ threadId, autoCancelPendingToolCalls, stream, onSwitchToNewThread, onSwitchToThread, }: {
58
+ declare const useLangGraphRuntime: ({ threadId, autoCancelPendingToolCalls, unstable_allowImageAttachments, stream, onSwitchToNewThread, onSwitchToThread, }: {
59
59
  threadId?: string | undefined;
60
60
  autoCancelPendingToolCalls?: boolean | undefined;
61
+ unstable_allowImageAttachments?: boolean | undefined;
61
62
  stream: (messages: LangChainMessage[]) => Promise<AsyncGenerator<{
62
63
  event: string;
63
64
  data: any;
package/dist/index.d.ts CHANGED
@@ -55,9 +55,10 @@ type LangChainEvent = {
55
55
  data: LangChainMessage[];
56
56
  };
57
57
 
58
- declare const useLangGraphRuntime: ({ threadId, autoCancelPendingToolCalls, stream, onSwitchToNewThread, onSwitchToThread, }: {
58
+ declare const useLangGraphRuntime: ({ threadId, autoCancelPendingToolCalls, unstable_allowImageAttachments, stream, onSwitchToNewThread, onSwitchToThread, }: {
59
59
  threadId?: string | undefined;
60
60
  autoCancelPendingToolCalls?: boolean | undefined;
61
+ unstable_allowImageAttachments?: boolean | undefined;
61
62
  stream: (messages: LangChainMessage[]) => Promise<AsyncGenerator<{
62
63
  event: string;
63
64
  data: any;
package/dist/index.js CHANGED
@@ -147,6 +147,7 @@ var useLangGraphMessages = ({
147
147
  };
148
148
 
149
149
  // src/useLangGraphRuntime.ts
150
+ var import_react5 = require("@assistant-ui/react");
150
151
  var getPendingToolCalls = (messages) => {
151
152
  const pendingToolCalls = /* @__PURE__ */ new Map();
152
153
  for (const message of messages) {
@@ -164,6 +165,7 @@ var getPendingToolCalls = (messages) => {
164
165
  var useLangGraphRuntime = ({
165
166
  threadId,
166
167
  autoCancelPendingToolCalls,
168
+ unstable_allowImageAttachments,
167
169
  stream,
168
170
  onSwitchToNewThread,
169
171
  onSwitchToThread
@@ -191,9 +193,10 @@ var useLangGraphRuntime = ({
191
193
  threadId,
192
194
  isRunning,
193
195
  messages: threadMessages,
196
+ adapters: {
197
+ attachments: unstable_allowImageAttachments ? new import_react5.SimpleImageAttachmentAdapter() : void 0
198
+ },
194
199
  onNew: (msg) => {
195
- if (msg.content.length !== 1 || msg.content[0]?.type !== "text")
196
- throw new Error("Only text messages are supported");
197
200
  const cancellations = autoCancelPendingToolCalls !== false ? getPendingToolCalls(messages).map(
198
201
  (t) => ({
199
202
  type: "tool",
@@ -202,11 +205,30 @@ var useLangGraphRuntime = ({
202
205
  content: JSON.stringify({ cancelled: true })
203
206
  })
204
207
  ) : [];
208
+ const allContent = [
209
+ ...msg.content,
210
+ ...msg.attachments?.flatMap((a) => a.content) ?? []
211
+ ];
205
212
  return handleSendMessage([
206
213
  ...cancellations,
207
214
  {
208
215
  type: "human",
209
- content: msg.content[0].text
216
+ content: allContent.map((part) => {
217
+ const type = part.type;
218
+ switch (type) {
219
+ case "text":
220
+ return { type: "text", text: part.text };
221
+ case "image":
222
+ return { type: "image_url", image_url: part.image };
223
+ case "tool-call":
224
+ throw new Error("Tool call appends are not supported yet.");
225
+ default:
226
+ const _exhaustiveCheck = type;
227
+ throw new Error(
228
+ `Unknown content part type: ${_exhaustiveCheck}`
229
+ );
230
+ }
231
+ })
210
232
  }
211
233
  ]);
212
234
  },
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 { useLangGraphRuntime } 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 { useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport { useLangGraphMessages } from \"./useLangGraphMessages\";\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\nexport const useLangGraphRuntime = ({\n threadId,\n autoCancelPendingToolCalls,\n stream,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n stream: (messages: LangChainMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n}) => {\n const { messages, sendMessage, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (messages: LangChainMessage[]) => {\n try {\n setIsRunning(true);\n await sendMessage(messages);\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 return useExternalStoreRuntime({\n threadId,\n isRunning,\n messages: threadMessages,\n onNew: (msg) => {\n if (msg.content.length !== 1 || msg.content[0]?.type !== \"text\")\n throw new Error(\"Only text messages are supported\");\n\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 ...cancellations,\n {\n type: \"human\",\n content: msg.content[0].text,\n },\n ]);\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n await handleSendMessage([\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ]);\n },\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: !onSwitchToThread\n ? undefined\n : async (threadId) => {\n const { messages } = await onSwitchToThread(threadId);\n setMessages(messages);\n },\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 } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\n\nconst { generateId } = INTERNAL;\n\nexport const useLangGraphMessages = <TMessage>({\n stream,\n}: {\n stream: (messages: TMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[]) => {\n const optimisticMessages = [...messages, ...newMessages];\n if (newMessages.length > 0) {\n setMessages(optimisticMessages);\n }\n\n const response = await stream(newMessages);\n\n const completeMessages: TMessage[] = [];\n let partialMessages: Map<string, TMessage> = new Map();\n for await (const chunk of response) {\n if (chunk.event === \"messages/partial\") {\n // bug fix: messages/complete is not sent for some python langchain backends\n if (completeMessages.length === 0) {\n completeMessages.push(...optimisticMessages);\n }\n\n for (const message of chunk.data) {\n if (!message.id) throw new Error(\"Partial message missing id\");\n\n partialMessages.set(message.id, message);\n }\n } else if (chunk.event === \"messages/complete\") {\n for (const message of chunk.data) {\n if (message.id) {\n partialMessages.delete(message.id);\n }\n\n // bug fix: tool results can arrive before the message is complete ?\n // if we have partial messages left, we add complete message to partial messages\n if (partialMessages.size > 0) {\n partialMessages.set(message.id ?? generateId(), message);\n } else {\n completeMessages.push(message);\n }\n }\n } else {\n continue;\n }\n\n setMessages([...completeMessages, ...partialMessages.values()]);\n }\n // if (partialMessages.size > 0) {\n // throw new Error(\"A partial message was not marked as complete\");\n // }\n },\n [stream],\n );\n console.log(\"messages\", messages);\n return { messages, sendMessage, setMessages };\n};\n"],"mappings":"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","names":["import_react","import_react","messages","threadId"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["export { useLangGraphRuntime } 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 { useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport { useLangGraphMessages } from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } 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\nexport const useLangGraphRuntime = ({\n threadId,\n autoCancelPendingToolCalls,\n unstable_allowImageAttachments,\n stream,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n unstable_allowImageAttachments?: boolean | undefined;\n stream: (messages: LangChainMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n}) => {\n const { messages, sendMessage, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (messages: LangChainMessage[]) => {\n try {\n setIsRunning(true);\n await sendMessage(messages);\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 return useExternalStoreRuntime({\n threadId,\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments: unstable_allowImageAttachments\n ? new SimpleImageAttachmentAdapter()\n : undefined,\n },\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 const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n\n return handleSendMessage([\n ...cancellations,\n {\n type: \"human\",\n content: allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image\":\n return { type: \"image_url\", image_url: part.image };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported yet.\");\n\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(\n `Unknown content part type: ${_exhaustiveCheck}`,\n );\n }\n }),\n },\n ]);\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n await handleSendMessage([\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ]);\n },\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: !onSwitchToThread\n ? undefined\n : async (threadId) => {\n const { messages } = await onSwitchToThread(threadId);\n setMessages(messages);\n },\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 } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\n\nconst { generateId } = INTERNAL;\n\nexport const useLangGraphMessages = <TMessage>({\n stream,\n}: {\n stream: (messages: TMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[]) => {\n const optimisticMessages = [...messages, ...newMessages];\n if (newMessages.length > 0) {\n setMessages(optimisticMessages);\n }\n\n const response = await stream(newMessages);\n\n const completeMessages: TMessage[] = [];\n let partialMessages: Map<string, TMessage> = new Map();\n for await (const chunk of response) {\n if (chunk.event === \"messages/partial\") {\n // bug fix: messages/complete is not sent for some python langchain backends\n if (completeMessages.length === 0) {\n completeMessages.push(...optimisticMessages);\n }\n\n for (const message of chunk.data) {\n if (!message.id) throw new Error(\"Partial message missing id\");\n\n partialMessages.set(message.id, message);\n }\n } else if (chunk.event === \"messages/complete\") {\n for (const message of chunk.data) {\n if (message.id) {\n partialMessages.delete(message.id);\n }\n\n // bug fix: tool results can arrive before the message is complete ?\n // if we have partial messages left, we add complete message to partial messages\n if (partialMessages.size > 0) {\n partialMessages.set(message.id ?? generateId(), message);\n } else {\n completeMessages.push(message);\n }\n }\n } else {\n continue;\n }\n\n setMessages([...completeMessages, ...partialMessages.values()]);\n }\n // if (partialMessages.size > 0) {\n // throw new Error(\"A partial message was not marked as complete\");\n // }\n },\n [stream],\n );\n console.log(\"messages\", messages);\n return { messages, sendMessage, setMessages };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAAyB;AAEzB,IAAAA,gBAGO;;;ACEP,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,mBAAsC;AACtC,IAAAC,gBAAyB;AAEzB,IAAM,EAAE,WAAW,IAAI;AAEhB,IAAM,uBAAuB,CAAW;AAAA,EAC7C;AACF,MAOM;AACJ,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAqB,CAAC,CAAC;AAEvD,QAAM,kBAAc;AAAA,IAClB,OAAO,gBAA4B;AACjC,YAAM,qBAAqB,CAAC,GAAG,UAAU,GAAG,WAAW;AACvD,UAAI,YAAY,SAAS,GAAG;AAC1B,oBAAY,kBAAkB;AAAA,MAChC;AAEA,YAAM,WAAW,MAAM,OAAO,WAAW;AAEzC,YAAM,mBAA+B,CAAC;AACtC,UAAI,kBAAyC,oBAAI,IAAI;AACrD,uBAAiB,SAAS,UAAU;AAClC,YAAI,MAAM,UAAU,oBAAoB;AAEtC,cAAI,iBAAiB,WAAW,GAAG;AACjC,6BAAiB,KAAK,GAAG,kBAAkB;AAAA,UAC7C;AAEA,qBAAW,WAAW,MAAM,MAAM;AAChC,gBAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,4BAA4B;AAE7D,4BAAgB,IAAI,QAAQ,IAAI,OAAO;AAAA,UACzC;AAAA,QACF,WAAW,MAAM,UAAU,qBAAqB;AAC9C,qBAAW,WAAW,MAAM,MAAM;AAChC,gBAAI,QAAQ,IAAI;AACd,8BAAgB,OAAO,QAAQ,EAAE;AAAA,YACnC;AAIA,gBAAI,gBAAgB,OAAO,GAAG;AAC5B,8BAAgB,IAAI,QAAQ,MAAM,WAAW,GAAG,OAAO;AAAA,YACzD,OAAO;AACL,+BAAiB,KAAK,OAAO;AAAA,YAC/B;AAAA,UACF;AAAA,QACF,OAAO;AACL;AAAA,QACF;AAEA,oBAAY,CAAC,GAAG,kBAAkB,GAAG,gBAAgB,OAAO,CAAC,CAAC;AAAA,MAChE;AAAA,IAIF;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AACA,UAAQ,IAAI,YAAY,QAAQ;AAChC,SAAO,EAAE,UAAU,aAAa,YAAY;AAC9C;;;AF5DA,IAAAC,gBAA6C;AAE7C,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;AAEO,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAcM;AACJ,QAAM,EAAE,UAAU,aAAa,YAAY,IAAI,qBAAqB;AAAA,IAClE;AAAA,EACF,CAAC;AAED,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,oBAAoB,OAAOC,cAAiC;AAChE,QAAI;AACF,mBAAa,IAAI;AACjB,YAAM,YAAYA,SAAQ;AAAA,IAC5B,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAAA,IAClD,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,qBAAiB,2CAA4B;AAAA,IACjD,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF,CAAC;AAED,aAAO,uCAAwB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,MACR,aAAa,iCACT,IAAI,2CAA6B,IACjC;AAAA,IACN;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,YAAM,aAAa;AAAA,QACjB,GAAG,IAAI;AAAA,QACP,GAAI,IAAI,aAAa,QAAQ,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC;AAAA,MACrD;AAEA,aAAO,kBAAkB;AAAA,QACvB,GAAG;AAAA,QACH;AAAA,UACE,MAAM;AAAA,UACN,SAAS,WAAW,IAAI,CAAC,SAAS;AAChC,kBAAM,OAAO,KAAK;AAClB,oBAAQ,MAAM;AAAA,cACZ,KAAK;AACH,uBAAO,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK;AAAA,cACzC,KAAK;AACH,uBAAO,EAAE,MAAM,aAAa,WAAW,KAAK,MAAM;AAAA,cAEpD,KAAK;AACH,sBAAM,IAAI,MAAM,0CAA0C;AAAA,cAE5D;AACE,sBAAM,mBAA0B;AAChC,sBAAM,IAAI;AAAA,kBACR,8BAA8B,gBAAgB;AAAA,gBAChD;AAAA,YACJ;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,iBAAiB,OAAO,EAAE,YAAY,UAAU,OAAO,MAAM;AAC3D,YAAM,kBAAkB;AAAA,QACtB;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,cAAc;AAAA,UACd,SAAS,KAAK,UAAU,MAAM;AAAA,QAChC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,qBAAqB,CAAC,sBAClB,SACA,YAAY;AACV,YAAM,oBAAoB;AAC1B,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,IACJ,kBAAkB,CAAC,mBACf,SACA,OAAOC,cAAa;AAClB,YAAM,EAAE,UAAAD,UAAS,IAAI,MAAM,iBAAiBC,SAAQ;AACpD,kBAAYD,SAAQ;AAAA,IACtB;AAAA,EACN,CAAC;AACH;","names":["import_react","import_react","import_react","messages","threadId"]}
package/dist/index.mjs CHANGED
@@ -122,6 +122,7 @@ var useLangGraphMessages = ({
122
122
  };
123
123
 
124
124
  // src/useLangGraphRuntime.ts
125
+ import { SimpleImageAttachmentAdapter } from "@assistant-ui/react";
125
126
  var getPendingToolCalls = (messages) => {
126
127
  const pendingToolCalls = /* @__PURE__ */ new Map();
127
128
  for (const message of messages) {
@@ -139,6 +140,7 @@ var getPendingToolCalls = (messages) => {
139
140
  var useLangGraphRuntime = ({
140
141
  threadId,
141
142
  autoCancelPendingToolCalls,
143
+ unstable_allowImageAttachments,
142
144
  stream,
143
145
  onSwitchToNewThread,
144
146
  onSwitchToThread
@@ -166,9 +168,10 @@ var useLangGraphRuntime = ({
166
168
  threadId,
167
169
  isRunning,
168
170
  messages: threadMessages,
171
+ adapters: {
172
+ attachments: unstable_allowImageAttachments ? new SimpleImageAttachmentAdapter() : void 0
173
+ },
169
174
  onNew: (msg) => {
170
- if (msg.content.length !== 1 || msg.content[0]?.type !== "text")
171
- throw new Error("Only text messages are supported");
172
175
  const cancellations = autoCancelPendingToolCalls !== false ? getPendingToolCalls(messages).map(
173
176
  (t) => ({
174
177
  type: "tool",
@@ -177,11 +180,30 @@ var useLangGraphRuntime = ({
177
180
  content: JSON.stringify({ cancelled: true })
178
181
  })
179
182
  ) : [];
183
+ const allContent = [
184
+ ...msg.content,
185
+ ...msg.attachments?.flatMap((a) => a.content) ?? []
186
+ ];
180
187
  return handleSendMessage([
181
188
  ...cancellations,
182
189
  {
183
190
  type: "human",
184
- content: msg.content[0].text
191
+ content: allContent.map((part) => {
192
+ const type = part.type;
193
+ switch (type) {
194
+ case "text":
195
+ return { type: "text", text: part.text };
196
+ case "image":
197
+ return { type: "image_url", image_url: part.image };
198
+ case "tool-call":
199
+ throw new Error("Tool call appends are not supported yet.");
200
+ default:
201
+ const _exhaustiveCheck = type;
202
+ throw new Error(
203
+ `Unknown content part type: ${_exhaustiveCheck}`
204
+ );
205
+ }
206
+ })
185
207
  }
186
208
  ]);
187
209
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport { useLangGraphMessages } from \"./useLangGraphMessages\";\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\nexport const useLangGraphRuntime = ({\n threadId,\n autoCancelPendingToolCalls,\n stream,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n stream: (messages: LangChainMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n}) => {\n const { messages, sendMessage, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (messages: LangChainMessage[]) => {\n try {\n setIsRunning(true);\n await sendMessage(messages);\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 return useExternalStoreRuntime({\n threadId,\n isRunning,\n messages: threadMessages,\n onNew: (msg) => {\n if (msg.content.length !== 1 || msg.content[0]?.type !== \"text\")\n throw new Error(\"Only text messages are supported\");\n\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 ...cancellations,\n {\n type: \"human\",\n content: msg.content[0].text,\n },\n ]);\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n await handleSendMessage([\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ]);\n },\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: !onSwitchToThread\n ? undefined\n : async (threadId) => {\n const { messages } = await onSwitchToThread(threadId);\n setMessages(messages);\n },\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 } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\n\nconst { generateId } = INTERNAL;\n\nexport const useLangGraphMessages = <TMessage>({\n stream,\n}: {\n stream: (messages: TMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[]) => {\n const optimisticMessages = [...messages, ...newMessages];\n if (newMessages.length > 0) {\n setMessages(optimisticMessages);\n }\n\n const response = await stream(newMessages);\n\n const completeMessages: TMessage[] = [];\n let partialMessages: Map<string, TMessage> = new Map();\n for await (const chunk of response) {\n if (chunk.event === \"messages/partial\") {\n // bug fix: messages/complete is not sent for some python langchain backends\n if (completeMessages.length === 0) {\n completeMessages.push(...optimisticMessages);\n }\n\n for (const message of chunk.data) {\n if (!message.id) throw new Error(\"Partial message missing id\");\n\n partialMessages.set(message.id, message);\n }\n } else if (chunk.event === \"messages/complete\") {\n for (const message of chunk.data) {\n if (message.id) {\n partialMessages.delete(message.id);\n }\n\n // bug fix: tool results can arrive before the message is complete ?\n // if we have partial messages left, we add complete message to partial messages\n if (partialMessages.size > 0) {\n partialMessages.set(message.id ?? generateId(), message);\n } else {\n completeMessages.push(message);\n }\n }\n } else {\n continue;\n }\n\n setMessages([...completeMessages, ...partialMessages.values()]);\n }\n // if (partialMessages.size > 0) {\n // throw new Error(\"A partial message was not marked as complete\");\n // }\n },\n [stream],\n );\n console.log(\"messages\", messages);\n return { messages, sendMessage, setMessages };\n};\n"],"mappings":"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","names":["useState","useState","messages","threadId"]}
1
+ {"version":3,"sources":["../src/useLangGraphRuntime.ts","../src/convertLangchainMessages.ts","../src/useLangGraphMessages.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { LangChainMessage, LangChainToolCall } from \"./types\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertLangchainMessages } from \"./convertLangchainMessages\";\nimport { useLangGraphMessages } from \"./useLangGraphMessages\";\nimport { SimpleImageAttachmentAdapter } 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\nexport const useLangGraphRuntime = ({\n threadId,\n autoCancelPendingToolCalls,\n unstable_allowImageAttachments,\n stream,\n onSwitchToNewThread,\n onSwitchToThread,\n}: {\n threadId?: string | undefined;\n autoCancelPendingToolCalls?: boolean | undefined;\n unstable_allowImageAttachments?: boolean | undefined;\n stream: (messages: LangChainMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (\n threadId: string,\n ) => Promise<{ messages: LangChainMessage[] }>;\n}) => {\n const { messages, sendMessage, setMessages } = useLangGraphMessages({\n stream,\n });\n\n const [isRunning, setIsRunning] = useState(false);\n const handleSendMessage = async (messages: LangChainMessage[]) => {\n try {\n setIsRunning(true);\n await sendMessage(messages);\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 return useExternalStoreRuntime({\n threadId,\n isRunning,\n messages: threadMessages,\n adapters: {\n attachments: unstable_allowImageAttachments\n ? new SimpleImageAttachmentAdapter()\n : undefined,\n },\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 const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n\n return handleSendMessage([\n ...cancellations,\n {\n type: \"human\",\n content: allContent.map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\", text: part.text };\n case \"image\":\n return { type: \"image_url\", image_url: part.image };\n\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported yet.\");\n\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(\n `Unknown content part type: ${_exhaustiveCheck}`,\n );\n }\n }),\n },\n ]);\n },\n onAddToolResult: async ({ toolCallId, toolName, result }) => {\n await handleSendMessage([\n {\n type: \"tool\",\n name: toolName,\n tool_call_id: toolCallId,\n content: JSON.stringify(result),\n },\n ]);\n },\n onSwitchToNewThread: !onSwitchToNewThread\n ? undefined\n : async () => {\n await onSwitchToNewThread();\n setMessages([]);\n },\n onSwitchToThread: !onSwitchToThread\n ? undefined\n : async (threadId) => {\n const { messages } = await onSwitchToThread(threadId);\n setMessages(messages);\n },\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 } from \"react\";\nimport { INTERNAL } from \"@assistant-ui/react\";\n\nconst { generateId } = INTERNAL;\n\nexport const useLangGraphMessages = <TMessage>({\n stream,\n}: {\n stream: (messages: TMessage[]) => Promise<\n AsyncGenerator<{\n event: string;\n data: any;\n }>\n >;\n}) => {\n const [messages, setMessages] = useState<TMessage[]>([]);\n\n const sendMessage = useCallback(\n async (newMessages: TMessage[]) => {\n const optimisticMessages = [...messages, ...newMessages];\n if (newMessages.length > 0) {\n setMessages(optimisticMessages);\n }\n\n const response = await stream(newMessages);\n\n const completeMessages: TMessage[] = [];\n let partialMessages: Map<string, TMessage> = new Map();\n for await (const chunk of response) {\n if (chunk.event === \"messages/partial\") {\n // bug fix: messages/complete is not sent for some python langchain backends\n if (completeMessages.length === 0) {\n completeMessages.push(...optimisticMessages);\n }\n\n for (const message of chunk.data) {\n if (!message.id) throw new Error(\"Partial message missing id\");\n\n partialMessages.set(message.id, message);\n }\n } else if (chunk.event === \"messages/complete\") {\n for (const message of chunk.data) {\n if (message.id) {\n partialMessages.delete(message.id);\n }\n\n // bug fix: tool results can arrive before the message is complete ?\n // if we have partial messages left, we add complete message to partial messages\n if (partialMessages.size > 0) {\n partialMessages.set(message.id ?? generateId(), message);\n } else {\n completeMessages.push(message);\n }\n }\n } else {\n continue;\n }\n\n setMessages([...completeMessages, ...partialMessages.values()]);\n }\n // if (partialMessages.size > 0) {\n // throw new Error(\"A partial message was not marked as complete\");\n // }\n },\n [stream],\n );\n console.log(\"messages\", messages);\n return { messages, sendMessage, setMessages };\n};\n"],"mappings":"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","names":["useState","useState","messages","threadId"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-langgraph",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {