atlarix 15.8.2 → 15.9.0
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.
|
@@ -9587,6 +9587,10 @@ var init_schema = __esm({
|
|
|
9587
9587
|
name: text("name").notNull(),
|
|
9588
9588
|
api_base_url: text("api_base_url").notNull(),
|
|
9589
9589
|
env_var_name: text("env_var_name"),
|
|
9590
|
+
/** Wire format: null / "openai" = OpenAI-compatible, "anthropic" = Messages API. */
|
|
9591
|
+
api_format: text("api_format"),
|
|
9592
|
+
/** How the key is sent: null = the format's usual header, or "x-api-key" / "bearer". */
|
|
9593
|
+
auth_header: text("auth_header"),
|
|
9590
9594
|
createdAt: integer("created_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`),
|
|
9591
9595
|
updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`)
|
|
9592
9596
|
}
|
|
@@ -10911,6 +10915,14 @@ var init_usage_stats = __esm({
|
|
|
10911
10915
|
}
|
|
10912
10916
|
});
|
|
10913
10917
|
|
|
10918
|
+
// raw-file:/home/runner/work/Atlarix/Atlarix/drizzle/0080_custom_provider_api_format.sql
|
|
10919
|
+
var custom_provider_api_format_default;
|
|
10920
|
+
var init_custom_provider_api_format = __esm({
|
|
10921
|
+
"raw-file:/home/runner/work/Atlarix/Atlarix/drizzle/0080_custom_provider_api_format.sql"() {
|
|
10922
|
+
custom_provider_api_format_default = "-- The wire format a provider the user added speaks, and how it takes the key.\n--\n-- A custom provider could only be OpenAI-compatible. Many endpoints serve the\n-- Anthropic Messages API instead (Bedrock's /anthropic, gateways, proxies), and\n-- those take the key either as `x-api-key` or as `Authorization: Bearer`.\n--\n-- Additive only (two nullable columns, null = OpenAI-compatible with its usual\n-- Bearer key): an older reader ignores them, so min_reader stays where it is.\nALTER TABLE `language_model_providers` ADD `api_format` text;--> statement-breakpoint\nALTER TABLE `language_model_providers` ADD `auth_header` text;\n";
|
|
10923
|
+
}
|
|
10924
|
+
});
|
|
10925
|
+
|
|
10914
10926
|
// src/db/migrations/bundled.generated.ts
|
|
10915
10927
|
var BUNDLED_MIGRATIONS, DRIZZLE_HASH_TO_NAME;
|
|
10916
10928
|
var init_bundled_generated = __esm({
|
|
@@ -10995,6 +11007,7 @@ var init_bundled_generated = __esm({
|
|
|
10995
11007
|
init_automation_leases();
|
|
10996
11008
|
init_mcp_headers();
|
|
10997
11009
|
init_usage_stats();
|
|
11010
|
+
init_custom_provider_api_format();
|
|
10998
11011
|
BUNDLED_MIGRATIONS = [
|
|
10999
11012
|
{ name: "0000_nebulous_proemial_gods", sql: nebulous_proemial_gods_default, drizzleHash: "2fd0348e72ac1429b9246311e8db17a34078771470c622a13ab09afdee0a0d31", when: 1744692127560 },
|
|
11000
11013
|
{ name: "0001_hesitant_roland_deschain", sql: hesitant_roland_deschain_default, drizzleHash: "b9b37284db688cf3aaaa2719dda788238fd216933d3756c0482f26b5343d0059", when: 1744999922420 },
|
|
@@ -11075,7 +11088,8 @@ var init_bundled_generated = __esm({
|
|
|
11075
11088
|
{ name: "0076_drop_installed_skills", sql: drop_installed_skills_default, drizzleHash: "b361a2b664ce74a3efeaa2f73cdf6de582509c6569a1aab54febbef507b98b3c", when: 17877024e5 },
|
|
11076
11089
|
{ name: "0077_automation_leases", sql: automation_leases_default, drizzleHash: "22f09427b49eb0fcdd2b62cd472735a88e5dd60974af0d0c008f6e6fddfdf545", when: 17877888e5 },
|
|
11077
11090
|
{ name: "0078_mcp_headers", sql: mcp_headers_default, drizzleHash: "2e2b040eac31e336e8e7662555fd8526e8cdfd59929671e9ca6e063a3f2d4004", when: 17878752e5 },
|
|
11078
|
-
{ name: "0079_usage_stats", sql: usage_stats_default, drizzleHash: "8ea9653e8339a4f4c4f0fb140766daace073443ed9e6efae3d4597b2fc6bd60d", when: 17879616e5 }
|
|
11091
|
+
{ name: "0079_usage_stats", sql: usage_stats_default, drizzleHash: "8ea9653e8339a4f4c4f0fb140766daace073443ed9e6efae3d4597b2fc6bd60d", when: 17879616e5 },
|
|
11092
|
+
{ name: "0080_custom_provider_api_format", sql: custom_provider_api_format_default, drizzleHash: "0c66aed1a57dea6a1e9925a9a74dc1ca4f181db3de0c8e446a860a9f3ef7b950", when: 1788048e6 }
|
|
11079
11093
|
];
|
|
11080
11094
|
DRIZZLE_HASH_TO_NAME = {
|
|
11081
11095
|
"2fd0348e72ac1429b9246311e8db17a34078771470c622a13ab09afdee0a0d31": "0000_nebulous_proemial_gods",
|
|
@@ -11157,7 +11171,8 @@ var init_bundled_generated = __esm({
|
|
|
11157
11171
|
"b361a2b664ce74a3efeaa2f73cdf6de582509c6569a1aab54febbef507b98b3c": "0076_drop_installed_skills",
|
|
11158
11172
|
"22f09427b49eb0fcdd2b62cd472735a88e5dd60974af0d0c008f6e6fddfdf545": "0077_automation_leases",
|
|
11159
11173
|
"2e2b040eac31e336e8e7662555fd8526e8cdfd59929671e9ca6e063a3f2d4004": "0078_mcp_headers",
|
|
11160
|
-
"8ea9653e8339a4f4c4f0fb140766daace073443ed9e6efae3d4597b2fc6bd60d": "0079_usage_stats"
|
|
11174
|
+
"8ea9653e8339a4f4c4f0fb140766daace073443ed9e6efae3d4597b2fc6bd60d": "0079_usage_stats",
|
|
11175
|
+
"0c66aed1a57dea6a1e9925a9a74dc1ca4f181db3de0c8e446a860a9f3ef7b950": "0080_custom_provider_api_format"
|
|
11161
11176
|
};
|
|
11162
11177
|
}
|
|
11163
11178
|
});
|
|
@@ -31811,7 +31826,26 @@ function renderModeSystemBlock(activeMode) {
|
|
|
31811
31826
|
lines.push("</mode_system>");
|
|
31812
31827
|
return lines.join("\n");
|
|
31813
31828
|
}
|
|
31814
|
-
|
|
31829
|
+
function joinSystemPromptParts({ stableHeader, dynamicTail }) {
|
|
31830
|
+
return `${stableHeader}
|
|
31831
|
+
|
|
31832
|
+
${dynamicTail}
|
|
31833
|
+
`;
|
|
31834
|
+
}
|
|
31835
|
+
function splitDynamicTail(systemPrompt, dynamicTail) {
|
|
31836
|
+
if (!dynamicTail?.trim()) return systemPrompt;
|
|
31837
|
+
const joined = `
|
|
31838
|
+
|
|
31839
|
+
${dynamicTail}
|
|
31840
|
+
`;
|
|
31841
|
+
const at2 = systemPrompt.indexOf(joined);
|
|
31842
|
+
if (at2 < 0) return systemPrompt;
|
|
31843
|
+
return {
|
|
31844
|
+
systemPromptOverride: systemPrompt.slice(0, at2) + systemPrompt.slice(at2 + joined.length),
|
|
31845
|
+
dynamicSystemTail: dynamicTail
|
|
31846
|
+
};
|
|
31847
|
+
}
|
|
31848
|
+
async function buildSystemPromptPartsWithProjectInstructions(params) {
|
|
31815
31849
|
const {
|
|
31816
31850
|
workspacePath,
|
|
31817
31851
|
workspacePromptContent,
|
|
@@ -31840,7 +31874,7 @@ async function buildSystemPromptWithProjectInstructions(params) {
|
|
|
31840
31874
|
buildInstructionsFromLayers(layers),
|
|
31841
31875
|
projectDocsHint
|
|
31842
31876
|
].filter((s3) => s3.trim().length > 0).join("\n\n");
|
|
31843
|
-
return
|
|
31877
|
+
return constructSystemPromptParts({
|
|
31844
31878
|
contextSize,
|
|
31845
31879
|
chatMode,
|
|
31846
31880
|
effectiveWorkMode,
|
|
@@ -31866,7 +31900,7 @@ async function buildSystemPromptWithProjectInstructions(params) {
|
|
|
31866
31900
|
registeredToolNames
|
|
31867
31901
|
});
|
|
31868
31902
|
}
|
|
31869
|
-
var import_electron_log10, logger8, cachedPromptShell, AGENTS_MD, loadAgentsFile, FALLBACK_AGENTS, getAgentsMdForContextSize, getAgentsMdForWorkMode, MODE_SYSTEM_DESCRIPTIONS, constructSystemPromptParts
|
|
31903
|
+
var import_electron_log10, logger8, cachedPromptShell, AGENTS_MD, loadAgentsFile, FALLBACK_AGENTS, getAgentsMdForContextSize, getAgentsMdForWorkMode, MODE_SYSTEM_DESCRIPTIONS, constructSystemPromptParts;
|
|
31870
31904
|
var init_system_prompt = __esm({
|
|
31871
31905
|
"src/prompts/system_prompt.ts"() {
|
|
31872
31906
|
import_electron_log10 = __toESM(require_src());
|
|
@@ -32047,13 +32081,6 @@ When you need clarification or a decision from the user (architecture choices, d
|
|
|
32047
32081
|
}
|
|
32048
32082
|
return { stableHeader, dynamicTail: tail };
|
|
32049
32083
|
};
|
|
32050
|
-
constructSystemPrompt = (params) => {
|
|
32051
|
-
const { stableHeader, dynamicTail } = constructSystemPromptParts(params);
|
|
32052
|
-
return `${stableHeader}
|
|
32053
|
-
|
|
32054
|
-
${dynamicTail}
|
|
32055
|
-
`;
|
|
32056
|
-
};
|
|
32057
32084
|
}
|
|
32058
32085
|
});
|
|
32059
32086
|
|
|
@@ -67768,7 +67795,11 @@ var init_provider_sdk_factories = __esm({
|
|
|
67768
67795
|
const provider = createOpenAI({ apiKey, ...baseURL ? { baseURL } : {} });
|
|
67769
67796
|
return baseURL ? provider(modelId) : provider.responses(modelId);
|
|
67770
67797
|
},
|
|
67771
|
-
|
|
67798
|
+
// Exactly one of apiKey / authToken: the SDK refuses both.
|
|
67799
|
+
"@ai-sdk/anthropic": ({ modelId, apiKey, baseURL, authHeader }) => createAnthropic({
|
|
67800
|
+
...authHeader === "bearer" ? { authToken: apiKey } : { apiKey },
|
|
67801
|
+
...baseURL ? { baseURL } : {}
|
|
67802
|
+
})(modelId),
|
|
67772
67803
|
"@ai-sdk/google": ({ modelId, apiKey, baseURL }) => createGoogle({ apiKey, ...baseURL ? { baseURL } : {} })(modelId),
|
|
67773
67804
|
"@ai-sdk/xai": ({ modelId, apiKey, baseURL }) => createXai({ apiKey, ...baseURL ? { baseURL } : {} })(modelId)
|
|
67774
67805
|
};
|
|
@@ -68427,7 +68458,7 @@ var init_model_reasoning_profile = __esm({
|
|
|
68427
68458
|
temperatureById = /* @__PURE__ */ new Map();
|
|
68428
68459
|
effortOverrides = /* @__PURE__ */ new Map();
|
|
68429
68460
|
BUDGET_LEVELS = ["low", "medium", "high"];
|
|
68430
|
-
BUDGET_HINT = { low: "
|
|
68461
|
+
BUDGET_HINT = { low: "low", medium: "medium", high: "max" };
|
|
68431
68462
|
NO_REASONING = /* @__PURE__ */ new Set(["none", "minimal"]);
|
|
68432
68463
|
AUTO_EFFORT_LEVELS = ["low", "medium", "max"];
|
|
68433
68464
|
AUTO_EFFORT_CHOICES = { kind: "effort", levels: [...AUTO_EFFORT_LEVELS], defaultLevel: "medium" };
|
|
@@ -68963,6 +68994,18 @@ var init_models_dev = __esm({
|
|
|
68963
68994
|
}
|
|
68964
68995
|
});
|
|
68965
68996
|
|
|
68997
|
+
// src/lib/provider-key-check.ts
|
|
68998
|
+
function anthropicHeaders(apiKey, authHeader) {
|
|
68999
|
+
return {
|
|
69000
|
+
...authHeader === "bearer" ? { Authorization: `Bearer ${apiKey}` } : { "x-api-key": apiKey },
|
|
69001
|
+
"anthropic-version": "2023-06-01"
|
|
69002
|
+
};
|
|
69003
|
+
}
|
|
69004
|
+
var init_provider_key_check = __esm({
|
|
69005
|
+
"src/lib/provider-key-check.ts"() {
|
|
69006
|
+
}
|
|
69007
|
+
});
|
|
69008
|
+
|
|
68966
69009
|
// node_modules/isexe/windows.js
|
|
68967
69010
|
var require_windows = __commonJS({
|
|
68968
69011
|
"node_modules/isexe/windows.js"(exports2, module2) {
|
|
@@ -71123,21 +71166,22 @@ async function fetchModelsFromOpenAI(apiKey) {
|
|
|
71123
71166
|
return [];
|
|
71124
71167
|
}
|
|
71125
71168
|
}
|
|
71126
|
-
async function fetchModelsFromAnthropic(apiKey) {
|
|
71127
|
-
const
|
|
71169
|
+
async function fetchModelsFromAnthropic(apiKey, endpoint2) {
|
|
71170
|
+
const cacheId = endpoint2?.providerId ?? "anthropic";
|
|
71171
|
+
const label = endpoint2 ? endpoint2.providerId : "Anthropic";
|
|
71172
|
+
const cached4 = fromCache(cacheId);
|
|
71128
71173
|
if (cached4) return cached4;
|
|
71129
71174
|
try {
|
|
71130
71175
|
const items = [];
|
|
71131
71176
|
let after2;
|
|
71132
71177
|
for (let page = 0; page < MAX_PAGES; page++) {
|
|
71133
|
-
const url2 = new URL(
|
|
71178
|
+
const url2 = new URL(
|
|
71179
|
+
endpoint2 ? `${endpoint2.baseUrl.replace(/\/+$/, "")}/models` : "https://api.anthropic.com/v1/models"
|
|
71180
|
+
);
|
|
71134
71181
|
url2.searchParams.set("limit", "1000");
|
|
71135
71182
|
if (after2) url2.searchParams.set("after_id", after2);
|
|
71136
71183
|
const res = await fetch(url2, {
|
|
71137
|
-
headers:
|
|
71138
|
-
"x-api-key": apiKey,
|
|
71139
|
-
"anthropic-version": "2023-06-01"
|
|
71140
|
-
},
|
|
71184
|
+
headers: anthropicHeaders(apiKey, endpoint2?.authHeader),
|
|
71141
71185
|
signal: AbortSignal.timeout(15e3)
|
|
71142
71186
|
});
|
|
71143
71187
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
@@ -71149,18 +71193,18 @@ async function fetchModelsFromAnthropic(apiKey) {
|
|
|
71149
71193
|
const models = items.map((m3) => ({
|
|
71150
71194
|
apiName: m3.id,
|
|
71151
71195
|
displayName: m3.display_name ?? m3.id,
|
|
71152
|
-
description: "Claude model with tool support",
|
|
71196
|
+
description: endpoint2 ? "Chat model with tool support" : "Claude model with tool support",
|
|
71153
71197
|
...m3.max_input_tokens ? { contextWindow: m3.max_input_tokens } : {},
|
|
71154
71198
|
...m3.max_tokens ? { maxOutputTokens: m3.max_tokens } : {},
|
|
71155
71199
|
type: "cloud",
|
|
71156
71200
|
supportsToolChoice: true
|
|
71157
71201
|
}));
|
|
71158
71202
|
sortModels(models);
|
|
71159
|
-
toCache(
|
|
71160
|
-
logger10.info(`[
|
|
71203
|
+
toCache(cacheId, models);
|
|
71204
|
+
logger10.info(`[${label}] Fetched ${models.length} models`);
|
|
71161
71205
|
return models;
|
|
71162
71206
|
} catch (e3) {
|
|
71163
|
-
logger10.warn(
|
|
71207
|
+
logger10.warn(`[${label}] Fetch failed`, e3);
|
|
71164
71208
|
return [];
|
|
71165
71209
|
}
|
|
71166
71210
|
}
|
|
@@ -71363,7 +71407,14 @@ async function fetchModelsFromOpenRouter(apiKey) {
|
|
|
71363
71407
|
return [];
|
|
71364
71408
|
}
|
|
71365
71409
|
}
|
|
71366
|
-
async function fetchCustomProviderModels(providerId, baseUrl, apiKey) {
|
|
71410
|
+
async function fetchCustomProviderModels(providerId, baseUrl, apiKey, wire = {}) {
|
|
71411
|
+
if (wire.apiFormat === "anthropic") {
|
|
71412
|
+
return fetchModelsFromAnthropic(apiKey?.trim() || "none", {
|
|
71413
|
+
providerId,
|
|
71414
|
+
baseUrl,
|
|
71415
|
+
authHeader: wire.authHeader
|
|
71416
|
+
});
|
|
71417
|
+
}
|
|
71367
71418
|
return fetchOpenAICompatibleModels({
|
|
71368
71419
|
providerId,
|
|
71369
71420
|
url: `${baseUrl.replace(/\/+$/, "")}/models`,
|
|
@@ -71434,6 +71485,7 @@ var init_provider_model_fetchers = __esm({
|
|
|
71434
71485
|
import_electron_log12 = __toESM(require_src());
|
|
71435
71486
|
init_openrouter_app_headers();
|
|
71436
71487
|
init_language_model_constants();
|
|
71488
|
+
init_provider_key_check();
|
|
71437
71489
|
logger10 = import_electron_log12.default.scope("provider_fetchers");
|
|
71438
71490
|
CACHE_MS = 5 * 60 * 1e3;
|
|
71439
71491
|
cache = /* @__PURE__ */ new Map();
|
|
@@ -71560,6 +71612,29 @@ var init_provider_api_keys = __esm({
|
|
|
71560
71612
|
}
|
|
71561
71613
|
});
|
|
71562
71614
|
|
|
71615
|
+
// src/lib/routing/custom-provider-format.ts
|
|
71616
|
+
function rememberCustomProviderFormats(providers) {
|
|
71617
|
+
anthropicFormat.clear();
|
|
71618
|
+
for (const p2 of providers) {
|
|
71619
|
+
if (p2.apiFormat === "anthropic") anthropicFormat.add(p2.id);
|
|
71620
|
+
}
|
|
71621
|
+
}
|
|
71622
|
+
function isCustomAnthropicFormat(providerId) {
|
|
71623
|
+
return Boolean(providerId && anthropicFormat.has(providerId));
|
|
71624
|
+
}
|
|
71625
|
+
function anthropicFormatCapabilityId(providerId) {
|
|
71626
|
+
return isCustomAnthropicFormat(providerId) ? "anthropic" : providerId;
|
|
71627
|
+
}
|
|
71628
|
+
function anthropicCatalogModelId(modelId) {
|
|
71629
|
+
return modelId.trim().replace(/^(?:[a-z]{2,6}\.)?anthropic\./i, "").replace(/-v\d+(?::\d+)?$/i, "");
|
|
71630
|
+
}
|
|
71631
|
+
var anthropicFormat;
|
|
71632
|
+
var init_custom_provider_format = __esm({
|
|
71633
|
+
"src/lib/routing/custom-provider-format.ts"() {
|
|
71634
|
+
anthropicFormat = /* @__PURE__ */ new Set();
|
|
71635
|
+
}
|
|
71636
|
+
});
|
|
71637
|
+
|
|
71563
71638
|
// src/ipc/utils/thinking_utils.ts
|
|
71564
71639
|
function reasoningCeiling(providerId) {
|
|
71565
71640
|
return providerId && PROVIDERS_THAT_SUPPORT_THINKING.includes(providerId) ? "max" : "high";
|
|
@@ -71583,7 +71658,7 @@ function reasoningBudgetTokens(effort, maxOutputTokens) {
|
|
|
71583
71658
|
const max4 = Math.max(1, Math.floor(maxOutputTokens));
|
|
71584
71659
|
const reserve = Math.max(Math.round(max4 * 0.15), 2048);
|
|
71585
71660
|
const ceil = Math.max(1024, max4 - reserve);
|
|
71586
|
-
const frac = effort === "max" ? 0.85 : effort === "xhigh" ? 0.7 : effort === "high" ? 0.5 : 0.33;
|
|
71661
|
+
const frac = effort === "max" ? 0.85 : effort === "xhigh" ? 0.7 : effort === "high" ? 0.5 : effort === "low" ? 0.15 : 0.33;
|
|
71587
71662
|
return Math.min(ceil, Math.max(1024, Math.round(max4 * frac)));
|
|
71588
71663
|
}
|
|
71589
71664
|
function getExtraProviderOptions(providerId, settings, includeExtendedThinking = false, maxOutputTokens, modelId) {
|
|
@@ -71667,6 +71742,9 @@ function resolveReasoningCatalogModelId(effectiveModel) {
|
|
|
71667
71742
|
if (effectiveModel.provider === "compass") {
|
|
71668
71743
|
return getCoreModelsDevTargetForTier(name29)?.modelId ?? getCoreModelIdForCoreTier(name29) ?? name29;
|
|
71669
71744
|
}
|
|
71745
|
+
if (isCustomAnthropicFormat(effectiveModel.provider)) {
|
|
71746
|
+
return anthropicCatalogModelId(name29);
|
|
71747
|
+
}
|
|
71670
71748
|
return name29;
|
|
71671
71749
|
}
|
|
71672
71750
|
function resolveMediaModelId(effectiveModel) {
|
|
@@ -71677,13 +71755,13 @@ function resolveMediaModelId(effectiveModel) {
|
|
|
71677
71755
|
}
|
|
71678
71756
|
function resolveCapabilityProviderId(effectiveModel) {
|
|
71679
71757
|
const provider = (effectiveModel.provider ?? "").trim();
|
|
71680
|
-
if (provider !== "compass") return provider;
|
|
71758
|
+
if (provider !== "compass") return anthropicFormatCapabilityId(provider);
|
|
71681
71759
|
return getCoreModelsDevTargetForTier(effectiveModel.name ?? "")?.providerId ?? provider;
|
|
71682
71760
|
}
|
|
71683
71761
|
function detectReasoningCapability(modelApiId, builtinProviderId) {
|
|
71684
71762
|
const id = modelApiId.trim();
|
|
71685
71763
|
const lower2 = id.toLowerCase();
|
|
71686
|
-
const pid = builtinProviderId ?? "";
|
|
71764
|
+
const pid = anthropicFormatCapabilityId(builtinProviderId) ?? "";
|
|
71687
71765
|
let useOpenRouterReasoning = false;
|
|
71688
71766
|
if (pid === "openrouter" || pid === "compass") {
|
|
71689
71767
|
const row = id.includes("/") ? getCachedOpenRouterModelRow(id) : void 0;
|
|
@@ -71737,7 +71815,7 @@ function isReasoningCapableModel(model) {
|
|
|
71737
71815
|
return offersAChannel(capabilityProvider) || offersAChannel(model.provider ?? "");
|
|
71738
71816
|
}
|
|
71739
71817
|
function resolveDispatchCapabilityProviderId(effectiveModel, builtinProviderId) {
|
|
71740
|
-
if (builtinProviderId !== "compass") return builtinProviderId;
|
|
71818
|
+
if (builtinProviderId !== "compass") return anthropicFormatCapabilityId(builtinProviderId);
|
|
71741
71819
|
if (effectiveModel.provider !== "compass") return builtinProviderId;
|
|
71742
71820
|
return resolveCapabilityProviderId(effectiveModel);
|
|
71743
71821
|
}
|
|
@@ -71833,6 +71911,7 @@ var init_reasoning_detector = __esm({
|
|
|
71833
71911
|
init_model_capability_profile();
|
|
71834
71912
|
init_language_model_constants();
|
|
71835
71913
|
init_model_reasoning_profile();
|
|
71914
|
+
init_custom_provider_format();
|
|
71836
71915
|
init_thinking_utils();
|
|
71837
71916
|
GEMINI_LEVELS = /* @__PURE__ */ new Set(["minimal", "low", "medium", "high"]);
|
|
71838
71917
|
}
|
|
@@ -72009,11 +72088,16 @@ async function getLanguageModelProviders() {
|
|
|
72009
72088
|
name: cp.name,
|
|
72010
72089
|
apiBaseUrl: cp.api_base_url,
|
|
72011
72090
|
envVarName: cp.env_var_name ?? void 0,
|
|
72091
|
+
// The Anthropic format dispatches through the catalog's own Anthropic SDK
|
|
72092
|
+
// factory (provider-sdk-factories), like any models.dev provider on it.
|
|
72093
|
+
...cp.api_format === "anthropic" ? { apiFormat: "anthropic", npm: ANTHROPIC_NPM } : {},
|
|
72094
|
+
...cp.auth_header === "x-api-key" || cp.auth_header === "bearer" ? { authHeader: cp.auth_header } : {},
|
|
72012
72095
|
type: "custom"
|
|
72013
72096
|
// hasFreeTier, websiteUrl, gatewayPrefix are not in the custom DB schema
|
|
72014
72097
|
// They will be undefined unless overridden by hardcoded values if IDs match
|
|
72015
72098
|
});
|
|
72016
72099
|
}
|
|
72100
|
+
rememberCustomProviderFormats([...customProvidersMap.values()]);
|
|
72017
72101
|
const catalogById = /* @__PURE__ */ new Map();
|
|
72018
72102
|
try {
|
|
72019
72103
|
for (const c2 of await getModelsDevProviderCatalog())
|
|
@@ -72100,15 +72184,15 @@ function providerDisplayName(providerId) {
|
|
|
72100
72184
|
if (!providerId) return void 0;
|
|
72101
72185
|
return providerNames.get(providerId) ?? providerId.replace(/^custom::/, "");
|
|
72102
72186
|
}
|
|
72103
|
-
async function liveCustomModels(providerId, baseUrl, apiKey, now2 = Date.now()) {
|
|
72187
|
+
async function liveCustomModels(providerId, baseUrl, apiKey, now2 = Date.now(), wire = {}) {
|
|
72104
72188
|
const { createHash: createHash10 } = await import("node:crypto");
|
|
72105
72189
|
const keyTag = apiKey?.trim() ? createHash10("sha256").update(apiKey.trim()).digest("hex").slice(0, 12) : "none";
|
|
72106
|
-
const cacheKey = `${providerId}|${baseUrl}|${keyTag}`;
|
|
72190
|
+
const cacheKey = `${providerId}|${baseUrl}|${keyTag}|${wire.apiFormat ?? "openai"}|${wire.authHeader ?? ""}`;
|
|
72107
72191
|
const hit = liveCache.get(cacheKey);
|
|
72108
72192
|
if (hit && now2 - hit.at < LIVE_TTL_MS) return hit.models;
|
|
72109
72193
|
const { fetchCustomProviderModels: fetchCustomProviderModels2 } = await Promise.resolve().then(() => (init_provider_model_fetchers(), provider_model_fetchers_exports));
|
|
72110
72194
|
const models = Promise.race([
|
|
72111
|
-
fetchCustomProviderModels2(providerId, baseUrl, apiKey).catch(
|
|
72195
|
+
fetchCustomProviderModels2(providerId, baseUrl, apiKey, wire).catch(
|
|
72112
72196
|
() => []
|
|
72113
72197
|
),
|
|
72114
72198
|
new Promise(
|
|
@@ -72141,7 +72225,10 @@ async function getLanguageModels({
|
|
|
72141
72225
|
maxOutputTokens: language_models.max_output_tokens,
|
|
72142
72226
|
contextWindow: language_models.context_window
|
|
72143
72227
|
}).from(language_models).where(
|
|
72144
|
-
|
|
72228
|
+
// A provider from the providers table, whatever its id: the CLI's dev
|
|
72229
|
+
// endpoint is `atlarix-cli-dev`, with no `custom::`, and its model row
|
|
72230
|
+
// was looked up as a built-in's and never found (QA B3).
|
|
72231
|
+
provider.type === "custom" || isCustomProvider({ providerId }) ? eq(language_models.customProviderId, providerId) : eq(language_models.builtinProviderId, providerId)
|
|
72145
72232
|
);
|
|
72146
72233
|
customModels = customModelsDb.map((model) => ({
|
|
72147
72234
|
...model,
|
|
@@ -72202,7 +72289,10 @@ async function getLanguageModels({
|
|
|
72202
72289
|
key = readSettings2().providerSettings?.[providerId]?.apiKey?.value;
|
|
72203
72290
|
} catch {
|
|
72204
72291
|
}
|
|
72205
|
-
const listed = await liveCustomModels(providerId, provider.apiBaseUrl, key)
|
|
72292
|
+
const listed = await liveCustomModels(providerId, provider.apiBaseUrl, key, Date.now(), {
|
|
72293
|
+
apiFormat: provider.apiFormat,
|
|
72294
|
+
authHeader: provider.authHeader
|
|
72295
|
+
});
|
|
72206
72296
|
const typed = new Set(customModels.map((m3) => m3.apiName));
|
|
72207
72297
|
return [...customModels, ...listed.filter((m3) => !typed.has(m3.apiName))];
|
|
72208
72298
|
}
|
|
@@ -72313,7 +72403,7 @@ function stampDeepThinkingSupport(modelsByProvider) {
|
|
|
72313
72403
|
function isCustomProvider({ providerId }) {
|
|
72314
72404
|
return providerId.startsWith(CUSTOM_PROVIDER_PREFIX);
|
|
72315
72405
|
}
|
|
72316
|
-
var providerNames, LIVE_TTL_MS, liveCache, CUSTOM_PROVIDER_PREFIX;
|
|
72406
|
+
var ANTHROPIC_NPM, providerNames, LIVE_TTL_MS, liveCache, CUSTOM_PROVIDER_PREFIX;
|
|
72317
72407
|
var init_language_model_helpers = __esm({
|
|
72318
72408
|
"src/ipc/shared/language_model_helpers.ts"() {
|
|
72319
72409
|
init_db2();
|
|
@@ -72328,6 +72418,8 @@ var init_language_model_helpers = __esm({
|
|
|
72328
72418
|
init_compass_constants();
|
|
72329
72419
|
init_reasoning_detector();
|
|
72330
72420
|
init_model_capability_profile();
|
|
72421
|
+
init_custom_provider_format();
|
|
72422
|
+
ANTHROPIC_NPM = "@ai-sdk/anthropic";
|
|
72331
72423
|
providerNames = /* @__PURE__ */ new Map();
|
|
72332
72424
|
LIVE_TTL_MS = 6e4;
|
|
72333
72425
|
liveCache = /* @__PURE__ */ new Map();
|
|
@@ -95745,7 +95837,8 @@ async function resolveModelContextLimit(model, settings) {
|
|
|
95745
95837
|
if (pid.startsWith("custom::")) {
|
|
95746
95838
|
try {
|
|
95747
95839
|
const { getLanguageModelProviders: getLanguageModelProviders2 } = await Promise.resolve().then(() => (init_language_model_helpers(), language_model_helpers_exports));
|
|
95748
|
-
const
|
|
95840
|
+
const custom2 = (await getLanguageModelProviders2()).find((p2) => p2.id.toLowerCase() === pid);
|
|
95841
|
+
const base = custom2?.apiFormat === "anthropic" ? void 0 : custom2?.apiBaseUrl;
|
|
95749
95842
|
if (base) {
|
|
95750
95843
|
const { isOllamaEndpoint: isOllamaEndpoint2, ollamaOrigin: ollamaOrigin2, ollamaNumCtx: ollamaNumCtx2 } = await Promise.resolve().then(() => (init_ollama_native_fetch(), ollama_native_fetch_exports));
|
|
95751
95844
|
if (await isOllamaEndpoint2(base)) {
|
|
@@ -95768,10 +95861,7 @@ async function resolveModelContextLimit(model, settings) {
|
|
|
95768
95861
|
}
|
|
95769
95862
|
try {
|
|
95770
95863
|
const { getModelsDevLimits: getModelsDevLimits2 } = await Promise.resolve().then(() => (init_models_dev(), models_dev_exports));
|
|
95771
|
-
const limits = await getModelsDevLimits2(
|
|
95772
|
-
model.provider ?? "",
|
|
95773
|
-
model.name ?? ""
|
|
95774
|
-
);
|
|
95864
|
+
const limits = isCustomAnthropicFormat(model.provider) ? await getModelsDevLimits2("anthropic", anthropicCatalogModelId(model.name ?? "")) : await getModelsDevLimits2(model.provider ?? "", model.name ?? "");
|
|
95775
95865
|
if (limits?.context && limits.context > 0) {
|
|
95776
95866
|
return {
|
|
95777
95867
|
tierLimit: floorSafe(limits.context * clamp),
|
|
@@ -95793,6 +95883,7 @@ var init_resolve_model_context_limit = __esm({
|
|
|
95793
95883
|
init_compass_constants();
|
|
95794
95884
|
init_findLanguageModel();
|
|
95795
95885
|
import_electron_log16 = __toESM(require_src());
|
|
95886
|
+
init_custom_provider_format();
|
|
95796
95887
|
logger14 = import_electron_log16.default.scope("context-limit");
|
|
95797
95888
|
SAFETY_FACTOR = 0.8;
|
|
95798
95889
|
localContextCache = /* @__PURE__ */ new Map();
|
|
@@ -215041,7 +215132,7 @@ async function getRegularModelClient(model, settings, providerConfig, options) {
|
|
|
215041
215132
|
};
|
|
215042
215133
|
}
|
|
215043
215134
|
default: {
|
|
215044
|
-
if (providerConfig.type === "custom" && providerConfig.apiBaseUrl) {
|
|
215135
|
+
if (providerConfig.type === "custom" && providerConfig.apiBaseUrl && providerConfig.apiFormat !== "anthropic") {
|
|
215045
215136
|
const { isOllamaEndpoint: isOllamaEndpoint2, ollamaOrigin: ollamaOrigin2 } = await Promise.resolve().then(() => (init_ollama_native_fetch(), ollama_native_fetch_exports));
|
|
215046
215137
|
if (await isOllamaEndpoint2(providerConfig.apiBaseUrl)) {
|
|
215047
215138
|
return {
|
|
@@ -215061,7 +215152,8 @@ async function getRegularModelClient(model, settings, providerConfig, options) {
|
|
|
215061
215152
|
modelId: model.name,
|
|
215062
215153
|
apiKey,
|
|
215063
215154
|
baseURL: providerConfig.apiBaseUrl,
|
|
215064
|
-
npm: providerConfig.npm
|
|
215155
|
+
npm: providerConfig.npm,
|
|
215156
|
+
authHeader: providerConfig.authHeader
|
|
215065
215157
|
}),
|
|
215066
215158
|
builtinProviderId: providerConfig.id
|
|
215067
215159
|
},
|
|
@@ -241873,6 +241965,7 @@ var init_dist21 = __esm({
|
|
|
241873
241965
|
function resolveCacheMarkerPlacement(builtinProviderId, modelName) {
|
|
241874
241966
|
if (builtinProviderId === "anthropic") return "message";
|
|
241875
241967
|
if (!/claude|anthropic/i.test(modelName ?? "")) return "none";
|
|
241968
|
+
if (isCustomAnthropicFormat(builtinProviderId)) return "message";
|
|
241876
241969
|
if (builtinProviderId === "bedrock" || builtinProviderId === "vertex") {
|
|
241877
241970
|
return "message";
|
|
241878
241971
|
}
|
|
@@ -241984,6 +242077,7 @@ function advanceCacheBreakpointsForStep(messages, placement) {
|
|
|
241984
242077
|
var CACHE_MARKER, CACHE_MARKER_HEADER_1H, CACHE_KEY_BY_PROVIDER;
|
|
241985
242078
|
var init_anthropic_cache_breakpoints = __esm({
|
|
241986
242079
|
"src/lib/ai/anthropic-cache-breakpoints.ts"() {
|
|
242080
|
+
init_custom_provider_format();
|
|
241987
242081
|
CACHE_MARKER = {
|
|
241988
242082
|
anthropic: { cacheControl: { type: "ephemeral" } },
|
|
241989
242083
|
openrouter: { cacheControl: { type: "ephemeral" } },
|
|
@@ -338396,7 +338490,8 @@ async function simpleStreamText(ctx, deps, {
|
|
|
338396
338490
|
...reasoningPatch.anthropic
|
|
338397
338491
|
};
|
|
338398
338492
|
}
|
|
338399
|
-
const handledNatively = offByBudget ||
|
|
338493
|
+
const handledNatively = offByBudget || // The Anthropic SDK reads only its own bucket, in its own shape.
|
|
338494
|
+
isCustomAnthropicFormat(modelClient.builtinProviderId) || Boolean(reasoningPatch.openrouter) || Boolean(reasoningPatch.google) || Boolean(reasoningPatch.openai) || Boolean(reasoningPatch.anthropic);
|
|
338400
338495
|
if (modelClient.builtinProviderId && !handledNatively) {
|
|
338401
338496
|
const compatibleReasoning = getExtraProviderOptions(
|
|
338402
338497
|
capabilityProviderId,
|
|
@@ -338415,6 +338510,7 @@ async function simpleStreamText(ctx, deps, {
|
|
|
338415
338510
|
}
|
|
338416
338511
|
}
|
|
338417
338512
|
const isAnthropic = modelClient.builtinProviderId === "anthropic";
|
|
338513
|
+
const speaksAnthropic = isAnthropic || isCustomAnthropicFormat(modelClient.builtinProviderId);
|
|
338418
338514
|
const cacheMarkerPlacement = resolveCacheMarkerPlacement(
|
|
338419
338515
|
modelClient.builtinProviderId,
|
|
338420
338516
|
effectiveModel?.name
|
|
@@ -338486,7 +338582,7 @@ async function simpleStreamText(ctx, deps, {
|
|
|
338486
338582
|
history,
|
|
338487
338583
|
placement: cacheMarkerPlacement,
|
|
338488
338584
|
// v13.3: header prefix survives >5min between-turn gaps.
|
|
338489
|
-
headerTtl1h:
|
|
338585
|
+
headerTtl1h: speaksAnthropic
|
|
338490
338586
|
});
|
|
338491
338587
|
const completedStepMessages = [];
|
|
338492
338588
|
const recordStepMessages = (msgs) => {
|
|
@@ -338935,6 +339031,7 @@ var init_simple_stream_text = __esm({
|
|
|
338935
339031
|
init_perf_marks();
|
|
338936
339032
|
init_byok_pricing();
|
|
338937
339033
|
init_reasoning_detector();
|
|
339034
|
+
init_custom_provider_format();
|
|
338938
339035
|
init_system_reminder();
|
|
338939
339036
|
init_step_messages();
|
|
338940
339037
|
init_texts();
|
|
@@ -343033,6 +343130,7 @@ async function runBuildBranch(ctx, deps) {
|
|
|
343033
343130
|
modelContextResolved,
|
|
343034
343131
|
placeholderAssistantMessage,
|
|
343035
343132
|
systemPrompt,
|
|
343133
|
+
dynamicTail,
|
|
343036
343134
|
taskLedgerBlock,
|
|
343037
343135
|
simpleStreamTextDeps,
|
|
343038
343136
|
streamTurnId,
|
|
@@ -344280,7 +344378,9 @@ async function runBuildBranch(ctx, deps) {
|
|
|
344280
344378
|
escalationMode: effectiveWorkMode === "plan" ? "plan" : effectiveWorkMode === "build" ? "build" : "agent",
|
|
344281
344379
|
tools,
|
|
344282
344380
|
repetition: agenticRepetition,
|
|
344283
|
-
|
|
344381
|
+
// The per-turn tail in its own system message, after the cached
|
|
344382
|
+
// header, so the next turn reads the cache instead of rewriting it.
|
|
344383
|
+
buildRoundSystemPrompt: () => splitDynamicTail(systemPrompt, dynamicTail),
|
|
344284
344384
|
detectTextToolCalls: (fr2) => useTextToolFallback && containsTextToolCall2(fr2) ? parseTextToolCalls2(fr2) : null,
|
|
344285
344385
|
executeTextToolCalls: (calls) => execBuildTextToolCalls(
|
|
344286
344386
|
calls
|
|
@@ -344423,6 +344523,7 @@ var init_build_branch = __esm({
|
|
|
344423
344523
|
init_dist21();
|
|
344424
344524
|
import_electron_log102 = __toESM(require_src());
|
|
344425
344525
|
init_edit_stats2();
|
|
344526
|
+
init_system_prompt();
|
|
344426
344527
|
logger99 = import_electron_log102.default.scope("chat_stream_handlers");
|
|
344427
344528
|
}
|
|
344428
344529
|
});
|
|
@@ -346470,11 +346571,11 @@ function registerChatStreamHandlers() {
|
|
|
346470
346571
|
providerBrand: modelIdentity.providerBrand,
|
|
346471
346572
|
labelWithProvider: modelIdentity.labelWithProvider
|
|
346472
346573
|
};
|
|
346473
|
-
let
|
|
346574
|
+
let baseParts;
|
|
346474
346575
|
if (hasWorkspace && appPath && effectiveAppId != null) {
|
|
346475
|
-
|
|
346576
|
+
baseParts = await preflight.time(
|
|
346476
346577
|
"system-prompt",
|
|
346477
|
-
() =>
|
|
346578
|
+
() => buildSystemPromptPartsWithProjectInstructions({
|
|
346478
346579
|
workspacePath: appPath,
|
|
346479
346580
|
workspacePromptContent: null,
|
|
346480
346581
|
contextSize,
|
|
@@ -346487,7 +346588,7 @@ function registerChatStreamHandlers() {
|
|
|
346487
346588
|
})
|
|
346488
346589
|
);
|
|
346489
346590
|
} else {
|
|
346490
|
-
|
|
346591
|
+
baseParts = constructSystemPromptParts({
|
|
346491
346592
|
chatMode,
|
|
346492
346593
|
effectiveWorkMode: modeBlockKey,
|
|
346493
346594
|
contextSize,
|
|
@@ -346497,6 +346598,8 @@ function registerChatStreamHandlers() {
|
|
|
346497
346598
|
...promptIdentityOpts
|
|
346498
346599
|
});
|
|
346499
346600
|
}
|
|
346601
|
+
let baseSystemPrompt = joinSystemPromptParts(baseParts);
|
|
346602
|
+
const baseDynamicTail = baseParts.dynamicTail;
|
|
346500
346603
|
if (activeUserAgent) {
|
|
346501
346604
|
const { renderUserAgentSystemBlock: renderUserAgentSystemBlock2 } = await Promise.resolve().then(() => (init_user_agents(), user_agents_exports));
|
|
346502
346605
|
baseSystemPrompt = `${renderUserAgentSystemBlock2(activeUserAgent)}
|
|
@@ -347006,6 +347109,7 @@ ${baseSystemPrompt}`;
|
|
|
347006
347109
|
modelContextResolved,
|
|
347007
347110
|
placeholderAssistantMessage,
|
|
347008
347111
|
systemPrompt,
|
|
347112
|
+
dynamicTail: baseDynamicTail,
|
|
347009
347113
|
taskLedgerBlock,
|
|
347010
347114
|
simpleStreamTextDeps,
|
|
347011
347115
|
streamTurnId,
|
|
@@ -347939,7 +348043,7 @@ ${err2.stack}` : "";
|
|
|
347939
348043
|
}
|
|
347940
348044
|
|
|
347941
348045
|
// src/headless/atlarix-headless.mts
|
|
347942
|
-
var VERSION15 = false ? "dev" : "15.
|
|
348046
|
+
var VERSION15 = false ? "dev" : "15.9.0";
|
|
347943
348047
|
if (process.argv[2] === "run") process.argv.splice(2, 1);
|
|
347944
348048
|
var RUN_HELP = `atlarix run: one turn without the UI, for scripts and CI
|
|
347945
348049
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atlarix",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.9.0",
|
|
4
4
|
"description": "Atlarix CLI: an AI coding agent in your terminal. Works with any model (Atlarix Auto, your own API key, or a local model) and runs unattended with `atlarix run` for CI.",
|
|
5
5
|
"license": "PROPRIETARY",
|
|
6
6
|
"author": {
|
|
@@ -65,12 +65,12 @@
|
|
|
65
65
|
"provenance": false
|
|
66
66
|
},
|
|
67
67
|
"optionalDependencies": {
|
|
68
|
-
"atlarix-darwin-arm64": "15.
|
|
69
|
-
"atlarix-darwin-x64": "15.
|
|
70
|
-
"atlarix-linux-x64": "15.
|
|
71
|
-
"atlarix-linux-arm64": "15.
|
|
72
|
-
"atlarix-linux-x64-musl": "15.
|
|
73
|
-
"atlarix-linux-arm64-musl": "15.
|
|
74
|
-
"atlarix-windows-x64": "15.
|
|
68
|
+
"atlarix-darwin-arm64": "15.9.0",
|
|
69
|
+
"atlarix-darwin-x64": "15.9.0",
|
|
70
|
+
"atlarix-linux-x64": "15.9.0",
|
|
71
|
+
"atlarix-linux-arm64": "15.9.0",
|
|
72
|
+
"atlarix-linux-x64-musl": "15.9.0",
|
|
73
|
+
"atlarix-linux-arm64-musl": "15.9.0",
|
|
74
|
+
"atlarix-windows-x64": "15.9.0"
|
|
75
75
|
}
|
|
76
76
|
}
|