mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
Merge #777: auto-compact and auto-clear from the statusLine context size
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
commit
6fa2dfa549
16 files changed
+579
-45
No files matched your search
+21
-6
@@ -153,7 +153,7 @@ import {
|
||||
buildMuxAttachEnv,
|
||||
buildShellEnv,
|
||||
} from './session-cli-builder.js';
|
||||
import { SessionAutoOps } from './session-auto-ops.js';
|
||||
import { SessionAutoOps, type ContextReport } from './session-auto-ops.js';
|
||||
import { detectUsageLimitPause } from './usage-limit-patterns.js';
|
||||
import { SessionTaskCache } from './session-task-cache.js';
|
||||
import { InteractivePtyExitBreaker } from './session-pty-exit-breaker.js';
|
||||
@@ -675,6 +675,7 @@ export class Session extends EventEmitter {
|
||||
private _watching: string | null = null;
|
||||
/** Last `prompt_cache` report from the statusline exporter; null until Claude sends one. */
|
||||
private _promptCache: PromptCacheStatus | null = null;
|
||||
private _contextReport: ContextReport | null = null;
|
||||
/** Prompt-cache keep-warm opt-in; undefined = follow the app-wide default. Persisted. */
|
||||
private _keepWarmEnabled: boolean | undefined;
|
||||
/** Last status the keep-warm service published for this session; ephemeral. */
|
||||
@@ -1290,6 +1291,7 @@ export class Session extends EventEmitter {
|
||||
isWorking: () => this._isWorking,
|
||||
isStopped: () => this._isStopped,
|
||||
getTotalTokens: () => this._totalInputTokens + this._totalOutputTokens,
|
||||
getContextReport: () => this._contextReport,
|
||||
getSessionId: () => this.id,
|
||||
});
|
||||
this._autoOps.on('autoCompact', (data) => this.emit('autoCompact', data));
|
||||
@@ -1485,6 +1487,7 @@ export class Session extends EventEmitter {
|
||||
// rather than show the previous conversation's "warm until" against the new one; the
|
||||
// next statusline render repopulates. A same-id reattach returned above, untouched.
|
||||
this._promptCache = null;
|
||||
this._contextReport = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1833,6 +1836,17 @@ export class Session extends EventEmitter {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the context size from a statusline report and run the threshold checks on it. The
|
||||
* token paths above cannot do this: they only run when the counter moves, and the counter
|
||||
* does not see the cached context.
|
||||
*/
|
||||
noteContextReport(report: ContextReport): void {
|
||||
this._contextReport = report;
|
||||
this._autoOps.checkAutoCompact();
|
||||
this._autoOps.checkAutoClear();
|
||||
}
|
||||
|
||||
/** Prompt-cache keep-warm opt-in; undefined means the app-wide default applies. */
|
||||
get keepWarmEnabled(): boolean | undefined {
|
||||
return this._keepWarmEnabled;
|
||||
@@ -2479,6 +2493,7 @@ export class Session extends EventEmitter {
|
||||
autoResumeEnabled: this._autoOps.autoResumeEnabled,
|
||||
autoResumeAt: this._autoOps.autoResumeAt ?? undefined,
|
||||
promptCache: this._promptCache ?? undefined,
|
||||
contextWindowSize: this._contextReport?.windowSize,
|
||||
statusLineExporter: this.statusLineExporter,
|
||||
keepWarmEnabled: this._keepWarmEnabled,
|
||||
keepWarm: this._keepWarm ?? undefined,
|
||||
@@ -5006,9 +5021,9 @@ export class Session extends EventEmitter {
|
||||
// Matches patterns like "123.4k tokens", "5234 tokens", "1.2M tokens"
|
||||
//
|
||||
// SAFETY LIMITS:
|
||||
// - Max tokens per session: 500k (Claude's context is ~200k)
|
||||
// - Max tokens per session: MAX_SESSION_TOKENS (the largest context Claude reports is 1M)
|
||||
// - Max delta per update: 100k (prevents sudden jumps from parsing errors)
|
||||
// - Rejects "M" suffix values > 0.5 (500k) to prevent false matches
|
||||
// - Rejects "M" suffix values above that maximum to prevent false matches
|
||||
private parseTokensFromStatusLine(cleanData: string): void {
|
||||
// Quick pre-check: skip expensive regex if "token" not present (performance optimization)
|
||||
if (!cleanData.includes('token')) return;
|
||||
@@ -5026,9 +5041,8 @@ export class Session extends EventEmitter {
|
||||
if (suffix === 'k') {
|
||||
tokenCount *= 1000;
|
||||
} else if (suffix === 'm') {
|
||||
// Safety: Reject M values that would result in > 500k tokens
|
||||
// Claude's context window is ~200k, so anything claiming millions is likely a false match
|
||||
if (tokenCount > 0.5) {
|
||||
// Safety: anything claiming more than the largest context is likely a false match
|
||||
if (tokenCount * 1000000 > MAX_SESSION_TOKENS) {
|
||||
console.warn(
|
||||
`[Session ${this.id}] Rejected suspicious M token value: ${tokenMatch[0]} (would be ${tokenCount * 1000000} tokens)`
|
||||
);
|
||||
@@ -5064,6 +5078,7 @@ export class Session extends EventEmitter {
|
||||
this._totalOutputTokens += Math.round(delta * 0.4);
|
||||
|
||||
// Check if we should auto-compact or auto-clear
|
||||
this._autoOps.noteAbsoluteCounter();
|
||||
this._autoOps.checkAutoCompact();
|
||||
this._autoOps.checkAutoClear();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user