1. 24 Apr, 2026 10 commits
    • keh4l's avatar
      feat(gateway): add billing attribution block with cc_version fingerprint · 5862e2d8
      keh4l authored
      Real Claude Code CLI always sends a 2-block system array:
      
        [0] {"type":"text", "text":"x-anthropic-billing-header: cc_version=X.Y.Z.{fp}; cc_entrypoint=cli; cch=00000;"}
        [1] {"type":"text", "text":"You are Claude Code...", "cache_control":{...}}
      
      Before this commit, sub2api's mimicry path only produced block [1].
      The missing billing block is one of the primary third-party detection
      signals Anthropic uses for Claude-Code-scoped OAuth tokens.
      
      New file gateway_billing_block.go ports the fingerprint algorithm
      (byte-for-byte from Parrot cc_mimicry.py:compute_fingerprint):
      pick chars at positions [4,7,20] of the first user text, then
      `sha256(SALT + chars + cc_version)[:3]`.
      
        - claude/constants.go: CLICurrentVersion = "2.1.92" (must match UA)
        - gateway_billing_block.go: computeClaudeCodeFingerprint +
          buildBillingAttributionBlockJSON + extractFirstUserText
        - gateway_service.go: rewriteSystemForNonClaudeCode now emits both
          blocks in order; cch=00000 is filled in later by
          signBillingHeaderCCH in buildUpstreamRequest.
      
      Downstream compat note: syncBillingHeaderVersion's regex
      `cc_version=\d+\.\d+\.\d+` only matches the semver triple,
      leaving the `.{fp}` suffix intact when rewriting in buildUpstreamRequest.
      5862e2d8
    • keh4l's avatar
      feat(claude): add ttl to cache_control with default 5m · 66d64545
      keh4l authored
      Real Claude CLI traffic sends cache_control as
      `{"type":"ephemeral","ttl":"1h"}`. Our previous payload only
      sent `{"type":"ephemeral"}`, which is a bytewise mismatch with
      the official CLI and one more third-party detection signal.
      
      Policy: client-provided ttl is always passed through unchanged.
      Proxy-generated cache_control blocks default to 5m (vs Parrot's 1h)
      to avoid burning the 1h cache budget on automatic breakpoints while
      still aligning with the `ttl` field being present.
      
        - claude/constants.go: DefaultCacheControlTTL = "5m"
        - apicompat/types.go: new AnthropicCacheControl type with TTL field;
          AnthropicTool gains optional CacheControl pointer so the mimicry
          path can attach a cache breakpoint to tools[-1] later.
        - service/gateway_service.go: anthropicCacheControlPayload gains TTL;
          marshalAnthropicSystemTextBlock and rewriteSystemForNonClaudeCode
          emit ttl=5m by default.
      66d64545
    • keh4l's avatar
      fix(gateway): use full beta list in buildUpstreamRequest mimicry path · 165553cf
      keh4l authored
      The previous commit added FullClaudeCodeMimicryBetas() but the two
      call sites in buildUpstreamRequest still hardcoded the old 3-token
      subset. Anthropic now checks the complete set of beta tokens to
      decide if a request qualifies as Claude Code. Wire them up:
      
        - /v1/messages mimic path: requiredBetas = FullClaudeCodeMimicryBetas()
        - /v1/messages/count_tokens mimic path: same + BetaTokenCounting
      
      Haiku models keep the 2-token exemption (BetaOAuth + InterleaveThinking).
      165553cf
    • keh4l's avatar
      fix(gateway): apply full Claude Code mimicry on /chat/completions and /responses · b5467d61
      keh4l authored
      Before: the OpenAI-compat forwarders only called injectClaudeCodePrompt,
      which prepends the Claude Code banner but leaves the rest of the body
      in its original non-Claude-Code shape. The codebase already admits this
      is insufficient (see the comment on rewriteSystemForNonClaudeCode in
      gateway_service.go: "仅前置追加 Claude Code 提示词无法通过检测").
      
      Effect: OAuth accounts served through /v1/chat/completions or /v1/responses
      were detected as third-party apps and bled plan quota with:
      
          Third-party apps now draw from your extra usage, not your plan limits.
      
      Fix:
        - apicompat.AnthropicRequest: add Metadata json.RawMessage so metadata
          survives the OpenAI->Anthropic->Marshal round trip; without it the
          downstream rewrite has no user_id to work with.
        - service: extract applyClaudeCodeOAuthMimicryToBody, a ParsedRequest-free
          variant of the /v1/messages mimicry pipeline
          (rewriteSystemForNonClaudeCode + normalizeClaudeOAuthRequestBody +
          metadata.user_id injection) so the OpenAI-compat forwarders can reuse it.
        - service: add buildOAuthMetadataUserIDFromBody + hashBodyForSessionSeed
          for the same reason (no ParsedRequest at the call site).
        - ForwardAsChatCompletions / ForwardAsResponses: replace the 3-line
          prompt-prepend with the full mimicry pipeline.
        - applyClaudeCodeMimicHeaders: set x-client-request-id per-request
          (real Claude CLI always does); missing/duplicated values are one more
          third-party fingerprint signal.
      
      No change to the native /v1/messages path: it already called the full
      pipeline, we only lift those helpers into a reusable function.
      
      Tests:
        - go build ./... passes
        - go test ./internal/service/... ./internal/pkg/apicompat/... passes
        - lsp_diagnostics clean on all touched files
        - pre-existing failures in internal/config are unrelated (env-sensitive
          tests that also fail on upstream main)
      b5467d61
    • keh4l's avatar
      chore(claude): bump mimicked CLI to 2.1.92 and extend anthropic-beta list · 57ff9796
      keh4l authored
      Align Claude Code mimicry constants with the latest real CLI traffic
      (see Parrot's src/transform/cc_mimicry.py). Anthropic now uses the full
      set of anthropic-beta tokens to decide whether a request counts as
      "official Claude Code"; requests missing tokens that real CLI ships
      today are demoted to third-party usage:
      
        Third-party apps now draw from your extra usage, not your plan limits.
      
      Changes:
        - claude/constants.go: add new beta tokens (prompt-caching-scope,
          effort, redact-thinking, context-management, extended-cache-ttl) and
          expose FullClaudeCodeMimicryBetas() for the OAuth mimicry path.
        - claude/constants.go: bump default User-Agent to claude-cli/2.1.92.
        - identity_service.go: bump defaultFingerprint User-Agent accordingly.
      
      No behavioral change for clients that already send a newer UA (fingerprint
      merge still prefers the incoming value).
      57ff9796
    • github-actions[bot]'s avatar
      d162604f
    • shaw's avatar
      fix: openai默认模型新增gpt5.5 · a4e329c1
      shaw authored
      a4e329c1
    • shaw's avatar
      fix(openai): preserve image outputs when text content serialization fails · ca204ddd
      shaw authored
      In reconstructResponseOutputFromSSE, text content Marshal/Unmarshal
      failure previously caused an early return that silently discarded
      already-extracted image_generation_call outputs. Now serialization
      errors are tolerated so image results still reach the client.
      ca204ddd
    • Wesley Liddick's avatar
      Merge pull request #1853 from gaoren002/fix/codex-image-generation-bridge · ff08f9d7
      Wesley Liddick authored
      fix(openai): 完善 Codex 在 Responses 链路下的图片生成兼容性
      ff08f9d7
    • Wesley Liddick's avatar
      Merge pull request #1850 from touwaeriol/feat/channel-insights · ac114738
      Wesley Liddick authored
      feat(monitor): channel monitor with available channels & feature flags
      ac114738
  2. 23 Apr, 2026 30 commits