Skip to content

feat(agents): createAI on env.AI.run and the provider-native path, for the AI SDK and pi-ai - #2576

Merged
mattzcarey merged 7 commits into
mainfrom
feat/createai-run-transport
Oct 14, 2026
Merged

mattzcarey merged 7 commits into
mainfrom
feat/createai-run-transport

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

createAI (agents/models/ai-sdk and agents/models/pi-ai) stops using AI Gateway's deprecated Universal Endpoint. Every request now goes through one of the AI binding's two routes: env.AI.run for model ids, and the binding's fetch to the provider-native path for a vendor's own model object.

// agents/models/ai-sdk
ai("@cf/zai-org/glm-4.7-flash");  // env.AI.run → Workers AI
ai("anthropic/claude-opus-4.8");  // env.AI.run → /run (catalog id, gateway spelling)
ai("dynamic/support");            // env.AI.run → /run (dynamic route)
ai(anthropic("claude-opus-4-8")); // env.AI.fetch → provider-native path

// agents/models/pi-ai
ai("anthropic/claude-opus-4.8");  // env.AI.run → /run, Messages in and out
ai("openai/gpt-5.4");             // env.AI.run → /run, Responses in and out
ai(getBuiltinModel("anthropic", "claude-opus-4-8")); // provider-native path

The Universal Endpoint (env.AI.gateway(id).run) is deprecated and no longer in the binding docs.

  • Catalog ids go to /run, which looks models up by exact catalog name, so they use the gateway's spelling. The binding's openaiEndpoint option tells aig-entry which requestFormat to use.
    • AI SDK string ids are always chat completions.
    • pi-ai sends each catalog model in its native format, Messages or Responses, so /run converts 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.
  • Model objects go to the provider-native path through the binding's own fetch, which aig-entry serves at /ai-gateway/gateways/{gateway}/{provider}/*. The request is the vendor's, untouched, multipart included. Gateway options become cf-aig-* headers. The vendor keeps its own id spelling, which its package uses to pick capabilities.
  • The universal transport is deleted from the core.
  • Known limit: pi-ai sends catalog Claude models to /run without anthropic-beta, because aig-entry forwards only cf-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.
  • A model object's fetch(Request) body streams through to the binding instead of being read into memory.
  • agents/models/opencode wraps 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, zdr and vendorKey apply where the gateway reads them. All three work on the provider-native path. On /run, byokAlias works for catalog ids and zdr does nothing.
  • Fixes found by calling live models:
    • pi-ai's chat-completions wire read usage.prompt_tokens on OpenAI chunks that carry usage: null, so a pi-ai dynamic route served by OpenAI failed. It now skips null.
    • Strict-OpenAI requests send max_completion_tokens, because openai/gpt-5* rejects max_tokens.
    • When the AI SDK asks /run for 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 agents account's default gateway, with both frameworks. Every case returned the right answer:

  • AI SDK: @cf/ generate; catalog generate and streaming for openai/gpt-5-mini and anthropic/claude-haiku-4.5; a streamed catalog tool loop; Anthropic and OpenAI model objects, generated and streamed.
  • Dynamic routes: a throwaway route on default (served by openai/gpt-5-mini) through AI SDK generateText and streamText, and through pi-ai.
  • pi-ai: @cf/; anthropic/claude-haiku-4.5 and openai/gpt-5-mini on /run, with runId captured; Anthropic and OpenAI registry models on the provider-native path.

/run streams carry cf-aig-run-id, and the binding's resume route replays from an event index (404 once the buffer is gone). That's for the follow-up that adds resume. pnpm run check and the model tests pass.

@changeset-bot

changeset-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fda892f

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

This PR includes changesets to release 2 packages
Name Type
agents Patch
@cloudflare/agent-think 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

devin-ai-integration[bot]

This comment was marked as resolved.

@agent-think

agent-think Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

🟡 agents import sizes: 1 entry point grew

Entry point Exports Largest gzip change Size now
🟡 agents/models/ai-sdk 2 resized up to +680 B (+3.38%) 20.3 KiB
Changed exports (2)
Import Gzip change Size now
🟡 agents/models/ai-sdk#createAI +680 B (+3.38%) 20.3 KiB
🟡 agents/models/ai-sdk#GatewayLanguageModel +513 B (+3.34%) 15.5 KiB
How this works

Each 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 89ab4f6e → fda892f8 · workflow run · reported by agent-think[bot]

@mattzcarey
mattzcarey marked this pull request as draft October 13, 2026 11:46
@pkg-pr-new

pkg-pr-new Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2576

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2576

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2576

hono-agents

npm i https://pkg.pr.new/hono-agents@2576

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2576

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2576

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2576

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2576

commit: fda892f

@mattzcarey mattzcarey changed the title feat(agents)!: createAI runs every model on env.AI.run, with AI Gateway catalog ids feat(agents): createAI takes AI Gateway catalog ids, model objects move to the provider-native path Oct 13, 2026
@mattzcarey mattzcarey changed the title feat(agents): createAI takes AI Gateway catalog ids, model objects move to the provider-native path feat(agents): createAI on env.AI.run and the provider-native path, for the AI SDK and pi-ai Oct 13, 2026
@mattzcarey
mattzcarey marked this pull request as ready for review October 14, 2026 13:10

@devin-ai-integration devin-ai-integration 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.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 2 new potential issues.

Devin Review

const response = await transport.run({
format,
gateway: resolved.gateway,
headers: request.headers,

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.

🔴 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.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

Comment thread packages/agents/src/models/ai-sdk/models/gateway.ts Outdated
devin-ai-integration[bot]

This comment was marked as resolved.

@mattzcarey
mattzcarey added this pull request to stack #2590 October 14, 2026 13:30

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 new potential issue.

Devin Review

Comment thread docs/agents/models.md
Comment on lines 154 to 156
import { createOpenAI } from "@ai-sdk/openai";

const anthropic = createAnthropic({ apiKey: "cloudflare" }); // placeholder
const openai = createOpenAI({ apiKey: "cloudflare" });

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.

🔍 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.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@mattzcarey
mattzcarey merged commit b048873 into main Oct 14, 2026
17 checks passed
@mattzcarey
mattzcarey deleted the feat/createai-run-transport branch October 14, 2026 15:42
@github-actions github-actions Bot mentioned this pull request Oct 14, 2026
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