@veryfront/ext-llm-openai 0.1.1186 → 0.1.1189
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/README.md +49 -2
- package/esm/_dnt.polyfills.d.ts +12 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +15 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +7 -1
- package/esm/openai-chat-request-builder.d.ts +5 -43
- package/esm/openai-chat-request-builder.d.ts.map +1 -1
- package/esm/openai-chat-request-builder.js +18 -4
- package/esm/openai-chat-stream.d.ts +8 -1
- package/esm/openai-chat-stream.d.ts.map +1 -1
- package/esm/openai-chat-stream.js +286 -104
- package/esm/openai-provider-options.d.ts +6 -0
- package/esm/openai-provider-options.d.ts.map +1 -0
- package/esm/openai-provider-options.js +14 -0
- package/esm/openai-provider.d.ts +6 -5
- package/esm/openai-provider.d.ts.map +1 -1
- package/esm/openai-provider.js +579 -129
- package/esm/openai-reasoning-models.d.ts +3 -6
- package/esm/openai-reasoning-models.d.ts.map +1 -1
- package/esm/openai-responses-request-builder.d.ts.map +1 -1
- package/esm/openai-responses-request-builder.js +240 -19
- package/esm/openai-responses-stream.d.ts +12 -1
- package/esm/openai-responses-stream.d.ts.map +1 -1
- package/esm/openai-responses-stream.js +1053 -113
- package/esm/openai-sse-buffer.d.ts +8 -0
- package/esm/openai-sse-buffer.d.ts.map +1 -0
- package/esm/openai-sse-buffer.js +47 -0
- package/esm/openai-stream-metadata.d.ts +6 -0
- package/esm/openai-stream-metadata.d.ts.map +1 -0
- package/esm/openai-stream-metadata.js +10 -0
- package/esm/openai-tool-input.d.ts +10 -0
- package/esm/openai-tool-input.d.ts.map +1 -0
- package/esm/openai-tool-input.js +30 -0
- package/esm/openai-web-search.d.ts +35 -0
- package/esm/openai-web-search.d.ts.map +1 -0
- package/esm/openai-web-search.js +369 -0
- package/package.json +3 -3
|
@@ -1,10 +1,7 @@
|
|
|
1
|
+
import type { RuntimeReasoningOption } from "veryfront/provider/types";
|
|
1
2
|
export type OpenAIReasoningEffort = "low" | "medium" | "high";
|
|
2
|
-
export type OpenAIProviderReasoningEffort =
|
|
3
|
-
export type OpenAIProviderReasoningOption =
|
|
4
|
-
enabled?: boolean;
|
|
5
|
-
effort?: OpenAIProviderReasoningEffort;
|
|
6
|
-
budgetTokens?: number;
|
|
7
|
-
};
|
|
3
|
+
export type OpenAIProviderReasoningEffort = NonNullable<RuntimeReasoningOption["effort"]>;
|
|
4
|
+
export type OpenAIProviderReasoningOption = RuntimeReasoningOption;
|
|
8
5
|
export type ResolvedOpenAIReasoning = {
|
|
9
6
|
effort: OpenAIReasoningEffort;
|
|
10
7
|
source: "default" | "explicit";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-reasoning-models.d.ts","sourceRoot":"","sources":["../src/openai-reasoning-models.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"openai-reasoning-models.d.ts","sourceRoot":"","sources":["../src/openai-reasoning-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE1F,MAAM,MAAM,6BAA6B,GAAG,sBAAsB,CAAC;AAEnE,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC,CAAC;AAIF,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAG5E;AAuBD,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,YAAY,SAAW,GACtB,qBAAqB,GAAG,SAAS,CAwBnC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAChD,uBAAuB,GAAG,SAAS,CAoBrC;AAED,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,SAAW,GAAG,OAAO,CAExF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-responses-request-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAoBxF,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAyYF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,sBAAsB,CA+IxB"}
|
|
@@ -1,10 +1,179 @@
|
|
|
1
|
-
import { readProviderOptions,
|
|
1
|
+
import { jsonValuesEqual, readProviderOptions, stringifyToolArguments, stringifyToolResultValue, unwrapToolInputSchema, } from "veryfront/provider/shared";
|
|
2
2
|
import { rejectsOpenAISamplingParams, resolveOpenAIReasoningConfig, shouldRequestOpenAIReasoningSummary, } from "./openai-reasoning-models.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { defineOpenAIProviderOptions } from "./openai-provider-options.js";
|
|
4
|
+
import { isBoundedOpenAIStreamString, MAX_OPENAI_STREAM_TOOL_NAME_BYTES, } from "./openai-stream-metadata.js";
|
|
5
|
+
import { normalizeOpenAIWebSearchCall, OPENAI_REASONING_ENCRYPTED_CONTENT_INCLUDE, OPENAI_WEB_SEARCH_SOURCES_INCLUDE, readOpenAIRawResponseOutputItems, resolveOpenAIWebSearchDescriptor, } from "./openai-web-search.js";
|
|
6
|
+
function invalidOpenAIProviderHistory() {
|
|
7
|
+
return new TypeError("OpenAI raw response metadata did not match canonical provider tool history");
|
|
8
|
+
}
|
|
9
|
+
function assertUniqueOpenAIToolCallIds(calls) {
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
for (const call of calls) {
|
|
12
|
+
if (seen.has(call.id)) {
|
|
13
|
+
throw invalidOpenAIProviderHistory();
|
|
14
|
+
}
|
|
15
|
+
seen.add(call.id);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function assertOrderedOpenAIToolCallsEqual(left, right) {
|
|
19
|
+
if (left.length !== right.length) {
|
|
20
|
+
throw invalidOpenAIProviderHistory();
|
|
21
|
+
}
|
|
22
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
23
|
+
const leftCall = left[index];
|
|
24
|
+
const rightCall = right[index];
|
|
25
|
+
if (!leftCall ||
|
|
26
|
+
!rightCall ||
|
|
27
|
+
leftCall.id !== rightCall.id ||
|
|
28
|
+
leftCall.name !== rightCall.name ||
|
|
29
|
+
!jsonValuesEqual(leftCall.input, rightCall.input, true)) {
|
|
30
|
+
throw invalidOpenAIProviderHistory();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function validateOpenAIProviderReplay(message, rawOutputItems) {
|
|
35
|
+
const metadataProviderCalls = (message.providerToolCalls ?? []).map((call) => ({
|
|
36
|
+
id: call.toolCallId,
|
|
37
|
+
name: call.toolName,
|
|
38
|
+
input: call.input,
|
|
39
|
+
}));
|
|
40
|
+
const contentProviderCalls = [];
|
|
41
|
+
const clientCalls = [];
|
|
42
|
+
const providerResults = [];
|
|
43
|
+
const contentCallKinds = [];
|
|
44
|
+
for (const part of message.content) {
|
|
45
|
+
if (part.type === "tool-call") {
|
|
46
|
+
const providerExecuted = part.providerExecuted === true;
|
|
47
|
+
const target = providerExecuted ? contentProviderCalls : clientCalls;
|
|
48
|
+
target.push({
|
|
49
|
+
id: part.toolCallId,
|
|
50
|
+
name: part.toolName,
|
|
51
|
+
input: part.input,
|
|
52
|
+
});
|
|
53
|
+
contentCallKinds.push(providerExecuted ? "provider" : "client");
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (part.type === "tool-result" && part.providerExecuted === true) {
|
|
57
|
+
providerResults.push({
|
|
58
|
+
id: part.toolCallId,
|
|
59
|
+
name: part.toolName,
|
|
60
|
+
result: part.result,
|
|
61
|
+
isError: part.isError === true,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
assertUniqueOpenAIToolCallIds(metadataProviderCalls);
|
|
66
|
+
assertUniqueOpenAIToolCallIds(contentProviderCalls);
|
|
67
|
+
assertUniqueOpenAIToolCallIds(clientCalls);
|
|
68
|
+
const seenProviderResultIds = new Set();
|
|
69
|
+
for (const result of providerResults) {
|
|
70
|
+
if (seenProviderResultIds.has(result.id)) {
|
|
71
|
+
throw invalidOpenAIProviderHistory();
|
|
72
|
+
}
|
|
73
|
+
seenProviderResultIds.add(result.id);
|
|
74
|
+
}
|
|
75
|
+
// providerToolCalls is the legacy projection of provider-executed content.
|
|
76
|
+
// Coalesce it only after proving both surviving projections are identical
|
|
77
|
+
// occurrence-for-occurrence; duplicates or a different order are ambiguous.
|
|
78
|
+
if (metadataProviderCalls.length > 0 &&
|
|
79
|
+
contentProviderCalls.length > 0) {
|
|
80
|
+
assertOrderedOpenAIToolCallsEqual(metadataProviderCalls, contentProviderCalls);
|
|
81
|
+
}
|
|
82
|
+
const providerCalls = metadataProviderCalls.length > 0
|
|
83
|
+
? metadataProviderCalls
|
|
84
|
+
: contentProviderCalls;
|
|
85
|
+
const rawProviderCalls = [];
|
|
86
|
+
const rawClientCalls = [];
|
|
87
|
+
const rawCallKinds = [];
|
|
88
|
+
for (const item of rawOutputItems) {
|
|
89
|
+
if (item.type === "web_search_call") {
|
|
90
|
+
const call = normalizeOpenAIWebSearchCall(item, () => invalidOpenAIProviderHistory());
|
|
91
|
+
rawProviderCalls.push({
|
|
92
|
+
id: call.id,
|
|
93
|
+
input: call.input,
|
|
94
|
+
result: call.result,
|
|
95
|
+
isError: call.isError,
|
|
96
|
+
});
|
|
97
|
+
rawCallKinds.push("provider");
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (item.type === "function_call") {
|
|
101
|
+
if (typeof item.call_id !== "string" ||
|
|
102
|
+
typeof item.name !== "string" ||
|
|
103
|
+
typeof item.arguments !== "string") {
|
|
104
|
+
throw invalidOpenAIProviderHistory();
|
|
105
|
+
}
|
|
106
|
+
rawClientCalls.push({
|
|
107
|
+
id: item.call_id,
|
|
108
|
+
name: item.name,
|
|
109
|
+
input: item.arguments,
|
|
110
|
+
});
|
|
111
|
+
rawCallKinds.push("client");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// The provider parser rejects duplicate call ids across both provider- and
|
|
115
|
+
// client-executed tools. Exact replay must enforce the same invariant even
|
|
116
|
+
// for legacy metadata that predates that parser check.
|
|
117
|
+
assertUniqueOpenAIToolCallIds([
|
|
118
|
+
...rawProviderCalls,
|
|
119
|
+
...rawClientCalls,
|
|
120
|
+
]);
|
|
121
|
+
if (providerCalls.length > 0) {
|
|
122
|
+
if (providerCalls.length !== rawProviderCalls.length) {
|
|
123
|
+
throw invalidOpenAIProviderHistory();
|
|
124
|
+
}
|
|
125
|
+
for (let index = 0; index < providerCalls.length; index += 1) {
|
|
126
|
+
const canonical = providerCalls[index];
|
|
127
|
+
const raw = rawProviderCalls[index];
|
|
128
|
+
if (!canonical ||
|
|
129
|
+
!raw ||
|
|
130
|
+
canonical.id !== raw.id ||
|
|
131
|
+
!jsonValuesEqual(canonical.input, raw.input, true)) {
|
|
132
|
+
throw invalidOpenAIProviderHistory();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (providerResults.length > 0) {
|
|
137
|
+
if (providerResults.length !== rawProviderCalls.length) {
|
|
138
|
+
throw invalidOpenAIProviderHistory();
|
|
139
|
+
}
|
|
140
|
+
for (let index = 0; index < providerResults.length; index += 1) {
|
|
141
|
+
const canonical = providerResults[index];
|
|
142
|
+
const raw = rawProviderCalls[index];
|
|
143
|
+
if (!canonical ||
|
|
144
|
+
!raw ||
|
|
145
|
+
canonical.id !== raw.id ||
|
|
146
|
+
canonical.isError !== raw.isError ||
|
|
147
|
+
!jsonValuesEqual(canonical.result, raw.result)) {
|
|
148
|
+
throw invalidOpenAIProviderHistory();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const historicalProviderName = providerCalls[0]?.name ?? providerResults[0]?.name;
|
|
153
|
+
if (historicalProviderName !== undefined &&
|
|
154
|
+
(!isBoundedOpenAIStreamString(historicalProviderName, MAX_OPENAI_STREAM_TOOL_NAME_BYTES) ||
|
|
155
|
+
providerCalls.some((call) => call.name !== historicalProviderName) ||
|
|
156
|
+
providerResults.some((result) => result.name !== historicalProviderName))) {
|
|
157
|
+
throw invalidOpenAIProviderHistory();
|
|
158
|
+
}
|
|
159
|
+
// Ordinary function calls have an exact provider-native representation.
|
|
160
|
+
// If their canonical projection survived compaction, correlate it in order;
|
|
161
|
+
// otherwise the already-validated raw items remain the legacy source of
|
|
162
|
+
// truth.
|
|
163
|
+
if (clientCalls.length > 0) {
|
|
164
|
+
assertOrderedOpenAIToolCallsEqual(clientCalls, rawClientCalls);
|
|
165
|
+
}
|
|
166
|
+
// providerToolCalls has no position relative to ordinary content calls. When
|
|
167
|
+
// both kinds survive in assistant content, however, their complete
|
|
168
|
+
// interleaving is observable and must match the raw item order. If either
|
|
169
|
+
// content projection was compacted, only its per-kind order can be proven;
|
|
170
|
+
// the exact raw item sequence remains authoritative for transmission.
|
|
171
|
+
if (contentProviderCalls.length > 0 && clientCalls.length > 0) {
|
|
172
|
+
if (contentCallKinds.length !== rawCallKinds.length ||
|
|
173
|
+
contentCallKinds.some((kind, index) => kind !== rawCallKinds[index])) {
|
|
174
|
+
throw invalidOpenAIProviderHistory();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
8
177
|
}
|
|
9
178
|
function toOpenAIResponsesInput(prompt) {
|
|
10
179
|
const instructionsParts = [];
|
|
@@ -23,6 +192,12 @@ function toOpenAIResponsesInput(prompt) {
|
|
|
23
192
|
});
|
|
24
193
|
break;
|
|
25
194
|
case "assistant": {
|
|
195
|
+
const rawOutputItems = readOpenAIRawResponseOutputItems(message.providerMetadata);
|
|
196
|
+
if (rawOutputItems) {
|
|
197
|
+
validateOpenAIProviderReplay(message, rawOutputItems);
|
|
198
|
+
input.push(...rawOutputItems);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
26
201
|
const messageContent = [];
|
|
27
202
|
for (const part of message.content) {
|
|
28
203
|
if (part.type === "text") {
|
|
@@ -45,6 +220,12 @@ function toOpenAIResponsesInput(prompt) {
|
|
|
45
220
|
});
|
|
46
221
|
continue;
|
|
47
222
|
}
|
|
223
|
+
if (part.type === "tool-result") {
|
|
224
|
+
throw new TypeError("OpenAI provider-executed assistant tool results require exact raw replay metadata");
|
|
225
|
+
}
|
|
226
|
+
if (part.providerExecuted === true) {
|
|
227
|
+
throw new TypeError("OpenAI provider-executed assistant tool calls require exact raw replay metadata");
|
|
228
|
+
}
|
|
48
229
|
if (messageContent.length > 0) {
|
|
49
230
|
input.push({ role: "assistant", content: [...messageContent] });
|
|
50
231
|
messageContent.length = 0;
|
|
@@ -53,7 +234,7 @@ function toOpenAIResponsesInput(prompt) {
|
|
|
53
234
|
type: "function_call",
|
|
54
235
|
call_id: part.toolCallId,
|
|
55
236
|
name: part.toolName,
|
|
56
|
-
arguments:
|
|
237
|
+
arguments: stringifyToolArguments(part.input),
|
|
57
238
|
});
|
|
58
239
|
}
|
|
59
240
|
if (messageContent.length > 0) {
|
|
@@ -66,7 +247,7 @@ function toOpenAIResponsesInput(prompt) {
|
|
|
66
247
|
input.push({
|
|
67
248
|
type: "function_call_output",
|
|
68
249
|
call_id: part.toolCallId,
|
|
69
|
-
output:
|
|
250
|
+
output: stringifyToolResultValue(part.output.value),
|
|
70
251
|
});
|
|
71
252
|
}
|
|
72
253
|
break;
|
|
@@ -98,10 +279,11 @@ function toOpenAIResponsesUserContent(parts) {
|
|
|
98
279
|
}
|
|
99
280
|
return content;
|
|
100
281
|
}
|
|
101
|
-
function toOpenAIResponsesTools(tools) {
|
|
282
|
+
function toOpenAIResponsesTools(tools, webSearch) {
|
|
102
283
|
if (!tools)
|
|
103
284
|
return undefined;
|
|
104
285
|
const normalized = [];
|
|
286
|
+
let addedWebSearch = false;
|
|
105
287
|
for (const tool of tools) {
|
|
106
288
|
if (tool.type === "function") {
|
|
107
289
|
normalized.push({
|
|
@@ -119,13 +301,10 @@ function toOpenAIResponsesTools(tools) {
|
|
|
119
301
|
}
|
|
120
302
|
if (!tool.id.startsWith("openai."))
|
|
121
303
|
continue;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
type: providerType,
|
|
127
|
-
...toSnakeCaseRecord(tool.args),
|
|
128
|
-
});
|
|
304
|
+
if (webSearch && !addedWebSearch) {
|
|
305
|
+
normalized.push(webSearch.requestTool);
|
|
306
|
+
addedWebSearch = true;
|
|
307
|
+
}
|
|
129
308
|
}
|
|
130
309
|
return normalized.length > 0 ? normalized : undefined;
|
|
131
310
|
}
|
|
@@ -162,12 +341,13 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
|
|
|
162
341
|
}
|
|
163
342
|
}
|
|
164
343
|
}
|
|
344
|
+
const webSearch = resolveOpenAIWebSearchDescriptor(options.tools);
|
|
165
345
|
const { instructions, input } = toOpenAIResponsesInput(options.prompt);
|
|
166
|
-
const responsesTools = toOpenAIResponsesTools(options.tools);
|
|
346
|
+
const responsesTools = toOpenAIResponsesTools(options.tools, webSearch);
|
|
167
347
|
const body = {
|
|
168
348
|
model: modelId,
|
|
169
349
|
input,
|
|
170
|
-
// Stay stateless
|
|
350
|
+
// Stay stateless and preserve the complete provider history explicitly below.
|
|
171
351
|
store: false,
|
|
172
352
|
...(instructions !== undefined ? { instructions } : {}),
|
|
173
353
|
...(stream ? { stream: true } : {}),
|
|
@@ -217,6 +397,47 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
|
|
|
217
397
|
};
|
|
218
398
|
// Env-BYOK users historically registered options under "openai-compatible";
|
|
219
399
|
// keep merging that bucket at the lowest precedence.
|
|
220
|
-
|
|
400
|
+
defineOpenAIProviderOptions(body, readProviderOptions(options.providerOptions, ...(providerName === "openai" ? ["openai-compatible"] : []), "openai", providerName));
|
|
401
|
+
// Keep provider-native tuning extensible without allowing raw options to
|
|
402
|
+
// replace the runtime-owned transport, prompt, model, or privacy contract.
|
|
403
|
+
body.model = modelId;
|
|
404
|
+
body.input = input;
|
|
405
|
+
body.store = false;
|
|
406
|
+
if (instructions !== undefined) {
|
|
407
|
+
body.instructions = instructions;
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
delete body.instructions;
|
|
411
|
+
}
|
|
412
|
+
if (stream) {
|
|
413
|
+
body.stream = true;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
delete body.stream;
|
|
417
|
+
}
|
|
418
|
+
const requiredIncludes = [
|
|
419
|
+
...(reasoning ? [OPENAI_REASONING_ENCRYPTED_CONTENT_INCLUDE] : []),
|
|
420
|
+
...(webSearch ? [OPENAI_WEB_SEARCH_SOURCES_INCLUDE] : []),
|
|
421
|
+
];
|
|
422
|
+
if (requiredIncludes.length > 0) {
|
|
423
|
+
const providerIncludes = Array.isArray(body.include)
|
|
424
|
+
? body.include.filter((value) => typeof value === "string")
|
|
425
|
+
: [];
|
|
426
|
+
body.include = [
|
|
427
|
+
...new Set([
|
|
428
|
+
...providerIncludes,
|
|
429
|
+
...requiredIncludes,
|
|
430
|
+
]),
|
|
431
|
+
];
|
|
432
|
+
}
|
|
433
|
+
if (Object.hasOwn(body, "background")) {
|
|
434
|
+
delete body.background;
|
|
435
|
+
warnings.push({
|
|
436
|
+
type: "unsupported-setting",
|
|
437
|
+
provider: "openai",
|
|
438
|
+
setting: "background",
|
|
439
|
+
details: "Background Responses are asynchronous and cannot satisfy the runtime's immediate result contract; the value was dropped.",
|
|
440
|
+
});
|
|
441
|
+
}
|
|
221
442
|
return body;
|
|
222
443
|
}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { RuntimeUsage } from "veryfront/provider/shared";
|
|
2
|
+
type OpenAIResponsesStreamContext = {
|
|
3
|
+
providerKind?: "openai" | "mistral" | "moonshotai";
|
|
4
|
+
providerLabel?: string;
|
|
5
|
+
webSearchToolName?: string;
|
|
6
|
+
preserveRawOutputItems?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const MAX_OPENAI_STREAM_MESSAGE_SNAPSHOT_BYTES: number;
|
|
9
|
+
export declare const MAX_OPENAI_RESPONSES_RAW_METADATA_BYTES: number;
|
|
10
|
+
export declare const MAX_OPENAI_RESPONSES_STREAM_OUTPUT_ITEMS = 4096;
|
|
11
|
+
export declare const MAX_OPENAI_RESPONSES_STREAM_CONTENT_PARTS = 4096;
|
|
2
12
|
/**
|
|
3
13
|
* The Responses API uses `input_tokens` / `output_tokens` field names
|
|
4
14
|
* instead of Chat Completions' `prompt_tokens` / `completion_tokens`.
|
|
@@ -12,5 +22,6 @@ export declare function normalizeOpenAIResponsesFinishReason(raw: unknown): stri
|
|
|
12
22
|
* Parse the Responses API streaming event grammar into the same UI part
|
|
13
23
|
* shapes the existing OpenAI / Anthropic / Google streams emit.
|
|
14
24
|
*/
|
|
15
|
-
export declare function streamOpenAIResponsesParts(stream: ReadableStream<Uint8Array
|
|
25
|
+
export declare function streamOpenAIResponsesParts(stream: ReadableStream<Uint8Array>, context?: OpenAIResponsesStreamContext): AsyncIterable<unknown>;
|
|
26
|
+
export {};
|
|
16
27
|
//# sourceMappingURL=openai-responses-stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-responses-stream.d.ts","sourceRoot":"","sources":["../src/openai-responses-stream.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-responses-stream.d.ts","sourceRoot":"","sources":["../src/openai-responses-stream.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AA8E9D,KAAK,4BAA4B,GAAG;IAClC,YAAY,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,wCAAwC,QAAkB,CAAC;AACxE,eAAO,MAAM,uCAAuC,QAAyC,CAAC;AAC9F,eAAO,MAAM,wCAAwC,OAAQ,CAAC;AAC9D,eAAO,MAAM,yCAAyC,OAAQ,CAAC;AA4C/D;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAqEtF;AAED,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,OAAO,GACX,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBlD;AAED;;;GAGG;AACH,wBAAuB,0BAA0B,CAC/C,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,OAAO,GAAE,4BAAiC,GACzC,aAAa,CAAC,OAAO,CAAC,CAugDxB"}
|