@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ably/ai-transport",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Ably transport and codecs for building AI applications with Ably.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/ably-ai-transport.umd.cjs",
|
|
@@ -46,13 +46,15 @@
|
|
|
46
46
|
"prepare": "npm run build",
|
|
47
47
|
"lint": "eslint .",
|
|
48
48
|
"lint:fix": "eslint --fix .; (npm run format > /dev/null)",
|
|
49
|
-
"format": "prettier --list-different --write
|
|
50
|
-
"format:check": "prettier --check
|
|
49
|
+
"format": "prettier --list-different --write .",
|
|
50
|
+
"format:check": "prettier --check .",
|
|
51
51
|
"typecheck": "tsc --noEmit",
|
|
52
52
|
"test": "vitest run",
|
|
53
53
|
"test:integration": "vitest run --config vitest.config.integration.ts",
|
|
54
54
|
"check:error-codes": "tsx scripts/validate-error-codes.ts",
|
|
55
|
-
"precommit": "npm run format:check && npm run lint && npm run typecheck"
|
|
55
|
+
"precommit": "npm run format:check && npm run lint && npm run typecheck",
|
|
56
|
+
"docs": "typedoc",
|
|
57
|
+
"docs:lint": "typedoc --emit none"
|
|
56
58
|
},
|
|
57
59
|
"files": [
|
|
58
60
|
"dist/**",
|
|
@@ -94,28 +96,32 @@
|
|
|
94
96
|
}
|
|
95
97
|
},
|
|
96
98
|
"devDependencies": {
|
|
97
|
-
"@
|
|
99
|
+
"@ai-sdk/react": "^3.0.151",
|
|
100
|
+
"@eslint/compat": "^2.0.5",
|
|
98
101
|
"@eslint/eslintrc": "^3.3.0",
|
|
99
|
-
"@eslint/js": "^
|
|
102
|
+
"@eslint/js": "^10.0.1",
|
|
100
103
|
"@testing-library/react": "^16.3.2",
|
|
101
104
|
"@types/react": "^19.2.14",
|
|
102
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
103
|
-
"@typescript-eslint/parser": "^8.
|
|
105
|
+
"@typescript-eslint/eslint-plugin": "^8.58.2",
|
|
106
|
+
"@typescript-eslint/parser": "^8.58.2",
|
|
107
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
104
108
|
"ai": "^6.0.137",
|
|
105
|
-
"eslint": "^
|
|
106
|
-
"eslint-plugin-import": "^
|
|
107
|
-
"eslint-plugin-jsdoc": "^
|
|
109
|
+
"eslint": "^10.2.0",
|
|
110
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
111
|
+
"eslint-plugin-jsdoc": "^62.9.0",
|
|
108
112
|
"eslint-plugin-prefer-arrow-functions": "^3.6.2",
|
|
109
|
-
"eslint-plugin-security": "^
|
|
110
|
-
"eslint-plugin-simple-import-sort": "^
|
|
111
|
-
"eslint-plugin-unicorn": "^
|
|
112
|
-
"globals": "^
|
|
113
|
+
"eslint-plugin-security": "^4.0.0",
|
|
114
|
+
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
115
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
116
|
+
"globals": "^17.5.0",
|
|
113
117
|
"jiti": "^2.6.1",
|
|
114
118
|
"jsdom": "^29.0.1",
|
|
115
119
|
"prettier": "^3.5.3",
|
|
116
120
|
"tsx": "^4.21.0",
|
|
117
|
-
"
|
|
118
|
-
"
|
|
121
|
+
"typedoc": "^0.28.13",
|
|
122
|
+
"typedoc-plugin-no-inherit": "^1.5.0",
|
|
123
|
+
"typescript": "^6.0.2",
|
|
124
|
+
"typescript-eslint": "^8.58.2",
|
|
119
125
|
"vite": "^8.0.0",
|
|
120
126
|
"vite-plugin-dts": "^4.5.4",
|
|
121
127
|
"vitest": "^4.1.0"
|
package/src/constants.ts
CHANGED
|
@@ -22,6 +22,9 @@ export const HEADER_STATUS = 'x-ably-status';
|
|
|
22
22
|
/** Header: stream identity. Set by the encoder on every streamed message; read by the decoder to correlate streams. */
|
|
23
23
|
export const HEADER_STREAM_ID = 'x-ably-stream-id';
|
|
24
24
|
|
|
25
|
+
/** Header: marks a message as a discrete message part (from writeMessages). Set by publishDiscreteBatch; not set on lifecycle events from publishDiscrete. */
|
|
26
|
+
export const HEADER_DISCRETE = 'x-ably-discrete';
|
|
27
|
+
|
|
25
28
|
// ---------------------------------------------------------------------------
|
|
26
29
|
// Identity headers (used by transport for turn correlation)
|
|
27
30
|
// ---------------------------------------------------------------------------
|
|
@@ -38,6 +41,9 @@ export const HEADER_TURN_CLIENT_ID = 'x-ably-turn-client-id';
|
|
|
38
41
|
/** Header: message role (e.g. "user", "assistant"). */
|
|
39
42
|
export const HEADER_ROLE = 'x-ably-role';
|
|
40
43
|
|
|
44
|
+
/** Header: the msg-id of the existing message this Ably message amends. Present on cross-turn amendment events. */
|
|
45
|
+
export const HEADER_AMEND = 'x-ably-amend';
|
|
46
|
+
|
|
41
47
|
// ---------------------------------------------------------------------------
|
|
42
48
|
// Cancel headers
|
|
43
49
|
// ---------------------------------------------------------------------------
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import * as Ably from 'ably';
|
|
13
13
|
|
|
14
|
-
import { HEADER_MSG_ID, HEADER_STATUS, HEADER_STREAM, HEADER_STREAM_ID } from '../../constants.js';
|
|
14
|
+
import { HEADER_DISCRETE, HEADER_MSG_ID, HEADER_STATUS, HEADER_STREAM, HEADER_STREAM_ID } from '../../constants.js';
|
|
15
15
|
import { ErrorCode } from '../../errors.js';
|
|
16
16
|
import type { Logger } from '../../logger.js';
|
|
17
17
|
import { mergeHeaders } from '../../utils.js';
|
|
@@ -129,6 +129,13 @@ class DefaultEncoderCore implements EncoderCore {
|
|
|
129
129
|
this._assertNotClosed();
|
|
130
130
|
this._logger?.trace('DefaultEncoderCore.publishDiscreteBatch();', { count: payloads.length });
|
|
131
131
|
const msgs = payloads.map((p) => this._buildDiscreteMessage(p, opts));
|
|
132
|
+
// Mark batch-published payloads as discrete message parts (from writeMessages).
|
|
133
|
+
// The decoder relies on this header to distinguish message parts from lifecycle
|
|
134
|
+
// events that also happen to be discrete (x-ably-stream: false).
|
|
135
|
+
for (const msg of msgs) {
|
|
136
|
+
// CAST: extras is built by _buildDiscreteMessage with a known { headers } shape.
|
|
137
|
+
(msg.extras as { headers: Record<string, string> }).headers[HEADER_DISCRETE] = 'true';
|
|
138
|
+
}
|
|
132
139
|
return this._writer.publish(msgs);
|
|
133
140
|
}
|
|
134
141
|
|
|
@@ -154,6 +161,7 @@ class DefaultEncoderCore implements EncoderCore {
|
|
|
154
161
|
const result = await this._writer.publish(msg);
|
|
155
162
|
const serial = result.serials[0];
|
|
156
163
|
|
|
164
|
+
// Spec: AIT-CD2a
|
|
157
165
|
if (!serial) {
|
|
158
166
|
throw new Ably.ErrorInfo(
|
|
159
167
|
`unable to start stream; no serial returned for stream '${payload.name}' (streamId: ${streamId})`,
|
|
@@ -181,6 +189,7 @@ class DefaultEncoderCore implements EncoderCore {
|
|
|
181
189
|
// Spec: AIT-CD3
|
|
182
190
|
appendStream(streamId: string, data: string): void {
|
|
183
191
|
this._assertNotClosed();
|
|
192
|
+
// Spec: AIT-CD3a
|
|
184
193
|
const tracker = this._trackers.get(streamId);
|
|
185
194
|
if (!tracker) {
|
|
186
195
|
throw new Ably.ErrorInfo(
|
package/src/core/codec/types.ts
CHANGED
|
@@ -203,6 +203,19 @@ export interface MessageAccumulator<TEvent, TMessage> {
|
|
|
203
203
|
processOutputs(outputs: DecoderOutput<TEvent, TMessage>[]): void;
|
|
204
204
|
/** Apply an external update to a message (e.g. from an update callback). */
|
|
205
205
|
updateMessage(message: TMessage): void;
|
|
206
|
+
/**
|
|
207
|
+
* Ensure the accumulator is ready to process events for the given message.
|
|
208
|
+
* If not already active, creates internal tracking state from the message.
|
|
209
|
+
* If already active, syncs internal state with the provided message
|
|
210
|
+
* (picking up external changes like cross-turn amendments).
|
|
211
|
+
* Idempotent — safe to call before every processOutputs.
|
|
212
|
+
*/
|
|
213
|
+
initMessage(messageId: string, message: TMessage): void;
|
|
214
|
+
/**
|
|
215
|
+
* Mark a message as completed. Removes it from active tracking so it
|
|
216
|
+
* appears in {@link completedMessages}. No-op if not active.
|
|
217
|
+
*/
|
|
218
|
+
completeMessage(messageId: string): void;
|
|
206
219
|
/** All messages accumulated so far (in-progress and completed). */
|
|
207
220
|
readonly messages: TMessage[];
|
|
208
221
|
/** Only messages whose streams have finished. */
|
|
@@ -223,6 +236,12 @@ export interface EncoderOptions {
|
|
|
223
236
|
extras?: Extras;
|
|
224
237
|
/** Hook called before each Ably message is published. Mutate the message in place to add transport-level headers. */
|
|
225
238
|
onMessage?: (message: Ably.Message) => void;
|
|
239
|
+
/**
|
|
240
|
+
* Domain-level message identity. Domain encoders use this as a fallback
|
|
241
|
+
* messageId when a lifecycle chunk (e.g. `start`) does not provide one,
|
|
242
|
+
* ensuring useChat and the transport accumulator assign the same ID.
|
|
243
|
+
*/
|
|
244
|
+
messageId?: string;
|
|
226
245
|
}
|
|
227
246
|
|
|
228
247
|
/**
|
|
@@ -243,7 +262,4 @@ export interface Codec<TEvent, TMessage> {
|
|
|
243
262
|
|
|
244
263
|
/** Whether an event signals stream completion (finish, error, abort). */
|
|
245
264
|
isTerminal(event: TEvent): boolean;
|
|
246
|
-
|
|
247
|
-
/** Return a stable key for a message (used by MessageStore for upsert/delete). */
|
|
248
|
-
getMessageKey(message: TMessage): string;
|
|
249
265
|
}
|