@atlasharness/atlascode 0.1.67 → 0.1.69

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.
Files changed (3) hide show
  1. package/README.md +18 -3
  2. package/dist/cli.js +316 -127
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  (OpenAI-protocol 静态键车道,任意 OpenAI-compatible 端点)与国产平台工具链预留
6
6
  (Ascend NPU 域包为可插拔叠加层,W6 起接入)。
7
7
 
8
- > 版本现状:G-α 前置阶段(v0.1.0 发布待 W2–W4 闭环 + P-1 远端仓库,见
9
- > `docs/roadmap-domestic-and-residuals.md`)。
8
+ > 版本现状:v0.1.x 持续发布(npm `@atlasharness/atlascode` live,P-1 远端仓已解除,
9
+ > 见 `docs/roadmap-domestic-and-residuals.md`)。
10
10
 
11
11
  ## 安装
12
12
 
@@ -20,7 +20,22 @@ npm install -g @atlasharness/atlascode
20
20
  atlascode --help # 别名 `atlas` 同效
21
21
  ```
22
22
 
23
- **② git 源码**(前置:`git` + [bun](https://bun.sh)(构建)+ `node`(运行))
23
+ **Windows(PowerShell / cmd)**
24
+
25
+ ```powershell
26
+ # npm 通道(与 Unix 同款,仅需 Node ≥ 20)
27
+ npm install -g @atlasharness/atlascode
28
+ atlascode --help # 别名 `atlas` 同效
29
+ ```
30
+
31
+ > - 装完 `atlascode`/`atlas` 不识别 → 重开终端(或把 npm 全局 bin 目录加入 `PATH`)。
32
+ > - git 源码通道 `./install.sh` 为 Unix shell 脚本,Windows 不可直接用;Windows 走 npm 通道,
33
+ > 或手动 `git clone <repo-url>` + [bun](https://bun.sh)(`bun install && bun run build`)。
34
+ > - 镜像 registry(如 npmmirror)超时/403 时切官方源:
35
+ > `npm install -g @atlasharness/atlascode --registry https://registry.npmjs.org`
36
+ > (Windows 多 OS 波 0.1.43 已验 npm 通道安装 + 启动链)。
37
+
38
+ **② git 源码**(Unix;前置:`git` + [bun](https://bun.sh)(构建)+ `node`(运行))
24
39
 
25
40
  ```bash
26
41
  ./install.sh [repo-url]
package/dist/cli.js CHANGED
@@ -80987,10 +80987,10 @@ function buildPostCompactMessages(result) {
80987
80987
  ...result.hookResults
80988
80988
  ];
80989
80989
  }
80990
- function compactConversation(messages, contextOrDeps, cacheSafeParamsOrInstructions, suppressFollowUpQuestions, customInstructions, isAutoCompact, recompactionInfo) {
80990
+ function compactConversation(messages, contextOrDeps, cacheSafeParamsOrInstructions, suppressFollowUpQuestions, customInstructions, isAutoCompact, recompactionInfo, keepRecent) {
80991
80991
  const rich = typeof contextOrDeps.getAppState === "function";
80992
80992
  if (rich) {
80993
- return richCompactConversation(messages, contextOrDeps, cacheSafeParamsOrInstructions, suppressFollowUpQuestions ?? false, customInstructions, isAutoCompact ?? false, recompactionInfo);
80993
+ return richCompactConversation(messages, contextOrDeps, cacheSafeParamsOrInstructions, suppressFollowUpQuestions ?? false, customInstructions, isAutoCompact ?? false, recompactionInfo, keepRecent ?? 0);
80994
80994
  }
80995
80995
  return trimmedCompactConversation(messages, contextOrDeps, typeof cacheSafeParamsOrInstructions === "string" ? cacheSafeParamsOrInstructions : undefined);
80996
80996
  }
@@ -81039,7 +81039,7 @@ async function trimmedCompactConversation(messages, deps, customInstructions) {
81039
81039
  }
81040
81040
  return result;
81041
81041
  }
81042
- async function richCompactConversation(messages, context, cacheSafeParams, suppressFollowUpQuestions, customInstructions, isAutoCompact, recompactionInfo) {
81042
+ async function richCompactConversation(messages, context, cacheSafeParams, suppressFollowUpQuestions, customInstructions, isAutoCompact, recompactionInfo, keepRecent = 0) {
81043
81043
  const p = getCompactPorts();
81044
81044
  if (!p) {
81045
81045
  throw new Error("compactConversation rich path requires setCompactPorts(...) — register host compact ports (tui wiring, D-2a S8)");
@@ -81140,6 +81140,7 @@ async function richCompactConversation(messages, context, cacheSafeParams, suppr
81140
81140
  preCompactDiscoveredTools: [...preCompactDiscovered].sort()
81141
81141
  };
81142
81142
  }
81143
+ const messagesToKeep = keepRecent > 0 ? messages.slice(-keepRecent) : undefined;
81143
81144
  const transcriptPath = getTranscriptPath();
81144
81145
  const summaryMessages = [
81145
81146
  {
@@ -81149,7 +81150,7 @@ async function richCompactConversation(messages, context, cacheSafeParams, suppr
81149
81150
  timestamp: new Date().toISOString(),
81150
81151
  message: {
81151
81152
  role: "user",
81152
- content: getCompactUserSummaryMessage(summary, suppressFollowUpQuestions, transcriptPath)
81153
+ content: getCompactUserSummaryMessage(summary, suppressFollowUpQuestions, transcriptPath, messagesToKeep !== undefined)
81153
81154
  }
81154
81155
  }
81155
81156
  ];
@@ -81159,6 +81160,7 @@ async function richCompactConversation(messages, context, cacheSafeParams, suppr
81159
81160
  const truePostCompactTokenCount = roughTokenCountEstimationForMessages([
81160
81161
  boundaryMarker,
81161
81162
  ...summaryMessages,
81163
+ ...messagesToKeep ?? [],
81162
81164
  ...postCompactFileAttachments,
81163
81165
  ...hookMessages
81164
81166
  ]);
@@ -81184,6 +81186,7 @@ async function richCompactConversation(messages, context, cacheSafeParams, suppr
81184
81186
  summaryMessages,
81185
81187
  attachments: postCompactFileAttachments,
81186
81188
  hookResults: hookMessages,
81189
+ ...messagesToKeep ? { messagesToKeep } : {},
81187
81190
  userDisplayMessage: combinedUserDisplayMessage || undefined,
81188
81191
  preCompactTokenCount,
81189
81192
  postCompactTokenCount: compactionCallTotalTokens,
@@ -81391,7 +81394,17 @@ REMINDER: Do NOT call any tools. Respond with plain text only — ` + "an <analy
81391
81394
  });
81392
81395
 
81393
81396
  // src/engine/context/autoCompactWindow.ts
