Repository: https://github.com/ViceEye/cpa-provider-nexus
cpa-provider-nexus is an independent AGPL-3.0 native provider plugin for
CLIProxyAPI. It connects multiple credential and model sources behind one CPA
provider identity. The current release supports Kiro, Cline and WorkBuddy OAuth.
The production runtime consists only of CLIProxyAPI and
cpa-provider-nexus-v0.10.4.so (or .dylib on macOS, .dll on Windows). Kiro Gateway is the protocol reference and is not a
sidecar or runtime dependency.
- 同步 9router v0.5.112(提交
1fe586bb)的 WorkBuddy/CodeBuddy 渠道请求头: CN/Intl 聊天及认证重试均生成新的 UUID,三个请求级 ID 保持一致,会话 ID 独立。 - 流式失败时有界读取并关闭上游错误流,保留业务码和渠道校验提示,不再只返回 HTTP 400。
- 将业务码
6004或明确的频率限制信封映射为 429,交由 CPA 处理冷却; HTTP 200 中的 JSON 错误信封也不能作为成功回答。 - 不改模型别名、凭证身份、OAuth、额度查询或现有提示词转换;未自动部署。
- Adds daily and manual Claude OAuth quota activation plans to the Nexus console, with per-credential model selection and timezone settings.
- Sends a native OAuth Messages request through the CPA host HTTP bridge, limited to one output token and the selected credential without fallback.
- Rejects disabled, mismatched and non-OAuth credentials; requires a completed message with valid usage before reporting success.
- Adds full multi-platform binary distributions for CLIProxyAPI Plugins Store submission (issue #2):
- Linux (
amd64,arm64) - Darwin / macOS (
amd64,arm64) - Windows (
amd64)
- Linux (
- Packages each target dynamic library directly at the archive root (
<id>.<ext>) with an unifiedchecksums.txt.
- Removes OAuth callback processing from unauthenticated
/v0/resource/plugins/routes (issue #1). Only static console and icon assets remain public. - Submit browser callbacks through the console using the authenticated
POST /v0/management/plugins/cpa-provider-nexus/oauth/callbackAPI. Existing resource callback URLs now return 404 and are rejected in login configuration. Use a loopback redirect with manual callback submission, oraws-devicelogin. - Existing credentials and model requests are unaffected.
- Adds WorkBuddy / CodeBuddy CN and international browser authorization, region-specific models, streaming and non-streaming Chat Completions, and quota cards.
- Stores credentials as
type: "nexus", kind: "workbuddy", region: "cn" | "intl". Refreshes preserve the original auth file, stable statistics ID, and host-owned fields. - Rejects invalid requests and malformed or incomplete non-streaming SSE responses; propagates host stream errors instead of recording them as successful requests.
- WorkBuddy uses the gateway compatibility transformations from the local 9router adapter: CN may replace agent system prompts, while Intl replaces system/developer messages with the required CodeBuddy identity. This changes instruction semantics; it is not transparent Responses or remote-compaction support.
- WorkBuddy models are a static catalog. Account-specific availability and live OAuth/inference still require validation with an authorized account.
- Docker builds target the selected platform and write artifacts under
dist/linux/<arch>/. Match the plugin architecture to the CPA container.
Quota activation usability update:
- Adds daily scheduled real-model quota activation for Codex and Antigravity, with account, model, timezone, enable/disable, and immediate-run controls.
- Presents the quota activation configuration as an in-place popup with its own scroll area, backdrop dismissal, and Escape-key dismissal.
- Keeps the scheduler configuration persisted in the Nexus plugin without requiring changes to CPA source code.
Compatibility and observability update:
- Adds Cline request result tracking and free-tier status reporting.
- Adds Antigravity quota refresh and grouped quota display through CPA's management API.
- Aligns the Nexus credential cards, health status, and quota presentation with CPA's native auth-file card design.
- Keeps the embedded console synchronized with the current Nexus branding and provider model prefix.
Breaking identity change:
- Renames the project and plugin from
kiro-providertocpa-provider-nexus. - Changes the CPA provider identity and credential
typefromkirotonexus. - Changes registered model IDs from
kiro/<model>tonexus/<model>. - Stores the upstream credential source separately as
kind: "kiro"orkind: "cline". - Moves management and resource routes to
/v0/management/plugins/cpa-provider-nexus/...and/v0/resource/plugins/cpa-provider-nexus/.... - Renames the embedded panel to Nexus Console and the Linux artifact to
cpa-provider-nexus-v0.9.0.so.
Verification completed for this release:
go vet ./...go test ./...- Linux amd64
c-sharedbuild in Docker. - Live CPA deployment: refreshed credential persisted to the original file and the auth manager kept exactly one record for it.
Early 0.x versions were fast local integration builds rather than separately
published releases. The milestones below record verified capability groups;
they do not claim a one-to-one mapping between every local .so and a Git
commit.
| Version milestone | Date | Development result |
|---|---|---|
v0.1.x-v0.3.x |
2026-08-16 | Established the standalone Linux plugin ABI, Kiro credential import and refresh, model registration, OpenAI Chat Completions conversion, AWS Event Stream parsing, and multi-account execution. |
v0.4.x |
2026-08-16 | Added dynamic model discovery, profileArn handling, quota reporting, management routes, and isolated CPA protocol fixtures. |
v0.5.0-v0.5.4 |
2026-08-16 to 2026-08-17 | Added first-time Kiro browser login, organization IAM Identity Center continuation, device authorization, region separation, persisted OAuth repair, and request compatibility fixes found during live CPA testing. |
v0.5.5 |
2026-08-17 | Added bounded history trimming so large Codex requests remain below Kiro's payload limit while preserving complete turns. |
v0.5.6 |
2026-08-17 | Preserved system/developer instructions during trimming and hardened orphaned tool-result removal. |
v0.6.0 |
2026-08-17 | Added plugin-owned OAuth Resource Routes and callback handling for compatible environments. Production app.kiro.dev still requires a loopback redirect URI, so remote Builder ID and organization login use aws-device. |
v0.6.1 |
2026-08-17 | Accepted organization-specific AWS device verification URLs without broadening the trusted-host boundary. |
v0.6.2 |
2026-08-26 | Added Codex-to-Kiro Claude history normalization and fixed fragmented toolUseEvent output producing duplicate malformed OpenAI tool calls. |
v0.7.0 |
2026-08-27 | Fixed object-valued tool arguments concatenating into invalid JSON, dropped required entries with no matching property, removed the assistant-content filler sentence that models echoed back as output, and degraded oversized requests by dropping large images and truncating large tool results instead of failing the turn. |
v0.7.7 |
2026-08-29 | Unified auth record identity on the host's file-based ID so plugin saves upsert instead of duplicating credentials, kept host record IDs out of stored credential JSON, and made the console close the relogin flow after success. |
v0.8.0 |
2026-08-30 | Added Cline OAuth, free-model execution, Cline credential cards, and the provider-selection login page. |
v0.9.0 |
2026-08-30 | Renamed the plugin to CPA Provider Nexus and changed the public provider identity and model prefix to nexus. |
v0.9.1 |
2026-09-01 | Added Antigravity quota refresh, aligned Nexus card status and quota presentation with CPA, and improved Cline request status tracking. |
v0.9.5 |
2026-09-04 | Added scheduled Codex and Antigravity quota activation with popup-based configuration. |
When Git history starts, use commits and tags as the source of truth for later releases instead of extending this reconstructed pre-Git history.
- Kiro Desktop and AWS SSO OIDC refresh flows.
- Cline browser OAuth, token refresh, free-model discovery, and execution.
- First-time Kiro CLI-compatible browser PKCE login through
app.kiro.dev, including the organization choice shown by Kiro's unified sign-in page. - Optional AWS Builder ID and IAM Identity Center device-code login.
- Kiro IDE JSON, Enterprise
clientIdHash, AWS SSO cache JSON, kiro-cli and Amazon Q SQLite import. - Multi-account import through CPA-owned
AuthDatapersistence. - Reference mode (default) and independent copy mode.
- Namespaced
nexus/<model>registrations. - Per-account dynamic model discovery through Kiro
ListAvailableModels, with static models retained only as an outage fallback. - Automatic
profileArndiscovery through the AWS JSONListAvailableProfilesoperation for older OAuth credentials that contain valid tokens but no profile, with CPA auth persistence after discovery. - Authenticated Kiro subscription and credit quota Management API.
- OpenAI Chat Completions input/output, including streaming, images, tools, tool results, and multi-turn history.
- AWS Binary Event Stream framing and CRC validation.
- CPA host HTTP bridge usage for every upstream request.
- HTTP status propagation for CPA refresh, cooldown, retry, and failover.
- Build or download the Linux
.soand place it under CPA's configured plugin directory. - Enable
plugins.enabledandplugins.configs.cpa-provider-nexus.enabled. - Choose one login mode from the next section. Remote organization accounts
should use
aws-device. - Restart or recreate the CPA service and confirm that logs show
plugin registered plugin_id=cpa-provider-nexus. - Open Nexus Console and select either Kiro OAuth or Cline OAuth.
- Confirm that
nexus/...models appear inGET /v1/models, then call them through the normal OpenAI Chat Completions endpoint.
The plugin, OAuth login, model proxy, automatic token refresh, and quota API do
not require CPA core changes or a customized management.html.
Configure Nexus either from Management Center → Plugins → Nexus → Edit
configuration or directly in CPA's config.yaml under
plugins.configs.cpa-provider-nexus. The panel and YAML edit the same plugin-scoped
settings; rebuilding the .so is not required when only these values change.
For a remote CPA server using AWS IAM Identity Center, start with this complete configuration:
plugins:
enabled: true
dir: /CLIProxyAPI/plugins
configs:
cpa-provider-nexus:
enabled: true
priority: 100
import_mode: reference
login_mode: aws-device
browser_redirect_uri: http://localhost:3128
sso_start_url: https://your-company.awsapps.com/start
sso_region: eu-west-1
api_region: us-east-1
static_models: []Replace:
sso_start_urlwith the organization's AWS access portal URL.sso_regionwith the IAM Identity Center region used by that organization.dirwith the plugin path visible inside the CPA process or container.
Keep api_region: us-east-1 unless the Kiro runtime for the account is known to
use another region. sso_region controls login and token refresh;
api_region controls Kiro models, profiles, chat, and quota calls.
login_mode: aws-device names the OAuth flow, not the account type. A
non-default organization sso_start_url makes the resulting credential a
Kiro Organization credential. browser_redirect_uri is ignored by this
device flow, but keeping the safe localhost default prevents an invalid public
redirect if the login mode is changed later.
After saving, confirm that CPA logs contain:
plugin registered plugin_id=cpa-provider-nexus
Then open OAuth → Kiro OAuth, follow the AWS verification link, complete organization SSO, and leave the panel open until CPA reports success.
| Setting | Default | Purpose |
|---|---|---|
enabled |
true |
Enables this plugin configuration. |
priority |
host default | CPA provider priority. |
import_mode |
reference |
Controls imported files: reference reloads the source; copy stores an independent copy. OAuth logins are stored by CPA. |
login_mode |
kiro-browser |
Selects kiro-browser or aws-device. |
sso_start_url |
https://view.awsapps.com/start |
Default means Builder ID; an organization *.awsapps.com/start URL means IAM Identity Center. |
sso_region |
us-east-1 |
AWS SSO OIDC registration, device authorization, and refresh region. |
api_region |
us-east-1 |
Kiro runtime, model discovery, profile, and quota region. |
browser_redirect_uri |
http://localhost:3128 |
Used only by browser authorization-code flows; Kiro rejects arbitrary public CPA domains. |
model_prefix |
nexus/ |
Prefix registered on discovered model IDs. Use another non-empty prefix only when needed. |
static_models |
[] |
Additional fallback model IDs when dynamic discovery is unavailable. |
runtime_base_url, model_discovery_url, usage_url, refresh URLs, and token
URLs are test/private-gateway overrides. Leave them unset for production Kiro.
Choose the flow based on the account and where CPA runs:
login_mode |
Use case | Redirect behavior | Remote CPA |
|---|---|---|---|
aws-device |
AWS Builder ID or organization IAM Identity Center | Opens an AWS verification URL and CPA polls for completion | Recommended |
kiro-browser |
Kiro personal/social browser OAuth compatible with kiro-cli | Kiro redirects to http://localhost:3128 |
Requires a local callback listener, relay, or manual callback submission |
Kiro's production sign-in page rejects arbitrary public redirect hosts with
Invalid redirect URI. Must be localhost or a subdomain of app.kiro.dev.
Do not configure a CPA domain such as https://cpa.example.com/... as
browser_redirect_uri.
Use AWS device authorization. This is the simplest flow because it has no browser callback:
plugins:
configs:
cpa-provider-nexus:
enabled: true
login_mode: aws-device
sso_start_url: https://example.awsapps.com/start
sso_region: eu-west-1
api_region: us-east-1Open CPA's OAuth page, start Kiro OAuth, open the returned AWS verification
URL, complete organization SSO, and leave the panel open while CPA polls and
saves the credential. Although the setting is named aws-device, the account
is stored as Kiro Organization whenever sso_start_url is an organization
IAM Identity Center URL instead of the default Builder ID URL.
Use the Builder ID start URL. sso_region defaults to us-east-1 when omitted:
plugins:
configs:
cpa-provider-nexus:
login_mode: aws-device
sso_start_url: https://view.awsapps.com/start
sso_region: us-east-1
api_region: us-east-1Use the Kiro CLI-compatible loopback redirect:
plugins:
configs:
cpa-provider-nexus:
login_mode: kiro-browser
browser_redirect_uri: http://localhost:3128
api_region: us-east-1When CPA is remote, localhost belongs to the browser machine, not the CPA
server. Complete this flow with one of the following:
- Use a local Kiro CLI/browser listener or another loopback relay, then paste
the complete localhost callback URL into a management panel that submits it to
POST /v0/management/plugins/cpa-provider-nexus/oauth/callback. - Sign in with Kiro CLI or Quotio and import the resulting credential.
Never paste OAuth callback URLs into logs or issues; they may contain a short-lived authorization code.
cmd/cpa-provider-nexus/ Native C ABI entry point
internal/provider/ CPA/Kiro orchestration, OAuth, credentials and quota
internal/pluginrpc/ Shared CPA host callbacks, envelopes, and stream helpers
internal/chat/ OpenAI Chat Completions to Kiro request conversion
internal/eventstream/ AWS Event Stream parser
internal/jsonx/ Shared JSON value helpers
internal/provider/testdata/ Synthetic credential fixtures
integration/ Network-isolated CPA integration suite
.github/workflows/ GitHub Actions CI
Docker Desktop or a Linux Docker engine is required. The build target is Linux amd64 with glibc, matching the CPA Debian image.
git clone https://github.com/ViceEye/cpa-provider-nexus.git
cd cpa-provider-nexus
docker build --output type=local,dest=dist .The artifact is written to:
dist/linux/amd64/cpa-provider-nexus-v0.9.5.so
CPA searches both its plugin root and the matching <GOOS>/<GOARCH>
subdirectory. Copy the versioned library using either layout:
# Flat layout, such as the default /CLIProxyAPI/plugins mount:
cp dist/linux/amd64/cpa-provider-nexus-v0.9.5.so plugins/
# Or platform-specific layout:
mkdir -p plugins/linux/amd64
cp dist/linux/amd64/cpa-provider-nexus-v0.9.5.so plugins/linux/amd64/Enable the plugin in config.yaml:
Use the complete template and field reference in
Plugin configuration. The organization example is
also suitable for Docker Compose when dir matches the container mount.
For Docker Compose, mount the repository's plugins directory at
/CLIProxyAPI/plugins, as supported by the standard CPA compose file.
Reference mode is recommended when CPA and Kiro share an account. The plugin reloads the external source before refresh, reducing conflicts when Kiro rotates a refresh token.
./CLIProxyAPI --kiro-import /credentials --kiro-import-mode referenceCopy mode gives CPA an independent stored copy:
./CLIProxyAPI --kiro-import /credentials/token.json --kiro-import-mode copySupported sources:
- Kiro IDE token JSON.
- AWS SSO cache JSON.
- Enterprise token JSON plus sibling
<clientIdHash>.jsonregistration. - kiro-cli or Amazon Q SQLite databases containing
auth_kv. - A directory containing one or more of these formats.
- A direct JSON object using camelCase or snake_case token fields.
When CPA runs in Docker, mount external credentials read-only:
services:
cli-proxy-api:
volumes:
- /host/kiro-credentials:/credentials:roNever put real credentials in the plugin source tree, image, build context, logs, or test fixtures.
List models through the normal CPA endpoint:
curl http://127.0.0.1:8317/v1/models \
-H "Authorization: Bearer $CPA_API_KEY"Call a Kiro model through OpenAI Chat Completions:
curl http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer $CPA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nexus/claude-sonnet-4.5",
"stream": true,
"messages": [{"role": "user", "content": "Hello"}]
}'The plugin intentionally targets OpenAI Chat Completions, including streaming, for clients such as Codex.
The plugin dynamically calls Kiro ListAvailableModels for every account by
using the AWS JSON service endpoint at https://q.{region}.amazonaws.com/.
Before model execution, discovery, or quota lookup, a credential without a
profileArn is upgraded in place using ListAvailableProfiles; existing OAuth
logins therefore do not need to be repeated.
The bundled static list is used only when discovery fails. Set
model_discovery_url only to override the service endpoint for a private
gateway or integration fixture. runtime_base_url, desktop_refresh_url, and
oidc_refresh_url have the same override purpose.
The plugin exposes an authenticated Management API endpoint. It calls Kiro's
HTTP GET getUsageLimits endpoint with origin=AI_EDITOR and
resourceType=AGENTIC_REQUEST and the account's discovered profileArn:
GET /v0/management/plugins/cpa-provider-nexus/quota
It calls Kiro GetUsageLimits for every enabled Kiro credential and returns
sanitized subscription, credit usage, overage, charge, and reset information.
Tokens, refresh credentials, profile ARNs, and upstream user IDs are never
included. Set usage_url only to override the default Kiro service endpoint.
Plugin metadata uses the embedded Nexus logo served from
/v0/resource/plugins/cpa-provider-nexus/icon.svg.
The official CPA management.html can load the plugin and start Kiro OAuth,
but it does not render the plugin-specific quota endpoint. To see Kiro balance,
credits, reset time, and overage status in Quota Management, a customized
management.html is required.
The customization is limited to the Kiro quota adapter, types, translations,
icon, and tests. It does not modify the OAuth page or CPA core. Build it from
the sibling Cli-Proxy-API-Management-Center source tree.
cd ../Cli-Proxy-API-Management-Center
bun install --frozen-lockfile
bun run verifyThe single-file build is dist/index.html. Deploy it as CPA's
static/management.html (or the file selected by MANAGEMENT_STATIC_PATH).
Prevent CPA's automatic updater from replacing the custom build:
remote-management:
disable-auto-update-panel: trueFor Docker Compose, mount the file into the same static path used by the CPA container:
services:
cli-proxy-api:
environment:
MANAGEMENT_STATIC_PATH: /CLIProxyAPI/static/management.html
volumes:
- ./management.html:/CLIProxyAPI/static/management.html:roCopy dist/index.html to the host as management.html, then recreate only the
CPA service. The plugin quota endpoint remains usable even when the official
panel is restored; only the Kiro quota cards disappear.
An access token expiring after several hours does not mean that the saved credential must be deleted. OAuth login stores the access token together with its refresh token and, for AWS SSO accounts, the OIDC client ID and secret.
The plugin refreshes automatically:
- CPA schedules a refresh ten minutes before the recorded access-token expiry.
- Chat, streaming chat, model discovery, profile discovery, and quota lookup refresh before use when the token is missing or close to expiry.
- A Kiro API response of
401or403triggers one refresh and one retry. - Rotated access and refresh tokens are persisted back to the same CPA auth entry, so its file name and auth ID remain stable.
Normal eight-hour access-token expiry therefore needs no manual action and no new OAuth login.
Re-login is required only when refresh can no longer succeed, for example when the refresh token was revoked, organization access was removed, or the AWS OIDC client registration is no longer valid. In that case:
- Leave the old credential in place.
- Start Kiro OAuth again and complete authorization.
- Verify a model call and quota lookup with the new credential.
- Disable or delete the old failed credential afterward.
Deleting the old credential before re-login is unnecessary and removes the easy rollback path. The current CPA OAuth flow creates a new auth entry for a new AWS client registration; it does not overwrite an unrelated expired entry.
Each imported account becomes a separate provider=nexus CPA auth. CPA owns
selection, session affinity, retry, cooldown, and failover. The plugin maps:
401/403: refresh and retry once, then propagate the status.402/429: propagate for CPA cooldown and account switching.- network failures and
5xx: retryable upstream failures. - malformed client payloads: non-retryable
400. - corrupt or truncated Event Stream data: stream failure.
The plugin never logs authorization headers or credential payloads.
All fixtures use fake values and tests perform no real network requests:
docker run --rm -v "$PWD:/src" -w /src golang:1.26-bookworm \
sh -c '/usr/local/go/bin/gofmt -w cmd/cpa-provider-nexus/*.go internal/*/*.go && /usr/local/go/bin/go vet ./... && /usr/local/go/bin/go test -v ./...'An online smoke test is optional and must use a read-only credential mount.
The repository also includes a network-isolated CPA integration fixture. Once
the kiro-mock and cpa-provider-nexus-test containers are running on the
cpa-provider-nexus-test Docker network, run:
docker restart kiro-mock cpa-provider-nexus-test
docker run --rm --network cpa-provider-nexus-test \
-v "$PWD/integration:/tests:ro" \
python:3.12-slim python /tests/run_integration.pyThis verifies dynamic model discovery, the authenticated quota Management API, OpenAI Chat Completions streaming and non-streaming output, tool calls, credential refresh, and multi-account failover for 402, 403, 429, and 5xx responses. All fixture credentials and responses are synthetic.
For a focused OAuth route-boundary check, run integration/run_oauth_boundary.py
against an isolated CPA configured with integration/oauth-config.yaml and the
built plugin. Set CPA_BASE_URL, CPA_MANAGEMENT_KEY, and CPA_API_KEY to the
fixture values. This checks public callback rejection with a valid login state,
static asset access, and callback submission with missing, incorrect, API-only,
and valid Management keys. It does not contact the OAuth upstream.
- Update
pluginVersion, the Docker output filename, and README artifact references together. - Run
gofmt,go vet ./..., andgo test ./...in the pinned Go image. - Build the Linux amd64
.soand run the isolated CPA integration suite. - Confirm that test fixtures contain synthetic values only.
- Push a
v<version>tag. CI creates or updates the GitHub Release and uploadscpa-provider-nexus_<version>_linux_amd64.zippluschecksums.txt. The ZIP containscpa-provider-nexus.soat its root as required by the CPA Plugin Store. - To repair assets for an existing tag, manually run the CI workflow with
release_tagset to that tag, such asv0.7.0. - Do not commit
dist/, credentials, OAuth callbacks, or local CPA configuration.
This plugin is licensed under AGPL-3.0-or-later. See LICENSE and NOTICE.