Skip to content

feat: embed CLIProxyAPIPlus, eliminate vibeproxy dependency#3

Merged
johannhipp merged 5 commits into
masterfrom
pr/2
Apr 13, 2026
Merged

feat: embed CLIProxyAPIPlus, eliminate vibeproxy dependency#3
johannhipp merged 5 commits into
masterfrom
pr/2

Conversation

@johannhipp
Copy link
Copy Markdown
Owner

Embeds CLIProxyAPIPlus directly into amp-proxy via cliproxy.Builder/Service on a localhost ephemeral port, eliminating the need for a separate vibeproxy process.

Changes

  • gateway.go — new ProviderGateway that manages the embedded CLIProxyAPIPlus service (config generation, startup, readiness probing, shared transport, graceful shutdown)
  • proxy.go — simplified routing: provider requests → embedded gateway, everything else → ampcode.com reverse proxy. Added stripCacheControl, nil-gateway guard
  • config.go — new AppConfig with optional YAML config, env var expansion, model remap support, layered defaults
  • auth.gologin/logout/status CLI subcommands with single providerDefs source of truth
  • main.go — subcommand dispatch (serve/login/logout/status/version), extracted loadConfigFromArgs helper
  • remap.go — uses config-driven ModelRemapConfig instead of hardcoded mappings, routes through gateway transport
  • ARCHITECTURE.md — updated to reflect actual implementation

Key design decisions

  • Zero config for common use — clone, build, amp-proxy login claude, amp-proxy serve
  • gin accepted as transitive dep — SDK does not expose a gin-free embedding path; acceptable tradeoff (~10MB, localhost-only)
  • Shared transport — gateway reverse proxy and remap direct calls share the same http.Transport (no total timeout for SSE streams)
  • Reuses existing tokens~/.cli-proxy-api/ works as-is for users migrating from vibeproxy

Johann Hipp 🐻 and others added 5 commits March 27, 2026 15:05
Single binary with built-in provider auth. No vibeproxy needed.

- Embed CLIProxyAPIPlus as in-process provider gateway on ephemeral loopback port
- Add CLI subcommands: serve, login, logout, status, version
- Add optional YAML config with env var expansion and sensible defaults
- Move hard-coded model remappings to config (with same defaults)
- Add cache_control stripping middleware (was in vibeproxy's ThinkingProxy)
- Add install script (bin/install.sh) for macOS and Linux
- Reuse existing ~/.cli-proxy-api/ tokens from vibeproxy
- Default bind to 127.0.0.1 (was 0.0.0.0)
- All 12 tests pass, live-tested on separate port

Amp-Thread-ID: https://ampcode.com/threads/T-019d30f2-a7d6-73cd-ae34-2a8dabb213d8
Co-authored-by: Amp <[email protected]>
- gateway: fix TOCTOU port race (documented), racy startup error detection
  (concurrent select), writeConfig uses yaml.Marshal with correct SDK keys
  (api-key-entries, populated ampcode upstream-url), shared transport for
  remap path (fixes 5min streaming timeout), log os.Remove errors
- proxy: nil gateway guard returns 503, stripCacheControl handles chunked bodies
- remap: readiness check, use gateway.Do() with shared transport, consistent
  error format matching gateway
- config: AMP_PROXY_CONFIG always returned when set (no silent fallthrough),
  remove double-fallback in FindModelRemap
- main: remove dead configPath/debug globals, extract loadConfigFromArgs helper
- auth: single providerDefs source of truth, derived maps via init()
- proxy_test: remove dead newTestConfig function
- ARCHITECTURE.md: match implementation (Builder/Service, correct code example,
  actual package structure, no stale coreauth references)

Amp-Thread-ID: https://ampcode.com/threads/T-019d75d5-5f9e-776c-9b7d-5bc0b02b7899
Co-authored-by: Amp <[email protected]>
Stripping cache_control prevents 400 errors on some OAuth routes but
disables Anthropic prompt caching, which can significantly increase
token usage in long sessions. Users can now set strip_cache_control:
false to preserve cache markers and enable prompt caching.

Amp-Thread-ID: https://ampcode.com/threads/T-019d75d5-5f9e-776c-9b7d-5bc0b02b7899
Co-authored-by: Amp <[email protected]>
… casing

Amp's agent modes (smart, rush, etc.) check tool names case-sensitively
via includeTools.includes(). Some models return lowercase names like "bash"
but Amp expects "Bash", causing "tool X is not allowed for Y mode" errors.

Adds a streaming response writer that rewrites "name":"bash" → "name":"Bash"
(and read→Read, grep→Grep, task→Task) in SSE chunks flowing back from the
provider gateway.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@johannhipp johannhipp merged commit 14d65ad into master Apr 13, 2026
1 check passed
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