11 Commits

  • feat: passthrough upstream response headers to clients
    CPA previously stripped ALL response headers from upstream AI provider
    APIs, preventing clients from seeing rate-limit info, request IDs,
    server-timing and other useful headers.
    
    Changes:
    - Add Headers field to Response and StreamResult structs
    - Add FilterUpstreamHeaders helper (hop-by-hop + security denylist)
    - Add WriteUpstreamHeaders helper (respects CPA-set headers)
    - ExecuteWithAuthManager/ExecuteCountWithAuthManager now return headers
    - ExecuteStreamWithAuthManager returns headers from initial connection
    - All 11 provider executors populate Response.Headers
    - All handler call sites write filtered upstream headers before response
    
    Filtered headers (not forwarded):
    - RFC 7230 hop-by-hop: Connection, Transfer-Encoding, Keep-Alive, etc.
    - Security: Set-Cookie
    - CPA-managed: Content-Length, Content-Encoding
  • feat(api): add non-streaming keep-alive support for idle timeout prevention
    - Introduced `StartNonStreamingKeepAlive` to emit periodic blank lines during non-streaming responses.
    - Added `nonstream-keepalive` configuration option in `SDKConfig`.
    - Updated handlers to utilize `StartNonStreamingKeepAlive` and ensure proper cleanup.
    - Extended config diff and tests to include `nonstream-keepalive` changes.
  • refactor(handlers): streamline error and data channel handling in streaming logic
    Improved consistency across OpenAI, Claude, and Gemini handlers by replacing initial `select` statement with a `for` loop for better readability and error-handling robustness.
  • Update sdk/api/handlers/claude/code_handlers.go
    thank you gemini
    
    Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
  • fix: flush Claude SSE chunks immediately to match OpenAI behavior
    - Write each SSE chunk directly to c.Writer and flush immediately
    - Remove buffered writer and ticker-based flushing that caused delayed output
    - Add 500ms timeout case for consistency with OpenAI/Gemini handlers
    - Clean up unused bufio import
    
    This fixes the 'not streaming' issue where small responses were held
    in the buffer until timeout/threshold was reached.
    
    Amp-Thread-ID: https://ampcode.com/threads/T-019b1186-164e-740c-96ab-856f64ee6bee
    Co-authored-by: Amp <amp@ampcode.com>
  • feat: Add Amp CLI integration with comprehensive documentation
    Add full Amp CLI support to enable routing AI model requests through the proxy
    while maintaining Amp-specific features like thread management, user info, and
    telemetry. Includes complete documentation and pull bot configuration.
    
    Features:
    - Modular architecture with RouteModule interface for clean integration
    - Reverse proxy for Amp management routes (thread/user/meta/ads/telemetry)
    - Provider-specific route aliases (/api/provider/{provider}/*)
    - Secret management with precedence: config > env > file
    - 5-minute secret caching to reduce file I/O
    - Automatic gzip decompression for responses
    - Proper connection cleanup to prevent leaks
    - Localhost-only restriction for management routes (configurable)
    - CORS protection for management endpoints
    
    Documentation:
    - Complete setup guide (USING_WITH_FACTORY_AND_AMP.md)
    - OAuth setup for OpenAI (ChatGPT Plus/Pro) and Anthropic (Claude Pro/Max)
    - Factory CLI config examples with all model variants
    - Amp CLI/IDE configuration examples
    - tmux setup for remote server deployment
    - Screenshots and diagrams
    
    Configuration:
    - Pull bot disabled for this repo (manual rebase workflow)
    - Config fields: AmpUpstreamURL, AmpUpstreamAPIKey, AmpRestrictManagementToLocalhost
    - Compatible with upstream DisableCooling and other features
    
    Technical details:
    - internal/api/modules/amp/: Complete Amp routing module
    - sdk/api/httpx/: HTTP utilities for gzip/transport
    - 94.6% test coverage with 34 comprehensive test cases
    - Clean integration minimizes merge conflict risk
    
    Security:
    - Management routes restricted to localhost by default
    - Configurable via amp-restrict-management-to-localhost
    - Prevents drive-by browser attacks on user data
    
    This provides a production-ready foundation for Amp CLI integration while
    maintaining clean separation from upstream code for easy rebasing.
    
    Amp-Thread-ID: https://ampcode.com/threads/T-9e2befc5-f969-41c6-890c-5b779d58cf18
  • fix: add Claude→Claude passthrough to prevent SSE event fragmentation
    When from==to (Claude→Claude scenario), directly forward SSE stream
    line-by-line without invoking TranslateStream. This preserves the
    multi-line SSE event structure (event:/data:/blank) and prevents
    JSON parsing errors caused by event fragmentation.
    
    Resolves: JSON parsing error when using Claude Code streaming responses
    
    fix: correct SSE event formatting in Handler layer
    
    Remove duplicate newline additions (\n\n) that were breaking SSE event format.
    The Executor layer already provides properly formatted SSE chunks with correct
    line endings, so the Handler should forward them as-is without modification.
    
    Changes:
    - Remove redundant \n\n addition after each chunk
    - Add len(chunk) > 0 check before writing
    - Format error messages as proper SSE events (event: error\ndata: {...}\n\n)
    - Add chunkIdx counter for future debugging needs
    
    This fixes JSON parsing errors caused by malformed SSE event streams.
    
    fix: update comments for clarity in SSE event forwarding
  • refactor(config): migrate to SDKConfig and streamline proxy handling
    - Replaced `config.Config` with `config.SDKConfig` across components for simpler configuration management.
    - Updated proxy setup functions and handlers to align with `SDKConfig` improvements.
    - Reorganized handler imports to match new SDK structure.