ai 2.1.2 → 2.1.6
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 +91 -0
- package/dist/index.d.ts +61 -7
- package/dist/index.js +31 -26
- package/dist/index.mjs +31 -26
- package/package.json +3 -3
- package/react/dist/index.d.ts +8 -8
- package/react/dist/index.js +13 -6
- package/react/dist/index.mjs +13 -6
- package/svelte/dist/index.d.ts +6 -6
- package/svelte/dist/index.js +14 -7
- package/svelte/dist/index.mjs +14 -7
- package/vue/dist/index.d.ts +6 -6
- package/vue/dist/index.js +11 -5
- package/vue/dist/index.mjs +11 -5
package/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Vercel AI SDK
|
2
|
+
|
3
|
+
The Vercel AI SDK is **a library for building edge-ready AI-powered streaming text and chat UIs**.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- [SWR](https://swr.vercel.app)-powered React, Svelte and Vue helpers for streaming text responses and building chat and completion UIs
|
8
|
+
- First-class support for [LangChain](js.langchain.com/docs) and [OpenAI](https://openai.com), [Anthropic](https://www.anthropic.com), and [HuggingFace](https://huggingface.co)
|
9
|
+
- [Edge Runtime](https://edge-runtime.vercel.app/) compatibility
|
10
|
+
- Callbacks for saving completed streaming responses to a database (in the same request)
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
```sh
|
15
|
+
pnpm install ai
|
16
|
+
```
|
17
|
+
|
18
|
+
View the full documentation and examples on [sdk.vercel.ai/docs](https://sdk.vercel.ai/docs)
|
19
|
+
|
20
|
+
## Example: An AI Chatbot with Next.js and OpenAI
|
21
|
+
|
22
|
+
With the Vercel AI SDK, you can build a ChatGPT-like app in just a few lines of code:
|
23
|
+
|
24
|
+
```tsx
|
25
|
+
// ./app/api/chat/route.js
|
26
|
+
import { Configuration, OpenAIApi } from 'openai-edge'
|
27
|
+
import { OpenAIStream, StreamingTextResponse } from 'ai'
|
28
|
+
|
29
|
+
const config = new Configuration({
|
30
|
+
apiKey: process.env.OPENAI_API_KEY
|
31
|
+
})
|
32
|
+
const openai = new OpenAIApi(config)
|
33
|
+
|
34
|
+
export const runtime = 'edge'
|
35
|
+
|
36
|
+
export async function POST(req) {
|
37
|
+
const { messages } = await req.json()
|
38
|
+
const response = await openai.createChatCompletion({
|
39
|
+
model: 'gpt-4',
|
40
|
+
stream: true,
|
41
|
+
messages
|
42
|
+
})
|
43
|
+
const stream = OpenAIStream(response)
|
44
|
+
return new StreamingTextResponse(stream)
|
45
|
+
}
|
46
|
+
```
|
47
|
+
|
48
|
+
```tsx
|
49
|
+
// ./app/page.js
|
50
|
+
'use client'
|
51
|
+
|
52
|
+
import { useChat } from 'ai/react'
|
53
|
+
|
54
|
+
export default function Chat() {
|
55
|
+
const { messages, input, handleInputChange, handleSubmit } = useChat()
|
56
|
+
|
57
|
+
return (
|
58
|
+
<div>
|
59
|
+
{messages.map(m => (
|
60
|
+
<div key={m.id}>
|
61
|
+
{m.role}: {m.content}
|
62
|
+
</div>
|
63
|
+
))}
|
64
|
+
|
65
|
+
<form onSubmit={handleSubmit}>
|
66
|
+
<input
|
67
|
+
value={input}
|
68
|
+
placeholder="Say something..."
|
69
|
+
onChange={handleInputChange}
|
70
|
+
/>
|
71
|
+
</form>
|
72
|
+
</div>
|
73
|
+
)
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
---
|
78
|
+
|
79
|
+
View the full documentation and examples on [sdk.vercel.ai/docs](https://sdk.vercel.ai/docs)
|
80
|
+
|
81
|
+
## Authors
|
82
|
+
|
83
|
+
This library is created by [Vercel](https://vercel.com) and [Next.js](https://nextjs.org) team members, with contributions from:
|
84
|
+
|
85
|
+
- Jared Palmer ([@jaredpalmer](https://twitter.com/jaredpalmer)) - [Vercel](https://vercel.com)
|
86
|
+
- Shu Ding ([@shuding\_](https://twitter.com/shuding_)) - [Vercel](https://vercel.com)
|
87
|
+
- Max Leiter ([@max_leiter](https://twitter.com/max_leiter)) - [Vercel](https://vercel.com)
|
88
|
+
- Malte Ubl ([@cramforce](https://twitter.com/cramforce)) - [Vercel](https://vercel.com)
|
89
|
+
- Justin Ridgewell ([@jridgewell](https://github.com/jridgewell)) - [Vercel](https://vercel.com)
|
90
|
+
|
91
|
+
[Contributors](https://github.com/vercel-labs/ai/graphs/contributors)
|
package/dist/index.d.ts
CHANGED
@@ -1,21 +1,75 @@
|
|
1
1
|
import { ServerResponse } from 'node:http';
|
2
2
|
|
3
|
+
/**
|
4
|
+
* Helper callback methods for AIStream stream lifecycle events
|
5
|
+
* @interface
|
6
|
+
*/
|
3
7
|
interface AIStreamCallbacks {
|
4
8
|
onStart?: () => Promise<void>;
|
5
9
|
onCompletion?: (completion: string) => Promise<void>;
|
6
10
|
onToken?: (token: string) => Promise<void>;
|
7
11
|
}
|
12
|
+
/**
|
13
|
+
* Custom parser for AIStream data.
|
14
|
+
* @interface
|
15
|
+
*/
|
8
16
|
interface AIStreamParser {
|
9
17
|
(data: string): string | void;
|
10
18
|
}
|
19
|
+
/**
|
20
|
+
* Creates a TransformStream that parses events from an EventSource stream using a custom parser.
|
21
|
+
* @param {AIStreamParser} customParser - Function to handle event data.
|
22
|
+
* @returns {TransformStream<Uint8Array, string>} TransformStream parsing events.
|
23
|
+
*/
|
11
24
|
declare function createEventStreamTransformer(customParser: AIStreamParser): TransformStream<Uint8Array, string>;
|
12
25
|
/**
|
13
|
-
*
|
14
|
-
*
|
26
|
+
* Creates a transform stream that encodes input messages and invokes optional callback functions.
|
27
|
+
* The transform stream uses the provided callbacks to execute custom logic at different stages of the stream's lifecycle.
|
28
|
+
* - `onStart`: Called once when the stream is initialized.
|
29
|
+
* - `onToken`: Called for each tokenized message.
|
30
|
+
* - `onCompletion`: Called once when the stream is flushed, with the aggregated messages.
|
31
|
+
*
|
32
|
+
* This function is useful when you want to process a stream of messages and perform specific actions during the stream's lifecycle.
|
33
|
+
*
|
34
|
+
* @param {AIStreamCallbacks} [callbacks] - An object containing the callback functions.
|
35
|
+
* @return {TransformStream<string, Uint8Array>} A transform stream that encodes input messages as Uint8Array and allows the execution of custom logic through callbacks.
|
36
|
+
*
|
37
|
+
* @example
|
38
|
+
* const callbacks = {
|
39
|
+
* onStart: async () => console.log('Stream started'),
|
40
|
+
* onToken: async (token) => console.log(`Token: ${token}`),
|
41
|
+
* onCompletion: async (completion) => console.log(`Completion: ${completion}`)
|
42
|
+
* };
|
43
|
+
* const transformer = createCallbacksTransformer(callbacks);
|
15
44
|
*/
|
16
45
|
declare function createCallbacksTransformer(callbacks: AIStreamCallbacks | undefined): TransformStream<string, Uint8Array>;
|
46
|
+
/**
|
47
|
+
* Returns a stateful function that, when invoked, trims leading whitespace
|
48
|
+
* from the input text. The trimming only occurs on the first invocation, ensuring that
|
49
|
+
* subsequent calls do not alter the input text. This is particularly useful in scenarios
|
50
|
+
* where a text stream is being processed and only the initial whitespace should be removed.
|
51
|
+
*
|
52
|
+
* @return {function(string): string} A function that takes a string as input and returns a string
|
53
|
+
* with leading whitespace removed if it is the first invocation; otherwise, it returns the input unchanged.
|
54
|
+
*
|
55
|
+
* @example
|
56
|
+
* const trimStart = trimStartOfStreamHelper();
|
57
|
+
* const output1 = trimStart(" text"); // "text"
|
58
|
+
* const output2 = trimStart(" text"); // " text"
|
59
|
+
*
|
60
|
+
*/
|
17
61
|
declare function trimStartOfStreamHelper(): (text: string) => string;
|
18
|
-
|
62
|
+
/**
|
63
|
+
* Returns a ReadableStream created from the response, parsed and handled with custom logic.
|
64
|
+
* The stream goes through two transformation stages, first parsing the events and then
|
65
|
+
* invoking the provided callbacks.
|
66
|
+
* @param {Response} response - The response.
|
67
|
+
* @param {AIStreamParser} customParser - The custom parser function.
|
68
|
+
* @param {AIStreamCallbacks} callbacks - The callbacks.
|
69
|
+
* @return {ReadableStream} The AIStream.
|
70
|
+
* @throws Will throw an error if the response is not OK.
|
71
|
+
*/
|
72
|
+
declare function AIStream(response: Response, customParser: AIStreamParser, callbacks?: AIStreamCallbacks): ReadableStream;
|
19
73
|
|
20
74
|
declare function OpenAIStream(res: Response, cb?: AIStreamCallbacks): ReadableStream;
|
21
75
|
|
@@ -49,19 +103,19 @@ declare function LangChainStream(callbacks?: AIStreamCallbacks): {
|
|
49
103
|
/**
|
50
104
|
* Shared types between the API and UI packages.
|
51
105
|
*/
|
52
|
-
type Message = {
|
106
|
+
declare type Message = {
|
53
107
|
id: string;
|
54
108
|
createdAt?: Date;
|
55
109
|
content: string;
|
56
110
|
role: 'system' | 'user' | 'assistant';
|
57
111
|
};
|
58
|
-
type CreateMessage = {
|
112
|
+
declare type CreateMessage = {
|
59
113
|
id?: string;
|
60
114
|
createdAt?: Date;
|
61
115
|
content: string;
|
62
116
|
role: 'system' | 'user' | 'assistant';
|
63
117
|
};
|
64
|
-
type UseChatOptions = {
|
118
|
+
declare type UseChatOptions = {
|
65
119
|
/**
|
66
120
|
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
|
67
121
|
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
|
@@ -117,7 +171,7 @@ type UseChatOptions = {
|
|
117
171
|
*/
|
118
172
|
sendExtraMessageFields?: boolean;
|
119
173
|
};
|
120
|
-
type UseCompletionOptions = {
|
174
|
+
declare type UseCompletionOptions = {
|
121
175
|
/**
|
122
176
|
* The API endpoint that accepts a `{ prompt: string }` object and returns
|
123
177
|
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
|
package/dist/index.js
CHANGED
@@ -73,34 +73,34 @@ module.exports = __toCommonJS(streams_exports);
|
|
73
73
|
// streams/ai-stream.ts
|
74
74
|
var import_eventsource_parser = require("eventsource-parser");
|
75
75
|
function createEventStreamTransformer(customParser) {
|
76
|
-
const
|
77
|
-
let
|
76
|
+
const textDecoder = new TextDecoder();
|
77
|
+
let eventSourceParser;
|
78
78
|
return new TransformStream({
|
79
79
|
start(controller) {
|
80
80
|
return __async(this, null, function* () {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if (data === "[DONE]") {
|
81
|
+
eventSourceParser = (0, import_eventsource_parser.createParser)(
|
82
|
+
(event) => {
|
83
|
+
if ("data" in event && event.type === "event" && event.data === "[DONE]") {
|
85
84
|
controller.terminate();
|
86
85
|
return;
|
87
86
|
}
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
if ("data" in event) {
|
88
|
+
const parsedMessage = customParser(event.data);
|
89
|
+
if (parsedMessage)
|
90
|
+
controller.enqueue(parsedMessage);
|
91
|
+
}
|
91
92
|
}
|
92
|
-
|
93
|
-
parser = (0, import_eventsource_parser.createParser)(onParse);
|
93
|
+
);
|
94
94
|
});
|
95
95
|
},
|
96
96
|
transform(chunk) {
|
97
|
-
|
97
|
+
eventSourceParser.feed(textDecoder.decode(chunk));
|
98
98
|
}
|
99
99
|
});
|
100
100
|
}
|
101
101
|
function createCallbacksTransformer(callbacks) {
|
102
|
-
const
|
103
|
-
let
|
102
|
+
const textEncoder = new TextEncoder();
|
103
|
+
let aggregatedResponse = "";
|
104
104
|
const { onStart, onToken, onCompletion } = callbacks || {};
|
105
105
|
return new TransformStream({
|
106
106
|
start() {
|
@@ -111,42 +111,47 @@ function createCallbacksTransformer(callbacks) {
|
|
111
111
|
},
|
112
112
|
transform(message, controller) {
|
113
113
|
return __async(this, null, function* () {
|
114
|
-
controller.enqueue(
|
114
|
+
controller.enqueue(textEncoder.encode(message));
|
115
115
|
if (onToken)
|
116
116
|
yield onToken(message);
|
117
117
|
if (onCompletion)
|
118
|
-
|
118
|
+
aggregatedResponse += message;
|
119
119
|
});
|
120
120
|
},
|
121
121
|
flush() {
|
122
122
|
return __async(this, null, function* () {
|
123
|
-
|
123
|
+
if (onCompletion)
|
124
|
+
yield onCompletion(aggregatedResponse);
|
124
125
|
});
|
125
126
|
}
|
126
127
|
});
|
127
128
|
}
|
128
129
|
function trimStartOfStreamHelper() {
|
129
|
-
let
|
130
|
+
let isStreamStart = true;
|
130
131
|
return (text) => {
|
131
|
-
if (
|
132
|
+
if (isStreamStart) {
|
132
133
|
text = text.trimStart();
|
133
|
-
|
134
|
-
|
134
|
+
if (text)
|
135
|
+
isStreamStart = false;
|
136
|
+
}
|
135
137
|
return text;
|
136
138
|
};
|
137
139
|
}
|
138
|
-
function AIStream(
|
139
|
-
if (!
|
140
|
+
function AIStream(response, customParser, callbacks) {
|
141
|
+
if (!response.ok) {
|
140
142
|
throw new Error(
|
141
|
-
`Failed to convert the response to stream. Received status code: ${
|
143
|
+
`Failed to convert the response to stream. Received status code: ${response.status}.`
|
142
144
|
);
|
143
145
|
}
|
144
|
-
const
|
146
|
+
const responseBodyStream = response.body || createEmptyReadableStream();
|
147
|
+
return responseBodyStream.pipeThrough(createEventStreamTransformer(customParser)).pipeThrough(createCallbacksTransformer(callbacks));
|
148
|
+
}
|
149
|
+
function createEmptyReadableStream() {
|
150
|
+
return new ReadableStream({
|
145
151
|
start(controller) {
|
146
152
|
controller.close();
|
147
153
|
}
|
148
154
|
});
|
149
|
-
return stream.pipeThrough(createEventStreamTransformer(customParser)).pipeThrough(createCallbacksTransformer(callbacks));
|
150
155
|
}
|
151
156
|
|
152
157
|
// streams/openai-stream.ts
|
package/dist/index.mjs
CHANGED
@@ -43,34 +43,34 @@ import {
|
|
43
43
|
createParser
|
44
44
|
} from "eventsource-parser";
|
45
45
|
function createEventStreamTransformer(customParser) {
|
46
|
-
const
|
47
|
-
let
|
46
|
+
const textDecoder = new TextDecoder();
|
47
|
+
let eventSourceParser;
|
48
48
|
return new TransformStream({
|
49
49
|
start(controller) {
|
50
50
|
return __async(this, null, function* () {
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
if (data === "[DONE]") {
|
51
|
+
eventSourceParser = createParser(
|
52
|
+
(event) => {
|
53
|
+
if ("data" in event && event.type === "event" && event.data === "[DONE]") {
|
55
54
|
controller.terminate();
|
56
55
|
return;
|
57
56
|
}
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
if ("data" in event) {
|
58
|
+
const parsedMessage = customParser(event.data);
|
59
|
+
if (parsedMessage)
|
60
|
+
controller.enqueue(parsedMessage);
|
61
|
+
}
|
61
62
|
}
|
62
|
-
|
63
|
-
parser = createParser(onParse);
|
63
|
+
);
|
64
64
|
});
|
65
65
|
},
|
66
66
|
transform(chunk) {
|
67
|
-
|
67
|
+
eventSourceParser.feed(textDecoder.decode(chunk));
|
68
68
|
}
|
69
69
|
});
|
70
70
|
}
|
71
71
|
function createCallbacksTransformer(callbacks) {
|
72
|
-
const
|
73
|
-
let
|
72
|
+
const textEncoder = new TextEncoder();
|
73
|
+
let aggregatedResponse = "";
|
74
74
|
const { onStart, onToken, onCompletion } = callbacks || {};
|
75
75
|
return new TransformStream({
|
76
76
|
start() {
|
@@ -81,42 +81,47 @@ function createCallbacksTransformer(callbacks) {
|
|
81
81
|
},
|
82
82
|
transform(message, controller) {
|
83
83
|
return __async(this, null, function* () {
|
84
|
-
controller.enqueue(
|
84
|
+
controller.enqueue(textEncoder.encode(message));
|
85
85
|
if (onToken)
|
86
86
|
yield onToken(message);
|
87
87
|
if (onCompletion)
|
88
|
-
|
88
|
+
aggregatedResponse += message;
|
89
89
|
});
|
90
90
|
},
|
91
91
|
flush() {
|
92
92
|
return __async(this, null, function* () {
|
93
|
-
|
93
|
+
if (onCompletion)
|
94
|
+
yield onCompletion(aggregatedResponse);
|
94
95
|
});
|
95
96
|
}
|
96
97
|
});
|
97
98
|
}
|
98
99
|
function trimStartOfStreamHelper() {
|
99
|
-
let
|
100
|
+
let isStreamStart = true;
|
100
101
|
return (text) => {
|
101
|
-
if (
|
102
|
+
if (isStreamStart) {
|
102
103
|
text = text.trimStart();
|
103
|
-
|
104
|
-
|
104
|
+
if (text)
|
105
|
+
isStreamStart = false;
|
106
|
+
}
|
105
107
|
return text;
|
106
108
|
};
|
107
109
|
}
|
108
|
-
function AIStream(
|
109
|
-
if (!
|
110
|
+
function AIStream(response, customParser, callbacks) {
|
111
|
+
if (!response.ok) {
|
110
112
|
throw new Error(
|
111
|
-
`Failed to convert the response to stream. Received status code: ${
|
113
|
+
`Failed to convert the response to stream. Received status code: ${response.status}.`
|
112
114
|
);
|
113
115
|
}
|
114
|
-
const
|
116
|
+
const responseBodyStream = response.body || createEmptyReadableStream();
|
117
|
+
return responseBodyStream.pipeThrough(createEventStreamTransformer(customParser)).pipeThrough(createCallbacksTransformer(callbacks));
|
118
|
+
}
|
119
|
+
function createEmptyReadableStream() {
|
120
|
+
return new ReadableStream({
|
115
121
|
start(controller) {
|
116
122
|
controller.close();
|
117
123
|
}
|
118
124
|
});
|
119
|
-
return stream.pipeThrough(createEventStreamTransformer(customParser)).pipeThrough(createCallbacksTransformer(callbacks));
|
120
125
|
}
|
121
126
|
|
122
127
|
// streams/openai-stream.ts
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ai",
|
3
|
-
"version": "2.1.
|
3
|
+
"version": "2.1.6",
|
4
4
|
"license": "Apache-2.0",
|
5
5
|
"sideEffects": false,
|
6
6
|
"main": "./dist/index.js",
|
@@ -61,8 +61,8 @@
|
|
61
61
|
"ts-jest": "29.0.3",
|
62
62
|
"tsup": "^6.7.0",
|
63
63
|
"typescript": "^4.5.3",
|
64
|
-
"
|
65
|
-
"
|
64
|
+
"@vercel/ai-tsconfig": "0.0.0",
|
65
|
+
"eslint-config-vercel-ai": "0.0.0"
|
66
66
|
},
|
67
67
|
"peerDependencies": {
|
68
68
|
"react": "^18.0.0",
|
package/react/dist/index.d.ts
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
/**
|
2
2
|
* Shared types between the API and UI packages.
|
3
3
|
*/
|
4
|
-
type Message = {
|
4
|
+
declare type Message = {
|
5
5
|
id: string;
|
6
6
|
createdAt?: Date;
|
7
7
|
content: string;
|
8
8
|
role: 'system' | 'user' | 'assistant';
|
9
9
|
};
|
10
|
-
type CreateMessage = {
|
10
|
+
declare type CreateMessage = {
|
11
11
|
id?: string;
|
12
12
|
createdAt?: Date;
|
13
13
|
content: string;
|
14
14
|
role: 'system' | 'user' | 'assistant';
|
15
15
|
};
|
16
|
-
type UseChatOptions = {
|
16
|
+
declare type UseChatOptions = {
|
17
17
|
/**
|
18
18
|
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
|
19
19
|
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
|
@@ -69,7 +69,7 @@ type UseChatOptions = {
|
|
69
69
|
*/
|
70
70
|
sendExtraMessageFields?: boolean;
|
71
71
|
};
|
72
|
-
type UseCompletionOptions = {
|
72
|
+
declare type UseCompletionOptions = {
|
73
73
|
/**
|
74
74
|
* The API endpoint that accepts a `{ prompt: string }` object and returns
|
75
75
|
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
|
@@ -120,7 +120,7 @@ type UseCompletionOptions = {
|
|
120
120
|
body?: object;
|
121
121
|
};
|
122
122
|
|
123
|
-
type UseChatHelpers = {
|
123
|
+
declare type UseChatHelpers = {
|
124
124
|
/** Current messages in the chat */
|
125
125
|
messages: Message[];
|
126
126
|
/** The error object of the API request */
|
@@ -151,7 +151,7 @@ type UseChatHelpers = {
|
|
151
151
|
/** setState-powered method to update the input value */
|
152
152
|
setInput: React.Dispatch<React.SetStateAction<string>>;
|
153
153
|
/** An input/textarea-ready onChange handler to control the value of the input */
|
154
|
-
handleInputChange: (e:
|
154
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
|
155
155
|
/** Form submission handler to automattically reset input and append a user message */
|
156
156
|
handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
157
157
|
/** Whether the API request is in progress */
|
@@ -159,7 +159,7 @@ type UseChatHelpers = {
|
|
159
159
|
};
|
160
160
|
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
|
161
161
|
|
162
|
-
type UseCompletionHelpers = {
|
162
|
+
declare type UseCompletionHelpers = {
|
163
163
|
/** The current completion result */
|
164
164
|
completion: string;
|
165
165
|
/**
|
@@ -187,7 +187,7 @@ type UseCompletionHelpers = {
|
|
187
187
|
* <input onChange={handleInputChange} value={input} />
|
188
188
|
* ```
|
189
189
|
*/
|
190
|
-
handleInputChange: (e:
|
190
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
|
191
191
|
/**
|
192
192
|
* Form submission handler to automattically reset input and append a user message
|
193
193
|
* @example
|
package/react/dist/index.js
CHANGED
@@ -81,9 +81,13 @@ var nanoid = (0, import_nanoid.customAlphabet)(
|
|
81
81
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
82
82
|
7
|
83
83
|
);
|
84
|
-
|
85
|
-
|
86
|
-
return
|
84
|
+
function createChunkDecoder() {
|
85
|
+
const decoder = new TextDecoder();
|
86
|
+
return function(chunk) {
|
87
|
+
if (!chunk)
|
88
|
+
return "";
|
89
|
+
return decoder.decode(chunk, { stream: true });
|
90
|
+
};
|
87
91
|
}
|
88
92
|
|
89
93
|
// react/use-chat.ts
|
@@ -162,12 +166,13 @@ function useChat({
|
|
162
166
|
const createdAt = /* @__PURE__ */ new Date();
|
163
167
|
const replyId = nanoid();
|
164
168
|
const reader = res.body.getReader();
|
169
|
+
const decode = createChunkDecoder();
|
165
170
|
while (true) {
|
166
171
|
const { done, value } = yield reader.read();
|
167
172
|
if (done) {
|
168
173
|
break;
|
169
174
|
}
|
170
|
-
result +=
|
175
|
+
result += decode(value);
|
171
176
|
mutate(
|
172
177
|
[
|
173
178
|
...messagesSnapshot,
|
@@ -250,7 +255,8 @@ function useChat({
|
|
250
255
|
return;
|
251
256
|
append({
|
252
257
|
content: input,
|
253
|
-
role: "user"
|
258
|
+
role: "user",
|
259
|
+
createdAt: /* @__PURE__ */ new Date()
|
254
260
|
});
|
255
261
|
setInput("");
|
256
262
|
},
|
@@ -340,12 +346,13 @@ function useCompletion({
|
|
340
346
|
}
|
341
347
|
let result = "";
|
342
348
|
const reader = res.body.getReader();
|
349
|
+
const decoder = createChunkDecoder();
|
343
350
|
while (true) {
|
344
351
|
const { done, value } = yield reader.read();
|
345
352
|
if (done) {
|
346
353
|
break;
|
347
354
|
}
|
348
|
-
result +=
|
355
|
+
result += decoder(value);
|
349
356
|
mutate(result, false);
|
350
357
|
if (abortController2 === null) {
|
351
358
|
reader.cancel();
|
package/react/dist/index.mjs
CHANGED
@@ -47,9 +47,13 @@ var nanoid = customAlphabet(
|
|
47
47
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
48
48
|
7
|
49
49
|
);
|
50
|
-
|
51
|
-
|
52
|
-
return
|
50
|
+
function createChunkDecoder() {
|
51
|
+
const decoder = new TextDecoder();
|
52
|
+
return function(chunk) {
|
53
|
+
if (!chunk)
|
54
|
+
return "";
|
55
|
+
return decoder.decode(chunk, { stream: true });
|
56
|
+
};
|
53
57
|
}
|
54
58
|
|
55
59
|
// react/use-chat.ts
|
@@ -128,12 +132,13 @@ function useChat({
|
|
128
132
|
const createdAt = /* @__PURE__ */ new Date();
|
129
133
|
const replyId = nanoid();
|
130
134
|
const reader = res.body.getReader();
|
135
|
+
const decode = createChunkDecoder();
|
131
136
|
while (true) {
|
132
137
|
const { done, value } = yield reader.read();
|
133
138
|
if (done) {
|
134
139
|
break;
|
135
140
|
}
|
136
|
-
result +=
|
141
|
+
result += decode(value);
|
137
142
|
mutate(
|
138
143
|
[
|
139
144
|
...messagesSnapshot,
|
@@ -216,7 +221,8 @@ function useChat({
|
|
216
221
|
return;
|
217
222
|
append({
|
218
223
|
content: input,
|
219
|
-
role: "user"
|
224
|
+
role: "user",
|
225
|
+
createdAt: /* @__PURE__ */ new Date()
|
220
226
|
});
|
221
227
|
setInput("");
|
222
228
|
},
|
@@ -306,12 +312,13 @@ function useCompletion({
|
|
306
312
|
}
|
307
313
|
let result = "";
|
308
314
|
const reader = res.body.getReader();
|
315
|
+
const decoder = createChunkDecoder();
|
309
316
|
while (true) {
|
310
317
|
const { done, value } = yield reader.read();
|
311
318
|
if (done) {
|
312
319
|
break;
|
313
320
|
}
|
314
|
-
result +=
|
321
|
+
result += decoder(value);
|
315
322
|
mutate(result, false);
|
316
323
|
if (abortController2 === null) {
|
317
324
|
reader.cancel();
|
package/svelte/dist/index.d.ts
CHANGED
@@ -3,19 +3,19 @@ import { Readable, Writable } from 'svelte/store';
|
|
3
3
|
/**
|
4
4
|
* Shared types between the API and UI packages.
|
5
5
|
*/
|
6
|
-
type Message = {
|
6
|
+
declare type Message = {
|
7
7
|
id: string;
|
8
8
|
createdAt?: Date;
|
9
9
|
content: string;
|
10
10
|
role: 'system' | 'user' | 'assistant';
|
11
11
|
};
|
12
|
-
type CreateMessage = {
|
12
|
+
declare type CreateMessage = {
|
13
13
|
id?: string;
|
14
14
|
createdAt?: Date;
|
15
15
|
content: string;
|
16
16
|
role: 'system' | 'user' | 'assistant';
|
17
17
|
};
|
18
|
-
type UseChatOptions = {
|
18
|
+
declare type UseChatOptions = {
|
19
19
|
/**
|
20
20
|
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
|
21
21
|
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
|
@@ -71,7 +71,7 @@ type UseChatOptions = {
|
|
71
71
|
*/
|
72
72
|
sendExtraMessageFields?: boolean;
|
73
73
|
};
|
74
|
-
type UseCompletionOptions = {
|
74
|
+
declare type UseCompletionOptions = {
|
75
75
|
/**
|
76
76
|
* The API endpoint that accepts a `{ prompt: string }` object and returns
|
77
77
|
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
|
@@ -122,7 +122,7 @@ type UseCompletionOptions = {
|
|
122
122
|
body?: object;
|
123
123
|
};
|
124
124
|
|
125
|
-
type UseChatHelpers = {
|
125
|
+
declare type UseChatHelpers = {
|
126
126
|
/** Current messages in the chat */
|
127
127
|
messages: Readable<Message[]>;
|
128
128
|
/** The error object of the API request */
|
@@ -157,7 +157,7 @@ type UseChatHelpers = {
|
|
157
157
|
};
|
158
158
|
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
|
159
159
|
|
160
|
-
type UseCompletionHelpers = {
|
160
|
+
declare type UseCompletionHelpers = {
|
161
161
|
/** The current completion result */
|
162
162
|
completion: Readable<string>;
|
163
163
|
/** The error object of the API request */
|
package/svelte/dist/index.js
CHANGED
@@ -395,7 +395,7 @@ var SWR = class {
|
|
395
395
|
}
|
396
396
|
};
|
397
397
|
|
398
|
-
// ../../node_modules/.pnpm/sswr@1.10.0_svelte@3.
|
398
|
+
// ../../node_modules/.pnpm/sswr@1.10.0_svelte@3.54.0/node_modules/sswr/dist/sswr.mjs
|
399
399
|
var import_svelte = require("svelte");
|
400
400
|
function h() {
|
401
401
|
}
|
@@ -506,9 +506,13 @@ var nanoid = (0, import_nanoid.customAlphabet)(
|
|
506
506
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
507
507
|
7
|
508
508
|
);
|
509
|
-
|
510
|
-
|
511
|
-
return
|
509
|
+
function createChunkDecoder() {
|
510
|
+
const decoder = new TextDecoder();
|
511
|
+
return function(chunk) {
|
512
|
+
if (!chunk)
|
513
|
+
return "";
|
514
|
+
return decoder.decode(chunk, { stream: true });
|
515
|
+
};
|
512
516
|
}
|
513
517
|
|
514
518
|
// svelte/use-chat.ts
|
@@ -582,12 +586,13 @@ function useChat({
|
|
582
586
|
const createdAt = /* @__PURE__ */ new Date();
|
583
587
|
const replyId = nanoid();
|
584
588
|
const reader = res.body.getReader();
|
589
|
+
const decoder = createChunkDecoder();
|
585
590
|
while (true) {
|
586
591
|
const { done, value } = yield reader.read();
|
587
592
|
if (done) {
|
588
593
|
break;
|
589
594
|
}
|
590
|
-
result +=
|
595
|
+
result += decoder(value);
|
591
596
|
mutate([
|
592
597
|
...messagesSnapshot,
|
593
598
|
{
|
@@ -659,7 +664,8 @@ function useChat({
|
|
659
664
|
return;
|
660
665
|
append({
|
661
666
|
content: inputValue,
|
662
|
-
role: "user"
|
667
|
+
role: "user",
|
668
|
+
createdAt: /* @__PURE__ */ new Date()
|
663
669
|
});
|
664
670
|
input.set("");
|
665
671
|
};
|
@@ -739,12 +745,13 @@ function useCompletion({
|
|
739
745
|
}
|
740
746
|
let result = "";
|
741
747
|
const reader = res.body.getReader();
|
748
|
+
const decoder = createChunkDecoder();
|
742
749
|
while (true) {
|
743
750
|
const { done, value } = yield reader.read();
|
744
751
|
if (done) {
|
745
752
|
break;
|
746
753
|
}
|
747
|
-
result +=
|
754
|
+
result += decoder(value);
|
748
755
|
mutate(result);
|
749
756
|
if (abortController === null) {
|
750
757
|
reader.cancel();
|
package/svelte/dist/index.mjs
CHANGED
@@ -371,7 +371,7 @@ var SWR = class {
|
|
371
371
|
}
|
372
372
|
};
|
373
373
|
|
374
|
-
// ../../node_modules/.pnpm/sswr@1.10.0_svelte@3.
|
374
|
+
// ../../node_modules/.pnpm/sswr@1.10.0_svelte@3.54.0/node_modules/sswr/dist/sswr.mjs
|
375
375
|
import { beforeUpdate as _, onDestroy as D } from "svelte";
|
376
376
|
function h() {
|
377
377
|
}
|
@@ -482,9 +482,13 @@ var nanoid = customAlphabet(
|
|
482
482
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
483
483
|
7
|
484
484
|
);
|
485
|
-
|
486
|
-
|
487
|
-
return
|
485
|
+
function createChunkDecoder() {
|
486
|
+
const decoder = new TextDecoder();
|
487
|
+
return function(chunk) {
|
488
|
+
if (!chunk)
|
489
|
+
return "";
|
490
|
+
return decoder.decode(chunk, { stream: true });
|
491
|
+
};
|
488
492
|
}
|
489
493
|
|
490
494
|
// svelte/use-chat.ts
|
@@ -558,12 +562,13 @@ function useChat({
|
|
558
562
|
const createdAt = /* @__PURE__ */ new Date();
|
559
563
|
const replyId = nanoid();
|
560
564
|
const reader = res.body.getReader();
|
565
|
+
const decoder = createChunkDecoder();
|
561
566
|
while (true) {
|
562
567
|
const { done, value } = yield reader.read();
|
563
568
|
if (done) {
|
564
569
|
break;
|
565
570
|
}
|
566
|
-
result +=
|
571
|
+
result += decoder(value);
|
567
572
|
mutate([
|
568
573
|
...messagesSnapshot,
|
569
574
|
{
|
@@ -635,7 +640,8 @@ function useChat({
|
|
635
640
|
return;
|
636
641
|
append({
|
637
642
|
content: inputValue,
|
638
|
-
role: "user"
|
643
|
+
role: "user",
|
644
|
+
createdAt: /* @__PURE__ */ new Date()
|
639
645
|
});
|
640
646
|
input.set("");
|
641
647
|
};
|
@@ -715,12 +721,13 @@ function useCompletion({
|
|
715
721
|
}
|
716
722
|
let result = "";
|
717
723
|
const reader = res.body.getReader();
|
724
|
+
const decoder = createChunkDecoder();
|
718
725
|
while (true) {
|
719
726
|
const { done, value } = yield reader.read();
|
720
727
|
if (done) {
|
721
728
|
break;
|
722
729
|
}
|
723
|
-
result +=
|
730
|
+
result += decoder(value);
|
724
731
|
mutate(result);
|
725
732
|
if (abortController === null) {
|
726
733
|
reader.cancel();
|
package/vue/dist/index.d.ts
CHANGED
@@ -3,19 +3,19 @@ import { Ref } from 'vue';
|
|
3
3
|
/**
|
4
4
|
* Shared types between the API and UI packages.
|
5
5
|
*/
|
6
|
-
type Message = {
|
6
|
+
declare type Message = {
|
7
7
|
id: string;
|
8
8
|
createdAt?: Date;
|
9
9
|
content: string;
|
10
10
|
role: 'system' | 'user' | 'assistant';
|
11
11
|
};
|
12
|
-
type CreateMessage = {
|
12
|
+
declare type CreateMessage = {
|
13
13
|
id?: string;
|
14
14
|
createdAt?: Date;
|
15
15
|
content: string;
|
16
16
|
role: 'system' | 'user' | 'assistant';
|
17
17
|
};
|
18
|
-
type UseChatOptions = {
|
18
|
+
declare type UseChatOptions = {
|
19
19
|
/**
|
20
20
|
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
|
21
21
|
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
|
@@ -71,7 +71,7 @@ type UseChatOptions = {
|
|
71
71
|
*/
|
72
72
|
sendExtraMessageFields?: boolean;
|
73
73
|
};
|
74
|
-
type UseCompletionOptions = {
|
74
|
+
declare type UseCompletionOptions = {
|
75
75
|
/**
|
76
76
|
* The API endpoint that accepts a `{ prompt: string }` object and returns
|
77
77
|
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
|
@@ -122,7 +122,7 @@ type UseCompletionOptions = {
|
|
122
122
|
body?: object;
|
123
123
|
};
|
124
124
|
|
125
|
-
type UseChatHelpers = {
|
125
|
+
declare type UseChatHelpers = {
|
126
126
|
/** Current messages in the chat */
|
127
127
|
messages: Ref<Message[]>;
|
128
128
|
/** The error object of the API request */
|
@@ -157,7 +157,7 @@ type UseChatHelpers = {
|
|
157
157
|
};
|
158
158
|
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
|
159
159
|
|
160
|
-
type UseCompletionHelpers = {
|
160
|
+
declare type UseCompletionHelpers = {
|
161
161
|
/** The current completion result */
|
162
162
|
completion: Ref<string>;
|
163
163
|
/** The error object of the API request */
|
package/vue/dist/index.js
CHANGED
@@ -79,9 +79,13 @@ var nanoid = (0, import_nanoid.customAlphabet)(
|
|
79
79
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
80
80
|
7
|
81
81
|
);
|
82
|
-
|
83
|
-
|
84
|
-
return
|
82
|
+
function createChunkDecoder() {
|
83
|
+
const decoder = new TextDecoder();
|
84
|
+
return function(chunk) {
|
85
|
+
if (!chunk)
|
86
|
+
return "";
|
87
|
+
return decoder.decode(chunk, { stream: true });
|
88
|
+
};
|
85
89
|
}
|
86
90
|
|
87
91
|
// vue/use-chat.ts
|
@@ -156,12 +160,13 @@ function useChat({
|
|
156
160
|
const createdAt = /* @__PURE__ */ new Date();
|
157
161
|
const replyId = nanoid();
|
158
162
|
const reader = res.body.getReader();
|
163
|
+
const decoder = createChunkDecoder();
|
159
164
|
while (true) {
|
160
165
|
const { done, value } = yield reader.read();
|
161
166
|
if (done) {
|
162
167
|
break;
|
163
168
|
}
|
164
|
-
result +=
|
169
|
+
result += decoder(value);
|
165
170
|
mutate([
|
166
171
|
...messagesSnapshot,
|
167
172
|
{
|
@@ -315,12 +320,13 @@ function useCompletion({
|
|
315
320
|
}
|
316
321
|
let result = "";
|
317
322
|
const reader = res.body.getReader();
|
323
|
+
const decoder = createChunkDecoder();
|
318
324
|
while (true) {
|
319
325
|
const { done, value } = yield reader.read();
|
320
326
|
if (done) {
|
321
327
|
break;
|
322
328
|
}
|
323
|
-
result +=
|
329
|
+
result += decoder(value);
|
324
330
|
mutate(result);
|
325
331
|
if (abortController === null) {
|
326
332
|
reader.cancel();
|
package/vue/dist/index.mjs
CHANGED
@@ -45,9 +45,13 @@ var nanoid = customAlphabet(
|
|
45
45
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
46
46
|
7
|
47
47
|
);
|
48
|
-
|
49
|
-
|
50
|
-
return
|
48
|
+
function createChunkDecoder() {
|
49
|
+
const decoder = new TextDecoder();
|
50
|
+
return function(chunk) {
|
51
|
+
if (!chunk)
|
52
|
+
return "";
|
53
|
+
return decoder.decode(chunk, { stream: true });
|
54
|
+
};
|
51
55
|
}
|
52
56
|
|
53
57
|
// vue/use-chat.ts
|
@@ -122,12 +126,13 @@ function useChat({
|
|
122
126
|
const createdAt = /* @__PURE__ */ new Date();
|
123
127
|
const replyId = nanoid();
|
124
128
|
const reader = res.body.getReader();
|
129
|
+
const decoder = createChunkDecoder();
|
125
130
|
while (true) {
|
126
131
|
const { done, value } = yield reader.read();
|
127
132
|
if (done) {
|
128
133
|
break;
|
129
134
|
}
|
130
|
-
result +=
|
135
|
+
result += decoder(value);
|
131
136
|
mutate([
|
132
137
|
...messagesSnapshot,
|
133
138
|
{
|
@@ -281,12 +286,13 @@ function useCompletion({
|
|
281
286
|
}
|
282
287
|
let result = "";
|
283
288
|
const reader = res.body.getReader();
|
289
|
+
const decoder = createChunkDecoder();
|
284
290
|
while (true) {
|
285
291
|
const { done, value } = yield reader.read();
|
286
292
|
if (done) {
|
287
293
|
break;
|
288
294
|
}
|
289
|
-
result +=
|
295
|
+
result += decoder(value);
|
290
296
|
mutate(result);
|
291
297
|
if (abortController === null) {
|
292
298
|
reader.cancel();
|