@atlasharness/atlascode 0.1.79 → 0.1.80

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 (2) hide show
  1. package/dist/cli.js +317 -71
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -19862,7 +19862,7 @@ var init_openai = __esm(() => {
19862
19862
  });
19863
19863
 
19864
19864
  // src/modelprovider/constants.ts
19865
- var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, LLM_TIMEOUT_DEFAULT_MS = 900000, LLM_TIMEOUT_CAP_MS = 1800000, LLM_TIMEOUT_UNIT_WARN_THRESHOLD_MS = 60000, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
19865
+ var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, LLM_TIMEOUT_DEFAULT_MS = 900000, LLM_TIMEOUT_CAP_MS = 1800000, LLM_TIMEOUT_UNIT_WARN_THRESHOLD_MS = 60000, STREAM_IDLE_TIMEOUT_MS = 300000, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
19866
19866
  var init_constants2 = __esm(() => {
19867
19867
  init_shared();
19868
19868
  API_IMAGE_MAX_BASE64_SIZE = 5 * 1024 * 1024;
@@ -19900,6 +19900,56 @@ var init_clients = __esm(() => {
19900
19900
  clientCache = new Map;
19901
19901
  });
19902
19902
 
19903
+ // src/modelprovider/streamIdleWatchdog.ts
19904
+ async function* withStreamIdleWatchdog(stream, timeoutMs = STREAM_IDLE_TIMEOUT_MS) {
19905
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
19906
+ yield* stream;
19907
+ return;
19908
+ }
19909
+ const iterator = typeof stream[Symbol.asyncIterator] === "function" ? stream[Symbol.asyncIterator]() : async function* wrapSyncIterable() {
19910
+ yield* stream;
19911
+ }();
19912
+ try {
19913
+ while (true) {
19914
+ const nextPromise = iterator.next();
19915
+ nextPromise.catch(() => {});
19916
+ let timer;
19917
+ const timerPromise = new Promise((resolve) => {
19918
+ timer = setTimeout(() => resolve("timeout"), timeoutMs);
19919
+ if (typeof timer === "object" && timer !== null && "unref" in timer) {
19920
+ timer.unref();
19921
+ }
19922
+ });
19923
+ const winner = await Promise.race([nextPromise, timerPromise]);
19924
+ if (timer !== undefined)
19925
+ clearTimeout(timer);
19926
+ if (winner === "timeout") {
19927
+ throw new StreamIdleTimeoutError(timeoutMs);
19928
+ }
19929
+ const result = winner;
19930
+ if (result.done)
19931
+ return;
19932
+ yield result.value;
19933
+ }
19934
+ } finally {
19935
+ try {
19936
+ await iterator.return?.();
19937
+ } catch {}
19938
+ }
19939
+ }
19940
+ var StreamIdleTimeoutError;
19941
+ var init_streamIdleWatchdog = __esm(() => {
19942
+ init_constants2();
19943
+ StreamIdleTimeoutError = class StreamIdleTimeoutError extends Error {
19944
+ timeoutMs;
19945
+ constructor(timeoutMs) {
19946
+ super(`Stream idle timeout: no chunk received for ${timeoutMs}ms`);
19947
+ this.name = "StreamIdleTimeoutError";
19948
+ this.timeoutMs = timeoutMs;
19949
+ }
19950
+ };
19951
+ });
19952
+
19903
19953
  // src/modelprovider/roles.ts
19904
19954
  function setEndpointConfigSource(source) {
19905
19955
  activeSource = source;
@@ -26560,6 +26610,46 @@ var init_schema = __esm(() => {
26560
26610
  cache = new WeakMap;
26561
26611
  });
26562
26612
 
26613
+ // src/modelprovider/capabilities.ts
26614
+ function stripProviderPrefix(model) {
26615
+ const idx = model.lastIndexOf("/");
26616
+ return idx >= 0 ? model.slice(idx + 1) : model;
26617
+ }
26618
+ function getModelMeta(modelId) {
26619
+ if (!modelId)
26620
+ return;
26621
+ const providers = getEndpointConfigSource().getProviders();
26622
+ for (const pCfg of Object.values(providers)) {
26623
+ const models = pCfg.models || [];
26624
+ const entry = models.find((m) => m?.id === modelId) ?? models.find((m) => m?.id === stripProviderPrefix(modelId));
26625
+ if (entry) {
26626
+ return {
26627
+ knowledgeCutoff: entry.knowledgeCutoff,
26628
+ supportsThinking: entry.supportsThinking,
26629
+ supportsEffort: entry.supportsEffort,
26630
+ supportsStructuredOutputs: entry.supportsStructuredOutputs,
26631
+ skipCyberMitigation: entry.skipCyberMitigation
26632
+ };
26633
+ }
26634
+ }
26635
+ return;
26636
+ }
26637
+ function getProviderContextWindow(modelId) {
26638
+ if (!modelId)
26639
+ return;
26640
+ const providers = getEndpointConfigSource().getProviders();
26641
+ for (const pCfg of Object.values(providers)) {
26642
+ const models = pCfg.models || [];
26643
+ const entry = models.find((m) => m?.id === modelId) ?? models.find((m) => m?.id === stripProviderPrefix(modelId));
26644
+ if (entry?.contextWindow)
26645
+ return entry.contextWindow;
26646
+ }
26647
+ return;
26648
+ }
26649
+ var init_capabilities = __esm(() => {
26650
+ init_roles7();
26651
+ });
26652
+
26563
26653
  // src/modelprovider/effort.ts
26564
26654
  function isEffortLevel(value) {
26565
26655
  return EFFORT_LEVELS.includes(value);
@@ -26625,6 +26715,13 @@ function lookupEffortByModel(model) {
26625
26715
  if (key.toLowerCase() === wanted)
26626
26716
  return level;
26627
26717
  }
26718
+ const base = stripProviderPrefix(model).toLowerCase();
26719
+ if (base !== wanted) {
26720
+ for (const [key, level] of Object.entries(map)) {
26721
+ if (key.toLowerCase() === base)
26722
+ return level;
26723
+ }
26724
+ }
26628
26725
  return;
26629
26726
  }
26630
26727
  function resolveAppliedEffort(model, appStateEffortValue) {
@@ -26638,6 +26735,7 @@ function resolveAppliedEffort(model, appStateEffortValue) {
26638
26735
  var effortByModelSource = null;
26639
26736
  var init_effort = __esm(() => {
26640
26737
  init_shared();
26738
+ init_capabilities();
26641
26739
  });
26642
26740
 
26643
26741
  // src/modelprovider/params.ts
@@ -26785,7 +26883,23 @@ async function buildOpenAITools(tools, options, emptyPermissionContext) {
26785
26883
  });
26786
26884
  }
26787
26885
  }
26788
- return out;
26886
+ return stableSortDedupeTools(out);
26887
+ }
26888
+ function stableSortDedupeTools(tools) {
26889
+ const nameOf = (t) => t.type === "function" ? t.function.name : t.custom.name;
26890
+ const sorted = [...tools].sort((a, b) => {
26891
+ const an = nameOf(a);
26892
+ const bn = nameOf(b);
26893
+ return an < bn ? -1 : an > bn ? 1 : 0;
26894
+ });
26895
+ const seen = new Set;
26896
+ return sorted.filter((t) => {
26897
+ const n = nameOf(t);
26898
+ if (seen.has(n))
26899
+ return false;
26900
+ seen.add(n);
26901
+ return true;
26902
+ });
26789
26903
  }
