Does ContextLength in llm-router/internal/types/model_registry.go actually get taken into consideration by Shofer UI when showing/calculating the context window utilization?
Yes. ContextLength in model_registry.go flows through the entire pipeline and determines the context window number displayed in Shofer's UI progress bar. The pipeline was fixed (2026-05-01) — previously the webview used a static map that caused a fallback to 128K.
| Step | File | Field |
|---|---|---|
| Source | model_registry.go:8 |
ContextLength int |
| API | models.go:226 |
JSON context_length |
| Proxy | Shofer Router (hosted) | remaps → context_window |
| Fetcher | useSelectedModel.ts:354 |
info.contextWindow (via routerModels.shofer) |
| Schema | shofer.ts:35 |
context_window: z.number() |
| UI | TaskHeader.tsx:106 |
model?.contextWindow |
| Step | File | Field |
|---|---|---|
| Source | model_registry.go:218 |
ContextLength: 1000000 |
| API | models.go:226 |
JSON context_length: 1000000 |
| llm-provider | llm-client.ts:651 |
contextLength: model.context_length |
| VSCode info | language-model-provider.ts:976 |
maxInputTokens: contextLength |
| VSCode LM | vscode.lm.selectChatModels() |
LanguageModelChat.maxInputTokens |
| Runtime handler | vscode-lm.ts getModel() |
contextWindow: this.client.maxInputTokens (no 128K fallback) |
| IPC message | webviewMessageHandler.ts:1238-1241 |
{ type: "vsCodeLmModels" } (now VsCodeLmChatInfo[] with shoferCapabilities/shoferPricing) |
| Context | ExtensionStateContext.tsx:327 |
vsCodeLmModels state |
| Hook | useSelectedModel.ts |
dynamic lookup from context |
| UI | TaskHeader.tsx:106 |
model?.contextWindow |
The webview's useSelectedModel hook for vscode-lm used a static vscodeLlmModels map. Unknown models (from provider extensions like llm-provider) fell through to openAiModelInfoSaneDefaults which has contextWindow: 128_000.
The backend vscode-lm handler's getModel() correctly returned 1M from this.client.maxInputTokens, but the webview never used it — it used its own static lookup.
vscode-llm.ts— emptied static map, kept type compatibility; later extendedVsCodeLmChatInfowithcapabilities,shoferCapabilities, andshoferPricingfields populated from the side channel.ExtensionStateContext.tsx— addedvsCodeLmModelsstate +vsCodeLmModelsIPC message handler.useSelectedModel.ts— vscode-lm case looks up the dynamicvsCodeLmModelsfrom context, derivescontextWindowfrommaxInputTokens, and readssupportsImages/supportsPromptCache/pricing fromshoferCapabilities/shoferPricinginstead of hardcoded defaults.VSCodeLM.tsx— reads models fromuseExtensionState(), usesmaxInputTokensforcontextWindow.vscode-lm.ts— runtime handler removed theopenAiModelInfoSaneDefaults.contextWindow(128K) fallback and the hardcodedsupportsImages: false/supportsPromptCache: trueflags; all three now come fromthis.client.maxInputTokensandshoferCapabilities(fetched viashofer.llm.getModelCapabilities).llm-router+llm-provider— addedprompt_cachecapability to/v1/models(derived fromContextCacheRead > 0) and theshofer.llm.getModelCapabilitiesside-channel command in llm-provider, since VS Code'sLanguageModelChatProviderCapabilitiesonly exposesimageInputandtoolCalling.
$ curl -s http://localhost:30081/v1/models | jq '.data[] | select(.id | test("deepseek")) | {id, context_length}'
deepseek/deepseek-v4-pro: context_length=1000000 ✅
deepseek/deepseek-v4-flash: context_length=1000000 ✅Diagnostic logs prefixed [CONTEXT-DIAG] (in Task.attemptApiRequest, context-management/index.ts, and condense/index.ts) confirm maxInputTokens=1000000 at every pipeline stage and trace condensation triggers/bails.
- Context window progress bar — the "N / M tokens" display and three-segment utilization bar
- Context condensation thresholds — condensation triggers at percentage of
contextWindow getModelMaxOutputTokens()clamping —maxTokensclamped to 20% ofcontextWindowfor Anthropic models- Context truncation — sliding window removal uses
contextWindowas the upper bound - Model picker display —
VSCodeLM.tsxusesmaxInputTokensascontextWindowin the settings UI
The "Shofer Router (hosted)" proxy step (line 17) is the only row in either path table without a file path or line reference. The hosted proxy is not part of this repository, making this step unverifiable. Consider either removing this row (the proxy is an implementation detail, not a code-level concern) or documenting the proxy's transformation logic explicitly.
Several hops have fallback values that are not mentioned:
| Hop | Fallback | Where |
|---|---|---|
language-model-provider.ts → maxInputTokens |
4096 |
language-model-provider.ts:976 — contextLength ?? 4096 |
vscode-lm.ts no-client fallback |
128_000 |
vscode-lm.ts:920 — ...openAiModelInfoSaneDefaults when this.client is null |
useSelectedModel.ts vscode-lm fallback |
128_000 |
useSelectedModel.ts:317 — openAiModelInfoSaneDefaults.contextWindow |
TaskHeader.tsx zero guard |
1 |
TaskHeader.tsx:106 — model?.contextWindow || 1 |
The doc states the 128K fallback was "removed" (line 49), but it still exists in the no-client fallback path of vscode-lm.ts getModel() and in the useSelectedModel.ts vscode-lm case. The removal only applies to the happy path where this.client is set.
The modelCache.ts returns {} for the "shofer" provider case (line 91: // Shofer models no longer available). The requestRooModels handler (webviewMessageHandler.ts:1207) says the same. Path A still works via routerModels.shofer populated by requestRouterModels, but the explicit shofer-only path is dead. Consider noting this in the doc.
The contextLength mapping at llm-client.ts:651 is in parseModelsResponse(), a private method of LLMClient. This is not discoverable from the public API. The doc should note this for readers tracing the data flow.
None of the table rows carry a "verified on" annotation. Line numbers drift as source files evolve. Consider adding a verification timestamp to the doc header or to each table so readers can gauge staleness. This review found 9 incorrect line references across 6 source files — all corrected in the current version.
Items 2–4 in the "What ContextLength Drives" section lack file/line references, making them impossible to verify without grepping the codebase. Items that could benefit from references:
- Item 2:
context-management/index.ts - Item 3:
getModelMaxOutputTokens()(search forgetModelMaxOutputTokens) - Item 4:
context-management/index.ts:68(truncateConversation)
The curl command at line 55 assumes llm-router is running on localhost:30081. Add a note that this requires the service to be running, or provide an alternative verification method (e.g., checking model_registry.go directly).