Use encoding/json instead of Go string quoting when promoting message content to cached text blocks. Add regression coverage for control characters, Unicode, literal backslashes, text preservation, and idempotence.
Payment and admin fulfillment shared the public Redeem entry point, so
fulfillment retries were blocked by, and contributed to, the user's
public redeem failure counter, and lookup errors were silently treated as
"code does not exist" on a partial re-run.
- resolveRedeemAction now distinguishes a genuine not-found lookup from
other lookup errors (which now fail the fulfillment instead of being
swallowed and re-created).
- Add validatePaymentRedeemCode: before reusing an existing code during
fulfillment, verify it belongs to the order (code id, balance type,
amount, user, status), so a stale or foreign code can never be
credited against the wrong order/user.
- Split Redeem into a policy-based core: public redemption enforces the
failure counter; payment fulfillment (redeemForPaymentFulfillment) and
admin fulfillment (RedeemForAdminFulfillment) bypass it, while all code
validation and transactional updates remain identical. Admin
fulfillment keeps the normal redeem-level affiliate rebate.
- The admin CreateAndRedeem endpoint now uses RedeemForAdminFulfillment.
Tests: updated resolveRedeemAction cases, new TestValidatePaymentRedeemCode,
code-used-by-another-user rejection, payment/admin rate-limit bypass
coverage, and public-path regression coverage.
Cyber-policy detection only inspected response.failed, and the ingress check ran after error-specific early returns. As a result, error-shaped failures and the connection-pool, HTTP-bridge, and WSv2 paths could miss cyber-policy hits.
Centralize event marking and invoke it before retry and failover returns across the WebSocket implementations. Preserve the recorded guard during account failover and defer connection blocking until the logical failover chain completes, avoiding duplicate records while ensuring subsequent turns are blocked.
Official OpenAI hosts and models.dev entries without an api field left
Astra falling back to reasoning effort none and empty Fast tiers. Persist
complete per-model metadata, advertise Astra reasoning/Fast locally, and
surface partial sync warnings when image models remain incomplete.
Co-authored-by: Cursor <cursoragent@cursor.com>
Anthropic gates newer models on a minimum Claude Code client version. With
CLICurrentVersion pinned at 2.1.220, claude-fable-5-1 fails every request with
"Claude Code 2.1.220 does not support this model; version 2.1.251 or newer is
required", and the only fix is a release that bumps one constant.
Add SUB2API_CLAUDE_CLI_VERSION, mirroring what internal/pkg/xai already does
with XAI_GROK_CLI_VERSION. CLICurrentVersion remains the built-in pin; the new
CLIVersion() is what every consumer reads. With no env var set the resolved
value equals the pin, so existing deployments are unaffected.
The value is resolved once at package init rather than per call: the User-Agent
header and the request body's cc_version are written by different code paths for
the same request, and reading different values would make that request
contradict itself.
Validation is strict (three numeric segments, not below the pin) because
identity_service.go documents what a malformed version does once it reaches an
account's persistent fingerprint: sustained 429s without reset headers, 5s
fallback cooldown, pool collapse into a 503 storm, and no reset entry point.
Invalid values warn and fall back rather than being silently dropped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168uDMAj9anaJrnH8CeFze6