@braedonsaunders/appkit-ai 1.1.1 → 1.1.3
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/README.md +38 -0
- package/package.json +1 -1
- package/react.d.ts +50 -1
- package/react.d.ts.map +1 -1
- package/react.js +174 -9
- package/react.js.map +1 -1
package/README.md
CHANGED
|
@@ -24,6 +24,44 @@ plus parts for the optimistic user turn. Persisted user messages can include
|
|
|
24
24
|
`{ type: 'file', filename, url? }` parts, which render as compact attachment
|
|
25
25
|
links.
|
|
26
26
|
|
|
27
|
+
While the first assistant parts are streaming, `AgentPanel` renders a subtle
|
|
28
|
+
three-dot typing cadence through the exported `AgentTypingIndicator`. Its pure
|
|
29
|
+
CSS motion uses AppKit duration/easing tokens, is independent of an app's
|
|
30
|
+
Tailwind content scan, and becomes a static ellipsis under reduced motion.
|
|
31
|
+
|
|
32
|
+
Assistant messages may also contain a typed `secret-request` part with a
|
|
33
|
+
request id, provider label, credential label, purpose, optional HTTPS help URL,
|
|
34
|
+
and `pending`, `stored`, or `expired` status. `AgentPanel` renders the exported
|
|
35
|
+
`AgentSecretRequestCard` inline and delegates submission and cancellation to
|
|
36
|
+
`onSubmitSecretRequest` / `onCancelSecretRequest`. The credential is held only
|
|
37
|
+
in the uncontrolled password field, cleared before the submit handler runs,
|
|
38
|
+
and never added to message parts, React state, rendered text, or AppKit-owned
|
|
39
|
+
persistence. The application remains responsible for authorization, sealing,
|
|
40
|
+
storage, audit, and updating the durable request status.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<AgentPanel
|
|
44
|
+
enabled
|
|
45
|
+
initialMessages={[{
|
|
46
|
+
id: 'assistant-credential',
|
|
47
|
+
role: 'assistant',
|
|
48
|
+
parts: [{
|
|
49
|
+
type: 'secret-request',
|
|
50
|
+
requestId: request.id,
|
|
51
|
+
providerLabel: 'Delivery provider',
|
|
52
|
+
credentialLabel: 'API key',
|
|
53
|
+
purpose: 'Authorize approved carrier status updates.',
|
|
54
|
+
helpUrl: 'https://provider.example/docs/api-keys',
|
|
55
|
+
status: request.status,
|
|
56
|
+
}],
|
|
57
|
+
}]}
|
|
58
|
+
onSubmitSecretRequest={async (requestId, secret) => {
|
|
59
|
+
await storeSealedCredential({ requestId, secret })
|
|
60
|
+
}}
|
|
61
|
+
onCancelSecretRequest={expireCredentialRequest}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
27
65
|
Applications with durable session dispatch can pass `dispatchState` and an
|
|
28
66
|
ordered `queuedMessages` collection. While work is running, recovering, or
|
|
29
67
|
already queued, new composer submissions go through the app-owned `enqueue`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@braedonsaunders/appkit-ai",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "App-agnostic bounded agent loop and streaming assistant interface, with provider policy supplied by the host app.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
package/react.d.ts
CHANGED
|
@@ -14,6 +14,30 @@ export type AgentQueuedMessage = {
|
|
|
14
14
|
removable?: boolean;
|
|
15
15
|
retryable?: boolean;
|
|
16
16
|
};
|
|
17
|
+
export type AgentSecretRequestStatus = 'pending' | 'stored' | 'expired';
|
|
18
|
+
/** Transcript-safe metadata for an inline credential request. */
|
|
19
|
+
export type AgentSecretRequestPart = {
|
|
20
|
+
type: 'secret-request';
|
|
21
|
+
requestId: string;
|
|
22
|
+
providerLabel: string;
|
|
23
|
+
credentialLabel: string;
|
|
24
|
+
purpose: string;
|
|
25
|
+
helpUrl?: string;
|
|
26
|
+
status: AgentSecretRequestStatus;
|
|
27
|
+
};
|
|
28
|
+
export type AgentSecretRequestLabels = {
|
|
29
|
+
show: string;
|
|
30
|
+
hide: string;
|
|
31
|
+
submit: string;
|
|
32
|
+
cancel: string;
|
|
33
|
+
help: string;
|
|
34
|
+
submitting: string;
|
|
35
|
+
stored: string;
|
|
36
|
+
expired: string;
|
|
37
|
+
required: string;
|
|
38
|
+
failed: string;
|
|
39
|
+
cancelFailed: string;
|
|
40
|
+
};
|
|
17
41
|
export type AgentDispatchState = 'idle' | 'running' | 'recovering';
|
|
18
42
|
export type AgentPanelLabels = {
|
|
19
43
|
title: string;
|
|
@@ -40,6 +64,7 @@ export type AgentPanelLabels = {
|
|
|
40
64
|
editQueued: string;
|
|
41
65
|
removeQueued: string;
|
|
42
66
|
retryQueued: string;
|
|
67
|
+
responding: string;
|
|
43
68
|
};
|
|
44
69
|
export type AgentPanelProps = {
|
|
45
70
|
enabled: boolean;
|
|
@@ -72,6 +97,10 @@ export type AgentPanelProps = {
|
|
|
72
97
|
onEditQueuedMessage?: (message: AgentQueuedMessage) => void;
|
|
73
98
|
onRemoveQueuedMessage?: (message: AgentQueuedMessage) => void;
|
|
74
99
|
onRetryQueuedMessage?: (message: AgentQueuedMessage) => void;
|
|
100
|
+
/** Receives the transient input value after AppKit clears the field. */
|
|
101
|
+
onSubmitSecretRequest?: (requestId: string, secret: string) => void | Promise<void>;
|
|
102
|
+
onCancelSecretRequest?: (requestId: string) => void | Promise<void>;
|
|
103
|
+
secretRequestLabels?: Partial<AgentSecretRequestLabels>;
|
|
75
104
|
maxPromptCharacters?: number;
|
|
76
105
|
toolLabels?: Record<string, string>;
|
|
77
106
|
};
|
|
@@ -80,7 +109,7 @@ export type AgentPanelProps = {
|
|
|
80
109
|
* owns persistence and the HTTP transport; appkit owns UI-message decoding,
|
|
81
110
|
* cancellation, ordered part rendering, and tool cards.
|
|
82
111
|
*/
|
|
83
|
-
export declare function AgentPanel({ enabled, initialMessages, suggestions, labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState, queuedMessages, enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, maxPromptCharacters, toolLabels, }: AgentPanelProps): React.JSX.Element;
|
|
112
|
+
export declare function AgentPanel({ enabled, initialMessages, suggestions, labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState, queuedMessages, enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, maxPromptCharacters, toolLabels, }: AgentPanelProps): React.JSX.Element;
|
|
84
113
|
export declare function AgentMessageQueue({ messages, labels: labelOverrides, onEdit, onRemove, onRetry, }: {
|
|
85
114
|
messages: readonly AgentQueuedMessage[];
|
|
86
115
|
labels?: Partial<AgentPanelLabels>;
|
|
@@ -88,6 +117,26 @@ export declare function AgentMessageQueue({ messages, labels: labelOverrides, on
|
|
|
88
117
|
onRemove?: (message: AgentQueuedMessage) => void;
|
|
89
118
|
onRetry?: (message: AgentQueuedMessage) => void;
|
|
90
119
|
}): React.JSX.Element;
|
|
120
|
+
/**
|
|
121
|
+
* A self-contained streaming cue that does not depend on the consuming app's
|
|
122
|
+
* Tailwind content scan. The cadence uses AppKit motion tokens and becomes a
|
|
123
|
+
* still, readable ellipsis when the user requests reduced motion.
|
|
124
|
+
*/
|
|
125
|
+
export declare function AgentTypingIndicator({ label }: {
|
|
126
|
+
label?: string;
|
|
127
|
+
}): React.JSX.Element;
|
|
128
|
+
export type AgentSecretRequestCardProps = {
|
|
129
|
+
request: AgentSecretRequestPart;
|
|
130
|
+
labels?: Partial<AgentSecretRequestLabels>;
|
|
131
|
+
onSubmit?: (requestId: string, secret: string) => void | Promise<void>;
|
|
132
|
+
onCancel?: (requestId: string) => void | Promise<void>;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Inline credential handoff for an assistant transcript. The password field is
|
|
136
|
+
* uncontrolled: its value is read directly from the DOM, cleared before the
|
|
137
|
+
* caller receives it, and never copied into React or transcript state.
|
|
138
|
+
*/
|
|
139
|
+
export declare function AgentSecretRequestCard({ request, labels: labelOverrides, onSubmit, onCancel }: AgentSecretRequestCardProps): React.JSX.Element;
|
|
91
140
|
export declare function ChatMarkdown({ children }: {
|
|
92
141
|
children: string;
|
|
93
142
|
}): React.JSX.Element;
|
package/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
package/react.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { parseJsonEventStream, readUIMessageStream, uiMessageChunkSchema, } from 'ai';
|
|
5
|
-
import { AlertCircle, CheckCircle2, ChevronRight, Database, ListPlus, Loader2, Pencil, RotateCcw, Send, Sparkles, Square, Trash2, } from 'lucide-react';
|
|
5
|
+
import { AlertCircle, CheckCircle2, ChevronRight, Database, ExternalLink, Eye, EyeOff, KeyRound, ListPlus, Loader2, Pencil, RotateCcw, Send, Sparkles, Square, Trash2, } from 'lucide-react';
|
|
6
6
|
import Markdown from 'react-markdown';
|
|
7
7
|
import remarkGfm from 'remark-gfm';
|
|
8
|
-
import { Button, EmptyState, UiLink, cn } from '@braedonsaunders/appkit-ui';
|
|
8
|
+
import { Button, EmptyState, Input, UiLink, cn } from '@braedonsaunders/appkit-ui';
|
|
9
|
+
const DEFAULT_SECRET_REQUEST_LABELS = {
|
|
10
|
+
show: 'Show credential',
|
|
11
|
+
hide: 'Hide credential',
|
|
12
|
+
submit: 'Submit securely',
|
|
13
|
+
cancel: 'Cancel',
|
|
14
|
+
help: 'Open setup instructions',
|
|
15
|
+
submitting: 'Submitting securely',
|
|
16
|
+
stored: 'Credential stored securely.',
|
|
17
|
+
expired: 'This credential request has expired.',
|
|
18
|
+
required: 'Enter the credential before submitting.',
|
|
19
|
+
failed: 'The credential could not be submitted. Enter it again and retry.',
|
|
20
|
+
cancelFailed: 'The credential request could not be canceled. Please retry.',
|
|
21
|
+
};
|
|
9
22
|
const DEFAULT_LABELS = {
|
|
10
23
|
title: 'Assistant',
|
|
11
24
|
welcomeTitle: 'How can I help?',
|
|
@@ -31,13 +44,14 @@ const DEFAULT_LABELS = {
|
|
|
31
44
|
editQueued: 'Edit queued message',
|
|
32
45
|
removeQueued: 'Remove queued message',
|
|
33
46
|
retryQueued: 'Retry queued message',
|
|
47
|
+
responding: 'Assistant is responding',
|
|
34
48
|
};
|
|
35
49
|
/**
|
|
36
50
|
* The streaming thread/composer extracted from the sibling assistant. The app
|
|
37
51
|
* owns persistence and the HTTP transport; appkit owns UI-message decoding,
|
|
38
52
|
* cancellation, ordered part rendering, and tool cards.
|
|
39
53
|
*/
|
|
40
|
-
export function AgentPanel({ enabled, initialMessages = [], suggestions = [], labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState = 'idle', queuedMessages = [], enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, maxPromptCharacters = 32_000, toolLabels, }) {
|
|
54
|
+
export function AgentPanel({ enabled, initialMessages = [], suggestions = [], labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState = 'idle', queuedMessages = [], enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, maxPromptCharacters = 32_000, toolLabels, }) {
|
|
41
55
|
const labels = { ...DEFAULT_LABELS, ...labelOverrides };
|
|
42
56
|
const [messages, setMessages] = React.useState(initialMessages);
|
|
43
57
|
const [input, setInput] = React.useState('');
|
|
@@ -122,7 +136,7 @@ export function AgentPanel({ enabled, initialMessages = [], suggestions = [], la
|
|
|
122
136
|
}
|
|
123
137
|
}, [composerDraft, dispatchState, enabled, enqueue, enqueueing, labels.failed, labels.queueFailed, maxPromptCharacters, queuedMessages.length, scrollToBottom, send]);
|
|
124
138
|
const queueMode = dispatchState !== 'idle' || streaming || queuedMessages.length > 0;
|
|
125
|
-
return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col bg-bg-subtle", children: [_jsxs("header", { className: "flex h-12 shrink-0 items-center gap-2 border-b border-border bg-surface px-4", children: [_jsx(Sparkles, { size: 16, className: "text-primary" }), _jsx("span", { className: "text-sm font-medium text-fg", children: labels.title }), headerActions != null ? _jsx("div", { className: "ml-auto flex items-center gap-2", children: headerActions }) : null] }), _jsxs("div", { ref: messageViewportRef, className: "app-scroll min-h-0 flex-1 overflow-y-auto", children: [messages.length === 0 && emptyContent != null ? (_jsx("div", { className: "flex min-h-full flex-col", children: emptyContent })) : (_jsx("div", { className: "mx-auto w-full max-w-3xl px-4 py-6", children: messages.length === 0 ? _jsx(AgentWelcome, { enabled: enabled, title: enabled ? labels.welcomeTitle : labels.disabledTitle, description: enabled ? labels.welcomeDescription : labels.disabledDescription, suggestions: suggestions, onPick: (value) => void submit(value) }) : _jsx("div", { className: "space-y-6", children: messages.map((message) => message.role === 'system' ? null : _jsx(AgentMessageRow, { message: message, streaming: streaming, labels: labels, toolLabels: toolLabels }, message.id)) }) })), error ? _jsx("div", { role: "alert", className: "mx-auto mb-5 w-[calc(100%-2rem)] max-w-3xl rounded-lg border border-danger/25 bg-danger-subtle px-3 py-2 text-sm text-danger", children: error }) : null] }), enabled ? _jsx("div", { className: "shrink-0 border-t border-border bg-surface px-4 py-3", children: _jsxs("div", { className: "mx-auto w-full max-w-3xl", children: [queuedMessages.length > 0 ? _jsx(AgentMessageQueue, { messages: queuedMessages, labels: labels, onEdit: onEditQueuedMessage, onRemove: onRemoveQueuedMessage, onRetry: onRetryQueuedMessage }) : null, composerContent != null ? _jsx("div", { className: "mb-2", children: composerContent }) : null, _jsxs("div", { className: "flex items-end gap-2 rounded-2xl border border-border-strong bg-surface p-2 shadow-sm focus-within:border-primary focus-within:ring-2 focus-within:ring-ring/20", children: [composerActions, _jsx("textarea", { value: input, onChange: (event) => setInput(event.target.value), onKeyDown: (event) => { if (event.key === 'Enter' && !event.shiftKey) {
|
|
139
|
+
return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col bg-bg-subtle", children: [_jsxs("header", { className: "flex h-12 shrink-0 items-center gap-2 border-b border-border bg-surface px-4", children: [_jsx(Sparkles, { size: 16, className: "text-primary" }), _jsx("span", { className: "text-sm font-medium text-fg", children: labels.title }), headerActions != null ? _jsx("div", { className: "ml-auto flex items-center gap-2", children: headerActions }) : null] }), _jsxs("div", { ref: messageViewportRef, className: "app-scroll min-h-0 flex-1 overflow-y-auto", children: [messages.length === 0 && emptyContent != null ? (_jsx("div", { className: "flex min-h-full flex-col", children: emptyContent })) : (_jsx("div", { className: "mx-auto w-full max-w-3xl px-4 py-6", children: messages.length === 0 ? _jsx(AgentWelcome, { enabled: enabled, title: enabled ? labels.welcomeTitle : labels.disabledTitle, description: enabled ? labels.welcomeDescription : labels.disabledDescription, suggestions: suggestions, onPick: (value) => void submit(value) }) : _jsx("div", { className: "space-y-6", children: messages.map((message) => message.role === 'system' ? null : _jsx(AgentMessageRow, { message: message, streaming: streaming, labels: labels, toolLabels: toolLabels, onSubmitSecretRequest: onSubmitSecretRequest, onCancelSecretRequest: onCancelSecretRequest, secretRequestLabels: secretRequestLabels }, message.id)) }) })), error ? _jsx("div", { role: "alert", className: "mx-auto mb-5 w-[calc(100%-2rem)] max-w-3xl rounded-lg border border-danger/25 bg-danger-subtle px-3 py-2 text-sm text-danger", children: error }) : null] }), enabled ? _jsx("div", { className: "shrink-0 border-t border-border bg-surface px-4 py-3", children: _jsxs("div", { className: "mx-auto w-full max-w-3xl", children: [queuedMessages.length > 0 ? _jsx(AgentMessageQueue, { messages: queuedMessages, labels: labels, onEdit: onEditQueuedMessage, onRemove: onRemoveQueuedMessage, onRetry: onRetryQueuedMessage }) : null, composerContent != null ? _jsx("div", { className: "mb-2", children: composerContent }) : null, _jsxs("div", { className: "flex items-end gap-2 rounded-2xl border border-border-strong bg-surface p-2 shadow-sm focus-within:border-primary focus-within:ring-2 focus-within:ring-ring/20", children: [composerActions, _jsx("textarea", { value: input, onChange: (event) => setInput(event.target.value), onKeyDown: (event) => { if (event.key === 'Enter' && !event.shiftKey) {
|
|
126
140
|
event.preventDefault();
|
|
127
141
|
void submit(input);
|
|
128
142
|
} }, maxLength: maxPromptCharacters, rows: 1, placeholder: labels.placeholder, className: "max-h-40 flex-1 resize-none overflow-y-auto border-0 bg-transparent px-2 py-1.5 text-base text-fg outline-none placeholder:text-fg-subtle sm:text-sm" }), streaming ? _jsx(Button, { type: "button", variant: "outline", size: "icon", onClick: () => abortRef.current?.abort(), "aria-label": labels.stop, children: _jsx(Square, { size: 16 }) }) : null, _jsx(Button, { type: "button", size: "icon", onClick: () => void submit(input), disabled: !(input.trim() || composerDraft?.fallbackPrompt?.trim()) || (queueMode ? !enqueue || enqueueing : !send), "aria-label": queueMode ? labels.queue : labels.send, children: enqueueing ? _jsx(Loader2, { size: 16, className: "animate-spin" }) : queueMode ? _jsx(ListPlus, { size: 16 }) : _jsx(Send, { size: 16 }) })] })] }) }) : null] }));
|
|
@@ -153,13 +167,43 @@ function replaceLastAssistantParts(messages, parts) {
|
|
|
153
167
|
function AgentWelcome({ enabled, title, description, suggestions, onPick }) {
|
|
154
168
|
return _jsxs("div", { className: "pt-10", children: [_jsx(EmptyState, { icon: _jsx(Sparkles, {}), title: title, description: description }), enabled && suggestions.length ? _jsx("div", { className: "mx-auto mt-6 grid max-w-2xl gap-2 sm:grid-cols-2", children: suggestions.map((suggestion) => _jsx("button", { type: "button", onClick: () => onPick(suggestion), className: "rounded-xl border border-border bg-surface px-4 py-3 text-left text-sm text-fg-muted shadow-sm transition-colors hover:border-primary/40 hover:bg-primary-subtle hover:text-fg", children: suggestion }, suggestion)) }) : null] });
|
|
155
169
|
}
|
|
156
|
-
function AgentMessageRow({ message, streaming, labels, toolLabels }) {
|
|
170
|
+
function AgentMessageRow({ message, streaming, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels }) {
|
|
157
171
|
if (message.role === 'user') {
|
|
158
172
|
const text = message.parts.find((part) => part.type === 'text')?.text;
|
|
159
173
|
const files = message.parts.filter(isAgentFilePart);
|
|
160
174
|
return _jsx("div", { className: "flex justify-end", children: _jsxs("div", { className: "max-w-[85%] space-y-2 rounded-2xl rounded-br-md bg-primary px-4 py-2 text-sm whitespace-pre-wrap text-primary-fg", children: [text ? _jsx("div", { children: text }) : null, files.length > 0 ? _jsx("div", { className: "flex flex-wrap justify-end gap-1.5", children: files.map((file, index) => file.url ? _jsx("a", { href: file.url, className: "rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium hover:bg-primary-fg/15", download: true, children: file.filename }, `${file.filename}-${index}`) : _jsx("span", { className: "rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium", children: file.filename }, `${file.filename}-${index}`)) }) : null] }) });
|
|
161
175
|
}
|
|
162
|
-
return _jsxs("div", { className: "flex gap-3", children: [_jsx("span", { className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-primary-fg shadow-sm", children: _jsx(Sparkles, { size: 16 }) }), _jsx("div", { className: "min-w-0 flex-1 pt-0.5", children: message.parts.length === 0 && streaming ? _jsx(
|
|
176
|
+
return _jsxs("div", { className: "flex gap-3", children: [_jsx("span", { className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-primary-fg shadow-sm", children: _jsx(Sparkles, { size: 16 }) }), _jsx("div", { className: "min-w-0 flex-1 pt-0.5", children: message.parts.length === 0 && streaming ? _jsx(AgentTypingIndicator, { label: labels.responding }) : _jsx(AgentMessageParts, { parts: message.parts, labels: labels, toolLabels: toolLabels, onSubmitSecretRequest: onSubmitSecretRequest, onCancelSecretRequest: onCancelSecretRequest, secretRequestLabels: secretRequestLabels }) })] });
|
|
177
|
+
}
|
|
178
|
+
const TYPING_DOT_DELAYS = [
|
|
179
|
+
'0ms',
|
|
180
|
+
'var(--duration-fast)',
|
|
181
|
+
'calc(var(--duration-fast) + var(--duration-fast))',
|
|
182
|
+
];
|
|
183
|
+
/**
|
|
184
|
+
* A self-contained streaming cue that does not depend on the consuming app's
|
|
185
|
+
* Tailwind content scan. The cadence uses AppKit motion tokens and becomes a
|
|
186
|
+
* still, readable ellipsis when the user requests reduced motion.
|
|
187
|
+
*/
|
|
188
|
+
export function AgentTypingIndicator({ label = DEFAULT_LABELS.responding }) {
|
|
189
|
+
return (_jsxs("div", { role: "status", "aria-label": label, className: "flex items-center gap-1 py-1.5", children: [_jsx("style", { children: `
|
|
190
|
+
@keyframes appkit-agent-typing-dot {
|
|
191
|
+
0%, 36%, 100% { opacity: 0.55; transform: translateY(0); }
|
|
192
|
+
18% { opacity: 1; transform: translateY(-0.2rem); }
|
|
193
|
+
}
|
|
194
|
+
.appkit-agent-typing-dot {
|
|
195
|
+
animation: appkit-agent-typing-dot calc(var(--duration-slow) + var(--duration-slow) + var(--duration-slow)) var(--ease-out) infinite;
|
|
196
|
+
will-change: transform, opacity;
|
|
197
|
+
}
|
|
198
|
+
@media (prefers-reduced-motion: reduce) {
|
|
199
|
+
.appkit-agent-typing-dot {
|
|
200
|
+
animation: none;
|
|
201
|
+
opacity: 0.7;
|
|
202
|
+
transform: none;
|
|
203
|
+
will-change: auto;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
` }), TYPING_DOT_DELAYS.map((animationDelay) => (_jsx("span", { "aria-hidden": "true", className: "appkit-agent-typing-dot size-1.5 rounded-full bg-fg-subtle", style: { animationDelay } }, animationDelay)))] }));
|
|
163
207
|
}
|
|
164
208
|
function isAgentFilePart(part) {
|
|
165
209
|
if (!part || typeof part !== 'object')
|
|
@@ -170,7 +214,7 @@ function isAgentFilePart(part) {
|
|
|
170
214
|
&& candidate.filename.trim().length > 0
|
|
171
215
|
&& (candidate.url === undefined || typeof candidate.url === 'string');
|
|
172
216
|
}
|
|
173
|
-
function AgentMessageParts({ parts, labels, toolLabels }) {
|
|
217
|
+
function AgentMessageParts({ parts, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels }) {
|
|
174
218
|
const rendered = [];
|
|
175
219
|
let tools = [];
|
|
176
220
|
let toolGroupStart = 0;
|
|
@@ -180,7 +224,10 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
|
|
|
180
224
|
rendered.push(_jsx(AgentToolActivity, { parts: tools, labels: labels, toolLabels: toolLabels }, `tools-${toolGroupStart}`));
|
|
181
225
|
tools = [];
|
|
182
226
|
};
|
|
183
|
-
parts.forEach((
|
|
227
|
+
parts.forEach((value, index) => {
|
|
228
|
+
if (!value || typeof value !== 'object' || typeof value.type !== 'string')
|
|
229
|
+
return;
|
|
230
|
+
const part = value;
|
|
184
231
|
if (isAgentToolPart(part)) {
|
|
185
232
|
if (tools.length === 0)
|
|
186
233
|
toolGroupStart = index;
|
|
@@ -190,6 +237,10 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
|
|
|
190
237
|
if (part.type === 'step-start' || part.type === 'reasoning')
|
|
191
238
|
return;
|
|
192
239
|
flushTools();
|
|
240
|
+
if (isAgentSecretRequestPart(part)) {
|
|
241
|
+
rendered.push(_jsx(AgentSecretRequestCard, { request: part, labels: secretRequestLabels, onSubmit: onSubmitSecretRequest, onCancel: onCancelSecretRequest }, `secret-${part.requestId}-${part.status}`));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
193
244
|
if (part.type === 'text' && typeof part.text === 'string' && part.text.trim()) {
|
|
194
245
|
rendered.push(_jsx(ChatMarkdown, { children: part.text }, `text-${index}`));
|
|
195
246
|
}
|
|
@@ -197,6 +248,120 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
|
|
|
197
248
|
flushTools();
|
|
198
249
|
return _jsx("div", { className: "space-y-2.5", children: rendered });
|
|
199
250
|
}
|
|
251
|
+
function isAgentSecretRequestPart(part) {
|
|
252
|
+
return part.type === 'secret-request'
|
|
253
|
+
&& typeof part.requestId === 'string'
|
|
254
|
+
&& part.requestId.trim().length > 0
|
|
255
|
+
&& typeof part.providerLabel === 'string'
|
|
256
|
+
&& part.providerLabel.trim().length > 0
|
|
257
|
+
&& typeof part.credentialLabel === 'string'
|
|
258
|
+
&& part.credentialLabel.trim().length > 0
|
|
259
|
+
&& typeof part.purpose === 'string'
|
|
260
|
+
&& part.purpose.trim().length > 0
|
|
261
|
+
&& (part.helpUrl === undefined || typeof part.helpUrl === 'string')
|
|
262
|
+
&& (part.status === 'pending' || part.status === 'stored' || part.status === 'expired');
|
|
263
|
+
}
|
|
264
|
+
function safeSecretHelpUrl(value) {
|
|
265
|
+
if (!value)
|
|
266
|
+
return undefined;
|
|
267
|
+
if (value.startsWith('/') && !value.startsWith('//'))
|
|
268
|
+
return value;
|
|
269
|
+
try {
|
|
270
|
+
const url = new URL(value);
|
|
271
|
+
return url.protocol === 'https:' ? url.href : undefined;
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Inline credential handoff for an assistant transcript. The password field is
|
|
279
|
+
* uncontrolled: its value is read directly from the DOM, cleared before the
|
|
280
|
+
* caller receives it, and never copied into React or transcript state.
|
|
281
|
+
*/
|
|
282
|
+
export function AgentSecretRequestCard({ request, labels: labelOverrides, onSubmit, onCancel }) {
|
|
283
|
+
const labels = { ...DEFAULT_SECRET_REQUEST_LABELS, ...labelOverrides };
|
|
284
|
+
const inputId = React.useId();
|
|
285
|
+
const inputRef = React.useRef(null);
|
|
286
|
+
const [revealed, setRevealed] = React.useState(false);
|
|
287
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
288
|
+
const [settledStatus, setSettledStatus] = React.useState(null);
|
|
289
|
+
const [error, setError] = React.useState(null);
|
|
290
|
+
const requestIdentityRef = React.useRef(`${request.requestId}:${request.status}`);
|
|
291
|
+
const status = settledStatus ?? request.status;
|
|
292
|
+
const helpUrl = safeSecretHelpUrl(request.helpUrl);
|
|
293
|
+
const clearInput = React.useCallback(() => {
|
|
294
|
+
if (inputRef.current)
|
|
295
|
+
inputRef.current.value = '';
|
|
296
|
+
}, []);
|
|
297
|
+
React.useEffect(() => {
|
|
298
|
+
const identity = `${request.requestId}:${request.status}`;
|
|
299
|
+
if (requestIdentityRef.current !== identity) {
|
|
300
|
+
requestIdentityRef.current = identity;
|
|
301
|
+
clearInput();
|
|
302
|
+
setRevealed(false);
|
|
303
|
+
setSubmitting(false);
|
|
304
|
+
setSettledStatus(null);
|
|
305
|
+
setError(null);
|
|
306
|
+
}
|
|
307
|
+
}, [clearInput, request.requestId, request.status]);
|
|
308
|
+
React.useEffect(() => {
|
|
309
|
+
return clearInput;
|
|
310
|
+
}, [clearInput]);
|
|
311
|
+
const submit = React.useCallback(async (event) => {
|
|
312
|
+
event.preventDefault();
|
|
313
|
+
if (!onSubmit || submitting || status !== 'pending')
|
|
314
|
+
return;
|
|
315
|
+
const secret = inputRef.current?.value ?? '';
|
|
316
|
+
if (secret.length === 0) {
|
|
317
|
+
setError(labels.required);
|
|
318
|
+
inputRef.current?.focus();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
clearInput();
|
|
322
|
+
setRevealed(false);
|
|
323
|
+
setError(null);
|
|
324
|
+
setSubmitting(true);
|
|
325
|
+
try {
|
|
326
|
+
await onSubmit(request.requestId, secret);
|
|
327
|
+
setSettledStatus('stored');
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
setError(labels.failed);
|
|
331
|
+
inputRef.current?.focus();
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
clearInput();
|
|
335
|
+
setSubmitting(false);
|
|
336
|
+
}
|
|
337
|
+
}, [clearInput, labels.failed, labels.required, onSubmit, request.requestId, status, submitting]);
|
|
338
|
+
const cancel = React.useCallback(async () => {
|
|
339
|
+
if (!onCancel || submitting || status !== 'pending')
|
|
340
|
+
return;
|
|
341
|
+
clearInput();
|
|
342
|
+
setRevealed(false);
|
|
343
|
+
setError(null);
|
|
344
|
+
setSubmitting(true);
|
|
345
|
+
try {
|
|
346
|
+
await onCancel(request.requestId);
|
|
347
|
+
setSettledStatus('expired');
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
setError(labels.cancelFailed);
|
|
351
|
+
}
|
|
352
|
+
finally {
|
|
353
|
+
clearInput();
|
|
354
|
+
setSubmitting(false);
|
|
355
|
+
}
|
|
356
|
+
}, [clearInput, labels.cancelFailed, onCancel, request.requestId, status, submitting]);
|
|
357
|
+
return (_jsxs("section", { className: "overflow-hidden rounded-xl border border-border bg-surface shadow-sm", "aria-labelledby": `${inputId}-title`, children: [_jsxs("div", { className: "flex items-start gap-3 p-3", children: [_jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary-subtle text-primary", children: _jsx(KeyRound, { size: 16 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { id: `${inputId}-title`, className: "text-sm font-semibold text-fg", children: request.providerLabel }), _jsx("div", { className: "mt-0.5 text-xs font-medium text-fg-muted", children: request.credentialLabel }), _jsx("p", { className: "mt-1.5 text-sm leading-relaxed text-fg-muted", children: request.purpose }), helpUrl ? helpUrl.startsWith('/') ? _jsx(UiLink, { href: helpUrl, className: "mt-2 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline", children: labels.help }) : _jsxs("a", { href: helpUrl, target: "_blank", rel: "noreferrer", className: "mt-2 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline", children: [labels.help, _jsx(ExternalLink, { size: 12, "aria-hidden": "true" })] }) : null] })] }), status === 'pending' ? (_jsxs("form", { onSubmit: (event) => void submit(event), onKeyDown: (event) => { if (event.key === 'Escape') {
|
|
358
|
+
event.preventDefault();
|
|
359
|
+
void cancel();
|
|
360
|
+
} }, className: "space-y-2.5 border-t border-border bg-bg-subtle p-3", children: [_jsx("label", { htmlFor: inputId, className: "sr-only", children: request.credentialLabel }), _jsxs("div", { className: "relative", children: [_jsx(Input, { ref: inputRef, id: inputId, type: revealed ? 'text' : 'password', autoComplete: "new-password", autoCapitalize: "none", spellCheck: false, disabled: submitting || !onSubmit, "aria-invalid": error ? true : undefined, onKeyDown: (event) => { if (event.key === 'Enter') {
|
|
361
|
+
event.preventDefault();
|
|
362
|
+
event.currentTarget.form?.requestSubmit();
|
|
363
|
+
} }, className: "pr-11 font-mono" }), _jsx("button", { type: "button", onClick: () => setRevealed((value) => !value), disabled: submitting || !onSubmit, "aria-label": revealed ? labels.hide : labels.show, "aria-pressed": revealed, className: "absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-md text-fg-muted transition-colors hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/60 disabled:pointer-events-none disabled:opacity-50 motion-reduce:transition-none", children: revealed ? _jsx(EyeOff, { size: 16 }) : _jsx(Eye, { size: 16 }) })] }), error ? _jsx("p", { role: "alert", className: "text-xs text-danger", children: error }) : null, _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => void cancel(), disabled: submitting || !onCancel, children: labels.cancel }), _jsx(Button, { type: "submit", size: "sm", disabled: submitting || !onSubmit, children: submitting ? _jsxs(_Fragment, { children: [_jsx(Loader2, { size: 14, className: "animate-spin motion-reduce:animate-none" }), labels.submitting] }) : labels.submit })] })] })) : (_jsxs("div", { role: "status", className: cn('flex items-center gap-2 border-t border-border px-3 py-2.5 text-sm font-medium', status === 'stored' ? 'bg-success-subtle text-success' : 'bg-bg-subtle text-fg-muted'), children: [status === 'stored' ? _jsx(CheckCircle2, { size: 16 }) : _jsx(AlertCircle, { size: 16 }), status === 'stored' ? labels.stored : labels.expired] }))] }));
|
|
364
|
+
}
|
|
200
365
|
function isAgentToolPart(part) {
|
|
201
366
|
return part.type === 'dynamic-tool' || part.type.startsWith('tool-');
|
|
202
367
|
}
|
package/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {\n parseJsonEventStream,\n readUIMessageStream,\n uiMessageChunkSchema,\n type UIMessageChunk,\n} from 'ai'\nimport {\n AlertCircle,\n CheckCircle2,\n ChevronRight,\n Database,\n ListPlus,\n Loader2,\n Pencil,\n RotateCcw,\n Send,\n Sparkles,\n Square,\n Trash2,\n} from 'lucide-react'\nimport Markdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport { Button, EmptyState, UiLink, cn } from '@braedonsaunders/appkit-ui'\n\nexport type AgentMessage = {\n id: string\n role: 'user' | 'assistant' | 'system'\n parts: unknown[]\n}\n\nexport type AgentQueuedMessage = {\n id: string\n text: string\n position: number\n status: 'queued' | 'dispatching' | 'retrying' | 'failed'\n statusLabel?: string\n editable?: boolean\n removable?: boolean\n retryable?: boolean\n}\n\nexport type AgentDispatchState = 'idle' | 'running' | 'recovering'\n\nexport type AgentPanelLabels = {\n title: string\n welcomeTitle: string\n welcomeDescription: string\n disabledTitle: string\n disabledDescription: string\n placeholder: string\n send: string\n stop: string\n failed: string\n input: string\n result: string\n working: string\n step: string\n steps: string\n queue: string\n queueTitle: string\n queuePosition: string\n queued: string\n dispatching: string\n retrying: string\n queueFailed: string\n editQueued: string\n removeQueued: string\n retryQueued: string\n}\n\nconst DEFAULT_LABELS: AgentPanelLabels = {\n title: 'Assistant',\n welcomeTitle: 'How can I help?',\n welcomeDescription: 'Ask about your workspace or let the assistant use an approved tool.',\n disabledTitle: 'Connect an AI provider',\n disabledDescription: 'Connect an AI provider to enable agent conversations. No provider credentials are included in the demo.',\n placeholder: 'Ask the assistant…',\n send: 'Send',\n stop: 'Stop generating',\n failed: 'The assistant could not complete that turn. Please try again.',\n input: 'Input',\n result: 'Result',\n working: 'Working',\n step: 'step',\n steps: 'steps',\n queue: 'Add to queue',\n queueTitle: 'Up next',\n queuePosition: 'Position',\n queued: 'Queued',\n dispatching: 'Starting',\n retrying: 'Retrying',\n queueFailed: 'This queued message needs attention.',\n editQueued: 'Edit queued message',\n removeQueued: 'Remove queued message',\n retryQueued: 'Retry queued message',\n}\n\nexport type AgentPanelProps = {\n enabled: boolean\n initialMessages?: AgentMessage[]\n suggestions?: string[]\n labels?: Partial<AgentPanelLabels>\n headerActions?: React.ReactNode\n /** Replaces the stock empty-state card while preserving the panel header and composer. */\n emptyContent?: React.ReactNode\n /** Application-owned draft UI rendered immediately above the composer row. */\n composerContent?: React.ReactNode\n /** Application-owned controls rendered before the text input. */\n composerActions?: React.ReactNode\n /**\n * Non-text content currently attached to the draft. `fallbackPrompt` makes\n * a file-only draft sendable; `parts` are included in the optimistic user\n * turn so the attachment does not disappear while the response streams.\n */\n composerDraft?: { fallbackPrompt?: string; parts?: readonly unknown[] }\n send?: (prompt: string, signal: AbortSignal) => Promise<Response>\n /** Durable dispatch state supplied by the application after reload or handoff. */\n dispatchState?: AgentDispatchState\n /** Application-owned queue, already ordered by its durable dispatch position. */\n queuedMessages?: readonly AgentQueuedMessage[]\n /** Persists a turn behind the active or previously queued work. */\n enqueue?: (prompt: string) => Promise<void>\n onEditQueuedMessage?: (message: AgentQueuedMessage) => void\n onRemoveQueuedMessage?: (message: AgentQueuedMessage) => void\n onRetryQueuedMessage?: (message: AgentQueuedMessage) => void\n maxPromptCharacters?: number\n toolLabels?: Record<string, string>\n}\n\n/**\n * The streaming thread/composer extracted from the sibling assistant. The app\n * owns persistence and the HTTP transport; appkit owns UI-message decoding,\n * cancellation, ordered part rendering, and tool cards.\n */\nexport function AgentPanel({\n enabled,\n initialMessages = [],\n suggestions = [],\n labels: labelOverrides,\n headerActions,\n emptyContent,\n composerContent,\n composerActions,\n composerDraft,\n send,\n dispatchState = 'idle',\n queuedMessages = [],\n enqueue,\n onEditQueuedMessage,\n onRemoveQueuedMessage,\n onRetryQueuedMessage,\n maxPromptCharacters = 32_000,\n toolLabels,\n}: AgentPanelProps) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides }\n const [messages, setMessages] = React.useState(initialMessages)\n const [input, setInput] = React.useState('')\n const [streaming, setStreaming] = React.useState(false)\n const [enqueueing, setEnqueueing] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const abortRef = React.useRef<AbortController | null>(null)\n const messageViewportRef = React.useRef<HTMLDivElement>(null)\n\n const scrollToBottom = React.useCallback(() => {\n window.requestAnimationFrame(() => {\n const viewport = messageViewportRef.current\n if (viewport) viewport.scrollTop = viewport.scrollHeight\n })\n }, [])\n\n // An existing conversation opens where work most recently happened. Keep\n // this scoped to the panel's own viewport: scrollIntoView also moves every\n // scrolling ancestor and can make an otherwise app-height page jump.\n React.useLayoutEffect(() => {\n scrollToBottom()\n }, [scrollToBottom])\n\n const submit = React.useCallback(async (raw: string) => {\n const prompt = raw.trim() || composerDraft?.fallbackPrompt?.trim() || ''\n if (!enabled || !prompt || prompt.length > maxPromptCharacters) return\n const shouldEnqueue = dispatchState !== 'idle' || abortRef.current !== null || queuedMessages.length > 0\n if (shouldEnqueue) {\n if (!enqueue || enqueueing) return\n setEnqueueing(true)\n setError(null)\n try {\n await enqueue(prompt)\n setInput('')\n } catch {\n setError(labels.queueFailed)\n } finally {\n setEnqueueing(false)\n }\n return\n }\n if (!send) return\n const controller = new AbortController()\n abortRef.current = controller\n const stamp = Date.now()\n setInput('')\n setError(null)\n setMessages((current) => [...current, { id: `user-${stamp}`, role: 'user', parts: [{ type: 'text', text: prompt }, ...(composerDraft?.parts ?? [])] }, { id: `assistant-${stamp}`, role: 'assistant', parts: [] }])\n setStreaming(true)\n scrollToBottom()\n let producedParts = false\n try {\n const response = await send(prompt, controller.signal)\n if (!response.ok || !response.body) throw new Error('agent request failed')\n const chunks = parseJsonEventStream({ stream: response.body, schema: uiMessageChunkSchema }).pipeThrough(new TransformStream<{ success: boolean; value?: UIMessageChunk }, UIMessageChunk>({ transform(part, stream) { if (part.success && part.value) stream.enqueue(part.value) } }))\n let lastParts: unknown[] = []\n for await (const message of readUIMessageStream({ stream: chunks })) {\n lastParts = message.parts as unknown[]\n producedParts = lastParts.length > 0\n setMessages((current) => replaceLastAssistantParts(current, lastParts))\n scrollToBottom()\n }\n if (lastParts.length === 0 && !controller.signal.aborted) setError(labels.failed)\n } catch (reason) {\n if ((reason as Error).name !== 'AbortError') setError(labels.failed)\n } finally {\n if (!producedParts) {\n setMessages((current) => current.filter((message) => message.id !== `assistant-${stamp}`))\n }\n setStreaming(false)\n if (abortRef.current === controller) abortRef.current = null\n }\n }, [composerDraft, dispatchState, enabled, enqueue, enqueueing, labels.failed, labels.queueFailed, maxPromptCharacters, queuedMessages.length, scrollToBottom, send])\n\n const queueMode = dispatchState !== 'idle' || streaming || queuedMessages.length > 0\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col bg-bg-subtle\">\n <header className=\"flex h-12 shrink-0 items-center gap-2 border-b border-border bg-surface px-4\"><Sparkles size={16} className=\"text-primary\" /><span className=\"text-sm font-medium text-fg\">{labels.title}</span>{headerActions != null ? <div className=\"ml-auto flex items-center gap-2\">{headerActions}</div> : null}</header>\n <div ref={messageViewportRef} className=\"app-scroll min-h-0 flex-1 overflow-y-auto\">\n {messages.length === 0 && emptyContent != null ? (\n <div className=\"flex min-h-full flex-col\">{emptyContent}</div>\n ) : (\n <div className=\"mx-auto w-full max-w-3xl px-4 py-6\">\n {messages.length === 0 ? <AgentWelcome enabled={enabled} title={enabled ? labels.welcomeTitle : labels.disabledTitle} description={enabled ? labels.welcomeDescription : labels.disabledDescription} suggestions={suggestions} onPick={(value) => void submit(value)} /> : <div className=\"space-y-6\">{messages.map((message) => message.role === 'system' ? null : <AgentMessageRow key={message.id} message={message} streaming={streaming} labels={labels} toolLabels={toolLabels} />)}</div>}\n </div>\n )}\n {error ? <div role=\"alert\" className=\"mx-auto mb-5 w-[calc(100%-2rem)] max-w-3xl rounded-lg border border-danger/25 bg-danger-subtle px-3 py-2 text-sm text-danger\">{error}</div> : null}\n </div>\n {enabled ? <div className=\"shrink-0 border-t border-border bg-surface px-4 py-3\"><div className=\"mx-auto w-full max-w-3xl\">{queuedMessages.length > 0 ? <AgentMessageQueue messages={queuedMessages} labels={labels} onEdit={onEditQueuedMessage} onRemove={onRemoveQueuedMessage} onRetry={onRetryQueuedMessage} /> : null}{composerContent != null ? <div className=\"mb-2\">{composerContent}</div> : null}<div className=\"flex items-end gap-2 rounded-2xl border border-border-strong bg-surface p-2 shadow-sm focus-within:border-primary focus-within:ring-2 focus-within:ring-ring/20\">{composerActions}<textarea value={input} onChange={(event) => setInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); void submit(input) } }} maxLength={maxPromptCharacters} rows={1} placeholder={labels.placeholder} className=\"max-h-40 flex-1 resize-none overflow-y-auto border-0 bg-transparent px-2 py-1.5 text-base text-fg outline-none placeholder:text-fg-subtle sm:text-sm\" />{streaming ? <Button type=\"button\" variant=\"outline\" size=\"icon\" onClick={() => abortRef.current?.abort()} aria-label={labels.stop}><Square size={16} /></Button> : null}<Button type=\"button\" size=\"icon\" onClick={() => void submit(input)} disabled={!(input.trim() || composerDraft?.fallbackPrompt?.trim()) || (queueMode ? !enqueue || enqueueing : !send)} aria-label={queueMode ? labels.queue : labels.send}>{enqueueing ? <Loader2 size={16} className=\"animate-spin\" /> : queueMode ? <ListPlus size={16} /> : <Send size={16} />}</Button></div></div></div> : null}\n </div>\n )\n}\n\nexport function AgentMessageQueue({\n messages,\n labels: labelOverrides,\n onEdit,\n onRemove,\n onRetry,\n}: {\n messages: readonly AgentQueuedMessage[]\n labels?: Partial<AgentPanelLabels>\n onEdit?: (message: AgentQueuedMessage) => void\n onRemove?: (message: AgentQueuedMessage) => void\n onRetry?: (message: AgentQueuedMessage) => void\n}) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides }\n return (\n <section className=\"mb-3 rounded-xl border border-border bg-bg-subtle p-2\" aria-label={labels.queueTitle}>\n <div className=\"px-2 pb-1 text-xs font-medium text-fg-muted\">{labels.queueTitle}</div>\n <ol className=\"space-y-1\">\n {messages.map((message) => (\n <li key={message.id} className=\"flex min-w-0 items-center gap-2 rounded-lg bg-surface px-2 py-1.5 shadow-xs\">\n <span className=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary-subtle text-xs font-medium text-primary\" aria-label={`${labels.queuePosition} ${message.position}`}>{message.position}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm text-fg\">{message.text}</span>\n <span className={cn('shrink-0 text-xs', message.status === 'failed' ? 'text-danger' : 'text-fg-muted')}>{message.statusLabel ?? queueStatusLabel(message.status, labels)}</span>\n {message.retryable && onRetry ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onRetry(message)} aria-label={labels.retryQueued}><RotateCcw size={14} /></Button> : null}\n {message.editable && onEdit ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onEdit(message)} aria-label={labels.editQueued}><Pencil size={14} /></Button> : null}\n {message.removable && onRemove ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onRemove(message)} aria-label={labels.removeQueued}><Trash2 size={14} /></Button> : null}\n </li>\n ))}\n </ol>\n </section>\n )\n}\n\nfunction queueStatusLabel(status: AgentQueuedMessage['status'], labels: AgentPanelLabels): string {\n if (status === 'dispatching') return labels.dispatching\n if (status === 'retrying') return labels.retrying\n if (status === 'failed') return labels.queueFailed\n return labels.queued\n}\n\nfunction replaceLastAssistantParts(messages: AgentMessage[], parts: unknown[]): AgentMessage[] {\n const copy = messages.slice()\n for (let index = copy.length - 1; index >= 0; index -= 1) {\n if (copy[index]?.role === 'assistant') { copy[index] = { ...copy[index]!, parts }; break }\n }\n return copy\n}\n\nfunction AgentWelcome({ enabled, title, description, suggestions, onPick }: { enabled: boolean; title: string; description: string; suggestions: string[]; onPick: (value: string) => void }) {\n return <div className=\"pt-10\"><EmptyState icon={<Sparkles />} title={title} description={description} />{enabled && suggestions.length ? <div className=\"mx-auto mt-6 grid max-w-2xl gap-2 sm:grid-cols-2\">{suggestions.map((suggestion) => <button key={suggestion} type=\"button\" onClick={() => onPick(suggestion)} className=\"rounded-xl border border-border bg-surface px-4 py-3 text-left text-sm text-fg-muted shadow-sm transition-colors hover:border-primary/40 hover:bg-primary-subtle hover:text-fg\">{suggestion}</button>)}</div> : null}</div>\n}\n\nfunction AgentMessageRow({ message, streaming, labels, toolLabels }: { message: AgentMessage; streaming: boolean; labels: AgentPanelLabels; toolLabels?: Record<string, string> }) {\n if (message.role === 'user') {\n const text = (message.parts.find((part) => (part as { type?: string }).type === 'text') as { text?: string } | undefined)?.text\n const files = message.parts.filter(isAgentFilePart)\n return <div className=\"flex justify-end\"><div className=\"max-w-[85%] space-y-2 rounded-2xl rounded-br-md bg-primary px-4 py-2 text-sm whitespace-pre-wrap text-primary-fg\">{text ? <div>{text}</div> : null}{files.length > 0 ? <div className=\"flex flex-wrap justify-end gap-1.5\">{files.map((file, index) => file.url ? <a key={`${file.filename}-${index}`} href={file.url} className=\"rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium hover:bg-primary-fg/15\" download>{file.filename}</a> : <span key={`${file.filename}-${index}`} className=\"rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium\">{file.filename}</span>)}</div> : null}</div></div>\n }\n return <div className=\"flex gap-3\"><span className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-primary-fg shadow-sm\"><Sparkles size={16} /></span><div className=\"min-w-0 flex-1 pt-0.5\">{message.parts.length === 0 && streaming ? <div className=\"flex items-center gap-1 py-1.5\">{[0,1,2].map((index) => <span key={index} className=\"size-1.5 animate-bounce rounded-full bg-fg-subtle\" style={{ animationDelay: `${index * 0.15}s` }} />)}</div> : <AgentMessageParts parts={message.parts} labels={labels} toolLabels={toolLabels} />}</div></div>\n}\n\nfunction isAgentFilePart(part: unknown): part is { type: 'file'; filename: string; url?: string } {\n if (!part || typeof part !== 'object') return false\n const candidate = part as { type?: unknown; filename?: unknown; url?: unknown }\n return candidate.type === 'file'\n && typeof candidate.filename === 'string'\n && candidate.filename.trim().length > 0\n && (candidate.url === undefined || typeof candidate.url === 'string')\n}\n\nfunction AgentMessageParts({ parts, labels, toolLabels }: { parts: unknown[]; labels: AgentPanelLabels; toolLabels?: Record<string, string> }) {\n const rendered: React.ReactNode[] = []\n let tools: AgentToolPart[] = []\n let toolGroupStart = 0\n const flushTools = () => {\n if (tools.length === 0) return\n rendered.push(<AgentToolActivity key={`tools-${toolGroupStart}`} parts={tools} labels={labels} toolLabels={toolLabels} />)\n tools = []\n }\n ;(parts as { type: string; [key: string]: unknown }[]).forEach((part, index) => {\n if (isAgentToolPart(part)) {\n if (tools.length === 0) toolGroupStart = index\n tools.push(part)\n return\n }\n if (part.type === 'step-start' || part.type === 'reasoning') return\n flushTools()\n if (part.type === 'text' && typeof part.text === 'string' && part.text.trim()) {\n rendered.push(<ChatMarkdown key={`text-${index}`}>{part.text}</ChatMarkdown>)\n }\n })\n flushTools()\n return <div className=\"space-y-2.5\">{rendered}</div>\n}\n\ntype AgentToolPart = { type: string; toolName?: unknown; state?: unknown; input?: unknown; output?: unknown }\n\nfunction isAgentToolPart(part: { type: string }): part is AgentToolPart {\n return part.type === 'dynamic-tool' || part.type.startsWith('tool-')\n}\n\nfunction agentToolName(part: AgentToolPart): string {\n return part.type === 'dynamic-tool' ? String(part.toolName ?? 'tool') : part.type.slice(5)\n}\n\nfunction agentToolRunning(part: AgentToolPart): boolean {\n const state = String(part.state ?? 'output-available')\n return state === 'input-streaming' || state === 'input-available'\n}\n\nfunction agentToolErrored(part: AgentToolPart): boolean {\n return String(part.state) === 'output-error' || (part.output as { ok?: boolean } | undefined)?.ok === false\n}\n\n/**\n * A multi-step run stays quiet in the transcript: the newest action and total\n * step count occupy one line, while the complete inputs/results remain one\n * click away. Applications keep their full durable audit trail separately.\n */\nfunction AgentToolActivity({ parts, labels, toolLabels }: { parts: AgentToolPart[]; labels: AgentPanelLabels; toolLabels?: Record<string, string> }) {\n const [open, setOpen] = React.useState(false)\n const latest = parts.at(-1)!\n const latestName = agentToolName(latest)\n const running = parts.some(agentToolRunning)\n const errored = parts.some(agentToolErrored)\n const count = parts.length\n const status = running ? labels.working : `${count} ${count === 1 ? labels.step : labels.steps}`\n return <div className=\"text-sm\"><button type=\"button\" onClick={() => setOpen((value) => !value)} aria-expanded={open} className=\"flex h-7 max-w-full items-center gap-1.5 rounded-md px-1.5 text-left text-xs text-fg-muted transition-colors hover:bg-surface-hover hover:text-fg\"><span className={cn('size-1.5 shrink-0 rounded-full', running ? 'animate-pulse bg-primary' : errored ? 'bg-danger' : 'bg-success')} /><span className=\"shrink-0 font-medium\">{status}</span><span aria-hidden className=\"text-fg-subtle\">·</span><span className=\"min-w-0 truncate\">{toolLabels?.[latestName] ?? latestName.replaceAll('_', ' ')}</span><ChevronRight size={12} className={cn('shrink-0 text-fg-subtle transition-transform', open && 'rotate-90')} /></button>{open ? <div className=\"mt-1.5 space-y-1.5 border-l border-border pl-2\">{parts.map((part, index) => { const name = agentToolName(part); return <AgentToolCard key={`${name}-${index}`} name={name} label={toolLabels?.[name]} state={String(part.state ?? 'output-available')} input={part.input} output={part.output} inputLabel={labels.input} resultLabel={labels.result} /> })}</div> : null}</div>\n}\n\nexport function ChatMarkdown({ children }: { children: string }) {\n return <div className=\"space-y-2 text-sm leading-relaxed text-fg\"><Markdown remarkPlugins={[remarkGfm]} components={{ p: ({ children: content }) => <p className=\"whitespace-pre-wrap\">{content}</p>, h1: ({ children: content }) => <h1 className=\"text-lg font-semibold\">{content}</h1>, h2: ({ children: content }) => <h2 className=\"text-base font-semibold\">{content}</h2>, ul: ({ children: content }) => <ul className=\"list-disc space-y-1 pl-5\">{content}</ul>, ol: ({ children: content }) => <ol className=\"list-decimal space-y-1 pl-5\">{content}</ol>, code: ({ children: content }) => <code className=\"rounded bg-bg-subtle px-1 py-0.5 font-mono text-[0.85em] text-primary\">{content}</code>, pre: ({ children: content }) => <pre className=\"overflow-auto rounded-lg bg-overlay p-3 text-sm whitespace-pre-wrap text-white\">{content}</pre>, table: ({ children: content }) => <div className=\"overflow-x-auto\"><table className=\"w-full border-collapse text-sm\">{content}</table></div>, th: ({ children: content }) => <th className=\"border-b border-border px-2 py-1 text-left\">{content}</th>, td: ({ children: content }) => <td className=\"border-b border-border-subtle px-2 py-1\">{content}</td>, a: ({ href, children: content }) => href?.startsWith('/') ? <UiLink href={href} className=\"font-medium text-primary underline-offset-2 hover:underline\">{content}</UiLink> : <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"font-medium text-primary underline-offset-2 hover:underline\">{content}</a> }}>{children}</Markdown></div>\n}\n\nexport function AgentToolCard({ name, label, state, input, output, inputLabel = 'Input', resultLabel = 'Result' }: { name: string; label?: string; state: string; input?: unknown; output?: unknown; inputLabel?: string; resultLabel?: string }) {\n const [open, setOpen] = React.useState(false)\n const running = state === 'input-streaming' || state === 'input-available'\n const errored = state === 'output-error' || (output as { ok?: boolean } | undefined)?.ok === false\n return <div className=\"overflow-hidden rounded-lg border border-border bg-bg-subtle text-sm\"><button type=\"button\" onClick={() => setOpen((value) => !value)} className=\"flex w-full items-center gap-2.5 px-3 py-2 text-left transition-colors hover:bg-surface-hover\"><span className={cn('flex size-6 shrink-0 items-center justify-center rounded-md', errored ? 'bg-danger-subtle text-danger' : 'bg-primary-subtle text-primary')}><Database size={14} /></span><span className=\"min-w-0 flex-1 truncate font-medium text-fg\">{label ?? name.replaceAll('_', ' ')}</span>{running ? <Loader2 size={14} className=\"animate-spin text-fg-subtle\" /> : errored ? <AlertCircle size={14} className=\"text-danger\" /> : <CheckCircle2 size={14} className=\"text-success\" />}<ChevronRight size={14} className={cn('text-fg-subtle transition-transform', open && 'rotate-90')} /></button>{open ? <div className=\"space-y-2 border-t border-border px-3 py-2\">{input !== undefined ? <AgentToolDetail label={inputLabel} value={input} /> : null}{output !== undefined ? <AgentToolDetail label={resultLabel} value={output} /> : null}</div> : null}</div>\n}\n\nfunction AgentToolDetail({ label, value }: { label: string; value: unknown }) {\n let text: string\n try { text = JSON.stringify(value, null, 2) } catch { text = String(value) }\n return <div><div className=\"mb-1 text-[11px] font-semibold tracking-wide text-fg-subtle uppercase\">{label}</div><pre className=\"max-h-60 overflow-auto rounded-md bg-surface p-2 text-xs leading-relaxed text-fg ring-1 ring-border\">{text}</pre></div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {\n parseJsonEventStream,\n readUIMessageStream,\n uiMessageChunkSchema,\n type UIMessageChunk,\n} from 'ai'\nimport {\n AlertCircle,\n CheckCircle2,\n ChevronRight,\n Database,\n ExternalLink,\n Eye,\n EyeOff,\n KeyRound,\n ListPlus,\n Loader2,\n Pencil,\n RotateCcw,\n Send,\n Sparkles,\n Square,\n Trash2,\n} from 'lucide-react'\nimport Markdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport { Button, EmptyState, Input, UiLink, cn } from '@braedonsaunders/appkit-ui'\n\nexport type AgentMessage = {\n id: string\n role: 'user' | 'assistant' | 'system'\n parts: unknown[]\n}\n\nexport type AgentQueuedMessage = {\n id: string\n text: string\n position: number\n status: 'queued' | 'dispatching' | 'retrying' | 'failed'\n statusLabel?: string\n editable?: boolean\n removable?: boolean\n retryable?: boolean\n}\n\nexport type AgentSecretRequestStatus = 'pending' | 'stored' | 'expired'\n\n/** Transcript-safe metadata for an inline credential request. */\nexport type AgentSecretRequestPart = {\n type: 'secret-request'\n requestId: string\n providerLabel: string\n credentialLabel: string\n purpose: string\n helpUrl?: string\n status: AgentSecretRequestStatus\n}\n\nexport type AgentSecretRequestLabels = {\n show: string\n hide: string\n submit: string\n cancel: string\n help: string\n submitting: string\n stored: string\n expired: string\n required: string\n failed: string\n cancelFailed: string\n}\n\nconst DEFAULT_SECRET_REQUEST_LABELS: AgentSecretRequestLabels = {\n show: 'Show credential',\n hide: 'Hide credential',\n submit: 'Submit securely',\n cancel: 'Cancel',\n help: 'Open setup instructions',\n submitting: 'Submitting securely',\n stored: 'Credential stored securely.',\n expired: 'This credential request has expired.',\n required: 'Enter the credential before submitting.',\n failed: 'The credential could not be submitted. Enter it again and retry.',\n cancelFailed: 'The credential request could not be canceled. Please retry.',\n}\n\nexport type AgentDispatchState = 'idle' | 'running' | 'recovering'\n\nexport type AgentPanelLabels = {\n title: string\n welcomeTitle: string\n welcomeDescription: string\n disabledTitle: string\n disabledDescription: string\n placeholder: string\n send: string\n stop: string\n failed: string\n input: string\n result: string\n working: string\n step: string\n steps: string\n queue: string\n queueTitle: string\n queuePosition: string\n queued: string\n dispatching: string\n retrying: string\n queueFailed: string\n editQueued: string\n removeQueued: string\n retryQueued: string\n responding: string\n}\n\nconst DEFAULT_LABELS: AgentPanelLabels = {\n title: 'Assistant',\n welcomeTitle: 'How can I help?',\n welcomeDescription: 'Ask about your workspace or let the assistant use an approved tool.',\n disabledTitle: 'Connect an AI provider',\n disabledDescription: 'Connect an AI provider to enable agent conversations. No provider credentials are included in the demo.',\n placeholder: 'Ask the assistant…',\n send: 'Send',\n stop: 'Stop generating',\n failed: 'The assistant could not complete that turn. Please try again.',\n input: 'Input',\n result: 'Result',\n working: 'Working',\n step: 'step',\n steps: 'steps',\n queue: 'Add to queue',\n queueTitle: 'Up next',\n queuePosition: 'Position',\n queued: 'Queued',\n dispatching: 'Starting',\n retrying: 'Retrying',\n queueFailed: 'This queued message needs attention.',\n editQueued: 'Edit queued message',\n removeQueued: 'Remove queued message',\n retryQueued: 'Retry queued message',\n responding: 'Assistant is responding',\n}\n\nexport type AgentPanelProps = {\n enabled: boolean\n initialMessages?: AgentMessage[]\n suggestions?: string[]\n labels?: Partial<AgentPanelLabels>\n headerActions?: React.ReactNode\n /** Replaces the stock empty-state card while preserving the panel header and composer. */\n emptyContent?: React.ReactNode\n /** Application-owned draft UI rendered immediately above the composer row. */\n composerContent?: React.ReactNode\n /** Application-owned controls rendered before the text input. */\n composerActions?: React.ReactNode\n /**\n * Non-text content currently attached to the draft. `fallbackPrompt` makes\n * a file-only draft sendable; `parts` are included in the optimistic user\n * turn so the attachment does not disappear while the response streams.\n */\n composerDraft?: { fallbackPrompt?: string; parts?: readonly unknown[] }\n send?: (prompt: string, signal: AbortSignal) => Promise<Response>\n /** Durable dispatch state supplied by the application after reload or handoff. */\n dispatchState?: AgentDispatchState\n /** Application-owned queue, already ordered by its durable dispatch position. */\n queuedMessages?: readonly AgentQueuedMessage[]\n /** Persists a turn behind the active or previously queued work. */\n enqueue?: (prompt: string) => Promise<void>\n onEditQueuedMessage?: (message: AgentQueuedMessage) => void\n onRemoveQueuedMessage?: (message: AgentQueuedMessage) => void\n onRetryQueuedMessage?: (message: AgentQueuedMessage) => void\n /** Receives the transient input value after AppKit clears the field. */\n onSubmitSecretRequest?: (requestId: string, secret: string) => void | Promise<void>\n onCancelSecretRequest?: (requestId: string) => void | Promise<void>\n secretRequestLabels?: Partial<AgentSecretRequestLabels>\n maxPromptCharacters?: number\n toolLabels?: Record<string, string>\n}\n\n/**\n * The streaming thread/composer extracted from the sibling assistant. The app\n * owns persistence and the HTTP transport; appkit owns UI-message decoding,\n * cancellation, ordered part rendering, and tool cards.\n */\nexport function AgentPanel({\n enabled,\n initialMessages = [],\n suggestions = [],\n labels: labelOverrides,\n headerActions,\n emptyContent,\n composerContent,\n composerActions,\n composerDraft,\n send,\n dispatchState = 'idle',\n queuedMessages = [],\n enqueue,\n onEditQueuedMessage,\n onRemoveQueuedMessage,\n onRetryQueuedMessage,\n onSubmitSecretRequest,\n onCancelSecretRequest,\n secretRequestLabels,\n maxPromptCharacters = 32_000,\n toolLabels,\n}: AgentPanelProps) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides }\n const [messages, setMessages] = React.useState(initialMessages)\n const [input, setInput] = React.useState('')\n const [streaming, setStreaming] = React.useState(false)\n const [enqueueing, setEnqueueing] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const abortRef = React.useRef<AbortController | null>(null)\n const messageViewportRef = React.useRef<HTMLDivElement>(null)\n\n const scrollToBottom = React.useCallback(() => {\n window.requestAnimationFrame(() => {\n const viewport = messageViewportRef.current\n if (viewport) viewport.scrollTop = viewport.scrollHeight\n })\n }, [])\n\n // An existing conversation opens where work most recently happened. Keep\n // this scoped to the panel's own viewport: scrollIntoView also moves every\n // scrolling ancestor and can make an otherwise app-height page jump.\n React.useLayoutEffect(() => {\n scrollToBottom()\n }, [scrollToBottom])\n\n const submit = React.useCallback(async (raw: string) => {\n const prompt = raw.trim() || composerDraft?.fallbackPrompt?.trim() || ''\n if (!enabled || !prompt || prompt.length > maxPromptCharacters) return\n const shouldEnqueue = dispatchState !== 'idle' || abortRef.current !== null || queuedMessages.length > 0\n if (shouldEnqueue) {\n if (!enqueue || enqueueing) return\n setEnqueueing(true)\n setError(null)\n try {\n await enqueue(prompt)\n setInput('')\n } catch {\n setError(labels.queueFailed)\n } finally {\n setEnqueueing(false)\n }\n return\n }\n if (!send) return\n const controller = new AbortController()\n abortRef.current = controller\n const stamp = Date.now()\n setInput('')\n setError(null)\n setMessages((current) => [...current, { id: `user-${stamp}`, role: 'user', parts: [{ type: 'text', text: prompt }, ...(composerDraft?.parts ?? [])] }, { id: `assistant-${stamp}`, role: 'assistant', parts: [] }])\n setStreaming(true)\n scrollToBottom()\n let producedParts = false\n try {\n const response = await send(prompt, controller.signal)\n if (!response.ok || !response.body) throw new Error('agent request failed')\n const chunks = parseJsonEventStream({ stream: response.body, schema: uiMessageChunkSchema }).pipeThrough(new TransformStream<{ success: boolean; value?: UIMessageChunk }, UIMessageChunk>({ transform(part, stream) { if (part.success && part.value) stream.enqueue(part.value) } }))\n let lastParts: unknown[] = []\n for await (const message of readUIMessageStream({ stream: chunks })) {\n lastParts = message.parts as unknown[]\n producedParts = lastParts.length > 0\n setMessages((current) => replaceLastAssistantParts(current, lastParts))\n scrollToBottom()\n }\n if (lastParts.length === 0 && !controller.signal.aborted) setError(labels.failed)\n } catch (reason) {\n if ((reason as Error).name !== 'AbortError') setError(labels.failed)\n } finally {\n if (!producedParts) {\n setMessages((current) => current.filter((message) => message.id !== `assistant-${stamp}`))\n }\n setStreaming(false)\n if (abortRef.current === controller) abortRef.current = null\n }\n }, [composerDraft, dispatchState, enabled, enqueue, enqueueing, labels.failed, labels.queueFailed, maxPromptCharacters, queuedMessages.length, scrollToBottom, send])\n\n const queueMode = dispatchState !== 'idle' || streaming || queuedMessages.length > 0\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col bg-bg-subtle\">\n <header className=\"flex h-12 shrink-0 items-center gap-2 border-b border-border bg-surface px-4\"><Sparkles size={16} className=\"text-primary\" /><span className=\"text-sm font-medium text-fg\">{labels.title}</span>{headerActions != null ? <div className=\"ml-auto flex items-center gap-2\">{headerActions}</div> : null}</header>\n <div ref={messageViewportRef} className=\"app-scroll min-h-0 flex-1 overflow-y-auto\">\n {messages.length === 0 && emptyContent != null ? (\n <div className=\"flex min-h-full flex-col\">{emptyContent}</div>\n ) : (\n <div className=\"mx-auto w-full max-w-3xl px-4 py-6\">\n {messages.length === 0 ? <AgentWelcome enabled={enabled} title={enabled ? labels.welcomeTitle : labels.disabledTitle} description={enabled ? labels.welcomeDescription : labels.disabledDescription} suggestions={suggestions} onPick={(value) => void submit(value)} /> : <div className=\"space-y-6\">{messages.map((message) => message.role === 'system' ? null : <AgentMessageRow key={message.id} message={message} streaming={streaming} labels={labels} toolLabels={toolLabels} onSubmitSecretRequest={onSubmitSecretRequest} onCancelSecretRequest={onCancelSecretRequest} secretRequestLabels={secretRequestLabels} />)}</div>}\n </div>\n )}\n {error ? <div role=\"alert\" className=\"mx-auto mb-5 w-[calc(100%-2rem)] max-w-3xl rounded-lg border border-danger/25 bg-danger-subtle px-3 py-2 text-sm text-danger\">{error}</div> : null}\n </div>\n {enabled ? <div className=\"shrink-0 border-t border-border bg-surface px-4 py-3\"><div className=\"mx-auto w-full max-w-3xl\">{queuedMessages.length > 0 ? <AgentMessageQueue messages={queuedMessages} labels={labels} onEdit={onEditQueuedMessage} onRemove={onRemoveQueuedMessage} onRetry={onRetryQueuedMessage} /> : null}{composerContent != null ? <div className=\"mb-2\">{composerContent}</div> : null}<div className=\"flex items-end gap-2 rounded-2xl border border-border-strong bg-surface p-2 shadow-sm focus-within:border-primary focus-within:ring-2 focus-within:ring-ring/20\">{composerActions}<textarea value={input} onChange={(event) => setInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); void submit(input) } }} maxLength={maxPromptCharacters} rows={1} placeholder={labels.placeholder} className=\"max-h-40 flex-1 resize-none overflow-y-auto border-0 bg-transparent px-2 py-1.5 text-base text-fg outline-none placeholder:text-fg-subtle sm:text-sm\" />{streaming ? <Button type=\"button\" variant=\"outline\" size=\"icon\" onClick={() => abortRef.current?.abort()} aria-label={labels.stop}><Square size={16} /></Button> : null}<Button type=\"button\" size=\"icon\" onClick={() => void submit(input)} disabled={!(input.trim() || composerDraft?.fallbackPrompt?.trim()) || (queueMode ? !enqueue || enqueueing : !send)} aria-label={queueMode ? labels.queue : labels.send}>{enqueueing ? <Loader2 size={16} className=\"animate-spin\" /> : queueMode ? <ListPlus size={16} /> : <Send size={16} />}</Button></div></div></div> : null}\n </div>\n )\n}\n\nexport function AgentMessageQueue({\n messages,\n labels: labelOverrides,\n onEdit,\n onRemove,\n onRetry,\n}: {\n messages: readonly AgentQueuedMessage[]\n labels?: Partial<AgentPanelLabels>\n onEdit?: (message: AgentQueuedMessage) => void\n onRemove?: (message: AgentQueuedMessage) => void\n onRetry?: (message: AgentQueuedMessage) => void\n}) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides }\n return (\n <section className=\"mb-3 rounded-xl border border-border bg-bg-subtle p-2\" aria-label={labels.queueTitle}>\n <div className=\"px-2 pb-1 text-xs font-medium text-fg-muted\">{labels.queueTitle}</div>\n <ol className=\"space-y-1\">\n {messages.map((message) => (\n <li key={message.id} className=\"flex min-w-0 items-center gap-2 rounded-lg bg-surface px-2 py-1.5 shadow-xs\">\n <span className=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary-subtle text-xs font-medium text-primary\" aria-label={`${labels.queuePosition} ${message.position}`}>{message.position}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm text-fg\">{message.text}</span>\n <span className={cn('shrink-0 text-xs', message.status === 'failed' ? 'text-danger' : 'text-fg-muted')}>{message.statusLabel ?? queueStatusLabel(message.status, labels)}</span>\n {message.retryable && onRetry ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onRetry(message)} aria-label={labels.retryQueued}><RotateCcw size={14} /></Button> : null}\n {message.editable && onEdit ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onEdit(message)} aria-label={labels.editQueued}><Pencil size={14} /></Button> : null}\n {message.removable && onRemove ? <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"size-7\" onClick={() => onRemove(message)} aria-label={labels.removeQueued}><Trash2 size={14} /></Button> : null}\n </li>\n ))}\n </ol>\n </section>\n )\n}\n\nfunction queueStatusLabel(status: AgentQueuedMessage['status'], labels: AgentPanelLabels): string {\n if (status === 'dispatching') return labels.dispatching\n if (status === 'retrying') return labels.retrying\n if (status === 'failed') return labels.queueFailed\n return labels.queued\n}\n\nfunction replaceLastAssistantParts(messages: AgentMessage[], parts: unknown[]): AgentMessage[] {\n const copy = messages.slice()\n for (let index = copy.length - 1; index >= 0; index -= 1) {\n if (copy[index]?.role === 'assistant') { copy[index] = { ...copy[index]!, parts }; break }\n }\n return copy\n}\n\nfunction AgentWelcome({ enabled, title, description, suggestions, onPick }: { enabled: boolean; title: string; description: string; suggestions: string[]; onPick: (value: string) => void }) {\n return <div className=\"pt-10\"><EmptyState icon={<Sparkles />} title={title} description={description} />{enabled && suggestions.length ? <div className=\"mx-auto mt-6 grid max-w-2xl gap-2 sm:grid-cols-2\">{suggestions.map((suggestion) => <button key={suggestion} type=\"button\" onClick={() => onPick(suggestion)} className=\"rounded-xl border border-border bg-surface px-4 py-3 text-left text-sm text-fg-muted shadow-sm transition-colors hover:border-primary/40 hover:bg-primary-subtle hover:text-fg\">{suggestion}</button>)}</div> : null}</div>\n}\n\nfunction AgentMessageRow({ message, streaming, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels }: { message: AgentMessage; streaming: boolean; labels: AgentPanelLabels; toolLabels?: Record<string, string>; onSubmitSecretRequest?: AgentPanelProps['onSubmitSecretRequest']; onCancelSecretRequest?: AgentPanelProps['onCancelSecretRequest']; secretRequestLabels?: Partial<AgentSecretRequestLabels> }) {\n if (message.role === 'user') {\n const text = (message.parts.find((part) => (part as { type?: string }).type === 'text') as { text?: string } | undefined)?.text\n const files = message.parts.filter(isAgentFilePart)\n return <div className=\"flex justify-end\"><div className=\"max-w-[85%] space-y-2 rounded-2xl rounded-br-md bg-primary px-4 py-2 text-sm whitespace-pre-wrap text-primary-fg\">{text ? <div>{text}</div> : null}{files.length > 0 ? <div className=\"flex flex-wrap justify-end gap-1.5\">{files.map((file, index) => file.url ? <a key={`${file.filename}-${index}`} href={file.url} className=\"rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium hover:bg-primary-fg/15\" download>{file.filename}</a> : <span key={`${file.filename}-${index}`} className=\"rounded-md border border-primary-fg/25 bg-primary-fg/10 px-2 py-1 text-xs font-medium\">{file.filename}</span>)}</div> : null}</div></div>\n }\n return <div className=\"flex gap-3\"><span className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-primary-fg shadow-sm\"><Sparkles size={16} /></span><div className=\"min-w-0 flex-1 pt-0.5\">{message.parts.length === 0 && streaming ? <AgentTypingIndicator label={labels.responding} /> : <AgentMessageParts parts={message.parts} labels={labels} toolLabels={toolLabels} onSubmitSecretRequest={onSubmitSecretRequest} onCancelSecretRequest={onCancelSecretRequest} secretRequestLabels={secretRequestLabels} />}</div></div>\n}\n\nconst TYPING_DOT_DELAYS = [\n '0ms',\n 'var(--duration-fast)',\n 'calc(var(--duration-fast) + var(--duration-fast))',\n] as const\n\n/**\n * A self-contained streaming cue that does not depend on the consuming app's\n * Tailwind content scan. The cadence uses AppKit motion tokens and becomes a\n * still, readable ellipsis when the user requests reduced motion.\n */\nexport function AgentTypingIndicator({ label = DEFAULT_LABELS.responding }: { label?: string }) {\n return (\n <div role=\"status\" aria-label={label} className=\"flex items-center gap-1 py-1.5\">\n <style>{`\n @keyframes appkit-agent-typing-dot {\n 0%, 36%, 100% { opacity: 0.55; transform: translateY(0); }\n 18% { opacity: 1; transform: translateY(-0.2rem); }\n }\n .appkit-agent-typing-dot {\n animation: appkit-agent-typing-dot calc(var(--duration-slow) + var(--duration-slow) + var(--duration-slow)) var(--ease-out) infinite;\n will-change: transform, opacity;\n }\n @media (prefers-reduced-motion: reduce) {\n .appkit-agent-typing-dot {\n animation: none;\n opacity: 0.7;\n transform: none;\n will-change: auto;\n }\n }\n `}</style>\n {TYPING_DOT_DELAYS.map((animationDelay) => (\n <span\n key={animationDelay}\n aria-hidden=\"true\"\n className=\"appkit-agent-typing-dot size-1.5 rounded-full bg-fg-subtle\"\n style={{ animationDelay }}\n />\n ))}\n </div>\n )\n}\n\nfunction isAgentFilePart(part: unknown): part is { type: 'file'; filename: string; url?: string } {\n if (!part || typeof part !== 'object') return false\n const candidate = part as { type?: unknown; filename?: unknown; url?: unknown }\n return candidate.type === 'file'\n && typeof candidate.filename === 'string'\n && candidate.filename.trim().length > 0\n && (candidate.url === undefined || typeof candidate.url === 'string')\n}\n\nfunction AgentMessageParts({ parts, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels }: { parts: unknown[]; labels: AgentPanelLabels; toolLabels?: Record<string, string>; onSubmitSecretRequest?: AgentPanelProps['onSubmitSecretRequest']; onCancelSecretRequest?: AgentPanelProps['onCancelSecretRequest']; secretRequestLabels?: Partial<AgentSecretRequestLabels> }) {\n const rendered: React.ReactNode[] = []\n let tools: AgentToolPart[] = []\n let toolGroupStart = 0\n const flushTools = () => {\n if (tools.length === 0) return\n rendered.push(<AgentToolActivity key={`tools-${toolGroupStart}`} parts={tools} labels={labels} toolLabels={toolLabels} />)\n tools = []\n }\n parts.forEach((value, index) => {\n if (!value || typeof value !== 'object' || typeof (value as { type?: unknown }).type !== 'string') return\n const part = value as { type: string; [key: string]: unknown }\n if (isAgentToolPart(part)) {\n if (tools.length === 0) toolGroupStart = index\n tools.push(part)\n return\n }\n if (part.type === 'step-start' || part.type === 'reasoning') return\n flushTools()\n if (isAgentSecretRequestPart(part)) {\n rendered.push(<AgentSecretRequestCard key={`secret-${part.requestId}-${part.status}`} request={part} labels={secretRequestLabels} onSubmit={onSubmitSecretRequest} onCancel={onCancelSecretRequest} />)\n return\n }\n if (part.type === 'text' && typeof part.text === 'string' && part.text.trim()) {\n rendered.push(<ChatMarkdown key={`text-${index}`}>{part.text}</ChatMarkdown>)\n }\n })\n flushTools()\n return <div className=\"space-y-2.5\">{rendered}</div>\n}\n\nfunction isAgentSecretRequestPart(part: { type: string; [key: string]: unknown }): part is AgentSecretRequestPart & { [key: string]: unknown } {\n return part.type === 'secret-request'\n && typeof part.requestId === 'string'\n && part.requestId.trim().length > 0\n && typeof part.providerLabel === 'string'\n && part.providerLabel.trim().length > 0\n && typeof part.credentialLabel === 'string'\n && part.credentialLabel.trim().length > 0\n && typeof part.purpose === 'string'\n && part.purpose.trim().length > 0\n && (part.helpUrl === undefined || typeof part.helpUrl === 'string')\n && (part.status === 'pending' || part.status === 'stored' || part.status === 'expired')\n}\n\nfunction safeSecretHelpUrl(value: string | undefined): string | undefined {\n if (!value) return undefined\n if (value.startsWith('/') && !value.startsWith('//')) return value\n try {\n const url = new URL(value)\n return url.protocol === 'https:' ? url.href : undefined\n } catch {\n return undefined\n }\n}\n\nexport type AgentSecretRequestCardProps = {\n request: AgentSecretRequestPart\n labels?: Partial<AgentSecretRequestLabels>\n onSubmit?: (requestId: string, secret: string) => void | Promise<void>\n onCancel?: (requestId: string) => void | Promise<void>\n}\n\n/**\n * Inline credential handoff for an assistant transcript. The password field is\n * uncontrolled: its value is read directly from the DOM, cleared before the\n * caller receives it, and never copied into React or transcript state.\n */\nexport function AgentSecretRequestCard({ request, labels: labelOverrides, onSubmit, onCancel }: AgentSecretRequestCardProps) {\n const labels = { ...DEFAULT_SECRET_REQUEST_LABELS, ...labelOverrides }\n const inputId = React.useId()\n const inputRef = React.useRef<HTMLInputElement>(null)\n const [revealed, setRevealed] = React.useState(false)\n const [submitting, setSubmitting] = React.useState(false)\n const [settledStatus, setSettledStatus] = React.useState<Exclude<AgentSecretRequestStatus, 'pending'> | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const requestIdentityRef = React.useRef(`${request.requestId}:${request.status}`)\n const status = settledStatus ?? request.status\n const helpUrl = safeSecretHelpUrl(request.helpUrl)\n\n const clearInput = React.useCallback(() => {\n if (inputRef.current) inputRef.current.value = ''\n }, [])\n\n React.useEffect(() => {\n const identity = `${request.requestId}:${request.status}`\n if (requestIdentityRef.current !== identity) {\n requestIdentityRef.current = identity\n clearInput()\n setRevealed(false)\n setSubmitting(false)\n setSettledStatus(null)\n setError(null)\n }\n }, [clearInput, request.requestId, request.status])\n\n React.useEffect(() => {\n return clearInput\n }, [clearInput])\n\n const submit = React.useCallback(async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n if (!onSubmit || submitting || status !== 'pending') return\n const secret = inputRef.current?.value ?? ''\n if (secret.length === 0) {\n setError(labels.required)\n inputRef.current?.focus()\n return\n }\n clearInput()\n setRevealed(false)\n setError(null)\n setSubmitting(true)\n try {\n await onSubmit(request.requestId, secret)\n setSettledStatus('stored')\n } catch {\n setError(labels.failed)\n inputRef.current?.focus()\n } finally {\n clearInput()\n setSubmitting(false)\n }\n }, [clearInput, labels.failed, labels.required, onSubmit, request.requestId, status, submitting])\n\n const cancel = React.useCallback(async () => {\n if (!onCancel || submitting || status !== 'pending') return\n clearInput()\n setRevealed(false)\n setError(null)\n setSubmitting(true)\n try {\n await onCancel(request.requestId)\n setSettledStatus('expired')\n } catch {\n setError(labels.cancelFailed)\n } finally {\n clearInput()\n setSubmitting(false)\n }\n }, [clearInput, labels.cancelFailed, onCancel, request.requestId, status, submitting])\n\n return (\n <section className=\"overflow-hidden rounded-xl border border-border bg-surface shadow-sm\" aria-labelledby={`${inputId}-title`}>\n <div className=\"flex items-start gap-3 p-3\">\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary-subtle text-primary\"><KeyRound size={16} /></span>\n <div className=\"min-w-0 flex-1\">\n <div id={`${inputId}-title`} className=\"text-sm font-semibold text-fg\">{request.providerLabel}</div>\n <div className=\"mt-0.5 text-xs font-medium text-fg-muted\">{request.credentialLabel}</div>\n <p className=\"mt-1.5 text-sm leading-relaxed text-fg-muted\">{request.purpose}</p>\n {helpUrl ? helpUrl.startsWith('/') ? <UiLink href={helpUrl} className=\"mt-2 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline\">{labels.help}</UiLink> : <a href={helpUrl} target=\"_blank\" rel=\"noreferrer\" className=\"mt-2 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline\">{labels.help}<ExternalLink size={12} aria-hidden=\"true\" /></a> : null}\n </div>\n </div>\n {status === 'pending' ? (\n <form onSubmit={(event) => void submit(event)} onKeyDown={(event) => { if (event.key === 'Escape') { event.preventDefault(); void cancel() } }} className=\"space-y-2.5 border-t border-border bg-bg-subtle p-3\">\n <label htmlFor={inputId} className=\"sr-only\">{request.credentialLabel}</label>\n <div className=\"relative\">\n <Input ref={inputRef} id={inputId} type={revealed ? 'text' : 'password'} autoComplete=\"new-password\" autoCapitalize=\"none\" spellCheck={false} disabled={submitting || !onSubmit} aria-invalid={error ? true : undefined} onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); event.currentTarget.form?.requestSubmit() } }} className=\"pr-11 font-mono\" />\n <button type=\"button\" onClick={() => setRevealed((value) => !value)} disabled={submitting || !onSubmit} aria-label={revealed ? labels.hide : labels.show} aria-pressed={revealed} className=\"absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-md text-fg-muted transition-colors hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/60 disabled:pointer-events-none disabled:opacity-50 motion-reduce:transition-none\">{revealed ? <EyeOff size={16} /> : <Eye size={16} />}</button>\n </div>\n {error ? <p role=\"alert\" className=\"text-xs text-danger\">{error}</p> : null}\n <div className=\"flex items-center justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => void cancel()} disabled={submitting || !onCancel}>{labels.cancel}</Button>\n <Button type=\"submit\" size=\"sm\" disabled={submitting || !onSubmit}>{submitting ? <><Loader2 size={14} className=\"animate-spin motion-reduce:animate-none\" />{labels.submitting}</> : labels.submit}</Button>\n </div>\n </form>\n ) : (\n <div role=\"status\" className={cn('flex items-center gap-2 border-t border-border px-3 py-2.5 text-sm font-medium', status === 'stored' ? 'bg-success-subtle text-success' : 'bg-bg-subtle text-fg-muted')}>\n {status === 'stored' ? <CheckCircle2 size={16} /> : <AlertCircle size={16} />}\n {status === 'stored' ? labels.stored : labels.expired}\n </div>\n )}\n </section>\n )\n}\n\ntype AgentToolPart = { type: string; toolName?: unknown; state?: unknown; input?: unknown; output?: unknown }\n\nfunction isAgentToolPart(part: { type: string }): part is AgentToolPart {\n return part.type === 'dynamic-tool' || part.type.startsWith('tool-')\n}\n\nfunction agentToolName(part: AgentToolPart): string {\n return part.type === 'dynamic-tool' ? String(part.toolName ?? 'tool') : part.type.slice(5)\n}\n\nfunction agentToolRunning(part: AgentToolPart): boolean {\n const state = String(part.state ?? 'output-available')\n return state === 'input-streaming' || state === 'input-available'\n}\n\nfunction agentToolErrored(part: AgentToolPart): boolean {\n return String(part.state) === 'output-error' || (part.output as { ok?: boolean } | undefined)?.ok === false\n}\n\n/**\n * A multi-step run stays quiet in the transcript: the newest action and total\n * step count occupy one line, while the complete inputs/results remain one\n * click away. Applications keep their full durable audit trail separately.\n */\nfunction AgentToolActivity({ parts, labels, toolLabels }: { parts: AgentToolPart[]; labels: AgentPanelLabels; toolLabels?: Record<string, string> }) {\n const [open, setOpen] = React.useState(false)\n const latest = parts.at(-1)!\n const latestName = agentToolName(latest)\n const running = parts.some(agentToolRunning)\n const errored = parts.some(agentToolErrored)\n const count = parts.length\n const status = running ? labels.working : `${count} ${count === 1 ? labels.step : labels.steps}`\n return <div className=\"text-sm\"><button type=\"button\" onClick={() => setOpen((value) => !value)} aria-expanded={open} className=\"flex h-7 max-w-full items-center gap-1.5 rounded-md px-1.5 text-left text-xs text-fg-muted transition-colors hover:bg-surface-hover hover:text-fg\"><span className={cn('size-1.5 shrink-0 rounded-full', running ? 'animate-pulse bg-primary' : errored ? 'bg-danger' : 'bg-success')} /><span className=\"shrink-0 font-medium\">{status}</span><span aria-hidden className=\"text-fg-subtle\">·</span><span className=\"min-w-0 truncate\">{toolLabels?.[latestName] ?? latestName.replaceAll('_', ' ')}</span><ChevronRight size={12} className={cn('shrink-0 text-fg-subtle transition-transform', open && 'rotate-90')} /></button>{open ? <div className=\"mt-1.5 space-y-1.5 border-l border-border pl-2\">{parts.map((part, index) => { const name = agentToolName(part); return <AgentToolCard key={`${name}-${index}`} name={name} label={toolLabels?.[name]} state={String(part.state ?? 'output-available')} input={part.input} output={part.output} inputLabel={labels.input} resultLabel={labels.result} /> })}</div> : null}</div>\n}\n\nexport function ChatMarkdown({ children }: { children: string }) {\n return <div className=\"space-y-2 text-sm leading-relaxed text-fg\"><Markdown remarkPlugins={[remarkGfm]} components={{ p: ({ children: content }) => <p className=\"whitespace-pre-wrap\">{content}</p>, h1: ({ children: content }) => <h1 className=\"text-lg font-semibold\">{content}</h1>, h2: ({ children: content }) => <h2 className=\"text-base font-semibold\">{content}</h2>, ul: ({ children: content }) => <ul className=\"list-disc space-y-1 pl-5\">{content}</ul>, ol: ({ children: content }) => <ol className=\"list-decimal space-y-1 pl-5\">{content}</ol>, code: ({ children: content }) => <code className=\"rounded bg-bg-subtle px-1 py-0.5 font-mono text-[0.85em] text-primary\">{content}</code>, pre: ({ children: content }) => <pre className=\"overflow-auto rounded-lg bg-overlay p-3 text-sm whitespace-pre-wrap text-white\">{content}</pre>, table: ({ children: content }) => <div className=\"overflow-x-auto\"><table className=\"w-full border-collapse text-sm\">{content}</table></div>, th: ({ children: content }) => <th className=\"border-b border-border px-2 py-1 text-left\">{content}</th>, td: ({ children: content }) => <td className=\"border-b border-border-subtle px-2 py-1\">{content}</td>, a: ({ href, children: content }) => href?.startsWith('/') ? <UiLink href={href} className=\"font-medium text-primary underline-offset-2 hover:underline\">{content}</UiLink> : <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"font-medium text-primary underline-offset-2 hover:underline\">{content}</a> }}>{children}</Markdown></div>\n}\n\nexport function AgentToolCard({ name, label, state, input, output, inputLabel = 'Input', resultLabel = 'Result' }: { name: string; label?: string; state: string; input?: unknown; output?: unknown; inputLabel?: string; resultLabel?: string }) {\n const [open, setOpen] = React.useState(false)\n const running = state === 'input-streaming' || state === 'input-available'\n const errored = state === 'output-error' || (output as { ok?: boolean } | undefined)?.ok === false\n return <div className=\"overflow-hidden rounded-lg border border-border bg-bg-subtle text-sm\"><button type=\"button\" onClick={() => setOpen((value) => !value)} className=\"flex w-full items-center gap-2.5 px-3 py-2 text-left transition-colors hover:bg-surface-hover\"><span className={cn('flex size-6 shrink-0 items-center justify-center rounded-md', errored ? 'bg-danger-subtle text-danger' : 'bg-primary-subtle text-primary')}><Database size={14} /></span><span className=\"min-w-0 flex-1 truncate font-medium text-fg\">{label ?? name.replaceAll('_', ' ')}</span>{running ? <Loader2 size={14} className=\"animate-spin text-fg-subtle\" /> : errored ? <AlertCircle size={14} className=\"text-danger\" /> : <CheckCircle2 size={14} className=\"text-success\" />}<ChevronRight size={14} className={cn('text-fg-subtle transition-transform', open && 'rotate-90')} /></button>{open ? <div className=\"space-y-2 border-t border-border px-3 py-2\">{input !== undefined ? <AgentToolDetail label={inputLabel} value={input} /> : null}{output !== undefined ? <AgentToolDetail label={resultLabel} value={output} /> : null}</div> : null}</div>\n}\n\nfunction AgentToolDetail({ label, value }: { label: string; value: unknown }) {\n let text: string\n try { text = JSON.stringify(value, null, 2) } catch { text = String(value) }\n return <div><div className=\"mb-1 text-[11px] font-semibold tracking-wide text-fg-subtle uppercase\">{label}</div><pre className=\"max-h-60 overflow-auto rounded-md bg-surface p-2 text-xs leading-relaxed text-fg ring-1 ring-border\">{text}</pre></div>\n}\n"]}
|