Commit graph

2042 commits

Author SHA1 Message Date
Armin Ronacher
d547949184 Add [Unreleased] section for next cycle 2026-10-13 00:47:08 +02:00
Armin Ronacher
06a4669355 Release v1.2.0 2026-10-13 00:46:55 +02:00
Armin Ronacher
0d79b74db1 docs: audit changelogs and add new features for next release 2026-10-13 00:36:49 +02:00
David Brailovsky
7bd01fb924 fix(ai): retry "The upstream provider returned an error"
closes #10842
2026-10-12 18:24:53 +02:00
Armin Ronacher
d4d53612be fix(ai): fall back on Anthropic strict tool limits
Retry known strict tool capacity rejections once with preferred tools using their original non-strict schemas. Preserve required constraints and payload hooks, and never retry a started stream.

closes #10409
2026-10-12 17:20:36 +02:00
David Brailovsky
ee409a85f6
feat(ai,coding-agent): list only the OpenRouter models a key may use (#10672)
On each OpenRouter refresh, combine the catalog (built-in models plus a newer pi.dev catalog) with GET /models/user for the user's key: keep only the listed chat models and take their context size, max output and prices from it. Image and classifier models are kept. The combined list is saved and replaces the OpenRouter catalog, including offline.

- ai: add personalizeOpenRouterCatalog and RefreshModelsContext.baseUrl, so the request follows a base URL configured in models.json (regional endpoints)
- ai: share OpenRouter price conversion with the generator; negative prices (router models such as openrouter/auto) become 0
- coding-agent: add withPersonalizedCatalog next to withRemoteCatalog
- docs: OpenRouter section in providers.md

fixes #10353
2026-10-12 10:17:40 +02:00
Mario Zechner
0f4b1465a4 fix(ai): send the codex request body as a Uint8Array<ArrayBuffer> copy
fetch accepts it as a body under the DOM lib too. From pi-private e97c4a60e.
2026-10-11 16:35:13 +00:00
Mario Zechner
2a33bbee89 test(ai): e2e repro for radius dropping replayed Claude thinking
Radius omits providerThinkingLevel from pi-messages done events, so replayed
signed thinking has no effort marker and Anthropic drops it (block_binding
drop_block). Compares follow-up input tokens with and without the thinking
block against an Anthropic control.
2026-10-11 16:35:08 +00:00
David Brailovsky
ce950d78f4 fix(ai): use models.dev metadata for Claude 5.5 models
Remove hardcoded Opus 5.5, Sonnet 5.5, and Haiku 5.5 fallbacks now that models.dev lists them. Fix the Sonnet 5.5 test to expect the official cache read price of 0.1.
2026-10-08 11:20:26 +02:00
David Brailovsky
6b07b4e572 fix(ai): apply Mistral request timeout only to response headers
Long Mistral streams (e.g. extended thinking) were aborted once timeoutMs
elapsed, even while data was still arriving. The timeout now covers only
waiting for response headers; body stalls are left to the HTTP client idle
timeout.

fixes #10609
2026-10-08 10:24:04 +02:00
Christian Klotz
7f9e1198f2
feat(coding-agent): publish configuration schemas (#9880)
* feat(coding-agent): publish configuration schemas

* fix(coding-agent): preserve config schema metadata

* fix(coding-agent): align schemas with public contracts

* fix(ai): place compatibility schema with providers

* fix(ai,coding-agent): align configuration schema contracts

* fix(ai): reuse session affinity schema

* docs(coding-agent): document strict theme validation

* fix(ai,coding-agent): align runtime and generated schemas

* fix(ai,coding-agent): centralize configuration schema contracts

* fix(ai,coding-agent): preserve schema validation contracts

* fix(coding-agent): validate keybinding schema grammar

* fix(ai,coding-agent): refine configuration schemas

* fix(ai,tui,coding-agent): align schemas with runtime behavior

* fix(tui): normalize shifted symbol keybindings

* fix(ai): preserve compatibility auto-detection
2026-10-08 10:01:17 +02:00
Armin Ronacher
75a99721d1 Add [Unreleased] section for next cycle 2026-10-07 23:33:49 +02:00
Armin Ronacher
abe508e1b8 Release v1.1.0 2026-10-07 23:33:33 +02:00
Armin Ronacher
a2eef9eb60 fix(ai): pin Kimi K3 Moonshot pricing and expect Haiku 5.5 adaptive thinking
models.dev now lists the input rate as Kimi K3's cache write cost on Moonshot, which does not bill cache writes. Claude Haiku 5.5 uses adaptive thinking, so the metadata test now expects it.
2026-10-07 22:41:41 +02:00
Armin Ronacher
dce4ae6f79 docs: audit changelogs for v1.1.0 2026-10-07 22:20:04 +02:00
Armin Ronacher
943a10e744 fix(ai): keep prompt-length pricing tiers from all model catalogs
models.dev loaders for opencode, opencode-go, google, minimax, and others built costs by hand and dropped tiers; they now use getModelsDevCost. OpenRouter prompt-length overrides and Vercel AI Gateway per-rate tiers are parsed into request-wide tiers. Rates a tier does not list keep the base price. OpenRouter time-of-day overrides are skipped.
2026-10-07 21:54:18 +02:00
Armin Ronacher
f76c1db662 feat(ai): add Claude Haiku 5.5
Adds claude-haiku-5-5 to the anthropic provider with its prompt-length pricing tier (5x above 100k input tokens), adaptive thinking with xhigh/max effort, per-message effort, and mid-conversation system messages and tool changes. Bedrock requests detect Haiku 5.5 for adaptive thinking, native xhigh, block binding, and prompt caching.
2026-10-07 21:44:58 +02:00
Mario Zechner
7fb59f995b fix(ai): retry Mistral finish_reason error
Mistral reports transient server failures as finish_reason "error". Its
error message now includes "server error" so the retry classifier treats
it as retryable.

closes #10487
2026-10-07 09:06:19 +00:00
Mario Zechner
8d8ae2fc24 fix(ai): fall back to a free port for Anthropic OAuth callback
Try 53692 first so forwarded setups keep working, then let the OS pick a
free loopback port when 53692 cannot be bound (e.g. Hyper-V/WSL port
exclusions on Windows). The authorize URL, paste prompt and token exchange
use the bound redirect URI.

closes #10571
2026-10-07 07:47:22 +00:00
Armin Ronacher
6b58544540 fix(ai): type empty OpenAI classifier catalogs 2026-10-07 08:35:06 +02:00
Armin Ronacher
ce8972a0e9 feat(ai,coding-agent): add OpenAI Decisions classifier and classifier images
Adds the openai-decisions classifier API with gpt-6-luna on the openai provider. bool questions map to predicates with the criteria in the instructions, refusals fail the result, and gateway timeouts (504) are not retried. The model needs an API key and is hidden from availability while openai uses Sign in with ChatGPT.

Adds optional images to ClassifierContext. Models without image input and APIs that cannot send images return an error result. Codemode's models.classify() accepts images.

Moves the shared classifier HTTP code out of system-one-shared.ts into classifier-shared.ts.
2026-10-07 08:27:56 +02:00
Mario Zechner
fe11328b0d fix(ai): compare faux prompt-cache usage per message
The faux provider's prompt-cache usage estimate compared the previous and
current prompt as two joined strings, character by character, on every
call. It now compares the prompts message by message and compares
characters only from the first differing message. Usage numbers are
unchanged.
2026-10-06 20:58:35 +02:00
Mario Zechner
f284a2460c fix(ai): time responses with private fields; use the real stream in proxy and test mocks
Replaces the WeakMap workaround. streamProxy and the agent and coding-agent test
mocks reimplemented AssistantMessageEventStream as plain EventStream subclasses;
they now use createAssistantMessageEventStream().
2026-10-06 20:26:27 +02:00
Mario Zechner
3ba22ce17a fix(ai): keep AssistantMessageEventStream assignable from plain event streams
The response timing added private fields, which made test and host streams built on
EventStream no longer assignable to StreamFn. Keep the start in a WeakMap instead.
2026-10-06 20:08:35 +02:00
Armin Ronacher
43d3763991 fix(ai): replace bundled Radius catalog with gateway catalog
Models disabled by an organization owner were still listed because the
fetched catalog was merged into the shipped default catalog.
2026-10-06 19:46:54 +02:00
Mario Zechner
36a686ee8d feat: record response, tool execution, and durable task times
pi-ai's AssistantMessageEventStream sets AssistantMessage.durationMs with a
monotonic clock for every API implementation. The agent loop and the durable
tool task set ToolResultMessage.durationMs around execute(). Durable task
records carry startedAt/endedAt stamped by the Session. The coding agent's bash
renderer shows Took from the recorded duration, also after a reload.

closes #10549
2026-10-06 19:28:54 +02:00
Justin Santer
2989eb581f
fix(ai): send reasoning effort to OpenAI models on Bedrock Converse (#10142)
buildAdditionalModelRequestFields only handled Claude, so the configured
thinking level never reached OpenAI models on Bedrock and they always ran at
Bedrock's default effort. gpt-oss now gets the flat reasoning_effort, clamped
to low/medium/high. Other GPT models (GPT-5.x, GPT-6) get nested
reasoning.effort, with minimal sent as low since Bedrock rejects it.

closes #9331
2026-10-06 18:06:46 +02:00
David Brailovsky
311f0e020d fix(ai): update output limit assertions for token estimate 2026-10-06 15:58:16 +00:00
David Brailovsky
27075fe075 fix(ai): estimate request context at 3.5 characters per token
Increase estimated input size to leave more room when calculating
output limits. Verified against OpenRouter DeepSeek V4 Flash: the
same large input now succeeds with an explicit output limit.

Fixes #10497
2026-10-06 17:37:24 +02:00
David Brailovsky
8b5708dbb1 fix(ai): retry transient server-busy provider errors
Recognize server_busy and servers are currently busy as retryable errors.

Fixes #10543
2026-10-06 15:59:24 +02:00
Lucas Meijer
0cf65d2bf7
fix(ai): let caller headers override Codex originator and User-Agent (#10429)
StreamOptions.headers documents that caller values override provider
defaults, and every other provider applies model/caller headers after its
User-Agent default. The Codex provider set originator and User-Agent after
merging caller headers, so they could not be overridden. Set the defaults
first; Authorization and chatgpt-account-id stay fixed.

Co-authored-by: Lucas Meijer <308974+lucasmeijer@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: David Brailovsky <davidbrai@gmail.com>
2026-10-06 10:01:19 +02:00
Lucas Meijer
9ad083102a
feat(ai): let apps name themselves in OpenAI logins (#10433)
LoginOptions.agentName replaces pi's name in the Sign in with ChatGPT
agent_name_hint and the Codex browser login originator.
2026-10-06 09:27:40 +02:00
Armin Ronacher
f6127a1bf9
feat(coding-agent): use llama.cpp classifier models natively (#10382)
This adds llama.cpp support for classifiers. Classifier models (Julia-1, Laya, Kev, lev, OpenJev) are listed as typesafe-system-one classifiers instead of chat models; other models keep the llama-cpp-classify fallback. Only 501 and 404 mark a model as chat, and classifier models restored from the model store are checked again once loaded.
2026-10-06 09:23:07 +02:00
Armin Ronacher
28dcce2ba4 Add [Unreleased] section for next cycle 2026-10-05 21:23:02 +02:00
Armin Ronacher
7c10bd4337 Release v1.0.4 2026-10-05 21:22:49 +02:00
David Brailovsky
5b6c792b42 fix(ai): retry HTTP/2 pending stream cancellation
Bedrock's HTTP/2 connection can stall until the SDK's 5-minute session
timeout, which fails the request with "The pending stream has been
canceled" (ERR_HTTP2_STREAM_CANCEL). The request was never sent, so it
is safe to retry, but the message was only retried when a DNS cause was
appended.

closes #10379
2026-10-05 13:49:46 +02:00
Armin Ronacher
997d31f286 Add [Unreleased] section for next cycle 2026-10-05 10:21:24 +02:00
Armin Ronacher
d78dc83d63 Release v1.0.3 2026-10-05 10:21:10 +02:00
Justin Santer
a37306d437
feat(ai): support Azure Foundry Chat Completions deployments (#9714)
* feat(ai): support Azure Foundry Chat Completions deployments

The Azure provider only implemented the Responses API, so Foundry
deployments that speak Chat Completions could not be used. On Chat
Completions the deepseek/deepseek-v4-pro model sends `thinking` and
`prompt_cache_key`, both of which Azure rejects with 400.

The provider now dispatches openai-completions alongside
azure-openai-responses. A stream wrapper resolves the Azure endpoint
onto the model first, since the shared openai-completions
implementation reads it off the model.

The request-shape differences are catalog compat rather than api code:
reasoning_effort instead of DeepSeek's thinking field, no prompt cache
parameters, reasoning_content kept on assistant turns so the prefix
Foundry cached stays byte-identical, and effort clamped to the
low/medium/high the deployment accepts.

The provider is renamed from azure-openai-responses to azure, since it
now serves more than the Responses API. The azure-openai-responses api
id is unchanged. Breaking: auth.json and models.json entries keyed on
azure-openai-responses must move to azure, and existing sessions see a
different provider on their next turn.

closes #9645

* feat(ai): apply the Azure deployment name map to Chat Completions

The Responses path already sent the deployment name from
AZURE_OPENAI_DEPLOYMENT_NAME_MAP. The Chat Completions path sent the
catalog model id, so any deployment not named after the model 404'd.

The Azure provider now swaps the deployment name into the request via
onPayload before dispatch, then runs the caller's own onPayload on it.
model.id stays the catalog id. The map helpers move to
azure-openai-config.ts so the provider can share them without
importing the SDK.

* docs(ai,coding-agent): add changelog entries for the Azure provider rename

Breaking: the azure-openai-responses provider is now azure. Users rename
the key in auth.json, models.json, and settings.json; SDK users switch to
getModel("azure", ...) and providers/azure.

Also note Azure Foundry Chat Completions support (DeepSeek V4 Pro).

---------

Co-authored-by: David Brailovsky <davidbrai@gmail.com>
2026-10-05 09:46:48 +02:00
Armin Ronacher
bde882c747 fix(ai,coding-agent): persist rotated OAuth tokens when a refresh is cancelled
Cancelling a request or model refresh while an OAuth token refresh was in
flight discarded the rotated credential. Providers that rotate refresh tokens
(e.g. Sign in with ChatGPT) had already invalidated the old token, so the next
request failed with refresh_token_invalidated.

The caller's signal now cancels only the wait for the credential lock. Once a
refresh starts, it completes and is persisted, bounded by the refresh timeout.
Request auth and model-list refresh share this path.
2026-10-04 21:48:12 +02:00
Armin Ronacher
200387122c Add [Unreleased] section for next cycle 2026-10-04 02:41:25 +02:00
Armin Ronacher
cd32f7725f Release v1.0.2 2026-10-04 02:41:16 +02:00
Armin Ronacher
750105c80e docs(ai,coding-agent): move #9776 changelog entries to Unreleased 2026-10-04 02:36:48 +02:00
Duncan Ogilvie
76dfb88f63
feat(ai): add per-thinking-level sampling parameters (#9776) 2026-10-04 01:29:01 +02:00
Armin Ronacher
4c6fb7cfe8 Add [Unreleased] section for next cycle 2026-10-03 14:21:11 +02:00
Armin Ronacher
a7229ddc21 Release v1.0.1 2026-10-03 14:20:57 +02:00
Armin Ronacher
49b9df4895 fix(coding-agent): default NVIDIA to Nemotron 3 Ultra
NVIDIA no longer serves nvidia/nemotron-3-super-120b-a12b, so the default model and the NVIDIA e2e test now use nvidia/nemotron-3-ultra-550b-a55b.
2026-10-03 14:14:51 +02:00
Armin Ronacher
4215d4d6be docs(ai,coding-agent): audit changelog entries since v1.0.0
Add missing entries for the Together DeepSeek V4 Pro fix and the Nix flake, duplicate user-facing ai and tui changes into coding-agent, and add the New Features section.
2026-10-03 14:10:22 +02:00
Armin Ronacher
69f0be6f0a fix(ai): drop stale thinking blocks on Bedrock Claude replays
Send thinking.block_binding with prefix_mismatch_behavior=drop_block and
the thinking-binding-controls-2026-08-01 beta for Bedrock Claude Opus 4.7+,
Sonnet 5+, and Fable 5, matching the Anthropic provider. Opus 4.6 and
Sonnet 4.6 reject the field, and GovCloud is skipped.

closes #10324
2026-10-02 22:38:43 +02:00
Armin Ronacher
c71a496ff9
feat(coding-agent): add Nix flake (#9137)
Add a Nix flake that builds Pi from the checkout on aarch64/x86_64 Linux
and macOS. The build is offline: provider model data is hydrated from a
pi.dev model catalog revision pinned in nix/model-catalog.json, and the
runtime dependency tree comes from packages/coding-agent/install-lock with
internal packages built from source.

The Nix workflow keeps the catalog pin current on main, builds release
tags on all systems, and fast-forwards the stable branch to each release
that builds. The release script refreshes the pin before tagging.
2026-10-02 18:30:51 +02:00