Gateway model discovery from Claude Desktop 3P inference never advertises the 1M context window
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 85
- Forks
- 33
- Avg merge
- 45m
- Merged PRs (30d)
- 10
Description
Filed by Claude Code (Opus 5), running as an agent on behalf of @moooyo. Everything below is either directly observed on the reporter's machine or read out of
mainatac2bbb0; I've marked clearly which parts are hypothesis.
Summary
When Claude Desktop's third-party (custom) inference is pointed at a Floway gateway, gateway model discovery never yields the 1M-context variant of a 1M-capable model. Every discovered model behaves as the default 200K context window; there is no way to select 1M from the Desktop client.
Environment
- Floway: self-hosted; behavior below read from
main@ac2bbb0 - Client: Claude Desktop
1.30096.5on Windows 11, configured for third-party inference against the Floway gateway - Bundled CLI in that profile:
claude-code2.1.234 - Upstream: an Anthropic-native upstream serving a model whose
limits.max_context_window_tokensis ≥ 1,000,000
Expected
Discovery through Claude Desktop's 3P inference path advertises the 1M-capable model such that the 1M context window is selectable, the same way it is for the Claude Code CLI.
Actual
Only the default 200K context window is available. No [1m] variant is offered anywhere in the Desktop model picker.
Where it comes from
packages/gateway/src/data-plane/models/http.ts gates the whole Anthropic-native catalog shape — including the [1m] id rewrite — behind a claude-code/ User-Agent prefix:
https://github.com/Menci/Floway/blob/ac2bbb0/packages/gateway/src/data-plane/models/http.ts#L72-L96
const isClaudeCodeUserAgent = (userAgent: string | undefined): boolean =>
userAgent?.startsWith('claude-code/') ?? false;
// ...
return Response.json(isClaudeCodeUserAgent(userAgent)
? toClaudeCodeCatalog(publicCatalog)
: publicCatalog);
and toClaudeCodeCatalog is the only place the suffix is ever applied:
id: max !== undefined && max >= 1_000_000 ? `${model.id}[1m]` : model.id,
The file's own comment states why this is fatal rather than cosmetic — the suffix has to arrive on the wire, because the client will not synthesize it:
the
[1m]suffix convention — append[1m]to a model id and the CLI switches that pick to the 1M-context window — only reaches the picker when the discovered id itself carries the suffix; the CLI does not synthesize the variant on discovered ids in gateway mode.
So any discovery client that does not present a claude-code/<version> User-Agent falls through to the generic PublicModelsResponse branch, whose ids never carry [1m]. limits.max_context_window_tokens is still 1000000 on that payload, but nothing downstream turns that number into a selectable 1M window.
Hypothesis (unverified): Claude Desktop's 3P gateway discovery is issued by the Electron app itself rather than by the bundled CLI, so it presents some other User-Agent and misses the prefix check. I was not able to capture the exact User-Agent string Desktop sends — I only have the client side here, not the gateway's request log. If it's useful, the reporter can capture it from the Floway instance and post it.
Worth noting the codebase already treats "is this Claude Code?" as two different tests: the strict claude-code/ prefix here, versus /^claude-cli\/\d+\.\d+\.\d+/i in answer-claude-code-probe.ts. Neither would match a Desktop-originated request.
Possible directions
Listing these as options, not as a preferred design — the right call depends on how you want discovery clients identified:
- Recognize Claude Desktop's discovery User-Agent alongside
claude-code/. - Stop keying the Anthropic-native catalog shape on User-Agent, and instead serve it when the request is unambiguously Anthropic-native discovery (e.g. path/
anthropic-versionbased), keeping the superset only as the fallback. - Make it an operator-visible switch (per API key or per gateway) so a client whose UA you don't yet recognize can still be served the
[1m]-suffixed catalog.
Happy to supply any further detail from the client side — logs, exact Desktop build, or a reproduction against a clean upstream.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/gateway/src/data-plane/models/http.ts, especially the User-Agent check and toClaudeCodeCatalog path, then confirm the User-Agent used by Claude Desktop's discovery request. Decide how that client should receive the Anthropic-native catalog and verify that discovery exposes the [1m] model variant without regressing the existing Claude Code behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100