Skip to content

fix(provider): match xAI base URL by hostname, not 'x.ai' substring#1669

Merged
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
0xfandom:fix/xai-baseurl-substring-host-match
Jun 17, 2026
Merged

fix(provider): match xAI base URL by hostname, not 'x.ai' substring#1669
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
0xfandom:fix/xai-baseurl-substring-host-match

Conversation

@0xfandom

@0xfandom 0xfandom commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Problem

The xAI credential-mirroring checks in src/utils/providerProfiles.ts matched the base URL with a raw substring:

profile.baseUrl?.toLowerCase().includes('x.ai')

x.ai is a substring of unrelated hostnames — vertex.ai, essex.ai, max.ai, prox.ai all contain it. So an OpenAI-compatible profile pointed at such a host was wrongly treated as xAI:

  • its api key was mirrored into XAI_API_KEY, and
  • provider detection (getAPIProvider) flipped to xai,

which breaks model routing for that profile.

This file already imports isFireworksBaseUrl / isNearaiBaseUrl from routeMetadata and uses them for exactly this kind of check; the xAI sites were just inconsistent leftovers. A matching isXaiBaseUrl helper already exists and matches hostname === 'api.x.ai'.

Fix

Route the three xAI sites through isXaiBaseUrl:

  • profileSecretsAreComplete
  • the OpenAI profile-env builder (openAIProfileEnv.XAI_API_KEY)
  • the active-profile env builder (env.XAI_API_KEY)

No behavior change for real xAI profiles (https://api.x.ai/v1); lookalike hosts are no longer misrouted.

Test

Added a regression test in providerProfiles.test.ts: a profile with baseUrl: https://vertex.ai/v1 does not set XAI_API_KEY and is not detected as the xai provider. Verified it fails before the fix and passes after. tsc --noEmit clean; full providerProfiles.test.ts suite green (91 tests).

Summary by CodeRabbit

  • Bug Fixes

    • Improved detection of XAI-compatible API endpoints to accurately distinguish from services with similar domain names (e.g., Vertex AI).
  • Tests

    • Added regression test to verify correct API key handling for lookalike service URLs.

The xAI credential-mirroring checks in providerProfiles.ts used
`baseUrl.toLowerCase().includes('x.ai')`. That substring matches unrelated
hosts — e.g. `vertex.ai`, `essex.ai`, `max.ai` all contain `x.ai` — so an
OpenAI-compatible profile pointed at such a host was wrongly treated as xAI:
its api key got mirrored into XAI_API_KEY and route detection flipped to
`xai`, breaking model routing.

Route the three sites (profileSecretsAreComplete, the openAI profile-env
builder, and the active-profile env builder) through the existing
`isXaiBaseUrl` helper, which matches `hostname === 'api.x.ai'` — consistent
with how isFireworksBaseUrl/isNearaiBaseUrl are already used in this file.

Add a regression test asserting a `vertex.ai` profile does not set
XAI_API_KEY and is not detected as the xai provider.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 066ac519-1ddb-45b5-95ee-f3a2fe936a73

📥 Commits

Reviewing files that changed from the base of the PR and between 7be9dce and 0abb235.

📒 Files selected for processing (2)
  • src/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: typecheck
  • GitHub Check: smoke-and-tests
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise in code

Files:

  • src/utils/providerProfiles.test.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/providerProfiles.test.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/providerProfiles.test.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/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 fix: skip assertMinVersion for third-party providers #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/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
🔇 Additional comments (2)
src/utils/providerProfiles.ts (1)

47-47: LGTM!

Also applies to: 563-566, 713-715, 1013-1015

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

783-805: LGTM!


📝 Walkthrough

Walkthrough

Replaces the substring-based baseUrl.toLowerCase().includes('x.ai') XAI detection with a dedicated isXaiBaseUrl() helper across three call sites in providerProfiles.ts. Adds a corresponding regression test that confirms a vertex.ai base URL does not trigger XAI key mirroring.

Changes

XAI URL Detection Fix

Layer / File(s) Summary
isXaiBaseUrl() adoption in providerProfiles
src/utils/providerProfiles.ts
Imports isXaiBaseUrl from routeMetadata.js and replaces the loose includes('x.ai') string check in three call sites: profile env alignment check, applyProviderProfileToProcessEnv, and buildOpenAICompatibleStartupEnv.
Regression test for lookalike host
src/utils/providerProfiles.test.ts
Adds a test case asserting that a vertex.ai base URL does not set XAI_API_KEY, keeps OPENAI_API_KEY set, and does not resolve the provider as xai.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

bug

Suggested reviewers

  • kevincodex1
🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed Title accurately and concisely describes the core fix: replacing substring-based xAI URL detection with hostname matching via the isXaiBaseUrl helper.
Description check ✅ Passed Description covers the problem, root cause, fix approach, testing methodology, and verification steps. All key template sections (Summary, Impact, Testing, Notes) are substantially addressed with concrete details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Risk Surface Disclosed ✅ Passed PR touches provider routing (sensitive area). Risk surface is fully disclosed: credential mirroring bug with substring matching, impact on model routing, specific lookalike hosts listed, no behavio...
No Hidden Policy Change ✅ Passed PR fixes a credential-mirroring bug in xAI detection using proper hostname validation (isXaiBaseUrl) instead of substring matching. No hidden product, trust-model, routing-default, telemetry, or pe...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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 contribution. I do not see any actionable issues from my review.

@kevincodex1 LGTM

@kevincodex1 kevincodex1 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.

lgtm

@kevincodex1 kevincodex1 merged commit 1b33fa6 into Gitlawb:main Jun 17, 2026
4 checks passed
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.

3 participants