@assistant-ui/react-langchain 0.0.15 → 0.0.17
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/convertMessages.d.ts +37 -3
- package/dist/convertMessages.d.ts.map +1 -1
- package/dist/convertMessages.js +57 -11
- package/dist/convertMessages.js.map +1 -1
- package/dist/findForkCheckpointInHistory.d.ts +26 -0
- package/dist/findForkCheckpointInHistory.d.ts.map +1 -0
- package/dist/findForkCheckpointInHistory.js +34 -0
- package/dist/findForkCheckpointInHistory.js.map +1 -0
- package/dist/hooks.d.ts +88 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +99 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -2
- package/dist/resolveForkCheckpoint.d.ts +17 -0
- package/dist/resolveForkCheckpoint.d.ts.map +1 -0
- package/dist/resolveForkCheckpoint.js +26 -0
- package/dist/resolveForkCheckpoint.js.map +1 -0
- package/dist/runtimeExtras.d.ts +7 -0
- package/dist/runtimeExtras.d.ts.map +1 -0
- package/dist/runtimeExtras.js +7 -0
- package/dist/runtimeExtras.js.map +1 -0
- package/dist/streamingTiming.d.ts +16 -0
- package/dist/streamingTiming.d.ts.map +1 -0
- package/dist/streamingTiming.js +53 -0
- package/dist/streamingTiming.js.map +1 -0
- package/dist/types.d.ts +105 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/uiMessages.d.ts +24 -0
- package/dist/uiMessages.d.ts.map +1 -0
- package/dist/uiMessages.js +68 -0
- package/dist/uiMessages.js.map +1 -0
- package/dist/useStreamRuntime.d.ts +10 -85
- package/dist/useStreamRuntime.d.ts.map +1 -1
- package/dist/useStreamRuntime.js +186 -135
- package/dist/useStreamRuntime.js.map +1 -1
- package/package.json +9 -9
- package/src/__tests__/langChainTestUtils.ts +3 -3
- package/src/convertMessages.test.ts +160 -3
- package/src/convertMessages.ts +104 -11
- package/src/findForkCheckpointInHistory.test.ts +263 -0
- package/src/findForkCheckpointInHistory.ts +68 -0
- package/src/groupUIMessagesByParent.test.ts +61 -0
- package/src/hooks.ts +156 -0
- package/src/index.ts +18 -3
- package/src/resolveForkCheckpoint.test.ts +202 -0
- package/src/resolveForkCheckpoint.ts +49 -0
- package/src/runtimeExtras.ts +5 -0
- package/src/streamingTiming.test.ts +118 -0
- package/src/streamingTiming.ts +85 -0
- package/src/types.ts +140 -3
- package/src/uiMessages.test.ts +190 -0
- package/src/uiMessages.ts +91 -0
- package/src/useLangChainError.test.tsx +1 -1
- package/src/useLangChainInterrupts.test.tsx +48 -0
- package/src/useLangChainRespond.test.tsx +49 -0
- package/src/useLangChainRespondAll.test.tsx +52 -0
- package/src/useLangChainState.test.tsx +1 -1
- package/src/useLangChainStream.test.tsx +42 -0
- package/src/useLangChainSubagents.test.tsx +48 -0
- package/src/useLangChainSubgraphs.test.tsx +48 -0
- package/src/useLangChainToolCalls.test.tsx +1 -1
- package/src/useStreamRuntime.test.tsx +232 -0
- package/src/useStreamRuntime.ts +301 -268
|
@@ -1,9 +1,43 @@
|
|
|
1
|
-
import { LangChainBaseMessage } from "./types.js";
|
|
1
|
+
import { LangChainBaseMessage, UIMessage } from "./types.js";
|
|
2
|
+
import { AppendMessage, MessageTiming } from "@assistant-ui/core";
|
|
2
3
|
import { useExternalMessageConverter } from "@assistant-ui/core/react";
|
|
3
4
|
|
|
4
5
|
//#region src/convertMessages.d.ts
|
|
6
|
+
type LangChainMessageConverterMetadata = useExternalMessageConverter.Metadata & {
|
|
7
|
+
uiMessagesByParent?: Map<string, UIMessage[]>;
|
|
8
|
+
messageTiming?: Record<string, MessageTiming>;
|
|
9
|
+
};
|
|
5
10
|
declare const getMessageType: (message: LangChainBaseMessage) => string;
|
|
6
|
-
declare const convertLangChainBaseMessage: useExternalMessageConverter.
|
|
11
|
+
declare const convertLangChainBaseMessage: (message: LangChainBaseMessage, metadata?: LangChainMessageConverterMetadata) => useExternalMessageConverter.Message;
|
|
12
|
+
declare const getMessageContent: (msg: AppendMessage) => string | ({
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
image_url?: never;
|
|
16
|
+
data?: never;
|
|
17
|
+
mime_type?: never;
|
|
18
|
+
metadata?: never;
|
|
19
|
+
source_type?: never;
|
|
20
|
+
} | {
|
|
21
|
+
type: "image_url";
|
|
22
|
+
image_url: {
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
text?: never;
|
|
26
|
+
data?: never;
|
|
27
|
+
mime_type?: never;
|
|
28
|
+
metadata?: never;
|
|
29
|
+
source_type?: never;
|
|
30
|
+
} | {
|
|
31
|
+
type: "file";
|
|
32
|
+
data: string;
|
|
33
|
+
mime_type: string;
|
|
34
|
+
metadata: {
|
|
35
|
+
filename: string;
|
|
36
|
+
};
|
|
37
|
+
source_type: "base64";
|
|
38
|
+
text?: never;
|
|
39
|
+
image_url?: never;
|
|
40
|
+
})[];
|
|
7
41
|
//#endregion
|
|
8
|
-
export { convertLangChainBaseMessage, getMessageType };
|
|
42
|
+
export { convertLangChainBaseMessage, getMessageContent, getMessageType };
|
|
9
43
|
//# sourceMappingURL=convertMessages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertMessages.d.ts","names":[],"sources":["../src/convertMessages.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"convertMessages.d.ts","names":[],"sources":["../src/convertMessages.ts"],"mappings":";;;;;KAeK,iCAAA,GACH,2BAAA,CAA4B,QAAA;EAC1B,kBAAA,GAAqB,GAAA,SAAY,SAAA;EACjC,aAAA,GAAgB,MAAA,SAAe,aAAA;AAAA;AAAA,cAStB,cAAA,GAAkB,OAA6B,EAApB,oBAAoB;AAAA,cAoE/C,2BAAA,GACX,OAAA,EAAS,oBAAA,EACT,QAAA,GAAU,iCAAA,KACT,2BAAA,CAA4B,OAAA;AAAA,cAyFlB,iBAAA,GAAqB,GAAA,EAAK,aAAa"}
|
package/dist/convertMessages.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
//#region src/convertMessages.ts
|
|
3
|
+
const uiMessageToDataPart = (ui) => ({
|
|
4
|
+
type: "data",
|
|
5
|
+
name: ui.name,
|
|
6
|
+
data: ui.props
|
|
7
|
+
});
|
|
3
8
|
const getMessageType = (message) => {
|
|
4
9
|
if (typeof message._getType === "function") return message._getType();
|
|
5
10
|
if ("type" in message) return message.type;
|
|
@@ -17,15 +22,14 @@ const contentToParts = (content) => {
|
|
|
17
22
|
type: "text",
|
|
18
23
|
text: part.text
|
|
19
24
|
};
|
|
20
|
-
case "image_url":
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
image: part.image_url
|
|
24
|
-
};
|
|
25
|
+
case "image_url": {
|
|
26
|
+
const image = typeof part.image_url === "string" ? part.image_url : part.image_url?.url;
|
|
27
|
+
if (!image) return null;
|
|
25
28
|
return {
|
|
26
29
|
type: "image",
|
|
27
|
-
image
|
|
30
|
+
image
|
|
28
31
|
};
|
|
32
|
+
}
|
|
29
33
|
case "file": return {
|
|
30
34
|
type: "file",
|
|
31
35
|
filename: part.metadata?.filename ?? "file",
|
|
@@ -38,7 +42,7 @@ const contentToParts = (content) => {
|
|
|
38
42
|
};
|
|
39
43
|
case "reasoning": return {
|
|
40
44
|
type: "reasoning",
|
|
41
|
-
text: part.summary
|
|
45
|
+
text: part.summary?.map((s) => s?.text ?? "").join("\n\n\n") ?? part.reasoning ?? ""
|
|
42
46
|
};
|
|
43
47
|
case "tool_use":
|
|
44
48
|
case "input_json_delta": return null;
|
|
@@ -51,7 +55,7 @@ const getStringContent = (content) => {
|
|
|
51
55
|
if (typeof content === "string") return content;
|
|
52
56
|
return content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
53
57
|
};
|
|
54
|
-
const convertLangChainBaseMessage = (message) => {
|
|
58
|
+
const convertLangChainBaseMessage = (message, metadata = {}) => {
|
|
55
59
|
switch (getMessageType(message)) {
|
|
56
60
|
case "system": return {
|
|
57
61
|
role: "system",
|
|
@@ -77,11 +81,20 @@ const convertLangChainBaseMessage = (message) => {
|
|
|
77
81
|
argsText: JSON.stringify(tc.args)
|
|
78
82
|
})) ?? [];
|
|
79
83
|
const assistantStatus = typeof message.status === "object" ? message.status : void 0;
|
|
84
|
+
const uiDataParts = (message.id ? metadata.uiMessagesByParent?.get(message.id)?.map(uiMessageToDataPart) : void 0) ?? [];
|
|
85
|
+
const timing = metadata.messageTiming?.[message.id ?? ""];
|
|
80
86
|
return {
|
|
81
87
|
role: "assistant",
|
|
82
88
|
id: message.id,
|
|
83
|
-
content: [
|
|
84
|
-
|
|
89
|
+
content: [
|
|
90
|
+
...contentToParts(message.content),
|
|
91
|
+
...toolCallParts,
|
|
92
|
+
...uiDataParts
|
|
93
|
+
],
|
|
94
|
+
metadata: {
|
|
95
|
+
custom: getCustomMetadata(message.additional_kwargs),
|
|
96
|
+
...timing && { timing }
|
|
97
|
+
},
|
|
85
98
|
...assistantStatus && { status: assistantStatus }
|
|
86
99
|
};
|
|
87
100
|
}
|
|
@@ -103,7 +116,40 @@ const convertLangChainBaseMessage = (message) => {
|
|
|
103
116
|
};
|
|
104
117
|
}
|
|
105
118
|
};
|
|
119
|
+
const getMessageContent = (msg) => {
|
|
120
|
+
const allContent = [...msg.content, ...msg.attachments?.flatMap((a) => a.content) ?? []];
|
|
121
|
+
const hasNonText = allContent.some((part) => part.type === "file" || part.type === "image");
|
|
122
|
+
const hasText = allContent.some((part) => part.type === "text");
|
|
123
|
+
if (hasNonText && !hasText) allContent.unshift({
|
|
124
|
+
type: "text",
|
|
125
|
+
text: " "
|
|
126
|
+
});
|
|
127
|
+
const content = allContent.map((part) => {
|
|
128
|
+
const type = part.type;
|
|
129
|
+
switch (type) {
|
|
130
|
+
case "text": return {
|
|
131
|
+
type: "text",
|
|
132
|
+
text: part.text
|
|
133
|
+
};
|
|
134
|
+
case "image": return {
|
|
135
|
+
type: "image_url",
|
|
136
|
+
image_url: { url: part.image }
|
|
137
|
+
};
|
|
138
|
+
case "file": return {
|
|
139
|
+
type: "file",
|
|
140
|
+
data: part.data,
|
|
141
|
+
mime_type: part.mimeType,
|
|
142
|
+
metadata: { filename: part.filename ?? "file" },
|
|
143
|
+
source_type: "base64"
|
|
144
|
+
};
|
|
145
|
+
case "tool-call": throw new Error("Tool call appends are not supported.");
|
|
146
|
+
default: throw new Error(`Unsupported append message part type: ${type}`);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (content.length === 1 && content[0]?.type === "text") return content[0].text ?? "";
|
|
150
|
+
return content;
|
|
151
|
+
};
|
|
106
152
|
//#endregion
|
|
107
|
-
export { convertLangChainBaseMessage, getMessageType };
|
|
153
|
+
export { convertLangChainBaseMessage, getMessageContent, getMessageType };
|
|
108
154
|
|
|
109
155
|
//# sourceMappingURL=convertMessages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertMessages.js","names":["parts"],"sources":["../src/convertMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { LangChainBaseMessage, LangChainContentBlock } from \"./types\";\n\nexport const getMessageType = (message: LangChainBaseMessage): string => {\n if (typeof message._getType === \"function\") return message._getType();\n if (\"type\" in message)\n return (message as Record<string, unknown>).type as string;\n throw new Error(\"Cannot determine message type\");\n};\n\nconst contentToParts = (content: unknown) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n const parts = content as readonly LangChainContentBlock[];\n return parts\n .map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"text_delta\":\n return { type: \"text\" as const, text: part.text };\n case \"image_url\":\n if (typeof part.image_url === \"string\") {\n return { type: \"image\" as const, image: part.image_url };\n }\n return { type: \"image\" as const, image: part.image_url.url };\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.metadata?.filename ?? \"file\",\n data: part.data,\n mimeType: part.mime_type,\n };\n case \"thinking\":\n return { type: \"reasoning\" as const, text: part.thinking };\n case \"reasoning\":\n return {\n type: \"reasoning\" as const,\n text: part.summary.map((s) => s.text).join(\"\\n\\n\\n\"),\n };\n case \"tool_use\":\n case \"input_json_delta\":\n return null;\n default:\n return null;\n }\n })\n .filter((p) => p !== null);\n};\n\nconst getCustomMetadata = (\n additionalKwargs: Record<string, unknown> | undefined,\n): Record<string, unknown> =>\n (additionalKwargs?.metadata as Record<string, unknown>) ?? {};\n\nconst getStringContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n const parts = content as readonly LangChainContentBlock[];\n return parts\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\");\n};\n\nexport const convertLangChainBaseMessage: useExternalMessageConverter.Callback<\n LangChainBaseMessage\n> = (message) => {\n const type = getMessageType(message);\n\n switch (type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: getStringContent(message.content) }],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"ai\": {\n const toolCallParts =\n message.tool_calls?.map((tc) => ({\n type: \"tool-call\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n args: tc.args as ReadonlyJSONObject,\n argsText: JSON.stringify(tc.args),\n })) ?? [];\n\n const assistantStatus =\n typeof message.status === \"object\" ? message.status : undefined;\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [...contentToParts(message.content), ...toolCallParts],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n ...(assistantStatus && { status: assistantStatus }),\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 isError: message.status === \"error\",\n };\n\n default:\n return {\n role: \"system\",\n id: message.id,\n content: [\n {\n type: \"text\",\n text:\n typeof message.content === \"string\"\n ? message.content\n : JSON.stringify(message.content),\n },\n ],\n };\n }\n};\n"],"mappings":";;AAMA,MAAa,kBAAkB,YAA0C;CACvE,IAAI,OAAO,QAAQ,aAAa,YAAY,OAAO,QAAQ,SAAS;CACpE,IAAI,UAAU,SACZ,OAAQ,QAAoC;CAC9C,MAAM,IAAI,MAAM,+BAA+B;AACjD;AAEA,MAAM,kBAAkB,YAAqB;CAC3C,IAAI,OAAO,YAAY,UACrB,OAAO,CAAC;EAAE,MAAM;EAAiB,MAAM;CAAQ,CAAC;CAGlD,OAAOA,QACJ,KAAK,SAAS;EAEb,QADa,KAAK,MAClB;GACE,KAAK;GACL,KAAK,cACH,OAAO;IAAE,MAAM;IAAiB,MAAM,KAAK;GAAK;GAClD,KAAK;IACH,IAAI,OAAO,KAAK,cAAc,UAC5B,OAAO;KAAE,MAAM;KAAkB,OAAO,KAAK;IAAU;IAEzD,OAAO;KAAE,MAAM;KAAkB,OAAO,KAAK,UAAU;IAAI;GAC7D,KAAK,QACH,OAAO;IACL,MAAM;IACN,UAAU,KAAK,UAAU,YAAY;IACrC,MAAM,KAAK;IACX,UAAU,KAAK;GACjB;GACF,KAAK,YACH,OAAO;IAAE,MAAM;IAAsB,MAAM,KAAK;GAAS;GAC3D,KAAK,aACH,OAAO;IACL,MAAM;IACN,MAAM,KAAK,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,QAAQ;GACrD;GACF,KAAK;GACL,KAAK,oBACH,OAAO;GACT,SACE,OAAO;EACX;CACF,CAAC,CAAC,CACD,QAAQ,MAAM,MAAM,IAAI;AAC7B;AAEA,MAAM,qBACJ,qBAEC,kBAAkB,YAAwC,CAAC;AAE9D,MAAM,oBAAoB,YAA6B;CACrD,IAAI,OAAO,YAAY,UAAU,OAAO;CAExC,OAAOA,QACJ,QAAQ,MAA2C,EAAE,SAAS,MAAM,CAAC,CACrE,KAAK,MAAM,EAAE,IAAI,CAAC,CAClB,KAAK,EAAE;AACZ;AAEA,MAAa,+BAER,YAAY;CAGf,QAFa,eAAe,OAEjB,GAAX;EACE,KAAK,UACH,OAAO;GACL,MAAM;GACN,IAAI,QAAQ;GACZ,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,iBAAiB,QAAQ,OAAO;GAAE,CAAC;GACnE,UAAU,EACR,QAAQ,kBAAkB,QAAQ,iBAAiB,EACrD;EACF;EAEF,KAAK,SACH,OAAO;GACL,MAAM;GACN,IAAI,QAAQ;GACZ,SAAS,eAAe,QAAQ,OAAO;GACvC,UAAU,EACR,QAAQ,kBAAkB,QAAQ,iBAAiB,EACrD;EACF;EAEF,KAAK,MAAM;GACT,MAAM,gBACJ,QAAQ,YAAY,KAAK,QAAQ;IAC/B,MAAM;IACN,YAAY,GAAG;IACf,UAAU,GAAG;IACb,MAAM,GAAG;IACT,UAAU,KAAK,UAAU,GAAG,IAAI;GAClC,EAAE,KAAK,CAAC;GAEV,MAAM,kBACJ,OAAO,QAAQ,WAAW,WAAW,QAAQ,SAAS,KAAA;GAExD,OAAO;IACL,MAAM;IACN,IAAI,QAAQ;IACZ,SAAS,CAAC,GAAG,eAAe,QAAQ,OAAO,GAAG,GAAG,aAAa;IAC9D,UAAU,EACR,QAAQ,kBAAkB,QAAQ,iBAAiB,EACrD;IACA,GAAI,mBAAmB,EAAE,QAAQ,gBAAgB;GACnD;EACF;EAEA,KAAK,QACH,OAAO;GACL,MAAM;GACN,UAAU,QAAQ,QAAQ;GAC1B,YAAY,QAAQ,gBAAgB;GACpC,QAAQ,QAAQ;GAChB,UAAU,QAAQ;GAClB,SAAS,QAAQ,WAAW;EAC9B;EAEF,SACE,OAAO;GACL,MAAM;GACN,IAAI,QAAQ;GACZ,SAAS,CACP;IACE,MAAM;IACN,MACE,OAAO,QAAQ,YAAY,WACvB,QAAQ,UACR,KAAK,UAAU,QAAQ,OAAO;GACtC,CACF;EACF;CACJ;AACF"}
|
|
1
|
+
{"version":3,"file":"convertMessages.js","names":["parts","_exhaustiveCheck"],"sources":["../src/convertMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type {\n AppendMessage,\n DataMessagePart,\n MessageTiming,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type {\n LangChainBaseMessage,\n LangChainContentBlock,\n UIMessage,\n} from \"./types\";\n\ntype LangChainMessageConverterMetadata =\n useExternalMessageConverter.Metadata & {\n uiMessagesByParent?: Map<string, UIMessage[]>;\n messageTiming?: Record<string, MessageTiming>;\n };\n\nconst uiMessageToDataPart = (ui: UIMessage): DataMessagePart => ({\n type: \"data\",\n name: ui.name,\n data: ui.props,\n});\n\nexport const getMessageType = (message: LangChainBaseMessage): string => {\n if (typeof message._getType === \"function\") return message._getType();\n if (\"type\" in message)\n return (message as Record<string, unknown>).type as string;\n throw new Error(\"Cannot determine message type\");\n};\n\nconst contentToParts = (content: unknown) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n const parts = content as readonly LangChainContentBlock[];\n return parts\n .map((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"text_delta\":\n return { type: \"text\" as const, text: part.text };\n case \"image_url\": {\n const image =\n typeof part.image_url === \"string\"\n ? part.image_url\n : part.image_url?.url;\n if (!image) return null;\n return { type: \"image\" as const, image };\n }\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.metadata?.filename ?? \"file\",\n data: part.data,\n mimeType: part.mime_type,\n };\n case \"thinking\":\n return { type: \"reasoning\" as const, text: part.thinking };\n case \"reasoning\":\n return {\n type: \"reasoning\" as const,\n text:\n part.summary?.map((s) => s?.text ?? \"\").join(\"\\n\\n\\n\") ??\n part.reasoning ??\n \"\",\n };\n case \"tool_use\":\n case \"input_json_delta\":\n return null;\n default:\n return null;\n }\n })\n .filter((p) => p !== null);\n};\n\nconst getCustomMetadata = (\n additionalKwargs: Record<string, unknown> | undefined,\n): Record<string, unknown> =>\n (additionalKwargs?.metadata as Record<string, unknown>) ?? {};\n\nconst getStringContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n const parts = content as readonly LangChainContentBlock[];\n return parts\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\");\n};\n\nexport const convertLangChainBaseMessage = (\n message: LangChainBaseMessage,\n metadata: LangChainMessageConverterMetadata = {},\n): useExternalMessageConverter.Message => {\n const type = getMessageType(message);\n\n switch (type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: getStringContent(message.content) }],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"ai\": {\n const toolCallParts =\n message.tool_calls?.map((tc) => ({\n type: \"tool-call\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n args: tc.args as ReadonlyJSONObject,\n argsText: JSON.stringify(tc.args),\n })) ?? [];\n\n const assistantStatus =\n typeof message.status === \"object\" ? message.status : undefined;\n\n const uiDataParts =\n (message.id\n ? metadata.uiMessagesByParent\n ?.get(message.id)\n ?.map(uiMessageToDataPart)\n : undefined) ?? [];\n\n const timing = metadata.messageTiming?.[message.id ?? \"\"];\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...contentToParts(message.content),\n ...toolCallParts,\n ...uiDataParts,\n ],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n ...(timing && { timing }),\n },\n ...(assistantStatus && { status: assistantStatus }),\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 isError: message.status === \"error\",\n };\n\n default:\n return {\n role: \"system\",\n id: message.id,\n content: [\n {\n type: \"text\",\n text:\n typeof message.content === \"string\"\n ? message.content\n : JSON.stringify(message.content),\n },\n ],\n };\n }\n};\n\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n\n const hasNonText = allContent.some(\n (part) => part.type === \"file\" || part.type === \"image\",\n );\n const hasText = allContent.some((part) => part.type === \"text\");\n if (hasNonText && !hasText) {\n allContent.unshift({ type: \"text\", text: \" \" });\n }\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 case \"file\":\n return {\n type: \"file\" as const,\n data: part.data,\n mime_type: part.mimeType,\n metadata: { filename: part.filename ?? \"file\" },\n source_type: \"base64\" as const,\n };\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n default: {\n const _exhaustiveCheck:\n | \"reasoning\"\n | \"source\"\n | \"audio\"\n | \"data\"\n | \"generative-ui\" = type;\n throw new Error(\n `Unsupported append message part type: ${_exhaustiveCheck}`,\n );\n }\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n return content;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LangChainBaseMessage } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/findForkCheckpointInHistory.d.ts
|
|
4
|
+
type ForkCheckpointHistoryState = {
|
|
5
|
+
values?: Record<string, unknown> | undefined;
|
|
6
|
+
checkpoint?: {
|
|
7
|
+
checkpoint_id?: string | null | undefined;
|
|
8
|
+
} | undefined;
|
|
9
|
+
};
|
|
10
|
+
type ForkHistoryCursor = {
|
|
11
|
+
configurable: {
|
|
12
|
+
checkpoint_id: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type ForkCheckpointClient = {
|
|
16
|
+
threads: {
|
|
17
|
+
getHistory: (threadId: string, options?: {
|
|
18
|
+
limit?: number;
|
|
19
|
+
before?: ForkHistoryCursor;
|
|
20
|
+
}) => Promise<readonly ForkCheckpointHistoryState[]>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
declare const findForkCheckpointInHistory: (client: ForkCheckpointClient, threadId: string, messagesUpToParent: readonly LangChainBaseMessage[], messagesKey: string, pageSize?: number) => Promise<string | null>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ForkCheckpointClient, findForkCheckpointInHistory };
|
|
26
|
+
//# sourceMappingURL=findForkCheckpointInHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findForkCheckpointInHistory.d.ts","names":[],"sources":["../src/findForkCheckpointInHistory.ts"],"mappings":";;;KAEK,0BAAA;EACH,MAAA,GAAS,MAAM;EACf,UAAA;IAAe,aAAA;EAAA;AAAA;AAAA,KAGZ,iBAAA;EAAsB,YAAA;IAAgB,aAAa;EAAA;AAAA;AAAA,KAE5C,oBAAA;EACV,OAAA;IACE,UAAA,GACE,QAAA,UACA,OAAA;MAAY,KAAA;MAAgB,MAAA,GAAS,iBAAA;IAAA,MAClC,OAAA,UAAiB,0BAAA;EAAA;AAAA;AAAA,cAIb,2BAAA,GACX,MAAA,EAAQ,oBAAA,EACR,QAAA,UACA,kBAAA,WAA6B,oBAAA,IAC7B,WAAA,UACA,QAAA,cACC,OAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/findForkCheckpointInHistory.ts
|
|
2
|
+
const findForkCheckpointInHistory = async (client, threadId, messagesUpToParent, messagesKey, pageSize = 100) => {
|
|
3
|
+
if (!messagesUpToParent.every((m) => typeof m.id === "string")) return null;
|
|
4
|
+
const scanned = /* @__PURE__ */ new Set();
|
|
5
|
+
let before;
|
|
6
|
+
for (;;) {
|
|
7
|
+
const page = await client.threads.getHistory(threadId, before ? {
|
|
8
|
+
limit: pageSize,
|
|
9
|
+
before
|
|
10
|
+
} : { limit: pageSize });
|
|
11
|
+
let oldestCheckpointId;
|
|
12
|
+
let advanced = false;
|
|
13
|
+
for (const state of page) {
|
|
14
|
+
const checkpointId = state.checkpoint?.checkpoint_id;
|
|
15
|
+
if (typeof checkpointId === "string") {
|
|
16
|
+
oldestCheckpointId = checkpointId;
|
|
17
|
+
if (!scanned.has(checkpointId)) {
|
|
18
|
+
scanned.add(checkpointId);
|
|
19
|
+
advanced = true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const stateMessages = state.values?.[messagesKey];
|
|
23
|
+
if (!Array.isArray(stateMessages) || stateMessages.length !== messagesUpToParent.length) continue;
|
|
24
|
+
if (!stateMessages.every((m) => typeof m.id === "string")) continue;
|
|
25
|
+
if (messagesUpToParent.every((m, i) => m.id === stateMessages[i]?.id) && checkpointId) return checkpointId;
|
|
26
|
+
}
|
|
27
|
+
if (page.length < pageSize || oldestCheckpointId === void 0 || !advanced) return null;
|
|
28
|
+
before = { configurable: { checkpoint_id: oldestCheckpointId } };
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { findForkCheckpointInHistory };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=findForkCheckpointInHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findForkCheckpointInHistory.js","names":[],"sources":["../src/findForkCheckpointInHistory.ts"],"sourcesContent":["import type { LangChainBaseMessage } from \"./types\";\n\ntype ForkCheckpointHistoryState = {\n values?: Record<string, unknown> | undefined;\n checkpoint?: { checkpoint_id?: string | null | undefined } | undefined;\n};\n\ntype ForkHistoryCursor = { configurable: { checkpoint_id: string } };\n\nexport type ForkCheckpointClient = {\n threads: {\n getHistory: (\n threadId: string,\n options?: { limit?: number; before?: ForkHistoryCursor },\n ) => Promise<readonly ForkCheckpointHistoryState[]>;\n };\n};\n\nexport const findForkCheckpointInHistory = async (\n client: ForkCheckpointClient,\n threadId: string,\n messagesUpToParent: readonly LangChainBaseMessage[],\n messagesKey: string,\n pageSize = 100,\n): Promise<string | null> => {\n if (!messagesUpToParent.every((m) => typeof m.id === \"string\")) return null;\n\n const scanned = new Set<string>();\n let before: ForkHistoryCursor | undefined;\n\n for (;;) {\n const page = await client.threads.getHistory(\n threadId,\n before ? { limit: pageSize, before } : { limit: pageSize },\n );\n\n let oldestCheckpointId: string | undefined;\n let advanced = false;\n for (const state of page) {\n const checkpointId = state.checkpoint?.checkpoint_id;\n if (typeof checkpointId === \"string\") {\n oldestCheckpointId = checkpointId;\n if (!scanned.has(checkpointId)) {\n scanned.add(checkpointId);\n advanced = true;\n }\n }\n const stateMessages = state.values?.[messagesKey] as\n | readonly LangChainBaseMessage[]\n | undefined;\n if (\n !Array.isArray(stateMessages) ||\n stateMessages.length !== messagesUpToParent.length\n )\n continue;\n if (!stateMessages.every((m) => typeof m.id === \"string\")) continue;\n const isMatch = messagesUpToParent.every(\n (m, i) => m.id === stateMessages[i]?.id,\n );\n if (isMatch && checkpointId) return checkpointId;\n }\n\n // `advanced` halts paging if the backend ignores `before` and repeats a page\n if (page.length < pageSize || oldestCheckpointId === undefined || !advanced)\n return null;\n before = { configurable: { checkpoint_id: oldestCheckpointId } };\n }\n};\n"],"mappings":";AAkBA,MAAa,8BAA8B,OACzC,QACA,UACA,oBACA,aACA,WAAW,QACgB;CAC3B,IAAI,CAAC,mBAAmB,OAAO,MAAM,OAAO,EAAE,OAAO,QAAQ,GAAG,OAAO;CAEvE,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI;CAEJ,SAAS;EACP,MAAM,OAAO,MAAM,OAAO,QAAQ,WAChC,UACA,SAAS;GAAE,OAAO;GAAU;EAAO,IAAI,EAAE,OAAO,SAAS,CAC3D;EAEA,IAAI;EACJ,IAAI,WAAW;EACf,KAAK,MAAM,SAAS,MAAM;GACxB,MAAM,eAAe,MAAM,YAAY;GACvC,IAAI,OAAO,iBAAiB,UAAU;IACpC,qBAAqB;IACrB,IAAI,CAAC,QAAQ,IAAI,YAAY,GAAG;KAC9B,QAAQ,IAAI,YAAY;KACxB,WAAW;IACb;GACF;GACA,MAAM,gBAAgB,MAAM,SAAS;GAGrC,IACE,CAAC,MAAM,QAAQ,aAAa,KAC5B,cAAc,WAAW,mBAAmB,QAE5C;GACF,IAAI,CAAC,cAAc,OAAO,MAAM,OAAO,EAAE,OAAO,QAAQ,GAAG;GAI3D,IAHgB,mBAAmB,OAChC,GAAG,MAAM,EAAE,OAAO,cAAc,EAAE,EAAE,EAE7B,KAAK,cAAc,OAAO;EACtC;EAGA,IAAI,KAAK,SAAS,YAAY,uBAAuB,KAAA,KAAa,CAAC,UACjE,OAAO;EACT,SAAS,EAAE,cAAc,EAAE,eAAe,mBAAmB,EAAE;CACjE;AACF"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { LangChainBaseMessage } from "./types.js";
|
|
2
|
+
import { AssembledToolCall, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot } from "@langchain/react";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Read the current LangGraph interrupt state from the runtime extras.
|
|
7
|
+
*/
|
|
8
|
+
declare const useLangChainInterruptState: () => {
|
|
9
|
+
value?: unknown;
|
|
10
|
+
} | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Read every interrupt pending at the current checkpoint, each with `id`
|
|
13
|
+
* and `value`. Defaults to an empty array. Pair with `useLangChainRespondAll`
|
|
14
|
+
* (keyed by interrupt id) to resolve several at once.
|
|
15
|
+
*/
|
|
16
|
+
declare const useLangChainInterrupts: () => readonly {
|
|
17
|
+
id?: string;
|
|
18
|
+
value?: unknown;
|
|
19
|
+
}[];
|
|
20
|
+
/** Read the last run/hydration error from the runtime extras. */
|
|
21
|
+
declare const useLangChainError: () => unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Read the root tool calls assembled by `useStream` from the `tools`
|
|
24
|
+
* channel. Defaults to an empty array, so consumers can `.map` without
|
|
25
|
+
* a guard. Useful for rendering pending/streamed tool calls and
|
|
26
|
+
* approval UIs.
|
|
27
|
+
*/
|
|
28
|
+
declare const useLangChainToolCalls: () => readonly AssembledToolCall<string, unknown, unknown>[];
|
|
29
|
+
/** Subagents discovered on the current run (multi-agent graphs). */
|
|
30
|
+
declare const useLangChainSubagents: () => ReadonlyMap<string, SubagentDiscoverySnapshot>;
|
|
31
|
+
/** Subgraphs discovered on the current run. */
|
|
32
|
+
declare const useLangChainSubgraphs: () => ReadonlyMap<string, SubgraphDiscoverySnapshot>;
|
|
33
|
+
/**
|
|
34
|
+
* The underlying `useStream` handle, for advanced views — pass it to v1's
|
|
35
|
+
* `useMessages(stream, target)` / `useToolCalls(stream, target)` with a
|
|
36
|
+
* subagent/subgraph from `useLangChainSubagents` / `useLangChainSubgraphs`.
|
|
37
|
+
* `undefined` outside the runtime provider.
|
|
38
|
+
*/
|
|
39
|
+
declare const useLangChainStream: () => import("@langchain/react").AnyStream | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Returns a function to submit raw state updates to the LangGraph agent,
|
|
42
|
+
* bypassing the normal message flow. Useful for sending interrupt resume
|
|
43
|
+
* commands.
|
|
44
|
+
*/
|
|
45
|
+
declare const useLangChainSubmit: () => (values: Record<string, unknown> | null | undefined, options?: Record<string, unknown>) => Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Resume a LangGraph interrupt with a response payload via
|
|
48
|
+
* `useStream().respond`. Preferred over `useLangChainSendCommand`; it
|
|
49
|
+
* carries the response cleanly and handles interrupt namespaces.
|
|
50
|
+
*/
|
|
51
|
+
declare const useLangChainRespond: () => (response: unknown, options?: Record<string, unknown>) => Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Resume several LangGraph interrupts pending at the same checkpoint in
|
|
54
|
+
* one run via `useStream().respondAll`. Use when a run pauses on multiple
|
|
55
|
+
* interrupts at once; sequential `useLangChainRespond` calls can't service
|
|
56
|
+
* them (the first resume starts a run, stranding the rest).
|
|
57
|
+
*/
|
|
58
|
+
declare const useLangChainRespondAll: () => (responsesById: Record<string, unknown>, options?: Record<string, unknown>) => Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Submit a list of LangChain-shaped messages on the current thread.
|
|
61
|
+
* Parity helper for migrating from `useLangGraphSend`. Routes to
|
|
62
|
+
* `useStream().submit({ [messagesKey]: messages }, options)`.
|
|
63
|
+
*/
|
|
64
|
+
declare const useLangChainSend: () => (messages: readonly LangChainBaseMessage[], options?: Record<string, unknown>) => Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Submit a `useStream` command (e.g. interrupt resume). Parity helper
|
|
67
|
+
* for migrating from `useLangGraphSendCommand`. Note that v1's command
|
|
68
|
+
* shape (`{ resume?, goto?, update? }`) differs from the legacy
|
|
69
|
+
* `{ resume: string }` form; to carry a payload, use the input or
|
|
70
|
+
* `stream.respond` instead.
|
|
71
|
+
*/
|
|
72
|
+
declare const useLangChainSendCommand: () => (command: Record<string, unknown>) => Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Read a custom LangGraph state key from the current thread. Mirrors
|
|
75
|
+
* `useStream().values[key]` from `@langchain/react` and updates when the
|
|
76
|
+
* stream emits new state.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```tsx
|
|
80
|
+
* const todos = useLangChainState<Todo[]>("todos");
|
|
81
|
+
* const files = useLangChainState<Record<string, string>>("files", {});
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
declare function useLangChainState<T>(key: string): T | undefined;
|
|
85
|
+
declare function useLangChainState<T>(key: string, defaultValue: T): T;
|
|
86
|
+
//#endregion
|
|
87
|
+
export { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls };
|
|
88
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;;;AAwBA;cAAa,0BAAA;EACuC,KAAA;AAAA;;AAOpD;;;;cAAa,sBAAA;EAIV,EAAA;EAAA,KAAA;AAAA;;cAGU,iBAAA;AASb;;;;AAAkC;AAIlC;AAJA,cAAa,qBAAA,iBAAqB,iBAAA;;cAIrB,qBAAA,QAAqB,WAAA,SAAA,yBAAA;AAAA;AAAA,cAIrB,qBAAA,QAAqB,WAAA,SAAA,yBAAA;;;;AAAA;AASlC;;cAAa,kBAAA,mCAAkB,SAAA;;AAAA;AAQ/B;;;cAAa,kBAAA,SAGT,MAAA,EAAQ,MAAA,sCACR,OAAA,GAAU,MAAA,sBAAuB,OAAA;;;;;;cASxB,mBAAA,SAEH,QAAA,WAAmB,OAAA,GAAU,MAAA,sBAAuB,OAAA;;;;;AAXzB;AASrC;cAYa,sBAAA,SAGT,aAAA,EAAe,MAAA,mBACf,OAAA,GAAU,MAAA,sBAAuB,OAAA;;;;;;cASxB,gBAAA,SAGT,QAAA,WAAmB,oBAAA,IACnB,OAAA,GAAU,MAAA,sBAAuB,OAAA;;AA3ByB;AAU9D;;;;;cA+Ba,uBAAA,SAEH,OAAA,EAAS,MAAA,sBAAuB,OAAA;;;;;;;;;AA7BL;AASrC;;iBAkCgB,iBAAA,IAAqB,GAAA,WAAc,CAAC;AAAA,iBACpC,iBAAA,IAAqB,GAAA,UAAa,YAAA,EAAc,CAAA,GAAI,CAAC"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { langChainExtras } from "./runtimeExtras.js";
|
|
3
|
+
import { useAui } from "@assistant-ui/store";
|
|
4
|
+
//#region src/hooks.ts
|
|
5
|
+
const EMPTY_TOOL_CALLS = [];
|
|
6
|
+
const EMPTY_INTERRUPTS = [];
|
|
7
|
+
const EMPTY_SUBAGENTS = /* @__PURE__ */ new Map();
|
|
8
|
+
const EMPTY_SUBGRAPHS = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Read the current LangGraph interrupt state from the runtime extras.
|
|
11
|
+
*/
|
|
12
|
+
const useLangChainInterruptState = () => langChainExtras.use((e) => e.interrupt, void 0);
|
|
13
|
+
/**
|
|
14
|
+
* Read every interrupt pending at the current checkpoint, each with `id`
|
|
15
|
+
* and `value`. Defaults to an empty array. Pair with `useLangChainRespondAll`
|
|
16
|
+
* (keyed by interrupt id) to resolve several at once.
|
|
17
|
+
*/
|
|
18
|
+
const useLangChainInterrupts = () => langChainExtras.use((e) => e.interrupts ?? EMPTY_INTERRUPTS, EMPTY_INTERRUPTS);
|
|
19
|
+
/** Read the last run/hydration error from the runtime extras. */
|
|
20
|
+
const useLangChainError = () => langChainExtras.use((e) => e.error, void 0);
|
|
21
|
+
/**
|
|
22
|
+
* Read the root tool calls assembled by `useStream` from the `tools`
|
|
23
|
+
* channel. Defaults to an empty array, so consumers can `.map` without
|
|
24
|
+
* a guard. Useful for rendering pending/streamed tool calls and
|
|
25
|
+
* approval UIs.
|
|
26
|
+
*/
|
|
27
|
+
const useLangChainToolCalls = () => langChainExtras.use((e) => e.toolCalls ?? EMPTY_TOOL_CALLS, EMPTY_TOOL_CALLS);
|
|
28
|
+
/** Subagents discovered on the current run (multi-agent graphs). */
|
|
29
|
+
const useLangChainSubagents = () => langChainExtras.use((e) => e.subagents ?? EMPTY_SUBAGENTS, EMPTY_SUBAGENTS);
|
|
30
|
+
/** Subgraphs discovered on the current run. */
|
|
31
|
+
const useLangChainSubgraphs = () => langChainExtras.use((e) => e.subgraphs ?? EMPTY_SUBGRAPHS, EMPTY_SUBGRAPHS);
|
|
32
|
+
/**
|
|
33
|
+
* The underlying `useStream` handle, for advanced views — pass it to v1's
|
|
34
|
+
* `useMessages(stream, target)` / `useToolCalls(stream, target)` with a
|
|
35
|
+
* subagent/subgraph from `useLangChainSubagents` / `useLangChainSubgraphs`.
|
|
36
|
+
* `undefined` outside the runtime provider.
|
|
37
|
+
*/
|
|
38
|
+
const useLangChainStream = () => langChainExtras.use((e) => e.stream, void 0);
|
|
39
|
+
/**
|
|
40
|
+
* Returns a function to submit raw state updates to the LangGraph agent,
|
|
41
|
+
* bypassing the normal message flow. Useful for sending interrupt resume
|
|
42
|
+
* commands.
|
|
43
|
+
*/
|
|
44
|
+
const useLangChainSubmit = () => {
|
|
45
|
+
const aui = useAui();
|
|
46
|
+
return (values, options) => langChainExtras.get(aui).submit(values, options);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Resume a LangGraph interrupt with a response payload via
|
|
50
|
+
* `useStream().respond`. Preferred over `useLangChainSendCommand`; it
|
|
51
|
+
* carries the response cleanly and handles interrupt namespaces.
|
|
52
|
+
*/
|
|
53
|
+
const useLangChainRespond = () => {
|
|
54
|
+
const aui = useAui();
|
|
55
|
+
return (response, options) => langChainExtras.get(aui).respond(response, options);
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Resume several LangGraph interrupts pending at the same checkpoint in
|
|
59
|
+
* one run via `useStream().respondAll`. Use when a run pauses on multiple
|
|
60
|
+
* interrupts at once; sequential `useLangChainRespond` calls can't service
|
|
61
|
+
* them (the first resume starts a run, stranding the rest).
|
|
62
|
+
*/
|
|
63
|
+
const useLangChainRespondAll = () => {
|
|
64
|
+
const aui = useAui();
|
|
65
|
+
return (responsesById, options) => langChainExtras.get(aui).respondAll(responsesById, options);
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Submit a list of LangChain-shaped messages on the current thread.
|
|
69
|
+
* Parity helper for migrating from `useLangGraphSend`. Routes to
|
|
70
|
+
* `useStream().submit({ [messagesKey]: messages }, options)`.
|
|
71
|
+
*/
|
|
72
|
+
const useLangChainSend = () => {
|
|
73
|
+
const aui = useAui();
|
|
74
|
+
return (messages, options) => {
|
|
75
|
+
const extras = langChainExtras.get(aui);
|
|
76
|
+
return extras.submit({ [extras.messagesKey]: messages }, options);
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Submit a `useStream` command (e.g. interrupt resume). Parity helper
|
|
81
|
+
* for migrating from `useLangGraphSendCommand`. Note that v1's command
|
|
82
|
+
* shape (`{ resume?, goto?, update? }`) differs from the legacy
|
|
83
|
+
* `{ resume: string }` form; to carry a payload, use the input or
|
|
84
|
+
* `stream.respond` instead.
|
|
85
|
+
*/
|
|
86
|
+
const useLangChainSendCommand = () => {
|
|
87
|
+
const submit = useLangChainSubmit();
|
|
88
|
+
return (command) => submit(null, { command });
|
|
89
|
+
};
|
|
90
|
+
function useLangChainState(key, defaultValue) {
|
|
91
|
+
return langChainExtras.use((e) => {
|
|
92
|
+
const value = e.values[key];
|
|
93
|
+
return value !== void 0 ? value : defaultValue;
|
|
94
|
+
}, defaultValue);
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls };
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useAui } from \"@assistant-ui/store\";\nimport type {\n AssembledToolCall,\n SubagentDiscoverySnapshot,\n SubgraphDiscoverySnapshot,\n} from \"@langchain/react\";\nimport { langChainExtras } from \"./runtimeExtras\";\nimport type { LangChainBaseMessage } from \"./types\";\n\nconst EMPTY_TOOL_CALLS: readonly AssembledToolCall[] = [];\n\nconst EMPTY_INTERRUPTS: readonly { id?: string; value?: unknown }[] = [];\n\nconst EMPTY_SUBAGENTS: ReadonlyMap<string, SubagentDiscoverySnapshot> =\n new Map();\n\nconst EMPTY_SUBGRAPHS: ReadonlyMap<string, SubgraphDiscoverySnapshot> =\n new Map();\n\n/**\n * Read the current LangGraph interrupt state from the runtime extras.\n */\nexport const useLangChainInterruptState = () =>\n langChainExtras.use((e) => e.interrupt, undefined);\n\n/**\n * Read every interrupt pending at the current checkpoint, each with `id`\n * and `value`. Defaults to an empty array. Pair with `useLangChainRespondAll`\n * (keyed by interrupt id) to resolve several at once.\n */\nexport const useLangChainInterrupts = () =>\n langChainExtras.use(\n (e) => e.interrupts ?? EMPTY_INTERRUPTS,\n EMPTY_INTERRUPTS,\n );\n\n/** Read the last run/hydration error from the runtime extras. */\nexport const useLangChainError = () =>\n langChainExtras.use((e) => e.error, undefined);\n\n/**\n * Read the root tool calls assembled by `useStream` from the `tools`\n * channel. Defaults to an empty array, so consumers can `.map` without\n * a guard. Useful for rendering pending/streamed tool calls and\n * approval UIs.\n */\nexport const useLangChainToolCalls = () =>\n langChainExtras.use((e) => e.toolCalls ?? EMPTY_TOOL_CALLS, EMPTY_TOOL_CALLS);\n\n/** Subagents discovered on the current run (multi-agent graphs). */\nexport const useLangChainSubagents = () =>\n langChainExtras.use((e) => e.subagents ?? EMPTY_SUBAGENTS, EMPTY_SUBAGENTS);\n\n/** Subgraphs discovered on the current run. */\nexport const useLangChainSubgraphs = () =>\n langChainExtras.use((e) => e.subgraphs ?? EMPTY_SUBGRAPHS, EMPTY_SUBGRAPHS);\n\n/**\n * The underlying `useStream` handle, for advanced views — pass it to v1's\n * `useMessages(stream, target)` / `useToolCalls(stream, target)` with a\n * subagent/subgraph from `useLangChainSubagents` / `useLangChainSubgraphs`.\n * `undefined` outside the runtime provider.\n */\nexport const useLangChainStream = () =>\n langChainExtras.use((e) => e.stream, undefined);\n\n/**\n * Returns a function to submit raw state updates to the LangGraph agent,\n * bypassing the normal message flow. Useful for sending interrupt resume\n * commands.\n */\nexport const useLangChainSubmit = () => {\n const aui = useAui();\n return (\n values: Record<string, unknown> | null | undefined,\n options?: Record<string, unknown>,\n ) => langChainExtras.get(aui).submit(values, options);\n};\n\n/**\n * Resume a LangGraph interrupt with a response payload via\n * `useStream().respond`. Preferred over `useLangChainSendCommand`; it\n * carries the response cleanly and handles interrupt namespaces.\n */\nexport const useLangChainRespond = () => {\n const aui = useAui();\n return (response: unknown, options?: Record<string, unknown>) =>\n langChainExtras.get(aui).respond(response, options);\n};\n\n/**\n * Resume several LangGraph interrupts pending at the same checkpoint in\n * one run via `useStream().respondAll`. Use when a run pauses on multiple\n * interrupts at once; sequential `useLangChainRespond` calls can't service\n * them (the first resume starts a run, stranding the rest).\n */\nexport const useLangChainRespondAll = () => {\n const aui = useAui();\n return (\n responsesById: Record<string, unknown>,\n options?: Record<string, unknown>,\n ) => langChainExtras.get(aui).respondAll(responsesById, options);\n};\n\n/**\n * Submit a list of LangChain-shaped messages on the current thread.\n * Parity helper for migrating from `useLangGraphSend`. Routes to\n * `useStream().submit({ [messagesKey]: messages }, options)`.\n */\nexport const useLangChainSend = () => {\n const aui = useAui();\n return (\n messages: readonly LangChainBaseMessage[],\n options?: Record<string, unknown>,\n ) => {\n const extras = langChainExtras.get(aui);\n return extras.submit({ [extras.messagesKey]: messages }, options);\n };\n};\n\n/**\n * Submit a `useStream` command (e.g. interrupt resume). Parity helper\n * for migrating from `useLangGraphSendCommand`. Note that v1's command\n * shape (`{ resume?, goto?, update? }`) differs from the legacy\n * `{ resume: string }` form; to carry a payload, use the input or\n * `stream.respond` instead.\n */\nexport const useLangChainSendCommand = () => {\n const submit = useLangChainSubmit();\n return (command: Record<string, unknown>) => submit(null, { command });\n};\n\n/**\n * Read a custom LangGraph state key from the current thread. Mirrors\n * `useStream().values[key]` from `@langchain/react` and updates when the\n * stream emits new state.\n *\n * @example\n * ```tsx\n * const todos = useLangChainState<Todo[]>(\"todos\");\n * const files = useLangChainState<Record<string, string>>(\"files\", {});\n * ```\n */\nexport function useLangChainState<T>(key: string): T | undefined;\nexport function useLangChainState<T>(key: string, defaultValue: T): T;\nexport function useLangChainState<T>(\n key: string,\n defaultValue?: T,\n): T | undefined {\n return langChainExtras.use((e) => {\n const value = e.values[key] as T | undefined;\n return value !== undefined ? value : defaultValue;\n }, defaultValue);\n}\n"],"mappings":";;;;AAWA,MAAM,mBAAiD,CAAC;AAExD,MAAM,mBAAgE,CAAC;AAEvE,MAAM,kCACJ,IAAI,IAAI;AAEV,MAAM,kCACJ,IAAI,IAAI;;;;AAKV,MAAa,mCACX,gBAAgB,KAAK,MAAM,EAAE,WAAW,KAAA,CAAS;;;;;;AAOnD,MAAa,+BACX,gBAAgB,KACb,MAAM,EAAE,cAAc,kBACvB,gBACF;;AAGF,MAAa,0BACX,gBAAgB,KAAK,MAAM,EAAE,OAAO,KAAA,CAAS;;;;;;;AAQ/C,MAAa,8BACX,gBAAgB,KAAK,MAAM,EAAE,aAAa,kBAAkB,gBAAgB;;AAG9E,MAAa,8BACX,gBAAgB,KAAK,MAAM,EAAE,aAAa,iBAAiB,eAAe;;AAG5E,MAAa,8BACX,gBAAgB,KAAK,MAAM,EAAE,aAAa,iBAAiB,eAAe;;;;;;;AAQ5E,MAAa,2BACX,gBAAgB,KAAK,MAAM,EAAE,QAAQ,KAAA,CAAS;;;;;;AAOhD,MAAa,2BAA2B;CACtC,MAAM,MAAM,OAAO;CACnB,QACE,QACA,YACG,gBAAgB,IAAI,GAAG,CAAC,CAAC,OAAO,QAAQ,OAAO;AACtD;;;;;;AAOA,MAAa,4BAA4B;CACvC,MAAM,MAAM,OAAO;CACnB,QAAQ,UAAmB,YACzB,gBAAgB,IAAI,GAAG,CAAC,CAAC,QAAQ,UAAU,OAAO;AACtD;;;;;;;AAQA,MAAa,+BAA+B;CAC1C,MAAM,MAAM,OAAO;CACnB,QACE,eACA,YACG,gBAAgB,IAAI,GAAG,CAAC,CAAC,WAAW,eAAe,OAAO;AACjE;;;;;;AAOA,MAAa,yBAAyB;CACpC,MAAM,MAAM,OAAO;CACnB,QACE,UACA,YACG;EACH,MAAM,SAAS,gBAAgB,IAAI,GAAG;EACtC,OAAO,OAAO,OAAO,GAAG,OAAO,cAAc,SAAS,GAAG,OAAO;CAClE;AACF;;;;;;;;AASA,MAAa,gCAAgC;CAC3C,MAAM,SAAS,mBAAmB;CAClC,QAAQ,YAAqC,OAAO,MAAM,EAAE,QAAQ,CAAC;AACvE;AAeA,SAAgB,kBACd,KACA,cACe;CACf,OAAO,gBAAgB,KAAK,MAAM;EAChC,MAAM,QAAQ,EAAE,OAAO;EACvB,OAAO,UAAU,KAAA,IAAY,QAAQ;CACvC,GAAG,YAAY;AACjB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { LangChainBaseMessage, LangChainContentBlock, LangChainToolCall } from "./types.js";
|
|
1
|
+
import { LangChainBaseMessage, LangChainContentBlock, LangChainToolCall, RemoveUIMessage, UIMessage, UseStreamRuntimeOptions } from "./types.js";
|
|
2
2
|
import { convertLangChainBaseMessage } from "./convertMessages.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls } from "./hooks.js";
|
|
4
|
+
import { useStreamRuntime } from "./useStreamRuntime.js";
|
|
5
|
+
import { useLangChainStreamingTiming } from "./streamingTiming.js";
|
|
6
|
+
import { SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot } from "@langchain/react";
|
|
7
|
+
export { type LangChainBaseMessage, type LangChainContentBlock, type LangChainToolCall, type RemoveUIMessage, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type UIMessage, type UseStreamRuntimeOptions, convertLangChainBaseMessage, useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainStreamingTiming, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls, useStreamRuntime };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { convertLangChainBaseMessage } from "./convertMessages.js";
|
|
2
|
-
import { useLangChainError, useLangChainInterruptState, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainSubmit, useLangChainToolCalls
|
|
3
|
-
|
|
2
|
+
import { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls } from "./hooks.js";
|
|
3
|
+
import { useLangChainStreamingTiming } from "./streamingTiming.js";
|
|
4
|
+
import { useStreamRuntime } from "./useStreamRuntime.js";
|
|
5
|
+
export { convertLangChainBaseMessage, useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainStreamingTiming, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls, useStreamRuntime };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LangChainBaseMessage } from "./types.js";
|
|
2
|
+
import { ForkCheckpointClient } from "./findForkCheckpointInHistory.js";
|
|
3
|
+
|
|
4
|
+
//#region src/resolveForkCheckpoint.d.ts
|
|
5
|
+
type MessageMetadataSnapshot = ReadonlyMap<string, {
|
|
6
|
+
readonly parentCheckpointId: string | undefined;
|
|
7
|
+
}> | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Hydration seeds every message with the head's parent checkpoint, so only the
|
|
10
|
+
* head's recorded fork checkpoint is reliable; older turns are matched against
|
|
11
|
+
* server history by message id. A `null` `parentId` edits the first human
|
|
12
|
+
* message and forks from the thread's initial (empty-message) checkpoint.
|
|
13
|
+
*/
|
|
14
|
+
declare const resolveForkCheckpoint: (client: ForkCheckpointClient, threadId: string, messages: readonly LangChainBaseMessage[], parentId: string | null, sourceId: string | null | undefined, metadata: MessageMetadataSnapshot, messagesKey: string) => Promise<string | null>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { resolveForkCheckpoint };
|
|
17
|
+
//# sourceMappingURL=resolveForkCheckpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveForkCheckpoint.d.ts","names":[],"sources":["../src/resolveForkCheckpoint.ts"],"mappings":";;;;KAMK,uBAAA,GACD,WAAW;EAAA,SAAoB,kBAAkB;AAAA;;;;AAAA;AASrD;;cAAa,qBAAA,GACX,MAAA,EAAQ,oBAAA,EACR,QAAA,UACA,QAAA,WAAmB,oBAAA,IACnB,QAAA,iBACA,QAAA,6BACA,QAAA,EAAU,uBAAA,EACV,WAAA,aACC,OAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { findForkCheckpointInHistory } from "./findForkCheckpointInHistory.js";
|
|
2
|
+
//#region src/resolveForkCheckpoint.ts
|
|
3
|
+
/**
|
|
4
|
+
* Hydration seeds every message with the head's parent checkpoint, so only the
|
|
5
|
+
* head's recorded fork checkpoint is reliable; older turns are matched against
|
|
6
|
+
* server history by message id. A `null` `parentId` edits the first human
|
|
7
|
+
* message and forks from the thread's initial (empty-message) checkpoint.
|
|
8
|
+
*/
|
|
9
|
+
const resolveForkCheckpoint = async (client, threadId, messages, parentId, sourceId, metadata, messagesKey) => {
|
|
10
|
+
const lastMessage = messages[messages.length - 1];
|
|
11
|
+
let checkpointId = sourceId != null && lastMessage?.id === sourceId ? metadata?.get(sourceId)?.parentCheckpointId ?? null : null;
|
|
12
|
+
if (!checkpointId) {
|
|
13
|
+
const parentIndex = parentId == null ? -1 : messages.findIndex((m) => m.id === parentId);
|
|
14
|
+
if (parentId != null && parentIndex === -1) return null;
|
|
15
|
+
try {
|
|
16
|
+
checkpointId = await findForkCheckpointInHistory(client, threadId, messages.slice(0, parentIndex + 1), messagesKey);
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return checkpointId;
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { resolveForkCheckpoint };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=resolveForkCheckpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveForkCheckpoint.js","names":[],"sources":["../src/resolveForkCheckpoint.ts"],"sourcesContent":["import type { LangChainBaseMessage } from \"./types\";\nimport {\n findForkCheckpointInHistory,\n type ForkCheckpointClient,\n} from \"./findForkCheckpointInHistory\";\n\ntype MessageMetadataSnapshot =\n | ReadonlyMap<string, { readonly parentCheckpointId: string | undefined }>\n | undefined;\n\n/**\n * Hydration seeds every message with the head's parent checkpoint, so only the\n * head's recorded fork checkpoint is reliable; older turns are matched against\n * server history by message id. A `null` `parentId` edits the first human\n * message and forks from the thread's initial (empty-message) checkpoint.\n */\nexport const resolveForkCheckpoint = async (\n client: ForkCheckpointClient,\n threadId: string,\n messages: readonly LangChainBaseMessage[],\n parentId: string | null,\n sourceId: string | null | undefined,\n metadata: MessageMetadataSnapshot,\n messagesKey: string,\n): Promise<string | null> => {\n const lastMessage = messages[messages.length - 1];\n let checkpointId: string | null =\n sourceId != null && lastMessage?.id === sourceId\n ? (metadata?.get(sourceId)?.parentCheckpointId ?? null)\n : null;\n\n if (!checkpointId) {\n const parentIndex =\n parentId == null ? -1 : messages.findIndex((m) => m.id === parentId);\n if (parentId != null && parentIndex === -1) return null;\n try {\n checkpointId = await findForkCheckpointInHistory(\n client,\n threadId,\n messages.slice(0, parentIndex + 1),\n messagesKey,\n );\n } catch {\n return null;\n }\n }\n\n return checkpointId;\n};\n"],"mappings":";;;;;;;;AAgBA,MAAa,wBAAwB,OACnC,QACA,UACA,UACA,UACA,UACA,UACA,gBAC2B;CAC3B,MAAM,cAAc,SAAS,SAAS,SAAS;CAC/C,IAAI,eACF,YAAY,QAAQ,aAAa,OAAO,WACnC,UAAU,IAAI,QAAQ,CAAC,EAAE,sBAAsB,OAChD;CAEN,IAAI,CAAC,cAAc;EACjB,MAAM,cACJ,YAAY,OAAO,KAAK,SAAS,WAAW,MAAM,EAAE,OAAO,QAAQ;EACrE,IAAI,YAAY,QAAQ,gBAAgB,IAAI,OAAO;EACnD,IAAI;GACF,eAAe,MAAM,4BACnB,QACA,UACA,SAAS,MAAM,GAAG,cAAc,CAAC,GACjC,WACF;EACF,QAAQ;GACN,OAAO;EACT;CACF;CAEA,OAAO;AACT"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LangChainRuntimeExtras } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/runtimeExtras.d.ts
|
|
4
|
+
declare const langChainExtras: import("@assistant-ui/core/internal").RuntimeExtras<LangChainRuntimeExtras>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { langChainExtras };
|
|
7
|
+
//# sourceMappingURL=runtimeExtras.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeExtras.d.ts","names":[],"sources":["../src/runtimeExtras.ts"],"mappings":";;;cAGa,eAAA,wCAAe,aAAA,CAAA,sBAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeExtras.js","names":[],"sources":["../src/runtimeExtras.ts"],"sourcesContent":["import { createRuntimeExtras } from \"@assistant-ui/core/internal\";\nimport type { LangChainRuntimeExtras } from \"./types\";\n\nexport const langChainExtras =\n createRuntimeExtras<LangChainRuntimeExtras>(\"useStreamRuntime\");\n"],"mappings":";;AAGA,MAAa,kBACX,oBAA4C,kBAAkB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LangChainBaseMessage } from "./types.js";
|
|
2
|
+
import { MessageTiming } from "@assistant-ui/core";
|
|
3
|
+
import { StreamingTimingAccessors } from "@assistant-ui/core/react";
|
|
4
|
+
|
|
5
|
+
//#region src/streamingTiming.d.ts
|
|
6
|
+
declare const langChainStreamingTimingAccessors: StreamingTimingAccessors<LangChainBaseMessage>;
|
|
7
|
+
/**
|
|
8
|
+
* Tracks per-message streaming timing for LangChain messages. Delegates to
|
|
9
|
+
* the shared `useStreamingTiming` primitive in `@assistant-ui/core/react`,
|
|
10
|
+
* adapted to the `LangChainBaseMessage` shape (`_getType() -> "ai"`, content
|
|
11
|
+
* blocks including text/thinking/reasoning, `tool_calls`).
|
|
12
|
+
*/
|
|
13
|
+
declare const useLangChainStreamingTiming: (messages: readonly LangChainBaseMessage[], isRunning: boolean) => Record<string, MessageTiming>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { langChainStreamingTimingAccessors, useLangChainStreamingTiming };
|
|
16
|
+
//# sourceMappingURL=streamingTiming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamingTiming.d.ts","names":[],"sources":["../src/streamingTiming.ts"],"mappings":";;;;;cAmEa,iCAAA,EAAmC,wBAAwB,CAAC,oBAAA;;AAAzE;;;;AAA6F;cAahF,2BAAA,GACX,QAAA,WAAmB,oBAAA,IACnB,SAAA,cACC,MAAA,SAAe,aAAA"}
|