langgraph-ui-components 0.0.10 → 0.0.11
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.es116.js +1 -1
- package/dist/index.es119.js +1 -1
- package/dist/index.es12.js +1 -1
- package/dist/index.es120.js +9 -9
- package/dist/index.es13.js +6 -6
- package/dist/index.es15.js +59 -31
- package/dist/index.es15.js.map +1 -1
- package/dist/index.es16.js +1 -1
- package/dist/index.es18.js +7 -7
- package/dist/index.es2.js +25 -11
- package/dist/index.es2.js.map +1 -1
- package/dist/index.es20.js +2 -2
- package/dist/index.es22.js +15 -119
- package/dist/index.es22.js.map +1 -1
- package/dist/index.es23.js +37 -17
- package/dist/index.es23.js.map +1 -1
- package/dist/index.es233.js +1 -1
- package/dist/index.es234.js +3 -3
- package/dist/index.es235.js +1 -1
- package/dist/index.es24.js +27 -34
- package/dist/index.es24.js.map +1 -1
- package/dist/index.es25.js +146 -27
- package/dist/index.es25.js.map +1 -1
- package/dist/index.es26.js +100 -144
- package/dist/index.es26.js.map +1 -1
- package/dist/index.es260.js +5 -8
- package/dist/index.es260.js.map +1 -1
- package/dist/index.es261.js +13 -5
- package/dist/index.es261.js.map +1 -1
- package/dist/index.es262.js +5 -12
- package/dist/index.es262.js.map +1 -1
- package/dist/index.es263.js +8 -6
- package/dist/index.es263.js.map +1 -1
- package/dist/index.es27.js +66 -101
- package/dist/index.es27.js.map +1 -1
- package/dist/index.es28.js +295 -58
- package/dist/index.es28.js.map +1 -1
- package/dist/index.es280.js +131 -3726
- package/dist/index.es280.js.map +1 -1
- package/dist/index.es281.js +2 -342
- package/dist/index.es281.js.map +1 -1
- package/dist/index.es282.js +3704 -76
- package/dist/index.es282.js.map +1 -1
- package/dist/index.es283.js +326 -117
- package/dist/index.es283.js.map +1 -1
- package/dist/index.es284.js +107 -13
- package/dist/index.es284.js.map +1 -1
- package/dist/index.es285.js +123 -142
- package/dist/index.es285.js.map +1 -1
- package/dist/index.es286.js +13 -13
- package/dist/index.es286.js.map +1 -1
- package/dist/index.es287.js +150 -6
- package/dist/index.es287.js.map +1 -1
- package/dist/index.es288.js +13 -19
- package/dist/index.es288.js.map +1 -1
- package/dist/index.es289.js +6 -88
- package/dist/index.es289.js.map +1 -1
- package/dist/index.es29.js +114 -298
- package/dist/index.es29.js.map +1 -1
- package/dist/index.es290.js +16 -238
- package/dist/index.es290.js.map +1 -1
- package/dist/index.es291.js +88 -22
- package/dist/index.es291.js.map +1 -1
- package/dist/index.es292.js +243 -6
- package/dist/index.es292.js.map +1 -1
- package/dist/index.es293.js +24 -4
- package/dist/index.es293.js.map +1 -1
- package/dist/index.es294.js +6 -18
- package/dist/index.es294.js.map +1 -1
- package/dist/index.es295.js +4 -8
- package/dist/index.es295.js.map +1 -1
- package/dist/index.es296.js +17 -141
- package/dist/index.es296.js.map +1 -1
- package/dist/index.es297.js +8 -2
- package/dist/index.es297.js.map +1 -1
- package/dist/index.es31.js +7 -7
- package/dist/index.es32.js +1 -1
- package/dist/index.es35.js +4 -4
- package/dist/index.es36.js +204 -114
- package/dist/index.es36.js.map +1 -1
- package/dist/index.es37.js +5 -71
- package/dist/index.es37.js.map +1 -1
- package/dist/index.es38.js +119 -19
- package/dist/index.es38.js.map +1 -1
- package/dist/index.es39.js +66 -256
- package/dist/index.es39.js.map +1 -1
- package/dist/index.es40.js +17 -42
- package/dist/index.es40.js.map +1 -1
- package/dist/index.es41.js +239 -193
- package/dist/index.es41.js.map +1 -1
- package/dist/index.es42.js +17 -41
- package/dist/index.es42.js.map +1 -1
- package/dist/index.es43.js +193 -120
- package/dist/index.es43.js.map +1 -1
- package/dist/index.es44.js +60 -17
- package/dist/index.es44.js.map +1 -1
- package/dist/index.es45.js +123 -211
- package/dist/index.es45.js.map +1 -1
- package/dist/index.es46.js +22 -7
- package/dist/index.es46.js.map +1 -1
- package/dist/index.es47.js +214 -1176
- package/dist/index.es47.js.map +1 -1
- package/dist/index.es48.js +10 -8
- package/dist/index.es48.js.map +1 -1
- package/dist/index.es49.js +1182 -137
- package/dist/index.es49.js.map +1 -1
- package/dist/index.es50.js +7 -208
- package/dist/index.es50.js.map +1 -1
- package/dist/index.es51.js +147 -5
- package/dist/index.es51.js.map +1 -1
- package/dist/index.es55.js +1 -1
- package/dist/index.es56.js +1 -1
- package/dist/index.es57.js +1 -1
- package/dist/index.es58.js +7 -7
- package/dist/index.es97.js +1 -1
- package/dist/index.es98.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.es116.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __export } from "./index.es52.js";
|
|
2
|
-
import { getBufferString } from "./index.
|
|
2
|
+
import { getBufferString } from "./index.es47.js";
|
|
3
3
|
import { getEnvironmentVariable } from "./index.es231.js";
|
|
4
4
|
import { isBaseCallbackHandler, BaseCallbackHandler } from "./index.es232.js";
|
|
5
5
|
import { isBaseTracer } from "./index.es123.js";
|
package/dist/index.es119.js
CHANGED
package/dist/index.es12.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useStreamContext } from "./index.es7.js";
|
|
3
3
|
import { useGeneratedSuggestions } from "./index.es11.js";
|
|
4
|
-
import { LiquidButton } from "./index.
|
|
4
|
+
import { LiquidButton } from "./index.es28.js";
|
|
5
5
|
function Suggestion() {
|
|
6
6
|
const stream = useStreamContext();
|
|
7
7
|
const agentSuggestions = stream.values?.suggestions;
|
package/dist/index.es120.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Client } from "./index.
|
|
2
|
-
import { isTracingEnabled } from "./index.
|
|
3
|
-
import { isConflictingEndpointsError, ConflictingEndpointsError } from "./index.
|
|
4
|
-
import { _LC_CONTEXT_VARIABLES_KEY, _REPLICA_TRACE_ROOTS_KEY } from "./index.
|
|
5
|
-
import { getContextVar, setContextVar } from "./index.
|
|
6
|
-
import { getEnvironmentVariable, getRuntimeEnvironment, getLangSmithEnvironmentVariable } from "./index.
|
|
7
|
-
import { getDefaultProjectName } from "./index.
|
|
8
|
-
import { warnOnce } from "./index.
|
|
9
|
-
import { uuid7FromTime } from "./index.
|
|
1
|
+
import { Client } from "./index.es282.js";
|
|
2
|
+
import { isTracingEnabled } from "./index.es294.js";
|
|
3
|
+
import { isConflictingEndpointsError, ConflictingEndpointsError } from "./index.es291.js";
|
|
4
|
+
import { _LC_CONTEXT_VARIABLES_KEY, _REPLICA_TRACE_ROOTS_KEY } from "./index.es295.js";
|
|
5
|
+
import { getContextVar, setContextVar } from "./index.es296.js";
|
|
6
|
+
import { getEnvironmentVariable, getRuntimeEnvironment, getLangSmithEnvironmentVariable } from "./index.es287.js";
|
|
7
|
+
import { getDefaultProjectName } from "./index.es262.js";
|
|
8
|
+
import { warnOnce } from "./index.es289.js";
|
|
9
|
+
import { uuid7FromTime } from "./index.es288.js";
|
|
10
10
|
import { v5 } from "uuid";
|
|
11
11
|
const UUID_NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
12
12
|
function getReplicaKey(replica) {
|
package/dist/index.es13.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useStreamContext } from "./index.es7.js";
|
|
3
|
-
import { isAiWithToolCalls, isToolMessage } from "./index.
|
|
3
|
+
import { isAiWithToolCalls, isToolMessage } from "./index.es22.js";
|
|
4
4
|
import React__default, { useMemo, useRef, useCallback, useEffect, useLayoutEffect } from "react";
|
|
5
|
-
import AgentMessage from "./index.
|
|
6
|
-
import CustomComponentRender from "./index.
|
|
7
|
-
import HumanMessage from "./index.
|
|
8
|
-
import Thinking from "./index.
|
|
9
|
-
import ToolCallFunctions from "./index.
|
|
5
|
+
import AgentMessage from "./index.es23.js";
|
|
6
|
+
import CustomComponentRender from "./index.es24.js";
|
|
7
|
+
import HumanMessage from "./index.es25.js";
|
|
8
|
+
import Thinking from "./index.es26.js";
|
|
9
|
+
import ToolCallFunctions from "./index.es27.js";
|
|
10
10
|
function ChatBody({ setIsFirstMessage, enableToolCallIndicator }) {
|
|
11
11
|
const stream = useStreamContext();
|
|
12
12
|
const messages = stream.messages;
|
package/dist/index.es15.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import "react";
|
|
2
|
+
import { Paperclip, Loader2, MoveUp } from "lucide-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
4
|
function ChatInput({
|
|
5
5
|
input,
|
|
6
6
|
inputFileAccept = ".png,.jpg,.jpeg,.pdf,.docx",
|
|
@@ -10,41 +10,69 @@ function ChatInput({
|
|
|
10
10
|
setFileInput,
|
|
11
11
|
handleFileSelect,
|
|
12
12
|
isLoading = false,
|
|
13
|
-
onCancel
|
|
13
|
+
onCancel,
|
|
14
|
+
filePreview
|
|
14
15
|
}) {
|
|
15
16
|
const canSubmit = (input.trim().length > 0 || fileInput.length > 0) && !isLoading;
|
|
17
|
+
const [isDragOver, setIsDragOver] = useState(false);
|
|
18
|
+
const handleDragOver = (e) => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
setIsDragOver(true);
|
|
22
|
+
};
|
|
23
|
+
const handleDragLeave = (e) => {
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
e.stopPropagation();
|
|
26
|
+
setIsDragOver(false);
|
|
27
|
+
};
|
|
28
|
+
const handleDrop = async (e) => {
|
|
29
|
+
e.preventDefault();
|
|
30
|
+
e.stopPropagation();
|
|
31
|
+
setIsDragOver(false);
|
|
32
|
+
const files = Array.from(e.dataTransfer.files);
|
|
33
|
+
if (files.length === 0) return;
|
|
34
|
+
const acceptedFiles = files.filter((file) => {
|
|
35
|
+
if (!inputFileAccept) return true;
|
|
36
|
+
const acceptTypes = inputFileAccept.split(",").map((type) => type.trim());
|
|
37
|
+
return acceptTypes.some((type) => {
|
|
38
|
+
if (type.startsWith(".")) {
|
|
39
|
+
return file.name.toLowerCase().endsWith(type.toLowerCase());
|
|
40
|
+
}
|
|
41
|
+
return file.type.match(type.replace("*", ".*"));
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
if (acceptedFiles.length === 0) return;
|
|
45
|
+
const fileDetails = await Promise.all(
|
|
46
|
+
acceptedFiles.map(async (file) => {
|
|
47
|
+
const base64Data = await new Promise((resolve, reject) => {
|
|
48
|
+
const reader = new FileReader();
|
|
49
|
+
reader.onload = () => {
|
|
50
|
+
const result = reader.result;
|
|
51
|
+
resolve(result.split(",")[1]);
|
|
52
|
+
};
|
|
53
|
+
reader.onerror = reject;
|
|
54
|
+
reader.readAsDataURL(file);
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
fileName: file.name,
|
|
58
|
+
fileType: file.type,
|
|
59
|
+
file,
|
|
60
|
+
fileData: base64Data
|
|
61
|
+
};
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
setFileInput((prevFile) => [...prevFile, ...fileDetails]);
|
|
65
|
+
};
|
|
16
66
|
return /* @__PURE__ */ jsxs(
|
|
17
67
|
"form",
|
|
18
68
|
{
|
|
19
69
|
onSubmit: handleSubmit,
|
|
20
|
-
className:
|
|
70
|
+
className: `relative flex flex-col gap-2 border rounded-xl m-2 bg-zinc-900 border-zinc-800 transition-colors ${isDragOver ? "border-blue-500 bg-zinc-800" : ""}`,
|
|
71
|
+
onDragOver: handleDragOver,
|
|
72
|
+
onDragLeave: handleDragLeave,
|
|
73
|
+
onDrop: handleDrop,
|
|
21
74
|
children: [
|
|
22
|
-
|
|
23
|
-
"div",
|
|
24
|
-
{
|
|
25
|
-
className: "flex items-center justify-between gap-3 bg-zinc-800 p-2 rounded group hover:bg-zinc-700 transition-colors",
|
|
26
|
-
children: [
|
|
27
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0 flex-1", children: [
|
|
28
|
-
/* @__PURE__ */ jsx(FileIcon, { className: "text-blue-400 shrink-0", size: 20 }),
|
|
29
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 overflow-hidden", children: [
|
|
30
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-zinc-200 truncate", children: file.fileName }),
|
|
31
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-500 truncate", children: file.fileType || "Unknown file type" })
|
|
32
|
-
] })
|
|
33
|
-
] }),
|
|
34
|
-
/* @__PURE__ */ jsx(
|
|
35
|
-
"button",
|
|
36
|
-
{
|
|
37
|
-
type: "button",
|
|
38
|
-
onClick: () => setFileInput((prev) => prev.filter((_, i) => i !== index)),
|
|
39
|
-
className: "shrink-0 p-1 rounded hover:bg-zinc-600 transition-colors",
|
|
40
|
-
"aria-label": "Remove file",
|
|
41
|
-
children: /* @__PURE__ */ jsx(X, { size: 16, className: "text-red-400" })
|
|
42
|
-
}
|
|
43
|
-
)
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
`file-${index}-${file.fileName}`
|
|
47
|
-
)) }),
|
|
75
|
+
filePreview && filePreview(fileInput, setFileInput),
|
|
48
76
|
/* @__PURE__ */ jsx(
|
|
49
77
|
"textarea",
|
|
50
78
|
{
|
|
@@ -115,7 +143,7 @@ function ChatInput({
|
|
|
115
143
|
disabled: !canSubmit,
|
|
116
144
|
className: "focus:outline-none transition-all bg-zinc-300 border rounded-full p-1 cursor-pointer",
|
|
117
145
|
style: { border: "none" },
|
|
118
|
-
children: /* @__PURE__ */ jsx(MoveUp, { size: 24, className: "text-black p-1" })
|
|
146
|
+
children: isLoading ? /* @__PURE__ */ jsx(Loader2, { size: 24, className: "animate-spin text-black p-1" }) : /* @__PURE__ */ jsx(MoveUp, { size: 24, className: "text-black p-1" })
|
|
119
147
|
}
|
|
120
148
|
)
|
|
121
149
|
] })
|
package/dist/index.es15.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es15.js","sources":["../src/components/sidebar/ChatInput.tsx"],"sourcesContent":["import type { FileInfo } from \"@/types/fileInput\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.es15.js","sources":["../src/components/sidebar/ChatInput.tsx"],"sourcesContent":["import type { FileInfo } from \"@/types/fileInput\";\nimport { MoveUp, Paperclip, Loader2 } from \"lucide-react\";\nimport {\n type ChangeEvent,\n type Dispatch,\n type FormEvent,\n type SetStateAction,\n useState,\n type DragEvent,\n} from \"react\";\n\nexport default function ChatInput({\n input,\n inputFileAccept = \".png,.jpg,.jpeg,.pdf,.docx\",\n setInput,\n handleSubmit,\n fileInput,\n setFileInput,\n handleFileSelect,\n isLoading = false,\n onCancel,\n filePreview,\n}: {\n input: string;\n setInput: (value: string) => void;\n handleSubmit: (e: FormEvent<HTMLFormElement>) => void;\n fileInput: FileInfo[];\n setFileInput: Dispatch<SetStateAction<FileInfo[]>>;\n handleFileSelect: (event: ChangeEvent<HTMLInputElement>) => void;\n inputFileAccept?: string;\n isLoading?: boolean;\n onCancel?: () => void;\n filePreview?: (files: FileInfo[], setFileInput: Dispatch<SetStateAction<FileInfo[]>>) => React.ReactNode;\n}) {\n const canSubmit =\n (input.trim().length > 0 || fileInput.length > 0) && !isLoading;\n\n const [isDragOver, setIsDragOver] = useState(false);\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(true);\n };\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n };\n\n const handleDrop = async (e: DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n const files = Array.from(e.dataTransfer.files);\n if (files.length === 0) return;\n\n const acceptedFiles = files.filter(file => {\n if (!inputFileAccept) return true;\n const acceptTypes = inputFileAccept.split(',').map(type => type.trim());\n return acceptTypes.some(type => {\n if (type.startsWith('.')) {\n return file.name.toLowerCase().endsWith(type.toLowerCase());\n }\n return file.type.match(type.replace('*', '.*'));\n });\n });\n\n if (acceptedFiles.length === 0) return;\n\n const fileDetails: FileInfo[] = await Promise.all(\n acceptedFiles.map(async (file) => {\n const base64Data = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n resolve(result.split(\",\")[1]); \n };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n\n return {\n fileName: file.name,\n fileType: file.type,\n file: file,\n fileData: base64Data,\n };\n })\n );\n\n setFileInput((prevFile) => [...prevFile, ...fileDetails]);\n };\n\n return (\n <form\n onSubmit={handleSubmit}\n className={`relative flex flex-col gap-2 border rounded-xl m-2 bg-zinc-900 border-zinc-800 transition-colors ${\n isDragOver ? 'border-blue-500 bg-zinc-800' : ''\n }`}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {/* File attachments preview */}\n {filePreview && filePreview(fileInput, setFileInput)}\n\n {/* Text input */}\n <textarea\n placeholder=\"Type your message...\"\n value={input}\n onChange={(e) => {\n setInput(e.target.value)\n const maxHeight = 300; // max height in pixels\n e.target.style.height = \"auto\"; // reset height\n e.target.style.height = Math.min(e.target.scrollHeight, maxHeight) + \"px\";\n }}\n onKeyDown={(e) => {\n if (\n e.key === \"Enter\" &&\n !e.shiftKey &&\n !e.metaKey &&\n !e.nativeEvent.isComposing\n ) {\n e.preventDefault();\n if (canSubmit) {\n e.currentTarget.form?.requestSubmit();\n }\n }\n }}\n disabled={isLoading}\n className=\"w-full field-sizing-content resize-none p-3.5 bg-transparent text-white placeholder-zinc-500 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed overflow-y-auto thread-scrollbar\"\n rows={1}\n />\n\n {/* Footer with controls */}\n <div className=\"flex justify-between items-center px-1 pb-2\">\n <div className=\"flex gap-1 m-2\">\n <label\n htmlFor=\"file-input\"\n className={`cursor-pointer ${isLoading ? \"opacity-50 cursor-not-allowed\" : \"\"\n }`}\n >\n <Paperclip\n size={24}\n className=\"text-zinc-400 hover:text-white hover:bg-zinc-800 rounded p-1 transition-colors\"\n />\n </label>\n <input\n id=\"file-input\"\n type=\"file\"\n multiple\n disabled={isLoading}\n accept={inputFileAccept}\n className=\"hidden\"\n onChange={handleFileSelect}\n />\n </div>\n\n <div className=\"flex gap-2 items-center\">\n {isLoading && onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-3 py-1 text-xs text-zinc-400 hover:text-white hover:bg-zinc-800 rounded transition-colors\"\n >\n Cancel\n </button>\n )}\n\n <button\n type=\"submit\"\n disabled={!canSubmit}\n className=\"focus:outline-none transition-all bg-zinc-300 border rounded-full p-1 cursor-pointer\"\n style={{ border: \"none\" }}\n >\n {isLoading ? (\n <Loader2 size={24} className=\"animate-spin text-black p-1\" />\n ) : (\n <MoveUp size={24} className=\"text-black p-1\" />\n )}\n </button>\n </div>\n </div>\n </form>\n );\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.es16.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import useTools from "./index.es10.js";
|
|
3
3
|
import { useThread } from "./index.es6.js";
|
|
4
|
-
import { getContentString } from "./index.
|
|
4
|
+
import { getContentString } from "./index.es22.js";
|
|
5
5
|
import { PanelLeft, MoreVertical, Pencil, Share2, Archive, Trash2 } from "lucide-react";
|
|
6
6
|
import { useState, useEffect, useRef } from "react";
|
|
7
7
|
function ThreadHistory() {
|
package/dist/index.es18.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { __export } from "./index.es52.js";
|
|
2
2
|
import { parseMimeType, parseBase64DataUrl, isURLContentBlock, isPlainTextContentBlock, isIDContentBlock, isDataContentBlock, isBase64ContentBlock, convertToProviderContentBlock, convertToOpenAIImageBlock } from "./index.es53.js";
|
|
3
3
|
import { isMessage } from "./index.es54.js";
|
|
4
|
-
import { mergeContent, isOpenAIToolCallArray, isBaseMessageChunk, isBaseMessage, _mergeStatus, _mergeObj, _mergeLists, _mergeDicts, _isMessageFieldWithRole, BaseMessageChunk, BaseMessage } from "./index.
|
|
4
|
+
import { mergeContent, isOpenAIToolCallArray, isBaseMessageChunk, isBaseMessage, _mergeStatus, _mergeObj, _mergeLists, _mergeDicts, _isMessageFieldWithRole, BaseMessageChunk, BaseMessage } from "./index.es41.js";
|
|
5
5
|
import { mergeUsageMetadata, mergeResponseMetadata } from "./index.es55.js";
|
|
6
|
-
import { isToolMessageChunk, isToolMessage, isDirectToolOutput, defaultToolCallParser, ToolMessageChunk, ToolMessage } from "./index.
|
|
6
|
+
import { isToolMessageChunk, isToolMessage, isDirectToolOutput, defaultToolCallParser, ToolMessageChunk, ToolMessage } from "./index.es45.js";
|
|
7
7
|
import { isChatMessageChunk, isChatMessage, ChatMessageChunk, ChatMessage } from "./index.es56.js";
|
|
8
8
|
import { isFunctionMessageChunk, isFunctionMessage, FunctionMessageChunk, FunctionMessage } from "./index.es57.js";
|
|
9
|
-
import { isHumanMessageChunk, isHumanMessage, HumanMessageChunk, HumanMessage } from "./index.
|
|
10
|
-
import { RemoveMessage } from "./index.
|
|
11
|
-
import { isSystemMessageChunk, isSystemMessage, SystemMessageChunk, SystemMessage } from "./index.
|
|
12
|
-
import { mapStoredMessagesToChatMessages, mapStoredMessageToChatMessage, mapChatMessagesToStoredMessages, iife, getBufferString, convertToChunk, collapseToolCallChunks, coerceMessageLikeToMessage } from "./index.
|
|
13
|
-
import { isAIMessageChunk, isAIMessage, AIMessageChunk, AIMessage } from "./index.
|
|
9
|
+
import { isHumanMessageChunk, isHumanMessage, HumanMessageChunk, HumanMessage } from "./index.es42.js";
|
|
10
|
+
import { RemoveMessage } from "./index.es46.js";
|
|
11
|
+
import { isSystemMessageChunk, isSystemMessage, SystemMessageChunk, SystemMessage } from "./index.es44.js";
|
|
12
|
+
import { mapStoredMessagesToChatMessages, mapStoredMessageToChatMessage, mapChatMessagesToStoredMessages, iife, getBufferString, convertToChunk, collapseToolCallChunks, coerceMessageLikeToMessage } from "./index.es47.js";
|
|
13
|
+
import { isAIMessageChunk, isAIMessage, AIMessageChunk, AIMessage } from "./index.es43.js";
|
|
14
14
|
import { trimMessages, mergeMessageRuns, filterMessages, defaultTextSplitter } from "./index.es58.js";
|
|
15
15
|
import { KNOWN_BLOCK_TYPES as KNOWN_BLOCK_TYPES$2 } from "./index.es59.js";
|
|
16
16
|
var messages_exports = {};
|
package/dist/index.es2.js
CHANGED
|
@@ -11,7 +11,7 @@ import ChatBody from "./index.es13.js";
|
|
|
11
11
|
import ChatButton from "./index.es14.js";
|
|
12
12
|
import ChatInput from "./index.es15.js";
|
|
13
13
|
function Sidebar(props) {
|
|
14
|
-
const { handleFileSelect, callThisOnSubmit, enableToolCallIndicator, header, inputFileAccept } = props;
|
|
14
|
+
const { handleFileSelect, callThisOnSubmit, enableToolCallIndicator, header, inputFileAccept, filePreview, s3_upload, preventSubmit } = props;
|
|
15
15
|
const [open, setOpen] = useState(false);
|
|
16
16
|
const [input, setInput] = useState("");
|
|
17
17
|
const { fileInput, setFileInput } = useFileProvider();
|
|
@@ -23,21 +23,34 @@ function Sidebar(props) {
|
|
|
23
23
|
}, [setMode]);
|
|
24
24
|
const defaultHandleSubmit = async (e) => {
|
|
25
25
|
e.preventDefault();
|
|
26
|
-
if (input.trim().length === 0 && fileInput.length === 0 || isLoading)
|
|
26
|
+
if (preventSubmit || input.trim().length === 0 && fileInput.length === 0 || isLoading)
|
|
27
27
|
return;
|
|
28
28
|
let latestFiles = fileInput;
|
|
29
29
|
if (callThisOnSubmit) {
|
|
30
30
|
const result = await callThisOnSubmit();
|
|
31
31
|
if (result && result.length > 0) latestFiles = result;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
let contentBlocks;
|
|
34
|
+
if (s3_upload) {
|
|
35
|
+
let messageText = input.trim();
|
|
36
|
+
if (latestFiles.length > 0) {
|
|
37
|
+
const fileNames = latestFiles.map((file) => file.fileName).join(", ");
|
|
38
|
+
const fileText = `file${latestFiles.length > 1 ? "s" : ""} uploaded: ${fileNames}`;
|
|
39
|
+
messageText = messageText ? `${fileText}
|
|
40
|
+
|
|
41
|
+
- ${messageText}` : fileText;
|
|
42
|
+
}
|
|
43
|
+
contentBlocks = [{ type: "text", text: messageText }];
|
|
44
|
+
} else {
|
|
45
|
+
contentBlocks = [
|
|
46
|
+
...input.trim().length > 0 ? [{ type: "text", text: input }] : [],
|
|
47
|
+
...latestFiles.map((file) => ({
|
|
48
|
+
type: "document",
|
|
49
|
+
...file,
|
|
50
|
+
cache_control: { type: "ephemeral" }
|
|
51
|
+
}))
|
|
52
|
+
];
|
|
53
|
+
}
|
|
41
54
|
const newHumanMessage = {
|
|
42
55
|
id: v4(),
|
|
43
56
|
type: "human",
|
|
@@ -128,7 +141,8 @@ function Sidebar(props) {
|
|
|
128
141
|
fileInput,
|
|
129
142
|
handleFileSelect: onFileSelect,
|
|
130
143
|
setFileInput,
|
|
131
|
-
onCancel: () => stream.stop?.()
|
|
144
|
+
onCancel: () => stream.stop?.(),
|
|
145
|
+
filePreview
|
|
132
146
|
}
|
|
133
147
|
) })
|
|
134
148
|
] })
|
package/dist/index.es2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es2.js","sources":["../src/pages/Sidebar/sidebar.tsx"],"sourcesContent":["import Suggestion from \"@/components/Suggestion\";\nimport { useFileProvider } from \"@/providers/FileProvider\";\nimport { useStreamContext } from \"@/providers/Stream\";\nimport { useThread } from \"@/providers/Thread\";\nimport type { ChatSidebarProps } from \"@/types/ChatProps\";\nimport type { FileInfo } from \"@/types/fileInput\";\nimport type { Message } from \"@langchain/langgraph-sdk\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { X } from \"lucide-react\";\nimport { useEffect, useState, type FormEvent } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport ChatBody from \"../../components/ChatBody\";\nimport ChatButton from \"../../components/ChatButton\";\nimport ChatInput from \"../../components/sidebar/ChatInput\";\n\n/**\n * Main sidebar chat interface component.\n * Displays a chat button that opens a sliding sidebar with full chat functionality.\n * \n * @param header - Custom header text for the chat sidebar (default: \"AI Assistant\")\n * @param handleFileSelect - Optional custom file selection handler\n * @param callThisOnSubmit - Optional callback invoked before message submission, can return updated file list\n * \n * @example\n * ```tsx\n * <Sidebar \n * header=\"My Custom AI\"\n * callThisOnSubmit={async () => {\n * // Upload files to your backend\n * return updatedFiles;\n * }}\n * />\n * ```\n */\nexport default function Sidebar(props: ChatSidebarProps) {\n\n const { handleFileSelect, callThisOnSubmit, enableToolCallIndicator, header, inputFileAccept } = props;\n const [open, setOpen] = useState(false);\n const [input, setInput] = useState(\"\");\n const { fileInput, setFileInput } = useFileProvider();\n\n const stream = useStreamContext();\n const isLoading = stream.isLoading;\n const { setMode } = useThread();\n\n // Set thread mode to single when using Sidebar\n useEffect(() => {\n setMode(\"single\");\n }, [setMode]);\n\n const defaultHandleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n\n if ((input.trim().length === 0 && fileInput.length === 0) || isLoading)\n return;\n\n // Call the custom upload and get the latest files\n let latestFiles: FileInfo[] = fileInput;\n if (callThisOnSubmit) {\n const result = await callThisOnSubmit();\n if (result && result.length > 0) latestFiles = result;\n }\n\n const contentBlocks = [\n ...(input.trim().length > 0 ? [{ type: \"text\", text: input }] : []),\n ...latestFiles.map((file) => ({\n type: \"document\" as const,\n ...file,\n cache_control: { type: \"ephemeral\" as const },\n })),\n ] as unknown as Message[\"content\"];\n\n const newHumanMessage: Message = {\n id: uuidv4(),\n type: \"human\",\n content: contentBlocks,\n };\n\n // Use the unified submitMessage function\n await stream.submitMessage(newHumanMessage);\n\n setInput(\"\");\n setFileInput([]);\n };\n\n const defaultHandleFileSelect = async (\n event: React.ChangeEvent<HTMLInputElement>\n ) => {\n const files = event.target.files;\n if (!files) return;\n\n // Convert files to base64 for sending\n const fileDetails: FileInfo[] = await Promise.all(\n Array.from(files).map(async (file) => {\n const base64Data = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n resolve(result.split(\",\")[1]); // Remove data:...;base64, prefix\n };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n\n return {\n fileName: file.name,\n fileType: file.type,\n file: file,\n fileData: base64Data, // Add this to your FileInfo type\n };\n })\n );\n\n setFileInput((prevFile) => [...prevFile, ...fileDetails]);\n };\n\n const onFileSelect = handleFileSelect || defaultHandleFileSelect;\n \n return (\n <>\n <AnimatePresence>\n {open && (\n <>\n {/* Overlay */}\n <motion.div\n className=\"fixed inset-0 z-40 bg-black/30\"\n onClick={() => setOpen(false)}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n />\n\n {/* Sidebar */}\n <motion.aside\n className=\"fixed right-0 top-0 z-50 h-screen w-[520px] bg-black flex flex-col text-white\"\n initial={{ x: \"100%\" }}\n animate={{ x: 0 }}\n exit={{ x: \"100%\" }}\n transition={{ type: \"spring\", stiffness: 260, damping: 30 }}\n >\n <div className=\"flex h-full flex-col\">\n <div className=\"flex border-b border-zinc-800 py-4 px-6 justify-between items-center\">\n <div className=\"flex items-center gap-3\">\n {header?.logoUrl && (\n // Render provided logo image if present\n <img\n src={header?.logoUrl}\n alt={header?.title ? `${header.title} logo` : \"AI Assistant logo\"}\n className=\"h-8 w-8 object-contain rounded-sm\"\n />\n )}\n <div className=\"text-start text-2xl font-bold\">{header?.title || \"AI Assistant\"}</div>\n </div>\n <X\n className=\"text-zinc-400 cursor-pointer\"\n onClick={() => setOpen(false)}\n />\n </div>\n\n <div className=\"flex-1 overflow-auto scrollbar-none\">\n <div className=\"p-4\">\n <ChatBody enableToolCallIndicator={enableToolCallIndicator} />\n </div>\n </div>\n <Suggestion />\n <div className=\"sticky bottom-0 border-t border-zinc-800 m-2\">\n <ChatInput\n input={input}\n inputFileAccept={inputFileAccept}\n setInput={setInput}\n handleSubmit={defaultHandleSubmit}\n isLoading={isLoading}\n fileInput={fileInput}\n handleFileSelect={onFileSelect}\n setFileInput={setFileInput}\n onCancel={() => stream.stop?.()}\n />\n </div>\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n\n <ChatButton isVisible={!open} setOpen={setOpen} />\n </>\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es2.js","sources":["../src/pages/Sidebar/sidebar.tsx"],"sourcesContent":["import Suggestion from \"@/components/Suggestion\";\nimport { useFileProvider } from \"@/providers/FileProvider\";\nimport { useStreamContext } from \"@/providers/Stream\";\nimport { useThread } from \"@/providers/Thread\";\nimport type { ChatSidebarProps } from \"@/types/ChatProps\";\nimport type { FileInfo } from \"@/types/fileInput\";\nimport type { Message } from \"@langchain/langgraph-sdk\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { X } from \"lucide-react\";\nimport { useEffect, useState, type FormEvent } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport ChatBody from \"../../components/ChatBody\";\nimport ChatButton from \"../../components/ChatButton\";\nimport ChatInput from \"../../components/sidebar/ChatInput\";\n\n/**\n * Main sidebar chat interface component.\n * Displays a chat button that opens a sliding sidebar with full chat functionality.\n * \n * @param header - Custom header text for the chat sidebar (default: \"AI Assistant\")\n * @param handleFileSelect - Optional custom file selection handler\n * @param callThisOnSubmit - Optional callback invoked before message submission, can return updated file list\n * @param preventSubmit - Optional boolean to prevent all submit actions when true\n * \n * @example\n * ```tsx\n * <Sidebar \n * header=\"My Custom AI\"\n * preventSubmit={true} // Disables all submit functionality\n * callThisOnSubmit={async () => {\n * // Upload files to your backend\n * return updatedFiles;\n * }}\n * />\n * ```\n */\nexport default function Sidebar(props: ChatSidebarProps) {\n\n const { handleFileSelect, callThisOnSubmit, enableToolCallIndicator, header, inputFileAccept, filePreview, s3_upload, preventSubmit } = props;\n const [open, setOpen] = useState(false);\n const [input, setInput] = useState(\"\");\n const { fileInput, setFileInput } = useFileProvider();\n\n const stream = useStreamContext();\n const isLoading = stream.isLoading;\n const { setMode } = useThread();\n\n // Set thread mode to single when using Sidebar\n useEffect(() => {\n setMode(\"single\");\n }, [setMode]);\n\n const defaultHandleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n\n if (preventSubmit || (input.trim().length === 0 && fileInput.length === 0) || isLoading)\n return;\n\n // Call the custom upload and get the latest files\n let latestFiles: FileInfo[] = fileInput;\n if (callThisOnSubmit) {\n const result = await callThisOnSubmit();\n if (result && result.length > 0) latestFiles = result;\n }\n\n // Create content blocks based on upload type\n let contentBlocks: any;\n if (s3_upload) {\n // For S3 uploads, send text message\n let messageText = input.trim();\n if (latestFiles.length > 0) {\n const fileNames = latestFiles.map(file => file.fileName).join(\", \");\n const fileText = `file${latestFiles.length > 1 ? 's' : ''} uploaded: ${fileNames}`;\n messageText = messageText ? `${fileText}\\n\\n - ${messageText}` : fileText;\n }\n contentBlocks = [{ type: \"text\", text: messageText }];\n } else {\n contentBlocks = [\n ...(input.trim().length > 0 ? [{ type: \"text\", text: input }] : []),\n ...latestFiles.map((file) => ({\n type: \"document\" as const,\n ...file,\n cache_control: { type: \"ephemeral\" as const },\n })),\n ];\n }\n\n const newHumanMessage: Message = {\n id: uuidv4(),\n type: \"human\",\n content: contentBlocks,\n };\n\n // Use the unified submitMessage function\n await stream.submitMessage(newHumanMessage);\n\n setInput(\"\");\n setFileInput([]);\n };\n\n const defaultHandleFileSelect = async (\n event: React.ChangeEvent<HTMLInputElement>\n ) => {\n const files = event.target.files;\n if (!files) return;\n\n // Convert files to base64 for sending\n const fileDetails: FileInfo[] = await Promise.all(\n Array.from(files).map(async (file) => {\n const base64Data = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n resolve(result.split(\",\")[1]); // Remove data:...;base64, prefix\n };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n\n return {\n fileName: file.name,\n fileType: file.type,\n file: file,\n fileData: base64Data, // Add this to your FileInfo type\n };\n })\n );\n\n setFileInput((prevFile) => [...prevFile, ...fileDetails]);\n };\n\n const onFileSelect = handleFileSelect || defaultHandleFileSelect;\n \n return (\n <>\n <AnimatePresence>\n {open && (\n <>\n {/* Overlay */}\n <motion.div\n className=\"fixed inset-0 z-40 bg-black/30\"\n onClick={() => setOpen(false)}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n />\n\n {/* Sidebar */}\n <motion.aside\n className=\"fixed right-0 top-0 z-50 h-screen w-[520px] bg-black flex flex-col text-white\"\n initial={{ x: \"100%\" }}\n animate={{ x: 0 }}\n exit={{ x: \"100%\" }}\n transition={{ type: \"spring\", stiffness: 260, damping: 30 }}\n >\n <div className=\"flex h-full flex-col\">\n <div className=\"flex border-b border-zinc-800 py-4 px-6 justify-between items-center\">\n <div className=\"flex items-center gap-3\">\n {header?.logoUrl && (\n // Render provided logo image if present\n <img\n src={header?.logoUrl}\n alt={header?.title ? `${header.title} logo` : \"AI Assistant logo\"}\n className=\"h-8 w-8 object-contain rounded-sm\"\n />\n )}\n <div className=\"text-start text-2xl font-bold\">{header?.title || \"AI Assistant\"}</div>\n </div>\n <X\n className=\"text-zinc-400 cursor-pointer\"\n onClick={() => setOpen(false)}\n />\n </div>\n\n <div className=\"flex-1 overflow-auto scrollbar-none\">\n <div className=\"p-4\">\n <ChatBody enableToolCallIndicator={enableToolCallIndicator} />\n </div>\n </div>\n <Suggestion />\n <div className=\"sticky bottom-0 border-t border-zinc-800 m-2\">\n <ChatInput\n input={input}\n inputFileAccept={inputFileAccept}\n setInput={setInput}\n handleSubmit={defaultHandleSubmit}\n isLoading={isLoading}\n fileInput={fileInput}\n handleFileSelect={onFileSelect}\n setFileInput={setFileInput}\n onCancel={() => stream.stop?.()}\n filePreview={filePreview}\n />\n </div>\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n\n <ChatButton isVisible={!open} setOpen={setOpen} />\n </>\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
|
package/dist/index.es20.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { bootstrapUiContext } from "./index.
|
|
2
|
-
import { LoadExternalComponent, useStreamContext } from "./index.
|
|
1
|
+
import { bootstrapUiContext } from "./index.es29.js";
|
|
2
|
+
import { LoadExternalComponent, useStreamContext } from "./index.es29.js";
|
|
3
3
|
bootstrapUiContext();
|
|
4
4
|
export {
|
|
5
5
|
LoadExternalComponent,
|
package/dist/index.es22.js
CHANGED
|
@@ -1,125 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import * as JsxRuntime from "react/jsx-runtime";
|
|
6
|
-
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
7
|
-
const UseStreamContext = React.createContext(null);
|
|
8
|
-
function useStreamContext() {
|
|
9
|
-
const ctx = React.useContext(UseStreamContext);
|
|
10
|
-
if (!ctx) throw new Error("useStreamContext must be used within a LoadExternalComponent");
|
|
11
|
-
return new Proxy(ctx, { get(target, prop) {
|
|
12
|
-
if (prop === "meta") return target.meta;
|
|
13
|
-
return target.stream[prop];
|
|
14
|
-
} });
|
|
1
|
+
function getContentString(content) {
|
|
2
|
+
if (typeof content === "string") return content;
|
|
3
|
+
const texts = content.filter((c) => c.type === "text").map((c) => c.text);
|
|
4
|
+
return texts.join(" ");
|
|
15
5
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.cache[shadowRootId] = {
|
|
22
|
-
comp,
|
|
23
|
-
target: targetElement
|
|
24
|
-
};
|
|
25
|
-
this.callbacks[shadowRootId]?.forEach((c) => c(comp, targetElement));
|
|
26
|
-
}
|
|
27
|
-
getBoundStore(shadowRootId) {
|
|
28
|
-
this.boundCache[shadowRootId] ??= {
|
|
29
|
-
subscribe: (onStoreChange) => {
|
|
30
|
-
this.callbacks[shadowRootId] ??= [];
|
|
31
|
-
this.callbacks[shadowRootId].push(onStoreChange);
|
|
32
|
-
return () => {
|
|
33
|
-
this.callbacks[shadowRootId] = this.callbacks[shadowRootId].filter((c) => c !== onStoreChange);
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
getSnapshot: () => this.cache[shadowRootId]
|
|
37
|
-
};
|
|
38
|
-
return this.boundCache[shadowRootId];
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
const COMPONENT_STORE = new ComponentStore();
|
|
42
|
-
const EXT_STORE_SYMBOL = /* @__PURE__ */ Symbol.for("LGUI_EXT_STORE");
|
|
43
|
-
const REQUIRE_SYMBOL = /* @__PURE__ */ Symbol.for("LGUI_REQUIRE");
|
|
44
|
-
const REQUIRE_EXTRA_SYMBOL = /* @__PURE__ */ Symbol.for("LGUI_REQUIRE_EXTRA");
|
|
45
|
-
const isIterable = (value) => value != null && typeof value === "object" && Symbol.iterator in value;
|
|
46
|
-
const isPromise = (value) => value != null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
47
|
-
const isReactNode = (value) => {
|
|
48
|
-
if (React.isValidElement(value)) return true;
|
|
49
|
-
if (value == null) return true;
|
|
50
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") return true;
|
|
51
|
-
if (isIterable(value)) return true;
|
|
52
|
-
if (isPromise(value)) return true;
|
|
53
|
-
return false;
|
|
54
|
-
};
|
|
55
|
-
function LoadExternalComponent({ stream, namespace, message, meta, fallback, components, ...props }) {
|
|
56
|
-
const ref = React.useRef(null);
|
|
57
|
-
const shadowRootId = `child-shadow-${React.useId()}`;
|
|
58
|
-
const store = React.useMemo(() => COMPONENT_STORE.getBoundStore(shadowRootId), [shadowRootId]);
|
|
59
|
-
const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
60
|
-
const clientComponent = components?.[message.name];
|
|
61
|
-
const hasClientComponent = clientComponent != null;
|
|
62
|
-
let fallbackComponent = null;
|
|
63
|
-
if (isReactNode(fallback)) fallbackComponent = fallback;
|
|
64
|
-
else if (typeof fallback === "object" && fallback != null) fallbackComponent = fallback?.[message.name];
|
|
65
|
-
const uiNamespace = namespace ?? stream.assistantId;
|
|
66
|
-
const uiClient = stream.client["~ui"];
|
|
67
|
-
React.useEffect(() => {
|
|
68
|
-
if (hasClientComponent) return;
|
|
69
|
-
uiClient.getComponent(uiNamespace, message.name).then((html) => {
|
|
70
|
-
const dom = ref.current;
|
|
71
|
-
if (!dom) return;
|
|
72
|
-
const root = dom.shadowRoot ?? dom.attachShadow({ mode: "open" });
|
|
73
|
-
const fragment = document.createRange().createContextualFragment(html.replace("{{shadowRootId}}", shadowRootId));
|
|
74
|
-
root.appendChild(fragment);
|
|
75
|
-
});
|
|
76
|
-
}, [
|
|
77
|
-
uiClient,
|
|
78
|
-
uiNamespace,
|
|
79
|
-
message.name,
|
|
80
|
-
shadowRootId,
|
|
81
|
-
hasClientComponent
|
|
82
|
-
]);
|
|
83
|
-
if (hasClientComponent) return /* @__PURE__ */ jsx(UseStreamContext.Provider, {
|
|
84
|
-
value: {
|
|
85
|
-
stream,
|
|
86
|
-
meta
|
|
87
|
-
},
|
|
88
|
-
children: React.createElement(clientComponent, message.props)
|
|
89
|
-
});
|
|
90
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
91
|
-
id: shadowRootId,
|
|
92
|
-
ref,
|
|
93
|
-
...props
|
|
94
|
-
}), /* @__PURE__ */ jsx(UseStreamContext.Provider, {
|
|
95
|
-
value: {
|
|
96
|
-
stream,
|
|
97
|
-
meta
|
|
98
|
-
},
|
|
99
|
-
children: state?.target != null ? ReactDOM.createPortal(React.createElement(state.comp, message.props), state.target) : fallbackComponent
|
|
100
|
-
})] });
|
|
6
|
+
function isAIMessage(message) {
|
|
7
|
+
return message.type === "ai";
|
|
8
|
+
}
|
|
9
|
+
function isAiWithToolCalls(message) {
|
|
10
|
+
return isAIMessage(message) && message.tool_calls && message.tool_calls.length > 0;
|
|
101
11
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
window[EXT_STORE_SYMBOL] = COMPONENT_STORE;
|
|
105
|
-
window[REQUIRE_SYMBOL] = (name) => {
|
|
106
|
-
if (name === "react") return React;
|
|
107
|
-
if (name === "react-dom") return ReactDOM;
|
|
108
|
-
if (name === "react/jsx-runtime") return JsxRuntime;
|
|
109
|
-
if (name === "@langchain/langgraph-sdk/react") return { useStream };
|
|
110
|
-
if (name === "@langchain/langgraph-sdk/react-ui") return {
|
|
111
|
-
useStreamContext,
|
|
112
|
-
LoadExternalComponent: () => {
|
|
113
|
-
throw new Error("Nesting LoadExternalComponent is not supported");
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
if (window[REQUIRE_EXTRA_SYMBOL] != null && typeof window[REQUIRE_EXTRA_SYMBOL] === "object" && name in window[REQUIRE_EXTRA_SYMBOL]) return window[REQUIRE_EXTRA_SYMBOL][name];
|
|
117
|
-
throw new Error(`Unknown module...: ${name}`);
|
|
118
|
-
};
|
|
12
|
+
function isToolMessage(message) {
|
|
13
|
+
return message.type === "tool";
|
|
119
14
|
}
|
|
120
15
|
export {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
16
|
+
getContentString,
|
|
17
|
+
isAIMessage,
|
|
18
|
+
isAiWithToolCalls,
|
|
19
|
+
isToolMessage
|
|
124
20
|
};
|
|
125
21
|
//# sourceMappingURL=index.es22.js.map
|
package/dist/index.es22.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es22.js","sources":["../
|
|
1
|
+
{"version":3,"file":"index.es22.js","sources":["../src/utils/utils.ts"],"sourcesContent":["import type { AIMessage, Message } from \"@langchain/langgraph-sdk\";\n\n/**\n * Extracts a string summary from a message's content, supporting multimodal (text, image, file, etc.).\n * - If text is present, returns the joined text.\n * - If not, returns a label for the first non-text modality (e.g., 'Image', 'Other').\n * - If unknown, returns 'Multimodal message'.\n */\nexport function getContentString(content: Message[\"content\"]): string {\n if (typeof content === \"string\") return content;\n const texts = content\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text);\n return texts.join(\" \");\n}\n\nexport function isAIMessage(message: Message): message is AIMessage {\n return message.type === \"ai\";\n}\n\nexport function isAiWithToolCalls(message: Message) {\n return (\n isAIMessage(message) && message.tool_calls && message.tool_calls.length > 0\n );\n}\n\nexport function isToolMessage(message: Message) {\n return message.type === \"tool\";\n}\n"],"names":[],"mappings":"AAQO,SAAS,iBAAiB,SAAqC;AACpE,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,QAAM,QAAQ,QACX,OAAO,CAAC,MAA2C,EAAE,SAAS,MAAM,EACpE,IAAI,CAAC,MAAM,EAAE,IAAI;AACpB,SAAO,MAAM,KAAK,GAAG;AACvB;AAEO,SAAS,YAAY,SAAwC;AAClE,SAAO,QAAQ,SAAS;AAC1B;AAEO,SAAS,kBAAkB,SAAkB;AAClD,SACE,YAAY,OAAO,KAAK,QAAQ,cAAc,QAAQ,WAAW,SAAS;AAE9E;AAEO,SAAS,cAAc,SAAkB;AAC9C,SAAO,QAAQ,SAAS;AAC1B;"}
|