@braedonsaunders/appkit-ai 1.1.2 → 1.1.4

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 CHANGED
@@ -29,6 +29,47 @@ three-dot typing cadence through the exported `AgentTypingIndicator`. Its pure
29
29
  CSS motion uses AppKit duration/easing tokens, is independent of an app's
30
30
  Tailwind content scan, and becomes a static ellipsis under reduced motion.
31
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
+ Governed actions can use a typed `approval-request` part with an approval id,
43
+ category, human-readable description, optional exact-action details, and a
44
+ durable pending/approved/rejected/expired status. `AgentPanel` renders the
45
+ exported `AgentApprovalRequestCard` inline, so an agent can end a suspended turn
46
+ with a clear handoff instead of a bare tool call. Applications persist and
47
+ authorize the decision through `onDecideApprovalRequest`; AppKit never treats
48
+ rendering the card as authorization.
49
+
50
+ ```tsx
51
+ <AgentPanel
52
+ enabled
53
+ initialMessages={[{
54
+ id: 'assistant-credential',
55
+ role: 'assistant',
56
+ parts: [{
57
+ type: 'secret-request',
58
+ requestId: request.id,
59
+ providerLabel: 'Delivery provider',
60
+ credentialLabel: 'API key',
61
+ purpose: 'Authorize approved carrier status updates.',
62
+ helpUrl: 'https://provider.example/docs/api-keys',
63
+ status: request.status,
64
+ }],
65
+ }]}
66
+ onSubmitSecretRequest={async (requestId, secret) => {
67
+ await storeSealedCredential({ requestId, secret })
68
+ }}
69
+ onCancelSecretRequest={expireCredentialRequest}
70
+ />
71
+ ```
72
+
32
73
  Applications with durable session dispatch can pass `dispatchState` and an
33
74
  ordered `queuedMessages` collection. While work is running, recovering, or
34
75
  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.2",
3
+ "version": "1.1.4",
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,55 @@ export type AgentQueuedMessage = {
14
14
  removable?: boolean;
15
15
  retryable?: boolean;
16
16
  };
17
+ export type AgentSecretRequestStatus = 'pending' | 'stored' | 'expired';
18
+ export type AgentApprovalRequestStatus = 'pending' | 'approved' | 'rejected' | 'expired';
19
+ /** Transcript-safe metadata for an inline governed-action decision. */
20
+ export type AgentApprovalRequestPart = {
21
+ type: 'approval-request';
22
+ approvalId: string;
23
+ categoryLabel: string;
24
+ description: string;
25
+ details?: Array<{
26
+ label: string;
27
+ value: string;
28
+ }>;
29
+ status: AgentApprovalRequestStatus;
30
+ decisionNote?: string;
31
+ };
32
+ export type AgentApprovalRequestLabels = {
33
+ title: string;
34
+ note: string;
35
+ approve: string;
36
+ reject: string;
37
+ deciding: string;
38
+ approved: string;
39
+ rejected: string;
40
+ expired: string;
41
+ failed: string;
42
+ };
43
+ /** Transcript-safe metadata for an inline credential request. */
44
+ export type AgentSecretRequestPart = {
45
+ type: 'secret-request';
46
+ requestId: string;
47
+ providerLabel: string;
48
+ credentialLabel: string;
49
+ purpose: string;
50
+ helpUrl?: string;
51
+ status: AgentSecretRequestStatus;
52
+ };
53
+ export type AgentSecretRequestLabels = {
54
+ show: string;
55
+ hide: string;
56
+ submit: string;
57
+ cancel: string;
58
+ help: string;
59
+ submitting: string;
60
+ stored: string;
61
+ expired: string;
62
+ required: string;
63
+ failed: string;
64
+ cancelFailed: string;
65
+ };
17
66
  export type AgentDispatchState = 'idle' | 'running' | 'recovering';
