@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/openai/provider.ts
|
|
4
233
|
var OPENAI_MODELS = {
|
|
5
234
|
// GPT-4o series
|
|
@@ -94,13 +323,17 @@ function openai(modelId, options = {}) {
|
|
|
94
323
|
},
|
|
95
324
|
async doGenerate(params) {
|
|
96
325
|
const client2 = await getClient();
|
|
97
|
-
const messages =
|
|
326
|
+
const messages = formatMessagesForOpenAI2(params.messages);
|
|
98
327
|
const response = await client2.chat.completions.create({
|
|
99
328
|
model: modelId,
|
|
100
329
|
messages,
|
|
101
330
|
tools: params.tools,
|
|
102
|
-
|
|
103
|
-
|
|
331
|
+
...buildOpenAITokenParams(
|
|
332
|
+
modelId,
|
|
333
|
+
params.maxTokens,
|
|
334
|
+
params.temperature
|
|
335
|
+
),
|
|
336
|
+
response_format: toOpenAIResponseFormat(params.responseFormat)
|
|
104
337
|
});
|
|
105
338
|
const choice = response.choices[0];
|
|
106
339
|
const message = choice.message;
|
|
@@ -125,13 +358,17 @@ function openai(modelId, options = {}) {
|
|
|
125
358
|
},
|
|
126
359
|
async *doStream(params) {
|
|
127
360
|
const client2 = await getClient();
|
|
128
|
-
const messages =
|
|
361
|
+
const messages = formatMessagesForOpenAI2(params.messages);
|
|
129
362
|
const stream = await client2.chat.completions.create({
|
|
130
363
|
model: modelId,
|
|
131
364
|
messages,
|
|
132
365
|
tools: params.tools,
|
|
133
|
-
|
|
134
|
-
|
|
366
|
+
...buildOpenAITokenParams(
|
|
367
|
+
modelId,
|
|
368
|
+
params.maxTokens,
|
|
369
|
+
params.temperature
|
|
370
|
+
),
|
|
371
|
+
response_format: toOpenAIResponseFormat(params.responseFormat),
|
|
135
372
|
stream: true
|
|
136
373
|
});
|
|
137
374
|
let currentToolCall = null;
|
|
@@ -165,18 +402,8 @@ function openai(modelId, options = {}) {
|
|
|
165
402
|
name: tc.function?.name ?? "",
|
|
166
403
|
arguments: tc.function?.arguments ?? ""
|
|
167
404
|
};
|
|
168
|
-
yield {
|
|
169
|
-
type: "tool-call-start",
|
|
170
|
-
toolCallId: tc.id,
|
|
171
|
-
toolName: tc.function?.name ?? ""
|
|
172
|
-
};
|
|
173
405
|
} else if (currentToolCall && tc.function?.arguments) {
|
|
174
406
|
currentToolCall.arguments += tc.function.arguments;
|
|
175
|
-
yield {
|
|
176
|
-
type: "tool-call-delta",
|
|
177
|
-
toolCallId: currentToolCall.id,
|
|
178
|
-
argsText: currentToolCall.arguments
|
|
179
|
-
};
|
|
180
407
|
}
|
|
181
408
|
}
|
|
182
409
|
}
|
|
@@ -225,7 +452,7 @@ function mapFinishReason(reason) {
|
|
|
225
452
|
return "unknown";
|
|
226
453
|
}
|
|
227
454
|
}
|
|
228
|
-
function
|
|
455
|
+
function formatMessagesForOpenAI2(messages) {
|
|
229
456
|
return messages.map((msg) => {
|
|
230
457
|
switch (msg.role) {
|
|
231
458
|
case "system":
|
|
@@ -287,204 +514,6 @@ function generateToolCallId() {
|
|
|
287
514
|
return generateId("call");
|
|
288
515
|
}
|
|
289
516
|
|
|
290
|
-
// src/adapters/base.ts
|
|
291
|
-
function stringifyForDebug(value) {
|
|
292
|
-
return JSON.stringify(
|
|
293
|
-
value,
|
|
294
|
-
(_key, currentValue) => {
|
|
295
|
-
if (typeof currentValue === "bigint") {
|
|
296
|
-
return currentValue.toString();
|
|
297
|
-
}
|
|
298
|
-
if (currentValue instanceof Error) {
|
|
299
|
-
return {
|
|
300
|
-
name: currentValue.name,
|
|
301
|
-
message: currentValue.message,
|
|
302
|
-
stack: currentValue.stack
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
return currentValue;
|
|
306
|
-
},
|
|
307
|
-
2
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
311
|
-
if (!enabled) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
try {
|
|
318
|
-
console.log(
|
|
319
|
-
`[llm-sdk:${provider}] ${label}
|
|
320
|
-
${stringifyForDebug(payload)}`
|
|
321
|
-
);
|
|
322
|
-
} catch (error) {
|
|
323
|
-
console.log(
|
|
324
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
325
|
-
error
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
function parameterToJsonSchema(param) {
|
|
330
|
-
const schema = {
|
|
331
|
-
type: param.type
|
|
332
|
-
};
|
|
333
|
-
if (param.description) {
|
|
334
|
-
schema.description = param.description;
|
|
335
|
-
}
|
|
336
|
-
if (param.enum) {
|
|
337
|
-
schema.enum = param.enum;
|
|
338
|
-
}
|
|
339
|
-
if (param.type === "array" && param.items) {
|
|
340
|
-
schema.items = parameterToJsonSchema(
|
|
341
|
-
param.items
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
if (param.type === "object" && param.properties) {
|
|
345
|
-
schema.properties = Object.fromEntries(
|
|
346
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
347
|
-
key,
|
|
348
|
-
parameterToJsonSchema(
|
|
349
|
-
prop
|
|
350
|
-
)
|
|
351
|
-
])
|
|
352
|
-
);
|
|
353
|
-
schema.additionalProperties = false;
|
|
354
|
-
}
|
|
355
|
-
return schema;
|
|
356
|
-
}
|
|
357
|
-
function normalizeObjectJsonSchema(schema) {
|
|
358
|
-
if (!schema || typeof schema !== "object") {
|
|
359
|
-
return {
|
|
360
|
-
type: "object",
|
|
361
|
-
properties: {},
|
|
362
|
-
required: [],
|
|
363
|
-
additionalProperties: false
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
const normalized = { ...schema };
|
|
367
|
-
const type = normalized.type;
|
|
368
|
-
if (type === "object") {
|
|
369
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
370
|
-
normalized.properties = Object.fromEntries(
|
|
371
|
-
Object.entries(properties).map(([key, value]) => [
|
|
372
|
-
key,
|
|
373
|
-
normalizeObjectJsonSchema(value)
|
|
374
|
-
])
|
|
375
|
-
);
|
|
376
|
-
const propertyKeys = Object.keys(properties);
|
|
377
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
378
|
-
(value) => typeof value === "string"
|
|
379
|
-
) : [];
|
|
380
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
381
|
-
if (normalized.additionalProperties === void 0) {
|
|
382
|
-
normalized.additionalProperties = false;
|
|
383
|
-
}
|
|
384
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
385
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
386
|
-
normalized.items
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
return normalized;
|
|
390
|
-
}
|
|
391
|
-
function formatTools(actions) {
|
|
392
|
-
return actions.map((action) => ({
|
|
393
|
-
type: "function",
|
|
394
|
-
function: {
|
|
395
|
-
name: action.name,
|
|
396
|
-
description: action.description,
|
|
397
|
-
parameters: {
|
|
398
|
-
type: "object",
|
|
399
|
-
properties: action.parameters ? Object.fromEntries(
|
|
400
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
401
|
-
key,
|
|
402
|
-
parameterToJsonSchema(param)
|
|
403
|
-
])
|
|
404
|
-
) : {},
|
|
405
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
406
|
-
additionalProperties: false
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}));
|
|
410
|
-
}
|
|
411
|
-
function hasImageAttachments(message) {
|
|
412
|
-
const attachments = message.metadata?.attachments;
|
|
413
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
414
|
-
}
|
|
415
|
-
function attachmentToOpenAIImage(attachment) {
|
|
416
|
-
if (attachment.type !== "image") return null;
|
|
417
|
-
let imageUrl;
|
|
418
|
-
if (attachment.url) {
|
|
419
|
-
imageUrl = attachment.url;
|
|
420
|
-
} else if (attachment.data) {
|
|
421
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
422
|
-
} else {
|
|
423
|
-
return null;
|
|
424
|
-
}
|
|
425
|
-
return {
|
|
426
|
-
type: "image_url",
|
|
427
|
-
image_url: {
|
|
428
|
-
url: imageUrl,
|
|
429
|
-
detail: "auto"
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
function messageToOpenAIContent(message) {
|
|
434
|
-
const attachments = message.metadata?.attachments;
|
|
435
|
-
const content = message.content ?? "";
|
|
436
|
-
if (!hasImageAttachments(message)) {
|
|
437
|
-
return content;
|
|
438
|
-
}
|
|
439
|
-
const blocks = [];
|
|
440
|
-
if (content) {
|
|
441
|
-
blocks.push({ type: "text", text: content });
|
|
442
|
-
}
|
|
443
|
-
if (attachments) {
|
|
444
|
-
for (const attachment of attachments) {
|
|
445
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
446
|
-
if (imageBlock) {
|
|
447
|
-
blocks.push(imageBlock);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
return blocks;
|
|
452
|
-
}
|
|
453
|
-
function formatMessagesForOpenAI2(messages, systemPrompt) {
|
|
454
|
-
const formatted = [];
|
|
455
|
-
if (systemPrompt) {
|
|
456
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
457
|
-
}
|
|
458
|
-
for (const msg of messages) {
|
|
459
|
-
if (msg.role === "system") {
|
|
460
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
461
|
-
} else if (msg.role === "user") {
|
|
462
|
-
formatted.push({
|
|
463
|
-
role: "user",
|
|
464
|
-
content: messageToOpenAIContent(msg)
|
|
465
|
-
});
|
|
466
|
-
} else if (msg.role === "assistant") {
|
|
467
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
468
|
-
const assistantMsg = {
|
|
469
|
-
role: "assistant",
|
|
470
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
471
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
472
|
-
};
|
|
473
|
-
if (hasToolCalls) {
|
|
474
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
475
|
-
}
|
|
476
|
-
formatted.push(assistantMsg);
|
|
477
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
478
|
-
formatted.push({
|
|
479
|
-
role: "tool",
|
|
480
|
-
content: msg.content ?? "",
|
|
481
|
-
tool_call_id: msg.tool_call_id
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return formatted;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
517
|
// src/adapters/openai.ts
|
|
489
518
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
490
519
|
constructor(config) {
|
|
@@ -497,7 +526,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
497
526
|
if (baseUrl.includes("generativelanguage.googleapis.com")) return "google";
|
|
498
527
|
if (baseUrl.includes("x.ai")) return "xai";
|
|
499
528
|
if (baseUrl.includes("azure")) return "azure";
|
|
500
|
-
if (baseUrl.includes("openrouter.ai")) return "openrouter";
|
|
501
529
|
return "openai";
|
|
502
530
|
}
|
|
503
531
|
async getClient() {
|
|
@@ -514,7 +542,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
514
542
|
return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
|
|
515
543
|
}
|
|
516
544
|
buildResponsesInput(request) {
|
|
517
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages :
|
|
545
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
|
|
518
546
|
const input = [];
|
|
519
547
|
for (const message of sourceMessages) {
|
|
520
548
|
if (message.role === "system") {
|
|
@@ -597,259 +625,12 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
597
625
|
rawResponse: response
|
|
598
626
|
};
|
|
599
627
|
}
|
|
600
|
-
/**
|
|
601
|
-
* OpenAI reasoning models on OpenRouter (o1/o3/o4/gpt-5 family) hide their
|
|
602
|
-
* reasoning content on the chat-completions endpoint. To surface reasoning
|
|
603
|
-
* SUMMARIES (not raw CoT, which OpenAI never exposes) we have to use the
|
|
604
|
-
* Responses API, which streams `response.reasoning_summary_text.delta` events.
|
|
605
|
-
*
|
|
606
|
-
* Match by prefix on the OpenRouter model id. Excludes openai/gpt-4o,
|
|
607
|
-
* openai/gpt-4.1, openai/chatgpt-* — those continue on chat-completions.
|
|
608
|
-
*/
|
|
609
|
-
isOpenAIReasoningModelOnOpenRouter(activeModel) {
|
|
610
|
-
if (this.provider !== "openrouter") return false;
|
|
611
|
-
return activeModel.startsWith("openai/o1") || activeModel.startsWith("openai/o3") || activeModel.startsWith("openai/o4") || activeModel.startsWith("openai/gpt-5");
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* Convert ActionDefinition[] (the chat-completions tool shape used by the
|
|
615
|
-
* adapter) to the Responses API tool shape.
|
|
616
|
-
*/
|
|
617
|
-
buildResponsesToolsFromActions(actions) {
|
|
618
|
-
if (!actions || actions.length === 0) return void 0;
|
|
619
|
-
const formatted = formatTools(actions);
|
|
620
|
-
return formatted.map((t) => ({
|
|
621
|
-
type: "function",
|
|
622
|
-
name: t.function.name,
|
|
623
|
-
description: t.function.description,
|
|
624
|
-
parameters: t.function.parameters
|
|
625
|
-
}));
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* Streaming Responses API path for OpenAI reasoning models on OpenRouter.
|
|
629
|
-
*
|
|
630
|
-
* Maps Responses API SSE events back to the same StreamEvent shapes the
|
|
631
|
-
* chat-completions path emits, so downstream consumers (processChunk.ts,
|
|
632
|
-
* frontend tool handlers, plan approval, specialist delegations) see
|
|
633
|
-
* identical events regardless of which path produced them.
|
|
634
|
-
*
|
|
635
|
-
* response.reasoning_summary_text.delta → thinking:start (once) + thinking:delta
|
|
636
|
-
* response.output_text.delta → message:delta
|
|
637
|
-
* response.output_item.added (function_call) → action:start (queued buffer)
|
|
638
|
-
* response.function_call_arguments.delta → action:args (progressive)
|
|
639
|
-
* response.output_item.done (function_call) → final action:args + action:end
|
|
640
|
-
* response.completed → message:end + done(usage)
|
|
641
|
-
* response.error → error
|
|
642
|
-
*/
|
|
643
|
-
async *streamWithResponsesAPI(request, activeModel, messageId) {
|
|
644
|
-
const client = await this.getClient();
|
|
645
|
-
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
646
|
-
const payload = {
|
|
647
|
-
model: activeModel,
|
|
648
|
-
input: this.buildResponsesInput(request),
|
|
649
|
-
stream: true,
|
|
650
|
-
reasoning: {
|
|
651
|
-
effort: request.config?.reasoningEffort ?? "medium",
|
|
652
|
-
summary: "auto"
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
if (request.systemPrompt) payload.instructions = request.systemPrompt;
|
|
656
|
-
if (typeof maxTokensValue === "number")
|
|
657
|
-
payload.max_output_tokens = maxTokensValue;
|
|
658
|
-
const tools = this.buildResponsesToolsFromActions(request.actions);
|
|
659
|
-
if (tools && tools.length > 0) payload.tools = tools;
|
|
660
|
-
logProviderPayload(
|
|
661
|
-
"openai",
|
|
662
|
-
"responses-api request payload",
|
|
663
|
-
payload,
|
|
664
|
-
request.debug
|
|
665
|
-
);
|
|
666
|
-
let stream;
|
|
667
|
-
try {
|
|
668
|
-
stream = await client.responses.create(payload);
|
|
669
|
-
} catch (error) {
|
|
670
|
-
yield {
|
|
671
|
-
type: "error",
|
|
672
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
673
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
674
|
-
};
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
const toolBuffers = /* @__PURE__ */ new Map();
|
|
678
|
-
const itemIdToCallId = /* @__PURE__ */ new Map();
|
|
679
|
-
let usage;
|
|
680
|
-
let reasoningStarted = false;
|
|
681
|
-
let textStarted = false;
|
|
682
|
-
let finishEmitted = false;
|
|
683
|
-
const resolveCallId = (evt) => {
|
|
684
|
-
if (evt?.call_id) return evt.call_id;
|
|
685
|
-
if (evt?.item_id) return itemIdToCallId.get(evt.item_id) ?? evt.item_id;
|
|
686
|
-
if (evt?.item?.call_id) return evt.item.call_id;
|
|
687
|
-
if (evt?.item?.id) return evt.item.id;
|
|
688
|
-
return "";
|
|
689
|
-
};
|
|
690
|
-
try {
|
|
691
|
-
for await (const evt of stream) {
|
|
692
|
-
logProviderPayload(
|
|
693
|
-
"openai",
|
|
694
|
-
"responses-api stream chunk",
|
|
695
|
-
evt,
|
|
696
|
-
request.debug
|
|
697
|
-
);
|
|
698
|
-
if (request.signal?.aborted) break;
|
|
699
|
-
const t = evt?.type ?? "";
|
|
700
|
-
if (t === "response.reasoning_summary_text.delta") {
|
|
701
|
-
const delta = evt.delta ?? "";
|
|
702
|
-
if (!delta) continue;
|
|
703
|
-
if (!reasoningStarted) {
|
|
704
|
-
yield { type: "thinking:start" };
|
|
705
|
-
reasoningStarted = true;
|
|
706
|
-
}
|
|
707
|
-
yield { type: "thinking:delta", content: delta };
|
|
708
|
-
continue;
|
|
709
|
-
}
|
|
710
|
-
if (t === "response.reasoning_summary_text.done" || t === "response.reasoning.done") {
|
|
711
|
-
continue;
|
|
712
|
-
}
|
|
713
|
-
if (t === "response.output_text.delta") {
|
|
714
|
-
const text = evt.delta ?? "";
|
|
715
|
-
if (!text) continue;
|
|
716
|
-
if (reasoningStarted && !textStarted) {
|
|
717
|
-
yield { type: "thinking:end" };
|
|
718
|
-
textStarted = true;
|
|
719
|
-
}
|
|
720
|
-
yield { type: "message:delta", content: text };
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
if (t === "response.output_item.added") {
|
|
724
|
-
const item = evt.item;
|
|
725
|
-
if (item?.type === "function_call") {
|
|
726
|
-
const callId = item.call_id ?? item.id ?? "";
|
|
727
|
-
const itemId = item.id ?? callId;
|
|
728
|
-
if (callId) {
|
|
729
|
-
if (itemId && itemId !== callId) {
|
|
730
|
-
itemIdToCallId.set(itemId, callId);
|
|
731
|
-
}
|
|
732
|
-
if (!toolBuffers.has(callId)) {
|
|
733
|
-
toolBuffers.set(callId, {
|
|
734
|
-
id: callId,
|
|
735
|
-
name: item.name ?? "",
|
|
736
|
-
arguments: item.arguments ?? "",
|
|
737
|
-
emittedStart: false
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
|
-
const buf = toolBuffers.get(callId);
|
|
741
|
-
if (buf.name && !buf.emittedStart) {
|
|
742
|
-
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
743
|
-
buf.emittedStart = true;
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
continue;
|
|
748
|
-
}
|
|
749
|
-
if (t === "response.function_call_arguments.delta") {
|
|
750
|
-
const callId = resolveCallId(evt);
|
|
751
|
-
const delta = evt.delta ?? "";
|
|
752
|
-
if (!callId || !delta) continue;
|
|
753
|
-
let buf = toolBuffers.get(callId);
|
|
754
|
-
if (!buf) {
|
|
755
|
-
buf = { id: callId, name: "", arguments: "", emittedStart: false };
|
|
756
|
-
toolBuffers.set(callId, buf);
|
|
757
|
-
}
|
|
758
|
-
buf.arguments += delta;
|
|
759
|
-
if (buf.emittedStart) {
|
|
760
|
-
yield {
|
|
761
|
-
type: "action:args",
|
|
762
|
-
id: buf.id,
|
|
763
|
-
args: buf.arguments
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
continue;
|
|
767
|
-
}
|
|
768
|
-
if (t === "response.output_item.done") {
|
|
769
|
-
const item = evt.item;
|
|
770
|
-
if (item?.type === "function_call") {
|
|
771
|
-
const callId = item.call_id ?? item.id ?? "";
|
|
772
|
-
const buf = toolBuffers.get(callId);
|
|
773
|
-
const name = buf?.name || item.name || "";
|
|
774
|
-
const argsStr = buf?.arguments || item.arguments || "{}";
|
|
775
|
-
if (callId && name) {
|
|
776
|
-
if (!buf?.emittedStart) {
|
|
777
|
-
yield { type: "action:start", id: callId, name };
|
|
778
|
-
}
|
|
779
|
-
yield {
|
|
780
|
-
type: "action:args",
|
|
781
|
-
id: callId,
|
|
782
|
-
args: argsStr
|
|
783
|
-
};
|
|
784
|
-
yield {
|
|
785
|
-
type: "action:end",
|
|
786
|
-
id: callId,
|
|
787
|
-
name
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
|
-
toolBuffers.delete(callId);
|
|
791
|
-
}
|
|
792
|
-
continue;
|
|
793
|
-
}
|
|
794
|
-
if (t === "response.completed") {
|
|
795
|
-
const u = evt.response?.usage;
|
|
796
|
-
if (u) {
|
|
797
|
-
usage = {
|
|
798
|
-
prompt_tokens: u.input_tokens ?? 0,
|
|
799
|
-
completion_tokens: u.output_tokens ?? 0,
|
|
800
|
-
total_tokens: u.total_tokens ?? (u.input_tokens ?? 0) + (u.output_tokens ?? 0)
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
for (const buf of toolBuffers.values()) {
|
|
804
|
-
if (!buf.id || !buf.name) continue;
|
|
805
|
-
if (!buf.emittedStart) {
|
|
806
|
-
yield { type: "action:start", id: buf.id, name: buf.name };
|
|
807
|
-
}
|
|
808
|
-
yield {
|
|
809
|
-
type: "action:args",
|
|
810
|
-
id: buf.id,
|
|
811
|
-
args: buf.arguments || "{}"
|
|
812
|
-
};
|
|
813
|
-
yield { type: "action:end", id: buf.id, name: buf.name };
|
|
814
|
-
}
|
|
815
|
-
toolBuffers.clear();
|
|
816
|
-
if (reasoningStarted && !textStarted) {
|
|
817
|
-
yield { type: "thinking:end" };
|
|
818
|
-
}
|
|
819
|
-
yield { type: "message:end" };
|
|
820
|
-
yield { type: "done", usage };
|
|
821
|
-
finishEmitted = true;
|
|
822
|
-
continue;
|
|
823
|
-
}
|
|
824
|
-
if (t === "response.error" || t === "error") {
|
|
825
|
-
const msg = evt.error?.message || evt.message || "Responses API error";
|
|
826
|
-
yield {
|
|
827
|
-
type: "error",
|
|
828
|
-
message: msg,
|
|
829
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
830
|
-
};
|
|
831
|
-
return;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
} catch (error) {
|
|
835
|
-
yield {
|
|
836
|
-
type: "error",
|
|
837
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
838
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
839
|
-
};
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
if (!finishEmitted) {
|
|
843
|
-
if (reasoningStarted && !textStarted) {
|
|
844
|
-
yield { type: "thinking:end" };
|
|
845
|
-
}
|
|
846
|
-
yield { type: "message:end" };
|
|
847
|
-
yield { type: "done", usage };
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
628
|
async completeWithResponses(request) {
|
|
851
629
|
const client = await this.getClient();
|
|
852
630
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
631
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
632
|
+
request.config?.responseFormat
|
|
633
|
+
);
|
|
853
634
|
const payload = {
|
|
854
635
|
model: request.config?.model || this.model,
|
|
855
636
|
instructions: request.systemPrompt,
|
|
@@ -859,6 +640,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
859
640
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
860
641
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
861
642
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
643
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
862
644
|
stream: false
|
|
863
645
|
};
|
|
864
646
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -953,7 +735,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
953
735
|
messages = processedMessages;
|
|
954
736
|
}
|
|
955
737
|
} else {
|
|
956
|
-
messages =
|
|
738
|
+
messages = formatMessagesForOpenAI(
|
|
957
739
|
request.messages,
|
|
958
740
|
request.systemPrompt
|
|
959
741
|
);
|
|
@@ -980,37 +762,21 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
980
762
|
name: openaiToolOptions.toolChoice.name
|
|
981
763
|
}
|
|
982
764
|
} : openaiToolOptions?.toolChoice;
|
|
983
|
-
const
|
|
984
|
-
const activeModel = request.config?.model || this.model;
|
|
985
|
-
const modelSlug = activeModel.replace("openai/", "");
|
|
986
|
-
const isOSeries = /^o[1-9]/.test(modelSlug);
|
|
987
|
-
const isOpenAIOnOpenRouter = isOpenRouter && activeModel.startsWith("openai/");
|
|
988
|
-
if (!this.config.disableThinking && this.isOpenAIReasoningModelOnOpenRouter(activeModel)) {
|
|
989
|
-
yield* this.streamWithResponsesAPI(request, activeModel, messageId);
|
|
990
|
-
return;
|
|
991
|
-
}
|
|
992
|
-
const maxTokensValue = request.config?.maxTokens ?? this.config.maxTokens;
|
|
765
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
993
766
|
const payload = {
|
|
994
|
-
model:
|
|
767
|
+
model: modelIdForPayload,
|
|
995
768
|
messages,
|
|
996
769
|
tools: tools.length > 0 ? tools : void 0,
|
|
997
770
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
998
771
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
772
|
+
...buildOpenAITokenParams(
|
|
773
|
+
modelIdForPayload,
|
|
774
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
775
|
+
request.config?.temperature ?? this.config.temperature
|
|
776
|
+
),
|
|
777
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
999
778
|
stream: true,
|
|
1000
|
-
stream_options: { include_usage: true }
|
|
1001
|
-
// o-series: use max_completion_tokens + reasoning_effort, no temperature
|
|
1002
|
-
// regular models: use max_tokens + temperature
|
|
1003
|
-
...isOSeries ? {
|
|
1004
|
-
max_completion_tokens: maxTokensValue,
|
|
1005
|
-
reasoning_effort: request.config?.reasoningEffort ?? "medium"
|
|
1006
|
-
} : {
|
|
1007
|
-
temperature: request.config?.temperature ?? this.config.temperature,
|
|
1008
|
-
max_tokens: maxTokensValue
|
|
1009
|
-
},
|
|
1010
|
-
// Non-OpenAI OpenRouter models support OR's reasoning/include_reasoning params.
|
|
1011
|
-
// When disableThinking=true we must explicitly send include_reasoning:false because
|
|
1012
|
-
// models like Qwen3 and DeepSeek-R1 reason by default even without the reasoning param.
|
|
1013
|
-
...isOpenRouter && !isOpenAIOnOpenRouter ? this.config.disableThinking ? { include_reasoning: false } : { reasoning: { max_tokens: 8e3 }, include_reasoning: true } : {}
|
|
779
|
+
stream_options: { include_usage: true }
|
|
1014
780
|
};
|
|
1015
781
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1016
782
|
const stream = await client.chat.completions.create(payload);
|
|
@@ -1018,7 +784,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1018
784
|
const collectedCitations = [];
|
|
1019
785
|
let citationIndex = 0;
|
|
1020
786
|
let usage;
|
|
1021
|
-
let adapterReasoningStarted = false;
|
|
1022
787
|
for await (const chunk of stream) {
|
|
1023
788
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
1024
789
|
if (request.signal?.aborted) {
|
|
@@ -1029,22 +794,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1029
794
|
if (delta?.content) {
|
|
1030
795
|
yield { type: "message:delta", content: delta.content };
|
|
1031
796
|
}
|
|
1032
|
-
if (isOpenRouter) {
|
|
1033
|
-
const rc = delta?.reasoning_content ?? delta?.reasoning ?? null;
|
|
1034
|
-
if (rc) {
|
|
1035
|
-
const rcText = typeof rc === "string" ? rc : Array.isArray(rc) && rc[0]?.text ? rc[0].text : "";
|
|
1036
|
-
if (rcText) {
|
|
1037
|
-
if (!adapterReasoningStarted) {
|
|
1038
|
-
yield { type: "thinking:start" };
|
|
1039
|
-
adapterReasoningStarted = true;
|
|
1040
|
-
}
|
|
1041
|
-
yield { type: "thinking:delta", content: rcText };
|
|
1042
|
-
}
|
|
1043
|
-
} else if (adapterReasoningStarted && (delta?.content || choice?.finish_reason)) {
|
|
1044
|
-
yield { type: "thinking:end" };
|
|
1045
|
-
adapterReasoningStarted = false;
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
797
|
const annotations = delta?.annotations;
|
|
1049
798
|
if (annotations && annotations.length > 0) {
|
|
1050
799
|
for (const annotation of annotations) {
|
|
@@ -1092,11 +841,6 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1092
841
|
};
|
|
1093
842
|
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
1094
843
|
currentToolCall.arguments += toolCall.function.arguments;
|
|
1095
|
-
yield {
|
|
1096
|
-
type: "action:args",
|
|
1097
|
-
id: currentToolCall.id,
|
|
1098
|
-
args: currentToolCall.arguments
|
|
1099
|
-
};
|
|
1100
844
|
}
|
|
1101
845
|
}
|
|
1102
846
|
}
|
|
@@ -1159,7 +903,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1159
903
|
messages = sanitized;
|
|
1160
904
|
}
|
|
1161
905
|
} else {
|
|
1162
|
-
messages =
|
|
906
|
+
messages = formatMessagesForOpenAI(
|
|
1163
907
|
request.messages,
|
|
1164
908
|
request.systemPrompt
|
|
1165
909
|
);
|
|
@@ -1172,24 +916,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1172
916
|
name: openaiToolOptions.toolChoice.name
|
|
1173
917
|
}
|
|
1174
918
|
} : openaiToolOptions?.toolChoice;
|
|
1175
|
-
const
|
|
1176
|
-
const modelSlug2 = activeModel2.replace("openai/", "");
|
|
1177
|
-
const isOSeries2 = /^o[1-9]/.test(modelSlug2);
|
|
1178
|
-
const maxTokensValue2 = request.config?.maxTokens ?? this.config.maxTokens;
|
|
919
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
1179
920
|
const payload = {
|
|
1180
|
-
model:
|
|
921
|
+
model: modelIdForCompletePayload,
|
|
1181
922
|
messages,
|
|
1182
923
|
tools: tools.length > 0 ? tools : void 0,
|
|
1183
924
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1184
925
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
}
|
|
926
|
+
...buildOpenAITokenParams(
|
|
927
|
+
modelIdForCompletePayload,
|
|
928
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
929
|
+
request.config?.temperature ?? this.config.temperature
|
|
930
|
+
),
|
|
931
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
932
|
+
stream: false
|
|
1193
933
|
};
|
|
1194
934
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1195
935
|
const response = await client.chat.completions.create(payload);
|