@cntyclub/agent-react 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/schema.d.ts +347 -0
- package/dist/api/schema.d.ts.map +1 -0
- package/dist/api-client.d.ts +30 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/components/agent-panel.d.ts +20 -0
- package/dist/components/agent-panel.d.ts.map +1 -0
- package/dist/components/agent-widget.d.ts +23 -0
- package/dist/components/agent-widget.d.ts.map +1 -0
- package/dist/components/message-item.d.ts +7 -0
- package/dist/components/message-item.d.ts.map +1 -0
- package/dist/components/tool-approval-card.d.ts +14 -0
- package/dist/components/tool-approval-card.d.ts.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/index.d.ts +10 -547
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -88
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/use-agent-chat.d.ts +26 -0
- package/dist/use-agent-chat.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ChatMessage, ChatMessageBubble, Markdown, DataTablePaged, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Button, Spinner, Tooltip, TooltipTrigger, TooltipContent, Chat, ChatMessages, ChatTypingIndicator, cn, ChatInput, useMediaQuery, TooltipProvider, Fab } from '@cntyclub/ui-react';
|
|
2
|
-
import { WrenchIcon,
|
|
1
|
+
import { ChatMessage, ChatMessageBubble, Markdown, ChatToolChip, DataTablePaged, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Button, Spinner, ChatHeader, ChatHeaderAvatar, ChatHeaderTitle, ChatHeaderActions, Tooltip, TooltipTrigger, TooltipContent, Chat, ChatMessages, ChatEmptyState, ChatEmptyStateIcon, ChatEmptyStateTitle, ChatEmptyStateDescription, ChatSuggestions, ChatSuggestion, ChatTypingIndicator, cn, ChatInput, useMediaQuery, TooltipProvider, Fab } from '@cntyclub/ui-react';
|
|
2
|
+
import { WrenchIcon, CheckIcon, ShieldAlertIcon, HistoryIcon, SquarePenIcon, Minimize2Icon, Maximize2Icon, XIcon, Trash2Icon, SparklesIcon } from 'lucide-react';
|
|
3
3
|
import * as React2 from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -89,19 +89,11 @@ function MessageItem({ message }) {
|
|
|
89
89
|
if (!message.content && requestedTools.length === 0) return null;
|
|
90
90
|
return /* @__PURE__ */ jsxs(ChatMessage, { from: "assistant", children: [
|
|
91
91
|
message.content ? /* @__PURE__ */ jsx(ChatMessageBubble, { from: "assistant", children: /* @__PURE__ */ jsx(Markdown, { children: message.content }) }) : null,
|
|
92
|
-
requestedTools.map((toolCall) => /* @__PURE__ */ jsxs(
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/* @__PURE__ */ jsx(WrenchIcon, { className: "size-3" }),
|
|
98
|
-
"Using ",
|
|
99
|
-
humanizeToolName(toolCall.name ?? "tool"),
|
|
100
|
-
"\u2026"
|
|
101
|
-
]
|
|
102
|
-
},
|
|
103
|
-
toolCall.id ?? toolCall.name
|
|
104
|
-
))
|
|
92
|
+
requestedTools.map((toolCall) => /* @__PURE__ */ jsxs(ChatToolChip, { icon: /* @__PURE__ */ jsx(WrenchIcon, {}), children: [
|
|
93
|
+
"Using ",
|
|
94
|
+
humanizeToolName(toolCall.name ?? "tool"),
|
|
95
|
+
"\u2026"
|
|
96
|
+
] }, toolCall.id ?? toolCall.name))
|
|
105
97
|
] });
|
|
106
98
|
}
|
|
107
99
|
const tableBlocks = (message.blocks ?? []).filter((block) => block.type === "table");
|
|
@@ -113,8 +105,7 @@ function MessageItem({ message }) {
|
|
|
113
105
|
rows: block.rows,
|
|
114
106
|
totalCount: typeof block.pagination?.count === "number" ? block.pagination.count : block.row_count
|
|
115
107
|
}
|
|
116
|
-
) }, `${message.id}-${index}`)) : /* @__PURE__ */ jsxs(
|
|
117
|
-
/* @__PURE__ */ jsx(CheckCircle2Icon, { className: "size-3" }),
|
|
108
|
+
) }, `${message.id}-${index}`)) : /* @__PURE__ */ jsxs(ChatToolChip, { icon: /* @__PURE__ */ jsx(CheckIcon, {}), children: [
|
|
118
109
|
humanizeToolName(message.tool_name ?? "tool"),
|
|
119
110
|
" finished"
|
|
120
111
|
] }) });
|
|
@@ -205,72 +196,74 @@ function AgentPanel({
|
|
|
205
196
|
),
|
|
206
197
|
"data-slot": "agent-panel",
|
|
207
198
|
children: [
|
|
208
|
-
/* @__PURE__ */ jsxs(
|
|
209
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
210
|
-
/* @__PURE__ */ jsx(
|
|
211
|
-
/* @__PURE__ */ jsxs(
|
|
199
|
+
/* @__PURE__ */ jsxs(ChatHeader, { children: [
|
|
200
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: [
|
|
201
|
+
/* @__PURE__ */ jsx(ChatHeaderAvatar, {}),
|
|
202
|
+
/* @__PURE__ */ jsxs(ChatHeaderTitle, { children: [
|
|
212
203
|
/* @__PURE__ */ jsx("div", { className: "truncate font-medium text-sm", children: agentName }),
|
|
213
204
|
config.tagline ? /* @__PURE__ */ jsx("div", { className: "truncate text-muted-foreground text-xs", children: config.tagline }) : null
|
|
214
205
|
] })
|
|
215
206
|
] }),
|
|
216
|
-
/* @__PURE__ */ jsxs(
|
|
217
|
-
/* @__PURE__ */
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
/* @__PURE__ */
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
207
|
+
/* @__PURE__ */ jsxs(ChatHeaderActions, { children: [
|
|
208
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
209
|
+
/* @__PURE__ */ jsx(
|
|
210
|
+
TooltipTrigger,
|
|
211
|
+
{
|
|
212
|
+
render: /* @__PURE__ */ jsx(
|
|
213
|
+
Button,
|
|
214
|
+
{
|
|
215
|
+
"aria-label": "Conversation history",
|
|
216
|
+
onClick: view === "history" ? () => setView("chat") : openHistory,
|
|
217
|
+
size: "icon-sm",
|
|
218
|
+
variant: "ghost",
|
|
219
|
+
children: /* @__PURE__ */ jsx(HistoryIcon, {})
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "History" })
|
|
225
|
+
] }),
|
|
226
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
227
|
+
/* @__PURE__ */ jsx(
|
|
228
|
+
TooltipTrigger,
|
|
229
|
+
{
|
|
230
|
+
render: /* @__PURE__ */ jsx(
|
|
231
|
+
Button,
|
|
232
|
+
{
|
|
233
|
+
"aria-label": "New chat",
|
|
234
|
+
onClick: () => {
|
|
235
|
+
chat.newChat();
|
|
236
|
+
setView("chat");
|
|
237
|
+
},
|
|
238
|
+
size: "icon-sm",
|
|
239
|
+
variant: "ghost",
|
|
240
|
+
children: /* @__PURE__ */ jsx(SquarePenIcon, {})
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
),
|
|
245
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: "New chat" })
|
|
246
|
+
] }),
|
|
247
|
+
canToggleAgentMode ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
248
|
+
/* @__PURE__ */ jsx(
|
|
249
|
+
TooltipTrigger,
|
|
250
|
+
{
|
|
251
|
+
render: /* @__PURE__ */ jsx(
|
|
252
|
+
Button,
|
|
253
|
+
{
|
|
254
|
+
"aria-label": agentMode ? "Exit Agent Mode" : "Enter Agent Mode",
|
|
255
|
+
onClick: onToggleAgentMode,
|
|
256
|
+
size: "icon-sm",
|
|
257
|
+
variant: "ghost",
|
|
258
|
+
children: agentMode ? /* @__PURE__ */ jsx(Minimize2Icon, {}) : /* @__PURE__ */ jsx(Maximize2Icon, {})
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
}
|
|
262
|
+
),
|
|
263
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: agentMode ? "Exit Agent Mode" : "Agent Mode" })
|
|
264
|
+
] }) : null,
|
|
265
|
+
/* @__PURE__ */ jsx(Button, { "aria-label": "Close", onClick: onClose, size: "icon-sm", variant: "ghost", children: /* @__PURE__ */ jsx(XIcon, {}) })
|
|
266
|
+
] })
|
|
274
267
|
] }),
|
|
275
268
|
view === "history" ? /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto p-2", children: chat.conversations.length === 0 ? /* @__PURE__ */ jsx("p", { className: "p-4 text-center text-muted-foreground text-sm", children: "No conversations yet." }) : chat.conversations.map((conversation) => /* @__PURE__ */ jsxs(
|
|
276
269
|
"div",
|
|
@@ -307,22 +300,21 @@ function AgentPanel({
|
|
|
307
300
|
},
|
|
308
301
|
conversation.id
|
|
309
302
|
)) }) : /* @__PURE__ */ jsxs(Chat, { children: [
|
|
310
|
-
/* @__PURE__ */ jsx(ChatMessages, { className: cn(agentMode && "mx-auto w-full max-w-3xl"), children: chat.messages.length === 0 && !chat.sending ? /* @__PURE__ */ jsxs(
|
|
311
|
-
/* @__PURE__ */ jsx(
|
|
303
|
+
/* @__PURE__ */ jsx(ChatMessages, { className: cn(agentMode && "mx-auto w-full max-w-3xl"), children: chat.messages.length === 0 && !chat.sending ? /* @__PURE__ */ jsxs(ChatEmptyState, { children: [
|
|
304
|
+
/* @__PURE__ */ jsx(ChatEmptyStateIcon, {}),
|
|
312
305
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
313
|
-
/* @__PURE__ */ jsxs(
|
|
306
|
+
/* @__PURE__ */ jsxs(ChatEmptyStateTitle, { children: [
|
|
314
307
|
"Hi! I'm ",
|
|
315
308
|
agentName,
|
|
316
309
|
"."
|
|
317
310
|
] }),
|
|
318
|
-
/* @__PURE__ */ jsx(
|
|
311
|
+
/* @__PURE__ */ jsx(ChatEmptyStateDescription, { className: "mt-1", children: "Ask me anything about your data \u2014 I can look things up and take actions (with your approval)." })
|
|
319
312
|
] }),
|
|
320
|
-
/* @__PURE__ */ jsx(
|
|
321
|
-
|
|
313
|
+
/* @__PURE__ */ jsx(ChatSuggestions, { children: suggestions.slice(0, 4).map((suggestion, index) => /* @__PURE__ */ jsx(
|
|
314
|
+
ChatSuggestion,
|
|
322
315
|
{
|
|
316
|
+
index,
|
|
323
317
|
onClick: () => handleSubmit(suggestion),
|
|
324
|
-
size: "sm",
|
|
325
|
-
variant: "outline",
|
|
326
318
|
children: suggestion
|
|
327
319
|
},
|
|
328
320
|
suggestion
|
|
@@ -347,7 +339,7 @@ function AgentPanel({
|
|
|
347
339
|
/* @__PURE__ */ jsx(
|
|
348
340
|
ChatInput,
|
|
349
341
|
{
|
|
350
|
-
className: cn(agentMode && "mx-auto w-full max-w-3xl
|
|
342
|
+
className: cn(agentMode && "mx-auto w-full max-w-3xl"),
|
|
351
343
|
disabled: busy || chat.pendingApprovals.length > 0,
|
|
352
344
|
onSubmit: handleSubmit,
|
|
353
345
|
onValueChange: setDraft,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api-client.ts","../src/components/message-item.tsx","../src/components/tool-approval-card.tsx","../src/components/agent-panel.tsx","../src/use-agent-chat.ts","../src/components/agent-widget.tsx","../src/config.ts"],"names":["humanizeToolName","jsxs","jsx","React","Button","React3","SparklesIcon","cn"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n AgentConfig,\n AgentPublicConfig,\n ChatResponse,\n ConversationSummary,\n} from \"./types\";\n\nexport class AgentApiError extends Error {\n status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = \"AgentApiError\";\n this.status = status;\n }\n}\n\n/**\n * Thin fetch client for the Country Club Agent Mode API.\n *\n * Every request carries the agent client_id (query param — also used by the\n * backend's per-agent CORS middleware, including on preflights) and the\n * logged-in user's bearer token.\n */\nexport class AgentApiClient {\n private config: AgentConfig;\n\n constructor(config: AgentConfig) {\n this.config = config;\n }\n\n private async request<T>(\n path: string,\n options: { method?: string; body?: unknown } = {},\n ): Promise<T> {\n const token = await this.config.getAccessToken();\n if (!token) {\n throw new AgentApiError(\"You need to be signed in to use the assistant.\", 401);\n }\n\n const base = this.config.apiBaseUrl.replace(/\\/$/, \"\");\n const separator = path.includes(\"?\") ? \"&\" : \"?\";\n const url = `${base}${path}${separator}client_id=${encodeURIComponent(this.config.clientId)}`;\n\n const response = await fetch(url, {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n \"X-Agent-Client-Id\": this.config.clientId,\n },\n method: options.method ?? \"GET\",\n });\n\n if (response.status === 204) return undefined as T;\n\n let payload: Record<string, unknown> = {};\n try {\n payload = (await response.json()) as Record<string, unknown>;\n } catch {\n // Non-JSON error body — fall through to the status check.\n }\n\n if (!response.ok) {\n const detail =\n (payload.detail as string) ||\n (payload.message as string) ||\n `Request failed (${response.status})`;\n throw new AgentApiError(detail, response.status);\n }\n return payload as T;\n }\n\n getConfig(): Promise<AgentPublicConfig> {\n return this.request<AgentPublicConfig>(\"/agent-mode/config/\");\n }\n\n sendMessage(message: string, conversationId?: string | null): Promise<ChatResponse> {\n return this.request<ChatResponse>(\"/agent-mode/chat/\", {\n body: {\n client_id: this.config.clientId,\n conversation_id: conversationId ?? null,\n message,\n },\n method: \"POST\",\n });\n }\n\n resolveApproval(callId: string, approve: boolean): Promise<ChatResponse> {\n return this.request<ChatResponse>(`/agent-mode/approvals/${callId}/resolve/`, {\n body: { approve, client_id: this.config.clientId },\n method: \"POST\",\n });\n }\n\n listConversations(): Promise<{ conversations: ConversationSummary[] }> {\n return this.request(\"/agent-mode/conversations/\");\n }\n\n getConversation(conversationId: string): Promise<{\n conversation: ConversationSummary;\n messages: ChatResponse[\"messages\"];\n pending_approvals: ChatResponse[\"pending_approvals\"];\n }> {\n return this.request(`/agent-mode/conversations/${conversationId}/`);\n }\n\n deleteConversation(conversationId: string): Promise<void> {\n return this.request(`/agent-mode/conversations/${conversationId}/`, {\n method: \"DELETE\",\n });\n }\n}\n","\"use client\";\n\nimport {\n ChatMessage,\n ChatMessageBubble,\n DataTablePaged,\n Markdown,\n} from \"@cntyclub/ui-react\";\nimport { CheckCircle2Icon, WrenchIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentMessage } from \"../types\";\n\nfunction humanizeToolName(toolName: string): string {\n return toolName.replace(/^[a-z]+_/, \"\").replaceAll(\"_\", \" \");\n}\n\n/** Renders one conversation message: user/assistant bubbles or tool results. */\nexport function MessageItem({ message }: { message: AgentMessage }) {\n if (message.role === \"user\") {\n return (\n <ChatMessage from=\"user\">\n <ChatMessageBubble from=\"user\">{message.content}</ChatMessageBubble>\n </ChatMessage>\n );\n }\n\n if (message.role === \"assistant\") {\n const requestedTools = message.tool_calls ?? [];\n if (!message.content && requestedTools.length === 0) return null;\n return (\n <ChatMessage from=\"assistant\">\n {message.content ? (\n <ChatMessageBubble from=\"assistant\">\n <Markdown>{message.content}</Markdown>\n </ChatMessageBubble>\n ) : null}\n {requestedTools.map((toolCall) => (\n <div\n className=\"flex items-center gap-1.5 px-1 text-muted-foreground text-xs\"\n key={toolCall.id ?? toolCall.name}\n >\n <WrenchIcon className=\"size-3\" />\n Using {humanizeToolName(toolCall.name ?? \"tool\")}…\n </div>\n ))}\n </ChatMessage>\n );\n }\n\n // Tool result: show table blocks when present, otherwise a completion line.\n const tableBlocks = (message.blocks ?? []).filter((block) => block.type === \"table\");\n return (\n <ChatMessage from=\"assistant\">\n {tableBlocks.length > 0 ? (\n tableBlocks.map((block, index) => (\n <div className=\"w-full max-w-full\" key={`${message.id}-${index}`}>\n <DataTablePaged\n columns={block.columns.map((key) => ({ key }))}\n pageSize={8}\n rows={block.rows}\n totalCount={\n typeof block.pagination?.count === \"number\"\n ? (block.pagination.count as number)\n : block.row_count\n }\n />\n </div>\n ))\n ) : (\n <div className=\"flex items-center gap-1.5 px-1 text-muted-foreground text-xs\">\n <CheckCircle2Icon className=\"size-3\" />\n {humanizeToolName(message.tool_name ?? \"tool\")} finished\n </div>\n )}\n </ChatMessage>\n );\n}\n","\"use client\";\n\nimport {\n Button,\n ChatToolCard,\n ChatToolCardActions,\n ChatToolCardHeader,\n Spinner,\n} from \"@cntyclub/ui-react\";\nimport { ShieldAlertIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { PendingApproval } from \"../types\";\n\nfunction humanizeToolName(toolName: string): string {\n return toolName.replace(/^[a-z]+_/, \"\").replaceAll(\"_\", \" \");\n}\n\nexport interface ToolApprovalCardProps {\n approval: PendingApproval;\n resolving: boolean;\n onResolve: (callId: string, approve: boolean) => void;\n}\n\n/**\n * Approval prompt for a write action the agent wants to perform. The stored\n * arguments are shown so the user knows exactly what will change; nothing runs\n * until they approve.\n */\nexport function ToolApprovalCard({ approval, onResolve, resolving }: ToolApprovalCardProps) {\n const argumentEntries = Object.entries(approval.arguments ?? {});\n\n return (\n <ChatToolCard className=\"border-warning/40\">\n <ChatToolCardHeader>\n <ShieldAlertIcon className=\"size-4 text-warning\" />\n Approval needed\n </ChatToolCardHeader>\n <p className=\"mt-1 text-muted-foreground\">\n The assistant wants to run{\" \"}\n <span className=\"font-medium text-foreground\">{humanizeToolName(approval.tool_name)}</span>{\" \"}\n — this will change your data.\n </p>\n {argumentEntries.length > 0 && (\n <dl className=\"mt-2 space-y-0.5 rounded-lg bg-muted p-2 font-mono text-xs\">\n {argumentEntries.slice(0, 8).map(([key, value]) => (\n <div className=\"flex gap-2\" key={key}>\n <dt className=\"shrink-0 text-muted-foreground\">{key}:</dt>\n <dd className=\"truncate\">{typeof value === \"object\" ? JSON.stringify(value) : String(value)}</dd>\n </div>\n ))}\n {argumentEntries.length > 8 && (\n <div className=\"text-muted-foreground\">…and {argumentEntries.length - 8} more</div>\n )}\n </dl>\n )}\n <ChatToolCardActions>\n <Button\n disabled={resolving}\n onClick={() => onResolve(approval.id, false)}\n size=\"sm\"\n variant=\"outline\"\n >\n Decline\n </Button>\n <Button disabled={resolving} onClick={() => onResolve(approval.id, true)} size=\"sm\">\n {resolving ? <Spinner /> : null}\n Approve\n </Button>\n </ChatToolCardActions>\n </ChatToolCard>\n );\n}\n","\"use client\";\n\nimport {\n Button,\n Chat,\n ChatInput,\n ChatMessages,\n ChatTypingIndicator,\n cn,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@cntyclub/ui-react\";\nimport {\n HistoryIcon,\n Maximize2Icon,\n Minimize2Icon,\n SparklesIcon,\n SquarePenIcon,\n Trash2Icon,\n XIcon,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentChatActions, AgentChatState } from \"../use-agent-chat\";\nimport type { AgentConfig } from \"../types\";\nimport { MessageItem } from \"./message-item\";\nimport { ToolApprovalCard } from \"./tool-approval-card\";\n\nexport interface AgentPanelProps {\n config: AgentConfig;\n chat: AgentChatState & AgentChatActions;\n /** Fullscreen \"Agent Mode\" is active. */\n agentMode: boolean;\n /** Hide the expand button (mobile is always fullscreen). */\n canToggleAgentMode: boolean;\n onToggleAgentMode: () => void;\n onClose: () => void;\n className?: string;\n}\n\n/**\n * The chat surface shared by the popup panel and fullscreen Agent Mode.\n * Header (title, history, new chat, expand/collapse, close) + messages + input.\n */\nexport function AgentPanel({\n agentMode,\n canToggleAgentMode,\n chat,\n className,\n config,\n onClose,\n onToggleAgentMode,\n}: AgentPanelProps) {\n const [draft, setDraft] = React.useState(\"\");\n const [view, setView] = React.useState<\"chat\" | \"history\">(\"chat\");\n\n const agentName = config.agentName ?? chat.agentInfo?.name ?? \"Assistant\";\n const suggestions = config.suggestions ?? [\n \"What can you help me with?\",\n \"Give me a quick summary of my data.\",\n ];\n\n const handleSubmit = React.useCallback(\n (text: string) => {\n setDraft(\"\");\n void chat.send(text);\n },\n [chat],\n );\n\n const openHistory = React.useCallback(() => {\n setView(\"history\");\n void chat.refreshConversations();\n }, [chat]);\n\n const busy = chat.sending || chat.resolvingApprovalId !== null;\n\n return (\n <div\n className={cn(\n \"flex min-h-0 flex-col overflow-hidden bg-background text-foreground\",\n className,\n )}\n data-slot=\"agent-panel\"\n >\n {/* Header */}\n <div className=\"flex shrink-0 items-center gap-1 border-border border-b px-3 py-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground\">\n <SparklesIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium text-sm\">{agentName}</div>\n {config.tagline ? (\n <div className=\"truncate text-muted-foreground text-xs\">{config.tagline}</div>\n ) : null}\n </div>\n </div>\n\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label=\"Conversation history\"\n onClick={view === \"history\" ? () => setView(\"chat\") : openHistory}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <HistoryIcon />\n </Button>\n }\n />\n <TooltipContent>History</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label=\"New chat\"\n onClick={() => {\n chat.newChat();\n setView(\"chat\");\n }}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <SquarePenIcon />\n </Button>\n }\n />\n <TooltipContent>New chat</TooltipContent>\n </Tooltip>\n\n {canToggleAgentMode ? (\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label={agentMode ? \"Exit Agent Mode\" : \"Enter Agent Mode\"}\n onClick={onToggleAgentMode}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n {agentMode ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n }\n />\n <TooltipContent>{agentMode ? \"Exit Agent Mode\" : \"Agent Mode\"}</TooltipContent>\n </Tooltip>\n ) : null}\n\n <Button aria-label=\"Close\" onClick={onClose} size=\"icon-sm\" variant=\"ghost\">\n <XIcon />\n </Button>\n </div>\n\n {view === \"history\" ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto p-2\">\n {chat.conversations.length === 0 ? (\n <p className=\"p-4 text-center text-muted-foreground text-sm\">\n No conversations yet.\n </p>\n ) : (\n chat.conversations.map((conversation) => (\n <div\n className=\"group flex items-center gap-1 rounded-lg hover:bg-accent\"\n key={conversation.id}\n >\n <button\n className=\"min-w-0 flex-1 cursor-pointer px-3 py-2 text-left\"\n onClick={() => {\n void chat.openConversation(conversation.id);\n setView(\"chat\");\n }}\n type=\"button\"\n >\n <span className=\"block truncate text-sm\">{conversation.title || \"Untitled\"}</span>\n <span className=\"block text-muted-foreground text-xs\">\n {new Date(conversation.updated_at).toLocaleString()}\n </span>\n </button>\n <Button\n aria-label=\"Delete conversation\"\n className=\"opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={() => void chat.deleteConversation(conversation.id)}\n size=\"icon-xs\"\n variant=\"destructive-ghost\"\n >\n <Trash2Icon />\n </Button>\n </div>\n ))\n )}\n </div>\n ) : (\n <Chat>\n <ChatMessages className={cn(agentMode && \"mx-auto w-full max-w-3xl\")}>\n {chat.messages.length === 0 && !chat.sending ? (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center\">\n <span className=\"flex size-12 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <SparklesIcon className=\"size-6\" />\n </span>\n <div>\n <p className=\"font-medium text-sm\">Hi! I'm {agentName}.</p>\n <p className=\"mt-1 text-muted-foreground text-sm\">\n Ask me anything about your data — I can look things up and take actions\n (with your approval).\n </p>\n </div>\n <div className=\"flex flex-col gap-2\">\n {suggestions.slice(0, 3).map((suggestion) => (\n <Button\n key={suggestion}\n onClick={() => handleSubmit(suggestion)}\n size=\"sm\"\n variant=\"outline\"\n >\n {suggestion}\n </Button>\n ))}\n </div>\n </div>\n ) : (\n <>\n {chat.messages.map((message) => (\n <MessageItem key={message.id} message={message} />\n ))}\n {chat.pendingApprovals.map((approval) => (\n <ToolApprovalCard\n approval={approval}\n key={approval.id}\n onResolve={(callId, approve) => void chat.resolveApproval(callId, approve)}\n resolving={chat.resolvingApprovalId === approval.id}\n />\n ))}\n {busy ? <ChatTypingIndicator /> : null}\n </>\n )}\n </ChatMessages>\n\n {chat.error ? (\n <div className=\"mx-3 mb-1 flex items-center justify-between gap-2 rounded-lg bg-destructive/10 px-3 py-2 text-destructive text-xs\">\n <span className=\"min-w-0 truncate\">{chat.error}</span>\n <button className=\"shrink-0 cursor-pointer font-medium\" onClick={chat.clearError} type=\"button\">\n Dismiss\n </button>\n </div>\n ) : null}\n\n <ChatInput\n className={cn(agentMode && \"mx-auto w-full max-w-3xl border-t-0\")}\n disabled={busy || chat.pendingApprovals.length > 0}\n onSubmit={handleSubmit}\n onValueChange={setDraft}\n placeholder={\n chat.pendingApprovals.length > 0\n ? \"Approve or decline the pending action first…\"\n : `Ask ${agentName}…`\n }\n value={draft}\n />\n </Chat>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { AgentApiClient, AgentApiError } from \"./api-client\";\nimport type {\n AgentConfig,\n AgentMessage,\n AgentPublicConfig,\n ConversationSummary,\n PendingApproval,\n} from \"./types\";\n\nexport interface AgentChatState {\n agentInfo: AgentPublicConfig | null;\n conversationId: string | null;\n conversations: ConversationSummary[];\n messages: AgentMessage[];\n pendingApprovals: PendingApproval[];\n sending: boolean;\n resolvingApprovalId: string | null;\n error: string | null;\n}\n\nexport interface AgentChatActions {\n send: (text: string) => Promise<void>;\n resolveApproval: (callId: string, approve: boolean) => Promise<void>;\n newChat: () => void;\n openConversation: (conversationId: string) => Promise<void>;\n refreshConversations: () => Promise<void>;\n deleteConversation: (conversationId: string) => Promise<void>;\n clearError: () => void;\n}\n\n/**\n * Headless chat state for an Agent Mode agent: message history, sending,\n * pending write-tool approvals, and conversation management. UI-agnostic.\n */\nexport function useAgentChat(config: AgentConfig): AgentChatState & AgentChatActions {\n const client = React.useMemo(() => new AgentApiClient(config), [config]);\n\n const [agentInfo, setAgentInfo] = React.useState<AgentPublicConfig | null>(null);\n const [conversationId, setConversationId] = React.useState<string | null>(null);\n const [conversations, setConversations] = React.useState<ConversationSummary[]>([]);\n const [messages, setMessages] = React.useState<AgentMessage[]>([]);\n const [pendingApprovals, setPendingApprovals] = React.useState<PendingApproval[]>([]);\n const [sending, setSending] = React.useState(false);\n const [resolvingApprovalId, setResolvingApprovalId] = React.useState<string | null>(null);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n let cancelled = false;\n client\n .getConfig()\n .then((info) => {\n if (!cancelled) setAgentInfo(info);\n })\n .catch(() => {\n // Non-fatal: the panel falls back to config-provided naming.\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n const handleFailure = React.useCallback((err: unknown) => {\n const message =\n err instanceof AgentApiError\n ? err.message\n : \"Something went wrong. Please try again.\";\n setError(message);\n }, []);\n\n const applyResponse = React.useCallback(\n (response: {\n status?: string;\n message?: string;\n conversation_id?: string;\n messages?: AgentMessage[];\n pending_approvals?: PendingApproval[];\n }) => {\n if (response.status === \"error\" && !response.messages?.length) {\n setError(response.message ?? \"The assistant could not answer.\");\n return;\n }\n if (response.conversation_id) setConversationId(response.conversation_id);\n if (response.messages?.length) {\n setMessages((current) => {\n const seen = new Set(current.map((message) => message.id));\n const fresh = response.messages?.filter((message) => !seen.has(message.id)) ?? [];\n return [...current, ...fresh];\n });\n }\n setPendingApprovals(response.pending_approvals ?? []);\n if (response.status === \"error\" && response.message) {\n setError(response.message);\n }\n },\n [],\n );\n\n const send = React.useCallback(\n async (text: string) => {\n if (sending) return;\n setSending(true);\n setError(null);\n try {\n const response = await client.sendMessage(text, conversationId);\n applyResponse(response);\n } catch (err) {\n handleFailure(err);\n } finally {\n setSending(false);\n }\n },\n [applyResponse, client, conversationId, handleFailure, sending],\n );\n\n const resolveApproval = React.useCallback(\n async (callId: string, approve: boolean) => {\n if (resolvingApprovalId) return;\n setResolvingApprovalId(callId);\n setError(null);\n try {\n const response = await client.resolveApproval(callId, approve);\n applyResponse(response);\n } catch (err) {\n handleFailure(err);\n } finally {\n setResolvingApprovalId(null);\n }\n },\n [applyResponse, client, handleFailure, resolvingApprovalId],\n );\n\n const newChat = React.useCallback(() => {\n setConversationId(null);\n setMessages([]);\n setPendingApprovals([]);\n setError(null);\n }, []);\n\n const refreshConversations = React.useCallback(async () => {\n try {\n const { conversations: list } = await client.listConversations();\n setConversations(list);\n } catch (err) {\n handleFailure(err);\n }\n }, [client, handleFailure]);\n\n const openConversation = React.useCallback(\n async (id: string) => {\n setError(null);\n try {\n const payload = await client.getConversation(id);\n setConversationId(id);\n setMessages(payload.messages ?? []);\n setPendingApprovals(payload.pending_approvals ?? []);\n } catch (err) {\n handleFailure(err);\n }\n },\n [client, handleFailure],\n );\n\n const deleteConversation = React.useCallback(\n async (id: string) => {\n try {\n await client.deleteConversation(id);\n setConversations((current) => current.filter((c) => c.id !== id));\n if (conversationId === id) newChat();\n } catch (err) {\n handleFailure(err);\n }\n },\n [client, conversationId, handleFailure, newChat],\n );\n\n const clearError = React.useCallback(() => setError(null), []);\n\n return {\n agentInfo,\n clearError,\n conversationId,\n conversations,\n deleteConversation,\n error,\n messages,\n newChat,\n openConversation,\n pendingApprovals,\n refreshConversations,\n resolveApproval,\n resolvingApprovalId,\n send,\n sending,\n };\n}\n","\"use client\";\n\nimport { cn, Fab, TooltipProvider, useMediaQuery } from \"@cntyclub/ui-react\";\nimport { SparklesIcon, XIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentConfig, AgentMessage } from \"../types\";\nimport { useAgentChat } from \"../use-agent-chat\";\nimport { AgentPanel } from \"./agent-panel\";\n\nexport interface AgentWidgetProps {\n config: AgentConfig;\n /** Controlled open state (optional). */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * The embeddable Agent Mode widget.\n *\n * - Closed: a floating round button (bottom-right by default).\n * - Open on desktop: a popup panel anchored to the button, with an\n * \"Agent Mode\" button that expands to a fullscreen chat. While in the popup,\n * the widget can navigate the host app to pages related to the tools the\n * agent uses (via `config.pages` + `config.navigate`).\n * - Open on mobile: fullscreen from the start.\n *\n * All colors come from the host app's UI-kit theme tokens, so light/dark mode\n * follows the dashboard automatically.\n */\nexport function AgentWidget({ config, onOpenChange, open: controlledOpen }: AgentWidgetProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const open = controlledOpen ?? uncontrolledOpen;\n const setOpen = React.useCallback(\n (next: boolean) => {\n setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [onOpenChange],\n );\n\n const [agentMode, setAgentMode] = React.useState(false);\n const isDesktop = useMediaQuery(\"(min-width: 640px)\", {\n defaultSSRValue: true,\n ssr: true,\n });\n const fullscreen = !isDesktop || agentMode;\n\n const chat = useAgentChat(config);\n\n // ----- page-follow navigation (popup mode only) -----\n const lastNavigatedMessageId = React.useRef<string | null>(null);\n const { messages } = chat;\n React.useEffect(() => {\n if (!open || fullscreen || !config.navigate || !config.pages?.length) return;\n const toolMessages = messages.filter((message) => message.role === \"tool\");\n const latest = toolMessages[toolMessages.length - 1];\n if (!latest || latest.id === lastNavigatedMessageId.current) return;\n lastNavigatedMessageId.current = latest.id;\n\n const mapping = config.pages.find((page) => page.tools.includes(latest.tool_name ?? \"\"));\n if (!mapping) return;\n\n const args = findToolArguments(messages, latest);\n const path = mapping.buildRoute ? mapping.buildRoute(args) : mapping.route;\n if (path) config.navigate(path);\n }, [config, fullscreen, messages, open]);\n\n const closePanel = React.useCallback(() => {\n setOpen(false);\n setAgentMode(false);\n }, [setOpen]);\n\n return (\n <TooltipProvider>\n {!open && !config.appearance?.hideLauncher ? (\n <Fab\n aria-label=\"Open assistant\"\n onClick={() => setOpen(true)}\n position={config.appearance?.position ?? \"bottom-right\"}\n >\n <SparklesIcon />\n </Fab>\n ) : null}\n\n {open ? (\n fullscreen ? (\n <div\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex flex-col bg-background\"\n role=\"dialog\"\n >\n <AgentPanel\n agentMode={agentMode}\n canToggleAgentMode={isDesktop}\n chat={chat}\n className=\"flex-1\"\n config={config}\n onClose={closePanel}\n onToggleAgentMode={() => setAgentMode((value) => !value)}\n />\n </div>\n ) : (\n <div\n className={cn(\n \"fixed z-50 flex flex-col overflow-hidden rounded-2xl border border-border shadow-2xl\",\n (config.appearance?.position ?? \"bottom-right\") === \"bottom-left\"\n ? \"bottom-4 left-4 sm:bottom-6 sm:left-6\"\n : \"right-4 bottom-4 sm:right-6 sm:bottom-6\",\n )}\n role=\"dialog\"\n style={{\n height: `min(${config.appearance?.panelHeight ?? 640}px, calc(100dvh - 3rem))`,\n width: `min(${config.appearance?.panelWidth ?? 400}px, calc(100vw - 2rem))`,\n }}\n >\n <AgentPanel\n agentMode={false}\n canToggleAgentMode\n chat={chat}\n className=\"flex-1\"\n config={config}\n onClose={closePanel}\n onToggleAgentMode={() => setAgentMode(true)}\n />\n </div>\n )\n ) : null}\n </TooltipProvider>\n );\n}\n\n/** Look up the arguments of the assistant tool_call a tool message answers. */\nfunction findToolArguments(\n messages: AgentMessage[],\n toolMessage: AgentMessage,\n): Record<string, unknown> {\n if (!toolMessage.tool_call_id) return {};\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message.role !== \"assistant\" || !message.tool_calls) continue;\n const match = message.tool_calls.find((call) => call.id === toolMessage.tool_call_id);\n if (match) return match.arguments ?? {};\n }\n return {};\n}\n","import type { AgentConfig } from \"./types\";\n\n/**\n * Identity helper that gives host apps full type inference/checking when\n * declaring their agent config file.\n */\nexport function defineAgentConfig(config: AgentConfig): AgentConfig {\n return config;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api-client.ts","../src/components/message-item.tsx","../src/components/tool-approval-card.tsx","../src/components/agent-panel.tsx","../src/use-agent-chat.ts","../src/components/agent-widget.tsx","../src/config.ts"],"names":["humanizeToolName","jsxs","jsx","React","Button","React3","cn"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n AgentConfig,\n AgentPublicConfig,\n ChatResponse,\n ConversationSummary,\n} from \"./types\";\n\nexport class AgentApiError extends Error {\n status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = \"AgentApiError\";\n this.status = status;\n }\n}\n\n/**\n * Thin fetch client for the Country Club Agent Mode API.\n *\n * Every request carries the agent client_id (query param — also used by the\n * backend's per-agent CORS middleware, including on preflights) and the\n * logged-in user's bearer token.\n */\nexport class AgentApiClient {\n private config: AgentConfig;\n\n constructor(config: AgentConfig) {\n this.config = config;\n }\n\n private async request<T>(\n path: string,\n options: { method?: string; body?: unknown } = {},\n ): Promise<T> {\n const token = await this.config.getAccessToken();\n if (!token) {\n throw new AgentApiError(\"You need to be signed in to use the assistant.\", 401);\n }\n\n const base = this.config.apiBaseUrl.replace(/\\/$/, \"\");\n const separator = path.includes(\"?\") ? \"&\" : \"?\";\n const url = `${base}${path}${separator}client_id=${encodeURIComponent(this.config.clientId)}`;\n\n const response = await fetch(url, {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n \"X-Agent-Client-Id\": this.config.clientId,\n },\n method: options.method ?? \"GET\",\n });\n\n if (response.status === 204) return undefined as T;\n\n let payload: Record<string, unknown> = {};\n try {\n payload = (await response.json()) as Record<string, unknown>;\n } catch {\n // Non-JSON error body — fall through to the status check.\n }\n\n if (!response.ok) {\n const detail =\n (payload.detail as string) ||\n (payload.message as string) ||\n `Request failed (${response.status})`;\n throw new AgentApiError(detail, response.status);\n }\n return payload as T;\n }\n\n getConfig(): Promise<AgentPublicConfig> {\n return this.request<AgentPublicConfig>(\"/agent-mode/config/\");\n }\n\n sendMessage(message: string, conversationId?: string | null): Promise<ChatResponse> {\n return this.request<ChatResponse>(\"/agent-mode/chat/\", {\n body: {\n client_id: this.config.clientId,\n conversation_id: conversationId ?? null,\n message,\n },\n method: \"POST\",\n });\n }\n\n resolveApproval(callId: string, approve: boolean): Promise<ChatResponse> {\n return this.request<ChatResponse>(`/agent-mode/approvals/${callId}/resolve/`, {\n body: { approve, client_id: this.config.clientId },\n method: \"POST\",\n });\n }\n\n listConversations(): Promise<{ conversations: ConversationSummary[] }> {\n return this.request(\"/agent-mode/conversations/\");\n }\n\n getConversation(conversationId: string): Promise<{\n conversation: ConversationSummary;\n messages: ChatResponse[\"messages\"];\n pending_approvals: ChatResponse[\"pending_approvals\"];\n }> {\n return this.request(`/agent-mode/conversations/${conversationId}/`);\n }\n\n deleteConversation(conversationId: string): Promise<void> {\n return this.request(`/agent-mode/conversations/${conversationId}/`, {\n method: \"DELETE\",\n });\n }\n}\n","\"use client\";\n\nimport {\n ChatMessage,\n ChatMessageBubble,\n ChatToolChip,\n DataTablePaged,\n Markdown,\n} from \"@cntyclub/ui-react\";\nimport { CheckIcon, WrenchIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentMessage } from \"../types\";\n\nfunction humanizeToolName(toolName: string): string {\n return toolName.replace(/^[a-z]+_/, \"\").replaceAll(\"_\", \" \");\n}\n\n/** Renders one conversation message: user/assistant bubbles or tool results. */\nexport function MessageItem({ message }: { message: AgentMessage }) {\n if (message.role === \"user\") {\n return (\n <ChatMessage from=\"user\">\n <ChatMessageBubble from=\"user\">{message.content}</ChatMessageBubble>\n </ChatMessage>\n );\n }\n\n if (message.role === \"assistant\") {\n const requestedTools = message.tool_calls ?? [];\n if (!message.content && requestedTools.length === 0) return null;\n return (\n <ChatMessage from=\"assistant\">\n {message.content ? (\n <ChatMessageBubble from=\"assistant\">\n <Markdown>{message.content}</Markdown>\n </ChatMessageBubble>\n ) : null}\n {requestedTools.map((toolCall) => (\n <ChatToolChip icon={<WrenchIcon />} key={toolCall.id ?? toolCall.name}>\n Using {humanizeToolName(toolCall.name ?? \"tool\")}…\n </ChatToolChip>\n ))}\n </ChatMessage>\n );\n }\n\n // Tool result: show table blocks when present, otherwise a completion line.\n const tableBlocks = (message.blocks ?? []).filter((block) => block.type === \"table\");\n return (\n <ChatMessage from=\"assistant\">\n {tableBlocks.length > 0 ? (\n tableBlocks.map((block, index) => (\n <div className=\"w-full max-w-full\" key={`${message.id}-${index}`}>\n <DataTablePaged\n columns={block.columns.map((key) => ({ key }))}\n pageSize={8}\n rows={block.rows}\n totalCount={\n typeof block.pagination?.count === \"number\"\n ? (block.pagination.count as number)\n : block.row_count\n }\n />\n </div>\n ))\n ) : (\n <ChatToolChip icon={<CheckIcon />}>\n {humanizeToolName(message.tool_name ?? \"tool\")} finished\n </ChatToolChip>\n )}\n </ChatMessage>\n );\n}\n","\"use client\";\n\nimport {\n Button,\n ChatToolCard,\n ChatToolCardActions,\n ChatToolCardHeader,\n Spinner,\n} from \"@cntyclub/ui-react\";\nimport { ShieldAlertIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { PendingApproval } from \"../types\";\n\nfunction humanizeToolName(toolName: string): string {\n return toolName.replace(/^[a-z]+_/, \"\").replaceAll(\"_\", \" \");\n}\n\nexport interface ToolApprovalCardProps {\n approval: PendingApproval;\n resolving: boolean;\n onResolve: (callId: string, approve: boolean) => void;\n}\n\n/**\n * Approval prompt for a write action the agent wants to perform. The stored\n * arguments are shown so the user knows exactly what will change; nothing runs\n * until they approve.\n */\nexport function ToolApprovalCard({ approval, onResolve, resolving }: ToolApprovalCardProps) {\n const argumentEntries = Object.entries(approval.arguments ?? {});\n\n return (\n <ChatToolCard className=\"border-warning/40\">\n <ChatToolCardHeader>\n <ShieldAlertIcon className=\"size-4 text-warning\" />\n Approval needed\n </ChatToolCardHeader>\n <p className=\"mt-1 text-muted-foreground\">\n The assistant wants to run{\" \"}\n <span className=\"font-medium text-foreground\">{humanizeToolName(approval.tool_name)}</span>{\" \"}\n — this will change your data.\n </p>\n {argumentEntries.length > 0 && (\n <dl className=\"mt-2 space-y-0.5 rounded-lg bg-muted p-2 font-mono text-xs\">\n {argumentEntries.slice(0, 8).map(([key, value]) => (\n <div className=\"flex gap-2\" key={key}>\n <dt className=\"shrink-0 text-muted-foreground\">{key}:</dt>\n <dd className=\"truncate\">{typeof value === \"object\" ? JSON.stringify(value) : String(value)}</dd>\n </div>\n ))}\n {argumentEntries.length > 8 && (\n <div className=\"text-muted-foreground\">…and {argumentEntries.length - 8} more</div>\n )}\n </dl>\n )}\n <ChatToolCardActions>\n <Button\n disabled={resolving}\n onClick={() => onResolve(approval.id, false)}\n size=\"sm\"\n variant=\"outline\"\n >\n Decline\n </Button>\n <Button disabled={resolving} onClick={() => onResolve(approval.id, true)} size=\"sm\">\n {resolving ? <Spinner /> : null}\n Approve\n </Button>\n </ChatToolCardActions>\n </ChatToolCard>\n );\n}\n","\"use client\";\n\nimport {\n Button,\n Chat,\n ChatEmptyState,\n ChatEmptyStateDescription,\n ChatEmptyStateIcon,\n ChatEmptyStateTitle,\n ChatHeader,\n ChatHeaderActions,\n ChatHeaderAvatar,\n ChatHeaderTitle,\n ChatInput,\n ChatMessages,\n ChatSuggestion,\n ChatSuggestions,\n ChatTypingIndicator,\n cn,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@cntyclub/ui-react\";\nimport {\n HistoryIcon,\n Maximize2Icon,\n Minimize2Icon,\n SquarePenIcon,\n Trash2Icon,\n XIcon,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentChatActions, AgentChatState } from \"../use-agent-chat\";\nimport type { AgentConfig } from \"../types\";\nimport { MessageItem } from \"./message-item\";\nimport { ToolApprovalCard } from \"./tool-approval-card\";\n\nexport interface AgentPanelProps {\n config: AgentConfig;\n chat: AgentChatState & AgentChatActions;\n /** Fullscreen \"Agent Mode\" is active. */\n agentMode: boolean;\n /** Hide the expand button (mobile is always fullscreen). */\n canToggleAgentMode: boolean;\n onToggleAgentMode: () => void;\n onClose: () => void;\n className?: string;\n}\n\n/**\n * The chat surface shared by the popup panel and fullscreen Agent Mode.\n * Header (title, history, new chat, expand/collapse, close) + messages + input.\n */\nexport function AgentPanel({\n agentMode,\n canToggleAgentMode,\n chat,\n className,\n config,\n onClose,\n onToggleAgentMode,\n}: AgentPanelProps) {\n const [draft, setDraft] = React.useState(\"\");\n const [view, setView] = React.useState<\"chat\" | \"history\">(\"chat\");\n\n const agentName = config.agentName ?? chat.agentInfo?.name ?? \"Assistant\";\n const suggestions = config.suggestions ?? [\n \"What can you help me with?\",\n \"Give me a quick summary of my data.\",\n ];\n\n const handleSubmit = React.useCallback(\n (text: string) => {\n setDraft(\"\");\n void chat.send(text);\n },\n [chat],\n );\n\n const openHistory = React.useCallback(() => {\n setView(\"history\");\n void chat.refreshConversations();\n }, [chat]);\n\n const busy = chat.sending || chat.resolvingApprovalId !== null;\n\n return (\n <div\n className={cn(\n \"flex min-h-0 flex-col overflow-hidden bg-background text-foreground\",\n className,\n )}\n data-slot=\"agent-panel\"\n >\n {/* Header */}\n <ChatHeader>\n <div className=\"flex min-w-0 flex-1 items-center gap-2.5\">\n <ChatHeaderAvatar />\n <ChatHeaderTitle>\n <div className=\"truncate font-medium text-sm\">{agentName}</div>\n {config.tagline ? (\n <div className=\"truncate text-muted-foreground text-xs\">{config.tagline}</div>\n ) : null}\n </ChatHeaderTitle>\n </div>\n\n <ChatHeaderActions>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label=\"Conversation history\"\n onClick={view === \"history\" ? () => setView(\"chat\") : openHistory}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <HistoryIcon />\n </Button>\n }\n />\n <TooltipContent>History</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label=\"New chat\"\n onClick={() => {\n chat.newChat();\n setView(\"chat\");\n }}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <SquarePenIcon />\n </Button>\n }\n />\n <TooltipContent>New chat</TooltipContent>\n </Tooltip>\n\n {canToggleAgentMode ? (\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n aria-label={agentMode ? \"Exit Agent Mode\" : \"Enter Agent Mode\"}\n onClick={onToggleAgentMode}\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n {agentMode ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n }\n />\n <TooltipContent>{agentMode ? \"Exit Agent Mode\" : \"Agent Mode\"}</TooltipContent>\n </Tooltip>\n ) : null}\n\n <Button aria-label=\"Close\" onClick={onClose} size=\"icon-sm\" variant=\"ghost\">\n <XIcon />\n </Button>\n </ChatHeaderActions>\n </ChatHeader>\n\n {view === \"history\" ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto p-2\">\n {chat.conversations.length === 0 ? (\n <p className=\"p-4 text-center text-muted-foreground text-sm\">\n No conversations yet.\n </p>\n ) : (\n chat.conversations.map((conversation) => (\n <div\n className=\"group flex items-center gap-1 rounded-lg hover:bg-accent\"\n key={conversation.id}\n >\n <button\n className=\"min-w-0 flex-1 cursor-pointer px-3 py-2 text-left\"\n onClick={() => {\n void chat.openConversation(conversation.id);\n setView(\"chat\");\n }}\n type=\"button\"\n >\n <span className=\"block truncate text-sm\">{conversation.title || \"Untitled\"}</span>\n <span className=\"block text-muted-foreground text-xs\">\n {new Date(conversation.updated_at).toLocaleString()}\n </span>\n </button>\n <Button\n aria-label=\"Delete conversation\"\n className=\"opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={() => void chat.deleteConversation(conversation.id)}\n size=\"icon-xs\"\n variant=\"destructive-ghost\"\n >\n <Trash2Icon />\n </Button>\n </div>\n ))\n )}\n </div>\n ) : (\n <Chat>\n <ChatMessages className={cn(agentMode && \"mx-auto w-full max-w-3xl\")}>\n {chat.messages.length === 0 && !chat.sending ? (\n <ChatEmptyState>\n <ChatEmptyStateIcon />\n <div>\n <ChatEmptyStateTitle>Hi! I'm {agentName}.</ChatEmptyStateTitle>\n <ChatEmptyStateDescription className=\"mt-1\">\n Ask me anything about your data — I can look things up and take actions\n (with your approval).\n </ChatEmptyStateDescription>\n </div>\n <ChatSuggestions>\n {suggestions.slice(0, 4).map((suggestion, index) => (\n <ChatSuggestion\n index={index}\n key={suggestion}\n onClick={() => handleSubmit(suggestion)}\n >\n {suggestion}\n </ChatSuggestion>\n ))}\n </ChatSuggestions>\n </ChatEmptyState>\n ) : (\n <>\n {chat.messages.map((message) => (\n <MessageItem key={message.id} message={message} />\n ))}\n {chat.pendingApprovals.map((approval) => (\n <ToolApprovalCard\n approval={approval}\n key={approval.id}\n onResolve={(callId, approve) => void chat.resolveApproval(callId, approve)}\n resolving={chat.resolvingApprovalId === approval.id}\n />\n ))}\n {busy ? <ChatTypingIndicator /> : null}\n </>\n )}\n </ChatMessages>\n\n {chat.error ? (\n <div className=\"mx-3 mb-1 flex items-center justify-between gap-2 rounded-lg bg-destructive/10 px-3 py-2 text-destructive text-xs\">\n <span className=\"min-w-0 truncate\">{chat.error}</span>\n <button className=\"shrink-0 cursor-pointer font-medium\" onClick={chat.clearError} type=\"button\">\n Dismiss\n </button>\n </div>\n ) : null}\n\n <ChatInput\n className={cn(agentMode && \"mx-auto w-full max-w-3xl\")}\n disabled={busy || chat.pendingApprovals.length > 0}\n onSubmit={handleSubmit}\n onValueChange={setDraft}\n placeholder={\n chat.pendingApprovals.length > 0\n ? \"Approve or decline the pending action first…\"\n : `Ask ${agentName}…`\n }\n value={draft}\n />\n </Chat>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { AgentApiClient, AgentApiError } from \"./api-client\";\nimport type {\n AgentConfig,\n AgentMessage,\n AgentPublicConfig,\n ConversationSummary,\n PendingApproval,\n} from \"./types\";\n\nexport interface AgentChatState {\n agentInfo: AgentPublicConfig | null;\n conversationId: string | null;\n conversations: ConversationSummary[];\n messages: AgentMessage[];\n pendingApprovals: PendingApproval[];\n sending: boolean;\n resolvingApprovalId: string | null;\n error: string | null;\n}\n\nexport interface AgentChatActions {\n send: (text: string) => Promise<void>;\n resolveApproval: (callId: string, approve: boolean) => Promise<void>;\n newChat: () => void;\n openConversation: (conversationId: string) => Promise<void>;\n refreshConversations: () => Promise<void>;\n deleteConversation: (conversationId: string) => Promise<void>;\n clearError: () => void;\n}\n\n/**\n * Headless chat state for an Agent Mode agent: message history, sending,\n * pending write-tool approvals, and conversation management. UI-agnostic.\n */\nexport function useAgentChat(config: AgentConfig): AgentChatState & AgentChatActions {\n const client = React.useMemo(() => new AgentApiClient(config), [config]);\n\n const [agentInfo, setAgentInfo] = React.useState<AgentPublicConfig | null>(null);\n const [conversationId, setConversationId] = React.useState<string | null>(null);\n const [conversations, setConversations] = React.useState<ConversationSummary[]>([]);\n const [messages, setMessages] = React.useState<AgentMessage[]>([]);\n const [pendingApprovals, setPendingApprovals] = React.useState<PendingApproval[]>([]);\n const [sending, setSending] = React.useState(false);\n const [resolvingApprovalId, setResolvingApprovalId] = React.useState<string | null>(null);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n let cancelled = false;\n client\n .getConfig()\n .then((info) => {\n if (!cancelled) setAgentInfo(info);\n })\n .catch(() => {\n // Non-fatal: the panel falls back to config-provided naming.\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n const handleFailure = React.useCallback((err: unknown) => {\n const message =\n err instanceof AgentApiError\n ? err.message\n : \"Something went wrong. Please try again.\";\n setError(message);\n }, []);\n\n const applyResponse = React.useCallback(\n (response: {\n status?: string;\n message?: string;\n conversation_id?: string;\n messages?: AgentMessage[];\n pending_approvals?: PendingApproval[];\n }) => {\n if (response.status === \"error\" && !response.messages?.length) {\n setError(response.message ?? \"The assistant could not answer.\");\n return;\n }\n if (response.conversation_id) setConversationId(response.conversation_id);\n if (response.messages?.length) {\n setMessages((current) => {\n const seen = new Set(current.map((message) => message.id));\n const fresh = response.messages?.filter((message) => !seen.has(message.id)) ?? [];\n return [...current, ...fresh];\n });\n }\n setPendingApprovals(response.pending_approvals ?? []);\n if (response.status === \"error\" && response.message) {\n setError(response.message);\n }\n },\n [],\n );\n\n const send = React.useCallback(\n async (text: string) => {\n if (sending) return;\n setSending(true);\n setError(null);\n try {\n const response = await client.sendMessage(text, conversationId);\n applyResponse(response);\n } catch (err) {\n handleFailure(err);\n } finally {\n setSending(false);\n }\n },\n [applyResponse, client, conversationId, handleFailure, sending],\n );\n\n const resolveApproval = React.useCallback(\n async (callId: string, approve: boolean) => {\n if (resolvingApprovalId) return;\n setResolvingApprovalId(callId);\n setError(null);\n try {\n const response = await client.resolveApproval(callId, approve);\n applyResponse(response);\n } catch (err) {\n handleFailure(err);\n } finally {\n setResolvingApprovalId(null);\n }\n },\n [applyResponse, client, handleFailure, resolvingApprovalId],\n );\n\n const newChat = React.useCallback(() => {\n setConversationId(null);\n setMessages([]);\n setPendingApprovals([]);\n setError(null);\n }, []);\n\n const refreshConversations = React.useCallback(async () => {\n try {\n const { conversations: list } = await client.listConversations();\n setConversations(list);\n } catch (err) {\n handleFailure(err);\n }\n }, [client, handleFailure]);\n\n const openConversation = React.useCallback(\n async (id: string) => {\n setError(null);\n try {\n const payload = await client.getConversation(id);\n setConversationId(id);\n setMessages(payload.messages ?? []);\n setPendingApprovals(payload.pending_approvals ?? []);\n } catch (err) {\n handleFailure(err);\n }\n },\n [client, handleFailure],\n );\n\n const deleteConversation = React.useCallback(\n async (id: string) => {\n try {\n await client.deleteConversation(id);\n setConversations((current) => current.filter((c) => c.id !== id));\n if (conversationId === id) newChat();\n } catch (err) {\n handleFailure(err);\n }\n },\n [client, conversationId, handleFailure, newChat],\n );\n\n const clearError = React.useCallback(() => setError(null), []);\n\n return {\n agentInfo,\n clearError,\n conversationId,\n conversations,\n deleteConversation,\n error,\n messages,\n newChat,\n openConversation,\n pendingApprovals,\n refreshConversations,\n resolveApproval,\n resolvingApprovalId,\n send,\n sending,\n };\n}\n","\"use client\";\n\nimport { cn, Fab, TooltipProvider, useMediaQuery } from \"@cntyclub/ui-react\";\nimport { SparklesIcon, XIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport type { AgentConfig, AgentMessage } from \"../types\";\nimport { useAgentChat } from \"../use-agent-chat\";\nimport { AgentPanel } from \"./agent-panel\";\n\nexport interface AgentWidgetProps {\n config: AgentConfig;\n /** Controlled open state (optional). */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * The embeddable Agent Mode widget.\n *\n * - Closed: a floating round button (bottom-right by default).\n * - Open on desktop: a popup panel anchored to the button, with an\n * \"Agent Mode\" button that expands to a fullscreen chat. While in the popup,\n * the widget can navigate the host app to pages related to the tools the\n * agent uses (via `config.pages` + `config.navigate`).\n * - Open on mobile: fullscreen from the start.\n *\n * All colors come from the host app's UI-kit theme tokens, so light/dark mode\n * follows the dashboard automatically.\n */\nexport function AgentWidget({ config, onOpenChange, open: controlledOpen }: AgentWidgetProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const open = controlledOpen ?? uncontrolledOpen;\n const setOpen = React.useCallback(\n (next: boolean) => {\n setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [onOpenChange],\n );\n\n const [agentMode, setAgentMode] = React.useState(false);\n const isDesktop = useMediaQuery(\"(min-width: 640px)\", {\n defaultSSRValue: true,\n ssr: true,\n });\n const fullscreen = !isDesktop || agentMode;\n\n const chat = useAgentChat(config);\n\n // ----- page-follow navigation (popup mode only) -----\n const lastNavigatedMessageId = React.useRef<string | null>(null);\n const { messages } = chat;\n React.useEffect(() => {\n if (!open || fullscreen || !config.navigate || !config.pages?.length) return;\n const toolMessages = messages.filter((message) => message.role === \"tool\");\n const latest = toolMessages[toolMessages.length - 1];\n if (!latest || latest.id === lastNavigatedMessageId.current) return;\n lastNavigatedMessageId.current = latest.id;\n\n const mapping = config.pages.find((page) => page.tools.includes(latest.tool_name ?? \"\"));\n if (!mapping) return;\n\n const args = findToolArguments(messages, latest);\n const path = mapping.buildRoute ? mapping.buildRoute(args) : mapping.route;\n if (path) config.navigate(path);\n }, [config, fullscreen, messages, open]);\n\n const closePanel = React.useCallback(() => {\n setOpen(false);\n setAgentMode(false);\n }, [setOpen]);\n\n return (\n <TooltipProvider>\n {!open && !config.appearance?.hideLauncher ? (\n <Fab\n aria-label=\"Open assistant\"\n onClick={() => setOpen(true)}\n position={config.appearance?.position ?? \"bottom-right\"}\n >\n <SparklesIcon />\n </Fab>\n ) : null}\n\n {open ? (\n fullscreen ? (\n <div\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex flex-col bg-background\"\n role=\"dialog\"\n >\n <AgentPanel\n agentMode={agentMode}\n canToggleAgentMode={isDesktop}\n chat={chat}\n className=\"flex-1\"\n config={config}\n onClose={closePanel}\n onToggleAgentMode={() => setAgentMode((value) => !value)}\n />\n </div>\n ) : (\n <div\n className={cn(\n \"fixed z-50 flex flex-col overflow-hidden rounded-2xl border border-border shadow-2xl\",\n (config.appearance?.position ?? \"bottom-right\") === \"bottom-left\"\n ? \"bottom-4 left-4 sm:bottom-6 sm:left-6\"\n : \"right-4 bottom-4 sm:right-6 sm:bottom-6\",\n )}\n role=\"dialog\"\n style={{\n height: `min(${config.appearance?.panelHeight ?? 640}px, calc(100dvh - 3rem))`,\n width: `min(${config.appearance?.panelWidth ?? 400}px, calc(100vw - 2rem))`,\n }}\n >\n <AgentPanel\n agentMode={false}\n canToggleAgentMode\n chat={chat}\n className=\"flex-1\"\n config={config}\n onClose={closePanel}\n onToggleAgentMode={() => setAgentMode(true)}\n />\n </div>\n )\n ) : null}\n </TooltipProvider>\n );\n}\n\n/** Look up the arguments of the assistant tool_call a tool message answers. */\nfunction findToolArguments(\n messages: AgentMessage[],\n toolMessage: AgentMessage,\n): Record<string, unknown> {\n if (!toolMessage.tool_call_id) return {};\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message.role !== \"assistant\" || !message.tool_calls) continue;\n const match = message.tool_calls.find((call) => call.id === toolMessage.tool_call_id);\n if (match) return match.arguments ?? {};\n }\n return {};\n}\n","import type { AgentConfig } from \"./types\";\n\n/**\n * Identity helper that gives host apps full type inference/checking when\n * declaring their agent config file.\n */\nexport function defineAgentConfig(config: AgentConfig): AgentConfig {\n return config;\n}\n"]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { components } from "./api/schema";
|
|
2
|
+
/**
|
|
3
|
+
* All wire types derive from the generated OpenAPI schema (src/api/schema.ts,
|
|
4
|
+
* generated from api-spec/agent-mode-api.yaml — the backend's
|
|
5
|
+
* /agent-mode/schema/ document). Regenerate with `pnpm gen:api` after updating
|
|
6
|
+
* the spec; see the README for the full update workflow.
|
|
7
|
+
*/
|
|
8
|
+
export type AgentModeSchemas = components["schemas"];
|
|
9
|
+
/** A structured UI block attached to a message (currently: result tables). */
|
|
10
|
+
export interface TableBlock {
|
|
11
|
+
type: "table";
|
|
12
|
+
tool_name: string;
|
|
13
|
+
columns: string[];
|
|
14
|
+
rows: Record<string, unknown>[];
|
|
15
|
+
row_count: number;
|
|
16
|
+
truncated?: boolean;
|
|
17
|
+
pagination?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export type MessageBlock = TableBlock;
|
|
20
|
+
export interface ToolCallInfo {
|
|
21
|
+
id?: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
arguments?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* One chat message. Wire shape from the schema; `blocks`/`tool_calls` are
|
|
27
|
+
* JSON fields on the wire, narrowed here to their documented structures.
|
|
28
|
+
*/
|
|
29
|
+
export interface AgentMessage extends Omit<AgentModeSchemas["AgentChatMessage"], "blocks" | "tool_calls"> {
|
|
30
|
+
blocks?: MessageBlock[];
|
|
31
|
+
tool_calls?: ToolCallInfo[];
|
|
32
|
+
}
|
|
33
|
+
export type PendingApproval = AgentModeSchemas["PendingApproval"];
|
|
34
|
+
export type ConversationSummary = Required<AgentModeSchemas["ConversationList"]>;
|
|
35
|
+
export type AgentPublicConfig = AgentModeSchemas["AgentPublicConfig"];
|
|
36
|
+
/** Response of the chat and approval-resolve endpoints. */
|
|
37
|
+
export interface ChatResponse extends Omit<AgentModeSchemas["AgentChatResponse"], "messages"> {
|
|
38
|
+
messages?: AgentMessage[];
|
|
39
|
+
}
|
|
40
|
+
export type ChatRequest = AgentModeSchemas["ChatRequestRequest"];
|
|
41
|
+
export type ApprovalRequest = AgentModeSchemas["ApprovalRequestRequest"];
|
|
42
|
+
/** Maps MCP tools to a page in the host app so the agent can navigate alongside chat. */
|
|
43
|
+
export interface AgentPageMapping {
|
|
44
|
+
/** MCP tool names whose execution relates to this page. */
|
|
45
|
+
tools: string[];
|
|
46
|
+
/** Host-app route (path) to navigate to, e.g. "/dashboard/target-companies". */
|
|
47
|
+
route: string;
|
|
48
|
+
/** Human title shown in navigation hints. */
|
|
49
|
+
title: string;
|
|
50
|
+
/**
|
|
51
|
+
* Optional builder for dynamic routes: receives the tool arguments and
|
|
52
|
+
* returns the concrete path (e.g. `/dashboard/company/${args.id}`).
|
|
53
|
+
* Return null to skip navigation for that call.
|
|
54
|
+
*/
|
|
55
|
+
buildRoute?: (args: Record<string, unknown>) => string | null;
|
|
56
|
+
}
|
|
57
|
+
export interface AgentConfig {
|
|
58
|
+
/** The Agent Mode client ID from the office panel (identifies the agent only). */
|
|
59
|
+
clientId: string;
|
|
60
|
+
/** Country Club backend base URL, e.g. https://api.country.club */
|
|
61
|
+
apiBaseUrl: string;
|
|
62
|
+
/** Returns the logged-in user's Country Club JWT (or null when logged out). */
|
|
63
|
+
getAccessToken: () => string | null | Promise<string | null>;
|
|
64
|
+
/** Display name override; falls back to the backend-configured agent name. */
|
|
65
|
+
agentName?: string;
|
|
66
|
+
/** Short line under the title in the panel header. */
|
|
67
|
+
tagline?: string;
|
|
68
|
+
/** Suggested prompts shown on the empty state. */
|
|
69
|
+
suggestions?: string[];
|
|
70
|
+
/** Navigate the host app (e.g. Next router push). Enables page-follow in popup mode. */
|
|
71
|
+
navigate?: (path: string) => void;
|
|
72
|
+
/** Tool → page mappings used for page-follow navigation and hints. */
|
|
73
|
+
pages?: AgentPageMapping[];
|
|
74
|
+
/** Widget appearance tweaks. All styling comes from the host's UI-kit theme tokens. */
|
|
75
|
+
appearance?: {
|
|
76
|
+
/** Floating button position. Default: "bottom-right". */
|
|
77
|
+
position?: "bottom-right" | "bottom-left";
|
|
78
|
+
/** Desktop popup panel size. Defaults: 400 x 640. */
|
|
79
|
+
panelWidth?: number;
|
|
80
|
+
panelHeight?: number;
|
|
81
|
+
/** Hide the floating button (render the panel through your own trigger). */
|
|
82
|
+
hideLauncher?: boolean;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentConfig, AgentMessage, AgentPublicConfig, ConversationSummary, PendingApproval } from "./types";
|
|
2
|
+
export interface AgentChatState {
|
|
3
|
+
agentInfo: AgentPublicConfig | null;
|
|
4
|
+
conversationId: string | null;
|
|
5
|
+
conversations: ConversationSummary[];
|
|
6
|
+
messages: AgentMessage[];
|
|
7
|
+
pendingApprovals: PendingApproval[];
|
|
8
|
+
sending: boolean;
|
|
9
|
+
resolvingApprovalId: string | null;
|
|
10
|
+
error: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface AgentChatActions {
|
|
13
|
+
send: (text: string) => Promise<void>;
|
|
14
|
+
resolveApproval: (callId: string, approve: boolean) => Promise<void>;
|
|
15
|
+
newChat: () => void;
|
|
16
|
+
openConversation: (conversationId: string) => Promise<void>;
|
|
17
|
+
refreshConversations: () => Promise<void>;
|
|
18
|
+
deleteConversation: (conversationId: string) => Promise<void>;
|
|
19
|
+
clearError: () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Headless chat state for an Agent Mode agent: message history, sending,
|
|
23
|
+
* pending write-tool approvals, and conversation management. UI-agnostic.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useAgentChat(config: AgentConfig): AgentChatState & AgentChatActions;
|
|
26
|
+
//# sourceMappingURL=use-agent-chat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-agent-chat.d.ts","sourceRoot":"","sources":["../src/use-agent-chat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,kBAAkB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAgKnF"}
|