Skip to content

fix: route Kimi coding fallback via Anthropic messages - #25706

Open
ksukys wants to merge 1 commit into
NousResearch:mainfrom
ksukys:fix/kimi-coding-fallback-api-mode
Open

fix: route Kimi coding fallback via Anthropic messages#25706
ksukys wants to merge 1 commit into
NousResearch:mainfrom
ksukys:fix/kimi-coding-fallback-api-mode

Conversation

@ksukys

@ksukys ksukys commented May 14, 2026

Copy link
Copy Markdown

Summary

  • Detect api.kimi.com/coding endpoints as Anthropic Messages-compatible during agent initialization
  • Apply the same detection when activating fallback providers
  • Add regression coverage for primary and fallback Kimi coding routing

Why

When a primary provider such as OpenAI Codex is rate-limited, fallback to the Kimi coding provider could incorrectly remain in chat_completions mode. That caused Hermes to create an OpenAI-style client against https://api.kimi.com/coding and hit a 404 instead of using the Anthropic Messages adapter.

Test Plan

  • python -m pytest tests/run_agent/test_run_agent.py::TestInit::test_kimi_coding_base_url_uses_anthropic_messages_mode tests/run_agent/test_run_agent.py::TestFallbackAnthropicProvider::test_fallback_to_kimi_coding_sets_anthropic_messages_mode tests/run_agent/test_run_agent.py::TestFallbackAnthropicProvider::test_fallback_to_openrouter_uses_openai_client -q -o 'addopts='
  • python -m pytest tests/run_agent/test_run_agent.py::TestInit tests/run_agent/test_run_agent.py::TestFallbackAnthropicProvider -q -o 'addopts='

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/kimi Kimi / Moonshot labels May 14, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Note: This PR treats api.kimi.com/coding as Anthropic Messages-compatible, which conflicts with #17107 (open) that argues it should NOT be treated as Anthropic Messages. Related: #17027 (merged, added the detection), #13782 (merged, earlier Kimi fix). Needs clarification on which wire protocol Kimi coding actually speaks.

@ksukys

ksukys commented May 24, 2026

Copy link
Copy Markdown
Author

Follow-up after retesting against current origin/main:

I verified the latest upstream behavior in a clean worktree before reducing this patch. Upstream now covers the normal provider-resolution path for Kimi, but two paths still keep Kimi Coding in chat_completions mode:

  1. Direct agent initialization with base_url=https://api.kimi.com/coding and provider=kimi-coding
  2. Fallback activation when switching from a rate-limited primary provider to Kimi Coding

Both should route through anthropic_messages, otherwise Hermes constructs an OpenAI-style client for https://api.kimi.com/coding and hits the wrong endpoint.

I also reduced the patch scope after that verification:

  • keep only URL/API-mode detection in the agent init path and fallback activation path
  • add regression tests for direct init and fallback activation
  • drop the previous AnthropicAuxiliaryClient.default_headers / auxiliary-client change, since upstream already fixed the normal provider-resolution/auxiliary-client side

On the #17107 concern: this PR should apply only to the bare Kimi Coding route (https://api.kimi.com/coding), which speaks Anthropic Messages. The OpenAI-compatible /coding/v1 path should remain chat_completions and should not be matched by this fix.

Local validation on the reduced patch:

  • venv/bin/python -m compileall -q agent run_agent.py
  • targeted regression tests for direct init + fallback activation: passed
  • Kimi fallback verifier: passed, including the broader Kimi/provider-related selected tests
  • hermes chat -q 'Reply with exactly: OK' --quiet --toolsets safe: OK

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating the direct-init and runtime-fallback paths; both remain unhandled on current main (agent/agent_init.py:441-454 and agent/chat_completion_helpers.py:1363-1380).

Problems

  • The new "/coding" in ... predicates and both new tests include /coding/v1, but the follow-up comment says only bare /coding should use Anthropic Messages and /coding/v1 must remain chat_completions. This needs resolution before the patch can express the intended contract.
  • agent/agent_init.py:989-1028 also activates a configured fallback without recomputing api_mode; it is a sibling fallback path not covered by this PR.
  • Current main already has a competing /coding/v1 Anthropic classification in hermes_cli/runtime_provider.py:131 and tests/agent/test_auxiliary_transport_autodetect.py:37, matching the open #17107 discussion conflict.

Suggested changes

  • Establish and test the bare /coding versus /coding/v1 wire contract, then make all agent fallback/init paths use that same exact rule.
  • Include init-time fallback coverage if its desired transport behavior is the same.

Automated hermes-sweeper review.

):
agent = AIAgent(
api_key="sk-kimi-test",
base_url="https://api.kimi.com/coding/v1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regression encodes /coding/v1 as Anthropic, but the follow-up comment says /coding/v1 must remain chat_completions and only bare /coding should change. Please split the endpoint cases after the transport contract is confirmed.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 13, 2026

@GottZ GottZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was generated by AI during triage.

Summary

Three open PRs address the Kimi fallback transport bug: #25706 covers direct initialization and runtime fallback, #33276 reuses the shared URL detector only in runtime fallback, and #41020 adds provider-wide runtime-fallback classification. All three currently over-classify at least one OpenAI-compatible Kimi or Moonshot route instead of distinguishing the bare api.kimi.com/coding endpoint from /coding/v1 and Moonshot /v1.

Related pull requests

  • #25706 related — (+56/-4) — preferred consolidation target, but not merge-ready: it is the only diff covering both direct initialization and runtime fallback with regression tests, yet its substring predicate and tests classify /coding/v1 as Anthropic Messages and it omits the sibling init-time fallback path. This aligns with the keep_open review on #25706: establish the exact bare /coding contract, preserve /coding/v1 as OpenAI-compatible, and apply the shared rule to every init/fallback path.
  • #33276 related — (+10/-0) — duplicate fallback-only approach: it delegates to the shared URL detector, but that detector currently also classifies /coding/v1 as Anthropic Messages and the PR adds no regression tests. Despite the keep_open review on #33276, its diff is a narrower subset of #25706 and does not independently resolve the disputed wire contract, so its useful detector-reuse approach should be incorporated into #25706 rather than maintained separately.
  • #41020 related — (+4/-0) — duplicate with an over-broad fix: provider-identity routing sends all kimi-coding and kimi-coding-cn fallbacks through Anthropic Messages, incorrectly including Moonshot /v1 endpoints documented by existing tests as non-Anthropic-wire. Despite the keep_open review on #41020, the diff duplicates only the fallback portion and requires replacement with URL-specific detection plus tests, making #25706 the stronger consolidation target.

Duplicates

#33276 and #41020 substantially duplicate the runtime-fallback portion of #25706; #33276 proposes shared URL-detector reuse, while #41020 uses a broader and incorrect provider-wide branch.

Suggested consolidation

Merge #25706 only after narrowing the contract to bare api.kimi.com/coding, keeping /coding/v1 and Moonshot /v1 OpenAI-compatible, centralizing that URL rule, and covering direct init, runtime fallback, and init-time fallback with positive and negative tests. Then close #33276 and #41020 as superseded duplicates; their keep_open reviews identify real fallback gaps, but their current diffs neither resolve the protocol distinction nor provide broader correct coverage than the amended #25706.

Cross-PR triage: Reviewed 3 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 7 kB of PR diffs, 4 kB of issue/PR text, 6 kB of discussion (6 comments), 1 verify verdict. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

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

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have provider/kimi Kimi / Moonshot sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants