@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/google/provider.ts
|
|
2
258
|
var GOOGLE_MODELS = {
|
|
3
259
|
// Gemini 2.5 (Experimental)
|
|
@@ -117,7 +373,8 @@ function google(modelId, options = {}) {
|
|
|
117
373
|
messages,
|
|
118
374
|
tools: params.tools,
|
|
119
375
|
temperature: params.temperature,
|
|
120
|
-
max_tokens: params.maxTokens
|
|
376
|
+
max_tokens: params.maxTokens,
|
|
377
|
+
response_format: toOpenAIResponseFormat(params.responseFormat)
|
|
121
378
|
});
|
|
122
379
|
const choice = response.choices[0];
|
|
123
380
|
const message = choice.message;
|
|
@@ -149,6 +406,7 @@ function google(modelId, options = {}) {
|
|
|
149
406
|
tools: params.tools,
|
|
150
407
|
temperature: params.temperature,
|
|
151
408
|
max_tokens: params.maxTokens,
|
|
409
|
+
response_format: toOpenAIResponseFormat(params.responseFormat),
|
|
152
410
|
stream: true
|
|
153
411
|
});
|
|
154
412
|
let currentToolCall = null;
|
|
@@ -294,204 +552,6 @@ function generateToolCallId() {
|
|
|
294
552
|
return generateId("call");
|
|
295
553
|
}
|
|
296
554
|
|
|
297
|
-
// src/adapters/base.ts
|
|
298
|
-
function stringifyForDebug(value) {
|
|
299
|
-
return JSON.stringify(
|
|
300
|
-
value,
|
|
301
|
-
(_key, currentValue) => {
|
|
302
|
-
if (typeof currentValue === "bigint") {
|
|
303
|
-
return currentValue.toString();
|
|
304
|
-
}
|
|
305
|
-
if (currentValue instanceof Error) {
|
|
306
|
-
return {
|
|
307
|
-
name: currentValue.name,
|
|
308
|
-
message: currentValue.message,
|
|
309
|
-
stack: currentValue.stack
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
return currentValue;
|
|
313
|
-
},
|
|
314
|
-
2
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
function logProviderPayload(provider, label, payload, enabled) {
|
|
318
|
-
if (!enabled) {
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
if (label.toLowerCase().includes("stream ")) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
try {
|
|
325
|
-
console.log(
|
|
326
|
-
`[llm-sdk:${provider}] ${label}
|
|
327
|
-
${stringifyForDebug(payload)}`
|
|
328
|
-
);
|
|
329
|
-
} catch (error) {
|
|
330
|
-
console.log(
|
|
331
|
-
`[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
|
|
332
|
-
error
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function parameterToJsonSchema(param) {
|
|
337
|
-
const schema = {
|
|
338
|
-
type: param.type
|
|
339
|
-
};
|
|
340
|
-
if (param.description) {
|
|
341
|
-
schema.description = param.description;
|
|
342
|
-
}
|
|
343
|
-
if (param.enum) {
|
|
344
|
-
schema.enum = param.enum;
|
|
345
|
-
}
|
|
346
|
-
if (param.type === "array" && param.items) {
|
|
347
|
-
schema.items = parameterToJsonSchema(
|
|
348
|
-
param.items
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
if (param.type === "object" && param.properties) {
|
|
352
|
-
schema.properties = Object.fromEntries(
|
|
353
|
-
Object.entries(param.properties).map(([key, prop]) => [
|
|
354
|
-
key,
|
|
355
|
-
parameterToJsonSchema(
|
|
356
|
-
prop
|
|
357
|
-
)
|
|
358
|
-
])
|
|
359
|
-
);
|
|
360
|
-
schema.additionalProperties = false;
|
|
361
|
-
}
|
|
362
|
-
return schema;
|
|
363
|
-
}
|
|
364
|
-
function normalizeObjectJsonSchema(schema) {
|
|
365
|
-
if (!schema || typeof schema !== "object") {
|
|
366
|
-
return {
|
|
367
|
-
type: "object",
|
|
368
|
-
properties: {},
|
|
369
|
-
required: [],
|
|
370
|
-
additionalProperties: false
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
const normalized = { ...schema };
|
|
374
|
-
const type = normalized.type;
|
|
375
|
-
if (type === "object") {
|
|
376
|
-
const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
|
|
377
|
-
normalized.properties = Object.fromEntries(
|
|
378
|
-
Object.entries(properties).map(([key, value]) => [
|
|
379
|
-
key,
|
|
380
|
-
normalizeObjectJsonSchema(value)
|
|
381
|
-
])
|
|
382
|
-
);
|
|
383
|
-
const propertyKeys = Object.keys(properties);
|
|
384
|
-
const required = Array.isArray(normalized.required) ? normalized.required.filter(
|
|
385
|
-
(value) => typeof value === "string"
|
|
386
|
-
) : [];
|
|
387
|
-
normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
|
|
388
|
-
if (normalized.additionalProperties === void 0) {
|
|
389
|
-
normalized.additionalProperties = false;
|
|
390
|
-
}
|
|
391
|
-
} else if (type === "array" && normalized.items && typeof normalized.items === "object") {
|
|
392
|
-
normalized.items = normalizeObjectJsonSchema(
|
|
393
|
-
normalized.items
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
|
-
return normalized;
|
|
397
|
-
}
|
|
398
|
-
function formatTools(actions) {
|
|
399
|
-
return actions.map((action) => ({
|
|
400
|
-
type: "function",
|
|
401
|
-
function: {
|
|
402
|
-
name: action.name,
|
|
403
|
-
description: action.description,
|
|
404
|
-
parameters: {
|
|
405
|
-
type: "object",
|
|
406
|
-
properties: action.parameters ? Object.fromEntries(
|
|
407
|
-
Object.entries(action.parameters).map(([key, param]) => [
|
|
408
|
-
key,
|
|
409
|
-
parameterToJsonSchema(param)
|
|
410
|
-
])
|
|
411
|
-
) : {},
|
|
412
|
-
required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
|
|
413
|
-
additionalProperties: false
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
}));
|
|
417
|
-
}
|
|
418
|
-
function hasImageAttachments(message) {
|
|
419
|
-
const attachments = message.metadata?.attachments;
|
|
420
|
-
return attachments?.some((a) => a.type === "image") ?? false;
|
|
421
|
-
}
|
|
422
|
-
function attachmentToOpenAIImage(attachment) {
|
|
423
|
-
if (attachment.type !== "image") return null;
|
|
424
|
-
let imageUrl;
|
|
425
|
-
if (attachment.url) {
|
|
426
|
-
imageUrl = attachment.url;
|
|
427
|
-
} else if (attachment.data) {
|
|
428
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
429
|
-
} else {
|
|
430
|
-
return null;
|
|
431
|
-
}
|
|
432
|
-
return {
|
|
433
|
-
type: "image_url",
|
|
434
|
-
image_url: {
|
|
435
|
-
url: imageUrl,
|
|
436
|
-
detail: "auto"
|
|
437
|
-
}
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
function messageToOpenAIContent(message) {
|
|
441
|
-
const attachments = message.metadata?.attachments;
|
|
442
|
-
const content = message.content ?? "";
|
|
443
|
-
if (!hasImageAttachments(message)) {
|
|
444
|
-
return content;
|
|
445
|
-
}
|
|
446
|
-
const blocks = [];
|
|
447
|
-
if (content) {
|
|
448
|
-
blocks.push({ type: "text", text: content });
|
|
449
|
-
}
|
|
450
|
-
if (attachments) {
|
|
451
|
-
for (const attachment of attachments) {
|
|
452
|
-
const imageBlock = attachmentToOpenAIImage(attachment);
|
|
453
|
-
if (imageBlock) {
|
|
454
|
-
blocks.push(imageBlock);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
return blocks;
|
|
459
|
-
}
|
|
460
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
461
|
-
const formatted = [];
|
|
462
|
-
if (systemPrompt) {
|
|
463
|
-
formatted.push({ role: "system", content: systemPrompt });
|
|
464
|
-
}
|
|
465
|
-
for (const msg of messages) {
|
|
466
|
-
if (msg.role === "system") {
|
|
467
|
-
formatted.push({ role: "system", content: msg.content ?? "" });
|
|
468
|
-
} else if (msg.role === "user") {
|
|
469
|
-
formatted.push({
|
|
470
|
-
role: "user",
|
|
471
|
-
content: messageToOpenAIContent(msg)
|
|
472
|
-
});
|
|
473
|
-
} else if (msg.role === "assistant") {
|
|
474
|
-
const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
|
|
475
|
-
const assistantMsg = {
|
|
476
|
-
role: "assistant",
|
|
477
|
-
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
478
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
479
|
-
};
|
|
480
|
-
if (hasToolCalls) {
|
|
481
|
-
assistantMsg.tool_calls = msg.tool_calls;
|
|
482
|
-
}
|
|
483
|
-
formatted.push(assistantMsg);
|
|
484
|
-
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
485
|
-
formatted.push({
|
|
486
|
-
role: "tool",
|
|
487
|
-
content: msg.content ?? "",
|
|
488
|
-
tool_call_id: msg.tool_call_id
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return formatted;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
555
|
// src/adapters/openai.ts
|
|
496
556
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
497
557
|
constructor(config) {
|
|
@@ -517,6 +577,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
517
577
|
return this.client;
|
|
518
578
|
}
|
|
519
579
|
shouldUseResponsesApi(request) {
|
|
580
|
+
if (request.config?.mcpServers && request.config.mcpServers.length > 0 || request.config?.reasoningEffort !== void 0) {
|
|
581
|
+
if (this.provider !== "openai" && this.provider !== "azure") {
|
|
582
|
+
throw new Error(
|
|
583
|
+
`[llm-sdk] Provider "${this.provider}" does not support MCP servers or per-request reasoning effort. Use OpenAI or Anthropic for these features.`
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
520
588
|
return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
|
|
521
589
|
}
|
|
522
590
|
buildResponsesInput(request) {
|
|
@@ -577,7 +645,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
577
645
|
strict: true,
|
|
578
646
|
defer_loading: tool.deferLoading === true
|
|
579
647
|
}));
|
|
580
|
-
return [{ type: "tool_search" }, ...nativeTools];
|
|
648
|
+
return nativeTools.length > 0 ? [{ type: "tool_search" }, ...nativeTools] : [];
|
|
581
649
|
}
|
|
582
650
|
parseResponsesResult(response) {
|
|
583
651
|
const content = typeof response?.output_text === "string" ? response.output_text : "";
|
|
@@ -606,15 +674,33 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
606
674
|
async completeWithResponses(request) {
|
|
607
675
|
const client = await this.getClient();
|
|
608
676
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
677
|
+
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
678
|
+
request.config?.responseFormat
|
|
679
|
+
);
|
|
680
|
+
const mcpTools = toOpenAIResponsesMcpTools(request.config?.mcpServers);
|
|
681
|
+
const modelId = request.config?.model || this.model;
|
|
682
|
+
const reasoning = isOpenAIReasoningModel(modelId) ? toOpenAIReasoning(request.config?.reasoningEffort) : void 0;
|
|
683
|
+
if (request.config?.reasoningEffort && !isOpenAIReasoningModel(modelId)) {
|
|
684
|
+
console.warn(
|
|
685
|
+
`[llm-sdk] openai/${modelId} is not a reasoning model; \`reasoningEffort\` is ignored. Use o1/o3/o4/gpt-5.x for reasoning.`
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
const functionTools = this.buildResponsesTools(
|
|
689
|
+
request.toolDefinitions ?? []
|
|
690
|
+
);
|
|
691
|
+
const tools = [...functionTools, ...mcpTools];
|
|
609
692
|
const payload = {
|
|
610
693
|
model: request.config?.model || this.model,
|
|
611
694
|
instructions: request.systemPrompt,
|
|
612
695
|
input: this.buildResponsesInput(request),
|
|
613
|
-
tools:
|
|
696
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
614
697
|
tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
|
|
615
698
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
616
699
|
temperature: request.config?.temperature ?? this.config.temperature,
|
|
617
700
|
max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
|
|
701
|
+
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
702
|
+
...reasoning ? { reasoning } : {},
|
|
703
|
+
store: false,
|
|
618
704
|
stream: false
|
|
619
705
|
};
|
|
620
706
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -736,14 +822,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
736
822
|
name: openaiToolOptions.toolChoice.name
|
|
737
823
|
}
|
|
738
824
|
} : openaiToolOptions?.toolChoice;
|
|
825
|
+
const modelIdForPayload = request.config?.model || this.model;
|
|
739
826
|
const payload = {
|
|
740
|
-
model:
|
|
827
|
+
model: modelIdForPayload,
|
|
741
828
|
messages,
|
|
742
829
|
tools: tools.length > 0 ? tools : void 0,
|
|
743
830
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
744
831
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
745
|
-
|
|
746
|
-
|
|
832
|
+
...buildOpenAITokenParams(
|
|
833
|
+
modelIdForPayload,
|
|
834
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
835
|
+
request.config?.temperature ?? this.config.temperature
|
|
836
|
+
),
|
|
837
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
747
838
|
stream: true,
|
|
748
839
|
stream_options: { include_usage: true }
|
|
749
840
|
};
|
|
@@ -885,14 +976,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
885
976
|
name: openaiToolOptions.toolChoice.name
|
|
886
977
|
}
|
|
887
978
|
} : openaiToolOptions?.toolChoice;
|
|
979
|
+
const modelIdForCompletePayload = request.config?.model || this.model;
|
|
888
980
|
const payload = {
|
|
889
|
-
model:
|
|
981
|
+
model: modelIdForCompletePayload,
|
|
890
982
|
messages,
|
|
891
983
|
tools: tools.length > 0 ? tools : void 0,
|
|
892
984
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
893
985
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
894
|
-
|
|
895
|
-
|
|
986
|
+
...buildOpenAITokenParams(
|
|
987
|
+
modelIdForCompletePayload,
|
|
988
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
989
|
+
request.config?.temperature ?? this.config.temperature
|
|
990
|
+
),
|
|
991
|
+
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
896
992
|
stream: false
|
|
897
993
|
};
|
|
898
994
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
export { d as OllamaModelOptions } from '../../types-
|
|
3
|
-
import '../../
|
|
4
|
-
import '../../types-CR8mi9I0.mjs';
|
|
1
|
+
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BvkiJ1dd.mjs';
|
|
2
|
+
export { d as OllamaModelOptions } from '../../types-BvkiJ1dd.mjs';
|
|
3
|
+
import '../../types-D774b0dg.mjs';
|
|
5
4
|
import 'zod';
|
|
5
|
+
import '../../base-BYQKp9TW.mjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Ollama Provider
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
export { d as OllamaModelOptions } from '../../types-
|
|
3
|
-
import '../../
|
|
4
|
-
import '../../types-CR8mi9I0.js';
|
|
1
|
+
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-TMilS-Dz.js';
|
|
2
|
+
export { d as OllamaModelOptions } from '../../types-TMilS-Dz.js';
|
|
3
|
+
import '../../types-D774b0dg.js';
|
|
5
4
|
import 'zod';
|
|
5
|
+
import '../../base-Cxq3ni0t.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Ollama Provider
|
|
@@ -78,6 +78,11 @@ function parameterToJsonSchema(param) {
|
|
|
78
78
|
}
|
|
79
79
|
return schema;
|
|
80
80
|
}
|
|
81
|
+
function toOllamaFormat(rf) {
|
|
82
|
+
if (!rf) return void 0;
|
|
83
|
+
if (rf.type === "json_object") return "json";
|
|
84
|
+
return rf.json_schema.schema;
|
|
85
|
+
}
|
|
81
86
|
function formatTools(actions) {
|
|
82
87
|
return actions.map((action) => ({
|
|
83
88
|
type: "function",
|
|
@@ -240,12 +245,14 @@ var OllamaAdapter = class {
|
|
|
240
245
|
if (this.config.options) {
|
|
241
246
|
Object.assign(ollamaOptions, this.config.options);
|
|
242
247
|
}
|
|
248
|
+
const ollamaFormat = toOllamaFormat(request.config?.responseFormat);
|
|
243
249
|
const payload = {
|
|
244
250
|
model: request.config?.model || this.model,
|
|
245
251
|
messages,
|
|
246
252
|
tools,
|
|
247
253
|
stream: true,
|
|
248
|
-
options: ollamaOptions
|
|
254
|
+
options: ollamaOptions,
|
|
255
|
+
...ollamaFormat !== void 0 ? { format: ollamaFormat } : {}
|
|
249
256
|
};
|
|
250
257
|
logProviderPayload("ollama", "request payload", payload, request.debug);
|
|
251
258
|
const response = await fetch(`${this.baseUrl}/api/chat`, {
|
|
@@ -496,7 +503,8 @@ function createOllama(config = {}) {
|
|
|
496
503
|
supportsVideo: false,
|
|
497
504
|
maxTokens: model.maxTokens,
|
|
498
505
|
supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif"] : [],
|
|
499
|
-
|
|
506
|
+
// Ollama 0.5+ supports `format: "json"` and JSON-schema constrained output.
|
|
507
|
+
supportsJsonMode: true,
|
|
500
508
|
supportsSystemMessages: true
|
|
501
509
|
};
|
|
502
510
|
};
|
|
@@ -76,6 +76,11 @@ function parameterToJsonSchema(param) {
|
|
|
76
76
|
}
|
|
77
77
|
return schema;
|
|
78
78
|
}
|
|
79
|
+
function toOllamaFormat(rf) {
|
|
80
|
+
if (!rf) return void 0;
|
|
81
|
+
if (rf.type === "json_object") return "json";
|
|
82
|
+
return rf.json_schema.schema;
|
|
83
|
+
}
|
|
79
84
|
function formatTools(actions) {
|
|
80
85
|
return actions.map((action) => ({
|
|
81
86
|
type: "function",
|
|
@@ -238,12 +243,14 @@ var OllamaAdapter = class {
|
|
|
238
243
|
if (this.config.options) {
|
|
239
244
|
Object.assign(ollamaOptions, this.config.options);
|
|
240
245
|
}
|
|
246
|
+
const ollamaFormat = toOllamaFormat(request.config?.responseFormat);
|
|
241
247
|
const payload = {
|
|
242
248
|
model: request.config?.model || this.model,
|
|
243
249
|
messages,
|
|
244
250
|
tools,
|
|
245
251
|
stream: true,
|
|
246
|
-
options: ollamaOptions
|
|
252
|
+
options: ollamaOptions,
|
|
253
|
+
...ollamaFormat !== void 0 ? { format: ollamaFormat } : {}
|
|
247
254
|
};
|
|
248
255
|
logProviderPayload("ollama", "request payload", payload, request.debug);
|
|
249
256
|
const response = await fetch(`${this.baseUrl}/api/chat`, {
|
|
@@ -494,7 +501,8 @@ function createOllama(config = {}) {
|
|
|
494
501
|
supportsVideo: false,
|
|
495
502
|
maxTokens: model.maxTokens,
|
|
496
503
|
supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif"] : [],
|
|
497
|
-
|
|
504
|
+
// Ollama 0.5+ supports `format: "json"` and JSON-schema constrained output.
|
|
505
|
+
supportsJsonMode: true,
|
|
498
506
|
supportsSystemMessages: true
|
|
499
507
|
};
|
|
500
508
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D774b0dg.mjs';
|
|
2
|
+
import { O as OpenAIProviderConfig, 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
|
* OpenAI Provider - Modern Pattern
|