@xsai/stream-text 0.2.0 → 0.2.2
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 +36 -2
- package/dist/index.js +36 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ToolMessagePart, FinishReason, Usage, ToolCall, ChatOptions, AssistantMessage, Message, StepType, CompletionToolCall, CompletionToolResult, Tool } from '@xsai/shared-chat';
|
|
2
|
+
|
|
3
|
+
type StreamTextEvent = {
|
|
4
|
+
error: unknown;
|
|
5
|
+
type: 'error';
|
|
6
|
+
} | {
|
|
7
|
+
error?: unknown;
|
|
8
|
+
id: string;
|
|
9
|
+
result?: string | ToolMessagePart[];
|
|
10
|
+
type: 'tool-call-result';
|
|
11
|
+
} | {
|
|
12
|
+
finishReason?: FinishReason;
|
|
13
|
+
type: 'finish';
|
|
14
|
+
usage?: Usage;
|
|
15
|
+
} | {
|
|
16
|
+
reasoning: string;
|
|
17
|
+
type: 'reasoning';
|
|
18
|
+
} | {
|
|
19
|
+
refusal: string;
|
|
20
|
+
type: 'refusal';
|
|
21
|
+
} | {
|
|
22
|
+
text: string;
|
|
23
|
+
type: 'text-delta';
|
|
24
|
+
} | {
|
|
25
|
+
toolCall: ToolCall;
|
|
26
|
+
type: 'tool-call';
|
|
27
|
+
} | {
|
|
28
|
+
toolCall: ToolCall;
|
|
29
|
+
type: 'tool-call-delta';
|
|
30
|
+
};
|
|
2
31
|
|
|
3
32
|
interface StreamTextChunkResult {
|
|
4
33
|
choices: {
|
|
@@ -29,6 +58,11 @@ interface StreamTextOptions extends ChatOptions {
|
|
|
29
58
|
* @param chunk - The current chunk of the stream.
|
|
30
59
|
*/
|
|
31
60
|
onChunk?: (chunk: StreamTextChunkResult) => Promise<unknown> | unknown;
|
|
61
|
+
/**
|
|
62
|
+
* Callback function that is called with each event of the stream.
|
|
63
|
+
* @param event - The current event of the stream.
|
|
64
|
+
*/
|
|
65
|
+
onEvent?: (event: StreamTextEvent) => Promise<unknown> | unknown;
|
|
32
66
|
/**
|
|
33
67
|
* Callback function that is called when the stream is finished.
|
|
34
68
|
* @param result - The final result of the stream.
|
|
@@ -94,4 +128,4 @@ interface StreamTextToolCall extends ToolCall {
|
|
|
94
128
|
}
|
|
95
129
|
declare const streamText: (options: StreamTextOptions) => Promise<StreamTextResult>;
|
|
96
130
|
|
|
97
|
-
export { type StreamTextChunkResult, type StreamTextOptions, type StreamTextResult, type StreamTextStep, streamText };
|
|
131
|
+
export { type StreamTextChunkResult, type StreamTextEvent, type StreamTextOptions, type StreamTextResult, type StreamTextStep, streamText };
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,8 @@ const streamText = async (options) => {
|
|
|
61
61
|
};
|
|
62
62
|
const choiceState = {};
|
|
63
63
|
let buffer = "";
|
|
64
|
+
let finishReason;
|
|
65
|
+
let usage;
|
|
64
66
|
let shouldOutputText = true;
|
|
65
67
|
const endToolCallByIndex = (state, idx) => {
|
|
66
68
|
if (state.endedToolCallIndex.has(idx)) {
|
|
@@ -99,13 +101,21 @@ const streamText = async (options) => {
|
|
|
99
101
|
stepCtrl.error(reason);
|
|
100
102
|
textCtrl.error(reason);
|
|
101
103
|
},
|
|
104
|
+
close: () => {
|
|
105
|
+
options2.onEvent?.({
|
|
106
|
+
finishReason,
|
|
107
|
+
type: "finish",
|
|
108
|
+
usage
|
|
109
|
+
});
|
|
110
|
+
},
|
|
102
111
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
103
112
|
write: async (chunk) => {
|
|
104
113
|
options2.onChunk?.(chunk);
|
|
105
114
|
chunkCtrl.enqueue(chunk);
|
|
115
|
+
usage = chunk.usage;
|
|
116
|
+
if (chunk.choices == null || chunk.choices.length === 0)
|
|
117
|
+
return;
|
|
106
118
|
const choice = chunk.choices[0];
|
|
107
|
-
if (!choice)
|
|
108
|
-
throw new XSAIError("no choice found");
|
|
109
119
|
if (choice.delta.tool_calls) {
|
|
110
120
|
shouldOutputText = false;
|
|
111
121
|
}
|
|
@@ -118,6 +128,7 @@ const streamText = async (options) => {
|
|
|
118
128
|
}
|
|
119
129
|
};
|
|
120
130
|
if (finish_reason !== void 0) {
|
|
131
|
+
finishReason = finish_reason;
|
|
121
132
|
step.finishReason = finish_reason;
|
|
122
133
|
choiceSnapshot.finishReason = finish_reason;
|
|
123
134
|
if (finish_reason === "length") {
|
|
@@ -133,12 +144,25 @@ const streamText = async (options) => {
|
|
|
133
144
|
Object.assign(message, rests);
|
|
134
145
|
if (refusal !== void 0) {
|
|
135
146
|
message.refusal = (message.refusal || "") + (refusal || "");
|
|
147
|
+
options2.onEvent?.({
|
|
148
|
+
refusal: message.refusal,
|
|
149
|
+
type: "refusal"
|
|
150
|
+
});
|
|
136
151
|
}
|
|
137
152
|
if (content !== void 0) {
|
|
138
153
|
message.content = (message.content || "") + (content || "");
|
|
139
154
|
shouldOutputText && textCtrl?.enqueue(content);
|
|
155
|
+
options2.onEvent?.({
|
|
156
|
+
text: content,
|
|
157
|
+
type: "text-delta"
|
|
158
|
+
});
|
|
140
159
|
}
|
|
141
|
-
for (const
|
|
160
|
+
for (const tool_call of tool_calls || []) {
|
|
161
|
+
options2.onEvent?.({
|
|
162
|
+
toolCall: tool_call,
|
|
163
|
+
type: "tool-call-delta"
|
|
164
|
+
});
|
|
165
|
+
const { function: fn, id, index: index2, type } = tool_call;
|
|
142
166
|
message.toolCalls ??= {};
|
|
143
167
|
const toolCall = message.toolCalls[index2] ??= {
|
|
144
168
|
function: {
|
|
@@ -202,6 +226,10 @@ const streamText = async (options) => {
|
|
|
202
226
|
if (state.toolCallResults[toolCall.id]) {
|
|
203
227
|
return;
|
|
204
228
|
}
|
|
229
|
+
options2.onEvent?.({
|
|
230
|
+
toolCall,
|
|
231
|
+
type: "tool-call"
|
|
232
|
+
});
|
|
205
233
|
try {
|
|
206
234
|
const { parsedArgs, result, toolName } = await executeTool({
|
|
207
235
|
abortSignal: options2.abortSignal,
|
|
@@ -222,6 +250,11 @@ const streamText = async (options) => {
|
|
|
222
250
|
toolCallId: toolCall.id,
|
|
223
251
|
toolName
|
|
224
252
|
});
|
|
253
|
+
options2.onEvent?.({
|
|
254
|
+
id: toolCall.id,
|
|
255
|
+
result,
|
|
256
|
+
type: "tool-call-result"
|
|
257
|
+
});
|
|
225
258
|
} catch (error) {
|
|
226
259
|
state.toolCallErrors[idx] = error;
|
|
227
260
|
}
|