@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.
@@ -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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datum-cloud/datum-ui",
3
3
  "type": "module",
4
- "version": "1.5.0",
4
+ "version": "1.6.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "url": "https://github.com/datum-cloud/datum-ui"