81394
- function resolveAutoCompactWindow(setting) {
81397
+ function isAutoCompactWindowSetting(x) {
81398
+ return typeof x === "object" && x !== null && "kind" in x;
81399
+ }
81400
+ function normalizeAutoCompactWindowSetting(raw) {
81401
+ if (!raw)
81402
+ return {};
81403
+ if (isAutoCompactWindowSetting(raw))
81404
+ return { default: raw };
81405
+ return raw;
81406
+ }
81407
+ function resolveAutoCompactWindowSingle(setting) {
81395
81408
  if (!setting || setting.kind === "auto") {
81396
81409
  return {};
81397
81410
  }
@@ -81409,6 +81422,11 @@ function resolveAutoCompactWindow(setting) {
81409
81422
  }
81410
81423
  return {};
81411
81424
  }
81425
+ function resolveAutoCompactWindow(setting, model) {
81426
+ const perModel = normalizeAutoCompactWindowSetting(setting);
81427
+ const chosen = model && perModel[model] || perModel.default;
81428
+ return resolveAutoCompactWindowSingle(chosen);
81429
+ }
81412
81430
  function parseAutoCompactTierInput(raw) {
81413
81431
  const s = raw.trim();
81414
81432
  if (s === "") {
@@ -81461,16 +81479,16 @@ function setAutoCompactSettingsSource(next) {
81461
81479
  function setAutoCompactWindowSettingsSource(next) {
81462
81480
  autoCompactWindowSettingsSource = next;
81463
81481
  }
81464
- function mergeAutoCompactOverrides(env, setting) {
81465
- const tier = resolveAutoCompactWindow(setting);
81482
+ function mergeAutoCompactOverrides(env, setting, model) {
81483
+ const tier = resolveAutoCompactWindow(setting, model);
81466
81484
  return {
81467
81485
  pctOverride: env.pctOverride ?? tier.pctOverride,
81468
81486
  windowOverride: env.windowOverride ?? tier.windowOverride,
81469
81487
  autoCompactDisabled: env.disabled === true || env.autoCompactDisabled === true || tier.autoCompactDisabled === true
81470
81488
  };
81471
81489
  }
81472
- function getMergedAutoCompactOverrides() {
81473
- return mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), autoCompactWindowSettingsSource?.() ?? null);
81490
+ function getMergedAutoCompactOverrides(model) {
81491
+ return mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), autoCompactWindowSettingsSource?.() ?? null, model);
81474
81492
  }
81475
81493
  function getEffectiveContextWindowSizeCore(contextWindow, maxOutputTokens, windowOverride) {
81476
81494
  const window2 = windowOverride !== undefined && windowOverride > 0 ? Math.min(contextWindow, windowOverride) : contextWindow;
@@ -81479,7 +81497,7 @@ function getEffectiveContextWindowSizeCore(contextWindow, maxOutputTokens, windo
81479
81497
  }
81480
81498
  function getEffectiveContextWindowSize(contextWindowOrModel, maxOutputTokens, windowOverride) {
81481
81499
  if (typeof contextWindowOrModel === "string") {
81482
- const { windowOverride } = getMergedAutoCompactOverrides();
81500
+ const { windowOverride } = getMergedAutoCompactOverrides(contextWindowOrModel);
81483
81501
  return getEffectiveContextWindowSizeCore(resolveModelContextWindow(contextWindowOrModel), undefined, windowOverride);
81484
81502
  }
81485
81503
  return getEffectiveContextWindowSizeCore(contextWindowOrModel, maxOutputTokens, windowOverride);
@@ -81494,18 +81512,21 @@ function getAutoCompactThresholdCore(contextWindow, maxOutputTokens, pctOverride
81494
81512
  }
81495
81513
  function getAutoCompactThreshold(contextWindowOrModel, maxOutputTokens, pctOverride, windowOverride) {
81496
81514
  if (typeof contextWindowOrModel === "string") {
81497
- const o = getMergedAutoCompactOverrides();
81515
+ const o = getMergedAutoCompactOverrides(contextWindowOrModel);
81498
81516
  return getAutoCompactThresholdCore(resolveModelContextWindow(contextWindowOrModel), undefined, o.pctOverride, o.windowOverride);
81499
81517
  }
81500
81518
  return getAutoCompactThresholdCore(contextWindowOrModel, maxOutputTokens, pctOverride, windowOverride);
81501
81519
  }
81520
+ function isAutoCompactThresholdPositive(contextWindow, maxOutputTokens, pctOverride, windowOverride) {
81521
+ return getAutoCompactThreshold(contextWindow, maxOutputTokens, pctOverride, windowOverride) > 0;
81522
+ }
81502
81523
  function calculateTokenWarningState(tokenUsage, paramsOrModel) {
81503
81524
  if (typeof paramsOrModel === "string") {
81504
81525
  const env = getAutoCompactEnvOverrides();
81505
- const o = getMergedAutoCompactOverrides();
81526
+ const o = getMergedAutoCompactOverrides(paramsOrModel);
81506
81527
  return calculateTokenWarningStateCore(tokenUsage, {
81507
81528
  contextWindow: resolveModelContextWindow(paramsOrModel),
81508
- autoCompactEnabled: isAutoCompactEnabled(),
81529
+ autoCompactEnabled: isAutoCompactEnabledForModel(paramsOrModel),
81509
81530
  pctOverride: o.pctOverride,
81510
81531
  windowOverride: o.windowOverride,
81511
81532
  blockingLimitOverride: env.blockingLimitOverride
@@ -81524,13 +81545,15 @@ function calculateTokenWarningStateCore(tokenUsage, params) {
81524
81545
  } = params;
81525
81546
  const enabled = autoCompactEnabled !== false;
81526
81547
  const autoCompactThreshold = getAutoCompactThreshold(contextWindow, maxOutputTokens, pctOverride, windowOverride);
81527
- const threshold = enabled ? autoCompactThreshold : getEffectiveContextWindowSize(contextWindow, maxOutputTokens, windowOverride);
81548
+ const thresholdUsable = isAutoCompactThresholdPositive(contextWindow, maxOutputTokens, pctOverride, windowOverride);
81549
+ const effectivelyEnabled = enabled && thresholdUsable;
81550
+ const threshold = effectivelyEnabled ? autoCompactThreshold : getEffectiveContextWindowSize(contextWindow, maxOutputTokens, windowOverride);
81528
81551
  const percentLeft = Math.max(0, Math.round((threshold - tokenUsage) / threshold * 100));
81529
81552
  const warningThreshold = threshold - WARNING_THRESHOLD_BUFFER_TOKENS;
81530
81553
  const errorThreshold = threshold - ERROR_THRESHOLD_BUFFER_TOKENS;
81531
81554
  const isAboveWarningThreshold = tokenUsage >= warningThreshold;
81532
81555
  const isAboveErrorThreshold = tokenUsage >= errorThreshold;
81533
- const isAboveAutoCompactThreshold = enabled && tokenUsage >= autoCompactThreshold;
81556
+ const isAboveAutoCompactThreshold = effectivelyEnabled && tokenUsage >= autoCompactThreshold;
81534
81557
  const actualContextWindow = getEffectiveContextWindowSize(contextWindow, maxOutputTokens, windowOverride);
81535
81558
  const defaultBlockingLimit = actualContextWindow - MANUAL_COMPACT_BUFFER_TOKENS;
81536
81559
  const blockingLimit = blockingLimitOverride !== undefined && blockingLimitOverride > 0 ? blockingLimitOverride : defaultBlockingLimit;
@@ -81540,7 +81563,8 @@ function calculateTokenWarningStateCore(tokenUsage, params) {
81540
81563
  isAboveWarningThreshold,
81541
81564
  isAboveErrorThreshold,
81542
81565
  isAboveAutoCompactThreshold,
81543
- isAtBlockingLimit
81566
+ isAtBlockingLimit,
81567
+ ...enabled && !thresholdUsable ? { autoCompactDisabledBySmallWindow: true } : {}
81544
81568
  };
81545
81569
  }
81546
81570
  function isAutoCompactEnabled(flags) {
@@ -81561,6 +81585,17 @@ function isAutoCompactEnabled(flags) {
81561
81585
  return false;
81562
81586
  return flags.settingsEnabled !== false;
81563
81587
  }
81588
+ function isAutoCompactEnabledForModel(model) {
81589
+ const o = getAutoCompactEnvOverrides();
81590
+ if (o.disabled)
81591
+ return false;
81592
+ if (o.autoCompactDisabled)
81593
+ return false;
81594
+ if (getMergedAutoCompactOverrides(model).autoCompactDisabled) {
81595
+ return false;
81596
+ }
81597
+ return autoCompactSettingsSource ? autoCompactSettingsSource() ?? true : true;
81598
+ }
81564
81599
  async function shouldAutoCompact(messages, deps) {
81565
81600
  if (deps.querySource === "compact" || deps.querySource === "session_memory") {
81566
81601
  return false;
@@ -81571,6 +81606,9 @@ async function shouldAutoCompact(messages, deps) {
81571
81606
  if (!deps.countTokens) {
81572
81607
  return false;
81573
81608
  }
81609
+ if (!isAutoCompactThresholdPositive(deps.contextWindow, deps.maxOutputTokens, deps.pctOverride, deps.windowOverride)) {
81610
+ return false;
81611
+ }
81574
81612
  const tokenCount = await deps.countTokens(messages);
81575
81613
  if (!Number.isFinite(tokenCount)) {
81576
81614
  return false;
@@ -81606,7 +81644,7 @@ async function autoCompactIfNeeded(messages, tracking, deps) {
81606
81644
  };
81607
81645
  }
81608
81646
  }
81609
- var AUTOCOMPACT_BUFFER_TOKENS = 13000, MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3, autoCompactSettingsSource = null, autoCompactWindowSettingsSource = null, WARNING_THRESHOLD_BUFFER_TOKENS = 20000, ERROR_THRESHOLD_BUFFER_TOKENS = 20000, MANUAL_COMPACT_BUFFER_TOKENS = 3000;
81647
+ var AUTOCOMPACT_BUFFER_TOKENS = 13000, MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3, autoCompactSettingsSource = null, autoCompactWindowSettingsSource = null, WARNING_THRESHOLD_BUFFER_TOKENS = 20000, ERROR_THRESHOLD_BUFFER_TOKENS = 20000, MANUAL_COMPACT_BUFFER_TOKENS = 3000, AUTOCOMPACT_KEEP_RECENT = 3;
81610
81648
  var init_autoCompact = __esm(() => {
81611
81649
  init_modelprovider2();
81612
81650
  init_config();
@@ -81614,6 +81652,23 @@ var init_autoCompact = __esm(() => {
81614
81652
  init_autoCompactWindow();
81615
81653
  });
81616
81654
 
81655
+ // src/engine/context/autoCompactRich.ts
81656
+ function createAutoCompactCompact(options) {
81657
+ return (messages) => {
81658
+ if (options.richContext && getCompactPorts()) {
81659
+ return compactConversation(messages, options.richContext, options.buildCacheSafeParams(messages), true, undefined, true, undefined, options.keepRecent ?? 0);
81660
+ }
81661
+ return compactConversation(messages, {
81662
+ summarize: options.trimmedSummarize,
81663
+ countTokens: options.countTokens,
81664
+ keepRecent: 0
81665
+ });
81666
+ };
81667
+ }
81668
+ var init_autoCompactRich = __esm(() => {
81669
+ init_compact();
81670
+ });
81671
+
81617
81672
  // src/engine/context/compactWarningState.ts
81618
81673
  function suppressCompactWarning() {
81619
81674
  compactWarningStore.setState(() => true);
@@ -82088,6 +82143,7 @@ var init_context = __esm(() => {
82088
82143
  init_autoCompact();
82089
82144
  init_autoCompactWindow();
82090
82145
  init_autoCompact();
82146
+ init_autoCompactRich();
82091
82147
  init_compact();
82092
82148
  init_compactPtl();
82093
82149
  init_microCompact();
@@ -82241,7 +82297,7 @@ async function queryAgentLoop(deps, args) {
82241
82297
  turns++;
82242
82298
  if (args.context?.autoCompact) {
82243
82299
  const oc = await autoCompactIfNeeded(messages, tracking, args.context.autoCompact);
82244
- if (oc.wasCompacted && oc.compactionResult) {
82300
+ if (oc.wasCompacted && oc.compactionResult && !oc.compactionResult.compactionSkipped) {
82245
82301
  messages = buildPostCompactMessages(oc.compactionResult);
82246
82302
  if (oc.tracking) {
82247
82303
  tracking = oc.tracking;
@@ -82265,7 +82321,7 @@ async function queryAgentLoop(deps, args) {
82265
82321
  tracking = { ...tracking, consecutiveFailures: oc.consecutiveFailures };
82266
82322
  reportAutoCompactCircuitFailures(oc.consecutiveFailures);
82267
82323
  }
82268
- if (oc.wasCompacted && oc.compactionResult) {
82324
+ if (oc.wasCompacted && oc.compactionResult && !oc.compactionResult.compactionSkipped) {
82269
82325
  deps.emit?.({ type: "compacted", turn: turns, messages });
82270
82326
  }
82271
82327
  }
@@ -123867,7 +123923,7 @@ var init_internalWrites = __esm(() => {
123867
123923
  timestamps = new Map;
123868
123924
  });
123869
123925
  // src/tui/utils/settings/types.ts
123870
- var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isMcpServerUrlEntry = () => ({}), SettingsSchema2 = () => object({
123926
+ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isMcpServerUrlEntry = () => ({}), autoCompactWindowSettingSchema, SettingsSchema2 = () => object({
123871
123927
  model: string2().optional(),
123872
123928
  modelRoles: record(string2(), any()).optional(),
123873
123929
  defaultRole: string2().optional(),
@@ -123910,11 +123966,9 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
123910
123966
  language: string2().optional(),
123911
123967
  theme: string2().optional(),
123912
123968
  tui: object({ fullscreen: boolean2().optional() }).optional(),
123913
- autoCompactWindow: discriminatedUnion("kind", [
123914
- object({ kind: literal("auto") }),
123915
- object({ kind: literal("off") }),
123916
- object({ kind: literal("window"), tokens: number2().int().min(1000) }),
123917
- object({ kind: literal("pct"), pct: number2().min(1).max(100) })
123969
+ autoCompactWindow: union([
123970
+ autoCompactWindowSettingSchema,
123971
+ record(string2(), autoCompactWindowSettingSchema)
123918
123972
  ]).optional(),
123919
123973
  llmTimeoutMs: number2().int().positive().optional(),
123920
123974
  prefersReducedMotion: boolean2().optional(),
@@ -123953,6 +124007,12 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
123953
124007
  }).passthrough(), CUSTOMIZATION_SURFACES;
123954
124008
  var init_types7 = __esm(() => {
123955
124009
  init_zod();
124010
+ autoCompactWindowSettingSchema = discriminatedUnion("kind", [
124011
+ object({ kind: literal("auto") }),
124012
+ object({ kind: literal("off") }),
124013
+ object({ kind: literal("window"), tokens: number2().int().min(1000) }),
124014
+ object({ kind: literal("pct"), pct: number2().min(1).max(100) })
124015
+ ]);
123956
124016
  CUSTOMIZATION_SURFACES = ["mcp", "command", "agent"];
123957
124017
  });
123958
124018
 
@@ -180228,6 +180288,7 @@ __export(exports_engineCompat, {
180228
180288
  ASK_USER_QUESTION_TOOL_NAME: () => ASK_USER_QUESTION_TOOL_NAME,
180229
180289
  ASYNC_AGENT_ALLOWED_TOOLS: () => ASYNC_AGENT_ALLOWED_TOOLS,
180230
180290
  AUTOCOMPACT_BUFFER_TOKENS: () => AUTOCOMPACT_BUFFER_TOKENS,
180291
+ AUTOCOMPACT_KEEP_RECENT: () => AUTOCOMPACT_KEEP_RECENT,
180231
180292
  AUTOCOMPACT_PRESET_WINDOW_TIERS: () => AUTOCOMPACT_PRESET_WINDOW_TIERS,
180232
180293
  AbortError: () => AbortError,
180233
180294
  AgentTool: () => AgentTool,
@@ -180432,6 +180493,7 @@ __export(exports_engineCompat, {
180432
180493
  createActivityDescriptionResolver: () => createActivityDescriptionResolver,
180433
180494
  createAgentLoopDeps: () => createAgentLoopDeps,
180434
180495
  createAgentWorktree: () => createAgentWorktree,
180496
+ createAutoCompactCompact: () => createAutoCompactCompact,
180435
180497
  createChildAbortController: () => createChildAbortController,
180436
180498
  createCompactBoundaryMessage: () => createCompactBoundaryMessage,
180437
180499
  createCronScheduler: () => createCronScheduler,
@@ -180647,6 +180709,9 @@ __export(exports_engineCompat, {
180647
180709
  isAscendToolsEnabled: () => isAscendToolsEnabled,
180648
180710
  isAutoCompactCircuitTripped: () => isAutoCompactCircuitTripped,
180649
180711
  isAutoCompactEnabled: () => isAutoCompactEnabled,
180712
+ isAutoCompactEnabledForModel: () => isAutoCompactEnabledForModel,
180713
+ isAutoCompactThresholdPositive: () => isAutoCompactThresholdPositive,
180714
+ isAutoCompactWindowSetting: () => isAutoCompactWindowSetting,
180650
180715
  isAutoModeGateEnabled: () => isAutoModeGateEnabled,
180651
180716
  isBuiltInAgent: () => isBuiltInAgent,
180652
180717
  isBypassPermissionsModeDisabled: () => isBypassPermissionsModeDisabled,
@@ -180747,6 +180812,7 @@ __export(exports_engineCompat, {
180747
180812
  mergeWith: () => mergeWith,
180748
180813
  microcompactMessages: () => microcompactMessages,
180749
180814
  nextCronRunMs: () => nextCronRunMs,
180815
+ normalizeAutoCompactWindowSetting: () => normalizeAutoCompactWindowSetting,
180750
180816
  normalizeControlMessageKeys: () => normalizeControlMessageKeys,
180751
180817
  normalizeNameForMCP: () => normalizeNameForMCP2,
180752
180818
  notifyTasksUpdated: () => notifyTasksUpdated,
@@ -321257,7 +321323,7 @@ function buildAgentLoopParams(m) {
321257
321323
  const resolved = pool.length > 0 ? resolveModel(pool[0]) : undefined;
321258
321324
  const toolList = m.tools;
321259
321325
  const countTokens = (msgs) => modelProvider.countTokens(role, sessionModel, msgs, toolList);
321260
- const mergedAutoCompact = mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), getInitialSettings2().autoCompactWindow);
321326
+ const mergedAutoCompact = mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), getInitialSettings2().autoCompactWindow, mainLoopModel);
321261
321327
  const autoCompact = {
321262
321328
  contextWindow: resolved?.contextWindow ?? HARD_DEFAULT_CONTEXT_WINDOW,
321263
321329
  maxOutputTokens: resolved?.maxTokens,
@@ -321265,8 +321331,8 @@ function buildAgentLoopParams(m) {
321265
321331
  enabled: mergedAutoCompact.autoCompactDisabled ? false : undefined,
321266
321332
  pctOverride: mergedAutoCompact.pctOverride,
321267
321333
  windowOverride: mergedAutoCompact.windowOverride,
321268
- compact: (msgs) => compactConversation(msgs, {
321269
- summarize: async (compactMsgs, prompt) => {
321334
+ compact: createAutoCompactCompact({
321335
+ trimmedSummarize: async (compactMsgs, prompt) => {
321270
321336
  const resp = await modelProvider.chat({
321271
321337
  messages: [...compactMsgs, prompt],
321272
321338
  role,
@@ -321278,7 +321344,15 @@ function buildAgentLoopParams(m) {
321278
321344
  return blocks.filter((b) => typeof b === "object" && b !== null && b.type === "text").map((b) => b.text ?? "").join("");
321279
321345
  },
321280
321346
  countTokens,
321281
- keepRecent: 0
321347
+ richContext: m.toolUseContext,
321348
+ keepRecent: AUTOCOMPACT_KEEP_RECENT,
321349
+ buildCacheSafeParams: (msgs) => ({
321350
+ systemPrompt: m.systemPrompt,
321351
+ userContext: m.userContext,
321352
+ systemContext: m.systemContext,
321353
+ toolUseContext: m.toolUseContext,
321354
+ forkContextMessages: msgs
321355
+ })
321282
321356
  }),
321283
321357
  querySource: m.querySource
321284
321358
  };
@@ -325707,7 +325781,7 @@ async function analyzeContextUsage(messages, model, getToolPermissionContext, to
325707
325781
  const skillInfo = skillResult.skillInfo;
325708
325782
  const skillFrontmatterTokens = skillInfo.skillFrontmatter.reduce((sum, skill) => sum + skill.tokens, 0);
325709
325783
  const messageTokens = messageBreakdown.totalTokens;
325710
- const isAutoCompact = isAutoCompactEnabled();
325784
+ const isAutoCompact = isAutoCompactEnabledForModel(model);
325711
325785
  const autoCompactThreshold = isAutoCompact ? getEffectiveContextWindowSize(model) - AUTOCOMPACT_BUFFER_TOKENS : undefined;
325712
325786
  const cats = [];
325713
325787
  if (systemPromptTokens > 0) {
@@ -329370,7 +329444,7 @@ function getCompactionReminderAttachment(messages, model) {
329370
329444
  if (!getFeatureValue_CACHED_MAY_BE_STALE("atlas_marble_fox", false)) {
329371
329445
  return [];
329372
329446
  }
329373
- if (!isAutoCompactEnabled()) {
329447
+ if (!isAutoCompactEnabledForModel(model)) {
329374
329448
  return [];
329375
329449
  }
329376
329450
  const contextWindow = getContextWindowForModel(model, getSdkBetas());
@@ -337270,6 +337344,13 @@ ${attachment.snippet}`,
337270
337344
  isMeta: true
337271
337345
  })
337272
337346
  ]);
337347
+ case "git_status_refresh":
337348
+ return wrapMessagesInSystemReminder([
337349
+ createUserMessage2({
337350
+ content: attachment.status,
337351
+ isMeta: true
337352
+ })
337353
+ ]);
337273
337354
  case "file": {
337274
337355
  const fileContent = attachment.content;
337275
337356
  switch (fileContent.type) {
@@ -349022,6 +349103,10 @@ var exports_autocompact = {};
349022
349103
  __export(exports_autocompact, {
349023
349104
  call: () => call9
349024
349105
  });
349106
+ function currentTierFor(raw, model) {
349107
+ const map = normalizeAutoCompactWindowSetting(raw);
349108
+ return map[model] ?? map.default;
349109
+ }
349025
349110
  function currentToOptionValue(setting) {
349026
349111
  if (!setting || setting.kind === "auto")
349027
349112
  return "auto";
@@ -349038,21 +349123,25 @@ function customInitialValue(setting) {
349038
349123
  }
349039
349124
  return setting.kind === "window" ? `${setting.tokens / 1000}k` : `${setting.pct}%`;
349040
349125
  }
349041
- function describeTier(setting) {
349126
+ function describeTier(setting, model) {
349127
+ const label = ` [${renderModelName(model)}]`;
349042
349128
  switch (setting.kind) {
349043
349129
  case "auto":
349044
- return "Auto-compact: Auto (default) — compact near the model window limit";
349130
+ return `Auto-compact: Auto (default)${label} — compact near the model window limit`;
349045
349131
  case "off":
349046
- return "Auto-compact: Off (manual /compact still works)";
349132
+ return `Auto-compact: Off${label} (manual /compact still works)`;
349047
349133
  case "window":
349048
- return `Auto-compact window: ${setting.tokens / 1000}k tokens`;
349134
+ return `Auto-compact window: ${setting.tokens / 1000}k tokens${label}`;
349049
349135
  case "pct":
349050
- return `Auto-compact threshold: ${setting.pct}% of the effective window`;
349136
+ return `Auto-compact threshold: ${setting.pct}% of the effective window${label}`;
349051
349137
  }
349052
349138
  }
349053
- function persistTier(setting, setAppState, onDone) {
349139
+ function persistTier(setting, model, setAppState, onDone) {
349140
+ const map = normalizeAutoCompactWindowSetting(getInitialSettings2().autoCompactWindow);
349141
+ map[model] = setting;
349142
+ const mapForSettings = map;
349054
349143
  const { error } = updateSettingsForSource2("userSettings", {
349055
- autoCompactWindow: setting
349144
+ autoCompactWindow: mapForSettings
349056
349145
  });
349057
349146
  if (error) {
349058
349147
  onDone(`Failed to persist auto-compact tier: ${error.message}`, {
@@ -349062,9 +349151,9 @@ function persistTier(setting, setAppState, onDone) {
349062
349151
  }
349063
349152
  setAppState((prev) => ({
349064
349153
  ...prev,
349065
- settings: { ...prev.settings, autoCompactWindow: setting }
349154
+ settings: { ...prev.settings, autoCompactWindow: mapForSettings }
349066
349155
  }));
349067
- onDone(describeTier(setting));
349156
+ onDone(describeTier(setting, model));
349068
349157
  }
349069
349158
  function AutoCompactApply({
349070
349159
  setting,
@@ -349072,34 +349161,23 @@ function AutoCompactApply({
349072
349161
  }) {
349073
349162
  const setAppState = useSetAppState();
349074
349163
  const doneRef = React41.useRef(false);
349164
+ const model = getMainLoopModel();
349075
349165
  React41.useEffect(() => {
349076
349166
  if (doneRef.current) {
349077
349167
  return;
349078
349168
  }
349079
349169
  doneRef.current = true;
349080
- persistTier(setting, setAppState, onDone);
349081
- }, [setting, onDone, setAppState]);
349170
+ persistTier(setting, model, setAppState, onDone);
349171
+ }, [setting, model, onDone, setAppState]);
349082
349172
  return null;
349083
349173
  }
349084
349174
  function AutoCompactCommand({ onDone }) {
349085
349175
  const setAppState = useSetAppState();
349176
+ const model = getMainLoopModel();
349086
349177
  const current = useAppState((s) => s.settings.autoCompactWindow);
349087
349178
  const [inputError, setInputError] = React41.useState(null);
349088
349179
  const apply = (setting) => {
349089
- const { error } = updateSettingsForSource2("userSettings", {
349090
- autoCompactWindow: setting
349091
- });
349092
- if (error) {
349093
- onDone(`Failed to persist auto-compact tier: ${error.message}`, {
349094
- display: "system"
349095
- });
349096
- return;
349097
- }
349098
- setAppState((prev) => ({
349099
- ...prev,
349100
- settings: { ...prev.settings, autoCompactWindow: setting }
349101
- }));
349102
- onDone(describeTier(setting));
349180
+ persistTier(setting, model, setAppState, onDone);
349103
349181
  };
349104
349182
  const options = [
349105
349183
  {
@@ -349117,7 +349195,7 @@ function AutoCompactCommand({ onDone }) {
349117
349195
  value: "custom",
349118
349196
  type: "input",
349119
349197
  placeholder: "e.g. 150k (window) or 75% (bare number = percent)",
349120
- initialValue: customInitialValue(current),
349198
+ initialValue: customInitialValue(currentTierFor(current, model)),
349121
349199
  onChange: (raw) => {
349122
349200
  const parsed = parseAutoCompactTierInput(raw);
349123
349201
  if (!parsed) {
@@ -349139,10 +349217,10 @@ function AutoCompactCommand({ onDone }) {
349139
349217
  children: [
349140
349218
  /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
349141
349219
  bold: true,
349142
- children: "Auto-compact window tier"
349220
+ children: `Auto-compact window tier — ${renderModelName(model)}`
349143
349221
  }, undefined, false, undefined, this),
349144
349222
  /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(Select, {
349145
- defaultValue: currentToOptionValue(current),
349223
+ defaultValue: currentToOptionValue(currentTierFor(current, model)),
349146
349224
  options,
349147
349225
  onChange: (value) => {
349148
349226
  if (value === "auto") {
@@ -349186,6 +349264,7 @@ var init_autocompact = __esm(() => {
349186
349264
  init_CustomSelect();
349187
349265
  init_ink2();
349188
349266
  init_AppState();
349267
+ init_model();
349189
349268
  init_settings3();
349190
349269
  init_engine();
349191
349270
  React41 = __toESM(require_react(), 1);
@@ -374919,6 +374998,7 @@ var init_nullRenderingAttachments = __esm(() => {
374919
374998
  "critical_system_reminder",
374920
374999
  "edited_image_file",
374921
375000
  "edited_text_file",
375001
+ "git_status_refresh",
374922
375002
  "opened_file_in_ide",
374923
375003
  "output_style",
374924
375004
  "plan_mode",
@@ -432105,7 +432185,8 @@ async function streamCompactSummary({
432105
432185
  appState,
432106
432186
  context,
432107
432187
  preCompactTokenCount,
432108
- cacheSafeParams
432188
+ cacheSafeParams,
432189
+ modelOverride
432109
432190
  }) {
432110
432191
  const promptCacheSharingEnabled = getFeatureValue_CACHED_MAY_BE_STALE("atlas_compact_cache_prefix", true);
432111
432192
  const activityInterval = isSessionActivityTrackingActive() ? setInterval((statusSetter) => {
@@ -432113,7 +432194,7 @@ async function streamCompactSummary({
432113
432194
  statusSetter?.("compacting");
432114
432195
  }, 30000, context.setSDKStatus) : undefined;
432115
432196
  try {
432116
- if (promptCacheSharingEnabled) {
432197
+ if (promptCacheSharingEnabled && !modelOverride) {
432117
432198
  try {
432118
432199
  const result = await runForkedAgent({
432119
432200
  promptMessages: [summaryRequest],
@@ -432138,11 +432219,12 @@ async function streamCompactSummary({
432138
432219
  }
432139
432220
  const retryEnabled = getFeatureValue_CACHED_MAY_BE_STALE("atlas_compact_streaming_retry", false);
432140
432221
  const maxAttempts = retryEnabled ? MAX_COMPACT_STREAMING_RETRIES : 1;
432222
+ const compactModel = modelOverride ?? context.options.mainLoopModel;
432141
432223
  for (let attempt = 1;attempt <= maxAttempts; attempt++) {
432142
432224
  let hasStartedStreaming = false;
432143
432225
  let response;
432144
432226
  context.setResponseLength?.(() => 0);
432145
- const useToolSearch = await isToolSearchEnabled(context.options.mainLoopModel, context.options.tools, async () => appState.toolPermissionContext, context.options.agentDefinitions.activeAgents, "compact");
432227
+ const useToolSearch = await isToolSearchEnabled(compactModel, context.options.tools, async () => appState.toolPermissionContext, context.options.agentDefinitions.activeAgents, "compact");
432146
432228
  const tools = useToolSearch ? uniqBy_default([
432147
432229
  FileReadTool,
432148
432230
  ToolSearchTool2,
@@ -432152,7 +432234,6 @@ async function streamCompactSummary({
432152
432234
  ...getMessagesAfterCompactBoundary(messages),
432153
432235
  summaryRequest
432154
432236
  ])), context.options.tools);
432155
- const compactModel = context.options.mainLoopModel;
432156
432237
  const compactRole = modelToRole(compactModel);
432157
432238
  const params = await buildOpenAIParams({
432158
432239
  messages: compactMessages,
@@ -432242,6 +432323,23 @@ async function createPostCompactFileAttachments(readFileState, toolUseContext, m
432242
432323
  return false;
432243
432324
  });
432244
432325
  }
432326
+ async function createCurrentGitStatusAttachment() {
432327
+ const baseline = getSessionStartGitStatusBlocks();
432328
+ if (!baseline) {
432329
+ return null;
432330
+ }
432331
+ const fresh = await getGitStatusFresh();
432332
+ if (!fresh) {
432333
+ return null;
432334
+ }
432335
+ if (JSON.stringify(fresh.blocks) === JSON.stringify(baseline)) {
432336
+ return null;
432337
+ }
432338
+ return createAttachmentMessage({
432339
+ type: "git_status_refresh",
432340
+ status: fresh.text
432341
+ });
432342
+ }
432245
432343
  function createPlanAttachmentIfNeeded(agentId) {
432246
432344
  const planContent = getPlan2(agentId);
432247
432345
  if (!planContent) {
@@ -432382,6 +432480,7 @@ var init_compact4 = __esm(() => {
432382
432480
  init_attachments();
432383
432481
  init_config6();
432384
432482
  init_context2();
432483
+ init_context5();
432385
432484
  init_debug();
432386
432485
  init_errors4();
432387
432486
  init_fileStateCache();
@@ -432412,6 +432511,62 @@ var init_compact4 = __esm(() => {
432412
432511
  init_prompt22();
432413
432512
  });
432414
432513
 
432514
+ // src/tui/contextBodies/summarizeFallback.ts
432515
+ function isFallbackEligibleError(err) {
432516
+ let msg = "";
432517
+ if (err instanceof Error) {
432518
+ if (err.name === "APIUserAbortError")
432519
+ return false;
432520
+ msg = err.message;
432521
+ } else if (typeof err === "string") {
432522
+ msg = err;
432523
+ } else {
432524
+ return false;
432525
+ }
432526
+ if (msg.includes(PROMPT_TOO_LONG_ERROR_MESSAGE))
432527
+ return false;
432528
+ if (msg.includes("Request was aborted."))
432529
+ return false;
432530
+ return true;
432531
+ }
432532
+ function isFallbackEligibleResult(msg, text) {
432533
+ if (!text)
432534
+ return false;
432535
+ if (text.includes(PROMPT_TOO_LONG_ERROR_MESSAGE))
432536
+ return false;
432537
+ if (text.includes("Request was aborted."))
432538
+ return false;
432539
+ const flagged = typeof msg === "object" && msg !== null && msg.isApiErrorMessage === true;
432540
+ return flagged || startsWithApiErrorPrefix(text);
432541
+ }
432542
+ function createSummarizeWithFallback(primary, opts) {
432543
+ return async (p) => {
432544
+ let result;
432545
+ try {
432546
+ result = await primary(p);
432547
+ } catch (err) {
432548
+ const fb = opts.resolveFallbackModel(p);
432549
+ if (!fb || !isFallbackEligibleError(err)) {
432550
+ throw err;
432551
+ }
432552
+ return primary({ ...p, modelOverride: fb });
432553
+ }
432554
+ if (opts.isEligibleResult?.(result)) {
432555
+ const fb = opts.resolveFallbackModel(p);
432556
+ if (fb) {
432557
+ const retried = await primary({ ...p, modelOverride: fb });
432558
+ if (!opts.isEligibleResult(retried)) {
432559
+ return retried;
432560
+ }
432561
+ }
432562
+ }
432563
+ return result;
432564
+ };
432565
+ }
432566
+ var init_summarizeFallback = __esm(() => {
432567
+ init_modelprovider2();
432568
+ });
432569
+
432415
432570
  // src/tui/services/SessionMemory/prompts.ts
432416
432571
  import { readFile as readFile61 } from "fs/promises";
432417
432572
  import { join as join165 } from "path";
@@ -432971,6 +433126,9 @@ async function composePostCompactAttachments(preCompactReadFileState, context) {
432971
433126
  createAsyncAgentAttachmentsIfNeeded(ctx)
432972
433127
  ]);
432973
433128
  const out = [...fileAttachments, ...asyncAgentAttachments];
433129
+ const gitStatusAttachment = await createCurrentGitStatusAttachment();
433130
+ if (gitStatusAttachment)
433131
+ out.push(gitStatusAttachment);
432974
433132
  const planAttachment = createPlanAttachmentIfNeeded(ctx.agentId);
432975
433133
  if (planAttachment)
432976
433134
  out.push(planAttachment);
@@ -432992,8 +433150,20 @@ async function composePostCompactAttachments(preCompactReadFileState, context) {
432992
433150
  return out;
432993
433151
  }
432994
433152
  function wireContextHostPorts() {
433153
+ const summarizePrimary = (p) => streamCompactSummary(p);
433154
+ const summarizeWithFallback = createSummarizeWithFallback(summarizePrimary, {
433155
+ resolveFallbackModel: (p) => {
433156
+ const fb = getRoleModel("small");
433157
+ if (!fb)
433158
+ return;
433159
+ if (p.context.options.mainLoopModel === fb)
433160
+ return;
433161
+ return fb;
433162
+ },
433163
+ isEligibleResult: (r) => isFallbackEligibleResult(r, getAssistantMessageText2(r))
433164
+ });
432995
433165
  setCompactPorts({
432996
- summarize: (p) => streamCompactSummary({
433166
+ summarize: (p) => summarizeWithFallback({
432997
433167
  messages: p.messages,
432998
433168
  summaryRequest: p.summaryRequest,
432999
433169
  appState: p.context.getAppState(),
@@ -433069,7 +433239,9 @@ var init_contextHostWiring = __esm(() => {
433069
433239
  init_sessionStorage();
433070
433240
  init_betaSessionTracing();
433071
433241
  init_compact4();
433242
+ init_messages3();
433072
433243
  init_compact4();
433244
+ init_summarizeFallback();
433073
433245
  init_sessionMemoryCompact();
433074
433246
  init_compact4();
433075
433247
  });
@@ -434246,7 +434418,77 @@ function setSystemPromptInjection(value) {
434246
434418
  getUserContext.cache.clear?.();
434247
434419
  getSystemContext.cache.clear?.();
434248
434420
  }
434249
- var MAX_STATUS_CHARS = 2000, systemPromptInjection = null, getGitStatus, getSystemContext, getUserContext;
434421
+ async function fetchGitStatusBlocks() {
434422
+ if (false) {}
434423
+ const startTime = Date.now();
434424
+ logForDiagnosticsNoPII("info", "git_status_started");
434425
+ const isGitStart = Date.now();
434426
+ const isGit = await getIsGit();
434427
+ logForDiagnosticsNoPII("info", "git_is_git_check_completed", {
434428
+ duration_ms: Date.now() - isGitStart,
434429
+ is_git: isGit
434430
+ });
434431
+ if (!isGit) {
434432
+ logForDiagnosticsNoPII("info", "git_status_skipped_not_git", {
434433
+ duration_ms: Date.now() - startTime
434434
+ });
434435
+ return null;
434436
+ }
434437
+ try {
434438
+ const gitCmdsStart = Date.now();
434439
+ const [branch, mainBranch, status, log, userName] = await Promise.all([
434440
+ getBranch2(),
434441
+ getDefaultBranch2(),
434442
+ execFileNoThrow3(gitExe2(), ["--no-optional-locks", "status", "--short"], {
434443
+ preserveOutputOnError: false
434444
+ }).then(({ stdout }) => stdout.trim()),
434445
+ execFileNoThrow3(gitExe2(), ["--no-optional-locks", "log", "--oneline", "-n", "5"], {
434446
+ preserveOutputOnError: false
434447
+ }).then(({ stdout }) => stdout.trim()),
434448
+ execFileNoThrow3(gitExe2(), ["config", "user.name"], {
434449
+ preserveOutputOnError: false
434450
+ }).then(({ stdout }) => stdout.trim())
434451
+ ]);
434452
+ logForDiagnosticsNoPII("info", "git_commands_completed", {
434453
+ duration_ms: Date.now() - gitCmdsStart,
434454
+ status_length: status.length
434455
+ });
434456
+ const truncatedStatus = status.length > MAX_STATUS_CHARS ? status.substring(0, MAX_STATUS_CHARS) + `
434457
+ ... (truncated because it exceeds 2k characters. If you need more information, run "git status" using BashTool)` : status;
434458
+ logForDiagnosticsNoPII("info", "git_status_completed", {
434459
+ duration_ms: Date.now() - startTime,
434460
+ truncated: status.length > MAX_STATUS_CHARS
434461
+ });
434462
+ return { branch, mainBranch, status: truncatedStatus, log, userName };
434463
+ } catch (error) {
434464
+ logForDiagnosticsNoPII("error", "git_status_failed", {
434465
+ duration_ms: Date.now() - startTime
434466
+ });
434467
+ logError3(error);
434468
+ return null;
434469
+ }
434470
+ }
434471
+ function formatGitStatus(blocks, header) {
434472
+ return [
434473
+ header,
434474
+ `Current branch: ${blocks.branch}`,
434475
+ `Main branch (you will usually use this for PRs): ${blocks.mainBranch}`,
434476
+ ...blocks.userName ? [`Git user: ${blocks.userName}`] : [],
434477
+ `Status:
434478
+ ${blocks.status || "(clean)"}`,
434479
+ `Recent commits:
434480
+ ${blocks.log}`
434481
+ ].join(`
434482
+
434483
+ `);
434484
+ }
434485
+ function getGitStatusFresh() {
434486
+ return fetchGitStatusBlocks().then((blocks) => blocks ? { text: formatGitStatus(blocks, GIT_STATUS_FRESH_HEADER), blocks } : null);
434487
+ }
434488
+ function getSessionStartGitStatusBlocks() {
434489
+ return sessionStartGitStatusBlocks;
434490
+ }
434491
+ var MAX_STATUS_CHARS = 2000, systemPromptInjection = null, GIT_STATUS_START_HEADER = "This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.", GIT_STATUS_FRESH_HEADER = "This is the current git status, re-injected after context compaction. It reflects the working tree as of now and supersedes any earlier session-start snapshot.", sessionStartGitStatusBlocks = null, getGitStatus, getSystemContext, getUserContext;
434250
434492
  var init_context5 = __esm(() => {
434251
434493
  init_shared();
434252
434494
  init_memoize();
@@ -434260,65 +434502,11 @@ var init_context5 = __esm(() => {
434260
434502
  init_gitSettings();
434261
434503
  init_log5();
434262
434504
  getGitStatus = memoize_default(async () => {
434263
- if (false) {}
434264
- const startTime = Date.now();
434265
- logForDiagnosticsNoPII("info", "git_status_started");
434266
- const isGitStart = Date.now();
434267
- const isGit = await getIsGit();
434268
- logForDiagnosticsNoPII("info", "git_is_git_check_completed", {
434269
- duration_ms: Date.now() - isGitStart,
434270
- is_git: isGit
434271
- });
434272
- if (!isGit) {
434273
- logForDiagnosticsNoPII("info", "git_status_skipped_not_git", {
434274
- duration_ms: Date.now() - startTime
434275
- });
434505
+ const blocks = await fetchGitStatusBlocks();
434506
+ if (!blocks)
434276
434507
  return null;
434277
- }
434278
- try {
434279
- const gitCmdsStart = Date.now();
434280
- const [branch, mainBranch, status, log, userName] = await Promise.all([
434281
- getBranch2(),
434282
- getDefaultBranch2(),
434283
- execFileNoThrow3(gitExe2(), ["--no-optional-locks", "status", "--short"], {
434284
- preserveOutputOnError: false
434285
- }).then(({ stdout }) => stdout.trim()),
434286
- execFileNoThrow3(gitExe2(), ["--no-optional-locks", "log", "--oneline", "-n", "5"], {
434287
- preserveOutputOnError: false
434288
- }).then(({ stdout }) => stdout.trim()),
434289
- execFileNoThrow3(gitExe2(), ["config", "user.name"], {
434290
- preserveOutputOnError: false
434291
- }).then(({ stdout }) => stdout.trim())
434292
- ]);
434293
- logForDiagnosticsNoPII("info", "git_commands_completed", {
434294
- duration_ms: Date.now() - gitCmdsStart,
434295
- status_length: status.length
434296
- });
434297
- const truncatedStatus = status.length > MAX_STATUS_CHARS ? status.substring(0, MAX_STATUS_CHARS) + `
434298
- ... (truncated because it exceeds 2k characters. If you need more information, run "git status" using BashTool)` : status;
434299
- logForDiagnosticsNoPII("info", "git_status_completed", {
434300
- duration_ms: Date.now() - startTime,
434301
- truncated: status.length > MAX_STATUS_CHARS
434302
- });
434303
- return [
434304
- `This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.`,
434305
- `Current branch: ${branch}`,
434306
- `Main branch (you will usually use this for PRs): ${mainBranch}`,
434307
- ...userName ? [`Git user: ${userName}`] : [],
434308
- `Status:
434309
- ${truncatedStatus || "(clean)"}`,
434310
- `Recent commits:
434311
- ${log}`
434312
- ].join(`
434313
-
434314
- `);
434315
- } catch (error) {
434316
- logForDiagnosticsNoPII("error", "git_status_failed", {
434317
- duration_ms: Date.now() - startTime
434318
- });
434319
- logError3(error);
434320
- return null;
434321
- }
434508
+ sessionStartGitStatusBlocks = blocks;
434509
+ return formatGitStatus(blocks, GIT_STATUS_START_HEADER);
434322
434510
  });
434323
434511
  getSystemContext = memoize_default(async () => {
434324
434512
  const startTime = Date.now();
@@ -451336,7 +451524,8 @@ function TokenWarning(t0) {
451336
451524
  const {
451337
451525
  percentLeft,
451338
451526
  isAboveWarningThreshold,
451339
- isAboveErrorThreshold
451527
+ isAboveErrorThreshold,
451528
+ autoCompactDisabledBySmallWindow
451340
451529
  } = t1;
451341
451530
  const suppressWarning = useCompactWarningSuppression();
451342
451531
  const circuitFailures = useAutoCompactCircuitFailures();
@@ -451345,7 +451534,7 @@ function TokenWarning(t0) {
451345
451534
  }
451346
451535
  let t2;
451347
451536
  if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
451348
- t2 = isAutoCompactEnabled();
451537
+ t2 = isAutoCompactEnabledForModel(model);
451349
451538
  $[3] = t2;
451350
451539
  } else {
451351
451540
  t2 = $[3];
@@ -451402,7 +451591,7 @@ function TokenWarning(t0) {
451402
451591
  return t4;
451403
451592
  }
451404
451593
  const circuitTripped = isAutoCompactCircuitTripped(circuitFailures);
451405
- const autocompactLabel = circuitTripped ? `auto-compact paused after ${circuitFailures} consecutive failures · run /compact, switch to a smaller model, or start a new session` : reactiveOnlyMode ? `${100 - displayPercentLeft}% context used` : `${displayPercentLeft}% until auto-compact`;
451594
+ const autocompactLabel = circuitTripped ? `auto-compact paused after ${circuitFailures} consecutive failures · run /compact, switch to a smaller model, or start a new session` : reactiveOnlyMode ? `${100 - displayPercentLeft}% context used` : autoCompactDisabledBySmallWindow ? `context window too small for auto-compact · auto-compact disabled · run /compact manually or use a smaller-context model` : `${displayPercentLeft}% until auto-compact`;
451406
451595
  let t4;
451407
451596
  if ($[9] !== autocompactLabel || $[10] !== isAboveErrorThreshold || $[11] !== percentLeft) {
451408
451597
  t4 = /* @__PURE__ */ jsx_dev_runtime364.jsxDEV(ThemedBox_default, {
@@ -459901,7 +460090,7 @@ var jsx_dev_runtime381, ContextBarSegment = ({ input }) => {
459901
460090
  }
459902
460091
  const color = contextColorForPercentage(pct);
459903
460092
  const modelId = input.model?.id;
459904
- const showCompactWarning = modelId != null && isAutoCompactEnabled() && calculateTokenWarningState(used, modelId).isAboveWarningThreshold;
460093
+ const showCompactWarning = modelId != null && isAutoCompactEnabledForModel(modelId) && calculateTokenWarningState(used, modelId).isAboveWarningThreshold;
459905
460094
  return /* @__PURE__ */ jsx_dev_runtime381.jsxDEV(ThemedText, {
459906
460095
  color,
459907
460096
  children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasharness/atlascode",
3
- "version": "0.1.67",
3
+ "version": "0.1.69",
4
4
  "description": "AtlasCode \u2014 Coding Agent for the domestic computing ecosystem (Ascend NPU + domestic LLM backends)",
5
5
  "bin": {
6
6
  "atlas": "dist/cli.js",