Problem
The TUI statusline ctx segment (ctx 32k/128k 25%) never renders. The entire pipeline is wired but the source never produces data:
TokenUsageEvent.contextRemaining is defined (packages/core/src/events.ts:487)
ai-sdk-flow.ts:465-466 forwards it to StoredMessage
pi-transcript.ts:478 stores it on state.usage
pi-transcript.ts:946 gates the ctx segment on usage.contextRemaining !== undefined
But ai-sdk-backend.ts:1770–1790 constructs the TokenUsageEvent without ever setting contextRemaining. The field is always undefined, so the gate is always false, and the ctx segment is always omitted.
#1064 identified the symptom and #1066 addressed the chrome side (color thresholds, cwd shortening), but deliberately omitted a fallback using token_usage.input because that field is a billing-cumulative sum across tool-loop steps — using it as "used context" would produce misleading percentages (potentially >100%). The correct fix is to set contextRemaining at the source.
Root cause
ai-sdk-backend.ts has both pieces of data needed to compute contextRemaining:
contextWindow — from resolveSelectedModelContextWindow(connection, modelId) (already used for mid-turn capacity compaction at line 2558)
- Last step's
inputTokens — from the finish-step chunk's stepUsage.inputTokens (captured at line 1525 as stepUsage, accumulated into completedStepUsage)
The last step's inputTokens is the actual prompt token count of the final API request = how much context is in use. contextRemaining = contextWindow - lastStepInputTokens.
tokenUsage.inputTokens (the totalUsage used for the event's input field) is NOT suitable — it is cumulative across all tool-loop steps, which is why #1066 correctly rejected it as a fallback.
Desired outcome
- Capture the last step's
inputTokens from the finish-step handler (not the cumulative totalUsage).
- When constructing the
TokenUsageEvent, compute contextRemaining = max(0, contextWindow - lastStepInputTokens) when both values are available, and include it on the event.
- The TUI ctx segment renders without any further changes — all downstream plumbing already exists.
- Desktop's context display (if any) also benefits if it consumes the same field.
Non-goals
Problem
The TUI statusline ctx segment (
ctx 32k/128k 25%) never renders. The entire pipeline is wired but the source never produces data:TokenUsageEvent.contextRemainingis defined (packages/core/src/events.ts:487)ai-sdk-flow.ts:465-466forwards it toStoredMessagepi-transcript.ts:478stores it onstate.usagepi-transcript.ts:946gates the ctx segment onusage.contextRemaining !== undefinedBut
ai-sdk-backend.ts:1770–1790constructs theTokenUsageEventwithout ever settingcontextRemaining. The field is alwaysundefined, so the gate is alwaysfalse, and the ctx segment is always omitted.#1064 identified the symptom and #1066 addressed the chrome side (color thresholds, cwd shortening), but deliberately omitted a fallback using
token_usage.inputbecause that field is a billing-cumulative sum across tool-loop steps — using it as "used context" would produce misleading percentages (potentially >100%). The correct fix is to setcontextRemainingat the source.Root cause
ai-sdk-backend.tshas both pieces of data needed to computecontextRemaining:contextWindow— fromresolveSelectedModelContextWindow(connection, modelId)(already used for mid-turn capacity compaction at line 2558)inputTokens— from thefinish-stepchunk'sstepUsage.inputTokens(captured at line 1525 asstepUsage, accumulated intocompletedStepUsage)The last step's
inputTokensis the actual prompt token count of the final API request = how much context is in use.contextRemaining = contextWindow - lastStepInputTokens.tokenUsage.inputTokens(thetotalUsageused for the event'sinputfield) is NOT suitable — it is cumulative across all tool-loop steps, which is why #1066 correctly rejected it as a fallback.Desired outcome
inputTokensfrom thefinish-stephandler (not the cumulativetotalUsage).TokenUsageEvent, computecontextRemaining = max(0, contextWindow - lastStepInputTokens)when both values are available, and include it on the event.Non-goals
input— that decision is correct.contextRemainingto providers that don't report per-step usage — this is an ai-sdk-backend fix only.