Skip to content

Commit a630808

Browse files
committed
fix(tui): real context window + hide cost on proxy sessions
Dogfooding surfaced two dead spots in the status line: ctx% divided by a hardcoded 200k instead of the model's actual window (wildly off for local 8k or 1M-context routes), and a $0.0000 cost that's pure noise for proxy users — the proxy bills a flat subscription and returns no usage. Use the resolved model.contextWindow, and show cost only on metered (BYOK) sessions.
1 parent d10d044 commit a630808

1 file changed

Lines changed: 18 additions & 4 deletions

File tree

src/ui-pi/app.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ export class App extends Container {
151151
// state change — pi-tui only paints on input events or explicit
152152
// requestRender, never automatically on child invalidate.
153153
const requestRender = (): void => this.tui?.requestRender();
154-
this.statusBar = new StatusBar(this.bundle.model.name, this.bundle.toolContext.cwd, requestRender);
154+
this.statusBar = new StatusBar(
155+
this.bundle.model.name,
156+
this.bundle.toolContext.cwd,
157+
requestRender,
158+
this.bundle.source !== "proxy",
159+
);
155160
this.bgShellPanel = new BackgroundShellPanel(this.bundle.backgroundShells, requestRender);
156161
this.compactionBanner = new CompactionBanner(this.bundle.compactionMonitor, requestRender);
157162
this.taskPanel = new TaskPanel(this.bundle.toolContext.tasks, requestRender);
@@ -1278,7 +1283,10 @@ export class App extends Container {
12781283
private pushMetrics(): void {
12791284
const state = this.buildChatStateShadow();
12801285
const usedTokens = estimateContextTokens(state);
1281-
const contextWindow = 200_000;
1286+
// Use the resolved model's real context window — a hardcoded 200k was
1287+
// wrong for local 8k models and 1M-context routes alike. Mirror the
1288+
// compaction engine, which already trusts model.contextWindow.
1289+
const contextWindow = this.bundle.model.contextWindow || 200_000;
12821290
const ctxPct = contextWindow > 0 ? Math.min(100, Math.round((usedTokens / contextWindow) * 100)) : 0;
12831291
this.statusBar.setMetrics(ctxPct, this.usage.cost.total, this.computeTokRate());
12841292
this.contextWarning.setPercent(ctxPct);
@@ -1568,11 +1576,16 @@ class StatusBar extends Container {
15681576
private verb = THINKING_VERBS[0];
15691577
private verbTimer: NodeJS.Timeout | undefined;
15701578
private readonly onTick: () => void;
1571-
constructor(modelName: string, cwd: string, onTick: () => void = () => undefined) {
1579+
/** Per-turn cost is only meaningful on metered (BYOK) sessions — the
1580+
* proxy bills a flat subscription and returns no usage, so $0.0000 there
1581+
* is noise, not information. Hidden for proxy. */
1582+
private readonly showCost: boolean;
1583+
constructor(modelName: string, cwd: string, onTick: () => void = () => undefined, showCost = true) {
15721584
super();
15731585
this.modelName = modelName;
15741586
this.cwdLabel = basename(cwd) || cwd;
15751587
this.onTick = onTick;
1588+
this.showCost = showCost;
15761589
this.line = new Text(this.format(), 1, 0);
15771590
this.notesContainer = new Container();
15781591
this.addChild(this.notesContainer);
@@ -1656,9 +1669,10 @@ class StatusBar extends Container {
16561669
const bar = ctxBar(this.ctxPercent);
16571670
const ctxText = colorByThreshold(`${bar} ${this.ctxPercent}%`, this.ctxPercent);
16581671
const tokPart = this.tokRate !== undefined ? ` · ${this.tokRate} tok/s` : "";
1672+
const costPart = this.showCost ? ` · $${formatCost(this.cost)}` : "";
16591673
// Model name reads at default brightness as the anchor; the rest of
16601674
// the meta recedes to dim so the line is glanceable, not a wall.
1661-
const meta = ansi.dim(`${this.cwdLabel} · ctx ${ctxText}${tokPart} · $${formatCost(this.cost)}`);
1675+
const meta = ansi.dim(`${this.cwdLabel} · ctx ${ctxText}${tokPart}${costPart}`);
16621676
return `${throb}${statusLabel} ${this.modelName} ${meta}`;
16631677
}
16641678
}

0 commit comments

Comments
 (0)