Skip to content

feat(provider): add Cloudflare Workers AI integration (#1100) - #1178

Merged
kevincodex1 merged 18 commits into
Twigpine:mainfrom
0xfandom:feat/1100-cloudflare-workers-ai
Jul 9, 2026
Merged

kevincodex1 merged 18 commits into
Twigpine:mainfrom
0xfandom:feat/1100-cloudflare-workers-ai

Conversation

@0xfandom

@0xfandom 0xfandom commented May 15, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1100.

Adds a Cloudflare Workers AI OpenAI-compatible preset/route.

What it does

  • Registers Cloudflare Workers AI as a GatewayDescriptor at src/integrations/gateways/cloudflare.ts (OpenAI-compatible transport; max_tokens field; removeBodyFields: ['store']), surfaced as the Cloudflare Workers AI preset in the provider picker.
  • Auth: the transport reads the generic OpenAI-compatible header, and CLOUDFLARE_API_TOKEN is mirrored into OPENAI_API_KEY (and vice-versa) so a user who sets only CLOUDFLARE_API_TOKEN is authenticated.

Route boundary (path-aware, not host-only)

Workers AI is identified by isCloudflareBaseUrl() — exact api.cloudflare.com host AND the /client/v4/accounts/<id>/ai/v1 path over HTTPS. Everything else on Cloudflare is intentionally excluded and falls back to the generic OpenAI-compatible (custom) route:

  • the shared AI Gateway host gateway.ai.cloudflare.com (it proxies arbitrary providers — OpenAI/Anthropic/…);
  • non-Workers api.cloudflare.com REST paths such as /client/v4/user/tokens/verify;
  • http:// (non-HTTPS) endpoints.

This boundary is applied consistently across route detection (resolveRouteIdFromBaseUrl / resolveActiveRouteIdFromEnv), startup validation, the --provider cloudflare CLI shortcut, and saved-profile env mirroring (apply / alignment / startup-env). A saved cloudflare profile retargeted to any of the excluded URLs resolves to custom and keeps generic OpenAI-compatible capabilities (apiFormat, custom auth/request headers) rather than the Workers AI shim.

Tests

Route-metadata coverage asserts the Workers AI URL resolves to cloudflare while the AI Gateway host and non-Workers REST path resolve to null / custom; provider-profile coverage asserts token mirroring/persistence happens only for the real Workers AI URL (negative apply + persist cases for the gateway host and the non-Workers REST path); a retargeted profile preserves OPENAI_API_FORMAT. First-run picker asserts the Cloudflare Workers AI preset is offered. Rebased on current main; smoke-and-tests green on GitHub.

Summary by CodeRabbit

  • New Features
    • Added Cloudflare Workers AI as a supported provider, including an OpenAI-compatible gateway with default base URL/model and CLOUDFLARE_API_TOKEN authentication.
  • Bug Fixes
    • Improved Workers AI endpoint detection to only match real https://api.cloudflare.com/.../ai/v1 URLs (rejects placeholders/lookalikes and the shared gateway host).
    • Hardened credential and profile syncing to avoid token leakage and correctly manage OPENAI_API_KEY/CLOUDFLARE_API_TOKEN based on the active endpoint.
  • Documentation
    • Updated README and advanced setup with Cloudflare Workers AI configuration examples and <ACCOUNT_ID> guidance.
  • Tests
    • Expanded routing, presets, provider-profile, and environment-variable validation coverage for Cloudflare Workers AI.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Findings

  • [P2] Narrow Cloudflare gateway URL matching to Workers AI routes
    src/integrations/vendors/cloudflare.ts:52
    Adding gateway.ai.cloudflare.com to matchBaseUrlHosts makes every Cloudflare AI Gateway URL resolve to the new cloudflare route, because resolveRouteIdFromBaseUrl() matches these entries by hostname only. That includes non-Workers-AI Gateway URLs such as https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/openai, which now get Workers-AI-specific runtime metadata and credential precedence (max_tokens, removeBodyFields: ['store'], no Responses format selection, and CLOUDFLARE_API_TOKEN before OPENAI_API_KEY). Please either remove the broad gateway host match or add path-aware matching that only classifies Workers AI/compat Gateway paths as this preset, with coverage that another provider's Cloudflare AI Gateway URL remains custom/OpenAI-compatible.

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

Blockers

  1. Broad gateway URL matching — Adding gateway.ai.cloudflare.com to matchBaseUrlHosts makes every Cloudflare AI Gateway URL resolve to the Workers AI route, including non-Workers-AI Gateway URLs. This applies Workers-AI-specific runtime metadata and credential precedence to other providers' Gateway URLs.

Non-Blocking

  • Follow-up work identified (AI Gateway integration, dynamic model discovery).

Looks Good

  • Mirrors the Venice / Xiaomi MiMo descriptor pattern
  • Good test coverage (303 tests passing)
  • No new dependencies
  • Clear documentation and setup guidance
  • removeBodyFields: ['store'] for Workers AI compatibility

Verdict: Changes Requested — gateway URL matching needs to be narrowed to Workers AI routes.

@jatmn

jatmn commented May 17, 2026

Copy link
Copy Markdown
Collaborator

please rebase from main, this should fix your smoke issues

@gnanam1990

Copy link
Copy Markdown
Collaborator

Confirmed @jatmn's point against the code: matchBaseUrlHosts includes gateway.ai.cloudflare.com, which is the shared host for all Cloudflare AI Gateway routes (/openai, /anthropic, etc.), so any AI Gateway URL — not just Workers AI — resolves to this preset and inherits CLOUDFLARE_API_TOKEN-before-OPENAI_API_KEY precedence and the store body-field strip. Path-aware matching (only Workers-AI/compat Gateway paths) or dropping the broad gateway host would fix it. The added test covers the save-message label but not this over-match case, so adding coverage where another provider's CF AI Gateway URL stays generic/OpenAI-compatible would lock the fix in. The rest of the integration (descriptor shape, static catalog, profile env wiring) looks consistent with the MiMo/Venice pattern. Thanks — happy to take another pass after that.

@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from 34c060c to 38e9e4f Compare May 19, 2026 06:14
@0xfandom

Copy link
Copy Markdown
Contributor Author

Rebased on f71e769 and pushed 38e9e4f addressing the host-match over-classification:

  • Dropped gateway.ai.cloudflare.com from matchBaseUrlHosts. The Workers AI preset now only auto-routes from api.cloudflare.com (the direct Workers AI host). Other providers behind Cloudflare AI Gateway (/anthropic, /openai, etc.) stay generic/OpenAI-compatible and don't inherit CLOUDFLARE_API_TOKEN-before-OPENAI_API_KEY precedence or the Workers-AI body-field strip.
  • Inline comment notes that path-aware AI Gateway routing is a separate follow-up (already mentioned in the file header alongside the dynamic-discovery TODO).
  • New routeMetadata.test.ts case covers two Gateway URLs (/anthropic, /openai) → not.toBe('cloudflare'), plus the positive api.cloudflare.com case.

bun test src/integrations/routeMetadata.test.ts → 23/0. Build + smoke clean.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for rebasing and narrowing the Cloudflare AI Gateway matching. The previous gateway over-classification concern looks addressed now: gateway.ai.cloudflare.com no longer resolves to the Workers AI route, and the new route metadata coverage checks that.

Findings

  • [P1] Restore the ProviderManager test preset order after adding Cloudflare
    src/components/ProviderManager.test.tsx:107
    Adding Cloudflare to ORDERED_PROVIDER_PRESETS shifts every later provider down by one row, but the PRESET_ORDER helper used by the ProviderManager tests was not updated with the new Cloudflare Workers AI label. As a result, label-based navigation now lands on the wrong preset for OpenAI, MiniMax, Hicap, Ollama, Atomic Chat, etc., and the smoke-and-tests check is failing with eight ProviderManager.test.tsx failures. Please add Cloudflare to the test helper order, or make the helper derive the order from the generated preset metadata, so the PR check can pass again.

@0xfandom
0xfandom requested a review from jatmn May 20, 2026 15:58
jatmn
jatmn previously approved these changes May 21, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the updates. The previous Cloudflare AI Gateway over-classification issue looks addressed, and the ProviderManager preset-order regression is fixed with the current helper update and passing coverage.

No remaining issues here, LGTM.

@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from d336e14 to 3405c23 Compare May 29, 2026 18:19

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the update. I took another pass through the changed paths and found issues that still need to be addressed before this is ready.

Findings

  • [P2] Keep saved Cloudflare gateway URLs generic after the hostname fix
    src/integrations/routeMetadata.ts:651
    Narrowing matchBaseUrlHosts fixed the raw base-URL path, but saved Cloudflare profiles still force non-Workers-AI Gateway URLs back onto the cloudflare route. resolveActiveRouteIdFromEnv(..., { activeProfileProvider }) returns the profile's route unconditionally for profile-managed OpenAI sessions, and providerProfiles.ts still mirrors CLOUDFLARE_API_TOKEN for gateway.ai.cloudflare.com. In a local repro, https://gateway.ai.cloudflare.com/v1/.../openai resolves as custom without the profile override but flips back to cloudflare with activeProfileProvider: 'cloudflare', so route-aware surfaces such as /model keep using the Workers AI catalog/shim metadata for non-Workers-AI Gateway URLs. Please make the saved-profile path honor the same gateway exclusion or add path-aware routing there too, with coverage for a Cloudflare preset retargeted to /openai or /anthropic Gateway URLs.

  • [P2] Reject the placeholder endpoint on the --provider cloudflare shortcut
    src/utils/providerFlag.ts:307
    applyProviderFlag('cloudflare') falls through the generic OpenAI-compatible branch and copies the descriptor default base URL verbatim, which is still https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1. That means openclaude --provider cloudflare now "succeeds" with CLAUDE_CODE_USE_OPENAI=1 and a literal <ACCOUNT_ID> endpoint that cannot actually serve requests until the user manually fixes OPENAI_BASE_URL. The preset wizard already treats placeholder endpoints as requiring explicit setup, so the flag path should do the same instead of silently seeding a broken configuration.

@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from 3405c23 to bb6ad60 Compare June 15, 2026 13:30
@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Cloudflare Workers AI support across gateway metadata, route detection, provider/profile env handling, UI coverage, and documentation.

Changes

Cloudflare Workers AI Provider Integration

Layer / File(s) Summary
Cloudflare gateway definition and model catalog
src/integrations/gateways/cloudflare.ts, src/integrations/index.test.ts, src/integrations/compatibility.test.ts
Adds the Cloudflare gateway, OpenAI-compatible shim settings, Cloudflare credential and base URL rules, supported models, and catalog exceptions for Cloudflare-specific model entries.
isCloudflareBaseUrl detection and route gating
src/integrations/routeMetadata.ts, src/integrations/index.ts, src/integrations/routeMetadata.test.ts, src/utils/providerValidation.ts, src/utils/providerValidation.test.ts
Adds isCloudflareBaseUrl, re-exports it, and covers Cloudflare route resolution plus validation targeting for real Workers AI endpoints only.
applyProviderFlag cloudflare branch and placeholder detection
src/utils/providerFlag.ts, src/utils/providerFlag.test.ts
Adds placeholder detection for base URL defaults, a cloudflare provider branch, and tests for mirroring or clearing OPENAI_API_KEY based on the configured Cloudflare base URL.
Profile env type and managed key updates
src/utils/providerProfiles.ts, src/utils/providerProfile.ts, src/utils/providerProfiles.test.ts
Extends profile env handling and startup env building to carry CLOUDFLARE_API_TOKEN only for Cloudflare-hosted OpenAI-compatible profiles, with matching test coverage.
Preset UI, save-message tests, and documentation
src/components/ProviderManager.test.tsx, src/commands/provider/provider.test.tsx, src/components/ConsoleOAuthFlow.test.tsx, README.md, docs/advanced-setup.md
Adds Cloudflare to preset ordering, covers saved-profile messaging and console provider visibility, and documents provider setup and env vars.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Gitlawb/openclaude#863: Also changes provider/profile environment handling in src/utils/providerProfile.ts.
  • Gitlawb/openclaude#1669: Also extends OpenAI-compatible provider plumbing and route/profile matching logic for a different provider.
  • Gitlawb/openclaude#1818: Also updates shared route/profile resolution logic in src/integrations/routeMetadata.ts.

Suggested labels: new: provider/gateway

Suggested reviewers: kevincodex1, jatmn

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR delivers the requested Cloudflare Workers AI support and accounts for Cloudflare AI Gateway behavior mentioned in #1100.
Out of Scope Changes check ✅ Passed The diff stays focused on Cloudflare Workers AI integration, docs, and tests, with no clear unrelated changes.
Risk Surface Disclosed ✅ Passed Cloudflare auth/routing risk is explicitly called out in comments/PR notes, and the shared AI Gateway path is treated as a clean non-blocking follow-up.
No Hidden Policy Change ✅ Passed No hidden policy shift found; Cloudflare auth/routing/telemetry behavior is explicit in the new descriptor and boundary checks, not buried in cleanup.
Title check ✅ Passed The title is concise, scoped, and accurately summarizes the Cloudflare Workers AI integration work.
Description check ✅ Passed The description covers the change, rationale, route behavior, and testing, though it omits the template's Impact and Notes sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/providerProfiles.test.ts`:
- Around line 616-640: The test `cloudflare profile applies OpenAI-compatible
env with CLOUDFLARE_API_TOKEN mirror` sets the environment variable
`CLOUDFLARE_API_TOKEN` (verified at line 638) but this key is not included in
the `RESTORED_KEYS` array that controls which environment variables are restored
during teardown. Add `CLOUDFLARE_API_TOKEN` to the `RESTORED_KEYS` array to
ensure proper cleanup and prevent this environment variable from leaking into
subsequent tests.

In `@src/utils/providerProfiles.ts`:
- Around line 587-592: The profile URL check in the Cloudflare validation logic
includes gateway.ai.cloudflare.com, which reintroduces a routing bug because
this shared host serves multiple backend providers (not just Workers AI). Remove
the OR condition that checks for gateway.ai.cloudflare.com from the
profile.baseUrl validation, keeping only the api.cloudflare.com check. This
ensures CLOUDFLARE_API_TOKEN is only set for direct Workers AI endpoints
(api.cloudflare.com) and not for shared gateway URLs that might point to other
providers like Anthropic.
- Around line 736-738: In the CLOUDFLARE_API_TOKEN assignment check, remove the
condition `profile.baseUrl.toLowerCase().includes('gateway.ai.cloudflare.com')`
from the if statement to prevent incorrectly triggering Workers-AI-specific
handling for AI Gateway URLs that point to non-Workers-AI backends. Keep only
the checks for `route.routeId === 'cloudflare'` and
`profile.baseUrl.toLowerCase().includes('api.cloudflare.com')`.
- Around line 1042-1047: The condition in the startup env builder that sets
CLOUDFLARE_API_TOKEN currently includes a check for 'gateway.ai.cloudflare.com',
which causes the same credential precedence and body transformation bug. Remove
the second condition that checks for 'gateway.ai.cloudflare.com' from the if
statement, keeping only the check for 'api.cloudflare.com' to properly exclude
Gateway URLs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6fc38e07-36c4-4ae7-add1-5ca96fd99441

📥 Commits

Reviewing files that changed from the base of the PR and between 8bce86f and bb6ad60.

⛔ Files ignored due to path filters (1)
  • src/integrations/generated/integrationArtifacts.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
📒 Files selected for processing (11)
  • README.md
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,py,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/integrations/compatibility.test.ts
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.test.ts
  • README.md
  • src/utils/providerFlag.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior in TypeScript and JavaScript files

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/utils/providerFlag.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.test.ts
**/{providers,integrations}/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

PRs that skip documented patterns in docs/integrations/ or introduce inconsistent provider behavior may be sent back for rework

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/integrations/compatibility.test.ts
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.test.ts
  • README.md
  • src/utils/providerFlag.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/utils/providerFlag.ts
  • src/commands/provider/provider.test.tsx
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfiles.test.ts
**

⚙️ CodeRabbit configuration file

**: # Contributing to OpenClaude

Thanks for contributing.

OpenClaude is a fast-moving open-source coding-agent CLI with support for multiple providers, local backends, MCP, and a terminal-first workflow. The best contributions here are focused, well-tested, and easy to review.

Before You Start

  • Search existing issues and discussions before opening a new thread.
  • Check open pull requests for work that overlaps with your contribution. If a PR already exists that addresses the same change, open an issue or discussion first to align on direction — duplicate PRs may be closed without review.
  • Use issues for confirmed bugs and actionable feature work.
  • Use discussions for setup help, ideas, and general community conversation.
  • For larger changes, open an issue first so the scope is clear before implementation.
  • For security reports, follow SECURITY.md.

Pull Requests

Every PR needs a reason. Your PR description must include:

  • what changed and why
  • the user or developer impact
  • the exact checks you ran
  • a linked issue when one exists, using Fixes #123, `Closes `#123, or another clear link
  • screenshots when the PR touches UI, terminal presentation, or the VS Code extension
  • which provider path was tested when the PR changes provider behavior

The PR author is responsible for ensuring their PR is merge-ready. PRs with merge conflicts will not be reviewed or approved until the conflicts are resolved.

Issues are the recommended starting point for anything non-trivial — opening one first helps avoid wasted effort if the change is out of scope or already being worked on. Small fixes, doc corrections, and obvious improvements can stand on their own without a linked issue, as long as the PR description explains the intent.

What Gets Closed Without Review

PRs may be closed without review...

Files:

  • src/integrations/compatibility.test.ts
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.test.ts
  • README.md
  • src/utils/providerFlag.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.test.ts
**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update docs when setup, commands, or user-facing behavior changes

Files:

  • docs/advanced-setup.md
  • README.md
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}

⚙️ CodeRabbit configuration file

{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.

Files:

  • docs/advanced-setup.md
  • README.md
🔇 Additional comments (10)
src/integrations/vendors/cloudflare.ts (1)

1-91: LGTM!

src/utils/providerFlag.ts (1)

304-307: LGTM!

src/integrations/compatibility.test.ts (1)

44-44: LGTM!

README.md (1)

176-176: LGTM!

docs/advanced-setup.md (1)

267-277: LGTM!

src/utils/providerProfile.ts (1)

105-105: LGTM!

Also applies to: 135-135, 198-198, 225-226

src/components/ProviderManager.test.tsx (1)

119-119: LGTM!

src/integrations/routeMetadata.test.ts (1)

94-116: LGTM!

src/utils/providerProfiles.test.ts (1)

246-257: LGTM!

src/commands/provider/provider.test.tsx (1)

385-409: LGTM!

Comment thread src/utils/providerProfiles.test.ts
Comment thread src/utils/providerProfiles.ts
Comment thread src/utils/providerProfiles.ts Outdated
Comment thread src/utils/providerProfiles.ts Outdated

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the updates. I took another pass through the changed Cloudflare provider paths and found issues that still need to be addressed before this is ready.

Findings

  • [P2] Complete CodeRabbit's request to stop treating Gateway URLs as Cloudflare profiles
    src/utils/providerProfiles.ts:736
    CodeRabbit's current review item is still valid: the descriptor and route metadata test now intentionally exclude gateway.ai.cloudflare.com, but the saved-profile env path still mirrors CLOUDFLARE_API_TOKEN whenever the profile URL contains that shared Gateway host. That keeps a Cloudflare preset retargeted to https://gateway.ai.cloudflare.com/v1/.../openai or /anthropic tied to the Cloudflare route through the profile marker path: resolveRouteIdFromBaseUrl(...) returns no Cloudflare match, but resolveActiveRouteIdFromEnv(..., { activeProfileProvider: 'cloudflare' }) still returns cloudflare. As a result, route-aware surfaces can keep using the Workers AI catalog/shim metadata and Cloudflare credential precedence for non-Workers-AI Gateway URLs. Please complete that review request by removing the broad Gateway host checks from the profile env/alignment/startup paths, or by adding path-aware Gateway routing with coverage for saved profiles retargeted to /openai and /anthropic Gateway URLs.

  • [P2] Reject placeholder Cloudflare defaults from the CLI shortcut
    src/utils/providerFlag.ts:501
    applyProviderFlag('cloudflare') falls through the generic OpenAI-compatible branch and applies the descriptor default base URL verbatim. With only CLOUDFLARE_API_TOKEN set, openclaude --provider cloudflare now succeeds with CLAUDE_CODE_USE_OPENAI=1, the Cloudflare model, and OPENAI_BASE_URL=https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1, which cannot serve requests until the user manually replaces the placeholder. The /provider wizard already treats placeholder endpoint defaults as requiring explicit setup, so the CLI shortcut should not silently seed a broken endpoint; it should require/provide a real account-scoped base URL or refuse the shortcut until one is configured.

  • [P3] Complete CodeRabbit's request to restore the Cloudflare token env in tests
    src/utils/providerProfiles.test.ts:17
    The new provider profile test sets and asserts process.env.CLOUDFLARE_API_TOKEN, but RESTORED_KEYS does not include that key. The file's beforeEach/afterEach cleanup therefore leaves the Cloudflare token in process state after the test that applies the Cloudflare profile, which can make later provider/env tests order-dependent as more Cloudflare route inference coverage is added. Please add CLOUDFLARE_API_TOKEN to the restored key list with the other provider-specific secret env vars.

@0xfandom

Copy link
Copy Markdown
Contributor Author

Addressed all three findings (rebased on current main; integration artifacts regenerated):

  • [P2] Gateway host routing: added isCloudflareBaseUrl (hostname === api.cloudflare.com, matching the Workers AI host and the descriptor's matchBaseUrlHosts) and routed all three profile env/alignment/startup sites through it. gateway.ai.cloudflare.com (the shared AI Gateway host that also fronts /openai, /anthropic) no longer mirrors CLOUDFLARE_API_TOKEN, consistent with isXaiBaseUrl/isFireworksBaseUrl. Regression test covers Workers-AI vs /openai+/anthropic Gateway URLs and a lookalike host.
  • [P2] Placeholder CLI default: applyOpenAIBaseUrlDefault now refuses to seed any base URL still containing a <…> placeholder, so --provider cloudflare no longer installs the broken …/<ACCOUNT_ID>/… endpoint; a real user-supplied OPENAI_BASE_URL is kept. Tests cover both cases.
  • [P3] Restored token: CLOUDFLARE_API_TOKEN added to the provider profile test's RESTORED_KEYS.

tsc clean; routeMetadata + providerFlag + providerProfiles suites pass (218).

@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from bb6ad60 to 29fa6db Compare June 23, 2026 07:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/integrations/routeMetadata.test.ts`:
- Around line 198-207: Replace the two expect assertions in the
resolveRouteIdFromBaseUrl test cases with explicit assertions that check for the
exact fallback value of null instead of using not.toBe('cloudflare'). Change
both calls to expect the function to return null when given the AI Gateway URLs,
which tightens the regression boundary and ensures the test validates the
specific fallback behavior rather than just ruling out one provider route.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fc84b0c4-dc30-4a0f-b9db-9378f9ce6274

📥 Commits

Reviewing files that changed from the base of the PR and between bb6ad60 and 29fa6db.

⛔ Files ignored due to path filters (1)
  • src/integrations/generated/integrationArtifacts.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
📒 Files selected for processing (8)
  • README.md
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/vendors/cloudflare.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
{src/integrations/**/*.ts,src/services/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Test the exact provider/model path you changed when possible for provider modifications

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
src/integrations/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Check existing provider implementations before adding a new pattern

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/integrations/compatibility.test.ts
  • README.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow TypeScript strict mode and type safety practices by running typecheck before submitting

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.
  • Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • `src/integration...

Files:

  • src/integrations/compatibility.test.ts
  • README.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/integrations/compatibility.test.ts
  • README.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/vendors/cloudflare.ts
  • src/components/ProviderManager.test.tsx
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/vendors/cloudflare.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}

⚙️ CodeRabbit configuration file

{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.

Files:

  • README.md
  • docs/advanced-setup.md
src/**/*provider*.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Provider implementations must follow documented patterns in docs/integrations/

Files:

  • src/commands/provider/provider.test.tsx
docs/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update docs when setup, commands, or user-facing behavior changes

Files:

  • docs/advanced-setup.md
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use React + Ink for terminal UI implementations

Files:

  • src/components/ProviderManager.test.tsx
🪛 LanguageTool
README.md

[uncategorized] ~452-~452: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...8zFR6AcB) to chat with the community in real time - Follow [@gitlawb on X](https://x.com/...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🔇 Additional comments (8)
README.md (1)

75-76: LGTM!

Also applies to: 108-108, 110-130, 198-210, 233-233, 267-267, 288-288, 369-369, 452-453, 475-475

docs/advanced-setup.md (1)

7-8: LGTM!

Also applies to: 18-18, 200-203, 270-280, 338-339, 385-390, 404-404, 447-447

src/integrations/vendors/cloudflare.ts (1)

1-91: LGTM!

src/integrations/routeMetadata.ts (1)

15-15: LGTM!

Also applies to: 34-37, 204-233, 276-278, 364-383, 523-535, 547-547, 632-652

src/integrations/routeMetadata.test.ts (1)

9-39: LGTM!

Also applies to: 63-177, 348-355

src/components/ProviderManager.test.tsx (1)

119-119: LGTM!

Also applies to: 144-144

src/integrations/compatibility.test.ts (1)

41-45: LGTM!

src/commands/provider/provider.test.tsx (1)

333-378: LGTM!

Also applies to: 431-455

Comment thread src/integrations/routeMetadata.test.ts Outdated

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the updates. I rechecked the changed paths and found one remaining issue that still needs to be addressed before this is ready.

Findings

  • [P3] Complete CodeRabbit's request to tighten the AI Gateway route regression test
    src/integrations/routeMetadata.test.ts:198
    CodeRabbit's review item is still open: the two AI Gateway URL assertions currently use .not.toBe('cloudflare'), which only rules out the Cloudflare route but would still pass if the function returned any other non-cloudflare value. Because the intended fallback for these shared-gateway URLs is null, please change both assertions to .toBe(null) so the test verifies the exact fallback behavior and locks in the regression boundary.

@0xfandom

Copy link
Copy Markdown
Contributor Author

Done — both AI Gateway assertions now use .toBe(null) to pin the exact fallback instead of just ruling out cloudflare.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Findings

  • [P2] Complete the Cloudflare AI Gateway exclusion in saved-profile env mirroring
    src/utils/providerProfiles.ts:812
    The other two Cloudflare mirror sites (isProcessEnvAlignedWithProfile at line 656 and buildOpenAICompatibleStartupEnv at line 1118) were already narrowed to isCloudflareBaseUrl(profile.baseUrl), but applyProviderProfileToProcessEnv still mirrors CLOUDFLARE_API_TOKEN whenever route.routeId === 'cloudflare'. Because route comes from resolveProfileCompatibility(profile.provider), that left side is always true for any saved cloudflare profile, including one retargeted to a shared gateway.ai.cloudflare.com URL. A cloudflare profile saved against https://gateway.ai.cloudflare.com/v1/.../openai or /anthropic therefore still gets CLOUDFLARE_API_TOKEN set and stays tied to the Cloudflare route through the profile marker path. Please complete the valid-reviewer request by replacing the condition with isCloudflareBaseUrl(profile.baseUrl) only, and add a regression test that applies a cloudflare profile with a gateway.ai.cloudflare.com base URL and asserts process.env.CLOUDFLARE_API_TOKEN is not set.

@0xfandom

Copy link
Copy Markdown
Contributor Author

Good catch — fixed in 9f2e9fb. applyProviderProfileToProcessEnv (providerProfiles.ts:812) now gates the CLOUDFLARE_API_TOKEN mirror on isCloudflareBaseUrl(profile.baseUrl) only, dropping the route.routeId === 'cloudflare' disjunct that was always true for a saved cloudflare profile. This matches the other two sites you mentioned (isProcessEnvAlignedWithProfile, buildOpenAICompatibleStartupEnv). Added a regression test applying a cloudflare profile retargeted to gateway.ai.cloudflare.com and asserting CLOUDFLARE_API_TOKEN stays unset; the existing api.cloudflare.com mirror test still passes. 104 pass.

@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from 9f2e9fb to 5d4255d Compare June 25, 2026 07:14
@0xfandom

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (was 27 behind). The only conflict was the generated integrationArtifacts file — resolved by taking main's and regenerating via bun run integrations:generate, so the Cloudflare vendor is registered alongside the providers main added. typecheck clean; provider/route/profile suites green (275 tests). No longer shows conflicts.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/providerFlag.ts`:
- Around line 321-324: The provider selection logic in applyProviderFlag
currently treats Cloudflare as a generic OpenAI-compatible path, so users with
only CLOUDFLARE_API_TOKEN never get OPENAI_API_KEY set. Add a dedicated
cloudflare branch in src/utils/providerFlag.ts that preserves the
placeholder-URL skip behavior and copies CLOUDFLARE_API_TOKEN into
OPENAI_API_KEY when selected, and update the related tests for applyProviderFlag
to cover this behavior.

In `@src/utils/providerProfiles.ts`:
- Around line 1124-1126: The Cloudflare token is only being mirrored in the
fallback env path, so the strictEnv branch in
providerProfiles/buildOpenAIProfileEnv logic can still drop CLOUDFLARE_API_TOKEN
on relaunch. Update the strictEnv return path to mirror CLOUDFLARE_API_TOKEN
whenever isCloudflareBaseUrl(activeProfile.baseUrl) is true, matching the
existing handling for other provider-specific keys in the same branch, and add
or update tests around the buildOpenAIProfileEnv/providerProfiles flow to cover
Cloudflare restart env preservation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 42393bc0-7d3b-42a8-acea-e481f7f33d9b

📥 Commits

Reviewing files that changed from the base of the PR and between 9f2e9fb and 5d4255d.

⛔ Files ignored due to path filters (2)
  • src/integrations/generated/integrationArtifacts.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
  • src/integrations/generated/integrationManifest.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
📒 Files selected for processing (13)
  • README.md
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerFlag.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • README.md
  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.
  • Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • `src/integration...

Files:

  • README.md
  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • README.md
  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • docs/advanced-setup.md
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}

⚙️ CodeRabbit configuration file

{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.

Files:

  • README.md
  • docs/advanced-setup.md
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use execa for child processes

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfiles.test.ts
src/**/*provider*.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Provider implementations must follow documented patterns in docs/integrations/

Files:

  • src/utils/providerFlag.test.ts
  • src/commands/provider/provider.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfiles.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow TypeScript strict mode and type safety practices by running typecheck before submitting

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfile.ts
  • src/integrations/vendors/cloudflare.ts
  • src/utils/providerProfiles.ts
  • src/utils/providerProfiles.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/utils/providerFlag.test.ts
  • src/integrations/compatibility.test.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.test.ts
  • src/components/ProviderManager.test.tsx
  • src/utils/providerProfiles.test.ts
{src/integrations/**/*.ts,src/services/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Test the exact provider/model path you changed when possible for provider modifications

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
src/integrations/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Check existing provider implementations before adding a new pattern

Files:

  • src/integrations/compatibility.test.ts
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/vendors/cloudflare.ts
docs/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update docs when setup, commands, or user-facing behavior changes

Files:

  • docs/advanced-setup.md
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use React + Ink for terminal UI implementations

Files:

  • src/components/ProviderManager.test.tsx

Comment thread src/utils/providerFlag.ts
Comment thread src/utils/providerProfiles.ts

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I found issues that need to be addressed before this is ready.

Findings

  • [P1] Copy CLOUDFLARE_API_TOKEN into OPENAI_API_KEY for the --provider cloudflare shortcut
    src/utils/providerFlag.ts:529
    applyProviderFlag('cloudflare', []) currently falls through to the generic OpenAI-compatible default branch, which only sets CLAUDE_CODE_USE_OPENAI=1 and seeds a base URL/model. Unlike the other dedicated providers (venice, xiaomi-mimo, atlas-cloud, nearai, fireworks, etc.), it never copies CLOUDFLARE_API_TOKEN into OPENAI_API_KEY. Because the Cloudflare transport reads the generic OpenAI-compatible auth header, a user who follows the docs and only sets CLOUDFLARE_API_TOKEN ends up with an unauthenticated request path. Please add a dedicated case 'cloudflare': branch (keeping the placeholder-URL skip) that mirrors CLOUDFLARE_API_TOKEN into OPENAI_API_KEY, and add a test that asserts the key is copied. This is the still-open CodeRabbit review item on src/utils/providerFlag.ts.

  • [P2] Mirror CLOUDFLARE_API_TOKEN in the strictEnv startup path too
    src/utils/providerProfiles.ts:1078
    buildOpenAICompatibleStartupEnv only sets CLOUDFLARE_API_TOKEN in the fallback env block at line 1124. For a normal keyed Cloudflare profile, buildOpenAIProfileEnv returns a non-null strictEnv, so the function returns at line 1078 before the fallback block is reached. The result is that the persisted startup env for a Cloudflare profile omits CLOUDFLARE_API_TOKEN, unlike NEARAI_API_KEY and FIREWORKS_API_KEY which are explicitly mirrored in the strictEnv branch at lines 1072–1076. That makes host-based re-detection and env alignment inconsistent after relaunch. Please add if (isCloudflareBaseUrl(activeProfile.baseUrl)) { strictEnv.CLOUDFLARE_API_TOKEN = activeProfile.apiKey } alongside the nearai/fireworks mirrors, and add a regression test for buildStartupEnvFromProfile / the persisted legacy profile path. This is the still-open CodeRabbit review item on src/utils/providerProfiles.ts.

@0xfandom

Copy link
Copy Markdown
Contributor Author

Thanks — both addressed in e3ee3ab:

  • [P1] --provider cloudflare shortcut — added a dedicated case 'cloudflare': in providerFlag.ts that mirrors CLOUDFLARE_API_TOKEN into OPENAI_API_KEY (and clears a stale generic key when the token is absent, like nearai/atlas-cloud), keeping the applyOpenAIBaseUrlDefault placeholder-URL skip. Tests assert the token is copied and that a leftover OPENAI_API_KEY is cleared with no token.

  • [P2] strictEnv startup path — buildOpenAICompatibleStartupEnv returned from its strict-env branch (line ~1078) before the fallback CLOUDFLARE_API_TOKEN mirror, so a keyed Cloudflare profile persisted a startup env without the token. Added the mirror in the strict branch next to the nearai/fireworks ones. New setActiveProviderProfile test asserts the persisted .openclaude-profile.json env includes CLOUDFLARE_API_TOKEN — verified red without the fix, green with it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/providerFlag.ts`:
- Around line 529-547: The Cloudflare branch in providerFlag.ts mirrors
CLOUDFLARE_API_TOKEN into OPENAI_API_KEY without verifying the active
OpenAI-compatible endpoint, which can leak the token to the wrong provider.
Update the cloudflare case to gate this mirroring on
getConfiguredOpenAIBaseUrl() resolving to the Cloudflare Workers AI base URL
(not a stale or empty OPENAI_BASE_URL), and otherwise fail fast or leave
OPENAI_API_KEY unset with a clear configuration error. Keep the fix localized to
the cloudflare provider routing logic around applyOpenAIBaseUrlDefault and the
OPENAI_API_KEY assignment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1af49233-be58-40df-8263-59d495b52d04

📥 Commits

Reviewing files that changed from the base of the PR and between 5d4255d and e3ee3ab.

📒 Files selected for processing (4)
  • src/utils/providerFlag.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
{src/services/**/*.ts,src/utils/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use execa for child processes

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
src/**/*provider*.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Provider implementations must follow documented patterns in docs/integrations/

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow TypeScript strict mode and type safety practices by running typecheck before submitting

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.
  • Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • `src/integration...

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerFlag.ts
  • src/utils/providerProfiles.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/utils/providerFlag.test.ts
  • src/utils/providerProfiles.test.ts
🔇 Additional comments (2)
src/utils/providerProfiles.ts (1)

1078-1084: LGTM!

Also applies to: 1131-1133

src/utils/providerProfiles.test.ts (1)

2237-2278: LGTM!

Comment thread src/utils/providerFlag.ts
@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from e3ee3ab to f839fae Compare June 26, 2026 07:37
0xfandom added 12 commits July 7, 2026 13:00
The shared AI Gateway URL assertions used `.not.toBe('cloudflare')`, which
would also pass for any other non-cloudflare return value. The intended
fallback is null, so assert `.toBe(null)` to lock the regression boundary.
applyProviderProfileToProcessEnv mirrored CLOUDFLARE_API_TOKEN whenever
route.routeId === 'cloudflare'. route comes from the saved profile.provider,
so that disjunct is always true for a cloudflare profile, including one
retargeted to the shared gateway.ai.cloudflare.com AI Gateway host. The
sibling sites (isProcessEnvAlignedWithProfile, buildOpenAICompatibleStartupEnv)
already key on isCloudflareBaseUrl only; align this site with them so a
shared-gateway profile no longer leaks the token or stays pinned to the
cloudflare route. Add a regression test for the gateway.ai.cloudflare.com case.
The rebase took main's generated artifacts at the conflict; regenerate so the
Cloudflare vendor descriptor is registered in VENDOR_DESCRIPTORS and the
manifest alongside the providers main added.
…le auth path

The --provider cloudflare shortcut fell through to the generic
OpenAI-compatible default branch and never copied CLOUDFLARE_API_TOKEN
into OPENAI_API_KEY, so a user who only set the token sent an
unauthenticated request. Add a dedicated cloudflare case that mirrors the
token (and clears a stale generic key when absent), keeping the
placeholder-URL skip.

buildOpenAICompatibleStartupEnv also returned from its strict-env branch
before the fallback CLOUDFLARE_API_TOKEN mirror, so a keyed Cloudflare
profile persisted a startup env that omitted the token and re-detected
inconsistently after relaunch. Mirror it in the strict branch alongside
nearai/fireworks. Add regression coverage for both paths.
The cloudflare shortcut copied CLOUDFLARE_API_TOKEN into the generic
OPENAI_API_KEY unconditionally. The descriptor default carries an
unresolved `<ACCOUNT_ID>` placeholder and is never seeded, so with
OPENAI_BASE_URL unset (or still pointing at a previous OpenAI-compatible
provider) the token would be attached to the wrong host. Gate the mirror
on isCloudflareBaseUrl(getConfiguredOpenAIBaseUrl()) — only seed
OPENAI_API_KEY once the configured base URL resolves to
api.cloudflare.com, otherwise fail fast and leave it unset. Add
regression coverage for the unconfigured, stale-host, and AI-Gateway-host
cases.
…allback

The token mirror keyed on the api.cloudflare.com host only, so the literal
<ACCOUNT_ID> placeholder URL (same host) passed the gate and copied the
token onto a non-working endpoint. It also deleted any generic
OPENAI_API_KEY when no token was set, breaking the documented
compatibility fallback for users authenticating a real Workers AI URL with
OPENAI_API_KEY. Mirror only on a real (non-placeholder) Cloudflare
endpoint, and preserve an existing generic key there when no dedicated
token is present.

Refs Twigpine#1100
Cloudflare Workers AI is a hosted OpenAI-compatible inference endpoint
reached over the shared openai transport, so it belongs with the gateway
providers (atlas-cloud, groq, together, ...) rather than the transport
vendors. Move it to gateways/cloudflare.ts via defineGateway (category
hosted, vendorId openai), regenerate the integration artifacts, and
allowlist its provider-specific @cf/* catalog ids in the gateway
descriptor check (no shared cross-provider descriptor exists, same as
azure-deployment).

Refs Twigpine#1100
…e host

api.cloudflare.com also serves the general Cloudflare REST API, so matching the
whole host treated unrelated URLs (e.g. /client/v4/user/tokens/verify) as the
Workers AI route and mirrored CLOUDFLARE_API_TOKEN into OPENAI_API_KEY for them.

isCloudflareBaseUrl now requires the Workers AI path
/client/v4/accounts/<account_id>/ai/v1 with a real (non-placeholder) account id,
and resolveRouteIdFromBaseUrl guards its cloudflare hostname match through the
same predicate. Both route detection and token/profile mirroring key on the
actual Workers AI endpoint.

Adds same-host negative regressions (general REST path is not routed and does
not mirror the token; unresolved <ACCOUNT_ID> placeholder is excluded) and
asserts the Cloudflare Workers AI preset appears in the first-run picker.
…ovider fallback

resolveActiveRouteIdFromEnv returned the saved active-profile provider's route
id before consulting its base URL. For a `cloudflare` profile that had been
retargeted to a non-Workers URL — the shared AI Gateway host, or a general
api.cloudflare.com REST path — this still resolved as `cloudflare`, so the
Workers AI shim config (removeBodyFields: ['store'], Cloudflare model metadata)
and CLOUDFLARE_API_TOKEN mirroring were applied to a generic endpoint, even
though resolveRouteIdFromBaseUrl already excludes those URLs.

Gate the profile-provider shortcut through profileRouteHonorsBaseUrlBoundary,
which requires the path-aware isCloudflareBaseUrl for the cloudflare route (all
other routes are host-scoped by resolveProfileRoute and unaffected). A retargeted
profile now falls through to the generic openai/custom resolution; a genuine
Workers AI profile base URL still resolves as cloudflare.

Adds regressions for both retarget cases (gateway host + REST path) and the
positive Workers AI profile case.
…ation

isCloudflareBaseUrl accepted any scheme, so http://api.cloudflare.com/
client/v4/accounts/<id>/ai/v1 resolved as the cloudflare route and mirrored
CLOUDFLARE_API_TOKEN into OPENAI_API_KEY over cleartext. Require url.protocol
=== 'https:'.

Startup validation selected the Cloudflare target on host match alone, so a
non-Workers path like /client/v4/user/tokens/verify demanded Workers AI auth
instead of falling back to generic OpenAI validation. Gate the cloudflare
target on isCloudflareBaseUrl(request.baseUrl), mirroring the runtime route
resolver's path boundary.
…t-only comments

The apply/persist paths already gate CLOUDFLARE_API_TOKEN mirroring on the
isCloudflareBaseUrl path predicate, but had no coverage for a same-host
non-Workers path (api.cloudflare.com/client/v4/user/tokens/verify) and the
comments beside the mirroring sites still described a host-only boundary.

Add negative apply and persist regressions asserting the token is not mirrored
or persisted for that non-Workers URL, and update the comments to describe the
real Workers AI path predicate instead of host-only matching.
resolveProfileCapabilityRouteId returned the cloudflare capability route id for
any saved cloudflare profile whose base URL no longer resolves — including one
retargeted to gateway.ai.cloudflare.com or another OpenAI-compatible host. That
stripped generic capabilities (apiFormat, custom auth/request headers) from
profile sanitize/apply even though the runtime resolver runs such a profile as
a generic OpenAI-compatible route. Mirror the same isCloudflareBaseUrl boundary:
keep the cloudflare route only for the real Workers AI URL (or the unset
descriptor default) and fall back to 'custom' otherwise. Regression asserts a
retargeted cloudflare profile preserves OPENAI_API_FORMAT.
@0xfandom
0xfandom force-pushed the feat/1100-cloudflare-workers-ai branch from 923fc5c to a3d72d1 Compare July 7, 2026 07:35
@0xfandom

0xfandom commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (resolved the providerProfile.ts / providerProfiles.ts env-mirror and route-metadata test conflicts, regenerated the integration artifacts) and addressed both findings in a3d72d1:

  • [P2] Retargeted-profile capability route — resolveProfileCapabilityRouteId() fell back to resolveProfileRoute(provider).routeId whenever the base URL didn't resolve, which returned cloudflare for a saved cloudflare profile retargeted to gateway.ai.cloudflare.com/.../openai or another OpenAI-compatible host. That stripped generic capabilities (apiFormat, custom auth/request headers) in sanitizeProfile/apply even though the runtime resolver runs such a profile as a generic OpenAI-compatible route. It now applies the same isCloudflareBaseUrl() boundary: the cloudflare capability route is kept only for the real Workers AI URL (resolved directly) or the unset descriptor default, and any other base URL falls back to custom. Added a regression that retargets a cloudflare profile to the shared gateway with apiFormat: 'responses' and asserts OPENAI_API_FORMAT survives (and the token still isn't mirrored). Verified red→green.

  • [P3] Startup-env comment — the strictEnv Cloudflare mirror comment already describes the path-aware predicate ("real Workers AI endpoint per the isCloudflareBaseUrl path predicate — exact api.cloudflare.com host AND the /client/v4/accounts/<id>/ai/v1 path"); there's no remaining hostname-exact / host-only wording at the mirroring sites.

Local: providerProfiles, routeMetadata, providerValidation, and ConsoleOAuthFlow suites pass; typecheck clean.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/integrations/routeMetadata.test.ts (1)

269-290: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten these assertions to the exact expected route.

.not.toBe('cloudflare') only rules out one value; it would still pass if a future regression remapped these URLs to some other incorrect route instead of falling back correctly. Given the current implementation, both cases resolve to 'custom' — assert that explicitly, consistent with the same tightening already applied to the resolveRouteIdFromBaseUrl assertions just above in this same test file (lines 255/260/266 use .toBe(null)).

🔧 Proposed fix
   expect(
     resolveActiveRouteIdFromEnv(
       { CLAUDE_CODE_USE_OPENAI: '1', OPENAI_BASE_URL: gatewayUrl },
       { activeProfileProvider: 'cloudflare', activeProfileBaseUrl: gatewayUrl },
     ),
-  ).not.toBe('cloudflare')
+  ).toBe('custom')

   const restUrl = 'https://api.cloudflare.com/client/v4/user/tokens/verify'
   expect(
     resolveActiveRouteIdFromEnv(
       { CLAUDE_CODE_USE_OPENAI: '1', OPENAI_BASE_URL: restUrl },
       { activeProfileProvider: 'cloudflare', activeProfileBaseUrl: restUrl },
     ),
-  ).not.toBe('cloudflare')
+  ).toBe('custom')

As per path instructions, "Review tests for meaningful coverage of the changed behavior... Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/integrations/routeMetadata.test.ts` around lines 269 - 290, Tighten the
route assertion in resolveActiveRouteIdFromEnv so it checks the exact fallback
behavior instead of only excluding cloudflare. Update the two expectations in
the routeMetadata test to assert the returned route is custom for both the
gatewayUrl and restUrl cases, using resolveActiveRouteIdFromEnv as the target
symbol so the regression coverage matches the intended runtime behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ProviderManager.test.tsx`:
- Around line 117-127: The PRESET_ORDER test fixture is out of sync with the
live provider manifest, which can cause navigateToPreset to target the wrong
preset for later entries. Update the PRESET_ORDER array in
ProviderManager.test.tsx to match the current manifest order exactly, especially
the entries after Cloudflare Workers AI, so the test navigation logic resolves
the intended rows.

---

Duplicate comments:
In `@src/integrations/routeMetadata.test.ts`:
- Around line 269-290: Tighten the route assertion in
resolveActiveRouteIdFromEnv so it checks the exact fallback behavior instead of
only excluding cloudflare. Update the two expectations in the routeMetadata test
to assert the returned route is custom for both the gatewayUrl and restUrl
cases, using resolveActiveRouteIdFromEnv as the target symbol so the regression
coverage matches the intended runtime behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79745567-d799-4216-9616-2af3dc9a01d2

📥 Commits

Reviewing files that changed from the base of the PR and between 923fc5c and a3d72d1.

⛔ Files ignored due to path filters (2)
  • src/integrations/generated/integrationArtifacts.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
  • src/integrations/generated/integrationManifest.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
📒 Files selected for processing (11)
  • README.md
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/integrations/compatibility.test.ts
  • src/integrations/gateways/cloudflare.ts
  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/routeMetadata.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: smoke-and-tests (22)
  • GitHub Check: smoke-and-tests (24.11.x)
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files

Files:

  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/compatibility.test.ts
  • src/components/ProviderManager.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/integrations/gateways/cloudflare.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • src/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/compatibility.test.ts
  • README.md
  • src/components/ProviderManager.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/integrations/gateways/cloudflare.ts
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/compatibility.test.ts
  • README.md
  • src/components/ProviderManager.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/integrations/gateways/cloudflare.ts
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/compatibility.test.ts
  • src/integrations/gateways/cloudflare.ts
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.ts
  • src/integrations/routeMetadata.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/integrations/index.test.ts
  • src/integrations/compatibility.test.ts
  • src/components/ProviderManager.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/commands/provider/provider.test.tsx
  • src/integrations/routeMetadata.test.ts
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}

⚙️ CodeRabbit configuration file

{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.

Files:

  • README.md
  • docs/advanced-setup.md
src/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Build terminal UI using React + Ink components in src/components/

Files:

  • src/components/ProviderManager.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
🔇 Additional comments (12)
src/commands/provider/provider.test.tsx (1)

431-456: Cloudflare Workers AI save-message coverage looks solid.

Model, endpoint, and redaction assertions line up with buildProfileSaveMessage/buildSavedProfileSummary. The earlier concern about OPENAI_API_KEY masking a broken CLOUDFLARE_API_TOKEN path was already flagged and marked addressed in prior commits — keeping both keys here appears intentional since buildSavedProfileSummary's default case only inspects OPENAI_API_KEYS/OPENAI_API_KEY for credentialLabel, so removing OPENAI_API_KEY would break this assertion regardless of the Cloudflare token.

src/components/ProviderManager.test.tsx (1)

840-900: LGTM!

README.md (1)

256-256: LGTM!

docs/advanced-setup.md (1)

329-339: LGTM!

src/integrations/gateways/cloudflare.ts (1)

1-95: LGTM!

src/integrations/index.test.ts (1)

64-85: LGTM!

src/integrations/compatibility.test.ts (1)

18-54: LGTM!

src/integrations/routeMetadata.ts (2)

381-433: LGTM!

isCloudflareBaseUrl correctly requires HTTPS, exact host match, and the Workers AI path shape, and rejects unresolved <ACCOUNT_ID> placeholders — properly closes the host-only matching gap flagged in earlier review rounds.


929-971: LGTM!

Verified the route/profile boundary gating traces correctly for both the retargeted-gateway and real-Workers-AI-endpoint test scenarios.

Also applies to: 1007-1063

src/integrations/index.ts (1)

141-141: LGTM!

src/integrations/routeMetadata.test.ts (1)

1-268: LGTM!

Also applies to: 292-661

src/components/ConsoleOAuthFlow.test.tsx (1)

136-144: LGTM!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/integrations/routeMetadata.test.ts (1)

269-290: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten these assertions to the exact expected route.

.not.toBe('cloudflare') only rules out one value; it would still pass if a future regression remapped these URLs to some other incorrect route instead of falling back correctly. Given the current implementation, both cases resolve to 'custom' — assert that explicitly, consistent with the same tightening already applied to the resolveRouteIdFromBaseUrl assertions just above in this same test file (lines 255/260/266 use .toBe(null)).

🔧 Proposed fix
   expect(
     resolveActiveRouteIdFromEnv(
       { CLAUDE_CODE_USE_OPENAI: '1', OPENAI_BASE_URL: gatewayUrl },
       { activeProfileProvider: 'cloudflare', activeProfileBaseUrl: gatewayUrl },
     ),
-  ).not.toBe('cloudflare')
+  ).toBe('custom')

   const restUrl = 'https://api.cloudflare.com/client/v4/user/tokens/verify'
   expect(
     resolveActiveRouteIdFromEnv(
       { CLAUDE_CODE_USE_OPENAI: '1', OPENAI_BASE_URL: restUrl },
       { activeProfileProvider: 'cloudflare', activeProfileBaseUrl: restUrl },
     ),
-  ).not.toBe('cloudflare')
+  ).toBe('custom')

As per path instructions, "Review tests for meaningful coverage of the changed behavior... Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/integrations/routeMetadata.test.ts` around lines 269 - 290, Tighten the
route assertion in resolveActiveRouteIdFromEnv so it checks the exact fallback
behavior instead of only excluding cloudflare. Update the two expectations in
the routeMetadata test to assert the returned route is custom for both the
gatewayUrl and restUrl cases, using resolveActiveRouteIdFromEnv as the target
symbol so the regression coverage matches the intended runtime behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ProviderManager.test.tsx`:
- Around line 117-127: The PRESET_ORDER test fixture is out of sync with the
live provider manifest, which can cause navigateToPreset to target the wrong
preset for later entries. Update the PRESET_ORDER array in
ProviderManager.test.tsx to match the current manifest order exactly, especially
the entries after Cloudflare Workers AI, so the test navigation logic resolves
the intended rows.

---

Duplicate comments:
In `@src/integrations/routeMetadata.test.ts`:
- Around line 269-290: Tighten the route assertion in
resolveActiveRouteIdFromEnv so it checks the exact fallback behavior instead of
only excluding cloudflare. Update the two expectations in the routeMetadata test
to assert the returned route is custom for both the gatewayUrl and restUrl
cases, using resolveActiveRouteIdFromEnv as the target symbol so the regression
coverage matches the intended runtime behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79745567-d799-4216-9616-2af3dc9a01d2

📥 Commits

Reviewing files that changed from the base of the PR and between 923fc5c and a3d72d1.

⛔ Files ignored due to path filters (2)
  • src/integrations/generated/integrationArtifacts.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
  • src/integrations/generated/integrationManifest.generated.ts is excluded by !**/generated/**, !src/integrations/generated/**
📒 Files selected for processing (11)
  • README.md
  • docs/advanced-setup.md
  • src/commands/provider/provider.test.tsx
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/components/ProviderManager.test.tsx
  • src/integrations/compatibility.test.ts
  • src/integrations/gateways/cloudflare.ts
  • src/integrations/index.test.ts
  • src/integrations/index.ts
  • src/integrations/routeMetadata.test.ts
  • src/integrations/routeMetadata.ts
📜 Review details
🔇 Additional comments (12)
src/commands/provider/provider.test.tsx (1)

431-456: Cloudflare Workers AI save-message coverage looks solid.

Model, endpoint, and redaction assertions line up with buildProfileSaveMessage/buildSavedProfileSummary. The earlier concern about OPENAI_API_KEY masking a broken CLOUDFLARE_API_TOKEN path was already flagged and marked addressed in prior commits — keeping both keys here appears intentional since buildSavedProfileSummary's default case only inspects OPENAI_API_KEYS/OPENAI_API_KEY for credentialLabel, so removing OPENAI_API_KEY would break this assertion regardless of the Cloudflare token.

src/components/ProviderManager.test.tsx (1)

840-900: LGTM!

README.md (1)

256-256: LGTM!

docs/advanced-setup.md (1)

329-339: LGTM!

src/integrations/gateways/cloudflare.ts (1)

1-95: LGTM!

src/integrations/index.test.ts (1)

64-85: LGTM!

src/integrations/compatibility.test.ts (1)

18-54: LGTM!

src/integrations/routeMetadata.ts (2)

381-433: LGTM!

isCloudflareBaseUrl correctly requires HTTPS, exact host match, and the Workers AI path shape, and rejects unresolved <ACCOUNT_ID> placeholders — properly closes the host-only matching gap flagged in earlier review rounds.


929-971: LGTM!

Verified the route/profile boundary gating traces correctly for both the retargeted-gateway and real-Workers-AI-endpoint test scenarios.

Also applies to: 1007-1063

src/integrations/index.ts (1)

141-141: LGTM!

src/integrations/routeMetadata.test.ts (1)

1-268: LGTM!

Also applies to: 292-661

src/components/ConsoleOAuthFlow.test.tsx (1)

136-144: LGTM!

🛑 Comments failed to post (1)
src/components/ProviderManager.test.tsx (1)

117-127: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate the actual preset list rendered by the component to confirm ordering matches the test constant.
rg -n "Cloudflare Workers AI" src/components src/utils src/integrations -C3

Repository: Gitlawb/openclaude

Length of output: 12087


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- ProviderManager.test.tsx ---\n'
sed -n '1,240p' src/components/ProviderManager.test.tsx

printf '\n--- locate preset list / Cloudflare Workers AI ---\n'
rg -n "Cloudflare Workers AI|PRESET_ORDER|navigateToPreset|providerProfiles|provider.tsx|preset" src/components src -C 3

Repository: Gitlawb/openclaude

Length of output: 247


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- ProviderManager.test.tsx ---'
sed -n '1,240p' src/components/ProviderManager.test.tsx

printf '\n%s\n' '--- locate preset list / Cloudflare Workers AI ---'
rg -n "Cloudflare Workers AI|PRESET_ORDER|navigateToPreset|providerProfiles|provider.tsx|preset" src/components src -C 3

Repository: Gitlawb/openclaude

Length of output: 50375


🌐 Web query:

"site:github.com/Gitlawb/openclaude \"Cloudflare Workers AI\" \"ProviderManager.test.tsx\""

💡 Result:

In the Gitlawb/openclaude repository, ProviderManager.test.tsx is a core test file responsible for verifying the behavior of the provider selection and management UI [1][2][3]. Specifically, it ensures that: 1. Provider Presets and Ordering: The test suite maintains a list of expected provider presets (e.g., Anthropic, DeepSeek, Z.AI, LLMTR) [2][4][3]. When new providers are added to the application, this file is typically updated to verify that the UI displays them in the correct order [4][3]. 2. UI Navigation and Interaction: It validates that the provider picker allows users to navigate, select, and configure different LLM providers, often testing that the navigation logic remains stable even as the list of providers grows [4]. 3. Configuration and Normalization: The tests ensure that provider-specific configurations—such as multi-model selections or specialized parameters—are correctly normalized and saved during user interactions [5]. While your query mentioned "Cloudflare Workers AI," the provided search results indicate that ProviderManager.test.tsx focuses on the integration and UI testing of various LLM provider presets (like OpenAI, Atomic Chat, and Z.AI) [2][3]. If "Cloudflare Workers AI" is implemented as a provider within this repository, it would be managed and tested via this same framework, likely requiring an entry in the provider list and associated logic within ProviderManager.tsx and its corresponding test file [2][4][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re
from pathlib import Path

def extract_array(path, const_name):
    text = Path(path).read_text()
    m = re.search(rf'const {re.escape(const_name)} = \[(.*?)\n\]', text, re.S)
    if not m:
        m = re.search(rf'export const {re.escape(const_name)} = \[(.*?)\n\]', text, re.S)
    if not m:
        raise SystemExit(f"could not find {const_name} in {path}")
    body = m.group(1)
    items = re.findall(r"'([^']*)'|\"([^\"]*)\"", body)
    return [a or b for a, b in items]

test_order = extract_array('src/components/ProviderManager.test.tsx', 'PRESET_ORDER')
live_order = extract_array('src/integrations/generated/integrationManifest.generated.ts', 'ORDERED_PROVIDER_PRESETS')

# Map a few human labels to manifest ids where obvious.
label_to_id = {
    'Gitlawb Opengateway': 'gitlawb-opengateway',
    'Anthropic': 'anthropic',
    'AI/ML API': 'aimlapi',
    'Alibaba Coding Plan (China)': 'dashscope-cn',
    'Alibaba Coding Plan': 'dashscope-intl',
    'Atlas Cloud': 'atlas-cloud',
    'Azure OpenAI': 'azure-openai',
    'Bankr': 'bankr',
    'ClinePass': 'clinepass',
    'Cloudflare Workers AI': 'cloudflare',
    'DeepSeek': 'deepseek',
    'Codex OAuth': 'openai',
}

# Normalize to ids when possible, otherwise keep literal.
norm_test = [label_to_id.get(x, x) for x in test_order]
print('Test length:', len(norm_test))
print('Live length:', len(live_order))
for i, (t, l) in enumerate(zip(norm_test, live_order)):
    if t != l:
        print('First mismatch at index', i, 'test=', t, 'live=', l)
        break
else:
    print('No mismatch in shared prefix; compared', min(len(norm_test), len(live_order)), 'items')

# Show the relevant window around cloudflare/deepseek.
for name in ['cloudflare', 'deepseek', 'openai']:
    if name in live_order:
        idx = live_order.index(name)
        print('Live window', name, idx, live_order[max(0, idx-2):idx+3])

for label in ['Cloudflare Workers AI', 'DeepSeek', 'Codex OAuth']:
    if label in test_order:
        idx = test_order.index(label)
        print('Test window', label, idx, test_order[max(0, idx-2):idx+3])
PY

Repository: Gitlawb/openclaude

Length of output: 839


Keep PRESET_ORDER aligned with the live manifest order. The test list diverges after Cloudflare Workers AI (Fireworks AI/Gemini/…), so navigateToPreset can land on the wrong row for later cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ProviderManager.test.tsx` around lines 117 - 127, The
PRESET_ORDER test fixture is out of sync with the live provider manifest, which
can cause navigateToPreset to target the wrong preset for later entries. Update
the PRESET_ORDER array in ProviderManager.test.tsx to match the current manifest
order exactly, especially the entries after Cloudflare Workers AI, so the test
navigation logic resolves the intended rows.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

CodeRabbit still has a valid Cloudflare route-metadata test request on this PR, and CONTRIBUTING.md asks PR authors to address automated review findings before waiting for maintainers to restate them. The runtime Cloudflare route boundary looks fixed now; I found two remaining cleanup items before this is ready.

Findings

  • [P3] Complete CodeRabbit's request to assert the exact fallback route
    src/integrations/routeMetadata.test.ts:269
    The current implementation returns custom when a saved cloudflare profile is retargeted to gateway.ai.cloudflare.com or to a non-Workers api.cloudflare.com REST path, but this regression test only checks .not.toBe('cloudflare'). That would still pass if a future change routed those URLs to some other incorrect route instead of the intended generic OpenAI-compatible fallback. Please complete CodeRabbit's current request by changing both resolveActiveRouteIdFromEnv() expectations in this test to assert custom explicitly.

  • [P3] Bring the PR description back in sync with the final implementation
    PR description
    The current PR body still describes the initial version rather than the code now under review: it says the descriptor is in src/integrations/vendors/cloudflare.ts, says validation routes on gateway.ai.cloudflare.com, says users can paste Cloudflare AI Gateway URLs and have matchBaseUrlHosts pick them up, and still lists smoke as failing locally. The current patch instead adds src/integrations/gateways/cloudflare.ts, intentionally excludes gateway.ai.cloudflare.com from Workers AI routing, and has green smoke checks on GitHub. Please update the description/testing notes so maintainers and future readers do not rely on the stale gateway behavior or stale check status.

Pin both resolveActiveRouteIdFromEnv assertions for a retargeted cloudflare
profile to .toBe('custom') instead of .not.toBe('cloudflare'), so the test
locks the intended generic OpenAI-compatible fallback rather than merely
excluding the cloudflare route.
@0xfandom

0xfandom commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Both cleanup items addressed:

  • Exact fallback assertion (b489a62) — the two resolveActiveRouteIdFromEnv() expectations for a retargeted cloudflare profile (shared AI Gateway host and non-Workers api.cloudflare.com REST path) now assert .toBe('custom') instead of .not.toBe('cloudflare'), pinning the intended generic OpenAI-compatible fallback. Confirmed both resolve to custom at runtime.
  • PR description — rewritten to match the code now under review: descriptor lives at src/integrations/gateways/cloudflare.ts, the Workers AI boundary is the path-aware isCloudflareBaseUrl() (excludes gateway.ai.cloudflare.com, non-Workers REST paths, and http://), retargeted profiles fall back to custom, and smoke is green on GitHub.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@0xfandom

0xfandom commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Both items were already resolved by b489a62 (pushed 2026-07-08, after this review):

  • routeMetadata.test.ts — both retargeted-profile resolveActiveRouteIdFromEnv() assertions now assert .toBe('custom') explicitly (lines 283, 291), not .not.toBe('cloudflare'), so the test fails if a future change routes the AI Gateway host or a non-Workers REST path anywhere other than the intended generic fallback.
  • PR description — the body now matches the current implementation: descriptor at src/integrations/gateways/cloudflare.ts, gateway.ai.cloudflare.com and non-Workers api.cloudflare.com paths intentionally excluded from Workers AI routing (fall back to custom), and green smoke-and-tests on GitHub. The stale gateway-routing / failing-smoke text is gone.

Also completed CodeRabbit's open profile-token-mirror request in the same push — all four mirror sites gate on the path-aware isCloudflareBaseUrl(...) predicate (resolved that thread with the site list).

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice one! thank you @0xfandom

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.

Add Cloudflare AI

5 participants