Skip to content

feat: add Anthropic /v1/messages compression support - #1

Open
futesat wants to merge 4 commits into
iafiscal1212:mainfrom
futesat:feat/anthropic-messages-compression-v2
Open

futesat wants to merge 4 commits into
iafiscal1212:mainfrom
futesat:feat/anthropic-messages-compression-v2

Conversation

@futesat

@futesat futesat commented Mar 30, 2026

Copy link
Copy Markdown

Problem

Claude Code and other Anthropic-native clients send requests to POST /v1/messages instead of POST /v1/chat/completions. The is_chat gate only matched the OpenAI path, so every Anthropic-format request bypassed the compressor entirely — compressor.calls stays at 0 and chat_requests never increments despite traffic flowing through the proxy.

Changes

server.py

  • Extend is_chat to also match paths ending in /messages
  • Compress the top-level "system" string (Anthropic-specific field, not present in OpenAI format) via _compress_text()

stats.py

  • Count /messages requests as chat_requests in summary()

Why it's safe

The messages[] array structure is identical between the two APIs, so compress_messages() works without any modification. The only Anthropic addition is the top-level "system" string, handled separately. Non-Anthropic traffic (/chat/completions) is completely unaffected.

Tested setup

Claude Code → aip-proxy (:4444) → LiteLLM (:4445) → GitHub Copilot API
Before After
compressor.calls 0 ✅ increments per request
chat_requests 0 ✅ increments per request
savings_pct 0% ✅ accumulates correctly
OpenAI /chat/completions traffic ✅ unaffected ✅ unaffected

Claude Code and other Anthropic-native clients send requests to
POST /v1/messages instead of POST /v1/chat/completions. The previous
is_chat gate only matched the OpenAI path, so every Anthropic-format
request bypassed the compressor entirely (0 savings, 0 chat_requests
in stats).

Changes:
- server.py: extend is_chat to also match paths ending in /messages,
  and compress the top-level "system" field (Anthropic-specific key
  not present in OpenAI format)
- stats.py: count /messages requests as chat_requests in summary()

The messages[] array structure is identical between the two APIs, so
compress_messages() works without modification. The only Anthropic
addition is the top-level "system" string, which is now piped through
_compress_text() separately.

Tested with Claude Code → aip-proxy → LiteLLM → GitHub Copilot API:
before this patch, compressor.calls stayed at 0; after, it correctly
tracks and compresses every chat request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for Anthropic's /messages endpoint and implements compression for the system prompt field. Feedback focuses on ensuring that compression statistics are correctly updated for the system field and standardizing the path-matching logic across the server and statistics modules to consistently handle query parameters and use precise matching.

Comment thread src/aip_proxy/server.py Outdated
Comment thread src/aip_proxy/server.py
Comment thread src/aip_proxy/stats.py
futesat and others added 3 commits March 30, 2026 17:07
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
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.

1 participant