Skip to content

Commit 969d25b

Browse files
committed
feat(core): add OAuth model policy plugin
1 parent b1a49f1 commit 969d25b

23 files changed

Lines changed: 1620 additions & 37 deletions

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ updates:
1616
directory: /cliproxyapi-pro-plugins/proxy-pool
1717
schedule:
1818
interval: weekly
19+
- package-ecosystem: gomod
20+
directory: /cliproxyapi-pro-plugins/oauth-model-policy
21+
schedule:
22+
interval: weekly

.github/workflows/release-core.yml

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ jobs:
283283
cp "${tmp_dir}/arm64/cli-proxy-api" "${context_dir}/binaries/linux/arm64/CLIProxyAPI"
284284
cp "${tmp_dir}/amd64/plugins/linux/amd64/proxy-pool.so" "${context_dir}/plugins/linux/amd64/proxy-pool.so"
285285
cp "${tmp_dir}/arm64/plugins/linux/arm64/proxy-pool.so" "${context_dir}/plugins/linux/arm64/proxy-pool.so"
286+
cp "${tmp_dir}/amd64/plugins/linux/amd64/oauth-model-policy.so" "${context_dir}/plugins/linux/amd64/oauth-model-policy.so"
287+
cp "${tmp_dir}/arm64/plugins/linux/arm64/oauth-model-policy.so" "${context_dir}/plugins/linux/arm64/oauth-model-policy.so"
286288
cp "${tmp_dir}/amd64/config.example.yaml" "${context_dir}/config.example.yaml"
287289
cp customizations-repo/cliproxyapi-pro-core/entrypoint.sh "${context_dir}/entrypoint.sh"
288290
cp customizations-repo/cliproxyapi-pro-core/Dockerfile.runtime "${context_dir}/Dockerfile.runtime"
@@ -294,7 +296,9 @@ jobs:
294296
"${context_dir}/binaries/linux/amd64/CLIProxyAPI" \
295297
"${context_dir}/binaries/linux/arm64/CLIProxyAPI" \
296298
"${context_dir}/plugins/linux/amd64/proxy-pool.so" \
297-
"${context_dir}/plugins/linux/arm64/proxy-pool.so"
299+
"${context_dir}/plugins/linux/arm64/proxy-pool.so" \
300+
"${context_dir}/plugins/linux/amd64/oauth-model-policy.so" \
301+
"${context_dir}/plugins/linux/arm64/oauth-model-policy.so"
298302
299303
- name: Set up QEMU
300304
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
@@ -524,23 +528,27 @@ jobs:
524528
plugin_extension="so"
525529
if [ "${GOOS}" = "darwin" ]; then plugin_extension="dylib"; fi
526530
if [ "${GOOS}" = "windows" ]; then plugin_extension="dll"; fi
527-
plugin_relative="plugins/${GOOS}/${GOARCH}/proxy-pool.${plugin_extension}"
528-
plugin_source=".proxy-pool-build"
529-
rm -rf "${plugin_source}"
530-
cp -R ../customizations-repo/cliproxyapi-pro-plugins/proxy-pool "${plugin_source}"
531-
go -C "${plugin_source}" mod edit -replace github.com/router-for-me/CLIProxyAPI/v7=..
532531
mkdir -p "${archive_dir}/plugins/${GOOS}/${GOARCH}"
533-
CGO_ENABLED=1 GOOS="${GOOS}" GOARCH="${GOARCH}" go -C "${plugin_source}" build \
534-
-buildvcs=false -trimpath -buildmode=c-shared \
535-
-o "${PWD}/${archive_dir}/${plugin_relative}" .
532+
plugin_relatives=()
533+
for plugin_name in proxy-pool oauth-model-policy; do
534+
plugin_relative="plugins/${GOOS}/${GOARCH}/${plugin_name}.${plugin_extension}"
535+
plugin_source=".${plugin_name}-build"
536+
rm -rf "${plugin_source}"
537+
cp -R "../customizations-repo/cliproxyapi-pro-plugins/${plugin_name}" "${plugin_source}"
538+
go -C "${plugin_source}" mod edit -replace github.com/router-for-me/CLIProxyAPI/v7=..
539+
CGO_ENABLED=1 GOOS="${GOOS}" GOARCH="${GOARCH}" go -C "${plugin_source}" build \
540+
-buildvcs=false -trimpath -buildmode=c-shared \
541+
-o "${PWD}/${archive_dir}/${plugin_relative}" .
542+
plugin_relatives+=("${plugin_relative}")
543+
done
536544
537545
cp LICENSE README.md README_EN.md config.example.yaml "${archive_dir}/"
538546
python ../customizations-repo/scripts/build/create_reproducible_archive.py \
539547
--format "${ARCHIVE_FORMAT}" \
540548
--output "dist/${archive_name}" \
541549
--root "${archive_dir}" \
542550
--source-date-epoch "${SOURCE_DATE_EPOCH}" \
543-
"${binary_name}" LICENSE README.md README_EN.md config.example.yaml "${plugin_relative}"
551+
"${binary_name}" LICENSE README.md README_EN.md config.example.yaml "${plugin_relatives[@]}"
544552
545553
- name: Build Linux glibc plugin-capable archive
546554
if: matrix.kind == 'linux-glibc-plugin'
@@ -560,8 +568,10 @@ jobs:
560568
archive_name="CLIProxyAPI_${RELEASE_TAG#v}_linux_${ASSET_ARCH}.tar.gz"
561569
rm -rf "dist/linux-${GOARCH}"
562570
mkdir -p "${archive_dir}"
563-
rm -rf .proxy-pool-build
564-
cp -R ../customizations-repo/cliproxyapi-pro-plugins/proxy-pool .proxy-pool-build
571+
for plugin_name in proxy-pool oauth-model-policy; do
572+
rm -rf ".${plugin_name}-build"
573+
cp -R "../customizations-repo/cliproxyapi-pro-plugins/${plugin_name}" ".${plugin_name}-build"
574+
done
565575
566576
go_archive="go${GO_VERSION}.linux-${GOARCH}.tar.gz"
567577
go_sha256="$(
@@ -595,11 +605,13 @@ jobs:
595605
-ldflags="-s -w -X main.Version=${RELEASE_TAG} -X main.Commit=release-${CORE_TAG} -X main.BuildDate=${BUILD_DATE}" \
596606
-o "'"${archive_dir}"'/cli-proxy-api" ./cmd/server/
597607
598-
go -C .proxy-pool-build mod edit -replace github.com/router-for-me/CLIProxyAPI/v7=/src
599608
mkdir -p "'"${archive_dir}"'/plugins/linux/${GOARCH}"
600-
CGO_ENABLED=1 GOOS=linux GOARCH="${GOARCH}" go -C .proxy-pool-build build \
601-
-buildvcs=false -trimpath -buildmode=c-shared \
602-
-o "/src/'"${archive_dir}"'/plugins/linux/${GOARCH}/proxy-pool.so" .
609+
for plugin_name in proxy-pool oauth-model-policy; do
610+
go -C ".${plugin_name}-build" mod edit -replace github.com/router-for-me/CLIProxyAPI/v7=/src
611+
CGO_ENABLED=1 GOOS=linux GOARCH="${GOARCH}" go -C ".${plugin_name}-build" build \
612+
-buildvcs=false -trimpath -buildmode=c-shared \
613+
-o "/src/'"${archive_dir}"'/plugins/linux/${GOARCH}/${plugin_name}.so" .
614+
done
603615
604616
glibc_versions="$(readelf --version-info "'"${archive_dir}"'/cli-proxy-api" | sed -n "s/.*Name: GLIBC_\([0-9.]*\).*/\1/p" | sort -Vu)"
605617
if [ -n "${glibc_versions}" ]; then
@@ -618,7 +630,9 @@ jobs:
618630
--output "dist/${archive_name}" \
619631
--root "${archive_dir}" \
620632
--source-date-epoch "${SOURCE_DATE_EPOCH}" \
621-
cli-proxy-api LICENSE README.md README_EN.md config.example.yaml "plugins/linux/${GOARCH}/proxy-pool.so"
633+
cli-proxy-api LICENSE README.md README_EN.md config.example.yaml \
634+
"plugins/linux/${GOARCH}/proxy-pool.so" \
635+
"plugins/linux/${GOARCH}/oauth-model-policy.so"
622636
623637
- name: Install FreeBSD plugin build dependencies
624638
if: matrix.kind == 'freebsd-plugin'

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CLIProxyAPI Pro 是对两个 upstream 项目的最小化定制层集合:
1616
- 账号巡检针对 Antigravity 软封禁和 xAI 可用性异常提供可选深度检测
1717
- 路由策略页面统一管理 upstream 路由行为与按 provider 配置的请求状态保护
1818
- 内置动态代理池插件,把多个 HTTP/SOCKS 节点汇聚为固定的本地 SOCKS5 地址,支持轮询、加权、健康隔离与故障转移
19+
- 内置 OAuth 模型策略插件,首期可按 xAI 账号套餐分别排除不可用模型,并同步约束模型列表和账号调度
1920

