@proxysoul/soulforge 2.18.3 → 2.18.5

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 CHANGED
@@ -3851,7 +3851,10 @@ function readJsonFile(path) {
3851
3851
  return null;
3852
3852
  }
3853
3853
  return JSON.parse(readFileSync5(path, "utf-8"));
3854
- } catch {
3854
+ } catch (err2) {
3855
+ const msg = err2 instanceof Error ? err2.message : String(err2);
3856
+ process.stderr.write(` Warning: invalid ${path} \u2014 ${msg}. Ignoring.
3857
+ `);
3855
3858
  return null;
3856
3859
  }
3857
3860
  }
@@ -5202,25 +5205,65 @@ function loadConfig() {
5202
5205
  if (!existsSync10(configDir2)) {
5203
5206
  mkdirSync8(configDir2, { recursive: true, mode: 448 });
5204
5207
  }
5205
- if (!existsSync10(configFile)) {
5206
- writeFileSync7(configFile, JSON.stringify(DEFAULT_CONFIG, null, 2));
5207
- if (!_presetOverlay)
5208
- return DEFAULT_CONFIG;
5209
- }
5210
5208
  let userConfig = {};
5211
- try {
5212
- userConfig = JSON.parse(readFileSync8(configFile, "utf-8"));
5213
- } catch (err2) {
5214
- logBackgroundError("config", `Failed to parse ${configFile}: ${err2 instanceof Error ? err2.message : String(err2)} \u2014 using defaults`);
5215
- if (!_presetOverlay)
5216
- return DEFAULT_CONFIG;
5209
+ let fileExists = existsSync10(configFile);
5210
+ if (!fileExists) {
5211
+ writeFileSync7(configFile, JSON.stringify(DEFAULT_CONFIG, null, 2));
5212
+ fileExists = true;
5213
+ } else {
5214
+ try {
5215
+ userConfig = JSON.parse(readFileSync8(configFile, "utf-8"));
5216
+ } catch (err2) {
5217
+ const msg = err2 instanceof Error ? err2.message : String(err2);
5218
+ process.stderr.write(`
5219
+ Error: invalid config.json \u2014 ${msg}
5220
+
5221
+ ` + ` Path: ${configFile}
5222
+
5223
+ ` + ` Fix the JSON syntax error and try again.
5224
+ ` + ` (Your config was NOT overwritten.)
5225
+
5226
+ `);
5227
+ process.exit(1);
5228
+ }
5217
5229
  }
5218
5230
  let merged = { ...DEFAULT_CONFIG };
5219
5231
  if (_presetOverlay)
5220
5232
  merged = applyConfigPatch(merged, _presetOverlay);
5221
- merged = { ...merged, ...userConfig };
5233
+ const userPatch = diffAgainstDefaults(userConfig);
5234
+ if (Object.keys(userPatch).length > 0) {
5235
+ merged = applyConfigPatch(merged, userPatch);
5236
+ }
5222
5237
  return merged;
5223
5238
  }
5239
+ function diffAgainstDefaults(userConfig) {
5240
+ const out2 = {};
5241
+ const defaults = DEFAULT_CONFIG;
5242
+ const nested = new Set(NESTED_KEYS);
5243
+ for (const [key, value] of Object.entries(userConfig)) {
5244
+ if (value === undefined)
5245
+ continue;
5246
+ const def = defaults[key];
5247
+ if (nested.has(key) && value && typeof value === "object" && !Array.isArray(value) && def && typeof def === "object" && !Array.isArray(def)) {
5248
+ const subPatch = {};
5249
+ const defRec = def;
5250
+ for (const [subKey, subValue] of Object.entries(value)) {
5251
+ if (subValue === undefined)
5252
+ continue;
5253
+ if (JSON.stringify(subValue) !== JSON.stringify(defRec[subKey])) {
5254
+ subPatch[subKey] = subValue;
5255
+ }
5256
+ }
5257
+ if (Object.keys(subPatch).length > 0)
5258
+ out2[key] = subPatch;
5259
+ continue;
5260
+ }
5261
+ if (JSON.stringify(value) !== JSON.stringify(def)) {
5262
+ out2[key] = value;
5263
+ }
5264
+ }
5265
+ return out2;
5266
+ }
5224
5267
  function loadProjectConfig(cwd) {
5225
5268
  const projectFile = join11(cwd, ".soulforge", "config.json");
5226
5269
  if (!existsSync10(projectFile))
@@ -5229,7 +5272,13 @@ function loadProjectConfig(cwd) {
5229
5272
  const raw = readFileSync8(projectFile, "utf-8");
5230
5273
  return JSON.parse(raw);
5231
5274
  } catch (err2) {
5232
- logBackgroundError("config", `Failed to parse ${projectFile}: ${err2 instanceof Error ? err2.message : String(err2)} \u2014 ignoring project config`);
5275
+ const msg = err2 instanceof Error ? err2.message : String(err2);
5276
+ process.stderr.write(`
5277
+ Warning: invalid project config.json \u2014 ${msg}
5278
+ ` + ` Path: ${projectFile}
5279
+ ` + ` Fix the JSON syntax error. Ignoring project config for now.
5280
+
5281
+ `);
5233
5282
  return null;
5234
5283
  }
5235
5284
  }
@@ -5360,7 +5409,6 @@ var DEFAULT_CONFIG, _presetOverlay = null, NESTED_KEYS;
5360
5409
  var init_config2 = __esm(() => {
5361
5410
  init_platform();
5362
5411
  init_ensure_soulforge_dir();
5363
- init_errors();
5364
5412
  DEFAULT_CONFIG = {
5365
5413
  defaultModel: "none",
5366
5414
  routerRules: [],
@@ -46796,6 +46844,13 @@ function supportsTemperature(modelId) {
46796
46844
  return true;
46797
46845
  return v.major < 5 && (v.major < 4 || v.minor < 7);
46798
46846
  }
46847
+ function isAdaptiveOnly(modelId) {
46848
+ const base = extractBaseModel(modelId);
46849
+ const v = parseOpusVersion(base);
46850
+ if (!v)
46851
+ return false;
46852
+ return v.major >= 5 || v.major === 4 && v.minor >= 7;
46853
+ }
46799
46854
 
46800
46855
  // src/utils/errors.ts
46801
46856
  function toErrorMessage(err2) {
@@ -51822,6 +51877,7 @@ var init_anthropic = __esm(() => {
51822
51877
  return result;
51823
51878
  },
51824
51879
  fallbackModels: [
51880
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8" },
51825
51881
  { id: "claude-opus-4-7", name: "Claude Opus 4.7" },
51826
51882
  { id: "claude-opus-4-6", name: "Claude Opus 4.6" },
51827
51883
  { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
@@ -51832,6 +51888,7 @@ var init_anthropic = __esm(() => {
51832
51888
  { id: "claude-haiku-4", name: "Claude Haiku 4" }
51833
51889
  ],
51834
51890
  contextWindows: [
51891
+ ["claude-opus-4-8", 1e6],
51835
51892
  ["claude-opus-4-7", 1e6],
51836
51893
  ["claude-opus-4-6", 1e6],
51837
51894
  ["claude-sonnet-4-6", 1e6],
@@ -64200,6 +64257,7 @@ var init_bedrock = __esm(() => {
64200
64257
  return null;
64201
64258
  },
64202
64259
  fallbackModels: [
64260
+ { id: "anthropic.claude-opus-4-8", name: "Claude Opus 4.8" },
64203
64261
  { id: "anthropic.claude-sonnet-4-20250514-v1:0", name: "Claude Sonnet 4" },
64204
64262
  { id: "anthropic.claude-haiku-4-5-20251001-v1:0", name: "Claude Haiku 4.5" },
64205
64263
  { id: "us.amazon.nova-pro-v1:0", name: "Amazon Nova Pro" },
@@ -64207,6 +64265,10 @@ var init_bedrock = __esm(() => {
64207
64265
  { id: "meta.llama3-1-70b-instruct-v1:0", name: "Llama 3.1 70B" }
64208
64266
  ],
64209
64267
  contextWindows: [
64268
+ ["claude-opus-4-8", 1e6],
64269
+ ["claude-opus-4-7", 1e6],
64270
+ ["claude-opus-4-6", 1e6],
64271
+ ["claude-sonnet-4-6", 1e6],
64210
64272
  ["claude-sonnet-4", 200000],
64211
64273
  ["claude-opus-4", 200000],
64212
64274
  ["claude-haiku-4", 200000],
@@ -71714,7 +71776,7 @@ var package_default;
71714
71776
  var init_package = __esm(() => {
71715
71777
  package_default = {
71716
71778
  name: "@proxysoul/soulforge",
71717
- version: "2.18.3",
71779
+ version: "2.18.5",
71718
71780
  description: "Graph-powered code intelligence \u2014 multi-agent coding with codebase-aware AI",
71719
71781
  repository: {
71720
71782
  type: "git",
@@ -72230,6 +72292,9 @@ function getCompatReasoningBody(modelId, config2) {
72230
72292
  return {};
72231
72293
  const isClaude = base.startsWith("claude");
72232
72294
  if (isClaude && provider === "opencode-zen") {
72295
+ if (isAdaptiveOnly(base)) {
72296
+ return { thinking: { type: "adaptive" } };
72297
+ }
72233
72298
  const explicitBudget = config2.thinking?.budgetTokens;
72234
72299
  const budget = explicitBudget ?? { low: 2048, medium: 5000, high: 1e4, xhigh: 20000 }[effort] ?? 5000;
72235
72300
  return { thinking: { type: "enabled", budget_tokens: budget } };
@@ -72436,8 +72501,10 @@ var init_copilot = __esm(() => {
72436
72501
  }
72437
72502
  },
72438
72503
  fallbackModels: [
72439
- { id: "claude-opus-4.6", name: "Claude Opus 4.6", contextWindow: 200000 },
72440
- { id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", contextWindow: 200000 },
72504
+ { id: "claude-opus-4.8", name: "Claude Opus 4.8", contextWindow: 1e6 },
72505
+ { id: "claude-opus-4.7", name: "Claude Opus 4.7", contextWindow: 1e6 },
72506
+ { id: "claude-opus-4.6", name: "Claude Opus 4.6", contextWindow: 1e6 },
72507
+ { id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", contextWindow: 1e6 },
72441
72508
  { id: "claude-sonnet-4", name: "Claude Sonnet 4", contextWindow: 128000 },
72442
72509
  { id: "claude-opus-4.5", name: "Claude Opus 4.5", contextWindow: 200000 },
72443
72510
  { id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5", contextWindow: 200000 },
@@ -72452,8 +72519,10 @@ var init_copilot = __esm(() => {
72452
72519
  { id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro", contextWindow: 1e6 }
72453
72520
  ],
72454
72521
  contextWindows: [
72455
- ["claude-opus-4.6", 200000],
72456
- ["claude-sonnet-4.6", 200000],
72522
+ ["claude-opus-4.8", 1e6],
72523
+ ["claude-opus-4.7", 1e6],
72524
+ ["claude-opus-4.6", 1e6],
72525
+ ["claude-sonnet-4.6", 1e6],
72457
72526
  ["claude-opus-4.5", 200000],
72458
72527
  ["claude-sonnet-4.5", 200000],
72459
72528
  ["claude-sonnet-4", 128000],
@@ -74060,6 +74129,17 @@ function createReasoningFetchWrapper(reasoningBody) {
74060
74129
  }
74061
74130
 
74062
74131
  // src/core/llm/providers/custom.ts
74132
+ function normalizeBaseURLPath(baseURL) {
74133
+ return baseURL.replace(/\/v1(?:\/)?$/i, "").replace(/\/+$/, "");
74134
+ }
74135
+ function resolveModelsAPIUrl(config2) {
74136
+ if (config2.modelsAPI === false)
74137
+ return null;
74138
+ if (config2.modelsAPI)
74139
+ return config2.modelsAPI;
74140
+ const normalized = normalizeBaseURLPath(config2.baseURL);
74141
+ return `${normalized}/models`;
74142
+ }
74063
74143
  function normalizeModels(models) {
74064
74144
  if (!models || models.length === 0)
74065
74145
  return [];
@@ -74097,22 +74177,41 @@ function buildCustomProvider(config2) {
74097
74177
  return client.chatModel(modelId);
74098
74178
  },
74099
74179
  async fetchModels() {
74100
- if (!config2.modelsAPI)
74180
+ const modelsUrl = resolveModelsAPIUrl(config2);
74181
+ if (!modelsUrl)
74101
74182
  return null;
74102
74183
  const apiKey = envVar ? getProviderApiKey(envVar) ?? "" : "";
74103
74184
  const headers = { "Content-Type": "application/json" };
74104
74185
  if (apiKey)
74105
74186
  headers.Authorization = `Bearer ${apiKey}`;
74106
- const res = await fetch(config2.modelsAPI, {
74107
- headers,
74108
- signal: AbortSignal.timeout(5000)
74109
- });
74187
+ let res;
74188
+ try {
74189
+ res = await fetch(modelsUrl, {
74190
+ headers,
74191
+ signal: AbortSignal.timeout(2000)
74192
+ });
74193
+ } catch {
74194
+ return null;
74195
+ }
74110
74196
  if (!res.ok)
74111
74197
  return null;
74112
- const data = await res.json();
74113
- if (!Array.isArray(data.data))
74198
+ let parsed;
74199
+ try {
74200
+ parsed = await res.json();
74201
+ } catch {
74114
74202
  return null;
74115
- return data.data.map((m) => ({ id: m.id, name: m.id }));
74203
+ }
74204
+ if (!Array.isArray(parsed.data))
74205
+ return null;
74206
+ return parsed.data.map((m) => {
74207
+ const rawContext = m.context_length ?? m.max_context_length ?? m.model_info?.max_input_tokens ?? m.meta?.n_ctx_train;
74208
+ const contextWindow = typeof rawContext === "number" ? rawContext : typeof rawContext === "string" ? Number(rawContext) : undefined;
74209
+ return {
74210
+ id: m.id,
74211
+ name: m.id,
74212
+ ...contextWindow !== undefined && !Number.isNaN(contextWindow) ? { contextWindow } : {}
74213
+ };
74214
+ });
74116
74215
  },
74117
74216
  fallbackModels: normalizeModels(config2.models),
74118
74217
  contextWindows: [],
@@ -84655,6 +84754,7 @@ var init_llmgateway = __esm(() => {
84655
84754
  return null;
84656
84755
  },
84657
84756
  fallbackModels: [
84757
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8" },
84658
84758
  { id: "claude-opus-4-7", name: "Claude Opus 4.7" },
84659
84759
  { id: "claude-opus-4-6", name: "Claude Opus 4.6" },
84660
84760
  { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
@@ -84680,6 +84780,7 @@ var init_llmgateway = __esm(() => {
84680
84780
  ["glm-4", 128000]
84681
84781
  ],
84682
84782
  contextWindows: [
84783
+ ["claude-opus-4-8", 1e6],
84683
84784
  ["claude-opus-4-7", 1e6],
84684
84785
  ["claude-opus-4-6", 1e6],
84685
84786
  ["claude-sonnet-4-6", 200000],
@@ -93920,6 +94021,73 @@ var init_mistral = __esm(() => {
93920
94021
  };
93921
94022
  });
93922
94023
 
94024
+ // src/core/llm/providers/nim.ts
94025
+ var BASE_URL2 = "https://integrate.api.nvidia.com/v1", nim;
94026
+ var init_nim = __esm(() => {
94027
+ init_dist9();
94028
+ init_config2();
94029
+ init_secrets();
94030
+ init_compat_reasoning();
94031
+ nim = {
94032
+ id: "nim",
94033
+ name: "NVIDIA NIM",
94034
+ envVar: "NVIDIA_API_KEY",
94035
+ icon: "\uF0E7",
94036
+ secretKey: "nvidia-api-key",
94037
+ keyUrl: "build.nvidia.com",
94038
+ asciiIcon: "N",
94039
+ description: "NVIDIA-hosted open models",
94040
+ createModel(modelId) {
94041
+ const apiKey = getProviderApiKey("NVIDIA_API_KEY");
94042
+ if (!apiKey) {
94043
+ throw new Error("NVIDIA_API_KEY is not set");
94044
+ }
94045
+ const reasoningBody = getCompatReasoningBody(`nim/${modelId}`, loadConfig());
94046
+ const reasoningFetch = createReasoningFetchWrapper(reasoningBody);
94047
+ return createOpenAICompatible({
94048
+ name: "nim",
94049
+ baseURL: BASE_URL2,
94050
+ apiKey,
94051
+ ...reasoningFetch ? { fetch: reasoningFetch } : {}
94052
+ })(modelId);
94053
+ },
94054
+ async fetchModels() {
94055
+ const apiKey = getProviderApiKey("NVIDIA_API_KEY");
94056
+ if (!apiKey)
94057
+ return null;
94058
+ const res = await fetch(`${BASE_URL2}/models`, {
94059
+ headers: { Authorization: `Bearer ${apiKey}` }
94060
+ });
94061
+ if (!res.ok)
94062
+ throw new Error(`NVIDIA NIM API ${String(res.status)}`);
94063
+ const data = await res.json();
94064
+ return data.data.map((m) => ({ id: m.id, name: m.id }));
94065
+ },
94066
+ fallbackModels: [
94067
+ { id: "moonshotai/kimi-k2.6", name: "Kimi K2.6" },
94068
+ { id: "deepseek-ai/deepseek-v4-flash", name: "DeepSeek V4 Flash" },
94069
+ { id: "deepseek-ai/deepseek-v4-pro", name: "DeepSeek V4 Pro" },
94070
+ { id: "zai/glm-5.1", name: "GLM-5.1" },
94071
+ { id: "mistralai/mistral-medium-3.5", name: "Mistral Medium 3.5" },
94072
+ { id: "mistralai/mistral-small-4", name: "Mistral Small 4" },
94073
+ { id: "google/gemma-4-31b", name: "Gemma 4 31B" },
94074
+ { id: "nvidia/nemotron-3-super-120b", name: "Nemotron 3 Super 120B" },
94075
+ { id: "minimaxai/minimax-m2.7", name: "MiniMax M2.7" }
94076
+ ],
94077
+ contextWindows: [
94078
+ ["kimi-k2.6", 256000],
94079
+ ["deepseek-v4-flash", 1e6],
94080
+ ["deepseek-v4-pro", 1e6],
94081
+ ["glm-5.1", 200000],
94082
+ ["mistral-medium-3.5", 131072],
94083
+ ["mistral-small-4", 256000],
94084
+ ["gemma-4-31b", 131072],
94085
+ ["nemotron-3-super-120b", 1e6],
94086
+ ["minimax-m2.7", 200000]
94087
+ ]
94088
+ };
94089
+ });
94090
+
93923
94091
  // src/core/llm/providers/ollama.ts
93924
94092
  function getOllamaHost() {
93925
94093
  return (process.env.OLLAMA_HOST ?? "http://localhost:11434").replace(/\/+$/, "");
@@ -94089,7 +94257,7 @@ var init_openai = __esm(() => {
94089
94257
  });
94090
94258
 
94091
94259
  // src/core/llm/providers/opencode-go.ts
94092
- var BASE_URL2 = "https://opencode.ai/zen/go/v1", opencodeGo;
94260
+ var BASE_URL3 = "https://opencode.ai/zen/go/v1", opencodeGo;
94093
94261
  var init_opencode_go = __esm(() => {
94094
94262
  init_dist9();
94095
94263
  init_config2();
@@ -94113,7 +94281,7 @@ var init_opencode_go = __esm(() => {
94113
94281
  const reasoningFetch = createReasoningFetchWrapper(reasoningBody);
94114
94282
  const provider = createOpenAICompatible({
94115
94283
  name: "opencode-go",
94116
- baseURL: BASE_URL2,
94284
+ baseURL: BASE_URL3,
94117
94285
  apiKey,
94118
94286
  ...reasoningFetch ? { fetch: reasoningFetch } : {}
94119
94287
  });
@@ -94167,7 +94335,7 @@ var init_opencode_go = __esm(() => {
94167
94335
  });
94168
94336
 
94169
94337
  // src/core/llm/providers/opencode-zen.ts
94170
- var BASE_URL3 = "https://opencode.ai/zen/v1", opencodeZen;
94338
+ var BASE_URL4 = "https://opencode.ai/zen/v1", opencodeZen;
94171
94339
  var init_opencode_zen = __esm(() => {
94172
94340
  init_dist9();
94173
94341
  init_config2();
@@ -94193,7 +94361,7 @@ var init_opencode_zen = __esm(() => {
94193
94361
  const reasoningFetch = createReasoningFetchWrapper(reasoningBody);
94194
94362
  const provider = createOpenAICompatible({
94195
94363
  name: "opencode-zen",
94196
- baseURL: BASE_URL3,
94364
+ baseURL: BASE_URL4,
94197
94365
  apiKey,
94198
94366
  ...reasoningFetch ? { fetch: reasoningFetch } : {}
94199
94367
  });
@@ -94233,6 +94401,7 @@ var init_opencode_zen = __esm(() => {
94233
94401
  { id: "gpt-5", name: "GPT 5" },
94234
94402
  { id: "gpt-5-codex", name: "GPT 5 Codex" },
94235
94403
  { id: "gpt-5-nano", name: "GPT 5 Nano" },
94404
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8" },
94236
94405
  { id: "claude-opus-4-7", name: "Claude Opus 4.7" },
94237
94406
  { id: "claude-opus-4-6", name: "Claude Opus 4.6" },
94238
94407
  { id: "claude-opus-4-5", name: "Claude Opus 4.5" },
@@ -94291,6 +94460,7 @@ var init_opencode_zen = __esm(() => {
94291
94460
  ["gpt-5", 400000],
94292
94461
  ["gpt-5-codex", 400000],
94293
94462
  ["gpt-5-nano", 400000],
94463
+ ["claude-opus-4-8", 1e6],
94294
94464
  ["claude-opus-4-7", 1e6],
94295
94465
  ["claude-opus-4-6", 1e6],
94296
94466
  ["claude-opus-4-5", 200000],
@@ -94299,6 +94469,7 @@ var init_opencode_zen = __esm(() => {
94299
94469
  ["claude-sonnet-4-5", 1e6],
94300
94470
  ["claude-sonnet-4", 200000],
94301
94471
  ["claude-haiku-4-5", 200000],
94472
+ ["claude-opus-4.8", 1e6],
94302
94473
  ["claude-opus-4.6", 1e6],
94303
94474
  ["claude-sonnet-4.6", 1e6],
94304
94475
  ["claude-sonnet-4.5", 1e6],
@@ -99134,6 +99305,7 @@ var init_openrouter = __esm(() => {
99134
99305
  return null;
99135
99306
  },
99136
99307
  fallbackModels: [
99308
+ { id: "anthropic/claude-opus-4.8", name: "Claude Opus 4.8" },
99137
99309
  { id: "anthropic/claude-opus-4.7", name: "Claude Opus 4.7" },
99138
99310
  { id: "anthropic/claude-opus-4.6", name: "Claude Opus 4.6" },
99139
99311
  { id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
@@ -99167,6 +99339,8 @@ var init_openrouter = __esm(() => {
99167
99339
  ["glm-4", 128000]
99168
99340
  ],
99169
99341
  contextWindows: [
99342
+ ["claude-opus-4.8", 1e6],
99343
+ ["claude-opus-4.7", 1e6],
99170
99344
  ["claude-opus-4.6", 1e6],
99171
99345
  ["claude-sonnet-4.6", 1e6],
99172
99346
  ["claude-sonnet-4.5", 1e6],
@@ -401589,7 +401763,7 @@ function matchPricing(modelId) {
401589
401763
  return pricing;
401590
401764
  }
401591
401765
  if (id.includes("opus"))
401592
- return MODEL_PRICING["claude-opus-4-6"] ?? DEFAULT_PRICING;
401766
+ return MODEL_PRICING["claude-opus-4-8"] ?? DEFAULT_PRICING;
401593
401767
  if (id.includes("sonnet"))
401594
401768
  return DEFAULT_PRICING;
401595
401769
  if (id.includes("haiku"))
@@ -401790,6 +401964,7 @@ var init_statusbar = __esm(() => {
401790
401964
  init_platform();
401791
401965
  init_lifecycle();
401792
401966
  MODEL_PRICING = {
401967
+ "claude-opus-4-8": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
401793
401968
  "claude-opus-4-7": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
401794
401969
  "claude-opus-4-6": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
401795
401970
  "claude-opus-4-5": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
@@ -401886,8 +402061,11 @@ var init_statusbar = __esm(() => {
401886
402061
  "claude-opus-4.5": M3,
401887
402062
  "claude-opus-4.6": M3,
401888
402063
  "claude-opus-4.7": M75,
402064
+ "claude-opus-4.8": M75,
401889
402065
  "gpt-5.5": M75,
401890
- "claude-opus-4.6-fast": M30
402066
+ "claude-opus-4.8-fast": { input: 20, cacheWrite: 20, cacheRead: 2, output: 100 },
402067
+ "claude-opus-4.6-fast": M30,
402068
+ "claude-opus-4.7-fast": M30
401891
402069
  };
401892
402070
  LOCAL_PROVIDERS = new Set(["ollama", "lmstudio"]);
401893
402071
  ZERO_USAGE = {
@@ -407160,6 +407338,7 @@ var init_proxy2 = __esm(() => {
407160
407338
  stopProxy();
407161
407339
  },
407162
407340
  fallbackModels: [
407341
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8" },
407163
407342
  { id: "claude-opus-4-7", name: "Claude Opus 4.7" },
407164
407343
  { id: "claude-opus-4-6", name: "Claude Opus 4.6" },
407165
407344
  { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
@@ -407170,6 +407349,8 @@ var init_proxy2 = __esm(() => {
407170
407349
  { id: "claude-haiku-3-5-20241022", name: "Claude Haiku 3.5" }
407171
407350
  ],
407172
407351
  contextWindows: [
407352
+ ["claude-opus-4-8", 1e6],
407353
+ ["claude-opus-4.8", 1e6],
407173
407354
  ["claude-opus-4-7", 1e6],
407174
407355
  ["claude-opus-4.7", 1e6],
407175
407356
  ["claude-opus-4-6", 1e6],
@@ -410299,6 +410480,7 @@ __export(exports_providers, {
410299
410480
  openai: () => openai2,
410300
410481
  onProvidersChanged: () => onProvidersChanged,
410301
410482
  ollama: () => ollama,
410483
+ nim: () => nim,
410302
410484
  mistral: () => mistral2,
410303
410485
  minimax: () => minimax2,
410304
410486
  lmstudio: () => lmstudio,
@@ -410372,6 +410554,7 @@ var init_providers = __esm(() => {
410372
410554
  init_lmstudio();
410373
410555
  init_minimax();
410374
410556
  init_mistral();
410557
+ init_nim();
410375
410558
  init_ollama();
410376
410559
  init_openai();
410377
410560
  init_opencode_go();
@@ -410394,6 +410577,7 @@ var init_providers = __esm(() => {
410394
410577
  init_lmstudio();
410395
410578
  init_minimax();
410396
410579
  init_mistral();
410580
+ init_nim();
410397
410581
  init_ollama();
410398
410582
  init_openai();
410399
410583
  init_opencode_go();
@@ -410416,6 +410600,7 @@ var init_providers = __esm(() => {
410416
410600
  bedrock2,
410417
410601
  fireworks2,
410418
410602
  minimax2,
410603
+ nim,
410419
410604
  codex,
410420
410605
  copilot,
410421
410606
  githubModels,
@@ -411234,7 +411419,8 @@ async function buildAnthropicOptions(modelId, caps, config2) {
411234
411419
  let thinkingEnabled = false;
411235
411420
  if (caps.thinking) {
411236
411421
  const mode = config2.thinking?.mode ?? "off";
411237
- if (mode === "auto" || mode === "adaptive") {
411422
+ const adaptiveOnly = isAdaptiveOnly2(modelId);
411423
+ if (mode === "auto" || mode === "adaptive" || mode === "enabled" && adaptiveOnly) {
411238
411424
  if (caps.adaptiveThinking) {
411239
411425
  opts.thinking = { type: "adaptive" };
411240
411426
  thinkingEnabled = true;
@@ -411271,7 +411457,7 @@ async function buildAnthropicOptions(modelId, caps, config2) {
411271
411457
  opts.contextManagement = { edits };
411272
411458
  }
411273
411459
  }
411274
- if (thinkingEnabled && caps.interleavedThinking) {
411460
+ if (thinkingEnabled && caps.interleavedThinking && opts.thinking?.type !== "adaptive") {
411275
411461
  headers["anthropic-beta"] = "interleaved-thinking-2025-05-14";
411276
411462
  }
411277
411463
  return { opts, headers, thinkingEnabled };
@@ -411391,7 +411577,7 @@ function degradeProviderOptions(modelId, level) {
411391
411577
  const caps = getEffectiveCaps(modelId);
411392
411578
  const providerOptions = {};
411393
411579
  if (caps.anthropicOptions && caps.thinking) {
411394
- const opts = { thinking: { type: "enabled", budgetTokens: 5000 } };
411580
+ const opts = isAdaptiveOnly2(modelId) ? { thinking: { type: "adaptive" }, effort: "low" } : { thinking: { type: "enabled", budgetTokens: 5000 } };
411395
411581
  providerOptions.anthropic = opts;
411396
411582
  }
411397
411583
  if (caps.openaiOptions && caps.openaiReasoning) {
@@ -411410,9 +411596,7 @@ function degradeProviderOptions(modelId, level) {
411410
411596
  providerOptions.openrouter = { reasoning: { effort: "low" } };
411411
411597
  }
411412
411598
  if (caps.bedrockOptions && caps.thinking) {
411413
- providerOptions.bedrock = {
411414
- reasoningConfig: { type: "enabled", budgetTokens: 5000 }
411415
- };
411599
+ providerOptions.bedrock = isAdaptiveOnly2(modelId) ? { reasoningConfig: { type: "adaptive", maxReasoningEffort: "low" } } : { reasoningConfig: { type: "enabled", budgetTokens: 5000 } };
411416
411600
  }
411417
411601
  return {
411418
411602
  providerOptions,
@@ -411567,11 +411751,12 @@ function buildGroqOptions(config2) {
411567
411751
  function isDeepSeekReasoner(base) {
411568
411752
  return base === "deepseek-reasoner" || base.includes("reasoner") || base.endsWith("-think");
411569
411753
  }
411570
- var parseOpusVersion2, extractBaseModel2, getModelId2, supportsTemperature2, NO_SUPPORT, ANTHROPIC_FULL, OPENAI_FULL, GOOGLE_FULL, XAI_FULL, DEEPSEEK_FULL, OPENROUTER_FULL, GATEWAY_FULL, COMPAT_ONLY, PROVIDER_CONSTRAINTS, LEGACY_PREFIXES, CACHE_EPHEMERAL_5M, CACHE_EPHEMERAL_1H, EPHEMERAL_CACHE_5M, EPHEMERAL_CACHE_1H, EPHEMERAL_CACHE;
411754
+ var parseOpusVersion2, isAdaptiveOnly2, extractBaseModel2, getModelId2, supportsTemperature2, NO_SUPPORT, ANTHROPIC_FULL, OPENAI_FULL, GOOGLE_FULL, XAI_FULL, DEEPSEEK_FULL, OPENROUTER_FULL, GATEWAY_FULL, COMPAT_ONLY, PROVIDER_CONSTRAINTS, LEGACY_PREFIXES, CACHE_EPHEMERAL_5M, CACHE_EPHEMERAL_1H, EPHEMERAL_CACHE_5M, EPHEMERAL_CACHE_1H, EPHEMERAL_CACHE;
411571
411755
  var init_provider_options = __esm(() => {
411572
411756
  init_models();
411573
411757
  init_providers();
411574
411758
  parseOpusVersion2 = parseOpusVersion;
411759
+ isAdaptiveOnly2 = isAdaptiveOnly;
411575
411760
  extractBaseModel2 = extractBaseModel;
411576
411761
  getModelId2 = getModelId;
411577
411762
  supportsTemperature2 = supportsTemperature;
@@ -450064,7 +450249,7 @@ __export(exports_nim, {
450064
450249
  default: () => nim_default
450065
450250
  });
450066
450251
  var lang159, nim_default;
450067
- var init_nim = __esm(() => {
450252
+ var init_nim2 = __esm(() => {
450068
450253
  init_c();
450069
450254
  init_html();
450070
450255
  init_xml();
@@ -452160,7 +452345,7 @@ var init_langs_bundle_full_YTHnHqaM = __esm(() => {
452160
452345
  {
452161
452346
  id: "nim",
452162
452347
  name: "Nim",
452163
- import: () => Promise.resolve().then(() => (init_nim(), exports_nim))
452348
+ import: () => Promise.resolve().then(() => (init_nim2(), exports_nim))
452164
452349
  },
452165
452350
  {
452166
452351
  id: "nix",
@@ -468144,17 +468329,14 @@ function expandEnv(value) {
468144
468329
  return value;
468145
468330
  }
468146
468331
  function validatePreset(raw2, origin) {
468147
- if (!raw2 || typeof raw2 !== "object") {
468148
- throw new Error(`Preset at ${origin} is not an object`);
468149
- }
468150
- const obj = raw2;
468151
- if (typeof obj.name !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(obj.name)) {
468152
- throw new Error(`Preset at ${origin}: invalid or missing "name"`);
468153
- }
468154
- if (typeof obj.version !== "string" || !/^\d+\.\d+\.\d+$/.test(obj.version)) {
468155
- throw new Error(`Preset at ${origin}: invalid or missing "version" (semver required)`);
468332
+ const expanded = expandEnv(raw2);
468333
+ const parsed = PresetSchema.safeParse(expanded);
468334
+ if (!parsed.success) {
468335
+ const issue2 = parsed.error.issues[0];
468336
+ const path = issue2?.path.length ? issue2.path.join(".") : "<root>";
468337
+ throw new Error(`Preset at ${origin}: ${path} \u2014 ${issue2?.message ?? "invalid shape"}`);
468156
468338
  }
468157
- return expandEnv(obj);
468339
+ return parsed.data;
468158
468340
  }
468159
468341
  function cacheFile(name39, version2) {
468160
468342
  return join55(getCacheDir(), `${name39}@${version2}.json`);
@@ -468249,11 +468431,28 @@ async function resolvePresets(specs, opts = {}) {
468249
468431
  failures
468250
468432
  };
468251
468433
  }
468252
- var NETWORK_TIMEOUT_MS2 = 1e4, MAX_PRESET_BYTES;
468434
+ var NETWORK_TIMEOUT_MS2 = 1e4, MAX_PRESET_BYTES, PresetSchema;
468253
468435
  var init_loader3 = __esm(() => {
468436
+ init_zod();
468254
468437
  init_platform();
468255
468438
  init_registry2();
468256
468439
  MAX_PRESET_BYTES = 512 * 1024;
468440
+ PresetSchema = exports_external.object({
468441
+ name: exports_external.string().regex(/^[a-z0-9][a-z0-9-]*$/, "name must be lowercase, start with [a-z0-9], hyphen-separated"),
468442
+ version: exports_external.string().regex(/^\d+\.\d+\.\d+$/, "version must be semver (x.y.z)"),
468443
+ description: exports_external.string().optional(),
468444
+ author: exports_external.string().optional(),
468445
+ homepage: exports_external.string().optional(),
468446
+ tags: exports_external.array(exports_external.string()).optional(),
468447
+ router: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
468448
+ routerRules: exports_external.unknown().optional(),
468449
+ providers: exports_external.unknown().optional(),
468450
+ theme: exports_external.unknown().optional(),
468451
+ themes: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
468452
+ hooks: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
468453
+ prompts: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
468454
+ config: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
468455
+ }).passthrough();
468257
468456
  });
468258
468457
 
468259
468458
  // src/core/presets/merge.ts
@@ -485368,14 +485567,23 @@ var init_FinalResponseView = __esm(() => {
485368
485567
 
485369
485568
  `) : null;
485370
485569
  }, [segments, finalResponseCalled]);
485371
- const toolsRef = import_react62.useRef([]);
485372
485570
  const tools = import_react62.useMemo(() => {
485373
- const next = [];
485374
- for (const tc of liveToolCalls) {
485375
- if (!filterQuietTools(tc.toolName))
485571
+ const ids = [];
485572
+ for (const seg of segments) {
485573
+ if (seg?.type === "tools")
485574
+ ids.push(...seg.callIds);
485575
+ }
485576
+ const seen = new Set;
485577
+ const out2 = [];
485578
+ for (const id of ids) {
485579
+ if (seen.has(id))
485580
+ continue;
485581
+ seen.add(id);
485582
+ const tc = liveToolCalls.find((c) => c.id === id);
485583
+ if (!tc || !filterQuietTools(tc.toolName))
485376
485584
  continue;
485377
485585
  const isDispatch = SUBAGENT_NAMES.has(tc.toolName);
485378
- next.push({
485586
+ out2.push({
485379
485587
  id: tc.id,
485380
485588
  name: tc.toolName,
485381
485589
  done: tc.state !== "running",
@@ -485387,17 +485595,12 @@ var init_FinalResponseView = __esm(() => {
485387
485595
  imageArt: tc.imageArt
485388
485596
  });
485389
485597
  }
485390
- const prev = toolsRef.current;
485391
- if (prev.length === next.length && prev.every((p3, i4) => next[i4] !== undefined && p3.id === next[i4]?.id && p3.name === next[i4]?.name && p3.done === next[i4]?.done && p3.error === next[i4]?.error && p3.argStr === next[i4]?.argStr && !!p3.subtree === !!next[i4]?.subtree && p3.imageArt === next[i4]?.imageArt)) {
485392
- return prev;
485393
- }
485394
- toolsRef.current = next;
485395
- return next;
485396
- }, [liveToolCalls]);
485598
+ return out2;
485599
+ }, [segments, liveToolCalls]);
485397
485600
  const hasDispatch = import_react62.useMemo(() => liveToolCalls.some((tc) => SUBAGENT_NAMES.has(tc.toolName)), [liveToolCalls]);
485398
485601
  const hasEdits = import_react62.useMemo(() => liveToolCalls.some((tc) => FINAL_RESPONSE_EDIT_TOOLS.has(tc.toolName)), [liveToolCalls]);
485399
- const allToolsDone = tools.length > 0 && tools.every((t) => t.done);
485400
485602
  const dispatchActive = liveToolCalls.some((tc) => SUBAGENT_NAMES.has(tc.toolName) && tc.state === "running");
485603
+ const allToolsDone = tools.length > 0 && tools.every((t) => t.done);
485401
485604
  const pendingNarration = allToolsDone && !dispatchActive && !trailingText;
485402
485605
  if (chatOnlyText) {
485403
485606
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {