@dotobokuri/fleet-console 1.54.0 → 1.54.1

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/cli.mjs CHANGED
@@ -30470,10 +30470,6 @@ new Map(
30470
30470
  REASONING_EFFORTS.map((effort, index) => [effort, index])
30471
30471
  );
30472
30472
  var CLAUDE_COMPAT_CONTEXT_WINDOW = 1e6;
30473
- var CLAUDE_DEFAULT_CONTEXT_WINDOW = 2e5;
30474
- function canProjectClaudeContextWindow(contextWindow) {
30475
- return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > CLAUDE_DEFAULT_CONTEXT_WINDOW;
30476
- }
30477
30473
  function isClaudeOneMillionContextWindow(contextWindow) {
30478
30474
  return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW;
30479
30475
  }
@@ -31010,10 +31006,6 @@ var models_default = {
31010
31006
  };
31011
31007
  var GATEWAY_PROVIDERS = ["codex", "cursor", "kimi", "opencode"];
31012
31008
  var GATEWAY_MODEL_WIRES = ["anthropic", "responses", "chat-completions"];
31013
- function isAnthropicPassthroughModel(model) {
31014
- if (model.provider === "kimi") return true;
31015
- return model.provider === "opencode" && (model.wire ?? "anthropic") === "anthropic";
31016
- }
31017
31009
  var GATEWAY_REASONING_EFFORTS = [
31018
31010
  "low",
31019
31011
  "medium",
@@ -31149,10 +31141,7 @@ function toGatewayModelAlias(modelId) {
31149
31141
  }
31150
31142
  function toClaudeGatewayModelId(model) {
31151
31143
  const alias = toGatewayModelAlias(model.id);
31152
- if (canProjectClaudeContextWindow(model.contextWindow) && (!isAnthropicPassthroughModel(model) || isClaudeOneMillionContextWindow(model.contextWindow))) {
31153
- return `${alias}${CLAUDE_ONE_MILLION_MARKER}`;
31154
- }
31155
- return alias;
31144
+ return isClaudeOneMillionContextWindow(model.contextWindow) ? `${alias}${CLAUDE_ONE_MILLION_MARKER}` : alias;
31156
31145
  }
31157
31146
  function toClaudeGatewayModelDisplayName(model) {
31158
31147
  return isClaudeOneMillionContextWindow(model.contextWindow) ? `${model.displayName}${CLAUDE_ONE_MILLION_DISPLAY_SUFFIX}` : model.displayName;
@@ -34749,6 +34738,7 @@ function claudeGatewayLaunchEnv(inherited, options) {
34749
34738
  env.CLAUDE_SECURESTORAGE_CONFIG_DIR = "";
34750
34739
  env.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1";
34751
34740
  env.ENABLE_TOOL_SEARCH = "true";
34741
+ env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ??= "1000000";
34752
34742
  delete env.ANTHROPIC_AUTH_TOKEN;
34753
34743
  delete env.ANTHROPIC_API_KEY;
34754
34744
  delete env.ANTHROPIC_MODEL;
@@ -17475,10 +17475,6 @@ new Map(
17475
17475
  REASONING_EFFORTS.map((effort, index) => [effort, index])
17476
17476
  );
17477
17477
  var CLAUDE_COMPAT_CONTEXT_WINDOW = 1e6;
17478
- var CLAUDE_DEFAULT_CONTEXT_WINDOW = 2e5;
17479
- function canProjectClaudeContextWindow(contextWindow) {
17480
- return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > CLAUDE_DEFAULT_CONTEXT_WINDOW;
17481
- }
17482
17478
  function isClaudeOneMillionContextWindow(contextWindow) {
17483
17479
  return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW;
17484
17480
  }
@@ -18015,10 +18011,6 @@ var models_default = {
18015
18011
  };
18016
18012
  var GATEWAY_PROVIDERS = ["codex", "cursor", "kimi", "opencode"];
18017
18013
  var GATEWAY_MODEL_WIRES = ["anthropic", "responses", "chat-completions"];
18018
- function isAnthropicPassthroughModel(model) {
18019
- if (model.provider === "kimi") return true;
18020
- return model.provider === "opencode" && (model.wire ?? "anthropic") === "anthropic";
18021
- }
18022
18014
  var GATEWAY_REASONING_EFFORTS = [
18023
18015
  "low",
18024
18016
  "medium",
@@ -18154,10 +18146,7 @@ function toGatewayModelAlias(modelId) {
18154
18146
  }
18155
18147
  function toClaudeGatewayModelId(model) {
18156
18148
  const alias = toGatewayModelAlias(model.id);
18157
- if (canProjectClaudeContextWindow(model.contextWindow) && (!isAnthropicPassthroughModel(model) || isClaudeOneMillionContextWindow(model.contextWindow))) {
18158
- return `${alias}${CLAUDE_ONE_MILLION_MARKER}`;
18159
- }
18160
- return alias;
18149
+ return isClaudeOneMillionContextWindow(model.contextWindow) ? `${alias}${CLAUDE_ONE_MILLION_MARKER}` : alias;
18161
18150
  }
18162
18151
  function toClaudeGatewayModelDisplayName(model) {
18163
18152
  return isClaudeOneMillionContextWindow(model.contextWindow) ? `${model.displayName}${CLAUDE_ONE_MILLION_DISPLAY_SUFFIX}` : model.displayName;
@@ -19349,6 +19338,7 @@ function claudeGatewayLaunchEnv(inherited, options) {
19349
19338
  env.CLAUDE_SECURESTORAGE_CONFIG_DIR = "";
19350
19339
  env.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1";
19351
19340
  env.ENABLE_TOOL_SEARCH = "true";
19341
+ env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ??= "1000000";
19352
19342
  delete env.ANTHROPIC_AUTH_TOKEN;
19353
19343
  delete env.ANTHROPIC_API_KEY;
19354
19344
  delete env.ANTHROPIC_MODEL;
@@ -20113,6 +20113,8 @@ function cjkRatio(text2) {
20113
20113
  }
20114
20114
  var CLAUDE_COMPAT_CONTEXT_WINDOW = 1e6;
20115
20115
  var CLAUDE_DEFAULT_CONTEXT_WINDOW = 2e5;
20116
+ var CLAUDE_COMPACT_RESERVE = 32e3;
20117
+ var PROVIDER_COMPACT_RESERVE = 16e3;
20116
20118
  var DEFAULT_MAX_JSON_BYTES = 16 * 1024 * 1024;
20117
20119
  var DEFAULT_MAX_SSE_FRAME_BYTES = 1024 * 1024;
20118
20120
  var MAX_SSE_SEPARATOR_BYTES = 4;
@@ -20121,9 +20123,6 @@ var ANTHROPIC_INPUT_USAGE_FIELDS = [
20121
20123
  "cache_read_input_tokens",
20122
20124
  "cache_creation_input_tokens"
20123
20125
  ];
20124
- function canProjectClaudeContextWindow(contextWindow) {
20125
- return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > CLAUDE_DEFAULT_CONTEXT_WINDOW;
20126
- }
20127
20126
  function isClaudeOneMillionContextWindow(contextWindow) {
20128
20127
  return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW;
20129
20128
  }
@@ -20134,18 +20133,21 @@ function stripClaudeOneMillionMarker(modelId) {
20134
20133
  return modelId.replace(/\[1m\]$/i, "");
20135
20134
  }
20136
20135
  function projectClaudeContextInputTokens(inputTokens, advertisedContextWindow, upstreamContextWindow = advertisedContextWindow) {
20137
- if (!Number.isFinite(inputTokens) || inputTokens < 0 || !canProjectClaudeContextWindow(advertisedContextWindow)) {
20138
- return inputTokens;
20139
- }
20140
- const projectionWindow = positiveContextWindow(upstreamContextWindow) ?? positiveContextWindow(advertisedContextWindow);
20141
- if (projectionWindow === void 0) return inputTokens;
20136
+ if (!Number.isFinite(inputTokens) || inputTokens < 0) return inputTokens;
20137
+ const advertisedWindow = positiveContextWindow(advertisedContextWindow);
20138
+ if (advertisedWindow === void 0) return inputTokens;
20139
+ const projectionWindow = positiveContextWindow(upstreamContextWindow) ?? advertisedWindow;
20140
+ const coordinate = advertisedWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW ? CLAUDE_COMPAT_CONTEXT_WINDOW : CLAUDE_DEFAULT_CONTEXT_WINDOW;
20141
+ const claudeCompactThreshold = coordinate - CLAUDE_COMPACT_RESERVE;
20142
+ const providerCompactThreshold = projectionWindow - PROVIDER_COMPACT_RESERVE;
20143
+ if (providerCompactThreshold <= 0) return Math.min(coordinate, inputTokens);
20142
20144
  return Math.min(
20143
- CLAUDE_COMPAT_CONTEXT_WINDOW,
20144
- Math.ceil(inputTokens * CLAUDE_COMPAT_CONTEXT_WINDOW / projectionWindow)
20145
+ coordinate,
20146
+ Math.ceil(inputTokens * claudeCompactThreshold / providerCompactThreshold)
20145
20147
  );
20146
20148
  }
20147
20149
  async function* projectAnthropicResponseUsage(chunks, options) {
20148
- const contextWindow = canProjectClaudeContextWindow(options.contextWindow) ? options.contextWindow : void 0;
20150
+ const contextWindow = positiveContextWindow(options.contextWindow);
20149
20151
  const responseModel = typeof options.responseModel === "string" && options.responseModel.length > 0 ? options.responseModel : void 0;
20150
20152
  if (contextWindow === void 0 && responseModel === void 0) {
20151
20153
  yield* chunks;
@@ -20321,18 +20323,25 @@ function projectAnthropicUsageEnvelope(value, contextWindow, responseModel) {
20321
20323
  function projectUsageProperty(container, property, contextWindow) {
20322
20324
  const usage3 = container[property];
20323
20325
  if (!isRecord2(usage3)) return { changed: false, value: container };
20324
- let projectedUsage = usage3;
20325
- let changed = false;
20326
- for (const field of ANTHROPIC_INPUT_USAGE_FIELDS) {
20326
+ const coordinates = ANTHROPIC_INPUT_USAGE_FIELDS.map((field) => {
20327
20327
  const tokens = usage3[field];
20328
- if (typeof tokens !== "number" || !Number.isFinite(tokens) || tokens < 0) continue;
20329
- const projectedTokens = projectClaudeContextInputTokens(tokens, contextWindow);
20330
- if (projectedTokens === tokens) continue;
20331
- if (!changed) projectedUsage = { ...usage3 };
20332
- projectedUsage[field] = projectedTokens;
20333
- changed = true;
20334
- }
20335
- return changed ? { changed: true, value: { ...container, [property]: projectedUsage } } : { changed: false, value: container };
20328
+ return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { field, tokens } : void 0;
20329
+ }).filter((entry) => entry !== void 0);
20330
+ if (coordinates.length === 0) return { changed: false, value: container };
20331
+ const total = coordinates.reduce((sum, entry) => sum + entry.tokens, 0);
20332
+ const projectedTotal = projectClaudeContextInputTokens(total, contextWindow);
20333
+ if (projectedTotal === total) return { changed: false, value: container };
20334
+ const projectedUsage = { ...usage3 };
20335
+ const remainderField = coordinates.some((entry) => entry.field === "input_tokens") ? "input_tokens" : coordinates[0].field;
20336
+ let assigned = 0;
20337
+ for (const entry of coordinates) {
20338
+ if (entry.field === remainderField) continue;
20339
+ const projectedTokens = total === 0 ? 0 : Math.floor(entry.tokens * projectedTotal / total);
20340
+ projectedUsage[entry.field] = projectedTokens;
20341
+ assigned += projectedTokens;
20342
+ }
20343
+ projectedUsage[remainderField] = projectedTotal - assigned;
20344
+ return { changed: true, value: { ...container, [property]: projectedUsage } };
20336
20345
  }
20337
20346
  function findSseSeparator(bytes) {
20338
20347
  for (let index = 0; index < bytes.byteLength - 1; index += 1) {
@@ -20999,10 +21008,6 @@ var KIMI_CODE_API_BASE_URL = "https://api.kimi.com/coding";
20999
21008
  var KIMI_CODE_MODEL = "k3";
21000
21009
  var GATEWAY_PROVIDERS = ["codex", "cursor", "kimi", "opencode"];
21001
21010
  var GATEWAY_MODEL_WIRES = ["anthropic", "responses", "chat-completions"];
21002
- function isAnthropicPassthroughModel(model) {
21003
- if (model.provider === "kimi") return true;
21004
- return model.provider === "opencode" && (model.wire ?? "anthropic") === "anthropic";
21005
- }
21006
21011
  var GATEWAY_REASONING_EFFORTS = [
21007
21012
  "low",
21008
21013
  "medium",
@@ -21138,10 +21143,7 @@ function toGatewayModelAlias(modelId) {
21138
21143
  }
21139
21144
  function toClaudeGatewayModelId(model) {
21140
21145
  const alias = toGatewayModelAlias(model.id);
21141
- if (canProjectClaudeContextWindow(model.contextWindow) && (!isAnthropicPassthroughModel(model) || isClaudeOneMillionContextWindow(model.contextWindow))) {
21142
- return `${alias}${CLAUDE_ONE_MILLION_MARKER}`;
21143
- }
21144
- return alias;
21146
+ return isClaudeOneMillionContextWindow(model.contextWindow) ? `${alias}${CLAUDE_ONE_MILLION_MARKER}` : alias;
21145
21147
  }
21146
21148
  function toClaudeGatewayModelDisplayName(model) {
21147
21149
  return isClaudeOneMillionContextWindow(model.contextWindow) ? `${model.displayName}${CLAUDE_ONE_MILLION_DISPLAY_SUFFIX}` : model.displayName;
@@ -29691,7 +29693,7 @@ function createAiGatewayRouter(deps) {
29691
29693
  await proxyToAnthropic(req.headers, res, body, fetchImpl, controller.signal);
29692
29694
  return true;
29693
29695
  }
29694
- const claudeContextWindow = hasClaudeOneMillionMarker(toClaudeGatewayModelId(target2)) ? target2.contextWindow : void 0;
29696
+ const claudeContextWindow = target2.contextWindow;
29695
29697
  if (target2.provider === "kimi") {
29696
29698
  await proxyToKimi(
29697
29699
  req.headers,
@@ -29960,6 +29962,9 @@ function prepareAiGatewayLaunchProfile(profile, options) {
29960
29962
  ANTHROPIC_BASE_URL: options.baseUrl,
29961
29963
  // 이게 있어야 /model picker가 게이트웨이의 GET /v1/models를 조회한다.
29962
29964
  CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1",
29965
+ // 1M ceiling은 `[1m]` 모델의 선제 압축을 켜고, unmarked custom model에서는
29966
+ // Claude Code의 200k 좌표로 clamp된다. 명시적 운영자 override는 보존한다.
29967
+ CLAUDE_CODE_AUTO_COMPACT_WINDOW: profile.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ?? "1000000",
29963
29968
  // Gateway가 tool_reference 계약을 보존한다. Cursor는 이를 지연 catalog 선택에 쓰고,
29964
29969
  // 호환 프로바이더 경계는 각자의 eager wire 형식으로 정규화한다.
29965
29970
  ENABLE_TOOL_SEARCH: "true"
@@ -44098,6 +44103,7 @@ function claudeGatewayLaunchEnv(inherited, options) {
44098
44103
  env.CLAUDE_SECURESTORAGE_CONFIG_DIR = "";
44099
44104
  env.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1";
44100
44105
  env.ENABLE_TOOL_SEARCH = "true";
44106
+ env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ??= "1000000";
44101
44107
  delete env.ANTHROPIC_AUTH_TOKEN;
44102
44108
  delete env.ANTHROPIC_API_KEY;
44103
44109
  delete env.ANTHROPIC_MODEL;
package/dist/fleet.mjs CHANGED
@@ -21536,6 +21536,8 @@ function cjkRatio(text) {
21536
21536
  }
21537
21537
  var CLAUDE_COMPAT_CONTEXT_WINDOW = 1e6;
21538
21538
  var CLAUDE_DEFAULT_CONTEXT_WINDOW = 2e5;
21539
+ var CLAUDE_COMPACT_RESERVE = 32e3;
21540
+ var PROVIDER_COMPACT_RESERVE = 16e3;
21539
21541
  var DEFAULT_MAX_JSON_BYTES = 16 * 1024 * 1024;
21540
21542
  var DEFAULT_MAX_SSE_FRAME_BYTES = 1024 * 1024;
21541
21543
  var MAX_SSE_SEPARATOR_BYTES = 4;
@@ -21544,9 +21546,6 @@ var ANTHROPIC_INPUT_USAGE_FIELDS = [
21544
21546
  "cache_read_input_tokens",
21545
21547
  "cache_creation_input_tokens"
21546
21548
  ];
21547
- function canProjectClaudeContextWindow(contextWindow) {
21548
- return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > CLAUDE_DEFAULT_CONTEXT_WINDOW;
21549
- }
21550
21549
  function isClaudeOneMillionContextWindow(contextWindow) {
21551
21550
  return typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW;
21552
21551
  }
@@ -21557,18 +21556,21 @@ function stripClaudeOneMillionMarker(modelId) {
21557
21556
  return modelId.replace(/\[1m\]$/i, "");
21558
21557
  }
21559
21558
  function projectClaudeContextInputTokens(inputTokens, advertisedContextWindow, upstreamContextWindow = advertisedContextWindow) {
21560
- if (!Number.isFinite(inputTokens) || inputTokens < 0 || !canProjectClaudeContextWindow(advertisedContextWindow)) {
21561
- return inputTokens;
21562
- }
21563
- const projectionWindow = positiveContextWindow(upstreamContextWindow) ?? positiveContextWindow(advertisedContextWindow);
21564
- if (projectionWindow === void 0) return inputTokens;
21559
+ if (!Number.isFinite(inputTokens) || inputTokens < 0) return inputTokens;
21560
+ const advertisedWindow = positiveContextWindow(advertisedContextWindow);
21561
+ if (advertisedWindow === void 0) return inputTokens;
21562
+ const projectionWindow = positiveContextWindow(upstreamContextWindow) ?? advertisedWindow;
21563
+ const coordinate = advertisedWindow >= CLAUDE_COMPAT_CONTEXT_WINDOW ? CLAUDE_COMPAT_CONTEXT_WINDOW : CLAUDE_DEFAULT_CONTEXT_WINDOW;
21564
+ const claudeCompactThreshold = coordinate - CLAUDE_COMPACT_RESERVE;
21565
+ const providerCompactThreshold = projectionWindow - PROVIDER_COMPACT_RESERVE;
21566
+ if (providerCompactThreshold <= 0) return Math.min(coordinate, inputTokens);
21565
21567
  return Math.min(
21566
- CLAUDE_COMPAT_CONTEXT_WINDOW,
21567
- Math.ceil(inputTokens * CLAUDE_COMPAT_CONTEXT_WINDOW / projectionWindow)
21568
+ coordinate,
21569
+ Math.ceil(inputTokens * claudeCompactThreshold / providerCompactThreshold)
21568
21570
  );
21569
21571
  }
21570
21572
  async function* projectAnthropicResponseUsage(chunks, options) {
21571
- const contextWindow = canProjectClaudeContextWindow(options.contextWindow) ? options.contextWindow : void 0;
21573
+ const contextWindow = positiveContextWindow(options.contextWindow);
21572
21574
  const responseModel = typeof options.responseModel === "string" && options.responseModel.length > 0 ? options.responseModel : void 0;
21573
21575
  if (contextWindow === void 0 && responseModel === void 0) {
21574
21576
  yield* chunks;
@@ -21744,18 +21746,25 @@ function projectAnthropicUsageEnvelope(value, contextWindow, responseModel) {
21744
21746
  function projectUsageProperty(container, property, contextWindow) {
21745
21747
  const usage3 = container[property];
21746
21748
  if (!isRecord2(usage3)) return { changed: false, value: container };
21747
- let projectedUsage = usage3;
21748
- let changed = false;
21749
- for (const field of ANTHROPIC_INPUT_USAGE_FIELDS) {
21749
+ const coordinates = ANTHROPIC_INPUT_USAGE_FIELDS.map((field) => {
21750
21750
  const tokens = usage3[field];
21751
- if (typeof tokens !== "number" || !Number.isFinite(tokens) || tokens < 0) continue;
21752
- const projectedTokens = projectClaudeContextInputTokens(tokens, contextWindow);
21753
- if (projectedTokens === tokens) continue;
21754
- if (!changed) projectedUsage = { ...usage3 };
21755
- projectedUsage[field] = projectedTokens;
21756
- changed = true;
21757
- }
21758
- return changed ? { changed: true, value: { ...container, [property]: projectedUsage } } : { changed: false, value: container };
21751
+ return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { field, tokens } : void 0;
21752
+ }).filter((entry) => entry !== void 0);
21753
+ if (coordinates.length === 0) return { changed: false, value: container };
21754
+ const total = coordinates.reduce((sum, entry) => sum + entry.tokens, 0);
21755
+ const projectedTotal = projectClaudeContextInputTokens(total, contextWindow);
21756
+ if (projectedTotal === total) return { changed: false, value: container };
21757
+ const projectedUsage = { ...usage3 };
21758
+ const remainderField = coordinates.some((entry) => entry.field === "input_tokens") ? "input_tokens" : coordinates[0].field;
21759
+ let assigned = 0;
21760
+ for (const entry of coordinates) {
21761
+ if (entry.field === remainderField) continue;
21762
+ const projectedTokens = total === 0 ? 0 : Math.floor(entry.tokens * projectedTotal / total);
21763
+ projectedUsage[entry.field] = projectedTokens;
21764
+ assigned += projectedTokens;
21765
+ }
21766
+ projectedUsage[remainderField] = projectedTotal - assigned;
21767
+ return { changed: true, value: { ...container, [property]: projectedUsage } };
21759
21768
  }
21760
21769
  function findSseSeparator(bytes) {
21761
21770
  for (let index = 0; index < bytes.byteLength - 1; index += 1) {
@@ -22422,10 +22431,6 @@ var KIMI_CODE_API_BASE_URL = "https://api.kimi.com/coding";
22422
22431
  var KIMI_CODE_MODEL = "k3";
22423
22432
  var GATEWAY_PROVIDERS = ["codex", "cursor", "kimi", "opencode"];
22424
22433
  var GATEWAY_MODEL_WIRES = ["anthropic", "responses", "chat-completions"];
22425
- function isAnthropicPassthroughModel(model) {
22426
- if (model.provider === "kimi") return true;
22427
- return model.provider === "opencode" && (model.wire ?? "anthropic") === "anthropic";
22428
- }
22429
22434
  var GATEWAY_REASONING_EFFORTS = [
22430
22435
  "low",
22431
22436
  "medium",
@@ -22561,10 +22566,7 @@ function toGatewayModelAlias(modelId) {
22561
22566
  }
22562
22567
  function toClaudeGatewayModelId(model) {
22563
22568
  const alias = toGatewayModelAlias(model.id);
22564
- if (canProjectClaudeContextWindow(model.contextWindow) && (!isAnthropicPassthroughModel(model) || isClaudeOneMillionContextWindow(model.contextWindow))) {
22565
- return `${alias}${CLAUDE_ONE_MILLION_MARKER}`;
22566
- }
22567
- return alias;
22569
+ return isClaudeOneMillionContextWindow(model.contextWindow) ? `${alias}${CLAUDE_ONE_MILLION_MARKER}` : alias;
22568
22570
  }
22569
22571
  function toClaudeGatewayModelDisplayName(model) {
22570
22572
  return isClaudeOneMillionContextWindow(model.contextWindow) ? `${model.displayName}${CLAUDE_ONE_MILLION_DISPLAY_SUFFIX}` : model.displayName;
@@ -31874,7 +31876,7 @@ function createAiGatewayRouter(deps) {
31874
31876
  await proxyToAnthropic(req.headers, res, body2, fetchImpl, controller.signal);
31875
31877
  return true;
31876
31878
  }
31877
- const claudeContextWindow = hasClaudeOneMillionMarker(toClaudeGatewayModelId(target2)) ? target2.contextWindow : void 0;
31879
+ const claudeContextWindow = target2.contextWindow;
31878
31880
  if (target2.provider === "kimi") {
31879
31881
  await proxyToKimi(
31880
31882
  req.headers,
@@ -32460,6 +32462,9 @@ function prepareAiGatewayLaunchProfile(profile, options) {
32460
32462
  ANTHROPIC_BASE_URL: options.baseUrl,
32461
32463
  // 이게 있어야 /model picker가 게이트웨이의 GET /v1/models를 조회한다.
32462
32464
  CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1",
32465
+ // 1M ceiling은 `[1m]` 모델의 선제 압축을 켜고, unmarked custom model에서는
32466
+ // Claude Code의 200k 좌표로 clamp된다. 명시적 운영자 override는 보존한다.
32467
+ CLAUDE_CODE_AUTO_COMPACT_WINDOW: profile.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ?? "1000000",
32463
32468
  // Gateway가 tool_reference 계약을 보존한다. Cursor는 이를 지연 catalog 선택에 쓰고,
32464
32469
  // 호환 프로바이더 경계는 각자의 eager wire 형식으로 정규화한다.
32465
32470
  ENABLE_TOOL_SEARCH: "true"
@@ -48372,6 +48377,7 @@ function claudeGatewayLaunchEnv(inherited, options) {
48372
48377
  env.CLAUDE_SECURESTORAGE_CONFIG_DIR = "";
48373
48378
  env.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1";
48374
48379
  env.ENABLE_TOOL_SEARCH = "true";
48380
+ env.CLAUDE_CODE_AUTO_COMPACT_WINDOW ??= "1000000";
48375
48381
  delete env.ANTHROPIC_AUTH_TOKEN;
48376
48382
  delete env.ANTHROPIC_API_KEY;
48377
48383
  delete env.ANTHROPIC_MODEL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotobokuri/fleet-console",
3
- "version": "1.54.0",
3
+ "version": "1.54.1",
4
4
  "description": "Fleet Console — sole owner of the fleet and fleet-console bins, Console web surface, and thin Claude Code launcher.",
5
5
  "repository": {
6
6
  "type": "git",