@ably/ai-transport 0.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/LICENSE +176 -0
- package/README.md +426 -0
- package/dist/ably-ai-transport.js +1388 -0
- package/dist/ably-ai-transport.js.map +1 -0
- package/dist/ably-ai-transport.umd.cjs +2 -0
- package/dist/ably-ai-transport.umd.cjs.map +1 -0
- package/dist/constants.d.ts +50 -0
- package/dist/core/codec/decoder.d.ts +62 -0
- package/dist/core/codec/encoder.d.ts +56 -0
- package/dist/core/codec/index.d.ts +8 -0
- package/dist/core/codec/lifecycle-tracker.d.ts +74 -0
- package/dist/core/codec/types.d.ts +188 -0
- package/dist/core/transport/client-transport.d.ts +10 -0
- package/dist/core/transport/conversation-tree.d.ts +9 -0
- package/dist/core/transport/decode-history.d.ts +41 -0
- package/dist/core/transport/headers.d.ts +26 -0
- package/dist/core/transport/index.d.ts +4 -0
- package/dist/core/transport/pipe-stream.d.ts +16 -0
- package/dist/core/transport/server-transport.d.ts +7 -0
- package/dist/core/transport/stream-router.d.ts +19 -0
- package/dist/core/transport/turn-manager.d.ts +34 -0
- package/dist/core/transport/types.d.ts +407 -0
- package/dist/errors.d.ts +46 -0
- package/dist/event-emitter.d.ts +65 -0
- package/dist/index.d.ts +11 -0
- package/dist/logger.d.ts +103 -0
- package/dist/react/ably-ai-transport-react.js +823 -0
- package/dist/react/ably-ai-transport-react.js.map +1 -0
- package/dist/react/ably-ai-transport-react.umd.cjs +2 -0
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -0
- package/dist/react/index.d.ts +11 -0
- package/dist/react/use-ably-messages.d.ts +18 -0
- package/dist/react/use-active-turns.d.ts +8 -0
- package/dist/react/use-client-transport.d.ts +7 -0
- package/dist/react/use-conversation-tree.d.ts +20 -0
- package/dist/react/use-edit.d.ts +7 -0
- package/dist/react/use-history.d.ts +19 -0
- package/dist/react/use-messages.d.ts +7 -0
- package/dist/react/use-regenerate.d.ts +7 -0
- package/dist/react/use-send.d.ts +7 -0
- package/dist/utils.d.ts +127 -0
- package/dist/vercel/ably-ai-transport-vercel.js +2331 -0
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -0
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +2 -0
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -0
- package/dist/vercel/codec/accumulator.d.ts +21 -0
- package/dist/vercel/codec/decoder.d.ts +22 -0
- package/dist/vercel/codec/encoder.d.ts +41 -0
- package/dist/vercel/codec/index.d.ts +22 -0
- package/dist/vercel/index.d.ts +3 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +2082 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +2 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -0
- package/dist/vercel/react/index.d.ts +3 -0
- package/dist/vercel/react/use-chat-transport.d.ts +29 -0
- package/dist/vercel/react/use-message-sync.d.ts +19 -0
- package/dist/vercel/transport/chat-transport.d.ts +118 -0
- package/dist/vercel/transport/index.d.ts +36 -0
- package/package.json +123 -0
- package/react/README.md +3 -0
- package/react/index.d.ts +1 -0
- package/react/index.js +1 -0
- package/react/index.umd.cjs +1 -0
- package/src/constants.ts +98 -0
- package/src/core/codec/decoder.ts +402 -0
- package/src/core/codec/encoder.ts +470 -0
- package/src/core/codec/index.ts +28 -0
- package/src/core/codec/lifecycle-tracker.ts +140 -0
- package/src/core/codec/types.ts +249 -0
- package/src/core/transport/client-transport.ts +959 -0
- package/src/core/transport/conversation-tree.ts +434 -0
- package/src/core/transport/decode-history.ts +337 -0
- package/src/core/transport/headers.ts +46 -0
- package/src/core/transport/index.ts +34 -0
- package/src/core/transport/pipe-stream.ts +95 -0
- package/src/core/transport/server-transport.ts +458 -0
- package/src/core/transport/stream-router.ts +118 -0
- package/src/core/transport/turn-manager.ts +147 -0
- package/src/core/transport/types.ts +533 -0
- package/src/errors.ts +58 -0
- package/src/event-emitter.ts +103 -0
- package/src/index.ts +89 -0
- package/src/logger.ts +241 -0
- package/src/react/index.ts +11 -0
- package/src/react/use-ably-messages.ts +37 -0
- package/src/react/use-active-turns.ts +61 -0
- package/src/react/use-client-transport.ts +37 -0
- package/src/react/use-conversation-tree.ts +71 -0
- package/src/react/use-edit.ts +24 -0
- package/src/react/use-history.ts +111 -0
- package/src/react/use-messages.ts +32 -0
- package/src/react/use-regenerate.ts +24 -0
- package/src/react/use-send.ts +25 -0
- package/src/react/vite.config.ts +32 -0
- package/src/tsconfig.json +25 -0
- package/src/utils.ts +230 -0
- package/src/vercel/codec/accumulator.ts +603 -0
- package/src/vercel/codec/decoder.ts +615 -0
- package/src/vercel/codec/encoder.ts +396 -0
- package/src/vercel/codec/index.ts +37 -0
- package/src/vercel/index.ts +12 -0
- package/src/vercel/react/index.ts +4 -0
- package/src/vercel/react/use-chat-transport.ts +60 -0
- package/src/vercel/react/use-message-sync.ts +34 -0
- package/src/vercel/react/vite.config.ts +33 -0
- package/src/vercel/transport/chat-transport.ts +278 -0
- package/src/vercel/transport/index.ts +56 -0
- package/src/vercel/vite.config.ts +33 -0
- package/src/vite.config.ts +31 -0
- package/vercel/README.md +3 -0
- package/vercel/index.d.ts +1 -0
- package/vercel/index.js +1 -0
- package/vercel/index.umd.cjs +1 -0
- package/vercel/react/README.md +3 -0
- package/vercel/react/index.d.ts +1 -0
- package/vercel/react/index.js +1 -0
- package/vercel/react/index.umd.cjs +1 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel chat transport: wraps a core ClientTransport to satisfy the
|
|
3
|
+
* ChatTransport interface that useChat expects.
|
|
4
|
+
*
|
|
5
|
+
* This is a thin adapter — the real logic lives in the core transport.
|
|
6
|
+
* The chat transport maps Vercel's sendMessages/reconnectToStream contract
|
|
7
|
+
* to the core transport's send/cancel methods.
|
|
8
|
+
*
|
|
9
|
+
* useChat manages message state before calling sendMessages:
|
|
10
|
+
* - submit-message: appends the new user message, passes the full array
|
|
11
|
+
* - regenerate-message: truncates after the target, passes the truncated array
|
|
12
|
+
*
|
|
13
|
+
* The adapter uses `trigger` to determine the history/messages split:
|
|
14
|
+
* - submit-message: last message is new (publish to channel), rest is history
|
|
15
|
+
* - regenerate-message: no new messages, entire array is history
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import * as Ably from 'ably';
|
|
19
|
+
import type * as AI from 'ai';
|
|
20
|
+
|
|
21
|
+
import type { ClientTransport, CloseOptions, SendOptions } from '../../core/transport/types.js';
|
|
22
|
+
import { ErrorCode } from '../../errors.js';
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// ChatTransport options
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Context passed to {@link ChatTransportOptions.prepareSendMessagesRequest} for
|
|
30
|
+
* customizing the HTTP POST body and headers.
|
|
31
|
+
*/
|
|
32
|
+
export interface SendMessagesRequestContext {
|
|
33
|
+
/** Chat session ID (from useChat's id). */
|
|
34
|
+
id?: string;
|
|
35
|
+
/** What triggered the request: user sent a message, or requested regeneration. */
|
|
36
|
+
trigger: 'submit-message' | 'regenerate-message';
|
|
37
|
+
/**
|
|
38
|
+
* The message ID for regeneration requests. Identifies which assistant
|
|
39
|
+
* message to regenerate. Undefined for submit-message.
|
|
40
|
+
*/
|
|
41
|
+
messageId?: string;
|
|
42
|
+
/** Previous messages in the conversation (context for the LLM). */
|
|
43
|
+
history: AI.UIMessage[];
|
|
44
|
+
/** The new message(s) being sent (to publish to the channel). Empty for regeneration. */
|
|
45
|
+
messages: AI.UIMessage[];
|
|
46
|
+
/** The msg-id of the message being forked (regenerated or edited). */
|
|
47
|
+
forkOf?: string;
|
|
48
|
+
/** The msg-id of the predecessor in the conversation thread. */
|
|
49
|
+
parent?: string | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Options for customizing the ChatTransport behavior. */
|
|
53
|
+
export interface ChatTransportOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Customize the POST body before sending. Called by sendMessages()
|
|
56
|
+
* with the conversation context. Return the body and headers for
|
|
57
|
+
* the HTTP POST.
|
|
58
|
+
*
|
|
59
|
+
* Default: sends all previous messages as `history` in the body.
|
|
60
|
+
* @param context - The conversation context for the current request.
|
|
61
|
+
* @returns The body and headers to use for the HTTP POST.
|
|
62
|
+
*/
|
|
63
|
+
prepareSendMessagesRequest?: (context: SendMessagesRequestContext) => {
|
|
64
|
+
body?: Record<string, unknown>;
|
|
65
|
+
headers?: Record<string, string>;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// ChatTransport interface
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Additional options passed through from useChat alongside the core
|
|
75
|
+
* sendMessages/reconnectToStream parameters.
|
|
76
|
+
*
|
|
77
|
+
* Mirrors the AI SDK's internal ChatRequestOptions type, which is not
|
|
78
|
+
* exported from the `ai` package.
|
|
79
|
+
*/
|
|
80
|
+
interface ChatRequestOptions {
|
|
81
|
+
/** Additional headers for the request. */
|
|
82
|
+
headers?: Record<string, string> | Headers;
|
|
83
|
+
/** Additional JSON body properties for the request. */
|
|
84
|
+
body?: object;
|
|
85
|
+
/** Custom metadata to attach to the request. */
|
|
86
|
+
metadata?: unknown;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Transport interface for Vercel AI SDK's useChat hook.
|
|
91
|
+
*
|
|
92
|
+
* Structurally compatible with the AI SDK's internal `ChatTransport<UIMessage>`
|
|
93
|
+
* interface. Extended with `close()` for releasing the underlying Ably transport
|
|
94
|
+
* resources.
|
|
95
|
+
*/
|
|
96
|
+
export interface ChatTransport {
|
|
97
|
+
/** Send messages and return a streaming response of UIMessageChunk events. */
|
|
98
|
+
sendMessages: (
|
|
99
|
+
options: {
|
|
100
|
+
/** The type of message submission — new message or regeneration. */
|
|
101
|
+
trigger: 'submit-message' | 'regenerate-message';
|
|
102
|
+
/** Unique identifier for the chat session. */
|
|
103
|
+
chatId: string;
|
|
104
|
+
/** ID of the message to regenerate, or undefined for new messages. */
|
|
105
|
+
messageId: string | undefined;
|
|
106
|
+
/** Array of UI messages representing the conversation history. */
|
|
107
|
+
messages: AI.UIMessage[];
|
|
108
|
+
/** Signal to abort the request if needed. */
|
|
109
|
+
abortSignal: AbortSignal | undefined;
|
|
110
|
+
} & ChatRequestOptions,
|
|
111
|
+
) => Promise<ReadableStream<AI.UIMessageChunk>>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Reconnect to an existing streaming response. Returns null if no active
|
|
115
|
+
* stream exists for the specified chat session.
|
|
116
|
+
*/
|
|
117
|
+
reconnectToStream: (
|
|
118
|
+
options: {
|
|
119
|
+
/** Unique identifier for the chat session to reconnect to. */
|
|
120
|
+
chatId: string;
|
|
121
|
+
} & ChatRequestOptions,
|
|
122
|
+
) => Promise<ReadableStream<AI.UIMessageChunk> | null>;
|
|
123
|
+
|
|
124
|
+
/** Close the underlying transport, releasing all resources. */
|
|
125
|
+
close(options?: CloseOptions): Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// Factory
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Create a Vercel ChatTransport from a core ClientTransport.
|
|
134
|
+
*
|
|
135
|
+
* Maps Vercel's useChat contract to the core transport's methods:
|
|
136
|
+
* - trigger 'submit-message' → transport.send(lastMessage) with history in body
|
|
137
|
+
* - trigger 'regenerate-message' → transport.send([]) with all messages as history
|
|
138
|
+
* - abortSignal → transport.cancel({ all: true })
|
|
139
|
+
* - reconnectToStream → null (observer mode handles in-progress streams)
|
|
140
|
+
* @param transport - The core client transport to wrap.
|
|
141
|
+
* @param chatOptions - Optional hooks for customizing request construction.
|
|
142
|
+
* @returns A {@link ChatTransport} compatible with Vercel's useChat hook.
|
|
143
|
+
*/
|
|
144
|
+
export const createChatTransport = (
|
|
145
|
+
transport: ClientTransport<AI.UIMessageChunk, AI.UIMessage>,
|
|
146
|
+
chatOptions?: ChatTransportOptions,
|
|
147
|
+
): ChatTransport => ({
|
|
148
|
+
sendMessages: async (opts) => {
|
|
149
|
+
const { messages, abortSignal, trigger, messageId } = opts;
|
|
150
|
+
|
|
151
|
+
// Determine the history/messages split based on trigger.
|
|
152
|
+
// - submit-message: useChat appended the new user message → last is new
|
|
153
|
+
// - regenerate-message: useChat truncated the array → no new messages
|
|
154
|
+
let newMessages: AI.UIMessage[];
|
|
155
|
+
let history: AI.UIMessage[];
|
|
156
|
+
|
|
157
|
+
if (trigger === 'regenerate-message') {
|
|
158
|
+
newMessages = [];
|
|
159
|
+
history = messages;
|
|
160
|
+
} else {
|
|
161
|
+
if (messages.length === 0) {
|
|
162
|
+
throw new Ably.ErrorInfo(
|
|
163
|
+
'unable to send messages; messages array is empty for submit-message trigger',
|
|
164
|
+
ErrorCode.InvalidArgument,
|
|
165
|
+
400,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
// CAST: length check above guarantees at least one element; .at(-1) cannot be undefined.
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style -- prefer `as` over `!` per TYPES.md
|
|
170
|
+
newMessages = [messages.at(-1) as AI.UIMessage];
|
|
171
|
+
history = messages.slice(0, -1);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Compute fork metadata from the conversation tree.
|
|
175
|
+
// For regeneration: forkOf = messageId (the assistant message being regenerated),
|
|
176
|
+
// parent = the parent of that message in the tree.
|
|
177
|
+
let forkOf: string | undefined;
|
|
178
|
+
let parent: string | null | undefined;
|
|
179
|
+
|
|
180
|
+
if (trigger === 'regenerate-message' && messageId) {
|
|
181
|
+
forkOf = messageId;
|
|
182
|
+
// Look up the parent of the message being regenerated.
|
|
183
|
+
// messageId comes from useChat (UIMessage.id), so use getNodeByKey
|
|
184
|
+
// which resolves via the codec key secondary index.
|
|
185
|
+
const node = transport.getTree().getNodeByKey(messageId);
|
|
186
|
+
if (node) {
|
|
187
|
+
// Use the tree node's msgId (x-ably-msg-id) as forkOf — this is
|
|
188
|
+
// what the server stamps on the wire, not the UIMessage.id.
|
|
189
|
+
forkOf = node.msgId;
|
|
190
|
+
parent = node.parentId;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let sendBody: Record<string, unknown>;
|
|
195
|
+
let sendHeaders: Record<string, string> | undefined;
|
|
196
|
+
|
|
197
|
+
if (chatOptions?.prepareSendMessagesRequest) {
|
|
198
|
+
const prepared = chatOptions.prepareSendMessagesRequest({
|
|
199
|
+
id: opts.chatId,
|
|
200
|
+
trigger,
|
|
201
|
+
messageId,
|
|
202
|
+
history,
|
|
203
|
+
messages: newMessages,
|
|
204
|
+
forkOf,
|
|
205
|
+
parent,
|
|
206
|
+
});
|
|
207
|
+
sendBody = prepared.body ?? {};
|
|
208
|
+
sendHeaders = prepared.headers;
|
|
209
|
+
} else {
|
|
210
|
+
const historyWithHeaders = history.map((m) => ({
|
|
211
|
+
message: m,
|
|
212
|
+
headers: transport.getMessageHeaders(m),
|
|
213
|
+
}));
|
|
214
|
+
sendBody = {
|
|
215
|
+
history: historyWithHeaders,
|
|
216
|
+
id: opts.chatId,
|
|
217
|
+
trigger,
|
|
218
|
+
...(messageId !== undefined && { messageId }),
|
|
219
|
+
...(forkOf !== undefined && { forkOf }),
|
|
220
|
+
...(parent !== undefined && { parent }),
|
|
221
|
+
};
|
|
222
|
+
sendHeaders = undefined;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const sendOpts: SendOptions = { body: sendBody, headers: sendHeaders };
|
|
226
|
+
if (forkOf !== undefined) sendOpts.forkOf = forkOf;
|
|
227
|
+
if (parent !== undefined) sendOpts.parent = parent;
|
|
228
|
+
|
|
229
|
+
const turn = await transport.send(newMessages, sendOpts);
|
|
230
|
+
|
|
231
|
+
// Wire abort signal to cancel all turns on the channel.
|
|
232
|
+
// In multi-user scenarios, any client can stop any stream — cancelling
|
|
233
|
+
// by specific turnId would only work for the sender.
|
|
234
|
+
if (abortSignal) {
|
|
235
|
+
abortSignal.addEventListener('abort', () => void transport.cancel({ all: true }), {
|
|
236
|
+
once: true,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Return an empty stream that closes when the turn ends.
|
|
241
|
+
// useChat consumes the returned stream to accumulate the assistant message,
|
|
242
|
+
// but useMessageSync already pushes the transport's authoritative message
|
|
243
|
+
// state into useChat via setMessages. Returning the real event stream would
|
|
244
|
+
// cause useChat to accumulate a duplicate assistant message. Instead, we
|
|
245
|
+
// return a stream that produces no chunks and closes when the turn's stream
|
|
246
|
+
// finishes, so useChat knows when streaming is done without duplicating state.
|
|
247
|
+
const { readable, writable } = new TransformStream<AI.UIMessageChunk>();
|
|
248
|
+
const writer = writable.getWriter();
|
|
249
|
+
// Fire-and-forget: we only care about the close/abort signal, not the piped data.
|
|
250
|
+
// Errors on the turn stream are surfaced via transport.on('error'), not here.
|
|
251
|
+
/* eslint-disable @typescript-eslint/no-empty-function -- swallow: writer.close() rejection after stream teardown is unrecoverable */
|
|
252
|
+
turn.stream
|
|
253
|
+
.pipeTo(
|
|
254
|
+
new WritableStream({
|
|
255
|
+
close: () => {
|
|
256
|
+
writer.close().catch(() => {});
|
|
257
|
+
},
|
|
258
|
+
abort: () => {
|
|
259
|
+
writer.close().catch(() => {});
|
|
260
|
+
},
|
|
261
|
+
}),
|
|
262
|
+
)
|
|
263
|
+
.catch(() => {
|
|
264
|
+
writer.close().catch(() => {});
|
|
265
|
+
});
|
|
266
|
+
/* eslint-enable @typescript-eslint/no-empty-function */
|
|
267
|
+
return readable;
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// Observer mode handles in-progress streams automatically.
|
|
271
|
+
// The transport subscribes before attach — on the next server append,
|
|
272
|
+
// observer accumulation emits lifecycle events that useMessageSync
|
|
273
|
+
// upserts into React state.
|
|
274
|
+
// eslint-disable-next-line unicorn/no-null, @typescript-eslint/promise-function-async -- null is required by the AI SDK ChatTransport contract; no await needed
|
|
275
|
+
reconnectToStream: () => Promise.resolve(null),
|
|
276
|
+
|
|
277
|
+
close: async (options?: CloseOptions) => transport.close(options),
|
|
278
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel AI SDK transport wrappers that pre-bind the UIMessageCodec.
|
|
3
|
+
*
|
|
4
|
+
* These are convenience factories so consumers don't need to pass the codec
|
|
5
|
+
* explicitly when using the Vercel AI SDK integration.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { createClientTransport } from '@ably/ai-transport/vercel';
|
|
9
|
+
*
|
|
10
|
+
* const transport = createClientTransport({ channel });
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Chat transport adapter
|
|
15
|
+
export type { ChatTransport, ChatTransportOptions, SendMessagesRequestContext } from './chat-transport.js';
|
|
16
|
+
export { createChatTransport } from './chat-transport.js';
|
|
17
|
+
|
|
18
|
+
import type * as AI from 'ai';
|
|
19
|
+
|
|
20
|
+
import { createClientTransport as createCoreClientTransport } from '../../core/transport/client-transport.js';
|
|
21
|
+
import { createServerTransport as createCoreServerTransport } from '../../core/transport/server-transport.js';
|
|
22
|
+
import type {
|
|
23
|
+
ClientTransport,
|
|
24
|
+
ClientTransportOptions,
|
|
25
|
+
ServerTransport,
|
|
26
|
+
ServerTransportOptions,
|
|
27
|
+
} from '../../core/transport/types.js';
|
|
28
|
+
import { UIMessageCodec } from '../codec/index.js';
|
|
29
|
+
|
|
30
|
+
/** Options for creating a Vercel client transport. Same as core options but without the codec field. */
|
|
31
|
+
export type VercelClientTransportOptions = Omit<ClientTransportOptions<AI.UIMessageChunk, AI.UIMessage>, 'codec'>;
|
|
32
|
+
|
|
33
|
+
/** Options for creating a Vercel server transport. Same as core options but without the codec field. */
|
|
34
|
+
export type VercelServerTransportOptions = Omit<ServerTransportOptions<AI.UIMessageChunk, AI.UIMessage>, 'codec'>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Create a client-side transport pre-configured with the Vercel AI SDK codec.
|
|
38
|
+
*
|
|
39
|
+
* Equivalent to calling the core `createClientTransport` with `codec: UIMessageCodec`.
|
|
40
|
+
* @param options - Configuration for the client transport (codec is provided automatically).
|
|
41
|
+
* @returns A new {@link ClientTransport} for Vercel AI SDK UIMessage/UIMessageChunk types.
|
|
42
|
+
*/
|
|
43
|
+
export const createClientTransport = (
|
|
44
|
+
options: VercelClientTransportOptions,
|
|
45
|
+
): ClientTransport<AI.UIMessageChunk, AI.UIMessage> => createCoreClientTransport({ ...options, codec: UIMessageCodec });
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a server-side transport pre-configured with the Vercel AI SDK codec.
|
|
49
|
+
*
|
|
50
|
+
* Equivalent to calling the core `createServerTransport` with `codec: UIMessageCodec`.
|
|
51
|
+
* @param options - Configuration for the server transport (codec is provided automatically).
|
|
52
|
+
* @returns A new {@link ServerTransport} for Vercel AI SDK UIMessage/UIMessageChunk types.
|
|
53
|
+
*/
|
|
54
|
+
export const createServerTransport = (
|
|
55
|
+
options: VercelServerTransportOptions,
|
|
56
|
+
): ServerTransport<AI.UIMessageChunk, AI.UIMessage> => createCoreServerTransport({ ...options, codec: UIMessageCodec });
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
import dts from 'vite-plugin-dts';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
root: resolve(__dirname, '.'),
|
|
7
|
+
plugins: [
|
|
8
|
+
dts({
|
|
9
|
+
entryRoot: resolve(__dirname, '.'),
|
|
10
|
+
insertTypesEntry: true,
|
|
11
|
+
exclude: ['react/**'],
|
|
12
|
+
}),
|
|
13
|
+
],
|
|
14
|
+
build: {
|
|
15
|
+
outDir: '../../dist/vercel',
|
|
16
|
+
lib: {
|
|
17
|
+
entry: resolve(__dirname, 'index.ts'),
|
|
18
|
+
name: 'AblyAiTransportVercel',
|
|
19
|
+
fileName: 'ably-ai-transport-vercel',
|
|
20
|
+
formats: ['es', 'umd'],
|
|
21
|
+
},
|
|
22
|
+
rollupOptions: {
|
|
23
|
+
external: ['ably', 'ai'],
|
|
24
|
+
output: {
|
|
25
|
+
globals: {
|
|
26
|
+
ably: 'Ably',
|
|
27
|
+
ai: 'AI',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
sourcemap: true,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
import dts from 'vite-plugin-dts';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
root: resolve(__dirname, '.'),
|
|
7
|
+
plugins: [
|
|
8
|
+
dts({
|
|
9
|
+
entryRoot: resolve(__dirname, '.'),
|
|
10
|
+
insertTypesEntry: true,
|
|
11
|
+
exclude: ['react/**', 'vercel/**'],
|
|
12
|
+
}),
|
|
13
|
+
],
|
|
14
|
+
build: {
|
|
15
|
+
outDir: '../dist',
|
|
16
|
+
lib: {
|
|
17
|
+
entry: resolve(__dirname, 'index.ts'),
|
|
18
|
+
name: 'AblyAiTransport',
|
|
19
|
+
fileName: 'ably-ai-transport',
|
|
20
|
+
},
|
|
21
|
+
rollupOptions: {
|
|
22
|
+
external: ['ably'],
|
|
23
|
+
output: {
|
|
24
|
+
globals: {
|
|
25
|
+
ably: 'Ably',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
sourcemap: true,
|
|
30
|
+
},
|
|
31
|
+
});
|
package/vercel/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/vercel';
|
package/vercel/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/vercel/ably-ai-transport-vercel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('../dist/vercel/ably-ai-transport-vercel.umd');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../dist/vercel/react';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../dist/vercel/react/ably-ai-transport-vercel-react';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('../../dist/vercel/react/ably-ai-transport-vercel-react.umd');
|