@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.
- 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
- 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
- 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
- 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
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-interface.cjs +29 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-interface.mjs +29 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-layout.cjs +16 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-layout.mjs +16 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-message.cjs +35 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/chat-message.mjs +35 -3
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.cjs +123 -0
- package/dist/packages/better-stack/src/plugins/ai-chat/client/components/tool-call-display.mjs +121 -0
- package/dist/packages/ui/src/components/accordion.cjs +67 -0
- package/dist/packages/ui/src/components/accordion.mjs +62 -0
- package/dist/plugins/ai-chat/client/components/index.cjs +2 -0
- package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/components/index.mjs +1 -0
- package/dist/plugins/ai-chat/client/index.cjs +2 -0
- package/dist/plugins/ai-chat/client/index.d.cts +5 -176
- package/dist/plugins/ai-chat/client/index.d.mts +5 -176
- package/dist/plugins/ai-chat/client/index.d.ts +5 -176
- package/dist/plugins/ai-chat/client/index.mjs +1 -0
- package/dist/plugins/blog/client/components/shared/markdown-content-styles.css +6 -0
- package/dist/shared/stack.DaOcgmrM.d.cts +323 -0
- package/dist/shared/stack.DaOcgmrM.d.mts +323 -0
- package/dist/shared/stack.DaOcgmrM.d.ts +323 -0
- package/package.json +1 -1
- package/src/plugins/ai-chat/client/components/chat-interface.tsx +41 -2
- package/src/plugins/ai-chat/client/components/chat-layout.tsx +16 -1
- package/src/plugins/ai-chat/client/components/chat-message.tsx +59 -3
- package/src/plugins/ai-chat/client/components/index.ts +2 -0
- package/src/plugins/ai-chat/client/components/tool-call-display.tsx +197 -0
- package/src/plugins/ai-chat/client/index.ts +12 -1
- package/src/plugins/ai-chat/client/overrides.ts +71 -0
- package/src/plugins/blog/client/components/shared/markdown-content-styles.css +6 -0
- package/dist/shared/stack.DorMi9CZ.d.cts +0 -80
- package/dist/shared/stack.DorMi9CZ.d.mts +0 -80
- package/dist/shared/stack.DorMi9CZ.d.ts +0 -80
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Accordion,
|
|
5
|
+
AccordionContent,
|
|
6
|
+
AccordionItem,
|
|
7
|
+
AccordionTrigger,
|
|
8
|
+
} from "@workspace/ui/components/accordion";
|
|
9
|
+
import { MarkdownContent } from "@workspace/ui/components/markdown-content";
|
|
10
|
+
import { Skeleton } from "@workspace/ui/components/skeleton";
|
|
11
|
+
import { cn } from "@workspace/ui/lib/utils";
|
|
12
|
+
import { Wrench, Check, AlertCircle, Loader2 } from "lucide-react";
|
|
13
|
+
import type { ToolCallProps, ToolCallState } from "../overrides";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Formats a tool name for display (converts camelCase/snake_case to Title Case)
|
|
17
|
+
*/
|
|
18
|
+
function formatToolName(name: string): string {
|
|
19
|
+
return (
|
|
20
|
+
name
|
|
21
|
+
// Insert space before uppercase letters (camelCase)
|
|
22
|
+
.replace(/([A-Z])/g, " $1")
|
|
23
|
+
// Replace underscores and hyphens with spaces
|
|
24
|
+
.replace(/[_-]/g, " ")
|
|
25
|
+
// Capitalize first letter of each word
|
|
26
|
+
.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
27
|
+
.trim()
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the appropriate status icon based on tool call state
|
|
33
|
+
*/
|
|
34
|
+
function getStatusIcon(state: ToolCallState, isLoading: boolean) {
|
|
35
|
+
if (isLoading || state === "input-streaming" || state === "input-available") {
|
|
36
|
+
return (
|
|
37
|
+
<Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground" />
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (state === "output-error") {
|
|
41
|
+
return <AlertCircle className="h-3.5 w-3.5 text-destructive" />;
|
|
42
|
+
}
|
|
43
|
+
if (state === "output-available") {
|
|
44
|
+
return <Check className="h-3.5 w-3.5 text-green-500" />;
|
|
45
|
+
}
|
|
46
|
+
return <Wrench className="h-3.5 w-3.5 text-muted-foreground" />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Returns a human-readable status label based on tool call state
|
|
51
|
+
*/
|
|
52
|
+
function getStatusLabel(state: ToolCallState, isLoading: boolean): string {
|
|
53
|
+
if (isLoading || state === "input-streaming") {
|
|
54
|
+
return "Running...";
|
|
55
|
+
}
|
|
56
|
+
if (state === "input-available") {
|
|
57
|
+
return "Executing...";
|
|
58
|
+
}
|
|
59
|
+
if (state === "output-error") {
|
|
60
|
+
return "Error";
|
|
61
|
+
}
|
|
62
|
+
if (state === "output-available") {
|
|
63
|
+
return "Complete";
|
|
64
|
+
}
|
|
65
|
+
return "Pending";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface JsonDisplayProps {
|
|
69
|
+
data: unknown;
|
|
70
|
+
label: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Renders JSON data using MarkdownContent with syntax highlighting
|
|
75
|
+
*/
|
|
76
|
+
function JsonDisplay({ data, label }: JsonDisplayProps) {
|
|
77
|
+
if (data === undefined || data === null) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Format JSON with proper indentation
|
|
82
|
+
let jsonString: string;
|
|
83
|
+
try {
|
|
84
|
+
jsonString = JSON.stringify(data, null, 2);
|
|
85
|
+
} catch {
|
|
86
|
+
jsonString = String(data);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Wrap in markdown code fence for syntax highlighting
|
|
90
|
+
const markdown = `\`\`\`json\n${jsonString}\n\`\`\``;
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div className="space-y-1">
|
|
94
|
+
<span className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
95
|
+
{label}
|
|
96
|
+
</span>
|
|
97
|
+
<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">
|
|
98
|
+
<MarkdownContent markdown={markdown} variant="chat" />
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Default tool call display component.
|
|
106
|
+
* Shows an accordion with tool name, status, inputs, and outputs.
|
|
107
|
+
*/
|
|
108
|
+
export function ToolCallDisplay({
|
|
109
|
+
toolCallId,
|
|
110
|
+
toolName,
|
|
111
|
+
state,
|
|
112
|
+
input,
|
|
113
|
+
output,
|
|
114
|
+
errorText,
|
|
115
|
+
isLoading,
|
|
116
|
+
}: ToolCallProps) {
|
|
117
|
+
const displayName = formatToolName(toolName);
|
|
118
|
+
const statusLabel = getStatusLabel(state, isLoading);
|
|
119
|
+
const statusIcon = getStatusIcon(state, isLoading);
|
|
120
|
+
|
|
121
|
+
const isComplete = state === "output-available" || state === "output-error";
|
|
122
|
+
const hasError = state === "output-error";
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<Accordion type="single" collapsible className="w-full">
|
|
126
|
+
<AccordionItem
|
|
127
|
+
value={toolCallId}
|
|
128
|
+
className={cn(
|
|
129
|
+
"!border rounded-lg overflow-hidden transition-colors",
|
|
130
|
+
hasError && "border-destructive/50",
|
|
131
|
+
!hasError && isComplete && "border-green-500/30",
|
|
132
|
+
!isComplete && "border-border/50",
|
|
133
|
+
)}
|
|
134
|
+
>
|
|
135
|
+
<AccordionTrigger
|
|
136
|
+
className={cn("px-3 py-2 hover:no-underline hover:bg-muted/50")}
|
|
137
|
+
>
|
|
138
|
+
<div className="flex items-center gap-2 w-full">
|
|
139
|
+
<Wrench className="h-4 w-4 text-muted-foreground shrink-0" />
|
|
140
|
+
<span className="text-sm font-medium truncate text-left">
|
|
141
|
+
{displayName}
|
|
142
|
+
</span>
|
|
143
|
+
<span className="flex items-center gap-1.5 text-xs text-muted-foreground shrink-0">
|
|
144
|
+
{statusIcon}
|
|
145
|
+
<span className="sr-only">{statusLabel}</span>
|
|
146
|
+
</span>
|
|
147
|
+
</div>
|
|
148
|
+
</AccordionTrigger>
|
|
149
|
+
|
|
150
|
+
<AccordionContent className="px-3 pb-3 pt-0">
|
|
151
|
+
<div className="space-y-3 border-t border-border/50 pt-3">
|
|
152
|
+
{/* Loading skeleton when input is streaming */}
|
|
153
|
+
{state === "input-streaming" && !input && (
|
|
154
|
+
<div className="space-y-2">
|
|
155
|
+
<Skeleton className="h-4 w-24" />
|
|
156
|
+
<Skeleton className="h-16 w-full" />
|
|
157
|
+
</div>
|
|
158
|
+
)}
|
|
159
|
+
|
|
160
|
+
{/* Input section */}
|
|
161
|
+
{input !== undefined && <JsonDisplay data={input} label="Input" />}
|
|
162
|
+
|
|
163
|
+
{/* Output section */}
|
|
164
|
+
{state === "output-available" && output !== undefined && (
|
|
165
|
+
<JsonDisplay data={output} label="Output" />
|
|
166
|
+
)}
|
|
167
|
+
|
|
168
|
+
{/* Error section */}
|
|
169
|
+
{state === "output-error" && errorText && (
|
|
170
|
+
<div className="space-y-1">
|
|
171
|
+
<span className="text-xs font-medium text-destructive uppercase tracking-wide">
|
|
172
|
+
Error
|
|
173
|
+
</span>
|
|
174
|
+
<div className="text-xs text-destructive bg-destructive/10 p-2 rounded-md">
|
|
175
|
+
{errorText}
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
)}
|
|
179
|
+
|
|
180
|
+
{/* Loading skeleton for output */}
|
|
181
|
+
{(state === "input-available" || state === "input-streaming") && (
|
|
182
|
+
<div className="space-y-2">
|
|
183
|
+
<Skeleton className="h-4 w-20" />
|
|
184
|
+
<Skeleton className="h-12 w-full" />
|
|
185
|
+
</div>
|
|
186
|
+
)}
|
|
187
|
+
|
|
188
|
+
{/* Tool call ID for debugging (collapsed by default) */}
|
|
189
|
+
<div className="text-[10px] text-muted-foreground/50 truncate">
|
|
190
|
+
ID: {toolCallId}
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</AccordionContent>
|
|
194
|
+
</AccordionItem>
|
|
195
|
+
</Accordion>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
@@ -5,10 +5,21 @@ export type {
|
|
|
5
5
|
RouteContext,
|
|
6
6
|
LoaderContext,
|
|
7
7
|
} from "./plugin";
|
|
8
|
-
export type {
|
|
8
|
+
export type {
|
|
9
|
+
AiChatPluginOverrides,
|
|
10
|
+
AllowedFileType,
|
|
11
|
+
ToolCallProps,
|
|
12
|
+
ToolCallState,
|
|
13
|
+
ToolCallRenderer,
|
|
14
|
+
} from "./overrides";
|
|
9
15
|
export { DEFAULT_ALLOWED_FILE_TYPES } from "./overrides";
|
|
10
16
|
export { ChatInterface } from "./components/chat-interface";
|
|
11
17
|
export { ChatLayout } from "./components/chat-layout";
|
|
18
|
+
export type { ChatLayoutProps } from "./components/chat-layout";
|
|
12
19
|
export { ChatSidebar } from "./components/chat-sidebar";
|
|
13
20
|
export { ChatMessage } from "./components/chat-message";
|
|
14
21
|
export { ChatInput } from "./components/chat-input";
|
|
22
|
+
export { ToolCallDisplay } from "./components/tool-call-display";
|
|
23
|
+
|
|
24
|
+
// Re-export UIMessage type from AI SDK for consumer convenience
|
|
25
|
+
export type { UIMessage } from "ai";
|
|
@@ -8,6 +8,44 @@ import type { AiChatLocalization } from "./localization";
|
|
|
8
8
|
*/
|
|
9
9
|
export type AiChatMode = "authenticated" | "public";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* State of a tool call execution
|
|
13
|
+
*/
|
|
14
|
+
export type ToolCallState =
|
|
15
|
+
| "input-streaming"
|
|
16
|
+
| "input-available"
|
|
17
|
+
| "output-available"
|
|
18
|
+
| "output-error";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Props passed to custom tool call renderer components
|
|
22
|
+
*/
|
|
23
|
+
export interface ToolCallProps<TInput = unknown, TOutput = unknown> {
|
|
24
|
+
/** Unique identifier for this tool call */
|
|
25
|
+
toolCallId: string;
|
|
26
|
+
/** Name of the tool being called */
|
|
27
|
+
toolName: string;
|
|
28
|
+
/** Current state of the tool call execution */
|
|
29
|
+
state: ToolCallState;
|
|
30
|
+
/** Input arguments passed to the tool (may be partial during streaming) */
|
|
31
|
+
input: TInput | undefined;
|
|
32
|
+
/** Output from the tool (only available when state is 'output-available') */
|
|
33
|
+
output: TOutput | undefined;
|
|
34
|
+
/** Error message (only available when state is 'output-error') */
|
|
35
|
+
errorText?: string;
|
|
36
|
+
/** Whether the tool call is currently in progress */
|
|
37
|
+
isLoading: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A component that renders a custom UI for a specific tool call.
|
|
42
|
+
* Return `null` to fall back to the default tool call accordion.
|
|
43
|
+
*/
|
|
44
|
+
export type ToolCallRenderer<
|
|
45
|
+
TInput = unknown,
|
|
46
|
+
TOutput = unknown,
|
|
47
|
+
> = ComponentType<ToolCallProps<TInput, TOutput>>;
|
|
48
|
+
|
|
11
49
|
/**
|
|
12
50
|
* Allowed file type categories for uploads
|
|
13
51
|
*/
|
|
@@ -126,6 +164,39 @@ export interface AiChatPluginOverrides {
|
|
|
126
164
|
*/
|
|
127
165
|
showAttribution?: boolean;
|
|
128
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Suggested prompts to display in the empty chat state.
|
|
169
|
+
* When provided, these appear as clickable buttons that populate the input field.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```tsx
|
|
173
|
+
* chatSuggestions: [
|
|
174
|
+
* "What can you help me with?",
|
|
175
|
+
* "Tell me about your features",
|
|
176
|
+
* "How do I get started?",
|
|
177
|
+
* ]
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
chatSuggestions?: string[];
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Custom renderers for tool calls. Keys should match tool names.
|
|
184
|
+
* Each renderer receives ToolCallProps and can return custom UI.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```tsx
|
|
188
|
+
* toolRenderers: {
|
|
189
|
+
* getWeather: ({ toolName, input, output, state, isLoading }) => (
|
|
190
|
+
* <WeatherCard location={input?.location} weather={output} loading={isLoading} />
|
|
191
|
+
* ),
|
|
192
|
+
* searchDocs: ({ input, output, isLoading }) => (
|
|
193
|
+
* <SearchResults query={input?.query} results={output} loading={isLoading} />
|
|
194
|
+
* ),
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
toolRenderers?: Record<string, ToolCallRenderer>;
|
|
199
|
+
|
|
129
200
|
// ============== Lifecycle Hooks (optional) ==============
|
|
130
201
|
|
|
131
202
|
/**
|
|
@@ -158,6 +158,9 @@
|
|
|
158
158
|
.markdown-content .markdown-inner .markdown-body .hljs-params {
|
|
159
159
|
color: #ffb86c;
|
|
160
160
|
}
|
|
161
|
+
.markdown-content .markdown-inner .markdown-body .hljs-punctuation {
|
|
162
|
+
color: #c9d1d9;
|
|
163
|
+
}
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
/* Also support Tailwind dark class for dark mode */
|
|
@@ -167,6 +170,9 @@
|
|
|
167
170
|
.dark .markdown-content .markdown-inner .markdown-body .hljs-params {
|
|
168
171
|
color: #ffb86c;
|
|
169
172
|
}
|
|
173
|
+
.dark .markdown-content .markdown-inner .markdown-body .hljs-punctuation {
|
|
174
|
+
color: #c9d1d9;
|
|
175
|
+
}
|
|
170
176
|
|
|
171
177
|
.markdown-content .markdown-inner .markdown-code-block {
|
|
172
178
|
display: block;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { UIMessage } from 'ai';
|
|
3
|
-
import { FormEvent } from 'react';
|
|
4
|
-
|
|
5
|
-
interface ChatInterfaceProps {
|
|
6
|
-
apiPath?: string;
|
|
7
|
-
initialMessages?: UIMessage[];
|
|
8
|
-
id?: string;
|
|
9
|
-
/** Variant: 'full' for full-page layout, 'widget' for embedded widget */
|
|
10
|
-
variant?: "full" | "widget";
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
declare function ChatInterface({ apiPath, initialMessages, id, variant, className, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
interface ChatLayoutProps {
|
|
16
|
-
/** API base URL */
|
|
17
|
-
apiBaseURL: string;
|
|
18
|
-
/** API base path */
|
|
19
|
-
apiBasePath: string;
|
|
20
|
-
/** Current conversation ID (if viewing existing conversation) */
|
|
21
|
-
conversationId?: string;
|
|
22
|
-
/** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
|
|
23
|
-
layout?: "full" | "widget";
|
|
24
|
-
/** Additional class name for the container */
|
|
25
|
-
className?: string;
|
|
26
|
-
/** Whether to show the sidebar (default: true for full layout) */
|
|
27
|
-
showSidebar?: boolean;
|
|
28
|
-
/** Height of the widget (only applies to widget layout) */
|
|
29
|
-
widgetHeight?: string | number;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* ChatLayout component that provides a full-page chat experience with sidebar
|
|
33
|
-
* or a compact widget mode for embedding.
|
|
34
|
-
*/
|
|
35
|
-
declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
|
|
36
|
-
|
|
37
|
-
interface ChatSidebarProps {
|
|
38
|
-
currentConversationId?: string;
|
|
39
|
-
onNewChat?: () => void;
|
|
40
|
-
className?: string;
|
|
41
|
-
}
|
|
42
|
-
declare function ChatSidebar({ currentConversationId, onNewChat, className, }: ChatSidebarProps): react_jsx_runtime.JSX.Element;
|
|
43
|
-
|
|
44
|
-
interface ChatMessageProps {
|
|
45
|
-
message: UIMessage;
|
|
46
|
-
isStreaming?: boolean;
|
|
47
|
-
variant?: "default" | "compact";
|
|
48
|
-
/** Callback when user wants to retry/regenerate an AI response */
|
|
49
|
-
onRetry?: () => void;
|
|
50
|
-
/** Callback when user edits their message - receives the new text */
|
|
51
|
-
onEdit?: (newText: string) => void;
|
|
52
|
-
/** Whether retry is currently in progress */
|
|
53
|
-
isRetrying?: boolean;
|
|
54
|
-
}
|
|
55
|
-
declare function ChatMessage({ message, isStreaming, variant, onRetry, onEdit, isRetrying, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
|
|
56
|
-
|
|
57
|
-
/** Represents an attached file with metadata */
|
|
58
|
-
interface AttachedFile {
|
|
59
|
-
/** Data URL or uploaded URL */
|
|
60
|
-
url: string;
|
|
61
|
-
/** MIME type of the file */
|
|
62
|
-
mediaType: string;
|
|
63
|
-
/** Original filename */
|
|
64
|
-
filename: string;
|
|
65
|
-
}
|
|
66
|
-
interface ChatInputProps {
|
|
67
|
-
input?: string;
|
|
68
|
-
handleInputChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
69
|
-
handleSubmit: (e: FormEvent<HTMLFormElement>, files?: AttachedFile[]) => void;
|
|
70
|
-
isLoading: boolean;
|
|
71
|
-
placeholder?: string;
|
|
72
|
-
variant?: "default" | "compact";
|
|
73
|
-
/** Callback when files are attached (for controlled mode) */
|
|
74
|
-
onFilesAttached?: (files: AttachedFile[]) => void;
|
|
75
|
-
/** Attached files (for controlled mode) */
|
|
76
|
-
attachedFiles?: AttachedFile[];
|
|
77
|
-
}
|
|
78
|
-
declare function ChatInput({ input, handleInputChange, handleSubmit, isLoading, placeholder, variant, onFilesAttached, attachedFiles: controlledFiles, }: ChatInputProps): react_jsx_runtime.JSX.Element;
|
|
79
|
-
|
|
80
|
-
export { ChatInterface as C, ChatLayout as a, ChatSidebar as b, ChatMessage as c, ChatInput as d };
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { UIMessage } from 'ai';
|
|
3
|
-
import { FormEvent } from 'react';
|
|
4
|
-
|
|
5
|
-
interface ChatInterfaceProps {
|
|
6
|
-
apiPath?: string;
|
|
7
|
-
initialMessages?: UIMessage[];
|
|
8
|
-
id?: string;
|
|
9
|
-
/** Variant: 'full' for full-page layout, 'widget' for embedded widget */
|
|
10
|
-
variant?: "full" | "widget";
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
declare function ChatInterface({ apiPath, initialMessages, id, variant, className, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
interface ChatLayoutProps {
|
|
16
|
-
/** API base URL */
|
|
17
|
-
apiBaseURL: string;
|
|
18
|
-
/** API base path */
|
|
19
|
-
apiBasePath: string;
|
|
20
|
-
/** Current conversation ID (if viewing existing conversation) */
|
|
21
|
-
conversationId?: string;
|
|
22
|
-
/** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
|
|
23
|
-
layout?: "full" | "widget";
|
|
24
|
-
/** Additional class name for the container */
|
|
25
|
-
className?: string;
|
|
26
|
-
/** Whether to show the sidebar (default: true for full layout) */
|
|
27
|
-
showSidebar?: boolean;
|
|
28
|
-
/** Height of the widget (only applies to widget layout) */
|
|
29
|
-
widgetHeight?: string | number;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* ChatLayout component that provides a full-page chat experience with sidebar
|
|
33
|
-
* or a compact widget mode for embedding.
|
|
34
|
-
*/
|
|
35
|
-
declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
|
|
36
|
-
|
|
37
|
-
interface ChatSidebarProps {
|
|
38
|
-
currentConversationId?: string;
|
|
39
|
-
onNewChat?: () => void;
|
|
40
|
-
className?: string;
|
|
41
|
-
}
|
|
42
|
-
declare function ChatSidebar({ currentConversationId, onNewChat, className, }: ChatSidebarProps): react_jsx_runtime.JSX.Element;
|
|
43
|
-
|
|
44
|
-
interface ChatMessageProps {
|
|
45
|
-
message: UIMessage;
|
|
46
|
-
isStreaming?: boolean;
|
|
47
|
-
variant?: "default" | "compact";
|
|
48
|
-
/** Callback when user wants to retry/regenerate an AI response */
|
|
49
|
-
onRetry?: () => void;
|
|
50
|
-
/** Callback when user edits their message - receives the new text */
|
|
51
|
-
onEdit?: (newText: string) => void;
|
|
52
|
-
/** Whether retry is currently in progress */
|
|
53
|
-
isRetrying?: boolean;
|
|
54
|
-
}
|
|
55
|
-
declare function ChatMessage({ message, isStreaming, variant, onRetry, onEdit, isRetrying, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
|
|
56
|
-
|
|
57
|
-
/** Represents an attached file with metadata */
|
|
58
|
-
interface AttachedFile {
|
|
59
|
-
/** Data URL or uploaded URL */
|
|
60
|
-
url: string;
|
|
61
|
-
/** MIME type of the file */
|
|
62
|
-
mediaType: string;
|
|
63
|
-
/** Original filename */
|
|
64
|
-
filename: string;
|
|
65
|
-
}
|
|
66
|
-
interface ChatInputProps {
|
|
67
|
-
input?: string;
|
|
68
|
-
handleInputChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
69
|
-
handleSubmit: (e: FormEvent<HTMLFormElement>, files?: AttachedFile[]) => void;
|
|
70
|
-
isLoading: boolean;
|
|
71
|
-
placeholder?: string;
|
|
72
|
-
variant?: "default" | "compact";
|
|
73
|
-
/** Callback when files are attached (for controlled mode) */
|
|
74
|
-
onFilesAttached?: (files: AttachedFile[]) => void;
|
|
75
|
-
/** Attached files (for controlled mode) */
|
|
76
|
-
attachedFiles?: AttachedFile[];
|
|
77
|
-
}
|
|
78
|
-
declare function ChatInput({ input, handleInputChange, handleSubmit, isLoading, placeholder, variant, onFilesAttached, attachedFiles: controlledFiles, }: ChatInputProps): react_jsx_runtime.JSX.Element;
|
|
79
|
-
|
|
80
|
-
export { ChatInterface as C, ChatLayout as a, ChatSidebar as b, ChatMessage as c, ChatInput as d };
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { UIMessage } from 'ai';
|
|
3
|
-
import { FormEvent } from 'react';
|
|
4
|
-
|
|
5
|
-
interface ChatInterfaceProps {
|
|
6
|
-
apiPath?: string;
|
|
7
|
-
initialMessages?: UIMessage[];
|
|
8
|
-
id?: string;
|
|
9
|
-
/** Variant: 'full' for full-page layout, 'widget' for embedded widget */
|
|
10
|
-
variant?: "full" | "widget";
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
declare function ChatInterface({ apiPath, initialMessages, id, variant, className, }: ChatInterfaceProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
interface ChatLayoutProps {
|
|
16
|
-
/** API base URL */
|
|
17
|
-
apiBaseURL: string;
|
|
18
|
-
/** API base path */
|
|
19
|
-
apiBasePath: string;
|
|
20
|
-
/** Current conversation ID (if viewing existing conversation) */
|
|
21
|
-
conversationId?: string;
|
|
22
|
-
/** Layout mode: 'full' for full page with sidebar, 'widget' for embeddable widget */
|
|
23
|
-
layout?: "full" | "widget";
|
|
24
|
-
/** Additional class name for the container */
|
|
25
|
-
className?: string;
|
|
26
|
-
/** Whether to show the sidebar (default: true for full layout) */
|
|
27
|
-
showSidebar?: boolean;
|
|
28
|
-
/** Height of the widget (only applies to widget layout) */
|
|
29
|
-
widgetHeight?: string | number;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* ChatLayout component that provides a full-page chat experience with sidebar
|
|
33
|
-
* or a compact widget mode for embedding.
|
|
34
|
-
*/
|
|
35
|
-
declare function ChatLayout({ apiBaseURL, apiBasePath, conversationId, layout, className, showSidebar, widgetHeight, }: ChatLayoutProps): react_jsx_runtime.JSX.Element;
|
|
36
|
-
|
|
37
|
-
interface ChatSidebarProps {
|
|
38
|
-
currentConversationId?: string;
|
|
39
|
-
onNewChat?: () => void;
|
|
40
|
-
className?: string;
|
|
41
|
-
}
|
|
42
|
-
declare function ChatSidebar({ currentConversationId, onNewChat, className, }: ChatSidebarProps): react_jsx_runtime.JSX.Element;
|
|
43
|
-
|
|
44
|
-
interface ChatMessageProps {
|
|
45
|
-
message: UIMessage;
|
|
46
|
-
isStreaming?: boolean;
|
|
47
|
-
variant?: "default" | "compact";
|
|
48
|
-
/** Callback when user wants to retry/regenerate an AI response */
|
|
49
|
-
onRetry?: () => void;
|
|
50
|
-
/** Callback when user edits their message - receives the new text */
|
|
51
|
-
onEdit?: (newText: string) => void;
|
|
52
|
-
/** Whether retry is currently in progress */
|
|
53
|
-
isRetrying?: boolean;
|
|
54
|
-
}
|
|
55
|
-
declare function ChatMessage({ message, isStreaming, variant, onRetry, onEdit, isRetrying, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
|
|
56
|
-
|
|
57
|
-
/** Represents an attached file with metadata */
|
|
58
|
-
interface AttachedFile {
|
|
59
|
-
/** Data URL or uploaded URL */
|
|
60
|
-
url: string;
|
|
61
|
-
/** MIME type of the file */
|
|
62
|
-
mediaType: string;
|
|
63
|
-
/** Original filename */
|
|
64
|
-
filename: string;
|
|
65
|
-
}
|
|
66
|
-
interface ChatInputProps {
|
|
67
|
-
input?: string;
|
|
68
|
-
handleInputChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
69
|
-
handleSubmit: (e: FormEvent<HTMLFormElement>, files?: AttachedFile[]) => void;
|
|
70
|
-
isLoading: boolean;
|
|
71
|
-
placeholder?: string;
|
|
72
|
-
variant?: "default" | "compact";
|
|
73
|
-
/** Callback when files are attached (for controlled mode) */
|
|
74
|
-
onFilesAttached?: (files: AttachedFile[]) => void;
|
|
75
|
-
/** Attached files (for controlled mode) */
|
|
76
|
-
attachedFiles?: AttachedFile[];
|
|
77
|
-
}
|
|
78
|
-
declare function ChatInput({ input, handleInputChange, handleSubmit, isLoading, placeholder, variant, onFilesAttached, attachedFiles: controlledFiles, }: ChatInputProps): react_jsx_runtime.JSX.Element;
|
|
79
|
-
|
|
80
|
-
export { ChatInterface as C, ChatLayout as a, ChatSidebar as b, ChatMessage as c, ChatInput as d };
|