Skip to content

fix(models): update context limits and error types for paid plans - #233

Open
sendsaf wants to merge 14 commits into
jwadow:mainfrom
sendsaf:fix/model-context-limits-and-error-types
Open

fix(models): update context limits and error types for paid plans#233
sendsaf wants to merge 14 commits into
jwadow:mainfrom
sendsaf:fix/model-context-limits-and-error-types

Conversation

@sendsaf

@sendsaf sendsaf commented Jun 23, 2026

Copy link
Copy Markdown

Problem

The gateway had two related issues that caused hard failures for users on paid Kiro plans using newer models:

1. Wrong context window limits in fallback model list

FALLBACK_MODELS had no tokenLimits per model, so every model fell back to DEFAULT_MAX_INPUT_TOKENS = 200000. This was appropriate for the free plan era (sonnet-4.5 etc.), but Kiro's current paid plans offer 1M context on sonnet-4.6, opus-4.6/4.7/4.8, and auto. Users would hit a 400 error well before reaching the actual model limit.

2. Context overflow errors not recognised by clients

When Kiro returned CONTENT_LENGTH_EXCEEDS_THRESHOLD, the gateway forwarded it as "type": "kiro_api_error" (OpenAI) or "type": "api_error" (Anthropic). Claude Code and claude-code-router do not recognise these types as context errors, so automatic compaction (/compact) failed — clients had no way to recover without starting a fresh session.

Changes

kiro/config.py

  • Add per-model tokenLimits to FALLBACK_MODELS based on Kiro's documented context windows:
    • 1M: auto, claude-sonnet-4.6, claude-opus-4.6, claude-opus-4.7, claude-opus-4.8
    • 200k: claude-sonnet-4, claude-sonnet-4.5, claude-haiku-4.5, claude-opus-4.5
    • 128k: deepseek-3.2
    • 256k: qwen3-coder-next
    • 200k: glm-5, minimax-m2.1, minimax-m2.5
  • Raise DEFAULT_MAX_INPUT_TOKENS from 200k → 1M to match the highest-tier flagship models

kiro/routes_openai.py

  • Map CONTENT_LENGTH_EXCEEDS_THRESHOLD"type": "context_length_exceeded" in both the legacy and account-system error paths (standard OpenAI error type that clients use for context recovery)

kiro/routes_anthropic.py

  • Map CONTENT_LENGTH_EXCEEDS_THRESHOLD"type": "invalid_request_error" in both error paths (standard Anthropic error type recognised by Claude Code for automatic compaction)

Test plan

  • All 233 existing unit tests pass (pytest tests/unit/ -q)
  • Gateway starts and /v1/models returns models with correct context windows
  • Context overflow on sonnet-4.6 returns context_length_exceeded / invalid_request_error instead of generic API error
  • Claude Code /compact completes successfully after a context limit hit

Your Name and others added 6 commits May 29, 2026 10:14
…tem prompt

Claude Code 2.1.x prepends a per-request system text block of the form:

  x-anthropic-billing-header: cc_version=2.1.153.d02; cc_entrypoint=sdk-cli; cch=<5hex>;

The cch segment is a fresh random hex token on every request. Because
extract_system_prompt() concatenates all system text blocks into a single
string before forwarding to Kiro, this random prefix poisons the prompt
seen by the upstream and invalidates any prefix-keyed prompt cache (the
attribution header is meant to be an HTTP header but ships in body here).

Add _strip_billing_attribution() and call it from extract_system_prompt()
for both string and list system formats. Blocks that are pure attribution
are dropped; mixed blocks have the leading attribution line removed.

The behavior is gated by STRIP_BILLING_HEADER (default true) so it can be
disabled for A/B comparison.
When the Kiro API sends tool arguments split across multiple tool_input
events as dicts, the parser was serializing each dict independently and
concatenating the JSON strings — producing invalid JSON like
`{"file_path":"..."}{"content":"..."}`. The brace-counting diagnostic
then misidentified this as upstream truncation.

Fix: accumulate dict fragments via .update() and serialize once at
finalize time. String fragment path remains unchanged.

Fixes jwadow#153

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bedrock rejects tool input_schema containing oneOf, allOf, or anyOf at
the top level (TOOL_SCHEMA_INVALID). This resolves them before sending:
- anyOf/oneOf: picks the first object-type variant
- allOf: merges all variants into a single schema

Nested composition keywords are preserved since Bedrock only rejects
them at the root of input_schema.
…d plans

- Add per-model tokenLimits to FALLBACK_MODELS matching Kiro's documented
  context windows: 1M for sonnet-4-6, opus-4-6/4-7/4-8 and auto; 200k for
  older models; 128k/256k for non-Claude models
- Raise DEFAULT_MAX_INPUT_TOKENS from 200k to 1M to match the highest-tier
  models available on paid plans
- Map CONTENT_LENGTH_EXCEEDS_THRESHOLD errors to the standard error types
  that Claude Code and compatible clients recognise (invalid_request_error
  for Anthropic format, context_length_exceeded for OpenAI format), enabling
  automatic context compaction instead of a hard failure
@cla-bot

cla-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

Thanks for the PR! 🎉

Before merge, we need a one-time CLA confirmation.
It confirms that you have the right to contribute this code and allow the project to use it.

Full CLA text:
https://github.com/jwadow/kiro-gateway/blob/main/CLA.md

Please reply once with:

I have read the CLA and I accept its terms

You need to write once, all further messages from me can be ignored.

@sendsaf

sendsaf commented Jun 23, 2026

Copy link
Copy Markdown
Author

I have read the CLA and I accept its terms

@cla-bot

cla-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

Thanks for the PR! 🎉

Before merge, we need a one-time CLA confirmation.
It confirms that you have the right to contribute this code and allow the project to use it.

Full CLA text:
https://github.com/jwadow/kiro-gateway/blob/main/CLA.md

Please reply once with:

I have read the CLA and I accept its terms

You need to write once, all further messages from me can be ignored.

@cla-bot

cla-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Thanks for the PR! 🎉

Before merge, we need a one-time CLA confirmation.
It confirms that you have the right to contribute this code and allow the project to use it.

Full CLA text:
https://github.com/jwadow/kiro-gateway/blob/main/CLA.md

Please reply once with:

I have read the CLA and I accept its terms

You need to write once, all further messages from me can be ignored.

@sendsaf

sendsaf commented Jun 25, 2026

Copy link
Copy Markdown
Author

I have read the CLA and I accept its terms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants