atlarix 15.7.1 → 15.8.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.
@@ -27507,10 +27507,16 @@ var init_schemas3 = __esm({
27507
27507
  /** @deprecated superseded by the binary `deepThinking` toggle (v14.8.5). */
27508
27508
  thinkingBudget: external_exports.enum(["low", "medium", "high"]).optional(),
27509
27509
  /**
27510
- * Reasoning is a flat `medium` baseline for every model/provider/mode. This
27511
- * single toggle raises it to the model's max reasoning ("high") on demand.
27510
+ * The old two-state switch: on asks for the top of the model's effort list.
27511
+ * Read when no `effort` is chosen; /effort replaced it (2026-10-17).
27512
27512
  */
27513
27513
  deepThinking: external_exports.boolean().optional(),
27514
+ /**
27515
+ * /effort: a level exactly as the model lists it (models.dev, or Auto's
27516
+ * low / medium / max). Unset, or one the current model doesn't list, runs the
27517
+ * model's default.
27518
+ */
27519
+ effort: external_exports.string().optional(),
27514
27520
  enableSupabaseWriteSqlMigration: external_exports.boolean().optional(),
27515
27521
  selectedChatMode: ChatModeSchema.optional(),
27516
27522
  /** @deprecated Ignored — unified runtime always enables delegation. */
@@ -36733,8 +36739,8 @@ function convertToOpenAIChatMessages({
36733
36739
  }
36734
36740
  case "url":
36735
36741
  case "data": {
36736
- const topLevel = getTopLevelMediaType(part.mediaType);
36737
- if (topLevel === "image") {
36742
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
36743
+ if (topLevel2 === "image") {
36738
36744
  return {
36739
36745
  type: "image_url",
36740
36746
  image_url: {
@@ -36745,7 +36751,7 @@ function convertToOpenAIChatMessages({
36745
36751
  prompt_cache_breakpoint: promptCacheBreakpoint
36746
36752
  }
36747
36753
  };
36748
- } else if (topLevel === "audio") {
36754
+ } else if (topLevel2 === "audio") {
36749
36755
  if (part.data.type === "url") {
36750
36756
  throw new UnsupportedFunctionalityError({
36751
36757
  functionality: "audio file parts with URLs"
@@ -37329,8 +37335,8 @@ async function convertToOpenAIResponsesInput({
37329
37335
  }
37330
37336
  case "url":
37331
37337
  case "data": {
37332
- const topLevel = getTopLevelMediaType(part.mediaType);
37333
- if (topLevel === "image") {
37338
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
37339
+ if (topLevel2 === "image") {
37334
37340
  return {
37335
37341
  type: "input_image",
37336
37342
  ...part.data.type === "url" ? { image_url: part.data.url.toString() } : typeof part.data.data === "string" && isFileId(part.data.data, fileIdPrefixes) ? { file_id: part.data.data } : {
@@ -37910,13 +37916,13 @@ async function convertToOpenAIResponsesInput({
37910
37916
  }
37911
37917
  };
37912
37918
  case "file": {
37913
- const topLevel = getTopLevelMediaType(item.mediaType);
37919
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
37914
37920
  const imageDetail = (_b26 = (_a210 = item.providerOptions) == null ? void 0 : _a210[providerOptionsName]) == null ? void 0 : _b26.imageDetail;
37915
37921
  if (item.data.type === "data") {
37916
37922
  const fullMediaType = resolveFullMediaType({
37917
37923
  part: item
37918
37924
  });
37919
- if (topLevel === "image") {
37925
+ if (topLevel2 === "image") {
37920
37926
  return {
37921
37927
  type: "input_image",
37922
37928
  image_url: `data:${fullMediaType};base64,${convertToBase64(item.data.data)}`,
@@ -37936,7 +37942,7 @@ async function convertToOpenAIResponsesInput({
37936
37942
  };
37937
37943
  }
37938
37944
  if (item.data.type === "url") {
37939
- if (topLevel === "image") {
37945
+ if (topLevel2 === "image") {
37940
37946
  return {
37941
37947
  type: "input_image",
37942
37948
  image_url: item.data.url.toString(),
@@ -38013,13 +38019,13 @@ async function convertToOpenAIResponsesInput({
38013
38019
  };
38014
38020
  }
38015
38021
  case "file": {
38016
- const topLevel = getTopLevelMediaType(item.mediaType);
38022
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
38017
38023
  const imageDetail = (_b26 = (_a210 = item.providerOptions) == null ? void 0 : _a210[providerOptionsName]) == null ? void 0 : _b26.imageDetail;
38018
38024
  if (item.data.type === "data") {
38019
38025
  const fullMediaType = resolveFullMediaType({
38020
38026
  part: item
38021
38027
  });
38022
- if (topLevel === "image") {
38028
+ if (topLevel2 === "image") {
38023
38029
  return {
38024
38030
  type: "input_image",
38025
38031
  image_url: `data:${fullMediaType};base64,${convertToBase64(item.data.data)}`,
@@ -38039,7 +38045,7 @@ async function convertToOpenAIResponsesInput({
38039
38045
  };
38040
38046
  }
38041
38047
  if (item.data.type === "url") {
38042
- if (topLevel === "image") {
38048
+ if (topLevel2 === "image") {
38043
38049
  return {
38044
38050
  type: "input_image",
38045
38051
  image_url: item.data.url.toString(),
@@ -46935,8 +46941,8 @@ async function convertToAnthropicPrompt({
46935
46941
  }
46936
46942
  case "url":
46937
46943
  case "data": {
46938
- const topLevel = getTopLevelMediaType(part.mediaType);
46939
- if (topLevel === "image") {
46944
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
46945
+ if (topLevel2 === "image") {
46940
46946
  anthropicContent.push({
46941
46947
  type: "image",
46942
46948
  source: part.data.type === "url" ? {
@@ -46949,7 +46955,7 @@ async function convertToAnthropicPrompt({
46949
46955
  },
46950
46956
  cache_control: cacheControl
46951
46957
  });
46952
- } else if (topLevel === "application" && (part.data.type === "url" ? part.mediaType === "application/pdf" : resolveFullMediaType({ part }) === "application/pdf")) {
46958
+ } else if (topLevel2 === "application" && (part.data.type === "url" ? part.mediaType === "application/pdf" : resolveFullMediaType({ part }) === "application/pdf")) {
46953
46959
  betas.add("pdfs-2024-09-25");
46954
46960
  const enableCitations = await shouldEnableCitations2(
46955
46961
  part.providerOptions
@@ -47051,11 +47057,11 @@ async function convertToAnthropicPrompt({
47051
47057
  text: contentPart.text
47052
47058
  };
47053
47059
  case "file": {
47054
- const topLevel = getTopLevelMediaType(
47060
+ const topLevel2 = getTopLevelMediaType(
47055
47061
  contentPart.mediaType
47056
47062
  );
47057
47063
  if (contentPart.data.type === "url") {
47058
- if (topLevel === "image") {
47064
+ if (topLevel2 === "image") {
47059
47065
  return {
47060
47066
  type: "image",
47061
47067
  source: {
@@ -47073,7 +47079,7 @@ async function convertToAnthropicPrompt({
47073
47079
  };
47074
47080
  }
47075
47081
  if (contentPart.data.type === "data") {
47076
- if (topLevel === "image") {
47082
+ if (topLevel2 === "image") {
47077
47083
  return {
47078
47084
  type: "image",
47079
47085
  source: {
@@ -55399,9 +55405,9 @@ function convertFilePartToContent({
55399
55405
  text: part.data.text
55400
55406
  };
55401
55407
  }
55402
- const topLevel = getTopLevelMediaType(part.mediaType);
55408
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
55403
55409
  let kind;
55404
- switch (topLevel) {
55410
+ switch (topLevel2) {
55405
55411
  case "image":
55406
55412
  kind = "image";
55407
55413
  break;
@@ -55548,8 +55554,8 @@ function convertToolResultPart({
55548
55554
  if (item.type === "text") {
55549
55555
  blocks.push({ type: "text", text: item.text });
55550
55556
  } else if (item.type === "file") {
55551
- const topLevel = getTopLevelMediaType(item.mediaType);
55552
- if (topLevel !== "image") {
55557
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
55558
+ if (topLevel2 !== "image") {
55553
55559
  warnings.push({
55554
55560
  type: "other",
55555
55561
  message: `google.interactions: tool-result file with mediaType "${item.mediaType}" is not supported (Interactions \`function_result.result\` accepts only text and image content); part dropped.`
@@ -66144,8 +66150,8 @@ function convertToOpenAICompatibleChatMessages(prompt) {
66144
66150
  }
66145
66151
  case "url":
66146
66152
  case "data": {
66147
- const topLevel = getTopLevelMediaType(part.mediaType);
66148
- if (topLevel === "image") {
66153
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
66154
+ if (topLevel2 === "image") {
66149
66155
  return {
66150
66156
  type: "image_url",
66151
66157
  image_url: {
@@ -66154,7 +66160,7 @@ function convertToOpenAICompatibleChatMessages(prompt) {
66154
66160
  ...partMetadata
66155
66161
  };
66156
66162
  }
66157
- if (topLevel === "audio") {
66163
+ if (topLevel2 === "audio") {
66158
66164
  if (part.data.type === "url") {
66159
66165
  throw new UnsupportedFunctionalityError({
66160
66166
  functionality: "audio file parts with URLs"
@@ -66176,7 +66182,7 @@ function convertToOpenAICompatibleChatMessages(prompt) {
66176
66182
  ...partMetadata
66177
66183
  };
66178
66184
  }
66179
- if (topLevel === "application") {
66185
+ if (topLevel2 === "application") {
66180
66186
  if (part.data.type === "url") {
66181
66187
  throw new UnsupportedFunctionalityError({
66182
66188
  functionality: "PDF file parts with URLs"
@@ -66197,7 +66203,7 @@ function convertToOpenAICompatibleChatMessages(prompt) {
66197
66203
  ...partMetadata
66198
66204
  };
66199
66205
  }
66200
- if (topLevel === "text") {
66206
+ if (topLevel2 === "text") {
66201
66207
  const textContent = part.data.type === "url" ? part.data.url.toString() : typeof part.data.data === "string" ? new TextDecoder().decode(
66202
66208
  convertBase64ToUint8Array(part.data.data)
66203
66209
  ) : new TextDecoder().decode(part.data.data);
@@ -68186,16 +68192,35 @@ var init_model_capability_profile = __esm({
68186
68192
  // src/lib/routing/model-reasoning-profile.ts
68187
68193
  var model_reasoning_profile_exports = {};
68188
68194
  __export(model_reasoning_profile_exports, {
68195
+ AUTO_EFFORT_CHOICES: () => AUTO_EFFORT_CHOICES,
68196
+ AUTO_EFFORT_LEVELS: () => AUTO_EFFORT_LEVELS,
68197
+ BUDGET_LEVELS: () => BUDGET_LEVELS,
68189
68198
  __resetReasoningRegistryForTests: () => __resetReasoningRegistryForTests,
68199
+ autoEffort: () => autoEffort,
68190
68200
  catalogAllowsTemperature: () => catalogAllowsTemperature,
68191
68201
  catalogSaysReasons: () => catalogSaysReasons,
68202
+ chosenLevel: () => chosenLevel,
68203
+ effortAfterModelChange: () => effortAfterModelChange,
68204
+ effortChoicesFor: () => effortChoicesFor,
68205
+ effortSettingsPatch: () => effortSettingsPatch,
68192
68206
  hasMeaningfulReasoningControl: () => hasMeaningfulReasoningControl,
68207
+ isReasoningOff: () => isReasoningOff,
68208
+ levelShare: () => levelShare,
68193
68209
  normalizedEffortValues: () => normalizedEffortValues,
68210
+ rawEffortValues: () => rawEffortValues,
68194
68211
  reasoningProfileFor: () => reasoningProfileFor,
68212
+ registerEffortOverrides: () => registerEffortOverrides,
68195
68213
  registerModelsDevReasoning: () => registerModelsDevReasoning,
68196
68214
  resolveReasoningRequest: () => resolveReasoningRequest,
68197
- supportsTemperatureParam: () => supportsTemperatureParam
68215
+ supportsTemperatureParam: () => supportsTemperatureParam,
68216
+ topLevel: () => topLevel
68198
68217
  });
68218
+ function registerEffortOverrides(map3) {
68219
+ effortOverrides.clear();
68220
+ for (const [id, values2] of Object.entries(map3)) {
68221
+ if (Array.isArray(values2) && values2.length) effortOverrides.set(id.toLowerCase(), values2.map(String));
68222
+ }
68223
+ }
68199
68224
  function keyFor(providerId, modelId) {
68200
68225
  return providerId ? `${providerId.toLowerCase()}:${modelId.toLowerCase()}` : modelId.toLowerCase();
68201
68226
  }
@@ -68205,10 +68230,25 @@ function registerModelsDevReasoning(entries2) {
68205
68230
  const bare = e3.modelId.toLowerCase();
68206
68231
  profileById.set(scoped, e3.profile);
68207
68232
  temperatureById.set(scoped, e3.supportsTemperature);
68208
- if (!profileById.has(bare)) profileById.set(bare, e3.profile);
68209
68233
  if (!temperatureById.has(bare))
68210
68234
  temperatureById.set(bare, e3.supportsTemperature);
68211
68235
  }
68236
+ const byBare = /* @__PURE__ */ new Map();
68237
+ for (const e3 of entries2) {
68238
+ const bare = e3.modelId.toLowerCase();
68239
+ byBare.set(bare, [...byBare.get(bare) ?? [], e3.profile]);
68240
+ }
68241
+ for (const [bare, rows] of byBare) profileById.set(bare, consensusProfile(rows));
68242
+ }
68243
+ function consensusProfile(rows) {
68244
+ const sig = (p2) => JSON.stringify([p2.reasoning, p2.options.map((o2) => [o2.type, o2.values ?? []]).sort((a2, b3) => String(a2[0]).localeCompare(String(b3[0])))]);
68245
+ const size2 = (p2) => p2.options.reduce((n2, o2) => n2 + 1 + (o2.values?.length ?? 0), 0);
68246
+ const counts = /* @__PURE__ */ new Map();
68247
+ for (const p2 of rows) {
68248
+ const k2 = sig(p2);
68249
+ counts.set(k2, { n: (counts.get(k2)?.n ?? 0) + 1, p: p2 });
68250
+ }
68251
+ return [...counts.values()].sort((a2, b3) => b3.n - a2.n || size2(a2.p) - size2(b3.p))[0].p;
68212
68252
  }
68213
68253
  function lookup(map3, providerId, modelId) {
68214
68254
  if (!modelId) return void 0;
@@ -68254,19 +68294,107 @@ function normalizedEffortValues(options) {
68254
68294
  }
68255
68295
  return EFFORT_ORDER.filter((level) => seen.has(level));
68256
68296
  }
68297
+ function rawEffortValues(options) {
68298
+ const effort = options.find((o2) => o2.type === "effort");
68299
+ if (!effort || !Array.isArray(effort.values)) return [];
68300
+ const out = [];
68301
+ for (const raw of effort.values) {
68302
+ const v2 = String(raw).trim();
68303
+ if (v2 && !out.some((o2) => o2.toLowerCase() === v2.toLowerCase())) out.push(v2);
68304
+ }
68305
+ return out;
68306
+ }
68307
+ function defaultOf(levels) {
68308
+ const reasoning = levels.filter((l3) => !NO_REASONING.has(l3.toLowerCase()));
68309
+ const pool = reasoning.length ? reasoning : levels;
68310
+ return pool[Math.max(0, pool.length - 2)];
68311
+ }
68312
+ function overrideFor(modelId) {
68313
+ if (!modelId) return void 0;
68314
+ const id = modelId.toLowerCase();
68315
+ return effortOverrides.get(id) ?? effortOverrides.get(id.split("/").pop());
68316
+ }
68317
+ function defaultFor(providerId, levels) {
68318
+ const p2 = providerId?.toLowerCase();
68319
+ if ((p2 === "openai" || p2 === "azure") && levels.includes("medium")) return "medium";
68320
+ return defaultOf(levels);
68321
+ }
68322
+ function effortChoicesFor(providerId, modelId) {
68323
+ const override = overrideFor(modelId);
68324
+ if (override) return { kind: "effort", levels: override, defaultLevel: defaultFor(providerId, override) };
68325
+ const profile = reasoningProfileFor(providerId, modelId);
68326
+ if (!profile?.reasoning) return null;
68327
+ const values2 = rawEffortValues(profile.options);
68328
+ if (values2.length) return { kind: "effort", levels: values2, defaultLevel: defaultFor(providerId, values2) };
68329
+ if (profile.options.some((o2) => o2.type === "budget_tokens")) return { kind: "budget", levels: [...BUDGET_LEVELS], defaultLevel: "medium" };
68330
+ if (profile.options.some((o2) => o2.type === "toggle")) return { kind: "toggle", levels: ["off", "on"], defaultLevel: "off" };
68331
+ return null;
68332
+ }
68333
+ function autoEffort(settings) {
68334
+ return chosenLevel(AUTO_EFFORT_CHOICES, settings?.effort, !!settings?.deepThinking);
68335
+ }
68336
+ function topLevel(choices) {
68337
+ return choices.levels.at(-1);
68338
+ }
68339
+ function chosenLevel(choices, effort, deepThinking = false) {
68340
+ const want = effort?.trim().toLowerCase();
68341
+ const hit = want ? choices.levels.find((l3) => l3.toLowerCase() === want) : void 0;
68342
+ if (hit) return hit;
68343
+ return deepThinking ? topLevel(choices) : choices.defaultLevel;
68344
+ }
68345
+ function effortSettingsPatch(choices, level) {
68346
+ const hit = choices.levels.find((l3) => l3.toLowerCase() === level.trim().toLowerCase()) ?? choices.defaultLevel;
68347
+ if (hit === choices.defaultLevel) return { effort: "", deepThinking: false };
68348
+ return { effort: hit, deepThinking: hit === topLevel(choices) };
68349
+ }
68350
+ function effortAfterModelChange(choices, settings) {
68351
+ if (!choices) return { effort: "", deepThinking: false };
68352
+ if (!settings.effort?.trim() && !settings.deepThinking) return { effort: "", deepThinking: false };
68353
+ const current = chosenLevel(choices, settings.effort, !!settings.deepThinking && !settings.effort);
68354
+ const listed = settings.effort ? choices.levels.some((l3) => l3.toLowerCase() === settings.effort.trim().toLowerCase()) : true;
68355
+ return listed ? effortSettingsPatch(choices, current) : { effort: "", deepThinking: false };
68356
+ }
68357
+ function isReasoningOff(choices, level) {
68358
+ const l3 = level.toLowerCase();
68359
+ return NO_REASONING.has(l3) || choices.kind === "toggle" && l3 === "off";
68360
+ }
68361
+ function levelShare(choices, level) {
68362
+ if (choices.kind === "budget") return BUDGET_HINT[level] ?? "high";
68363
+ const reasoning = choices.levels.filter((l3) => !NO_REASONING.has(l3.toLowerCase()));
68364
+ const i4 = reasoning.findIndex((l3) => l3.toLowerCase() === level.toLowerCase());
68365
+ if (i4 < 0) return "medium";
68366
+ const steps = ["medium", "high", "xhigh", "max"];
68367
+ if (reasoning.length === 1) return "max";
68368
+ return steps[Math.round(i4 / (reasoning.length - 1) * (steps.length - 1))];
68369
+ }
68257
68370
  function resolveReasoningRequest({
68258
68371
  providerId,
68259
68372
  modelId,
68260
- deepThinking
68373
+ deepThinking,
68374
+ effort
68261
68375
  }) {
68376
+ if (effort?.trim()) {
68377
+ const choices = effortChoicesFor(providerId, modelId);
68378
+ const want = effort.trim().toLowerCase();
68379
+ if (choices?.levels.some((l3) => l3.toLowerCase() === want)) {
68380
+ const level = chosenLevel(choices, effort);
68381
+ if (choices.kind === "effort") return { kind: "effort", effort: level };
68382
+ if (choices.kind === "toggle") return { kind: "toggle", enabled: level === "on" };
68383
+ return { kind: "budget", effortHint: levelShare(choices, level) };
68384
+ }
68385
+ }
68386
+ const override = overrideFor(modelId);
68387
+ if (override) {
68388
+ const choices = { kind: "effort", levels: override, defaultLevel: defaultOf(override) };
68389
+ return { kind: "effort", effort: chosenLevel(choices, void 0, deepThinking) };
68390
+ }
68262
68391
  const profile = reasoningProfileFor(providerId, modelId);
68263
68392
  if (!profile) return { kind: "unknown" };
68264
68393
  if (!profile.reasoning) return { kind: "none" };
68265
- const values2 = normalizedEffortValues(profile.options);
68394
+ const values2 = rawEffortValues(profile.options);
68266
68395
  if (values2.length > 0) {
68267
- const ceilingIndex = values2.length - 1;
68268
- const index2 = deepThinking ? ceilingIndex : Math.max(0, ceilingIndex - 1);
68269
- return { kind: "effort", effort: values2[index2] };
68396
+ const choices = { kind: "effort", levels: values2, defaultLevel: defaultFor(providerId, values2) };
68397
+ return { kind: "effort", effort: chosenLevel(choices, void 0, deepThinking) };
68270
68398
  }
68271
68399
  if (profile.options.some((o2) => o2.type === "budget_tokens")) {
68272
68400
  return { kind: "budget", effortHint: deepThinking ? "max" : "high" };
@@ -68290,13 +68418,20 @@ function hasMeaningfulReasoningControl(providerId, modelId) {
68290
68418
  function __resetReasoningRegistryForTests() {
68291
68419
  profileById.clear();
68292
68420
  temperatureById.clear();
68421
+ effortOverrides.clear();
68293
68422
  }
68294
- var EFFORT_ORDER, profileById, temperatureById;
68423
+ var EFFORT_ORDER, profileById, temperatureById, effortOverrides, BUDGET_LEVELS, BUDGET_HINT, NO_REASONING, AUTO_EFFORT_LEVELS, AUTO_EFFORT_CHOICES;
68295
68424
  var init_model_reasoning_profile = __esm({
68296
68425
  "src/lib/routing/model-reasoning-profile.ts"() {
68297
68426
  EFFORT_ORDER = ["low", "medium", "high", "max"];
68298
68427
  profileById = /* @__PURE__ */ new Map();
68299
68428
  temperatureById = /* @__PURE__ */ new Map();
68429
+ effortOverrides = /* @__PURE__ */ new Map();
68430
+ BUDGET_LEVELS = ["low", "medium", "high"];
68431
+ BUDGET_HINT = { low: "medium", medium: "high", high: "max" };
68432
+ NO_REASONING = /* @__PURE__ */ new Set(["none", "minimal"]);
68433
+ AUTO_EFFORT_LEVELS = ["low", "medium", "max"];
68434
+ AUTO_EFFORT_CHOICES = { kind: "effort", levels: [...AUTO_EFFORT_LEVELS], defaultLevel: "medium" };
68300
68435
  }
68301
68436
  });
68302
68437
 
@@ -71438,6 +71573,13 @@ function getReasoningEffort(settings, ceiling) {
71438
71573
  function openAiReasoningEffort(settings) {
71439
71574
  return settings?.deepThinking ? "max" : "medium";
71440
71575
  }
71576
+ function chosenEffortFor(settings, providerId, modelId) {
71577
+ const want = settings?.effort?.trim();
71578
+ if (!want || !modelId) return null;
71579
+ const choices = effortChoicesFor(providerId, modelId);
71580
+ if (!choices?.levels.some((l3) => l3.toLowerCase() === want.toLowerCase())) return null;
71581
+ return { level: chosenLevel(choices, want), choices };
71582
+ }
71441
71583
  function reasoningBudgetTokens(effort, maxOutputTokens) {
71442
71584
  const max4 = Math.max(1, Math.floor(maxOutputTokens));
71443
71585
  const reserve = Math.max(Math.round(max4 * 0.15), 2048);
@@ -71453,10 +71595,13 @@ function getExtraProviderOptions(providerId, settings, includeExtendedThinking =
71453
71595
  return {};
71454
71596
  }
71455
71597
  if (providerId === "openai") {
71456
- return { reasoningEffort: openAiReasoningEffort(settings) };
71598
+ const chosen = chosenEffortFor(settings, providerId, modelId);
71599
+ return {
71600
+ reasoningEffort: chosen?.choices.kind === "effort" ? chosen.level : openAiReasoningEffort(settings)
71601
+ };
71457
71602
  }
71458
71603
  const deepThinking = !!settings?.deepThinking;
71459
- const resolved2 = modelId ? resolveReasoningRequest({ providerId, modelId, deepThinking }) : { kind: "unknown" };
71604
+ const resolved2 = modelId ? resolveReasoningRequest({ providerId, modelId, deepThinking, effort: settings?.effort }) : { kind: "unknown" };
71460
71605
  switch (resolved2.kind) {
71461
71606
  case "none":
71462
71607
  return {};
@@ -71568,6 +71713,13 @@ function detectReasoningCapability(modelApiId, builtinProviderId) {
71568
71713
  useAnthropicThinking
71569
71714
  };
71570
71715
  }
71716
+ function effortChoicesForModel(model) {
71717
+ if (!model) return null;
71718
+ if (model.provider === "compass" && isCoreAutoTier(model.name ?? "")) return AUTO_EFFORT_CHOICES;
71719
+ const choices = effortChoicesFor(resolveCapabilityProviderId(model), resolveReasoningCatalogModelId(model));
71720
+ if (choices) return choices;
71721
+ return isReasoningCapableModel(model) ? { kind: "toggle", levels: ["off", "on"], defaultLevel: "off" } : null;
71722
+ }
71571
71723
  function isReasoningCapableModel(model) {
71572
71724
  if (!model) return false;
71573
71725
  if (model.provider === "compass" && isCoreAutoTier(model.name ?? "")) return true;
@@ -71629,7 +71781,7 @@ function shouldOmitTemperature(providerOptions) {
71629
71781
  const anthropic2 = providerOptions?.anthropic;
71630
71782
  return Boolean(anthropic2?.thinking);
71631
71783
  }
71632
- function buildReasoningProviderOptions(cap, thinkingTier, effort = "medium", maxOutputTokens) {
71784
+ function buildReasoningProviderOptions(cap, thinkingTier, effort = "medium", maxOutputTokens, exactEffort, chosen) {
71633
71785
  if (!thinkingTier) {
71634
71786
  return {};
71635
71787
  }
@@ -71649,16 +71801,19 @@ function buildReasoningProviderOptions(cap, thinkingTier, effort = "medium", max
71649
71801
  };
71650
71802
  }
71651
71803
  if (cap.useGoogleThoughts) {
71804
+ const level = exactEffort && GEMINI_LEVELS.has(exactEffort.toLowerCase()) ? exactEffort.toLowerCase() : void 0;
71652
71805
  patch.google = {
71653
- thinkingConfig: {
71654
- includeThoughts: true
71806
+ thinkingConfig: chosen?.off ? { includeThoughts: false, thinkingBudget: 0 } : {
71807
+ includeThoughts: true,
71808
+ ...level ? { thinkingLevel: level } : {},
71809
+ ...chosen?.budget ? { thinkingBudget: reasoningBudgetTokens(effort, maxOutputTokens ?? 32e3) } : {}
71655
71810
  }
71656
71811
  };
71657
71812
  }
71658
71813
  if (cap.useOpenAiReasoningSummary) {
71659
71814
  patch.openai = {
71660
71815
  reasoningSummary: "auto",
71661
- reasoningEffort: effort
71816
+ reasoningEffort: exactEffort ?? effort
71662
71817
  };
71663
71818
  }
71664
71819
  if (cap.useAnthropicThinking) {
@@ -71671,6 +71826,7 @@ function buildReasoningProviderOptions(cap, thinkingTier, effort = "medium", max
71671
71826
  }
71672
71827
  return patch;
71673
71828
  }
71829
+ var GEMINI_LEVELS;
71674
71830
  var init_reasoning_detector = __esm({
71675
71831
  "src/lib/routing/reasoning-detector.ts"() {
71676
71832
  init_tier_context_limits();
@@ -71679,6 +71835,7 @@ var init_reasoning_detector = __esm({
71679
71835
  init_language_model_constants();
71680
71836
  init_model_reasoning_profile();
71681
71837
  init_thinking_utils();
71838
+ GEMINI_LEVELS = /* @__PURE__ */ new Set(["minimal", "low", "medium", "high"]);
71682
71839
  }
71683
71840
  });
71684
71841
 
@@ -72124,6 +72281,9 @@ function stampDeepThinkingSupport(modelsByProvider) {
72124
72281
  name: model.apiName,
72125
72282
  provider: providerId
72126
72283
  }),
72284
+ // /effort's levels for this model, on the same payload for the same
72285
+ // reasons (catalog and Core routing are main-process state).
72286
+ effortChoices: effortChoicesForModel({ name: model.apiName, provider: providerId }) ?? void 0,
72127
72287
  // AUDIO input rides the same payload for the same reasons: the modality
72128
72288
  // registry is main-process state, and this row is already invalidated on
72129
72289
  // provider CRUD and `core-models:changed`, so the mic follows a lineup
@@ -157062,9 +157222,9 @@ function convertFilePartToContent2({
157062
157222
  text: part.data.text
157063
157223
  };
157064
157224
  }
157065
- const topLevel = getTopLevelMediaType(part.mediaType);
157225
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
157066
157226
  let kind;
157067
- switch (topLevel) {
157227
+ switch (topLevel2) {
157068
157228
  case "image":
157069
157229
  kind = "image";
157070
157230
  break;
@@ -157211,8 +157371,8 @@ function convertToolResultPart2({
157211
157371
  if (item.type === "text") {
157212
157372
  blocks.push({ type: "text", text: item.text });
157213
157373
  } else if (item.type === "file") {
157214
- const topLevel = getTopLevelMediaType(item.mediaType);
157215
- if (topLevel !== "image") {
157374
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
157375
+ if (topLevel2 !== "image") {
157216
157376
  warnings.push({
157217
157377
  type: "other",
157218
157378
  message: `google.interactions: tool-result file with mediaType "${item.mediaType}" is not supported (Interactions \`function_result.result\` accepts only text and image content); part dropped.`
@@ -162570,8 +162730,8 @@ function convertToOpenAIChatMessages2({
162570
162730
  }
162571
162731
  case "url":
162572
162732
  case "data": {
162573
- const topLevel = getTopLevelMediaType(part.mediaType);
162574
- if (topLevel === "image") {
162733
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
162734
+ if (topLevel2 === "image") {
162575
162735
  return {
162576
162736
  type: "image_url",
162577
162737
  image_url: {
@@ -162582,7 +162742,7 @@ function convertToOpenAIChatMessages2({
162582
162742
  prompt_cache_breakpoint: promptCacheBreakpoint
162583
162743
  }
162584
162744
  };
162585
- } else if (topLevel === "audio") {
162745
+ } else if (topLevel2 === "audio") {
162586
162746
  if (part.data.type === "url") {
162587
162747
  throw new UnsupportedFunctionalityError({
162588
162748
  functionality: "audio file parts with URLs"
@@ -163334,8 +163494,8 @@ async function convertToOpenAIResponsesInput2({
163334
163494
  }
163335
163495
  case "url":
163336
163496
  case "data": {
163337
- const topLevel = getTopLevelMediaType(part.mediaType);
163338
- if (topLevel === "image") {
163497
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
163498
+ if (topLevel2 === "image") {
163339
163499
  return {
163340
163500
  type: "input_image",
163341
163501
  ...part.data.type === "url" ? { image_url: part.data.url.toString() } : typeof part.data.data === "string" && isFileId2(part.data.data, fileIdPrefixes) ? { file_id: part.data.data } : {
@@ -163915,13 +164075,13 @@ async function convertToOpenAIResponsesInput2({
163915
164075
  }
163916
164076
  };
163917
164077
  case "file": {
163918
- const topLevel = getTopLevelMediaType(item.mediaType);
164078
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
163919
164079
  const imageDetail = (_b26 = (_a210 = item.providerOptions) == null ? void 0 : _a210[providerOptionsName]) == null ? void 0 : _b26.imageDetail;
163920
164080
  if (item.data.type === "data") {
163921
164081
  const fullMediaType = resolveFullMediaType({
163922
164082
  part: item
163923
164083
  });
163924
- if (topLevel === "image") {
164084
+ if (topLevel2 === "image") {
163925
164085
  return {
163926
164086
  type: "input_image",
163927
164087
  image_url: `data:${fullMediaType};base64,${convertToBase64(item.data.data)}`,
@@ -163941,7 +164101,7 @@ async function convertToOpenAIResponsesInput2({
163941
164101
  };
163942
164102
  }
163943
164103
  if (item.data.type === "url") {
163944
- if (topLevel === "image") {
164104
+ if (topLevel2 === "image") {
163945
164105
  return {
163946
164106
  type: "input_image",
163947
164107
  image_url: item.data.url.toString(),
@@ -164018,13 +164178,13 @@ async function convertToOpenAIResponsesInput2({
164018
164178
  };
164019
164179
  }
164020
164180
  case "file": {
164021
- const topLevel = getTopLevelMediaType(item.mediaType);
164181
+ const topLevel2 = getTopLevelMediaType(item.mediaType);
164022
164182
  const imageDetail = (_b26 = (_a210 = item.providerOptions) == null ? void 0 : _a210[providerOptionsName]) == null ? void 0 : _b26.imageDetail;
164023
164183
  if (item.data.type === "data") {
164024
164184
  const fullMediaType = resolveFullMediaType({
164025
164185
  part: item
164026
164186
  });
164027
- if (topLevel === "image") {
164187
+ if (topLevel2 === "image") {
164028
164188
  return {
164029
164189
  type: "input_image",
164030
164190
  image_url: `data:${fullMediaType};base64,${convertToBase64(item.data.data)}`,
@@ -164044,7 +164204,7 @@ async function convertToOpenAIResponsesInput2({
164044
164204
  };
164045
164205
  }
164046
164206
  if (item.data.type === "url") {
164047
- if (topLevel === "image") {
164207
+ if (topLevel2 === "image") {
164048
164208
  return {
164049
164209
  type: "input_image",
164050
164210
  image_url: item.data.url.toString(),
@@ -181170,8 +181330,8 @@ async function convertToAnthropicPrompt2({
181170
181330
  }
181171
181331
  case "url":
181172
181332
  case "data": {
181173
- const topLevel = getTopLevelMediaType(part.mediaType);
181174
- if (topLevel === "image") {
181333
+ const topLevel2 = getTopLevelMediaType(part.mediaType);
181334
+ if (topLevel2 === "image") {
181175
181335
  anthropicContent.push({
181176
181336
  type: "image",
181177
181337
  source: part.data.type === "url" ? {
@@ -181184,7 +181344,7 @@ async function convertToAnthropicPrompt2({
181184
181344
  },
181185
181345
  cache_control: cacheControl
181186
181346
  });
181187
- } else if (topLevel === "application" && (part.data.type === "url" ? part.mediaType === "application/pdf" : resolveFullMediaType({ part }) === "application/pdf")) {
181347
+ } else if (topLevel2 === "application" && (part.data.type === "url" ? part.mediaType === "application/pdf" : resolveFullMediaType({ part }) === "application/pdf")) {
181188
181348
  betas.add("pdfs-2024-09-25");
181189
181349
  const enableCitations = await shouldEnableCitations2(
181190
181350
  part.providerOptions
@@ -181286,11 +181446,11 @@ async function convertToAnthropicPrompt2({
181286
181446
  text: contentPart.text
181287
181447
  };
181288
181448
  case "file": {
181289
- const topLevel = getTopLevelMediaType(
181449
+ const topLevel2 = getTopLevelMediaType(
181290
181450
  contentPart.mediaType
181291
181451
  );
181292
181452
  if (contentPart.data.type === "url") {
181293
- if (topLevel === "image") {
181453
+ if (topLevel2 === "image") {
181294
181454
  return {
181295
181455
  type: "image",
181296
181456
  source: {
@@ -181308,7 +181468,7 @@ async function convertToAnthropicPrompt2({
181308
181468
  };
181309
181469
  }
181310
181470
  if (contentPart.data.type === "data") {
181311
- if (topLevel === "image") {
181471
+ if (topLevel2 === "image") {
181312
181472
  return {
181313
181473
  type: "image",
181314
181474
  source: {
@@ -214428,9 +214588,11 @@ function getEffectiveModelForOptions(settings) {
214428
214588
  return settings.selectedModel;
214429
214589
  }
214430
214590
  function autoRequestHeaders(settings, options) {
214591
+ const effort = autoEffort(settings);
214431
214592
  const out = {
214432
214593
  "X-Atlarix-Purpose": options?.purpose ?? (options?.delegationRole === "subagent" ? "subagent" : "main"),
214433
- "X-Atlarix-Thinking": settings.deepThinking ? "1" : "0"
214594
+ "X-Atlarix-Effort": effort,
214595
+ "X-Atlarix-Thinking": effort === "max" ? "1" : "0"
214434
214596
  };
214435
214597
  if (options?.workMode) out["X-Atlarix-Mode"] = options.workMode;
214436
214598
  if (options?.escalate) out["X-Atlarix-Escalate"] = "1";
@@ -214901,6 +215063,7 @@ var init_get_model_client = __esm({
214901
215063
  init_ollama_provider();
214902
215064
  init_analytics();
214903
215065
  init_local_model_ollama_handler();
215066
+ init_model_reasoning_profile();
214904
215067
  logger19 = import_electron_log21.default.scope("getModelClient");
214905
215068
  }
214906
215069
  });
@@ -338153,14 +338316,19 @@ async function simpleStreamText(ctx, deps, {
338153
338316
  catalogModelId,
338154
338317
  modelClient.builtinProviderId
338155
338318
  );
338156
- const reasoningPatch = buildReasoningProviderOptions(
338319
+ const chosenEffort = chosenEffortFor(settings, capabilityProviderId, catalogModelId);
338320
+ const reasoningOff = chosenEffort ? isReasoningOff(chosenEffort.choices, chosenEffort.level) : false;
338321
+ const offByBudget = reasoningOff && (cap.useOpenRouterReasoning || cap.useAnthropicThinking);
338322
+ const reasoningPatch = offByBudget ? cap.useOpenRouterReasoning ? { openrouter: { reasoning: { enabled: false } } } : {} : buildReasoningProviderOptions(
338157
338323
  cap,
338158
338324
  true,
338159
- getReasoningEffort(
338325
+ chosenEffort ? levelShare(chosenEffort.choices, chosenEffort.level) : getReasoningEffort(
338160
338326
  settings,
338161
338327
  deriveReasoningCeiling(effectiveModel, modelClient.builtinProviderId)
338162
338328
  ),
338163
- maxOutputTokens
338329
+ maxOutputTokens,
338330
+ chosenEffort?.choices.kind === "effort" ? chosenEffort.level : void 0,
338331
+ chosenEffort ? { budget: chosenEffort.choices.kind === "budget", off: chosenEffort.choices.kind === "toggle" && reasoningOff } : void 0
338164
338332
  );
338165
338333
  if (reasoningPatch.openrouter) {
338166
338334
  providerOptions.openrouter = {
@@ -338182,7 +338350,7 @@ async function simpleStreamText(ctx, deps, {
338182
338350
  ...reasoningPatch.anthropic
338183
338351
  };
338184
338352
  }
338185
- const handledNatively = Boolean(reasoningPatch.openrouter) || Boolean(reasoningPatch.google) || Boolean(reasoningPatch.openai) || Boolean(reasoningPatch.anthropic);
338353
+ const handledNatively = offByBudget || Boolean(reasoningPatch.openrouter) || Boolean(reasoningPatch.google) || Boolean(reasoningPatch.openai) || Boolean(reasoningPatch.anthropic);
338186
338354
  if (modelClient.builtinProviderId && !handledNatively) {
338187
338355
  const compatibleReasoning = getExtraProviderOptions(
338188
338356
  capabilityProviderId,
@@ -338696,6 +338864,7 @@ var init_simple_stream_text = __esm({
338696
338864
  init_no_usable_model_output();
338697
338865
  init_safe_sender();
338698
338866
  init_native_history();
338867
+ init_model_reasoning_profile();
338699
338868
  init_thinking_utils();
338700
338869
  init_token_utils();
338701
338870
  init_network_retry();
@@ -344295,6 +344464,10 @@ async function finalizeTurn(ctx, deps) {
344295
344464
  userPrompt,
344296
344465
  abortController
344297
344466
  } = deps;
344467
+ if (ctx.askUserEndedTurn) {
344468
+ const live2 = stripToolCallXML(partialResponses.get(req.chatId) ?? "");
344469
+ if (live2.trim().length > ctx.fullResponse.trim().length) ctx.fullResponse = live2;
344470
+ }
344298
344471
  if (!ctx.fullResponse.trim() && !ctx.askUserEndedTurn) {
344299
344472
  ctx.fullResponse = AI_STREAM_EMPTY_RESPONSE_FALLBACK;
344300
344473
  }
@@ -344783,6 +344956,7 @@ var init_finalize = __esm({
344783
344956
  init_get_model_client();
344784
344957
  init_no_usable_model_output();
344785
344958
  init_safe_sender();
344959
+ init_text_tool_parser();
344786
344960
  init_thinking_tags();
344787
344961
  init_background_commands();
344788
344962
  init_mutation_verify();
@@ -346967,6 +347141,7 @@ var init_chat_stream_handlers = __esm({
346967
347141
  var core_model_overrides_exports = {};
346968
347142
  __export(core_model_overrides_exports, {
346969
347143
  parseCoreAuto: () => parseCoreAuto,
347144
+ parseModelEfforts: () => parseModelEfforts,
346970
347145
  refreshCoreModelOverrides: () => refreshCoreModelOverrides,
346971
347146
  warmCoreModelOverrides: () => warmCoreModelOverrides
346972
347147
  });
@@ -346992,15 +347167,29 @@ function applyOverridesAndNotify(raw) {
346992
347167
  setCoreModelRouting(parseCoreRouting(raw));
346993
347168
  const auto = parseCoreAuto(raw);
346994
347169
  setCoreAuto(auto);
347170
+ const efforts = parseModelEfforts(raw);
347171
+ registerEffortOverrides(efforts);
346995
347172
  const serialized = map3 ? JSON.stringify([
346996
347173
  Object.entries(map3).sort(([a2], [b3]) => a2.localeCompare(b3)),
346997
- auto
347174
+ auto,
347175
+ efforts
346998
347176
  ]) : null;
346999
347177
  if (serialized !== lastAppliedSerialized) {
347000
347178
  lastAppliedSerialized = serialized;
347001
347179
  broadcastCoreModelsChanged();
347002
347180
  }
347003
347181
  }
347182
+ function parseModelEfforts(raw) {
347183
+ const block = raw && typeof raw === "object" ? raw.modelEfforts : void 0;
347184
+ const out = {};
347185
+ if (!block || typeof block !== "object") return out;
347186
+ for (const [id, values2] of Object.entries(block)) {
347187
+ if (!Array.isArray(values2)) continue;
347188
+ const list = values2.filter((v2) => typeof v2 === "string" && v2.trim() !== "").map((v2) => v2.trim());
347189
+ if (list.length) out[id] = list;
347190
+ }
347191
+ return out;
347192
+ }
347004
347193
  function parseCoreModelsPayload(raw) {
347005
347194
  if (!raw || typeof raw !== "object") return null;
347006
347195
  const models = raw.models;
@@ -347175,6 +347364,7 @@ var init_core_model_overrides = __esm({
347175
347364
  import_electron_log110 = __toESM(require_src());
347176
347365
  init_electron_stub();
347177
347366
  init_paths();
347367
+ init_model_reasoning_profile();
347178
347368
  init_compass_constants();
347179
347369
  init_core_model_override_store();
347180
347370
  logger107 = import_electron_log110.default.scope("core-models");
@@ -347585,7 +347775,8 @@ async function runHeadlessAgent(opts) {
347585
347775
  telemetryConsent: "opted_out",
347586
347776
  // Always written, both states. `deepThinking` is `z.boolean().optional()` with no
347587
347777
  // default, so omitting it resolved to OFF — one notch below the model's ceiling.
347588
- deepThinking: !!opts.deepThinking
347778
+ deepThinking: !!opts.deepThinking,
347779
+ ...opts.effort ? { effort: opts.effort } : {}
347589
347780
  };
347590
347781
  if (opts.provider.apiKey) {
347591
347782
  settings.providerSettings = {
@@ -347702,7 +347893,7 @@ ${err2.stack}` : "";
347702
347893
  }
347703
347894
 
347704
347895
  // src/headless/atlarix-headless.mts
347705
- var VERSION15 = false ? "dev" : "15.7.1";
347896
+ var VERSION15 = false ? "dev" : "15.8.0";
347706
347897
  if (process.argv[2] === "run") process.argv.splice(2, 1);
347707
347898
  var RUN_HELP = `atlarix run: one turn without the UI, for scripts and CI
347708
347899
 
@@ -347719,6 +347910,7 @@ Options
347719
347910
  --api-key <key> | --api-key-file <path>
347720
347911
  --attach <file> Attach a file (repeatable)
347721
347912
  --deep-thinking The model's highest reasoning level
347913
+ --effort <level> A level exactly as the model lists it (e.g. xhigh)
347722
347914
  --timeout <ms> Stop after this long (default: no limit)
347723
347915
  --output-file <path> Write the final reply here
347724
347916
  --trajectory-file <path> Write the full trace here
@@ -347762,6 +347954,7 @@ async function main() {
347762
347954
  const openrouterProviderJson = arg("openrouter-provider") ?? process.env.ATLARIX_OPENROUTER_PROVIDER_JSON;
347763
347955
  const mode = arg("mode") ?? "build";
347764
347956
  const deepThinking = flag("deep-thinking") ?? envFlag("ATLARIX_HEADLESS_DEEP_THINKING") ?? false;
347957
+ const effort = arg("effort") ?? process.env.ATLARIX_HEADLESS_EFFORT;
347765
347958
  const timeoutArg = arg("timeout") ?? process.env.ATLARIX_HEADLESS_TIMEOUT_MS;
347766
347959
  const timeoutMs = timeoutArg ? Number(timeoutArg) : void 0;
347767
347960
  const outputFile = arg("output-file") ?? process.env.ATLARIX_HEADLESS_OUTPUT_FILE;
@@ -347826,6 +348019,7 @@ async function main() {
347826
348019
  mode,
347827
348020
  timeoutMs,
347828
348021
  deepThinking,
348022
+ effort,
347829
348023
  trajectoryFile,
347830
348024
  attachments
347831
348025
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atlarix",
3
- "version": "15.7.1",
3
+ "version": "15.8.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.7.1",
69
- "atlarix-darwin-x64": "15.7.1",
70
- "atlarix-linux-x64": "15.7.1",
71
- "atlarix-linux-arm64": "15.7.1",
72
- "atlarix-linux-x64-musl": "15.7.1",
73
- "atlarix-linux-arm64-musl": "15.7.1",
74
- "atlarix-windows-x64": "15.7.1"
68
+ "atlarix-darwin-arm64": "15.8.0",
69
+ "atlarix-darwin-x64": "15.8.0",
70
+ "atlarix-linux-x64": "15.8.0",
71
+ "atlarix-linux-arm64": "15.8.0",
72
+ "atlarix-linux-x64-musl": "15.8.0",
73
+ "atlarix-linux-arm64-musl": "15.8.0",
74
+ "atlarix-windows-x64": "15.8.0"
75
75
  }
76
76
  }