26790
26904
  function toResponseFormat(outputFormat) {
26791
26905
  if (!outputFormat)
@@ -27629,7 +27743,7 @@ class OpenAIProvider {
27629
27743
  let usage = null;
27630
27744
  let streamError = null;
27631
27745
  try {
27632
- for await (const chunk of stream) {
27746
+ for await (const chunk of withStreamIdleWatchdog(stream, STREAM_IDLE_TIMEOUT_MS)) {
27633
27747
  const choice = chunk.choices?.[0];
27634
27748
  const delta = choice?.delta;
27635
27749
  if (delta?.content) {
@@ -27887,6 +28001,8 @@ var init_modelprovider = __esm(() => {
27887
28001
  init_openai();
27888
28002
  init_clients();
27889
28003
  init_constants2();
28004
+ init_constants2();
28005
+ init_streamIdleWatchdog();
27890
28006
  init_roles7();
27891
28007
  init_shared();
27892
28008
  init_shared();
@@ -27912,42 +28028,6 @@ Fix: ${fix}`);
27912
28028
  };
27913
28029
  });
27914
28030
 
27915
- // src/modelprovider/capabilities.ts
27916
- function getModelMeta(modelId) {
27917
- if (!modelId)
27918
- return;
27919
- const providers = getEndpointConfigSource().getProviders();
27920
- for (const pCfg of Object.values(providers)) {
27921
- const models = pCfg.models || [];
27922
- const entry = models.find((m) => m?.id === modelId);
27923
- if (entry) {
27924
- return {
27925
- knowledgeCutoff: entry.knowledgeCutoff,
27926
- supportsThinking: entry.supportsThinking,
27927
- supportsEffort: entry.supportsEffort,
27928
- supportsStructuredOutputs: entry.supportsStructuredOutputs,
27929
- skipCyberMitigation: entry.skipCyberMitigation
27930
- };
27931
- }
27932
- }
27933
- return;
27934
- }
27935
- function getProviderContextWindow(modelId) {
27936
- if (!modelId)
27937
- return;
27938
- const providers = getEndpointConfigSource().getProviders();
27939
- for (const pCfg of Object.values(providers)) {
27940
- const models = pCfg.models || [];
27941
- const entry = models.find((m) => m?.id === modelId);
27942
- if (entry?.contextWindow)
27943
- return entry.contextWindow;
27944
- }
27945
- return;
27946
- }
27947
- var init_capabilities = __esm(() => {
27948
- init_roles7();
27949
- });
27950
-
27951
28031
  // src/modelprovider/roleFallbackStore.ts
27952
28032
  function clearRoleFallback() {
27953
28033
  lastRoleFallback = null;
@@ -28065,6 +28145,7 @@ var init_modelprovider2 = __esm(() => {
28065
28145
  init_roles7();
28066
28146
  init_modelprovider();
28067
28147
  init_constants2();
28148
+ init_streamIdleWatchdog();
28068
28149
  init_modelprovider();
28069
28150
  init_types2();
28070
28151
  init_modelErrors();
@@ -29444,6 +29525,7 @@ var SettingsSchema = () => object({
29444
29525
  skipWebFetchPreflight: boolean2().optional(),
29445
29526
  search: object({ tavilyApiKey: string2().optional() }).optional(),
29446
29527
  tui: object({ fullscreen: boolean2().optional() }).optional(),
29528
+ idleCompaction: boolean2().optional(),
29447
29529
  skillOverrides: union([
29448
29530
  literal("off"),
29449
29531
  literal("user-invocable-only"),
@@ -81784,9 +81866,14 @@ function resolveAutoCompactWindowSingle(setting) {
81784
81866
  }
81785
81867
  return {};
81786
81868
  }
81869
+ function lookupAutoCompactWindowSetting(perModel, model) {
81870
+ if (!model)
81871
+ return perModel.default;
81872
+ return perModel[model] ?? perModel[stripProviderPrefix(model)] ?? perModel.default;
81873
+ }
81787
81874
  function resolveAutoCompactWindow(setting, model) {
81788
81875
  const perModel = normalizeAutoCompactWindowSetting(setting);
81789
- const chosen = model && perModel[model] || perModel.default;
81876
+ const chosen = lookupAutoCompactWindowSetting(perModel, model);
81790
81877
  return resolveAutoCompactWindowSingle(chosen);
81791
81878
  }
81792
81879
  function parseAutoCompactTierInput(raw) {
@@ -81822,6 +81909,7 @@ function parseAutoCompactTierArg(raw) {
81822
81909
  }
81823
81910
  var AUTOCOMPACT_PRESET_WINDOW_TIERS;
81824
81911
  var init_autoCompactWindow = __esm(() => {
81912
+ init_modelprovider2();
81825
81913
  AUTOCOMPACT_PRESET_WINDOW_TIERS = [
81826
81914
  1e5,
81827
81915
  128000,
@@ -81830,6 +81918,56 @@ var init_autoCompactWindow = __esm(() => {
81830
81918
  ];
81831
81919
  });
81832
81920
 
81921
+ // src/engine/context/idleCompaction.ts
81922
+ function resolveIdleCompactionConfig(settingsRaw, envRaw) {
81923
+ const enabled = settingsRaw !== false;
81924
+ let minTokens = IDLE_COMPACT_MIN_TOKENS;
81925
+ if (envRaw !== undefined) {
81926
+ const parsed = Number(envRaw);
81927
+ if (Number.isInteger(parsed) && parsed >= 1)
81928
+ minTokens = parsed;
81929
+ }
81930
+ return { enabled, minTokens };
81931
+ }
81932
+ function shouldIdleCompact(config, idleMs, totalTokens) {
81933
+ return config.enabled && Number.isFinite(idleMs) && idleMs >= IDLE_COMPACT_TRIGGER_MS && Number.isFinite(totalTokens) && totalTokens >= config.minTokens;
81934
+ }
81935
+ function getIdleMs(messages, now = Date.now()) {
81936
+ let lastAssistant;
81937
+ for (let i = messages.length - 1;i >= 0; i--) {
81938
+ const m = messages[i];
81939
+ if (m && m.type === "assistant") {
81940
+ lastAssistant = m;
81941
+ break;
81942
+ }
81943
+ }
81944
+ if (!lastAssistant)
81945
+ return Number.NaN;
81946
+ const raw = lastAssistant.timestamp;
81947
+ if (raw === undefined || raw === null)
81948
+ return Number.NaN;
81949
+ const ts = typeof raw === "number" ? raw : new Date(String(raw)).getTime();
81950
+ if (!Number.isFinite(ts) || ts <= 0)
81951
+ return Number.NaN;
81952
+ return now - ts;
81953
+ }
81954
+ function setIdleCompactionSettingsSource(next) {
81955
+ idleCompactionSettingsSource = next;
81956
+ }
81957
+ function getIdleCompactionConfig() {
81958
+ return resolveIdleCompactionConfig(idleCompactionSettingsSource?.(), process.env.ATLAS_IDLE_COMPACT_MIN_TOKENS);
81959
+ }
81960
+ function resetIdleCompactionForTesting() {
81961
+ idleCompactionSettingsSource = null;
81962
+ }
81963
+ var PROMPT_CACHE_TTL_MS = 3600000, IDLE_COMPACT_TRIGGER_MS = 3240000, IDLE_COMPACT_MIN_TOKENS = 200000, IDLE_COMPACTION_CONFIG_DEFAULTS, idleCompactionSettingsSource = null;
81964
+ var init_idleCompaction = __esm(() => {
81965
+ IDLE_COMPACTION_CONFIG_DEFAULTS = {
81966
+ enabled: true,
81967
+ minTokens: IDLE_COMPACT_MIN_TOKENS
81968
+ };
81969
+ });
81970
+
81833
81971
  // src/engine/context/autoCompact.ts
81834
81972
  import { randomUUID as randomUUID17 } from "crypto";
81835
81973
  function resolveModelContextWindow(model) {
@@ -81975,7 +82113,19 @@ async function shouldAutoCompact(messages, deps) {
81975
82113
  if (!Number.isFinite(tokenCount)) {
81976
82114
  return false;
81977
82115
  }
81978
- return tokenCount >= getAutoCompactThreshold(deps.contextWindow, deps.maxOutputTokens, deps.pctOverride, deps.windowOverride);
82116
+ const thinkingBudget = deps.thinkingBudgetTokens !== undefined && Number.isFinite(deps.thinkingBudgetTokens) ? deps.thinkingBudgetTokens : 0;
82117
+ const thresholdMet = tokenCount + thinkingBudget >= getAutoCompactThreshold(deps.contextWindow, deps.maxOutputTokens, deps.pctOverride, deps.windowOverride);
82118
+ if (thresholdMet) {
82119
+ return true;
82120
+ }
82121
+ const idleConfig = getIdleCompactionConfig();
82122
+ if (idleConfig.enabled) {
82123
+ const idleMs = getIdleMs(messages);
82124
+ if (shouldIdleCompact(idleConfig, idleMs, tokenCount)) {
82125
+ return true;
82126
+ }
82127
+ }
82128
+ return false;
81979
82129
  }
81980
82130
  async function autoCompactIfNeeded(messages, tracking, deps) {
81981
82131
  if (tracking?.consecutiveFailures !== undefined && tracking.consecutiveFailures >= MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES) {
@@ -82012,6 +82162,7 @@ var init_autoCompact = __esm(() => {
82012
82162
  init_config();
82013
82163
  init_compact();
82014
82164
  init_autoCompactWindow();
82165
+ init_idleCompaction();
82015
82166
  });
82016
82167
 
82017
82168
  // src/engine/context/autoCompactRich.ts
@@ -82503,6 +82654,7 @@ var init_autoCompactCircuit = __esm(() => {
82503
82654
  // src/engine/context/index.ts
82504
82655
  var init_context = __esm(() => {
82505
82656
  init_autoCompact();
82657
+ init_idleCompaction();
82506
82658
  init_autoCompactWindow();
82507
82659
  init_autoCompact();
82508
82660
  init_autoCompactRich();
@@ -82660,7 +82812,7 @@ async function queryAgentLoop(deps, args) {
82660
82812
  deps.emit?.({ type: "loop_start", messageCount: messages.length });
82661
82813
  while (turns < maxTurns) {
82662
82814
  turns++;
82663
- if (args.context?.autoCompact) {
82815
+ if (args.context?.autoCompact && !deps.signal?.aborted) {
82664
82816
  const oc = await autoCompactIfNeeded(messages, tracking, args.context.autoCompact);
82665
82817
  if (oc.wasCompacted && oc.compactionResult && !oc.compactionResult.compactionSkipped) {
82666
82818
  messages = buildPostCompactMessages(oc.compactionResult);
@@ -82682,7 +82834,7 @@ async function queryAgentLoop(deps, args) {
82682
82834
  }
82683
82835
  }
82684
82836
  deps.transcript?.reAppendSessionMetadata?.();
82685
- } else if (oc.consecutiveFailures !== undefined) {
82837
+ } else if (oc.consecutiveFailures !== undefined && !deps.signal?.aborted) {
82686
82838
  tracking = { ...tracking, consecutiveFailures: oc.consecutiveFailures };
82687
82839
  reportAutoCompactCircuitFailures(oc.consecutiveFailures);
82688
82840
  }
@@ -124333,6 +124485,7 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
124333
124485
  prefersReducedMotion: boolean2().optional(),
124334
124486
  syntaxHighlightingDisabled: boolean2().optional(),
124335
124487
  spinnerTipsEnabled: boolean2().optional(),
124488
+ idleCompaction: boolean2().optional(),
124336
124489
  spinnerTipsOverride: any().optional(),
124337
124490
  spinnerVerbs: any().optional(),
124338
124491
  statusLine: any().optional(),
@@ -132971,6 +133124,13 @@ function getPersistedEffortForModel(model) {
132971
133124
  if (key.toLowerCase() === wanted)
132972
133125
  return level;
132973
133126
  }
133127
+ const base = stripProviderPrefix(model).toLowerCase();
133128
+ if (base !== wanted) {
133129
+ for (const [key, level] of Object.entries(getEffortByModel())) {
133130
+ if (key.toLowerCase() === base)
133131
+ return level;
133132
+ }
133133
+ }
132974
133134
  return;
132975
133135
  }
132976
133136
  function withEffortForModel(model, level) {
@@ -133050,6 +133210,7 @@ var init_effort2 = __esm(() => {
133050
133210
  init_thinking();
133051
133211
  init_settings3();
133052
133212
  init_envUtils2();
133213
+ init_modelprovider2();
133053
133214
  EFFORT_LEVELS2 = [
133054
133215
  "low",
133055
133216
  "medium",
@@ -151291,28 +151452,28 @@ function getEventPriority(eventType) {
151291
151452
  case "focus":
151292
151453
  case "blur":
151293
151454
  case "paste":
151294
- return import_constants54.DiscreteEventPriority;
151455
+ return import_constants56.DiscreteEventPriority;
151295
151456
  case "resize":
151296
151457
  case "scroll":
151297
151458
  case "mousemove":
151298
- return import_constants54.ContinuousEventPriority;
151459
+ return import_constants56.ContinuousEventPriority;
151299
151460
  default:
151300
- return import_constants54.DefaultEventPriority;
151461
+ return import_constants56.DefaultEventPriority;
151301
151462
  }
151302
151463
  }
151303
151464
 
151304
151465
  class Dispatcher {
151305
151466
  currentEvent = null;
151306
- currentUpdatePriority = import_constants54.DefaultEventPriority;
151467
+ currentUpdatePriority = import_constants56.DefaultEventPriority;
151307
151468
  discreteUpdates = null;
151308
151469
  resolveEventPriority() {
151309
- if (this.currentUpdatePriority !== import_constants54.NoEventPriority) {
151470
+ if (this.currentUpdatePriority !== import_constants56.NoEventPriority) {
151310
151471
  return this.currentUpdatePriority;
151311
151472
  }
151312
151473
  if (this.currentEvent) {
151313
151474
  return getEventPriority(this.currentEvent.type);
151314
151475
  }
151315
- return import_constants54.DefaultEventPriority;
151476
+ return import_constants56.DefaultEventPriority;
151316
151477
  }
151317
151478
  dispatch(target, event) {
151318
151479
  const previousEvent = this.currentEvent;
@@ -151337,18 +151498,18 @@ class Dispatcher {
151337
151498
  dispatchContinuous(target, event) {
151338
151499
  const previousPriority = this.currentUpdatePriority;
151339
151500
  try {
151340
- this.currentUpdatePriority = import_constants54.ContinuousEventPriority;
151501
+ this.currentUpdatePriority = import_constants56.ContinuousEventPriority;
151341
151502
  return this.dispatch(target, event);
151342
151503
  } finally {
151343
151504
  this.currentUpdatePriority = previousPriority;
151344
151505
  }
151345
151506
  }
151346
151507
  }
151347
- var import_constants54;
151508
+ var import_constants56;
151348
151509
  var init_dispatcher = __esm(() => {
151349
151510
  init_log5();
151350
151511
  init_event_handlers();
151351
- import_constants54 = __toESM(require_constants2(), 1);
151512
+ import_constants56 = __toESM(require_constants2(), 1);
151352
151513
  });
151353
151514
 
151354
151515
  // src/tui/ink/events/terminal-event.ts
@@ -160155,7 +160316,7 @@ function applyPositionedHighlight(screen, stylePool, positions, rowOffset, curre
160155
160316
  }
160156
160317
  return true;
160157
160318
  }
160158
- var import_constants56, timing;
160319
+ var import_constants58, timing;
160159
160320
  var init_render_to_screen = __esm(() => {
160160
160321
  init_debug();
160161
160322
  init_dom();
@@ -160164,7 +160325,7 @@ var init_render_to_screen = __esm(() => {
160164
160325
  init_reconciler();
160165
160326
  init_render_node_to_output();
160166
160327
  init_screen();
160167
- import_constants56 = __toESM(require_constants2(), 1);
160328
+ import_constants58 = __toESM(require_constants2(), 1);
160168
160329
  timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
160169
160330
  });
160170
160331
 
@@ -160470,7 +160631,7 @@ class Ink {
160470
160631
  };
160471
160632
  }
160472
160633
  };
160473
- this.container = reconciler_default.createContainer(this.rootNode, import_constants57.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160634
+ this.container = reconciler_default.createContainer(this.rootNode, import_constants59.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160474
160635
  if (false) {}
160475
160636
  }
160476
160637
  handleResume = () => {
@@ -161283,7 +161444,7 @@ function drainStdin(stdin = process.stdin) {
161283
161444
  }
161284
161445
  }
161285
161446
  }
161286
- var import_constants57, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161447
+ var import_constants59, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161287
161448
  var init_ink = __esm(() => {
161288
161449
  init_noop();
161289
161450
  init_throttle2();
@@ -161316,7 +161477,7 @@ var init_ink = __esm(() => {
161316
161477
  init_dec();
161317
161478
  init_osc();
161318
161479
  init_useTerminalNotification();
161319
- import_constants57 = __toESM(require_constants2(), 1);
161480
+ import_constants59 = __toESM(require_constants2(), 1);
161320
161481
  jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
161321
161482
  ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
161322
161483
  x: 0,
@@ -171913,6 +172074,7 @@ function parseAgentFromJson(name, definition, source = "flagSettings") {
171913
172074
  ...parsed.mcpServers && parsed.mcpServers.length > 0 ? { mcpServers: parsed.mcpServers } : {},
171914
172075
  ...parsed.hooks ? { hooks: parsed.hooks } : {},
171915
172076
  ...parsed.maxTurns !== undefined ? { maxTurns: parsed.maxTurns } : {},
172077
+ ...parsed.autoCompactWindow !== undefined ? { autoCompactWindow: parsed.autoCompactWindow } : {},
171916
172078
  ...parsed.skills && parsed.skills.length > 0 ? { skills: parsed.skills } : {},
171917
172079
  ...parsed.initialPrompt ? { initialPrompt: parsed.initialPrompt } : {},
171918
172080
  ...parsed.background ? { background: parsed.background } : {},
@@ -171999,6 +172161,11 @@ function parseAgentFromMarkdown2(filePath, baseDir, frontmatter, content, source
171999
172161
  if (maxTurnsRaw !== undefined && maxTurns === undefined) {
172000
172162
  logForDebugging3(`Agent file ${filePath} has invalid maxTurns '${maxTurnsRaw}'. Must be a positive integer.`);
172001
172163
  }
172164
+ const autoCompactWindowRaw = frontmatter["autoCompactWindow"];
172165
+ const autoCompactWindow = parsePositiveIntFromFrontmatter(autoCompactWindowRaw);
172166
+ if (autoCompactWindowRaw !== undefined && autoCompactWindow === undefined) {
172167
+ logForDebugging3(`Agent file ${filePath} has invalid autoCompactWindow '${autoCompactWindowRaw}'. Must be a positive integer (tokens).`);
172168
+ }
172002
172169
  const filename = basename16(filePath, ".md");
172003
172170
  let tools = parseAgentToolsFromFrontmatter2(frontmatter["tools"]);
172004
172171
  if (isAutoMemoryEnabled2() && memory && tools !== undefined) {
@@ -172058,6 +172225,7 @@ function parseAgentFromMarkdown2(filePath, baseDir, frontmatter, content, source
172058
172225
  ...parsedEffort !== undefined ? { effort: parsedEffort } : {},
172059
172226
  ...isValidPermissionMode ? { permissionMode: permissionModeRaw } : {},
172060
172227
  ...maxTurns !== undefined ? { maxTurns } : {},
172228
+ ...autoCompactWindow !== undefined ? { autoCompactWindow } : {},
172061
172229
  ...background ? { background } : {},
172062
172230
  ...memory ? { memory } : {},
172063
172231
  ...isolation ? { isolation } : {}
@@ -172109,6 +172277,7 @@ var init_loadAgentsDir2 = __esm(() => {
172109
172277
  mcpServers: array(AgentMcpServerSpecSchema2()).optional(),
172110
172278
  hooks: HooksSchema2().optional(),
172111
172279
  maxTurns: number2().int().positive().optional(),
172280
+ autoCompactWindow: number2().int().positive().optional(),
172112
172281
  skills: array(string2()).optional(),
172113
172282
  initialPrompt: string2().optional(),
172114
172283
  memory: _enum(["user", "project", "local"]).optional(),
@@ -180708,6 +180877,9 @@ __export(exports_engineCompat, {
180708
180877
  HookCommandSchema: () => HookCommandSchema,
180709
180878
  HookMatcherSchema: () => HookMatcherSchema,
180710
180879
  HooksSchema: () => HooksSchema,
180880
+ IDLE_COMPACTION_CONFIG_DEFAULTS: () => IDLE_COMPACTION_CONFIG_DEFAULTS,
180881
+ IDLE_COMPACT_MIN_TOKENS: () => IDLE_COMPACT_MIN_TOKENS,
180882
+ IDLE_COMPACT_TRIGGER_MS: () => IDLE_COMPACT_TRIGGER_MS,
180711
180883
  INTERNAL_WORKER_TOOLS: () => INTERNAL_WORKER_TOOLS,
180712
180884
  INTERRUPT_MESSAGE: () => INTERRUPT_MESSAGE,
180713
180885
  INTERRUPT_MESSAGE_FOR_TOOL_USE: () => INTERRUPT_MESSAGE_FOR_TOOL_USE,
@@ -180731,6 +180903,7 @@ __export(exports_engineCompat, {
180731
180903
  NotebookEditTool: () => NotebookEditTool,
180732
180904
  PANEL_GRACE_MS: () => PANEL_GRACE_MS,
180733
180905
  POLL_INTERVAL_MS: () => POLL_INTERVAL_MS2,
180906
+ PROMPT_CACHE_TTL_MS: () => PROMPT_CACHE_TTL_MS,
180734
180907
  PTL_RETRY_MARKER: () => PTL_RETRY_MARKER,
180735
180908
  PermissionModeSchema: () => PermissionModeSchema,
180736
180909
  PlanApprovalRequestMessageSchema: () => PlanApprovalRequestMessageSchema,
@@ -180984,6 +181157,8 @@ __export(exports_engineCompat, {
180984
181157
  getGoalPausedReason: () => getGoalPausedReason,
180985
181158
  getGoalStateForPersistence: () => getGoalStateForPersistence,
180986
181159
  getHooksConfigFromSnapshot: () => getHooksConfigFromSnapshot,
181160
+ getIdleCompactionConfig: () => getIdleCompactionConfig,
181161
+ getIdleMs: () => getIdleMs,
180987
181162
  getInboxPath: () => getInboxPath,
180988
181163
  getInitialSettings: () => getInitialSettings,
180989
181164
  getLastPeerDmSummary: () => getLastPeerDmSummary,
@@ -181156,6 +181331,7 @@ __export(exports_engineCompat, {
181156
181331
  lock: () => lock,
181157
181332
  lockSync: () => lockSync,
181158
181333
  looksLikePrompt: () => looksLikePrompt,
181334
+ lookupAutoCompactWindowSetting: () => lookupAutoCompactWindowSetting,
181159
181335
  makeDeferredToolUseMarker: () => makeDeferredToolUseMarker,
181160
181336
  markAgentsNotified: () => markAgentsNotified,
181161
181337
  markCronTasksFired: () => markCronTasksFired,
@@ -181256,6 +181432,7 @@ __export(exports_engineCompat, {
181256
181432
  resetDomainMountForTests: () => resetDomainMountForTests,
181257
181433
  resetGoalStateForTesting: () => resetGoalStateForTesting,
181258
181434
  resetHooksConfigSnapshot: () => resetHooksConfigSnapshot,
181435
+ resetIdleCompactionForTesting: () => resetIdleCompactionForTesting,
181259
181436
  resetMcpClientRegistry: () => resetMcpClientRegistry,
181260
181437
  resetMcpSkillCommandSource: () => resetMcpSkillCommandSource,
181261
181438
  resetMicrocompactState: () => resetMicrocompactState,
@@ -181278,6 +181455,7 @@ __export(exports_engineCompat, {
181278
181455
  resolveAgentTools: () => resolveAgentTools,
181279
181456
  resolveAutoCompactWindow: () => resolveAutoCompactWindow,
181280
181457
  resolveGitDir: () => resolveGitDir,
181458
+ resolveIdleCompactionConfig: () => resolveIdleCompactionConfig,
181281
181459
  resolveRef: () => resolveRef,
181282
181460
  resolveWebSearchApiKey: () => resolveWebSearchApiKey,
181283
181461
  resolveWebSearchProvider: () => resolveWebSearchProvider,
@@ -181315,6 +181493,7 @@ __export(exports_engineCompat, {
181315
181493
  setCompactPorts: () => setCompactPorts,
181316
181494
  setCronJitterConfigProvider: () => setCronJitterConfigProvider,
181317
181495
  setDynamicTeamContext: () => setDynamicTeamContext,
181496
+ setIdleCompactionSettingsSource: () => setIdleCompactionSettingsSource,
181318
181497
  setLastSummarizedMessageId: () => setLastSummarizedMessageId,
181319
181498
  setLeaderTeamName: () => setLeaderTeamName,
181320
181499
  setMcpClientRegistry: () => setMcpClientRegistry,
@@ -181343,6 +181522,7 @@ __export(exports_engineCompat, {
181343
181522
  shouldAutoCompact: () => shouldAutoCompact,
181344
181523
  shouldDisableAllHooksIncludingManaged: () => shouldDisableAllHooksIncludingManaged,
181345
181524
  shouldDisableBypassPermissions: () => shouldDisableBypassPermissions,
181525
+ shouldIdleCompact: () => shouldIdleCompact,
181346
181526
  shouldNudgeForSnips: () => shouldNudgeForSnips,
181347
181527
  shouldPlanUseAutoMode: () => shouldPlanUseAutoMode,
181348
181528
  shouldUseSandbox: () => shouldUseSandbox,
@@ -263542,6 +263722,10 @@ function CompactSummary(t0) {
263542
263722
  description: "expand history",
263543
263723
  parens: true
263544
263724
  }, undefined, false, undefined, this)
263725
+ }, undefined, false, undefined, this),
263726
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
263727
+ dimColor: true,
263728
+ children: "Summary is saved to the session transcript and restored on resume"
263545
263729
  }, undefined, false, undefined, this)
263546
263730
  ]
263547
263731
  }, undefined, true, undefined, this)
@@ -263634,14 +263818,20 @@ function CompactSummary(t0) {
263634
263818
  t2,
263635
263819
  /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedBox_default, {
263636
263820
  flexDirection: "column",
263637
- children: /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
263638
- bold: true,
263639
- children: [
263640
- "Compact summary",
263641
- t3
263642
- ]
263643
- }, undefined, true, undefined, this)
263644
- }, undefined, false, undefined, this)
263821
+ children: [
263822
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
263823
+ bold: true,
263824
+ children: [
263825
+ "Compact summary",
263826
+ t3
263827
+ ]
263828
+ }, undefined, true, undefined, this),
263829
+ /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(ThemedText, {
263830
+ dimColor: true,
263831
+ children: "Summary is saved to the session transcript and restored on resume"
263832
+ }, undefined, false, undefined, this)
263833
+ ]
263834
+ }, undefined, true, undefined, this)
263645
263835
  ]
263646
263836
  }, undefined, true, undefined, this);
263647
263837
  $[16] = t3;
@@ -274293,6 +274483,7 @@ async function* runAgent2({
274293
274483
  getAppState: () => agentToolUseContext.getAppState(),
274294
274484
  querySource,
274295
274485
  maxTurns: effectiveMaxTurns,
274486
+ ...agentDefinition.autoCompactWindow !== undefined ? { autoCompactWindowOverride: agentDefinition.autoCompactWindow } : {},
274296
274487
  signal: agentAbortController.signal
274297
274488
  });
274298
274489
  const stream = queryEngineLoopStream({
@@ -321484,14 +321675,19 @@ function buildAgentLoopParams(m) {
321484
321675
  const resolved = pool.length > 0 ? resolveModel(pool[0]) : undefined;
321485
321676
  const toolList = m.tools;
321486
321677
  const countTokens = (msgs) => modelProvider.countTokens(role, sessionModel, msgs, toolList);
321487
- const mergedAutoCompact = mergeAutoCompactOverrides(getAutoCompactEnvOverrides(), getInitialSettings2().autoCompactWindow, mainLoopModel);
321678
+ const envAutoCompact = getAutoCompactEnvOverrides();
321679
+ const mergedAutoCompact = mergeAutoCompactOverrides(envAutoCompact, getInitialSettings2().autoCompactWindow, mainLoopModel);
321680
+ const autoCompactWindowOverride = envAutoCompact.windowOverride !== undefined ? mergedAutoCompact.windowOverride : m.autoCompactWindowOverride ?? mergedAutoCompact.windowOverride;
321488
321681
  const autoCompact = {
321489
321682
  contextWindow: resolved?.contextWindow ?? HARD_DEFAULT_CONTEXT_WINDOW,
321490
321683
  maxOutputTokens: resolved?.maxTokens,
321491
321684
  countTokens,
321492
321685
  enabled: mergedAutoCompact.autoCompactDisabled ? false : undefined,
321493
321686
  pctOverride: mergedAutoCompact.pctOverride,
321494
- windowOverride: mergedAutoCompact.windowOverride,
321687
+ windowOverride: autoCompactWindowOverride,
321688
+ ...m.toolUseContext.options?.thinkingConfig?.type === "enabled" ? {
321689
+ thinkingBudgetTokens: m.toolUseContext.options.thinkingConfig.budgetTokens
321690
+ } : {},
321495
321691
  compact: createAutoCompactCompact({
321496
321692
  trimmedSummarize: async (compactMsgs, prompt) => {
321497
321693
  const resp = await modelProvider.chat({
@@ -349148,8 +349344,7 @@ __export(exports_autocompact, {
349148
349344
  call: () => call9
349149
349345
  });
349150
349346
  function currentTierFor(raw, model) {
349151
- const map = normalizeAutoCompactWindowSetting(raw);
349152
- return map[model] ?? map.default;
349347
+ return lookupAutoCompactWindowSetting(normalizeAutoCompactWindowSetting(raw), model);
349153
349348
  }
349154
349349
  function currentToOptionValue(setting) {
349155
349350
  if (!setting || setting.kind === "auto")
@@ -354956,6 +355151,21 @@ function Config({
354956
355151
  }));
354957
355152
  }
354958
355153
  },
355154
+ {
355155
+ id: "idleCompaction",
355156
+ label: "Idle compaction",
355157
+ value: settingsData?.idleCompaction ?? true,
355158
+ type: "boolean",
355159
+ onChange(idleCompaction) {
355160
+ updateSettingsForSource2("localSettings", {
355161
+ idleCompaction
355162
+ });
355163
+ setSettingsData((prev_3b) => ({
355164
+ ...prev_3b,
355165
+ idleCompaction
355166
+ }));
355167
+ }
355168
+ },
354959
355169
  {
354960
355170
  id: "prefersReducedMotion",
354961
355171
  label: "Reduce motion",
@@ -355592,6 +355802,7 @@ function Config({
355592
355802
  const il = initialLocalSettings;
355593
355803
  updateSettingsForSource2("localSettings", {
355594
355804
  spinnerTipsEnabled: il?.spinnerTipsEnabled,
355805
+ idleCompaction: il?.idleCompaction,
355595
355806
  prefersReducedMotion: il?.prefersReducedMotion,
355596
355807
  outputStyle: il?.outputStyle
355597
355808
  });
@@ -431302,6 +431513,30 @@ var init_hooks7 = __esm(() => {
431302
431513
  TOOL_HOOK_EXECUTION_TIMEOUT_MS = 10 * 60 * 1000;
431303
431514
  });
431304
431515
 
431516
+ // src/tui/contextBodies/compactModelSwitch.ts
431517
+ function recordMainLoopModelSwitch(previous, next) {
431518
+ if (!previous || previous === next) {
431519
+ previousMainLoopModel = null;
431520
+ return;
431521
+ }
431522
+ previousMainLoopModel = previous;
431523
+ }
431524
+ function resolveSwitchedCompactModel(current) {
431525
+ const previous = previousMainLoopModel;
431526
+ if (!previous || !current || previous === current)
431527
+ return;
431528
+ const previousWindow = getProviderContextWindow(previous) ?? HARD_DEFAULT_CONTEXT_WINDOW;
431529
+ const currentWindow = getProviderContextWindow(current) ?? HARD_DEFAULT_CONTEXT_WINDOW;
431530
+ return previousWindow > currentWindow ? previous : undefined;
431531
+ }
431532
+ function formatCompactStartMessage(summaryModel) {
431533
+ return summaryModel ? `Compacting conversation (summary: ${summaryModel})` : "Compacting conversation";
431534
+ }
431535
+ var previousMainLoopModel = null;
431536
+ var init_compactModelSwitch = __esm(() => {
431537
+ init_modelprovider2();
431538
+ });
431539
+
431305
431540
  // src/tui/utils/memory/types.ts
431306
431541
  var MEMORY_TYPE_VALUES;
431307
431542
  var init_types17 = __esm(() => {
@@ -432222,7 +432457,11 @@ async function streamCompactSummary({
432222
432457
  }
432223
432458
  const retryEnabled = getFeatureValue_CACHED_MAY_BE_STALE("atlas_compact_streaming_retry", false);
432224
432459
  const maxAttempts = retryEnabled ? MAX_COMPACT_STREAMING_RETRIES : 1;
432225
- const compactModel = modelOverride ?? context.options.mainLoopModel;
432460
+ const compactModel = modelOverride ?? resolveSwitchedCompactModel(context.options.mainLoopModel) ?? context.options.mainLoopModel;
432461
+ context.onCompactProgress?.({
432462
+ type: "compact_start",
432463
+ summaryModel: compactModel
432464
+ });
432226
432465
  for (let attempt = 1;attempt <= maxAttempts; attempt++) {
432227
432466
  let hasStartedStreaming = false;
432228
432467
  let response;
@@ -432475,6 +432714,7 @@ var init_compact4 = __esm(() => {
432475
432714
  init_shared();
432476
432715
  init_uniqBy();
432477
432716
  init_atlas();
432717
+ init_compactModelSwitch();
432478
432718
  init_bootstrapState();
432479
432719
  init_bootstrapState();
432480
432720
  init_FileReadTool();
@@ -433193,6 +433433,7 @@ function wireContextHostPorts() {
433193
433433
  });
433194
433434
  setAutoCompactSettingsSource(() => getGlobalConfig().autoCompactEnabled);
433195
433435
  setAutoCompactWindowSettingsSource(() => getInitialSettings2().autoCompactWindow);
433436
+ setIdleCompactionSettingsSource(() => getInitialSettings2().idleCompaction);
433196
433437
  setLlmTimeoutSettingsSource(() => getInitialSettings2().llmTimeoutMs);
433197
433438
  setEffortByModelSource(() => getEffortByModel());
433198
433439
  setTimeBasedMCConfigSource(() => getFeatureValue_CACHED_MAY_BE_STALE("atlas_slate_heron", TIME_BASED_MC_CONFIG_DEFAULTS));
@@ -435648,6 +435889,9 @@ function onChangeAppState({
435648
435889
  }
435649
435890
  notifyPermissionModeChanged(newMode);
435650
435891
  }
435892
+ if (newState.mainLoopModel !== oldState.mainLoopModel) {
435893
+ recordMainLoopModelSwitch(oldState.mainLoopModel, newState.mainLoopModel);
435894
+ }
435651
435895
  if (newState.mainLoopModel !== oldState.mainLoopModel && newState.mainLoopModel === null) {
435652
435896
  updateSettingsForSource2("userSettings", { model: undefined });
435653
435897
  setMainLoopModelOverride(null);
@@ -435689,6 +435933,7 @@ function onChangeAppState({
435689
435933
  }
435690
435934
  var init_onChangeAppState = __esm(() => {
435691
435935
  init_bootstrapState();
435936
+ init_compactModelSwitch();
435692
435937
  init_auth4();
435693
435938
  init_config6();
435694
435939
  init_errors4();
@@ -479753,7 +479998,7 @@ Error: sandbox required but unavailable: ${reason}
479753
479998
  setSpinnerMessage(event.hookType === "pre_compact" ? "Running PreCompact hooks…" : event.hookType === "post_compact" ? "Running PostCompact hooks…" : "Running SessionStart hooks…");
479754
479999
  break;
479755
480000
  case "compact_start":
479756
- setSpinnerMessage("Compacting conversation");
480001
+ setSpinnerMessage(formatCompactStartMessage(event.summaryModel));
479757
480002
  break;
479758
480003
  case "compact_end":
479759
480004
  setSpinnerMessage(null);
@@ -481809,6 +482054,7 @@ var init_REPL = __esm(() => {
481809
482054
  init_prompts2();
481810
482055
  init_systemPrompt();
481811
482056
  init_context5();
482057
+ init_compactModelSwitch();
481812
482058
  init_memoryFiles();
481813
482059
  init_backgroundHousekeeping();
481814
482060
  init_cost_tracker();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasharness/atlascode",
3
- "version": "0.1.79",
3
+ "version": "0.1.80",
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",