feat(coding-agent): added /context command flow for interactive dispatch

- Added a `/context` slash command flow from registry to interactive-mode command dispatch.
- Added `handleContextCommand()` to the mode context interface and command-controller wiring.
- Added context usage breakdown utilities, cell allocation, and 20x10 usage rendering for token categories.
- Reworked compaction token estimation to use tokenizer counts, role aggregation, image token estimates, and fallback handling.
- Exported `resolveThresholdTokens()` as a public compaction helper.
This commit is contained in:
can1357
2026-04-30 02:26:04 +02:00
parent fbe051bcbd
commit f8be2ceda5
7 changed files with 362 additions and 22 deletions
@@ -24,6 +24,7 @@ import { DynamicBorder } from "../../modes/components/dynamic-border";
import { PythonExecutionComponent } from "../../modes/components/python-execution";
import { getMarkdownTheme, getSymbolTheme, theme } from "../../modes/theme/theme";
import type { InteractiveModeContext } from "../../modes/types";
import { computeContextBreakdown, renderContextUsage } from "../../modes/utils/context-usage";
import { buildHotkeysMarkdown } from "../../modes/utils/hotkeys-markdown";
import { buildToolsMarkdown } from "../../modes/utils/tools-markdown";
import type { AsyncJobSnapshotItem } from "../../session/agent-session";
@@ -529,6 +530,22 @@ export class CommandController {
showMarkdownPanel(this.ctx, "Available Tools", tools);
}
handleContextCommand(): void {
const breakdown = computeContextBreakdown(this.ctx.session);
if (breakdown.contextWindow <= 0) {
this.ctx.showWarning("Context usage is unavailable: no model is selected for this session.");
return;
}
const output = renderContextUsage(breakdown, theme);
this.ctx.chatContainer.addChild(new Spacer(1));
this.ctx.chatContainer.addChild(new DynamicBorder());
this.ctx.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Context Usage")), 1, 0));
this.ctx.chatContainer.addChild(new Spacer(1));
this.ctx.chatContainer.addChild(new Text(output, 1, 0));
this.ctx.chatContainer.addChild(new DynamicBorder());
this.ctx.ui.requestRender();
}
async handleMemoryCommand(text: string): Promise<void> {
const argumentText = text.slice(7).trim();
const action = argumentText.split(/\s+/, 1)[0]?.toLowerCase() || "view";