Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
221 commits
Select commit Hold shift + click to select a range
fdeef48
feat(vertex): Add Prefix field to VertexCredentialStorage for per-fil…
dinhkarate Jan 29, 2026
14cb2b9
feat(vertex): add --vertex-import-prefix flag for model namespacing
dinhkarate Jan 29, 2026
07d6689
fix(claude): add interleaved-thinking beta header, AMP gzip error dec…
Blue-B Mar 7, 2026
5f58248
fix(claude): clamp max_tokens to model limit in normalizeClaudeBudget
Blue-B Mar 9, 2026
e166e56
Reconcile registry model states on auth changes
destinoantagonista-wq Mar 13, 2026
f09ed25
fix(auth): tighten registry model reconciliation
destinoantagonista-wq Mar 14, 2026
e08f68e
chore(auth): drop reconcile test file from pr
destinoantagonista-wq Mar 14, 2026
a337ecf
Merge branch 'router-for-me:main' into feat(vertex)/add-prefix-field
dinhkarate Mar 17, 2026
36efcc6
fix(vertex): include prefix in auth filename and validate at import
dinhkarate Mar 17, 2026
a34dfed
fix: preserve Claude thinking signatures in Codex translator
RaviTharuma Mar 24, 2026
76b53d6
fix: finalize pending thinking block before next summary part
RaviTharuma Mar 24, 2026
c31ae2f
fix: retain previously captured thinking signature on new summary part
RaviTharuma Mar 24, 2026
73b22ec
fix: omit empty signature field from thinking blocks
RaviTharuma Mar 25, 2026
66eb122
fix: clear stale thinking signature when no block is open
RaviTharuma Mar 25, 2026
5fc2bd3
fix: retain codex thinking signature until item done
RaviTharuma Mar 28, 2026
6fdff82
docs: add ProxyPal to 'Who is with us?' section
heyhuynhgiabuu Mar 31, 2026
e34b2b4
fix(gemini): clean tool schemas and eager_input_streaming
aikins01 Apr 1, 2026
ff7dbb5
test(amp): update tests to expect thinking blocks to pass through dur…
aikins01 Apr 1, 2026
f5e9f01
test(amp): update tests to expect thinking blocks to pass through dur…
aikins01 Apr 1, 2026
4045378
fix: 增强 Claude 反代检测对抗能力
Soein Apr 2, 2026
f65a9e4
feat: per-API-key model group routing and management API
BotHank-309 Apr 2, 2026
34339f6
Refactor websocket logging and error handling
hkfires Apr 2, 2026
94ff290
ci: add Docker build workflow with frontend integration
BotHank-309 Apr 2, 2026
4f8acec
refactor(logging): centralize websocket handshake recording
hkfires Apr 2, 2026
249f969
fix: Claude API 请求使用 utls Chrome TLS 指纹
Soein Apr 2, 2026
09e4800
feat(auth): add support for managing custom headers in auth files
luispater Apr 2, 2026
bb44671
fix: 修复反代检测对抗的 3 个问题
Soein Apr 2, 2026
da3a498
Keep Claude Code compatibility work low-risk and reviewable
mpfo0106 Apr 2, 2026
abc293c
Prevent malformed Responses SSE frames from breaking stream clients
davidwushi1145 Apr 2, 2026
108895f
Harden Responses SSE framing against partial chunk boundaries
davidwushi1145 Apr 2, 2026
a59e924
Merge pull request #2490 from router-for-me/logs
luispater Apr 2, 2026
e3eb048
Merge pull request #2489 from Soein/upstream-pr
luispater Apr 2, 2026
7170eee
Merge pull request #2454 from buddingnewinsights/add-proxypal-to-readme
luispater Apr 2, 2026
fcba912
Merge pull request #2492 from davidwushi1145/main
luispater Apr 2, 2026
3e78a8d
Merge branch 'main' into dev
luispater Apr 2, 2026
3171d52
docs: fix duplicated ProxyPal entry in README files
luispater Apr 2, 2026
7ee37ee
feat: add /healthz endpoint and test coverage for health check
luispater Apr 2, 2026
ab9ebea
Merge PR #2474
luispater Apr 2, 2026
058793c
feat(gitstore): honor configured branch and follow live remote default
Apr 2, 2026
9b5ce8c
Keep Claude builtin helpers aligned with the shared helper layout
mpfo0106 Apr 2, 2026
d2419ed
feat(executor): ensure default system message in QwenExecutor payload
luispater Apr 3, 2026
f63cf6f
Normalize Claude temperature for thinking
adamhelfgott Apr 3, 2026
8f0e66b
fix: repair websocket custom tool calls
lonr-6 Apr 3, 2026
b6c6379
fix: repair websocket custom tool calls
lonr-6 Apr 3, 2026
d1fd2c4
fix: repair websocket custom tool calls
lonr-6 Apr 3, 2026
06405f2
fix(security): enforce stricter localhost validation for GeminiCLIAPI…
luispater Apr 3, 2026
adb580b
feat(security): add configuration to toggle Gemini CLI endpoint access
luispater Apr 3, 2026
a824e7c
feat(models): add GPT-5.3, GPT-5.4, and GPT-5.4-mini with enhanced "t…
luispater Apr 3, 2026
29dba03
Comment out system message check in Qwen executor
Arronlong Apr 3, 2026
f389667
Merge pull request #2513 from lonr-6/codex/fix-ws-custom-tool-repair-v2
luispater Apr 3, 2026
42c062b
Merge pull request #2509 from adamhelfgott/fix-claude-thinking-temper…
luispater Apr 3, 2026
ae37ccf
Merge pull request #2520 from Arronlong/main
luispater Apr 3, 2026
754b126
fix(executor): remove commented-out code in QwenExecutor
luispater Apr 3, 2026
0e4f189
Merge pull request #1302 from dinhkarate/feat(vertex)/add-prefix-field
luispater Apr 3, 2026
f3ab8f4
chore: update antigravity UA version to 1.21.9
rensumo Apr 3, 2026
8430b28
Merge pull request #2526 from rensumo/main
luispater Apr 4, 2026
65e9e89
Fix missing `response.completed.usage` for late-usage OpenAI-compatib…
jamestut Apr 4, 2026
8d5e470
feat: dynamically fetch antigravity UA version from releases API
rensumo Apr 4, 2026
2ee938a
Merge pull request #2535 from rensumo/main
luispater Apr 4, 2026
c2d4137
feat(executor): enhance Qwen system message handling with strict inje…
luispater Apr 4, 2026
3774b56
feat(misc): add background updater for Antigravity version caching
luispater Apr 4, 2026
4ba1053
feat(docs): add Poixe AI sponsorship details to README files
luispater Apr 4, 2026
ada8e29
feat(api): enhance proxy resolution for API key-based auth
luispater Apr 4, 2026
22a1a24
feat(executor): add tests for preserving key order in cache control f…
luispater Apr 5, 2026
b0653ce
fix(amp): strip signature from tool_use blocks before forwarding to C…
aikins01 Apr 3, 2026
c1818f1
Merge pull request #1940 from Blue-B/fix/claude-interleaved-thinking-…
luispater Apr 6, 2026
ea43361
Merge pull request #2121 from destinoantagonista-wq/main
luispater Apr 6, 2026
000fcb1
Merge pull request #2298 from snoyiatk/feat/add-gitstore-branch
luispater Apr 6, 2026
6f58518
docs(readme): remove redundant GITSTORE_GIT_BRANCH description in REA…
luispater Apr 6, 2026
b851208
Merge pull request #2332 from RaviTharuma/fix/claude-thinking-signature
luispater Apr 6, 2026
c3f8dc3
Merge pull request #2491 from mpfo0106/feature/claude-code-safe-align…
luispater Apr 6, 2026
9eabdd0
Merge pull request #2522 from aikins01/fix/strip-tool-use-signature
luispater Apr 6, 2026
9f5bdfa
Merge pull request #2531 from jamestut/openai-vertex-token-usage-fix
luispater Apr 6, 2026
8b9dbe1
fix: record zero usage
Apr 6, 2026
0ea7680
fix(auth): honor disable-cooling and enrich no-auth errors
zilianpn Apr 6, 2026
163d683
feat: support socks5h scheme for proxy settings
berry-shake Apr 6, 2026
6a27bce
Merge pull request #2576 from zilianpn/fix/disable-cooling-auth-errors
luispater Apr 7, 2026
cad45ff
Merge pull request #2578 from LemonZuo/feat_socks5h
luispater Apr 7, 2026
8d5f40f
fix: extend model-group fallover to cover upstream 401/403
BotHank-309 Apr 7, 2026
c993a3b
fix: add 5xx errors to model-group fallover triggers
BotHank-309 Apr 7, 2026
2959eb3
feat: add allow-other-models toggle to APIKeyConfig
BotHank-309 Apr 7, 2026
bf4e030
chore: deploy updated management panel with tier-based model group UI
BotHank-309 Apr 7, 2026
d197852
docs: add cliproxyapi-config skill for agent-assisted configuration
BotHank-309 Apr 7, 2026
a5e066d
docs: restructure skill into standard skills/cliproxyapi-config/SKILL…
BotHank-309 Apr 7, 2026
5d6548e
ci: add multi-arch Docker build (amd64+arm64) and user deployment files
BotHank-309 Apr 7, 2026
43deb58
chore: simplify docker-compose to use MANAGEMENT_PASSWORD env var
BotHank-309 Apr 7, 2026
86c2e70
docs: rewrite README and add foragent.md for agent-assisted configura…
BotHank-309 Apr 7, 2026
9a8981d
feat: auto-seed config.yaml from template on first start
BotHank-309 Apr 7, 2026
62a57ed
fix: entrypoint auto-creates auths/logs dirs, no manual mkdir needed
BotHank-309 Apr 7, 2026
cf5b087
fix: disable panel auto-update in Docker image, handle dir/empty conf…
BotHank-309 Apr 7, 2026
89bc952
fix: use Anthropic reset header for exact quota cooldown, lock accoun…
BotHank-309 Apr 7, 2026
22cc155
fix: parse Retry-After header on 429 for openai-compat providers (Dou…
BotHank-309 Apr 7, 2026
cbd8092
fix: parse Doubao 429 reset timestamp from response body for exact qu…
BotHank-309 Apr 7, 2026
c8b7e2b
fix(executor): ensure empty stream completions use output_item.done a…
luispater Apr 7, 2026
91e7591
fix(executor): add transient 429 resource exhausted handling with ret…
luispater Apr 7, 2026
fcc59d6
fix(translator): add unit tests to validate output_item.done fallback…
luispater Apr 7, 2026
d1f6224
Merge pull request #2569 from LucasInsight/fix/record-zero-usage
luispater Apr 8, 2026
d390b95
fix(tests): update test cases
hkfires Apr 8, 2026
f5aa68e
chore: add workflow to prevent AGENTS.md modifications in pull requests
luispater Apr 8, 2026
70efd4e
chore: add workflow to retarget main PRs to dev automatically
luispater Apr 8, 2026
c698ac5
fix: break Doubao RequestBurstTooFast retry storm
BotHank-309 Apr 8, 2026
8fbe947
fix: reduce doubaoBurstCooldown from 60s to 15s
BotHank-309 Apr 8, 2026
12b9671
Merge pull request #2592 from router-for-me/tests
luispater Apr 8, 2026
dfa1889
fix: unify auth-blocked errors into model_cooldown (429)
BotHank-309 Apr 8, 2026
343a2fc
docs: update AGENTS.md for improved clarity and detail in commands an…
hkfires Apr 8, 2026
6264396
merge: sync upstream router-for-me/CLIProxyAPI
BotHank-309 Apr 8, 2026
47cbe9e
Merge branch 'sync-upstream-2026-04-08'
BotHank-309 Apr 8, 2026
b5f37fe
chore: add mempalace config for project memory indexing
BotHank-309 Apr 8, 2026
69b950d
fix(executor): fix OAuth extra usage detection by Anthropic API
wykk-12138 Apr 8, 2026
d54f816
fix(executor): update Qwen user agent and enhance header configuration
luispater Apr 8, 2026
941334d
fix(auth): handle OAuth model alias in retry logic and refine Qwen qu…
luispater Apr 8, 2026
ad8e396
fix(auth): add retry logic for 429 status with Retry-After and improv…
luispater Apr 8, 2026
613fe67
fix(executor): inject full Claude Code system prompt blocks with prop…
wykk-12138 Apr 9, 2026
f6f4640
fix: use sjson to build system blocks, avoid raw newlines in JSON
wykk-12138 Apr 9, 2026
8783caf
fix: buildTextBlock cache_control sjson path issue
wykk-12138 Apr 9, 2026
9e0ab4d
fix: build cache_control JSON manually to avoid sjson map marshaling
wykk-12138 Apr 9, 2026
e2e3c7d
fix: remove invalid org scope and match Claude Code block layout
wykk-12138 Apr 9, 2026
54f22fb
fix: eliminate remaining auth_unavailable (500) from scheduler/select…
BotHank-309 Apr 9, 2026
6ad18cd
refactor: extract makeCooldownError helper, remove dead cooldownCount
BotHank-309 Apr 9, 2026
7cdf8e9
fix(claude): sanitize forwarded third-party prompts for OAuth cloaking
wykk-12138 Apr 9, 2026
f0c20e8
fix(claude): remove invalid cache_control scope from static system block
wykk-12138 Apr 9, 2026
7e8e222
fix(claude): reduce forwarded OAuth prompt to minimal tool reminder
wykk-12138 Apr 9, 2026
b20b772
fix: reject usage:null in stream parser to prevent zero-token recording
BotHank-309 Apr 9, 2026
5e81b65
fix(auth, executor): normalize Qwen base URL, adjust RefreshLead dura…
luispater Apr 9, 2026
e8d1b79
fix(claude): remap OAuth tool names to Claude Code style to avoid thi…
wykk-12138 Apr 9, 2026
730809d
fix(auth): preserve and restore ready view cursors during index rebuilds
luispater Apr 9, 2026
1dba2d0
fix(handlers): add base URL validation and improve API key deletion t…
luispater Apr 9, 2026
cf24958
feat(antigravity): configurable signature cache with bypass-mode vali…
sususu98 Mar 31, 2026
38f0ae5
docs(antigravity): document signature validation spec alignment
sususu98 Mar 31, 2026
30e94b6
fix(antigravity): refine 429 handling and credits fallback
ZTXBOSS666 Apr 9, 2026
39dc455
Merge pull request #2412 from sususu98/feat/signature-cache-toggle
luispater Apr 9, 2026
ac36119
fix(claude): preserve OAuth tool renames when filtering tools
wykk-12138 Apr 9, 2026
f780c28
fix(claude): map question/skill to TitleCase instead of removing them
wykk-12138 Apr 9, 2026
96056d0
Merge remote-tracking branch 'upstream/main' into fix/oauth-extra-usa…
wykk-12138 Apr 9, 2026
0f45d89
fix(claude): address PR review feedback for OAuth cloaking
wykk-12138 Apr 9, 2026
f32c8c9
fix(handlers): update listener to bind on all interfaces instead of l…
luispater Apr 9, 2026
b2c0cdf
Merge pull request #2621 from wykk-12138/fix/oauth-extra-usage-detection
luispater Apr 10, 2026
d801393
feat(antigravity): prefer prod URL as first priority
sususu98 Apr 10, 2026
2a97037
Merge pull request #2670 from sususu98/feat/antigravity-prefer-prod-url
hkfires Apr 10, 2026
65ce863
fix(executor): implement immediate retry with token refresh on 429 fo…
luispater Apr 10, 2026
5ab9afa
fix(executor): handle OAuth tool name remapping with rename detection…
luispater Apr 10, 2026
5bb69fa
docs: refine CLIproxyAPI Quota Inspector description in all README lo…
AllenReder Apr 11, 2026
c585caa
docs: fix CLIProxyAPI Quota Inspector naming and link casing
AllenReder Apr 11, 2026
828df80
refactor(executor): remove immediate retry with token refresh on 429 …
luispater Apr 11, 2026
f135fdf
docs: clarify codex quota window wording in README locales
AllenReder Apr 11, 2026
9ded75d
Merge pull request #2702 from AllenReder/docs/add-quota-inspector
luispater Apr 11, 2026
0ab1f54
fix(executor): handle 429 Retry-After header and default retry logic …
luispater Apr 11, 2026
727221d
fix(antigravity): allow 32MB bypass signatures
sususu98 Apr 11, 2026
8ed290c
fix(antigravity): reduce bypass mode log noise
sususu98 Apr 11, 2026
a583463
feat(auth): implement auto-refresh loop for managing auth token schedule
luispater Apr 11, 2026
65158cc
fix(antigravity): drop redacted thinking blocks with empty text
sususu98 Apr 12, 2026
f5ed5c7
fix(antigravity): skip full schema cleanup for empty tool requests
sususu98 Apr 11, 2026
6c0a1ef
refactor(auth): simplify auth directory scanning and improve JSON pro…
luispater Apr 12, 2026
5bfaf80
feat(auth): add configurable worker pool size for auto-refresh loop
luispater Apr 12, 2026
26fd3ef
Merge pull request #2715 from sususu98/pr/antigravity-32mb-bypass-sig…
sususu98 Apr 12, 2026
1dc3018
Merge pull request #2716 from sususu98/pr/antigravity-bypass-log-noise
sususu98 Apr 12, 2026
61e0447
Merge pull request #2723 from sususu98/fix/drop-redacted-thinking-blocks
sususu98 Apr 12, 2026
c4459c4
Merge pull request #2724 from sususu98/fix/skip-schema-cleanup-empty-…
sususu98 Apr 12, 2026
278a898
fix(antigravity): strip thinking blocks with empty signatures instead…
sususu98 Apr 13, 2026
41ae2c8
fix(antigravity): discard thinking blocks with non-Claude-format sign…
sususu98 Apr 13, 2026
10b55b5
fix(antigravity): use E-prefixed fake signature in strict bypass test
sususu98 Apr 14, 2026
8fecd62
fix(antigravity): cap maxOutputTokens using registry max_completion_t…
sususu98 Apr 15, 2026
8fac296
chore: remove Qwen support from SDK and internal components
luispater Apr 15, 2026
3dea1da
Merge pull request #2782 from sususu98/fix/strip-invalid-signature-th…
luispater Apr 15, 2026
f56cf42
Merge pull request #2800 from sususu98/fix/antigravity-max-output-tok…
luispater Apr 15, 2026
a4c1e32
chore(models): remove outdated GPT-5 and related model entries from r…
luispater Apr 15, 2026
7c24d54
feat(session-affinity): add session-sticky routing for multi-account …
sususu98 Apr 14, 2026
d4a6a5a
fix(antigravity): strip billing header from system instruction before…
sususu98 Apr 14, 2026
d1508ca
Merge pull request #2816 from sususu98/feat/session-affinity
luispater Apr 15, 2026
ba454db
Merge pull request #2817 from sususu98/fix/antigravity-strip-billing-…
luispater Apr 15, 2026
1267fdd
fix(docker-build): improve argument handling and error messaging for …
hkfires Apr 16, 2026
8f9e662
fix(util): forward custom Host header to upstream
muzhi1991 Apr 16, 2026
7b03f04
fix(handlers): include execution session metadata and skip idempotenc…
luispater Apr 16, 2026
d949921
feat(auth): add proxy URL override support to auth constructors and e…
luispater Apr 16, 2026
f5dc648
chore: remove iFlow-related modules and dependencies
luispater Apr 16, 2026
5dcca69
feat(models): add Claude Opus 4.7 model entry to registry JSON
luispater Apr 16, 2026
d9a3b3e
fix(tests): update model lookup references and enhance Claude executo…
hkfires Apr 17, 2026
da43f63
fix(tests): update Gemini family test case numbers for consistency
hkfires Apr 17, 2026
eba561b
fix(util): also keep Host in header map for synthetic requests
muzhi1991 Apr 17, 2026
d7caae7
chore: sync upstream main (add claude-opus-4-7, remove iFlow/Qwen, se…
BotHank-309 Apr 17, 2026
4479392
fix(test): remove unused strings import in thinking_conversion_test.go
BotHank-309 Apr 17, 2026
894baad
feat(api): integrate auth index into key retrieval endpoints for Gemi…
LTbinglingfeng Apr 18, 2026
c26936e
fix(management): stabilize auth-index mapping
LTbinglingfeng Apr 18, 2026
a64141a
fix(tests): remove obsolete config_auth_index_test file
LTbinglingfeng Apr 18, 2026
c6baa64
Merge pull request #2892 from router-for-me/fix-provider
LTbinglingfeng Apr 18, 2026
86c856f
feat(translator): add partial and full image generation support in Co…
luispater Apr 18, 2026
f4eb161
fix(executor): drop obsolete context-1m-2025-08-07 beta header (fixes…
octo-patch Apr 19, 2026
e05abec
Merge pull request #2898 from octo-patch/fix/issue-2866-remove-obsole…
luispater Apr 19, 2026
8f4a4ea
feat(docs): add VisionCoder sponsorship details and optimize external…
luispater Apr 19, 2026
01f9ecf
fix(executor): disable 1M context beta for Claude OAuth requests
BotHank-309 Apr 20, 2026
81a396c
Merge remote-tracking branch 'upstream/main'
BotHank-309 Apr 20, 2026
73b7f84
feat(warmup): proactive OAuth session-window warmup scheduler
BotHank-309 Apr 20, 2026
710e73f
feat(management): expose warmup REST endpoints + live reload
BotHank-309 Apr 20, 2026
e6866ff
feat(auth): add refresh backoff for ineffective token updates
luispater Apr 20, 2026
35fcdeb
chore(panel): rebuild management.html with OAuth warmup page
BotHank-309 Apr 20, 2026
dd54b4e
fix(warmup): call provider executor directly to bypass model-registry…
BotHank-309 Apr 20, 2026
c4604dc
tweak(warmup): slightly beefier payload (max_tokens=16, content="ping")
BotHank-309 Apr 20, 2026
77c2992
fix(thinking): strip unsigned thinking blocks before forwarding to Cl…
BotHank-309 Apr 21, 2026
4a1e79e
test(thinking): integration coverage for ClaudeExecutor sanitize wiring
BotHank-309 Apr 21, 2026
bb8408c
fix(codex): backfill streaming response output
stringer07 Apr 21, 2026
b6781d6
perf(codex): avoid repeated output patch writes
stringer07 Apr 21, 2026
e1c19c7
docs(deploy): shadow-first deployment runbook
BotHank-309 Apr 21, 2026
1716a84
feat(api): add support for `HEAD` requests to `/healthz` endpoint
luispater Apr 21, 2026
3444820
Merge pull request #2939 from stringer07/fix/codex-stream-output-back…
luispater Apr 21, 2026
8ced7a5
Merge pull request #2834 from muzhi1991/fix/openai-compat-host-header
luispater Apr 21, 2026
4fc2c61
feat(models): add Kimi K2.6 model entry to registry JSON
luispater Apr 21, 2026
39c6fda
Merge branch 'upstream-main' into main
BotHank-309 Apr 22, 2026
5871106
fix(thinking): strip Fernet-prefixed signatures before forwarding to …
BotHank-309 Apr 22, 2026
ac71318
fix(auth): harden Claude OAuth refresh with retry + visible logs
BotHank-309 Apr 22, 2026
e935196
feat(models): add hardcoded GPT-Image-2 model support in Codex
luispater Apr 22, 2026
fd71960
fix(handlers): remove handling of unsupported `n` parameter in OpenAI…
luispater Apr 22, 2026
a188159
fix(handlers): remove references to unsupported `n` parameter in Open…
luispater Apr 22, 2026
2b62e44
fix(auth): log persist errors instead of silently discarding them
BotHank-309 Apr 23, 2026
ce6b47c
Merge remote-tracking branch 'upstream/main'
BotHank-309 Apr 23, 2026
cdba083
feat(config): add per-instance oauth refresh suppression
BotHank-309 Apr 27, 2026
b6d1f84
feat(auth): support runtime refresh suppression
BotHank-309 Apr 27, 2026
23e7ecd
feat(watcher): suppress oauth refresh per instance
BotHank-309 Apr 27, 2026
042d0c0
test(auth): cover refresh suppression scheduling
BotHank-309 Apr 27, 2026
6c36919
docs(warmup): clarify shadow provider allowlist behavior
BotHank-309 Apr 27, 2026
3892b9c
feat(runbook): auto-remove shadow after primary stability
BotHank-309 Apr 27, 2026
fd98dea
fix(runbook): bound primary stability probes and gate optional manage…
BotHank-309 Apr 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ logs/*
conv/*
config.yaml

# Frontend checkout dir (used by CI to build panel, excluded from image)
_frontend/*

# Development/editor
bin/*
.vscode/*
Expand Down
6 changes: 6 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CLI_PROXY_IMAGE=cliproxyapi:latest
MANAGEMENT_PASSWORD=test123
PORT=8318
CLI_PROXY_CONFIG_PATH=/tmp/cpa-test/config.yaml
CLI_PROXY_AUTH_PATH=/tmp/cpa-test/auths
CLI_PROXY_LOG_PATH=/tmp/cpa-test/logs
81 changes: 81 additions & 0 deletions .github/workflows/agents-md-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: agents-md-guard

on:
pull_request_target:
types:
- opened
- synchronize
- reopened

permissions:
contents: read
issues: write
pull-requests: write

jobs:
close-when-agents-md-changed:
runs-on: ubuntu-latest
steps:
- name: Detect AGENTS.md changes and close PR
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.pull_request.number;
const { owner, repo } = context.repo;

const files = await github.paginate(github.rest.pulls.listFiles, {
owner,
repo,
pull_number: prNumber,
per_page: 100,
});

const touchesAgentsMd = (path) =>
typeof path === "string" &&
(path === "AGENTS.md" || path.endsWith("/AGENTS.md"));

const touched = files.filter(
(f) => touchesAgentsMd(f.filename) || touchesAgentsMd(f.previous_filename),
);

if (touched.length === 0) {
core.info("No AGENTS.md changes detected.");
return;
}

const changedList = touched
.map((f) =>
f.previous_filename && f.previous_filename !== f.filename
? `- ${f.previous_filename} -> ${f.filename}`
: `- ${f.filename}`,
)
.join("\n");

const body = [
"This repository does not allow modifying `AGENTS.md` in pull requests.",
"",
"Detected changes:",
changedList,
"",
"Please revert these changes and open a new PR without touching `AGENTS.md`.",
].join("\n");

try {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body,
});
} catch (error) {
core.warning(`Failed to comment on PR #${prNumber}: ${error.message}`);
}

await github.rest.pulls.update({
owner,
repo,
pull_number: prNumber,
state: "closed",
});

core.setFailed("PR modifies AGENTS.md");
73 changes: 73 additions & 0 deletions .github/workflows/auto-retarget-main-pr-to-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: auto-retarget-main-pr-to-dev

on:
pull_request_target:
types:
- opened
- reopened
- edited
branches:
- main

permissions:
contents: read
issues: write
pull-requests: write

jobs:
retarget:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- name: Retarget PR base to dev
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const prNumber = pr.number;
const { owner, repo } = context.repo;

const baseRef = pr.base?.ref;
const headRef = pr.head?.ref;
const desiredBase = "dev";

if (baseRef !== "main") {
core.info(`PR #${prNumber} base is ${baseRef}; nothing to do.`);
return;
}

if (headRef === desiredBase) {
core.info(`PR #${prNumber} is ${desiredBase} -> main; skipping retarget.`);
return;
}

core.info(`Retargeting PR #${prNumber} base from ${baseRef} to ${desiredBase}.`);

try {
await github.rest.pulls.update({
owner,
repo,
pull_number: prNumber,
base: desiredBase,
});
} catch (error) {
core.setFailed(`Failed to retarget PR #${prNumber} to ${desiredBase}: ${error.message}`);
return;
}

const body = [
`This pull request targeted \`${baseRef}\`.`,
"",
`The base branch has been automatically changed to \`${desiredBase}\`.`,
].join("\n");

try {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body,
});
} catch (error) {
core.warning(`Failed to comment on PR #${prNumber}: ${error.message}`);
}
85 changes: 85 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Docker Build & Push

on:
push:
branches: [main]
repository_dispatch:
types: [frontend-updated]
workflow_dispatch:

env:
IMAGE: ghcr.io/minervacap2022/cliproxyapi

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout backend
uses: actions/checkout@v4

- name: Checkout frontend
uses: actions/checkout@v4
with:
repository: minervacap2022/Cli-Proxy-API-Management-Center
path: _frontend

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
cache-dependency-path: _frontend/package-lock.json

- name: Build frontend
run: |
cd _frontend
npm ci
npm run build
mkdir -p ../panel
cp dist/index.html ../panel/management.html

- name: Fetch models catalog
run: |
git fetch --depth 1 https://github.com/router-for-me/models.git main
git show FETCH_HEAD:models.json > internal/registry/models/models.json
continue-on-error: true

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set image metadata
id: meta
run: |
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "tags=${{ env.IMAGE }}:latest,${{ env.IMAGE }}:${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT

- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push (amd64 + arm64)
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
build-args: |
VERSION=${{ steps.meta.outputs.version }}
COMMIT=${{ github.sha }}
BUILD_DATE=${{ steps.meta.outputs.build_date }}
cache-from: type=gha
cache-to: type=gha,mode=max
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,23 @@ auths/*

# Documentation
docs/*
!docs/deployment.yaml
AGENTS.md
CLAUDE.md
GEMINI.md

# Tooling metadata
.vscode/*
.worktrees/
.codex/*
.claude/*
.gemini/*
.serena/*
.agent/*
.agents/*
.agents/*
.opencode/*
.idea/*
.beads/*
.bmad/*
_bmad/*
_bmad-output/*
Expand Down
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AGENTS.md

Go 1.26+ proxy server providing OpenAI/Gemini/Claude/Codex compatible APIs with OAuth and round-robin load balancing.

## Repository
- GitHub: https://github.com/router-for-me/CLIProxyAPI

## Commands
```bash
gofmt -w . # Format (required after Go changes)
go build -o cli-proxy-api ./cmd/server # Build
go run ./cmd/server # Run dev server
go test ./... # Run all tests
go test -v -run TestName ./path/to/pkg # Run single test
go build -o test-output ./cmd/server && rm test-output # Verify compile (REQUIRED after changes)
```
- Common flags: `--config <path>`, `--tui`, `--standalone`, `--local-model`, `--no-browser`, `--oauth-callback-port <port>`

## Config
- Default config: `config.yaml` (template: `config.example.yaml`)
- `.env` is auto-loaded from the working directory
- Auth material defaults under `auths/`
- Storage backends: file-based default; optional Postgres/git/object store (`PGSTORE_*`, `GITSTORE_*`, `OBJECTSTORE_*`)

## Architecture
- `cmd/server/` — Server entrypoint
- `internal/api/` — Gin HTTP API (routes, middleware, modules)
- `internal/api/modules/amp/` — Amp integration (Amp-style routes + reverse proxy)
- `internal/thinking/` — Main thinking/reasoning pipeline. `ApplyThinking()` (apply.go) parses suffixes (`suffix.go`, suffix overrides body), normalizes config to canonical `ThinkingConfig` (`types.go`), normalizes and validates centrally (`validate.go`/`convert.go`), then applies provider-specific output via `ProviderApplier`. Do not break this "canonical representation → per-provider translation" architecture.
- `internal/runtime/executor/` — Per-provider runtime executors (incl. Codex WebSocket)
- `internal/translator/` — Provider protocol translators (and shared `common`)
- `internal/registry/` — Model registry + remote updater (`StartModelsUpdater`); `--local-model` disables remote updates
- `internal/store/` — Storage implementations and secret resolution
- `internal/managementasset/` — Config snapshots and management assets
- `internal/cache/` — Request signature caching
- `internal/watcher/` — Config hot-reload and watchers
- `internal/wsrelay/` — WebSocket relay sessions
- `internal/usage/` — Usage and token accounting
- `internal/tui/` — Bubbletea terminal UI (`--tui`, `--standalone`)
- `sdk/cliproxy/` — Embeddable SDK entry (service/builder/watchers/pipeline)
- `test/` — Cross-module integration tests

## Code Conventions
- Keep changes small and simple (KISS)
- Comments in English only
- If editing code that already contains non-English comments, translate them to English (don’t add new non-English comments)
- For user-visible strings, keep the existing language used in that file/area
- New Markdown docs should be in English unless the file is explicitly language-specific (e.g. `README_CN.md`)
- As a rule, do not make standalone changes to `internal/translator/`. You may modify it only as part of broader changes elsewhere.
- If a task requires changing only `internal/translator/`, run `gh repo view --json viewerPermission -q .viewerPermission` to confirm you have `WRITE`, `MAINTAIN`, or `ADMIN`. If you do, you may proceed; otherwise, file a GitHub issue including the goal, rationale, and the intended implementation code, then stop further work.
- `internal/runtime/executor/` should contain executors and their unit tests only. Place any helper/supporting files under `internal/runtime/executor/helps/`.
- Follow `gofmt`; keep imports goimports-style; wrap errors with context where helpful
- Do not use `log.Fatal`/`log.Fatalf` (terminates the process); prefer returning errors and logging via logrus
- Shadowed variables: use method suffix (`errStart := server.Start()`)
- Wrap defer errors: `defer func() { if err := f.Close(); err != nil { log.Errorf(...) } }()`
- Use logrus structured logging; avoid leaking secrets/tokens in logs
- Avoid panics in HTTP handlers; prefer logged errors and meaningful HTTP status codes
- Timeouts are allowed only during credential acquisition; after an upstream connection is established, do not set timeouts for any subsequent network behavior. Intentional exceptions that must remain allowed are the Codex websocket liveness deadlines in `internal/runtime/executor/codex_websockets_executor.go`, the wsrelay session deadlines in `internal/wsrelay/session.go`, the management APICall timeout in `internal/api/handlers/management/api_tools.go`, and the `cmd/fetch_antigravity_models` utility timeouts
27 changes: 22 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,42 @@ COPY . .
ARG VERSION=dev
ARG COMMIT=none
ARG BUILD_DATE=unknown
ARG TARGETARCH
ARG TARGETOS=linux

RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w -X 'main.Version=${VERSION}' -X 'main.Commit=${COMMIT}' -X 'main.BuildDate=${BUILD_DATE}'" -o ./CLIProxyAPI ./cmd/server/
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -ldflags="-s -w \
-X 'main.Version=${VERSION}' \
-X 'main.Commit=${COMMIT}' \
-X 'main.BuildDate=${BUILD_DATE}'" \
-o ./CLIProxyAPI ./cmd/server/

FROM alpine:3.22.0

RUN apk add --no-cache tzdata
RUN apk add --no-cache tzdata ca-certificates

RUN mkdir /CLIProxyAPI
RUN mkdir -p /CLIProxyAPI/panel

COPY --from=builder ./app/CLIProxyAPI /CLIProxyAPI/CLIProxyAPI
COPY --from=builder /app/CLIProxyAPI /CLIProxyAPI/CLIProxyAPI

COPY config.example.yaml /CLIProxyAPI/config.example.yaml
COPY config.template.yaml /CLIProxyAPI/config.template.yaml
COPY docker-entrypoint.sh /CLIProxyAPI/docker-entrypoint.sh

# Management panel — built by CI from Cli-Proxy-API-Management-Center and
# placed at panel/management.html before docker build context is sent.
# If absent the server auto-downloads from GitHub on first start.
COPY panel/ /CLIProxyAPI/panel/

WORKDIR /CLIProxyAPI

RUN chmod +x docker-entrypoint.sh

EXPOSE 8317

ENV TZ=Asia/Shanghai
ENV MANAGEMENT_STATIC_PATH=/CLIProxyAPI/panel/management.html

RUN cp /usr/share/zoneinfo/${TZ} /etc/localtime && echo "${TZ}" > /etc/timezone

CMD ["./CLIProxyAPI"]
ENTRYPOINT ["./docker-entrypoint.sh"]
Loading
Loading