2021
## 项目结构
2122

@@ -36,7 +37,8 @@ CLIProxyAPI Pro 是对两个 upstream 项目的最小化定制层集合:
3637
│ └── overlay/
3738
3839
├── cliproxyapi-pro-plugins/
39-
│ └── proxy-pool/
40+
│ ├── proxy-pool/
41+
│ └── oauth-model-policy/
4042
4143
├── scripts/validation/
4244
└── .github/workflows/
@@ -62,11 +64,12 @@ CLIProxyAPI Pro 是对两个 upstream 项目的最小化定制层集合:
6264
- 支持 SQLite-backed quota cache。
6365
- 支持模型价格持久化。
6466
- 支持 QuotaProvider 插件协议和 Gemini CLI legacy adapter。
67+
- 支持通用 `AuthModelFilter` 插件协议;预打包的 `oauth-model-policy` 首期可按 xAI OAuth 套餐排除模型。
6568
- 启动时在内存中强制必要 upstream 配置;仅修改 YAML 中已存在的键,禁止自动新增键。
6669
- 支持后端账号巡检调度器和执行器,巡检探测前可刷新 token。
6770
- 支持统一路由策略与请求状态保护 API。
6871
- 支持 Komari agent 可选启动。
69-
- 标准 macOS、Windows amd64、Linux Release 和 Docker 镜像预打包 `proxy-pool` 动态插件;Windows ARM64、FreeBSD 与 `_no-plugin` 产物暂不内置代理池
72+
- 标准 macOS、Windows amd64、Linux Release 和 Docker 镜像预打包 `proxy-pool` `oauth-model-policy` 动态插件;Windows ARM64、FreeBSD 与 `_no-plugin` 产物暂不内置动态插件
7073
-`/` 跳转到 `/management.html`
7174
- 增强 `/healthz` 返回信息。
7275

