@assistant-ui/react-langgraph 0.4.4 → 0.5.0

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.
@@ -0,0 +1,36 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ class LangGraphMessageAccumulator {
3
+ messagesMap = /* @__PURE__ */ new Map();
4
+ appendMessage;
5
+ constructor({
6
+ initialMessages = [],
7
+ appendMessage = (_, curr) => curr
8
+ } = {}) {
9
+ this.appendMessage = appendMessage;
10
+ this.addMessages(initialMessages);
11
+ }
12
+ ensureMessageId(message) {
13
+ return message.id ? message : { ...message, id: uuidv4() };
14
+ }
15
+ addMessages(newMessages) {
16
+ if (newMessages.length === 0) return this.getMessages();
17
+ for (const message of newMessages.map(this.ensureMessageId)) {
18
+ const previous = message.id ? this.messagesMap.get(message.id) : void 0;
19
+ this.messagesMap.set(
20
+ message.id ?? uuidv4(),
21
+ this.appendMessage(previous, message)
22
+ );
23
+ }
24
+ return this.getMessages();
25
+ }
26
+ getMessages() {
27
+ return [...this.messagesMap.values()];
28
+ }
29
+ clear() {
30
+ this.messagesMap.clear();
31
+ }
32
+ }
33
+ export {
34
+ LangGraphMessageAccumulator
35
+ };
36
+ //# sourceMappingURL=LangGraphMessageAccumulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/LangGraphMessageAccumulator.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\n\nexport type LangGraphMessagesEvent<TMessage> = {\n event:\n | \"messages\"\n | \"messages/partial\"\n | \"messages/complete\"\n | \"metadata\"\n | \"updates\"\n | string;\n data: TMessage[] | any;\n};\n\nexport type LangGraphStateAccumulatorConfig<TMessage> = {\n initialMessages?: TMessage[];\n appendMessage?: (prev: TMessage | undefined, curr: TMessage) => TMessage;\n};\n\nexport class LangGraphMessageAccumulator<TMessage extends { id?: string }> {\n private messagesMap = new Map<string, TMessage>();\n private appendMessage: (\n prev: TMessage | undefined,\n curr: TMessage,\n ) => TMessage;\n\n constructor({\n initialMessages = [],\n appendMessage = ((_: TMessage | undefined, curr: TMessage) => curr) as (\n prev: TMessage | undefined,\n curr: TMessage,\n ) => TMessage,\n }: LangGraphStateAccumulatorConfig<TMessage> = {}) {\n this.appendMessage = appendMessage;\n this.addMessages(initialMessages);\n }\n\n private ensureMessageId(message: TMessage): TMessage {\n return message.id ? message : { ...message, id: uuidv4() };\n }\n\n public addMessages(newMessages: TMessage[]) {\n if (newMessages.length === 0) return this.getMessages();\n\n for (const message of newMessages.map(this.ensureMessageId)) {\n const previous = message.id\n ? this.messagesMap.get(message.id)\n : undefined;\n this.messagesMap.set(\n message.id ?? uuidv4(),\n this.appendMessage(previous, message),\n );\n }\n return this.getMessages();\n }\n\n public getMessages(): TMessage[] {\n return [...this.messagesMap.values()];\n }\n\n public clear() {\n this.messagesMap.clear();\n }\n}\n"],"mappings":"AAAA,SAAS,MAAM,cAAc;AAkBtB,MAAM,4BAA8D;AAAA,EACjE,cAAc,oBAAI,IAAsB;AAAA,EACxC;AAAA,EAKR,YAAY;AAAA,IACV,kBAAkB,CAAC;AAAA,IACnB,gBAAiB,CAAC,GAAyB,SAAmB;AAAA,EAIhE,IAA+C,CAAC,GAAG;AACjD,SAAK,gBAAgB;AACrB,SAAK,YAAY,eAAe;AAAA,EAClC;AAAA,EAEQ,gBAAgB,SAA6B;AACnD,WAAO,QAAQ,KAAK,UAAU,EAAE,GAAG,SAAS,IAAI,OAAO,EAAE;AAAA,EAC3D;AAAA,EAEO,YAAY,aAAyB;AAC1C,QAAI,YAAY,WAAW,EAAG,QAAO,KAAK,YAAY;AAEtD,eAAW,WAAW,YAAY,IAAI,KAAK,eAAe,GAAG;AAC3D,YAAM,WAAW,QAAQ,KACrB,KAAK,YAAY,IAAI,QAAQ,EAAE,IAC/B;AACJ,WAAK,YAAY;AAAA,QACf,QAAQ,MAAM,OAAO;AAAA,QACrB,KAAK,cAAc,UAAU,OAAO;AAAA,MACtC;AAAA,IACF;AACA,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEO,cAA0B;AAC/B,WAAO,CAAC,GAAG,KAAK,YAAY,OAAO,CAAC;AAAA,EACtC;AAAA,EAEO,QAAQ;AACb,SAAK,YAAY,MAAM;AAAA,EACzB;AACF;","names":[]}
@@ -0,0 +1,44 @@
1
+ import { parsePartialJsonObject } from "assistant-stream/utils";
2
+ const appendLangChainChunk = (prev, curr) => {
3
+ if (curr.type !== "AIMessageChunk") {
4
+ return curr;
5
+ }
6
+ if (!prev || prev.type !== "ai") {
7
+ return {
8
+ ...curr,
9
+ type: curr.type.replace("MessageChunk", "").toLowerCase()
10
+ };
11
+ }
12
+ const newContent = typeof prev.content === "string" ? [{ type: "text", text: prev.content }] : [...prev.content];
13
+ for (const chunk of curr.content) {
14
+ if (chunk.type === "text") {
15
+ const existing = newContent[chunk.index] ?? { type: "text", text: "" };
16
+ if (existing.type !== "text") throw new Error("");
17
+ newContent[chunk.index] = {
18
+ ...existing,
19
+ ...chunk,
20
+ text: existing.text + chunk.text
21
+ };
22
+ }
23
+ }
24
+ const newToolCalls = [...prev.tool_calls ?? []];
25
+ for (const chunk of curr.tool_call_chunks) {
26
+ const existing = newToolCalls[chunk.index - 1] ?? { argsText: "" };
27
+ const newArgsText = existing.argsText + chunk.args;
28
+ newToolCalls[chunk.index - 1] = {
29
+ ...chunk,
30
+ ...existing,
31
+ argsText: newArgsText,
32
+ args: parsePartialJsonObject(newArgsText) ?? ("args" in existing ? existing.args : {})
33
+ };
34
+ }
35
+ return {
36
+ ...prev,
37
+ content: newContent,
38
+ tool_calls: newToolCalls
39
+ };
40
+ };
41
+ export {
42
+ appendLangChainChunk
43
+ };
44
+ //# sourceMappingURL=appendLangChainChunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/appendLangChainChunk.ts"],"sourcesContent":["import { LangChainMessage, LangChainMessageChunk } from \"./types\";\nimport { parsePartialJsonObject } from \"assistant-stream/utils\";\n\nexport const appendLangChainChunk = (\n prev: LangChainMessage | undefined,\n curr: LangChainMessage | LangChainMessageChunk,\n): LangChainMessage => {\n if (curr.type !== \"AIMessageChunk\") {\n return curr;\n }\n\n if (!prev || prev.type !== \"ai\") {\n return {\n ...curr,\n type: curr.type.replace(\"MessageChunk\", \"\").toLowerCase(),\n } as LangChainMessage;\n }\n\n const newContent =\n typeof prev.content === \"string\"\n ? [{ type: \"text\" as const, text: prev.content }]\n : [...prev.content];\n\n for (const chunk of curr.content) {\n if (chunk.type === \"text\") {\n const existing = newContent[chunk.index] ?? { type: \"text\", text: \"\" };\n if (existing.type !== \"text\") throw new Error(\"\");\n newContent[chunk.index] = {\n ...existing,\n ...chunk,\n text: existing.text + chunk.text,\n };\n }\n }\n\n const newToolCalls = [...(prev.tool_calls ?? [])];\n for (const chunk of curr.tool_call_chunks) {\n const existing = newToolCalls[chunk.index - 1] ?? { argsText: \"\" };\n const newArgsText = existing.argsText + chunk.args;\n newToolCalls[chunk.index - 1] = {\n ...chunk,\n ...existing,\n argsText: newArgsText,\n args:\n parsePartialJsonObject(newArgsText) ??\n (\"args\" in existing ? existing.args : {}),\n };\n }\n\n return {\n ...prev,\n content: newContent,\n tool_calls: newToolCalls,\n };\n};\n"],"mappings":"AACA,SAAS,8BAA8B;AAEhC,MAAM,uBAAuB,CAClC,MACA,SACqB;AACrB,MAAI,KAAK,SAAS,kBAAkB;AAClC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ,KAAK,SAAS,MAAM;AAC/B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM,KAAK,KAAK,QAAQ,gBAAgB,EAAE,EAAE,YAAY;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,aACJ,OAAO,KAAK,YAAY,WACpB,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,QAAQ,CAAC,IAC9C,CAAC,GAAG,KAAK,OAAO;AAEtB,aAAW,SAAS,KAAK,SAAS;AAChC,QAAI,MAAM,SAAS,QAAQ;AACzB,YAAM,WAAW,WAAW,MAAM,KAAK,KAAK,EAAE,MAAM,QAAQ,MAAM,GAAG;AACrE,UAAI,SAAS,SAAS,OAAQ,OAAM,IAAI,MAAM,EAAE;AAChD,iBAAW,MAAM,KAAK,IAAI;AAAA,QACxB,GAAG;AAAA,QACH,GAAG;AAAA,QACH,MAAM,SAAS,OAAO,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,GAAI,KAAK,cAAc,CAAC,CAAE;AAChD,aAAW,SAAS,KAAK,kBAAkB;AACzC,UAAM,WAAW,aAAa,MAAM,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG;AACjE,UAAM,cAAc,SAAS,WAAW,MAAM;AAC9C,iBAAa,MAAM,QAAQ,CAAC,IAAI;AAAA,MAC9B,GAAG;AAAA,MACH,GAAG;AAAA,MACH,UAAU;AAAA,MACV,MACE,uBAAuB,WAAW,MACjC,UAAU,WAAW,SAAS,OAAO,CAAC;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AACF;","names":[]}
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ const contentToParts = (content) => {
3
+ if (typeof content === "string")
4
+ return [{ type: "text", text: content }];
5
+ return content.map((part) => {
6
+ const type = part.type;
7
+ switch (type) {
8
+ case "text":
9
+ return { type: "text", text: part.text };
10
+ case "image_url":
11
+ if (typeof part.image_url === "string") {
12
+ return { type: "image", image: part.image_url };
13
+ } else {
14
+ return {
15
+ type: "image",
16
+ image: part.image_url.url
17
+ };
18
+ }
19
+ case "tool_use":
20
+ return null;
21
+ default:
22
+ const _exhaustiveCheck = type;
23
+ throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);
24
+ }
25
+ }).filter((a) => a !== null);
26
+ };
27
+ const convertLangChainMessages = (message) => {
28
+ switch (message.type) {
29
+ case "system":
30
+ return {
31
+ role: "system",
32
+ id: message.id,
33
+ content: [{ type: "text", text: message.content }]
34
+ };
35
+ case "human":
36
+ return {
37
+ role: "user",
38
+ id: message.id,
39
+ content: contentToParts(message.content)
40
+ };
41
+ case "ai":
42
+ return {
43
+ role: "assistant",
44
+ id: message.id,
45
+ content: [
46
+ ...contentToParts(message.content),
47
+ ...message.tool_calls?.map(
48
+ (chunk) => ({
49
+ type: "tool-call",
50
+ toolCallId: chunk.id,
51
+ toolName: chunk.name,
52
+ args: chunk.args,
53
+ argsText: message.tool_call_chunks?.find((c) => c.id === chunk.id)?.args ?? JSON.stringify(chunk.args)
54
+ })
55
+ ) ?? []
56
+ ]
57
+ };
58
+ case "tool":
59
+ return {
60
+ role: "tool",
61
+ toolName: message.name,
62
+ toolCallId: message.tool_call_id,
63
+ result: message.content,
64
+ artifact: message.artifact
65
+ };
66
+ }
67
+ };
68
+ export {
69
+ convertLangChainMessages
70
+ };
71
+ //# sourceMappingURL=convertLangChainMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/convertLangChainMessages.ts"],"sourcesContent":["\"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 = (content: LangChainMessage[\"content\"]) => {\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 artifact: message.artifact,\n };\n }\n};\n"],"mappings":";AAOA,MAAM,iBAAiB,CAAC,YAAyC;AAC/D,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,MAAM,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,QAChB,UAAU,QAAQ;AAAA,MACpB;AAAA,EACJ;AACF;","names":[]}
package/dist/index.js CHANGED
@@ -1,424 +1,25 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- LangGraphMessageAccumulator: () => LangGraphMessageAccumulator,
24
- appendLangChainChunk: () => appendLangChainChunk,
25
- convertLangChainMessages: () => convertLangChainMessages,
26
- convertLangchainMessages: () => convertLangChainMessages,
27
- useLangGraphInterruptState: () => useLangGraphInterruptState,
28
- useLangGraphMessages: () => useLangGraphMessages,
29
- useLangGraphRuntime: () => useLangGraphRuntime,
30
- useLangGraphSend: () => useLangGraphSend,
31
- useLangGraphSendCommand: () => useLangGraphSendCommand
32
- });
33
- module.exports = __toCommonJS(index_exports);
34
-
35
- // src/useLangGraphRuntime.ts
36
- var import_react2 = require("react");
37
- var import_react3 = require("@assistant-ui/react");
38
-
39
- // src/convertLangChainMessages.ts
40
- var contentToParts = (content) => {
41
- if (typeof content === "string")
42
- return [{ type: "text", text: content }];
43
- return content.map((part) => {
44
- const type = part.type;
45
- switch (type) {
46
- case "text":
47
- return { type: "text", text: part.text };
48
- case "image_url":
49
- if (typeof part.image_url === "string") {
50
- return { type: "image", image: part.image_url };
51
- } else {
52
- return {
53
- type: "image",
54
- image: part.image_url.url
55
- };
56
- }
57
- case "tool_use":
58
- return null;
59
- default:
60
- const _exhaustiveCheck = type;
61
- throw new Error(`Unknown content part type: ${_exhaustiveCheck}`);
62
- }
63
- }).filter((a) => a !== null);
64
- };
65
- var convertLangChainMessages = (message) => {
66
- switch (message.type) {
67
- case "system":
68
- return {
69
- role: "system",
70
- id: message.id,
71
- content: [{ type: "text", text: message.content }]
72
- };
73
- case "human":
74
- return {
75
- role: "user",
76
- id: message.id,
77
- content: contentToParts(message.content)
78
- };
79
- case "ai":
80
- return {
81
- role: "assistant",
82
- id: message.id,
83
- content: [
84
- ...contentToParts(message.content),
85
- ...message.tool_calls?.map(
86
- (chunk) => ({
87
- type: "tool-call",
88
- toolCallId: chunk.id,
89
- toolName: chunk.name,
90
- args: chunk.args,
91
- argsText: message.tool_call_chunks?.find((c) => c.id === chunk.id)?.args ?? JSON.stringify(chunk.args)
92
- })
93
- ) ?? []
94
- ]
95
- };
96
- case "tool":
97
- return {
98
- role: "tool",
99
- toolName: message.name,
100
- toolCallId: message.tool_call_id,
101
- result: message.content,
102
- artifact: message.artifact
103
- };
104
- }
105
- };
106
-
107
- // src/useLangGraphMessages.ts
108
- var import_react = require("react");
109
- var import_uuid2 = require("uuid");
110
-
111
- // src/LangGraphMessageAccumulator.ts
112
- var import_uuid = require("uuid");
113
- var LangGraphMessageAccumulator = class {
114
- messagesMap = /* @__PURE__ */ new Map();
115
- appendMessage;
116
- constructor({
117
- initialMessages = [],
118
- appendMessage = (_, curr) => curr
119
- } = {}) {
120
- this.appendMessage = appendMessage;
121
- this.addMessages(initialMessages);
122
- }
123
- ensureMessageId(message) {
124
- return message.id ? message : { ...message, id: (0, import_uuid.v4)() };
125
- }
126
- addMessages(newMessages) {
127
- if (newMessages.length === 0) return this.getMessages();
128
- for (const message of newMessages.map(this.ensureMessageId)) {
129
- const previous = message.id ? this.messagesMap.get(message.id) : void 0;
130
- this.messagesMap.set(
131
- message.id ?? (0, import_uuid.v4)(),
132
- this.appendMessage(previous, message)
133
- );
134
- }
135
- return this.getMessages();
136
- }
137
- getMessages() {
138
- return [...this.messagesMap.values()];
139
- }
140
- clear() {
141
- this.messagesMap.clear();
142
- }
143
- };
144
-
145
- // src/useLangGraphMessages.ts
146
- var DEFAULT_APPEND_MESSAGE = (_, curr) => curr;
147
- var useLangGraphMessages = ({
148
- stream,
149
- appendMessage = DEFAULT_APPEND_MESSAGE
150
- }) => {
151
- const [interrupt, setInterrupt] = (0, import_react.useState)();
152
- const [messages, setMessages] = (0, import_react.useState)([]);
153
- const abortControllerRef = (0, import_react.useRef)(null);
154
- const sendMessage = (0, import_react.useCallback)(
155
- async (newMessages, config) => {
156
- newMessages = newMessages.map((m) => m.id ? m : { ...m, id: (0, import_uuid2.v4)() });
157
- const accumulator = new LangGraphMessageAccumulator({
158
- initialMessages: messages,
159
- appendMessage
160
- });
161
- setMessages(accumulator.addMessages(newMessages));
162
- const abortController = new AbortController();
163
- abortControllerRef.current = abortController;
164
- const response = await stream(newMessages, {
165
- ...config,
166
- abortSignal: abortController.signal
167
- });
168
- for await (const chunk of response) {
169
- if (chunk.event === "messages/partial" || chunk.event === "messages/complete") {
170
- setMessages(accumulator.addMessages(chunk.data));
171
- } else if (chunk.event === "updates") {
172
- setInterrupt(chunk.data.__interrupt__?.[0]);
173
- }
174
- }
175
- },
176
- [messages, stream, appendMessage]
177
- );
178
- const cancel = (0, import_react.useCallback)(() => {
179
- if (abortControllerRef.current) {
180
- abortControllerRef.current.abort();
181
- }
182
- }, [abortControllerRef]);
183
- return {
184
- interrupt,
185
- messages,
186
- sendMessage,
187
- cancel,
188
- setInterrupt,
189
- setMessages
190
- };
191
- };
192
-
193
- // src/appendLangChainChunk.ts
194
- var import_utils = require("assistant-stream/utils");
195
- var appendLangChainChunk = (prev, curr) => {
196
- if (curr.type !== "AIMessageChunk") {
197
- return curr;
198
- }
199
- if (!prev || prev.type !== "ai") {
200
- return {
201
- ...curr,
202
- type: curr.type.replace("MessageChunk", "").toLowerCase()
203
- };
204
- }
205
- const newContent = typeof prev.content === "string" ? [{ type: "text", text: prev.content }] : [...prev.content];
206
- for (const chunk of curr.content) {
207
- if (chunk.type === "text") {
208
- const existing = newContent[chunk.index] ?? { type: "text", text: "" };
209
- if (existing.type !== "text") throw new Error("");
210
- newContent[chunk.index] = {
211
- ...existing,
212
- ...chunk,
213
- text: existing.text + chunk.text
214
- };
215
- }
216
- }
217
- const newToolCalls = [...prev.tool_calls ?? []];
218
- for (const chunk of curr.tool_call_chunks) {
219
- const existing = newToolCalls[chunk.index - 1] ?? { argsText: "" };
220
- const newArgsText = existing.argsText + chunk.args;
221
- newToolCalls[chunk.index - 1] = {
222
- ...chunk,
223
- ...existing,
224
- argsText: newArgsText,
225
- args: (0, import_utils.parsePartialJsonObject)(newArgsText) ?? ("args" in existing ? existing.args : {})
226
- };
227
- }
228
- return {
229
- ...prev,
230
- content: newContent,
231
- tool_calls: newToolCalls
232
- };
233
- };
234
-
235
- // src/useLangGraphRuntime.ts
236
- var getPendingToolCalls = (messages) => {
237
- const pendingToolCalls = /* @__PURE__ */ new Map();
238
- for (const message of messages) {
239
- if (message.type === "ai") {
240
- for (const toolCall of message.tool_calls ?? []) {
241
- pendingToolCalls.set(toolCall.id, toolCall);
242
- }
243
- }
244
- if (message.type === "tool") {
245
- pendingToolCalls.delete(message.tool_call_id);
246
- }
247
- }
248
- return [...pendingToolCalls.values()];
249
- };
250
- var getMessageContent = (msg) => {
251
- const allContent = [
252
- ...msg.content,
253
- ...msg.attachments?.flatMap((a) => a.content) ?? []
254
- ];
255
- const content = allContent.map((part) => {
256
- const type = part.type;
257
- switch (type) {
258
- case "text":
259
- return { type: "text", text: part.text };
260
- case "image":
261
- return { type: "image_url", image_url: { url: part.image } };
262
- case "tool-call":
263
- throw new Error("Tool call appends are not supported.");
264
- default:
265
- const _exhaustiveCheck = type;
266
- throw new Error(
267
- `Unsupported append content part type: ${_exhaustiveCheck}`
268
- );
269
- }
270
- });
271
- if (content.length === 1 && content[0]?.type === "text") {
272
- return content[0].text ?? "";
273
- }
274
- return content;
275
- };
276
- var symbolLangGraphRuntimeExtras = Symbol("langgraph-runtime-extras");
277
- var asLangGraphRuntimeExtras = (extras) => {
278
- if (typeof extras !== "object" || extras == null || !(symbolLangGraphRuntimeExtras in extras))
279
- throw new Error(
280
- "This method can only be called when you are using useLangGraphRuntime"
281
- );
282
- return extras;
283
- };
284
- var useLangGraphInterruptState = () => {
285
- const { interrupt } = (0, import_react3.useThread)((t) => asLangGraphRuntimeExtras(t.extras));
286
- return interrupt;
287
- };
288
- var useLangGraphSend = () => {
289
- const { send } = (0, import_react3.useThread)((t) => asLangGraphRuntimeExtras(t.extras));
290
- return send;
291
- };
292
- var useLangGraphSendCommand = () => {
293
- const send = useLangGraphSend();
294
- return (command) => send([], { command });
295
- };
296
- var useLangGraphRuntime = ({
297
- autoCancelPendingToolCalls,
298
- adapters: { attachments, feedback, speech } = {},
299
- unstable_allowCancellation,
300
- stream,
301
- threadId,
302
- onSwitchToNewThread,
303
- onSwitchToThread
304
- }) => {
305
- const {
306
- interrupt,
307
- setInterrupt,
308
- messages,
309
- sendMessage,
310
- cancel,
311
- setMessages
312
- } = useLangGraphMessages({
313
- appendMessage: appendLangChainChunk,
314
- stream
315
- });
316
- const [isRunning, setIsRunning] = (0, import_react2.useState)(false);
317
- const handleSendMessage = async (messages2, config) => {
318
- try {
319
- setIsRunning(true);
320
- await sendMessage(messages2, config);
321
- } catch (error) {
322
- console.error("Error streaming messages:", error);
323
- } finally {
324
- setIsRunning(false);
325
- }
326
- };
327
- const threadMessages = (0, import_react3.useExternalMessageConverter)({
328
- callback: convertLangChainMessages,
329
- messages,
330
- isRunning
331
- });
332
- const switchToThread = !onSwitchToThread ? void 0 : async (externalId) => {
333
- const { messages: messages2, interrupts } = await onSwitchToThread(externalId);
334
- setMessages(messages2);
335
- setInterrupt(interrupts?.[0]);
336
- };
337
- const threadList = {
338
- threadId,
339
- onSwitchToNewThread: !onSwitchToNewThread ? void 0 : async () => {
340
- await onSwitchToNewThread();
341
- setMessages([]);
342
- },
343
- onSwitchToThread: switchToThread
344
- };
345
- const loadingRef = (0, import_react2.useRef)(false);
346
- const threadListItemRuntime = (0, import_react3.useThreadListItemRuntime)({ optional: true });
347
- (0, import_react2.useEffect)(() => {
348
- if (!threadListItemRuntime || !switchToThread || loadingRef.current) return;
349
- const externalId = threadListItemRuntime.getState().externalId;
350
- if (externalId) {
351
- loadingRef.current = true;
352
- switchToThread(externalId).finally(() => {
353
- loadingRef.current = false;
354
- });
355
- }
356
- }, []);
357
- return (0, import_react3.useExternalStoreRuntime)({
358
- isRunning,
359
- messages: threadMessages,
360
- adapters: {
361
- attachments,
362
- feedback,
363
- speech,
364
- threadList
365
- },
366
- extras: {
367
- [symbolLangGraphRuntimeExtras]: true,
368
- interrupt,
369
- send: handleSendMessage
370
- },
371
- onNew: (msg) => {
372
- const cancellations = autoCancelPendingToolCalls !== false ? getPendingToolCalls(messages).map(
373
- (t) => ({
374
- type: "tool",
375
- name: t.name,
376
- tool_call_id: t.id,
377
- content: JSON.stringify({ cancelled: true })
378
- })
379
- ) : [];
380
- return handleSendMessage(
381
- [
382
- ...cancellations,
383
- {
384
- type: "human",
385
- content: getMessageContent(msg)
386
- }
387
- ],
388
- {
389
- runConfig: msg.runConfig
390
- }
391
- );
392
- },
393
- onAddToolResult: async ({ toolCallId, toolName, result }) => {
394
- await handleSendMessage(
395
- [
396
- {
397
- type: "tool",
398
- name: toolName,
399
- tool_call_id: toolCallId,
400
- content: JSON.stringify(result)
401
- }
402
- ],
403
- // TODO reuse runconfig here!
404
- {}
405
- );
406
- },
407
- onCancel: unstable_allowCancellation ? async () => {
408
- cancel();
409
- } : void 0
410
- });
411
- };
412
- // Annotate the CommonJS export names for ESM import in node:
413
- 0 && (module.exports = {
1
+ import {
2
+ useLangGraphRuntime,
3
+ useLangGraphSend,
4
+ useLangGraphSendCommand,
5
+ useLangGraphInterruptState
6
+ } from "./useLangGraphRuntime";
7
+ import {
8
+ useLangGraphMessages
9
+ } from "./useLangGraphMessages";
10
+ import { convertLangChainMessages } from "./convertLangChainMessages";
11
+ import { convertLangChainMessages as convertLangChainMessages2 } from "./convertLangChainMessages";
12
+ import { LangGraphMessageAccumulator } from "./LangGraphMessageAccumulator";
13
+ import { appendLangChainChunk } from "./appendLangChainChunk";
14
+ export {
414
15
  LangGraphMessageAccumulator,
415
16
  appendLangChainChunk,
416
17
  convertLangChainMessages,
417
- convertLangchainMessages,
18
+ convertLangChainMessages2 as convertLangchainMessages,
418
19
  useLangGraphInterruptState,
419
20
  useLangGraphMessages,
420
21
  useLangGraphRuntime,
421
22
  useLangGraphSend,
422
23
  useLangGraphSendCommand
423
- });
24
+ };
424
25
  //# sourceMappingURL=index.js.map