@interopio/io-assist-ng 0.1.1-beta.0 → 1.0.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 CHANGED
@@ -1,6 +1,26 @@
1
1
  # @interopio/io-assist-ng
2
2
 
3
- Angular library for integrating io.Intelligence AI assistance capabilities into Angular applications (Angular 20.3+).
3
+ A full-featured AI assistant component for Angular applications. Drop a single `<io-assist>` tag into your app and get a conversational AI chat interface backed by any [AG-UI Protocol](https://docs.ag-ui.com) compatible agent server — with streaming responses, persistent threads, a prompt library, MCP tool access, working context awareness, and built-in sampling/elicitation handling.
4
+
5
+ Built on [io.Connect](https://interop.io/) and [@interopio/ai-web](https://www.npmjs.com/package/@interopio/ai-web).
6
+
7
+ ## Features
8
+
9
+ - **Conversational AI chat** — Streaming responses, markdown rendering, code highlighting
10
+ - **Persistent conversation threads** — Thread history with resume, rename, and delete
11
+ - **Prompt library** — Categorized pre-written prompts with favorites (persisted via IO Preferences)
12
+ - **MCP tool access** — Built-in io.Intelligence MCP server, extensible with remote and third-party servers
13
+ - **MCP Apps** — Custom HTML applications rendered inline in chat or in io.Connect workspace windows
14
+ - **Sampling & elicitation** — Built-in confirmation/input UI for MCP server requests (replaceable with custom handlers)
15
+ - **Working context** — Live data from io.Connect contexts passed to the agent with every message
16
+ - **Theming** — Automatic dark/light mode sync with io.Connect
17
+
18
+ ## Prerequisites
19
+
20
+ - **Angular** 20.3+
21
+ - **Node.js** 20.19+ (< 22)
22
+ - **npm** 10+
23
+ - An **AG-UI Protocol compatible agent server** (e.g. [Mastra](https://mastra.ai/))
4
24
 
5
25
  ## Installation
6
26
 
@@ -8,211 +28,610 @@ Angular library for integrating io.Intelligence AI assistance capabilities into
8
28
  npm install @interopio/io-assist-ng
9
29
  ```
10
30
 
11
- ## Prerequisites
31
+ **Install at least one platform package** — you always need to import and pass the factory in your `connectConfig`:
32
+
33
+ ```bash
34
+ # For io.Connect Browser (most common)
35
+ npm install @interopio/browser
36
+
37
+ # For io.Connect Desktop
38
+ npm install @interopio/desktop
39
+
40
+ # For both (if your app supports both environments)
41
+ npm install @interopio/browser @interopio/desktop
42
+ ```
43
+
44
+ The following packages are bundled as `dependencies` and are installed automatically:
45
+
46
+ > `zod`, `ngx-remark`, `remark-gfm`, `remark-parse`, `unified`, `@interopio/ai-web`, `@interopio/ng`, `@interopio/working-context`, `@ngrx/store`, `@ngrx/effects`, `@ngrx/store-devtools`, `rxjs`
47
+
48
+ The following are `peerDependencies` and must be present in your project. They are usually already installed in any Angular 20+ project:
49
+
50
+ ```bash
51
+ npm install @angular/cdk @angular/common @angular/core @angular/forms @angular/platform-browser
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Agent Server
57
+
58
+ io.Assist requires an **AG-UI Protocol compatible agent server** to handle chat requests. The recommended way to get started is with [Mastra](https://mastra.ai/).
59
+
60
+ ### Quick setup with Mastra
61
+
62
+ ```bash
63
+ npx create-mastra@latest
64
+ ```
65
+
66
+ This scaffolds a fully working Mastra project. Follow the prompts, then start the server:
67
+
68
+ ```bash
69
+ npm run dev
70
+ ```
71
+
72
+ By default the server runs on `http://localhost:4111` — the same URL used in the Quickstart examples below.
73
+
74
+ **Required environment variables:**
75
+
76
+ ```env
77
+ # At least one LLM provider key
78
+ OPENAI_API_KEY=your-key
79
+ ANTHROPIC_API_KEY=your-key
80
+ ```
81
+
82
+ > For full Mastra documentation — including custom agents, tools, memory, and deployment — see [mastra.ai/docs](https://mastra.ai/docs).
83
+
84
+ ## Quickstart
12
85
 
13
- - Angular 20.3 or higher
14
- - Node.js 20.19+ (< 22)
15
- - npm 10.0.0 or higher
86
+ ### New Angular project
16
87
 
17
- ## Setup
88
+ If you don't have an Angular project yet, create one first:
18
89
 
19
- ### 1. Import Styles
90
+ ```bash
91
+ npm install -g @angular/cli
92
+ ng new my-app
93
+ cd my-app
94
+ npm install @interopio/io-assist-ng @interopio/browser
95
+ ```
20
96
 
21
- Add the library styles to your Angular application:
97
+ > See the full Angular setup guide at [angular.dev/installation](https://angular.dev/installation).
98
+
99
+ ### Existing Angular project
100
+
101
+ ```bash
102
+ npm install @interopio/io-assist-ng @interopio/browser
103
+ ```
104
+
105
+ ---
106
+
107
+ ### 1. Add the stylesheet
108
+
109
+ ```css title="src/styles.css"
110
+ @import "@interopio/io-assist-ng/styles.css";
111
+ ```
112
+
113
+ Or in `angular.json`:
22
114
 
23
- **Option A: In `angular.json`**
24
115
  ```json
25
- {
26
- "projects": {
27
- "your-app": {
28
- "architect": {
29
- "build": {
30
- "options": {
31
- "styles": [
32
- "node_modules/@interopio/io-assist-ng/styles.css",
33
- "src/styles.css"
34
- ]
35
- }
36
- }
37
- }
38
- }
39
- }
40
- }
116
+ "styles": [
117
+ "node_modules/@interopio/io-assist-ng/styles.css",
118
+ "src/styles.css"
119
+ ]
41
120
  ```
42
121
 
43
- **Option B: In `styles.css`/`styles.scss`**
44
- ```css
45
- @import '@interopio/io-assist-ng/styles.css';
122
+ ### 2. Configure providers
123
+
124
+ ```typescript title="src/app/app.config.ts"
125
+ import { ApplicationConfig } from '@angular/core';
126
+ import { provideIoAssist } from '@interopio/io-assist-ng';
127
+ import IOBrowser from '@interopio/browser';
128
+
129
+ export const appConfig: ApplicationConfig = {
130
+ providers: [
131
+ provideIoAssist({
132
+ connectConfig: {
133
+ browser: {
134
+ factory: IOBrowser,
135
+ },
136
+ },
137
+ aiWebConfig: {
138
+ agentServer: {
139
+ baseUrl: 'http://localhost:4111',
140
+ },
141
+ },
142
+ }),
143
+ ],
144
+ };
46
145
  ```
47
146
 
48
- ### 2. Import Components
147
+ ### 3. Add the component
49
148
 
50
- Import the components you need in your Angular component:
149
+ The component requires a `[config]` input with the current user's identity. Pass a signal so the assistant can react to auth state changes:
51
150
 
52
- ```typescript
53
- import { Component } from '@angular/core';
54
- import { IoAssist } from '@interopio/io-assist-ng';
151
+ ```typescript title="src/app/app.component.ts"
152
+ import { Component, signal } from '@angular/core';
153
+ import { IoAssist, IoAssistDynamicConfig } from '@interopio/io-assist-ng';
55
154
 
56
155
  @Component({
57
- selector: 'app-root',
58
- standalone: true,
59
- imports: [IoAssist],
60
- template: `
61
- <io-assist [config]="assistConfig"></io-assist>
62
- `
156
+ selector: 'app-root',
157
+ imports: [IoAssist],
158
+ template: `<io-assist [config]="dynamicConfig()" />`,
63
159
  })
64
160
  export class AppComponent {
65
- assistConfig = {
66
- // Your configuration here
67
- };
161
+ readonly dynamicConfig = signal<IoAssistDynamicConfig>({
162
+ // id: Your access/auth token of choice
163
+ // name: UI name tha will be displayed
164
+ user: { id: 'yourIdOfChoice', name: 'Jane Doe' },
165
+ agentServer: {
166
+ headers: {
167
+ Authorization: `Bearer ${import.meta.env.VITE_AUTH_TOKEN}`,
168
+ }
169
+ },
170
+ });
68
171
  }
69
172
  ```
70
173
 
71
- ## Configuration
72
-
73
- The `IoAssist` component accepts a configuration object via the `[config]` input:
74
-
75
- ```typescript
76
- import { IoAssistTempConfig } from '@interopio/io-assist-ng';
174
+ ### 4. Run
77
175
 
78
- const assistConfig: IoAssistTempConfig = {
79
- // Configuration options
80
- apiEndpoint: 'https://your-api-endpoint.com',
81
- theme: 'light', // or 'dark'
82
- // Add other configuration options as needed
83
- };
176
+ ```bash
177
+ ng serve
84
178
  ```
85
179
 
86
- ## Components
180
+ Open http://localhost:4200. **io.Assist is live.**
87
181
 
88
- ### IoAssist
182
+ ---
89
183
 
90
- Main component for AI assistance functionality.
184
+ ### Quickstart with Login
91
185
 
92
- **Usage:**
93
- ```html
94
- <io-assist
95
- [config]="assistConfig"
96
- ></io-assist>
97
- ```
186
+ This pattern shows how to pair io.Assist with a login flow — the user's identity is only passed to the assistant after authentication.
98
187
 
99
- **Inputs:**
100
- - `config: IoAssistTempConfig` - Configuration object for the assistant
188
+ Follow steps 1–2 from the basic quickstart, then:
101
189
 
102
- ## Styling
190
+ **Login service**
103
191
 
104
- The library uses TailwindCSS for styling. The styles are pre-compiled and included in the distribution.
192
+ ```typescript title="src/app/auth/auth.service.ts"
193
+ import { Injectable, signal } from '@angular/core';
105
194
 
106
- ### Custom Theming
195
+ @Injectable({ providedIn: 'root' })
196
+ export class AuthService {
197
+ private readonly _userId = signal<string>('');
198
+ readonly userId = this._userId.asReadonly();
107
199
 
108
- To customize the appearance, override CSS variables in your application:
200
+ login(userId: string, password: string): boolean {
201
+ // Replace with your own authentication logic
202
+ const isValid = password === 'secret';
203
+ if (isValid) this._userId.set(userId);
204
+ return isValid;
205
+ }
109
206
 
110
- ```css
111
- :root {
112
- --io-assist-primary-color: #your-color;
113
- --io-assist-background: #your-background;
114
- /* Add other custom variables */
207
+ logout(): void {
208
+ this._userId.set('');
209
+ }
115
210
  }
116
211
  ```
117
212
 
118
- ## Examples
213
+ **Login component**
119
214
 
120
- ### Basic Integration
215
+ ```typescript title="src/app/login/login.component.ts"
216
+ import { Component, inject, signal } from '@angular/core';
217
+ import { Router } from '@angular/router';
218
+ import { AuthService } from '../auth/auth.service';
121
219
 
122
- ```typescript
123
- import { Component } from '@angular/core';
124
- import { IoAssist, IoAssistTempConfig } from '@interopio/io-assist-ng';
220
+ @Component({
221
+ selector: 'app-login',
222
+ template: `
223
+ <input [value]="username()" (input)="username.set($any($event.target).value)" placeholder="Username" />
224
+ <input [value]="password()" (input)="password.set($any($event.target).value)" type="password" placeholder="Password" />
225
+ <button (click)="submit()">Sign in</button>
226
+ `,
227
+ })
228
+ export class LoginComponent {
229
+ private readonly _auth = inject(AuthService);
230
+ private readonly _router = inject(Router);
231
+
232
+ protected readonly username = signal('');
233
+ protected readonly password = signal('');
234
+
235
+ protected submit(): void {
236
+ const success = this._auth.login(this.username(), this.password());
237
+ if (success) this._router.navigate(['/assistant']);
238
+ }
239
+ }
240
+ ```
241
+
242
+ **Assistant component** — pass the user identity as `[config]`
243
+
244
+ ```typescript title="src/app/assistant/assistant.component.ts"
245
+ import { Component, computed, inject } from '@angular/core';
246
+ import { IoAssist, IoAssistDynamicConfig } from '@interopio/io-assist-ng';
247
+ import { AuthService } from '../auth/auth.service';
125
248
 
126
249
  @Component({
127
- selector: 'app-dashboard',
128
- standalone: true,
129
- imports: [IoAssist],
130
- template: `
131
- <div class="dashboard">
132
- <h1>My Dashboard</h1>
133
- <io-assist [config]="config"></io-assist>
134
- </div>
135
- `
250
+ selector: 'app-assistant',
251
+ imports: [IoAssist],
252
+ template: `<io-assist [config]="dynamicConfig()" />`,
136
253
  })
137
- export class DashboardComponent {
138
- config: IoAssistTempConfig = {
139
- apiEndpoint: 'https://api.example.com/assist',
140
- theme: 'light'
141
- };
254
+ export class AssistantComponent {
255
+ private readonly _auth = inject(AuthService);
256
+
257
+ protected readonly dynamicConfig = computed<IoAssistDynamicConfig>(() => ({
258
+ user: { id: this._auth.userId() },
259
+ }));
142
260
  }
143
261
  ```
144
262
 
145
- ## Browser Support
263
+ Once the user logs in, `dynamicConfig` updates and io.Assist loads threads scoped to that user.
264
+
265
+ ---
266
+
267
+ ### What you get with the minimal config
146
268
 
147
- - Chrome/Edge (latest 2 versions)
148
- - Firefox (latest 2 versions)
149
- - Safari (latest 2 versions)
269
+ With just the three required fields (`user`, `connectConfig`, `aiWebConfig.agentServer`), io.Assist provides:
150
270
 
151
- ## Dependencies
271
+ - Full conversational AI chat with streaming markdown responses
272
+ - Persistent conversation threads (scoped to `user.id`)
273
+ - Automatic agent selection (first available agent from your server)
274
+ - Built-in sampling and elicitation UI panels (confirmation dialogs when MCP servers request them)
275
+ - Built-in io.Intelligence MCP server connection (local mode)
276
+ - Dark/light theme sync with io.Connect
277
+ - Auto-injected fonts and syntax highlighting
152
278
 
153
- This library has peer dependencies on:
154
- - `@angular/core`: ^20.3.0
155
- - `@angular/common`: ^20.3.0
156
- - `@interopio/intel-web`: Latest
279
+ No prompts, no working context, and no MCP Apps — those require additional configuration below.
280
+
281
+ ---
282
+
283
+ ## Configuration
157
284
 
158
- These will be automatically installed with npm 7+.
285
+ io.Assist uses two separate configuration objects:
159
286
 
160
- ## TypeScript Support
287
+ - **`IoAssistStaticConfig`** — passed to `provideIoAssist()` at application bootstrap. Contains infrastructure settings that don't change at runtime.
288
+ - **`IoAssistDynamicConfig`** — passed as `[config]` input to `<io-assist>` in your template. Contains the active user's identity, which may only be known after login.
161
289
 
162
- Full TypeScript support with type definitions included.
290
+ ### Static configuration (`IoAssistStaticConfig`)
291
+
292
+ Passed to `provideIoAssist()`. Validated at bootstrap with Zod — throws if invalid.
293
+
294
+ **Required fields**
295
+
296
+ | Field | Type | Description |
297
+ |-------|------|-------------|
298
+ | `connectConfig` | `IOConnectNgSettings` | io.Connect platform settings. Must include `browser` or `desktop`. |
299
+ | `aiWebConfig.agentServer.baseUrl` | `string` | Base URL of your AG-UI compatible agent server. |
300
+
301
+ **Optional fields**
302
+
303
+ | Field | Type | Description |
304
+ |-------|------|-------------|
305
+ | `aiWebConfig.agentServer.retries` | `number` | Number of retry attempts on failure. |
306
+ | `aiWebConfig.agentServer.backoffMs` | `number` | Initial backoff delay in milliseconds. |
307
+ | `aiWebConfig.agentServer.maxBackoffMs` | `number` | Maximum backoff delay. |
308
+ | `aiWebConfig.agentServer.credentials` | `'omit' \| 'same-origin' \| 'include'` | Fetch credentials mode. |
309
+ | `aiWebConfig.mcp` | `object` | MCP configuration — remote servers, MCP Apps, sampling/elicitation overrides. |
310
+ | `defaultAgentName` | `string` | Agent to select on startup. Falls back to first available if not found. |
311
+ | `defaultPrompts` | `IoAssistPromptCategory[]` | Categorized prompt library entries. |
312
+ | `workingContext` | `object` | Live context collection from io.Connect. |
313
+
314
+ ### Dynamic configuration (`IoAssistDynamicConfig`)
315
+
316
+ Passed as `[config]` input to `<io-assist>` in your template. Validated in `ngOnInit` with Zod — throws `ZodError` if invalid. Typically computed from your authentication state:
163
317
 
164
318
  ```typescript
165
- import type { IoAssistTempConfig, IoAssistResponse } from '@interopio/io-assist-ng';
319
+ protected readonly dynamicConfig = computed<IoAssistDynamicConfig>(() => ({
320
+ user: { id: this._auth.userId(), name: this._auth.displayName() },
321
+ }));
322
+ ```
323
+
324
+ ```html
325
+ <io-assist [config]="dynamicConfig()" />
166
326
  ```
167
327
 
168
- ## Troubleshooting
328
+ | Field | Type | Description |
329
+ |-------|------|-------------|
330
+ | `user.id` | `string` | **Required.** Unique user identifier. Scopes conversation threads — each user sees only their own threads. |
331
+ | `user.name` | `string?` | Display name shown in the chat UI and thread history. |
332
+ | `agentServer.headers` | `Record<string, string>?` | Request headers sent with every agent call. Use for auth tokens or per-user context. |
169
333
 
170
- ### Styles Not Loading
334
+ ---
171
335
 
172
- Ensure you've imported the styles in `angular.json` or your main stylesheet:
173
- ```json
174
- "styles": [
175
- "node_modules/@interopio/io-assist-ng/styles.css"
176
- ]
336
+ ## Configuration Examples
337
+
338
+ ### Standard — with prompts and named agent
339
+
340
+ ```typescript title="app.config.ts"
341
+ import { ApplicationConfig } from '@angular/core';
342
+ import { provideIoAssist } from '@interopio/io-assist-ng';
343
+ import IOBrowser from '@interopio/browser';
344
+
345
+ export const appConfig: ApplicationConfig = {
346
+ providers: [
347
+ provideIoAssist({
348
+ connectConfig: {
349
+ browser: { factory: IOBrowser },
350
+ },
351
+ aiWebConfig: {
352
+ agentServer: {
353
+ baseUrl: 'http://localhost:4111',
354
+ },
355
+ },
356
+ defaultAgentName: 'my-agent',
357
+ defaultPrompts: [
358
+ {
359
+ category: 'General',
360
+ prompts: [
361
+ { name: 'Summarize', prompt: 'Please summarize the following content:' },
362
+ { name: 'Explain', prompt: 'Please explain this in simple terms:' },
363
+ ],
364
+ },
365
+ {
366
+ category: 'Code',
367
+ prompts: [
368
+ { name: 'Review Code', prompt: 'Please review this code and suggest improvements:' },
369
+ {
370
+ name: 'Add Comments',
371
+ prompt: 'Annotate this code with detailed comments:',
372
+ iconResource: {
373
+ type: 'svg',
374
+ data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="..."/></svg>',
375
+ },
376
+ },
377
+ ],
378
+ },
379
+ ],
380
+ }),
381
+ ],
382
+ };
177
383
  ```
178
384
 
179
- ### Component Not Found
180
-
181
- Make sure you've imported the component in your standalone component or module:
182
- ```typescript
183
- imports: [IoAssist]
385
+ **What this adds over minimal:**
386
+
387
+ - **Named agent** pre-selected at startup
388
+ - **Prompt library** with two categories — users can browse, search, and favorite prompts
389
+
390
+ ### Advanced — custom handlers, MCP Apps, working context
391
+
392
+ ```typescript title="app.config.ts"
393
+ import { ApplicationConfig } from '@angular/core';
394
+ import { provideIoAssist } from '@interopio/io-assist-ng';
395
+ import { IoAiWeb } from '@interopio/ai-web';
396
+ import IOBrowser from '@interopio/browser';
397
+ import { IoIntelWorkingContextFactory, IoIntelWorkingContext } from '@interopio/working-context';
398
+
399
+ export const appConfig: ApplicationConfig = {
400
+ providers: [
401
+ provideIoAssist({
402
+ connectConfig: {
403
+ browser: { factory: IOBrowser },
404
+ },
405
+ aiWebConfig: {
406
+ agentServer: {
407
+ baseUrl: 'http://localhost:4111',
408
+ },
409
+ mcp: {
410
+ // Custom sampling handler — replaces the built-in confirmation panel
411
+ clientsConfig: {
412
+ enforceStrictCapabilities: false,
413
+ capabilities: {
414
+ sampling: {
415
+ handler: async (
416
+ serverId: string,
417
+ params: IoAiWeb.SamplingRequestParams,
418
+ ): Promise<IoAiWeb.SamplingSuccessResponse> => {
419
+ // Your custom logic — show your own UI, call your own APIs, etc.
420
+ return {
421
+ model: 'gpt-4',
422
+ role: 'assistant',
423
+ content: { type: 'text', text: 'Custom sampling response' },
424
+ stopReason: 'endTurn',
425
+ };
426
+ },
427
+ },
428
+ elicitation: {
429
+ handler: async (
430
+ serverId: string,
431
+ params: IoAiWeb.ElicitationRequestParams,
432
+ ): Promise<IoAiWeb.ElicitationResponse> => {
433
+ // Your custom logic — build a form, collect user input, etc.
434
+ return { action: 'accept', content: { confirmed: true } };
435
+ },
436
+ },
437
+ // Required for MCP Apps
438
+ extensions: {
439
+ 'io.modelcontextprotocol/ui': {
440
+ mimeTypes: ['text/html;profile=mcp-app'],
441
+ },
442
+ },
443
+ },
444
+ },
445
+ // MCP Apps — interactive UI panels in chat or workspace windows
446
+ mcpApps: {
447
+ sandboxProxyUrl: 'http://localhost:6565/index.html',
448
+ displayMode: 'workspace', // or 'inline'
449
+ },
450
+ // Remote MCP servers
451
+ ioIntel: {
452
+ remote: {
453
+ streamableHttp: {
454
+ url: 'http://localhost:8989/mcp',
455
+ name: 'remote-io-mcp-server',
456
+ },
457
+ },
458
+ },
459
+ remoteServers: [
460
+ {
461
+ streamableHttp: {
462
+ url: 'http://localhost:8081/mcp',
463
+ name: 'third-party-server',
464
+ },
465
+ },
466
+ ],
467
+ },
468
+ },
469
+ defaultAgentName: 'my-agent',
470
+ defaultPrompts: [
471
+ {
472
+ category: 'General',
473
+ prompts: [
474
+ { name: 'Summarize', prompt: 'Please summarize the following content:' },
475
+ ],
476
+ },
477
+ ],
478
+ workingContext: {
479
+ factory: IoIntelWorkingContextFactory,
480
+ config: {
481
+ schema: {
482
+ userId: {
483
+ type: 'string',
484
+ description: "Current user's identifier",
485
+ source: {
486
+ context: {
487
+ location: { global: { names: ['UserSession'] } },
488
+ path: 'user.id',
489
+ },
490
+ },
491
+ },
492
+ selectedClient: {
493
+ type: 'string',
494
+ description: 'Client currently selected in the workspace',
495
+ source: {
496
+ context: {
497
+ location: { workspace: {} },
498
+ path: 'client.name',
499
+ },
500
+ },
501
+ },
502
+ },
503
+ } as IoIntelWorkingContext.Config,
504
+ },
505
+ }),
506
+ ],
507
+ };
184
508
  ```
185
509
 
186
- ### Type Errors
510
+ **What this adds over standard:**
187
511
 
188
- Ensure your TypeScript version is 5.0 or higher and `strict` mode is enabled in `tsconfig.json`.
512
+ - **Custom sampling handler** replaces the built-in confirmation panel. When an MCP server makes a sampling request, your handler runs instead.
513
+ - **Custom elicitation handler** — replaces the built-in elicitation panel. When an MCP server requests user input, your handler runs instead.
514
+ - **MCP Apps** — interactive HTML panels that MCP tools can render inline in chat or in io.Connect workspace windows. Requires both `mcpApps` config and the `io.modelcontextprotocol/ui` extension.
515
+ - **Remote MCP servers** — switch io.Intelligence MCP to a remote endpoint and/or add third-party MCP servers.
516
+ - **Working context** — io.Assist reads live data from io.Connect contexts and passes it to the agent with every message.
189
517
 
190
- ## Development
518
+ > **Component usage:** In all examples above, pair `provideIoAssist()` with `<io-assist [config]="dynamicConfig()" />` in your template. Refer to the [Quickstart with Login](#quickstart-with-login) section for a full component example.
191
519
 
192
- This library is built with:
193
- - Angular 20.3
194
- - TailwindCSS 4.1
195
- - TypeScript 5.x
520
+ ---
196
521
 
197
- ## Support
522
+ ## MCP Apps
198
523
 
199
- For issues, questions, or contributions, please visit:
200
- - GitHub: [io.Intelligence JS Repository]
201
- - Documentation: [Coming Soon]
202
- - Issues: [GitHub Issues]
524
+ MCP Apps are fully interactive UI applications that MCP tools can display directly inside the assistant. Instead of returning only text, a tool can ship a complete HTML application that the user interacts with in context.
203
525
 
204
- ## License
526
+ **Requirements** — two config sections must both be present:
527
+
528
+ 1. **`mcpApps`** — enables the MCP Apps runtime:
529
+ ```typescript
530
+ mcpApps: {
531
+ sandboxProxyUrl: 'http://localhost:6565/index.html',
532
+ displayMode: 'workspace', // 'workspace' | 'inline' (optional, auto-detects if omitted)
533
+ },
534
+ ```
535
+
536
+ 2. **`extensions`** — tells MCP servers that this client supports UI:
537
+ ```typescript
538
+ capabilities: {
539
+ extensions: {
540
+ 'io.modelcontextprotocol/ui': {
541
+ mimeTypes: ['text/html;profile=mcp-app'],
542
+ },
543
+ },
544
+ },
545
+ ```
546
+
547
+ Without both, MCP servers will not expose UI metadata on tool definitions and no apps will be created.
548
+
549
+ **Display modes:**
550
+
551
+ | Mode | Behavior |
552
+ |------|----------|
553
+ | `'inline'` | App renders inside the chat message flow |
554
+ | `'workspace'` | App opens in a separate io.Connect workspace window (falls back to inline if workspaces unavailable) |
555
+
556
+ **Sandbox proxy** — MCP Apps run inside a sandboxed iframe. The `sandboxProxyUrl` points to an HTML file that bridges communication between the host and the app. This proxy page must be served alongside your application.
557
+
558
+ ---
559
+
560
+ ## Sampling & Elicitation
561
+
562
+ When an MCP server sends a sampling or elicitation request:
563
+
564
+ | Scenario | Behavior |
565
+ |----------|----------|
566
+ | **No custom handler** | io.Assist shows a built-in confirmation panel (uses io.Connect modal if available, otherwise an overlay panel) |
567
+ | **Custom handler provided** | Your handler function runs instead — full control over UI and response |
568
+ | **Request from background thread** | Automatically rejected (user must be on the active thread) |
569
+
570
+ **Sampling** — the MCP server asks the client to generate a model response. The built-in handler shows a "Permission to proceed" dialog. On accept, it calls your agent server and returns the result.
205
571
 
206
- ISC License
572
+ **Elicitation** — the MCP server asks the client to collect user input via a form schema. The built-in handler presents accept/decline options.
207
573
 
208
- ## Changelog
574
+ See the advanced configuration example above for custom handler signatures.
209
575
 
210
- ### 0.0.0 (Initial Release)
211
- - Initial release with core `IoAssist` component
212
- - TailwindCSS styling support
213
- - TypeScript type definitions
214
- - Angular 20.3 compatibility
576
+ ---
577
+
578
+ ## Public API
579
+
580
+ ```typescript
581
+ import { IoAssist, provideIoAssist } from '@interopio/io-assist-ng';
582
+ import type {
583
+ IoAssistStaticConfig,
584
+ IoAssistDynamicConfig,
585
+ AIWebConfig,
586
+ IoAssistUserConfig,
587
+ IO_ASSIST_CONFIG,
588
+ IO_ASSIST_DYNAMIC_CONFIG,
589
+ IoAssistPrompt,
590
+ IoAssistPromptCategory,
591
+ IconResource,
592
+ IconType,
593
+ } from '@interopio/io-assist-ng';
594
+ ```
595
+
596
+ | Export | Kind | Description |
597
+ |--------|------|-------------|
598
+ | `IoAssist` | Component | The `<io-assist>` root component. Requires `[config]` input. |
599
+ | `provideIoAssist(config)` | Function | Registers all providers — call once in `app.config.ts` |
600
+ | `IoAssistStaticConfig` | Type | Static configuration shape passed to `provideIoAssist()` |
601
+ | `IoAssistDynamicConfig` | Type | Runtime configuration shape passed as `[config]` to `<io-assist>` |
602
+ | `AIWebConfig` | Type | Agent server + MCP config shape |
603
+ | `IoAssistUserConfig` | Type | `{ id: string; name?: string }` |
604
+ | `IO_ASSIST_CONFIG` | InjectionToken | DI token for the validated static config |
605
+ | `IO_ASSIST_DYNAMIC_CONFIG` | InjectionToken | DI token for the `WritableSignal<IoAssistDynamicConfig>` (internal use) |
606
+ | `IoAssistPrompt` | Type | Single prompt definition |
607
+ | `IoAssistPromptCategory` | Type | Category with array of prompts |
608
+ | `IconResource` | Type | `{ type: IconType; data: string }` |
609
+ | `IconType` | Type | `'svg' \| 'url' \| 'data-url'` |
610
+
611
+ ---
612
+
613
+ ## Prompt Icons
614
+
615
+ Each prompt can have an optional `iconResource`. Three formats are supported:
616
+
617
+ | Type | Example | Notes |
618
+ |------|---------|-------|
619
+ | `'svg'` | `'<svg xmlns="..." viewBox="0 0 24 24">...</svg>'` | Auto-sanitized: `fill`, `width`, `height` stripped; hardcoded colors → `currentColor` |
620
+ | `'url'` | `'/icons/summarize.svg'` | Must be an absolute URL or absolute path from document root |
621
+ | `'data-url'` | `'data:image/svg+xml;base64,...'` | Base64-encoded SVG, PNG, or JPEG |
622
+
623
+ Prompts without an icon show a default icon.
215
624
 
216
625
  ---
217
626
 
218
- **Note:** This library is currently in development. API and features may change before the stable 1.0.0 release.
627
+ ## Related Packages
628
+
629
+ - [@interopio/ai-web](https://www.npmjs.com/package/@interopio/ai-web) — Core intelligence library
630
+ - [@interopio/ng](https://www.npmjs.com/package/@interopio/ng) — io.Connect Angular integration
631
+ - [@interopio/browser](https://www.npmjs.com/package/@interopio/browser) — io.Connect Browser platform
632
+ - [@interopio/desktop](https://www.npmjs.com/package/@interopio/desktop) — io.Connect Desktop platform
633
+ - [@interopio/working-context](https://www.npmjs.com/package/@interopio/working-context) — Working context collection
634
+
635
+ ## License
636
+
637
+ [MIT](./LICENSE)