@btst/stack 1.4.0 → 1.4.1

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.
Files changed (40) hide show
  1. package/dist/node_modules/.pnpm/@radix-ui_react-accordion@1.2.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types_re_947719a27ff11ec6f09710dd9e85efc5/node_modules/@radix-ui/react-accordion/dist/index.cjs +321 -0
  2. package/dist/node_modules/.pnpm/@radix-ui_react-accordion@1.2.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types_re_947719a27ff11ec6f09710dd9e85efc5/node_modules/@radix-ui/react-accordion/dist/index.mjs +306 -0
  3. package/dist/node_modules/.pnpm/@radix-ui_react-collapsible@1.1.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types__d025a77f62ee83ca6bd8b0ea1f9de738/node_modules/@radix-ui/react-collapsible/dist/index.cjs +168 -0
  4. package/dist/node_modules/.pnpm/@radix-ui_react-collapsible@1.1.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types__d025a77f62ee83ca6bd8b0ea1f9de738/node_modules/@radix-ui/react-collapsible/dist/index.mjs +146 -0
  5. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-interface.cjs +29 -3
  6. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-interface.mjs +29 -3
  7. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-layout.cjs +16 -3
  8. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-layout.mjs +16 -3
  9. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-message.cjs +35 -3
  10. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-message.mjs +35 -3
  11. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.cjs +123 -0
  12. package/dist/packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.mjs +121 -0
  13. package/dist/packages/ui/src/components/accordion.cjs +67 -0
  14. package/dist/packages/ui/src/components/accordion.mjs +62 -0
  15. package/dist/plugins/ai-chat/client/components/index.cjs +2 -0
  16. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  17. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  18. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  19. package/dist/plugins/ai-chat/client/components/index.mjs +1 -0
  20. package/dist/plugins/ai-chat/client/index.cjs +2 -0
  21. package/dist/plugins/ai-chat/client/index.d.cts +5 -176
  22. package/dist/plugins/ai-chat/client/index.d.mts +5 -176
  23. package/dist/plugins/ai-chat/client/index.d.ts +5 -176
  24. package/dist/plugins/ai-chat/client/index.mjs +1 -0
  25. package/dist/plugins/blog/client/components/shared/markdown-content-styles.css +6 -0
  26. package/dist/shared/stack.DaOcgmrM.d.cts +323 -0
  27. package/dist/shared/stack.DaOcgmrM.d.mts +323 -0
  28. package/dist/shared/stack.DaOcgmrM.d.ts +323 -0
  29. package/package.json +1 -1
  30. package/src/plugins/ai-chat/client/components/chat-interface.tsx +41 -2
  31. package/src/plugins/ai-chat/client/components/chat-layout.tsx +16 -1
  32. package/src/plugins/ai-chat/client/components/chat-message.tsx +59 -3
  33. package/src/plugins/ai-chat/client/components/index.ts +2 -0
  34. package/src/plugins/ai-chat/client/components/tool-call-display.tsx +197 -0
  35. package/src/plugins/ai-chat/client/index.ts +12 -1
  36. package/src/plugins/ai-chat/client/overrides.ts +71 -0
  37. package/src/plugins/blog/client/components/shared/markdown-content-styles.css +6 -0
  38. package/dist/shared/stack.DorMi9CZ.d.cts +0 -80
  39. package/dist/shared/stack.DorMi9CZ.d.mts +0 -80
  40. package/dist/shared/stack.DorMi9CZ.d.ts +0 -80
@@ -5,9 +5,11 @@ import { MarkdownContent } from '../../../../../../ui/src/components/markdown-co
5
5
  import { Button } from '../../../../../../ui/src/components/button.mjs';
6
6
  import { Dialog, DialogContent, DialogTitle } from '../../../../../../ui/src/components/dialog.mjs';
7
7
  import { Bot, FileText, X, Send, Pencil, Check, Copy, RefreshCw, User } from 'lucide-react';
8
+ import { isToolUIPart, getToolName } from 'ai';
8
9
  import { useState, useRef, useEffect, useMemo } from 'react';
9
10
  import { usePluginOverrides } from '@btst/stack/context';