README_EN.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This project does not maintain a full fork of either upstream project. Instead,
1616
- Optional deep probes for Antigravity soft bans and xAI availability anomalies.
1717
- A routing-policy page for upstream routing behavior and provider-scoped request-state protection.
1818
- A bundled dynamic proxy-pool plugin that aggregates HTTP/SOCKS nodes behind one fixed loopback SOCKS5 endpoint with rotation, health isolation, and failover.
19+
- A bundled OAuth model-policy plugin that initially removes unavailable models per xAI account plan and constrains both model listing and auth scheduling.
1920

2021
## Repository layout
2122

@@ -36,7 +37,8 @@ This project does not maintain a full fork of either upstream project. Instead,
3637
│ └── overlay/
3738
3839
├── cliproxyapi-pro-plugins/
39-
│ └── proxy-pool/
40+
│ ├── proxy-pool/
41+
│ └── oauth-model-policy/
4042
4143
├── scripts/validation/
4244
└── .github/workflows/
@@ -62,11 +64,12 @@ Main capabilities:
6264
- Supports SQLite-backed quota cache.
6365
- Supports model price persistence.
6466
- Supports the QuotaProvider plugin protocol and a Gemini CLI legacy adapter.
67+
- Supports a generic `AuthModelFilter` plugin protocol; the bundled `oauth-model-policy` initially filters xAI OAuth models by account plan.
6568
- Forces required upstream startup config: `usage-statistics-enabled=true` and the Pro management panel repository.
6669
- Adds a backend account-inspection scheduler and executor with token refresh before probing.
6770
- Adds unified routing-policy and request-state-protection APIs.
6871
- Optionally starts the Komari agent.
69-
- Prebundles the `proxy-pool` dynamic library in standard macOS, Windows amd64, and Linux releases plus Docker images; Windows ARM64, FreeBSD, and `_no-plugin` assets do not currently bundle it.
72+
- Prebundles the `proxy-pool` and `oauth-model-policy` dynamic libraries in standard macOS, Windows amd64, and Linux releases plus Docker images; Windows ARM64, FreeBSD, and `_no-plugin` assets do not currently bundle dynamic plugins.
7073
- Redirects `/` to `/management.html`.
7174
- Enhances the `/healthz` response.
7275

