@datum-cloud/datum-ui 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/assistant/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { t as Icon } from "../icon-wrapper-DKfJlJd0.mjs";
|
|
|
3
3
|
import { a as DropdownMenuRadioGroup, c as DropdownMenuTrigger, i as DropdownMenuLabel, o as DropdownMenuRadioItem, r as DropdownMenuContent, s as DropdownMenuSeparator, t as DropdownMenu } from "../dropdown-menu-b8zY5Cs6.mjs";
|
|
4
4
|
import { t as Tooltip } from "../tooltip-BhatUaar.mjs";
|
|
5
5
|
import { ArrowDown, ArrowRight, ArrowUp, Brain, Check, ChevronDown, Copy, Download, MessagesSquare, Mic, MicOff, PanelLeft, Plus, RotateCw, Square, Trash2 } from "lucide-react";
|
|
6
|
-
import { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
|
6
|
+
import { Fragment, createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { AnimatePresence, motion } from "motion/react";
|
|
9
9
|
import { EditorContent } from "@tiptap/react";
|
|
@@ -389,7 +389,7 @@ function messageText(msg) {
|
|
|
389
389
|
return msg.parts.filter(isTextUIPart).map((p) => p.text).join("\n\n");
|
|
390
390
|
}
|
|
391
391
|
function AssistantMessage({ msg, isLastMessage, status }) {
|
|
392
|
-
const { toolLabels, showReasoning, messageActions, renderLink } = useAssistantConfig();
|
|
392
|
+
const { toolLabels, showReasoning, messageActions, renderLink, renderToolOutput } = useAssistantConfig();
|
|
393
393
|
const isStreaming = isLastMessage && status === "streaming";
|
|
394
394
|
const hasText = msg.parts.some((p) => isTextUIPart(p) && p.text);
|
|
395
395
|
const activeToolPart = msg.parts.find((p) => isToolUIPart(p) && (p.state === "input-streaming" || p.state === "input-available"));
|
|
@@ -432,6 +432,10 @@ function AssistantMessage({ msg, isLastMessage, status }) {
|
|
|
432
432
|
},
|
|
433
433
|
children: part.text
|
|
434
434
|
}, i);
|
|
435
|
+
if (isToolUIPart(part) && part.state === "output-available" && renderToolOutput) {
|
|
436
|
+
const rendered = renderToolOutput(part, msg);
|
|
437
|
+
if (rendered) return /* @__PURE__ */ jsx(Fragment, { children: rendered }, i);
|
|
438
|
+
}
|
|
435
439
|
return null;
|
|
436
440
|
}),
|
|
437
441
|
showInitialLoading && /* @__PURE__ */ jsx("div", {
|
|
@@ -824,7 +828,7 @@ function downloadChat(chat) {
|
|
|
824
828
|
a.click();
|
|
825
829
|
URL.revokeObjectURL(url);
|
|
826
830
|
}
|
|
827
|
-
function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat }) {
|
|
831
|
+
function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, header }) {
|
|
828
832
|
const [query, setQuery] = useState("");
|
|
829
833
|
const filtered = useMemo(() => {
|
|
830
834
|
const q = query.trim().toLowerCase();
|
|
@@ -833,6 +837,10 @@ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat }) {
|
|
|
833
837
|
return /* @__PURE__ */ jsxs("div", {
|
|
834
838
|
className: "bg-background flex h-full w-64 shrink-0 flex-col border-r",
|
|
835
839
|
children: [
|
|
840
|
+
header && /* @__PURE__ */ jsx("div", {
|
|
841
|
+
className: "shrink-0 border-b px-3 py-2",
|
|
842
|
+
children: header
|
|
843
|
+
}),
|
|
836
844
|
/* @__PURE__ */ jsx("div", {
|
|
837
845
|
className: "flex h-12 items-center border-b px-2",
|
|
838
846
|
children: /* @__PURE__ */ jsx("input", {
|
|
@@ -894,7 +902,7 @@ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat }) {
|
|
|
894
902
|
}
|
|
895
903
|
//#endregion
|
|
896
904
|
//#region src/components/features/assistant/components/assistant-workspace.tsx
|
|
897
|
-
function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory }) {
|
|
905
|
+
function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory }) {
|
|
898
906
|
const hasMessages = messages.length > 0;
|
|
899
907
|
const promptCard = /* @__PURE__ */ jsx(PromptCard, {
|
|
900
908
|
editor,
|
|
@@ -937,6 +945,7 @@ function AssistantWorkspace({ config, userName, title, messages, status, error,
|
|
|
937
945
|
children: /* @__PURE__ */ jsx(HistoryPanel, {
|
|
938
946
|
chatList,
|
|
939
947
|
currentChatId,
|
|
948
|
+
header: sidebarHeader,
|
|
940
949
|
onLoadChat,
|
|
941
950
|
onDeleteChat
|
|
942
951
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Editor } from '@tiptap/react';
|
|
2
2
|
import type { UIMessage } from 'ai';
|
|
3
|
-
import type { MouseEvent as ReactMouseEvent, RefObject } from 'react';
|
|
3
|
+
import type { MouseEvent as ReactMouseEvent, ReactNode, RefObject } from 'react';
|
|
4
4
|
import type { AssistantConfig, ChatSummary, EffortId } from '../types';
|
|
5
5
|
/**
|
|
6
6
|
* Presentational, props-driven assistant layout: left rail + collapsible
|
|
@@ -21,6 +21,11 @@ export interface AssistantWorkspaceProps {
|
|
|
21
21
|
isReady: boolean;
|
|
22
22
|
chatList: ChatSummary[];
|
|
23
23
|
currentChatId: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional block pinned above the history search input, naming the scope the
|
|
26
|
+
* listed chats belong to (cloud-portal shows the current project).
|
|
27
|
+
*/
|
|
28
|
+
sidebarHeader?: ReactNode;
|
|
24
29
|
editor: Editor | null;
|
|
25
30
|
/** Sanitized HTML per user message index (for exact-render of the user's input). */
|
|
26
31
|
htmlByUserMsgIndex: RefObject<string[]>;
|
|
@@ -45,4 +50,4 @@ export interface AssistantWorkspaceProps {
|
|
|
45
50
|
historyOpen: boolean;
|
|
46
51
|
onToggleHistory: () => void;
|
|
47
52
|
}
|
|
48
|
-
export declare function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory, }: AssistantWorkspaceProps): import("react").JSX.Element;
|
|
53
|
+
export declare function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory, }: AssistantWorkspaceProps): import("react").JSX.Element;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { ChatSummary } from '../../types';
|
|
2
3
|
interface HistoryPanelProps {
|
|
3
4
|
chatList: ChatSummary[];
|
|
4
5
|
currentChatId: string;
|
|
5
6
|
onLoadChat: (chat: ChatSummary) => void;
|
|
6
7
|
onDeleteChat: (e: React.MouseEvent, chatId: string) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Optional host-supplied block pinned above the search input, naming the scope
|
|
10
|
+
* the listed chats belong to — cloud-portal shows the current project. Hosts
|
|
11
|
+
* whose history isn't scoped to anything (staff-portal) omit it.
|
|
12
|
+
*/
|
|
13
|
+
header?: ReactNode;
|
|
7
14
|
}
|
|
8
|
-
export declare function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, }: HistoryPanelProps): import("react").JSX.Element;
|
|
15
|
+
export declare function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, header, }: HistoryPanelProps): import("react").JSX.Element;
|
|
9
16
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UIMessage } from 'ai';
|
|
1
|
+
import type { DynamicToolUIPart, ToolUIPart, UIMessage } from 'ai';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
export type EffortId = 'low' | 'medium' | 'high';
|
|
4
4
|
export interface ModelOption {
|
|
@@ -46,6 +46,13 @@ export interface AssistantConfig {
|
|
|
46
46
|
renderLink: (props: LinkRenderProps) => ReactNode;
|
|
47
47
|
/** Override the per-message action toolbar (defaults to copy + download). */
|
|
48
48
|
messageActions?: (msg: UIMessage) => ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Renders a completed tool call inline, in message order. Return a falsy value
|
|
51
|
+
* to leave that tool invisible — the default for every tool, since most only
|
|
52
|
+
* feed the model. Hosts use this to surface a result as UI (cloud-portal turns
|
|
53
|
+
* an `openSupportTicket` result into a button).
|
|
54
|
+
*/
|
|
55
|
+
renderToolOutput?: (part: ToolUIPart | DynamicToolUIPart, msg: UIMessage) => ReactNode;
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* Minimal shape the history list needs. Host apps pass their own richer chat
|