@xsai/stream-text 0.4.0-beta.1 → 0.4.0-beta.3
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/dist/index.d.ts +2 -1
- package/dist/index.js +76 -65
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -51,8 +51,9 @@ interface StreamTextResult {
|
|
|
51
51
|
messages: Promise<Message[]>;
|
|
52
52
|
steps: Promise<CompletionStep[]>;
|
|
53
53
|
textStream: ReadableStream<string>;
|
|
54
|
+
totalUsage: Promise<undefined | Usage>;
|
|
54
55
|
usage: Promise<undefined | Usage>;
|
|
55
56
|
}
|
|
56
|
-
declare const streamText: (options: StreamTextOptions) =>
|
|
57
|
+
declare const streamText: (options: StreamTextOptions) => StreamTextResult;
|
|
57
58
|
|
|
58
59
|
export { type StreamTextEvent, type StreamTextOptions, type StreamTextResult, streamText };
|
package/dist/index.js
CHANGED
|
@@ -82,14 +82,16 @@ const transformChunk = () => {
|
|
|
82
82
|
});
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
const streamText =
|
|
85
|
+
const streamText = (options) => {
|
|
86
86
|
const steps = [];
|
|
87
87
|
const messages = structuredClone(options.messages);
|
|
88
88
|
const maxSteps = options.maxSteps ?? 1;
|
|
89
89
|
let usage;
|
|
90
|
+
let totalUsage;
|
|
90
91
|
const resultSteps = new DelayedPromise();
|
|
91
92
|
const resultMessages = new DelayedPromise();
|
|
92
93
|
const resultUsage = new DelayedPromise();
|
|
94
|
+
const resultTotalUsage = new DelayedPromise();
|
|
93
95
|
let eventCtrl;
|
|
94
96
|
let textCtrl;
|
|
95
97
|
const eventStream = new ReadableStream({ start: (controller) => eventCtrl = controller });
|
|
@@ -102,9 +104,21 @@ const streamText = async (options) => {
|
|
|
102
104
|
steps.push(step);
|
|
103
105
|
void options.onStepFinish?.(step);
|
|
104
106
|
};
|
|
105
|
-
const
|
|
107
|
+
const doStream = async () => {
|
|
108
|
+
const { body: stream } = await chat({
|
|
109
|
+
...options,
|
|
110
|
+
maxSteps: void 0,
|
|
111
|
+
messages,
|
|
112
|
+
stream: true,
|
|
113
|
+
streamOptions: options.streamOptions != null ? objCamelToSnake(options.streamOptions) : void 0
|
|
114
|
+
});
|
|
106
115
|
const pushUsage = (u) => {
|
|
107
116
|
usage = u;
|
|
117
|
+
totalUsage = totalUsage ? {
|
|
118
|
+
completion_tokens: totalUsage.completion_tokens + u.completion_tokens,
|
|
119
|
+
prompt_tokens: totalUsage.prompt_tokens + u.prompt_tokens,
|
|
120
|
+
total_tokens: totalUsage.total_tokens + u.total_tokens
|
|
121
|
+
} : { ...u };
|
|
108
122
|
};
|
|
109
123
|
let text = "";
|
|
110
124
|
const pushText = (content) => {
|
|
@@ -115,55 +129,47 @@ const streamText = async (options) => {
|
|
|
115
129
|
const toolCalls = [];
|
|
116
130
|
const toolResults = [];
|
|
117
131
|
let finishReason = "other";
|
|
118
|
-
await
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
pushEvent({
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const { index } = toolCall;
|
|
155
|
-
if (!tool_calls.at(index)) {
|
|
156
|
-
tool_calls[index] = toolCall;
|
|
157
|
-
pushEvent({ toolCallId: toolCall.id, toolName: toolCall.function.name, type: "tool-call-streaming-start" });
|
|
158
|
-
} else {
|
|
159
|
-
tool_calls[index].function.arguments += toolCall.function.arguments;
|
|
160
|
-
pushEvent({ argsTextDelta: toolCall.function.arguments, toolCallId: toolCall.id, toolName: toolCall.function.name, type: "tool-call-delta" });
|
|
161
|
-
}
|
|
132
|
+
await stream.pipeThrough(transformChunk()).pipeTo(new WritableStream({
|
|
133
|
+
abort: (reason) => {
|
|
134
|
+
eventCtrl?.error(reason);
|
|
135
|
+
textCtrl?.error(reason);
|
|
136
|
+
},
|
|
137
|
+
close: () => {
|
|
138
|
+
},
|
|
139
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
140
|
+
write: (chunk) => {
|
|
141
|
+
if (chunk.usage)
|
|
142
|
+
pushUsage(chunk.usage);
|
|
143
|
+
if (chunk.choices == null || chunk.choices.length === 0)
|
|
144
|
+
return;
|
|
145
|
+
const choice = chunk.choices[0];
|
|
146
|
+
if (choice.delta.reasoning_content != null)
|
|
147
|
+
pushEvent({ text: choice.delta.reasoning_content, type: "reasoning-delta" });
|
|
148
|
+
if (choice.finish_reason != null)
|
|
149
|
+
finishReason = choice.finish_reason;
|
|
150
|
+
if (choice.delta.tool_calls?.length === 0 || choice.delta.tool_calls == null) {
|
|
151
|
+
if (choice.delta.content != null) {
|
|
152
|
+
pushEvent({ text: choice.delta.content, type: "text-delta" });
|
|
153
|
+
pushText(choice.delta.content);
|
|
154
|
+
} else if (choice.delta.refusal != null) {
|
|
155
|
+
pushEvent({ error: choice.delta.refusal, type: "error" });
|
|
156
|
+
} else if (choice.finish_reason != null) {
|
|
157
|
+
pushEvent({ finishReason: choice.finish_reason, type: "finish", usage });
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
for (const toolCall of choice.delta.tool_calls) {
|
|
161
|
+
const { index } = toolCall;
|
|
162
|
+
if (!tool_calls.at(index)) {
|
|
163
|
+
tool_calls[index] = toolCall;
|
|
164
|
+
pushEvent({ toolCallId: toolCall.id, toolName: toolCall.function.name, type: "tool-call-streaming-start" });
|
|
165
|
+
} else {
|
|
166
|
+
tool_calls[index].function.arguments += toolCall.function.arguments;
|
|
167
|
+
pushEvent({ argsTextDelta: toolCall.function.arguments, toolCallId: toolCall.id, toolName: toolCall.function.name, type: "tool-call-delta" });
|
|
162
168
|
}
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
|
-
}
|
|
166
|
-
);
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
167
173
|
messages.push({ content: text, role: "assistant", tool_calls });
|
|
168
174
|
if (tool_calls.length !== 0) {
|
|
169
175
|
for (const toolCall of tool_calls) {
|
|
@@ -195,29 +201,34 @@ const streamText = async (options) => {
|
|
|
195
201
|
usage
|
|
196
202
|
});
|
|
197
203
|
if (toolCalls.length !== 0 && steps.length < maxSteps)
|
|
198
|
-
return async () =>
|
|
204
|
+
return async () => doStream();
|
|
199
205
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
206
|
+
void (async () => {
|
|
207
|
+
try {
|
|
208
|
+
await trampoline(async () => doStream());
|
|
209
|
+
eventCtrl?.close();
|
|
210
|
+
textCtrl?.close();
|
|
211
|
+
} catch (err) {
|
|
212
|
+
eventCtrl?.error(err);
|
|
213
|
+
textCtrl?.error(err);
|
|
214
|
+
resultSteps.reject(err);
|
|
215
|
+
resultMessages.reject(err);
|
|
216
|
+
resultUsage.reject(err);
|
|
217
|
+
resultTotalUsage.reject(err);
|
|
218
|
+
} finally {
|
|
219
|
+
resultSteps.resolve(steps);
|
|
220
|
+
resultMessages.resolve(messages);
|
|
221
|
+
resultUsage.resolve(usage);
|
|
222
|
+
resultTotalUsage.resolve(totalUsage);
|
|
223
|
+
void options.onFinish?.(steps.at(-1));
|
|
224
|
+
}
|
|
225
|
+
})();
|
|
216
226
|
return {
|
|
217
227
|
fullStream: eventStream,
|
|
218
228
|
messages: resultMessages.promise,
|
|
219
229
|
steps: resultSteps.promise,
|
|
220
230
|
textStream,
|
|
231
|
+
totalUsage: resultTotalUsage.promise,
|
|
221
232
|
usage: resultUsage.promise
|
|
222
233
|
};
|
|
223
234
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsai/stream-text",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.4.0-beta.
|
|
4
|
+
"version": "0.4.0-beta.3",
|
|
5
5
|
"description": "extra-small AI SDK.",
|
|
6
6
|
"author": "Moeru AI",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@xsai/shared-chat": "~0.4.0-beta.
|
|
32
|
+
"@xsai/shared-chat": "~0.4.0-beta.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"valibot": "^1.0.0",
|
|
36
|
-
"@xsai/
|
|
37
|
-
"@xsai/
|
|
36
|
+
"@xsai/shared": "~0.4.0-beta.3",
|
|
37
|
+
"@xsai/tool": "~0.4.0-beta.3"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "pkgroll",
|