@copilotz/chat-adapter 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +516 -6
- package/dist/index.d.ts +150 -3
- package/dist/index.js +273 -83
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,27 +1,537 @@
|
|
|
1
1
|
# @copilotz/chat-adapter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**From zero to agentic chat in one component.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
You built your AI with [Copilotz](https://github.com/copilotzhq/ts-lib). Now you need a frontend. You could wire up SSE streaming, thread persistence, tool call status updates, asset resolution, audio conversion, and context management. Or you could ship today.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@copilotz/chat-adapter)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://react.dev/)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
Your Copilotz backend handles memory, RAG, tool calling, and multi-tenancy. Now you need to connect it to a chat interface.
|
|
17
|
+
|
|
18
|
+
You could:
|
|
19
|
+
- Set up SSE streaming and parse token events
|
|
20
|
+
- Manage thread state and sync with the server
|
|
21
|
+
- Track tool call status in real-time (pending → running → completed)
|
|
22
|
+
- Convert browser-recorded audio to a format the API accepts
|
|
23
|
+
- Resolve `asset://` references to displayable data URLs
|
|
24
|
+
- Handle optimistic updates for instant feedback
|
|
25
|
+
- Wire up user context and memory sync
|
|
26
|
+
|
|
27
|
+
Or you could use one component.
|
|
28
|
+
|
|
29
|
+
## The Solution
|
|
30
|
+
|
|
31
|
+
`@copilotz/chat-adapter` is the official frontend binding for Copilotz. It wraps `@copilotz/chat-ui` with full API integration:
|
|
32
|
+
|
|
33
|
+
| What You'd Build | What This Gives You |
|
|
34
|
+
|------------------|---------------------|
|
|
35
|
+
| SSE parsing | Token-by-token streaming with cursor animation |
|
|
36
|
+
| Thread sync | Automatic fetch, create, rename, archive, delete |
|
|
37
|
+
| Tool status | Real-time updates as tools run |
|
|
38
|
+
| Audio handling | WebM/Opus → WAV conversion for API compatibility |
|
|
39
|
+
| Asset resolution | `asset://` refs → data URLs automatically |
|
|
40
|
+
| Context management | Shared user context across components |
|
|
41
|
+
| Error handling | Graceful fallbacks and retry logic |
|
|
42
|
+
|
|
43
|
+
**One component. Full Copilotz integration.**
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
6
48
|
|
|
7
49
|
```bash
|
|
8
50
|
npm install @copilotz/chat-adapter
|
|
9
51
|
```
|
|
10
52
|
|
|
11
|
-
|
|
53
|
+
Import the styles (from the UI package):
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import '@copilotz/chat-ui/styles.css';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Drop in the component:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { CopilotzChat } from '@copilotz/chat-adapter';
|
|
63
|
+
|
|
64
|
+
function App() {
|
|
65
|
+
return (
|
|
66
|
+
<CopilotzChat
|
|
67
|
+
userId="user-123"
|
|
68
|
+
userName="Alex"
|
|
69
|
+
config={{
|
|
70
|
+
branding: {
|
|
71
|
+
title: 'Acme Assistant',
|
|
72
|
+
subtitle: 'How can I help you today?',
|
|
73
|
+
},
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
That's it. You have a production chat interface connected to your Copilotz backend.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Environment Variables
|
|
85
|
+
|
|
86
|
+
Configure the API connection:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Base URL for the Copilotz API (default: /api)
|
|
90
|
+
VITE_API_URL=https://api.example.com
|
|
91
|
+
|
|
92
|
+
# Optional: API key for authenticated requests
|
|
93
|
+
VITE_API_KEY=your-api-key
|
|
94
|
+
# or
|
|
95
|
+
VITE_COPILOTZ_API_KEY=your-api-key
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Features
|
|
101
|
+
|
|
102
|
+
### Real-Time Streaming
|
|
103
|
+
|
|
104
|
+
Messages stream token-by-token with a thinking indicator while waiting for the first token. No configuration needed — it just works.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
<CopilotzChat userId="user-123" />
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Tool Calls with Live Status
|
|
111
|
+
|
|
112
|
+
When your agent calls tools, the UI shows real-time status updates:
|
|
113
|
+
|
|
114
|
+
1. **Pending** — Tool call received
|
|
115
|
+
2. **Running** — Tool is executing
|
|
116
|
+
3. **Completed/Failed** — Result displayed with execution time
|
|
117
|
+
|
|
118
|
+
All automatic. Just enable tool display in config:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<CopilotzChat
|
|
122
|
+
userId="user-123"
|
|
123
|
+
config={{
|
|
124
|
+
features: { enableToolCallsDisplay: true },
|
|
125
|
+
}}
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Bootstrap Conversations
|
|
130
|
+
|
|
131
|
+
Start conversations with an initial message or trigger tool calls immediately:
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<CopilotzChat
|
|
135
|
+
userId="user-123"
|
|
136
|
+
bootstrap={{
|
|
137
|
+
initialMessage: "Hello! I'm looking for help with my order.",
|
|
138
|
+
initialToolCalls: [
|
|
139
|
+
{ name: 'get_user_orders', args: { limit: 5 } },
|
|
140
|
+
],
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Audio Recording
|
|
146
|
+
|
|
147
|
+
Record voice messages directly in the chat. The adapter automatically converts browser-recorded audio (WebM/Opus) to WAV format for API compatibility.
|
|
148
|
+
|
|
149
|
+
### Asset Resolution
|
|
150
|
+
|
|
151
|
+
When your agent generates images or files, they're stored as `asset://` references. The adapter automatically resolves these to displayable data URLs.
|
|
152
|
+
|
|
153
|
+
### User Context
|
|
154
|
+
|
|
155
|
+
Share context across your app and sync with the Copilotz backend:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<CopilotzChat
|
|
159
|
+
userId="user-123"
|
|
160
|
+
initialContext={{
|
|
161
|
+
profile: { subscription: 'pro', preferences: { theme: 'dark' } },
|
|
162
|
+
customFields: [
|
|
163
|
+
{ key: 'company', label: 'Company', value: 'Acme Corp' },
|
|
164
|
+
],
|
|
165
|
+
}}
|
|
166
|
+
onToolOutput={(output) => {
|
|
167
|
+
// React to tool outputs (e.g., context updates)
|
|
168
|
+
console.log('Tool output:', output);
|
|
169
|
+
}}
|
|
170
|
+
/>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Agent Selector
|
|
174
|
+
|
|
175
|
+
Switch between multiple agents with a ChatGPT-style dropdown. The selected agent's name is passed to the Copilotz backend via `preferredAgentName`.
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
const [selectedAgent, setSelectedAgent] = useState('assistant');
|
|
179
|
+
|
|
180
|
+
const agents = [
|
|
181
|
+
{ id: 'assistant', name: 'Assistant', description: 'General purpose helper' },
|
|
182
|
+
{ id: 'coder', name: 'Code Expert', description: 'Specialized in programming' },
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
<CopilotzChat
|
|
186
|
+
userId="user-123"
|
|
187
|
+
agentOptions={agents}
|
|
188
|
+
selectedAgentId={selectedAgent}
|
|
189
|
+
onSelectAgent={setSelectedAgent}
|
|
190
|
+
/>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### URL State Sync
|
|
194
|
+
|
|
195
|
+
Persist chat state in URL parameters for shareable links, bookmarks, and deep linking from external sources.
|
|
196
|
+
|
|
197
|
+
**Features:**
|
|
198
|
+
- `?thread=abc123` — Open a specific conversation
|
|
199
|
+
- `?agent=support-bot` — Pre-select an agent
|
|
200
|
+
- `?prompt=Hello` — Pre-fill or auto-send a message
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
// Basic usage - enable URL sync
|
|
204
|
+
<CopilotzChat
|
|
205
|
+
userId="user-123"
|
|
206
|
+
urlSync={{ enabled: true }}
|
|
207
|
+
/>
|
|
208
|
+
|
|
209
|
+
// With custom parameter names
|
|
210
|
+
<CopilotzChat
|
|
211
|
+
userId="user-123"
|
|
212
|
+
urlSync={{
|
|
213
|
+
enabled: true,
|
|
214
|
+
params: { thread: 't', agent: 'a', prompt: 'q' },
|
|
215
|
+
}}
|
|
216
|
+
/>
|
|
217
|
+
|
|
218
|
+
// Auto-send the prompt instead of pre-filling
|
|
219
|
+
<CopilotzChat
|
|
220
|
+
userId="user-123"
|
|
221
|
+
urlSync={{
|
|
222
|
+
enabled: true,
|
|
223
|
+
promptBehavior: 'auto-send',
|
|
224
|
+
}}
|
|
225
|
+
/>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**URL Sync Options:**
|
|
229
|
+
|
|
230
|
+
| Option | Type | Default | Description |
|
|
231
|
+
|--------|------|---------|-------------|
|
|
232
|
+
| `enabled` | `boolean` | `true` | Enable/disable URL sync |
|
|
233
|
+
| `mode` | `'push' \| 'replace' \| 'read-only'` | `'replace'` | How to update URL |
|
|
234
|
+
| `params.thread` | `string` | `'thread'` | URL param name for thread ID |
|
|
235
|
+
| `params.agent` | `string` | `'agent'` | URL param name for agent ID |
|
|
236
|
+
| `params.prompt` | `string` | `'prompt'` | URL param name for initial prompt |
|
|
237
|
+
| `promptBehavior` | `'prefill' \| 'auto-send'` | `'prefill'` | How to handle the prompt param |
|
|
238
|
+
| `clearPromptAfterRead` | `boolean` | `true` | Remove prompt from URL after use |
|
|
239
|
+
|
|
240
|
+
**Example URLs:**
|
|
241
|
+
```
|
|
242
|
+
/chat?thread=abc123 # Open specific thread
|
|
243
|
+
/chat?agent=support-bot # Pre-select agent
|
|
244
|
+
/chat?prompt=How%20do%20I%20reset... # Pre-fill message
|
|
245
|
+
/chat?thread=abc123&agent=support&prompt=Hi # Combined
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Props Reference
|
|
251
|
+
|
|
252
|
+
### CopilotzChat
|
|
253
|
+
|
|
254
|
+
| Prop | Type | Description |
|
|
255
|
+
|------|------|-------------|
|
|
256
|
+
| `userId` | `string` | Required. User identifier for thread filtering |
|
|
257
|
+
| `userName` | `string` | Display name for the user |
|
|
258
|
+
| `userAvatar` | `string` | URL to user's avatar image |
|
|
259
|
+
| `userEmail` | `string` | User's email address |
|
|
260
|
+
| `initialContext` | `ChatUserContext` | Initial context to seed the conversation |
|
|
261
|
+
| `bootstrap` | `{ initialMessage?, initialToolCalls? }` | Start conversation with message/tools |
|
|
262
|
+
| `config` | `ChatConfig` | UI configuration (same as `@copilotz/chat-ui`) |
|
|
263
|
+
| `callbacks` | `Partial<ChatCallbacks>` | Additional event handlers |
|
|
264
|
+
| `customComponent` | `ReactNode \| Function` | Custom right sidebar panel |
|
|
265
|
+
| `onToolOutput` | `(output) => void` | Called when a tool produces output |
|
|
266
|
+
| `onLogout` | `() => void` | Called when user clicks logout |
|
|
267
|
+
| `onViewProfile` | `() => void` | Called when user clicks view profile |
|
|
268
|
+
| `onAddMemory` | `(content, category?) => void` | Called when user adds a memory |
|
|
269
|
+
| `onUpdateMemory` | `(memoryId, content) => void` | Called when user updates a memory |
|
|
270
|
+
| `onDeleteMemory` | `(memoryId) => void` | Called when user deletes a memory |
|
|
271
|
+
| `suggestions` | `string[]` | Suggested prompts shown when no messages |
|
|
272
|
+
| `agentOptions` | `AgentOption[]` | Available agents for the selector dropdown |
|
|
273
|
+
| `selectedAgentId` | `string \| null` | Currently selected agent ID |
|
|
274
|
+
| `onSelectAgent` | `(agentId: string) => void` | Called when user selects an agent |
|
|
275
|
+
| `urlSync` | `UrlSyncConfig` | URL state synchronization config (see URL State Sync section) |
|
|
276
|
+
| `className` | `string` | Additional CSS classes |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Hooks
|
|
281
|
+
|
|
282
|
+
### useCopilotz
|
|
283
|
+
|
|
284
|
+
For custom integrations, use the hook directly:
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import { useCopilotz } from '@copilotz/chat-adapter';
|
|
288
|
+
|
|
289
|
+
function CustomChat() {
|
|
290
|
+
const {
|
|
291
|
+
messages,
|
|
292
|
+
threads,
|
|
293
|
+
currentThreadId,
|
|
294
|
+
isStreaming,
|
|
295
|
+
userContextSeed,
|
|
296
|
+
sendMessage,
|
|
297
|
+
createThread,
|
|
298
|
+
selectThread,
|
|
299
|
+
renameThread,
|
|
300
|
+
archiveThread,
|
|
301
|
+
deleteThread,
|
|
302
|
+
stopGeneration,
|
|
303
|
+
reset,
|
|
304
|
+
} = useCopilotz({
|
|
305
|
+
userId: 'user-123',
|
|
306
|
+
initialContext: { /* ... */ },
|
|
307
|
+
bootstrap: { initialMessage: 'Hello!' },
|
|
308
|
+
defaultThreadName: 'Support Chat',
|
|
309
|
+
onToolOutput: (output) => console.log(output),
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<div>
|
|
314
|
+
{messages.map((msg) => (
|
|
315
|
+
<div key={msg.id}>{msg.content}</div>
|
|
316
|
+
))}
|
|
317
|
+
<button onClick={() => sendMessage('Hello!')}>Send</button>
|
|
318
|
+
</div>
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Hook Options
|
|
324
|
+
|
|
325
|
+
| Option | Type | Description |
|
|
326
|
+
|--------|------|-------------|
|
|
327
|
+
| `userId` | `string \| null` | User identifier (null resets state) |
|
|
328
|
+
| `initialContext` | `ChatUserContext` | Initial context seed |
|
|
329
|
+
| `bootstrap` | `{ initialMessage?, initialToolCalls? }` | Auto-start conversation |
|
|
330
|
+
| `defaultThreadName` | `string` | Name for bootstrap thread |
|
|
331
|
+
| `onToolOutput` | `(output) => void` | Tool output callback |
|
|
332
|
+
| `preferredAgentName` | `string \| null` | Agent name to use for requests |
|
|
333
|
+
| `urlSync` | `UrlSyncConfig` | URL state synchronization config |
|
|
334
|
+
|
|
335
|
+
### Hook Returns
|
|
336
|
+
|
|
337
|
+
| Property | Type | Description |
|
|
338
|
+
|----------|------|-------------|
|
|
339
|
+
| `messages` | `ChatMessage[]` | Current thread messages |
|
|
340
|
+
| `threads` | `ChatThread[]` | All user threads |
|
|
341
|
+
| `currentThreadId` | `string \| null` | Selected thread ID |
|
|
342
|
+
| `isStreaming` | `boolean` | Whether response is streaming |
|
|
343
|
+
| `userContextSeed` | `ChatUserContext` | Current user context |
|
|
344
|
+
| `sendMessage` | `(content, attachments?) => Promise` | Send a message |
|
|
345
|
+
| `createThread` | `(title?) => void` | Create new thread |
|
|
346
|
+
| `selectThread` | `(threadId) => Promise` | Switch threads |
|
|
347
|
+
| `renameThread` | `(threadId, title) => Promise` | Rename thread |
|
|
348
|
+
| `archiveThread` | `(threadId) => Promise` | Archive/unarchive |
|
|
349
|
+
| `deleteThread` | `(threadId) => Promise` | Delete thread |
|
|
350
|
+
| `stopGeneration` | `() => void` | Stop streaming |
|
|
351
|
+
| `reset` | `() => void` | Clear all state |
|
|
352
|
+
| `initialPrompt` | `string \| null` | Initial prompt from URL (if urlSync enabled) |
|
|
353
|
+
| `clearInitialPrompt` | `() => void` | Clear initial prompt from URL |
|
|
354
|
+
| `urlAgentId` | `string \| null` | Agent ID from URL (if urlSync enabled) |
|
|
355
|
+
| `setUrlAgentId` | `(agentId) => void` | Update agent ID in URL |
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Services
|
|
360
|
+
|
|
361
|
+
### copilotzService
|
|
362
|
+
|
|
363
|
+
Low-level API client for direct backend communication:
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
import {
|
|
367
|
+
runCopilotzStream,
|
|
368
|
+
fetchThreads,
|
|
369
|
+
fetchThreadMessages,
|
|
370
|
+
updateThread,
|
|
371
|
+
deleteThread,
|
|
372
|
+
} from '@copilotz/chat-adapter';
|
|
373
|
+
|
|
374
|
+
// Stream a message
|
|
375
|
+
const result = await runCopilotzStream({
|
|
376
|
+
content: 'Hello!',
|
|
377
|
+
user: { externalId: 'user-123', name: 'Alex' },
|
|
378
|
+
threadExternalId: 'thread-456',
|
|
379
|
+
onToken: (text, isComplete) => console.log(text),
|
|
380
|
+
onMessageEvent: (event) => console.log(event),
|
|
381
|
+
onAssetEvent: (asset) => console.log(asset),
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// Fetch threads
|
|
385
|
+
const threads = await fetchThreads('user-123');
|
|
386
|
+
|
|
387
|
+
// Fetch messages
|
|
388
|
+
const messages = await fetchThreadMessages('thread-456');
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### assetsService
|
|
392
|
+
|
|
393
|
+
Resolve asset references to data URLs:
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
import { getAssetDataUrl, resolveAssetsInMessages } from '@copilotz/chat-adapter';
|
|
397
|
+
|
|
398
|
+
// Single asset
|
|
399
|
+
const { dataUrl, mime } = await getAssetDataUrl('asset://abc123');
|
|
400
|
+
|
|
401
|
+
// Batch resolve in messages
|
|
402
|
+
const messagesWithAssets = await resolveAssetsInMessages(messages);
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Exports
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
// Components
|
|
411
|
+
export { CopilotzChat } from './CopilotzChat';
|
|
412
|
+
|
|
413
|
+
// Hooks
|
|
414
|
+
export { useCopilotz } from './useCopilotzChat';
|
|
415
|
+
export { useUrlState } from './useUrlState';
|
|
416
|
+
|
|
417
|
+
// Services
|
|
418
|
+
export {
|
|
419
|
+
runCopilotzStream,
|
|
420
|
+
fetchThreads,
|
|
421
|
+
fetchThreadMessages,
|
|
422
|
+
updateThread,
|
|
423
|
+
deleteThread,
|
|
424
|
+
copilotzService,
|
|
425
|
+
} from './copilotzService';
|
|
426
|
+
|
|
427
|
+
export {
|
|
428
|
+
getAssetDataUrl,
|
|
429
|
+
resolveAssetsInMessages,
|
|
430
|
+
} from './assetsService';
|
|
431
|
+
|
|
432
|
+
// Re-exported types from @copilotz/chat-ui
|
|
433
|
+
export type {
|
|
434
|
+
ChatConfig,
|
|
435
|
+
ChatCallbacks,
|
|
436
|
+
ChatUserContext,
|
|
437
|
+
ChatMessage,
|
|
438
|
+
ChatThread,
|
|
439
|
+
MediaAttachment,
|
|
440
|
+
MemoryItem,
|
|
441
|
+
} from '@copilotz/chat-ui';
|
|
442
|
+
|
|
443
|
+
// URL state types
|
|
444
|
+
export type {
|
|
445
|
+
UrlSyncConfig,
|
|
446
|
+
UrlParamsConfig,
|
|
447
|
+
UrlState,
|
|
448
|
+
UseUrlStateReturn,
|
|
449
|
+
} from './useUrlState';
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Full Example
|
|
12
455
|
|
|
13
456
|
```tsx
|
|
14
457
|
import { CopilotzChat } from '@copilotz/chat-adapter';
|
|
15
458
|
import '@copilotz/chat-ui/styles.css';
|
|
16
459
|
|
|
17
|
-
|
|
460
|
+
function App() {
|
|
461
|
+
const handleLogout = () => {
|
|
462
|
+
// Clear session, redirect to login
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
const handleToolOutput = (output) => {
|
|
466
|
+
// React to tool outputs
|
|
467
|
+
if (output.userContext) {
|
|
468
|
+
// Context was updated by a tool
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
18
472
|
return (
|
|
19
473
|
<CopilotzChat
|
|
20
|
-
userId="user-
|
|
474
|
+
userId="user-123"
|
|
475
|
+
userName="Alex"
|
|
476
|
+
userEmail="alex@example.com"
|
|
477
|
+
initialContext={{
|
|
478
|
+
customFields: [
|
|
479
|
+
{ key: 'plan', label: 'Plan', value: 'Pro' },
|
|
480
|
+
],
|
|
481
|
+
}}
|
|
482
|
+
bootstrap={{
|
|
483
|
+
initialMessage: 'Hello! I need help with my account.',
|
|
484
|
+
}}
|
|
21
485
|
config={{
|
|
22
|
-
branding: {
|
|
486
|
+
branding: {
|
|
487
|
+
title: 'Acme Support',
|
|
488
|
+
subtitle: 'We typically reply in a few seconds',
|
|
489
|
+
},
|
|
490
|
+
features: {
|
|
491
|
+
enableToolCallsDisplay: true,
|
|
492
|
+
enableFileUpload: true,
|
|
493
|
+
enableAudioRecording: true,
|
|
494
|
+
},
|
|
495
|
+
labels: {
|
|
496
|
+
inputPlaceholder: 'Describe your issue...',
|
|
497
|
+
},
|
|
23
498
|
}}
|
|
499
|
+
customComponent={({ onClose, isMobile }) => (
|
|
500
|
+
<div className="p-4">
|
|
501
|
+
<h2>Account Details</h2>
|
|
502
|
+
<button onClick={onClose}>Close</button>
|
|
503
|
+
</div>
|
|
504
|
+
)}
|
|
505
|
+
onToolOutput={handleToolOutput}
|
|
506
|
+
onLogout={handleLogout}
|
|
24
507
|
/>
|
|
25
508
|
);
|
|
26
509
|
}
|
|
27
510
|
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Requirements
|
|
515
|
+
|
|
516
|
+
- React 18+
|
|
517
|
+
- Copilotz backend with `/v1/providers/web` endpoint
|
|
518
|
+
- Environment variables configured
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Related Packages
|
|
523
|
+
|
|
524
|
+
- **[@copilotz/chat-ui](../copilotz-chat-ui)** — The underlying UI components (backend-agnostic)
|
|
525
|
+
- **[copilotz](https://github.com/copilotzhq/ts-lib)** — The full-stack framework for AI applications
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## License
|
|
530
|
+
|
|
531
|
+
MIT — see [LICENSE](./LICENSE)
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
<p align="center">
|
|
536
|
+
<strong>Your agent is ready. Your UI should be too.</strong>
|
|
537
|
+
</p>
|