Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 77 additions & 3 deletions docs/renderers.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,97 @@ A2UI JSON → Renderer → Native Components → Your App
npm install @a2ui/lit
```

TODO: Add a quickstart guide
##### Usage
```typescript
import { LitElement, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { v0_8 } from '@a2ui/lit';
// Import UI components registry
import '@a2ui/lit/ui';

@customElement('my-app')
export class MyApp extends LitElement {
// 1. Create a MessageProcessor
#processor = v0_8.Data.createSignalA2uiMessageProcessor();

// 2. Feed it messages (e.g., from your transport)
handleMessage(message: v0_8.Types.ServerToClientMessage) {
this.#processor.processMessages([message]);
}

render() {
// 3. Render the surfaces
return html`
${repeat(
this.#processor.getSurfaces(),
([id]) => id,
([id, surface]) => html`
<a2ui-surface
.surfaceId=${id}
.surface=${surface}
.processor=${this.#processor}
></a2ui-surface>
`
)}
`;
}
}
```

**Angular:**

```bash
npm install @a2ui/angular
```

TODO: Add a quickstart guide
##### Usage
```typescript
import { Component, inject } from '@angular/core';
import { MessageProcessor, Surface } from '@a2ui/angular';
import { Types } from '@a2ui/lit/0.8';

@Component({
selector: 'app-root',
template: `
@for (surface of processor.surfaces(); track surface.id) {
<a2ui-surface [surfaceId]="surface.id" [surface]="surface.state" />
}
`,
imports: [Surface],
standalone: true
})
export class AppComponent {
// 1. Inject the MessageProcessor
protected processor = inject(MessageProcessor);

// 2. Feed it messages
handleMessage(message: Types.ServerToClientMessage) {
this.processor.processMessages([message]);
}
}
```

**Flutter:**

```bash
flutter pub add flutter_genui
```

TODO: Add a quickstart guide
##### Usage
See the [GenUI Quickstart](https://docs.flutter.dev/ai/genui/get-started) for a complete tutorial.

```dart
// 1. Define your widgets
class MyWidgetFactory extends WidgetFactory {
// ... map A2UI types to Flutter widgets
}

// 2. Use the GenUiArea
GenUiArea(
messageStream: myMessageStream,
widgetFactory: MyWidgetFactory(),
)
```

## Adding custom components to a renderer

Expand Down
34 changes: 31 additions & 3 deletions docs/transports.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,47 @@ You can use any transport that sends JSON:
**HTTP/REST:**

```javascript
// TODO: Add an example
const response = await fetch('/api/agent', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(clientEventMessage)
});

if (response.ok) {
const serverMessages = await response.json();
// Pass messages to your A2UI renderer
processor.processMessages(serverMessages);
}
```

**WebSockets:**

```javascript
// TODO: Add an example
const socket = new WebSocket('ws://localhost:8080');

socket.addEventListener('open', () => {
socket.send(JSON.stringify(clientEventMessage));
});

socket.addEventListener('message', (event) => {
const serverMessage = JSON.parse(event.data);
// Pass individual message to your A2UI renderer
processor.processMessages([serverMessage]);
});
```

**Server-Sent Events:**

```javascript
// TODO: Add an example
const eventSource = new EventSource('/api/agent/stream');

eventSource.onmessage = (event) => {
const serverMessage = JSON.parse(event.data);
// Pass individual message to your A2UI renderer
processor.processMessages([serverMessage]);
};
```

```
Expand Down
4 changes: 2 additions & 2 deletions renderers/lit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"wireit": {
"copy-spec": {
"command": "mkdir -p src/0.8/schemas && cp ../../specification/0.8/json/*.json src/0.8/schemas",
"command": "node scripts/copy-schemas.js",
"files": [
"../../specification/0.8/json/*.json"
],
Expand Down Expand Up @@ -105,4 +105,4 @@
"markdown-it": "^14.1.0",
"signal-utils": "^0.21.1"
}
}
}
32 changes: 32 additions & 0 deletions renderers/lit/scripts/copy-schemas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const srcDir = path.resolve(__dirname, '../../../specification/0.8/json');
const destDir = path.resolve(__dirname, '../src/0.8/schemas');

console.log(`Copying schemas from ${srcDir} to ${destDir}...`);

if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}

try {
const files = fs.readdirSync(srcDir);
let count = 0;
for (const file of files) {
if (file.endsWith('.json')) {
const srcFile = path.join(srcDir, file);
const destFile = path.join(destDir, file);
fs.copyFileSync(srcFile, destFile);
count++;
}
}
console.log(`Successfully copied ${count} schema files.`);
} catch (err) {
console.error('Error copying schemas:', err);
process.exit(1);
}