@oai2lmapi/opencode-provider 0.3.11 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apiAdapters.d.ts +115 -0
- package/dist/apiAdapters.d.ts.map +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/clients/claudeClient.d.ts +135 -0
- package/dist/clients/claudeClient.d.ts.map +1 -0
- package/dist/clients/geminiClient.d.ts +128 -0
- package/dist/clients/geminiClient.d.ts.map +1 -0
- package/dist/clients/index.d.ts +8 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1048 -10
- package/dist/index.js.map +3 -3
- package/dist/plugin.js.map +1 -1
- package/oai2lm.schema.json +9 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2157,6 +2157,1031 @@ function wrapWithEnhancements(baseModel, modelId, override) {
|
|
|
2157
2157
|
return baseModel;
|
|
2158
2158
|
}
|
|
2159
2159
|
|
|
2160
|
+
// src/clients/geminiClient.ts
|
|
2161
|
+
var idCounter2 = 0;
|
|
2162
|
+
function generateId2() {
|
|
2163
|
+
return `gemini_${Date.now()}_${++idCounter2}`;
|
|
2164
|
+
}
|
|
2165
|
+
function normalizeGeminiEndpoint(endpoint) {
|
|
2166
|
+
let normalized = endpoint.replace(/\/+$/, "");
|
|
2167
|
+
if (normalized.endsWith("/v1")) {
|
|
2168
|
+
normalized = normalized.slice(0, -3);
|
|
2169
|
+
}
|
|
2170
|
+
return normalized;
|
|
2171
|
+
}
|
|
2172
|
+
function convertMessagesToGemini(messages) {
|
|
2173
|
+
const contents = [];
|
|
2174
|
+
let systemInstruction;
|
|
2175
|
+
for (const message of messages) {
|
|
2176
|
+
if (message.role === "system") {
|
|
2177
|
+
systemInstruction = (systemInstruction || "") + message.content;
|
|
2178
|
+
} else if (message.role === "user") {
|
|
2179
|
+
const parts = [];
|
|
2180
|
+
for (const part of message.content) {
|
|
2181
|
+
if (part.type === "text") {
|
|
2182
|
+
parts.push({ text: part.text });
|
|
2183
|
+
} else if (part.type === "file") {
|
|
2184
|
+
const filePart = part;
|
|
2185
|
+
if (filePart.mediaType.startsWith("image/")) {
|
|
2186
|
+
if (typeof filePart.data === "string") {
|
|
2187
|
+
if (filePart.data.startsWith("data:")) {
|
|
2188
|
+
const match = filePart.data.match(/^data:([^;]+);base64,(.+)$/);
|
|
2189
|
+
if (match) {
|
|
2190
|
+
parts.push({
|
|
2191
|
+
inlineData: {
|
|
2192
|
+
mimeType: match[1],
|
|
2193
|
+
data: match[2]
|
|
2194
|
+
}
|
|
2195
|
+
});
|
|
2196
|
+
}
|
|
2197
|
+
} else if (filePart.data.startsWith("http")) {
|
|
2198
|
+
parts.push({ text: `[Image URL: ${filePart.data}]` });
|
|
2199
|
+
} else {
|
|
2200
|
+
parts.push({
|
|
2201
|
+
inlineData: {
|
|
2202
|
+
mimeType: filePart.mediaType,
|
|
2203
|
+
data: filePart.data
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
} else if (filePart.data instanceof URL) {
|
|
2208
|
+
parts.push({ text: `[Image URL: ${filePart.data.toString()}]` });
|
|
2209
|
+
} else if (filePart.data instanceof Uint8Array) {
|
|
2210
|
+
const base64 = Buffer.from(filePart.data).toString("base64");
|
|
2211
|
+
parts.push({
|
|
2212
|
+
inlineData: {
|
|
2213
|
+
mimeType: filePart.mediaType,
|
|
2214
|
+
data: base64
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
if (parts.length > 0) {
|
|
2222
|
+
contents.push({ role: "user", parts });
|
|
2223
|
+
}
|
|
2224
|
+
} else if (message.role === "assistant") {
|
|
2225
|
+
const parts = [];
|
|
2226
|
+
for (const part of message.content) {
|
|
2227
|
+
if (part.type === "text") {
|
|
2228
|
+
parts.push({ text: part.text });
|
|
2229
|
+
} else if (part.type === "tool-call") {
|
|
2230
|
+
const input = part.input;
|
|
2231
|
+
parts.push({
|
|
2232
|
+
functionCall: {
|
|
2233
|
+
name: part.toolName,
|
|
2234
|
+
args: input
|
|
2235
|
+
}
|
|
2236
|
+
});
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
if (parts.length > 0) {
|
|
2240
|
+
contents.push({ role: "model", parts });
|
|
2241
|
+
}
|
|
2242
|
+
} else if (message.role === "tool") {
|
|
2243
|
+
const parts = [];
|
|
2244
|
+
for (const part of message.content) {
|
|
2245
|
+
if (part.type === "tool-result") {
|
|
2246
|
+
let response;
|
|
2247
|
+
const output = part.output;
|
|
2248
|
+
if (output.type === "text" || output.type === "error-text") {
|
|
2249
|
+
response = { result: output.value };
|
|
2250
|
+
} else if (output.type === "json" || output.type === "error-json") {
|
|
2251
|
+
response = typeof output.value === "object" && output.value !== null ? output.value : { result: output.value };
|
|
2252
|
+
} else if (output.type === "content") {
|
|
2253
|
+
const text = output.value.map(
|
|
2254
|
+
(c) => c.type === "text" ? c.text : "[media]"
|
|
2255
|
+
).join("\n");
|
|
2256
|
+
response = { result: text };
|
|
2257
|
+
} else {
|
|
2258
|
+
response = { result: String(output) };
|
|
2259
|
+
}
|
|
2260
|
+
parts.push({
|
|
2261
|
+
functionResponse: {
|
|
2262
|
+
name: part.toolName,
|
|
2263
|
+
response
|
|
2264
|
+
}
|
|
2265
|
+
});
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
if (parts.length > 0) {
|
|
2269
|
+
contents.push({ role: "user", parts });
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
return { contents, systemInstruction };
|
|
2274
|
+
}
|
|
2275
|
+
function convertToolsToGemini(tools) {
|
|
2276
|
+
if (!tools || tools.length === 0) {
|
|
2277
|
+
return void 0;
|
|
2278
|
+
}
|
|
2279
|
+
return tools.map((tool) => ({
|
|
2280
|
+
name: tool.name,
|
|
2281
|
+
description: tool.description,
|
|
2282
|
+
parameters: tool.inputSchema
|
|
2283
|
+
}));
|
|
2284
|
+
}
|
|
2285
|
+
function mapFinishReason(geminiReason) {
|
|
2286
|
+
switch (geminiReason) {
|
|
2287
|
+
case "STOP":
|
|
2288
|
+
return "stop";
|
|
2289
|
+
case "MAX_TOKENS":
|
|
2290
|
+
return "length";
|
|
2291
|
+
case "SAFETY":
|
|
2292
|
+
case "RECITATION":
|
|
2293
|
+
case "OTHER":
|
|
2294
|
+
return "content-filter";
|
|
2295
|
+
case "FUNCTION_CALL":
|
|
2296
|
+
return "tool-calls";
|
|
2297
|
+
default:
|
|
2298
|
+
return "stop";
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
var GeminiClient = class {
|
|
2302
|
+
baseURL;
|
|
2303
|
+
apiKey;
|
|
2304
|
+
headers;
|
|
2305
|
+
constructor(config) {
|
|
2306
|
+
this.baseURL = normalizeGeminiEndpoint(config.baseURL);
|
|
2307
|
+
this.apiKey = config.apiKey;
|
|
2308
|
+
this.headers = config.headers || {};
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Generate content (non-streaming)
|
|
2312
|
+
*/
|
|
2313
|
+
async doGenerate(modelId, options) {
|
|
2314
|
+
const { contents, systemInstruction } = convertMessagesToGemini(
|
|
2315
|
+
options.prompt
|
|
2316
|
+
);
|
|
2317
|
+
const tools = convertToolsToGemini(
|
|
2318
|
+
options.tools?.filter(
|
|
2319
|
+
(t) => t.type === "function"
|
|
2320
|
+
)
|
|
2321
|
+
);
|
|
2322
|
+
const modelPath = modelId.startsWith("models/") ? modelId : `models/${modelId}`;
|
|
2323
|
+
const url = `${this.baseURL}/v1beta/${modelPath}:generateContent`;
|
|
2324
|
+
const request = { contents };
|
|
2325
|
+
if (systemInstruction) {
|
|
2326
|
+
request.systemInstruction = { parts: [{ text: systemInstruction }] };
|
|
2327
|
+
}
|
|
2328
|
+
if (tools && tools.length > 0) {
|
|
2329
|
+
request.tools = [{ functionDeclarations: tools }];
|
|
2330
|
+
request.toolConfig = {
|
|
2331
|
+
functionCallingConfig: {
|
|
2332
|
+
mode: options.toolChoice?.type === "required" ? "ANY" : options.toolChoice?.type === "none" ? "NONE" : "AUTO"
|
|
2333
|
+
}
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
const generationConfig = {};
|
|
2337
|
+
if (options.maxOutputTokens) {
|
|
2338
|
+
generationConfig.maxOutputTokens = options.maxOutputTokens;
|
|
2339
|
+
}
|
|
2340
|
+
if (options.temperature !== void 0) {
|
|
2341
|
+
generationConfig.temperature = options.temperature;
|
|
2342
|
+
}
|
|
2343
|
+
if (options.topP !== void 0) {
|
|
2344
|
+
generationConfig.topP = options.topP;
|
|
2345
|
+
}
|
|
2346
|
+
if (options.topK !== void 0) {
|
|
2347
|
+
generationConfig.topK = options.topK;
|
|
2348
|
+
}
|
|
2349
|
+
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
2350
|
+
generationConfig.stopSequences = options.stopSequences;
|
|
2351
|
+
}
|
|
2352
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
2353
|
+
request.generationConfig = generationConfig;
|
|
2354
|
+
}
|
|
2355
|
+
const response = await fetch(url, {
|
|
2356
|
+
method: "POST",
|
|
2357
|
+
headers: {
|
|
2358
|
+
"Content-Type": "application/json",
|
|
2359
|
+
"X-Goog-Api-Key": this.apiKey,
|
|
2360
|
+
...this.headers
|
|
2361
|
+
},
|
|
2362
|
+
body: JSON.stringify(request),
|
|
2363
|
+
signal: options.abortSignal
|
|
2364
|
+
});
|
|
2365
|
+
if (!response.ok) {
|
|
2366
|
+
const errorText = await response.text();
|
|
2367
|
+
throw new Error(
|
|
2368
|
+
`Gemini API error: ${response.status} ${response.statusText} - ${errorText}`
|
|
2369
|
+
);
|
|
2370
|
+
}
|
|
2371
|
+
const data = await response.json();
|
|
2372
|
+
const candidate = data.candidates?.[0];
|
|
2373
|
+
const parts = candidate?.content?.parts || [];
|
|
2374
|
+
const content = [];
|
|
2375
|
+
for (const part of parts) {
|
|
2376
|
+
if (part.thought && part.text) {
|
|
2377
|
+
content.push({ type: "reasoning", text: part.text });
|
|
2378
|
+
} else if (part.text) {
|
|
2379
|
+
content.push({ type: "text", text: part.text });
|
|
2380
|
+
} else if (part.functionCall) {
|
|
2381
|
+
content.push({
|
|
2382
|
+
type: "tool-call",
|
|
2383
|
+
toolCallId: generateId2(),
|
|
2384
|
+
toolName: part.functionCall.name,
|
|
2385
|
+
input: JSON.stringify(part.functionCall.args)
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
return {
|
|
2390
|
+
content,
|
|
2391
|
+
finishReason: mapFinishReason(candidate?.finishReason),
|
|
2392
|
+
usage: {
|
|
2393
|
+
inputTokens: data.usageMetadata?.promptTokenCount,
|
|
2394
|
+
outputTokens: data.usageMetadata?.candidatesTokenCount
|
|
2395
|
+
}
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Stream content generation
|
|
2400
|
+
*/
|
|
2401
|
+
async doStream(modelId, options) {
|
|
2402
|
+
const { contents, systemInstruction } = convertMessagesToGemini(
|
|
2403
|
+
options.prompt
|
|
2404
|
+
);
|
|
2405
|
+
const tools = convertToolsToGemini(
|
|
2406
|
+
options.tools?.filter(
|
|
2407
|
+
(t) => t.type === "function"
|
|
2408
|
+
)
|
|
2409
|
+
);
|
|
2410
|
+
const modelPath = modelId.startsWith("models/") ? modelId : `models/${modelId}`;
|
|
2411
|
+
const url = `${this.baseURL}/v1beta/${modelPath}:streamGenerateContent?alt=sse`;
|
|
2412
|
+
const request = { contents };
|
|
2413
|
+
if (systemInstruction) {
|
|
2414
|
+
request.systemInstruction = { parts: [{ text: systemInstruction }] };
|
|
2415
|
+
}
|
|
2416
|
+
if (tools && tools.length > 0) {
|
|
2417
|
+
request.tools = [{ functionDeclarations: tools }];
|
|
2418
|
+
request.toolConfig = {
|
|
2419
|
+
functionCallingConfig: {
|
|
2420
|
+
mode: options.toolChoice?.type === "required" ? "ANY" : options.toolChoice?.type === "none" ? "NONE" : "AUTO"
|
|
2421
|
+
}
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
const generationConfig = {};
|
|
2425
|
+
if (options.maxOutputTokens) {
|
|
2426
|
+
generationConfig.maxOutputTokens = options.maxOutputTokens;
|
|
2427
|
+
}
|
|
2428
|
+
if (options.temperature !== void 0) {
|
|
2429
|
+
generationConfig.temperature = options.temperature;
|
|
2430
|
+
}
|
|
2431
|
+
if (options.topP !== void 0) {
|
|
2432
|
+
generationConfig.topP = options.topP;
|
|
2433
|
+
}
|
|
2434
|
+
if (options.topK !== void 0) {
|
|
2435
|
+
generationConfig.topK = options.topK;
|
|
2436
|
+
}
|
|
2437
|
+
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
2438
|
+
generationConfig.stopSequences = options.stopSequences;
|
|
2439
|
+
}
|
|
2440
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
2441
|
+
request.generationConfig = generationConfig;
|
|
2442
|
+
}
|
|
2443
|
+
const response = await fetch(url, {
|
|
2444
|
+
method: "POST",
|
|
2445
|
+
headers: {
|
|
2446
|
+
"Content-Type": "application/json",
|
|
2447
|
+
"X-Goog-Api-Key": this.apiKey,
|
|
2448
|
+
...this.headers
|
|
2449
|
+
},
|
|
2450
|
+
body: JSON.stringify(request),
|
|
2451
|
+
signal: options.abortSignal
|
|
2452
|
+
});
|
|
2453
|
+
if (!response.ok) {
|
|
2454
|
+
const errorText = await response.text();
|
|
2455
|
+
throw new Error(
|
|
2456
|
+
`Gemini API error: ${response.status} ${response.statusText} - ${errorText}`
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
if (!response.body) {
|
|
2460
|
+
throw new Error("Response body is null");
|
|
2461
|
+
}
|
|
2462
|
+
const reader = response.body.getReader();
|
|
2463
|
+
const decoder = new TextDecoder();
|
|
2464
|
+
const stream = new ReadableStream({
|
|
2465
|
+
async start(controller) {
|
|
2466
|
+
let buffer = "";
|
|
2467
|
+
let textId;
|
|
2468
|
+
let reasoningId;
|
|
2469
|
+
let hasEmittedTextStart = false;
|
|
2470
|
+
let hasEmittedReasoningStart = false;
|
|
2471
|
+
const toolCalls = [];
|
|
2472
|
+
let finishReason = "stop";
|
|
2473
|
+
let usage = { inputTokens: void 0, outputTokens: void 0 };
|
|
2474
|
+
try {
|
|
2475
|
+
while (true) {
|
|
2476
|
+
const { done, value } = await reader.read();
|
|
2477
|
+
if (done) {
|
|
2478
|
+
break;
|
|
2479
|
+
}
|
|
2480
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2481
|
+
const events = buffer.split(/\n\n/);
|
|
2482
|
+
buffer = events.pop() || "";
|
|
2483
|
+
for (const event of events) {
|
|
2484
|
+
const lines = event.split("\n");
|
|
2485
|
+
for (const line of lines) {
|
|
2486
|
+
if (line.startsWith("data: ")) {
|
|
2487
|
+
const jsonStr = line.substring(6).trim();
|
|
2488
|
+
if (!jsonStr || jsonStr === "[DONE]") {
|
|
2489
|
+
continue;
|
|
2490
|
+
}
|
|
2491
|
+
try {
|
|
2492
|
+
const chunk = JSON.parse(jsonStr);
|
|
2493
|
+
const candidate = chunk.candidates?.[0];
|
|
2494
|
+
const parts = candidate?.content?.parts;
|
|
2495
|
+
if (chunk.usageMetadata) {
|
|
2496
|
+
usage = {
|
|
2497
|
+
inputTokens: chunk.usageMetadata.promptTokenCount,
|
|
2498
|
+
outputTokens: chunk.usageMetadata.candidatesTokenCount
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
if (candidate?.finishReason) {
|
|
2502
|
+
finishReason = mapFinishReason(candidate.finishReason);
|
|
2503
|
+
}
|
|
2504
|
+
if (parts) {
|
|
2505
|
+
for (const part of parts) {
|
|
2506
|
+
if (part.thought && part.text) {
|
|
2507
|
+
if (!hasEmittedReasoningStart) {
|
|
2508
|
+
reasoningId = generateId2();
|
|
2509
|
+
controller.enqueue({
|
|
2510
|
+
type: "reasoning-start",
|
|
2511
|
+
id: reasoningId
|
|
2512
|
+
});
|
|
2513
|
+
hasEmittedReasoningStart = true;
|
|
2514
|
+
}
|
|
2515
|
+
controller.enqueue({
|
|
2516
|
+
type: "reasoning-delta",
|
|
2517
|
+
id: reasoningId,
|
|
2518
|
+
delta: part.text
|
|
2519
|
+
});
|
|
2520
|
+
} else if (part.text && !part.thought) {
|
|
2521
|
+
if (!hasEmittedTextStart) {
|
|
2522
|
+
textId = generateId2();
|
|
2523
|
+
controller.enqueue({
|
|
2524
|
+
type: "text-start",
|
|
2525
|
+
id: textId
|
|
2526
|
+
});
|
|
2527
|
+
hasEmittedTextStart = true;
|
|
2528
|
+
}
|
|
2529
|
+
controller.enqueue({
|
|
2530
|
+
type: "text-delta",
|
|
2531
|
+
id: textId,
|
|
2532
|
+
delta: part.text
|
|
2533
|
+
});
|
|
2534
|
+
} else if (part.functionCall) {
|
|
2535
|
+
const callId = generateId2();
|
|
2536
|
+
toolCalls.push({
|
|
2537
|
+
id: callId,
|
|
2538
|
+
name: part.functionCall.name,
|
|
2539
|
+
args: part.functionCall.args
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
} catch {
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
if (hasEmittedReasoningStart && reasoningId) {
|
|
2551
|
+
controller.enqueue({ type: "reasoning-end", id: reasoningId });
|
|
2552
|
+
}
|
|
2553
|
+
if (hasEmittedTextStart && textId) {
|
|
2554
|
+
controller.enqueue({ type: "text-end", id: textId });
|
|
2555
|
+
}
|
|
2556
|
+
if (toolCalls.length > 0) {
|
|
2557
|
+
finishReason = "tool-calls";
|
|
2558
|
+
for (const tc of toolCalls) {
|
|
2559
|
+
const inputJson = JSON.stringify(tc.args);
|
|
2560
|
+
controller.enqueue({
|
|
2561
|
+
type: "tool-input-start",
|
|
2562
|
+
id: tc.id,
|
|
2563
|
+
toolName: tc.name
|
|
2564
|
+
});
|
|
2565
|
+
controller.enqueue({
|
|
2566
|
+
type: "tool-input-delta",
|
|
2567
|
+
id: tc.id,
|
|
2568
|
+
delta: inputJson
|
|
2569
|
+
});
|
|
2570
|
+
controller.enqueue({
|
|
2571
|
+
type: "tool-input-end",
|
|
2572
|
+
id: tc.id
|
|
2573
|
+
});
|
|
2574
|
+
controller.enqueue({
|
|
2575
|
+
type: "tool-call",
|
|
2576
|
+
toolCallId: tc.id,
|
|
2577
|
+
toolName: tc.name,
|
|
2578
|
+
input: inputJson
|
|
2579
|
+
});
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
controller.enqueue({
|
|
2583
|
+
type: "finish",
|
|
2584
|
+
finishReason,
|
|
2585
|
+
usage: {
|
|
2586
|
+
inputTokens: usage.inputTokens,
|
|
2587
|
+
outputTokens: usage.outputTokens,
|
|
2588
|
+
totalTokens: usage.inputTokens !== void 0 && usage.outputTokens !== void 0 ? usage.inputTokens + usage.outputTokens : void 0
|
|
2589
|
+
}
|
|
2590
|
+
});
|
|
2591
|
+
controller.close();
|
|
2592
|
+
} catch (error) {
|
|
2593
|
+
controller.error(error);
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2597
|
+
return { stream };
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
|
|
2601
|
+
// src/clients/claudeClient.ts
|
|
2602
|
+
var idCounter3 = 0;
|
|
2603
|
+
function generateId3() {
|
|
2604
|
+
return `claude_${Date.now()}_${++idCounter3}`;
|
|
2605
|
+
}
|
|
2606
|
+
function normalizeClaudeEndpoint(endpoint) {
|
|
2607
|
+
let normalized = endpoint.replace(/\/+$/, "");
|
|
2608
|
+
if (normalized.endsWith("/v1")) {
|
|
2609
|
+
normalized = normalized.slice(0, -3);
|
|
2610
|
+
}
|
|
2611
|
+
return normalized;
|
|
2612
|
+
}
|
|
2613
|
+
function convertMessagesToClaude(messages) {
|
|
2614
|
+
const claudeMessages = [];
|
|
2615
|
+
let systemContent;
|
|
2616
|
+
for (const message of messages) {
|
|
2617
|
+
if (message.role === "system") {
|
|
2618
|
+
systemContent = (systemContent || "") + message.content;
|
|
2619
|
+
} else if (message.role === "user") {
|
|
2620
|
+
const content = [];
|
|
2621
|
+
for (const part of message.content) {
|
|
2622
|
+
if (part.type === "text") {
|
|
2623
|
+
content.push({ type: "text", text: part.text });
|
|
2624
|
+
} else if (part.type === "file") {
|
|
2625
|
+
const filePart = part;
|
|
2626
|
+
if (filePart.mediaType.startsWith("image/")) {
|
|
2627
|
+
if (typeof filePart.data === "string") {
|
|
2628
|
+
if (filePart.data.startsWith("data:")) {
|
|
2629
|
+
const match = filePart.data.match(/^data:([^;]+);base64,(.+)$/);
|
|
2630
|
+
if (match) {
|
|
2631
|
+
content.push({
|
|
2632
|
+
type: "image",
|
|
2633
|
+
source: {
|
|
2634
|
+
type: "base64",
|
|
2635
|
+
media_type: match[1],
|
|
2636
|
+
data: match[2]
|
|
2637
|
+
}
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
} else {
|
|
2641
|
+
content.push({
|
|
2642
|
+
type: "image",
|
|
2643
|
+
source: {
|
|
2644
|
+
type: "base64",
|
|
2645
|
+
media_type: filePart.mediaType,
|
|
2646
|
+
data: filePart.data
|
|
2647
|
+
}
|
|
2648
|
+
});
|
|
2649
|
+
}
|
|
2650
|
+
} else if (filePart.data instanceof Uint8Array) {
|
|
2651
|
+
const base64 = Buffer.from(filePart.data).toString("base64");
|
|
2652
|
+
content.push({
|
|
2653
|
+
type: "image",
|
|
2654
|
+
source: {
|
|
2655
|
+
type: "base64",
|
|
2656
|
+
media_type: filePart.mediaType,
|
|
2657
|
+
data: base64
|
|
2658
|
+
}
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
if (content.length > 0) {
|
|
2665
|
+
claudeMessages.push({
|
|
2666
|
+
role: "user",
|
|
2667
|
+
content: content.length === 1 && content[0].type === "text" ? content[0].text : content
|
|
2668
|
+
});
|
|
2669
|
+
}
|
|
2670
|
+
} else if (message.role === "assistant") {
|
|
2671
|
+
const content = [];
|
|
2672
|
+
for (const part of message.content) {
|
|
2673
|
+
if (part.type === "text") {
|
|
2674
|
+
content.push({ type: "text", text: part.text });
|
|
2675
|
+
} else if (part.type === "reasoning") {
|
|
2676
|
+
content.push({ type: "thinking", thinking: part.text });
|
|
2677
|
+
} else if (part.type === "tool-call") {
|
|
2678
|
+
const input = part.input;
|
|
2679
|
+
content.push({
|
|
2680
|
+
type: "tool_use",
|
|
2681
|
+
id: part.toolCallId,
|
|
2682
|
+
name: part.toolName,
|
|
2683
|
+
input
|
|
2684
|
+
});
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
if (content.length > 0) {
|
|
2688
|
+
claudeMessages.push({ role: "assistant", content });
|
|
2689
|
+
}
|
|
2690
|
+
} else if (message.role === "tool") {
|
|
2691
|
+
const content = [];
|
|
2692
|
+
for (const part of message.content) {
|
|
2693
|
+
if (part.type === "tool-result") {
|
|
2694
|
+
let resultContent;
|
|
2695
|
+
const output = part.output;
|
|
2696
|
+
if (output.type === "text" || output.type === "error-text") {
|
|
2697
|
+
resultContent = output.value;
|
|
2698
|
+
} else if (output.type === "json" || output.type === "error-json") {
|
|
2699
|
+
resultContent = JSON.stringify(output.value);
|
|
2700
|
+
} else if (output.type === "content") {
|
|
2701
|
+
resultContent = output.value.map(
|
|
2702
|
+
(c) => c.type === "text" ? c.text : "[media]"
|
|
2703
|
+
).join("\n");
|
|
2704
|
+
} else {
|
|
2705
|
+
resultContent = String(output);
|
|
2706
|
+
}
|
|
2707
|
+
const isError = output.type === "error-text" || output.type === "error-json";
|
|
2708
|
+
content.push({
|
|
2709
|
+
type: "tool_result",
|
|
2710
|
+
tool_use_id: part.toolCallId,
|
|
2711
|
+
content: resultContent,
|
|
2712
|
+
is_error: isError
|
|
2713
|
+
});
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
if (content.length > 0) {
|
|
2717
|
+
claudeMessages.push({ role: "user", content });
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
return { messages: claudeMessages, system: systemContent };
|
|
2722
|
+
}
|
|
2723
|
+
function convertToolsToClaude(tools) {
|
|
2724
|
+
if (!tools || tools.length === 0) {
|
|
2725
|
+
return void 0;
|
|
2726
|
+
}
|
|
2727
|
+
return tools.map((tool) => ({
|
|
2728
|
+
name: tool.name,
|
|
2729
|
+
description: tool.description,
|
|
2730
|
+
input_schema: tool.inputSchema
|
|
2731
|
+
}));
|
|
2732
|
+
}
|
|
2733
|
+
function mapFinishReason2(claudeReason) {
|
|
2734
|
+
switch (claudeReason) {
|
|
2735
|
+
case "end_turn":
|
|
2736
|
+
case "stop_sequence":
|
|
2737
|
+
return "stop";
|
|
2738
|
+
case "max_tokens":
|
|
2739
|
+
return "length";
|
|
2740
|
+
case "tool_use":
|
|
2741
|
+
return "tool-calls";
|
|
2742
|
+
default:
|
|
2743
|
+
return "stop";
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
var ClaudeClient = class {
|
|
2747
|
+
baseURL;
|
|
2748
|
+
apiKey;
|
|
2749
|
+
headers;
|
|
2750
|
+
constructor(config) {
|
|
2751
|
+
this.baseURL = normalizeClaudeEndpoint(config.baseURL);
|
|
2752
|
+
this.apiKey = config.apiKey;
|
|
2753
|
+
this.headers = config.headers || {};
|
|
2754
|
+
}
|
|
2755
|
+
/**
|
|
2756
|
+
* Generate content (non-streaming)
|
|
2757
|
+
*/
|
|
2758
|
+
async doGenerate(modelId, options) {
|
|
2759
|
+
const { messages, system } = convertMessagesToClaude(options.prompt);
|
|
2760
|
+
const tools = convertToolsToClaude(
|
|
2761
|
+
options.tools?.filter(
|
|
2762
|
+
(t) => t.type === "function"
|
|
2763
|
+
)
|
|
2764
|
+
);
|
|
2765
|
+
const url = `${this.baseURL}/v1/messages`;
|
|
2766
|
+
const request = {
|
|
2767
|
+
model: modelId,
|
|
2768
|
+
messages,
|
|
2769
|
+
max_tokens: options.maxOutputTokens || 8192,
|
|
2770
|
+
stream: false
|
|
2771
|
+
};
|
|
2772
|
+
if (system) {
|
|
2773
|
+
request.system = system;
|
|
2774
|
+
}
|
|
2775
|
+
if (tools && tools.length > 0) {
|
|
2776
|
+
request.tools = tools;
|
|
2777
|
+
if (options.toolChoice?.type === "required") {
|
|
2778
|
+
request.tool_choice = { type: "any" };
|
|
2779
|
+
} else if (options.toolChoice?.type === "none") {
|
|
2780
|
+
delete request.tools;
|
|
2781
|
+
} else if (options.toolChoice?.type === "tool") {
|
|
2782
|
+
request.tool_choice = {
|
|
2783
|
+
type: "tool",
|
|
2784
|
+
name: options.toolChoice.toolName
|
|
2785
|
+
};
|
|
2786
|
+
} else {
|
|
2787
|
+
request.tool_choice = { type: "auto" };
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
if (options.temperature !== void 0) {
|
|
2791
|
+
request.temperature = options.temperature;
|
|
2792
|
+
}
|
|
2793
|
+
if (options.topP !== void 0) {
|
|
2794
|
+
request.top_p = options.topP;
|
|
2795
|
+
}
|
|
2796
|
+
if (options.topK !== void 0) {
|
|
2797
|
+
request.top_k = options.topK;
|
|
2798
|
+
}
|
|
2799
|
+
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
2800
|
+
request.stop_sequences = options.stopSequences;
|
|
2801
|
+
}
|
|
2802
|
+
const response = await fetch(url, {
|
|
2803
|
+
method: "POST",
|
|
2804
|
+
headers: {
|
|
2805
|
+
"Content-Type": "application/json",
|
|
2806
|
+
"x-api-key": this.apiKey,
|
|
2807
|
+
"anthropic-version": "2023-06-01",
|
|
2808
|
+
...this.headers
|
|
2809
|
+
},
|
|
2810
|
+
body: JSON.stringify(request),
|
|
2811
|
+
signal: options.abortSignal
|
|
2812
|
+
});
|
|
2813
|
+
if (!response.ok) {
|
|
2814
|
+
const errorText = await response.text();
|
|
2815
|
+
throw new Error(
|
|
2816
|
+
`Claude API error: ${response.status} ${response.statusText} - ${errorText}`
|
|
2817
|
+
);
|
|
2818
|
+
}
|
|
2819
|
+
const data = await response.json();
|
|
2820
|
+
const content = [];
|
|
2821
|
+
for (const block of data.content) {
|
|
2822
|
+
if (block.type === "text") {
|
|
2823
|
+
content.push({ type: "text", text: block.text });
|
|
2824
|
+
} else if (block.type === "thinking") {
|
|
2825
|
+
content.push({ type: "reasoning", text: block.thinking });
|
|
2826
|
+
} else if (block.type === "tool_use") {
|
|
2827
|
+
content.push({
|
|
2828
|
+
type: "tool-call",
|
|
2829
|
+
toolCallId: block.id,
|
|
2830
|
+
toolName: block.name,
|
|
2831
|
+
input: JSON.stringify(block.input)
|
|
2832
|
+
});
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
return {
|
|
2836
|
+
content,
|
|
2837
|
+
finishReason: mapFinishReason2(data.stop_reason),
|
|
2838
|
+
usage: {
|
|
2839
|
+
inputTokens: data.usage?.input_tokens,
|
|
2840
|
+
outputTokens: data.usage?.output_tokens
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
/**
|
|
2845
|
+
* Stream content generation
|
|
2846
|
+
*/
|
|
2847
|
+
async doStream(modelId, options) {
|
|
2848
|
+
const { messages, system } = convertMessagesToClaude(options.prompt);
|
|
2849
|
+
const tools = convertToolsToClaude(
|
|
2850
|
+
options.tools?.filter(
|
|
2851
|
+
(t) => t.type === "function"
|
|
2852
|
+
)
|
|
2853
|
+
);
|
|
2854
|
+
const url = `${this.baseURL}/v1/messages`;
|
|
2855
|
+
const request = {
|
|
2856
|
+
model: modelId,
|
|
2857
|
+
messages,
|
|
2858
|
+
max_tokens: options.maxOutputTokens || 8192,
|
|
2859
|
+
stream: true
|
|
2860
|
+
};
|
|
2861
|
+
if (system) {
|
|
2862
|
+
request.system = system;
|
|
2863
|
+
}
|
|
2864
|
+
if (tools && tools.length > 0) {
|
|
2865
|
+
request.tools = tools;
|
|
2866
|
+
if (options.toolChoice?.type === "required") {
|
|
2867
|
+
request.tool_choice = { type: "any" };
|
|
2868
|
+
} else if (options.toolChoice?.type === "none") {
|
|
2869
|
+
delete request.tools;
|
|
2870
|
+
} else if (options.toolChoice?.type === "tool") {
|
|
2871
|
+
request.tool_choice = {
|
|
2872
|
+
type: "tool",
|
|
2873
|
+
name: options.toolChoice.toolName
|
|
2874
|
+
};
|
|
2875
|
+
} else {
|
|
2876
|
+
request.tool_choice = { type: "auto" };
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
if (options.temperature !== void 0) {
|
|
2880
|
+
request.temperature = options.temperature;
|
|
2881
|
+
}
|
|
2882
|
+
if (options.topP !== void 0) {
|
|
2883
|
+
request.top_p = options.topP;
|
|
2884
|
+
}
|
|
2885
|
+
if (options.topK !== void 0) {
|
|
2886
|
+
request.top_k = options.topK;
|
|
2887
|
+
}
|
|
2888
|
+
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
2889
|
+
request.stop_sequences = options.stopSequences;
|
|
2890
|
+
}
|
|
2891
|
+
const response = await fetch(url, {
|
|
2892
|
+
method: "POST",
|
|
2893
|
+
headers: {
|
|
2894
|
+
"Content-Type": "application/json",
|
|
2895
|
+
"x-api-key": this.apiKey,
|
|
2896
|
+
"anthropic-version": "2023-06-01",
|
|
2897
|
+
...this.headers
|
|
2898
|
+
},
|
|
2899
|
+
body: JSON.stringify(request),
|
|
2900
|
+
signal: options.abortSignal
|
|
2901
|
+
});
|
|
2902
|
+
if (!response.ok) {
|
|
2903
|
+
const errorText = await response.text();
|
|
2904
|
+
throw new Error(
|
|
2905
|
+
`Claude API error: ${response.status} ${response.statusText} - ${errorText}`
|
|
2906
|
+
);
|
|
2907
|
+
}
|
|
2908
|
+
if (!response.body) {
|
|
2909
|
+
throw new Error("Response body is null");
|
|
2910
|
+
}
|
|
2911
|
+
const reader = response.body.getReader();
|
|
2912
|
+
const decoder = new TextDecoder();
|
|
2913
|
+
const stream = new ReadableStream({
|
|
2914
|
+
async start(controller) {
|
|
2915
|
+
let buffer = "";
|
|
2916
|
+
let textId;
|
|
2917
|
+
let reasoningId;
|
|
2918
|
+
let hasEmittedTextStart = false;
|
|
2919
|
+
let hasEmittedReasoningStart = false;
|
|
2920
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
2921
|
+
let finishReason = "stop";
|
|
2922
|
+
let usage = { inputTokens: void 0, outputTokens: void 0 };
|
|
2923
|
+
try {
|
|
2924
|
+
while (true) {
|
|
2925
|
+
const { done, value } = await reader.read();
|
|
2926
|
+
if (done) {
|
|
2927
|
+
break;
|
|
2928
|
+
}
|
|
2929
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2930
|
+
const lines = buffer.split("\n");
|
|
2931
|
+
buffer = lines.pop() || "";
|
|
2932
|
+
for (const line of lines) {
|
|
2933
|
+
if (line.startsWith("data: ")) {
|
|
2934
|
+
const jsonStr = line.substring(6).trim();
|
|
2935
|
+
if (!jsonStr || jsonStr === "[DONE]") {
|
|
2936
|
+
continue;
|
|
2937
|
+
}
|
|
2938
|
+
try {
|
|
2939
|
+
const event = JSON.parse(jsonStr);
|
|
2940
|
+
switch (event.type) {
|
|
2941
|
+
case "message_start":
|
|
2942
|
+
if (event.message?.usage) {
|
|
2943
|
+
usage.inputTokens = event.message.usage.input_tokens;
|
|
2944
|
+
}
|
|
2945
|
+
break;
|
|
2946
|
+
case "content_block_start":
|
|
2947
|
+
if (event.content_block) {
|
|
2948
|
+
if (event.content_block.type === "text") {
|
|
2949
|
+
if (!hasEmittedTextStart) {
|
|
2950
|
+
textId = generateId3();
|
|
2951
|
+
controller.enqueue({
|
|
2952
|
+
type: "text-start",
|
|
2953
|
+
id: textId
|
|
2954
|
+
});
|
|
2955
|
+
hasEmittedTextStart = true;
|
|
2956
|
+
}
|
|
2957
|
+
} else if (event.content_block.type === "thinking") {
|
|
2958
|
+
if (!hasEmittedReasoningStart) {
|
|
2959
|
+
reasoningId = generateId3();
|
|
2960
|
+
controller.enqueue({
|
|
2961
|
+
type: "reasoning-start",
|
|
2962
|
+
id: reasoningId
|
|
2963
|
+
});
|
|
2964
|
+
hasEmittedReasoningStart = true;
|
|
2965
|
+
}
|
|
2966
|
+
} else if (event.content_block.type === "tool_use") {
|
|
2967
|
+
const block = event.content_block;
|
|
2968
|
+
toolCalls.set(event.index, {
|
|
2969
|
+
id: block.id,
|
|
2970
|
+
name: block.name,
|
|
2971
|
+
inputJson: ""
|
|
2972
|
+
});
|
|
2973
|
+
controller.enqueue({
|
|
2974
|
+
type: "tool-input-start",
|
|
2975
|
+
id: block.id,
|
|
2976
|
+
toolName: block.name
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
break;
|
|
2981
|
+
case "content_block_delta":
|
|
2982
|
+
if (event.delta) {
|
|
2983
|
+
if (event.delta.type === "text_delta" && event.delta.text) {
|
|
2984
|
+
if (!hasEmittedTextStart) {
|
|
2985
|
+
textId = generateId3();
|
|
2986
|
+
controller.enqueue({
|
|
2987
|
+
type: "text-start",
|
|
2988
|
+
id: textId
|
|
2989
|
+
});
|
|
2990
|
+
hasEmittedTextStart = true;
|
|
2991
|
+
}
|
|
2992
|
+
controller.enqueue({
|
|
2993
|
+
type: "text-delta",
|
|
2994
|
+
id: textId,
|
|
2995
|
+
delta: event.delta.text
|
|
2996
|
+
});
|
|
2997
|
+
} else if (event.delta.type === "thinking_delta" && event.delta.thinking) {
|
|
2998
|
+
if (!hasEmittedReasoningStart) {
|
|
2999
|
+
reasoningId = generateId3();
|
|
3000
|
+
controller.enqueue({
|
|
3001
|
+
type: "reasoning-start",
|
|
3002
|
+
id: reasoningId
|
|
3003
|
+
});
|
|
3004
|
+
hasEmittedReasoningStart = true;
|
|
3005
|
+
}
|
|
3006
|
+
controller.enqueue({
|
|
3007
|
+
type: "reasoning-delta",
|
|
3008
|
+
id: reasoningId,
|
|
3009
|
+
delta: event.delta.thinking
|
|
3010
|
+
});
|
|
3011
|
+
} else if (event.delta.type === "input_json_delta" && event.delta.partial_json !== void 0) {
|
|
3012
|
+
const tc2 = toolCalls.get(event.index);
|
|
3013
|
+
if (tc2) {
|
|
3014
|
+
tc2.inputJson += event.delta.partial_json;
|
|
3015
|
+
controller.enqueue({
|
|
3016
|
+
type: "tool-input-delta",
|
|
3017
|
+
id: tc2.id,
|
|
3018
|
+
delta: event.delta.partial_json
|
|
3019
|
+
});
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
break;
|
|
3024
|
+
case "content_block_stop":
|
|
3025
|
+
const tc = toolCalls.get(event.index);
|
|
3026
|
+
if (tc) {
|
|
3027
|
+
controller.enqueue({
|
|
3028
|
+
type: "tool-input-end",
|
|
3029
|
+
id: tc.id
|
|
3030
|
+
});
|
|
3031
|
+
controller.enqueue({
|
|
3032
|
+
type: "tool-call",
|
|
3033
|
+
toolCallId: tc.id,
|
|
3034
|
+
toolName: tc.name,
|
|
3035
|
+
input: tc.inputJson
|
|
3036
|
+
});
|
|
3037
|
+
}
|
|
3038
|
+
break;
|
|
3039
|
+
case "message_delta":
|
|
3040
|
+
if (event.delta && "stop_reason" in event.delta) {
|
|
3041
|
+
finishReason = mapFinishReason2(
|
|
3042
|
+
event.delta.stop_reason
|
|
3043
|
+
);
|
|
3044
|
+
}
|
|
3045
|
+
if (event.usage) {
|
|
3046
|
+
usage.outputTokens = event.usage.output_tokens;
|
|
3047
|
+
}
|
|
3048
|
+
break;
|
|
3049
|
+
case "message_stop":
|
|
3050
|
+
break;
|
|
3051
|
+
}
|
|
3052
|
+
} catch {
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
if (hasEmittedReasoningStart && reasoningId) {
|
|
3058
|
+
controller.enqueue({ type: "reasoning-end", id: reasoningId });
|
|
3059
|
+
}
|
|
3060
|
+
if (hasEmittedTextStart && textId) {
|
|
3061
|
+
controller.enqueue({ type: "text-end", id: textId });
|
|
3062
|
+
}
|
|
3063
|
+
controller.enqueue({
|
|
3064
|
+
type: "finish",
|
|
3065
|
+
finishReason,
|
|
3066
|
+
usage: {
|
|
3067
|
+
inputTokens: usage.inputTokens,
|
|
3068
|
+
outputTokens: usage.outputTokens,
|
|
3069
|
+
totalTokens: usage.inputTokens !== void 0 && usage.outputTokens !== void 0 ? usage.inputTokens + usage.outputTokens : void 0
|
|
3070
|
+
}
|
|
3071
|
+
});
|
|
3072
|
+
controller.close();
|
|
3073
|
+
} catch (error) {
|
|
3074
|
+
controller.error(error);
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
});
|
|
3078
|
+
return { stream };
|
|
3079
|
+
}
|
|
3080
|
+
};
|
|
3081
|
+
|
|
3082
|
+
// src/apiAdapters.ts
|
|
3083
|
+
var GeminiLanguageModel = class {
|
|
3084
|
+
specificationVersion = "v2";
|
|
3085
|
+
modelId;
|
|
3086
|
+
provider = "gemini";
|
|
3087
|
+
client;
|
|
3088
|
+
_override;
|
|
3089
|
+
constructor(modelId, config, override) {
|
|
3090
|
+
this.modelId = modelId;
|
|
3091
|
+
this.client = new GeminiClient(config);
|
|
3092
|
+
this._override = override;
|
|
3093
|
+
}
|
|
3094
|
+
get supportsStructuredOutputs() {
|
|
3095
|
+
return true;
|
|
3096
|
+
}
|
|
3097
|
+
get supportedUrls() {
|
|
3098
|
+
return {};
|
|
3099
|
+
}
|
|
3100
|
+
get defaultObjectGenerationMode() {
|
|
3101
|
+
return "json";
|
|
3102
|
+
}
|
|
3103
|
+
async doGenerate(options) {
|
|
3104
|
+
const result = await this.client.doGenerate(this.modelId, options);
|
|
3105
|
+
return {
|
|
3106
|
+
content: result.content,
|
|
3107
|
+
finishReason: result.finishReason,
|
|
3108
|
+
usage: {
|
|
3109
|
+
inputTokens: result.usage.inputTokens,
|
|
3110
|
+
outputTokens: result.usage.outputTokens,
|
|
3111
|
+
totalTokens: result.usage.inputTokens !== void 0 && result.usage.outputTokens !== void 0 ? result.usage.inputTokens + result.usage.outputTokens : void 0
|
|
3112
|
+
},
|
|
3113
|
+
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
3114
|
+
rawResponse: { headers: {} },
|
|
3115
|
+
request: { body: JSON.stringify({}) },
|
|
3116
|
+
response: {
|
|
3117
|
+
id: `gemini_${Date.now()}`,
|
|
3118
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
3119
|
+
modelId: this.modelId
|
|
3120
|
+
},
|
|
3121
|
+
warnings: []
|
|
3122
|
+
};
|
|
3123
|
+
}
|
|
3124
|
+
async doStream(options) {
|
|
3125
|
+
return this.client.doStream(this.modelId, options);
|
|
3126
|
+
}
|
|
3127
|
+
};
|
|
3128
|
+
var ClaudeLanguageModel = class {
|
|
3129
|
+
specificationVersion = "v2";
|
|
3130
|
+
modelId;
|
|
3131
|
+
provider = "claude";
|
|
3132
|
+
client;
|
|
3133
|
+
_override;
|
|
3134
|
+
constructor(modelId, config, override) {
|
|
3135
|
+
this.modelId = modelId;
|
|
3136
|
+
this.client = new ClaudeClient(config);
|
|
3137
|
+
this._override = override;
|
|
3138
|
+
}
|
|
3139
|
+
get supportsStructuredOutputs() {
|
|
3140
|
+
return true;
|
|
3141
|
+
}
|
|
3142
|
+
get supportedUrls() {
|
|
3143
|
+
return {};
|
|
3144
|
+
}
|
|
3145
|
+
get defaultObjectGenerationMode() {
|
|
3146
|
+
return "tool";
|
|
3147
|
+
}
|
|
3148
|
+
async doGenerate(options) {
|
|
3149
|
+
const result = await this.client.doGenerate(this.modelId, options);
|
|
3150
|
+
return {
|
|
3151
|
+
content: result.content,
|
|
3152
|
+
finishReason: result.finishReason,
|
|
3153
|
+
usage: {
|
|
3154
|
+
inputTokens: result.usage.inputTokens,
|
|
3155
|
+
outputTokens: result.usage.outputTokens,
|
|
3156
|
+
totalTokens: result.usage.inputTokens !== void 0 && result.usage.outputTokens !== void 0 ? result.usage.inputTokens + result.usage.outputTokens : void 0
|
|
3157
|
+
},
|
|
3158
|
+
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
3159
|
+
rawResponse: { headers: {} },
|
|
3160
|
+
request: { body: JSON.stringify({}) },
|
|
3161
|
+
response: {
|
|
3162
|
+
id: `claude_${Date.now()}`,
|
|
3163
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
3164
|
+
modelId: this.modelId
|
|
3165
|
+
},
|
|
3166
|
+
warnings: []
|
|
3167
|
+
};
|
|
3168
|
+
}
|
|
3169
|
+
async doStream(options) {
|
|
3170
|
+
return this.client.doStream(this.modelId, options);
|
|
3171
|
+
}
|
|
3172
|
+
};
|
|
3173
|
+
function createApiAdapter(apiType, modelId, config, override) {
|
|
3174
|
+
switch (apiType) {
|
|
3175
|
+
case "gemini":
|
|
3176
|
+
return new GeminiLanguageModel(modelId, config, override);
|
|
3177
|
+
case "claude":
|
|
3178
|
+
return new ClaudeLanguageModel(modelId, config, override);
|
|
3179
|
+
case "openai":
|
|
3180
|
+
default:
|
|
3181
|
+
return void 0;
|
|
3182
|
+
}
|
|
3183
|
+
}
|
|
3184
|
+
|
|
2160
3185
|
// src/index.ts
|
|
2161
3186
|
var modelCache = /* @__PURE__ */ new WeakMap();
|
|
2162
3187
|
function mergeWithConfig(options, config) {
|
|
@@ -2203,8 +3228,19 @@ function createOai2lm(options = {}) {
|
|
|
2203
3228
|
try {
|
|
2204
3229
|
let getOverride2 = function(modelId) {
|
|
2205
3230
|
return findModelOverride(modelId, mergedOptions.modelOverrides);
|
|
3231
|
+
}, createModel2 = function(modelId) {
|
|
3232
|
+
const override = getOverride2(modelId);
|
|
3233
|
+
const apiType = override?.apiType;
|
|
3234
|
+
if (apiType && apiType !== "openai") {
|
|
3235
|
+
const adapter = createApiAdapter(apiType, modelId, apiConfig, override);
|
|
3236
|
+
if (adapter) {
|
|
3237
|
+
return wrapWithEnhancements(adapter, modelId, override);
|
|
3238
|
+
}
|
|
3239
|
+
}
|
|
3240
|
+
const baseModel = baseProvider.languageModel(modelId);
|
|
3241
|
+
return wrapWithEnhancements(baseModel, modelId, override);
|
|
2206
3242
|
};
|
|
2207
|
-
var getOverride = getOverride2;
|
|
3243
|
+
var getOverride = getOverride2, createModel = createModel2;
|
|
2208
3244
|
const config = options.useConfigFile !== false ? loadConfig() : void 0;
|
|
2209
3245
|
const mergedOptions = mergeWithConfig(options, config);
|
|
2210
3246
|
if (!mergedOptions.baseURL) {
|
|
@@ -2270,20 +3306,19 @@ function createOai2lm(options = {}) {
|
|
|
2270
3306
|
}
|
|
2271
3307
|
return cache;
|
|
2272
3308
|
}
|
|
3309
|
+
const apiConfig = {
|
|
3310
|
+
baseURL,
|
|
3311
|
+
apiKey: mergedOptions.apiKey || "",
|
|
3312
|
+
headers: mergedOptions.headers
|
|
3313
|
+
};
|
|
2273
3314
|
const provider = function(modelId) {
|
|
2274
|
-
|
|
2275
|
-
const override = getOverride2(modelId);
|
|
2276
|
-
return wrapWithEnhancements(baseModel, modelId, override);
|
|
3315
|
+
return createModel2(modelId);
|
|
2277
3316
|
};
|
|
2278
3317
|
provider.languageModel = (modelId) => {
|
|
2279
|
-
|
|
2280
|
-
const override = getOverride2(modelId);
|
|
2281
|
-
return wrapWithEnhancements(baseModel, modelId, override);
|
|
3318
|
+
return createModel2(modelId);
|
|
2282
3319
|
};
|
|
2283
3320
|
provider.chatModel = (modelId) => {
|
|
2284
|
-
|
|
2285
|
-
const override = getOverride2(modelId);
|
|
2286
|
-
return wrapWithEnhancements(baseModel, modelId, override);
|
|
3321
|
+
return createModel2(modelId);
|
|
2287
3322
|
};
|
|
2288
3323
|
provider.completionModel = (modelId) => baseProvider.completionModel(modelId);
|
|
2289
3324
|
provider.textEmbeddingModel = (modelId) => baseProvider.textEmbeddingModel(modelId);
|
|
@@ -2308,7 +3343,10 @@ function createOai2lm(options = {}) {
|
|
|
2308
3343
|
var createOpenAICompatible = createOai2lm;
|
|
2309
3344
|
var index_default = createOai2lm;
|
|
2310
3345
|
export {
|
|
3346
|
+
ClaudeLanguageModel,
|
|
2311
3347
|
EnhancedLanguageModel,
|
|
3348
|
+
GeminiLanguageModel,
|
|
3349
|
+
createApiAdapter,
|
|
2312
3350
|
createOai2lm,
|
|
2313
3351
|
createOpenAICompatible,
|
|
2314
3352
|
index_default as default,
|