cliproxyapi-pro-core/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ RUN set -eux; \
3737
COPY cliproxyapi-pro-core/embeddedusage /tmp/embeddedusage
3838
COPY cliproxyapi-pro-core/patches /tmp/patches
3939
COPY cliproxyapi-pro-plugins/proxy-pool /tmp/proxy-pool
40+
COPY cliproxyapi-pro-plugins/oauth-model-policy /tmp/oauth-model-policy
4041

4142
RUN python3 /tmp/patches/apply_upstream_patches.py
4243

@@ -47,6 +48,13 @@ RUN set -eux; \
4748
CGO_ENABLED=1 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
4849
go build -buildvcs=false -trimpath -buildmode=c-shared -o /out/proxy-pool.so .
4950

51+
RUN set -eux; \
52+
cd /tmp/oauth-model-policy; \
53+
go mod edit -replace github.com/router-for-me/CLIProxyAPI/v7=/src/CLIProxyAPI; \
54+
go mod tidy; \
55+
CGO_ENABLED=1 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
56+
go build -buildvcs=false -trimpath -buildmode=c-shared -o /out/oauth-model-policy.so .
57+
5058
RUN set -eux; \
5159
go mod tidy; \
5260
CLIPROXY_SOURCE_VERSION="$(cat /tmp/cliproxy-version)"; \
@@ -77,6 +85,7 @@ WORKDIR /CLIProxyAPI
7785

7886
COPY --from=builder /out/CLIProxyAPI /CLIProxyAPI/CLIProxyAPI
7987
COPY --from=builder /out/proxy-pool.so /CLIProxyAPI/plugins/linux/${TARGETARCH}/proxy-pool.so
88+
COPY --from=builder /out/oauth-model-policy.so /CLIProxyAPI/plugins/linux/${TARGETARCH}/oauth-model-policy.so
8089
COPY --from=builder /src/CLIProxyAPI/config.example.yaml /CLIProxyAPI/config.example.yaml
8190
COPY cliproxyapi-pro-core/entrypoint.sh /CLIProxyAPI/entrypoint.sh
8291

cliproxyapi-pro-core/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
本目录不维护 upstream 的完整 fork。Docker 构建时会下载指定 upstream release,复制本地 `embeddedusage/` 包,执行 `patches/` 中的补丁脚本,然后构建 Pro 部署使用的多架构镜像。
66

7-
标准 macOS、Windows amd64、Linux Pro Release 与 Docker 镜像还会预打包 `cliproxyapi-pro-plugins/proxy-pool` 动态插件。插件在回环地址提供固定 SOCKS5 入口,Core 继续使用单一 `proxy-url`,节点轮询、健康隔离和故障转移由插件完成,不修改 upstream 的代理执行路径。Windows ARM64、FreeBSD 与 `_no-plugin` 资产暂不内置该功能
7+
标准 macOS、Windows amd64、Linux Pro Release 与 Docker 镜像会预打包 `proxy-pool` `oauth-model-policy` 动态插件。前者在回环地址提供固定 SOCKS5 入口;后者首期按 xAI OAuth 套餐排除账号不可用的模型。Windows ARM64、FreeBSD 与 `_no-plugin` 资产暂不内置动态插件
88

99
## 定制内容
1010