10
11
  import { AI_CHAT_LOCALIZATION } from '../localization/index.mjs';
12
+ import { ToolCallDisplay } from './tool-call-display.mjs';
11
13
  import 'highlight.js/styles/panda-syntax-light.css';
12
14
  import completeMarkdown from 'remend';
13
15
 
@@ -77,7 +79,8 @@ function ChatMessage({
77
79
  const {
78
80
  Link,
79
81
  Image,
80
- localization: customLocalization
82
+ localization: customLocalization,
83
+ toolRenderers
81
84
  } = usePluginOverrides(
82
85
  "ai-chat",
83
86
  {}
@@ -149,6 +152,12 @@ function ChatMessage({
149
152
  }
150
153
  return [];
151
154
  }, [message.parts]);
155
+ const toolParts = useMemo(() => {
156
+ if (message.parts && Array.isArray(message.parts)) {
157
+ return message.parts.filter((part) => isToolUIPart(part));
158
+ }
159
+ return [];
160
+ }, [message.parts]);
152
161
  const displayContent = useMemo(() => {
153
162
  if (!textContent) return "";
154
163
  if (isStreaming && !isUser) {
@@ -270,7 +279,7 @@ function ChatMessage({
270
279
  )
271
280
  ] })
272
281
  ) : (
273
- // Assistant messages: rendered markdown + files + images
282
+ // Assistant messages: rendered markdown + files + images + tool calls
274
283
  /* @__PURE__ */ jsxs("div", { className: "wrap-break-word space-y-2", children: [
275
284
  fileParts.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: fileParts.map((part, index) => /* @__PURE__ */ jsxs(
276
285
  "a",
@@ -298,6 +307,29 @@ function ChatMessage({
298
307
  },
299
308
  index
300
309
  )) }),
310
+ toolParts.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: toolParts.map((part) => {
311
+ const toolName = getToolName(part);
312
+ const toolCallId = part.toolCallId;
313
+ const state = part.state;
314
+ const input = part.input;
315
+ const output = part.output;
316
+ const errorText = part.errorText;
317
+ const isLoading = state === "input-streaming" || state === "input-available";
318
+ const toolCallProps = {
319
+ toolCallId,
320
+ toolName,
321
+ state,
322
+ input,
323
+ output,
324
+ errorText,
325
+ isLoading
326
+ };
327
+ const CustomRenderer = toolRenderers?.[toolName];
328
+ if (CustomRenderer) {
329
+ return /* @__PURE__ */ jsx(CustomRenderer, { ...toolCallProps }, toolCallId);
330
+ }
331
+ return /* @__PURE__ */ jsx(ToolCallDisplay, { ...toolCallProps }, toolCallId);
332
+ }) }),
301
333
  displayContent ? /* @__PURE__ */ jsx(
302
334
  MarkdownContent,
303
335
  {
@@ -306,7 +338,7 @@ function ChatMessage({
306
338
  LinkComponent: Link ?? DefaultLink,
307
339
  ImageComponent
308
340
  }
309
- ) : imageParts.length === 0 && fileParts.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "..." }) : null
341
+ ) : imageParts.length === 0 && fileParts.length === 0 && toolParts.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "..." }) : null
310
342
  ] })
311
343
  )
