open-agents-ai 0.184.71 → 0.184.72
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/index.js +131 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -560,6 +560,10 @@ var init_normalizeUrl = __esm({
|
|
|
560
560
|
"use strict";
|
|
561
561
|
PROVIDERS = [
|
|
562
562
|
// --- Cloud providers (specific domains) ---
|
|
563
|
+
{
|
|
564
|
+
match: (u) => /api\.anthropic\.com/i.test(u),
|
|
565
|
+
info: { id: "anthropic", label: "Anthropic (Claude)", local: false, authRequired: true, keyPrefix: "sk-ant-", modelsPath: "/v1/models" }
|
|
566
|
+
},
|
|
563
567
|
{
|
|
564
568
|
match: (u) => /api\.openai\.com/i.test(u),
|
|
565
569
|
info: { id: "openai", label: "OpenAI", local: false, authRequired: true, keyPrefix: "sk-", modelsPath: "/v1/models" }
|
|
@@ -28487,11 +28491,14 @@ ${transcript}`
|
|
|
28487
28491
|
/** Multi-key pool — round-robin rotation per request for load distribution */
|
|
28488
28492
|
_keyPool = [];
|
|
28489
28493
|
_keyIndex = 0;
|
|
28494
|
+
/** Whether this backend targets Anthropic's Messages API */
|
|
28495
|
+
_isAnthropic = false;
|
|
28490
28496
|
constructor(baseUrl, model, apiKey, thinking) {
|
|
28491
28497
|
this.baseUrl = normalizeBaseUrl(baseUrl);
|
|
28492
28498
|
this.model = model;
|
|
28493
28499
|
this.apiKey = apiKey ?? "";
|
|
28494
28500
|
this.thinking = thinking ?? true;
|
|
28501
|
+
this._isAnthropic = /api\.anthropic\.com/i.test(baseUrl);
|
|
28495
28502
|
}
|
|
28496
28503
|
/** Set multiple API keys for round-robin rotation per request */
|
|
28497
28504
|
setKeyPool(keys) {
|
|
@@ -28502,7 +28509,7 @@ ${transcript}`
|
|
|
28502
28509
|
setAbortSignal(signal) {
|
|
28503
28510
|
this._abortSignal = signal;
|
|
28504
28511
|
}
|
|
28505
|
-
/** Build auth headers —
|
|
28512
|
+
/** Build auth headers — adapts to provider (Bearer for most, x-api-key for Anthropic).
|
|
28506
28513
|
* When a key pool is set, round-robins through keys per request. */
|
|
28507
28514
|
authHeaders() {
|
|
28508
28515
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -28512,11 +28519,19 @@ ${transcript}`
|
|
|
28512
28519
|
this._keyIndex++;
|
|
28513
28520
|
}
|
|
28514
28521
|
if (key) {
|
|
28515
|
-
|
|
28522
|
+
if (this._isAnthropic) {
|
|
28523
|
+
headers["x-api-key"] = key;
|
|
28524
|
+
headers["anthropic-version"] = "2023-06-01";
|
|
28525
|
+
} else {
|
|
28526
|
+
headers["Authorization"] = `Bearer ${key}`;
|
|
28527
|
+
}
|
|
28516
28528
|
}
|
|
28517
28529
|
return headers;
|
|
28518
28530
|
}
|
|
28519
28531
|
async chatCompletion(request) {
|
|
28532
|
+
if (this._isAnthropic) {
|
|
28533
|
+
return this._anthropicChatCompletion(request);
|
|
28534
|
+
}
|
|
28520
28535
|
const body = {
|
|
28521
28536
|
model: this.model,
|
|
28522
28537
|
messages: request.messages,
|
|
@@ -28574,6 +28589,106 @@ ${transcript}`
|
|
|
28574
28589
|
} : void 0
|
|
28575
28590
|
};
|
|
28576
28591
|
}
|
|
28592
|
+
/** Anthropic Messages API translation — converts our standard format to/from Anthropic's. */
|
|
28593
|
+
async _anthropicChatCompletion(request) {
|
|
28594
|
+
const systemMsgs = request.messages.filter((m) => m.role === "system");
|
|
28595
|
+
const nonSystemMsgs = request.messages.filter((m) => m.role !== "system");
|
|
28596
|
+
const systemText = systemMsgs.map((m) => typeof m.content === "string" ? m.content : "").join("\n\n");
|
|
28597
|
+
const anthropicMessages = [];
|
|
28598
|
+
for (const msg of nonSystemMsgs) {
|
|
28599
|
+
if (msg.role === "tool") {
|
|
28600
|
+
anthropicMessages.push({
|
|
28601
|
+
role: "user",
|
|
28602
|
+
content: [{
|
|
28603
|
+
type: "tool_result",
|
|
28604
|
+
tool_use_id: msg.tool_call_id ?? "",
|
|
28605
|
+
content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)
|
|
28606
|
+
}]
|
|
28607
|
+
});
|
|
28608
|
+
} else if (msg.role === "assistant" && msg.tool_calls?.length > 0) {
|
|
28609
|
+
const blocks = [];
|
|
28610
|
+
if (typeof msg.content === "string" && msg.content) {
|
|
28611
|
+
blocks.push({ type: "text", text: msg.content });
|
|
28612
|
+
}
|
|
28613
|
+
for (const tc of msg.tool_calls) {
|
|
28614
|
+
blocks.push({
|
|
28615
|
+
type: "tool_use",
|
|
28616
|
+
id: tc.id,
|
|
28617
|
+
name: tc.function?.name ?? tc.name,
|
|
28618
|
+
input: typeof tc.function?.arguments === "string" ? (() => {
|
|
28619
|
+
try {
|
|
28620
|
+
return JSON.parse(tc.function.arguments);
|
|
28621
|
+
} catch {
|
|
28622
|
+
return {};
|
|
28623
|
+
}
|
|
28624
|
+
})() : tc.function?.arguments ?? {}
|
|
28625
|
+
});
|
|
28626
|
+
}
|
|
28627
|
+
anthropicMessages.push({ role: "assistant", content: blocks });
|
|
28628
|
+
} else {
|
|
28629
|
+
anthropicMessages.push({
|
|
28630
|
+
role: msg.role === "user" ? "user" : "assistant",
|
|
28631
|
+
content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content ?? "")
|
|
28632
|
+
});
|
|
28633
|
+
}
|
|
28634
|
+
}
|
|
28635
|
+
const anthropicTools = (request.tools ?? []).filter((t) => t.type === "function" && t.function).map((t) => ({
|
|
28636
|
+
name: t.function.name,
|
|
28637
|
+
description: t.function.description,
|
|
28638
|
+
input_schema: t.function.parameters
|
|
28639
|
+
}));
|
|
28640
|
+
const body = {
|
|
28641
|
+
model: this.model,
|
|
28642
|
+
messages: anthropicMessages,
|
|
28643
|
+
max_tokens: request.maxTokens ?? 8192,
|
|
28644
|
+
temperature: request.temperature
|
|
28645
|
+
};
|
|
28646
|
+
if (systemText)
|
|
28647
|
+
body.system = systemText;
|
|
28648
|
+
if (anthropicTools.length > 0)
|
|
28649
|
+
body.tools = anthropicTools;
|
|
28650
|
+
const fetchOpts = {
|
|
28651
|
+
method: "POST",
|
|
28652
|
+
headers: this.authHeaders(),
|
|
28653
|
+
body: JSON.stringify(body)
|
|
28654
|
+
};
|
|
28655
|
+
if (this._abortSignal)
|
|
28656
|
+
fetchOpts.signal = this._abortSignal;
|
|
28657
|
+
const resp = await fetch(`${this.baseUrl}/v1/messages`, fetchOpts);
|
|
28658
|
+
if (!resp.ok) {
|
|
28659
|
+
const text = await resp.text().catch(() => "");
|
|
28660
|
+
throw new Error(`Anthropic HTTP ${resp.status}: ${text.slice(0, 300)}`);
|
|
28661
|
+
}
|
|
28662
|
+
const data = await resp.json();
|
|
28663
|
+
const contentBlocks = data.content ?? [];
|
|
28664
|
+
const usage = data.usage;
|
|
28665
|
+
let textContent = "";
|
|
28666
|
+
const toolCalls = [];
|
|
28667
|
+
for (const block of contentBlocks) {
|
|
28668
|
+
if (block.type === "text") {
|
|
28669
|
+
textContent += block.text ?? "";
|
|
28670
|
+
} else if (block.type === "tool_use") {
|
|
28671
|
+
toolCalls.push({
|
|
28672
|
+
id: block.id || crypto.randomUUID(),
|
|
28673
|
+
name: block.name,
|
|
28674
|
+
arguments: block.input ?? {}
|
|
28675
|
+
});
|
|
28676
|
+
}
|
|
28677
|
+
}
|
|
28678
|
+
return {
|
|
28679
|
+
choices: [{
|
|
28680
|
+
message: {
|
|
28681
|
+
content: textContent || null,
|
|
28682
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0
|
|
28683
|
+
}
|
|
28684
|
+
}],
|
|
28685
|
+
usage: usage ? {
|
|
28686
|
+
totalTokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
|
|
28687
|
+
promptTokens: usage.input_tokens,
|
|
28688
|
+
completionTokens: usage.output_tokens
|
|
28689
|
+
} : void 0
|
|
28690
|
+
};
|
|
28691
|
+
}
|
|
28577
28692
|
/**
|
|
28578
28693
|
* SSE streaming variant — yields StreamChunks as tokens arrive.
|
|
28579
28694
|
* Uses `stream: true` and the current thinking setting.
|
|
@@ -38613,9 +38728,15 @@ async function fetchOllamaModels(baseUrl) {
|
|
|
38613
38728
|
async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
38614
38729
|
const normalized = normalizeBaseUrl(baseUrl);
|
|
38615
38730
|
const url = `${normalized}/v1/models`;
|
|
38731
|
+
const isAnthropic = /api\.anthropic\.com/i.test(baseUrl);
|
|
38616
38732
|
const headers = {};
|
|
38617
38733
|
if (apiKey) {
|
|
38618
|
-
|
|
38734
|
+
if (isAnthropic) {
|
|
38735
|
+
headers["x-api-key"] = apiKey;
|
|
38736
|
+
headers["anthropic-version"] = "2023-06-01";
|
|
38737
|
+
} else {
|
|
38738
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
38739
|
+
}
|
|
38619
38740
|
}
|
|
38620
38741
|
const resp = await fetch(url, {
|
|
38621
38742
|
headers,
|
|
@@ -50202,7 +50323,12 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
50202
50323
|
const healthUrl = `${normalizedUrl}${provider.modelsPath}`;
|
|
50203
50324
|
const headers = {};
|
|
50204
50325
|
if (apiKey) {
|
|
50205
|
-
|
|
50326
|
+
if (provider.id === "anthropic") {
|
|
50327
|
+
headers["x-api-key"] = apiKey;
|
|
50328
|
+
headers["anthropic-version"] = "2023-06-01";
|
|
50329
|
+
} else {
|
|
50330
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
50331
|
+
}
|
|
50206
50332
|
}
|
|
50207
50333
|
const resp = await fetch(healthUrl, {
|
|
50208
50334
|
headers,
|
|
@@ -65099,6 +65225,7 @@ async function startInteractive(config, repoPath) {
|
|
|
65099
65225
|
initOaDirectory(repoRoot);
|
|
65100
65226
|
const savedSettings = resolveSettings(repoRoot);
|
|
65101
65227
|
if (process.stdout.isTTY) {
|
|
65228
|
+
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
65102
65229
|
process.stdout.write("\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?1015l\x1B[?1049h\x1B[48;5;233m\x1B[2J\x1B[3J\x1B[H\x1B[?25l");
|
|
65103
65230
|
const restoreScreen = () => {
|
|
65104
65231
|
process.stdout.write("\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?1015l\x1B[?25h\x1B[?1049l");
|
package/package.json
CHANGED