openai 6.46.0 → 6.48.0
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/CHANGELOG.md +47 -0
- package/README.md +9 -2
- package/client.d.mts +1 -0
- package/client.d.mts.map +1 -1
- package/client.d.ts +1 -0
- package/client.d.ts.map +1 -1
- package/client.js +11 -5
- package/client.js.map +1 -1
- package/client.mjs +11 -5
- package/client.mjs.map +1 -1
- package/core/streaming.d.mts.map +1 -1
- package/core/streaming.d.ts.map +1 -1
- package/core/streaming.js +38 -6
- package/core/streaming.js.map +1 -1
- package/core/streaming.mjs +38 -6
- package/core/streaming.mjs.map +1 -1
- package/core/uploads.d.mts +1 -1
- package/core/uploads.d.mts.map +1 -1
- package/core/uploads.d.ts +1 -1
- package/core/uploads.d.ts.map +1 -1
- package/core/uploads.js +3 -1
- package/core/uploads.js.map +1 -1
- package/core/uploads.mjs +1 -0
- package/core/uploads.mjs.map +1 -1
- package/helpers/zod.d.mts +20 -7
- package/helpers/zod.d.mts.map +1 -1
- package/helpers/zod.d.ts +20 -7
- package/helpers/zod.d.ts.map +1 -1
- package/helpers/zod.js +24 -12
- package/helpers/zod.js.map +1 -1
- package/helpers/zod.mjs +24 -12
- package/helpers/zod.mjs.map +1 -1
- package/index.d.mts +1 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +2 -1
- package/index.js.map +1 -1
- package/index.mjs +1 -1
- package/index.mjs.map +1 -1
- package/internal/headers.d.mts.map +1 -1
- package/internal/headers.d.ts.map +1 -1
- package/internal/headers.js +7 -3
- package/internal/headers.js.map +1 -1
- package/internal/headers.mjs +7 -3
- package/internal/headers.mjs.map +1 -1
- package/internal/uploads.d.mts +26 -1
- package/internal/uploads.d.mts.map +1 -1
- package/internal/uploads.d.ts +26 -1
- package/internal/uploads.d.ts.map +1 -1
- package/internal/uploads.js +169 -1
- package/internal/uploads.js.map +1 -1
- package/internal/uploads.mjs +169 -2
- package/internal/uploads.mjs.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.mts +3 -3
- package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.ts +3 -3
- package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
- package/lib/AbstractChatCompletionRunner.js +4 -3
- package/lib/AbstractChatCompletionRunner.js.map +1 -1
- package/lib/AbstractChatCompletionRunner.mjs +4 -3
- package/lib/AbstractChatCompletionRunner.mjs.map +1 -1
- package/lib/AssistantStream.d.mts.map +1 -1
- package/lib/AssistantStream.d.ts.map +1 -1
- package/lib/AssistantStream.js +3 -2
- package/lib/AssistantStream.js.map +1 -1
- package/lib/AssistantStream.mjs +3 -2
- package/lib/AssistantStream.mjs.map +1 -1
- package/lib/ChatCompletionRunner.d.mts +26 -2
- package/lib/ChatCompletionRunner.d.mts.map +1 -1
- package/lib/ChatCompletionRunner.d.ts +26 -2
- package/lib/ChatCompletionRunner.d.ts.map +1 -1
- package/lib/ChatCompletionRunner.js.map +1 -1
- package/lib/ChatCompletionRunner.mjs.map +1 -1
- package/lib/ChatCompletionStream.d.mts +14 -1
- package/lib/ChatCompletionStream.d.mts.map +1 -1
- package/lib/ChatCompletionStream.d.ts +14 -1
- package/lib/ChatCompletionStream.d.ts.map +1 -1
- package/lib/ChatCompletionStream.js +68 -12
- package/lib/ChatCompletionStream.js.map +1 -1
- package/lib/ChatCompletionStream.mjs +67 -12
- package/lib/ChatCompletionStream.mjs.map +1 -1
- package/lib/ChatCompletionStreamingRunner.d.mts +25 -2
- package/lib/ChatCompletionStreamingRunner.d.mts.map +1 -1
- package/lib/ChatCompletionStreamingRunner.d.ts +25 -2
- package/lib/ChatCompletionStreamingRunner.d.ts.map +1 -1
- package/lib/ChatCompletionStreamingRunner.js +77 -0
- package/lib/ChatCompletionStreamingRunner.js.map +1 -1
- package/lib/ChatCompletionStreamingRunner.mjs +78 -1
- package/lib/ChatCompletionStreamingRunner.mjs.map +1 -1
- package/lib/EventStream.d.mts +13 -0
- package/lib/EventStream.d.mts.map +1 -1
- package/lib/EventStream.d.ts +13 -0
- package/lib/EventStream.d.ts.map +1 -1
- package/lib/EventStream.js +107 -2
- package/lib/EventStream.js.map +1 -1
- package/lib/EventStream.mjs +107 -2
- package/lib/EventStream.mjs.map +1 -1
- package/lib/RunnableFunction.d.mts +38 -21
- package/lib/RunnableFunction.d.mts.map +1 -1
- package/lib/RunnableFunction.d.ts +38 -21
- package/lib/RunnableFunction.d.ts.map +1 -1
- package/lib/RunnableFunction.js.map +1 -1
- package/lib/RunnableFunction.mjs.map +1 -1
- package/lib/parser.d.mts +2 -2
- package/lib/parser.d.mts.map +1 -1
- package/lib/parser.d.ts +2 -2
- package/lib/parser.d.ts.map +1 -1
- package/lib/parser.js.map +1 -1
- package/lib/parser.mjs.map +1 -1
- package/lib/responses/ResponseStream.d.mts +6 -1
- package/lib/responses/ResponseStream.d.mts.map +1 -1
- package/lib/responses/ResponseStream.d.ts +6 -1
- package/lib/responses/ResponseStream.d.ts.map +1 -1
- package/lib/responses/ResponseStream.js +21 -0
- package/lib/responses/ResponseStream.js.map +1 -1
- package/lib/responses/ResponseStream.mjs +21 -0
- package/lib/responses/ResponseStream.mjs.map +1 -1
- package/package.json +1 -1
- package/resources/admin/organization/audit-logs.d.mts +2 -2
- package/resources/admin/organization/audit-logs.d.mts.map +1 -1
- package/resources/admin/organization/audit-logs.d.ts +2 -2
- package/resources/admin/organization/audit-logs.d.ts.map +1 -1
- package/resources/admin/organization/projects/api-keys.d.mts +12 -0
- package/resources/admin/organization/projects/api-keys.d.mts.map +1 -1
- package/resources/admin/organization/projects/api-keys.d.ts +12 -0
- package/resources/admin/organization/projects/api-keys.d.ts.map +1 -1
- package/resources/admin/organization/projects/index.d.mts +1 -1
- package/resources/admin/organization/projects/index.d.mts.map +1 -1
- package/resources/admin/organization/projects/index.d.ts +1 -1
- package/resources/admin/organization/projects/index.d.ts.map +1 -1
- package/resources/admin/organization/projects/index.js +4 -4
- package/resources/admin/organization/projects/index.js.map +1 -1
- package/resources/admin/organization/projects/index.mjs +1 -1
- package/resources/admin/organization/projects/index.mjs.map +1 -1
- package/resources/admin/organization/projects/projects.d.mts +2 -2
- package/resources/admin/organization/projects/projects.d.mts.map +1 -1
- package/resources/admin/organization/projects/projects.d.ts +2 -2
- package/resources/admin/organization/projects/projects.d.ts.map +1 -1
- package/resources/admin/organization/projects/projects.js +2 -2
- package/resources/admin/organization/projects/projects.js.map +1 -1
- package/resources/admin/organization/projects/projects.mjs +2 -2
- package/resources/admin/organization/projects/projects.mjs.map +1 -1
- package/resources/admin/organization/projects/service-accounts/api-keys.d.mts +58 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.ts +58 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.js +26 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.mjs +22 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.d.mts +3 -0
- package/resources/admin/organization/projects/service-accounts/index.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.d.ts +3 -0
- package/resources/admin/organization/projects/service-accounts/index.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.js +9 -0
- package/resources/admin/organization/projects/service-accounts/index.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.mjs +4 -0
- package/resources/admin/organization/projects/service-accounts/index.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.mts +177 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.ts +177 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.js +109 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.mjs +104 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts.d.mts +1 -167
- package/resources/admin/organization/projects/service-accounts.d.mts.map +1 -1
- package/resources/admin/organization/projects/service-accounts.d.ts +1 -167
- package/resources/admin/organization/projects/service-accounts.d.ts.map +1 -1
- package/resources/admin/organization/projects/service-accounts.js +2 -97
- package/resources/admin/organization/projects/service-accounts.js.map +1 -1
- package/resources/admin/organization/projects/service-accounts.mjs +1 -95
- package/resources/admin/organization/projects/service-accounts.mjs.map +1 -1
- package/resources/admin/organization/usage.d.mts +517 -88
- package/resources/admin/organization/usage.d.mts.map +1 -1
- package/resources/admin/organization/usage.d.ts +517 -88
- package/resources/admin/organization/usage.d.ts.map +1 -1
- package/resources/beta/responses/responses.d.mts +7 -6
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +7 -6
- package/resources/beta/responses/responses.d.ts.map +1 -1
- package/resources/beta/responses/responses.js.map +1 -1
- package/resources/beta/responses/responses.mjs.map +1 -1
- package/resources/chat/completions/completions.d.mts +15 -6
- package/resources/chat/completions/completions.d.mts.map +1 -1
- package/resources/chat/completions/completions.d.ts +15 -6
- package/resources/chat/completions/completions.d.ts.map +1 -1
- package/resources/chat/completions/completions.js.map +1 -1
- package/resources/chat/completions/completions.mjs.map +1 -1
- package/resources/responses/responses.d.mts +3 -2
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +3 -2
- package/resources/responses/responses.d.ts.map +1 -1
- package/resources/responses/responses.js.map +1 -1
- package/resources/responses/responses.mjs.map +1 -1
- package/resources/webhooks/webhooks.d.mts +2 -54
- package/resources/webhooks/webhooks.d.mts.map +1 -1
- package/resources/webhooks/webhooks.d.ts +2 -54
- package/resources/webhooks/webhooks.d.ts.map +1 -1
- package/src/client.ts +13 -5
- package/src/core/streaming.ts +36 -8
- package/src/core/uploads.ts +6 -1
- package/src/helpers/zod.ts +62 -23
- package/src/index.ts +1 -1
- package/src/internal/headers.ts +7 -3
- package/src/internal/uploads.ts +214 -4
- package/src/lib/AbstractChatCompletionRunner.ts +17 -9
- package/src/lib/AssistantStream.ts +3 -2
- package/src/lib/ChatCompletionRunner.ts +46 -6
- package/src/lib/ChatCompletionStream.ts +108 -13
- package/src/lib/ChatCompletionStreamingRunner.ts +144 -7
- package/src/lib/EventStream.ts +114 -4
- package/src/lib/RunnableFunction.ts +60 -31
- package/src/lib/parser.ts +4 -0
- package/src/lib/responses/ResponseStream.ts +29 -1
- package/src/resources/admin/organization/audit-logs.ts +169 -1
- package/src/resources/admin/organization/projects/api-keys.ts +15 -1
- package/src/resources/admin/organization/projects/index.ts +1 -1
- package/src/resources/admin/organization/projects/projects.ts +13 -13
- package/src/resources/admin/organization/projects/service-accounts/api-keys.ts +80 -0
- package/src/resources/admin/organization/projects/service-accounts/index.ts +15 -0
- package/src/resources/admin/organization/projects/service-accounts/service-accounts.ts +284 -0
- package/src/resources/admin/organization/projects/service-accounts.ts +1 -264
- package/src/resources/admin/organization/usage.ts +616 -88
- package/src/resources/beta/responses/responses.ts +7 -6
- package/src/resources/chat/completions/completions.ts +66 -9
- package/src/resources/responses/responses.ts +3 -2
- package/src/resources/webhooks/api.md +0 -1
- package/src/resources/webhooks/webhooks.ts +1 -65
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -15,10 +15,15 @@ import type {
|
|
|
15
15
|
ParsedChatCompletion,
|
|
16
16
|
} from '../resources/chat/completions';
|
|
17
17
|
import type { CompletionUsage } from '../resources/completions';
|
|
18
|
-
import type {
|
|
18
|
+
import type {
|
|
19
|
+
ChatCompletionRunner,
|
|
20
|
+
ChatCompletionToolRunnerParamsWithContext,
|
|
21
|
+
ChatCompletionToolRunnerParamsWithoutContext,
|
|
22
|
+
} from './ChatCompletionRunner';
|
|
19
23
|
import type {
|
|
20
24
|
ChatCompletionStreamingRunner,
|
|
21
|
-
|
|
25
|
+
ChatCompletionStreamingToolRunnerParamsWithContext,
|
|
26
|
+
ChatCompletionStreamingToolRunnerParamsWithoutContext,
|
|
22
27
|
} from './ChatCompletionStreamingRunner';
|
|
23
28
|
import { isAssistantMessage, isToolMessage } from './chatCompletionUtils';
|
|
24
29
|
import { BaseEvents, EventStream } from './EventStream';
|
|
@@ -285,16 +290,19 @@ export class AbstractChatCompletionRunner<
|
|
|
285
290
|
return await this._createChatCompletion(client, params, options);
|
|
286
291
|
}
|
|
287
292
|
|
|
288
|
-
protected async _runTools<FunctionsArgs extends BaseFunctionsArgs>(
|
|
293
|
+
protected async _runTools<FunctionsArgs extends BaseFunctionsArgs, ToolContext>(
|
|
289
294
|
client: OpenAI,
|
|
290
295
|
params:
|
|
291
|
-
|
|
|
292
|
-
|
|
|
296
|
+
| ChatCompletionToolRunnerParamsWithContext<FunctionsArgs, ToolContext>
|
|
297
|
+
| ChatCompletionToolRunnerParamsWithoutContext<FunctionsArgs>
|
|
298
|
+
| ChatCompletionStreamingToolRunnerParamsWithContext<FunctionsArgs, ToolContext>
|
|
299
|
+
| ChatCompletionStreamingToolRunnerParamsWithoutContext<FunctionsArgs>,
|
|
293
300
|
runner: ChatCompletionRunner<any> | ChatCompletionStreamingRunner<any>,
|
|
294
301
|
options?: RunnerOptions,
|
|
295
302
|
) {
|
|
296
303
|
const role = 'tool' as const;
|
|
297
|
-
const { tool_choice = 'auto', stream, ...restParams } = params;
|
|
304
|
+
const { tool_choice = 'auto', stream, toolContext: inputToolContext, ...restParams } = params;
|
|
305
|
+
const toolContext = inputToolContext as ToolContext;
|
|
298
306
|
const singleFunctionToCall =
|
|
299
307
|
typeof tool_choice !== 'string' && tool_choice.type === 'function' && tool_choice?.function?.name;
|
|
300
308
|
const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS, afterCompletion } = options || {};
|
|
@@ -322,7 +330,7 @@ export class AbstractChatCompletionRunner<
|
|
|
322
330
|
return tool as any as RunnableToolFunction<any>;
|
|
323
331
|
});
|
|
324
332
|
|
|
325
|
-
const functionsByName: Record<string, RunnableFunction<any>> = {};
|
|
333
|
+
const functionsByName: Record<string, RunnableFunction<any, ToolContext>> = {};
|
|
326
334
|
for (const f of inputTools) {
|
|
327
335
|
if (f.type === 'function') {
|
|
328
336
|
functionsByName[f.function.name || f.function.function.name] = f.function;
|
|
@@ -389,9 +397,9 @@ export class AbstractChatCompletionRunner<
|
|
|
389
397
|
const content = error instanceof Error ? error.message : String(error);
|
|
390
398
|
return { message: { role, tool_call_id, content }, functionCalled: false };
|
|
391
399
|
}
|
|
392
|
-
rawContent = await fn.function(parsed, runner);
|
|
400
|
+
rawContent = await fn.function(parsed, runner, toolContext);
|
|
393
401
|
} else {
|
|
394
|
-
rawContent = await fn.function(args, runner);
|
|
402
|
+
rawContent = await fn.function(args, runner, toolContext);
|
|
395
403
|
}
|
|
396
404
|
|
|
397
405
|
const content = this.#stringifyFunctionCallResult(rawContent);
|
|
@@ -103,11 +103,12 @@ export class AssistantStream
|
|
|
103
103
|
|
|
104
104
|
//Catch all for passing along all events
|
|
105
105
|
this.on('event', (event) => {
|
|
106
|
+
const eventCopy = structuredClone(event);
|
|
106
107
|
const reader = readQueue.shift();
|
|
107
108
|
if (reader) {
|
|
108
|
-
reader.resolve(
|
|
109
|
+
reader.resolve(eventCopy);
|
|
109
110
|
} else {
|
|
110
|
-
pushQueue.push(
|
|
111
|
+
pushQueue.push(eventCopy);
|
|
111
112
|
}
|
|
112
113
|
});
|
|
113
114
|
|
|
@@ -16,20 +16,60 @@ export interface ChatCompletionRunnerEvents extends AbstractChatCompletionRunner
|
|
|
16
16
|
content: (content: string) => void;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
type ChatCompletionToolRunnerParamsBase = Omit<ChatCompletionCreateParamsNonStreaming, 'tools'>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parameters for tools that do not require a context value.
|
|
23
|
+
*/
|
|
24
|
+
export type ChatCompletionToolRunnerParamsWithoutContext<FunctionsArgs extends BaseFunctionsArgs> =
|
|
25
|
+
ChatCompletionToolRunnerParamsBase & {
|
|
26
|
+
tools: RunnableTools<FunctionsArgs> | AutoParseableTool<any, true>[];
|
|
27
|
+
toolContext?: never;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parameters for tools that require a context value.
|
|
32
|
+
*/
|
|
33
|
+
export type ChatCompletionToolRunnerParamsWithContext<
|
|
34
|
+
FunctionsArgs extends BaseFunctionsArgs,
|
|
35
|
+
ToolContext,
|
|
36
|
+
> = ChatCompletionToolRunnerParamsBase & {
|
|
37
|
+
tools: RunnableTools<FunctionsArgs, ToolContext> | AutoParseableTool<any, true>[];
|
|
38
|
+
/**
|
|
39
|
+
* Context to pass to each tool callback during this run.
|
|
40
|
+
*/
|
|
41
|
+
toolContext: ToolContext;
|
|
24
42
|
};
|
|
25
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Parameters for running tools. Supplying a context type makes `toolContext`
|
|
46
|
+
* required; omitting it preserves the existing no-context form.
|
|
47
|
+
*/
|
|
48
|
+
export type ChatCompletionToolRunnerParams<FunctionsArgs extends BaseFunctionsArgs, ToolContext = never> = [
|
|
49
|
+
ToolContext,
|
|
50
|
+
] extends [never] ?
|
|
51
|
+
ChatCompletionToolRunnerParamsWithoutContext<FunctionsArgs>
|
|
52
|
+
: ChatCompletionToolRunnerParamsWithContext<FunctionsArgs, ToolContext>;
|
|
53
|
+
|
|
26
54
|
export class ChatCompletionRunner<ParsedT = null> extends AbstractChatCompletionRunner<
|
|
27
55
|
ChatCompletionRunnerEvents,
|
|
28
56
|
ParsedT
|
|
29
57
|
> {
|
|
58
|
+
static runTools<ParsedT, ToolContext = unknown>(
|
|
59
|
+
client: OpenAI,
|
|
60
|
+
params: ChatCompletionToolRunnerParamsWithContext<any[], ToolContext>,
|
|
61
|
+
options?: RunnerOptions,
|
|
62
|
+
): ChatCompletionRunner<ParsedT>;
|
|
30
63
|
static runTools<ParsedT>(
|
|
31
64
|
client: OpenAI,
|
|
32
|
-
params:
|
|
65
|
+
params: ChatCompletionToolRunnerParamsWithoutContext<any[]>,
|
|
66
|
+
options?: RunnerOptions,
|
|
67
|
+
): ChatCompletionRunner<ParsedT>;
|
|
68
|
+
static runTools<ParsedT, ToolContext = unknown>(
|
|
69
|
+
client: OpenAI,
|
|
70
|
+
params:
|
|
71
|
+
| ChatCompletionToolRunnerParamsWithContext<any[], ToolContext>
|
|
72
|
+
| ChatCompletionToolRunnerParamsWithoutContext<any[]>,
|
|
33
73
|
options?: RunnerOptions,
|
|
34
74
|
): ChatCompletionRunner<ParsedT> {
|
|
35
75
|
const runner = new ChatCompletionRunner<ParsedT>();
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type ChatCompletionCreateParams,
|
|
27
27
|
type ChatCompletionCreateParamsBase,
|
|
28
28
|
type ChatCompletionCreateParamsStreaming,
|
|
29
|
+
type ChatCompletionMessageParam,
|
|
29
30
|
type ChatCompletionRole,
|
|
30
31
|
} from '../resources/chat/completions/completions';
|
|
31
32
|
import { Stream } from '../streaming';
|
|
@@ -118,6 +119,69 @@ export type ChatCompletionStreamParams = Omit<ChatCompletionCreateParamsBase, 's
|
|
|
118
119
|
stream?: true;
|
|
119
120
|
};
|
|
120
121
|
|
|
122
|
+
type ChatCompletionReadableStreamMessage = {
|
|
123
|
+
type: 'message';
|
|
124
|
+
message: ChatCompletionMessageParam;
|
|
125
|
+
tool_call_ids?: string[];
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Keep message records readable as empty chunks by older SDKs. Their finalizer
|
|
129
|
+
// overwrites `object`, so the encoded payload does not leak into completions.
|
|
130
|
+
const CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX = 'chat.completion.chunk.message:';
|
|
131
|
+
|
|
132
|
+
type ChatCompletionReadableStreamMessageChunk = Pick<ChatCompletionChunk, 'id' | 'created' | 'model'> & {
|
|
133
|
+
choices: [];
|
|
134
|
+
object: `${typeof CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX}${string}`;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type ChatCompletionReadableStreamItem =
|
|
138
|
+
| ChatCompletionChunk
|
|
139
|
+
| ChatCompletionReadableStreamMessage
|
|
140
|
+
| ChatCompletionReadableStreamMessageChunk;
|
|
141
|
+
|
|
142
|
+
export function makeChatCompletionReadableStreamMessageChunk(
|
|
143
|
+
chunk: ChatCompletionChunk,
|
|
144
|
+
message: ChatCompletionMessageParam,
|
|
145
|
+
toolCallIds?: string[],
|
|
146
|
+
): ChatCompletionReadableStreamMessageChunk {
|
|
147
|
+
const payload: ChatCompletionReadableStreamMessage = {
|
|
148
|
+
type: 'message',
|
|
149
|
+
message,
|
|
150
|
+
...(toolCallIds ? { tool_call_ids: toolCallIds } : {}),
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
id: chunk.id,
|
|
155
|
+
choices: [],
|
|
156
|
+
created: chunk.created,
|
|
157
|
+
model: chunk.model,
|
|
158
|
+
object: `${CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX}${JSON.stringify(payload)}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function isChatCompletionReadableStreamMessage(
|
|
163
|
+
item: ChatCompletionReadableStreamItem,
|
|
164
|
+
): item is ChatCompletionReadableStreamMessage | ChatCompletionReadableStreamMessageChunk {
|
|
165
|
+
return (
|
|
166
|
+
('type' in item && item.type === 'message' && 'message' in item) ||
|
|
167
|
+
('object' in item &&
|
|
168
|
+
typeof item.object === 'string' &&
|
|
169
|
+
item.object.startsWith(CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX))
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function getChatCompletionReadableStreamMessage(
|
|
174
|
+
item: ChatCompletionReadableStreamMessage | ChatCompletionReadableStreamMessageChunk,
|
|
175
|
+
): ChatCompletionReadableStreamMessage {
|
|
176
|
+
if ('type' in item) {
|
|
177
|
+
return item;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return JSON.parse(
|
|
181
|
+
item.object.slice(CHAT_COMPLETION_READABLE_STREAM_MESSAGE_PREFIX.length),
|
|
182
|
+
) as ChatCompletionReadableStreamMessage;
|
|
183
|
+
}
|
|
184
|
+
|
|
121
185
|
interface ChoiceEventState {
|
|
122
186
|
content_done: boolean;
|
|
123
187
|
refusal_done: boolean;
|
|
@@ -205,27 +269,28 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
205
269
|
|
|
206
270
|
for (const choice of chunk.choices) {
|
|
207
271
|
const choiceSnapshot = completion.choices[choice.index]!;
|
|
272
|
+
const { delta } = choice;
|
|
208
273
|
|
|
209
274
|
if (
|
|
210
|
-
|
|
275
|
+
delta?.content != null &&
|
|
211
276
|
choiceSnapshot.message?.role === 'assistant' &&
|
|
212
277
|
choiceSnapshot.message?.content
|
|
213
278
|
) {
|
|
214
|
-
this._emit('content',
|
|
279
|
+
this._emit('content', delta.content, choiceSnapshot.message.content);
|
|
215
280
|
this._emit('content.delta', {
|
|
216
|
-
delta:
|
|
281
|
+
delta: delta.content,
|
|
217
282
|
snapshot: choiceSnapshot.message.content,
|
|
218
283
|
parsed: choiceSnapshot.message.parsed,
|
|
219
284
|
});
|
|
220
285
|
}
|
|
221
286
|
|
|
222
287
|
if (
|
|
223
|
-
|
|
288
|
+
delta?.refusal != null &&
|
|
224
289
|
choiceSnapshot.message?.role === 'assistant' &&
|
|
225
290
|
choiceSnapshot.message?.refusal
|
|
226
291
|
) {
|
|
227
292
|
this._emit('refusal.delta', {
|
|
228
|
-
delta:
|
|
293
|
+
delta: delta.refusal,
|
|
229
294
|
snapshot: choiceSnapshot.message.refusal,
|
|
230
295
|
});
|
|
231
296
|
}
|
|
@@ -254,7 +319,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
254
319
|
}
|
|
255
320
|
}
|
|
256
321
|
|
|
257
|
-
for (const toolCall of
|
|
322
|
+
for (const toolCall of delta?.tool_calls ?? []) {
|
|
258
323
|
if (state.current_tool_call_index !== toolCall.index) {
|
|
259
324
|
this.#emitContentDoneEvents(choiceSnapshot);
|
|
260
325
|
|
|
@@ -267,7 +332,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
267
332
|
state.current_tool_call_index = toolCall.index;
|
|
268
333
|
}
|
|
269
334
|
|
|
270
|
-
for (const toolCallDelta of
|
|
335
|
+
for (const toolCallDelta of delta?.tool_calls ?? []) {
|
|
271
336
|
const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallDelta.index];
|
|
272
337
|
if (!toolCallSnapshot?.type) {
|
|
273
338
|
continue;
|
|
@@ -398,21 +463,51 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
398
463
|
this._listenForAbort(options?.signal);
|
|
399
464
|
this.#beginRequest();
|
|
400
465
|
this._connected();
|
|
401
|
-
const stream = Stream.fromReadableStream<
|
|
466
|
+
const stream = Stream.fromReadableStream<ChatCompletionReadableStreamItem>(
|
|
467
|
+
readableStream,
|
|
468
|
+
this.controller,
|
|
469
|
+
);
|
|
402
470
|
let chatId;
|
|
403
|
-
for await (const
|
|
404
|
-
if (
|
|
471
|
+
for await (const item of stream) {
|
|
472
|
+
if (isChatCompletionReadableStreamMessage(item)) {
|
|
473
|
+
const message = getChatCompletionReadableStreamMessage(item);
|
|
474
|
+
if (this.#currentChatCompletionSnapshot) {
|
|
475
|
+
const toolCalls = this.#currentChatCompletionSnapshot.choices[0]?.message.tool_calls;
|
|
476
|
+
for (const [index, id] of message.tool_call_ids?.entries() ?? []) {
|
|
477
|
+
const toolCall = toolCalls?.[index];
|
|
478
|
+
if (toolCall && id) {
|
|
479
|
+
toolCall.id = id;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
this._addChatCompletion(this.#endRequest());
|
|
484
|
+
chatId = undefined;
|
|
485
|
+
}
|
|
486
|
+
this._addMessage(message.message);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const chunk = item;
|
|
491
|
+
|
|
492
|
+
if (chatId && chunk.id && chatId !== chunk.id) {
|
|
405
493
|
// A new request has been made.
|
|
406
494
|
this._addChatCompletion(this.#endRequest());
|
|
407
495
|
}
|
|
408
496
|
|
|
409
497
|
this.#addChunk(chunk);
|
|
410
|
-
chatId = chunk.id;
|
|
498
|
+
if (chunk.id) chatId = chunk.id;
|
|
411
499
|
}
|
|
412
500
|
if (stream.controller.signal?.aborted) {
|
|
413
501
|
throw new APIUserAbortError();
|
|
414
502
|
}
|
|
415
|
-
|
|
503
|
+
if (this.#currentChatCompletionSnapshot) {
|
|
504
|
+
return this._addChatCompletion(this.#endRequest());
|
|
505
|
+
}
|
|
506
|
+
const lastChatCompletion = this._chatCompletions[this._chatCompletions.length - 1];
|
|
507
|
+
if (lastChatCompletion) {
|
|
508
|
+
return lastChatCompletion;
|
|
509
|
+
}
|
|
510
|
+
throw new OpenAIError(`request ended without sending any chunks`);
|
|
416
511
|
}
|
|
417
512
|
|
|
418
513
|
#getAutoParseableResponseFormat(): AutoParseableResponseFormat<ParsedT> | null {
|
|
@@ -432,7 +527,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
432
527
|
...rest,
|
|
433
528
|
choices: [],
|
|
434
529
|
};
|
|
435
|
-
} else {
|
|
530
|
+
} else if (chunk.id) {
|
|
436
531
|
Object.assign(snapshot, rest);
|
|
437
532
|
}
|
|
438
533
|
|
|
@@ -1,26 +1,63 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ChatCompletionChunk,
|
|
3
3
|
type ChatCompletionCreateParamsStreaming,
|
|
4
|
+
type ChatCompletionMessageParam,
|
|
4
5
|
} from '../resources/chat/completions';
|
|
5
6
|
import { RunnerOptions, type AbstractChatCompletionRunnerEvents } from './AbstractChatCompletionRunner';
|
|
6
7
|
import { type ReadableStream } from '../internal/shim-types';
|
|
7
8
|
import { RunnableTools, type BaseFunctionsArgs } from './RunnableFunction';
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type ChatCompletionReadableStreamItem,
|
|
11
|
+
ChatCompletionSnapshot,
|
|
12
|
+
ChatCompletionStream,
|
|
13
|
+
makeChatCompletionReadableStreamMessageChunk,
|
|
14
|
+
} from './ChatCompletionStream';
|
|
15
|
+
import { OpenAIError } from '../error';
|
|
9
16
|
import OpenAI from '../index';
|
|
10
17
|
import { AutoParseableTool } from '../lib/parser';
|
|
18
|
+
import { Stream } from '../streaming';
|
|
19
|
+
import { isAssistantMessage, isToolMessage } from './chatCompletionUtils';
|
|
11
20
|
|
|
12
21
|
export interface ChatCompletionStreamEvents extends AbstractChatCompletionRunnerEvents {
|
|
13
22
|
content: (contentDelta: string, contentSnapshot: string) => void;
|
|
14
23
|
chunk: (chunk: ChatCompletionChunk, snapshot: ChatCompletionSnapshot) => void;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
type ChatCompletionStreamingToolRunnerParamsBase = Omit<ChatCompletionCreateParamsStreaming, 'tools'>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parameters for tools that do not require a context value.
|
|
30
|
+
*/
|
|
31
|
+
export type ChatCompletionStreamingToolRunnerParamsWithoutContext<FunctionsArgs extends BaseFunctionsArgs> =
|
|
32
|
+
ChatCompletionStreamingToolRunnerParamsBase & {
|
|
33
|
+
tools: RunnableTools<FunctionsArgs> | AutoParseableTool<any, true>[];
|
|
34
|
+
toolContext?: never;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Parameters for tools that require a context value.
|
|
39
|
+
*/
|
|
40
|
+
export type ChatCompletionStreamingToolRunnerParamsWithContext<
|
|
41
|
+
FunctionsArgs extends BaseFunctionsArgs,
|
|
42
|
+
ToolContext,
|
|
43
|
+
> = ChatCompletionStreamingToolRunnerParamsBase & {
|
|
44
|
+
tools: RunnableTools<FunctionsArgs, ToolContext> | AutoParseableTool<any, true>[];
|
|
45
|
+
/**
|
|
46
|
+
* Context to pass to each tool callback during this run.
|
|
47
|
+
*/
|
|
48
|
+
toolContext: ToolContext;
|
|
22
49
|
};
|
|
23
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Parameters for running streaming tools. Supplying a context type makes
|
|
53
|
+
* `toolContext` required; omitting it preserves the existing no-context form.
|
|
54
|
+
*/
|
|
55
|
+
export type ChatCompletionStreamingToolRunnerParams<
|
|
56
|
+
FunctionsArgs extends BaseFunctionsArgs,
|
|
57
|
+
ToolContext = never,
|
|
58
|
+
> = [ToolContext] extends [never] ? ChatCompletionStreamingToolRunnerParamsWithoutContext<FunctionsArgs>
|
|
59
|
+
: ChatCompletionStreamingToolRunnerParamsWithContext<FunctionsArgs, ToolContext>;
|
|
60
|
+
|
|
24
61
|
export class ChatCompletionStreamingRunner<ParsedT = null>
|
|
25
62
|
extends ChatCompletionStream<ParsedT>
|
|
26
63
|
implements AsyncIterable<ChatCompletionChunk>
|
|
@@ -31,9 +68,109 @@ export class ChatCompletionStreamingRunner<ParsedT = null>
|
|
|
31
68
|
return runner;
|
|
32
69
|
}
|
|
33
70
|
|
|
71
|
+
override toReadableStream(): ReadableStream {
|
|
72
|
+
const pushQueue: ChatCompletionReadableStreamItem[] = [];
|
|
73
|
+
const readQueue: {
|
|
74
|
+
resolve: (event: ChatCompletionReadableStreamItem | undefined) => void;
|
|
75
|
+
reject: (err: unknown) => void;
|
|
76
|
+
}[] = [];
|
|
77
|
+
let done = false;
|
|
78
|
+
let lastChunk: ChatCompletionChunk | undefined;
|
|
79
|
+
let toolCallIds: string[] | undefined;
|
|
80
|
+
|
|
81
|
+
const pushEvent = (event: ChatCompletionReadableStreamItem) => {
|
|
82
|
+
const reader = readQueue.shift();
|
|
83
|
+
if (reader) {
|
|
84
|
+
reader.resolve(event);
|
|
85
|
+
} else {
|
|
86
|
+
pushQueue.push(event);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
this.on('chunk', (chunk) => {
|
|
91
|
+
lastChunk = chunk;
|
|
92
|
+
pushEvent(chunk);
|
|
93
|
+
});
|
|
94
|
+
this.on('message', (message: ChatCompletionMessageParam) => {
|
|
95
|
+
if (isAssistantMessage(message)) {
|
|
96
|
+
toolCallIds = message.tool_calls?.map((toolCall) => toolCall.id);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (isToolMessage(message)) {
|
|
101
|
+
if (!lastChunk) {
|
|
102
|
+
throw new OpenAIError('cannot serialize a tool message before receiving any chunks');
|
|
103
|
+
}
|
|
104
|
+
pushEvent(makeChatCompletionReadableStreamMessageChunk(lastChunk, message, toolCallIds));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
this.on('end', () => {
|
|
109
|
+
done = true;
|
|
110
|
+
for (const reader of readQueue) {
|
|
111
|
+
reader.resolve(undefined);
|
|
112
|
+
}
|
|
113
|
+
readQueue.length = 0;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.on('abort', (err) => {
|
|
117
|
+
done = true;
|
|
118
|
+
for (const reader of readQueue) {
|
|
119
|
+
reader.reject(err);
|
|
120
|
+
}
|
|
121
|
+
readQueue.length = 0;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
this.on('error', (err) => {
|
|
125
|
+
done = true;
|
|
126
|
+
for (const reader of readQueue) {
|
|
127
|
+
reader.reject(err);
|
|
128
|
+
}
|
|
129
|
+
readQueue.length = 0;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const iterator = (): AsyncIterator<ChatCompletionReadableStreamItem> => ({
|
|
133
|
+
next: async (): Promise<IteratorResult<ChatCompletionReadableStreamItem>> => {
|
|
134
|
+
if (!pushQueue.length) {
|
|
135
|
+
if (done) {
|
|
136
|
+
return { value: undefined, done: true };
|
|
137
|
+
}
|
|
138
|
+
return new Promise<ChatCompletionReadableStreamItem | undefined>((resolve, reject) =>
|
|
139
|
+
readQueue.push({ resolve, reject }),
|
|
140
|
+
).then((event) => (event ? { value: event, done: false } : { value: undefined, done: true }));
|
|
141
|
+
}
|
|
142
|
+
const event = pushQueue.shift();
|
|
143
|
+
if (!event) {
|
|
144
|
+
return { value: undefined, done: true };
|
|
145
|
+
}
|
|
146
|
+
return { value: event, done: false };
|
|
147
|
+
},
|
|
148
|
+
return: async () => {
|
|
149
|
+
this.abort();
|
|
150
|
+
return { value: undefined, done: true };
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const stream = new Stream(iterator, this.controller);
|
|
155
|
+
return stream.toReadableStream();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static runTools<T extends (string | object)[], ParsedT = null, ToolContext = unknown>(
|
|
159
|
+
client: OpenAI,
|
|
160
|
+
params: ChatCompletionStreamingToolRunnerParamsWithContext<T, ToolContext>,
|
|
161
|
+
options?: RunnerOptions,
|
|
162
|
+
): ChatCompletionStreamingRunner<ParsedT>;
|
|
163
|
+
|
|
34
164
|
static runTools<T extends (string | object)[], ParsedT = null>(
|
|
35
165
|
client: OpenAI,
|
|
36
|
-
params:
|
|
166
|
+
params: ChatCompletionStreamingToolRunnerParamsWithoutContext<T>,
|
|
167
|
+
options?: RunnerOptions,
|
|
168
|
+
): ChatCompletionStreamingRunner<ParsedT>;
|
|
169
|
+
static runTools<T extends (string | object)[], ParsedT = null, ToolContext = unknown>(
|
|
170
|
+
client: OpenAI,
|
|
171
|
+
params:
|
|
172
|
+
| ChatCompletionStreamingToolRunnerParamsWithContext<T, ToolContext>
|
|
173
|
+
| ChatCompletionStreamingToolRunnerParamsWithoutContext<T>,
|
|
37
174
|
options?: RunnerOptions,
|
|
38
175
|
): ChatCompletionStreamingRunner<ParsedT> {
|
|
39
176
|
const runner = new ChatCompletionStreamingRunner<ParsedT>(
|
package/src/lib/EventStream.ts
CHANGED
|
@@ -44,10 +44,17 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
44
44
|
// Unfortunately if we call `executor()` immediately we get runtime errors about
|
|
45
45
|
// references to `this` before the `super()` constructor call returns.
|
|
46
46
|
setTimeout(() => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
Promise.resolve()
|
|
48
|
+
.then(executor)
|
|
49
|
+
.then(() => {
|
|
50
|
+
try {
|
|
51
|
+
this._emitFinal();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
this.#handleError(error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this._emit('end');
|
|
57
|
+
}, this.#handleError.bind(this));
|
|
51
58
|
}, 0);
|
|
52
59
|
}
|
|
53
60
|
|
|
@@ -157,6 +164,109 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
157
164
|
});
|
|
158
165
|
}
|
|
159
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Returns an async iterator that yields every time the event is triggered.
|
|
169
|
+
* The iterator ends when the stream ends and rejects if the stream errors
|
|
170
|
+
* or is aborted. If you request the 'error' or 'abort' event, the iterator
|
|
171
|
+
* yields that event instead of rejecting.
|
|
172
|
+
*
|
|
173
|
+
* Example:
|
|
174
|
+
*
|
|
175
|
+
* for await (const [message] of stream.events('message')) {
|
|
176
|
+
* await processMessage(message);
|
|
177
|
+
* }
|
|
178
|
+
*/
|
|
179
|
+
events<Event extends keyof EventTypes>(
|
|
180
|
+
event: Event,
|
|
181
|
+
): AsyncIterableIterator<EventParameters<EventTypes, Event>> {
|
|
182
|
+
type Parameters = EventParameters<EventTypes, Event>;
|
|
183
|
+
type Result = IteratorResult<Parameters>;
|
|
184
|
+
type Reader = {
|
|
185
|
+
resolve: (result: Result) => void;
|
|
186
|
+
reject: (error: OpenAIError) => void;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const pushQueue: Parameters[] = [];
|
|
190
|
+
const readQueue: Reader[] = [];
|
|
191
|
+
let ended = this.ended;
|
|
192
|
+
let failure: OpenAIError | undefined;
|
|
193
|
+
let failureDelivered = false;
|
|
194
|
+
|
|
195
|
+
const doneResult = (): Result => ({ value: undefined as never, done: true });
|
|
196
|
+
const finishReaders = () => {
|
|
197
|
+
while (readQueue.length) {
|
|
198
|
+
readQueue.shift()!.resolve(doneResult());
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const rejectReader = () => {
|
|
202
|
+
if (!failure || failureDelivered || !readQueue.length) return;
|
|
203
|
+
failureDelivered = true;
|
|
204
|
+
readQueue.shift()!.reject(failure);
|
|
205
|
+
};
|
|
206
|
+
const cleanup = () => {
|
|
207
|
+
this.off(event, onEvent as EventListener<EventTypes, Event>);
|
|
208
|
+
this.off('end', onEnd);
|
|
209
|
+
if (event !== 'error') this.off('error', onFailure);
|
|
210
|
+
if (event !== 'abort') this.off('abort', onFailure);
|
|
211
|
+
};
|
|
212
|
+
const onEvent = (...args: Parameters) => {
|
|
213
|
+
if (ended) return;
|
|
214
|
+
const reader = readQueue.shift();
|
|
215
|
+
if (reader) {
|
|
216
|
+
reader.resolve({ value: args, done: false });
|
|
217
|
+
} else {
|
|
218
|
+
pushQueue.push(args);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
const onFailure = (error: OpenAIError) => {
|
|
222
|
+
failure = error;
|
|
223
|
+
if (!pushQueue.length) rejectReader();
|
|
224
|
+
};
|
|
225
|
+
const onEnd = () => {
|
|
226
|
+
ended = true;
|
|
227
|
+
cleanup();
|
|
228
|
+
if (!pushQueue.length) {
|
|
229
|
+
rejectReader();
|
|
230
|
+
finishReaders();
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
if (!ended) {
|
|
235
|
+
this.on(event, onEvent as EventListener<EventTypes, Event>);
|
|
236
|
+
this.on('end', onEnd);
|
|
237
|
+
if (event !== 'error') this.on('error', onFailure);
|
|
238
|
+
if (event !== 'abort') this.on('abort', onFailure);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
next: () => {
|
|
243
|
+
const value = pushQueue.shift();
|
|
244
|
+
if (value) return Promise.resolve({ value, done: false });
|
|
245
|
+
|
|
246
|
+
if (failure && !failureDelivered) {
|
|
247
|
+
failureDelivered = true;
|
|
248
|
+
return Promise.reject(failure);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (ended) return Promise.resolve(doneResult());
|
|
252
|
+
|
|
253
|
+
return new Promise<Result>((resolve, reject) => {
|
|
254
|
+
readQueue.push({ resolve, reject });
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
return: () => {
|
|
258
|
+
ended = true;
|
|
259
|
+
pushQueue.length = 0;
|
|
260
|
+
cleanup();
|
|
261
|
+
finishReaders();
|
|
262
|
+
return Promise.resolve(doneResult());
|
|
263
|
+
},
|
|
264
|
+
[Symbol.asyncIterator]() {
|
|
265
|
+
return this;
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
160
270
|
async done(): Promise<void> {
|
|
161
271
|
this.#catchingPromiseCreated = true;
|
|
162
272
|
await this.#endPromise;
|