312
344
  }
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const accordion = require('../../../../../../ui/src/components/accordion.cjs');
6
+ const markdownContent = require('../../../../../../ui/src/components/markdown-content.cjs');
7
+ const skeleton = require('../../../../../../ui/src/components/skeleton.cjs');
8
+ const utils = require('../../../../../../ui/src/lib/utils.cjs');
9
+ const lucideReact = require('lucide-react');
10
+
11
+ function formatToolName(name) {
12
+ return name.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()).trim();
13
+ }
14
+ function getStatusIcon(state, isLoading) {
15
+ if (isLoading || state === "input-streaming" || state === "input-available") {
16
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" });
17
+ }
18
+ if (state === "output-error") {
19
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-3.5 w-3.5 text-destructive" });
20
+ }
21
+ if (state === "output-available") {
22
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-500" });
23
+ }
24
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wrench, { className: "h-3.5 w-3.5 text-muted-foreground" });
25
+ }
26
+ function getStatusLabel(state, isLoading) {
27
+ if (isLoading || state === "input-streaming") {
28
+ return "Running...";
29
+ }
30
+ if (state === "input-available") {
31
+ return "Executing...";
32
+ }
33
+ if (state === "output-error") {
34
+ return "Error";
35
+ }
36
+ if (state === "output-available") {
37
+ return "Complete";
38
+ }
39
+ return "Pending";
40
+ }
41
+ function JsonDisplay({ data, label }) {
42
+ if (data === void 0 || data === null) {
43
+ return null;
44
+ }
45
+ let jsonString;
46
+ try {
47
+ jsonString = JSON.stringify(data, null, 2);
48
+ } catch {
49
+ jsonString = String(data);
50
+ }
51
+ const markdown = `\`\`\`json
52
+ ${jsonString}
53
+ \`\`\``;
54
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: label }),
56
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "[&_.markdown-code-block]:my-0 [&_.markdown-code-block]:max-h-48 [&_.markdown-code-block_.code-content]:max-h-40 [&_.markdown-code-block_.code-content]:overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(markdownContent.MarkdownContent, { markdown, variant: "chat" }) })
57
+ ] });
58
+ }
59
+ function ToolCallDisplay({
60
+ toolCallId,
61
+ toolName,
62
+ state,
63
+ input,
64
+ output,
65
+ errorText,
66
+ isLoading
67
+ }) {
68
+ const displayName = formatToolName(toolName);
69
+ const statusLabel = getStatusLabel(state, isLoading);
70
+ const statusIcon = getStatusIcon(state, isLoading);
71
+ const isComplete = state === "output-available" || state === "output-error";
72
+ const hasError = state === "output-error";
73
+ return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
74
+ accordion.AccordionItem,
75
+ {
76
+ value: toolCallId,
77
+ className: utils.cn(
78
+ "!border rounded-lg overflow-hidden transition-colors",
79
+ hasError && "border-destructive/50",
80
+ !hasError && isComplete && "border-green-500/30",
81
+ !isComplete && "border-border/50"
82
+ ),
83
+ children: [
84
+ /* @__PURE__ */ jsxRuntime.jsx(
85
+ accordion.AccordionTrigger,
86
+ {
87
+ className: utils.cn("px-3 py-2 hover:no-underline hover:bg-muted/50"),
88
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 w-full", children: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wrench, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
90
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium truncate text-left", children: displayName }),
91
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground shrink-0", children: [
92
+ statusIcon,
93
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: statusLabel })
94
+ ] })
95
+ ] })
96
+ }
97
+ ),
98
+ /* @__PURE__ */ jsxRuntime.jsx(accordion.AccordionContent, { className: "px-3 pb-3 pt-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 border-t border-border/50 pt-3", children: [
99
+ state === "input-streaming" && !input && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
100
+ /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-24" }),
101
+ /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-16 w-full" })
102
+ ] }),
103
+ input !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(JsonDisplay, { data: input, label: "Input" }),
104
+ state === "output-available" && output !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(JsonDisplay, { data: output, label: "Output" }),
105
+ state === "output-error" && errorText && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
106
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-destructive uppercase tracking-wide", children: "Error" }),
107
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-destructive bg-destructive/10 p-2 rounded-md", children: errorText })
108
+ ] }),
109
+ (state === "input-available" || state === "input-streaming") && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
110
+ /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-4 w-20" }),
111
+ /* @__PURE__ */ jsxRuntime.jsx(skeleton.Skeleton, { className: "h-12 w-full" })
112
+ ] }),
113
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] text-muted-foreground/50 truncate", children: [
114
+ "ID: ",
115
+ toolCallId
116
+ ] })
117
+ ] }) })
118
+ ]
119
+ }
120
+ ) });
121
+ }
122
+
123
+ exports.ToolCallDisplay = ToolCallDisplay;
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '../../../../../../ui/src/components/accordion.mjs';
4
+ import { MarkdownContent } from '../../../../../../ui/src/components/markdown-content.mjs';
5
+ import { Skeleton } from '../../../../../../ui/src/components/skeleton.mjs';
6
+ import { cn } from '../../../../../../ui/src/lib/utils.mjs';
7
+ import { Wrench, Loader2, AlertCircle, Check } from 'lucide-react';
8
+
9
+ function formatToolName(name) {
10
+ return name.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()).trim();
11
+ }
12
+ function getStatusIcon(state, isLoading) {
13
+ if (isLoading || state === "input-streaming" || state === "input-available") {
14
+ return /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" });
15
+ }
16
+ if (state === "output-error") {
17
+ return /* @__PURE__ */ jsx(AlertCircle, { className: "h-3.5 w-3.5 text-destructive" });
18
+ }
19
+ if (state === "output-available") {
20
+ return /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-500" });
21
+ }
22
+ return /* @__PURE__ */ jsx(Wrench, { className: "h-3.5 w-3.5 text-muted-foreground" });
23
+ }
24
+ function getStatusLabel(state, isLoading) {
25
+ if (isLoading || state === "input-streaming") {
26
+ return "Running...";
27
+ }
28
+ if (state === "input-available") {
29
+ return "Executing...";
30
+ }
31
+ if (state === "output-error") {
32
+ return "Error";
33
+ }
34
+ if (state === "output-available") {
35
+ return "Complete";
36
+ }
37
+ return "Pending";
38
+ }
39
+ function JsonDisplay({ data, label }) {
40
+ if (data === void 0 || data === null) {
41
+ return null;
42
+ }
43
+ let jsonString;
44
+ try {
45
+ jsonString = JSON.stringify(data, null, 2);
46
+ } catch {
47
+ jsonString = String(data);
48
+ }
49
+ const markdown = `\`\`\`json
50
+ ${jsonString}
51
+ \`\`\``;
52
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
53
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: label }),
54
+ /* @__PURE__ */ jsx("div", { className: "[&_.markdown-code-block]:my-0 [&_.markdown-code-block]:max-h-48 [&_.markdown-code-block_.code-content]:max-h-40 [&_.markdown-code-block_.code-content]:overflow-y-auto", children: /* @__PURE__ */ jsx(MarkdownContent, { markdown, variant: "chat" }) })
55
+ ] });
56
+ }
57
+ function ToolCallDisplay({
58
+ toolCallId,
59
+ toolName,
60
+ state,
61
+ input,
62
+ output,
63
+ errorText,
64
+ isLoading
65
+ }) {
66
+ const displayName = formatToolName(toolName);
67
+ const statusLabel = getStatusLabel(state, isLoading);
68
+ const statusIcon = getStatusIcon(state, isLoading);
69
+ const isComplete = state === "output-available" || state === "output-error";
70
+ const hasError = state === "output-error";
71
+ return /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "w-full", children: /* @__PURE__ */ jsxs(
72
+ AccordionItem,
73
+ {
74
+ value: toolCallId,
75
+ className: cn(
76
+ "!border rounded-lg overflow-hidden transition-colors",
77
+ hasError && "border-destructive/50",
78
+ !hasError && isComplete && "border-green-500/30",
79
+ !isComplete && "border-border/50"
80
+ ),
81
+ children: [
82
+ /* @__PURE__ */ jsx(
83
+ AccordionTrigger,
84
+ {
85
+ className: cn("px-3 py-2 hover:no-underline hover:bg-muted/50"),
86
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
87
+ /* @__PURE__ */ jsx(Wrench, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
88
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate text-left", children: displayName }),
89
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground shrink-0", children: [
90
+ statusIcon,
91
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: statusLabel })
92
+ ] })
93
+ ] })
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsx(AccordionContent, { className: "px-3 pb-3 pt-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3 border-t border-border/50 pt-3", children: [
97
+ state === "input-streaming" && !input && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
98
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" }),
99
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full" })
100
+ ] }),
101
+ input !== void 0 && /* @__PURE__ */ jsx(JsonDisplay, { data: input, label: "Input" }),
102
+ state === "output-available" && output !== void 0 && /* @__PURE__ */ jsx(JsonDisplay, { data: output, label: "Output" }),
103
+ state === "output-error" && errorText && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
104
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-destructive uppercase tracking-wide", children: "Error" }),
105
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-destructive bg-destructive/10 p-2 rounded-md", children: errorText })
106
+ ] }),
107
+ (state === "input-available" || state === "input-streaming") && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
108
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-20" }),
109
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" })
110
+ ] }),
111
+ /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-muted-foreground/50 truncate", children: [
112
+ "ID: ",
113
+ toolCallId
114
+ ] })
115
+ ] }) })
116
+ ]
117
+ }
118
+ ) });
119
+ }
120
+
121
+ export { ToolCallDisplay };
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const index = require('../../../../node_modules/.pnpm/@radix-ui_react-accordion@1.2.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types_re_947719a27ff11ec6f09710dd9e85efc5/node_modules/@radix-ui/react-accordion/dist/index.cjs');
6
+ const lucideReact = require('lucide-react');
7
+ const utils = require('../lib/utils.cjs');
8
+
9
+ function Accordion({
10
+ ...props
11
+ }) {
12
+ return /* @__PURE__ */ jsxRuntime.jsx(index.Root, { "data-slot": "accordion", ...props });
13
+ }
14
+ function AccordionItem({
15
+ className,
16
+ ...props
17
+ }) {
18
+ return /* @__PURE__ */ jsxRuntime.jsx(
19
+ index.Item,
20
+ {
21
+ "data-slot": "accordion-item",
22
+ className: utils.cn("border-b last:border-b-0", className),
23
+ ...props
24
+ }
25
+ );
26
+ }
27
+ function AccordionTrigger({
28
+ className,
29
+ children,
30
+ ...props
31
+ }) {
32
+ return /* @__PURE__ */ jsxRuntime.jsx(index.Header, { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
33
+ index.Trigger,
34
+ {
35
+ "data-slot": "accordion-trigger",
36
+ className: utils.cn(
37
+ "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
38
+ className
39
+ ),
40
+ ...props,
41
+ children: [
42
+ children,
43
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
44
+ ]
45
+ }
46
+ ) });
47
+ }
48
+ function AccordionContent({
49
+ className,
50
+ children,
51
+ ...props
52
+ }) {
53
+ return /* @__PURE__ */ jsxRuntime.jsx(
54
+ index.Content,
55
+ {
56
+ "data-slot": "accordion-content",
57
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
58
+ ...props,
59
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("pt-0 pb-4", className), children })
60
+ }
61
+ );
62
+ }
63
+
64
+ exports.Accordion = Accordion;
65
+ exports.AccordionContent = AccordionContent;
66
+ exports.AccordionItem = AccordionItem;
67
+ exports.AccordionTrigger = AccordionTrigger;
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { Root as Root2, Item, Header, Trigger as Trigger2, Content as Content2 } from '../../../../node_modules/.pnpm/@radix-ui_react-accordion@1.2.12_@types_react-dom@19.2.3_@types_react@19.2.6__@types_re_947719a27ff11ec6f09710dd9e85efc5/node_modules/@radix-ui/react-accordion/dist/index.mjs';
4
+ import { ChevronDownIcon } from 'lucide-react';
5
+ import { cn } from '../lib/utils.mjs';
6
+
7
+ function Accordion({
8
+ ...props
9
+ }) {
10
+ return /* @__PURE__ */ jsx(Root2, { "data-slot": "accordion", ...props });
11
+ }
12
+ function AccordionItem({
13
+ className,
14
+ ...props
15
+ }) {
16
+ return /* @__PURE__ */ jsx(
17
+ Item,
18
+ {
19
+ "data-slot": "accordion-item",
20
+ className: cn("border-b last:border-b-0", className),
21
+ ...props
22
+ }
23
+ );
24
+ }
25
+ function AccordionTrigger({
26
+ className,
27
+ children,
28
+ ...props
29
+ }) {
30
+ return /* @__PURE__ */ jsx(Header, { className: "flex", children: /* @__PURE__ */ jsxs(
31
+ Trigger2,
32
+ {
33
+ "data-slot": "accordion-trigger",
34
+ className: cn(
35
+ "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
36
+ className
37
+ ),
38
+ ...props,
39
+ children: [
40
+ children,
41
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
42
+ ]
43
+ }
44
+ ) });
45
+ }
46
+ function AccordionContent({
47
+ className,
48
+ children,
49
+ ...props
50
+ }) {
51
+ return /* @__PURE__ */ jsx(
52
+ Content2,
53
+ {
54
+ "data-slot": "accordion-content",
55
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
56
+ ...props,
57
+ children: /* @__PURE__ */ jsx("div", { className: cn("pt-0 pb-4", className), children })
58
+ }
59
+ );
60
+ }
61
+
62
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -5,6 +5,7 @@ const chatLayout = require('../../../../packages/better-stack/src/plugins/ai-cha
5
5
  const chatSidebar = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs');
6
6
  const chatMessage = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-message.cjs');
7
7
  const chatInput = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-input.cjs');
8
+ const toolCallDisplay = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.cjs');
8
9
  const chatPage = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/pages/chat-page.cjs');
9
10
  const index = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/loading/index.cjs');
10
11
  const defaultError = require('../../../../packages/better-stack/src/plugins/ai-chat/client/components/shared/default-error.cjs');
@@ -19,6 +20,7 @@ exports.ChatLayout = chatLayout.ChatLayout;
19
20
  exports.ChatSidebar = chatSidebar.ChatSidebar;
20
21
  exports.ChatMessage = chatMessage.ChatMessage;
21
22
  exports.ChatInput = chatInput.ChatInput;
23
+ exports.ToolCallDisplay = toolCallDisplay.ToolCallDisplay;
22
24
  exports.ChatPageComponent = chatPage.ChatPageComponent;
23
25
  exports.ChatLoading = index.ChatLoading;
24
26
  exports.DefaultError = defaultError.DefaultError;
@@ -1,4 +1,4 @@
1
- export { d as ChatInput, C as ChatInterface, a as ChatLayout, c as ChatMessage, b as ChatSidebar } from '../../../../shared/stack.DorMi9CZ.cjs';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.cjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -1,4 +1,4 @@
1
- export { d as ChatInput, C as ChatInterface, a as ChatLayout, c as ChatMessage, b as ChatSidebar } from '../../../../shared/stack.DorMi9CZ.mjs';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.mjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -1,4 +1,4 @@
1
- export { d as ChatInput, C as ChatInterface, a as ChatLayout, c as ChatMessage, b as ChatSidebar } from '../../../../shared/stack.DorMi9CZ.js';
1
+ export { i as ChatInput, C as ChatInterface, e as ChatLayout, f as ChatLayoutProps, h as ChatMessage, g as ChatSidebar, j as ToolCallDisplay } from '../../../../shared/stack.DaOcgmrM.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FallbackProps } from 'react-error-boundary';
4
4
  import 'ai';
@@ -3,6 +3,7 @@ export { ChatLayout } from '../../../../packages/better-stack/src/plugins/ai-cha
3
3
  export { ChatSidebar } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs';
4
4
  export { ChatMessage } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-message.mjs';
5
5
  export { ChatInput } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-input.mjs';
6
+ export { ToolCallDisplay } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.mjs';
6
7
  export { ChatPageComponent } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/pages/chat-page.mjs';
7
8
  export { ChatLoading } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/loading/index.mjs';
8
9
  export { DefaultError } from '../../../../packages/better-stack/src/plugins/ai-chat/client/components/shared/default-error.mjs';
@@ -7,6 +7,7 @@ const chatLayout = require('../../../packages/better-stack/src/plugins/ai-chat/c
7
7
  const chatSidebar = require('../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs');
8
8
  const chatMessage = require('../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-message.cjs');
9
9
  const chatInput = require('../../../packages/better-stack/src/plugins/ai-chat/client/components/chat-input.cjs');
10
+ const toolCallDisplay = require('../../../packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.cjs');
10
11
 
11
12
 
12
13
 
@@ -17,3 +18,4 @@ exports.ChatLayout = chatLayout.ChatLayout;
17
18
  exports.ChatSidebar = chatSidebar.ChatSidebar;
18
19
  exports.ChatMessage = chatMessage.ChatMessage;
19
20
  exports.ChatInput = chatInput.ChatInput;
21
+ exports.ToolCallDisplay = toolCallDisplay.ToolCallDisplay;