@bridgeline-digital/hawkai-assistant 1.0.0-beta.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/README.md +453 -0
- package/dist/api/client.d.ts +11 -0
- package/dist/api/types.d.ts +73 -0
- package/dist/bridge.d.ts +7 -0
- package/dist/components/App.d.ts +2 -0
- package/dist/components/AssistantButton.d.ts +7 -0
- package/dist/components/AssistantForm.d.ts +2 -0
- package/dist/components/AssistantWindow.d.ts +7 -0
- package/dist/components/LoadingIndicator.d.ts +2 -0
- package/dist/components/Message.d.ts +8 -0
- package/dist/components/MessageList.d.ts +2 -0
- package/dist/components/ProductCarousel.d.ts +7 -0
- package/dist/components/PromptOptions.d.ts +2 -0
- package/dist/components/RenderedTool.d.ts +7 -0
- package/dist/contexts/AssistantContext.d.ts +21 -0
- package/dist/hawkai-assistant.js +97 -0
- package/dist/hooks/useSendMessage.d.ts +7 -0
- package/dist/hooks/useTheme.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3948 -0
- package/dist/main.d.ts +7 -0
- package/dist/session-manager.d.ts +8 -0
- package/dist/tools/display-products-tool.d.ts +6 -0
- package/dist/tools/page-context-tool.d.ts +12 -0
- package/dist/types.d.ts +81 -0
- package/dist/utilities/parseMarkdown.d.ts +28 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
# HawkAI Assistant
|
|
2
|
+
|
|
3
|
+
A self-contained AI chat widget that drops into any web page with a single script tag. Powered by an agentic API backend, it supports streaming responses, multi-turn tool use, custom tool rendering, file uploads, and full UI customization — all isolated in a Shadow DOM so it won't conflict with your page's styles.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### CDN (recommended)
|
|
10
|
+
|
|
11
|
+
Once published to npm, load the widget directly from a CDN:
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<script src="https://cdn.jsdelivr.net/npm/@bridgeline-digital/hawkai-assistant/dist/hawkai-assistant.js"></script>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Or via unpkg:
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<script src="https://unpkg.com/@bridgeline-digital/hawkai-assistant/dist/hawkai-assistant.js"></script>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Self-hosted
|
|
24
|
+
|
|
25
|
+
Install the package and copy the built file to your project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @bridgeline-digital/hawkai-assistant
|
|
29
|
+
# or
|
|
30
|
+
pnpm add @bridgeline-digital/hawkai-assistant
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then copy `node_modules/@bridgeline-digital/hawkai-assistant/dist/hawkai-assistant.js` to your static assets directory and load it with a `<script>` tag.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script src="hawkai-assistant.js"></script>
|
|
41
|
+
<script>
|
|
42
|
+
HawkAI.Assistant.initialize({
|
|
43
|
+
apiUrl: 'https://your-api-endpoint.example.com',
|
|
44
|
+
accountId: 'your-account-id',
|
|
45
|
+
agentId: 'your-agent-uuid',
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That's it. The widget mounts itself as a fixed floating button in the corner of the page.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Configuration
|
|
55
|
+
|
|
56
|
+
Pass a `Config` object to `initialize()`:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
HawkAI.Assistant.initialize(config: Config): void
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### `Config`
|
|
63
|
+
|
|
64
|
+
| Property | Type | Required | Description |
|
|
65
|
+
|----------|------|----------|-------------|
|
|
66
|
+
| `apiUrl` | `string` | Yes | Base URL of the assistant API. |
|
|
67
|
+
| `accountId` | `string` | Yes | Your account identifier. |
|
|
68
|
+
| `agentId` | `string` | Yes | UUID of the agent to invoke. |
|
|
69
|
+
| `actorId` | `string` | No | User/actor identifier. Falls back to a stored value in `localStorage`, then a generated UUID. |
|
|
70
|
+
| `context` | `Record<string, unknown>` | No | Arbitrary contextual data sent with every API request (e.g. location, user preferences). |
|
|
71
|
+
| `tools` | `Tool[]` | No | Custom tools the model can invoke. See [Custom Tools](#custom-tools). |
|
|
72
|
+
| `addToCart` | `(product: Product) => void` | No | Callback invoked when the user clicks "Add to Cart" in a product carousel. When omitted, no button is shown. |
|
|
73
|
+
| `ui` | `UiConfig` | No | UI customization options. See [UI Config](#uiconfig). |
|
|
74
|
+
|
|
75
|
+
### `UiConfig`
|
|
76
|
+
|
|
77
|
+
| Property | Type | Default | Description |
|
|
78
|
+
|----------|------|---------|-------------|
|
|
79
|
+
| `open` | `boolean` | `false` | Whether the widget starts open. |
|
|
80
|
+
| `display` | `'window' \| 'drawer'` | `'window'` | Layout mode — floating window or a drawer panel. |
|
|
81
|
+
| `position` | `'left' \| 'right'` | `'right'` | Side of the screen for the button and panel. |
|
|
82
|
+
| `theme` | `'light' \| 'dark' \| 'automatic'` | `'automatic'` | Color scheme. `'automatic'` follows the user's OS preference. |
|
|
83
|
+
| `allowFullScreen` | `boolean` | `true` | Whether the user can expand the widget to full screen. |
|
|
84
|
+
| `allowFileUpload` | `boolean` | `true` | Whether the user can attach files to messages. |
|
|
85
|
+
| `logoUrl` | `string` | — | URL of a logo image shown in the widget header. |
|
|
86
|
+
| `heading` | `string` | — | Title text shown in the widget header. |
|
|
87
|
+
| `initialMessage` | `string` | — | First message shown to the user when the widget opens. |
|
|
88
|
+
| `promptOptions` | `string[]` | — | Quick-start prompt buttons shown when the chat is empty. Clicking one submits it as a message. |
|
|
89
|
+
| `placeholder` | `string` | — | Placeholder text for the message input. |
|
|
90
|
+
| `colors.primary.default` | `string` | — | CSS color value for the primary accent (button, send icon, etc.). |
|
|
91
|
+
| `colors.primary.hover` | `string` | — | CSS color value for the primary accent on hover. |
|
|
92
|
+
| `styles` | `string` | — | Raw CSS string injected into the shadow root after built-in styles. Use BEM class names (e.g. `.hawkai-assistant__window`). |
|
|
93
|
+
| `stylesheetUrl` | `string` | — | URL of an external CSS file loaded via `<link>` inside the shadow root. |
|
|
94
|
+
|
|
95
|
+
#### Example with full UI config
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
HawkAI.Assistant.initialize({
|
|
99
|
+
apiUrl: 'https://your-api.example.com',
|
|
100
|
+
accountId: '123',
|
|
101
|
+
agentId: 'your-agent-uuid',
|
|
102
|
+
ui: {
|
|
103
|
+
open: true,
|
|
104
|
+
display: 'window',
|
|
105
|
+
position: 'right',
|
|
106
|
+
allowFullScreen: true,
|
|
107
|
+
allowFileUpload: true,
|
|
108
|
+
heading: 'Support Assistant',
|
|
109
|
+
logoUrl: 'https://example.com/logo.png',
|
|
110
|
+
initialMessage: 'Hi! How can I help you today?',
|
|
111
|
+
promptOptions: ['What are your best deals?', 'Track my order', 'Return an item'],
|
|
112
|
+
placeholder: 'Type your question…',
|
|
113
|
+
theme: 'automatic',
|
|
114
|
+
colors: {
|
|
115
|
+
primary: {
|
|
116
|
+
default: '#2563eb',
|
|
117
|
+
hover: '#1d4ed8',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
styles: '.hawkai-assistant__window { border-radius: 16px; }',
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Custom Styling
|
|
126
|
+
|
|
127
|
+
The widget's Shadow DOM prevents host-page styles from bleeding in, but you can target widget internals using the stable BEM class names exposed on every element:
|
|
128
|
+
|
|
129
|
+
| Class | Element |
|
|
130
|
+
|-------|---------|
|
|
131
|
+
| `.hawkai-assistant__trigger` | The floating action button |
|
|
132
|
+
| `.hawkai-assistant__trigger--open` | Modifier applied when the widget is open |
|
|
133
|
+
| `.hawkai-assistant__window` | The chat panel container |
|
|
134
|
+
| `.hawkai-assistant__header` | The panel header bar |
|
|
135
|
+
| `.hawkai-assistant__message` | Individual message bubbles |
|
|
136
|
+
| `.hawkai-assistant__form` | The message input area |
|
|
137
|
+
|
|
138
|
+
Inject styles via `config.ui.styles` (inline string, good for small overrides) or `config.ui.stylesheetUrl` (external file, good for larger stylesheets). Both are applied inside the shadow root after built-in styles.
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
HawkAI.Assistant.initialize({
|
|
142
|
+
// ...
|
|
143
|
+
ui: {
|
|
144
|
+
styles: `
|
|
145
|
+
.hawkai-assistant__window { border-radius: 16px; }
|
|
146
|
+
.hawkai-assistant__trigger { background: purple; }
|
|
147
|
+
`,
|
|
148
|
+
// or:
|
|
149
|
+
stylesheetUrl: 'https://example.com/my-assistant-theme.css',
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Public API
|
|
157
|
+
|
|
158
|
+
After the script loads, all methods are available on `window.HawkAI.Assistant`:
|
|
159
|
+
|
|
160
|
+
### `initialize(config)`
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
HawkAI.Assistant.initialize(config: Config): void
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Mounts the widget. Can only be called once — subsequent calls are silently ignored. Config is frozen after initialization; do not mutate it.
|
|
167
|
+
|
|
168
|
+
### `toggle(open)`
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
HawkAI.Assistant.toggle(open: boolean): void
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Programmatically open or close the widget.
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
HawkAI.Assistant.toggle(true); // open
|
|
178
|
+
HawkAI.Assistant.toggle(false); // close
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### `sendMessage(message?, files?)`
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
HawkAI.Assistant.sendMessage(message?: string, files?: File[]): Promise<void>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Opens the widget and submits a message into the conversation. Useful for triggering the assistant from your own UI elements.
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
HawkAI.Assistant.sendMessage('Show me the latest deals');
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### `clearChat()`
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
HawkAI.Assistant.clearChat(): void
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Clears the conversation history and regenerates the session ID.
|
|
200
|
+
|
|
201
|
+
### `setActorId(value)`
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
HawkAI.Assistant.setActorId(value: string | undefined): void
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Changes the actor/user identity. Automatically calls `clearChat()` so the new actor starts a fresh session. Pass `undefined` to generate a new anonymous ID.
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
// After a user logs in:
|
|
211
|
+
HawkAI.Assistant.setActorId(user.id);
|
|
212
|
+
|
|
213
|
+
// After logout:
|
|
214
|
+
HawkAI.Assistant.setActorId(undefined);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### `setContext(context)`
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
HawkAI.Assistant.setContext(context: Record<string, unknown> | undefined): void
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Updates the contextual data sent with every subsequent API request.
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
HawkAI.Assistant.setContext({ cart: { items: 3, total: '$89.97' } });
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Custom Tools
|
|
232
|
+
|
|
233
|
+
Tools let the model take actions on your page. Each tool has a name, a description (for the model), a JSON schema for its inputs, and an `execute` function the widget calls when the model invokes it.
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
interface Tool<TInput, TOutput> {
|
|
237
|
+
name: string;
|
|
238
|
+
description: string;
|
|
239
|
+
inputSchema: {
|
|
240
|
+
type: 'object';
|
|
241
|
+
properties: Record<string, unknown>;
|
|
242
|
+
required?: string[];
|
|
243
|
+
};
|
|
244
|
+
execute: (input: TInput) => Promise<TOutput>;
|
|
245
|
+
render?: (data: RenderToolData<TInput>, helpers: RenderToolHelpers) => AsyncRenderToolResult;
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Pass tools in the `tools` array of `Config`:
|
|
250
|
+
|
|
251
|
+
```js
|
|
252
|
+
HawkAI.Assistant.initialize({
|
|
253
|
+
apiUrl: '...',
|
|
254
|
+
accountId: '...',
|
|
255
|
+
agentId: '...',
|
|
256
|
+
tools: [
|
|
257
|
+
{
|
|
258
|
+
name: 'add_to_cart',
|
|
259
|
+
description: 'Adds a product to the shopping cart.',
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: 'object',
|
|
262
|
+
properties: {
|
|
263
|
+
product_name: { type: 'string', description: 'Product name' },
|
|
264
|
+
price: { type: 'string', description: 'Product price (optional)' },
|
|
265
|
+
},
|
|
266
|
+
required: ['product_name'],
|
|
267
|
+
},
|
|
268
|
+
execute: async ({ product_name, price }) => {
|
|
269
|
+
// Your logic here — runs in the browser when the model calls this tool
|
|
270
|
+
addItemToCart(product_name, price);
|
|
271
|
+
return `${product_name} added to cart.`;
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Optional `render` function
|
|
279
|
+
|
|
280
|
+
Tools can optionally render UI inline in the chat message. Return a Preact `ComponentChild` or a plain `HTMLElement`:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
interface RenderToolData<TInput> {
|
|
284
|
+
input: TInput;
|
|
285
|
+
status: 'pending' | 'success' | 'error' | undefined;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
interface RenderToolHelpers {
|
|
289
|
+
sendMessage: (text: string) => Promise<void>;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
type AsyncRenderToolResult = ComponentChild | HTMLElement | null | Promise<ComponentChild | HTMLElement | null>;
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
- `status` is `'pending'` while `execute()` is running, then `'success'` or `'error'`. It is `undefined` when a tool use is loaded from conversation history — treat this the same as `'success'`.
|
|
296
|
+
- `helpers.sendMessage(text)` injects a follow-up user message into the agentic loop, useful for interactive buttons.
|
|
297
|
+
- Return `null` to render nothing.
|
|
298
|
+
- Return a `Promise` when setup is async (e.g. lazy-loading a web component).
|
|
299
|
+
|
|
300
|
+
#### Example — plain HTMLElement render
|
|
301
|
+
|
|
302
|
+
```js
|
|
303
|
+
{
|
|
304
|
+
name: 'show_rating',
|
|
305
|
+
description: 'Displays a visual rating bar for a product.',
|
|
306
|
+
inputSchema: {
|
|
307
|
+
type: 'object',
|
|
308
|
+
properties: {
|
|
309
|
+
label: { type: 'string' },
|
|
310
|
+
score: { type: 'number', description: 'Rating from 0 to 10' },
|
|
311
|
+
},
|
|
312
|
+
required: ['label', 'score'],
|
|
313
|
+
},
|
|
314
|
+
execute: async ({ label, score }) => ({ label, score }),
|
|
315
|
+
render: ({ input, status }) => {
|
|
316
|
+
const el = document.createElement('div');
|
|
317
|
+
|
|
318
|
+
if (status === 'pending') {
|
|
319
|
+
el.textContent = 'Loading rating…';
|
|
320
|
+
return el;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const pct = Math.round(Math.min(Math.max(input.score, 0), 10) * 10);
|
|
324
|
+
el.innerHTML = `<strong>${input.label}</strong>: ${input.score}/10`;
|
|
325
|
+
|
|
326
|
+
const bar = document.createElement('div');
|
|
327
|
+
bar.style.cssText = 'margin-top:6px;height:8px;border-radius:4px;background:#e2e8f0;overflow:hidden';
|
|
328
|
+
|
|
329
|
+
const fill = document.createElement('div');
|
|
330
|
+
fill.style.cssText = `height:100%;width:${pct}%;background:#2563eb;border-radius:4px`;
|
|
331
|
+
bar.appendChild(fill);
|
|
332
|
+
el.appendChild(bar);
|
|
333
|
+
|
|
334
|
+
return el;
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Built-in Tools
|
|
342
|
+
|
|
343
|
+
The widget registers two tools automatically — you don't need to declare them:
|
|
344
|
+
|
|
345
|
+
### `display_products`
|
|
346
|
+
|
|
347
|
+
Renders a product carousel inline in the chat. The model calls this tool when it wants to show product recommendations. Each product in the input array may include: `id`, `title`, `url`, `imageUrl`, `price`, `salePrice`, `rating`, `brand`, `sku`, `description`. When `config.addToCart` is provided, each product card displays an "Add to Cart" button that invokes the callback.
|
|
348
|
+
|
|
349
|
+
### `retrieve_page_context`
|
|
350
|
+
|
|
351
|
+
Reads the current page's URL, title, meta description, first `<h1>`, and main content text. The model calls this to understand what page the user is on without any setup on your part.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Session & Actor IDs
|
|
356
|
+
|
|
357
|
+
**Session ID** — identifies the current conversation. Persisted in `localStorage` so the user's conversation survives page reloads. Regenerated when `clearChat()` is called.
|
|
358
|
+
|
|
359
|
+
**Actor ID** — identifies the user across sessions. Resolved in this order:
|
|
360
|
+
1. `config.actorId` (if provided)
|
|
361
|
+
2. Previously stored value in `localStorage`
|
|
362
|
+
3. Auto-generated UUID
|
|
363
|
+
|
|
364
|
+
Use `setActorId()` to update the actor when a user logs in or out. This clears the conversation so the new actor starts fresh.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Custom Build
|
|
369
|
+
|
|
370
|
+
If you need to bundle your own tools with strong TypeScript typings — or encapsulate the `initialize` call for a specific site — you can create a custom build script using the npm package as a library.
|
|
371
|
+
|
|
372
|
+
### 1. Install
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
npm install @bridgeline-digital/hawkai-assistant
|
|
376
|
+
# or
|
|
377
|
+
pnpm add @bridgeline-digital/hawkai-assistant
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 2. Create your entry file
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
// src/my-assistant.ts
|
|
384
|
+
import { initialize } from '@bridgeline-digital/hawkai-assistant';
|
|
385
|
+
import type { Tool } from '@bridgeline-digital/hawkai-assistant';
|
|
386
|
+
|
|
387
|
+
interface AddToCartInput {
|
|
388
|
+
product_name: string;
|
|
389
|
+
price?: string;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const addToCartTool: Tool<AddToCartInput, string> = {
|
|
393
|
+
name: 'add_to_cart',
|
|
394
|
+
description: 'Adds a product to the shopping cart.',
|
|
395
|
+
inputSchema: {
|
|
396
|
+
type: 'object',
|
|
397
|
+
properties: {
|
|
398
|
+
product_name: { type: 'string', description: 'Product name' },
|
|
399
|
+
price: { type: 'string', description: 'Product price (optional)' },
|
|
400
|
+
},
|
|
401
|
+
required: ['product_name'],
|
|
402
|
+
},
|
|
403
|
+
execute: async ({ product_name, price }) => {
|
|
404
|
+
// your cart logic here
|
|
405
|
+
return `${product_name} added to cart.`;
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
initialize({
|
|
410
|
+
apiUrl: 'https://your-api.example.com',
|
|
411
|
+
accountId: '123',
|
|
412
|
+
agentId: 'your-agent-uuid',
|
|
413
|
+
tools: [addToCartTool],
|
|
414
|
+
});
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### 3. Add a Vite config
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
// vite.config.ts
|
|
421
|
+
import { defineConfig } from 'vite';
|
|
422
|
+
|
|
423
|
+
export default defineConfig({
|
|
424
|
+
build: {
|
|
425
|
+
lib: {
|
|
426
|
+
entry: 'src/my-assistant.ts',
|
|
427
|
+
name: 'MyAssistant',
|
|
428
|
+
formats: ['iife'],
|
|
429
|
+
fileName: () => 'my-assistant.js',
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### 4. Build and deploy
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
pnpm build
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
This produces `dist/my-assistant.js` — a single self-contained IIFE you can drop on any page:
|
|
442
|
+
|
|
443
|
+
```html
|
|
444
|
+
<script src="my-assistant.js"></script>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
No separate `initialize()` call is needed; your entry file handles it.
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Browser Support
|
|
452
|
+
|
|
453
|
+
The widget requires a browser that supports Shadow DOM, `CSSStyleSheet.adoptedStyleSheets`, and `EventSource`. All modern browsers (Chrome, Firefox, Safari, Edge) meet these requirements.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AnyTool } from '../types';
|
|
2
|
+
import { AssistantTurn, Turn, UserTurn } from './types';
|
|
3
|
+
export interface SendUserTurnCallbacks {
|
|
4
|
+
onAssistantTurnStart: () => void;
|
|
5
|
+
onAssistantTextDelta: (text: string) => void;
|
|
6
|
+
onAssistantTurnComplete: (turn: AssistantTurn) => void;
|
|
7
|
+
onToolResultsTurn: (turn: UserTurn) => void;
|
|
8
|
+
onToolResult: (toolUseId: string, output: unknown, status: 'success' | 'error') => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const sendUserTurn: (turn: UserTurn, tools: AnyTool[], callbacks: SendUserTurnCallbacks, signal?: AbortSignal) => Promise<void>;
|
|
11
|
+
export declare const getConversationHistory: () => Promise<Turn[]>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { AnyTool, Config, ToolRenderStatus } from '../types';
|
|
2
|
+
export type { Config };
|
|
3
|
+
export interface TextDeltaData {
|
|
4
|
+
delta: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FrontendToolEvent {
|
|
7
|
+
toolUseId: string;
|
|
8
|
+
tool: string;
|
|
9
|
+
args: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export type ApiTool = Pick<AnyTool, 'name' | 'description' | 'inputSchema'>;
|
|
12
|
+
export interface ApiToolResult {
|
|
13
|
+
toolUseId: string;
|
|
14
|
+
content: Array<{
|
|
15
|
+
json: unknown;
|
|
16
|
+
} | {
|
|
17
|
+
text: string;
|
|
18
|
+
}>;
|
|
19
|
+
status: 'success' | 'error';
|
|
20
|
+
}
|
|
21
|
+
export interface ToolUse<TInput, TOutput = unknown> {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
input?: TInput;
|
|
25
|
+
output?: TOutput;
|
|
26
|
+
status?: ToolRenderStatus;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolResult<TOutput> {
|
|
29
|
+
toolUseId: string;
|
|
30
|
+
output?: TOutput;
|
|
31
|
+
status: 'success' | 'error';
|
|
32
|
+
}
|
|
33
|
+
export interface UserFile {
|
|
34
|
+
name: string;
|
|
35
|
+
mediaType: string;
|
|
36
|
+
data?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface UserTurn {
|
|
39
|
+
role: 'user';
|
|
40
|
+
text?: string;
|
|
41
|
+
files?: UserFile[];
|
|
42
|
+
toolResults?: ToolResult<unknown>[];
|
|
43
|
+
}
|
|
44
|
+
export interface AssistantTurn {
|
|
45
|
+
role: 'assistant';
|
|
46
|
+
text?: string;
|
|
47
|
+
toolUses?: ToolUse<unknown, unknown>[];
|
|
48
|
+
}
|
|
49
|
+
export type Turn = UserTurn | AssistantTurn;
|
|
50
|
+
export interface UserTurnRequest {
|
|
51
|
+
accountId: string;
|
|
52
|
+
agentId: string;
|
|
53
|
+
sessionId: string;
|
|
54
|
+
actorId: string;
|
|
55
|
+
prompt?: string;
|
|
56
|
+
files?: UserFile[];
|
|
57
|
+
context?: Record<string, unknown>;
|
|
58
|
+
toolResults?: ApiToolResult[];
|
|
59
|
+
tools?: ApiTool[];
|
|
60
|
+
stream: true;
|
|
61
|
+
}
|
|
62
|
+
export interface HistoryRequest {
|
|
63
|
+
accountId: string;
|
|
64
|
+
agentId: string;
|
|
65
|
+
sessionId: string;
|
|
66
|
+
actorId: string;
|
|
67
|
+
action: 'getHistory';
|
|
68
|
+
}
|
|
69
|
+
export interface HistoryResponse {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
actorId: string;
|
|
72
|
+
turns: Turn[];
|
|
73
|
+
}
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface Bridge {
|
|
2
|
+
setActorId: ((value: string | undefined) => void) | undefined;
|
|
3
|
+
toggle: ((open: boolean) => void) | undefined;
|
|
4
|
+
sendMessage: ((prompt?: string, files?: File[]) => Promise<void>) | undefined;
|
|
5
|
+
clearChat: (() => void) | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare const bridge: Bridge;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentChildren, FunctionalComponent } from 'preact';
|
|
2
|
+
import { ToolUse, Turn } from '../api/types';
|
|
3
|
+
import { AnyTool } from '../types';
|
|
4
|
+
interface AssistantContextValue {
|
|
5
|
+
turns: Turn[];
|
|
6
|
+
tools: AnyTool[];
|
|
7
|
+
isStreaming: boolean;
|
|
8
|
+
setIsStreaming: (value: boolean) => void;
|
|
9
|
+
userClosed: boolean;
|
|
10
|
+
setUserClosed: (value: boolean) => void;
|
|
11
|
+
appendTurn: (turn: Turn) => void;
|
|
12
|
+
replaceLastTurn: (turn: Turn) => void;
|
|
13
|
+
updateLastAssistantText: (text: string) => void;
|
|
14
|
+
updateToolUse: (toolUseId: string, patch: Partial<ToolUse<unknown, unknown>>) => void;
|
|
15
|
+
clearChat: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const AssistantProvider: FunctionalComponent<{
|
|
18
|
+
children: ComponentChildren;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const useAssistant: () => AssistantContextValue;
|
|
21
|
+
export {};
|