@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/xai/provider.ts
|
|
2
258
|
var XAI_MODELS = {
|
|
3
259
|
// Grok 4.1 Fast (Latest - December 2025)
|
|
@@ -51,8 +307,8 @@ function xai(modelId, options = {}) {
|
|
|
51
307
|
supportsVision: modelConfig.vision,
|
|
52
308
|
supportsTools: modelConfig.tools,
|
|
53
309
|
supportsStreaming: true,
|
|
54
|
-
supportsJsonMode:
|
|
55
|
-
//
|
|
310
|
+
supportsJsonMode: true,
|
|
311
|
+
// OpenAI-compatible `response_format`
|
|
56
312
|
supportsThinking: false,
|
|
57
313
|
supportsPDF: false,
|
|
58
314
|
maxTokens: modelConfig.maxTokens,
|
|
@@ -66,7 +322,8 @@ function xai(modelId, options = {}) {
|
|
|
66
322
|
messages,
|
|
67
323
|
tools: params.tools,
|
|
68
324
|
temperature: params.temperature,
|
|
69
|
-
max_tokens: params.maxTokens
|
|
325
|
+
max_tokens: params.maxTokens,
|
|
326
|
+
response_format: toOpenAIResponseFormat(params.responseFormat)
|
|
70
327
|
});
|
|
71
328
|
const choice = response.choices[0];
|
|
72
329
|
const message = choice.message;
|
|
@@ -98,6 +355,7 @@ function xai(modelId, options = {}) {
|
|
|
98
355
|
tools: params.tools,
|
|
99
356
|
temperature: params.temperature,
|
|
100
357
|
max_tokens: params.maxTokens,
|
|
358
|
+
response_format: toOpenAIResponseFormat(params.responseFormat),
|
|
101
359
|
stream: true
|
|
102
360
|
});
|
|
103
361
|
let currentToolCall = null;
|
|
@@ -243,204 +501,6 @@ function generateToolCallId() {
|
|
|
243
501
|
return generateId("call");
|
|
244
502
|
}
|
|
245
503
|
|
|
246
|
-
// src/adapters/base.ts
|
|
247
|
-
function stringifyForDebug(value) {
|
|
248
|
-
return JSON.stringify(
|
|
249
|
-
value,
|
|
250
|
-
(_key, currentValue) => {
|
|
251
|
-
if (typeof currentValue === "bigint") {
|
|
252
|
-
return currentValue.toString();
|
|
253
|
-
}
|
|
254
|
-
if (currentValue instanceof Error) {
|
|
255
|
-
return {
|
|
256
|
-
name: currentValue.name,
|
|
257
|
-
message: currentValue.message,
|
|
258
|
-
stack: currentValue.stack
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
return currentValue;
|
|
262
|
-
},
|
|
263
|
-
2
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
267
|
-
if (!enabled) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
console.log(
|
|
275
|
-
`[llm-sdk:${provider}] ${label}
|
|
276
|
-
${stringifyForDebug(payload)}`
|
|
277
|
-
);
|
|
278
|
-
} catch (error) {
|
|
279
|
-
console.log(
|
|
280
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
281
|
-
error
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function parameterToJsonSchema(param) {
|
|
286
|
-
const schema = {
|
|
287
|
-
type: param.type
|
|
288
|
-
};
|
|
289
|
-
if (param.description) {
|
|
290
|
-
schema.description = param.description;
|
|
291
|
-
}
|
|
292
|
-
if (param.enum) {
|
|
293
|
-
schema.enum = param.enum;
|
|
294
|
-
}
|
|
295
|
-
if (param.type === "array" && param.items) {
|
|
296
|
-
schema.items = parameterToJsonSchema(
|
|
297
|
-
param.items
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
if (param.type === "object" && param.properties) {
|
|
301
|
-
schema.properties = Object.fromEntries(
|
|
302
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
303
|
-
key,
|
|
304
|
-
parameterToJsonSchema(
|
|
305
|
-
prop
|
|
306
|
-
)
|
|
307
|
-
])
|
|
308
|
-
);
|
|
309
|
-
schema.additionalProperties = false;
|
|
310
|
-
}
|
|
311
|
-
return schema;
|
|
312
|
-
}
|
|
313
|
-
function normalizeObjectJsonSchema(schema) {
|
|
314
|
-
if (!schema || typeof schema !== "object") {
|
|
315
|
-
return {
|
|
316
|
-
type: "object",
|
|
317
|
-
properties: {},
|
|
318
|
-
required: [],
|
|
319
|
-
additionalProperties: false
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
const normalized = { ...schema };
|
|
323
|
-
const type = normalized.type;
|
|
324
|
-
if (type === "object") {
|
|
325
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
326
|
-
normalized.properties = Object.fromEntries(
|
|
327
|
-
Object.entries(properties).map(([key, value]) => [
|
|
328
|
-
key,
|
|
329
|
-
normalizeObjectJsonSchema(value)
|
|
330
|
-
])
|
|
331
|
-
);
|
|
332
|
-
const propertyKeys = Object.keys(properties);
|
|
333
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
334
|
-
(value) => typeof value === "string"
|
|
335
|
-
) : [];
|
|
336
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
337
|
-
if (normalized.additionalProperties === void 0) {
|
|
338
|
-
normalized.additionalProperties = false;
|
|
339
|
-
}
|
|
340
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
341
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
342
|
-
normalized.items
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
return normalized;
|
|
346
|
-
}
|
|
347
|
-
function formatTools(actions) {
|
|
348
|
-
return actions.map((action) => ({
|
|
349
|
-
type: "function",
|
|
350
|
-
function: {
|
|
351
|
-
name: action.name,
|
|
352
|
-
description: action.description,
|
|
353
|
-
parameters: {
|
|
354
|
-
type: "object",
|
|
355
|
-
properties: action.parameters ? Object.fromEntries(
|
|
356
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
357
|
-
key,
|
|
358
|
-
parameterToJsonSchema(param)
|
|
359
|
-
])
|
|
360
|
-
) : {},
|
|
361
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
362
|
-
additionalProperties: false
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}));
|
|
366
|
-
}
|
|
367
|
-
function hasImageAttachments(message) {
|
|
368
|
-
const attachments = message.metadata?.attachments;
|
|
369
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
370
|
-
}
|
|
371
|
-
function attachmentToOpenAIImage(attachment) {
|
|
372
|
-
if (attachment.type !== "image") return null;
|
|
373
|
-
let imageUrl;
|
|
374
|
-
if (attachment.url) {
|
|
375
|
-
imageUrl = attachment.url;
|
|
376
|
-
} else if (attachment.data) {
|
|
377
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
378
|
-
} else {
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
|
-
return {
|
|
382
|
-
type: "image_url",
|
|
383
|
-
image_url: {
|
|
384
|
-
url: imageUrl,
|
|
385
|
-
detail: "auto"
|
|
386
|
-
}
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
function messageToOpenAIContent(message) {
|
|
390
|
-
const attachments = message.metadata?.attachments;
|
|
391
|
-
const content = message.content ?? "";
|
|
392
|
-
if (!hasImageAttachments(message)) {
|
|
393
|
-
return content;
|
|
394
|
-
}
|
|
395
|
-
const blocks = [];
|
|
396
|
-
if (content) {
|
|
397
|
-
blocks.push({ type: "text", text: content });
|
|
398
|
-
}
|
|
399
|
-
if (attachments) {
|
|
400
|
-
for (const attachment of attachments) {
|
|
401
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
402
|
-
if (imageBlock) {
|
|
403
|
-
blocks.push(imageBlock);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return blocks;
|
|
408
|
-
}
|
|
409
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
410
|
-
const formatted = [];
|
|
411
|
-
if (systemPrompt) {
|
|
412
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
413
|
-
}
|
|
414
|
-
for (const msg of messages) {
|
|
415
|
-
if (msg.role === "system") {
|
|
416
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
417
|
-
} else if (msg.role === "user") {
|
|
418
|
-
formatted.push({
|
|
419
|
-
role: "user",
|
|
420
|
-
content: messageToOpenAIContent(msg)
|
|
421
|
-
});
|
|
422
|
-
} else if (msg.role === "assistant") {
|
|
423
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
424
|
-
const assistantMsg = {
|
|
425
|
-
role: "assistant",
|
|
426
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
427
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
428
|
-
};
|
|
429
|
-
if (hasToolCalls) {
|
|
430
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
431
|
-
}
|
|
432
|
-
formatted.push(assistantMsg);
|
|
433
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
434
|
-
formatted.push({
|
|
435
|
-
role: "tool",
|
|
436
|
-
content: msg.content ?? "",
|
|
437
|
-
tool_call_id: msg.tool_call_id
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return formatted;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
504
|
// src/adapters/openai.ts
|
|
445
505
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
446
506
|
constructor(config) {
|
|
@@ -466,6 +526,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
466
526
|
return this.client;
|
|
467
527
|
}
|
|
468
528
|
shouldUseResponsesApi(request) {
|
|
529
|
+
if (request.config?.mcpServers && request.config.mcpServers.length > 0 || request.config?.reasoningEffort !== void 0) {
|
|
530
|
+
if (this.provider !== "openai" && this.provider !== "azure") {
|
|
531
|
+
throw new Error(
|
|
532
|
+
`[llm-sdk] Provider "${this.provider}" does not support MCP servers or per-request reasoning effort. Use OpenAI or Anthropic for these features.`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
469
537
|
return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
|
|
470
538
|
}
|
|
471
539
|
buildResponsesInput(request) {
|
|
@@ -526,7 +594,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
526
594
|
strict: true,
|
|
527
595
|
defer_loading: tool.deferLoading === true
|
|
528
596
|
}));
|
|
529
|
-
return [{ type: "tool_search" }, ...nativeTools];
|
|
597
|
+
return nativeTools.length > 0 ? [{ type: "tool_search" }, ...nativeTools] : [];
|
|
530
598
|
}
|
|
531
599
|
parseResponsesResult(response) {
|
|
532
600
|
const content = typeof response?.output_text === "string" ? response.output_text : "";
|
|
@@ -555,15 +623,33 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
555
623
|
async completeWithResponses(request) {
|
|
556
624
|
const client = await this.getClient();
|
|
557
625
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
626
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
627
|
+
request.config?.responseFormat
|
|
628
|
+
);
|
|
629
|
+
const mcpTools = toOpenAIResponsesMcpTools(request.config?.mcpServers);
|
|
630
|
+
const modelId = request.config?.model || this.model;
|
|
631
|
+
const reasoning = isOpenAIReasoningModel(modelId) ? toOpenAIReasoning(request.config?.reasoningEffort) : void 0;
|
|
632
|
+
if (request.config?.reasoningEffort && !isOpenAIReasoningModel(modelId)) {
|
|
633
|
+
console.warn(
|
|
634
|
+
`[llm-sdk] openai/${modelId} is not a reasoning model; \`reasoningEffort\` is ignored. Use o1/o3/o4/gpt-5.x for reasoning.`
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
const functionTools = this.buildResponsesTools(
|
|
638
|
+
request.toolDefinitions ?? []
|
|
639
|
+
);
|
|
640
|
+
const tools = [...functionTools, ...mcpTools];
|
|
558
641
|
const payload = {
|
|
559
642
|
model: request.config?.model || this.model,
|
|
560
643
|
instructions: request.systemPrompt,
|
|
561
644
|
input: this.buildResponsesInput(request),
|
|
562
|
-
tools:
|
|
645
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
563
646
|
tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
|
|
564
647
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
565
648
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
566
649
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
650
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
651
|
+
...reasoning ? { reasoning } : {},
|
|
652
|
+
store: false,
|
|
567
653
|
stream: false
|
|
568
654
|
};
|
|
569
655
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -685,14 +771,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
685
771
|
name: openaiToolOptions.toolChoice.name
|
|
686
772
|
}
|
|
687
773
|
} : openaiToolOptions?.toolChoice;
|
|
774
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
688
775
|
const payload = {
|
|
689
|
-
model:
|
|
776
|
+
model: modelIdForPayload,
|
|
690
777
|
messages,
|
|
691
778
|
tools: tools.length > 0 ? tools : void 0,
|
|
692
779
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
693
780
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
694
|
-
|
|
695
|
-
|
|
781
|
+
...buildOpenAITokenParams(
|
|
782
|
+
modelIdForPayload,
|
|
783
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
784
|
+
request.config?.temperature ?? this.config.temperature
|
|
785
|
+
),
|
|
786
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
696
787
|
stream: true,
|
|
697
788
|
stream_options: { include_usage: true }
|
|
698
789
|
};
|
|
@@ -834,14 +925,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
834
925
|
name: openaiToolOptions.toolChoice.name
|
|
835
926
|
}
|
|
836
927
|
} : openaiToolOptions?.toolChoice;
|
|
928
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
837
929
|
const payload = {
|
|
838
|
-
model:
|
|
930
|
+
model: modelIdForCompletePayload,
|
|
839
931
|
messages,
|
|
840
932
|
tools: tools.length > 0 ? tools : void 0,
|
|
841
933
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
842
934
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
843
|
-
|
|
844
|
-
|
|
935
|
+
...buildOpenAITokenParams(
|
|
936
|
+
modelIdForCompletePayload,
|
|
937
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
938
|
+
request.config?.temperature ?? this.config.temperature
|
|
939
|
+
),
|
|
940
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
845
941
|
stream: false
|
|
846
942
|
};
|
|
847
943
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -1037,7 +1133,8 @@ function createXAI(config = {}) {
|
|
|
1037
1133
|
supportsVideo: false,
|
|
1038
1134
|
maxTokens: model.maxTokens,
|
|
1039
1135
|
supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif", "image/webp"] : [],
|
|
1040
|
-
|
|
1136
|
+
// xAI accepts OpenAI-compatible `response_format` on grok-2-1212+.
|
|
1137
|
+
supportsJsonMode: true,
|
|
1041
1138
|
supportsSystemMessages: true
|
|
1042
1139
|
};
|
|
1043
1140
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as ToolDefinition, $ as UnifiedToolCall, a0 as UnifiedToolResult } from './types-D774b0dg.mjs';
|
|
2
|
+
import { L as LLMAdapter } from './base-BYQKp9TW.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Provider Types
|