Files
oh-my-pi/packages
roboomp 94ccb8a4a5 fix(catalog): treated zenmux anthropic proxy as a signing endpoint
ZenMux's `anthropic-messages` route (`zenmux.ai/api/anthropic`) forwards to
signature-enforcing Anthropic and returns full thinking signatures, but the
compat builder classified it as a non-signing reasoning endpoint via the
generic `reasoning && !official` default (`replayUnsignedThinking: true`).

Same failure class as GitHub Copilot #2851: when a checkpoint/branch-return
turn is an abandoned tool-use turn (adaptive Sonnet 5 emits a tool call then
ends on `stop`/`end_turn`), `transformMessages` correctly strips its
end_turn-bound, unreplayable signature. On a `replayUnsignedThinking`
endpoint the encoder then re-emitted that block as
`{ type: "thinking", signature: "" }`. An empty signature is rejected by
the signature-enforcing backend with
`400 messages.1.content.0: Invalid signature in thinking`.

Exclude ZenMux from `replayUnsignedThinking` (via a new `zenmux` host
classifier covering the `zenmux` provider id and the `zenmux.ai` url marker)
so unsigned/stripped thinking degrades to text exactly like the official
Anthropic API — wire-valid and lossless of the tool_use pairing. Z.AI /
DeepSeek / other 3p reasoning endpoints (#2005) and cross-model preservation
(#2257/#2265) are unaffected.

Tests:
- packages/catalog/test/anthropic-zenmux-signing-compat.test.ts: zenmux
  (provider id and url marker paths) -> replayUnsignedThinking false; generic
  3p reasoning -> true; official -> false. Fails before / passes after.
- packages/ai/test/anthropic-zenmux-checkpoint-thinking-signature.test.ts: a
  derived-compat zenmux sonnet 5 model never emits an empty-signature
  thinking block for a historical checkpoint turn (demotes to text, keeps
  tool_use), and still replays a clean signed historical thinking block
  natively.

Fixes #4192
2026-07-02 01:59:35 +00:00
..
2026-07-02 03:08:59 +02:00
2026-07-02 03:08:59 +02:00
2026-07-02 03:08:59 +02:00
2026-07-01 20:03:42 +02:00
2026-07-02 03:08:59 +02:00
2026-07-02 03:08:59 +02:00
2026-07-01 20:03:42 +02:00
2026-07-02 03:08:59 +02:00
2026-07-02 03:08:59 +02:00
2026-07-02 03:08:59 +02:00