18
67
  export type AgentPanelLabels = {
19
68
  title: string;
@@ -73,6 +122,12 @@ export type AgentPanelProps = {
73
122
  onEditQueuedMessage?: (message: AgentQueuedMessage) => void;
74
123
  onRemoveQueuedMessage?: (message: AgentQueuedMessage) => void;
75
124
  onRetryQueuedMessage?: (message: AgentQueuedMessage) => void;
125
+ /** Receives the transient input value after AppKit clears the field. */
126
+ onSubmitSecretRequest?: (requestId: string, secret: string) => void | Promise<void>;
127
+ onCancelSecretRequest?: (requestId: string) => void | Promise<void>;
128
+ secretRequestLabels?: Partial<AgentSecretRequestLabels>;
129
+ onDecideApprovalRequest?: (approvalId: string, decision: 'approved' | 'rejected', note?: string) => void | Promise<void>;
130
+ approvalRequestLabels?: Partial<AgentApprovalRequestLabels>;
76
131
  maxPromptCharacters?: number;
77
132
  toolLabels?: Record<string, string>;
78
133
  };
@@ -81,7 +136,7 @@ export type AgentPanelProps = {
81
136
  * owns persistence and the HTTP transport; appkit owns UI-message decoding,
82
137
  * cancellation, ordered part rendering, and tool cards.
83
138
  */
84
- 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;
139
+ export declare function AgentPanel({ enabled, initialMessages, suggestions, labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState, queuedMessages, enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, onDecideApprovalRequest, approvalRequestLabels, maxPromptCharacters, toolLabels, }: AgentPanelProps): React.JSX.Element;
85
140
  export declare function AgentMessageQueue({ messages, labels: labelOverrides, onEdit, onRemove, onRetry, }: {
86
141
  messages: readonly AgentQueuedMessage[];
87
142
  labels?: Partial<AgentPanelLabels>;
@@ -97,6 +152,25 @@ export declare function AgentMessageQueue({ messages, labels: labelOverrides, on
97
152
  export declare function AgentTypingIndicator({ label }: {
98
153
  label?: string;
99
154
  }): React.JSX.Element;
155
+ export type AgentApprovalRequestCardProps = {
156
+ request: AgentApprovalRequestPart;
157
+ labels?: Partial<AgentApprovalRequestLabels>;
158
+ onDecide?: (approvalId: string, decision: 'approved' | 'rejected', note?: string) => void | Promise<void>;
159
+ };
160
+ /** Inline, transcript-safe approval for a governed action. */
161
+ export declare function AgentApprovalRequestCard({ request, labels: labelOverrides, onDecide }: AgentApprovalRequestCardProps): React.JSX.Element;
162
+ export type AgentSecretRequestCardProps = {
163
+ request: AgentSecretRequestPart;
164
+ labels?: Partial<AgentSecretRequestLabels>;
165
+ onSubmit?: (requestId: string, secret: string) => void | Promise<void>;
166
+ onCancel?: (requestId: string) => void | Promise<void>;
167
+ };
168
+ /**
169
+ * Inline credential handoff for an assistant transcript. The password field is
170
+ * uncontrolled: its value is read directly from the DOM, cleared before the
171
+ * caller receives it, and never copied into React or transcript state.
172
+ */
173
+ export declare function AgentSecretRequestCard({ request, labels: labelOverrides, onSubmit, onCancel }: AgentSecretRequestCardProps): React.JSX.Element;
100
174
  export declare function ChatMarkdown({ children }: {
101
175
  children: string;
102
176
  }): 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":"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"}
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,35 @@
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, ShieldCheck, 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_APPROVAL_REQUEST_LABELS = {
10
+ title: 'Approval needed',
11
+ note: 'Add a note (optional)',
12
+ approve: 'Approve',
13
+ reject: 'Decline',
14
+ deciding: 'Saving decision',
15
+ approved: 'Approved. The agent will continue automatically.',
16
+ rejected: 'Declined. The agent will receive your decision.',
17
+ expired: 'This approval request has expired.',
18
+ failed: 'The decision could not be saved. Please retry.',
19
+ };
20
+ const DEFAULT_SECRET_REQUEST_LABELS = {
21
+ show: 'Show credential',
22
+ hide: 'Hide credential',
23
+ submit: 'Submit securely',
24
+ cancel: 'Cancel',
25
+ help: 'Open setup instructions',
26
+ submitting: 'Submitting securely',
27
+ stored: 'Credential stored securely.',
28
+ expired: 'This credential request has expired.',
29
+ required: 'Enter the credential before submitting.',
30
+ failed: 'The credential could not be submitted. Enter it again and retry.',
31
+ cancelFailed: 'The credential request could not be canceled. Please retry.',
32
+ };
9
33
  const DEFAULT_LABELS = {
10
34
  title: 'Assistant',
11
35
  welcomeTitle: 'How can I help?',
@@ -38,7 +62,7 @@ const DEFAULT_LABELS = {
38
62
  * owns persistence and the HTTP transport; appkit owns UI-message decoding,
39
63
  * cancellation, ordered part rendering, and tool cards.
40
64
  */
41
- 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, }) {
65
+ export function AgentPanel({ enabled, initialMessages = [], suggestions = [], labels: labelOverrides, headerActions, emptyContent, composerContent, composerActions, composerDraft, send, dispatchState = 'idle', queuedMessages = [], enqueue, onEditQueuedMessage, onRemoveQueuedMessage, onRetryQueuedMessage, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, onDecideApprovalRequest, approvalRequestLabels, maxPromptCharacters = 32_000, toolLabels, }) {
42
66
  const labels = { ...DEFAULT_LABELS, ...labelOverrides };
43
67
  const [messages, setMessages] = React.useState(initialMessages);
44
68
  const [input, setInput] = React.useState('');
@@ -123,7 +147,7 @@ export function AgentPanel({ enabled, initialMessages = [], suggestions = [], la
123
147
  }
124
148
  }, [composerDraft, dispatchState, enabled, enqueue, enqueueing, labels.failed, labels.queueFailed, maxPromptCharacters, queuedMessages.length, scrollToBottom, send]);
125
149
  const queueMode = dispatchState !== 'idle' || streaming || queuedMessages.length > 0;
126
- 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) {
150
+ 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, onDecideApprovalRequest: onDecideApprovalRequest, approvalRequestLabels: approvalRequestLabels }, 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) {
127
151
  event.preventDefault();
128
152
  void submit(input);
129
153
  } }, 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] }));
@@ -154,13 +178,13 @@ function replaceLastAssistantParts(messages, parts) {
154
178
  function AgentWelcome({ enabled, title, description, suggestions, onPick }) {
155
179
  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] });
156
180
  }
157
- function AgentMessageRow({ message, streaming, labels, toolLabels }) {
181
+ function AgentMessageRow({ message, streaming, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, onDecideApprovalRequest, approvalRequestLabels }) {
158
182
  if (message.role === 'user') {
159
183
  const text = message.parts.find((part) => part.type === 'text')?.text;
160
184
  const files = message.parts.filter(isAgentFilePart);
161
185
  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] }) });
162
186
  }
163
- 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 }) })] });
187
+ 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, onDecideApprovalRequest: onDecideApprovalRequest, approvalRequestLabels: approvalRequestLabels }) })] });
164
188
  }
165
189
  const TYPING_DOT_DELAYS = [
166
190
  '0ms',
@@ -201,7 +225,7 @@ function isAgentFilePart(part) {
201
225
  && candidate.filename.trim().length > 0
202
226
  && (candidate.url === undefined || typeof candidate.url === 'string');
203
227
  }
204
- function AgentMessageParts({ parts, labels, toolLabels }) {
228
+ function AgentMessageParts({ parts, labels, toolLabels, onSubmitSecretRequest, onCancelSecretRequest, secretRequestLabels, onDecideApprovalRequest, approvalRequestLabels }) {
205
229
  const rendered = [];
206
230
  let tools = [];
207
231
  let toolGroupStart = 0;
@@ -211,7 +235,10 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
211
235
  rendered.push(_jsx(AgentToolActivity, { parts: tools, labels: labels, toolLabels: toolLabels }, `tools-${toolGroupStart}`));
212
236
  tools = [];
213
237
  };
214
- parts.forEach((part, index) => {
238
+ parts.forEach((value, index) => {
239
+ if (!value || typeof value !== 'object' || typeof value.type !== 'string')
240
+ return;
241
+ const part = value;
215
242
  if (isAgentToolPart(part)) {
216
243
  if (tools.length === 0)
217
244
  toolGroupStart = index;
@@ -221,6 +248,14 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
221
248
  if (part.type === 'step-start' || part.type === 'reasoning')
222
249
  return;
223
250
  flushTools();
251
+ if (isAgentSecretRequestPart(part)) {
252
+ rendered.push(_jsx(AgentSecretRequestCard, { request: part, labels: secretRequestLabels, onSubmit: onSubmitSecretRequest, onCancel: onCancelSecretRequest }, `secret-${part.requestId}-${part.status}`));
253
+ return;
254
+ }
255
+ if (isAgentApprovalRequestPart(part)) {
256
+ rendered.push(_jsx(AgentApprovalRequestCard, { request: part, labels: approvalRequestLabels, onDecide: onDecideApprovalRequest }, `approval-${part.approvalId}-${part.status}`));
257
+ return;
258
+ }
224
259
  if (part.type === 'text' && typeof part.text === 'string' && part.text.trim()) {
225
260
  rendered.push(_jsx(ChatMarkdown, { children: part.text }, `text-${index}`));
226
261
  }
@@ -228,6 +263,171 @@ function AgentMessageParts({ parts, labels, toolLabels }) {
228
263
  flushTools();
229
264
  return _jsx("div", { className: "space-y-2.5", children: rendered });
230
265
  }
266
+ function isAgentApprovalRequestPart(part) {
267
+ return part.type === 'approval-request'
268
+ && typeof part.approvalId === 'string'
269
+ && part.approvalId.trim().length > 0
270
+ && typeof part.categoryLabel === 'string'
271
+ && part.categoryLabel.trim().length > 0
272
+ && typeof part.description === 'string'
273
+ && part.description.trim().length > 0
274
+ && (part.details === undefined || (Array.isArray(part.details) && part.details.every((detail) => (detail !== null
275
+ && typeof detail === 'object'
276
+ && typeof detail.label === 'string'
277
+ && typeof detail.value === 'string'))))
278
+ && (part.status === 'pending' || part.status === 'approved' || part.status === 'rejected' || part.status === 'expired')
279
+ && (part.decisionNote === undefined || typeof part.decisionNote === 'string');
280
+ }
281
+ /** Inline, transcript-safe approval for a governed action. */
282
+ export function AgentApprovalRequestCard({ request, labels: labelOverrides, onDecide }) {
283
+ const labels = { ...DEFAULT_APPROVAL_REQUEST_LABELS, ...labelOverrides };
284
+ const [deciding, setDeciding] = React.useState(null);
285
+ const [settledStatus, setSettledStatus] = React.useState(null);
286
+ const [error, setError] = React.useState(null);
287
+ const noteRef = React.useRef(null);
288
+ const status = settledStatus ?? request.status;
289
+ const decide = React.useCallback(async (decision) => {
290
+ if (!onDecide || deciding || status !== 'pending')
291
+ return;
292
+ const note = noteRef.current?.value.trim() || undefined;
293
+ setError(null);
294
+ setDeciding(decision);
295
+ try {
296
+ await onDecide(request.approvalId, decision, note);
297
+ setSettledStatus(decision);
298
+ if (noteRef.current)
299
+ noteRef.current.value = '';
300
+ }
301
+ catch {
302
+ setError(labels.failed);
303
+ }
304
+ finally {
305
+ setDeciding(null);
306
+ }
307
+ }, [deciding, labels.failed, onDecide, request.approvalId, status]);
308
+ const statusText = status === 'approved'
309
+ ? labels.approved
310
+ : status === 'rejected'
311
+ ? labels.rejected
312
+ : status === 'expired'
313
+ ? labels.expired
314
+ : null;
315
+ return (_jsx("section", { className: "rounded-xl border border-border bg-surface-raised p-3 shadow-sm", "aria-label": labels.title, children: _jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-warning-subtle text-warning", children: _jsx(ShieldCheck, { size: 17 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { className: "text-sm font-semibold text-fg", children: labels.title }), _jsx("span", { className: "rounded-full bg-surface-muted px-2 py-0.5 text-[11px] font-medium text-fg-muted", children: request.categoryLabel })] }), _jsx("p", { className: "mt-1 text-sm leading-5 text-fg-muted", children: request.description }), request.details?.length ? _jsx("dl", { className: "mt-2 grid gap-1 rounded-lg bg-surface-muted p-2 text-xs", children: request.details.map((detail) => _jsxs("div", { className: "grid grid-cols-[minmax(5rem,auto)_1fr] gap-2", children: [_jsx("dt", { className: "font-medium text-fg-muted", children: detail.label }), _jsx("dd", { className: "min-w-0 break-words text-fg", children: detail.value })] }, `${detail.label}:${detail.value}`)) }) : null, status === 'pending' ? (_jsxs("div", { className: "mt-3 space-y-2", children: [_jsx(Input, { ref: noteRef, placeholder: labels.note, "aria-label": labels.note, disabled: !onDecide || deciding !== null }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Button, { type: "button", size: "sm", onClick: () => void decide('approved'), disabled: !onDecide || deciding !== null, children: [deciding === 'approved' ? _jsx(Loader2, { className: "size-4 animate-spin" }) : null, deciding === 'approved' ? labels.deciding : labels.approve] }), _jsxs(Button, { type: "button", size: "sm", variant: "outline", onClick: () => void decide('rejected'), disabled: !onDecide || deciding !== null, children: [deciding === 'rejected' ? _jsx(Loader2, { className: "size-4 animate-spin" }) : null, deciding === 'rejected' ? labels.deciding : labels.reject] })] })] })) : _jsxs("p", { className: "mt-2 text-xs font-medium text-fg-muted", children: [statusText, request.decisionNote ? ` Note: ${request.decisionNote}` : ''] }), error ? _jsx("p", { role: "alert", className: "mt-2 text-xs text-danger", children: error }) : null] })] }) }));
316
+ }
317
+ function isAgentSecretRequestPart(part) {
318
+ return part.type === 'secret-request'
319
+ && typeof part.requestId === 'string'
320
+ && part.requestId.trim().length > 0
321
+ && typeof part.providerLabel === 'string'
322
+ && part.providerLabel.trim().length > 0
323
+ && typeof part.credentialLabel === 'string'
324
+ && part.credentialLabel.trim().length > 0
325
+ && typeof part.purpose === 'string'
326
+ && part.purpose.trim().length > 0
327
+ && (part.helpUrl === undefined || typeof part.helpUrl === 'string')
328
+ && (part.status === 'pending' || part.status === 'stored' || part.status === 'expired');
329
+ }
330
+ function safeSecretHelpUrl(value) {
331
+ if (!value)
332
+ return undefined;
333
+ if (value.startsWith('/') && !value.startsWith('//'))
334
+ return value;
335
+ try {
336
+ const url = new URL(value);
337
+ return url.protocol === 'https:' ? url.href : undefined;
338
+ }
339
+ catch {
340
+ return undefined;
341
+ }
342
+ }
343
+ /**
344
+ * Inline credential handoff for an assistant transcript. The password field is
345
+ * uncontrolled: its value is read directly from the DOM, cleared before the
346
+ * caller receives it, and never copied into React or transcript state.
347
+ */
348
+ export function AgentSecretRequestCard({ request, labels: labelOverrides, onSubmit, onCancel }) {
349
+ const labels = { ...DEFAULT_SECRET_REQUEST_LABELS, ...labelOverrides };
350
+ const inputId = React.useId();
351
+ const inputRef = React.useRef(null);
352
+ const [revealed, setRevealed] = React.useState(false);
353
+ const [submitting, setSubmitting] = React.useState(false);
354
+ const [settledStatus, setSettledStatus] = React.useState(null);
355
+ const [error, setError] = React.useState(null);
356
+ const requestIdentityRef = React.useRef(`${request.requestId}:${request.status}`);
357
+ const status = settledStatus ?? request.status;
358
+ const helpUrl = safeSecretHelpUrl(request.helpUrl);
359
+ const clearInput = React.useCallback(() => {
360
+ if (inputRef.current)
361
+ inputRef.current.value = '';
362
+ }, []);
363
+ React.useEffect(() => {
364
+ const identity = `${request.requestId}:${request.status}`;
365
+ if (requestIdentityRef.current !== identity) {
366
+ requestIdentityRef.current = identity;
367
+ clearInput();
368
+ setRevealed(false);
369
+ setSubmitting(false);
370
+ setSettledStatus(null);
371
+ setError(null);
372
+ }
373
+ }, [clearInput, request.requestId, request.status]);
374
+ React.useEffect(() => {
375
+ return clearInput;
376
+ }, [clearInput]);
377
+ const submit = React.useCallback(async (event) => {
378
+ event.preventDefault();
379
+ if (!onSubmit || submitting || status !== 'pending')
380
+ return;
381
+ const secret = inputRef.current?.value ?? '';
382
+ if (secret.length === 0) {
383
+ setError(labels.required);
384
+ inputRef.current?.focus();
385
+ return;
386
+ }
387
+ clearInput();
388
+ setRevealed(false);
389
+ setError(null);
390
+ setSubmitting(true);
391
+ try {
392
+ await onSubmit(request.requestId, secret);
393
+ setSettledStatus('stored');
394
+ }
395
+ catch {
396
+ setError(labels.failed);
397
+ inputRef.current?.focus();
398
+ }
399
+ finally {
400
+ clearInput();
401
+ setSubmitting(false);
402
+ }
403
+ }, [clearInput, labels.failed, labels.required, onSubmit, request.requestId, status, submitting]);
404
+ const cancel = React.useCallback(async () => {
405
+ if (!onCancel || submitting || status !== 'pending')
406
+ return;
407
+ clearInput();
408
+ setRevealed(false);
409
+ setError(null);
410
+ setSubmitting(true);
411
+ try {
412
+ await onCancel(request.requestId);
413
+ setSettledStatus('expired');
414
+ }
415
+ catch {
416
+ setError(labels.cancelFailed);
417
+ }
418
+ finally {
419
+ clearInput();
420
+ setSubmitting(false);
421
+ }
422
+ }, [clearInput, labels.cancelFailed, onCancel, request.requestId, status, submitting]);
423
+ 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') {
424
+ event.preventDefault();
425
+ void cancel();
426
+ } }, 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') {
427
+ event.preventDefault();
428
+ event.currentTarget.form?.requestSubmit();
429
+ } }, 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] }))] }));
430
+ }
231
431
  function isAgentToolPart(part) {
232
432
  return part.type === 'dynamic-tool' || part.type.startsWith('tool-');
233
433
  }
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 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 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 ? <AgentTypingIndicator label={labels.responding} /> : <AgentMessageParts parts={message.parts} labels={labels} toolLabels={toolLabels} />}</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 }: { 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 ShieldCheck,\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\nexport type AgentApprovalRequestStatus = 'pending' | 'approved' | 'rejected' | 'expired'\n\n/** Transcript-safe metadata for an inline governed-action decision. */\nexport type AgentApprovalRequestPart = {\n type: 'approval-request'\n approvalId: string\n categoryLabel: string\n description: string\n details?: Array<{ label: string; value: string }>\n status: AgentApprovalRequestStatus\n decisionNote?: string\n}\n\nexport type AgentApprovalRequestLabels = {\n title: string\n note: string\n approve: string\n reject: string\n deciding: string\n approved: string\n rejected: string\n expired: string\n failed: string\n}\n\nconst DEFAULT_APPROVAL_REQUEST_LABELS: AgentApprovalRequestLabels = {\n title: 'Approval needed',\n note: 'Add a note (optional)',\n approve: 'Approve',\n reject: 'Decline',\n deciding: 'Saving decision',\n approved: 'Approved. The agent will continue automatically.',\n rejected: 'Declined. The agent will receive your decision.',\n expired: 'This approval request has expired.',\n failed: 'The decision could not be saved. Please retry.',\n}\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 onDecideApprovalRequest?: (approvalId: string, decision: 'approved' | 'rejected', note?: string) => void | Promise<void>\n approvalRequestLabels?: Partial<AgentApprovalRequestLabels>\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 onDecideApprovalRequest,\n approvalRequestLabels,\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} onDecideApprovalRequest={onDecideApprovalRequest} approvalRequestLabels={approvalRequestLabels} />)}</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, onDecideApprovalRequest, approvalRequestLabels }: { message: AgentMessage; streaming: boolean; labels: AgentPanelLabels; toolLabels?: Record<string, string>; onSubmitSecretRequest?: AgentPanelProps['onSubmitSecretRequest']; onCancelSecretRequest?: AgentPanelProps['onCancelSecretRequest']; secretRequestLabels?: Partial<AgentSecretRequestLabels>; onDecideApprovalRequest?: AgentPanelProps['onDecideApprovalRequest']; approvalRequestLabels?: Partial<AgentApprovalRequestLabels> }) {\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} onDecideApprovalRequest={onDecideApprovalRequest} approvalRequestLabels={approvalRequestLabels} />}</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, onDecideApprovalRequest, approvalRequestLabels }: { parts: unknown[]; labels: AgentPanelLabels; toolLabels?: Record<string, string>; onSubmitSecretRequest?: AgentPanelProps['onSubmitSecretRequest']; onCancelSecretRequest?: AgentPanelProps['onCancelSecretRequest']; secretRequestLabels?: Partial<AgentSecretRequestLabels>; onDecideApprovalRequest?: AgentPanelProps['onDecideApprovalRequest']; approvalRequestLabels?: Partial<AgentApprovalRequestLabels> }) {\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 (isAgentApprovalRequestPart(part)) {\n rendered.push(<AgentApprovalRequestCard key={`approval-${part.approvalId}-${part.status}`} request={part} labels={approvalRequestLabels} onDecide={onDecideApprovalRequest} />)\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 isAgentApprovalRequestPart(part: { type: string; [key: string]: unknown }): part is AgentApprovalRequestPart & { [key: string]: unknown } {\n return part.type === 'approval-request'\n && typeof part.approvalId === 'string'\n && part.approvalId.trim().length > 0\n && typeof part.categoryLabel === 'string'\n && part.categoryLabel.trim().length > 0\n && typeof part.description === 'string'\n && part.description.trim().length > 0\n && (part.details === undefined || (Array.isArray(part.details) && part.details.every((detail) => (\n detail !== null\n && typeof detail === 'object'\n && typeof (detail as { label?: unknown }).label === 'string'\n && typeof (detail as { value?: unknown }).value === 'string'\n ))))\n && (part.status === 'pending' || part.status === 'approved' || part.status === 'rejected' || part.status === 'expired')\n && (part.decisionNote === undefined || typeof part.decisionNote === 'string')\n}\n\nexport type AgentApprovalRequestCardProps = {\n request: AgentApprovalRequestPart\n labels?: Partial<AgentApprovalRequestLabels>\n onDecide?: (approvalId: string, decision: 'approved' | 'rejected', note?: string) => void | Promise<void>\n}\n\n/** Inline, transcript-safe approval for a governed action. */\nexport function AgentApprovalRequestCard({ request, labels: labelOverrides, onDecide }: AgentApprovalRequestCardProps) {\n const labels = { ...DEFAULT_APPROVAL_REQUEST_LABELS, ...labelOverrides }\n const [deciding, setDeciding] = React.useState<'approved' | 'rejected' | null>(null)\n const [settledStatus, setSettledStatus] = React.useState<'approved' | 'rejected' | null>(null)\n const [error, setError] = React.useState<string | null>(null)\n const noteRef = React.useRef<HTMLInputElement>(null)\n const status = settledStatus ?? request.status\n\n const decide = React.useCallback(async (decision: 'approved' | 'rejected') => {\n if (!onDecide || deciding || status !== 'pending') return\n const note = noteRef.current?.value.trim() || undefined\n setError(null)\n setDeciding(decision)\n try {\n await onDecide(request.approvalId, decision, note)\n setSettledStatus(decision)\n if (noteRef.current) noteRef.current.value = ''\n } catch {\n setError(labels.failed)\n } finally {\n setDeciding(null)\n }\n }, [deciding, labels.failed, onDecide, request.approvalId, status])\n\n const statusText = status === 'approved'\n ? labels.approved\n : status === 'rejected'\n ? labels.rejected\n : status === 'expired'\n ? labels.expired\n : null\n\n return (\n <section className=\"rounded-xl border border-border bg-surface-raised p-3 shadow-sm\" aria-label={labels.title}>\n <div className=\"flex items-start gap-2.5\">\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-warning-subtle text-warning\"><ShieldCheck size={17} /></span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"text-sm font-semibold text-fg\">{labels.title}</p>\n <span className=\"rounded-full bg-surface-muted px-2 py-0.5 text-[11px] font-medium text-fg-muted\">{request.categoryLabel}</span>\n </div>\n <p className=\"mt-1 text-sm leading-5 text-fg-muted\">{request.description}</p>\n {request.details?.length ? <dl className=\"mt-2 grid gap-1 rounded-lg bg-surface-muted p-2 text-xs\">{request.details.map((detail) => <div key={`${detail.label}:${detail.value}`} className=\"grid grid-cols-[minmax(5rem,auto)_1fr] gap-2\"><dt className=\"font-medium text-fg-muted\">{detail.label}</dt><dd className=\"min-w-0 break-words text-fg\">{detail.value}</dd></div>)}</dl> : null}\n {status === 'pending' ? (\n <div className=\"mt-3 space-y-2\">\n <Input ref={noteRef} placeholder={labels.note} aria-label={labels.note} disabled={!onDecide || deciding !== null} />\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={() => void decide('approved')} disabled={!onDecide || deciding !== null}>{deciding === 'approved' ? <Loader2 className=\"size-4 animate-spin\" /> : null}{deciding === 'approved' ? labels.deciding : labels.approve}</Button>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => void decide('rejected')} disabled={!onDecide || deciding !== null}>{deciding === 'rejected' ? <Loader2 className=\"size-4 animate-spin\" /> : null}{deciding === 'rejected' ? labels.deciding : labels.reject}</Button>\n </div>\n </div>\n ) : <p className=\"mt-2 text-xs font-medium text-fg-muted\">{statusText}{request.decisionNote ? ` Note: ${request.decisionNote}` : ''}</p>}\n {error ? <p role=\"alert\" className=\"mt-2 text-xs text-danger\">{error}</p> : null}\n </div>\n </div>\n </section>\n )\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"]}