@ably/ai-transport 0.0.1 → 0.1.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 +54 -47
- package/dist/ably-ai-transport.js +1006 -539
- package/dist/ably-ai-transport.js.map +1 -1
- package/dist/ably-ai-transport.umd.cjs +1 -1
- package/dist/ably-ai-transport.umd.cjs.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/core/codec/types.d.ts +19 -2
- package/dist/core/transport/decode-history.d.ts +8 -6
- package/dist/core/transport/headers.d.ts +4 -2
- package/dist/core/transport/index.d.ts +4 -1
- package/dist/core/transport/pipe-stream.d.ts +3 -2
- package/dist/core/transport/stream-router.d.ts +11 -1
- package/dist/core/transport/tree.d.ts +171 -0
- package/dist/core/transport/turn-manager.d.ts +4 -1
- package/dist/core/transport/types.d.ts +270 -119
- package/dist/core/transport/view.d.ts +166 -0
- package/dist/errors.d.ts +19 -2
- package/dist/index.d.ts +3 -1
- package/dist/react/ably-ai-transport-react.js +1019 -486
- package/dist/react/ably-ai-transport-react.js.map +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
- package/dist/react/contexts/transport-context.d.ts +31 -0
- package/dist/react/contexts/transport-provider.d.ts +49 -0
- package/dist/react/create-transport-hooks.d.ts +124 -0
- package/dist/react/index.d.ts +14 -8
- package/dist/react/use-ably-messages.d.ts +14 -8
- package/dist/react/use-active-turns.d.ts +7 -3
- package/dist/react/use-client-transport.d.ts +78 -5
- package/dist/react/use-create-view.d.ts +22 -0
- package/dist/react/use-tree.d.ts +20 -0
- package/dist/react/use-view.d.ts +79 -0
- package/dist/vercel/ably-ai-transport-vercel.js +1478 -842
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
- package/dist/vercel/codec/tool-transitions.d.ts +50 -0
- package/dist/vercel/index.d.ts +3 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +9099 -852
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +45 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
- package/dist/vercel/react/contexts/chat-transport-context.d.ts +32 -0
- package/dist/vercel/react/contexts/chat-transport-provider.d.ts +84 -0
- package/dist/vercel/react/index.d.ts +5 -0
- package/dist/vercel/react/use-chat-transport.d.ts +61 -20
- package/dist/vercel/react/use-message-sync.d.ts +41 -9
- package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +30 -0
- package/dist/vercel/tool-approvals.d.ts +124 -0
- package/dist/vercel/tool-events.d.ts +26 -0
- package/dist/vercel/transport/chat-transport.d.ts +33 -11
- package/dist/vercel/transport/index.d.ts +5 -2
- package/package.json +23 -17
- package/src/constants.ts +6 -0
- package/src/core/codec/encoder.ts +10 -1
- package/src/core/codec/types.ts +19 -3
- package/src/core/transport/client-transport.ts +382 -364
- package/src/core/transport/decode-history.ts +229 -81
- package/src/core/transport/headers.ts +6 -2
- package/src/core/transport/index.ts +13 -5
- package/src/core/transport/pipe-stream.ts +8 -5
- package/src/core/transport/server-transport.ts +212 -58
- package/src/core/transport/stream-router.ts +21 -3
- package/src/core/transport/{conversation-tree.ts → tree.ts} +192 -77
- package/src/core/transport/turn-manager.ts +28 -10
- package/src/core/transport/types.ts +318 -139
- package/src/core/transport/view.ts +840 -0
- package/src/errors.ts +21 -1
- package/src/index.ts +10 -5
- package/src/react/contexts/transport-context.ts +37 -0
- package/src/react/contexts/transport-provider.tsx +164 -0
- package/src/react/create-transport-hooks.ts +144 -0
- package/src/react/index.ts +15 -8
- package/src/react/use-ably-messages.ts +34 -16
- package/src/react/use-active-turns.ts +28 -17
- package/src/react/use-client-transport.ts +184 -24
- package/src/react/use-create-view.ts +68 -0
- package/src/react/use-tree.ts +53 -0
- package/src/react/use-view.ts +233 -0
- package/src/react/vite.config.ts +4 -1
- package/src/vercel/codec/accumulator.ts +64 -79
- package/src/vercel/codec/decoder.ts +11 -8
- package/src/vercel/codec/encoder.ts +68 -54
- package/src/vercel/codec/index.ts +0 -2
- package/src/vercel/codec/tool-transitions.ts +122 -0
- package/src/vercel/index.ts +17 -0
- package/src/vercel/react/contexts/chat-transport-context.ts +40 -0
- package/src/vercel/react/contexts/chat-transport-provider.tsx +122 -0
- package/src/vercel/react/index.ts +14 -0
- package/src/vercel/react/use-chat-transport.ts +164 -42
- package/src/vercel/react/use-message-sync.ts +77 -19
- package/src/vercel/react/use-staged-add-tool-approval-response.ts +87 -0
- package/src/vercel/react/vite.config.ts +4 -2
- package/src/vercel/tool-approvals.ts +380 -0
- package/src/vercel/tool-events.ts +53 -0
- package/src/vercel/transport/chat-transport.ts +225 -79
- package/src/vercel/transport/index.ts +14 -3
- package/dist/core/transport/conversation-tree.d.ts +0 -9
- package/dist/react/use-conversation-tree.d.ts +0 -20
- package/dist/react/use-edit.d.ts +0 -7
- package/dist/react/use-history.d.ts +0 -19
- package/dist/react/use-messages.d.ts +0 -7
- package/dist/react/use-regenerate.d.ts +0 -7
- package/dist/react/use-send.d.ts +0 -7
- package/src/react/use-conversation-tree.ts +0 -71
- package/src/react/use-edit.ts +0 -24
- package/src/react/use-history.ts +0 -111
- package/src/react/use-messages.ts +0 -32
- package/src/react/use-regenerate.ts +0 -24
- package/src/react/use-send.ts +0 -25
package/README.md
CHANGED
|
@@ -89,14 +89,14 @@ import type { UIMessage } from 'ai';
|
|
|
89
89
|
import { anthropic } from '@ai-sdk/anthropic';
|
|
90
90
|
import Ably from 'ably';
|
|
91
91
|
import { createServerTransport } from '@ably/ai-transport/vercel';
|
|
92
|
-
import type {
|
|
92
|
+
import type { TreeNode } from '@ably/ai-transport';
|
|
93
93
|
|
|
94
94
|
interface ChatRequestBody {
|
|
95
95
|
turnId: string;
|
|
96
96
|
clientId: string;
|
|
97
|
-
messages:
|
|
98
|
-
history?:
|
|
99
|
-
|
|
97
|
+
messages: TreeNode<UIMessage>[];
|
|
98
|
+
history?: TreeNode<UIMessage>[];
|
|
99
|
+
chatId: string;
|
|
100
100
|
forkOf?: string;
|
|
101
101
|
parent?: string | null;
|
|
102
102
|
}
|
|
@@ -104,9 +104,9 @@ interface ChatRequestBody {
|
|
|
104
104
|
const ably = new Ably.Realtime({ key: process.env.ABLY_API_KEY });
|
|
105
105
|
|
|
106
106
|
export async function POST(req: Request) {
|
|
107
|
-
const { messages, history,
|
|
107
|
+
const { messages, history, chatId, turnId, clientId, forkOf, parent } = (await req.json()) as ChatRequestBody;
|
|
108
108
|
|
|
109
|
-
const channel = ably.channels.get(
|
|
109
|
+
const channel = ably.channels.get(chatId);
|
|
110
110
|
const transport = createServerTransport({ channel });
|
|
111
111
|
const turn = transport.newTurn({ turnId, clientId, parent, forkOf });
|
|
112
112
|
|
|
@@ -120,7 +120,7 @@ export async function POST(req: Request) {
|
|
|
120
120
|
const newMsgs = messages.map((m) => m.message);
|
|
121
121
|
|
|
122
122
|
const result = streamText({
|
|
123
|
-
model: anthropic('claude-sonnet-4-
|
|
123
|
+
model: anthropic('claude-sonnet-4-6'),
|
|
124
124
|
system: 'You are a helpful assistant.',
|
|
125
125
|
messages: await convertToModelMessages([...historyMsgs, ...newMsgs]),
|
|
126
126
|
abortSignal: turn.abortSignal,
|
|
@@ -143,26 +143,26 @@ export async function POST(req: Request) {
|
|
|
143
143
|
'use client';
|
|
144
144
|
|
|
145
145
|
import { useChat } from '@ai-sdk/react';
|
|
146
|
-
import {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
import {
|
|
147
|
+
ChatTransportProvider,
|
|
148
|
+
useChatTransport,
|
|
149
|
+
useMessageSync,
|
|
150
|
+
useActiveTurns,
|
|
151
|
+
useView,
|
|
152
|
+
} from '@ably/ai-transport/vercel/react';
|
|
150
153
|
|
|
151
|
-
function
|
|
152
|
-
const {
|
|
153
|
-
|
|
154
|
-
const transport = useClientTransport({ channel, codec: UIMessageCodec, clientId });
|
|
155
|
-
const chatTransport = useChatTransport(transport);
|
|
154
|
+
function ChatInner({ chatId }: { chatId: string }) {
|
|
155
|
+
const { chatTransport } = useChatTransport();
|
|
156
156
|
|
|
157
157
|
const { messages, setMessages, sendMessage, stop } = useChat({
|
|
158
158
|
id: chatId,
|
|
159
159
|
transport: chatTransport,
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
useMessageSync(
|
|
162
|
+
useMessageSync({ setMessages });
|
|
163
163
|
|
|
164
|
-
const activeTurns = useActiveTurns(
|
|
165
|
-
|
|
164
|
+
const activeTurns = useActiveTurns();
|
|
165
|
+
useView({ limit: 30 });
|
|
166
166
|
|
|
167
167
|
return (
|
|
168
168
|
<div>
|
|
@@ -189,6 +189,17 @@ function Chat({ chatId, clientId }: { chatId: string; clientId?: string }) {
|
|
|
189
189
|
</div>
|
|
190
190
|
);
|
|
191
191
|
}
|
|
192
|
+
|
|
193
|
+
function Chat({ chatId, clientId }: { chatId: string; clientId?: string }) {
|
|
194
|
+
return (
|
|
195
|
+
<ChatTransportProvider
|
|
196
|
+
channelName={chatId}
|
|
197
|
+
clientId={clientId}
|
|
198
|
+
>
|
|
199
|
+
<ChatInner chatId={chatId} />
|
|
200
|
+
</ChatTransportProvider>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
192
203
|
```
|
|
193
204
|
|
|
194
205
|
### Authentication
|
|
@@ -271,8 +282,8 @@ transport.close();
|
|
|
271
282
|
|
|
272
283
|
## Package exports
|
|
273
284
|
|
|
274
|
-
| Export path
|
|
275
|
-
|
|
|
285
|
+
| Export path | Purpose | Peer dependencies |
|
|
286
|
+
| --------------------------------- | ------------------------------------------- | --------------------- |
|
|
276
287
|
| `@ably/ai-transport` | Core transport, codec interfaces, utilities | `ably` |
|
|
277
288
|
| `@ably/ai-transport/react` | React hooks for any codec | `ably`, `react` |
|
|
278
289
|
| `@ably/ai-transport/vercel` | Vercel AI SDK codec, transport factories | `ably`, `ai` |
|
|
@@ -280,19 +291,15 @@ transport.close();
|
|
|
280
291
|
|
|
281
292
|
### React hooks
|
|
282
293
|
|
|
283
|
-
| Hook
|
|
284
|
-
|
|
|
285
|
-
| `useClientTransport`
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
| `
|
|
292
|
-
| `useConversationTree` | `/react` | Navigate branches in a forked conversation |
|
|
293
|
-
| `useAblyMessages` | `/react` | Access raw Ably messages |
|
|
294
|
-
| `useChatTransport` | `/vercel/react` | Wrap transport for Vercel's `useChat` |
|
|
295
|
-
| `useMessageSync` | `/vercel/react` | Sync transport state with `useChat`'s `setMessages` |
|
|
294
|
+
| Hook | Entry point | Description |
|
|
295
|
+
| -------------------- | --------------- | --------------------------------------------------- |
|
|
296
|
+
| `useClientTransport` | `/react` | Create and memoize a client transport instance |
|
|
297
|
+
| `useView` | `/react` | Subscribe to messages with history loading |
|
|
298
|
+
| `useActiveTurns` | `/react` | Track active turns by client ID |
|
|
299
|
+
| `useTree` | `/react` | Navigate branches in a forked conversation |
|
|
300
|
+
| `useAblyMessages` | `/react` | Access raw Ably messages |
|
|
301
|
+
| `useChatTransport` | `/vercel/react` | Wrap transport for Vercel's `useChat` |
|
|
302
|
+
| `useMessageSync` | `/vercel/react` | Sync transport state with `useChat`'s `setMessages` |
|
|
296
303
|
|
|
297
304
|
---
|
|
298
305
|
|
|
@@ -303,7 +310,7 @@ transport.close();
|
|
|
303
310
|
Two mechanisms cover different failure modes:
|
|
304
311
|
|
|
305
312
|
- **Network blips** - Ably's connection protocol automatically reconnects and delivers any messages published while the client was disconnected. No application code required.
|
|
306
|
-
- **Resumable streams** - A client that joins or rejoins a channel mid-response (after a page refresh, on a new device, or as a second participant) receives the in-progress stream immediately on subscribing. Load previous conversation history from the channel via `
|
|
313
|
+
- **Resumable streams** - A client that joins or rejoins a channel mid-response (after a page refresh, on a new device, or as a second participant) receives the in-progress stream immediately on subscribing. Load previous conversation history from the channel via `view.loadOlder()`, or from your own database.
|
|
307
314
|
|
|
308
315
|
### Cancellation
|
|
309
316
|
|
|
@@ -316,7 +323,7 @@ await transport.cancel({ turnId: 'turn-abc' });
|
|
|
316
323
|
|
|
317
324
|
// Server: the turn's abortSignal fires automatically
|
|
318
325
|
const result = streamText({
|
|
319
|
-
model: anthropic('claude-sonnet-4-
|
|
326
|
+
model: anthropic('claude-sonnet-4-6'),
|
|
320
327
|
messages,
|
|
321
328
|
abortSignal: turn.abortSignal, // Aborted when client cancels
|
|
322
329
|
});
|
|
@@ -334,7 +341,7 @@ const turn = await transport.regenerate(assistantMessageId);
|
|
|
334
341
|
const turn = await transport.edit(userMessageId, [newMessage]);
|
|
335
342
|
|
|
336
343
|
// Navigate branches
|
|
337
|
-
const tree = transport.
|
|
344
|
+
const tree = transport.tree;
|
|
338
345
|
const siblings = tree.getSiblings(messageId);
|
|
339
346
|
tree.select(messageId, 1); // Switch to second branch
|
|
340
347
|
```
|
|
@@ -344,22 +351,22 @@ tree.select(messageId, 1); // Switch to second branch
|
|
|
344
351
|
Load previous conversation state when a client joins or returns to a session.
|
|
345
352
|
|
|
346
353
|
```typescript
|
|
347
|
-
const
|
|
348
|
-
|
|
354
|
+
const view = transport.view;
|
|
355
|
+
await view.loadOlder(50);
|
|
356
|
+
// view.flattenNodes() returns the messages loaded so far
|
|
349
357
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
358
|
+
// Load more older messages
|
|
359
|
+
await view.loadOlder(50);
|
|
353
360
|
```
|
|
354
361
|
|
|
355
362
|
### Events
|
|
356
363
|
|
|
357
364
|
```typescript
|
|
358
|
-
transport.on('
|
|
359
|
-
console.log(transport.
|
|
365
|
+
transport.view.on('update', () => {
|
|
366
|
+
console.log(transport.view.flattenNodes().map((n) => n.message));
|
|
360
367
|
});
|
|
361
368
|
|
|
362
|
-
transport.on('turn', (event) => {
|
|
369
|
+
transport.tree.on('turn', (event) => {
|
|
363
370
|
console.log(event.turnId, event.type); // 'x-ably-turn-start' | 'x-ably-turn-end'
|
|
364
371
|
});
|
|
365
372
|
|
|
@@ -377,7 +384,7 @@ Detailed documentation lives in the [`docs/`](./docs/) directory:
|
|
|
377
384
|
- **[Concepts](./docs/concepts/)** - [Transport architecture](./docs/concepts/transport.md), [Turns](./docs/concepts/turns.md)
|
|
378
385
|
- **[Get started](./docs/get-started/)** - [Vercel AI SDK with useChat](./docs/get-started/vercel-use-chat.md), [Vercel AI SDK with useClientTransport](./docs/get-started/vercel-use-client-transport.md)
|
|
379
386
|
- **[Frameworks](./docs/frameworks/)** - [Vercel AI SDK](./docs/frameworks/vercel-ai-sdk.md)
|
|
380
|
-
- **[Features](./docs/features/)** - [Streaming](./docs/features/streaming.md), [Cancellation](./docs/features/cancel.md), [
|
|
387
|
+
- **[Features](./docs/features/)** - [Streaming](./docs/features/streaming.md), [Cancellation](./docs/features/cancel.md), [Interruption](./docs/features/interruption.md), [Optimistic updates](./docs/features/optimistic-updates.md), [History](./docs/features/history.md), [Branching](./docs/features/branching.md), [Multi-client sync](./docs/features/multi-client.md), [Concurrent turns](./docs/features/concurrent-turns.md)
|
|
381
388
|
- **[Reference](./docs/reference/)** - [React hooks](./docs/reference/react-hooks.md), [Error codes](./docs/reference/error-codes.md)
|
|
382
389
|
- **[Internals](./docs/internals/)** - Architecture details for contributors
|
|
383
390
|
|
|
@@ -410,7 +417,7 @@ npm run precommit # format:check + lint + typecheck
|
|
|
410
417
|
src/
|
|
411
418
|
├── core/ # Generic transport and codec (no framework deps)
|
|
412
419
|
│ ├── codec/ # Codec interfaces and core encoder/decoder
|
|
413
|
-
│ └── transport/ # ClientTransport, ServerTransport,
|
|
420
|
+
│ └── transport/ # ClientTransport, ServerTransport, Tree
|
|
414
421
|
├── react/ # React hooks for any codec
|
|
415
422
|
├── vercel/ # Vercel AI SDK codec and transport adapters
|
|
416
423
|
│ ├── codec/ # UIMessageCodec
|