@agentica/core 0.32.3 → 0.32.5
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/lib/context/MicroAgenticaContext.d.ts +4 -0
- package/lib/events/AgenticaJsonParseErrorEvent.d.ts +1 -0
- package/lib/events/AgenticaValidateEvent.d.ts +1 -0
- package/lib/factory/events.d.ts +2 -0
- package/lib/factory/events.js +3 -0
- package/lib/factory/events.js.map +1 -1
- package/lib/index.mjs +44 -28
- package/lib/index.mjs.map +1 -1
- package/lib/json/IAgenticaEventJson.d.ts +2 -0
- package/lib/orchestrate/call.js +8 -6
- package/lib/orchestrate/call.js.map +1 -1
- package/lib/orchestrate/cancel.js +1 -1
- package/lib/orchestrate/cancel.js.map +1 -1
- package/lib/orchestrate/describe.js +1 -1
- package/lib/orchestrate/describe.js.map +1 -1
- package/lib/orchestrate/initialize.js +1 -1
- package/lib/orchestrate/initialize.js.map +1 -1
- package/lib/orchestrate/select.js +5 -5
- package/lib/orchestrate/select.js.map +1 -1
- package/lib/utils/AssistantMessageEmptyError.js +9 -0
- package/lib/utils/AssistantMessageEmptyError.js.map +1 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.d.ts +1 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.js +2 -2
- package/lib/utils/ChatGptCompletionStreamingUtil.js.map +1 -1
- package/lib/utils/StreamUtil.d.ts +7 -4
- package/lib/utils/StreamUtil.js +17 -14
- package/lib/utils/StreamUtil.js.map +1 -1
- package/lib/utils/StreamUtil.spec.js +12 -12
- package/lib/utils/StreamUtil.spec.js.map +1 -1
- package/lib/utils/request.js +5 -4
- package/lib/utils/request.js.map +1 -1
- package/package.json +1 -1
- package/src/context/MicroAgenticaContext.ts +4 -0
- package/src/events/AgenticaJsonParseErrorEvent.ts +1 -0
- package/src/events/AgenticaValidateEvent.ts +2 -0
- package/src/factory/events.ts +5 -0
- package/src/json/IAgenticaEventJson.ts +4 -0
- package/src/orchestrate/call.ts +5 -1
- package/src/orchestrate/cancel.ts +1 -1
- package/src/orchestrate/describe.ts +1 -1
- package/src/orchestrate/initialize.ts +1 -1
- package/src/orchestrate/select.ts +2 -2
- package/src/utils/AssistantMessageEmptyError.ts +8 -1
- package/src/utils/ChatGptCompletionStreamingUtil.ts +2 -2
- package/src/utils/StreamUtil.spec.ts +12 -9
- package/src/utils/StreamUtil.ts +15 -11
- package/src/utils/request.ts +4 -3
package/lib/utils/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,iFAA8E;AAC9E,6CAA+E;AAC/E,wCAAgD;AAGhD,mGAAgG;AAEhG,+BAA0B;AAEnB,MAAM,sCAAsC,GAAG,CAAiC,KAMtF,EAAE,EAAE,CAAC,CACJ,MAA2B,EAC3B,IAA0E,EAC1E,EAAE;;IACF,MAAM,KAAK,GAAyB,IAAA,4BAAkB,EAAC;QACrD,MAAM;QACN,IAAI,kCACC,IAAI,KACP,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EACzB,MAAM,EAAE,IAAI,EACZ,cAAc,EAAE;gBACd,aAAa,EAAE,IAAI;aACpB,GACF;QACD,OAAO,kCACF,KAAK,CAAC,MAAM,CAAC,OAAO,KACvB,MAAM,EAAE,KAAK,CAAC,WAAW,GAC1B;KACF,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5B,aAAa;IACb,MAAM,eAAe,GAAG,MAAA,MAAA,KAAK,CAAC,MAAM,0CAAE,eAAe,mCAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAClE,MAAM,KAAK,CAAC,KAAK,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,MAAM,CAAC,GAAS,EAAE;QACnC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CACnD,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,OAAO,CACd,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC3D,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAA,CAAC,EAAE,CAAC;IAEL,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG,uBAAU,CAAC,SAAS,CAC5D,UAAU,CAAC,gBAAgB,EAAgC,EAC3D,KAAK,CAAC,EAAE,CACN,2DAA4B,CAAC,wBAAwB,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/utils/request.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/factory/events.ts
CHANGED
|
@@ -118,6 +118,7 @@ export function createJsonParseErrorEvent<Model extends ILlmSchema.Model>(props:
|
|
|
118
118
|
operation: AgenticaOperation<Model>;
|
|
119
119
|
arguments: string;
|
|
120
120
|
errorMessage: string;
|
|
121
|
+
life: number;
|
|
121
122
|
}): AgenticaJsonParseErrorEvent<Model> {
|
|
122
123
|
const created_at: string = new Date().toISOString();
|
|
123
124
|
return {
|
|
@@ -127,6 +128,7 @@ export function createJsonParseErrorEvent<Model extends ILlmSchema.Model>(props:
|
|
|
127
128
|
operation: props.operation,
|
|
128
129
|
arguments: props.arguments,
|
|
129
130
|
errorMessage: props.errorMessage,
|
|
131
|
+
life: props.life,
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -134,6 +136,7 @@ export function createValidateEvent<Model extends ILlmSchema.Model>(props: {
|
|
|
134
136
|
id: string;
|
|
135
137
|
operation: AgenticaOperation<Model>;
|
|
136
138
|
result: IValidation.IFailure;
|
|
139
|
+
life: number;
|
|
137
140
|
}): AgenticaValidateEvent<Model> {
|
|
138
141
|
const created_at: string = new Date().toISOString();
|
|
139
142
|
return {
|
|
@@ -142,12 +145,14 @@ export function createValidateEvent<Model extends ILlmSchema.Model>(props: {
|
|
|
142
145
|
created_at,
|
|
143
146
|
operation: props.operation,
|
|
144
147
|
result: props.result,
|
|
148
|
+
life: props.life,
|
|
145
149
|
toJSON: () => ({
|
|
146
150
|
type: "validate",
|
|
147
151
|
id: props.id,
|
|
148
152
|
created_at,
|
|
149
153
|
operation: props.operation.toJSON(),
|
|
150
154
|
result: props.result,
|
|
155
|
+
life: props.life,
|
|
151
156
|
}),
|
|
152
157
|
};
|
|
153
158
|
}
|
|
@@ -119,6 +119,8 @@ export namespace IAgenticaEventJson {
|
|
|
119
119
|
* Validation result as a failure.
|
|
120
120
|
*/
|
|
121
121
|
result: IValidation.IFailure;
|
|
122
|
+
|
|
123
|
+
life: number;
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
export interface IJsonParseError extends IBase<"jsonParseError"> {
|
|
@@ -138,6 +140,8 @@ export namespace IAgenticaEventJson {
|
|
|
138
140
|
* Error message of the JSON parse error.
|
|
139
141
|
*/
|
|
140
142
|
errorMessage: string;
|
|
143
|
+
|
|
144
|
+
life: number;
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
/**
|
package/src/orchestrate/call.ts
CHANGED
|
@@ -35,7 +35,7 @@ export async function call<Model extends ILlmSchema.Model>(
|
|
|
35
35
|
ctx: AgenticaContext<Model> | MicroAgenticaContext<Model>,
|
|
36
36
|
operations: AgenticaOperation<Model>[],
|
|
37
37
|
): Promise<AgenticaExecuteEvent<Model>[]> {
|
|
38
|
-
const _retryFn = __get_retry(
|
|
38
|
+
const _retryFn = __get_retry(1);
|
|
39
39
|
const retryFn = async (fn: (prevError?: unknown) => Promise<OpenAI.ChatCompletion>) => {
|
|
40
40
|
return _retryFn(fn).catch((e) => {
|
|
41
41
|
if (e instanceof AssistantMessageEmptyError) {
|
|
@@ -182,6 +182,7 @@ async function predicate<Model extends ILlmSchema.Model>(
|
|
|
182
182
|
= parseArguments(
|
|
183
183
|
operation,
|
|
184
184
|
toolCall,
|
|
185
|
+
life,
|
|
185
186
|
);
|
|
186
187
|
await ctx.dispatch(call);
|
|
187
188
|
if (call.type === "jsonParseError") {
|
|
@@ -195,6 +196,7 @@ async function predicate<Model extends ILlmSchema.Model>(
|
|
|
195
196
|
id: toolCall.id,
|
|
196
197
|
operation,
|
|
197
198
|
result: check,
|
|
199
|
+
life,
|
|
198
200
|
});
|
|
199
201
|
await ctx.dispatch(event);
|
|
200
202
|
return correctTypeError(
|
|
@@ -292,6 +294,7 @@ async function correctJsonError<Model extends ILlmSchema.Model>(
|
|
|
292
294
|
function parseArguments<Model extends ILlmSchema.Model>(
|
|
293
295
|
operation: AgenticaOperation<Model>,
|
|
294
296
|
toolCall: OpenAI.ChatCompletionMessageToolCall,
|
|
297
|
+
life: number,
|
|
295
298
|
): AgenticaCallEvent<Model> | AgenticaJsonParseErrorEvent<Model> {
|
|
296
299
|
try {
|
|
297
300
|
const data: Record<string, unknown> = JSON.parse(toolCall.function.arguments);
|
|
@@ -307,6 +310,7 @@ function parseArguments<Model extends ILlmSchema.Model>(
|
|
|
307
310
|
operation,
|
|
308
311
|
arguments: toolCall.function.arguments,
|
|
309
312
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
313
|
+
life,
|
|
310
314
|
});
|
|
311
315
|
}
|
|
312
316
|
}
|
|
@@ -171,7 +171,7 @@ async function step<Model extends ILlmSchema.Model>(
|
|
|
171
171
|
// parallel_tool_calls: true,
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
const chunks = await StreamUtil.readAll(completionStream);
|
|
174
|
+
const chunks = await StreamUtil.readAll(completionStream, ctx.abortSignal);
|
|
175
175
|
const completion = ChatGptCompletionMessageUtil.merge(chunks);
|
|
176
176
|
|
|
177
177
|
// ----
|
|
@@ -66,7 +66,7 @@ export async function initialize<Model extends ILlmSchema.Model>(ctx: AgenticaCo
|
|
|
66
66
|
const completion = await reduceStreamingWithDispatch(completionStream, (props) => {
|
|
67
67
|
const event: AgenticaAssistantMessageEvent = createAssistantMessageEvent(props);
|
|
68
68
|
ctx.dispatch(event);
|
|
69
|
-
});
|
|
69
|
+
}, ctx.abortSignal);
|
|
70
70
|
|
|
71
71
|
if (completion === null) {
|
|
72
72
|
throw new Error("No completion received");
|
|
@@ -95,7 +95,7 @@ async function step<Model extends ILlmSchema.Model>(
|
|
|
95
95
|
retry: number,
|
|
96
96
|
failures?: IFailure[],
|
|
97
97
|
): Promise<void> {
|
|
98
|
-
const _retryFn = __get_retry(
|
|
98
|
+
const _retryFn = __get_retry(1);
|
|
99
99
|
const retryFn = async (fn: (prevError?: unknown) => Promise<OpenAI.ChatCompletion>) => {
|
|
100
100
|
return _retryFn(fn).catch((e) => {
|
|
101
101
|
if (e instanceof AssistantMessageEmptyError) {
|
|
@@ -194,7 +194,7 @@ async function step<Model extends ILlmSchema.Model>(
|
|
|
194
194
|
const completion = await reduceStreamingWithDispatch(stream, (props) => {
|
|
195
195
|
const event: AgenticaAssistantMessageEvent = createAssistantMessageEvent(props);
|
|
196
196
|
void ctx.dispatch(event).catch(() => {});
|
|
197
|
-
});
|
|
197
|
+
}, ctx.abortSignal);
|
|
198
198
|
const allAssistantMessagesEmpty = completion.choices.every(v => v.message.tool_calls == null && v.message.content === "");
|
|
199
199
|
if (allAssistantMessagesEmpty) {
|
|
200
200
|
const firstChoice = completion.choices.at(0);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
export class AssistantMessageEmptyError extends Error {
|
|
2
2
|
constructor() {
|
|
3
3
|
super();
|
|
4
|
+
const proto = new.target.prototype;
|
|
5
|
+
// eslint-disable-next-line
|
|
6
|
+
if (Object.setPrototypeOf) { Object.setPrototypeOf(this, proto); }
|
|
7
|
+
else {
|
|
8
|
+
// eslint-disable-next-line
|
|
9
|
+
(this as any).__proto__ = proto;
|
|
10
|
+
}
|
|
4
11
|
}
|
|
5
12
|
}
|
|
6
13
|
|
|
@@ -10,4 +17,4 @@ export class AssistantMessageEmptyWithReasoningError extends AssistantMessageEmp
|
|
|
10
17
|
super();
|
|
11
18
|
this.reasoning = reasoning;
|
|
12
19
|
}
|
|
13
|
-
}
|
|
20
|
+
}
|
|
@@ -7,7 +7,7 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
|
|
|
7
7
|
done: () => boolean;
|
|
8
8
|
get: () => string;
|
|
9
9
|
join: () => Promise<string>;
|
|
10
|
-
}) => void) {
|
|
10
|
+
}) => void, abortSignal?: AbortSignal) {
|
|
11
11
|
const streamContext = new Map<number, { content: string; mpsc: MPSC<string> }>();
|
|
12
12
|
|
|
13
13
|
const nullableCompletion = await StreamUtil.reduce<ChatCompletionChunk, Promise<ChatCompletion>>(stream, async (accPromise, chunk) => {
|
|
@@ -59,7 +59,7 @@ async function reduceStreamingWithDispatch(stream: ReadableStream<ChatCompletion
|
|
|
59
59
|
}
|
|
60
60
|
registerContext(chunk.choices);
|
|
61
61
|
return ChatGptCompletionMessageUtil.accumulate(acc, chunk);
|
|
62
|
-
});
|
|
62
|
+
}, { abortSignal });
|
|
63
63
|
|
|
64
64
|
if (nullableCompletion == null) {
|
|
65
65
|
throw new Error(
|
|
@@ -149,7 +149,7 @@ describe("streamUtil", () => {
|
|
|
149
149
|
const stringResult = await StreamUtil.reduce<number, string>(
|
|
150
150
|
stringStream,
|
|
151
151
|
(acc, cur) => acc + cur.toString(),
|
|
152
|
-
"",
|
|
152
|
+
{ initial: ""},
|
|
153
153
|
);
|
|
154
154
|
|
|
155
155
|
expect(stringResult).toBe("123");
|
|
@@ -160,7 +160,7 @@ describe("streamUtil", () => {
|
|
|
160
160
|
const sumResult = await StreamUtil.reduce<number, number>(
|
|
161
161
|
sumStream,
|
|
162
162
|
(acc, cur) => acc + cur,
|
|
163
|
-
0,
|
|
163
|
+
{ initial: 0 },
|
|
164
164
|
);
|
|
165
165
|
|
|
166
166
|
expect(sumResult).toBe(15);
|
|
@@ -171,6 +171,7 @@ describe("streamUtil", () => {
|
|
|
171
171
|
const noInitialResult = await StreamUtil.reduce<number>(
|
|
172
172
|
noInitialStream,
|
|
173
173
|
(acc, cur) => acc + cur,
|
|
174
|
+
{ initial: 0 },
|
|
174
175
|
);
|
|
175
176
|
|
|
176
177
|
expect(noInitialResult).toBe(10);
|
|
@@ -181,7 +182,7 @@ describe("streamUtil", () => {
|
|
|
181
182
|
const emptyResult = await StreamUtil.reduce<number, string>(
|
|
182
183
|
emptyStream,
|
|
183
184
|
(acc, cur) => acc + cur.toString(),
|
|
184
|
-
"initial value",
|
|
185
|
+
{ initial: "initial value" },
|
|
185
186
|
);
|
|
186
187
|
|
|
187
188
|
expect(emptyResult).toBe("initial value");
|
|
@@ -192,6 +193,7 @@ describe("streamUtil", () => {
|
|
|
192
193
|
const emptyNoInitialResult = await StreamUtil.reduce<number>(
|
|
193
194
|
emptyNoInitialStream,
|
|
194
195
|
(acc, cur) => acc + cur,
|
|
196
|
+
{ initial: 0 },
|
|
195
197
|
);
|
|
196
198
|
|
|
197
199
|
expect(emptyNoInitialResult).toBeNull();
|
|
@@ -202,7 +204,7 @@ describe("streamUtil", () => {
|
|
|
202
204
|
const stringResult = await StreamUtil.reduce<number, string>(
|
|
203
205
|
stringStream,
|
|
204
206
|
(acc, cur) => acc + cur.toString(),
|
|
205
|
-
"",
|
|
207
|
+
{ initial: "" },
|
|
206
208
|
);
|
|
207
209
|
|
|
208
210
|
expect(stringResult).toBe("123");
|
|
@@ -213,6 +215,7 @@ describe("streamUtil", () => {
|
|
|
213
215
|
const noInitialResult = await StreamUtil.reduce<number>(
|
|
214
216
|
noInitialStream,
|
|
215
217
|
(acc, cur) => acc + cur,
|
|
218
|
+
{ initial: 0 },
|
|
216
219
|
);
|
|
217
220
|
|
|
218
221
|
expect(noInitialResult).toBe(10);
|
|
@@ -229,7 +232,7 @@ describe("streamUtil", () => {
|
|
|
229
232
|
}
|
|
230
233
|
return [...acc, `item${cur}`];
|
|
231
234
|
},
|
|
232
|
-
[],
|
|
235
|
+
{ initial: [] },
|
|
233
236
|
);
|
|
234
237
|
|
|
235
238
|
expect(transformResult).toEqual(["item1", "item2", "item3"]);
|
|
@@ -240,7 +243,7 @@ describe("streamUtil", () => {
|
|
|
240
243
|
const emptyResult = await StreamUtil.reduce<number, string>(
|
|
241
244
|
emptyStream,
|
|
242
245
|
(acc, cur) => acc + cur.toString(),
|
|
243
|
-
"initial",
|
|
246
|
+
{ initial: "initial" },
|
|
244
247
|
);
|
|
245
248
|
|
|
246
249
|
expect(emptyResult).toBe("initial");
|
|
@@ -256,7 +259,7 @@ describe("streamUtil", () => {
|
|
|
256
259
|
const delayResult = await StreamUtil.reduce<number, number>(
|
|
257
260
|
delayStream,
|
|
258
261
|
(acc, cur) => acc + cur,
|
|
259
|
-
0,
|
|
262
|
+
{ initial: 0 },
|
|
260
263
|
);
|
|
261
264
|
|
|
262
265
|
expect(delayResult).toBe(6);
|
|
@@ -274,7 +277,7 @@ describe("streamUtil", () => {
|
|
|
274
277
|
}
|
|
275
278
|
return acc + cur;
|
|
276
279
|
},
|
|
277
|
-
0,
|
|
280
|
+
{ initial: 0 },
|
|
278
281
|
),
|
|
279
282
|
).rejects.toThrow("Test error");
|
|
280
283
|
});
|
|
@@ -285,7 +288,7 @@ describe("streamUtil", () => {
|
|
|
285
288
|
const result = await StreamUtil.reduce<number | null | undefined, number>(
|
|
286
289
|
stream,
|
|
287
290
|
(acc, cur) => (acc ?? 0) + (cur ?? 0),
|
|
288
|
-
0,
|
|
291
|
+
{ initial: 0 },
|
|
289
292
|
);
|
|
290
293
|
|
|
291
294
|
expect(result).toBe(9); // 1 + 0 + 3 + 0 + 5 = 9
|
package/src/utils/StreamUtil.ts
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Utility functions for streams.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
async function readAll<T>(stream: ReadableStream<T
|
|
7
|
+
async function readAll<T>(stream: ReadableStream<T>, abortSignal?: AbortSignal): Promise<T[]> {
|
|
8
8
|
const reader = stream.getReader();
|
|
9
9
|
const result: T[] = [];
|
|
10
10
|
while (true) {
|
|
11
11
|
const { done, value } = await reader.read();
|
|
12
|
-
if (done) {
|
|
12
|
+
if (done || abortSignal?.aborted === true) {
|
|
13
13
|
break;
|
|
14
14
|
}
|
|
15
15
|
result.push(value);
|
|
@@ -17,12 +17,16 @@ async function readAll<T>(stream: ReadableStream<T>): Promise<T[]> {
|
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, initial?: R): Promise<R | null> {
|
|
20
|
+
async function reduce<T, R = T>(stream: ReadableStream<T>, reducer: (acc: T | R, cur: T) => R, options: { initial?: R, abortSignal?: AbortSignal }): Promise<R | null> {
|
|
21
21
|
const reader = stream.getReader();
|
|
22
22
|
const iterator = streamDefaultReaderToAsyncGenerator(reader);
|
|
23
|
-
let acc = (initial ?? null) as R | null | T;
|
|
23
|
+
let acc = (options.initial ?? null) as R | null | T;
|
|
24
24
|
|
|
25
25
|
for await (const value of iterator) {
|
|
26
|
+
if (options.abortSignal?.aborted === true) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
if (acc === null) {
|
|
27
31
|
acc = value;
|
|
28
32
|
continue;
|
|
@@ -49,28 +53,28 @@ export async function* toAsyncGenerator<T>(value: T): AsyncGenerator<T, undefine
|
|
|
49
53
|
yield value;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
export async function* streamDefaultReaderToAsyncGenerator<T>(reader: ReadableStreamDefaultReader<T
|
|
56
|
+
export async function* streamDefaultReaderToAsyncGenerator<T>(reader: ReadableStreamDefaultReader<T>, abortSignal?: AbortSignal): AsyncGenerator<Awaited<T>, undefined, undefined> {
|
|
53
57
|
while (true) {
|
|
54
58
|
const { done, value } = await reader.read();
|
|
55
|
-
if (done) {
|
|
59
|
+
if (done || abortSignal?.aborted === true) {
|
|
56
60
|
break;
|
|
57
61
|
}
|
|
58
62
|
yield value;
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
function transform<T, R>(stream: ReadableStream<T>, transformer: (value: T) => R): ReadableStream<R> {
|
|
66
|
+
function transform<T, R>(stream: ReadableStream<T>, transformer: (value: T) => R, abortSignal?: AbortSignal): ReadableStream<R> {
|
|
63
67
|
const reader = stream.getReader();
|
|
64
68
|
|
|
65
69
|
return new ReadableStream<R>({
|
|
66
70
|
pull: async (controller) => {
|
|
67
71
|
const { done, value } = await reader.read();
|
|
68
|
-
if (
|
|
69
|
-
controller.enqueue(transformer(value));
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
+
if (done === true || abortSignal?.aborted === true) {
|
|
72
73
|
controller.close();
|
|
74
|
+
return;
|
|
73
75
|
}
|
|
76
|
+
|
|
77
|
+
controller.enqueue(transformer(value));
|
|
74
78
|
},
|
|
75
79
|
});
|
|
76
80
|
}
|
package/src/utils/request.ts
CHANGED
|
@@ -61,6 +61,7 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
|
|
|
61
61
|
completion.toReadableStream() as ReadableStream<Uint8Array>,
|
|
62
62
|
value =>
|
|
63
63
|
ChatGptCompletionMessageUtil.transformCompletionChunk(value),
|
|
64
|
+
props.abortSignal,
|
|
64
65
|
).tee();
|
|
65
66
|
|
|
66
67
|
const [streamForAggregate, streamForReturn] = temporaryStream.tee();
|
|
@@ -69,7 +70,7 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
|
|
|
69
70
|
const reader = streamForAggregate.getReader();
|
|
70
71
|
while (true) {
|
|
71
72
|
const chunk = await reader.read();
|
|
72
|
-
if (chunk.done) {
|
|
73
|
+
if (chunk.done || props.abortSignal?.aborted === true) {
|
|
73
74
|
break;
|
|
74
75
|
}
|
|
75
76
|
if (chunk.value.usage != null) {
|
|
@@ -87,11 +88,11 @@ export const getChatCompletionWithStreamingFunction = <Model extends ILlmSchema.
|
|
|
87
88
|
id: v4(),
|
|
88
89
|
type: "response",
|
|
89
90
|
source,
|
|
90
|
-
stream: streamDefaultReaderToAsyncGenerator(streamForStream.getReader()),
|
|
91
|
+
stream: streamDefaultReaderToAsyncGenerator(streamForStream.getReader(), props.abortSignal),
|
|
91
92
|
body: event.body,
|
|
92
93
|
options: event.options,
|
|
93
94
|
join: async () => {
|
|
94
|
-
const chunks = await StreamUtil.readAll(streamForJoin);
|
|
95
|
+
const chunks = await StreamUtil.readAll(streamForJoin, props.abortSignal);
|
|
95
96
|
return ChatGptCompletionMessageUtil.merge(chunks);
|
|
96
97
|
},
|
|
97
98
|
created_at: new Date().toISOString(),
|