@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/togetherai/provider.ts
|
|
2
258
|
function togetherai(modelId, options = {}) {
|
|
3
259
|
const apiKey = options.apiKey ?? process.env.TOGETHER_API_KEY;
|
|
@@ -40,6 +296,10 @@ function togetherai(modelId, options = {}) {
|
|
|
40
296
|
if (params.tools) {
|
|
41
297
|
requestBody.tools = params.tools;
|
|
42
298
|
}
|
|
299
|
+
const responseFormat = toOpenAIResponseFormat(params.responseFormat);
|
|
300
|
+
if (responseFormat) {
|
|
301
|
+
requestBody.response_format = responseFormat;
|
|
302
|
+
}
|
|
43
303
|
const response = await client2.chat.completions.create(requestBody);
|
|
44
304
|
const choice = response.choices[0];
|
|
45
305
|
const message = choice.message;
|
|
@@ -75,6 +335,10 @@ function togetherai(modelId, options = {}) {
|
|
|
75
335
|
if (params.tools) {
|
|
76
336
|
requestBody.tools = params.tools;
|
|
77
337
|
}
|
|
338
|
+
const responseFormat = toOpenAIResponseFormat(params.responseFormat);
|
|
339
|
+
if (responseFormat) {
|
|
340
|
+
requestBody.response_format = responseFormat;
|
|
341
|
+
}
|
|
78
342
|
const stream = await client2.chat.completions.create(requestBody);
|
|
79
343
|
const toolCallMap = /* @__PURE__ */ new Map();
|
|
80
344
|
let totalPromptTokens = 0;
|
|
@@ -213,204 +477,6 @@ function generateToolCallId() {
|
|
|
213
477
|
return generateId("call");
|
|
214
478
|
}
|
|
215
479
|
|
|
216
|
-
// src/adapters/base.ts
|
|
217
|
-
function stringifyForDebug(value) {
|
|
218
|
-
return JSON.stringify(
|
|
219
|
-
value,
|
|
220
|
-
(_key, currentValue) => {
|
|
221
|
-
if (typeof currentValue === "bigint") {
|
|
222
|
-
return currentValue.toString();
|
|
223
|
-
}
|
|
224
|
-
if (currentValue instanceof Error) {
|
|
225
|
-
return {
|
|
226
|
-
name: currentValue.name,
|
|
227
|
-
message: currentValue.message,
|
|
228
|
-
stack: currentValue.stack
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
return currentValue;
|
|
232
|
-
},
|
|
233
|
-
2
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
237
|
-
if (!enabled) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
try {
|
|
244
|
-
console.log(
|
|
245
|
-
`[llm-sdk:${provider}] ${label}
|
|
246
|
-
${stringifyForDebug(payload)}`
|
|
247
|
-
);
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.log(
|
|
250
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
251
|
-
error
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
function parameterToJsonSchema(param) {
|
|
256
|
-
const schema = {
|
|
257
|
-
type: param.type
|
|
258
|
-
};
|
|
259
|
-
if (param.description) {
|
|
260
|
-
schema.description = param.description;
|
|
261
|
-
}
|
|
262
|
-
if (param.enum) {
|
|
263
|
-
schema.enum = param.enum;
|
|
264
|
-
}
|
|
265
|
-
if (param.type === "array" && param.items) {
|
|
266
|
-
schema.items = parameterToJsonSchema(
|
|
267
|
-
param.items
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
if (param.type === "object" && param.properties) {
|
|
271
|
-
schema.properties = Object.fromEntries(
|
|
272
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
273
|
-
key,
|
|
274
|
-
parameterToJsonSchema(
|
|
275
|
-
prop
|
|
276
|
-
)
|
|
277
|
-
])
|
|
278
|
-
);
|
|
279
|
-
schema.additionalProperties = false;
|
|
280
|
-
}
|
|
281
|
-
return schema;
|
|
282
|
-
}
|
|
283
|
-
function normalizeObjectJsonSchema(schema) {
|
|
284
|
-
if (!schema || typeof schema !== "object") {
|
|
285
|
-
return {
|
|
286
|
-
type: "object",
|
|
287
|
-
properties: {},
|
|
288
|
-
required: [],
|
|
289
|
-
additionalProperties: false
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
const normalized = { ...schema };
|
|
293
|
-
const type = normalized.type;
|
|
294
|
-
if (type === "object") {
|
|
295
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
296
|
-
normalized.properties = Object.fromEntries(
|
|
297
|
-
Object.entries(properties).map(([key, value]) => [
|
|
298
|
-
key,
|
|
299
|
-
normalizeObjectJsonSchema(value)
|
|
300
|
-
])
|
|
301
|
-
);
|
|
302
|
-
const propertyKeys = Object.keys(properties);
|
|
303
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
304
|
-
(value) => typeof value === "string"
|
|
305
|
-
) : [];
|
|
306
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
307
|
-
if (normalized.additionalProperties === void 0) {
|
|
308
|
-
normalized.additionalProperties = false;
|
|
309
|
-
}
|
|
310
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
311
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
312
|
-
normalized.items
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
return normalized;
|
|
316
|
-
}
|
|
317
|
-
function formatTools(actions) {
|
|
318
|
-
return actions.map((action) => ({
|
|
319
|
-
type: "function",
|
|
320
|
-
function: {
|
|
321
|
-
name: action.name,
|
|
322
|
-
description: action.description,
|
|
323
|
-
parameters: {
|
|
324
|
-
type: "object",
|
|
325
|
-
properties: action.parameters ? Object.fromEntries(
|
|
326
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
327
|
-
key,
|
|
328
|
-
parameterToJsonSchema(param)
|
|
329
|
-
])
|
|
330
|
-
) : {},
|
|
331
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
332
|
-
additionalProperties: false
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}));
|
|
336
|
-
}
|
|
337
|
-
function hasImageAttachments(message) {
|
|
338
|
-
const attachments = message.metadata?.attachments;
|
|
339
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
340
|
-
}
|
|
341
|
-
function attachmentToOpenAIImage(attachment) {
|
|
342
|
-
if (attachment.type !== "image") return null;
|
|
343
|
-
let imageUrl;
|
|
344
|
-
if (attachment.url) {
|
|
345
|
-
imageUrl = attachment.url;
|
|
346
|
-
} else if (attachment.data) {
|
|
347
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
348
|
-
} else {
|
|
349
|
-
return null;
|
|
350
|
-
}
|
|
351
|
-
return {
|
|
352
|
-
type: "image_url",
|
|
353
|
-
image_url: {
|
|
354
|
-
url: imageUrl,
|
|
355
|
-
detail: "auto"
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
function messageToOpenAIContent(message) {
|
|
360
|
-
const attachments = message.metadata?.attachments;
|
|
361
|
-
const content = message.content ?? "";
|
|
362
|
-
if (!hasImageAttachments(message)) {
|
|
363
|
-
return content;
|
|
364
|
-
}
|
|
365
|
-
const blocks = [];
|
|
366
|
-
if (content) {
|
|
367
|
-
blocks.push({ type: "text", text: content });
|
|
368
|
-
}
|
|
369
|
-
if (attachments) {
|
|
370
|
-
for (const attachment of attachments) {
|
|
371
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
372
|
-
if (imageBlock) {
|
|
373
|
-
blocks.push(imageBlock);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return blocks;
|
|
378
|
-
}
|
|
379
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
380
|
-
const formatted = [];
|
|
381
|
-
if (systemPrompt) {
|
|
382
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
383
|
-
}
|
|
384
|
-
for (const msg of messages) {
|
|
385
|
-
if (msg.role === "system") {
|
|
386
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
387
|
-
} else if (msg.role === "user") {
|
|
388
|
-
formatted.push({
|
|
389
|
-
role: "user",
|
|
390
|
-
content: messageToOpenAIContent(msg)
|
|
391
|
-
});
|
|
392
|
-
} else if (msg.role === "assistant") {
|
|
393
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
394
|
-
const assistantMsg = {
|
|
395
|
-
role: "assistant",
|
|
396
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
397
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
398
|
-
};
|
|
399
|
-
if (hasToolCalls) {
|
|
400
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
401
|
-
}
|
|
402
|
-
formatted.push(assistantMsg);
|
|
403
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
404
|
-
formatted.push({
|
|
405
|
-
role: "tool",
|
|
406
|
-
content: msg.content ?? "",
|
|
407
|
-
tool_call_id: msg.tool_call_id
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return formatted;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
480
|
// src/adapters/openai.ts
|
|
415
481
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
416
482
|
constructor(config) {
|
|
@@ -436,6 +502,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
436
502
|
return this.client;
|
|
437
503
|
}
|
|
438
504
|
shouldUseResponsesApi(request) {
|
|
505
|
+
if (request.config?.mcpServers && request.config.mcpServers.length > 0 || request.config?.reasoningEffort !== void 0) {
|
|
506
|
+
if (this.provider !== "openai" && this.provider !== "azure") {
|
|
507
|
+
throw new Error(
|
|
508
|
+
`[llm-sdk] Provider "${this.provider}" does not support MCP servers or per-request reasoning effort. Use OpenAI or Anthropic for these features.`
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
439
513
|
return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
|
|
440
514
|
}
|
|
441
515
|
buildResponsesInput(request) {
|
|
@@ -496,7 +570,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
496
570
|
strict: true,
|
|
497
571
|
defer_loading: tool.deferLoading === true
|
|
498
572
|
}));
|
|
499
|
-
return [{ type: "tool_search" }, ...nativeTools];
|
|
573
|
+
return nativeTools.length > 0 ? [{ type: "tool_search" }, ...nativeTools] : [];
|
|
500
574
|
}
|
|
501
575
|
parseResponsesResult(response) {
|
|
502
576
|
const content = typeof response?.output_text === "string" ? response.output_text : "";
|
|
@@ -525,15 +599,33 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
525
599
|
async completeWithResponses(request) {
|
|
526
600
|
const client = await this.getClient();
|
|
527
601
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
602
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
603
|
+
request.config?.responseFormat
|
|
604
|
+
);
|
|
605
|
+
const mcpTools = toOpenAIResponsesMcpTools(request.config?.mcpServers);
|
|
606
|
+
const modelId = request.config?.model || this.model;
|
|
607
|
+
const reasoning = isOpenAIReasoningModel(modelId) ? toOpenAIReasoning(request.config?.reasoningEffort) : void 0;
|
|
608
|
+
if (request.config?.reasoningEffort && !isOpenAIReasoningModel(modelId)) {
|
|
609
|
+
console.warn(
|
|
610
|
+
`[llm-sdk] openai/${modelId} is not a reasoning model; \`reasoningEffort\` is ignored. Use o1/o3/o4/gpt-5.x for reasoning.`
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
const functionTools = this.buildResponsesTools(
|
|
614
|
+
request.toolDefinitions ?? []
|
|
615
|
+
);
|
|
616
|
+
const tools = [...functionTools, ...mcpTools];
|
|
528
617
|
const payload = {
|
|
529
618
|
model: request.config?.model || this.model,
|
|
530
619
|
instructions: request.systemPrompt,
|
|
531
620
|
input: this.buildResponsesInput(request),
|
|
532
|
-
tools:
|
|
621
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
533
622
|
tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
|
|
534
623
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
535
624
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
536
625
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
626
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
627
|
+
...reasoning ? { reasoning } : {},
|
|
628
|
+
store: false,
|
|
537
629
|
stream: false
|
|
538
630
|
};
|
|
539
631
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -655,14 +747,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
655
747
|
name: openaiToolOptions.toolChoice.name
|
|
656
748
|
}
|
|
657
749
|
} : openaiToolOptions?.toolChoice;
|
|
750
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
658
751
|
const payload = {
|
|
659
|
-
model:
|
|
752
|
+
model: modelIdForPayload,
|
|
660
753
|
messages,
|
|
661
754
|
tools: tools.length > 0 ? tools : void 0,
|
|
662
755
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
663
756
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
664
|
-
|
|
665
|
-
|
|
757
|
+
...buildOpenAITokenParams(
|
|
758
|
+
modelIdForPayload,
|
|
759
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
760
|
+
request.config?.temperature ?? this.config.temperature
|
|
761
|
+
),
|
|
762
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
666
763
|
stream: true,
|
|
667
764
|
stream_options: { include_usage: true }
|
|
668
765
|
};
|
|
@@ -804,14 +901,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
804
901
|
name: openaiToolOptions.toolChoice.name
|
|
805
902
|
}
|
|
806
903
|
} : openaiToolOptions?.toolChoice;
|
|
904
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
807
905
|
const payload = {
|
|
808
|
-
model:
|
|
906
|
+
model: modelIdForCompletePayload,
|
|
809
907
|
messages,
|
|
810
908
|
tools: tools.length > 0 ? tools : void 0,
|
|
811
909
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
812
910
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
813
|
-
|
|
814
|
-
|
|
911
|
+
...buildOpenAITokenParams(
|
|
912
|
+
modelIdForCompletePayload,
|
|
913
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
914
|
+
request.config?.temperature ?? this.config.temperature
|
|
915
|
+
),
|
|
916
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
815
917
|
stream: false
|
|
816
918
|
};
|
|
817
919
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D774b0dg.mjs';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D774b0dg.js';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|