@veryfront/ext-llm-openai 0.1.985
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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +129 -0
- package/esm/index.d.ts +12 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +32 -0
- package/esm/openai-chat-request-builder.d.ts +67 -0
- package/esm/openai-chat-request-builder.d.ts.map +1 -0
- package/esm/openai-chat-request-builder.js +126 -0
- package/esm/openai-chat-stream.d.ts +2 -0
- package/esm/openai-chat-stream.d.ts.map +1 -0
- package/esm/openai-chat-stream.js +235 -0
- package/esm/openai-provider.d.ts +29 -0
- package/esm/openai-provider.d.ts.map +1 -0
- package/esm/openai-provider.js +436 -0
- package/esm/openai-responses-request-builder.d.ts +42 -0
- package/esm/openai-responses-request-builder.d.ts.map +1 -0
- package/esm/openai-responses-request-builder.js +220 -0
- package/esm/openai-responses-stream.d.ts +16 -0
- package/esm/openai-responses-stream.d.ts.map +1 -0
- package/esm/openai-responses-stream.js +235 -0
- package/esm/package.json +3 -0
- package/package.json +58 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI provider, implements the {@link LLMProvider} contract for OpenAI,
|
|
3
|
+
* OpenAI-compatible endpoints (Azure OpenAI, Moonshot AI), and OpenAI's
|
|
4
|
+
* Responses API.
|
|
5
|
+
*
|
|
6
|
+
* Ported from `src/provider/runtime-loader.ts` as part of PR 11.
|
|
7
|
+
*
|
|
8
|
+
* @module extensions/ext-llm-openai/openai-provider
|
|
9
|
+
*/
|
|
10
|
+
import { buildProviderError, createOpenAIRequestInit, createWarningCollector, getOpenAIChatCompletionsUrl, getOpenAIEmbeddingUrl, getOpenAIResponsesUrl, isNumberArray, mergeUsage, parseRetryAfterMs, ProviderError, ProviderOverloadedError, ProviderQuotaError, ProviderRateLimitError, ProviderRequestError, readGatewayBillingMode, readRecord, requestJson, requestStream, stringifyJsonValue, TOOL_INPUT_PENDING_THRESHOLD_MS, withToolInputStatusTransitions, } from "veryfront/provider/shared";
|
|
11
|
+
import { buildOpenAIChatRequest, } from "./openai-chat-request-builder.js";
|
|
12
|
+
import { streamOpenAICompatibleParts } from "./openai-chat-stream.js";
|
|
13
|
+
import { buildOpenAIResponsesRequest } from "./openai-responses-request-builder.js";
|
|
14
|
+
import { extractOpenAIResponsesUsage, normalizeOpenAIResponsesFinishReason, streamOpenAIResponsesParts, } from "./openai-responses-stream.js";
|
|
15
|
+
// Re-export error classes so extension tests can import from this module.
|
|
16
|
+
export { buildProviderError, isNumberArray, mergeUsage, parseRetryAfterMs, ProviderError, ProviderOverloadedError, ProviderQuotaError, ProviderRateLimitError, ProviderRequestError, TOOL_INPUT_PENDING_THRESHOLD_MS, withToolInputStatusTransitions, };
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Embedding helpers
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function extractOpenAIEmbeddings(payload) {
|
|
21
|
+
const record = readRecord(payload);
|
|
22
|
+
const data = record?.data;
|
|
23
|
+
if (!Array.isArray(data)) {
|
|
24
|
+
throw new Error("Invalid OpenAI embedding response: data array missing");
|
|
25
|
+
}
|
|
26
|
+
const embeddings = [];
|
|
27
|
+
for (const item of data) {
|
|
28
|
+
const itemRecord = readRecord(item);
|
|
29
|
+
const embedding = itemRecord?.embedding;
|
|
30
|
+
if (!isNumberArray(embedding)) {
|
|
31
|
+
throw new Error("Invalid OpenAI embedding response: embedding vector missing");
|
|
32
|
+
}
|
|
33
|
+
embeddings.push(embedding);
|
|
34
|
+
}
|
|
35
|
+
return embeddings;
|
|
36
|
+
}
|
|
37
|
+
function extractOpenAIUsageTokens(payload) {
|
|
38
|
+
const record = readRecord(payload);
|
|
39
|
+
const usage = readRecord(record?.usage);
|
|
40
|
+
const totalTokens = usage?.total_tokens;
|
|
41
|
+
return typeof totalTokens === "number" ? totalTokens : undefined;
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Chat helpers
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
function normalizeOpenAIFinishReason(raw) {
|
|
47
|
+
if (typeof raw !== "string") {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (raw === "tool_calls") {
|
|
51
|
+
return { unified: "tool-calls", raw };
|
|
52
|
+
}
|
|
53
|
+
if (raw === "content_filter") {
|
|
54
|
+
return { unified: "content-filter", raw };
|
|
55
|
+
}
|
|
56
|
+
return raw;
|
|
57
|
+
}
|
|
58
|
+
function extractOpenAIUsage(payload) {
|
|
59
|
+
const record = readRecord(payload);
|
|
60
|
+
const usage = readRecord(record?.usage);
|
|
61
|
+
if (!usage) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const inputTokens = usage.prompt_tokens;
|
|
65
|
+
const outputTokens = usage.completion_tokens;
|
|
66
|
+
const totalTokens = usage.total_tokens;
|
|
67
|
+
const promptTokensDetails = readRecord(usage.prompt_tokens_details);
|
|
68
|
+
const cachedTokens = promptTokensDetails?.cached_tokens;
|
|
69
|
+
const completionTokensDetails = readRecord(usage.completion_tokens_details);
|
|
70
|
+
const reasoningTokens = completionTokensDetails?.reasoning_tokens;
|
|
71
|
+
const veryfront = readRecord(usage.veryfront);
|
|
72
|
+
const costSource = veryfront?.cost_source;
|
|
73
|
+
const billingMode = readGatewayBillingMode(veryfront?.billing_mode);
|
|
74
|
+
const usageCaptureStatus = veryfront?.usage_capture_status;
|
|
75
|
+
return {
|
|
76
|
+
inputTokens: typeof inputTokens === "number" ? inputTokens : undefined,
|
|
77
|
+
outputTokens: typeof outputTokens === "number" ? outputTokens : undefined,
|
|
78
|
+
totalTokens: typeof totalTokens === "number" ? totalTokens : undefined,
|
|
79
|
+
...(typeof cachedTokens === "number" ? { cacheReadInputTokens: cachedTokens } : {}),
|
|
80
|
+
...(typeof reasoningTokens === "number" ? { reasoningTokens } : {}),
|
|
81
|
+
...(typeof veryfront?.billable_input_tokens === "number"
|
|
82
|
+
? { billableInputTokens: veryfront.billable_input_tokens }
|
|
83
|
+
: {}),
|
|
84
|
+
...(typeof veryfront?.billable_output_tokens === "number"
|
|
85
|
+
? { billableOutputTokens: veryfront.billable_output_tokens }
|
|
86
|
+
: {}),
|
|
87
|
+
...(typeof veryfront?.cost_usd === "number" ? { costUsd: veryfront.cost_usd } : {}),
|
|
88
|
+
...(typeof veryfront?.provider_input_cost_usd === "number"
|
|
89
|
+
? { providerInputCostUsd: veryfront.provider_input_cost_usd }
|
|
90
|
+
: {}),
|
|
91
|
+
...(typeof veryfront?.provider_output_cost_usd === "number"
|
|
92
|
+
? { providerOutputCostUsd: veryfront.provider_output_cost_usd }
|
|
93
|
+
: {}),
|
|
94
|
+
...(typeof veryfront?.provider_cost_usd === "number"
|
|
95
|
+
? { providerCostUsd: veryfront.provider_cost_usd }
|
|
96
|
+
: {}),
|
|
97
|
+
...(typeof veryfront?.veryfront_input_charge_usd === "number"
|
|
98
|
+
? { veryfrontInputChargeUsd: veryfront.veryfront_input_charge_usd }
|
|
99
|
+
: {}),
|
|
100
|
+
...(typeof veryfront?.veryfront_output_charge_usd === "number"
|
|
101
|
+
? { veryfrontOutputChargeUsd: veryfront.veryfront_output_charge_usd }
|
|
102
|
+
: {}),
|
|
103
|
+
...(typeof veryfront?.veryfront_charge_usd === "number"
|
|
104
|
+
? { veryfrontChargeUsd: veryfront.veryfront_charge_usd }
|
|
105
|
+
: {}),
|
|
106
|
+
...(typeof veryfront?.veryfront_billed_usd === "number"
|
|
107
|
+
? { veryfrontBilledUsd: veryfront.veryfront_billed_usd }
|
|
108
|
+
: {}),
|
|
109
|
+
...(typeof veryfront?.cost_credits === "number" ? { costCredits: veryfront.cost_credits } : {}),
|
|
110
|
+
...(costSource === "gateway" || costSource === "missing" || costSource === "partial"
|
|
111
|
+
? { costSource }
|
|
112
|
+
: {}),
|
|
113
|
+
...(billingMode !== undefined ? { billingMode } : {}),
|
|
114
|
+
...(usageCaptureStatus === "complete" ||
|
|
115
|
+
usageCaptureStatus === "missing" ||
|
|
116
|
+
usageCaptureStatus === "partial"
|
|
117
|
+
? { usageCaptureStatus }
|
|
118
|
+
: {}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function extractOpenAIContentText(content) {
|
|
122
|
+
if (typeof content === "string") {
|
|
123
|
+
return content;
|
|
124
|
+
}
|
|
125
|
+
if (!Array.isArray(content)) {
|
|
126
|
+
return "";
|
|
127
|
+
}
|
|
128
|
+
let text = "";
|
|
129
|
+
for (const part of content) {
|
|
130
|
+
const record = readRecord(part);
|
|
131
|
+
const type = record?.type;
|
|
132
|
+
if (type === "text" && typeof record?.text === "string") {
|
|
133
|
+
text += record.text;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return text;
|
|
137
|
+
}
|
|
138
|
+
function extractOpenAIToolCalls(message) {
|
|
139
|
+
const toolCalls = message.tool_calls;
|
|
140
|
+
if (!Array.isArray(toolCalls)) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
const normalized = [];
|
|
144
|
+
for (const entry of toolCalls) {
|
|
145
|
+
const record = readRecord(entry);
|
|
146
|
+
const id = typeof record?.id === "string" ? record.id : undefined;
|
|
147
|
+
const fn = readRecord(record?.function);
|
|
148
|
+
const name = typeof fn?.name === "string" ? fn.name : undefined;
|
|
149
|
+
const argumentsText = typeof fn?.arguments === "string" ? fn.arguments : undefined;
|
|
150
|
+
if (!id || !name || argumentsText === undefined) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
normalized.push({
|
|
154
|
+
toolCallId: id,
|
|
155
|
+
toolName: name,
|
|
156
|
+
input: argumentsText,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return normalized;
|
|
160
|
+
}
|
|
161
|
+
function extractFirstChoice(payload) {
|
|
162
|
+
const record = readRecord(payload);
|
|
163
|
+
const choices = record?.choices;
|
|
164
|
+
if (!Array.isArray(choices) || choices.length === 0) {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
const first = readRecord(choices[0]);
|
|
168
|
+
if (!first) {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
return first;
|
|
172
|
+
}
|
|
173
|
+
function buildOpenAIGenerateResult(payload) {
|
|
174
|
+
const choice = extractFirstChoice(payload);
|
|
175
|
+
const message = readRecord(choice?.message);
|
|
176
|
+
const text = extractOpenAIContentText(message?.content);
|
|
177
|
+
const toolCalls = message ? extractOpenAIToolCalls(message) : [];
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
...(text.length > 0 ? [{ type: "text", text }] : []),
|
|
181
|
+
...toolCalls.map((toolCall) => ({
|
|
182
|
+
type: "tool-call",
|
|
183
|
+
toolCallId: toolCall.toolCallId,
|
|
184
|
+
toolName: toolCall.toolName,
|
|
185
|
+
input: toolCall.input,
|
|
186
|
+
})),
|
|
187
|
+
],
|
|
188
|
+
finishReason: normalizeOpenAIFinishReason(choice?.finish_reason),
|
|
189
|
+
usage: extractOpenAIUsage(payload),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function buildOpenAIResponsesGenerateResult(payload) {
|
|
193
|
+
const record = readRecord(payload);
|
|
194
|
+
const output = Array.isArray(record?.output) ? record.output : [];
|
|
195
|
+
const content = [];
|
|
196
|
+
for (const item of output) {
|
|
197
|
+
const itemRecord = readRecord(item);
|
|
198
|
+
const itemType = typeof itemRecord?.type === "string" ? itemRecord.type : undefined;
|
|
199
|
+
if (itemType === "message" && Array.isArray(itemRecord?.content)) {
|
|
200
|
+
// A message item bundles one or more output_text parts.
|
|
201
|
+
let text = "";
|
|
202
|
+
for (const part of itemRecord.content) {
|
|
203
|
+
const p = readRecord(part);
|
|
204
|
+
if (typeof p?.type === "string" && p.type === "output_text" && typeof p.text === "string") {
|
|
205
|
+
text += p.text;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (text.length > 0) {
|
|
209
|
+
content.push({ type: "text", text });
|
|
210
|
+
}
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (itemType === "function_call") {
|
|
214
|
+
content.push({
|
|
215
|
+
type: "tool-call",
|
|
216
|
+
toolCallId: typeof itemRecord?.call_id === "string"
|
|
217
|
+
? itemRecord.call_id
|
|
218
|
+
: (typeof itemRecord?.id === "string" ? itemRecord.id : ""),
|
|
219
|
+
toolName: typeof itemRecord?.name === "string" ? itemRecord.name : "",
|
|
220
|
+
input: typeof itemRecord?.arguments === "string"
|
|
221
|
+
? itemRecord.arguments
|
|
222
|
+
: stringifyJsonValue(itemRecord?.arguments ?? {}),
|
|
223
|
+
});
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (itemType === "reasoning") {
|
|
227
|
+
const summary = Array.isArray(itemRecord?.summary) ? itemRecord.summary : [];
|
|
228
|
+
const summaries = [];
|
|
229
|
+
for (const s of summary) {
|
|
230
|
+
const sr = readRecord(s);
|
|
231
|
+
if (typeof sr?.text === "string" && sr.text.length > 0) {
|
|
232
|
+
summaries.push({
|
|
233
|
+
...(typeof sr?.id === "string" ? { id: sr.id } : {}),
|
|
234
|
+
text: sr.text,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
content.push({
|
|
239
|
+
type: "reasoning",
|
|
240
|
+
...(summaries.length > 0 ? { summaries } : {}),
|
|
241
|
+
...(typeof itemRecord?.encrypted_content === "string"
|
|
242
|
+
? { signature: itemRecord.encrypted_content }
|
|
243
|
+
: {}),
|
|
244
|
+
});
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
content,
|
|
250
|
+
finishReason: normalizeOpenAIResponsesFinishReason(record?.status),
|
|
251
|
+
usage: extractOpenAIResponsesUsage(payload),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Public factory functions
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
export function createOpenAIModelRuntime(config, modelId) {
|
|
258
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
259
|
+
return {
|
|
260
|
+
provider: config.name ?? "openai",
|
|
261
|
+
modelId,
|
|
262
|
+
specificationVersion: "v3",
|
|
263
|
+
supportedUrls: {},
|
|
264
|
+
doGenerate(optionsForRuntime) {
|
|
265
|
+
const options = optionsForRuntime;
|
|
266
|
+
const url = getOpenAIChatCompletionsUrl(config.baseURL);
|
|
267
|
+
const warnings = createWarningCollector();
|
|
268
|
+
const body = buildOpenAIChatRequest(modelId, config.name ?? "openai", options, false, warnings);
|
|
269
|
+
return requestJson({
|
|
270
|
+
url,
|
|
271
|
+
fetchImpl,
|
|
272
|
+
providerLabel: config.name ?? "openai",
|
|
273
|
+
providerKind: "openai",
|
|
274
|
+
init: createOpenAIRequestInit({
|
|
275
|
+
apiKey: config.apiKey,
|
|
276
|
+
extraHeaders: options.headers,
|
|
277
|
+
body: JSON.stringify(body),
|
|
278
|
+
signal: options.abortSignal,
|
|
279
|
+
}),
|
|
280
|
+
}).then((payload) => {
|
|
281
|
+
const drained = warnings.drain();
|
|
282
|
+
return {
|
|
283
|
+
...buildOpenAIGenerateResult(payload),
|
|
284
|
+
...(drained.length > 0 ? { warnings: drained } : {}),
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
doStream(optionsForRuntime) {
|
|
289
|
+
const options = optionsForRuntime;
|
|
290
|
+
const url = getOpenAIChatCompletionsUrl(config.baseURL);
|
|
291
|
+
const warnings = createWarningCollector();
|
|
292
|
+
const body = buildOpenAIChatRequest(modelId, config.name ?? "openai", options, true, warnings);
|
|
293
|
+
return requestStream({
|
|
294
|
+
url,
|
|
295
|
+
fetchImpl,
|
|
296
|
+
providerLabel: config.name ?? "openai",
|
|
297
|
+
providerKind: "openai",
|
|
298
|
+
init: createOpenAIRequestInit({
|
|
299
|
+
apiKey: config.apiKey,
|
|
300
|
+
extraHeaders: options.headers,
|
|
301
|
+
body: JSON.stringify(body),
|
|
302
|
+
signal: options.abortSignal,
|
|
303
|
+
}),
|
|
304
|
+
}).then((responseStream) => {
|
|
305
|
+
const drained = warnings.drain();
|
|
306
|
+
return {
|
|
307
|
+
stream: ReadableStream.from(withToolInputStatusTransitions(streamOpenAICompatibleParts(responseStream))),
|
|
308
|
+
...(drained.length > 0 ? { warnings: drained } : {}),
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
export function createOpenAIResponsesRuntime(config, modelId) {
|
|
315
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
316
|
+
return {
|
|
317
|
+
provider: config.name ?? "openai",
|
|
318
|
+
modelId,
|
|
319
|
+
specificationVersion: "v3",
|
|
320
|
+
supportedUrls: {},
|
|
321
|
+
doGenerate(optionsForRuntime) {
|
|
322
|
+
const options = optionsForRuntime;
|
|
323
|
+
const url = getOpenAIResponsesUrl(config.baseURL);
|
|
324
|
+
const warnings = createWarningCollector();
|
|
325
|
+
const body = buildOpenAIResponsesRequest(modelId, config.name ?? "openai", options, false, warnings);
|
|
326
|
+
return requestJson({
|
|
327
|
+
url,
|
|
328
|
+
fetchImpl,
|
|
329
|
+
providerLabel: config.name ?? "openai",
|
|
330
|
+
providerKind: "openai",
|
|
331
|
+
init: createOpenAIRequestInit({
|
|
332
|
+
apiKey: config.apiKey,
|
|
333
|
+
extraHeaders: options.headers,
|
|
334
|
+
body: JSON.stringify(body),
|
|
335
|
+
signal: options.abortSignal,
|
|
336
|
+
}),
|
|
337
|
+
}).then((payload) => {
|
|
338
|
+
const drained = warnings.drain();
|
|
339
|
+
return {
|
|
340
|
+
...buildOpenAIResponsesGenerateResult(payload),
|
|
341
|
+
...(drained.length > 0 ? { warnings: drained } : {}),
|
|
342
|
+
};
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
doStream(optionsForRuntime) {
|
|
346
|
+
const options = optionsForRuntime;
|
|
347
|
+
const url = getOpenAIResponsesUrl(config.baseURL);
|
|
348
|
+
const warnings = createWarningCollector();
|
|
349
|
+
const body = buildOpenAIResponsesRequest(modelId, config.name ?? "openai", options, true, warnings);
|
|
350
|
+
return requestStream({
|
|
351
|
+
url,
|
|
352
|
+
fetchImpl,
|
|
353
|
+
providerLabel: config.name ?? "openai",
|
|
354
|
+
providerKind: "openai",
|
|
355
|
+
init: createOpenAIRequestInit({
|
|
356
|
+
apiKey: config.apiKey,
|
|
357
|
+
extraHeaders: options.headers,
|
|
358
|
+
body: JSON.stringify(body),
|
|
359
|
+
signal: options.abortSignal,
|
|
360
|
+
}),
|
|
361
|
+
}).then((responseStream) => {
|
|
362
|
+
const drained = warnings.drain();
|
|
363
|
+
return {
|
|
364
|
+
stream: ReadableStream.from(withToolInputStatusTransitions(streamOpenAIResponsesParts(responseStream))),
|
|
365
|
+
...(drained.length > 0 ? { warnings: drained } : {}),
|
|
366
|
+
};
|
|
367
|
+
});
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
export function createOpenAIEmbeddingRuntime(config, modelId) {
|
|
372
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
373
|
+
return {
|
|
374
|
+
provider: config.name ?? "openai",
|
|
375
|
+
modelId,
|
|
376
|
+
supportsParallelCalls: true,
|
|
377
|
+
doEmbed({ values, abortSignal }) {
|
|
378
|
+
if (values.length === 0) {
|
|
379
|
+
return Promise.resolve({
|
|
380
|
+
embeddings: [],
|
|
381
|
+
warnings: [],
|
|
382
|
+
rawResponse: { data: [] },
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
const url = getOpenAIEmbeddingUrl(config.baseURL);
|
|
386
|
+
return requestJson({
|
|
387
|
+
url,
|
|
388
|
+
fetchImpl,
|
|
389
|
+
providerLabel: config.name ?? "openai",
|
|
390
|
+
providerKind: "openai",
|
|
391
|
+
init: createOpenAIRequestInit({
|
|
392
|
+
apiKey: config.apiKey,
|
|
393
|
+
body: JSON.stringify({
|
|
394
|
+
model: modelId,
|
|
395
|
+
input: values,
|
|
396
|
+
}),
|
|
397
|
+
signal: abortSignal,
|
|
398
|
+
}),
|
|
399
|
+
}).then((payload) => ({
|
|
400
|
+
embeddings: extractOpenAIEmbeddings(payload),
|
|
401
|
+
usage: {
|
|
402
|
+
tokens: extractOpenAIUsageTokens(payload),
|
|
403
|
+
},
|
|
404
|
+
rawResponse: payload,
|
|
405
|
+
warnings: [],
|
|
406
|
+
}));
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
export class OpenAIProvider {
|
|
411
|
+
id = "openai";
|
|
412
|
+
createModel(modelId, config) {
|
|
413
|
+
return createOpenAIModelRuntime({
|
|
414
|
+
apiKey: config.credential,
|
|
415
|
+
baseURL: config.baseURL,
|
|
416
|
+
name: config.name ?? "openai",
|
|
417
|
+
fetch: config.fetch,
|
|
418
|
+
}, modelId);
|
|
419
|
+
}
|
|
420
|
+
createEmbedding(modelId, config) {
|
|
421
|
+
return createOpenAIEmbeddingRuntime({
|
|
422
|
+
apiKey: config.credential,
|
|
423
|
+
baseURL: config.baseURL,
|
|
424
|
+
name: config.name ?? "openai",
|
|
425
|
+
fetch: config.fetch,
|
|
426
|
+
}, modelId);
|
|
427
|
+
}
|
|
428
|
+
createResponses(modelId, config) {
|
|
429
|
+
return createOpenAIResponsesRuntime({
|
|
430
|
+
apiKey: config.credential,
|
|
431
|
+
baseURL: config.baseURL,
|
|
432
|
+
name: config.name ?? "openai",
|
|
433
|
+
fetch: config.fetch,
|
|
434
|
+
}, modelId);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OpenAICompatibleLanguageOptions } from "./openai-chat-request-builder.js";
|
|
2
|
+
export type OpenAIResponsesInputItem = Record<string, unknown>;
|
|
3
|
+
export type OpenAIResponsesRequest = {
|
|
4
|
+
model: string;
|
|
5
|
+
input: OpenAIResponsesInputItem[];
|
|
6
|
+
instructions?: string;
|
|
7
|
+
stream?: boolean;
|
|
8
|
+
max_output_tokens?: number;
|
|
9
|
+
temperature?: number;
|
|
10
|
+
top_p?: number;
|
|
11
|
+
tools?: Array<Record<string, unknown>>;
|
|
12
|
+
tool_choice?: unknown;
|
|
13
|
+
reasoning?: {
|
|
14
|
+
effort?: string;
|
|
15
|
+
summary?: string;
|
|
16
|
+
};
|
|
17
|
+
metadata?: Record<string, string>;
|
|
18
|
+
user?: string;
|
|
19
|
+
service_tier?: string;
|
|
20
|
+
parallel_tool_calls?: boolean;
|
|
21
|
+
text?: {
|
|
22
|
+
format: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
};
|
|
26
|
+
type WarningCollector = {
|
|
27
|
+
push(warning: {
|
|
28
|
+
type: "unsupported-setting" | "other";
|
|
29
|
+
setting?: string;
|
|
30
|
+
details?: string;
|
|
31
|
+
provider: string;
|
|
32
|
+
}): void;
|
|
33
|
+
drain(): Array<{
|
|
34
|
+
type: "unsupported-setting" | "other";
|
|
35
|
+
setting?: string;
|
|
36
|
+
details?: string;
|
|
37
|
+
provider: string;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
export declare function buildOpenAIResponsesRequest(modelId: string, providerName: string, options: OpenAICompatibleLanguageOptions, stream: boolean, warnings: WarningCollector): OpenAIResponsesRequest;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=openai-responses-request-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,+BAA+B,EAEhC,MAAM,kCAAkC,CAAC;AAI1C,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,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;AAmKF,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,CAiFxB"}
|