Summary
AiGatewayChatLanguageModel in [email protected] (dist/index.mjs:143) hardcodes supportedUrls = {} instead of forwarding the underlying wrapped provider's supportedUrls. This silently disables URL passthrough for every provider wrapped by createAiGateway, causing AI SDK to download every file URL and inline it as base64 in the request body.
For a wrapped Anthropic model serving a real PDF (4.4 MiB), this means:
- AI SDK sees
supportedUrls === {} from the gateway wrapper
isUrlSupported({ mediaType: 'application/pdf', supportedUrls: {} }) → false
- AI SDK downloads the PDF via
download()
convertPartToLanguageModelPart replaces URL with bytes
- Anthropic provider falls into the
base64 branch (~5.9 MiB after base64)
- Final Anthropic request body is ~6 MB inline data per request
The same PDF, when sent direct to Anthropic without the gateway wrapper, goes through as source: { type: 'url', url: '...' } — Anthropic fetches it server-side, request body stays a few KB.
Reproducer
import { createAnthropic } from 'ai-gateway-provider/providers/anthropic'
import { createAiGateway } from 'ai-gateway-provider'
const anthropic = createAnthropic({ apiKey: 'sk-ant-...' })
const gw = createAiGateway({ accountId: '...', gateway: '...', apiKey: '...' })
const direct = anthropic('claude-sonnet-4-6')
const wrapped = gw(direct)
console.log('direct:', await direct.supportedUrls)
// { 'image/*': [/^https?:\/\/.*$/], 'application/pdf': [/^https?:\/\/.*$/] }
console.log('wrapped:', await wrapped.supportedUrls)
// {} ← bug
Real-world impact
We hit this in production with two symptoms before tracing both to this bug:
- PDF analysis triggered SessionDO (Cloudflare Durable Object) OOM: 128 MB isolate cap exceeded while AI SDK constructed the 6 MB request body around a 4.4 MiB PDF. Affected ~7 specific agents over a week, each in heavy use (~33 MiB VFS, dozens of accumulated sessions).
- Large image uploads hit Anthropic's 5 MiB base64 limit: a 4 MB JPEG that should have been URL-passed-through was downloaded by AI SDK, base64'd to 5.6 MB, rejected by Anthropic with
messages.N.content.M.image.source.base64: image exceeds 5 MB maximum.
Both are downstream effects of supportedUrls = {}.
Expected behavior
AiGatewayChatLanguageModel.supportedUrls should forward the wrapped provider's supportedUrls, the same way modelId and provider already do via getters.
Existing fix in PR #409
The full rewrite in #409 already implements this correctly:
// packages/ai-gateway-provider/src/index.ts (PR #409 HEAD)
get supportedUrls() {
return this.innerModel.supportedUrls; // single-model wrapper
}
get supportedUrls() {
return this.models[0]!.supportedUrls; // fallback wrapper
}
PR #409 has been open since 2026-03-22 with no reviews. It's a large rewrite that introduces a new API surface with backward-compat shims — sound work, but in the meantime users wrapped by createAiGateway are paying real costs (network egress, billable token recompute via cache misses, isolate memory pressure, request latency).
Suggested resolution
Two reasonable options:
a) Minimal targeted fix on the current major (3.x): add a getter to the existing AiGatewayChatLanguageModel class in src/index.ts:
var AiGatewayChatLanguageModel = class {
get modelId() { ... }
get provider() { ... }
+ get supportedUrls() {
+ return this.models[0]?.supportedUrls ?? {};
+ }
constructor(models, config) {
_defineProperty(this, "specificationVersion", "v3");
_defineProperty(this, "defaultObjectGenerationMode", "json");
- _defineProperty(this, "supportedUrls", {});
_defineProperty(this, "models", void 0);
...
}
}
This is what we're currently shipping as a pnpm patch — verified to restore URL passthrough end-to-end (PDF source type goes from base64 to url; request body shrinks from 6 MB to a few KB). Three-line diff, zero behavior change for callers that don't supply file URLs.
b) Land PR #409, which already contains the equivalent fix and additional improvements.
Happy to send a PR with just (a) if it would help unblock affected users while #409 is in flight — just let me know.
Environment
Summary
AiGatewayChatLanguageModelin[email protected](dist/index.mjs:143) hardcodessupportedUrls = {}instead of forwarding the underlying wrapped provider'ssupportedUrls. This silently disables URL passthrough for every provider wrapped bycreateAiGateway, causing AI SDK to download every file URL and inline it as base64 in the request body.For a wrapped Anthropic model serving a real PDF (4.4 MiB), this means:
supportedUrls === {}from the gateway wrapperisUrlSupported({ mediaType: 'application/pdf', supportedUrls: {} })→falsedownload()convertPartToLanguageModelPartreplaces URL with bytesbase64branch (~5.9 MiB after base64)The same PDF, when sent direct to Anthropic without the gateway wrapper, goes through as
source: { type: 'url', url: '...' }— Anthropic fetches it server-side, request body stays a few KB.Reproducer
Real-world impact
We hit this in production with two symptoms before tracing both to this bug:
messages.N.content.M.image.source.base64: image exceeds 5 MB maximum.Both are downstream effects of
supportedUrls = {}.Expected behavior
AiGatewayChatLanguageModel.supportedUrlsshould forward the wrapped provider'ssupportedUrls, the same waymodelIdandprovideralready do via getters.Existing fix in PR #409
The full rewrite in #409 already implements this correctly:
PR #409 has been open since 2026-03-22 with no reviews. It's a large rewrite that introduces a new API surface with backward-compat shims — sound work, but in the meantime users wrapped by
createAiGatewayare paying real costs (network egress, billable token recompute via cache misses, isolate memory pressure, request latency).Suggested resolution
Two reasonable options:
a) Minimal targeted fix on the current major (3.x): add a getter to the existing
AiGatewayChatLanguageModelclass insrc/index.ts:var AiGatewayChatLanguageModel = class { get modelId() { ... } get provider() { ... } + get supportedUrls() { + return this.models[0]?.supportedUrls ?? {}; + } constructor(models, config) { _defineProperty(this, "specificationVersion", "v3"); _defineProperty(this, "defaultObjectGenerationMode", "json"); - _defineProperty(this, "supportedUrls", {}); _defineProperty(this, "models", void 0); ... } }This is what we're currently shipping as a pnpm patch — verified to restore URL passthrough end-to-end (PDF source type goes from
base64tourl; request body shrinks from 6 MB to a few KB). Three-line diff, zero behavior change for callers that don't supply file URLs.b) Land PR #409, which already contains the equivalent fix and additional improvements.
Happy to send a PR with just (a) if it would help unblock affected users while #409 is in flight — just let me know.
Environment
[email protected](latest)@ai-sdk/[email protected][email protected]