Skip to content

feat(ai): add ClinePass provider - #572

Open
jaeyoung3048 wants to merge 7 commits into
code-yeongyu:mainfrom
jaeyoung3048:feat/clinepass-provider
Open

feat(ai): add ClinePass provider#572
jaeyoung3048 wants to merge 7 commits into
code-yeongyu:mainfrom
jaeyoung3048:feat/clinepass-provider

Conversation

@jaeyoung3048

@jaeyoung3048 jaeyoung3048 commented Jul 31, 2026

Copy link
Copy Markdown

Summary

Adds a built-in cline-pass provider for ClinePass, Cline's OpenAI-compatible subscription endpoint at https://api.cline.bot/api/v1, following the existing alibaba-token-plan / openrouter gateway pattern.

  • Generated catalog of 11 tool-capable models (DeepSeek V4 Flash/Pro, GLM 5.2, Kimi K2.6/K2.7-code/K3, MiMo v2.5/v2.5-pro, MiniMax M3, Qwen 3.7 Max/Plus) sourced from the models.dev cline-pass provider; non-tool-capable entries filtered by the tool_call gate
  • Like OpenRouter, ClinePass fronts many upstream models behind one gateway, keeps the provider/model id shape, and normalizes thinking through the nested reasoning object rather than provider-specific parameters. Its verified effort vocabulary (none/low/medium/high/xhigh) is applied after the upstream-model rules so the gateway's contract wins over direct-endpoint maps; pi's minimal and max have no ClinePass equivalent and clamp to low/xhigh
  • CLINE_API_KEY env detection, ClinePass display name for /login, default model cline-pass/kimi-k3, CLI --help env row, providers.md / README, devcontainer + devenv env surfaces, and CLINE_API_KEY unset in test.sh / pi-test.sh so hermetic runs stay offline
  • Live coverage is gated by describe.skipIf(!process.env.CLINE_API_KEY), the same shape the other ~24 API-key providers use — no new opt-in flag is introduced
  • Fork-ledger sections added to packages/ai/src/changes.md, packages/coding-agent/src/cli/changes.md, packages/coding-agent/src/core/changes.md, and a new packages/web-ui/src/changes.md
  • No credentials of any kind are included in this PR.

Why this belongs in core

Provider registration, KnownProvider, and browser-safe credential detection are composed inside packages/ai before any extension loads. model-resolver.ts and provider-display-names.ts are typed Record<KnownProvider, string>, so adding a provider is a compile-time obligation across those maps rather than something an extension can supply. An extension can add a model entry; it cannot make a provider first-class in the generated catalog or in env-api-keys.ts credential probing.

Per packages/ai/src/providers/AGENTS.md steps 2-4, no new wire implementation, package subpath, or option transform is needed: ClinePass reuses openAICompletionsApi() exactly as alibaba-token-plan.ts and openrouter.ts do. git diff --name-only <base>..HEAD -- packages/ai/src/api packages/ai/package.json is empty.

