Fix Gemini routing, Claude aliases, and server stability (Multi-stage build)
Browse files- Dockerfile +43 -0
- auth/antigravity-christoph_buchmueller_gmail_com.json +1 -0
- auth/antigravity-citrondon666_gmail_com.json +1 -0
- auth/antigravity-claracouve342_gmail_com.json +1 -0
- auth/antigravity-diesmalwichtigsamuel_gmail_com.json +1 -0
- auth/antigravity-hintermaier_pascal_gmail_com.json +1 -0
- auth/antigravity-hintermaierpascal0_gmail_com.json +1 -0
- auth/antigravity-pascal_hintermaier_gmail_com.json +1 -0
- auth/antigravity-rave_riotofficial_gmail_com.json +1 -0
- auth/citrondon666@gmail.com-gen-lang-client-0171616182.json +1 -0
- auth/claracouve342@gmail.com-bluebirdhub-clara-2025.json +1 -0
- auth/hintermaier.pascal@gmail.com-gen-lang-client-0084172363.json +1 -0
- auth/hintermaierpascal0@gmail.com-gen-lang-client-0476252734.json +1 -0
- auth/kiro-aws-thewolfofvaalstreet@gmail.com.json +1 -0
- auth/kiro-imported.json +11 -0
- auth/pascal.hintermaier@gmail.com-uniqueuniquesfromuniquewa.json +1 -0
- auth/qwen-qwen-1767306169376.json +1 -0
- auth/qwen-qwen-1768083358627.json +1 -0
- auth/rave.riotofficial@gmail.com-gen-lang-client-0808033057.json +1 -0
- config.yaml +40 -1
- internal/api/handlers/management/config_basic.go +24 -0
- internal/api/modules/amp/routes.go +1 -0
- internal/api/server.go +23 -13
- internal/registry/model_definitions.go +60 -0
- internal/runtime/executor/claude_executor.go +2 -2
- internal/runtime/executor/codex_executor.go +2 -2
- internal/runtime/executor/gemini_cli_executor.go +2 -2
- internal/runtime/executor/gemini_executor.go +4 -8
- internal/runtime/executor/gemini_vertex_executor.go +8 -8
- internal/runtime/executor/openai_compat_executor.go +2 -2
- internal/runtime/executor/qwen_executor.go +2 -2
- static/management.html +0 -0
Dockerfile
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Build stage
|
| 2 |
+
FROM golang:1.23-alpine AS builder
|
| 3 |
+
|
| 4 |
+
# Install build dependencies
|
| 5 |
+
RUN apk add --no-cache git
|
| 6 |
+
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
# Copy go.mod and go.sum and download dependencies
|
| 10 |
+
COPY go.mod go.sum ./
|
| 11 |
+
RUN go mod download
|
| 12 |
+
|
| 13 |
+
# Copy the entire source code
|
| 14 |
+
COPY . .
|
| 15 |
+
|
| 16 |
+
# Build the binary
|
| 17 |
+
RUN go build -o main ./cmd/server
|
| 18 |
+
|
| 19 |
+
# Final stage
|
| 20 |
+
FROM debian:stable-slim
|
| 21 |
+
|
| 22 |
+
# Install CA certificates for HTTPS requests
|
| 23 |
+
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
|
| 24 |
+
|
| 25 |
+
# Create a non-root user
|
| 26 |
+
RUN useradd -m -u 1000 user
|
| 27 |
+
USER user
|
| 28 |
+
WORKDIR /app
|
| 29 |
+
|
| 30 |
+
# Copy the binary and necessary runtime files
|
| 31 |
+
COPY --from=builder --chown=user /app/main /app/cli-proxy-api-plus
|
| 32 |
+
COPY --chown=user config.yaml /app/config.yaml
|
| 33 |
+
COPY --chown=user static /app/static
|
| 34 |
+
COPY --chown=user auth /app/auth
|
| 35 |
+
|
| 36 |
+
# Ensure the binary is executable
|
| 37 |
+
RUN chmod +x /app/cli-proxy-api-plus
|
| 38 |
+
|
| 39 |
+
# CLIProxyAPI runs on port 7860 for HF Spaces
|
| 40 |
+
EXPOSE 7860
|
| 41 |
+
|
| 42 |
+
# Start the proxy server
|
| 43 |
+
CMD ["./cli-proxy-api-plus", "-config", "config.yaml"]
|
auth/antigravity-christoph_buchmueller_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA8KLdt68Cjv9kNObSx6rbJ0SJERwFI13GDfQqL8yQ9irGSFROlM4_awejZuWEXdn3C3xcyHnA2oG1nPtdjjLPSml9fupqOV78QpRTzn8cXxzze8bE9zEzfmfVx7-yPzybPGNuHsAX-t4dKfPL6hcyisrf-rJav_ZU532FCwP7_s7yKMmcYUKEwTGnEq2gxqP26YkfaraCgYKAdESARcSFQHGX2Mi-Pq8LF40cUPgv_sAvFGxZA0211","email":"christoph.buchmueller@gmail.com","expired":"2026-01-02T18:32:59+01:00","expires_in":3599,"project_id":"silent-handler-mgcm5","refresh_token":"1//09yHucCaBHDtOCgYIARAAGAkSNwF-L9IrEHLa0C_QeXxY7JeHDkFrGDMCdG5whxRd2EY16KtADKVdXsBDlIkTmX-fNXs0UZYZ05U","timestamp":1767371580076,"type":"antigravity"}
|
auth/antigravity-citrondon666_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA-OrgBS2TT7VWCWnWo6Lz2YTZdlIJAgoBXvPnE_vTK2BLZN70YPBOY17bnPgMUZWJ0b3Y7Gh_faq6yNFgZR-gl3_2g21mYtUKtCur3C4diNaZBjYZ28dxA2CtD1sTf7ogxNUXRDbSWx-l5jYqNLBJnjqaiwO1X9PMxE8JYeEHksu1b7Qr44Xl6afMuHXSU5997OxuWQaCgYKARISARASFQHGX2MiGe0Tf_54BVJ8TvjDtPzXVg0211","email":"citrondon666@gmail.com","expired":"2026-01-02T00:19:25+01:00","expires_in":3599,"project_id":"refined-shield-p6v41","refresh_token":"1//091tu8uSgBlZoCgYIARAAGAkSNwF-L9IrhZB5y3tWZlPXxa1iAnP1jcN9g9IW1FwWKfv4bwhL87ThOM_lQ_od35l27TERPGvunSs","timestamp":1767305966638,"type":"antigravity"}
|
auth/antigravity-claracouve342_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA_70alhbg9TxA_L64Qeh0jqH8bydreSpyVCFGrfN-RZ7MwiHdtjJW1pwp40ZwtHd1NoS4fjf52IH78GkO4F9lUHumCO6v0WaLbk-dSFrf9AwwT1BWmi7sVlvV6rOVBNS7Cc3kchwXz6nplxv2GQI7ZxvHSNdzzmWPIFQWUydMf25hnJl1e0BKJtSeJioN8ysTUHn4TZaCgYKAXcSARUSFQHGX2Mi9K286fUkMtZwJNhejeJZxg0211","email":"claracouve342@gmail.com","expired":"2026-01-02T00:18:24+01:00","expires_in":3599,"project_id":"lofty-sorter-00fqx","refresh_token":"1//09GZJ6C1n1VwFCgYIARAAGAkSNwF-L9IrM3IOj19bnFTuU99g7NEZh2v-q-_HkHVu0nQzvKii1eNlhPJeaBYo9JlQ0IkGQ1QkwDE","timestamp":1767305905292,"type":"antigravity"}
|
auth/antigravity-diesmalwichtigsamuel_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA-digf4tFdMayz_Dd9GAZH1hbQauskM7JZvpa6N8VjVXHzr0FHOOxv1Na_wz84RzHHIDpRcpNBYFApievjaEDpxoMGTT0v2Rr_Rq_n9znyEvC1PFCCjQlVmgyXYBgfsTW7J2G51d7gvoYKnr5DiHqyZgaGCFrAQnf9wW5Z-rsa4S1X6xL5bW-RDicAWpOi5FgNc2sQ-aCgYKAWwSARQSFQHGX2MilKC3mz76wZKDL03WjTSQbw0211","email":"diesmalwichtigsamuel@gmail.com","expired":"2026-01-02T00:19:39+01:00","expires_in":3599,"refresh_token":"1//09tvr0tts6qmvCgYIARAAGAkSNwF-L9Ir2Q6uDIlIhVcgzxWHSpvKy4WkxyXvR1NU9LORdLs7bvtbbl7ahF9TvInw__LQEUx6yKQ","timestamp":1767305980210,"type":"antigravity"}
|
auth/antigravity-hintermaier_pascal_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA9IDNSnhAjLh2PbI7xjiKpF_4rmeq1iep6M0HS80zZtHx8vv3alRfJ9b2HuCsaf-10xI916Bwim9PGH6Opttxrerv3-P9YGfeVVP5J2gjzXPZke1FOkb7WI-dGTRwLdP52MW15nXsXgXiBALXQzS1ZzAAORWGFfnV3hh_341f1vPeObdHCTLaAiR5lO0Ml7fQ3Nob3IaCgYKAWQSARYSFQHGX2MiupVKZOsM2fxyS57yOfc47Q0211","email":"hintermaier.pascal@gmail.com","expired":"2026-01-02T00:17:58+01:00","expires_in":3599,"project_id":"modified-fastness-wlr19","refresh_token":"1//09l9GQlj_VRTFCgYIARAAGAkSNwF-L9IrbS2oCSBRwQBzNzOFIMEqtD8q8dfSTZ8lswoQQ-mUzpXWPLKdoVqCfdYH9z0ilLRoHmI","timestamp":1767305879026,"type":"antigravity"}
|
auth/antigravity-hintermaierpascal0_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA8J_q9LPSBVRtJ2bIAXxE7FTCwEKmWxa0nESOQMvY0zS6aoS5TMsU6JteMrTHGN_iL9yNYtteOO6BQv2kuJ3k-MuU0M4A2NJ1mkUT1J3Mu8cR_VVK5pN4UTRY9N5l9ujzBrDHC1WMTXmxxjh51Fi78rZ7QWv9t7Ch_DES_te47pFz8x1eDh1jjraLU6NIIXU5pVna4AaCgYKAbgSARYSFQHGX2MiV7V0yJN7Au__melh6T_l_g0211","email":"hintermaierpascal0@gmail.com","expired":"2026-01-02T00:18:32+01:00","expires_in":3599,"project_id":"phonic-pillar-1zftk","refresh_token":"1//09L559Xu1HR65CgYIARAAGAkSNwF-L9IrNRO1A6ybH155Y6Y1TGKmrVCN7-0TsC3tonouMFsKAfnRNxO9TEZ5EhymmK_bnq60q3c","timestamp":1767305913612,"type":"antigravity"}
|
auth/antigravity-pascal_hintermaier_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA9jRjQOmohIG_pzuvi6PU0TLzxtWziImkHyzrj87Can6-B475kZ2rVFzEjZMEwEjtqsKiZNl4UNCpqkDU5Xg_ajX4SGxocRlTQYltKw8saL9yc0mH5-PsVFzQ10bp8bjH50ZkG9zhGEO3O3FawmeqAZ5zT3vO_dd5LLQopMo5TH0s-SMozZSs6BKInUoAFl23o_BntRaCgYKAacSARYSFQHGX2Mi07efzoG1Wy3HeuazuxUgDQ0211","email":"pascal.hintermaier@gmail.com","expired":"2026-01-02T00:17:41+01:00","expires_in":3599,"project_id":"alert-brace-j1nhr","refresh_token":"1//09zyxez21TBu2CgYIARAAGAkSNwF-L9IrIOs7JCFeBds7LqcJZKMouL7vk40uWA77KJiYvdeV49RQz4SUxhz8rM4SL3B2fZ9INwk","timestamp":1767305862567,"type":"antigravity"}
|
auth/antigravity-rave_riotofficial_gmail_com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ya29.a0Aa7pCA8YBU00C_zuB548ozVzlaXES5VhvyrqStyJv38m96lf2g_mJyIr-ywDP63sdlzYZ8Ec8SOtxaj9A7SvWhiw1gvo3CvH_rVvQH8kaQfYSbadtO3RLo3GMYf0L8omuTyZKI7bunOUxYhXJo7nTsmKEo3FZ6wnz02n2L-jYPkyGZTq_ghBv2rOoKHGv8SnOYzSpshg1dVaaCgYKAUoSARISFQHGX2Mi40PKBz2bpbCexj7DzBCevQ0211","email":"rave.riotofficial@gmail.com","expired":"2026-01-02T00:19:57+01:00","expires_in":3599,"project_id":"blissful-age-zww27","refresh_token":"1//093bq-VRNSCPfCgYIARAAGAkSNwF-L9IrQP0RZvGVhhshN7lIHkbsu5zgE4qmDsKdfdx0oWUO6q1DqRUQOjTcepkFnitCNuOLpME","timestamp":1767305998823,"type":"antigravity"}
|
auth/citrondon666@gmail.com-gen-lang-client-0171616182.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA9i1naLUPL-0-tftJdh88tAfpQRAqmJLUZbkuu3bfMWqS_0_lenKOtS5Vn1xeVj8BODMH-6jtTkaRkvPW4YugsQEILGOt4yXC4P4GxEFvIsKEE2jw-GMyVIPocbBmPOXeGJ_lWU3RmtMB1oLob1XW2vPjzd-A0CJ6TI0obV0qV9BJ5SWojz-f4Rn-mHc5QXfND1tV28aCgYKAbkSARASFQHGX2Miwo8dM2I97qjOYCvH5-Z6aQ0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:15:45.829310593+01:00","refresh_token":"1//09Lwiwr528W7JCgYIARAAGAkSNwF-L9Ir5G6OfSE68L5SDtdBaT2-EydTmYcg4XBye_6gkYtNuXVuYlH9aLxEJg4gL3ZEkp3xIhM","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"gen-lang-client-0171616182","email":"citrondon666@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
auth/claracouve342@gmail.com-bluebirdhub-clara-2025.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA8YcixUQXmIuzbo7vySb8n8aohMsqWia1_sYitaBPDHcQl50Ikb_8_PvWHIXgDESmaVWBL0-aKG_YDKPxGtq87Mxic9FSJMMqM7MUuvRHRM8rgmdPKI5XggnOkX8kqT66AKfI4OglhI_ojD05JXofRaHlBZBttquTiJLbXsXmwOHu8AC4nZxxaNutOBzzSaVpu_89ABaCgYKARkSARUSFQHGX2MiZmzlC0JJ1Pm3FCmlgU0c1w0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:11:47.777597698+01:00","refresh_token":"1//09Pe3DLMsnRhFCgYIARAAGAkSNwF-L9IrNg_BGMBsI2AWcZbR8n-1iMi9pmscb3r9T50fG2Ok_Cz4FH_bZGf-oRzmc_Zzi7m-Bf8","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"bluebirdhub-clara-2025","email":"claracouve342@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
auth/hintermaier.pascal@gmail.com-gen-lang-client-0084172363.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA-tT7fzxjembWop9gxC6gMoOgECa8rDmrSj18w-ikGPyna08vQZbRnsJ_9RPPWD0N-Ifkb3OkQ1i7CnbZGVlkaxOI8eBEDzDCGqmKvh45z_6smwk_mteAq3HBauYNyeot1ouitgIlcMXDaEHs5igTMjvpOJFSxUKY980yPAEPiv57NAwBXhfTQQlfaZ9qKRDLJ1UfPWaCgYKAdcSARYSFQHGX2Mi_I69sgBKDPmsCHr_2dvJrQ0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:10:08.911390808+01:00","refresh_token":"1//09ob8pMdbHcbpCgYIARAAGAkSNwF-L9Ir2LnNCRo20RUeAusLILxBDQiwveCJWJFYsayiRGOBbvpzb8-q_KfUZ_P01Yq7p_USp_M","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"gen-lang-client-0084172363","email":"hintermaier.pascal@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
auth/hintermaierpascal0@gmail.com-gen-lang-client-0476252734.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA85OQRBB7u8YgcQRfayVnLk8I6dunNZp6oArZ9llWfKj7wLdqiJNAl2U51XIiFNdZpeL1tOgBvm2H8z9eUROJ2qw2D0pT8cOaQv7r-weT2RSSMve7I_2Yk5U2pHZBg4VMFRsd015UhwpACIIHhFl3EBjCc1Iy7xApFjq9Rxkg2yBzxsj1pJ0QSMVIV7e58YUGL2FPjoaCgYKASwSARYSFQHGX2MivWwKs3LijABXANjQ3RqEkg0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:13:15.204806529+01:00","refresh_token":"1//09AUg0-ZLVaHmCgYIARAAGAkSNwF-L9Ir7-ZgC0mclyGm8A8PpB52zp212A6GTlD8BXnBsvw8fjTcdQ8RdC-z9HSLiv3BjY1AQ5E","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"gen-lang-client-0476252734","email":"hintermaierpascal0@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
auth/kiro-aws-thewolfofvaalstreet@gmail.com.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"aoaAAAAAGlkFKoxVq73tgXDpSo80R0INlcVelAqpmjtG-s4gSyh0SBJg1btQc_NXrkaUPCIFrj2epxXlXbwX_zudkBkc0:MGUCMCc8akLHezKXbx9EQ7Q2qQhHzINnsplvlmkvC0yx3W+vza20l4VuV8kkXlAHqkMHiAIxALPSQYKTKurWy97XJrERxpLkEuKio0731p3LYVQPphi6oktnfL+tZJV6vthmAk8nZA","auth_method":"builder-id","client_id":"5FisoOIBeETVXgV2F7wnqXVzLWVhc3QtMQ","client_secret":"eyJraWQiOiJrZXktMTU2NDAyODA5OSIsImFsZyI6IkhTMzg0In0.eyJzZXJpYWxpemVkIjoie1wiY2xpZW50SWRcIjp7XCJ2YWx1ZVwiOlwiNUZpc29PSUJlRVRWWGdWMkY3d25xWFZ6TFdWaGMzUXRNUVwifSxcImlkZW1wb3RlbnRLZXlcIjpudWxsLFwidGVuYW50SWRcIjpudWxsLFwiY2xpZW50TmFtZVwiOlwiS2lybyBJREVcIixcImJhY2tmaWxsVmVyc2lvblwiOm51bGwsXCJjbGllbnRUeXBlXCI6XCJQVUJMSUNcIixcInRlbXBsYXRlQXJuXCI6bnVsbCxcInRlbXBsYXRlQ29udGV4dFwiOm51bGwsXCJleHBpcmF0aW9uVGltZXN0YW1wXCI6MTc3NTExODU5OC44MTIwNzg4NDcsXCJjcmVhdGVkVGltZXN0YW1wXCI6MTc2NzM0MjU5OC44MTIwNzg4NDcsXCJ1cGRhdGVkVGltZXN0YW1wXCI6MTc2NzM0MjU5OC44MTIwNzg4NDcsXCJjcmVhdGVkQnlcIjpudWxsLFwidXBkYXRlZEJ5XCI6bnVsbCxcInN0YXR1c1wiOm51bGwsXCJpbml0aWF0ZUxvZ2luVXJpXCI6bnVsbCxcImVudGl0bGVkUmVzb3VyY2VJZFwiOm51bGwsXCJlbnRpdGxlZFJlc291cmNlQ29udGFpbmVySWRcIjpudWxsLFwiZXh0ZXJuYWxJZFwiOm51bGwsXCJzb2Z0d2FyZUlkXCI6bnVsbCxcInNjb3Blc1wiOlt7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6Y29tcGxldGlvbnNcIixcInN0YXR1c1wiOlwiSU5JVElBTFwiLFwiYXBwbGljYXRpb25Bcm5cIjpudWxsLFwiZnJpZW5kbHlJZFwiOlwiY29kZXdoaXNwZXJlclwiLFwidXNlQ2FzZUFjdGlvblwiOlwiY29tcGxldGlvbnNcIixcInR5cGVcIjpcIkltbXV0YWJsZUFjY2Vzc1Njb3BlXCIsXCJzY29wZVR5cGVcIjpcIkFDQ0VTU19TQ09QRVwifSx7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6YW5hbHlzaXNcIixcInN0YXR1c1wiOlwiSU5JVElBTFwiLFwiYXBwbGljYXRpb25Bcm5cIjpudWxsLFwiZnJpZW5kbHlJZFwiOlwiY29kZXdoaXNwZXJlclwiLFwidXNlQ2FzZUFjdGlvblwiOlwiYW5hbHlzaXNcIixcInR5cGVcIjpcIkltbXV0YWJsZUFjY2Vzc1Njb3BlXCIsXCJzY29wZVR5cGVcIjpcIkFDQ0VTU19TQ09QRVwifSx7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6Y29udmVyc2F0aW9uc1wiLFwic3RhdHVzXCI6XCJJTklUSUFMXCIsXCJhcHBsaWNhdGlvbkFyblwiOm51bGwsXCJmcmllbmRseUlkXCI6XCJjb2Rld2hpc3BlcmVyXCIsXCJ1c2VDYXNlQWN0aW9uXCI6XCJjb252ZXJzYXRpb25zXCIsXCJ0eXBlXCI6XCJJbW11dGFibGVBY2Nlc3NTY29wZVwiLFwic2NvcGVUeXBlXCI6XCJBQ0NFU1NfU0NPUEVcIn0se1wiZnVsbFNjb3BlXCI6XCJjb2Rld2hpc3BlcmVyOnRyYW5zZm9ybWF0aW9uc1wiLFwic3RhdHVzXCI6XCJJTklUSUFMXCIsXCJhcHBsaWNhdGlvbkFyblwiOm51bGwsXCJmcmllbmRseUlkXCI6XCJjb2Rld2hpc3BlcmVyXCIsXCJ1c2VDYXNlQWN0aW9uXCI6XCJ0cmFuc2Zvcm1hdGlvbnNcIixcInR5cGVcIjpcIkltbXV0YWJsZUFjY2Vzc1Njb3BlXCIsXCJzY29wZVR5cGVcIjpcIkFDQ0VTU19TQ09QRVwifSx7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6dGFza2Fzc2lzdFwiLFwic3RhdHVzXCI6XCJJTklUSUFMXCIsXCJhcHBsaWNhdGlvbkFyblwiOm51bGwsXCJmcmllbmRseUlkXCI6XCJjb2Rld2hpc3BlcmVyXCIsXCJ1c2VDYXNlQWN0aW9uXCI6XCJ0YXNrYXNzaXN0XCIsXCJ0eXBlXCI6XCJJbW11dGFibGVBY2Nlc3NTY29wZVwiLFwic2NvcGVUeXBlXCI6XCJBQ0NFU1NfU0NPUEVcIn1dLFwiYXV0aGVudGljYXRpb25Db25maWd1cmF0aW9uXCI6bnVsbCxcInNoYWRvd0F1dGhlbnRpY2F0aW9uQ29uZmlndXJhdGlvblwiOm51bGwsXCJlbmFibGVkR3JhbnRzXCI6bnVsbCxcImVuZm9yY2VBdXRoTkNvbmZpZ3VyYXRpb25cIjpudWxsLFwib3duZXJBY2NvdW50SWRcIjpudWxsLFwic3NvSW5zdGFuY2VBY2NvdW50SWRcIjpudWxsLFwidXNlckNvbnNlbnRcIjpudWxsLFwibm9uSW50ZXJhY3RpdmVTZXNzaW9uc0VuYWJsZWRcIjpudWxsLFwiYXNzb2NpYXRlZEluc3RhbmNlQXJuXCI6bnVsbCxcImlzQmFja2ZpbGxlZFwiOmZhbHNlLFwiaGFzSW5pdGlhbFNjb3Blc1wiOnRydWUsXCJhcmVBbGxTY29wZXNDb25zZW50ZWRUb1wiOmZhbHNlLFwiaXNFeHBpcmVkXCI6ZmFsc2UsXCJzc29TY29wZXNcIjpbXSxcImdyb3VwU2NvcGVzQnlGcmllbmRseUlkXCI6e1wiY29kZXdoaXNwZXJlclwiOlt7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6YW5hbHlzaXNcIixcInN0YXR1c1wiOlwiSU5JVElBTFwiLFwiYXBwbGljYXRpb25Bcm5cIjpudWxsLFwiZnJpZW5kbHlJZFwiOlwiY29kZXdoaXNwZXJlclwiLFwidXNlQ2FzZUFjdGlvblwiOlwiYW5hbHlzaXNcIixcInR5cGVcIjpcIkltbXV0YWJsZUFjY2Vzc1Njb3BlXCIsXCJzY29wZVR5cGVcIjpcIkFDQ0VTU19TQ09QRVwifSx7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6dHJhbnNmb3JtYXRpb25zXCIsXCJzdGF0dXNcIjpcIklOSVRJQUxcIixcImFwcGxpY2F0aW9uQXJuXCI6bnVsbCxcImZyaWVuZGx5SWRcIjpcImNvZGV3aGlzcGVyZXJcIixcInVzZUNhc2VBY3Rpb25cIjpcInRyYW5zZm9ybWF0aW9uc1wiLFwidHlwZVwiOlwiSW1tdXRhYmxlQWNjZXNzU2NvcGVcIixcInNjb3BlVHlwZVwiOlwiQUNDRVNTX1NDT1BFXCJ9LHtcImZ1bGxTY29wZVwiOlwiY29kZXdoaXNwZXJlcjpjb252ZXJzYXRpb25zXCIsXCJzdGF0dXNcIjpcIklOSVRJQUxcIixcImFwcGxpY2F0aW9uQXJuXCI6bnVsbCxcImZyaWVuZGx5SWRcIjpcImNvZGV3aGlzcGVyZXJcIixcInVzZUNhc2VBY3Rpb25cIjpcImNvbnZlcnNhdGlvbnNcIixcInR5cGVcIjpcIkltbXV0YWJsZUFjY2Vzc1Njb3BlXCIsXCJzY29wZVR5cGVcIjpcIkFDQ0VTU19TQ09QRVwifSx7XCJmdWxsU2NvcGVcIjpcImNvZGV3aGlzcGVyZXI6dGFza2Fzc2lzdFwiLFwic3RhdHVzXCI6XCJJTklUSUFMXCIsXCJhcHBsaWNhdGlvbkFyblwiOm51bGwsXCJmcmllbmRseUlkXCI6XCJjb2Rld2hpc3BlcmVyXCIsXCJ1c2VDYXNlQWN0aW9uXCI6XCJ0YXNrYXNzaXN0XCIsXCJ0eXBlXCI6XCJJbW11dGFibGVBY2Nlc3NTY29wZVwiLFwic2NvcGVUeXBlXCI6XCJBQ0NFU1NfU0NPUEVcIn0se1wiZnVsbFNjb3BlXCI6XCJjb2Rld2hpc3BlcmVyOmNvbXBsZXRpb25zXCIsXCJzdGF0dXNcIjpcIklOSVRJQUxcIixcImFwcGxpY2F0aW9uQXJuXCI6bnVsbCxcImZyaWVuZGx5SWRcIjpcImNvZGV3aGlzcGVyZXJcIixcInVzZUNhc2VBY3Rpb25cIjpcImNvbXBsZXRpb25zXCIsXCJ0eXBlXCI6XCJJbW11dGFibGVBY2Nlc3NTY29wZVwiLFwic2NvcGVUeXBlXCI6XCJBQ0NFU1NfU0NPUEVcIn1dfSxcInNob3VsZEdldFZhbHVlRnJvbVRlbXBsYXRlXCI6dHJ1ZSxcImhhc1JlcXVlc3RlZFNjb3Blc1wiOmZhbHNlLFwiY29udGFpbnNPbmx5U3NvU2NvcGVzXCI6ZmFsc2UsXCJpc1YxQmFja2ZpbGxlZFwiOmZhbHNlLFwiaXNWMkJhY2tmaWxsZWRcIjpmYWxzZSxcImlzVjNCYWNrZmlsbGVkXCI6ZmFsc2UsXCJpc1Y0QmFja2ZpbGxlZFwiOmZhbHNlfSJ9.DiJpx0r9gC_jmCWyCnT1IlZvHeUvMSKJfjPR-DuOI3q4LT7em4LIyxbVoE9WHGJW","email":"thewolfofvaalstreet@gmail.com","expires_at":"2026-01-11T22:22:50+01:00","last_refresh":"2026-01-11T21:22:50+01:00","profile_arn":"","provider":"AWS","refresh_token":"aorAAAAAGnOKY0Am29SYn6By21bOzldZAxR193g2QTyRS6KXX6AK1M4Fma12aZE2TDCPnRsI_uj1HUjJfE2zEydqMBkc0:MGUCMCzzb1rRj5AAhg+kfEk/1qPME44GUly/qn8Oarh3lo1z02Xi/zi0qxlw1ZcV5AgRYwIxAOTwAyJo7mWQ1LekVwkyzguAH4jAipwYrdKVvXtzzdHsyRZn2W98dbT5+lh9au2NDA","type":"kiro"}
|
auth/kiro-imported.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"access_token": "aoaAAAAAGlkDekrMnJSl1YIFYAJ29XEpOETQOyIuBN7i5uNeRSRQToomd8IOdhu2UKhOw2ool4WAy0qNheY6Cye5gBkc0:MGYCMQDTHENT4w0BzqbwDoA/IJwxn1+Ce7c9rX8D1WdwNxzNtHQWva10pYQsXrZ9fO/qXzMCMQDLFUQEnzFh9PK68TSlUFSx/1tghIG96l4ngax8085Pvgz+6dSgp7mPH1ZlRGyOFgc",
|
| 3 |
+
"refresh_token": "aorAAAAAGnaptg1icfwZhyXuM5cBjQtZPs2LQJyOlbSRf6I_AKvtLmtHSgnHOLQf8Gi0emeTbxjwiGwbNZMTLUCQABkc0:MGQCMAVg1bvvEOfPWs/36xo0O++ymfuZV9qbVGVnc44p0mhP6mCaw4mbaWq7P+zxzYr5/AIwXnJ+pFLb/XOz8orjlctjZlINcnxadpPWn7ljEHXH1DHVYFRpBbNP4RCHqeynWgE9",
|
| 4 |
+
"client_id": "5FisoOIBeETVXgV2F7wnqXVzLWVhc3QtMQ",
|
| 5 |
+
"client_secret": "PLACEHOLDER_SECRET_HOPE_IT_WORKS_OR_REAUTH_IS_NEEDED",
|
| 6 |
+
"expires_at": "2026-02-11T20:43:01+01:00",
|
| 7 |
+
"auth_method": "builder-id",
|
| 8 |
+
"email": "imported-session@kiro.dev",
|
| 9 |
+
"provider": "AWS",
|
| 10 |
+
"type": "kiro"
|
| 11 |
+
}
|
auth/pascal.hintermaier@gmail.com-uniqueuniquesfromuniquewa.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA-JmhVnLjUMvTDNINUisfjwu7TYAGUEEBB8BkskL4N_EDKHnPiFm5c2CQy4ZXj7qrGFY-GV6xFBoLl5zz1AvCZEEQpOgZqwOJ70mp8Tej7hCeksQSsWsg7T7As11ooVRrcocaJAop0UWrGzvctGNmXkhdzfenWasifGvFs4IeO9H3D4ZfVKvQ33xkv-5ywm-L7z0SnGaCgYKAW4SARYSFQHGX2MiHAUPf_7OlClRr9w2KsuOpA0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:09:51.395235364+01:00","refresh_token":"1//090htx9bnW3FhCgYIARAAGAkSNwF-L9IrQFx7l8-oZzygHuJZ7qI5YuYr8f0UFpcy1SUKGCvG5MIaiKfAaKy71ipGQSRmVq6DgYE","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"uniqueuniquesfromuniquewa","email":"pascal.hintermaier@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
auth/qwen-qwen-1767306169376.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"0exSDQrcZiCvP-wj7p6HjGaouYiLDfw6dIxnsTnqh9B6CgemJz8vT-BKS1YQhK5tCr07gECe3mibLQ6W826f_g","email":"qwen-1767306169376","expired":"2026-01-04T03:10:33+01:00","last_refresh":"2026-01-03T21:10:33+01:00","refresh_token":"q1j2tXG9fh3YvOQDWbMyVMUf7SIo_mUb87q4iWnzU4WostN8faarjLqkYvJk-J1rLzbofHGouUde2yhZFOksVw","resource_url":"portal.qwen.ai","type":"qwen"}
|
auth/qwen-qwen-1768083358627.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"access_token":"ekJyQZXCGIyGEYvjJkingGK-7mDjYQ_tJyp45tI72uVRNeCptiHK52xC0tpfg6iMfcUirIAT7JA6-GxGgVivTA","email":"qwen-1768083358627","expired":"2026-01-12T02:27:44+01:00","last_refresh":"2026-01-11T20:27:44+01:00","refresh_token":"R8_pR0ZK7q_i2lmMWVH0in_QuhKzhr0BsjD5fkPYafBIPunPiNU7TC9V5fQnfSO7XP-eDoOIqdlz44qrmc9hNQ","resource_url":"portal.qwen.ai","type":"qwen"}
|
auth/rave.riotofficial@gmail.com-gen-lang-client-0808033057.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"token":{"access_token":"ya29.a0Aa7pCA99cbhSEpb2VASWH4ve1PT90NXhZlA-Vizvv5jTjZtkCcPsrZiRx0ePQb3RP1jrnVcl3FIcD9vm1Y9qECfxt_pht6ix0NyiVhaomFfllY8x7N8iiQ_84Kbzdtx6ZqDEtTE94I4tezDMnwInYOJ-lgjUTfdaZdCh5pPzdPokeTKpIsva_H6AoxFU4c-64rWXUpZQ_RA0aCgYKAY4SARISFQHGX2Mi0OOAitFV7HIB1eWyuItT7w0211","client_id":"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com","client_secret":"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","expires_in":3599,"expiry":"2026-01-02T00:14:41.673223313+01:00","refresh_token":"1//09tt-yEwjTCtECgYIARAAGAkSNwF-L9IrMDhY1GirEU2mJDg1J57FOuougJaiCzZEIjIxBr08ewkiqCqOyhhz_qbm0BUfii3Mq-g","scopes":["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],"token_type":"Bearer","token_uri":"https://oauth2.googleapis.com/token","universe_domain":"googleapis.com"},"project_id":"gen-lang-client-0808033057","email":"rave.riotofficial@gmail.com","auto":false,"checked":true,"type":"gemini"}
|
config.yaml
CHANGED
|
@@ -19,6 +19,7 @@ auth-dir: "./auth"
|
|
| 19 |
# Client Keys for YOU to access the API
|
| 20 |
api-keys:
|
| 21 |
- "sk-admin-power-1"
|
|
|
|
| 22 |
- "sk-client-key-custom"
|
| 23 |
|
| 24 |
# Performance & Logging
|
|
@@ -70,6 +71,44 @@ oauth-model-mappings:
|
|
| 70 |
alias: "g-pro"
|
| 71 |
- name: "gemini-2.5-flash"
|
| 72 |
alias: "g-flash"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
claude:
|
| 74 |
- name: "claude-3-5-sonnet-20241022"
|
| 75 |
-
alias: "sonnet"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# Client Keys for YOU to access the API
|
| 20 |
api-keys:
|
| 21 |
- "sk-admin-power-1"
|
| 22 |
+
- "sk-ant-proxy-key-1"
|
| 23 |
- "sk-client-key-custom"
|
| 24 |
|
| 25 |
# Performance & Logging
|
|
|
|
| 71 |
alias: "g-pro"
|
| 72 |
- name: "gemini-2.5-flash"
|
| 73 |
alias: "g-flash"
|
| 74 |
+
- name: "gemini-2.5-pro"
|
| 75 |
+
alias: "gemini-1.5-pro"
|
| 76 |
+
- name: "gemini-2.5-flash"
|
| 77 |
+
alias: "gemini-1.5-flash"
|
| 78 |
claude:
|
| 79 |
- name: "claude-3-5-sonnet-20241022"
|
| 80 |
+
alias: "sonnet"
|
| 81 |
+
- name: "claude-3-5-sonnet-20241022"
|
| 82 |
+
alias: "claude-sonnet-4-5-20250929"
|
| 83 |
+
- name: "claude-3-5-sonnet-20241022"
|
| 84 |
+
alias: "claude-haiku-4-5-20251001"
|
| 85 |
+
- name: "claude-3-5-sonnet-20241022"
|
| 86 |
+
alias: "claude-3-5-sonnet-latest"
|
| 87 |
+
- name: "claude-3-5-sonnet-20241022"
|
| 88 |
+
alias: "claude-3-5-sonnet-20241022"
|
| 89 |
+
openrouter:
|
| 90 |
+
- name: "anthropic/claude-3-5-sonnet"
|
| 91 |
+
alias: "claude-3-5-sonnet-20241022"
|
| 92 |
+
- name: "anthropic/claude-3-5-sonnet"
|
| 93 |
+
alias: "claude-3-5-sonnet-latest"
|
| 94 |
+
- name: "anthropic/claude-3-5-haiku"
|
| 95 |
+
alias: "claude-3-5-haiku-20241022"
|
| 96 |
+
|
| 97 |
+
# 5. Amp Integration (Claude Code)
|
| 98 |
+
oauth-excluded-models:
|
| 99 |
+
# Removed kiro exclusion to enable Kiro models
|
| 100 |
+
claude: []
|
| 101 |
+
|
| 102 |
+
ampcode:
|
| 103 |
+
force-model-mappings: true
|
| 104 |
+
model-mappings:
|
| 105 |
+
- from: "gpt-4o"
|
| 106 |
+
to: "gemini-2.5-flash"
|
| 107 |
+
- from: "gpt-4o-mini"
|
| 108 |
+
to: "gemini-2.5-flash"
|
| 109 |
+
- from: "claude-sonnet-4-5-20250929"
|
| 110 |
+
to: "kiro-claude-sonnet-4-5"
|
| 111 |
+
- from: "claude-haiku-4-5-20251001"
|
| 112 |
+
to: "kiro-claude-sonnet-4-5"
|
| 113 |
+
|
| 114 |
+
ws-auth: false
|
internal/api/handlers/management/config_basic.go
CHANGED
|
@@ -241,3 +241,27 @@ func (h *Handler) DeleteProxyURL(c *gin.Context) {
|
|
| 241 |
h.cfg.ProxyURL = ""
|
| 242 |
h.persist(c)
|
| 243 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
h.cfg.ProxyURL = ""
|
| 242 |
h.persist(c)
|
| 243 |
}
|
| 244 |
+
|
| 245 |
+
// Logs max total size
|
| 246 |
+
func (h *Handler) GetLogsMaxTotalSizeMb(c *gin.Context) {
|
| 247 |
+
c.JSON(200, gin.H{"logs-max-total-size-mb": h.cfg.LogsMaxTotalSizeMB})
|
| 248 |
+
}
|
| 249 |
+
func (h *Handler) PutLogsMaxTotalSizeMb(c *gin.Context) {
|
| 250 |
+
h.updateIntField(c, func(v int) { h.cfg.LogsMaxTotalSizeMB = v })
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
// Routing strategy
|
| 254 |
+
func (h *Handler) GetRoutingStrategy(c *gin.Context) {
|
| 255 |
+
c.JSON(200, gin.H{"strategy": h.cfg.Routing.Strategy})
|
| 256 |
+
}
|
| 257 |
+
func (h *Handler) PutRoutingStrategy(c *gin.Context) {
|
| 258 |
+
h.updateStringField(c, func(v string) { h.cfg.Routing.Strategy = v })
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
// Force model prefix
|
| 262 |
+
func (h *Handler) GetForceModelPrefix(c *gin.Context) {
|
| 263 |
+
c.JSON(200, gin.H{"force-model-prefix": h.cfg.ForceModelPrefix})
|
| 264 |
+
}
|
| 265 |
+
func (h *Handler) PutForceModelPrefix(c *gin.Context) {
|
| 266 |
+
h.updateBoolField(c, func(v bool) { h.cfg.ForceModelPrefix = v })
|
| 267 |
+
}
|
internal/api/modules/amp/routes.go
CHANGED
|
@@ -307,6 +307,7 @@ func (m *AmpModule) registerProviderAliases(engine *gin.Engine, baseHandler *han
|
|
| 307 |
provider.POST("/chat/completions", fallbackHandler.WrapHandler(openaiHandlers.ChatCompletions))
|
| 308 |
provider.POST("/completions", fallbackHandler.WrapHandler(openaiHandlers.Completions))
|
| 309 |
provider.POST("/responses", fallbackHandler.WrapHandler(openaiResponsesHandlers.Responses))
|
|
|
|
| 310 |
|
| 311 |
// /v1 routes (OpenAI/Claude-compatible endpoints)
|
| 312 |
v1Amp := provider.Group("/v1")
|
|
|
|
| 307 |
provider.POST("/chat/completions", fallbackHandler.WrapHandler(openaiHandlers.ChatCompletions))
|
| 308 |
provider.POST("/completions", fallbackHandler.WrapHandler(openaiHandlers.Completions))
|
| 309 |
provider.POST("/responses", fallbackHandler.WrapHandler(openaiResponsesHandlers.Responses))
|
| 310 |
+
provider.POST("/messages", fallbackHandler.WrapHandler(claudeCodeHandlers.ClaudeMessages))
|
| 311 |
|
| 312 |
// /v1 routes (OpenAI/Claude-compatible endpoints)
|
| 313 |
v1Amp := provider.Group("/v1")
|
internal/api/server.go
CHANGED
|
@@ -361,6 +361,10 @@ func (s *Server) setupRoutes() {
|
|
| 361 |
s.engine.POST("/api/event_logging/batch", func(c *gin.Context) {
|
| 362 |
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
| 363 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
s.engine.POST("/v1internal:method", geminiCLIHandlers.CLIHandler)
|
| 365 |
|
| 366 |
// OAuth callback endpoints (reuse main server port)
|
|
@@ -548,6 +552,18 @@ func (s *Server) registerManagementRoutes() {
|
|
| 548 |
mgmt.PATCH("/gemini-api-key", s.mgmt.PatchGeminiKey)
|
| 549 |
mgmt.DELETE("/gemini-api-key", s.mgmt.DeleteGeminiKey)
|
| 550 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 551 |
mgmt.GET("/logs", s.mgmt.GetLogs)
|
| 552 |
mgmt.DELETE("/logs", s.mgmt.DeleteLogs)
|
| 553 |
mgmt.GET("/request-error-logs", s.mgmt.GetRequestErrorLogs)
|
|
@@ -665,25 +681,19 @@ func (s *Server) serveManagementControlPanel(c *gin.Context) {
|
|
| 665 |
// Direct fallback: serve management.html from memory if file access fails
|
| 666 |
c.File(filePath)
|
| 667 |
}
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
|
|
|
| 672 |
}
|
|
|
|
| 673 |
if _, err := os.Stat(filePath); err != nil {
|
| 674 |
-
|
| 675 |
-
go managementasset.EnsureLatestManagementHTML(context.Background(), managementasset.StaticDir(s.configFilePath), cfg.ProxyURL, cfg.RemoteManagement.PanelGitHubRepository)
|
| 676 |
-
c.AbortWithStatus(http.StatusNotFound)
|
| 677 |
-
return
|
| 678 |
-
}
|
| 679 |
-
log.WithError(err).Error("failed to stat management control panel asset")
|
| 680 |
-
c.AbortWithStatus(http.StatusInternalServerError)
|
| 681 |
return
|
| 682 |
}
|
| 683 |
-
// Direct fallback: serve management.html from memory if file access fails
|
| 684 |
c.File(filePath)
|
| 685 |
}
|
| 686 |
-
}
|
| 687 |
|
| 688 |
func (s *Server) enableKeepAlive(timeout time.Duration, onTimeout func()) {
|
| 689 |
if timeout <= 0 || onTimeout == nil {
|
|
|
|
| 361 |
s.engine.POST("/api/event_logging/batch", func(c *gin.Context) {
|
| 362 |
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
| 363 |
})
|
| 364 |
+
// Add catch-all for provider-specific event logging
|
| 365 |
+
s.engine.POST("/api/provider/:provider/api/event_logging/batch", func(c *gin.Context) {
|
| 366 |
+
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
| 367 |
+
})
|
| 368 |
s.engine.POST("/v1internal:method", geminiCLIHandlers.CLIHandler)
|
| 369 |
|
| 370 |
// OAuth callback endpoints (reuse main server port)
|
|
|
|
| 552 |
mgmt.PATCH("/gemini-api-key", s.mgmt.PatchGeminiKey)
|
| 553 |
mgmt.DELETE("/gemini-api-key", s.mgmt.DeleteGeminiKey)
|
| 554 |
|
| 555 |
+
mgmt.GET("/logs-max-total-size-mb", s.mgmt.GetLogsMaxTotalSizeMb)
|
| 556 |
+
mgmt.PUT("/logs-max-total-size-mb", s.mgmt.PutLogsMaxTotalSizeMb)
|
| 557 |
+
mgmt.PATCH("/logs-max-total-size-mb", s.mgmt.PutLogsMaxTotalSizeMb)
|
| 558 |
+
|
| 559 |
+
mgmt.GET("/routing/strategy", s.mgmt.GetRoutingStrategy)
|
| 560 |
+
mgmt.PUT("/routing/strategy", s.mgmt.PutRoutingStrategy)
|
| 561 |
+
mgmt.PATCH("/routing/strategy", s.mgmt.PutRoutingStrategy)
|
| 562 |
+
|
| 563 |
+
mgmt.GET("/force-model-prefix", s.mgmt.GetForceModelPrefix)
|
| 564 |
+
mgmt.PUT("/force-model-prefix", s.mgmt.PutForceModelPrefix)
|
| 565 |
+
mgmt.PATCH("/force-model-prefix", s.mgmt.PutForceModelPrefix)
|
| 566 |
+
|
| 567 |
mgmt.GET("/logs", s.mgmt.GetLogs)
|
| 568 |
mgmt.DELETE("/logs", s.mgmt.DeleteLogs)
|
| 569 |
mgmt.GET("/request-error-logs", s.mgmt.GetRequestErrorLogs)
|
|
|
|
| 681 |
// Direct fallback: serve management.html from memory if file access fails
|
| 682 |
c.File(filePath)
|
| 683 |
}
|
| 684 |
+
|
| 685 |
+
func (s *Server) serveStatusPage(c *gin.Context) {
|
| 686 |
+
staticPath := os.Getenv("MANAGEMENT_STATIC_PATH")
|
| 687 |
+
if staticPath == "" {
|
| 688 |
+
staticPath = filepath.Join(s.currentPath, "static")
|
| 689 |
}
|
| 690 |
+
filePath := filepath.Join(staticPath, "status.html")
|
| 691 |
if _, err := os.Stat(filePath); err != nil {
|
| 692 |
+
c.AbortWithStatus(http.StatusNotFound)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 693 |
return
|
| 694 |
}
|
|
|
|
| 695 |
c.File(filePath)
|
| 696 |
}
|
|
|
|
| 697 |
|
| 698 |
func (s *Server) enableKeepAlive(timeout time.Duration, onTimeout func()) {
|
| 699 |
if timeout <= 0 || onTimeout == nil {
|
internal/registry/model_definitions.go
CHANGED
|
@@ -85,6 +85,17 @@ func GetClaudeModels() []*ModelInfo {
|
|
| 85 |
MaxCompletionTokens: 8192,
|
| 86 |
Thinking: &ThinkingSupport{Min: 1024, Max: 100000, ZeroAllowed: false, DynamicAllowed: true},
|
| 87 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
{
|
| 89 |
ID: "claude-3-5-haiku-20241022",
|
| 90 |
Object: "model",
|
|
@@ -192,6 +203,34 @@ func GetGeminiModels() []*ModelInfo {
|
|
| 192 |
SupportedGenerationMethods: []string{"generateContent", "countTokens", "createCachedContent", "batchGenerateContent"},
|
| 193 |
Thinking: &ThinkingSupport{Min: 128, Max: 32768, ZeroAllowed: false, DynamicAllowed: true, Levels: []string{"low", "high"}},
|
| 194 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
}
|
| 196 |
}
|
| 197 |
|
|
@@ -1104,6 +1143,17 @@ func GetKiroModels() []*ModelInfo {
|
|
| 1104 |
MaxCompletionTokens: 64000,
|
| 1105 |
Thinking: &ThinkingSupport{Min: 1024, Max: 32000, ZeroAllowed: true, DynamicAllowed: true},
|
| 1106 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1107 |
}
|
| 1108 |
}
|
| 1109 |
|
|
@@ -1166,5 +1216,15 @@ func GetAmazonQModels() []*ModelInfo {
|
|
| 1166 |
ContextLength: 200000,
|
| 1167 |
MaxCompletionTokens: 64000,
|
| 1168 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1169 |
}
|
| 1170 |
}
|
|
|
|
| 85 |
MaxCompletionTokens: 8192,
|
| 86 |
Thinking: &ThinkingSupport{Min: 1024, Max: 100000, ZeroAllowed: false, DynamicAllowed: true},
|
| 87 |
},
|
| 88 |
+
{
|
| 89 |
+
ID: "claude-3-5-sonnet-20241022",
|
| 90 |
+
Object: "model",
|
| 91 |
+
Created: 1729555200, // 2024-10-22
|
| 92 |
+
OwnedBy: "anthropic",
|
| 93 |
+
Type: "claude",
|
| 94 |
+
DisplayName: "Claude 3.5 Sonnet",
|
| 95 |
+
ContextLength: 200000,
|
| 96 |
+
MaxCompletionTokens: 8192,
|
| 97 |
+
Thinking: &ThinkingSupport{Min: 1024, Max: 100000, ZeroAllowed: false, DynamicAllowed: true},
|
| 98 |
+
},
|
| 99 |
{
|
| 100 |
ID: "claude-3-5-haiku-20241022",
|
| 101 |
Object: "model",
|
|
|
|
| 203 |
SupportedGenerationMethods: []string{"generateContent", "countTokens", "createCachedContent", "batchGenerateContent"},
|
| 204 |
Thinking: &ThinkingSupport{Min: 128, Max: 32768, ZeroAllowed: false, DynamicAllowed: true, Levels: []string{"low", "high"}},
|
| 205 |
},
|
| 206 |
+
{
|
| 207 |
+
ID: "gemini-1.5-pro",
|
| 208 |
+
Object: "model",
|
| 209 |
+
Created: 1715644800,
|
| 210 |
+
OwnedBy: "google",
|
| 211 |
+
Type: "gemini",
|
| 212 |
+
Name: "models/gemini-1.5-pro",
|
| 213 |
+
Version: "1.5",
|
| 214 |
+
DisplayName: "Gemini 1.5 Pro",
|
| 215 |
+
Description: "Gemini 1.5 Pro reflects our latest research and engineering, including our work on multimodal large-scale training and our work in making models more efficient to serve while maintaining maximum quality.",
|
| 216 |
+
InputTokenLimit: 1048576,
|
| 217 |
+
OutputTokenLimit: 8192,
|
| 218 |
+
SupportedGenerationMethods: []string{"generateContent", "countTokens", "createCachedContent", "batchGenerateContent"},
|
| 219 |
+
},
|
| 220 |
+
{
|
| 221 |
+
ID: "gemini-1.5-flash",
|
| 222 |
+
Object: "model",
|
| 223 |
+
Created: 1715644800,
|
| 224 |
+
OwnedBy: "google",
|
| 225 |
+
Type: "gemini",
|
| 226 |
+
Name: "models/gemini-1.5-flash",
|
| 227 |
+
Version: "1.5",
|
| 228 |
+
DisplayName: "Gemini 1.5 Flash",
|
| 229 |
+
Description: "Fast and versatile multimodal model for scaling across a diverse range of tasks.",
|
| 230 |
+
InputTokenLimit: 1048576,
|
| 231 |
+
OutputTokenLimit: 8192,
|
| 232 |
+
SupportedGenerationMethods: []string{"generateContent", "countTokens", "createCachedContent", "batchGenerateContent"},
|
| 233 |
+
},
|
| 234 |
}
|
| 235 |
}
|
| 236 |
|
|
|
|
| 1143 |
MaxCompletionTokens: 64000,
|
| 1144 |
Thinking: &ThinkingSupport{Min: 1024, Max: 32000, ZeroAllowed: true, DynamicAllowed: true},
|
| 1145 |
},
|
| 1146 |
+
{
|
| 1147 |
+
ID: "claude-3-5-sonnet-20241022",
|
| 1148 |
+
Object: "model",
|
| 1149 |
+
Created: 1729555200, // 2024-10-22
|
| 1150 |
+
OwnedBy: "aws",
|
| 1151 |
+
Type: "kiro",
|
| 1152 |
+
DisplayName: "Claude 3.5 Sonnet (via Kiro)",
|
| 1153 |
+
ContextLength: 200000,
|
| 1154 |
+
MaxCompletionTokens: 8192,
|
| 1155 |
+
Thinking: &ThinkingSupport{Min: 1024, Max: 32000, ZeroAllowed: true, DynamicAllowed: true},
|
| 1156 |
+
},
|
| 1157 |
}
|
| 1158 |
}
|
| 1159 |
|
|
|
|
| 1216 |
ContextLength: 200000,
|
| 1217 |
MaxCompletionTokens: 64000,
|
| 1218 |
},
|
| 1219 |
+
{
|
| 1220 |
+
ID: "claude-3-5-sonnet-20241022",
|
| 1221 |
+
Object: "model",
|
| 1222 |
+
Created: 1729555200,
|
| 1223 |
+
OwnedBy: "aws",
|
| 1224 |
+
Type: "kiro",
|
| 1225 |
+
DisplayName: "Claude 3.5 Sonnet (via Q)",
|
| 1226 |
+
ContextLength: 200000,
|
| 1227 |
+
MaxCompletionTokens: 8192,
|
| 1228 |
+
},
|
| 1229 |
}
|
| 1230 |
}
|
internal/runtime/executor/claude_executor.go
CHANGED
|
@@ -116,7 +116,7 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r
|
|
| 116 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 117 |
b, _ := io.ReadAll(httpResp.Body)
|
| 118 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 119 |
-
log.
|
| 120 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 121 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 122 |
log.Errorf("response body close error: %v", errClose)
|
|
@@ -228,7 +228,7 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A
|
|
| 228 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 229 |
b, _ := io.ReadAll(httpResp.Body)
|
| 230 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 231 |
-
log.
|
| 232 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 233 |
log.Errorf("response body close error: %v", errClose)
|
| 234 |
}
|
|
|
|
| 116 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 117 |
b, _ := io.ReadAll(httpResp.Body)
|
| 118 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 119 |
+
log.Warnf("claude executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 120 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 121 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 122 |
log.Errorf("response body close error: %v", errClose)
|
|
|
|
| 228 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 229 |
b, _ := io.ReadAll(httpResp.Body)
|
| 230 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 231 |
+
log.Warnf("claude executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 232 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 233 |
log.Errorf("response body close error: %v", errClose)
|
| 234 |
}
|
internal/runtime/executor/codex_executor.go
CHANGED
|
@@ -110,7 +110,7 @@ func (e *CodexExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, re
|
|
| 110 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 111 |
b, _ := io.ReadAll(httpResp.Body)
|
| 112 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 113 |
-
log.
|
| 114 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 115 |
return resp, err
|
| 116 |
}
|
|
@@ -218,7 +218,7 @@ func (e *CodexExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Au
|
|
| 218 |
return nil, readErr
|
| 219 |
}
|
| 220 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 221 |
-
log.
|
| 222 |
err = statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 223 |
return nil, err
|
| 224 |
}
|
|
|
|
| 110 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 111 |
b, _ := io.ReadAll(httpResp.Body)
|
| 112 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 113 |
+
log.Warnf("codex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 114 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 115 |
return resp, err
|
| 116 |
}
|
|
|
|
| 218 |
return nil, readErr
|
| 219 |
}
|
| 220 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 221 |
+
log.Warnf("codex executor: upstream API error (stream), status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
|
| 222 |
err = statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 223 |
return nil, err
|
| 224 |
}
|
internal/runtime/executor/gemini_cli_executor.go
CHANGED
|
@@ -186,7 +186,7 @@ func (e *GeminiCLIExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth
|
|
| 186 |
|
| 187 |
lastStatus = httpResp.StatusCode
|
| 188 |
lastBody = append([]byte(nil), data...)
|
| 189 |
-
log.
|
| 190 |
if httpResp.StatusCode == 429 {
|
| 191 |
if idx+1 < len(models) {
|
| 192 |
log.Debugf("gemini cli executor: rate limited, retrying with next model: %s", models[idx+1])
|
|
@@ -313,7 +313,7 @@ func (e *GeminiCLIExecutor) ExecuteStream(ctx context.Context, auth *cliproxyaut
|
|
| 313 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 314 |
lastStatus = httpResp.StatusCode
|
| 315 |
lastBody = append([]byte(nil), data...)
|
| 316 |
-
log.
|
| 317 |
if httpResp.StatusCode == 429 {
|
| 318 |
if idx+1 < len(models) {
|
| 319 |
log.Debugf("gemini cli executor: rate limited, retrying with next model: %s", models[idx+1])
|
|
|
|
| 186 |
|
| 187 |
lastStatus = httpResp.StatusCode
|
| 188 |
lastBody = append([]byte(nil), data...)
|
| 189 |
+
log.Warnf("gemini-cli executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
|
| 190 |
if httpResp.StatusCode == 429 {
|
| 191 |
if idx+1 < len(models) {
|
| 192 |
log.Debugf("gemini cli executor: rate limited, retrying with next model: %s", models[idx+1])
|
|
|
|
| 313 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 314 |
lastStatus = httpResp.StatusCode
|
| 315 |
lastBody = append([]byte(nil), data...)
|
| 316 |
+
log.Warnf("gemini-cli executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
|
| 317 |
if httpResp.StatusCode == 429 {
|
| 318 |
if idx+1 < len(models) {
|
| 319 |
log.Debugf("gemini cli executor: rate limited, retrying with next model: %s", models[idx+1])
|
internal/runtime/executor/gemini_executor.go
CHANGED
|
@@ -157,7 +157,7 @@ func (e *GeminiExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r
|
|
| 157 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 158 |
b, _ := io.ReadAll(httpResp.Body)
|
| 159 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 160 |
-
log.
|
| 161 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 162 |
return resp, err
|
| 163 |
}
|
|
@@ -251,12 +251,8 @@ func (e *GeminiExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A
|
|
| 251 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 252 |
b, _ := io.ReadAll(httpResp.Body)
|
| 253 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 254 |
-
log.
|
| 255 |
-
|
| 256 |
-
log.Errorf("gemini executor: close response body error: %v", errClose)
|
| 257 |
-
}
|
| 258 |
-
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 259 |
-
return nil, err
|
| 260 |
}
|
| 261 |
out := make(chan cliproxyexecutor.StreamChunk)
|
| 262 |
stream = out
|
|
@@ -370,7 +366,7 @@ func (e *GeminiExecutor) CountTokens(ctx context.Context, auth *cliproxyauth.Aut
|
|
| 370 |
}
|
| 371 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 372 |
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
| 373 |
-
log.
|
| 374 |
return cliproxyexecutor.Response{}, statusErr{code: resp.StatusCode, msg: string(data)}
|
| 375 |
}
|
| 376 |
|
|
|
|
| 157 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 158 |
b, _ := io.ReadAll(httpResp.Body)
|
| 159 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 160 |
+
log.Warnf("gemini executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 161 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 162 |
return resp, err
|
| 163 |
}
|
|
|
|
| 251 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 252 |
b, _ := io.ReadAll(httpResp.Body)
|
| 253 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 254 |
+
log.Warnf("gemini executor: upstream API error (stream), status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 255 |
+
return nil, statusErr{code: httpResp.StatusCode, msg: string(b)}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
}
|
| 257 |
out := make(chan cliproxyexecutor.StreamChunk)
|
| 258 |
stream = out
|
|
|
|
| 366 |
}
|
| 367 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 368 |
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
| 369 |
+
log.Warnf("gemini executor: upstream API error, status: %d, body: %s", resp.StatusCode, summarizeErrorBody(resp.Header.Get("Content-Type"), data))
|
| 370 |
return cliproxyexecutor.Response{}, statusErr{code: resp.StatusCode, msg: string(data)}
|
| 371 |
}
|
| 372 |
|
internal/runtime/executor/gemini_vertex_executor.go
CHANGED
|
@@ -201,7 +201,7 @@ func (e *GeminiVertexExecutor) executeWithServiceAccount(ctx context.Context, au
|
|
| 201 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 202 |
b, _ := io.ReadAll(httpResp.Body)
|
| 203 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 204 |
-
log.
|
| 205 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 206 |
return resp, err
|
| 207 |
}
|
|
@@ -310,7 +310,7 @@ func (e *GeminiVertexExecutor) executeWithAPIKey(ctx context.Context, auth *clip
|
|
| 310 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 311 |
b, _ := io.ReadAll(httpResp.Body)
|
| 312 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 313 |
-
log.
|
| 314 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 315 |
return resp, err
|
| 316 |
}
|
|
@@ -404,7 +404,7 @@ func (e *GeminiVertexExecutor) executeStreamWithServiceAccount(ctx context.Conte
|
|
| 404 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 405 |
b, _ := io.ReadAll(httpResp.Body)
|
| 406 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 407 |
-
log.
|
| 408 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 409 |
log.Errorf("vertex executor: close response body error: %v", errClose)
|
| 410 |
}
|
|
@@ -529,7 +529,7 @@ func (e *GeminiVertexExecutor) executeStreamWithAPIKey(ctx context.Context, auth
|
|
| 529 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 530 |
b, _ := io.ReadAll(httpResp.Body)
|
| 531 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 532 |
-
log.
|
| 533 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 534 |
log.Errorf("vertex executor: close response body error: %v", errClose)
|
| 535 |
}
|
|
@@ -641,7 +641,7 @@ func (e *GeminiVertexExecutor) countTokensWithServiceAccount(ctx context.Context
|
|
| 641 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 642 |
b, _ := io.ReadAll(httpResp.Body)
|
| 643 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 644 |
-
log.
|
| 645 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 646 |
}
|
| 647 |
data, errRead := io.ReadAll(httpResp.Body)
|
|
@@ -651,7 +651,7 @@ func (e *GeminiVertexExecutor) countTokensWithServiceAccount(ctx context.Context
|
|
| 651 |
}
|
| 652 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 653 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 654 |
-
log.
|
| 655 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 656 |
}
|
| 657 |
count := gjson.GetBytes(data, "totalTokens").Int()
|
|
@@ -733,7 +733,7 @@ func (e *GeminiVertexExecutor) countTokensWithAPIKey(ctx context.Context, auth *
|
|
| 733 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 734 |
b, _ := io.ReadAll(httpResp.Body)
|
| 735 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 736 |
-
log.
|
| 737 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 738 |
}
|
| 739 |
data, errRead := io.ReadAll(httpResp.Body)
|
|
@@ -743,7 +743,7 @@ func (e *GeminiVertexExecutor) countTokensWithAPIKey(ctx context.Context, auth *
|
|
| 743 |
}
|
| 744 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 745 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 746 |
-
log.
|
| 747 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 748 |
}
|
| 749 |
count := gjson.GetBytes(data, "totalTokens").Int()
|
|
|
|
| 201 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 202 |
b, _ := io.ReadAll(httpResp.Body)
|
| 203 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 204 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 205 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 206 |
return resp, err
|
| 207 |
}
|
|
|
|
| 310 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 311 |
b, _ := io.ReadAll(httpResp.Body)
|
| 312 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 313 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 314 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 315 |
return resp, err
|
| 316 |
}
|
|
|
|
| 404 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 405 |
b, _ := io.ReadAll(httpResp.Body)
|
| 406 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 407 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 408 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 409 |
log.Errorf("vertex executor: close response body error: %v", errClose)
|
| 410 |
}
|
|
|
|
| 529 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 530 |
b, _ := io.ReadAll(httpResp.Body)
|
| 531 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 532 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 533 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 534 |
log.Errorf("vertex executor: close response body error: %v", errClose)
|
| 535 |
}
|
|
|
|
| 641 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 642 |
b, _ := io.ReadAll(httpResp.Body)
|
| 643 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 644 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 645 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 646 |
}
|
| 647 |
data, errRead := io.ReadAll(httpResp.Body)
|
|
|
|
| 651 |
}
|
| 652 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 653 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 654 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
|
| 655 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 656 |
}
|
| 657 |
count := gjson.GetBytes(data, "totalTokens").Int()
|
|
|
|
| 733 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 734 |
b, _ := io.ReadAll(httpResp.Body)
|
| 735 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 736 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 737 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 738 |
}
|
| 739 |
data, errRead := io.ReadAll(httpResp.Body)
|
|
|
|
| 743 |
}
|
| 744 |
appendAPIResponseChunk(ctx, e.cfg, data)
|
| 745 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 746 |
+
log.Warnf("gemini-vertex executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), data))
|
| 747 |
return cliproxyexecutor.Response{}, statusErr{code: httpResp.StatusCode, msg: string(data)}
|
| 748 |
}
|
| 749 |
count := gjson.GetBytes(data, "totalTokens").Int()
|
internal/runtime/executor/openai_compat_executor.go
CHANGED
|
@@ -119,7 +119,7 @@ func (e *OpenAICompatExecutor) Execute(ctx context.Context, auth *cliproxyauth.A
|
|
| 119 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 120 |
b, _ := io.ReadAll(httpResp.Body)
|
| 121 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 122 |
-
log.
|
| 123 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 124 |
return resp, err
|
| 125 |
}
|
|
@@ -213,7 +213,7 @@ func (e *OpenAICompatExecutor) ExecuteStream(ctx context.Context, auth *cliproxy
|
|
| 213 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 214 |
b, _ := io.ReadAll(httpResp.Body)
|
| 215 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 216 |
-
log.
|
| 217 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 218 |
log.Errorf("openai compat executor: close response body error: %v", errClose)
|
| 219 |
}
|
|
|
|
| 119 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 120 |
b, _ := io.ReadAll(httpResp.Body)
|
| 121 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 122 |
+
log.Warnf("openai-compat executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 123 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 124 |
return resp, err
|
| 125 |
}
|
|
|
|
| 213 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 214 |
b, _ := io.ReadAll(httpResp.Body)
|
| 215 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 216 |
+
log.Warnf("openai-compat executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 217 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 218 |
log.Errorf("openai compat executor: close response body error: %v", errClose)
|
| 219 |
}
|
internal/runtime/executor/qwen_executor.go
CHANGED
|
@@ -102,7 +102,7 @@ func (e *QwenExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, req
|
|
| 102 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 103 |
b, _ := io.ReadAll(httpResp.Body)
|
| 104 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 105 |
-
log.
|
| 106 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 107 |
return resp, err
|
| 108 |
}
|
|
@@ -186,7 +186,7 @@ func (e *QwenExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Aut
|
|
| 186 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 187 |
b, _ := io.ReadAll(httpResp.Body)
|
| 188 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 189 |
-
log.
|
| 190 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 191 |
log.Errorf("qwen executor: close response body error: %v", errClose)
|
| 192 |
}
|
|
|
|
| 102 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 103 |
b, _ := io.ReadAll(httpResp.Body)
|
| 104 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 105 |
+
log.Warnf("qwen executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 106 |
err = statusErr{code: httpResp.StatusCode, msg: string(b)}
|
| 107 |
return resp, err
|
| 108 |
}
|
|
|
|
| 186 |
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
| 187 |
b, _ := io.ReadAll(httpResp.Body)
|
| 188 |
appendAPIResponseChunk(ctx, e.cfg, b)
|
| 189 |
+
log.Warnf("qwen executor: upstream API error, status: %d, body: %s", httpResp.StatusCode, summarizeErrorBody(httpResp.Header.Get("Content-Type"), b))
|
| 190 |
if errClose := httpResp.Body.Close(); errClose != nil {
|
| 191 |
log.Errorf("qwen executor: close response body error: %v", errClose)
|
| 192 |
}
|
static/management.html
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|