@@ -137,6 +137,12 @@ detail 还会保留 upstream `ClientRequestMetadata` 提供的 `client_ip`、`x_
137137
`Executor.HttpRequest` 提供兼容适配;插件未来原生实现协议后会自动优先使用原生能力。
138138
协议字段与兼容策略见 [QUOTA_PROVIDER.md](QUOTA_PROVIDER.md)
139139

140+
### OAuth 套餐模型策略插件
141+
142+
补丁层为 upstream 插件 SDK/ABI 增加通用 `AuthModelFilter` 能力。Core 只提供当前 auth、原始模型集合和受控 HTTP callback,并强制插件只能减去已有模型;套餐识别与规则均位于预打包的 `oauth-model-policy` 插件中。
143+
144+
首期仅支持 xAI OAuth,规则键包括 `free``supergrok``x-premium-plus``supergrok-heavy``paid-unknown` 以及 `_unknown` 回退。处理顺序为 upstream `excluded_models`、插件套餐过滤、OAuth alias/prefix、模型注册。最终注册结果同时约束 `/v1/models` 聚合和请求调度候选账号。配置与探测细节见 `cliproxyapi-pro-plugins/oauth-model-policy/README.md`
145+
140146
### 后端账号巡检调度器
141147

142148
补丁层在 management API 下增加账号巡检路由:
@@ -227,6 +233,7 @@ https://github.com/ssfun/CLIProxyAPI-Pro
227233
- `Dockerfile` — 下载 upstream CLIProxyAPI,应用定制层,并构建最终镜像。
228234
- `Dockerfile.runtime` — GitHub Actions 使用预构建 Linux 二进制组装运行时镜像。
229235
- `QUOTA_PROVIDER.md` — QuotaProvider 插件协议和兼容策略。
236+
- `../cliproxyapi-pro-plugins/oauth-model-policy/` — 按 OAuth 套餐过滤账号模型的动态插件。
230237
- `entrypoint.sh` — 启动 Komari、主 API 和 WebDAV usage 恢复逻辑。
231238
- `embeddedusage/` — 内嵌 SQLite usage service 和 management routes。
232239
- `patches/apply_upstream_patches.py` — Docker build 阶段 patch upstream 源码。

cliproxyapi-pro-core/README_EN.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Customized Docker build layer for upstream `router-for-me/CLIProxyAPI`.
44

55
This directory does not maintain a full fork of upstream. During Docker build it downloads an upstream release, copies in the local `embeddedusage/` package, applies the patch script in `patches/`, and builds a multi-arch image for the Pro deployment.
66

7-
Standard macOS, Windows amd64, and Linux Pro releases plus Docker images prebundle the `cliproxyapi-pro-plugins/proxy-pool` dynamic plugin. It exposes a fixed loopback SOCKS5 endpoint while rotation, health isolation, and failover stay inside the plugin, so upstream's proxy execution path is unchanged. Windows ARM64, FreeBSD, and `_no-plugin` assets do not currently bundle this feature.
7+
Standard macOS, Windows amd64, and Linux Pro releases plus Docker images prebundle the `proxy-pool` and `oauth-model-policy` dynamic plugins. The former exposes a fixed loopback SOCKS5 endpoint; the latter initially removes models unavailable to each xAI OAuth plan. Windows ARM64, FreeBSD, and `_no-plugin` assets do not currently bundle dynamic plugins.
88

99
## What this customization adds
1010

@@ -138,6 +138,12 @@ changes: Core adapts its existing `Executor.HttpRequest`; a future native implem
138138
priority automatically. See [QUOTA_PROVIDER.md](QUOTA_PROVIDER.md) for the schema and compatibility
139139
rules.
140140

141+
### OAuth plan model policy plugin
142+
143+
The patch layer adds a generic `AuthModelFilter` capability to the upstream plugin SDK/ABI. Core provides the current auth, its native model set, and a controlled HTTP callback, while enforcing that a plugin may only subtract existing models. Plan discovery and policy rules stay in the bundled `oauth-model-policy` plugin.
144+
145+
The first version supports xAI OAuth with `free`, `supergrok`, `x-premium-plus`, `supergrok-heavy`, `paid-unknown`, and `_unknown` fallback rules. Processing order is upstream `excluded_models`, plugin plan filtering, OAuth alias/prefix, then model registration. The final registration constrains both `/v1/models` aggregation and scheduler candidates. See `cliproxyapi-pro-plugins/oauth-model-policy/README.md` for configuration and discovery details.
146+
141147
### Backend account inspection scheduler
142148

143149
The patch layer adds backend account-inspection routes under the management API:
@@ -228,6 +234,7 @@ It then starts `CLIProxyAPI` and optionally restores the latest usage backup fro
228234
- `Dockerfile` — downloads upstream CLIProxyAPI, applies this customization layer, and builds the final image.
229235
- `Dockerfile.runtime` — assembles the Actions runtime image from prebuilt Linux binaries.
230236
- `QUOTA_PROVIDER.md` — QuotaProvider plugin protocol and compatibility rules.
237+
- `../cliproxyapi-pro-plugins/oauth-model-policy/` — dynamic plugin for filtering auth models by OAuth plan.
231238
- `entrypoint.sh` — starts Komari, starts the main API, and restores WebDAV usage backups.
232239
- `embeddedusage/` — embedded SQLite usage service and management routes.
233240
- `patches/apply_upstream_patches.py` — patches upstream source during Docker build.

0 commit comments

Comments
 (0)