Repository navigation
feat(agents): createAI on env.AI.run and the provider-native path, for the AI SDK and pi-ai - #2576
Conversation
🦋 Changeset detectedLatest commit: fda892f The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
🟡 agents import sizes: 1 entry point grew
Changed exports (2)
How this worksEach runtime export is bundled on its own, minified, and gzipped. Changes smaller than 100 B, or smaller than 1% and 1 KiB, are ignored. Growth over 10% or 5 KiB is marked 🔴. This report is informational and does not fail CI. The workflow artifact contains every measurement. Compared |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
| const response = await transport.run({ | ||
| format, | ||
| gateway: resolved.gateway, | ||
| headers: request.headers, |
There was a problem hiding this comment.
🔴 Catalog Claude loses beta feature headers
For catalog Claude models using interleaved thinking or fine-grained tool streaming, sendGateway drops pi-ai's anthropic-beta header. The gateway receives only request.headers, so these requests lose the beta features their bodies require.
Learn more
Pi-ai supplies beta feature names through betas when building Anthropic Messages requests. anthropicVendorHeaders puts those names in anthropic-beta, which the provider-native branch sends but this catalog branch omits. Catalog requests using interleaved thinking or fine-grained tool streaming therefore reach /run without the header pi-ai selected.
Example: A Sonnet catalog model requests budgeted thinking and pi-ai selects interleaved-thinking-2025-05-14. The native request includes the beta header, but the catalog request sends only request.headers; the beta feature is not enabled.
Recommended fix: Include the applicable vendorHeaders in the catalog run request's extra headers, at least anthropic-beta, while preserving the gateway and caller header precedence. Test a catalog model that produces nonempty betas.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Not fixable from the client today. On the binding's /run path, aig-entry forwards only cf-aig-* keys from extraHeaders (apps/aig-entry/src/ai-gateway-run.ts), so an anthropic-beta header never reaches the connector, and /run takes no body field for betas. The request still works; it runs without those beta features (interleaved thinking, fine-grained tool streaming). A model object on the provider-native path keeps the header, because that path forwards the vendor's request unchanged.
…ams read as chat completions
…th; drop the universal transport
fd562ce to
6cfc9bc
Compare
| import { createOpenAI } from "@ai-sdk/openai"; | ||
|
|
||
| const anthropic = createAnthropic({ apiKey: "cloudflare" }); // placeholder | ||
| const openai = createOpenAI({ apiKey: "cloudflare" }); |
There was a problem hiding this comment.
🔍 Catalog vendor-feature guidance is missing
The catalog section no longer directs users to model objects for vendor-only features. The pending header tests acknowledge that /run drops anthropic-beta, while the options table still lists headers without that limitation.
Was this helpful? React with 👍 or 👎 to provide feedback.
createAI(agents/models/ai-sdkandagents/models/pi-ai) stops using AI Gateway's deprecated Universal Endpoint. Every request now goes through one of theAIbinding's two routes:env.AI.runfor model ids, and the binding'sfetchto the provider-native path for a vendor's own model object.The Universal Endpoint (
env.AI.gateway(id).run) is deprecated and no longer in the binding docs./run, which looks models up by exact catalog name, so they use the gateway's spelling. The binding'sopenaiEndpointoption tellsaig-entrywhichrequestFormatto use./runconverts nothing and pi's own stream processors read the answer. The old pi path put the catalog spelling (claude-opus-4.8) in the body sent to Anthropic, which Anthropic rejects.fetch, whichaig-entryserves at/ai-gateway/gateways/{gateway}/{provider}/*. The request is the vendor's, untouched, multipart included. Gateway options becomecf-aig-*headers. The vendor keeps its own id spelling, which its package uses to pick capabilities./runwithoutanthropic-beta, becauseaig-entryforwards onlycf-aig-*headers on that path. Requests work, just without beta features such as interleaved thinking. Model objects on the provider-native path keep the header.fetch(Request)body streams through to the binding instead of being read into memory.agents/models/opencodewraps the AI SDK provider, so it inherits all of this. Its types and docs now take catalog ids and dynamic routes too, and it checks an id when the model is named.byokAlias,zdrandvendorKeyapply where the gateway reads them. All three work on the provider-native path. On/run,byokAliasworks for catalog ids andzdrdoes nothing.usage.prompt_tokenson OpenAI chunks that carryusage: null, so a pi-ai dynamic route served by OpenAI failed. It now skipsnull.max_completion_tokens, becauseopenai/gpt-5*rejectsmax_tokens./runfor chat completions, a streamed Claude catalog model still answers in Anthropic events, because the legacy runtime doesn't convert streams. The stream normalizer turns those events into chat-completions chunks, recognising them by shape, so the code stops running once the gateway converts streams.I ran this on the
agentsaccount'sdefaultgateway, with both frameworks. Every case returned the right answer:@cf/generate; catalog generate and streaming foropenai/gpt-5-miniandanthropic/claude-haiku-4.5; a streamed catalog tool loop; Anthropic and OpenAI model objects, generated and streamed.default(served byopenai/gpt-5-mini) through AI SDKgenerateTextandstreamText, and through pi-ai.@cf/;anthropic/claude-haiku-4.5andopenai/gpt-5-minion/run, withrunIdcaptured; Anthropic and OpenAI registry models on the provider-native path./runstreams carrycf-aig-run-id, and the binding's resume route replays from an event index (404once the buffer is gone). That's for the follow-up that adds resume.pnpm run checkand the model tests pass.