* 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.
* feat(coding-agent): add fold/unfold to tree branch navigation
Remap left/right arrow keys in the session tree to jump between branch
segment starts (first child of each branching point). Left on a foldable
node (root or segment start) folds it, hiding its descendants. Right on
a folded node unfolds it. Nested fold state is preserved. Search and
filter changes reset all folds.
Folded branches show ⊞ in the connector (├⊞/└⊞) or as a prefix for
roots. Active path marker • appears after the fold indicator.
Add Page Up/Down support for paging through the tree list, consistent
with session selector and config selector.
* feat(coding-agent): improve tree branch folding closes#1724
---------
Co-authored-by: Sviatoslav Abakumov <dust.harvesting@gmail.com>
When Kitty keyboard protocol is not available (e.g. inside tmux), fall
back to xterm modifyOtherKeys mode 2 so that Shift+Enter, Ctrl+Enter,
and other modified keys are distinguishable from plain Enter.
tmux users need to add to ~/.tmux.conf:
set -g extended-keys on
set -g extended-keys-format csi-u
closes#1872