diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index 7137e23b6..04a4c3053 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -6,7 +6,12 @@
"main": "src/index.sdk.ts",
"types": "src/index.sdk.ts",
"dependencies": {
+ "@ai-sdk/openai": "^1.3.22",
"@ant-design/icons": "^5.3.0",
+ "@assistant-ui/react": "^0.10.24",
+ "@assistant-ui/react-ai-sdk": "^0.10.14",
+ "@assistant-ui/react-markdown": "^0.10.5",
+ "@assistant-ui/styles": "^0.1.13",
"@bany/curl-to-json": "^1.2.8",
"@codemirror/autocomplete": "^6.11.1",
"@codemirror/commands": "^6.3.2",
@@ -28,6 +33,8 @@
"@jsonforms/core": "^3.5.1",
"@lottiefiles/dotlottie-react": "^0.13.0",
"@manaflair/redux-batch": "^1.0.0",
+ "@radix-ui/react-slot": "^1.2.3",
+ "@radix-ui/react-tooltip": "^1.2.7",
"@rjsf/antd": "^5.24.9",
"@rjsf/core": "^5.24.9",
"@rjsf/utils": "^5.24.9",
@@ -37,11 +44,13 @@
"@types/react-signature-canvas": "^1.0.2",
"@types/react-test-renderer": "^18.0.0",
"@types/react-virtualized": "^9.21.21",
+ "ai": "^4.3.16",
"alasql": "^4.6.6",
"animate.css": "^4.1.1",
"antd": "^5.25.2",
"axios": "^1.7.7",
"buffer": "^6.0.3",
+ "class-variance-authority": "^0.7.1",
"clsx": "^2.0.0",
"cnchar": "^3.2.4",
"coolshapes-react": "lowcoder-org/coolshapes-react",
@@ -61,6 +70,7 @@
"loglevel": "^1.8.0",
"lowcoder-core": "workspace:^",
"lowcoder-design": "workspace:^",
+ "lucide-react": "^0.525.0",
"mime": "^3.0.0",
"moment": "^2.29.4",
"numbro": "^2.3.6",
@@ -98,7 +108,7 @@
"regenerator-runtime": "^0.13.9",
"rehype-raw": "^6.1.1",
"rehype-sanitize": "^5.0.1",
- "remark-gfm": "^4.0.0",
+ "remark-gfm": "^4.0.1",
"resize-observer-polyfill": "^1.5.1",
"simplebar-react": "^3.2.4",
"sql-formatter": "^8.2.0",
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/chatComp.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/chatComp.tsx
new file mode 100644
index 000000000..75de96494
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/chatComp.tsx
@@ -0,0 +1,19 @@
+// client/packages/lowcoder/src/comps/comps/chatComp/chatComp.tsx
+import { UICompBuilder } from "comps/generators";
+import { NameConfig, withExposingConfigs } from "comps/generators/withExposing";
+import { chatChildrenMap } from "./chatCompTypes";
+import { ChatView } from "./chatView";
+import { ChatPropertyView } from "./chatPropertyView";
+
+// Build the component
+const ChatTmpComp = new UICompBuilder(
+ chatChildrenMap,
+ (props) =>
+)
+ .setPropertyViewFn((children) => )
+ .build();
+
+// Export the component
+export const ChatComp = withExposingConfigs(ChatTmpComp, [
+ new NameConfig("text", "Chat component text"),
+]);
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/chatCompTypes.ts b/client/packages/lowcoder/src/comps/comps/chatComp/chatCompTypes.ts
new file mode 100644
index 000000000..79ba4c80d
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/chatCompTypes.ts
@@ -0,0 +1,32 @@
+// client/packages/lowcoder/src/comps/comps/chatComp/chatCompTypes.ts
+import { StringControl, NumberControl } from "comps/controls/codeControl";
+import { withDefault } from "comps/generators";
+import { BoolControl } from "comps/controls/boolControl";
+import { dropdownControl } from "comps/controls/dropdownControl";
+import QuerySelectControl from "comps/controls/querySelectControl";
+
+// Model type dropdown options
+const ModelTypeOptions = [
+ { label: "Direct LLM", value: "direct-llm" },
+ { label: "n8n Workflow", value: "n8n" },
+] as const;
+
+export const chatChildrenMap = {
+ text: withDefault(StringControl, "Chat Component Placeholder"),
+ chatQuery: QuerySelectControl,
+ modelType: dropdownControl(ModelTypeOptions, "direct-llm"),
+ streaming: BoolControl.DEFAULT_TRUE,
+ systemPrompt: withDefault(StringControl, "You are a helpful assistant."),
+ agent: BoolControl,
+ maxInteractions: withDefault(NumberControl, 10),
+};
+
+export type ChatCompProps = {
+ text: string;
+ chatQuery: string;
+ modelType: string;
+ streaming: boolean;
+ systemPrompt: string;
+ agent: boolean;
+ maxInteractions: number;
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/chatPropertyView.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/chatPropertyView.tsx
new file mode 100644
index 000000000..b4f42c8e1
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/chatPropertyView.tsx
@@ -0,0 +1,28 @@
+// client/packages/lowcoder/src/comps/comps/chatComp/chatPropertyView.tsx
+import React from "react";
+import { Section, sectionNames } from "lowcoder-design";
+
+export const ChatPropertyView = React.memo((props: any) => {
+ const { children } = props;
+
+ return (
+
+ {children.text.propertyView({ label: "Text" })}
+ {children.chatQuery.propertyView({ label: "Chat Query" })}
+ {children.modelType.propertyView({ label: "Model Type" })}
+ {children.streaming.propertyView({ label: "Enable Streaming" })}
+ {children.systemPrompt.propertyView({
+ label: "System Prompt",
+ placeholder: "Enter system prompt...",
+ enableSpellCheck: false,
+ })}
+ {children.agent.propertyView({ label: "Enable Agent Mode" })}
+ {children.maxInteractions.propertyView({
+ label: "Max Interactions",
+ placeholder: "10",
+ })}
+
+ );
+});
+
+ChatPropertyView.displayName = 'ChatPropertyView';
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx
new file mode 100644
index 000000000..07383b48a
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx
@@ -0,0 +1,13 @@
+// client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx
+import React from "react";
+import { ChatCompProps } from "./chatCompTypes";
+import { ChatApp } from "./components/ChatApp";
+
+import "@assistant-ui/styles/index.css";
+import "@assistant-ui/styles/markdown.css";
+
+export const ChatView = React.memo((props: ChatCompProps) => {
+ return ;
+});
+
+ChatView.displayName = 'ChatView';
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatApp.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatApp.tsx
new file mode 100644
index 000000000..e87ed8585
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatApp.tsx
@@ -0,0 +1,10 @@
+import { ChatProvider } from "./context/ChatContext";
+import { ChatMain } from "./ChatMain";
+
+export function ChatApp() {
+ return (
+
+
+
+ );
+}
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatMain.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatMain.tsx
new file mode 100644
index 000000000..d0e151d88
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/ChatMain.tsx
@@ -0,0 +1,231 @@
+import React, { useState } from "react";
+import {
+ useExternalStoreRuntime,
+ ThreadMessageLike,
+ AppendMessage,
+ AssistantRuntimeProvider,
+ ExternalStoreThreadListAdapter,
+} from "@assistant-ui/react";
+import { Thread } from "./assistant-ui/thread";
+import { ThreadList } from "./assistant-ui/thread-list";
+import {
+ useChatContext,
+ MyMessage,
+ ThreadData,
+ RegularThreadData,
+ ArchivedThreadData
+} from "./context/ChatContext";
+import styled from "styled-components";
+
+const ChatContainer = styled.div`
+ display: flex;
+ height: 500px;
+
+ .aui-thread-list-root {
+ width: 250px;
+ background-color: #fff;
+ padding: 10px;
+ }
+
+ .aui-thread-root {
+ flex: 1;
+ background-color: #f9fafb;
+ }
+
+ .aui-thread-list-item {
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+
+ &[data-active="true"] {
+ background-color: #dbeafe;
+ border: 1px solid #bfdbfe;
+ }
+ }
+`;
+
+const generateId = () => Math.random().toString(36).substr(2, 9);
+
+const callYourAPI = async (text: string) => {
+ // Simulate API delay
+ await new Promise(resolve => setTimeout(resolve, 1500));
+
+ // Simple responses
+ return {
+ content: "This is a mock response from your backend. You typed: " + text
+ };
+};
+
+export function ChatMain() {
+ const { state, actions } = useChatContext();
+ const [isRunning, setIsRunning] = useState(false);
+
+ console.log("STATE", state);
+
+ // Get messages for current thread
+ const currentMessages = actions.getCurrentMessages();
+
+ // Convert custom format to ThreadMessageLike
+ const convertMessage = (message: MyMessage): ThreadMessageLike => ({
+ role: message.role,
+ content: [{ type: "text", text: message.text }],
+ id: message.id,
+ createdAt: new Date(message.timestamp),
+ });
+
+ const onNew = async (message: AppendMessage) => {
+ // Extract text from AppendMessage content array
+ if (message.content.length !== 1 || message.content[0]?.type !== "text") {
+ throw new Error("Only text content is supported");
+ }
+
+ // Add user message in custom format
+ const userMessage: MyMessage = {
+ id: generateId(),
+ role: "user",
+ text: message.content[0].text,
+ timestamp: Date.now(),
+ };
+
+ // Update current thread with new user message
+ await actions.addMessage(state.currentThreadId, userMessage);
+ setIsRunning(true);
+
+ try {
+ // Call mock API
+ const response = await callYourAPI(userMessage.text);
+
+ const assistantMessage: MyMessage = {
+ id: generateId(),
+ role: "assistant",
+ text: response.content,
+ timestamp: Date.now(),
+ };
+
+ // Update current thread with assistant response
+ await actions.addMessage(state.currentThreadId, assistantMessage);
+ } catch (error) {
+ // Handle errors gracefully
+ const errorMessage: MyMessage = {
+ id: generateId(),
+ role: "assistant",
+ text: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,
+ timestamp: Date.now(),
+ };
+
+ await actions.addMessage(state.currentThreadId, errorMessage);
+ } finally {
+ setIsRunning(false);
+ }
+ };
+
+ // Add onEdit functionality
+ const onEdit = async (message: AppendMessage) => {
+ // Extract text from AppendMessage content array
+ if (message.content.length !== 1 || message.content[0]?.type !== "text") {
+ throw new Error("Only text content is supported");
+ }
+
+ // Find the index where to insert the edited message
+ const index = currentMessages.findIndex((m) => m.id === message.parentId) + 1;
+
+ // Keep messages up to the parent
+ const newMessages = [...currentMessages.slice(0, index)];
+
+ // Add the edited message in custom format
+ const editedMessage: MyMessage = {
+ id: generateId(),
+ role: "user",
+ text: message.content[0].text,
+ timestamp: Date.now(),
+ };
+ newMessages.push(editedMessage);
+
+ // Update messages using the new context action
+ await actions.updateMessages(state.currentThreadId, newMessages);
+ setIsRunning(true);
+
+ try {
+ // Generate new response
+ const response = await callYourAPI(editedMessage.text);
+
+ const assistantMessage: MyMessage = {
+ id: generateId(),
+ role: "assistant",
+ text: response.content,
+ timestamp: Date.now(),
+ };
+
+ newMessages.push(assistantMessage);
+ await actions.updateMessages(state.currentThreadId, newMessages);
+ } catch (error) {
+ // Handle errors gracefully
+ const errorMessage: MyMessage = {
+ id: generateId(),
+ role: "assistant",
+ text: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,
+ timestamp: Date.now(),
+ };
+
+ newMessages.push(errorMessage);
+ await actions.updateMessages(state.currentThreadId, newMessages);
+ } finally {
+ setIsRunning(false);
+ }
+ };
+
+ // Thread list adapter for managing multiple threads
+ const threadListAdapter: ExternalStoreThreadListAdapter = {
+ threadId: state.currentThreadId,
+ threads: state.threadList.filter((t): t is RegularThreadData => t.status === "regular"),
+ archivedThreads: state.threadList.filter((t): t is ArchivedThreadData => t.status === "archived"),
+
+ onSwitchToNewThread: async () => {
+ const threadId = await actions.createThread("New Chat");
+ actions.setCurrentThread(threadId);
+ },
+
+ onSwitchToThread: (threadId) => {
+ actions.setCurrentThread(threadId);
+ },
+
+ onRename: async (threadId, newTitle) => {
+ await actions.updateThread(threadId, { title: newTitle });
+ },
+
+ onArchive: async (threadId) => {
+ await actions.updateThread(threadId, { status: "archived" });
+ },
+
+ onDelete: async (threadId) => {
+ await actions.deleteThread(threadId);
+ },
+ };
+
+ const runtime = useExternalStoreRuntime({
+ messages: currentMessages,
+ setMessages: (messages) => {
+ actions.updateMessages(state.currentThreadId, messages);
+ },
+ convertMessage,
+ isRunning,
+ onNew,
+ onEdit,
+ adapters: {
+ threadList: threadListAdapter,
+ },
+ });
+
+ if (!state.isInitialized) {
+ return
Loading...
;
+ }
+
+ return (
+
+
+
+
+
+
+ );
+}
+
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/markdown-text.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/markdown-text.tsx
new file mode 100644
index 000000000..bbf2e5648
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/markdown-text.tsx
@@ -0,0 +1,130 @@
+import "@assistant-ui/react-markdown/styles/dot.css";
+
+import {
+ CodeHeaderProps,
+ MarkdownTextPrimitive,
+ unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
+ useIsMarkdownCodeBlock,
+} from "@assistant-ui/react-markdown";
+import remarkGfm from "remark-gfm";
+import { FC, memo, useState } from "react";
+import { CheckIcon, CopyIcon } from "lucide-react";
+
+import { TooltipIconButton } from "./tooltip-icon-button";
+import { cn } from "../../utils/cn";
+
+const MarkdownTextImpl = () => {
+ return (
+
+ );
+};
+
+export const MarkdownText = memo(MarkdownTextImpl);
+
+const CodeHeader: FC = ({ language, code }) => {
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
+ const onCopy = () => {
+ if (!code || isCopied) return;
+ copyToClipboard(code);
+ };
+
+ return (
+
+ {language}
+
+ {!isCopied && }
+ {isCopied && }
+
+
+ );
+};
+
+const useCopyToClipboard = ({
+ copiedDuration = 3000,
+}: {
+ copiedDuration?: number;
+} = {}) => {
+ const [isCopied, setIsCopied] = useState(false);
+
+ const copyToClipboard = (value: string) => {
+ if (!value) return;
+
+ navigator.clipboard.writeText(value).then(() => {
+ setIsCopied(true);
+ setTimeout(() => setIsCopied(false), copiedDuration);
+ });
+ };
+
+ return { isCopied, copyToClipboard };
+};
+
+const defaultComponents = memoizeMarkdownComponents({
+ h1: ({ className, ...props }) => (
+
+ ),
+ h2: ({ className, ...props }) => (
+
+ ),
+ h3: ({ className, ...props }) => (
+
+ ),
+ h4: ({ className, ...props }) => (
+
+ ),
+ h5: ({ className, ...props }) => (
+
+ ),
+ h6: ({ className, ...props }) => (
+
+ ),
+ p: ({ className, ...props }) => (
+
+ ),
+ a: ({ className, ...props }) => (
+
+ ),
+ blockquote: ({ className, ...props }) => (
+
+ ),
+ ul: ({ className, ...props }) => (
+
+ ),
+ ol: ({ className, ...props }) => (
+
+ ),
+ hr: ({ className, ...props }) => (
+
+ ),
+ table: ({ className, ...props }) => (
+
+ ),
+ th: ({ className, ...props }) => (
+ |
+ ),
+ td: ({ className, ...props }) => (
+ |
+ ),
+ tr: ({ className, ...props }) => (
+
+ ),
+ sup: ({ className, ...props }) => (
+
+ ),
+ pre: ({ className, ...props }) => (
+
+ ),
+ code: function Code({ className, ...props }) {
+ const isCodeBlock = useIsMarkdownCodeBlock();
+ return (
+
+ );
+ },
+ CodeHeader,
+});
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread-list.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread-list.tsx
new file mode 100644
index 000000000..bb01b7d5e
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread-list.tsx
@@ -0,0 +1,113 @@
+import type { FC } from "react";
+import {
+ ThreadListItemPrimitive,
+ ThreadListPrimitive,
+} from "@assistant-ui/react";
+import { PencilIcon, PlusIcon, Trash2Icon } from "lucide-react";
+
+import { TooltipIconButton } from "./tooltip-icon-button";
+import { useThreadListItemRuntime } from "@assistant-ui/react";
+import { Button } from "antd";
+
+import styled from "styled-components";
+import { useChatContext } from "../context/ChatContext";
+
+const StyledPrimaryButton = styled(Button)`
+ padding: 20px;
+ margin-bottom: 20px;
+`;
+
+
+export const ThreadList: FC = () => {
+ return (
+
+
+
+
+ );
+};
+
+const ThreadListNew: FC = () => {
+ return (
+
+ }>
+ New Thread
+
+
+ );
+};
+
+const ThreadListItems: FC = () => {
+ return ;
+};
+
+const ThreadListItem: FC = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const ThreadListItemTitle: FC = () => {
+
+ return (
+
+
+
+ );
+};
+
+const ThreadListItemDelete: FC = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+
+const ThreadListItemRename: FC = () => {
+ const runtime = useThreadListItemRuntime();
+
+ const handleClick = async () => {
+ // runtime doesn't expose a direct `title` prop; read it from its state
+ let current = "";
+ try {
+ // getState is part of the public runtime surface
+ current = (runtime.getState?.() as any)?.title ?? "";
+ } catch {
+ // fallback – generate a title if the runtime provides a helper
+ if (typeof (runtime as any).generateTitle === "function") {
+ // generateTitle(threadId) in older builds, generateTitle() in newer ones
+ current = (runtime as any).generateTitle((runtime as any).threadId ?? undefined);
+ }
+ }
+
+ const next = prompt("Rename thread", current)?.trim();
+ if (next && next !== current) {
+ await runtime.rename(next);
+ }
+ };
+
+ return (
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread.tsx
new file mode 100644
index 000000000..ae3749fb7
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread.tsx
@@ -0,0 +1,283 @@
+import {
+ ActionBarPrimitive,
+ BranchPickerPrimitive,
+ ComposerPrimitive,
+ MessagePrimitive,
+ ThreadPrimitive,
+ } from "@assistant-ui/react";
+ import type { FC } from "react";
+ import {
+ ArrowDownIcon,
+ CheckIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ CopyIcon,
+ PencilIcon,
+ RefreshCwIcon,
+ SendHorizontalIcon,
+ } from "lucide-react";
+ import { cn } from "../../utils/cn";
+
+ import { Button } from "../ui/button";
+ import { MarkdownText } from "./markdown-text";
+ import { TooltipIconButton } from "./tooltip-icon-button";
+
+ export const Thread: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ const ThreadScrollToBottom: FC = () => {
+ return (
+
+
+
+
+
+ );
+ };
+
+ const ThreadWelcome: FC = () => {
+ return (
+
+
+
+
+ How can I help you today?
+
+
+
+
+
+ );
+ };
+
+ const ThreadWelcomeSuggestions: FC = () => {
+ return (
+
+
+
+ What is the weather in Tokyo?
+
+
+
+
+ What is assistant-ui?
+
+
+
+ );
+ };
+
+ const Composer: FC = () => {
+ return (
+
+
+
+
+ );
+ };
+
+ const ComposerAction: FC = () => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+ };
+
+ const UserMessage: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ const UserActionBar: FC = () => {
+ return (
+
+
+
+
+
+
+
+ );
+ };
+
+ const EditComposer: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ const AssistantMessage: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ const AssistantActionBar: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ const BranchPicker: FC = ({
+ className,
+ ...rest
+ }) => {
+ return (
+
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+ );
+ };
+
+ const CircleStopIcon = () => {
+ return (
+
+ );
+ };
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/tooltip-icon-button.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/tooltip-icon-button.tsx
new file mode 100644
index 000000000..d2434babf
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/tooltip-icon-button.tsx
@@ -0,0 +1,42 @@
+import { ComponentPropsWithoutRef, forwardRef } from "react";
+
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "../ui/tooltip";
+import { Button } from "../ui/button";
+import { cn } from "../../utils/cn";
+
+export type TooltipIconButtonProps = ComponentPropsWithoutRef & {
+ tooltip: string;
+ side?: "top" | "bottom" | "left" | "right";
+};
+
+export const TooltipIconButton = forwardRef<
+ HTMLButtonElement,
+ TooltipIconButtonProps
+>(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
+ return (
+
+
+
+
+
+ {tooltip}
+
+
+ );
+});
+
+TooltipIconButton.displayName = "TooltipIconButton";
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/context/ChatContext.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/context/ChatContext.tsx
new file mode 100644
index 000000000..41ef892af
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/context/ChatContext.tsx
@@ -0,0 +1,378 @@
+import React, { createContext, useContext, useReducer, useEffect, ReactNode } from "react";
+import { chatStorage, ThreadData as StoredThreadData } from "../../utils/chatStorage";
+
+// Define thread-specific message type
+export interface MyMessage {
+ id: string;
+ role: "user" | "assistant";
+ text: string;
+ timestamp: number;
+}
+
+// Thread data interfaces
+export interface RegularThreadData {
+ threadId: string;
+ status: "regular";
+ title: string;
+}
+
+export interface ArchivedThreadData {
+ threadId: string;
+ status: "archived";
+ title: string;
+}
+
+export type ThreadData = RegularThreadData | ArchivedThreadData;
+
+// Chat state interface
+interface ChatState {
+ isInitialized: boolean;
+ isLoading: boolean;
+ currentThreadId: string;
+ threadList: ThreadData[];
+ threads: Map;
+ lastSaved: number; // Timestamp for tracking when data was last saved
+}
+
+// Action types
+type ChatAction =
+ | { type: "INITIALIZE_START" }
+ | { type: "INITIALIZE_SUCCESS"; threadList: ThreadData[]; threads: Map; currentThreadId: string }
+ | { type: "INITIALIZE_ERROR" }
+ | { type: "SET_CURRENT_THREAD"; threadId: string }
+ | { type: "ADD_THREAD"; thread: ThreadData }
+ | { type: "UPDATE_THREAD"; threadId: string; updates: Partial }
+ | { type: "DELETE_THREAD"; threadId: string }
+ | { type: "SET_MESSAGES"; threadId: string; messages: MyMessage[] }
+ | { type: "ADD_MESSAGE"; threadId: string; message: MyMessage }
+ | { type: "UPDATE_MESSAGES"; threadId: string; messages: MyMessage[] }
+ | { type: "MARK_SAVED" };
+
+// Initial state
+const initialState: ChatState = {
+ isInitialized: false,
+ isLoading: false,
+ currentThreadId: "default",
+ threadList: [{ threadId: "default", status: "regular", title: "New Chat" }],
+ threads: new Map([["default", []]]),
+ lastSaved: 0,
+};
+
+// Reducer function
+function chatReducer(state: ChatState, action: ChatAction): ChatState {
+ switch (action.type) {
+ case "INITIALIZE_START":
+ return {
+ ...state,
+ isLoading: true,
+ };
+
+ case "INITIALIZE_SUCCESS":
+ return {
+ ...state,
+ isInitialized: true,
+ isLoading: false,
+ threadList: action.threadList,
+ threads: action.threads,
+ currentThreadId: action.currentThreadId,
+ lastSaved: Date.now(),
+ };
+
+ case "INITIALIZE_ERROR":
+ return {
+ ...state,
+ isInitialized: true,
+ isLoading: false,
+ };
+
+ case "SET_CURRENT_THREAD":
+ return {
+ ...state,
+ currentThreadId: action.threadId,
+ };
+
+ case "ADD_THREAD":
+ return {
+ ...state,
+ threadList: [...state.threadList, action.thread],
+ threads: new Map(state.threads).set(action.thread.threadId, []),
+ };
+
+ case "UPDATE_THREAD":
+ return {
+ ...state,
+ threadList: state.threadList.map(thread =>
+ thread.threadId === action.threadId
+ ? { ...thread, ...action.updates }
+ : thread
+ ),
+ };
+
+ case "DELETE_THREAD":
+ const newThreads = new Map(state.threads);
+ newThreads.delete(action.threadId);
+ return {
+ ...state,
+ threadList: state.threadList.filter(t => t.threadId !== action.threadId),
+ threads: newThreads,
+ currentThreadId: state.currentThreadId === action.threadId
+ ? "default"
+ : state.currentThreadId,
+ };
+
+ case "SET_MESSAGES":
+ return {
+ ...state,
+ threads: new Map(state.threads).set(action.threadId, action.messages),
+ };
+
+ case "ADD_MESSAGE":
+ const currentMessages = state.threads.get(action.threadId) || [];
+ return {
+ ...state,
+ threads: new Map(state.threads).set(action.threadId, [...currentMessages, action.message]),
+ };
+
+ case "UPDATE_MESSAGES":
+ return {
+ ...state,
+ threads: new Map(state.threads).set(action.threadId, action.messages),
+ };
+
+ case "MARK_SAVED":
+ return {
+ ...state,
+ lastSaved: Date.now(),
+ };
+
+ default:
+ return state;
+ }
+}
+
+// Context type
+interface ChatContextType {
+ state: ChatState;
+ actions: {
+ // Initialization
+ initialize: () => Promise;
+
+ // Thread management
+ setCurrentThread: (threadId: string) => void;
+ createThread: (title?: string) => Promise;
+ updateThread: (threadId: string, updates: Partial) => Promise;
+ deleteThread: (threadId: string) => Promise;
+
+ // Message management
+ addMessage: (threadId: string, message: MyMessage) => Promise;
+ updateMessages: (threadId: string, messages: MyMessage[]) => Promise;
+
+ // Utility
+ getCurrentMessages: () => MyMessage[];
+ };
+}
+
+// Create the context
+const ChatContext = createContext(null);
+
+// Chat provider component
+export function ChatProvider({ children }: { children: ReactNode }) {
+ const [state, dispatch] = useReducer(chatReducer, initialState);
+
+ // Initialize data from storage
+ const initialize = async () => {
+ dispatch({ type: "INITIALIZE_START" });
+
+ try {
+ await chatStorage.initialize();
+
+ // Load all threads from storage
+ const storedThreads = await chatStorage.getAllThreads();
+
+ if (storedThreads.length > 0) {
+ // Convert stored threads to UI format
+ const uiThreads: ThreadData[] = storedThreads.map(stored => ({
+ threadId: stored.threadId,
+ status: stored.status as "regular" | "archived",
+ title: stored.title,
+ }));
+
+ // Load messages for each thread
+ const threadMessages = new Map();
+ for (const thread of storedThreads) {
+ const messages = await chatStorage.getMessages(thread.threadId);
+ threadMessages.set(thread.threadId, messages);
+ }
+
+ // Ensure default thread exists
+ if (!threadMessages.has("default")) {
+ threadMessages.set("default", []);
+ }
+
+ // Find the most recently updated thread
+ const latestThread = storedThreads.sort((a, b) => b.updatedAt - a.updatedAt)[0];
+ const currentThreadId = latestThread ? latestThread.threadId : "default";
+
+ dispatch({
+ type: "INITIALIZE_SUCCESS",
+ threadList: uiThreads,
+ threads: threadMessages,
+ currentThreadId
+ });
+ } else {
+ // Initialize with default thread
+ const defaultThread: StoredThreadData = {
+ threadId: "default",
+ status: "regular",
+ title: "New Chat",
+ createdAt: Date.now(),
+ updatedAt: Date.now(),
+ };
+ await chatStorage.saveThread(defaultThread);
+
+ dispatch({
+ type: "INITIALIZE_SUCCESS",
+ threadList: initialState.threadList,
+ threads: initialState.threads,
+ currentThreadId: "default"
+ });
+ }
+ } catch (error) {
+ console.error("Failed to initialize chat data:", error);
+ dispatch({ type: "INITIALIZE_ERROR" });
+ }
+ };
+
+ // Thread management actions
+ const setCurrentThread = (threadId: string) => {
+ dispatch({ type: "SET_CURRENT_THREAD", threadId });
+ };
+
+ const createThread = async (title: string = "New Chat"): Promise => {
+ const threadId = `thread-${Date.now()}`;
+ const newThread: ThreadData = {
+ threadId,
+ status: "regular",
+ title,
+ };
+
+ // Update local state first
+ dispatch({ type: "ADD_THREAD", thread: newThread });
+
+ // Save to storage
+ try {
+ const storedThread: StoredThreadData = {
+ threadId,
+ status: "regular",
+ title,
+ createdAt: Date.now(),
+ updatedAt: Date.now(),
+ };
+ await chatStorage.saveThread(storedThread);
+ dispatch({ type: "MARK_SAVED" });
+ } catch (error) {
+ console.error("Failed to save new thread:", error);
+ }
+
+ return threadId;
+ };
+
+ const updateThread = async (threadId: string, updates: Partial) => {
+ // Update local state first
+ dispatch({ type: "UPDATE_THREAD", threadId, updates });
+
+ // Save to storage
+ try {
+ const existingThread = await chatStorage.getThread(threadId);
+ if (existingThread) {
+ const updatedThread: StoredThreadData = {
+ ...existingThread,
+ ...updates,
+ updatedAt: Date.now(),
+ };
+ await chatStorage.saveThread(updatedThread);
+ dispatch({ type: "MARK_SAVED" });
+ }
+ } catch (error) {
+ console.error("Failed to update thread:", error);
+ }
+ };
+
+ const deleteThread = async (threadId: string) => {
+ // Update local state first
+ dispatch({ type: "DELETE_THREAD", threadId });
+
+ // Delete from storage
+ try {
+ await chatStorage.deleteThread(threadId);
+ dispatch({ type: "MARK_SAVED" });
+ } catch (error) {
+ console.error("Failed to delete thread:", error);
+ }
+ };
+
+ // Message management actions
+ const addMessage = async (threadId: string, message: MyMessage) => {
+ // Update local state first
+ dispatch({ type: "ADD_MESSAGE", threadId, message });
+
+ // Save to storage
+ try {
+ await chatStorage.saveMessage(message, threadId);
+ dispatch({ type: "MARK_SAVED" });
+ } catch (error) {
+ console.error("Failed to save message:", error);
+ }
+ };
+
+ const updateMessages = async (threadId: string, messages: MyMessage[]) => {
+ // Update local state first
+ dispatch({ type: "UPDATE_MESSAGES", threadId, messages });
+
+ // Save to storage
+ try {
+ await chatStorage.saveMessages(messages, threadId);
+ dispatch({ type: "MARK_SAVED" });
+ } catch (error) {
+ console.error("Failed to save messages:", error);
+ }
+ };
+
+ // Utility functions
+ const getCurrentMessages = (): MyMessage[] => {
+ return state.threads.get(state.currentThreadId) || [];
+ };
+
+ // Auto-initialize on mount
+ useEffect(() => {
+ if (!state.isInitialized && !state.isLoading) {
+ initialize();
+ }
+ }, [state.isInitialized, state.isLoading]);
+
+ const actions = {
+ initialize,
+ setCurrentThread,
+ createThread,
+ updateThread,
+ deleteThread,
+ addMessage,
+ updateMessages,
+ getCurrentMessages,
+ };
+
+ return (
+
+ {children}
+
+ );
+}
+
+// Hook for accessing chat context
+export function useChatContext() {
+ const context = useContext(ChatContext);
+ if (!context) {
+ throw new Error("useChatContext must be used within ChatProvider");
+ }
+ return context;
+}
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/button.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/button.tsx
new file mode 100644
index 000000000..4406b74e6
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/button.tsx
@@ -0,0 +1,45 @@
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+import { cn } from "../../utils/cn";
+
+const buttonVariants = cva("aui-button", {
+ variants: {
+ variant: {
+ default: "aui-button-primary",
+ outline: "aui-button-outline",
+ ghost: "aui-button-ghost",
+ },
+ size: {
+ default: "aui-button-medium",
+ icon: "aui-button-icon",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+});
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean;
+ }) {
+ const Comp = asChild ? Slot : "button";
+
+ return (
+
+ );
+}
+
+export { Button, buttonVariants };
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/tooltip.tsx b/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/tooltip.tsx
new file mode 100644
index 000000000..ede610e32
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/components/ui/tooltip.tsx
@@ -0,0 +1,29 @@
+"use client";
+
+import * as React from "react";
+import * as TooltipPrimitive from "@radix-ui/react-tooltip";
+
+import { cn } from "../../utils/cn";
+
+const TooltipProvider = TooltipPrimitive.Provider;
+
+const Tooltip = TooltipPrimitive.Root;
+
+const TooltipTrigger = TooltipPrimitive.Trigger;
+
+const TooltipContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, sideOffset = 4, ...props }, ref) => (
+
+
+
+));
+TooltipContent.displayName = TooltipPrimitive.Content.displayName;
+
+export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/index.ts b/client/packages/lowcoder/src/comps/comps/chatComp/index.ts
new file mode 100644
index 000000000..32064185b
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/index.ts
@@ -0,0 +1,3 @@
+// client/packages/lowcoder/src/comps/comps/chatComp/index.ts
+export { ChatComp } from "./chatComp";
+export type { ChatCompProps } from "./chatCompTypes";
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/utils/chatStorage.ts b/client/packages/lowcoder/src/comps/comps/chatComp/utils/chatStorage.ts
new file mode 100644
index 000000000..edc68a0d9
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/utils/chatStorage.ts
@@ -0,0 +1,281 @@
+import alasql from "alasql";
+import { MyMessage } from "../components/context/ChatContext";
+
+// Database configuration
+const DB_NAME = "ChatDB";
+const THREADS_TABLE = "threads";
+const MESSAGES_TABLE = "messages";
+
+// Thread data interface
+export interface ThreadData {
+ threadId: string;
+ status: "regular" | "archived";
+ title: string;
+ createdAt: number;
+ updatedAt: number;
+}
+
+// Initialize the database
+class ChatStorage {
+ private initialized = false;
+
+ async initialize() {
+ if (this.initialized) return;
+
+ try {
+ // Create database with localStorage backend
+ await alasql.promise(`CREATE LOCALSTORAGE DATABASE IF NOT EXISTS ${DB_NAME}`);
+ await alasql.promise(`ATTACH LOCALSTORAGE DATABASE ${DB_NAME}`);
+ await alasql.promise(`USE ${DB_NAME}`);
+
+ // Create threads table
+ await alasql.promise(`
+ CREATE TABLE IF NOT EXISTS ${THREADS_TABLE} (
+ threadId STRING PRIMARY KEY,
+ status STRING,
+ title STRING,
+ createdAt NUMBER,
+ updatedAt NUMBER
+ )
+ `);
+
+ // Create messages table
+ await alasql.promise(`
+ CREATE TABLE IF NOT EXISTS ${MESSAGES_TABLE} (
+ id STRING PRIMARY KEY,
+ threadId STRING,
+ role STRING,
+ text STRING,
+ timestamp NUMBER
+ )
+ `);
+
+ this.initialized = true;
+ console.log("Chat database initialized successfully");
+ } catch (error) {
+ console.error("Failed to initialize chat database:", error);
+ throw error;
+ }
+ }
+
+ // Thread operations
+ async saveThread(thread: ThreadData): Promise {
+ await this.initialize();
+
+ try {
+ // Insert or replace thread
+ await alasql.promise(`
+ DELETE FROM ${THREADS_TABLE} WHERE threadId = ?
+ `, [thread.threadId]);
+
+ await alasql.promise(`
+ INSERT INTO ${THREADS_TABLE} VALUES (?, ?, ?, ?, ?)
+ `, [thread.threadId, thread.status, thread.title, thread.createdAt, thread.updatedAt]);
+ } catch (error) {
+ console.error("Failed to save thread:", error);
+ throw error;
+ }
+ }
+
+ async getThread(threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ const result = await alasql.promise(`
+ SELECT * FROM ${THREADS_TABLE} WHERE threadId = ?
+ `, [threadId]) as ThreadData[];
+
+ return result && result.length > 0 ? result[0] : null;
+ } catch (error) {
+ console.error("Failed to get thread:", error);
+ return null;
+ }
+ }
+
+ async getAllThreads(): Promise {
+ await this.initialize();
+
+ try {
+ const result = await alasql.promise(`
+ SELECT * FROM ${THREADS_TABLE} ORDER BY updatedAt DESC
+ `) as ThreadData[];
+
+ return Array.isArray(result) ? result : [];
+ } catch (error) {
+ console.error("Failed to get threads:", error);
+ return [];
+ }
+ }
+
+ async deleteThread(threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ // Delete thread and all its messages
+ await alasql.promise(`DELETE FROM ${THREADS_TABLE} WHERE threadId = ?`, [threadId]);
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE} WHERE threadId = ?`, [threadId]);
+ } catch (error) {
+ console.error("Failed to delete thread:", error);
+ throw error;
+ }
+ }
+
+ // Message operations
+ async saveMessage(message: MyMessage, threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ // Insert or replace message
+ await alasql.promise(`
+ DELETE FROM ${MESSAGES_TABLE} WHERE id = ?
+ `, [message.id]);
+
+ await alasql.promise(`
+ INSERT INTO ${MESSAGES_TABLE} VALUES (?, ?, ?, ?, ?)
+ `, [message.id, threadId, message.role, message.text, message.timestamp]);
+ } catch (error) {
+ console.error("Failed to save message:", error);
+ throw error;
+ }
+ }
+
+ async saveMessages(messages: MyMessage[], threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ // Delete existing messages for this thread
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE} WHERE threadId = ?`, [threadId]);
+
+ // Insert all messages
+ for (const message of messages) {
+ await alasql.promise(`
+ INSERT INTO ${MESSAGES_TABLE} VALUES (?, ?, ?, ?, ?)
+ `, [message.id, threadId, message.role, message.text, message.timestamp]);
+ }
+ } catch (error) {
+ console.error("Failed to save messages:", error);
+ throw error;
+ }
+ }
+
+ async getMessages(threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ const result = await alasql.promise(`
+ SELECT id, role, text, timestamp FROM ${MESSAGES_TABLE}
+ WHERE threadId = ? ORDER BY timestamp ASC
+ `, [threadId]) as MyMessage[];
+
+ return Array.isArray(result) ? result : [];
+ } catch (error) {
+ console.error("Failed to get messages:", error);
+ return [];
+ }
+ }
+
+ async deleteMessages(threadId: string): Promise {
+ await this.initialize();
+
+ try {
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE} WHERE threadId = ?`, [threadId]);
+ } catch (error) {
+ console.error("Failed to delete messages:", error);
+ throw error;
+ }
+ }
+
+ // Utility methods
+ async clearAllData(): Promise {
+ await this.initialize();
+
+ try {
+ await alasql.promise(`DELETE FROM ${THREADS_TABLE}`);
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE}`);
+ } catch (error) {
+ console.error("Failed to clear all data:", error);
+ throw error;
+ }
+ }
+
+ async resetDatabase(): Promise {
+ try {
+ // Drop the entire database
+ await alasql.promise(`DROP LOCALSTORAGE DATABASE IF EXISTS ${DB_NAME}`);
+ this.initialized = false;
+
+ // Reinitialize fresh
+ await this.initialize();
+ console.log("✅ Database reset and reinitialized");
+ } catch (error) {
+ console.error("Failed to reset database:", error);
+ throw error;
+ }
+ }
+
+ async clearOnlyMessages(): Promise {
+ await this.initialize();
+
+ try {
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE}`);
+ console.log("✅ All messages cleared, threads preserved");
+ } catch (error) {
+ console.error("Failed to clear messages:", error);
+ throw error;
+ }
+ }
+
+ async clearOnlyThreads(): Promise {
+ await this.initialize();
+
+ try {
+ await alasql.promise(`DELETE FROM ${THREADS_TABLE}`);
+ await alasql.promise(`DELETE FROM ${MESSAGES_TABLE}`); // Clear orphaned messages
+ console.log("✅ All threads and messages cleared");
+ } catch (error) {
+ console.error("Failed to clear threads:", error);
+ throw error;
+ }
+ }
+
+ async exportData(): Promise<{ threads: ThreadData[]; messages: any[] }> {
+ await this.initialize();
+
+ try {
+ const threads = await this.getAllThreads();
+ const messages = await alasql.promise(`SELECT * FROM ${MESSAGES_TABLE}`) as any[];
+
+ return { threads, messages: Array.isArray(messages) ? messages : [] };
+ } catch (error) {
+ console.error("Failed to export data:", error);
+ throw error;
+ }
+ }
+
+ async importData(data: { threads: ThreadData[]; messages: any[] }): Promise {
+ await this.initialize();
+
+ try {
+ // Clear existing data
+ await this.clearAllData();
+
+ // Import threads
+ for (const thread of data.threads) {
+ await this.saveThread(thread);
+ }
+
+ // Import messages
+ for (const message of data.messages) {
+ await alasql.promise(`
+ INSERT INTO ${MESSAGES_TABLE} VALUES (?, ?, ?, ?, ?)
+ `, [message.id, message.threadId, message.role, message.text, message.timestamp]);
+ }
+ } catch (error) {
+ console.error("Failed to import data:", error);
+ throw error;
+ }
+ }
+}
+
+// Export singleton instance
+export const chatStorage = new ChatStorage();
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/comps/chatComp/utils/cn.ts b/client/packages/lowcoder/src/comps/comps/chatComp/utils/cn.ts
new file mode 100644
index 000000000..5ba370c74
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/comps/chatComp/utils/cn.ts
@@ -0,0 +1,5 @@
+import { type ClassValue, clsx } from "clsx";
+
+export function cn(...inputs: ClassValue[]) {
+ return clsx(inputs);
+}
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/index.tsx b/client/packages/lowcoder/src/comps/index.tsx
index 2395f4f29..1d3b7314f 100644
--- a/client/packages/lowcoder/src/comps/index.tsx
+++ b/client/packages/lowcoder/src/comps/index.tsx
@@ -193,6 +193,7 @@ import { DrawerComp } from "./hooks/drawerComp";
import { ModalComp } from "./hooks/modalComp";
import { defaultCollapsibleContainerData } from "./comps/containerComp/collapsibleContainerComp";
import { ContainerComp as FloatTextContainerComp } from "./comps/containerComp/textContainerComp";
+import { ChatComp } from "./comps/chatComp";
type Registry = {
[key in UICompType]?: UICompManifest;
@@ -1669,6 +1670,19 @@ export var uiCompMap: Registry = {
h: 20,
},
},
+ chat: {
+ name: "Chat",
+ enName: "Chat",
+ description: "Chat Component",
+ categories: ["collaboration"],
+ icon: CommentCompIcon, // Use existing icon for now
+ keywords: "chat,conversation",
+ comp: ChatComp,
+ layoutInfo: {
+ w: 12,
+ h: 20,
+ },
+ },
// Integration
diff --git a/client/packages/lowcoder/src/comps/uiCompRegistry.ts b/client/packages/lowcoder/src/comps/uiCompRegistry.ts
index 4c320de47..48fb2079b 100644
--- a/client/packages/lowcoder/src/comps/uiCompRegistry.ts
+++ b/client/packages/lowcoder/src/comps/uiCompRegistry.ts
@@ -169,6 +169,7 @@ export type UICompType =
| "columnLayout"
| "ganttChart"
| "kanban"
+ | "chat" // Added by Faran
;
diff --git a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
index a931455d4..d18705af1 100644
--- a/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
+++ b/client/packages/lowcoder/src/pages/editor/editorConstants.tsx
@@ -306,4 +306,5 @@ export const CompStateIcon: {
sunburstChart: ,
themeriverChart: ,
basicChart: ,
+ chat: ,
} as const;
diff --git a/client/yarn.lock b/client/yarn.lock
index b3885ff80..e8357b3c0 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -45,6 +45,71 @@ __metadata:
languageName: node
linkType: hard
+"@ai-sdk/openai@npm:^1.3.22":
+ version: 1.3.22
+ resolution: "@ai-sdk/openai@npm:1.3.22"
+ dependencies:
+ "@ai-sdk/provider": 1.1.3
+ "@ai-sdk/provider-utils": 2.2.8
+ peerDependencies:
+ zod: ^3.0.0
+ checksum: 5572a349c93cb4953e4afcb837870eef876f022b8a931a52820a8d51106c67382cd77c1defc8725d43d8e03d5baf48c52d4b198c8fa68e1a724408567fc2d62a
+ languageName: node
+ linkType: hard
+
+"@ai-sdk/provider-utils@npm:2.2.8":
+ version: 2.2.8
+ resolution: "@ai-sdk/provider-utils@npm:2.2.8"
+ dependencies:
+ "@ai-sdk/provider": 1.1.3
+ nanoid: ^3.3.8
+ secure-json-parse: ^2.7.0
+ peerDependencies:
+ zod: ^3.23.8
+ checksum: 15487a4b4f1cc4eb72d7fc7afb71506f7bf439b538ef98b0c189a2b6d0dd72f10614c716c2206390b2624d6aeeb0799a0dad86010f6a505bbd9bd1b1d76adc60
+ languageName: node
+ linkType: hard
+
+"@ai-sdk/provider@npm:1.1.3, @ai-sdk/provider@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "@ai-sdk/provider@npm:1.1.3"
+ dependencies:
+ json-schema: ^0.4.0
+ checksum: 197b5907aaca7d96b0d114c3456d46fa1134e6d98bb22617c2bd28b3592c1ab79d524ea894209cedc0e74695ee250b2a32de7d084122fd047565b64cbba009bb
+ languageName: node
+ linkType: hard
+
+"@ai-sdk/react@npm:*, @ai-sdk/react@npm:1.2.12":
+ version: 1.2.12
+ resolution: "@ai-sdk/react@npm:1.2.12"
+ dependencies:
+ "@ai-sdk/provider-utils": 2.2.8
+ "@ai-sdk/ui-utils": 1.2.11
+ swr: ^2.2.5
+ throttleit: 2.1.0
+ peerDependencies:
+ react: ^18 || ^19 || ^19.0.0-rc
+ zod: ^3.23.8
+ peerDependenciesMeta:
+ zod:
+ optional: true
+ checksum: 2bb15f4e9416c6cf17e66581435497e9ed46d8e19be657a8e3507c847017f9aa0fb9c64b989890d5b9614468df6ee94e271bd96ef65212fd193e2e356a84c54b
+ languageName: node
+ linkType: hard
+
+"@ai-sdk/ui-utils@npm:*, @ai-sdk/ui-utils@npm:1.2.11":
+ version: 1.2.11
+ resolution: "@ai-sdk/ui-utils@npm:1.2.11"
+ dependencies:
+ "@ai-sdk/provider": 1.1.3
+ "@ai-sdk/provider-utils": 2.2.8
+ zod-to-json-schema: ^3.24.1
+ peerDependencies:
+ zod: ^3.23.8
+ checksum: 8ea01d026923aae73a06810f33ce24020fc7f001331ac0b801d2a8be576d42353abdd3344278dcfdb4eb43914c38b4fb7d3305354a6cd2ba0cb5359f1fd01a49
+ languageName: node
+ linkType: hard
+
"@ampproject/remapping@npm:^2.2.0":
version: 2.3.0
resolution: "@ampproject/remapping@npm:2.3.0"
@@ -143,6 +208,113 @@ __metadata:
languageName: node
linkType: hard
+"@assistant-ui/react-ai-sdk@npm:^0.10.14":
+ version: 0.10.14
+ resolution: "@assistant-ui/react-ai-sdk@npm:0.10.14"
+ dependencies:
+ "@ai-sdk/react": "*"
+ "@ai-sdk/ui-utils": "*"
+ "@assistant-ui/react-edge": 0.2.12
+ "@radix-ui/react-use-callback-ref": ^1.1.1
+ "@types/json-schema": ^7.0.15
+ zod: ^3.25.64
+ zustand: ^5.0.5
+ peerDependencies:
+ "@assistant-ui/react": ^0.10.24
+ "@types/react": "*"
+ react: ^18 || ^19 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 1deb3310ca1cf3b901e4afe06e1fd7256759f2b55e8e658ec56a2075636bdd61a670cf373b3a1f2b9877674fc62df9c18c79852c0a3a05f97063cc57b15b9cf7
+ languageName: node
+ linkType: hard
+
+"@assistant-ui/react-edge@npm:0.2.12":
+ version: 0.2.12
+ resolution: "@assistant-ui/react-edge@npm:0.2.12"
+ dependencies:
+ "@ai-sdk/provider": ^1.1.3
+ assistant-stream: ^0.2.17
+ json-schema: ^0.4.0
+ zod: ^3.25.64
+ zod-to-json-schema: ^3.24.5
+ peerDependencies:
+ "@assistant-ui/react": "*"
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^18 || ^19 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 6d533f26e533b7d177689ce3aa8d6b6fe0077d1f77d9f5b3707bae09bf084b7ba629a242e92fdf7f99328edc7521f3d0845587e961f19bce55c820ece7bba828
+ languageName: node
+ linkType: hard
+
+"@assistant-ui/react-markdown@npm:^0.10.5":
+ version: 0.10.5
+ resolution: "@assistant-ui/react-markdown@npm:0.10.5"
+ dependencies:
+ "@radix-ui/react-primitive": ^2.1.3
+ "@radix-ui/react-use-callback-ref": ^1.1.1
+ "@types/hast": ^3.0.4
+ classnames: ^2.5.1
+ react-markdown: ^10.1.0
+ peerDependencies:
+ "@assistant-ui/react": ^0.10.24
+ "@types/react": "*"
+ react: ^18 || ^19 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 85991a87a04f34c68b0290dfa6061e760b90bdcef694f7b938138b34836eaafe7dd0159faa54e262c227007dd8b912e5cab53329a99c26561a91a0a17d14a2ac
+ languageName: node
+ linkType: hard
+
+"@assistant-ui/react@npm:^0.10.24":
+ version: 0.10.24
+ resolution: "@assistant-ui/react@npm:0.10.24"
+ dependencies:
+ "@radix-ui/primitive": ^1.1.2
+ "@radix-ui/react-compose-refs": ^1.1.2
+ "@radix-ui/react-context": ^1.1.2
+ "@radix-ui/react-popover": ^1.1.14
+ "@radix-ui/react-primitive": ^2.1.3
+ "@radix-ui/react-slot": ^1.2.3
+ "@radix-ui/react-use-callback-ref": ^1.1.1
+ "@radix-ui/react-use-escape-keydown": ^1.1.1
+ "@standard-schema/spec": ^1.0.0
+ assistant-cloud: 0.0.2
+ assistant-stream: ^0.2.17
+ json-schema: ^0.4.0
+ nanoid: 5.1.5
+ react-textarea-autosize: ^8.5.9
+ zod: ^3.25.64
+ zustand: ^5.0.5
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^18 || ^19 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 4f9483464ac24caf7271161683dc8a8ab17c2263b16ebb5f1a4da75ea1ecda93048f93c7b06c90202e76215d72beb190408d3833ab54e4d19bdbd0ee2523a5f3
+ languageName: node
+ linkType: hard
+
+"@assistant-ui/styles@npm:^0.1.13":
+ version: 0.1.13
+ resolution: "@assistant-ui/styles@npm:0.1.13"
+ checksum: edbe7f3aa144eb823830f662cc1f44cfe3a53fff05f1ec918a7e0a692cad86a276069c7834531102ff37125070cc42dfa84380c8daeee3cdbceae0d42c517f64
+ languageName: node
+ linkType: hard
+
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/code-frame@npm:7.27.1"
@@ -2181,6 +2353,15 @@ __metadata:
languageName: node
linkType: hard
+"@floating-ui/core@npm:^1.7.2":
+ version: 1.7.2
+ resolution: "@floating-ui/core@npm:1.7.2"
+ dependencies:
+ "@floating-ui/utils": ^0.2.10
+ checksum: aea540ea0101daf83e5beb2769af81f0532dcb8514dbee9d4c0a06576377d56dbfd4e5c3b031359594a26649734d1145bbd5524e8a573a745a5fcadc6b307906
+ languageName: node
+ linkType: hard
+
"@floating-ui/dom@npm:^1.4.2":
version: 1.7.0
resolution: "@floating-ui/dom@npm:1.7.0"
@@ -2191,6 +2372,35 @@ __metadata:
languageName: node
linkType: hard
+"@floating-ui/dom@npm:^1.7.2":
+ version: 1.7.2
+ resolution: "@floating-ui/dom@npm:1.7.2"
+ dependencies:
+ "@floating-ui/core": ^1.7.2
+ "@floating-ui/utils": ^0.2.10
+ checksum: 232d6668693cfecec038f3fb1f5398eace340427a9108701b895136c18d303d8bdd6237dce224626abf56a5a4592db776fbd0d187aa0f72c729bfca14a474b65
+ languageName: node
+ linkType: hard
+
+"@floating-ui/react-dom@npm:^2.0.0":
+ version: 2.1.4
+ resolution: "@floating-ui/react-dom@npm:2.1.4"
+ dependencies:
+ "@floating-ui/dom": ^1.7.2
+ peerDependencies:
+ react: ">=16.8.0"
+ react-dom: ">=16.8.0"
+ checksum: be2cc094b0c5cd7f6a06c6c58944e4f070e231bdc8d9f84fc8246eedf91e1545a8a9e6d8560664054de126aae6520da57a30b7d81433cb2625641a08eea8f029
+ languageName: node
+ linkType: hard
+
+"@floating-ui/utils@npm:^0.2.10":
+ version: 0.2.10
+ resolution: "@floating-ui/utils@npm:0.2.10"
+ checksum: ffc4c24a46a665cfd0337e9aaf7de8415b572f8a0f323af39175e4b575582aed13d172e7f049eedeece9eaf022bad019c140a2d192580451984ae529bdf1285c
+ languageName: node
+ linkType: hard
+
"@floating-ui/utils@npm:^0.2.9":
version: 0.2.9
resolution: "@floating-ui/utils@npm:0.2.9"
@@ -3137,6 +3347,13 @@ __metadata:
languageName: node
linkType: hard
+"@opentelemetry/api@npm:1.9.0":
+ version: 1.9.0
+ resolution: "@opentelemetry/api@npm:1.9.0"
+ checksum: 9e88e59d53ced668f3daaecfd721071c5b85a67dd386f1c6f051d1be54375d850016c881f656ffbe9a03bedae85f7e89c2f2b635313f9c9b195ad033cdc31020
+ languageName: node
+ linkType: hard
+
"@pkgjs/parseargs@npm:^0.11.0":
version: 0.11.0
resolution: "@pkgjs/parseargs@npm:0.11.0"
@@ -3158,6 +3375,423 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/primitive@npm:1.1.2, @radix-ui/primitive@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "@radix-ui/primitive@npm:1.1.2"
+ checksum: 6cb2ac097faf77b7288bdfd87d92e983e357252d00ee0d2b51ad8e7897bf9f51ec53eafd7dd64c613671a2b02cb8166177bc3de444a6560ec60835c363321c18
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-arrow@npm:1.1.7":
+ version: 1.1.7
+ resolution: "@radix-ui/react-arrow@npm:1.1.7"
+ dependencies:
+ "@radix-ui/react-primitive": 2.1.3
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 6cdf74f06090f8994cdf6d3935a44ea3ac309163a4f59c476482c4907e8e0775f224045030abf10fa4f9e1cb7743db034429249b9e59354988e247eeb0f4fdcf
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-compose-refs@npm:1.1.2, @radix-ui/react-compose-refs@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "@radix-ui/react-compose-refs@npm:1.1.2"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 9a91f0213014ffa40c5b8aae4debb993be5654217e504e35aa7422887eb2d114486d37e53c482d0fffb00cd44f51b5269fcdf397b280c71666fa11b7f32f165d
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-context@npm:1.1.2, @radix-ui/react-context@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "@radix-ui/react-context@npm:1.1.2"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 6d08437f23df362672259e535ae463e70bf7a0069f09bfa06c983a5a90e15250bde19da1d63ef8e3da06df1e1b4f92afa9d28ca6aa0297bb1c8aaf6ca83d28c5
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-dismissable-layer@npm:1.1.10":
+ version: 1.1.10
+ resolution: "@radix-ui/react-dismissable-layer@npm:1.1.10"
+ dependencies:
+ "@radix-ui/primitive": 1.1.2
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-use-callback-ref": 1.1.1
+ "@radix-ui/react-use-escape-keydown": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: c4f31e8e93ae979a1bcd60726f8ebe7b79f23baafcd1d1e65f62cff6b322b2c6ff6132d82f2e63737f9955a8f04407849036f5b64b478e9a5678747d835957d8
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-focus-guards@npm:1.1.2":
+ version: 1.1.2
+ resolution: "@radix-ui/react-focus-guards@npm:1.1.2"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 618658e2b98575198b94ccfdd27f41beb37f83721c9a04617e848afbc47461124ae008d703d713b9644771d96d4852e49de322cf4be3b5f10a4f94d200db5248
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-focus-scope@npm:1.1.7":
+ version: 1.1.7
+ resolution: "@radix-ui/react-focus-scope@npm:1.1.7"
+ dependencies:
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-use-callback-ref": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: bb642d192d3da8431f8b39f64959b493a7ba743af8501b76699ef93357c96507c11fb76d468824b52b0e024eaee130a641f3a213268ac7c9af34883b45610c9b
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-id@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-id@npm:1.1.1"
+ dependencies:
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 8d68e200778eb3038906870fc869b3d881f4a46715fb20cddd9c76cba42fdaaa4810a3365b6ec2daf0f185b9201fc99d009167f59c7921bc3a139722c2e976db
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-popover@npm:^1.1.14":
+ version: 1.1.14
+ resolution: "@radix-ui/react-popover@npm:1.1.14"
+ dependencies:
+ "@radix-ui/primitive": 1.1.2
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-context": 1.1.2
+ "@radix-ui/react-dismissable-layer": 1.1.10
+ "@radix-ui/react-focus-guards": 1.1.2
+ "@radix-ui/react-focus-scope": 1.1.7
+ "@radix-ui/react-id": 1.1.1
+ "@radix-ui/react-popper": 1.2.7
+ "@radix-ui/react-portal": 1.1.9
+ "@radix-ui/react-presence": 1.1.4
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-slot": 1.2.3
+ "@radix-ui/react-use-controllable-state": 1.2.2
+ aria-hidden: ^1.2.4
+ react-remove-scroll: ^2.6.3
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 50f146117ebf675944181ef2df4fbc2d7ca017c71a2ab78eaa67159eb8a0101c682fa02bafa2b132ea7744592b7f103d02935ace2c1f430ab9040a0ece9246c8
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-popper@npm:1.2.7":
+ version: 1.2.7
+ resolution: "@radix-ui/react-popper@npm:1.2.7"
+ dependencies:
+ "@floating-ui/react-dom": ^2.0.0
+ "@radix-ui/react-arrow": 1.1.7
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-context": 1.1.2
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-use-callback-ref": 1.1.1
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ "@radix-ui/react-use-rect": 1.1.1
+ "@radix-ui/react-use-size": 1.1.1
+ "@radix-ui/rect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 1d672b8b635846501212eb0cd15273c8acdd31e76e78d2b9ba29ce29730d5a2d3a61a8ed49bb689c94f67f45d1dffe0d49449e0810f08c4e112d8aef8430e76d
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-portal@npm:1.1.9":
+ version: 1.1.9
+ resolution: "@radix-ui/react-portal@npm:1.1.9"
+ dependencies:
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: bd6be39bf021d5c917e2474ecba411e2625171f7ef96862b9af04bbd68833bb3662a7f1fbdeb5a7a237111b10e811e76d2cd03e957dadd6e668ef16541bfbd68
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-presence@npm:1.1.4":
+ version: 1.1.4
+ resolution: "@radix-ui/react-presence@npm:1.1.4"
+ dependencies:
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: d3b0976368fccdfa07100c1f07ca434d0092d4132d1ed4a5c213802f7318d77fc1fd61d1b7038b87e82912688fafa97d8af000a6cca4027b09d92c5477f79dd0
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-primitive@npm:2.1.3, @radix-ui/react-primitive@npm:^2.1.3":
+ version: 2.1.3
+ resolution: "@radix-ui/react-primitive@npm:2.1.3"
+ dependencies:
+ "@radix-ui/react-slot": 1.2.3
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 01f82e4bad76b57767198762c905e5bcea04f4f52129749791e31adfcb1b36f6fdc89c73c40017d812b6e25e4ac925d837214bb280cfeaa5dc383457ce6940b0
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-slot@npm:1.2.3, @radix-ui/react-slot@npm:^1.2.3":
+ version: 1.2.3
+ resolution: "@radix-ui/react-slot@npm:1.2.3"
+ dependencies:
+ "@radix-ui/react-compose-refs": 1.1.2
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 2731089e15477dd5eef98a5757c36113dd932d0c52ff05123cd89f05f0412e95e5b205229185d1cd705cda4a674a838479cce2b3b46ed903f82f5d23d9e3f3c2
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-tooltip@npm:^1.2.7":
+ version: 1.2.7
+ resolution: "@radix-ui/react-tooltip@npm:1.2.7"
+ dependencies:
+ "@radix-ui/primitive": 1.1.2
+ "@radix-ui/react-compose-refs": 1.1.2
+ "@radix-ui/react-context": 1.1.2
+ "@radix-ui/react-dismissable-layer": 1.1.10
+ "@radix-ui/react-id": 1.1.1
+ "@radix-ui/react-popper": 1.2.7
+ "@radix-ui/react-portal": 1.1.9
+ "@radix-ui/react-presence": 1.1.4
+ "@radix-ui/react-primitive": 2.1.3
+ "@radix-ui/react-slot": 1.2.3
+ "@radix-ui/react-use-controllable-state": 1.2.2
+ "@radix-ui/react-visually-hidden": 1.2.3
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: aebb5c124c73dc236e9362899cb81bb0b1d4103d29205122f55dd64a9b9bdf4be7cc335964e1885098be3c570416a35899a317e0e6f373b6f9d39334699e4694
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-callback-ref@npm:1.1.1, @radix-ui/react-use-callback-ref@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: cde8c40f1d4e79e6e71470218163a746858304bad03758ac84dc1f94247a046478e8e397518350c8d6609c84b7e78565441d7505bb3ed573afce82cfdcd19faf
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-controllable-state@npm:1.2.2":
+ version: 1.2.2
+ resolution: "@radix-ui/react-use-controllable-state@npm:1.2.2"
+ dependencies:
+ "@radix-ui/react-use-effect-event": 0.0.2
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: b438ee199d0630bf95eaafe8bf4bce219e73b371cfc8465f47548bfa4ee231f1134b5c6696b242890a01a0fd25fa34a7b172346bbfc5ee25cfb28b3881b1dc92
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-effect-event@npm:0.0.2":
+ version: 0.0.2
+ resolution: "@radix-ui/react-use-effect-event@npm:0.0.2"
+ dependencies:
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 5a1950a30a399ea7e4b98154da9f536737a610de80189b7aacd4f064a89a3cd0d2a48571d527435227252e72e872bdb544ff6ffcfbdd02de2efd011be4aaa902
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-escape-keydown@npm:1.1.1, @radix-ui/react-use-escape-keydown@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.1"
+ dependencies:
+ "@radix-ui/react-use-callback-ref": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 0eb0756c2c55ddcde9ff01446ab01c085ab2bf799173e97db7ef5f85126f9e8600225570801a1f64740e6d14c39ffe8eed7c14d29737345a5797f4622ac96f6f
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-layout-effect@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: bad2ba4f206e6255263582bedfb7868773c400836f9a1b423c0b464ffe4a17e13d3f306d1ce19cf7a19a492e9d0e49747464f2656451bb7c6a99f5a57bd34de2
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-rect@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-use-rect@npm:1.1.1"
+ dependencies:
+ "@radix-ui/rect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 116461bebc49472f7497e66a9bd413541181b3d00c5e0aaeef45d790dc1fbd7c8dcea80b169ea273306228b9a3c2b70067e902d1fd5004b3057e3bbe35b9d55d
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-size@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-use-size@npm:1.1.1"
+ dependencies:
+ "@radix-ui/react-use-layout-effect": 1.1.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 64e61f65feb67ffc80e1fc4a8d5e32480fb6d68475e2640377e021178dead101568cba5f936c9c33e6c142c7cf2fb5d76ad7b23ef80e556ba142d56cf306147b
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-visually-hidden@npm:1.2.3":
+ version: 1.2.3
+ resolution: "@radix-ui/react-visually-hidden@npm:1.2.3"
+ dependencies:
+ "@radix-ui/react-primitive": 2.1.3
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 42296bde1ddf4af4e7445e914c35d6bc8406d6ede49f0a959a553e75b3ed21da09fda80a81c48d8ec058ed8129ce7137499d02ee26f90f0d3eaa2417922d6509
+ languageName: node
+ linkType: hard
+
+"@radix-ui/rect@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/rect@npm:1.1.1"
+ checksum: c1c111edeab70b14a735bca43601de6468c792482864b766ac8940b43321492e5c0ae62f92b156cecdc9265ec3c680c32b3fa0c8a90b5e796923a9af13c5dc20
+ languageName: node
+ linkType: hard
+
"@rc-component/async-validator@npm:^5.0.3":
version: 5.0.4
resolution: "@rc-component/async-validator@npm:5.0.4"
@@ -3927,6 +4561,13 @@ __metadata:
languageName: node
linkType: hard
+"@standard-schema/spec@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@standard-schema/spec@npm:1.0.0"
+ checksum: 2d7d73a1c9706622750ab06fc40ef7c1d320b52d5e795f8a1c7a77d0d6a9f978705092bc4149327b3cff4c9a14e5b3800d3b00dc945489175a2d3031ded8332a
+ languageName: node
+ linkType: hard
+
"@supabase/auth-js@npm:2.69.1":
version: 2.69.1
resolution: "@supabase/auth-js@npm:2.69.1"
@@ -4516,6 +5157,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/diff-match-patch@npm:^1.0.36":
+ version: 1.0.36
+ resolution: "@types/diff-match-patch@npm:1.0.36"
+ checksum: 7d7ce03422fcc3e79d0cda26e4748aeb176b75ca4b4e5f38459b112bf24660d628424bdb08d330faefa69039d19a5316e7a102a8ab68b8e294c8346790e55113
+ languageName: node
+ linkType: hard
+
"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
@@ -4648,7 +5296,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/hast@npm:^3.0.0":
+"@types/hast@npm:^3.0.0, @types/hast@npm:^3.0.4":
version: 3.0.4
resolution: "@types/hast@npm:3.0.4"
dependencies:
@@ -5844,6 +6492,26 @@ __metadata:
languageName: node
linkType: hard
+"ai@npm:^4.3.16":
+ version: 4.3.16
+ resolution: "ai@npm:4.3.16"
+ dependencies:
+ "@ai-sdk/provider": 1.1.3
+ "@ai-sdk/provider-utils": 2.2.8
+ "@ai-sdk/react": 1.2.12
+ "@ai-sdk/ui-utils": 1.2.11
+ "@opentelemetry/api": 1.9.0
+ jsondiffpatch: 0.6.0
+ peerDependencies:
+ react: ^18 || ^19 || ^19.0.0-rc
+ zod: ^3.23.8
+ peerDependenciesMeta:
+ react:
+ optional: true
+ checksum: 1c13e641f04440d5ea550435defda01508473f4c5e65b248df4d39911c5accb77dd17009563c16163097642a33fe9eb421c6bedbcf824835ace9dfd96c785061
+ languageName: node
+ linkType: hard
+
"ajv-formats@npm:^2.1.0, ajv-formats@npm:^2.1.1":
version: 2.1.1
resolution: "ajv-formats@npm:2.1.1"
@@ -6130,6 +6798,15 @@ __metadata:
languageName: node
linkType: hard
+"aria-hidden@npm:^1.2.4":
+ version: 1.2.6
+ resolution: "aria-hidden@npm:1.2.6"
+ dependencies:
+ tslib: ^2.0.0
+ checksum: 56409c55c43ad917607f3f3aa67748dcf30a27e8bb5cb3c5d86b43e38babadd63cd77731a27bc8a8c4332c2291741ed92333bf7ca45f8b99ebc87b94a8070a6e
+ languageName: node
+ linkType: hard
+
"aria-query@npm:5.1.3":
version: 5.1.3
resolution: "aria-query@npm:5.1.3"
@@ -6319,6 +6996,26 @@ __metadata:
languageName: node
linkType: hard
+"assistant-cloud@npm:0.0.2":
+ version: 0.0.2
+ resolution: "assistant-cloud@npm:0.0.2"
+ dependencies:
+ assistant-stream: ^0.2.17
+ checksum: 5a4df3ca6c40dad15eb38c3f974bffd321bf52859f41bc3459d75f912e37579211a07876a5d28ce462396407f87a863dc849034f9bc24e04c010ab31827c6f82
+ languageName: node
+ linkType: hard
+
+"assistant-stream@npm:^0.2.17":
+ version: 0.2.17
+ resolution: "assistant-stream@npm:0.2.17"
+ dependencies:
+ "@types/json-schema": ^7.0.15
+ nanoid: 5.1.5
+ secure-json-parse: ^4.0.0
+ checksum: 1b317f2e5c19ce013cb8673ff73461b5ba39fe80ff05c3d4b6e67704d89a70ab76337dac6974901962caedcffc45429e990856c3e551122de6a3b37649a2d8cb
+ languageName: node
+ linkType: hard
+
"ast-types-flow@npm:^0.0.8":
version: 0.0.8
resolution: "ast-types-flow@npm:0.0.8"
@@ -7166,6 +7863,13 @@ __metadata:
languageName: node
linkType: hard
+"chalk@npm:^5.3.0":
+ version: 5.4.1
+ resolution: "chalk@npm:5.4.1"
+ checksum: 0c656f30b782fed4d99198825c0860158901f449a6b12b818b0aabad27ec970389e7e8767d0e00762175b23620c812e70c4fd92c0210e55fc2d993638b74e86e
+ languageName: node
+ linkType: hard
+
"char-regex@npm:^1.0.2":
version: 1.0.2
resolution: "char-regex@npm:1.0.2"
@@ -7258,6 +7962,15 @@ __metadata:
languageName: node
linkType: hard
+"class-variance-authority@npm:^0.7.1":
+ version: 0.7.1
+ resolution: "class-variance-authority@npm:0.7.1"
+ dependencies:
+ clsx: ^2.1.1
+ checksum: e05ba26ef9ec38f7c675047ce366b067d60af6c954dba08f7802af19a9460a534ae752d8fe1294fff99d0fa94a669b16ccebd87e8a20f637c0736cf2751dd2c5
+ languageName: node
+ linkType: hard
+
"classnames@npm:2.x, classnames@npm:^2.2.1, classnames@npm:^2.2.3, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.3.2, classnames@npm:^2.5.1":
version: 2.5.1
resolution: "classnames@npm:2.5.1"
@@ -7347,7 +8060,7 @@ __metadata:
languageName: node
linkType: hard
-"clsx@npm:^2.0.0":
+"clsx@npm:^2.0.0, clsx@npm:^2.1.1":
version: 2.1.1
resolution: "clsx@npm:2.1.1"
checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57
@@ -8811,7 +9524,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
-"dequal@npm:^2.0.0":
+"dequal@npm:^2.0.0, dequal@npm:^2.0.3":
version: 2.0.3
resolution: "dequal@npm:2.0.3"
checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90
@@ -8842,6 +9555,13 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"detect-node-es@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "detect-node-es@npm:1.1.0"
+ checksum: e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449
+ languageName: node
+ linkType: hard
+
"detect-node@npm:^2.0.4":
version: 2.1.0
resolution: "detect-node@npm:2.1.0"
@@ -8858,6 +9578,13 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"diff-match-patch@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "diff-match-patch@npm:1.0.5"
+ checksum: 841522d01b09cccbc4e4402cf61514a81b906349a7d97b67222390f2d35cf5df277cb23959eeed212d5e46afb5629cebab41b87918672c5a05c11c73688630e3
+ languageName: node
+ linkType: hard
+
"diff-sequences@npm:^29.6.3":
version: 29.6.3
resolution: "diff-sequences@npm:29.6.3"
@@ -10763,6 +11490,13 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"get-nonce@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "get-nonce@npm:1.0.1"
+ checksum: e2614e43b4694c78277bb61b0f04583d45786881289285c73770b07ded246a98be7e1f78b940c80cbe6f2b07f55f0b724e6db6fd6f1bcbd1e8bdac16521074ed
+ languageName: node
+ linkType: hard
+
"get-package-type@npm:^0.1.0":
version: 0.1.0
resolution: "get-package-type@npm:0.1.0"
@@ -13227,7 +13961,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
-"json-schema@npm:0.4.0":
+"json-schema@npm:0.4.0, json-schema@npm:^0.4.0":
version: 0.4.0
resolution: "json-schema@npm:0.4.0"
checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72
@@ -13277,6 +14011,19 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"jsondiffpatch@npm:0.6.0":
+ version: 0.6.0
+ resolution: "jsondiffpatch@npm:0.6.0"
+ dependencies:
+ "@types/diff-match-patch": ^1.0.36
+ chalk: ^5.3.0
+ diff-match-patch: ^1.0.5
+ bin:
+ jsondiffpatch: bin/jsondiffpatch.js
+ checksum: 27d7aa42c3b9f9359fd179bb49c621ed848f6095615014cd0acbd29c37e364c11cb5a19c3ef2c873631e7b5f7ba6d1465978a489efa28cb1dc9fba98b0498712
+ languageName: node
+ linkType: hard
+
"jsonfile@npm:^6.0.1":
version: 6.1.0
resolution: "jsonfile@npm:6.1.0"
@@ -14103,7 +14850,12 @@ coolshapes-react@lowcoder-org/coolshapes-react:
version: 0.0.0-use.local
resolution: "lowcoder@workspace:packages/lowcoder"
dependencies:
+ "@ai-sdk/openai": ^1.3.22
"@ant-design/icons": ^5.3.0
+ "@assistant-ui/react": ^0.10.24
+ "@assistant-ui/react-ai-sdk": ^0.10.14
+ "@assistant-ui/react-markdown": ^0.10.5
+ "@assistant-ui/styles": ^0.1.13
"@bany/curl-to-json": ^1.2.8
"@codemirror/autocomplete": ^6.11.1
"@codemirror/commands": ^6.3.2
@@ -14125,6 +14877,8 @@ coolshapes-react@lowcoder-org/coolshapes-react:
"@jsonforms/core": ^3.5.1
"@lottiefiles/dotlottie-react": ^0.13.0
"@manaflair/redux-batch": ^1.0.0
+ "@radix-ui/react-slot": ^1.2.3
+ "@radix-ui/react-tooltip": ^1.2.7
"@rjsf/antd": ^5.24.9
"@rjsf/core": ^5.24.9
"@rjsf/utils": ^5.24.9
@@ -14143,11 +14897,13 @@ coolshapes-react@lowcoder-org/coolshapes-react:
"@types/supercluster": ^7.1.3
"@types/uuid": ^8.3.4
"@vitejs/plugin-react": ^2.2.0
+ ai: ^4.3.16
alasql: ^4.6.6
animate.css: ^4.1.1
antd: ^5.25.2
axios: ^1.7.7
buffer: ^6.0.3
+ class-variance-authority: ^0.7.1
clsx: ^2.0.0
cnchar: ^3.2.4
coolshapes-react: lowcoder-org/coolshapes-react
@@ -14172,6 +14928,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
loglevel: ^1.8.0
lowcoder-core: "workspace:^"
lowcoder-design: "workspace:^"
+ lucide-react: ^0.525.0
mime: ^3.0.0
moment: ^2.29.4
numbro: ^2.3.6
@@ -14209,7 +14966,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
regenerator-runtime: ^0.13.9
rehype-raw: ^6.1.1
rehype-sanitize: ^5.0.1
- remark-gfm: ^4.0.0
+ remark-gfm: ^4.0.1
resize-observer-polyfill: ^1.5.1
rollup-plugin-terser: ^7.0.2
rollup-plugin-visualizer: ^5.9.2
@@ -14274,6 +15031,15 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"lucide-react@npm:^0.525.0":
+ version: 0.525.0
+ resolution: "lucide-react@npm:0.525.0"
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ checksum: eef781bfcfd211dac1ca93d0e7c5830aec1bacef72f4af3994807ac04d2a0fe327aca1a77234daf7f13e06ea47e5585766c927c8e1f2e7dcb982e4dc55aeda5e
+ languageName: node
+ linkType: hard
+
"lz-string@npm:^1.5.0":
version: 1.5.0
resolution: "lz-string@npm:1.5.0"
@@ -15685,6 +16451,15 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"nanoid@npm:5.1.5":
+ version: 5.1.5
+ resolution: "nanoid@npm:5.1.5"
+ bin:
+ nanoid: bin/nanoid.js
+ checksum: 6de2d006b51c983be385ef7ee285f7f2a57bd96f8c0ca881c4111461644bd81fafc2544f8e07cb834ca0f3e0f3f676c1fe78052183f008b0809efe6e273119f5
+ languageName: node
+ linkType: hard
+
"nanoid@npm:^3.3.7, nanoid@npm:^3.3.8":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
@@ -17933,6 +18708,28 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"react-markdown@npm:^10.1.0":
+ version: 10.1.0
+ resolution: "react-markdown@npm:10.1.0"
+ dependencies:
+ "@types/hast": ^3.0.0
+ "@types/mdast": ^4.0.0
+ devlop: ^1.0.0
+ hast-util-to-jsx-runtime: ^2.0.0
+ html-url-attributes: ^3.0.0
+ mdast-util-to-hast: ^13.0.0
+ remark-parse: ^11.0.0
+ remark-rehype: ^11.0.0
+ unified: ^11.0.0
+ unist-util-visit: ^5.0.0
+ vfile: ^6.0.0
+ peerDependencies:
+ "@types/react": ">=18"
+ react: ">=18"
+ checksum: fa7ef860e32a18206c5b301de8672be609b108f46f0f091e9779d50ff8145bd63d0f6e82ffb18fc1b7aee2264cbdac1100205596ff10d2c3d2de6627abb3868f
+ languageName: node
+ linkType: hard
+
"react-markdown@npm:^9.0.1":
version: 9.1.0
resolution: "react-markdown@npm:9.1.0"
@@ -18026,6 +18823,41 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"react-remove-scroll-bar@npm:^2.3.7":
+ version: 2.3.8
+ resolution: "react-remove-scroll-bar@npm:2.3.8"
+ dependencies:
+ react-style-singleton: ^2.2.2
+ tslib: ^2.0.0
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: c4663247f689dbe51c370836edf735487f6d8796acb7f15b09e8a1c14e84c7997360e8e3d54de2bc9c0e782fed2b2c4127d15b4053e4d2cf26839e809e57605f
+ languageName: node
+ linkType: hard
+
+"react-remove-scroll@npm:^2.6.3":
+ version: 2.7.1
+ resolution: "react-remove-scroll@npm:2.7.1"
+ dependencies:
+ react-remove-scroll-bar: ^2.3.7
+ react-style-singleton: ^2.2.3
+ tslib: ^2.1.0
+ use-callback-ref: ^1.3.3
+ use-sidecar: ^1.1.3
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: c8b1988d473ca0b4911a0a42f09dc7806d5db998c3ec938ae2791a5f82d807c2cdebb78a1c58a0bab62a83112528dda2f20d509d0e048fe281b9dfc027c39763
+ languageName: node
+ linkType: hard
+
"react-resizable@npm:^3.0.4, react-resizable@npm:^3.0.5":
version: 3.0.5
resolution: "react-resizable@npm:3.0.5"
@@ -18132,6 +18964,22 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"react-style-singleton@npm:^2.2.2, react-style-singleton@npm:^2.2.3":
+ version: 2.2.3
+ resolution: "react-style-singleton@npm:2.2.3"
+ dependencies:
+ get-nonce: ^1.0.0
+ tslib: ^2.0.0
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: a7b0bf493c9231065ebafa84c4237aed997c746c561196121b7de82fe155a5355b372db5070a3ac9fe980cf7f60dc0f1e8cf6402a2aa5b2957392932ccf76e76
+ languageName: node
+ linkType: hard
+
"react-test-renderer@npm:^18.1.0":
version: 18.3.1
resolution: "react-test-renderer@npm:18.3.1"
@@ -18145,7 +18993,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
-"react-textarea-autosize@npm:^8.3.2":
+"react-textarea-autosize@npm:^8.3.2, react-textarea-autosize@npm:^8.5.9":
version: 8.5.9
resolution: "react-textarea-autosize@npm:8.5.9"
dependencies:
@@ -18534,7 +19382,7 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
-"remark-gfm@npm:^4.0.0":
+"remark-gfm@npm:^4.0.0, remark-gfm@npm:^4.0.1":
version: 4.0.1
resolution: "remark-gfm@npm:4.0.1"
dependencies:
@@ -19291,6 +20139,20 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"secure-json-parse@npm:^2.7.0":
+ version: 2.7.0
+ resolution: "secure-json-parse@npm:2.7.0"
+ checksum: d9d7d5a01fc6db6115744ba23cf9e67ecfe8c524d771537c062ee05ad5c11b64c730bc58c7f33f60bd6877f96b86f0ceb9ea29644e4040cb757f6912d4dd6737
+ languageName: node
+ linkType: hard
+
+"secure-json-parse@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "secure-json-parse@npm:4.0.0"
+ checksum: 5092d1385f242ae1a189a193eeb2f5ed1f00350270edefe209fbd35898a93745da58e7d8d4833a6da2235a89df7140d2959817ca4f2b1a4bfd135a812fab4f01
+ languageName: node
+ linkType: hard
+
"select-hose@npm:^2.0.0":
version: 2.0.0
resolution: "select-hose@npm:2.0.0"
@@ -20402,6 +21264,18 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"swr@npm:^2.2.5":
+ version: 2.3.3
+ resolution: "swr@npm:2.3.3"
+ dependencies:
+ dequal: ^2.0.3
+ use-sync-external-store: ^1.4.0
+ peerDependencies:
+ react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ checksum: 25b2ab03d0149951e4612fae8458d333d6fbe912298684495969250553176b5b5b731be119f406ebadf6e9c5dc39726dd2492cca9684f448aa1734274e2a4919
+ languageName: node
+ linkType: hard
+
"symbol-tree@npm:^3.2.2, symbol-tree@npm:^3.2.4":
version: 3.2.4
resolution: "symbol-tree@npm:3.2.4"
@@ -20558,6 +21432,13 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"throttleit@npm:2.1.0":
+ version: 2.1.0
+ resolution: "throttleit@npm:2.1.0"
+ checksum: a2003947aafc721c4a17e6f07db72dc88a64fa9bba0f9c659f7997d30f9590b3af22dadd6a41851e0e8497d539c33b2935c2c7919cf4255922509af6913c619b
+ languageName: node
+ linkType: hard
+
"thunky@npm:^1.0.2":
version: 1.1.0
resolution: "thunky@npm:1.1.0"
@@ -21478,6 +22359,21 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"use-callback-ref@npm:^1.3.3":
+ version: 1.3.3
+ resolution: "use-callback-ref@npm:1.3.3"
+ dependencies:
+ tslib: ^2.0.0
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 4da1c82d7a2409cee6c882748a40f4a083decf238308bf12c3d0166f0e338f8d512f37b8d11987eb5a421f14b9b5b991edf3e11ed25c3bb7a6559081f8359b44
+ languageName: node
+ linkType: hard
+
"use-composed-ref@npm:^1.3.0":
version: 1.4.0
resolution: "use-composed-ref@npm:1.4.0"
@@ -21516,7 +22412,23 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
-"use-sync-external-store@npm:^1.2.0":
+"use-sidecar@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "use-sidecar@npm:1.1.3"
+ dependencies:
+ detect-node-es: ^1.1.0
+ tslib: ^2.0.0
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 88664c6b2c5b6e53e4d5d987694c9053cea806da43130248c74ca058945c8caa6ccb7b1787205a9eb5b9d124633e42153848904002828acabccdc48cda026622
+ languageName: node
+ linkType: hard
+
+"use-sync-external-store@npm:^1.2.0, use-sync-external-store@npm:^1.4.0":
version: 1.5.0
resolution: "use-sync-external-store@npm:1.5.0"
peerDependencies:
@@ -22741,6 +23653,22 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"zod-to-json-schema@npm:^3.24.1, zod-to-json-schema@npm:^3.24.5":
+ version: 3.24.6
+ resolution: "zod-to-json-schema@npm:3.24.6"
+ peerDependencies:
+ zod: ^3.24.1
+ checksum: 5f4d29597cfd88d8fb8a539f0169affb8705d67ee9cbe478aa01bb1d2554e0540ca713fa4ddeb2fd834e87e7cdff61fa396f6d1925a9006de70afe6cd68bf7d2
+ languageName: node
+ linkType: hard
+
+"zod@npm:^3.25.64":
+ version: 3.25.67
+ resolution: "zod@npm:3.25.67"
+ checksum: 56ab904d33b1cd00041ce64ae05b0628fcbfeb7e707fa31cd498a97b540135e4dfe685200c9c62aea307695ee132870b4bc34f035228ea728aa75cc96a4954cb
+ languageName: node
+ linkType: hard
+
"zrender@npm:5.6.1, zrender@npm:^5.1.1":
version: 5.6.1
resolution: "zrender@npm:5.6.1"
@@ -22750,6 +23678,27 @@ coolshapes-react@lowcoder-org/coolshapes-react:
languageName: node
linkType: hard
+"zustand@npm:^5.0.5":
+ version: 5.0.6
+ resolution: "zustand@npm:5.0.6"
+ peerDependencies:
+ "@types/react": ">=18.0.0"
+ immer: ">=9.0.6"
+ react: ">=18.0.0"
+ use-sync-external-store: ">=1.2.0"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+ use-sync-external-store:
+ optional: true
+ checksum: 1808cd7d49e8ba6777e0d8d524a858a918a4fd0bcbde88eb19ea3f4be9c8066276ecc236a8ed071623d3f13373424c56a5ddb0013be590b641ac99bf8f9b4e19
+ languageName: node
+ linkType: hard
+
"zwitch@npm:^2.0.0":
version: 2.0.4
resolution: "zwitch@npm:2.0.4"