@yourgpt/llm-sdk 2.1.10-alpha.0 → 2.5.1-beta.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/dist/adapters/index.d.mts +4 -38
- package/dist/adapters/index.d.ts +4 -38
- package/dist/adapters/index.js +158 -325
- package/dist/adapters/index.mjs +158 -325
- package/dist/base-C58Dsr9p.d.ts +259 -0
- package/dist/base-tNgbBaSo.d.mts +259 -0
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/index.d.mts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +35 -43
- package/dist/index.mjs +35 -43
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +271 -212
- package/dist/providers/anthropic/index.mjs +271 -212
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/azure/index.js +49 -1
- package/dist/providers/azure/index.mjs +49 -1
- package/dist/providers/fireworks/index.d.mts +1 -1
- package/dist/providers/fireworks/index.d.ts +1 -1
- package/dist/providers/fireworks/index.js +56 -0
- package/dist/providers/fireworks/index.mjs +56 -0
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +254 -510
- package/dist/providers/google/index.mjs +254 -510
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/ollama/index.js +10 -2
- package/dist/providers/ollama/index.mjs +10 -2
- package/dist/providers/openai/index.d.mts +3 -3
- package/dist/providers/openai/index.d.ts +3 -3
- package/dist/providers/openai/index.js +269 -529
- package/dist/providers/openai/index.mjs +269 -529
- package/dist/providers/openrouter/index.d.mts +3 -7
- package/dist/providers/openrouter/index.d.ts +3 -7
- package/dist/providers/openrouter/index.js +365 -902
- package/dist/providers/openrouter/index.mjs +365 -902
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +259 -509
- package/dist/providers/togetherai/index.mjs +259 -509
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +258 -513
- package/dist/providers/xai/index.mjs +258 -513
- package/dist/{types-BNCmlJMs.d.mts → types-B6dhnguR.d.mts} +1 -1
- package/dist/{types-DhktekQ3.d.ts → types-BQ31QIsA.d.ts} +2 -1
- package/dist/{types-CMMQ8s2O.d.mts → types-BSSiJW2o.d.mts} +2 -1
- package/dist/{base-DN1EfKnE.d.mts → types-BkQCSiIt.d.mts} +388 -214
- package/dist/{base-DuUNxtVg.d.ts → types-BkQCSiIt.d.ts} +388 -214
- package/dist/{types-Pj-vpmoT.d.ts → types-CCxPmkmK.d.ts} +1 -1
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/types-CMvvDo-E.d.mts +0 -428
- package/dist/types-CMvvDo-E.d.ts +0 -428
|
@@ -1,5 +1,234 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/adapters/base.ts
|
|
4
|
+
function stringifyForDebug(value) {
|
|
5
|
+
return JSON.stringify(
|
|
6
|
+
value,
|
|
7
|
+
(_key, currentValue) => {
|
|
8
|
+
if (typeof currentValue === "bigint") {
|
|
9
|
+
return currentValue.toString();
|
|
10
|
+
}
|
|
11
|
+
if (currentValue instanceof Error) {
|
|
12
|
+
return {
|
|
13
|
+
name: currentValue.name,
|
|
14
|
+
message: currentValue.message,
|
|
15
|
+
stack: currentValue.stack
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return currentValue;
|
|
19
|
+
},
|
|
20
|
+
2
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
function logProviderPayload(provider, label, payload, enabled) {
|
|
24
|
+
if (!enabled) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (label.toLowerCase().includes("stream ")) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
console.log(
|
|
32
|
+
`[llm-sdk:${provider}] ${label}
|
|
33
|
+
${stringifyForDebug(payload)}`
|
|
34
|
+
);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.log(
|
|
37
|
+
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
38
|
+
error
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function parameterToJsonSchema(param) {
|
|
43
|
+
const schema = {
|
|
44
|
+
type: param.type
|
|
45
|
+
};
|
|
46
|
+
if (param.description) {
|
|
47
|
+
schema.description = param.description;
|
|
48
|
+
}
|
|
49
|
+
if (param.enum) {
|
|
50
|
+
schema.enum = param.enum;
|
|
51
|
+
}
|
|
52
|
+
if (param.type === "array" && param.items) {
|
|
53
|
+
schema.items = parameterToJsonSchema(
|
|
54
|
+
param.items
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (param.type === "object" && param.properties) {
|
|
58
|
+
schema.properties = Object.fromEntries(
|
|
59
|
+
Object.entries(param.properties).map(([key, prop]) => [
|
|
60
|
+
key,
|
|
61
|
+
parameterToJsonSchema(
|
|
62
|
+
prop
|
|
63
|
+
)
|
|
64
|
+
])
|
|
65
|
+
);
|
|
66
|
+
schema.additionalProperties = false;
|
|
67
|
+
}
|
|
68
|
+
return schema;
|
|
69
|
+
}
|
|
70
|
+
function normalizeObjectJsonSchema(schema) {
|
|
71
|
+
if (!schema || typeof schema !== "object") {
|
|
72
|
+
return {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {},
|
|
75
|
+
required: [],
|
|
76
|
+
additionalProperties: false
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const normalized = { ...schema };
|
|
80
|
+
const type = normalized.type;
|
|
81
|
+
if (type === "object") {
|
|
82
|
+
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
83
|
+
normalized.properties = Object.fromEntries(
|
|
84
|
+
Object.entries(properties).map(([key, value]) => [
|
|
85
|
+
key,
|
|
86
|
+
normalizeObjectJsonSchema(value)
|
|
87
|
+
])
|
|
88
|
+
);
|
|
89
|
+
const propertyKeys = Object.keys(properties);
|
|
90
|
+
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
91
|
+
(value) => typeof value === "string"
|
|
92
|
+
) : [];
|
|
93
|
+
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
94
|
+
if (normalized.additionalProperties === void 0) {
|
|
95
|
+
normalized.additionalProperties = false;
|
|
96
|
+
}
|
|
97
|
+
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
98
|
+
normalized.items = normalizeObjectJsonSchema(
|
|
99
|
+
normalized.items
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return normalized;
|
|
103
|
+
}
|
|
104
|
+
function isOpenAIReasoningModel(modelId) {
|
|
105
|
+
if (!modelId) return false;
|
|
106
|
+
return /^(o1|o3|o4|gpt-5)/i.test(modelId);
|
|
107
|
+
}
|
|
108
|
+
function buildOpenAITokenParams(modelId, maxTokens, temperature) {
|
|
109
|
+
if (isOpenAIReasoningModel(modelId)) {
|
|
110
|
+
return { max_completion_tokens: maxTokens };
|
|
111
|
+
}
|
|
112
|
+
return { max_tokens: maxTokens, temperature };
|
|
113
|
+
}
|
|
114
|
+
function toOpenAIResponseFormat(rf) {
|
|
115
|
+
if (!rf) return void 0;
|
|
116
|
+
if (rf.type === "json_object") return { type: "json_object" };
|
|
117
|
+
return {
|
|
118
|
+
type: "json_schema",
|
|
119
|
+
json_schema: {
|
|
120
|
+
name: rf.json_schema.name,
|
|
121
|
+
schema: normalizeObjectJsonSchema(rf.json_schema.schema),
|
|
122
|
+
strict: rf.json_schema.strict ?? true
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function toOpenAIResponsesTextFormat(rf) {
|
|
127
|
+
if (!rf || rf.type !== "json_schema") return void 0;
|
|
128
|
+
return {
|
|
129
|
+
type: "json_schema",
|
|
130
|
+
name: rf.json_schema.name,
|
|
131
|
+
schema: normalizeObjectJsonSchema(rf.json_schema.schema),
|
|
132
|
+
strict: rf.json_schema.strict ?? true
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function formatTools(actions) {
|
|
136
|
+
return actions.map((action) => ({
|
|
137
|
+
type: "function",
|
|
138
|
+
function: {
|
|
139
|
+
name: action.name,
|
|
140
|
+
description: action.description,
|
|
141
|
+
parameters: {
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: action.parameters ? Object.fromEntries(
|
|
144
|
+
Object.entries(action.parameters).map(([key, param]) => [
|
|
145
|
+
key,
|
|
146
|
+
parameterToJsonSchema(param)
|
|
147
|
+
])
|
|
148
|
+
) : {},
|
|
149
|
+
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
150
|
+
additionalProperties: false
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
function hasImageAttachments(message) {
|
|
156
|
+
const attachments = message.metadata?.attachments;
|
|
157
|
+
return attachments?.some((a) => a.type === "image") ?? false;
|
|
158
|
+
}
|
|
159
|
+
function attachmentToOpenAIImage(attachment) {
|
|
160
|
+
if (attachment.type !== "image") return null;
|
|
161
|
+
let imageUrl;
|
|
162
|
+
if (attachment.url) {
|
|
163
|
+
imageUrl = attachment.url;
|
|
164
|
+
} else if (attachment.data) {
|
|
165
|
+
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
166
|
+
} else {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
type: "image_url",
|
|
171
|
+
image_url: {
|
|
172
|
+
url: imageUrl,
|
|
173
|
+
detail: "auto"
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function messageToOpenAIContent(message) {
|
|
178
|
+
const attachments = message.metadata?.attachments;
|
|
179
|
+
const content = message.content ?? "";
|
|
180
|
+
if (!hasImageAttachments(message)) {
|
|
181
|
+
return content;
|
|
182
|
+
}
|
|
183
|
+
const blocks = [];
|
|
184
|
+
if (content) {
|
|
185
|
+
blocks.push({ type: "text", text: content });
|
|
186
|
+
}
|
|
187
|
+
if (attachments) {
|
|
188
|
+
for (const attachment of attachments) {
|
|
189
|
+
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
190
|
+
if (imageBlock) {
|
|
191
|
+
blocks.push(imageBlock);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return blocks;
|
|
196
|
+
}
|
|
197
|
+
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
198
|
+
const formatted = [];
|
|
199
|
+
if (systemPrompt) {
|
|
200
|
+
formatted.push({ role: "system", content: systemPrompt });
|
|
201
|
+
}
|
|
202
|
+
for (const msg of messages) {
|
|
203
|
+
if (msg.role === "system") {
|
|
204
|
+
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
205
|
+
} else if (msg.role === "user") {
|
|
206
|
+
formatted.push({
|
|
207
|
+
role: "user",
|
|
208
|
+
content: messageToOpenAIContent(msg)
|
|
209
|
+
});
|
|
210
|
+
} else if (msg.role === "assistant") {
|
|
211
|
+
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
212
|
+
const assistantMsg = {
|
|
213
|
+
role: "assistant",
|
|
214
|
+
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
215
|
+
content: hasToolCalls ? msg.content || null : msg.content
|
|
216
|
+
};
|
|
217
|
+
if (hasToolCalls) {
|
|
218
|
+
assistantMsg.tool_calls = msg.tool_calls;
|
|
219
|
+
}
|
|
220
|
+
formatted.push(assistantMsg);
|
|
221
|
+
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
222
|
+
formatted.push({
|
|
223
|
+
role: "tool",
|
|
224
|
+
content: msg.content ?? "",
|
|
225
|
+
tool_call_id: msg.tool_call_id
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return formatted;
|
|
230
|
+
}
|
|
231
|
+
|
|
3
232
|
// src/providers/google/provider.ts
|
|
4
233
|
var GOOGLE_MODELS = {
|
|
5
234
|
// Gemini 2.5 (Experimental)
|
|
@@ -119,7 +348,8 @@ function google(modelId, options = {}) {
|
|
|
119
348
|
messages,
|
|
120
349
|
tools: params.tools,
|
|
121
350
|
temperature: params.temperature,
|
|
122
|
-
max_tokens: params.maxTokens
|
|
351
|
+
max_tokens: params.maxTokens,
|
|
352
|
+
response_format: toOpenAIResponseFormat(params.responseFormat)
|
|
123
353
|
});
|
|
124
354
|
const choice = response.choices[0];
|
|
125
355
|
const message = choice.message;
|
|
@@ -151,6 +381,7 @@ function google(modelId, options = {}) {
|
|
|
151
381
|
tools: params.tools,
|
|
152
382
|
temperature: params.temperature,
|
|
153
383
|
max_tokens: params.maxTokens,
|
|
384
|
+
response_format: toOpenAIResponseFormat(params.responseFormat),
|
|
154
385
|
stream: true
|
|
155
386
|
});
|
|
156
387
|
let currentToolCall = null;
|
|
@@ -296,204 +527,6 @@ function generateToolCallId() {
|
|
|
296
527
|
return generateId("call");
|
|
297
528
|
}
|
|
298
529
|
|
|
299
|
-
// src/adapters/base.ts
|
|
300
|
-
function stringifyForDebug(value) {
|
|
301
|
-
return JSON.stringify(
|
|
302
|
-
value,
|
|
303
|
-
(_key, currentValue) => {
|
|
304
|
-
if (typeof currentValue === "bigint") {
|
|
305
|
-
return currentValue.toString();
|
|
306
|
-
}
|
|
307
|
-
if (currentValue instanceof Error) {
|
|
308
|
-
return {
|
|
309
|
-
name: currentValue.name,
|
|
310
|
-
message: currentValue.message,
|
|
311
|
-
stack: currentValue.stack
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
return currentValue;
|
|
315
|
-
},
|
|
316
|
-
2
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
320
|
-
if (!enabled) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
try {
|
|
327
|
-
console.log(
|
|
328
|
-
`[llm-sdk:${provider}] ${label}
|
|
329
|
-
${stringifyForDebug(payload)}`
|
|
330
|
-
);
|
|
331
|
-
} catch (error) {
|
|
332
|
-
console.log(
|
|
333
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
334
|
-
error
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
function parameterToJsonSchema(param) {
|
|
339
|
-
const schema = {
|
|
340
|
-
type: param.type
|
|
341
|
-
};
|
|
342
|
-
if (param.description) {
|
|
343
|
-
schema.description = param.description;
|
|
344
|
-
}
|
|
345
|
-
if (param.enum) {
|
|
346
|
-
schema.enum = param.enum;
|
|
347
|
-
}
|
|
348
|
-
if (param.type === "array" && param.items) {
|
|
349
|
-
schema.items = parameterToJsonSchema(
|
|
350
|
-
param.items
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
if (param.type === "object" && param.properties) {
|
|
354
|
-
schema.properties = Object.fromEntries(
|
|
355
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
356
|
-
key,
|
|
357
|
-
parameterToJsonSchema(
|
|
358
|
-
prop
|
|
359
|
-
)
|
|
360
|
-
])
|
|
361
|
-
);
|
|
362
|
-
schema.additionalProperties = false;
|
|
363
|
-
}
|
|
364
|
-
return schema;
|
|
365
|
-
}
|
|
366
|
-
function normalizeObjectJsonSchema(schema) {
|
|
367
|
-
if (!schema || typeof schema !== "object") {
|
|
368
|
-
return {
|
|
369
|
-
type: "object",
|
|
370
|
-
properties: {},
|
|
371
|
-
required: [],
|
|
372
|
-
additionalProperties: false
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
const normalized = { ...schema };
|
|
376
|
-
const type = normalized.type;
|
|
377
|
-
if (type === "object") {
|
|
378
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
379
|
-
normalized.properties = Object.fromEntries(
|
|
380
|
-
Object.entries(properties).map(([key, value]) => [
|
|
381
|
-
key,
|
|
382
|
-
normalizeObjectJsonSchema(value)
|
|
383
|
-
])
|
|
384
|
-
);
|
|
385
|
-
const propertyKeys = Object.keys(properties);
|
|
386
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
387
|
-
(value) => typeof value === "string"
|
|
388
|
-
) : [];
|
|
389
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
390
|
-
if (normalized.additionalProperties === void 0) {
|
|
391
|
-
normalized.additionalProperties = false;
|
|
392
|
-
}
|
|
393
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
394
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
395
|
-
normalized.items
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
return normalized;
|
|
399
|
-
}
|
|
400
|
-
function formatTools(actions) {
|
|
401
|
-
return actions.map((action) => ({
|
|
402
|
-
type: "function",
|
|
403
|
-
function: {
|
|
404
|
-
name: action.name,
|
|
405
|
-
description: action.description,
|
|
406
|
-
parameters: {
|
|
407
|
-
type: "object",
|
|
408
|
-
properties: action.parameters ? Object.fromEntries(
|
|
409
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
410
|
-
key,
|
|
411
|
-
parameterToJsonSchema(param)
|
|
412
|
-
])
|
|
413
|
-
) : {},
|
|
414
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
415
|
-
additionalProperties: false
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}));
|
|
419
|
-
}
|
|
420
|
-
function hasImageAttachments(message) {
|
|
421
|
-
const attachments = message.metadata?.attachments;
|
|
422
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
423
|
-
}
|
|
424
|
-
function attachmentToOpenAIImage(attachment) {
|
|
425
|
-
if (attachment.type !== "image") return null;
|
|
426
|
-
let imageUrl;
|
|
427
|
-
if (attachment.url) {
|
|
428
|
-
imageUrl = attachment.url;
|
|
429
|
-
} else if (attachment.data) {
|
|
430
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
431
|
-
} else {
|
|
432
|
-
return null;
|
|
433
|
-
}
|
|
434
|
-
return {
|
|
435
|
-
type: "image_url",
|
|
436
|
-
image_url: {
|
|
437
|
-
url: imageUrl,
|
|
438
|
-
detail: "auto"
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
function messageToOpenAIContent(message) {
|
|
443
|
-
const attachments = message.metadata?.attachments;
|
|
444
|
-
const content = message.content ?? "";
|
|
445
|
-
if (!hasImageAttachments(message)) {
|
|
446
|
-
return content;
|
|
447
|
-
}
|
|
448
|
-
const blocks = [];
|
|
449
|
-
if (content) {
|
|
450
|
-
blocks.push({ type: "text", text: content });
|
|
451
|
-
}
|
|
452
|
-
if (attachments) {
|
|
453
|
-
for (const attachment of attachments) {
|
|
454
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
455
|
-
if (imageBlock) {
|
|
456
|
-
blocks.push(imageBlock);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
return blocks;
|
|
461
|
-
}
|
|
462
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
463
|
-
const formatted = [];
|
|
464
|
-
if (systemPrompt) {
|
|
465
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
466
|
-
}
|
|
467
|
-
for (const msg of messages) {
|
|
468
|
-
if (msg.role === "system") {
|
|
469
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
470
|
-
} else if (msg.role === "user") {
|
|
471
|
-
formatted.push({
|
|
472
|
-
role: "user",
|
|
473
|
-
content: messageToOpenAIContent(msg)
|
|
474
|
-
});
|
|
475
|
-
} else if (msg.role === "assistant") {
|
|
476
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
477
|
-
const assistantMsg = {
|
|
478
|
-
role: "assistant",
|
|
479
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
480
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
481
|
-
};
|
|
482
|
-
if (hasToolCalls) {
|
|
483
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
484
|
-
}
|
|
485
|
-
formatted.push(assistantMsg);
|
|
486
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
487
|
-
formatted.push({
|
|
488
|
-
role: "tool",
|
|
489
|
-
content: msg.content ?? "",
|
|
490
|
-
tool_call_id: msg.tool_call_id
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
return formatted;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
530
|
// src/adapters/openai.ts
|
|
498
531
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
499
532
|
constructor(config) {
|
|
@@ -506,7 +539,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
506
539
|
if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
|
|
507
540
|
if (baseUrl.includes("x.ai")) return "xai";
|
|
508
541
|
if (baseUrl.includes("azure")) return "azure";
|
|
509
|
-
if (baseUrl.includes("openrouter.ai")) return "openrouter";
|
|
510
542
|
return "openai";
|
|
511
543
|
}
|
|
512
544
|
async getClient() {
|
|
@@ -606,259 +638,12 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
606
638
|
rawResponse: response
|
|
607
639
|
};
|
|
608
640
|
}
|
|
609
|
-
/**
|
|
610
|
-
* OpenAI reasoning models on OpenRouter (o1/o3/o4/gpt-5 family) hide their
|
|
611
|
-
* reasoning content on the chat-completions endpoint. To surface reasoning
|
|
612
|
-
* SUMMARIES (not raw CoT, which OpenAI never exposes) we have to use the
|
|
613
|
-
* Responses API, which streams `response.reasoning_summary_text.delta` events.
|
|
614
|
-
*
|
|
615
|
-
* Match by prefix on the OpenRouter model id. Excludes openai/gpt-4o,
|
|
616
|
-
* openai/gpt-4.1, openai/chatgpt-* — those continue on chat-completions.
|
|
617
|
-
*/
|
|
618
|
-
isOpenAIReasoningModelOnOpenRouter(activeModel) {
|
|
619
|
-
if (this.provider !== "openrouter") return false;
|
|
620
|
-
return activeModel.startsWith("openai/o1") || activeModel.startsWith("openai/o3") || activeModel.startsWith("openai/o4") || activeModel.startsWith("openai/gpt-5");
|
|
621
|
-
}
|
|
622
|
-
/**
|
|
623
|
-
* Convert ActionDefinition[] (the chat-completions tool shape used by the
|
|
624
|
-
* adapter) to the Responses API tool shape.
|
|
625
|
-
*/
|
|
626
|
-
buildResponsesToolsFromActions(actions) {
|
|
627
|
-
if (!actions || actions.length === 0) return void 0;
|
|
628
|
-
const formatted = formatTools(actions);
|
|
629
|
-
return formatted.map((t) => ({
|
|
630
|
-
type: "function",
|
|
631
|
-
name: t.function.name,
|
|
632
|
-
description: t.function.description,
|
|
633
|
-
parameters: t.function.parameters
|
|
634
|
-
}));
|
|
635
|
-
}
|
|
636
|
-
/**
|
|
637
|
-
* Streaming Responses API path for OpenAI reasoning models on OpenRouter.
|
|
638
|
-
*
|
|
639
|
-
* Maps Responses API SSE events back to the same StreamEvent shapes the
|
|
640
|
-
* chat-completions path emits, so downstream consumers (processChunk.ts,
|
|
641
|
-
* frontend tool handlers, plan approval, specialist delegations) see
|
|
642
|
-
* identical events regardless of which path produced them.
|
|
643
|
-
*
|
|
644
|
-
* response.reasoning_summary_text.delta → thinking:start (once) + thinking:delta
|
|
645
|
-
* response.output_text.delta → message:delta
|
|
646
|
-
* response.output_item.added (function_call) → action:start (queued buffer)
|
|
647
|
-
* response.function_call_arguments.delta → action:args (progressive)
|
|
648
|
-
* response.output_item.done (function_call) → final action:args + action:end
|
|
649
|
-
* response.completed → message:end + done(usage)
|
|
650
|
-
* response.error → error
|
|
651
|
-
*/
|
|
652
|
-
async *streamWithResponsesAPI(request, activeModel, messageId) {
|
|
653
|
-
const client = await this.getClient();
|
|
654
|
-
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
655
|
-
const payload = {
|
|
656
|
-
model: activeModel,
|
|
657
|
-
input: this.buildResponsesInput(request),
|
|
658
|
-
stream: true,
|
|
659
|
-
reasoning: {
|
|
660
|
-
effort: request.config?.reasoningEffort ?? "medium",
|
|
661
|
-
summary: "auto"
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
if (request.systemPrompt) payload.instructions = request.systemPrompt;
|
|
665
|
-
if (typeof maxTokensValue === "number")
|
|
666
|
-
payload.max_output_tokens = maxTokensValue;
|
|
667
|
-
const tools = this.buildResponsesToolsFromActions(request.actions);
|
|
668
|
-
if (tools && tools.length > 0) payload.tools = tools;
|
|
669
|
-
logProviderPayload(
|
|
670
|
-
"openai",
|
|
671
|
-
"responses-api request payload",
|
|
672
|
-
payload,
|
|
673
|
-
request.debug
|
|
674
|
-
);
|
|
675
|
-
let stream;
|
|
676
|
-
try {
|
|
677
|
-
stream = await client.responses.create(payload);
|
|
678
|
-
} catch (error) {
|
|
679
|
-
yield {
|
|
680
|
-
type: "error",
|
|
681
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
682
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
683
|
-
};
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
const toolBuffers = /* @__PURE__ */ new Map();
|
|
687
|
-
const itemIdToCallId = /* @__PURE__ */ new Map();
|
|
688
|
-
let usage;
|
|
689
|
-
let reasoningStarted = false;
|
|
690
|
-
let textStarted = false;
|
|
691
|
-
let finishEmitted = false;
|
|
692
|
-
const resolveCallId = (evt) => {
|
|
693
|
-
if (evt?.call_id) return evt.call_id;
|
|
694
|
-
if (evt?.item_id) return itemIdToCallId.get(evt.item_id) ?? evt.item_id;
|
|
695
|
-
if (evt?.item?.call_id) return evt.item.call_id;
|
|
696
|
-
if (evt?.item?.id) return evt.item.id;
|
|
697
|
-
return "";
|
|
698
|
-
};
|
|
699
|
-
try {
|
|
700
|
-
for await (const evt of stream) {
|
|
701
|
-
logProviderPayload(
|
|
702
|
-
"openai",
|
|
703
|
-
"responses-api stream chunk",
|
|
704
|
-
evt,
|
|
705
|
-
request.debug
|
|
706
|
-
);
|
|
707
|
-
if (request.signal?.aborted) break;
|
|
708
|
-
const t = evt?.type ?? "";
|
|
709
|
-
if (t === "response.reasoning_summary_text.delta") {
|
|
710
|
-
const delta = evt.delta ?? "";
|
|
711
|
-
if (!delta) continue;
|
|
712
|
-
if (!reasoningStarted) {
|
|
713
|
-
yield { type: "thinking:start" };
|
|
714
|
-
reasoningStarted = true;
|
|
715
|
-
}
|
|
716
|
-
yield { type: "thinking:delta", content: delta };
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
if (t === "response.reasoning_summary_text.done" || t === "response.reasoning.done") {
|
|
720
|
-
continue;
|
|
721
|
-
}
|
|
722
|
-
if (t === "response.output_text.delta") {
|
|
723
|
-
const text = evt.delta ?? "";
|
|
724
|
-
if (!text) continue;
|
|
725
|
-
if (reasoningStarted && !textStarted) {
|
|
726
|
-
yield { type: "thinking:end" };
|
|
727
|
-
textStarted = true;
|
|
728
|
-
}
|
|
729
|
-
yield { type: "message:delta", content: text };
|
|
730
|
-
continue;
|
|
731
|
-
}
|
|
732
|
-
if (t === "response.output_item.added") {
|
|
733
|
-
const item = evt.item;
|
|
734
|
-
if (item?.type === "function_call") {
|
|
735
|
-
const callId = item.call_id ?? item.id ?? "";
|
|
736
|
-
const itemId = item.id ?? callId;
|
|
737
|
-
if (callId) {
|
|
738
|
-
if (itemId && itemId !== callId) {
|
|
739
|
-
itemIdToCallId.set(itemId, callId);
|
|
740
|
-
}
|
|
741
|
-
if (!toolBuffers.has(callId)) {
|
|
742
|
-
toolBuffers.set(callId, {
|
|
743
|
-
id: callId,
|
|
744
|
-
name: item.name ?? "",
|
|
745
|
-
arguments: item.arguments ?? "",
|
|
746
|
-
emittedStart: false
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
const buf = toolBuffers.get(callId);
|
|
750
|
-
if (buf.name && !buf.emittedStart) {
|
|
751
|
-
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
752
|
-
buf.emittedStart = true;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
continue;
|
|
757
|
-
}
|
|
758
|
-
if (t === "response.function_call_arguments.delta") {
|
|
759
|
-
const callId = resolveCallId(evt);
|
|
760
|
-
const delta = evt.delta ?? "";
|
|
761
|
-
if (!callId || !delta) continue;
|
|
762
|
-
let buf = toolBuffers.get(callId);
|
|
763
|
-
if (!buf) {
|
|
764
|
-
buf = { id: callId, name: "", arguments: "", emittedStart: false };
|
|
765
|
-
toolBuffers.set(callId, buf);
|
|
766
|
-
}
|
|
767
|
-
buf.arguments += delta;
|
|
768
|
-
if (buf.emittedStart) {
|
|
769
|
-
yield {
|
|
770
|
-
type: "action:args",
|
|
771
|
-
id: buf.id,
|
|
772
|
-
args: buf.arguments
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
continue;
|
|
776
|
-
}
|
|
777
|
-
if (t === "response.output_item.done") {
|
|
778
|
-
const item = evt.item;
|
|
779
|
-
if (item?.type === "function_call") {
|
|
780
|
-
const callId = item.call_id ?? item.id ?? "";
|
|
781
|
-
const buf = toolBuffers.get(callId);
|
|
782
|
-
const name = buf?.name || item.name || "";
|
|
783
|
-
const argsStr = buf?.arguments || item.arguments || "{}";
|
|
784
|
-
if (callId && name) {
|
|
785
|
-
if (!buf?.emittedStart) {
|
|
786
|
-
yield { type: "action:start", id: callId, name };
|
|
787
|
-
}
|
|
788
|
-
yield {
|
|
789
|
-
type: "action:args",
|
|
790
|
-
id: callId,
|
|
791
|
-
args: argsStr
|
|
792
|
-
};
|
|
793
|
-
yield {
|
|
794
|
-
type: "action:end",
|
|
795
|
-
id: callId,
|
|
796
|
-
name
|
|
797
|
-
};
|
|
798
|
-
}
|
|
799
|
-
toolBuffers.delete(callId);
|
|
800
|
-
}
|
|
801
|
-
continue;
|
|
802
|
-
}
|
|
803
|
-
if (t === "response.completed") {
|
|
804
|
-
const u = evt.response?.usage;
|
|
805
|
-
if (u) {
|
|
806
|
-
usage = {
|
|
807
|
-
prompt_tokens: u.input_tokens ?? 0,
|
|
808
|
-
completion_tokens: u.output_tokens ?? 0,
|
|
809
|
-
total_tokens: u.total_tokens ?? (u.input_tokens ?? 0) + (u.output_tokens ?? 0)
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
for (const buf of toolBuffers.values()) {
|
|
813
|
-
if (!buf.id || !buf.name) continue;
|
|
814
|
-
if (!buf.emittedStart) {
|
|
815
|
-
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
816
|
-
}
|
|
817
|
-
yield {
|
|
818
|
-
type: "action:args",
|
|
819
|
-
id: buf.id,
|
|
820
|
-
args: buf.arguments || "{}"
|
|
821
|
-
};
|
|
822
|
-
yield { type: "action:end", id: buf.id, name: buf.name };
|
|
823
|
-
}
|
|
824
|
-
toolBuffers.clear();
|
|
825
|
-
if (reasoningStarted && !textStarted) {
|
|
826
|
-
yield { type: "thinking:end" };
|
|
827
|
-
}
|
|
828
|
-
yield { type: "message:end" };
|
|
829
|
-
yield { type: "done", usage };
|
|
830
|
-
finishEmitted = true;
|
|
831
|
-
continue;
|
|
832
|
-
}
|
|
833
|
-
if (t === "response.error" || t === "error") {
|
|
834
|
-
const msg = evt.error?.message || evt.message || "Responses API error";
|
|
835
|
-
yield {
|
|
836
|
-
type: "error",
|
|
837
|
-
message: msg,
|
|
838
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
839
|
-
};
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
} catch (error) {
|
|
844
|
-
yield {
|
|
845
|
-
type: "error",
|
|
846
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
847
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
848
|
-
};
|
|
849
|
-
return;
|
|
850
|
-
}
|
|
851
|
-
if (!finishEmitted) {
|
|
852
|
-
if (reasoningStarted && !textStarted) {
|
|
853
|
-
yield { type: "thinking:end" };
|
|
854
|
-
}
|
|
855
|
-
yield { type: "message:end" };
|
|
856
|
-
yield { type: "done", usage };
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
641
|
async completeWithResponses(request) {
|
|
860
642
|
const client = await this.getClient();
|
|
861
643
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
644
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
645
|
+
request.config?.responseFormat
|
|
646
|
+
);
|
|
862
647
|
const payload = {
|
|
863
648
|
model: request.config?.model || this.model,
|
|
864
649
|
instructions: request.systemPrompt,
|
|
@@ -868,6 +653,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
868
653
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
869
654
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
870
655
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
656
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
871
657
|
stream: false
|
|
872
658
|
};
|
|
873
659
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -989,37 +775,21 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
989
775
|
name: openaiToolOptions.toolChoice.name
|
|
990
776
|
}
|
|
991
777
|
} : openaiToolOptions?.toolChoice;
|
|
992
|
-
const
|
|
993
|
-
const activeModel = request.config?.model || this.model;
|
|
994
|
-
const modelSlug = activeModel.replace("openai/", "");
|
|
995
|
-
const isOSeries = /^o[1-9]/.test(modelSlug);
|
|
996
|
-
const isOpenAIOnOpenRouter = isOpenRouter && activeModel.startsWith("openai/");
|
|
997
|
-
if (!this.config.disableThinking && this.isOpenAIReasoningModelOnOpenRouter(activeModel)) {
|
|
998
|
-
yield* this.streamWithResponsesAPI(request, activeModel, messageId);
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
778
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
1002
779
|
const payload = {
|
|
1003
|
-
model:
|
|
780
|
+
model: modelIdForPayload,
|
|
1004
781
|
messages,
|
|
1005
782
|
tools: tools.length > 0 ? tools : void 0,
|
|
1006
783
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1007
784
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
785
|
+
...buildOpenAITokenParams(
|
|
786
|
+
modelIdForPayload,
|
|
787
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
788
|
+
request.config?.temperature ?? this.config.temperature
|
|
789
|
+
),
|
|
790
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
1008
791
|
stream: true,
|
|
1009
|
-
stream_options: { include_usage: true }
|
|
1010
|
-
// o-series: use max_completion_tokens + reasoning_effort, no temperature
|
|
1011
|
-
// regular models: use max_tokens + temperature
|
|
1012
|
-
...isOSeries ? {
|
|
1013
|
-
max_completion_tokens: maxTokensValue,
|
|
1014
|
-
reasoning_effort: request.config?.reasoningEffort ?? "medium"
|
|
1015
|
-
} : {
|
|
1016
|
-
temperature: request.config?.temperature ?? this.config.temperature,
|
|
1017
|
-
max_tokens: maxTokensValue
|
|
1018
|
-
},
|
|
1019
|
-
// Non-OpenAI OpenRouter models support OR's reasoning/include_reasoning params.
|
|
1020
|
-
// When disableThinking=true we must explicitly send include_reasoning:false because
|
|
1021
|
-
// models like Qwen3 and DeepSeek-R1 reason by default even without the reasoning param.
|
|
1022
|
-
...isOpenRouter && !isOpenAIOnOpenRouter ? this.config.disableThinking ? { include_reasoning: false } : { reasoning: { max_tokens: 8e3 }, include_reasoning: true } : {}
|
|
792
|
+
stream_options: { include_usage: true }
|
|
1023
793
|
};
|
|
1024
794
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1025
795
|
const stream = await client.chat.completions.create(payload);
|
|
@@ -1027,7 +797,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1027
797
|
const collectedCitations = [];
|
|
1028
798
|
let citationIndex = 0;
|
|
1029
799
|
let usage;
|
|
1030
|
-
let adapterReasoningStarted = false;
|
|
1031
800
|
for await (const chunk of stream) {
|
|
1032
801
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
1033
802
|
if (request.signal?.aborted) {
|
|
@@ -1038,22 +807,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1038
807
|
if (delta?.content) {
|
|
1039
808
|
yield { type: "message:delta", content: delta.content };
|
|
1040
809
|
}
|
|
1041
|
-
if (isOpenRouter) {
|
|
1042
|
-
const rc = delta?.reasoning_content ?? delta?.reasoning ?? null;
|
|
1043
|
-
if (rc) {
|
|
1044
|
-
const rcText = typeof rc === "string" ? rc : Array.isArray(rc) && rc[0]?.text ? rc[0].text : "";
|
|
1045
|
-
if (rcText) {
|
|
1046
|
-
if (!adapterReasoningStarted) {
|
|
1047
|
-
yield { type: "thinking:start" };
|
|
1048
|
-
adapterReasoningStarted = true;
|
|
1049
|
-
}
|
|
1050
|
-
yield { type: "thinking:delta", content: rcText };
|
|
1051
|
-
}
|
|
1052
|
-
} else if (adapterReasoningStarted && (delta?.content || choice?.finish_reason)) {
|
|
1053
|
-
yield { type: "thinking:end" };
|
|
1054
|
-
adapterReasoningStarted = false;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
810
|
const annotations = delta?.annotations;
|
|
1058
811
|
if (annotations && annotations.length > 0) {
|
|
1059
812
|
for (const annotation of annotations) {
|
|
@@ -1101,11 +854,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1101
854
|
};
|
|
1102
855
|
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
1103
856
|
currentToolCall.arguments += toolCall.function.arguments;
|
|
1104
|
-
yield {
|
|
1105
|
-
type: "action:args",
|
|
1106
|
-
id: currentToolCall.id,
|
|
1107
|
-
args: currentToolCall.arguments
|
|
1108
|
-
};
|
|
1109
857
|
}
|
|
1110
858
|
}
|
|
1111
859
|
}
|
|
@@ -1181,24 +929,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1181
929
|
name: openaiToolOptions.toolChoice.name
|
|
1182
930
|
}
|
|
1183
931
|
} : openaiToolOptions?.toolChoice;
|
|
1184
|
-
const
|
|
1185
|
-
const modelSlug2 = activeModel2.replace("openai/", "");
|
|
1186
|
-
const isOSeries2 = /^o[1-9]/.test(modelSlug2);
|
|
1187
|
-
const maxTokensValue2 = request.config?.maxTokens ?? this.config.maxTokens;
|
|
932
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
1188
933
|
const payload = {
|
|
1189
|
-
model:
|
|
934
|
+
model: modelIdForCompletePayload,
|
|
1190
935
|
messages,
|
|
1191
936
|
tools: tools.length > 0 ? tools : void 0,
|
|
1192
937
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1193
938
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
}
|
|
939
|
+
...buildOpenAITokenParams(
|
|
940
|
+
modelIdForCompletePayload,
|
|
941
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
942
|
+
request.config?.temperature ?? this.config.temperature
|
|
943
|
+
),
|
|
944
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
945
|
+
stream: false
|
|
1202
946
|
};
|
|
1203
947
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1204
948
|
const response = await client.chat.completions.create(payload);
|