Skip to content

Rewrite ai-gateway-provider: new API, backward-compatible deprecations, comprehensive tests#409

Open
threepointone wants to merge 6 commits intomainfrom
aig-rewrite
Open

Rewrite ai-gateway-provider: new API, backward-compatible deprecations, comprehensive tests#409
threepointone wants to merge 6 commits intomainfrom
aig-rewrite

Conversation

@threepointone
Copy link
Copy Markdown
Collaborator

@threepointone threepointone commented Feb 22, 2026

Summary

New API for ai-gateway-provider — users now bring their own AI SDK provider and wrap it with createAIGateway. The old API (createAiGateway, ai-gateway-provider/providers/*) still works with deprecation warnings, making this a non-breaking minor release.

Before:

import { createAiGateway } from "ai-gateway-provider";
import { createOpenAI } from "ai-gateway-provider/providers/openai";
const aigateway = createAiGateway({ accountId, gateway, apiKey });
const openai = createOpenAI({ apiKey });
generateText({ model: aigateway([openai.chat("gpt-4o")]), prompt: "..." });

After:

import { createAIGateway } from "ai-gateway-provider";
import { createOpenAI } from "@ai-sdk/openai";
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
const gateway = createAIGateway({
  provider: openai,
  binding: env.AI.gateway("my-gateway"),
});
generateText({ model: gateway("gpt-4o"), prompt: "..." });

New features

  • createAIGateway — wraps any AI SDK provider, supports binding + REST API modes
  • createAIGatewayFallback — cross-provider fallback in a single gateway request
  • providerName — explicit provider name for custom base URLs / proxies
  • byok: true — strips provider auth headers for BYOK / Unified Billing
  • byokAlias and zdr gateway options (were missing entirely)
  • 22 providers auto-detected from URL (up from 13)
  • resolveProvider exported as a utility

Bug fixes

  • Updated stale cache header names (cf-skip-cachecf-aig-skip-cache, cf-cache-ttlcf-aig-cache-ttl)
  • Fixed BYOK leaking dummy API keys (Authorization: Bearer unused was forwarded to the provider)
  • Fixed fetch mutation not restored after gateway calls — now uses try/finally so model instances recover from errors
  • Fixed cacheTtl: 0 silently ignored (falsy check → !== undefined)
  • Fixed non-JSON gateway error responses (400/401) crashing with SyntaxError instead of returning the raw response
  • Fixed case-sensitive auth header stripping — headers are now normalized to lowercase before BYOK stripping
  • Fixed feedResponseToModel returning a consumed Response on repeated calls — now uses resp.clone()
  • Fixed fallback finally cleanup not running when captureModelRequest fails partway through the model list
  • Propagated abort signals to binding.run() and fetch() calls
  • Removed unanchored Google Vertex regex (could match unintended URLs)
  • Fixed query parameter loss for custom URLs with providerName
  • Removed dead headerKey fields from provider registry
  • Removed bigint from metadata type (was a runtime crash — JSON.stringify can't serialize bigints)

Deprecated (all still work, with one-time console warnings)

Deprecated Replacement
createAiGateway() createAIGateway() / createAIGatewayFallback()
ai-gateway-provider/providers/* subpath imports Import directly from @ai-sdk/*
AiGatewaySettings type AiGatewayConfig
AiGatewayAPISettings type AiGatewayAPIConfig
AiGatewayBindingSettings type AiGatewayBindingConfig
AiGatewayReties type AiGatewayRetries

Deprecated shims preserve the old provider subpath imports by re-exporting from @ai-sdk/* packages (kept as optionalDependencies). The old authWrapper / CF_TEMP_TOKEN BYOK mechanism is intentionally dropped — it was leaking keys. Users doing BYOK should use byok: true on the new API.

All deprecated APIs will be removed in the next major version.

Tests

  • 124 unit tests (mocked via msw) covering:
    • Gateway dispatch (API + binding modes), streaming, options, provider detection
    • Fallback (step routing, body structure, error paths, out-of-bounds step)
    • BYOK auth stripping (all 4 header types, case-insensitive)
    • Abort signal propagation (binding + API + fallback)
    • Fetch restoration after errors (try/finally correctness)
    • Non-JSON gateway error responses (400/401 with HTML/text bodies)
    • Deprecated createAiGateway compat (callable, .chat(), array fallback, binding)
    • Unsupported provider detection, partial capture failure cleanup
    • providerName, custom base URLs, compat endpoint
  • Integration tests for both binding and REST API modes (auth + unauth, own key + BYOK, generate + stream)
  • Gateway e2e tests added to workers-ai-provider (chat, stream, multi-turn, tools, structured output, embeddings, images via AI Gateway binding)

Notes for reviewers

  1. The fetch-hijack pattern is inherited from the old code. It works by replacing model.config.fetch with a spy to capture the request, then replaying with the gateway response. We now save and restore the original fetch in a try/finally block. Concurrent use of the same model instance is still unsafe (but each gateway("gpt-4o") call creates a fresh instance, so this isn't a practical concern).

  2. Workers AI doesn't go through createAIGateway — it uses binding.run() (RPC, not HTTP) and has its own built-in gateway option. This is documented in both READMEs. The workers-ai-provider change is test-only (adding ?gateway= param support to the test worker).

  3. BYOK requires byok: true on the gateway config. Without it, the provider's auth header is forwarded to the gateway. With byok: true, auth headers (authorization, x-api-key, api-key, x-goog-api-key) are stripped before dispatch. Headers are normalized to lowercase first so stripping works regardless of original casing.

  4. The compat provider entry enables the Unified API / Dynamic Routes flow. Users point the OpenAI SDK at https://gateway.ai.cloudflare.com/v1/compat and use model names like google-ai-studio/gemini-2.5-pro or dynamic/my-route.

  5. .env filestest/integration/.env contains real credentials and is gitignored. Only .env.example is committed.

Test plan

  • All 124 unit tests pass (npm run test:unit)
  • TypeScript compiles cleanly (npx tsc --noEmit)
  • Integration tests pass with real Cloudflare gateways (auth + unauth, own key + BYOK, binding + REST)
  • No breaking changes — all old exports preserved with deprecation warnings
  • Manual testing of gateway options (caching, metadata, retries, etc.)
  • Verify with providers beyond OpenAI (Anthropic, Google, Mistral)

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 22, 2026

🦋 Changeset detected

Latest commit: 0adac9c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
ai-gateway-provider Minor
workers-ai-provider Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Feb 22, 2026

Open in StackBlitz

npx https://pkg.pr.new/cloudflare/ai/ai-gateway-provider@409
npx https://pkg.pr.new/cloudflare/ai/@cloudflare/tanstack-ai@409
npx https://pkg.pr.new/cloudflare/ai/workers-ai-provider@409

commit: 0adac9c

Major rewrite of packages/ai-gateway-provider: new public API (createAIGateway and createAIGatewayFallback) that wraps standard AI SDK providers instead of providing many internal provider wrappers. Removes src/auth.ts and all src/providers/* wrapper files, drops optionalDependencies and subpath provider exports, and updates package.json scripts and peerDeps. index.ts was refactored to add resolveProvider, capture/restore fetch logic, request normalization, BYOK auth stripping, cf-aig-* gateway option headers, and binding vs REST dispatch. README and new chat.md updated with usage, options, supported providers, and Workers guidance. Added comprehensive unit, integration, and e2e tests and accompanying changeset files.
Delete the local patch for @ai-sdk/google-vertex and clear patchedDependencies in package.json. pnpm-lock.yaml was updated (regenerated) to remove references to the patch and related patched package entries — the patch is no longer required.
Delete the CODEOWNERS file which previously assigned /packages/ai-gateway-provider/* to @G4brym, removing that ownership entry and any associated automatic reviews/notifications.
Allow request cancellation for AI Gateway calls by adding an optional AbortSignal parameter. Updated AiGatewayBinding.run signature to accept options with signal, extended dispatchToGateway to accept and forward a signal to either the binding.run call or the underlying fetch, and wired options.abortSignal through AiGatewayChatLanguageModel and AiGatewayFallbackModel when dispatching. This enables callers to abort in-flight gateway requests.
Introduce new createAIGateway API that wraps standard AI SDK providers and add deprecation-compatible shims for old provider imports. Add provider subpath exports in package.json and optionalDependencies for @ai-sdk/* packages. Implement robustness and bug fixes: normalize headers, clone responses for model fetch, restore original fetch via try/finally, propagate abort signals to bindings/fetch, handle non-JSON 400/401 gateway bodies, and strip BYOK auth headers. Add deprecated createAiGateway compatibility layer and type aliases with one-time console warnings, update README migration docs, and add unit/robustness tests covering these behaviors.
@threepointone threepointone changed the title Rewrite ai-gateway-provider: new API, comprehensive tests, full docs Rewrite ai-gateway-provider: new API, backward-compatible deprecations, comprehensive tests Mar 22, 2026
Add a new README section showing how to combine createAIGateway with the AI SDK's createProviderRegistry to route requests by model name across multiple providers. Includes a TypeScript example wiring OpenAI and Anthropic through the same gateway and explains that provider-specific features are preserved while routing traffic for caching, logging, and analytics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant