openai 6.44.0 → 6.45.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 +48 -0
- package/README.md +85 -102
- package/_vendor/zod-to-json-schema/parseDef.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parseDef.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parseDef.js +41 -15
- package/_vendor/zod-to-json-schema/parseDef.js.map +1 -1
- package/_vendor/zod-to-json-schema/parseDef.mjs +41 -15
- package/_vendor/zod-to-json-schema/parseDef.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/branded.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/branded.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/branded.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/catch.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/catch.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/catch.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/default.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/default.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/default.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/nullable.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/nullable.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/nullable.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.js +3 -3
- package/_vendor/zod-to-json-schema/parsers/optional.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/optional.mjs +3 -3
- package/_vendor/zod-to-json-schema/parsers/optional.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.js +3 -3
- package/_vendor/zod-to-json-schema/parsers/pipeline.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/pipeline.mjs +3 -3
- package/_vendor/zod-to-json-schema/parsers/pipeline.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/promise.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/promise.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/promise.mjs.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.d.mts +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.d.mts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.d.ts +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.d.ts.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.js +2 -2
- package/_vendor/zod-to-json-schema/parsers/readonly.js.map +1 -1
- package/_vendor/zod-to-json-schema/parsers/readonly.mjs +2 -2
- package/_vendor/zod-to-json-schema/parsers/readonly.mjs.map +1 -1
- package/auth/workload-identity-auth.d.mts.map +1 -1
- package/auth/workload-identity-auth.d.ts.map +1 -1
- package/auth/workload-identity-auth.js +12 -4
- package/auth/workload-identity-auth.js.map +1 -1
- package/auth/workload-identity-auth.mjs +13 -5
- package/auth/workload-identity-auth.mjs.map +1 -1
- package/azure.d.mts +3 -1
- package/azure.d.mts.map +1 -1
- package/azure.d.ts +3 -1
- package/azure.d.ts.map +1 -1
- package/azure.js.map +1 -1
- package/azure.mjs.map +1 -1
- package/beta/realtime/internal-base.d.mts +14 -1
- package/beta/realtime/internal-base.d.mts.map +1 -1
- package/beta/realtime/internal-base.d.ts +14 -1
- package/beta/realtime/internal-base.d.ts.map +1 -1
- package/beta/realtime/internal-base.js +21 -5
- package/beta/realtime/internal-base.js.map +1 -1
- package/beta/realtime/internal-base.mjs +21 -5
- package/beta/realtime/internal-base.mjs.map +1 -1
- package/beta/realtime/websocket.d.mts +3 -5
- package/beta/realtime/websocket.d.mts.map +1 -1
- package/beta/realtime/websocket.d.ts +3 -5
- package/beta/realtime/websocket.d.ts.map +1 -1
- package/beta/realtime/websocket.js +2 -3
- package/beta/realtime/websocket.js.map +1 -1
- package/beta/realtime/websocket.mjs +3 -4
- package/beta/realtime/websocket.mjs.map +1 -1
- package/beta/realtime/ws.d.mts +3 -5
- package/beta/realtime/ws.d.mts.map +1 -1
- package/beta/realtime/ws.d.ts +3 -5
- package/beta/realtime/ws.d.ts.map +1 -1
- package/beta/realtime/ws.js +2 -3
- package/beta/realtime/ws.js.map +1 -1
- package/beta/realtime/ws.mjs +3 -4
- package/beta/realtime/ws.mjs.map +1 -1
- package/client.d.mts +9 -1
- package/client.d.mts.map +1 -1
- package/client.d.ts +9 -1
- package/client.d.ts.map +1 -1
- package/client.js +56 -9
- package/client.js.map +1 -1
- package/client.mjs +56 -9
- package/client.mjs.map +1 -1
- package/helpers/zod.d.mts.map +1 -1
- package/helpers/zod.d.ts.map +1 -1
- package/helpers/zod.js +12 -0
- package/helpers/zod.js.map +1 -1
- package/helpers/zod.mjs +12 -0
- package/helpers/zod.mjs.map +1 -1
- package/internal/bedrock.d.mts +34 -0
- package/internal/bedrock.d.mts.map +1 -0
- package/internal/bedrock.d.ts +34 -0
- package/internal/bedrock.d.ts.map +1 -0
- package/internal/bedrock.js +107 -0
- package/internal/bedrock.js.map +1 -0
- package/internal/bedrock.mjs +99 -0
- package/internal/bedrock.mjs.map +1 -0
- package/internal/provider.d.mts +23 -0
- package/internal/provider.d.mts.map +1 -0
- package/internal/provider.d.ts +23 -0
- package/internal/provider.d.ts.map +1 -0
- package/internal/provider.js +36 -0
- package/internal/provider.js.map +1 -0
- package/internal/provider.mjs +32 -0
- package/internal/provider.mjs.map +1 -0
- package/internal/utils/log.d.mts.map +1 -1
- package/internal/utils/log.d.ts.map +1 -1
- package/internal/utils/log.js +1 -0
- package/internal/utils/log.js.map +1 -1
- package/internal/utils/log.mjs +1 -0
- package/internal/utils/log.mjs.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.mts +15 -4
- package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.ts +15 -4
- package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
- package/lib/AbstractChatCompletionRunner.js +63 -40
- package/lib/AbstractChatCompletionRunner.js.map +1 -1
- package/lib/AbstractChatCompletionRunner.mjs +63 -40
- 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 +4 -24
- package/lib/AssistantStream.js.map +1 -1
- package/lib/AssistantStream.mjs +4 -24
- package/lib/AssistantStream.mjs.map +1 -1
- package/lib/ChatCompletionRunner.js +1 -1
- package/lib/ChatCompletionRunner.js.map +1 -1
- package/lib/ChatCompletionRunner.mjs +1 -1
- package/lib/ChatCompletionRunner.mjs.map +1 -1
- package/lib/ChatCompletionStream.d.mts.map +1 -1
- package/lib/ChatCompletionStream.d.ts.map +1 -1
- package/lib/ChatCompletionStream.js +4 -13
- package/lib/ChatCompletionStream.js.map +1 -1
- package/lib/ChatCompletionStream.mjs +4 -13
- package/lib/ChatCompletionStream.mjs.map +1 -1
- package/lib/ChatCompletionStreamingRunner.js +1 -1
- package/lib/ChatCompletionStreamingRunner.js.map +1 -1
- package/lib/ChatCompletionStreamingRunner.mjs +1 -1
- package/lib/ChatCompletionStreamingRunner.mjs.map +1 -1
- package/lib/EventEmitter.d.mts.map +1 -1
- package/lib/EventEmitter.d.ts.map +1 -1
- package/lib/EventEmitter.js +12 -2
- package/lib/EventEmitter.js.map +1 -1
- package/lib/EventEmitter.mjs +12 -2
- package/lib/EventEmitter.mjs.map +1 -1
- package/lib/EventStream.d.mts +1 -0
- package/lib/EventStream.d.mts.map +1 -1
- package/lib/EventStream.d.ts +1 -0
- package/lib/EventStream.d.ts.map +1 -1
- package/lib/EventStream.js +19 -2
- package/lib/EventStream.js.map +1 -1
- package/lib/EventStream.mjs +19 -2
- package/lib/EventStream.mjs.map +1 -1
- package/lib/ResponsesParser.d.mts.map +1 -1
- package/lib/ResponsesParser.d.ts.map +1 -1
- package/lib/ResponsesParser.js +12 -4
- package/lib/ResponsesParser.js.map +1 -1
- package/lib/ResponsesParser.mjs +12 -4
- package/lib/ResponsesParser.mjs.map +1 -1
- package/lib/responses/ResponseAccumulator.d.mts +10 -0
- package/lib/responses/ResponseAccumulator.d.mts.map +1 -0
- package/lib/responses/ResponseAccumulator.d.ts +10 -0
- package/lib/responses/ResponseAccumulator.d.ts.map +1 -0
- package/lib/responses/ResponseAccumulator.js +402 -0
- package/lib/responses/ResponseAccumulator.js.map +1 -0
- package/lib/responses/ResponseAccumulator.mjs +399 -0
- package/lib/responses/ResponseAccumulator.mjs.map +1 -0
- package/lib/responses/ResponseInputItems.d.mts +19 -0
- package/lib/responses/ResponseInputItems.d.mts.map +1 -0
- package/lib/responses/ResponseInputItems.d.ts +19 -0
- package/lib/responses/ResponseInputItems.d.ts.map +1 -0
- package/lib/responses/ResponseInputItems.js +102 -0
- package/lib/responses/ResponseInputItems.js.map +1 -0
- package/lib/responses/ResponseInputItems.mjs +98 -0
- package/lib/responses/ResponseInputItems.mjs.map +1 -0
- package/lib/responses/ResponseStream.d.mts.map +1 -1
- package/lib/responses/ResponseStream.d.ts.map +1 -1
- package/lib/responses/ResponseStream.js +5 -90
- package/lib/responses/ResponseStream.js.map +1 -1
- package/lib/responses/ResponseStream.mjs +5 -90
- package/lib/responses/ResponseStream.mjs.map +1 -1
- package/package.json +24 -1
- package/providers/bedrock/aws.d.mts +24 -0
- package/providers/bedrock/aws.d.mts.map +1 -0
- package/providers/bedrock/aws.d.ts +24 -0
- package/providers/bedrock/aws.d.ts.map +1 -0
- package/providers/bedrock/aws.js +170 -0
- package/providers/bedrock/aws.js.map +1 -0
- package/providers/bedrock/aws.mjs +166 -0
- package/providers/bedrock/aws.mjs.map +1 -0
- package/providers/bedrock.d.mts +7 -0
- package/providers/bedrock.d.mts.map +1 -0
- package/providers/bedrock.d.ts +7 -0
- package/providers/bedrock.d.ts.map +1 -0
- package/providers/bedrock.js +26 -0
- package/providers/bedrock.js.map +1 -0
- package/providers/bedrock.mjs +22 -0
- package/providers/bedrock.mjs.map +1 -0
- package/realtime/internal-base.d.mts +28 -1
- package/realtime/internal-base.d.mts.map +1 -1
- package/realtime/internal-base.d.ts +28 -1
- package/realtime/internal-base.d.ts.map +1 -1
- package/realtime/internal-base.js +50 -7
- package/realtime/internal-base.js.map +1 -1
- package/realtime/internal-base.mjs +49 -7
- package/realtime/internal-base.mjs.map +1 -1
- package/realtime/websocket.d.mts +4 -7
- package/realtime/websocket.d.mts.map +1 -1
- package/realtime/websocket.d.ts +4 -7
- package/realtime/websocket.d.ts.map +1 -1
- package/realtime/websocket.js +4 -8
- package/realtime/websocket.js.map +1 -1
- package/realtime/websocket.mjs +5 -9
- package/realtime/websocket.mjs.map +1 -1
- package/realtime/ws.d.mts +4 -7
- package/realtime/ws.d.mts.map +1 -1
- package/realtime/ws.d.ts +4 -7
- package/realtime/ws.d.ts.map +1 -1
- package/realtime/ws.js +4 -8
- package/realtime/ws.js.map +1 -1
- package/realtime/ws.mjs +5 -9
- package/realtime/ws.mjs.map +1 -1
- package/src/_vendor/zod-to-json-schema/parseDef.ts +44 -16
- package/src/_vendor/zod-to-json-schema/parsers/branded.ts +2 -2
- package/src/_vendor/zod-to-json-schema/parsers/catch.ts +2 -2
- package/src/_vendor/zod-to-json-schema/parsers/default.ts +6 -2
- package/src/_vendor/zod-to-json-schema/parsers/nullable.ts +13 -5
- package/src/_vendor/zod-to-json-schema/parsers/optional.ts +14 -6
- package/src/_vendor/zod-to-json-schema/parsers/pipeline.ts +3 -2
- package/src/_vendor/zod-to-json-schema/parsers/promise.ts +6 -2
- package/src/_vendor/zod-to-json-schema/parsers/readonly.ts +2 -2
- package/src/auth/workload-identity-auth.ts +16 -5
- package/src/azure.ts +4 -1
- package/src/beta/realtime/internal-base.ts +43 -5
- package/src/beta/realtime/websocket.ts +10 -7
- package/src/beta/realtime/ws.ts +10 -7
- package/src/client.ts +80 -18
- package/src/helpers/zod.ts +16 -0
- package/src/internal/bedrock.ts +153 -0
- package/src/internal/provider.ts +60 -0
- package/src/internal/utils/log.ts +1 -0
- package/src/lib/AbstractChatCompletionRunner.ts +96 -45
- package/src/lib/AssistantStream.ts +4 -20
- package/src/lib/ChatCompletionRunner.ts +1 -1
- package/src/lib/ChatCompletionStream.ts +4 -11
- package/src/lib/ChatCompletionStreamingRunner.ts +1 -1
- package/src/lib/EventEmitter.ts +11 -2
- package/src/lib/EventStream.ts +20 -0
- package/src/lib/ResponsesParser.ts +18 -4
- package/src/lib/responses/ResponseAccumulator.ts +412 -0
- package/src/lib/responses/ResponseInputItems.ts +127 -0
- package/src/lib/responses/ResponseStream.ts +4 -93
- package/src/providers/bedrock/aws.ts +255 -0
- package/src/providers/bedrock.ts +33 -0
- package/src/realtime/internal-base.ts +90 -7
- package/src/realtime/websocket.ts +15 -13
- package/src/realtime/ws.ts +15 -13
- 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
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as Errors from '../error';
|
|
2
|
+
import type { ApiKeySetter } from '../client';
|
|
3
|
+
import type { FinalizedRequestInit } from './types';
|
|
4
|
+
import type { ProviderRequestContext } from './provider';
|
|
5
|
+
import { readEnv } from './utils';
|
|
6
|
+
|
|
7
|
+
export interface BedrockEndpointOptions {
|
|
8
|
+
/** AWS region used to derive the default Mantle endpoint. */
|
|
9
|
+
region?: string | undefined;
|
|
10
|
+
|
|
11
|
+
/** Bedrock API root. Defaults to AWS_BEDROCK_BASE_URL or the regional Mantle endpoint. */
|
|
12
|
+
baseURL?: string | null | undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BedrockBearerOptions {
|
|
16
|
+
/** Explicit Bedrock bearer credential. Set to null to skip the environment bearer fallback. */
|
|
17
|
+
apiKey?: string | null | undefined;
|
|
18
|
+
|
|
19
|
+
/** A function that resolves a Bedrock bearer credential before every request attempt. */
|
|
20
|
+
tokenProvider?: ApiKeySetter | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface BedrockRequestAuth {
|
|
24
|
+
prepareRequest(request: FinalizedRequestInit, context: ProviderRequestContext): void | Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type BedrockAuthFactory = () => BedrockRequestAuth;
|
|
28
|
+
|
|
29
|
+
export function errorWithCause(message: string, cause: unknown): Errors.OpenAIError {
|
|
30
|
+
const error = new Errors.OpenAIError(message) as Errors.OpenAIError & { cause?: unknown };
|
|
31
|
+
error.cause = cause;
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function normalizeOptionalString(value: string | null | undefined): string | undefined {
|
|
36
|
+
const normalized = typeof value === 'string' ? value.trim() : undefined;
|
|
37
|
+
return normalized ? normalized : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function normalizeBaseURL(baseURL: string): string {
|
|
41
|
+
const url = new URL(baseURL);
|
|
42
|
+
const responsesMatch = url.pathname.match(/\/responses(?:\/.*)?$/);
|
|
43
|
+
if (responsesMatch?.index !== undefined) {
|
|
44
|
+
url.pathname = url.pathname.slice(0, responsesMatch.index) || '/';
|
|
45
|
+
}
|
|
46
|
+
return url.toString().replace(/\/$/, '');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function resolveBedrockEndpoint(options: BedrockEndpointOptions): {
|
|
50
|
+
region: string | undefined;
|
|
51
|
+
baseURL: string;
|
|
52
|
+
} {
|
|
53
|
+
if (options.region !== undefined && !normalizeOptionalString(options.region)) {
|
|
54
|
+
throw new Errors.OpenAIError('The Bedrock AWS `region` must not be empty.');
|
|
55
|
+
}
|
|
56
|
+
if (
|
|
57
|
+
options.baseURL !== undefined &&
|
|
58
|
+
options.baseURL !== null &&
|
|
59
|
+
!normalizeOptionalString(options.baseURL)
|
|
60
|
+
) {
|
|
61
|
+
throw new Errors.OpenAIError('The Bedrock `baseURL` must not be empty.');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const region =
|
|
65
|
+
normalizeOptionalString(options.region) ??
|
|
66
|
+
normalizeOptionalString(readEnv('AWS_REGION')) ??
|
|
67
|
+
normalizeOptionalString(readEnv('AWS_DEFAULT_REGION'));
|
|
68
|
+
const configuredBaseURL =
|
|
69
|
+
options.baseURL === undefined ? normalizeOptionalString(readEnv('AWS_BEDROCK_BASE_URL'))
|
|
70
|
+
: options.baseURL === null ? undefined
|
|
71
|
+
: normalizeOptionalString(options.baseURL);
|
|
72
|
+
|
|
73
|
+
if (configuredBaseURL) return { region, baseURL: normalizeBaseURL(configuredBaseURL) };
|
|
74
|
+
if (!region) {
|
|
75
|
+
throw new Errors.OpenAIError(
|
|
76
|
+
'Bedrock requires an AWS region. Pass `region` to `bedrock(...)`, or set `AWS_REGION` or `AWS_DEFAULT_REGION`.',
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return { region, baseURL: `https://bedrock-mantle.${region}.api.aws/openai/v1` };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function assertProviderOwnsAuthorization(headers: Headers): void {
|
|
83
|
+
if (headers.has('authorization')) {
|
|
84
|
+
throw new Errors.OpenAIError(
|
|
85
|
+
'Bedrock provider authentication cannot be combined with a custom `Authorization` header.',
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
class BedrockBearerAuth implements BedrockRequestAuth {
|
|
91
|
+
constructor(private readonly tokenProvider: ApiKeySetter) {}
|
|
92
|
+
|
|
93
|
+
async prepareRequest(request: FinalizedRequestInit, _context: ProviderRequestContext): Promise<void> {
|
|
94
|
+
const headers = new Headers(request.headers);
|
|
95
|
+
assertProviderOwnsAuthorization(headers);
|
|
96
|
+
|
|
97
|
+
let token: unknown;
|
|
98
|
+
try {
|
|
99
|
+
token = await this.tokenProvider();
|
|
100
|
+
} catch (cause) {
|
|
101
|
+
throw errorWithCause('Failed to resolve a bearer credential for Bedrock.', cause);
|
|
102
|
+
}
|
|
103
|
+
if (typeof token !== 'string' || !token.trim()) {
|
|
104
|
+
throw new Errors.OpenAIError('The Bedrock bearer credential provider must return a non-empty string.');
|
|
105
|
+
}
|
|
106
|
+
headers.set('authorization', `Bearer ${token}`);
|
|
107
|
+
request.headers = headers;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function resolveBedrockBearerAuth(
|
|
112
|
+
options: BedrockBearerOptions,
|
|
113
|
+
{ allowEnvironment = true }: { allowEnvironment?: boolean } = {},
|
|
114
|
+
): { factory: BedrockAuthFactory | undefined; explicit: boolean } {
|
|
115
|
+
if (
|
|
116
|
+
options.apiKey !== undefined &&
|
|
117
|
+
options.apiKey !== null &&
|
|
118
|
+
(typeof options.apiKey !== 'string' || !options.apiKey.trim())
|
|
119
|
+
) {
|
|
120
|
+
throw new Errors.OpenAIError('The Bedrock bearer credential must not be empty.');
|
|
121
|
+
}
|
|
122
|
+
if (options.apiKey != null && options.tokenProvider) {
|
|
123
|
+
throw new Errors.OpenAIError(
|
|
124
|
+
'The `apiKey` and `tokenProvider` options are mutually exclusive. Configure only one.',
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (options.tokenProvider) {
|
|
129
|
+
const tokenProvider = options.tokenProvider;
|
|
130
|
+
return { factory: () => new BedrockBearerAuth(tokenProvider), explicit: true };
|
|
131
|
+
}
|
|
132
|
+
if (options.apiKey != null) {
|
|
133
|
+
const apiKey = options.apiKey;
|
|
134
|
+
return { factory: () => new BedrockBearerAuth(async () => apiKey), explicit: true };
|
|
135
|
+
}
|
|
136
|
+
if (allowEnvironment && options.apiKey !== null && readEnv('AWS_BEARER_TOKEN_BEDROCK')) {
|
|
137
|
+
return {
|
|
138
|
+
explicit: false,
|
|
139
|
+
factory: () =>
|
|
140
|
+
new BedrockBearerAuth(async () => {
|
|
141
|
+
const token = readEnv('AWS_BEARER_TOKEN_BEDROCK');
|
|
142
|
+
if (!token) {
|
|
143
|
+
throw new Errors.OpenAIError(
|
|
144
|
+
'Could not find credentials for Bedrock. Set `AWS_BEARER_TOKEN_BEDROCK` or configure AWS credential authentication.',
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return token;
|
|
148
|
+
}),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { factory: undefined, explicit: false };
|
|
153
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FinalRequestOptions } from './request-options';
|
|
2
|
+
import type { FinalizedRequestInit } from './types';
|
|
3
|
+
|
|
4
|
+
declare const providerBrand: unique symbol;
|
|
5
|
+
|
|
6
|
+
/** An opaque provider configuration created by {@link createProvider}. */
|
|
7
|
+
export interface Provider {
|
|
8
|
+
readonly [providerBrand]: true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ProviderRequestContext {
|
|
12
|
+
url: string;
|
|
13
|
+
options: FinalRequestOptions;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ProviderRuntime {
|
|
17
|
+
name: string;
|
|
18
|
+
baseURL: string;
|
|
19
|
+
prepareRequest?(request: FinalizedRequestInit, context: ProviderRequestContext): void | Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ProviderDefinition {
|
|
23
|
+
configure(): ProviderRuntime;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A provider factory such as `bedrock(options)` captures configuration in a
|
|
28
|
+
* definition, while every OpenAI client receives a fresh runtime from
|
|
29
|
+
* `definition.configure()`. Keeping definitions out of the provider object
|
|
30
|
+
* makes providers opaque and prevents arbitrary objects from imitating one.
|
|
31
|
+
* It also leaves provider-specific dependencies outside the core SDK.
|
|
32
|
+
*
|
|
33
|
+
* The registry lives on `globalThis` under a global symbol so a provider made
|
|
34
|
+
* by one copy of the package still works with another copy, including mixed
|
|
35
|
+
* CommonJS and ESM installations. The WeakMap avoids retaining discarded
|
|
36
|
+
* provider configurations.
|
|
37
|
+
*/
|
|
38
|
+
const providerDefinitionsKey = Symbol.for('openai.node.providerDefinitions.v1');
|
|
39
|
+
const providerGlobal = globalThis as any;
|
|
40
|
+
const existingProviderDefinitions = providerGlobal[providerDefinitionsKey] as
|
|
41
|
+
| WeakMap<Provider, ProviderDefinition>
|
|
42
|
+
| undefined;
|
|
43
|
+
const providerDefinitions = existingProviderDefinitions ?? new WeakMap<Provider, ProviderDefinition>();
|
|
44
|
+
if (!existingProviderDefinitions) {
|
|
45
|
+
Object.defineProperty(providerGlobal, providerDefinitionsKey, { value: providerDefinitions });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function createProvider(definition: ProviderDefinition): Provider {
|
|
49
|
+
const provider = Object.freeze({}) as Provider;
|
|
50
|
+
providerDefinitions.set(provider, definition);
|
|
51
|
+
return provider;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function configureProvider(provider: Provider): ProviderRuntime {
|
|
55
|
+
const definition = providerDefinitions.get(provider);
|
|
56
|
+
if (!definition) {
|
|
57
|
+
throw new Error('Invalid provider. Providers must be created with createProvider().');
|
|
58
|
+
}
|
|
59
|
+
return definition.configure();
|
|
60
|
+
}
|
|
@@ -109,6 +109,7 @@ export const formatRequestDetails = (details: {
|
|
|
109
109
|
name.toLowerCase() === 'authorization' ||
|
|
110
110
|
name.toLowerCase() === 'api-key' ||
|
|
111
111
|
name.toLowerCase() === 'x-api-key' ||
|
|
112
|
+
name.toLowerCase() === 'x-amz-security-token' ||
|
|
112
113
|
name.toLowerCase() === 'cookie' ||
|
|
113
114
|
name.toLowerCase() === 'set-cookie'
|
|
114
115
|
) ?
|
|
@@ -8,12 +8,17 @@ import type {
|
|
|
8
8
|
ChatCompletionMessage,
|
|
9
9
|
ChatCompletionMessageFunctionToolCall,
|
|
10
10
|
ChatCompletionMessageParam,
|
|
11
|
+
ChatCompletionMessageToolCall,
|
|
11
12
|
ChatCompletionTool,
|
|
13
|
+
ChatCompletionToolMessageParam,
|
|
12
14
|
ParsedChatCompletion,
|
|
13
15
|
} from '../resources/chat/completions';
|
|
14
16
|
import type { CompletionUsage } from '../resources/completions';
|
|
15
|
-
import type { ChatCompletionToolRunnerParams } from './ChatCompletionRunner';
|
|
16
|
-
import type {
|
|
17
|
+
import type { ChatCompletionRunner, ChatCompletionToolRunnerParams } from './ChatCompletionRunner';
|
|
18
|
+
import type {
|
|
19
|
+
ChatCompletionStreamingRunner,
|
|
20
|
+
ChatCompletionStreamingToolRunnerParams,
|
|
21
|
+
} from './ChatCompletionStreamingRunner';
|
|
17
22
|
import { isAssistantMessage, isToolMessage } from './chatCompletionUtils';
|
|
18
23
|
import { BaseEvents, EventStream } from './EventStream';
|
|
19
24
|
import {
|
|
@@ -24,9 +29,22 @@ import {
|
|
|
24
29
|
} from './RunnableFunction';
|
|
25
30
|
|
|
26
31
|
const DEFAULT_MAX_CHAT_COMPLETIONS = 10;
|
|
32
|
+
|
|
33
|
+
export interface ChatCompletionRunnerContext {
|
|
34
|
+
messages: ChatCompletionMessageParam[];
|
|
35
|
+
abort(): void;
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
export interface RunnerOptions extends RequestOptions {
|
|
28
39
|
/** How many requests to make before canceling. Default 10. */
|
|
29
40
|
maxChatCompletions?: number;
|
|
41
|
+
/**
|
|
42
|
+
* A callback that runs after each chat completion and after any tool calls from
|
|
43
|
+
* that completion have finished. The callback is awaited before the next
|
|
44
|
+
* request starts or before the runner ends. The runner's mutable `messages`
|
|
45
|
+
* array can be used to add context for the next request.
|
|
46
|
+
*/
|
|
47
|
+
afterCompletion?: (completion: ChatCompletion, runner: ChatCompletionRunnerContext) => void | Promise<void>;
|
|
30
48
|
}
|
|
31
49
|
|
|
32
50
|
export class AbstractChatCompletionRunner<
|
|
@@ -113,7 +131,7 @@ export class AbstractChatCompletionRunner<
|
|
|
113
131
|
}
|
|
114
132
|
|
|
115
133
|
/**
|
|
116
|
-
* @returns a promise that resolves with the
|
|
134
|
+
* @returns a promise that resolves with the final assistant ChatCompletionMessage response,
|
|
117
135
|
* or rejects if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage.
|
|
118
136
|
*/
|
|
119
137
|
async finalMessage(): Promise<ChatCompletionMessage> {
|
|
@@ -230,11 +248,7 @@ export class AbstractChatCompletionRunner<
|
|
|
230
248
|
params: ChatCompletionCreateParams,
|
|
231
249
|
options?: RequestOptions,
|
|
232
250
|
): Promise<ParsedChatCompletion<ParsedT>> {
|
|
233
|
-
|
|
234
|
-
if (signal) {
|
|
235
|
-
if (signal.aborted) this.controller.abort();
|
|
236
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
237
|
-
}
|
|
251
|
+
this._listenForAbort(options?.signal);
|
|
238
252
|
this.#validateParams(params);
|
|
239
253
|
|
|
240
254
|
const chatCompletion = await client.chat.completions.create(
|
|
@@ -261,13 +275,14 @@ export class AbstractChatCompletionRunner<
|
|
|
261
275
|
params:
|
|
262
276
|
| ChatCompletionToolRunnerParams<FunctionsArgs>
|
|
263
277
|
| ChatCompletionStreamingToolRunnerParams<FunctionsArgs>,
|
|
278
|
+
runner: ChatCompletionRunner<any> | ChatCompletionStreamingRunner<any>,
|
|
264
279
|
options?: RunnerOptions,
|
|
265
280
|
) {
|
|
266
281
|
const role = 'tool' as const;
|
|
267
282
|
const { tool_choice = 'auto', stream, ...restParams } = params;
|
|
268
283
|
const singleFunctionToCall =
|
|
269
284
|
typeof tool_choice !== 'string' && tool_choice.type === 'function' && tool_choice?.function?.name;
|
|
270
|
-
const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {};
|
|
285
|
+
const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS, afterCompletion } = options || {};
|
|
271
286
|
|
|
272
287
|
// TODO(someday): clean this logic up
|
|
273
288
|
const inputTools = params.tools.map((tool): RunnableToolFunction<any> => {
|
|
@@ -320,6 +335,54 @@ export class AbstractChatCompletionRunner<
|
|
|
320
335
|
this._addMessage(message, false);
|
|
321
336
|
}
|
|
322
337
|
|
|
338
|
+
type ToolCallResult = {
|
|
339
|
+
message: ChatCompletionToolMessageParam | undefined;
|
|
340
|
+
functionCalled: boolean;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
const runToolCall = async (toolCall: ChatCompletionMessageToolCall): Promise<ToolCallResult> => {
|
|
344
|
+
if (toolCall.type !== 'function') return { message: undefined, functionCalled: false };
|
|
345
|
+
|
|
346
|
+
const tool_call_id = toolCall.id;
|
|
347
|
+
const { name, arguments: args } = toolCall.function;
|
|
348
|
+
const fn = functionsByName[name];
|
|
349
|
+
|
|
350
|
+
if (!fn) {
|
|
351
|
+
const content = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${Object.keys(
|
|
352
|
+
functionsByName,
|
|
353
|
+
)
|
|
354
|
+
.map((name) => JSON.stringify(name))
|
|
355
|
+
.join(', ')}. Please try again`;
|
|
356
|
+
|
|
357
|
+
return { message: { role, tool_call_id, content }, functionCalled: false };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (singleFunctionToCall && singleFunctionToCall !== name) {
|
|
361
|
+
const content = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(
|
|
362
|
+
singleFunctionToCall,
|
|
363
|
+
)} requested. Please try again`;
|
|
364
|
+
|
|
365
|
+
return { message: { role, tool_call_id, content }, functionCalled: false };
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
let rawContent: unknown;
|
|
369
|
+
if (isRunnableFunctionWithParse(fn)) {
|
|
370
|
+
let parsed;
|
|
371
|
+
try {
|
|
372
|
+
parsed = await fn.parse(args);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
const content = error instanceof Error ? error.message : String(error);
|
|
375
|
+
return { message: { role, tool_call_id, content }, functionCalled: false };
|
|
376
|
+
}
|
|
377
|
+
rawContent = await fn.function(parsed, runner);
|
|
378
|
+
} else {
|
|
379
|
+
rawContent = await fn.function(args, runner);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const content = this.#stringifyFunctionCallResult(rawContent);
|
|
383
|
+
return { message: { role, tool_call_id, content }, functionCalled: true };
|
|
384
|
+
};
|
|
385
|
+
|
|
323
386
|
for (let i = 0; i < maxChatCompletions; ++i) {
|
|
324
387
|
const chatCompletion: ChatCompletion = await this._createChatCompletion(
|
|
325
388
|
client,
|
|
@@ -336,51 +399,39 @@ export class AbstractChatCompletionRunner<
|
|
|
336
399
|
throw new OpenAIError(`missing message in ChatCompletion response`);
|
|
337
400
|
}
|
|
338
401
|
if (!message.tool_calls?.length) {
|
|
402
|
+
await afterCompletion?.(chatCompletion, runner);
|
|
339
403
|
return;
|
|
340
404
|
}
|
|
341
405
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const fn = functionsByName[name];
|
|
347
|
-
|
|
348
|
-
if (!fn) {
|
|
349
|
-
const content = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${Object.keys(
|
|
350
|
-
functionsByName,
|
|
351
|
-
)
|
|
352
|
-
.map((name) => JSON.stringify(name))
|
|
353
|
-
.join(', ')}. Please try again`;
|
|
354
|
-
|
|
355
|
-
this._addMessage({ role, tool_call_id, content });
|
|
356
|
-
continue;
|
|
357
|
-
} else if (singleFunctionToCall && singleFunctionToCall !== name) {
|
|
358
|
-
const content = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(
|
|
359
|
-
singleFunctionToCall,
|
|
360
|
-
)} requested. Please try again`;
|
|
361
|
-
|
|
362
|
-
this._addMessage({ role, tool_call_id, content });
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
406
|
+
if (singleFunctionToCall || params.parallel_tool_calls === false) {
|
|
407
|
+
for (const toolCall of message.tool_calls) {
|
|
408
|
+
const result = await runToolCall(toolCall);
|
|
409
|
+
if (result.message) this._addMessage(result.message);
|
|
365
410
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const content = error instanceof Error ? error.message : String(error);
|
|
371
|
-
this._addMessage({ role, tool_call_id, content });
|
|
372
|
-
continue;
|
|
411
|
+
if (singleFunctionToCall && result.functionCalled) {
|
|
412
|
+
await afterCompletion?.(chatCompletion, runner);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
373
415
|
}
|
|
416
|
+
} else {
|
|
417
|
+
const results = await Promise.allSettled(message.tool_calls.map(runToolCall));
|
|
374
418
|
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
419
|
+
// Wait for every concurrently running tool to settle before surfacing an
|
|
420
|
+
// error so tool side effects cannot continue after the runner has ended.
|
|
421
|
+
for (const result of results) {
|
|
422
|
+
if (result.status === 'rejected') throw result.reason;
|
|
423
|
+
}
|
|
379
424
|
|
|
380
|
-
|
|
381
|
-
|
|
425
|
+
// Promise.allSettled preserves input order, so the next request receives
|
|
426
|
+
// tool result messages in the same order as the assistant's tool calls.
|
|
427
|
+
for (const result of results) {
|
|
428
|
+
if (result.status === 'fulfilled' && result.value.message) {
|
|
429
|
+
this._addMessage(result.value.message);
|
|
430
|
+
}
|
|
382
431
|
}
|
|
383
432
|
}
|
|
433
|
+
|
|
434
|
+
await afterCompletion?.(chatCompletion, runner);
|
|
384
435
|
}
|
|
385
436
|
|
|
386
437
|
return;
|
|
@@ -165,11 +165,7 @@ export class AssistantStream
|
|
|
165
165
|
readableStream: ReadableStream,
|
|
166
166
|
options?: RequestOptions,
|
|
167
167
|
): Promise<Run> {
|
|
168
|
-
|
|
169
|
-
if (signal) {
|
|
170
|
-
if (signal.aborted) this.controller.abort();
|
|
171
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
172
|
-
}
|
|
168
|
+
this._listenForAbort(options?.signal);
|
|
173
169
|
this._connected();
|
|
174
170
|
const stream = Stream.fromReadableStream<AssistantStreamEvent>(readableStream, this.controller);
|
|
175
171
|
for await (const event of stream) {
|
|
@@ -208,11 +204,7 @@ export class AssistantStream
|
|
|
208
204
|
params: RunSubmitToolOutputsParamsStream,
|
|
209
205
|
options?: RequestOptions,
|
|
210
206
|
): Promise<Run> {
|
|
211
|
-
|
|
212
|
-
if (signal) {
|
|
213
|
-
if (signal.aborted) this.controller.abort();
|
|
214
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
215
|
-
}
|
|
207
|
+
this._listenForAbort(options?.signal);
|
|
216
208
|
|
|
217
209
|
const body: RunSubmitToolOutputsParamsStreaming = { ...params, stream: true };
|
|
218
210
|
const stream = await run.submitToolOutputs(runId, body, {
|
|
@@ -303,11 +295,7 @@ export class AssistantStream
|
|
|
303
295
|
params: ThreadCreateAndRunParamsBase,
|
|
304
296
|
options?: RequestOptions,
|
|
305
297
|
): Promise<Run> {
|
|
306
|
-
|
|
307
|
-
if (signal) {
|
|
308
|
-
if (signal.aborted) this.controller.abort();
|
|
309
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
310
|
-
}
|
|
298
|
+
this._listenForAbort(options?.signal);
|
|
311
299
|
|
|
312
300
|
const body: RunCreateParamsStreaming = { ...params, stream: true };
|
|
313
301
|
const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal });
|
|
@@ -330,11 +318,7 @@ export class AssistantStream
|
|
|
330
318
|
params: RunCreateParamsBase,
|
|
331
319
|
options?: RequestOptions,
|
|
332
320
|
): Promise<Run> {
|
|
333
|
-
|
|
334
|
-
if (signal) {
|
|
335
|
-
if (signal.aborted) this.controller.abort();
|
|
336
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
337
|
-
}
|
|
321
|
+
this._listenForAbort(options?.signal);
|
|
338
322
|
|
|
339
323
|
const body: RunCreateParamsStreaming = { ...params, stream: true };
|
|
340
324
|
const stream = await run.create(threadId, body, { ...options, signal: this.controller.signal });
|
|
@@ -37,7 +37,7 @@ export class ChatCompletionRunner<ParsedT = null> extends AbstractChatCompletion
|
|
|
37
37
|
...options,
|
|
38
38
|
headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' },
|
|
39
39
|
};
|
|
40
|
-
runner._run(() => runner._runTools(client, params, opts));
|
|
40
|
+
runner._run(() => runner._runTools(client, params, runner, opts));
|
|
41
41
|
return runner;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -373,11 +373,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
373
373
|
options?: RequestOptions,
|
|
374
374
|
): Promise<ParsedChatCompletion<ParsedT>> {
|
|
375
375
|
super._createChatCompletion;
|
|
376
|
-
|
|
377
|
-
if (signal) {
|
|
378
|
-
if (signal.aborted) this.controller.abort();
|
|
379
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
380
|
-
}
|
|
376
|
+
this._listenForAbort(options?.signal);
|
|
381
377
|
this.#beginRequest();
|
|
382
378
|
|
|
383
379
|
const stream = await client.chat.completions.create(
|
|
@@ -398,11 +394,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
398
394
|
readableStream: ReadableStream,
|
|
399
395
|
options?: RequestOptions,
|
|
400
396
|
): Promise<ChatCompletion> {
|
|
401
|
-
|
|
402
|
-
if (signal) {
|
|
403
|
-
if (signal.aborted) this.controller.abort();
|
|
404
|
-
signal.addEventListener('abort', () => this.controller.abort());
|
|
405
|
-
}
|
|
397
|
+
this._listenForAbort(options?.signal);
|
|
406
398
|
this.#beginRequest();
|
|
407
399
|
this._connected();
|
|
408
400
|
const stream = Stream.fromReadableStream<ChatCompletionChunk>(readableStream, this.controller);
|
|
@@ -511,7 +503,8 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
511
503
|
choice.message.content = (choice.message.content || '') + content;
|
|
512
504
|
|
|
513
505
|
if (!choice.message.refusal && this.#getAutoParseableResponseFormat()) {
|
|
514
|
-
|
|
506
|
+
// The partial parser does not accept whitespace-only input.
|
|
507
|
+
choice.message.parsed = choice.message.content.trim() ? partialParse(choice.message.content) : null;
|
|
515
508
|
}
|
|
516
509
|
}
|
|
517
510
|
|
|
@@ -44,7 +44,7 @@ export class ChatCompletionStreamingRunner<ParsedT = null>
|
|
|
44
44
|
...options,
|
|
45
45
|
headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' },
|
|
46
46
|
};
|
|
47
|
-
runner._run(() => runner._runTools(client, params, opts));
|
|
47
|
+
runner._run(() => runner._runTools(client, params, runner, opts));
|
|
48
48
|
return runner;
|
|
49
49
|
}
|
|
50
50
|
}
|
package/src/lib/EventEmitter.ts
CHANGED
|
@@ -74,8 +74,17 @@ export class EventEmitter<EventTypes extends Record<string, (...args: any) => an
|
|
|
74
74
|
: EventParameters<EventTypes, Event>
|
|
75
75
|
> {
|
|
76
76
|
return new Promise((resolve, reject) => {
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const onError = (error: unknown) => {
|
|
78
|
+
this.off(event, onEvent as any);
|
|
79
|
+
reject(error);
|
|
80
|
+
};
|
|
81
|
+
const onEvent = (value: unknown) => {
|
|
82
|
+
if (event !== 'error') this.off('error', onError as any);
|
|
83
|
+
resolve(value as any);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if (event !== 'error') this.once('error', onError as any);
|
|
87
|
+
this.once(event, onEvent as any);
|
|
79
88
|
});
|
|
80
89
|
}
|
|
81
90
|
|
package/src/lib/EventStream.ts
CHANGED
|
@@ -14,6 +14,7 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
14
14
|
#listeners: {
|
|
15
15
|
[Event in keyof EventTypes]?: EventListeners<EventTypes, Event>;
|
|
16
16
|
} = {};
|
|
17
|
+
#abortListeners: Array<{ signal: AbortSignal; listener: () => void }> = [];
|
|
17
18
|
|
|
18
19
|
#ended = false;
|
|
19
20
|
#errored = false;
|
|
@@ -72,6 +73,24 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
72
73
|
this.controller.abort();
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
protected _listenForAbort(signal: AbortSignal | null | undefined) {
|
|
77
|
+
if (!signal || this.ended) return;
|
|
78
|
+
if (signal.aborted) {
|
|
79
|
+
this.controller.abort();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const listener = () => this.controller.abort();
|
|
84
|
+
signal.addEventListener('abort', listener, { once: true });
|
|
85
|
+
this.#abortListeners.push({ signal, listener });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#removeAbortListeners() {
|
|
89
|
+
for (const { signal, listener } of this.#abortListeners.splice(0)) {
|
|
90
|
+
signal.removeEventListener('abort', listener);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
75
94
|
/**
|
|
76
95
|
* Adds the listener function to the end of the listeners array for the event.
|
|
77
96
|
* No checks are made to see if the listener has already been added. Multiple calls passing
|
|
@@ -177,6 +196,7 @@ export class EventStream<EventTypes extends BaseEvents> {
|
|
|
177
196
|
}
|
|
178
197
|
|
|
179
198
|
if (event === 'end') {
|
|
199
|
+
this.#removeAbortListeners();
|
|
180
200
|
this.#ended = true;
|
|
181
201
|
this.#resolveEndPromise();
|
|
182
202
|
}
|
|
@@ -31,7 +31,7 @@ export function maybeParseResponse<
|
|
|
31
31
|
ParsedT = Params extends null ? null : ExtractParsedContentFromParams<NonNullable<Params>>,
|
|
32
32
|
>(response: Response, params: Params): ParsedResponse<ParsedT> {
|
|
33
33
|
if (!params || !hasAutoParseableInput(params)) {
|
|
34
|
-
|
|
34
|
+
const parsed = {
|
|
35
35
|
...response,
|
|
36
36
|
output_parsed: null,
|
|
37
37
|
output: response.output.map((item) => {
|
|
@@ -55,6 +55,12 @@ export function maybeParseResponse<
|
|
|
55
55
|
}
|
|
56
56
|
}),
|
|
57
57
|
};
|
|
58
|
+
|
|
59
|
+
if (needsOutputText(response, parsed)) {
|
|
60
|
+
addOutputText(parsed as Response);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return parsed;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
return parseResponse(response, params);
|
|
@@ -64,12 +70,13 @@ export function parseResponse<
|
|
|
64
70
|
Params extends ResponseCreateParamsBase,
|
|
65
71
|
ParsedT = ExtractParsedContentFromParams<Params>,
|
|
66
72
|
>(response: Response, params: Params): ParsedResponse<ParsedT> {
|
|
73
|
+
const shouldParse = !response.status || response.status === 'completed';
|
|
67
74
|
const output: Array<ParsedResponseOutputItem<ParsedT>> = response.output.map(
|
|
68
75
|
(item): ParsedResponseOutputItem<ParsedT> => {
|
|
69
76
|
if (item.type === 'function_call') {
|
|
70
77
|
return {
|
|
71
78
|
...item,
|
|
72
|
-
parsed_arguments: parseToolCall(params, item),
|
|
79
|
+
parsed_arguments: shouldParse ? parseToolCall(params, item) : null,
|
|
73
80
|
};
|
|
74
81
|
}
|
|
75
82
|
if (item.type === 'message') {
|
|
@@ -77,7 +84,7 @@ export function parseResponse<
|
|
|
77
84
|
if (content.type === 'output_text') {
|
|
78
85
|
return {
|
|
79
86
|
...content,
|
|
80
|
-
parsed: parseTextFormat(params, content.text),
|
|
87
|
+
parsed: shouldParse ? parseTextFormat(params, content.text) : null,
|
|
81
88
|
};
|
|
82
89
|
}
|
|
83
90
|
|
|
@@ -95,7 +102,7 @@ export function parseResponse<
|
|
|
95
102
|
);
|
|
96
103
|
|
|
97
104
|
const parsed: Omit<ParsedResponse<ParsedT>, 'output_parsed'> = Object.assign({}, response, { output });
|
|
98
|
-
if (
|
|
105
|
+
if (needsOutputText(response, parsed)) {
|
|
99
106
|
addOutputText(parsed);
|
|
100
107
|
}
|
|
101
108
|
|
|
@@ -247,6 +254,13 @@ export function validateInputTools(tools: ChatCompletionTool[] | undefined) {
|
|
|
247
254
|
}
|
|
248
255
|
}
|
|
249
256
|
|
|
257
|
+
function needsOutputText(
|
|
258
|
+
response: Response,
|
|
259
|
+
target: { output_text?: Response['output_text'] | null },
|
|
260
|
+
): boolean {
|
|
261
|
+
return !Object.getOwnPropertyDescriptor(response, 'output_text') || target.output_text == null;
|
|
262
|
+
}
|
|
263
|
+
|
|
250
264
|
export function addOutputText(rsp: Response): void {
|
|
251
265
|
const texts: string[] = [];
|
|
252
266
|
for (const output of rsp.output) {
|