@yourgpt/llm-sdk 2.5.0 → 2.5.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/dist/adapters/index.d.mts +4 -4
- package/dist/adapters/index.d.ts +4 -4
- package/dist/adapters/index.js +293 -23
- package/dist/adapters/index.mjs +293 -23
- package/dist/base-BYQKp9TW.d.mts +263 -0
- package/dist/base-Cxq3ni0t.d.ts +263 -0
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/index.d.mts +61 -8
- package/dist/index.d.ts +61 -8
- package/dist/index.js +71 -0
- package/dist/index.mjs +71 -0
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +360 -203
- package/dist/providers/anthropic/index.mjs +360 -203
- 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 +303 -207
- package/dist/providers/google/index.mjs +303 -207
- 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 +318 -216
- package/dist/providers/openai/index.mjs +318 -216
- package/dist/providers/openrouter/index.d.mts +3 -3
- package/dist/providers/openrouter/index.d.ts +3 -3
- package/dist/providers/openrouter/index.js +308 -206
- package/dist/providers/openrouter/index.mjs +308 -206
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +308 -206
- package/dist/providers/togetherai/index.mjs +308 -206
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +307 -210
- package/dist/providers/xai/index.mjs +307 -210
- package/dist/{types-BctsnC3g.d.ts → types-BvkiJ1dd.d.mts} +2 -1
- package/dist/{types-38yolWJn.d.ts → types-ChORafYS.d.ts} +1 -1
- package/dist/types-D774b0dg.d.mts +1018 -0
- package/dist/types-D774b0dg.d.ts +1018 -0
- package/dist/{types-DRqxMIjF.d.mts → types-TMilS-Dz.d.ts} +2 -1
- package/dist/{types-D4YfrQJR.d.mts → types-mwMhCwOq.d.mts} +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/base-D-U61JaB.d.mts +0 -788
- package/dist/base-iGi9Va6Z.d.ts +0 -788
- package/dist/types-CR8mi9I0.d.mts +0 -417
- package/dist/types-CR8mi9I0.d.ts +0 -417
|
@@ -1,3 +1,259 @@
|
|
|
1
|
+
// src/adapters/base.ts
|
|
2
|
+
function stringifyForDebug(value) {
|
|
3
|
+
return JSON.stringify(
|
|
4
|
+
value,
|
|
5
|
+
(_key, currentValue) => {
|
|
6
|
+
if (typeof currentValue === "bigint") {
|
|
7
|
+
return currentValue.toString();
|
|
8
|
+
}
|
|
9
|
+
if (currentValue instanceof Error) {
|
|
10
|
+
return {
|
|
11
|
+
name: currentValue.name,
|
|
12
|
+
message: currentValue.message,
|
|
13
|
+
stack: currentValue.stack
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return currentValue;
|
|
17
|
+
},
|
|
18
|
+
2
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
function logProviderPayload(provider, label, payload, enabled) {
|
|
22
|
+
if (!enabled) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (label.toLowerCase().includes("stream ")) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
console.log(
|
|
30
|
+
`[llm-sdk:${provider}] ${label}
|
|
31
|
+
${stringifyForDebug(payload)}`
|
|
32
|
+
);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.log(
|
|
35
|
+
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
36
|
+
error
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function parameterToJsonSchema(param) {
|
|
41
|
+
const schema = {
|
|
42
|
+
type: param.type
|
|
43
|
+
};
|
|
44
|
+
if (param.description) {
|
|
45
|
+
schema.description = param.description;
|
|
46
|
+
}
|
|
47
|
+
if (param.enum) {
|
|
48
|
+
schema.enum = param.enum;
|
|
49
|
+
}
|
|
50
|
+
if (param.type === "array" && param.items) {
|
|
51
|
+
schema.items = parameterToJsonSchema(
|
|
52
|
+
param.items
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (param.type === "object" && param.properties) {
|
|
56
|
+
schema.properties = Object.fromEntries(
|
|
57
|
+
Object.entries(param.properties).map(([key, prop]) => [
|
|
58
|
+
key,
|
|
59
|
+
parameterToJsonSchema(
|
|
60
|
+
prop
|
|
61
|
+
)
|
|
62
|
+
])
|
|
63
|
+
);
|
|
64
|
+
schema.additionalProperties = false;
|
|
65
|
+
}
|
|
66
|
+
return schema;
|
|
67
|
+
}
|
|
68
|
+
function normalizeObjectJsonSchema(schema) {
|
|
69
|
+
if (!schema || typeof schema !== "object") {
|
|
70
|
+
return {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {},
|
|
73
|
+
required: [],
|
|
74
|
+
additionalProperties: false
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const normalized = { ...schema };
|
|
78
|
+
const type = normalized.type;
|
|
79
|
+
if (type === "object") {
|
|
80
|
+
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
81
|
+
normalized.properties = Object.fromEntries(
|
|
82
|
+
Object.entries(properties).map(([key, value]) => [
|
|
83
|
+
key,
|
|
84
|
+
normalizeObjectJsonSchema(value)
|
|
85
|
+
])
|
|
86
|
+
);
|
|
87
|
+
const propertyKeys = Object.keys(properties);
|
|
88
|
+
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
89
|
+
(value) => typeof value === "string"
|
|
90
|
+
) : [];
|
|
91
|
+
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
92
|
+
if (normalized.additionalProperties === void 0) {
|
|
93
|
+
normalized.additionalProperties = false;
|
|
94
|
+
}
|
|
95
|
+
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
96
|
+
normalized.items = normalizeObjectJsonSchema(
|
|
97
|
+
normalized.items
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return normalized;
|
|
101
|
+
}
|
|
102
|
+
function isOpenAIReasoningModel(modelId) {
|
|
103
|
+
if (!modelId) return false;
|
|
104
|
+
return /^(o1|o3|o4|gpt-5)/i.test(modelId);
|
|
105
|
+
}
|
|
106
|
+
function buildOpenAITokenParams(modelId, maxTokens, temperature) {
|
|
107
|
+
if (isOpenAIReasoningModel(modelId)) {
|
|
108
|
+
return { max_completion_tokens: maxTokens };
|
|
109
|
+
}
|
|
110
|
+
return { max_tokens: maxTokens, temperature };
|
|
111
|
+
}
|
|
112
|
+
function toOpenAIResponseFormat(rf) {
|
|
113
|
+
if (!rf) return void 0;
|
|
114
|
+
if (rf.type === "json_object") return { type: "json_object" };
|
|
115
|
+
return {
|
|
116
|
+
type: "json_schema",
|
|
117
|
+
json_schema: {
|
|
118
|
+
name: rf.json_schema.name,
|
|
119
|
+
schema: normalizeObjectJsonSchema(rf.json_schema.schema),
|
|
120
|
+
strict: rf.json_schema.strict ?? true
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function toOpenAIResponsesTextFormat(rf) {
|
|
125
|
+
if (!rf || rf.type !== "json_schema") return void 0;
|
|
126
|
+
return {
|
|
127
|
+
type: "json_schema",
|
|
128
|
+
name: rf.json_schema.name,
|
|
129
|
+
schema: normalizeObjectJsonSchema(rf.json_schema.schema),
|
|
130
|
+
strict: rf.json_schema.strict ?? true
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function toOpenAIResponsesMcpTools(mcpServers) {
|
|
134
|
+
if (!mcpServers || mcpServers.length === 0) return [];
|
|
135
|
+
return mcpServers.map((mcp) => ({
|
|
136
|
+
type: "mcp",
|
|
137
|
+
server_label: mcp.label,
|
|
138
|
+
server_url: mcp.url,
|
|
139
|
+
...mcp.headers ? { headers: mcp.headers } : {},
|
|
140
|
+
...mcp.allowedTools ? { allowed_tools: mcp.allowedTools } : {},
|
|
141
|
+
require_approval: mcp.requireApproval ?? "never"
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
function isStringEffort(effort) {
|
|
145
|
+
return typeof effort === "string" && (effort === "minimal" || effort === "low" || effort === "medium" || effort === "high");
|
|
146
|
+
}
|
|
147
|
+
function toOpenAIReasoning(effort) {
|
|
148
|
+
if (!effort) return void 0;
|
|
149
|
+
if (typeof effort === "object" && "raw" in effort) return effort.raw;
|
|
150
|
+
if (typeof effort === "object" && "budgetTokens" in effort) {
|
|
151
|
+
const budget = effort.budgetTokens;
|
|
152
|
+
const mapped = budget >= 16e3 ? "high" : budget >= 8e3 ? "medium" : "low";
|
|
153
|
+
return { effort: mapped, summary: "auto" };
|
|
154
|
+
}
|
|
155
|
+
if (isStringEffort(effort)) {
|
|
156
|
+
return { effort, summary: "auto" };
|
|
157
|
+
}
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
function formatTools(actions) {
|
|
161
|
+
return actions.map((action) => ({
|
|
162
|
+
type: "function",
|
|
163
|
+
function: {
|
|
164
|
+
name: action.name,
|
|
165
|
+
description: action.description,
|
|
166
|
+
parameters: {
|
|
167
|
+
type: "object",
|
|
168
|
+
properties: action.parameters ? Object.fromEntries(
|
|
169
|
+
Object.entries(action.parameters).map(([key, param]) => [
|
|
170
|
+
key,
|
|
171
|
+
parameterToJsonSchema(param)
|
|
172
|
+
])
|
|
173
|
+
) : {},
|
|
174
|
+
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
175
|
+
additionalProperties: false
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
function hasImageAttachments(message) {
|
|
181
|
+
const attachments = message.metadata?.attachments;
|
|
182
|
+
return attachments?.some((a) => a.type === "image") ?? false;
|
|
183
|
+
}
|
|
184
|
+
function attachmentToOpenAIImage(attachment) {
|
|
185
|
+
if (attachment.type !== "image") return null;
|
|
186
|
+
let imageUrl;
|
|
187
|
+
if (attachment.url) {
|
|
188
|
+
imageUrl = attachment.url;
|
|
189
|
+
} else if (attachment.data) {
|
|
190
|
+
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
191
|
+
} else {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
type: "image_url",
|
|
196
|
+
image_url: {
|
|
197
|
+
url: imageUrl,
|
|
198
|
+
detail: "auto"
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function messageToOpenAIContent(message) {
|
|
203
|
+
const attachments = message.metadata?.attachments;
|
|
204
|
+
const content = message.content ?? "";
|
|
205
|
+
if (!hasImageAttachments(message)) {
|
|
206
|
+
return content;
|
|
207
|
+
}
|
|
208
|
+
const blocks = [];
|
|
209
|
+
if (content) {
|
|
210
|
+
blocks.push({ type: "text", text: content });
|
|
211
|
+
}
|
|
212
|
+
if (attachments) {
|
|
213
|
+
for (const attachment of attachments) {
|
|
214
|
+
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
215
|
+
if (imageBlock) {
|
|
216
|
+
blocks.push(imageBlock);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return blocks;
|
|
221
|
+
}
|
|
222
|
+
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
223
|
+
const formatted = [];
|
|
224
|
+
if (systemPrompt) {
|
|
225
|
+
formatted.push({ role: "system", content: systemPrompt });
|
|
226
|
+
}
|
|
227
|
+
for (const msg of messages) {
|
|
228
|
+
if (msg.role === "system") {
|
|
229
|
+
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
230
|
+
} else if (msg.role === "user") {
|
|
231
|
+
formatted.push({
|
|
232
|
+
role: "user",
|
|
233
|
+
content: messageToOpenAIContent(msg)
|
|
234
|
+
});
|
|
235
|
+
} else if (msg.role === "assistant") {
|
|
236
|
+
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
237
|
+
const assistantMsg = {
|
|
238
|
+
role: "assistant",
|
|
239
|
+
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
240
|
+
content: hasToolCalls ? msg.content || null : msg.content
|
|
241
|
+
};
|
|
242
|
+
if (hasToolCalls) {
|
|
243
|
+
assistantMsg.tool_calls = msg.tool_calls;
|
|
244
|
+
}
|
|
245
|
+
formatted.push(assistantMsg);
|
|
246
|
+
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
247
|
+
formatted.push({
|
|
248
|
+
role: "tool",
|
|
249
|
+
content: msg.content ?? "",
|
|
250
|
+
tool_call_id: msg.tool_call_id
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return formatted;
|
|
255
|
+
}
|
|
256
|
+
|
|
1
257
|
// src/providers/openrouter/provider.ts
|
|
2
258
|
var DEFAULT_MODEL_CONFIG = {
|
|
3
259
|
vision: true,
|
|
@@ -56,6 +312,10 @@ function openrouter(modelId, options = {}) {
|
|
|
56
312
|
if (options.providerPreferences) {
|
|
57
313
|
requestBody.provider = options.providerPreferences;
|
|
58
314
|
}
|
|
315
|
+
const responseFormat = toOpenAIResponseFormat(params.responseFormat);
|
|
316
|
+
if (responseFormat) {
|
|
317
|
+
requestBody.response_format = responseFormat;
|
|
318
|
+
}
|
|
59
319
|
const response = await client2.chat.completions.create(requestBody);
|
|
60
320
|
const choice = response.choices[0];
|
|
61
321
|
const message = choice.message;
|
|
@@ -94,6 +354,10 @@ function openrouter(modelId, options = {}) {
|
|
|
94
354
|
if (options.providerPreferences) {
|
|
95
355
|
requestBody.provider = options.providerPreferences;
|
|
96
356
|
}
|
|
357
|
+
const responseFormat = toOpenAIResponseFormat(params.responseFormat);
|
|
358
|
+
if (responseFormat) {
|
|
359
|
+
requestBody.response_format = responseFormat;
|
|
360
|
+
}
|
|
97
361
|
const stream = await client2.chat.completions.create(requestBody);
|
|
98
362
|
let currentToolCall = null;
|
|
99
363
|
let totalPromptTokens = 0;
|
|
@@ -261,204 +525,6 @@ function generateToolCallId() {
|
|
|
261
525
|
return generateId("call");
|
|
262
526
|
}
|
|
263
527
|
|
|
264
|
-
// src/adapters/base.ts
|
|
265
|
-
function stringifyForDebug(value) {
|
|
266
|
-
return JSON.stringify(
|
|
267
|
-
value,
|
|
268
|
-
(_key, currentValue) => {
|
|
269
|
-
if (typeof currentValue === "bigint") {
|
|
270
|
-
return currentValue.toString();
|
|
271
|
-
}
|
|
272
|
-
if (currentValue instanceof Error) {
|
|
273
|
-
return {
|
|
274
|
-
name: currentValue.name,
|
|
275
|
-
message: currentValue.message,
|
|
276
|
-
stack: currentValue.stack
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
return currentValue;
|
|
280
|
-
},
|
|
281
|
-
2
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
285
|
-
if (!enabled) {
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
try {
|
|
292
|
-
console.log(
|
|
293
|
-
`[llm-sdk:${provider}] ${label}
|
|
294
|
-
${stringifyForDebug(payload)}`
|
|
295
|
-
);
|
|
296
|
-
} catch (error) {
|
|
297
|
-
console.log(
|
|
298
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
299
|
-
error
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
function parameterToJsonSchema(param) {
|
|
304
|
-
const schema = {
|
|
305
|
-
type: param.type
|
|
306
|
-
};
|
|
307
|
-
if (param.description) {
|
|
308
|
-
schema.description = param.description;
|
|
309
|
-
}
|
|
310
|
-
if (param.enum) {
|
|
311
|
-
schema.enum = param.enum;
|
|
312
|
-
}
|
|
313
|
-
if (param.type === "array" && param.items) {
|
|
314
|
-
schema.items = parameterToJsonSchema(
|
|
315
|
-
param.items
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
if (param.type === "object" && param.properties) {
|
|
319
|
-
schema.properties = Object.fromEntries(
|
|
320
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
321
|
-
key,
|
|
322
|
-
parameterToJsonSchema(
|
|
323
|
-
prop
|
|
324
|
-
)
|
|
325
|
-
])
|
|
326
|
-
);
|
|
327
|
-
schema.additionalProperties = false;
|
|
328
|
-
}
|
|
329
|
-
return schema;
|
|
330
|
-
}
|
|
331
|
-
function normalizeObjectJsonSchema(schema) {
|
|
332
|
-
if (!schema || typeof schema !== "object") {
|
|
333
|
-
return {
|
|
334
|
-
type: "object",
|
|
335
|
-
properties: {},
|
|
336
|
-
required: [],
|
|
337
|
-
additionalProperties: false
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
const normalized = { ...schema };
|
|
341
|
-
const type = normalized.type;
|
|
342
|
-
if (type === "object") {
|
|
343
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
344
|
-
normalized.properties = Object.fromEntries(
|
|
345
|
-
Object.entries(properties).map(([key, value]) => [
|
|
346
|
-
key,
|
|
347
|
-
normalizeObjectJsonSchema(value)
|
|
348
|
-
])
|
|
349
|
-
);
|
|
350
|
-
const propertyKeys = Object.keys(properties);
|
|
351
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
352
|
-
(value) => typeof value === "string"
|
|
353
|
-
) : [];
|
|
354
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
355
|
-
if (normalized.additionalProperties === void 0) {
|
|
356
|
-
normalized.additionalProperties = false;
|
|
357
|
-
}
|
|
358
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
359
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
360
|
-
normalized.items
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
return normalized;
|
|
364
|
-
}
|
|
365
|
-
function formatTools(actions) {
|
|
366
|
-
return actions.map((action) => ({
|
|
367
|
-
type: "function",
|
|
368
|
-
function: {
|
|
369
|
-
name: action.name,
|
|
370
|
-
description: action.description,
|
|
371
|
-
parameters: {
|
|
372
|
-
type: "object",
|
|
373
|
-
properties: action.parameters ? Object.fromEntries(
|
|
374
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
375
|
-
key,
|
|
376
|
-
parameterToJsonSchema(param)
|
|
377
|
-
])
|
|
378
|
-
) : {},
|
|
379
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
380
|
-
additionalProperties: false
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}));
|
|
384
|
-
}
|
|
385
|
-
function hasImageAttachments(message) {
|
|
386
|
-
const attachments = message.metadata?.attachments;
|
|
387
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
388
|
-
}
|
|
389
|
-
function attachmentToOpenAIImage(attachment) {
|
|
390
|
-
if (attachment.type !== "image") return null;
|
|
391
|
-
let imageUrl;
|
|
392
|
-
if (attachment.url) {
|
|
393
|
-
imageUrl = attachment.url;
|
|
394
|
-
} else if (attachment.data) {
|
|
395
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
396
|
-
} else {
|
|
397
|
-
return null;
|
|
398
|
-
}
|
|
399
|
-
return {
|
|
400
|
-
type: "image_url",
|
|
401
|
-
image_url: {
|
|
402
|
-
url: imageUrl,
|
|
403
|
-
detail: "auto"
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
function messageToOpenAIContent(message) {
|
|
408
|
-
const attachments = message.metadata?.attachments;
|
|
409
|
-
const content = message.content ?? "";
|
|
410
|
-
if (!hasImageAttachments(message)) {
|
|
411
|
-
return content;
|
|
412
|
-
}
|
|
413
|
-
const blocks = [];
|
|
414
|
-
if (content) {
|
|
415
|
-
blocks.push({ type: "text", text: content });
|
|
416
|
-
}
|
|
417
|
-
if (attachments) {
|
|
418
|
-
for (const attachment of attachments) {
|
|
419
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
420
|
-
if (imageBlock) {
|
|
421
|
-
blocks.push(imageBlock);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
return blocks;
|
|
426
|
-
}
|
|
427
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
428
|
-
const formatted = [];
|
|
429
|
-
if (systemPrompt) {
|
|
430
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
431
|
-
}
|
|
432
|
-
for (const msg of messages) {
|
|
433
|
-
if (msg.role === "system") {
|
|
434
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
435
|
-
} else if (msg.role === "user") {
|
|
436
|
-
formatted.push({
|
|
437
|
-
role: "user",
|
|
438
|
-
content: messageToOpenAIContent(msg)
|
|
439
|
-
});
|
|
440
|
-
} else if (msg.role === "assistant") {
|
|
441
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
442
|
-
const assistantMsg = {
|
|
443
|
-
role: "assistant",
|
|
444
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
445
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
446
|
-
};
|
|
447
|
-
if (hasToolCalls) {
|
|
448
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
449
|
-
}
|
|
450
|
-
formatted.push(assistantMsg);
|
|
451
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
452
|
-
formatted.push({
|
|
453
|
-
role: "tool",
|
|
454
|
-
content: msg.content ?? "",
|
|
455
|
-
tool_call_id: msg.tool_call_id
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
return formatted;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
528
|
// src/adapters/openai.ts
|
|
463
529
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
464
530
|
constructor(config) {
|
|
@@ -484,6 +550,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
484
550
|
return this.client;
|
|
485
551
|
}
|
|
486
552
|
shouldUseResponsesApi(request) {
|
|
553
|
+
if (request.config?.mcpServers && request.config.mcpServers.length > 0 || request.config?.reasoningEffort !== void 0) {
|
|
554
|
+
if (this.provider !== "openai" && this.provider !== "azure") {
|
|
555
|
+
throw new Error(
|
|
556
|
+
`[llm-sdk] Provider "${this.provider}" does not support MCP servers or per-request reasoning effort. Use OpenAI or Anthropic for these features.`
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
487
561
|
return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
|
|
488
562
|
}
|
|
489
563
|
buildResponsesInput(request) {
|
|
@@ -544,7 +618,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
544
618
|
strict: true,
|
|
545
619
|
defer_loading: tool.deferLoading === true
|
|
546
620
|
}));
|
|
547
|
-
return [{ type: "tool_search" }, ...nativeTools];
|
|
621
|
+
return nativeTools.length > 0 ? [{ type: "tool_search" }, ...nativeTools] : [];
|
|
548
622
|
}
|
|
549
623
|
parseResponsesResult(response) {
|
|
550
624
|
const content = typeof response?.output_text === "string" ? response.output_text : "";
|
|
@@ -573,15 +647,33 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
573
647
|
async completeWithResponses(request) {
|
|
574
648
|
const client = await this.getClient();
|
|
575
649
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
650
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
651
|
+
request.config?.responseFormat
|
|
652
|
+
);
|
|
653
|
+
const mcpTools = toOpenAIResponsesMcpTools(request.config?.mcpServers);
|
|
654
|
+
const modelId = request.config?.model || this.model;
|
|
655
|
+
const reasoning = isOpenAIReasoningModel(modelId) ? toOpenAIReasoning(request.config?.reasoningEffort) : void 0;
|
|
656
|
+
if (request.config?.reasoningEffort && !isOpenAIReasoningModel(modelId)) {
|
|
657
|
+
console.warn(
|
|
658
|
+
`[llm-sdk] openai/${modelId} is not a reasoning model; \`reasoningEffort\` is ignored. Use o1/o3/o4/gpt-5.x for reasoning.`
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
const functionTools = this.buildResponsesTools(
|
|
662
|
+
request.toolDefinitions ?? []
|
|
663
|
+
);
|
|
664
|
+
const tools = [...functionTools, ...mcpTools];
|
|
576
665
|
const payload = {
|
|
577
666
|
model: request.config?.model || this.model,
|
|
578
667
|
instructions: request.systemPrompt,
|
|
579
668
|
input: this.buildResponsesInput(request),
|
|
580
|
-
tools:
|
|
669
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
581
670
|
tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
|
|
582
671
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
583
672
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
584
673
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
674
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
675
|
+
...reasoning ? { reasoning } : {},
|
|
676
|
+
store: false,
|
|
585
677
|
stream: false
|
|
586
678
|
};
|
|
587
679
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -703,14 +795,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
703
795
|
name: openaiToolOptions.toolChoice.name
|
|
704
796
|
}
|
|
705
797
|
} : openaiToolOptions?.toolChoice;
|
|
798
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
706
799
|
const payload = {
|
|
707
|
-
model:
|
|
800
|
+
model: modelIdForPayload,
|
|
708
801
|
messages,
|
|
709
802
|
tools: tools.length > 0 ? tools : void 0,
|
|
710
803
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
711
804
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
712
|
-
|
|
713
|
-
|
|
805
|
+
...buildOpenAITokenParams(
|
|
806
|
+
modelIdForPayload,
|
|
807
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
808
|
+
request.config?.temperature ?? this.config.temperature
|
|
809
|
+
),
|
|
810
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
714
811
|
stream: true,
|
|
715
812
|
stream_options: { include_usage: true }
|
|
716
813
|
};
|
|
@@ -852,14 +949,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
852
949
|
name: openaiToolOptions.toolChoice.name
|
|
853
950
|
}
|
|
854
951
|
} : openaiToolOptions?.toolChoice;
|
|
952
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
855
953
|
const payload = {
|
|
856
|
-
model:
|
|
954
|
+
model: modelIdForCompletePayload,
|
|
857
955
|
messages,
|
|
858
956
|
tools: tools.length > 0 ? tools : void 0,
|
|
859
957
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
860
958
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
861
|
-
|
|
862
|
-
|
|
959
|
+
...buildOpenAITokenParams(
|
|
960
|
+
modelIdForCompletePayload,
|
|
961
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
962
|
+
request.config?.temperature ?? this.config.temperature
|
|
963
|
+
),
|
|
964
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
863
965
|
stream: false
|
|
864
966
|
};
|
|
865
967
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D774b0dg.mjs';
|
|
2
|
+
import { A as AIProvider } from '../../types-BvkiJ1dd.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-BYQKp9TW.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Together AI Provider
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D774b0dg.js';
|
|
2
|
+
import { A as AIProvider } from '../../types-TMilS-Dz.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-Cxq3ni0t.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Together AI Provider
|