Verification

  • npm run check — exit 0 (Biome, pinned-deps, ts-imports, shrinkwrap, install-lock, tsgo --noEmit, browser smoke, web-ui check)
  • node --test scripts/*.test.mjs — 72 passed / 0 failed
  • packages/ai — 173 files passed / 25 skipped; 1,534 tests passed / 824 skipped / 0 failed, with CLINE_API_KEY unset
  • packages/coding-agent — 6,153 passed / 33 skipped / 3 failed in the full-suite run. None of the three failing files (footer-data-provider, permission/external-dir, app-server-thread-handlers-archive) is touched by this branch, and all three were re-run individually at the base commit in a detached worktree with these commits absent — each exits 1 there as well, so all three are pre-existing failures independent of this change. permission/external-dir (symlinked cwd) and app-server-thread-handlers-archive (unarchive) also fail individually on this branch; footer-data-provider (reftable branch detection) passes individually on this branch, so its failure additionally depends on the surrounding environment
  • Every commit typechecks standalone: npx tsgo --noEmit exit 0 at each of the 6 commits in a detached worktree, so the history is bisectable
  • Real CLI, credential-free: senpi --list-models | grep -c '^cline-pass '11; senpi --help lists CLINE_API_KEY - ClinePass API key
  • packages/ai/test/cline-pass-request.test.ts captures the outgoing request and pins the endpoint https://api.cline.bot/api/v1/chat/completions, the Bearer header, the full model id, the nested reasoning: { effort } object, and the absence of reasoning_effort. Mutation-verified: changing the baseUrl in providers/data/cline-pass.json (the catalog the runtime reads) turns the suite red at the endpoint assertion
  • Opt-in live matrix added to stream / tokens / abort / empty / context-overflow / unicode-surrogate / tool-call-without-result / image-tool-result / total-tokens / cross-provider-handoff, gated so the default suite runs with zero credentials

Compatibility

  • Additive only: every change to an existing file is a new entry in an alphabetically-ordered per-provider map. No existing provider's behavior, catalog, or wire shape changes.
  • models.generated.ts, providers/data/cline-pass.json, and providers/data/.manifest.json are regenerated artifacts from npm run generate:models and npm run hydrate:model-data — not hand-edited.
  • Rebased onto main with zero conflicts. packages/ai/src/providers/data/.manifest.json is regenerated and committed inside the first commit, so npm --prefix packages/ai run check:model-data exits 0 at every commit in the series (verified per-commit in a detached worktree). If a future rebase does conflict on the manifest, resolve it by regenerating rather than hand-merging: it is a single JSON object whose files map holds one hash per provider catalog, so a textual union produces two concatenated objects and invalid JSON. Use npm run hydrate:model-data, then npm run check:model-data.
  • Two documentation caveats worth a maintainer's judgement: (1) CLINE_API_KEY follows this client's <PROVIDER>_API_KEY convention, but ClinePass's published API docs specify only the Authorization: Bearer header and do not name an environment variable; (2) model ids, pricing, and context windows come from models.dev rather than a first-party ClinePass model list.

Review follow-ups

Both P2 findings from the automated reviewer are addressed in this series:

  • Model-data manifest regenerated. packages/ai/src/providers/data/.manifest.json now ships in the first commit with the cline-pass.json hash and the updated structureHash. It was regenerated through the repo's own createModelDataManifest(), so all 38 pre-existing provider hashes are byte-identical and only cline-pass.json is added. check:model-data exits 0 at all 6 commits.
  • CLINE_API_KEY isolated in app-server QA. Added to REAL_PROVIDER_ENV_KEYS in both test/qa/app-server/task17-model-list.ts and task17-unimplemented.ts, immediately after ALIBABA_TOKEN_PLAN_API_KEY, matching commit b700ddaf7 ("test: isolate Alibaba token plan credentials"). Verified on the real surface: with CLINE_API_KEY set in the environment, task17-model-list.ts exited 1 before the change and exits 0 after.
  • test/helpers/rpc-hermetic.ts deliberately not touched. Its PROVIDER_ENV_KEYS list is not exhaustive — it already omits ALIBABA_TOKEN_PLAN_API_KEY, ANT_LING_API_KEY, and the XIAOMI_* keys — and b700ddaf7 skipped it for the same reason. Adding only CLINE_API_KEY there would introduce an inconsistency rather than remove one. Happy to add it if you would prefer that list become exhaustive.

Known limitations

  • Web UI, no-proxy path (pre-existing, not introduced here). applyProxyIfNeeded() returns the unproxied model when no proxy URL is configured, before consulting shouldUseProxyForProvider(). With the CORS proxy setting off, a valid ClinePass key is reported as invalid instead of surfacing "this provider requires the proxy". zai has behaved this way since b6b64df; ClinePass joins that existing class. Fixing it changes the shared no-proxy path for every proxy-required provider, which does not belong in a provider addition.
  • Test scope nit. cline-pass-request.test.ts resolves its model through getModels("cline-pass"), which is the catalog the runtime reads and the value models.ts sends, so the wire contract is genuinely pinned. It does not additionally assert clinePassProvider()'s own factory-level baseUrl; adding that assertion would tighten coverage for dynamically-registered models.

Summary by cubic

Adds a built-in cline-pass provider for ClinePass’s OpenAI-compatible endpoint at https://api.cline.bot/api/v1, with cline-pass/kimi-k3 as the default model, CLINE_API_KEY auth, proxy-aware web UI, and a generated catalog of 11 tool-capable models using normalized reasoning: { effort }.

  • New Features

    • Registered cline-pass at https://api.cline.bot/api/v1; keeps provider/model IDs and uses OpenRouter-style reasoning.effort (none/low/medium/high/xhigh), clamping unsupported values and applying gateway rules over upstream (DeepSeek/Qwen/Kimi/GLM preserved under nested reasoning).
    • Generated 11 tool-capable models (DeepSeek, GLM, Kimi, MiMo, MiniMax, Qwen) from models.dev; non-tool models filtered; catalog and manifest regenerated.
    • Auth via CLINE_API_KEY; CLI --help lists it; display name ClinePass; default cline-pass/kimi-k3 wired into the model resolver; devcontainer seeds the key; tests/scripts unset it for hermetic runs.
    • Web UI: marked proxy-required and added a test model for key validation.
    • Tests: opt-in coverage (stream/tokens/abort/etc.) gated by CLINE_API_KEY; request contract pinned (endpoint .../chat/completions, bearer header, full model ID, nested reasoning, max_tokens).
  • Migration

    • Set CLINE_API_KEY to use cline-pass.
    • Enable the CORS proxy in the web UI for cline-pass (direct browser calls are blocked by api.cline.bot).

Written for commit 313f05d. Summary will update on new commits.

Review in cubic

@jaeyoung3048
jaeyoung3048 force-pushed the feat/clinepass-provider branch from d36918a to 039cbc4 Compare July 31, 2026 05:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d36918a7dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

readonly "anthropic": typeof ANTHROPIC_MODELS;
readonly "azure-openai-responses": typeof AZURE_OPENAI_RESPONSES_MODELS;
readonly "cerebras": typeof CEREBRAS_MODELS;
readonly "cline-pass": typeof CLINE_PASS_MODELS;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Regenerate the model-data manifest

Adding ClinePass to the generated catalog expands the provider set, but packages/ai/src/providers/data/.manifest.json remains unchanged and contains neither cline-pass.json nor the new structure hash. Consequently, npm --prefix packages/ai run check:model-data reports a catalog/manifest mismatch, preventing validation and offline builds until the manifest is regenerated and committed.

AGENTS.md reference: packages/ai/src/providers/AGENTS.md:L23-L24

Useful? React with 👍 / 👎.

const envMap: Record<string, string> = {
"alibaba-token-plan": "ALIBABA_TOKEN_PLAN_API_KEY",
"ant-ling": "ANT_LING_API_KEY",
"cline-pass": "CLINE_API_KEY",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the new key to every hermetic environment sanitizer

When a developer has CLINE_API_KEY set, this new credential is now discovered, but the coding-agent sanitizers in test/helpers/rpc-hermetic.ts, scripts/qa-app-server/lib/env.mjs, and both task17 REAL_PROVIDER_ENV_KEYS lists do not clear it. Direct package tests and app-server QA can therefore inherit a real credential and expose ClinePass models in runs intended to contain only faux/mock providers; add the key to those related environment surfaces as well.

AGENTS.md reference: AGENTS.md:L90-L90

Useful? React with 👍 / 👎.

Register the cline-pass provider against ClinePass OpenAI-compatible endpoint at https://api.cline.bot/api/v1, generate its 11-model tool-capable catalog from models.dev, and resolve keys from CLINE_API_KEY. Thinking is normalized through the nested OpenRouter-style reasoning object, and the gateway effort vocabulary (none/low/medium/high/xhigh) overrides upstream direct-endpoint maps.
Default cline-pass to cline-pass/kimi-k3, display it as ClinePass, and document CLINE_API_KEY in --help.
List ClinePass in provider tables and changelog, seed CLINE_API_KEY through devcontainer/devenv setup, and unset it in test.sh so hermetic runs stay offline.
CONTRIBUTING.md requires a nearest-changes.md section for every modification to
an upstream-tracked file. Document the ClinePass provider registration, the CLI
help/default-model wiring, and the browser key-validation entries, including the
pre-existing no-proxy limitation inherited from the shared proxy path.
…ider

# Conflicts:
#	packages/ai/src/changes.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 313f05d117

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

},
);

describe.skipIf(!process.env.CLINE_API_KEY)("ClinePass Provider (Kimi K3 via OpenAI Completions)", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require explicit opt-in before running ClinePass live tests

When CLINE_API_KEY is present, an ordinary npm test now runs this paid, network-dependent stream matrix and the other newly added ClinePass suites automatically; the devcontainer and setup changes make that ambient-key scenario especially likely. This can consume subscription quota and make the default test result depend on the live service, so resolve the key through getLiveEnvApiKey and require PI_ENABLE_LIVE_API_TESTS=1 or a ClinePass-specific live-test flag before enabling these suites.

AGENTS.md reference: packages/ai/AGENTS.md:L50-L50

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant