Skip to content

feat(ai): add Cloudflare Workers AI as a provider#3851

Merged
badlogic merged 2 commits into
earendil-works:mainfrom
mchenco:feat/cloudflare-workers-ai
Apr 27, 2026
Merged

feat(ai): add Cloudflare Workers AI as a provider#3851
badlogic merged 2 commits into
earendil-works:mainfrom
mchenco:feat/cloudflare-workers-ai

Conversation

@mchenco
Copy link
Copy Markdown
Contributor

@mchenco mchenco commented Apr 27, 2026

closes #3850

Adds cloudflare-workers-ai to KnownProvider. OpenAI-compatible endpoint at https://api.cloudflare.com/client/v4/accounts/{account}/ai/v1, reusing the existing openai-completions API protocol. The per-account URL contains a {CLOUDFLARE_ACCOUNT_ID} placeholder resolved at request time.

Auth: CLOUDFLARE_API_KEY (matches pi's *_API_KEY convention) + CLOUDFLARE_ACCOUNT_ID.

Summary

  • adds cloudflare workers ai to KnownProvider types, env-api-keys.ts. works with /login and env vars
  • generate-models.ts fetches workers ai models from models.dev, filtered to tool-capable
  • cli commands added
  • tests
  • docs added

Verification

Verified end-to-end against my Cloudflare account: 17 e2e tests pass against @cf/moonshotai/kimi-k2.6 across stream/empty/tokens/unicode/tool-call-without-result/total-tokens.

Note on models.generated.ts

I added only the new "cloudflare-workers-ai" block. The rest is byte-identical to main — I deliberately did not run npm run generate-models because live models.dev data has drifted (zai removed several glm models that current tests reference) and a full regenerate would break unrelated tests

A separate cloudflare-ai-gateway PR will follow this one: #3852

Cloudflare Workers AI hosts open-weight LLMs (Kimi K2.6, GPT-OSS,
GLM-4.7, Llama 4, Gemma 4, Nemotron 3) on Cloudflare's GPU network with
an OpenAI-compatible endpoint. Reuses the openai-completions API
protocol; the per-account URL contains a {CLOUDFLARE_ACCOUNT_ID}
placeholder resolved at request time by a small helper.

Pi automatically sets x-session-affinity for prefix caching:
https://developers.cloudflare.com/workers-ai/features/prompt-caching/

Auth: CLOUDFLARE_API_KEY (matches pi's *_API_KEY convention) +
CLOUDFLARE_ACCOUNT_ID. The User-Agent identifies traffic as
'pi-coding-agent' in Cloudflare analytics.

Verified end-to-end against a real Cloudflare account: 17 e2e tests
pass across stream/empty/tokens/unicode/tool-call-without-result/
total-tokens against @cf/moonshotai/kimi-k2.6.

Cloudflare AI Gateway is a separate, larger change (it requires routing
through provider-specific subpaths with the matching API protocol per
upstream) and will land in a follow-up PR.
@github-actions
Copy link
Copy Markdown
Contributor

This PR was auto-closed. Only contributors approved with lgtm can open PRs. Open an issue first.

Maintainers review auto-closed issues daily. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply.

If a maintainer replies lgtmi, your future issues will stay open. If a maintainer replies lgtm, your future issues and PRs will stay open.

See CONTRIBUTING.md.

return new OpenAI({
apiKey,
baseURL: model.baseUrl,
baseURL: isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i don't love this, open to suggestions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we could do a baseURL: resolveBaseUrl(model), general function, not cloudflare-specific. in case more providers want to be onboarded too

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.

i think it's fine. the only reason we need resolveCloudflareBaseUrl here is due to the substitution. openai-completions.ts has become a mess already anways due to all provider specific "fixes". one more will not hurt much.

… per-model metadata

Instead of conditionally setting them in openai-completions.ts based on
provider detection, declare them as model-level fields in the catalog
(headers + compat). This is consistent with how the github-copilot and
kimi-coding entries already declare their static headers.

  packages/ai/scripts/generate-models.ts: emit headers and compat fields
  on each cloudflare-workers-ai entry (CLOUDFLARE_STATIC_HEADERS).
  packages/ai/src/providers/openai-completions.ts: drop the
  isCloudflareProvider conditional that injected User-Agent and the
  isCloudflareWorkersAI override of sendSessionAffinityHeaders.
  packages/ai/src/models.generated.ts: re-spliced 8 cloudflare-workers-ai
  entries with headers + compat.

Behavior is unchanged - verified via fetch interceptor that User-Agent
and x-session-affinity / session_id / x-client-request-id are still sent
on outbound requests. 5/5 e2e tests pass.
@badlogic badlogic reopened this Apr 27, 2026
Copy link
Copy Markdown
Collaborator

@badlogic badlogic left a comment

Choose a reason for hiding this comment

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

Looks good to me overall. resolveCloudflareBaseUrl is quite unfortunate. i'll think about this for a bit, fail to come up with a better solution, then merge.

Cheers!

} as const;

const CLOUDFLARE_STATIC_HEADERS = {
"User-Agent": "pi-coding-agent",
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.

sneaky :) will have to honor telemetry setting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hehe. let me know if i have to change anything to honor it!

return new OpenAI({
apiKey,
baseURL: model.baseUrl,
baseURL: isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl,
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.

i think it's fine. the only reason we need resolveCloudflareBaseUrl here is due to the substitution. openai-completions.ts has become a mess already anways due to all provider specific "fixes". one more will not hurt much.

// Cerebras
{ provider: "cerebras", model: "zai-glm-4.7", label: "cerebras-zai-glm-4.7" },
// Cloudflare Workers AI
{ provider: "cloudflare-workers-ai", model: "@cf/moonshotai/kimi-k2.6", label: "cloudflare-kimi-k2.6" },
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.

good choice

@badlogic badlogic merged commit d6e08b3 into earendil-works:main Apr 27, 2026
mchenco added a commit to mchenco/pi-mono that referenced this pull request Apr 27, 2026
Adapts to badlogic#3851's follow-up fix ("honor telemetry for
Cloudflare attribution headers", fbb5eed) which moved the
'User-Agent: pi-coding-agent' header out of per-model catalog metadata
and into a centralized telemetry-honoring helper
(coding-agent/src/core/sdk.ts:getAttributionHeaders).

- packages/coding-agent/src/core/sdk.ts: extend the cloudflare branch of
  getAttributionHeaders to also match cloudflare-ai-gateway and
  gateway.ai.cloudflare.com.

- packages/ai/scripts/generate-models.ts and src/models.generated.ts:
  drop 'headers' from the 35 cloudflare-ai-gateway entries (constant
  CLOUDFLARE_STATIC_HEADERS no longer exists). Per-route
  compat.sendSessionAffinityHeaders is unchanged.

End-to-end behavior unchanged: 9/9 tests still pass across all three
upstream families (Workers AI, Anthropic, OpenAI Responses).
larsboes pushed a commit to larsboes/pi-mono that referenced this pull request Apr 30, 2026
* feat(ai): add Cloudflare Workers AI as a provider

Cloudflare Workers AI hosts open-weight LLMs (Kimi K2.6, GPT-OSS,
GLM-4.7, Llama 4, Gemma 4, Nemotron 3) on Cloudflare's GPU network with
an OpenAI-compatible endpoint. Reuses the openai-completions API
protocol; the per-account URL contains a {CLOUDFLARE_ACCOUNT_ID}
placeholder resolved at request time by a small helper.

Pi automatically sets x-session-affinity for prefix caching:
https://developers.cloudflare.com/workers-ai/features/prompt-caching/

Auth: CLOUDFLARE_API_KEY (matches pi's *_API_KEY convention) +
CLOUDFLARE_ACCOUNT_ID. The User-Agent identifies traffic as
'pi-coding-agent' in Cloudflare analytics.

Verified end-to-end against a real Cloudflare account: 17 e2e tests
pass across stream/empty/tokens/unicode/tool-call-without-result/
total-tokens against @cf/moonshotai/kimi-k2.6.

Cloudflare AI Gateway is a separate, larger change (it requires routing
through provider-specific subpaths with the matching API protocol per
upstream) and will land in a follow-up PR.

* refactor(ai): move Cloudflare User-Agent and session-affinity flag to per-model metadata

Instead of conditionally setting them in openai-completions.ts based on
provider detection, declare them as model-level fields in the catalog
(headers + compat). This is consistent with how the github-copilot and
kimi-coding entries already declare their static headers.

  packages/ai/scripts/generate-models.ts: emit headers and compat fields
  on each cloudflare-workers-ai entry (CLOUDFLARE_STATIC_HEADERS).
  packages/ai/src/providers/openai-completions.ts: drop the
  isCloudflareProvider conditional that injected User-Agent and the
  isCloudflareWorkersAI override of sendSessionAffinityHeaders.
  packages/ai/src/models.generated.ts: re-spliced 8 cloudflare-workers-ai
  entries with headers + compat.

Behavior is unchanged - verified via fetch interceptor that User-Agent
and x-session-affinity / session_id / x-client-request-id are still sent
on outbound requests. 5/5 e2e tests pass.
LutfiGarzon pushed a commit to LutfiGarzon/pi-mono that referenced this pull request Apr 30, 2026
* feat(ai): add Cloudflare Workers AI as a provider

Cloudflare Workers AI hosts open-weight LLMs (Kimi K2.6, GPT-OSS,
GLM-4.7, Llama 4, Gemma 4, Nemotron 3) on Cloudflare's GPU network with
an OpenAI-compatible endpoint. Reuses the openai-completions API
protocol; the per-account URL contains a {CLOUDFLARE_ACCOUNT_ID}
placeholder resolved at request time by a small helper.

Pi automatically sets x-session-affinity for prefix caching:
https://developers.cloudflare.com/workers-ai/features/prompt-caching/

Auth: CLOUDFLARE_API_KEY (matches pi's *_API_KEY convention) +
CLOUDFLARE_ACCOUNT_ID. The User-Agent identifies traffic as
'pi-coding-agent' in Cloudflare analytics.

Verified end-to-end against a real Cloudflare account: 17 e2e tests
pass across stream/empty/tokens/unicode/tool-call-without-result/
total-tokens against @cf/moonshotai/kimi-k2.6.

Cloudflare AI Gateway is a separate, larger change (it requires routing
through provider-specific subpaths with the matching API protocol per
upstream) and will land in a follow-up PR.

* refactor(ai): move Cloudflare User-Agent and session-affinity flag to per-model metadata

Instead of conditionally setting them in openai-completions.ts based on
provider detection, declare them as model-level fields in the catalog
(headers + compat). This is consistent with how the github-copilot and
kimi-coding entries already declare their static headers.

  packages/ai/scripts/generate-models.ts: emit headers and compat fields
  on each cloudflare-workers-ai entry (CLOUDFLARE_STATIC_HEADERS).
  packages/ai/src/providers/openai-completions.ts: drop the
  isCloudflareProvider conditional that injected User-Agent and the
  isCloudflareWorkersAI override of sendSessionAffinityHeaders.
  packages/ai/src/models.generated.ts: re-spliced 8 cloudflare-workers-ai
  entries with headers + compat.

Behavior is unchanged - verified via fetch interceptor that User-Agent
and x-session-affinity / session_id / x-client-request-id are still sent
on outbound requests. 5/5 e2e tests pass.
badlogic added a commit that referenced this pull request Apr 30, 2026
* feat(ai): add Cloudflare AI Gateway as a provider

Routes through Cloudflare's Unified API (`/compat`) for Workers AI and
Anthropic models, and through the provider-specific `/openai` subpath
for OpenAI models so reasoning models (gpt-5.x, o-series) can hit
`/v1/responses` natively. Once `/compat` adds Responses-API support,
the OpenAI subpath can be folded back in.

Catalog layout:
  workers-ai/@cf/...  -> openai-completions, gateway/.../compat
  anthropic/...       -> openai-completions, gateway/.../compat
  <native-id>         -> openai-responses,   gateway/.../openai
                         (gpt-5.1, claude-... no, sorry: gpt-5.x and o-series only;
                          prefix stripped because the OpenAI SDK posts native ids)

Touches:
  packages/ai/src/types.ts                       add cloudflare-ai-gateway to KnownProvider
  packages/ai/src/env-api-keys.ts                map to CLOUDFLARE_API_KEY
  packages/ai/src/providers/cloudflare.ts        add CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL
                                                 and CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL
  packages/ai/src/providers/openai-responses.ts  one-line dispatch through resolveCloudflareBaseUrl
                                                 (matches what openai-completions.ts already does)
  packages/ai/scripts/generate-models.ts         branch openai/* vs workers-ai/anthropic/*
  packages/ai/src/models.generated.ts            spliced 34 entries
  packages/ai/test/stream.test.ts                3 e2e blocks (one per upstream)
  packages/coding-agent/*                        defaultModelPerProvider, login, env docs,
                                                 README, providers.md

Verified end-to-end against a real Cloudflare account with unified
billing: 9/9 e2e tests pass across all three upstreams (Workers AI
Kimi K2.6, OpenAI gpt-5.1 reasoning, Anthropic claude-sonnet-4-5).

* refactor(ai): move AI Gateway User-Agent and per-route session-affinity flag to catalog

Mirrors the same per-model metadata refactor done for Workers AI in the
parent branch. All cloudflare-ai-gateway entries get the User-Agent
header. Only workers-ai/* gateway entries set
`compat.sendSessionAffinityHeaders: true` because the gateway
forwards that header to the underlying Workers AI runtime; anthropic/*
upstream and openai/* (openai-responses) don't use it.

  packages/ai/scripts/generate-models.ts: emit headers (always) and
  per-upstream compat (workers-ai only) on each cloudflare-ai-gateway
  entry.
  packages/ai/src/models.generated.ts: re-spliced 35 entries with
  headers + conditional compat.

Behavior unchanged - 9/9 e2e tests pass across all three upstream
families.

* fix(ai): align AI Gateway with telemetry-aware UA helper

Adapts to #3851's follow-up fix ("honor telemetry for
Cloudflare attribution headers", fbb5eed) which moved the
'User-Agent: pi-coding-agent' header out of per-model catalog metadata
and into a centralized telemetry-honoring helper
(coding-agent/src/core/sdk.ts:getAttributionHeaders).

- packages/coding-agent/src/core/sdk.ts: extend the cloudflare branch of
  getAttributionHeaders to also match cloudflare-ai-gateway and
  gateway.ai.cloudflare.com.

- packages/ai/scripts/generate-models.ts and src/models.generated.ts:
  drop 'headers' from the 35 cloudflare-ai-gateway entries (constant
  CLOUDFLARE_STATIC_HEADERS no longer exists). Per-route
  compat.sendSessionAffinityHeaders is unchanged.

End-to-end behavior unchanged: 9/9 tests still pass across all three
upstream families (Workers AI, Anthropic, OpenAI Responses).

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
ssyram pushed a commit to ssyram/pi-mono that referenced this pull request May 4, 2026
* feat(ai): add Cloudflare AI Gateway as a provider

Routes through Cloudflare's Unified API (`/compat`) for Workers AI and
Anthropic models, and through the provider-specific `/openai` subpath
for OpenAI models so reasoning models (gpt-5.x, o-series) can hit
`/v1/responses` natively. Once `/compat` adds Responses-API support,
the OpenAI subpath can be folded back in.

Catalog layout:
  workers-ai/@cf/...  -> openai-completions, gateway/.../compat
  anthropic/...       -> openai-completions, gateway/.../compat
  <native-id>         -> openai-responses,   gateway/.../openai
                         (gpt-5.1, claude-... no, sorry: gpt-5.x and o-series only;
                          prefix stripped because the OpenAI SDK posts native ids)

Touches:
  packages/ai/src/types.ts                       add cloudflare-ai-gateway to KnownProvider
  packages/ai/src/env-api-keys.ts                map to CLOUDFLARE_API_KEY
  packages/ai/src/providers/cloudflare.ts        add CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL
                                                 and CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL
  packages/ai/src/providers/openai-responses.ts  one-line dispatch through resolveCloudflareBaseUrl
                                                 (matches what openai-completions.ts already does)
  packages/ai/scripts/generate-models.ts         branch openai/* vs workers-ai/anthropic/*
  packages/ai/src/models.generated.ts            spliced 34 entries
  packages/ai/test/stream.test.ts                3 e2e blocks (one per upstream)
  packages/coding-agent/*                        defaultModelPerProvider, login, env docs,
                                                 README, providers.md

Verified end-to-end against a real Cloudflare account with unified
billing: 9/9 e2e tests pass across all three upstreams (Workers AI
Kimi K2.6, OpenAI gpt-5.1 reasoning, Anthropic claude-sonnet-4-5).

* refactor(ai): move AI Gateway User-Agent and per-route session-affinity flag to catalog

Mirrors the same per-model metadata refactor done for Workers AI in the
parent branch. All cloudflare-ai-gateway entries get the User-Agent
header. Only workers-ai/* gateway entries set
`compat.sendSessionAffinityHeaders: true` because the gateway
forwards that header to the underlying Workers AI runtime; anthropic/*
upstream and openai/* (openai-responses) don't use it.

  packages/ai/scripts/generate-models.ts: emit headers (always) and
  per-upstream compat (workers-ai only) on each cloudflare-ai-gateway
  entry.
  packages/ai/src/models.generated.ts: re-spliced 35 entries with
  headers + conditional compat.

Behavior unchanged - 9/9 e2e tests pass across all three upstream
families.

* fix(ai): align AI Gateway with telemetry-aware UA helper

Adapts to earendil-works#3851's follow-up fix ("honor telemetry for
Cloudflare attribution headers", fbb5eed) which moved the
'User-Agent: pi-coding-agent' header out of per-model catalog metadata
and into a centralized telemetry-honoring helper
(coding-agent/src/core/sdk.ts:getAttributionHeaders).

- packages/coding-agent/src/core/sdk.ts: extend the cloudflare branch of
  getAttributionHeaders to also match cloudflare-ai-gateway and
  gateway.ai.cloudflare.com.

- packages/ai/scripts/generate-models.ts and src/models.generated.ts:
  drop 'headers' from the 35 cloudflare-ai-gateway entries (constant
  CLOUDFLARE_STATIC_HEADERS no longer exists). Per-route
  compat.sendSessionAffinityHeaders is unchanged.

End-to-end behavior unchanged: 9/9 tests still pass across all three
upstream families (Workers AI, Anthropic, OpenAI Responses).

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
ssyram added a commit to ssyram/pi-mono that referenced this pull request May 4, 2026
commit 324aa1d
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Mon May 4 00:52:56 2026 +0200

    fix(coding-agent): render compact read calls directly

    Render compact read classifications in the call row and leave the collapsed result row empty. The previous implementation used shared renderer state to let renderResult hide renderCall, which leaked an internal ReadRenderState type through the tool definition and coupled two render phases unnecessarily. The call renderer has all context needed to choose the compact presentation itself.

commit 2342001
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Mon May 4 00:45:56 2026 +0200

    fix(coding-agent): decouple codex session cleanup

commit 5fa277b
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Sun May 3 23:25:56 2026 +0200

    fix(coding-agent): close codex websocket sessions

    Fixes earendil-works#4103

commit 370fdae
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Sun May 3 22:51:42 2026 +0200

    fix(ai): fall back from codex websocket to sse (earendil-works#4133)

commit a646639
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sun May 3 22:14:52 2026 +0200

    chore: label bigrefactor issue closures

commit 21026cb
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sun May 3 22:04:05 2026 +0200

    chore: update temporary issue gate message

commit 693888a
Author: Jake Jia <87770044+Phoen1xCode@users.noreply.github.com>
Date:   Sun May 3 18:57:11 2026 +0800

    feat(ai): switch xiaomi default to api billing, add per-region token plan providers (earendil-works#4112)

    Built-in `xiaomi` provider now targets the API billing endpoint (https://api.xiaomimimo.com/anthropic) — a single stable URL for keys issued at platform.xiaomimimo.com. The Token Plan endpoints are exposed as three sibling providers, each with its own env var:

    - xiaomi-token-plan-cn: XIAOMI_TOKEN_PLAN_CN_API_KEY
    - xiaomi-token-plan-ams: XIAOMI_TOKEN_PLAN_AMS_API_KEY
    - xiaomi-token-plan-sgp: XIAOMI_TOKEN_PLAN_SGP_API_KEY

    BREAKING CHANGE: users who previously set XIAOMI_API_KEY against the Token Plan AMS endpoint must move to xiaomi-token-plan-ams and set XIAOMI_TOKEN_PLAN_AMS_API_KEY. This also resolves the 401 reported by on earendil-works#4005, where a platform.xiaomimimo.com key fails against the Token Plan endpoint.

    closes earendil-works#4082

commit 7c5ef0b
Author: myu003 <yzhg1983@163.com>
Date:   Sun May 3 18:55:23 2026 +0800

    test(ai,coding-agent): stabilize env-sensitive test cases (earendil-works#4119)

commit c8edb25
Author: Jakub Synowiec <jsynowiec@users.noreply.github.com>
Date:   Sun May 3 00:41:55 2026 +0200

    fix(ai): fix mismatch between models.dev and OpenCode Go (Qwen3.5/3.6, MiniMax M2.7) (earendil-works#4110)

commit b9efafc
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Sun May 3 00:04:27 2026 +0200

    fix(ci): repair failing test expectations

commit cd5bfd0
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Sat May 2 23:46:37 2026 +0200

    fix(ci): install sandbox runtime for root typecheck

commit 588639f
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Sat May 2 20:36:07 2026 +0200

    feat(read): compact resource read rendering

commit 7268e9a
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 14:58:41 2026 +0200

    Add [Unreleased] section for next cycle

commit 036bde0
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 14:57:51 2026 +0200

    Release v0.72.1

commit 97352ac
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 14:56:52 2026 +0200

    chore(ai): update generated models

commit b8bb241
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 14:14:22 2026 +0200

    fix(ai): honor codex transport option

    closes earendil-works#4083

commit e4163fe
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 01:55:50 2026 +0200

    Add [Unreleased] section for next cycle

commit 196226b
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 01:54:59 2026 +0200

    Release v0.72.0

commit 2d33616
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 01:54:04 2026 +0200

    docs: audit changelog entries for v0.71.1..HEAD

commit c0e0469
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 01:36:34 2026 +0200

    fix(ai): use Xiaomi Token Plan Anthropic endpoint

    closes earendil-works#3912

commit 80f06d3
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 01:20:01 2026 +0200

    feat: add model thinking level metadata

    closes earendil-works#3208

commit 73b7b2c
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Sat May 2 00:49:22 2026 +0200

    feat(agent): add post-turn stop callback

commit a446226
Author: Jake Jia <87770044+Phoen1xCode@users.noreply.github.com>
Date:   Sat May 2 06:46:05 2026 +0800

    feat(ai): add Xiaomi MiMo provider (earendil-works#4005)

    * fix(ai): include minimax-cn in cross-provider-handoff matrix

    * feat(ai): add Xiaomi MiMo provider

    Adds Xiaomi MiMo as an openai-completions-compatible provider.

    - packages/ai: register provider in types/KnownProvider, env-api-keys (XIAOMI_API_KEY), generate-models, models.generated.ts, overflow util, README, CHANGELOG
    - packages/ai/test: extend stream, tokens, abort, empty, context-overflow, overflow, image-tool-result, tool-call-without-result, total-tokens, unicode-surrogate, cross-provider-handoff matrices with Xiaomi
    - packages/coding-agent: default model (mimo-v2.5-pro), display name (Xiaomi MiMo), CLI env var docs, README, docs/providers.md

    closes earendil-works#3912

    ---------

    Co-authored-by: Mario Zechner <badlogicgames@gmail.com>

commit ddb8ed0
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 22:18:49 2026 +0200

    fix(coding-agent): honor registered model base urls

    closes earendil-works#4063

commit f5b6e4f
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 19:07:59 2026 +0200

    fix(ai): handle OpenRouter DeepSeek V4 reasoning

    Closes earendil-works#4055

    Closes earendil-works#4047

commit ad3f7d7
Author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Date:   Fri May 1 20:18:53 2026 +0000

    chore: approve contributor pandada8

commit c3282e4
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Fri May 1 18:52:54 2026 +0200

    refactor(coding-agent): inline npm command parsing

commit ade08de
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Thu Apr 30 19:10:06 2026 +0200

    fix(coding-agent): repair self-update detection

    Fixes earendil-works#3942
    Fixes earendil-works#3980
    Fixes earendil-works#3922

commit def47ec
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 13:12:41 2026 +0200

    Add [Unreleased] section for next cycle

commit 80a4390
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 13:11:52 2026 +0200

    Release v0.71.1

commit 4745a95
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 13:07:40 2026 +0200

    feat(ai): add cached codex websocket transport

commit 8040dd6
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 01:32:13 2026 +0200

    docs(coding-agent): update subscription provider notes

commit 3d44094
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 01:03:49 2026 +0200

    Add [Unreleased] section for next cycle

commit f4efeb2
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 01:03:02 2026 +0200

    Release v0.71.0

commit 8db0d28
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 01:01:54 2026 +0200

    chore(coding-agent): remove Qwen CLI extension example

commit 879e46a
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 00:58:33 2026 +0200

    docs(coding-agent): add Cloudflare gateway feature changelog

    Closes earendil-works#3856

commit a45577b
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Fri May 1 00:56:05 2026 +0200

    fix(ai): finalize cloudflare gateway provider support

commit 24fb6b8
Author: MC <mchen@cloudflare.com>
Date:   Thu Apr 30 22:29:37 2026 +0100

    feat(ai): add Cloudflare AI Gateway as a provider (earendil-works#3856)

    * feat(ai): add Cloudflare AI Gateway as a provider

    Routes through Cloudflare's Unified API (`/compat`) for Workers AI and
    Anthropic models, and through the provider-specific `/openai` subpath
    for OpenAI models so reasoning models (gpt-5.x, o-series) can hit
    `/v1/responses` natively. Once `/compat` adds Responses-API support,
    the OpenAI subpath can be folded back in.

    Catalog layout:
      workers-ai/@cf/...  -> openai-completions, gateway/.../compat
      anthropic/...       -> openai-completions, gateway/.../compat
      <native-id>         -> openai-responses,   gateway/.../openai
                             (gpt-5.1, claude-... no, sorry: gpt-5.x and o-series only;
                              prefix stripped because the OpenAI SDK posts native ids)

    Touches:
      packages/ai/src/types.ts                       add cloudflare-ai-gateway to KnownProvider
      packages/ai/src/env-api-keys.ts                map to CLOUDFLARE_API_KEY
      packages/ai/src/providers/cloudflare.ts        add CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL
                                                     and CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL
      packages/ai/src/providers/openai-responses.ts  one-line dispatch through resolveCloudflareBaseUrl
                                                     (matches what openai-completions.ts already does)
      packages/ai/scripts/generate-models.ts         branch openai/* vs workers-ai/anthropic/*
      packages/ai/src/models.generated.ts            spliced 34 entries
      packages/ai/test/stream.test.ts                3 e2e blocks (one per upstream)
      packages/coding-agent/*                        defaultModelPerProvider, login, env docs,
                                                     README, providers.md

    Verified end-to-end against a real Cloudflare account with unified
    billing: 9/9 e2e tests pass across all three upstreams (Workers AI
    Kimi K2.6, OpenAI gpt-5.1 reasoning, Anthropic claude-sonnet-4-5).

    * refactor(ai): move AI Gateway User-Agent and per-route session-affinity flag to catalog

    Mirrors the same per-model metadata refactor done for Workers AI in the
    parent branch. All cloudflare-ai-gateway entries get the User-Agent
    header. Only workers-ai/* gateway entries set
    `compat.sendSessionAffinityHeaders: true` because the gateway
    forwards that header to the underlying Workers AI runtime; anthropic/*
    upstream and openai/* (openai-responses) don't use it.

      packages/ai/scripts/generate-models.ts: emit headers (always) and
      per-upstream compat (workers-ai only) on each cloudflare-ai-gateway
      entry.
      packages/ai/src/models.generated.ts: re-spliced 35 entries with
      headers + conditional compat.

    Behavior unchanged - 9/9 e2e tests pass across all three upstream
    families.

    * fix(ai): align AI Gateway with telemetry-aware UA helper

    Adapts to earendil-works#3851's follow-up fix ("honor telemetry for
    Cloudflare attribution headers", fbb5eed) which moved the
    'User-Agent: pi-coding-agent' header out of per-model catalog metadata
    and into a centralized telemetry-honoring helper
    (coding-agent/src/core/sdk.ts:getAttributionHeaders).

    - packages/coding-agent/src/core/sdk.ts: extend the cloudflare branch of
      getAttributionHeaders to also match cloudflare-ai-gateway and
      gateway.ai.cloudflare.com.

    - packages/ai/scripts/generate-models.ts and src/models.generated.ts:
      drop 'headers' from the 35 cloudflare-ai-gateway entries (constant
      CLOUDFLARE_STATIC_HEADERS no longer exists). Per-route
      compat.sendSessionAffinityHeaders is unchanged.

    End-to-end behavior unchanged: 9/9 tests still pass across all three
    upstream families (Workers AI, Anthropic, OpenAI Responses).

    ---------

    Co-authored-by: Mario Zechner <badlogicgames@gmail.com>

commit c9ddca1
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:29:12 2026 +0200

    docs: note removed Google provider support as breaking

commit bd429f7
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:17:32 2026 +0200

    test(coding-agent): update stale expectations

commit 23fce57
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:10:08 2026 +0200

    fix(ci): install sandbox extension dependency

commit 0b8452c
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:08:51 2026 +0200

    fix(coding-agent): fix WSL clipboard image paste

    closes earendil-works#2469

commit 0452735
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:02:40 2026 +0200

    docs: audit unreleased changelogs

commit 0ed0d43
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 23:00:56 2026 +0200

    remove mom and pods packages

    People should check out pi-chat (earendil-works/pi-chat on GitHub), or use an older commit for mom and fork.

commit 3ffc2b4
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 22:50:40 2026 +0200

    fix(coding-agent): avoid duplicate blocked edit output

    closes earendil-works#3830

commit 95ae590
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 22:49:31 2026 +0200

    fix(coding-agent): refresh thinking border from extensions

    closes earendil-works#3888

commit f7df474
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:59:21 2026 +0200

    fix google vertex unsigned tool call replay closes earendil-works#4032

commit 9600a0c
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:47:51 2026 +0200

    chore: add session usage stats script

commit 8191d59
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:37:53 2026 +0200

    feat(coding-agent): support session dir env

    closes earendil-works#4027

commit 8632e1b
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:32:53 2026 +0200

    fix(coding-agent): update agent package readme link

    closes earendil-works#4023

commit 3d43d2e
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:31:43 2026 +0200

    fix(coding-agent): stop tool argument injection

    closes earendil-works#4018

commit fe66edd
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:24:17 2026 +0200

    remove gemini cli and antigravity support

commit 40c6eab
Author: Mario Zechner <badlogicgames@gmail.com>
Date:   Thu Apr 30 21:19:09 2026 +0200

    feat(coding-agent): allow message_end replacements

    closes earendil-works#3982

commit 24dec9f
Author: pica <cumt.xiaochi@gmail.com>
Date:   Fri May 1 02:59:02 2026 +0800

    fix(coding-agent): remove detached: true on Windows to fix pwsh.exe stdio (earendil-works#4013)

    On Windows, spawn(..., { detached: true }) prevents pwsh.exe (PowerShell) from
    producing any stdout/stderr through pipe streams. This is because detached creates
    a new process group which breaks pwsh's console host communication.

    bash.exe and other cygwin/msys2 shells are unaffected by detached: true, but
    they don't need it either -- on Windows, killProcessTree() already uses
    taskkill /F /T /PID which kills the process tree by PID regardless of
    whether the process was spawned detached.

    The detached flag only matters on Unix, where kill(-pid, SIGKILL) requires a
    process group that is only created via detached: true.

    Fixes earendil-works#4012

commit 7dc1bed
Author: Armin Ronacher <armin.ronacher@active-4.com>
Date:   Thu Apr 30 16:12:03 2026 +0200

    feat(ai): add Moonshot AI provider model support
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.

Add Workers AI and AI Gateway to Pi

2 participants