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 main at ac2bbb0; 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.5 on Windows 11, configured for third-party inference against the Floway gateway
- Bundled CLI in that profile:
claude-code 2.1.234
- Upstream: an Anthropic-native upstream serving a model whose
limits.max_context_window_tokens is ≥ 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-version based), 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.
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
main@ac2bbb01.30096.5on Windows 11, configured for third-party inference against the Floway gatewayclaude-code2.1.234limits.max_context_window_tokensis ≥ 1,000,000Expected
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.tsgates the whole Anthropic-native catalog shape — including the[1m]id rewrite — behind aclaude-code/User-Agent prefix:https://github.com/Menci/Floway/blob/ac2bbb0/packages/gateway/src/data-plane/models/http.ts#L72-L96
and
toClaudeCodeCatalogis the only place the suffix is ever applied: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:
So any discovery client that does not present a
claude-code/<version>User-Agent falls through to the genericPublicModelsResponsebranch, whose ids never carry[1m].limits.max_context_window_tokensis still1000000on 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+/iinanswer-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:
claude-code/.anthropic-versionbased), keeping the superset only as the fallback.[1m]-suffixed catalog.Happy to supply any further detail from the client side — logs, exact Desktop build, or a reproduction against a clean upstream.