Commit graph

6977 commits

Author SHA1 Message Date
Christian Klotz
8efd314fa3
docs(ai,coding-agent): generate models.json reference from schemas (#11038)
* docs(ai,coding-agent): generate models.json reference from schemas

Add npm run generate:references, which renders docs/models-configuration.md
from the models.json TypeBox schemas, and describe provider and model fields
in those schemas. Overrides get their own descriptions without defaults, and
compat sections cover the Responses API aliases.

closes #10790

* Modify changelog

* docs(ai,coding-agent): use shared thinkingLevelMap and promptCache schemas

Replace the per-use schema helpers with fixed schemas whose descriptions
hold for both models and modelOverrides entries.
2026-10-16 21:53:00 +01:00
Carlos Villela
95364a54ef
feat(coding-agent): default NVIDIA to Nemotron 3.5 Super VL (#10910)
* feat(coding-agent): default NVIDIA to Nemotron 3.5 Super VL

Co-authored-by: prademacher-nvidia <235594174+prademacher-nvidia@users.noreply.github.com>

* docs(coding-agent): changelog for NVIDIA default model change

* fix(ai): run NVIDIA E2E tests against Nemotron 3.5 Super VL

---------

Co-authored-by: prademacher-nvidia <235594174+prademacher-nvidia@users.noreply.github.com>
2026-10-16 22:26:37 +02:00
Mario Zechner
14ff455a0a fix(env): make the read/bash differential test deterministic and meaningful
The fake tool API lacked retainedOutput, so every bash case threw on both sides
and the test only compared the error text. Its stdout+stderr case also depended
on the order of two concurrently read pipes and failed intermittently in CI.
The API now provides retainedOutput, each bash case writes to one stream, and
bash cases must return a result.
2026-10-16 19:58:24 +00:00
Mario Zechner
2331785c33 fix(durable): run the Codex prompt-cache e2e test on gpt-6.1-sol
Codex no longer serves gpt-5.5 to ChatGPT accounts ("The 'gpt-5.5' model is not
supported when using Codex with a ChatGPT account"), so the test failed in its
first turn as unanswered.
2026-10-16 19:42:02 +00:00
Mario Zechner
7ec1f648e9 feat(durable): accept functions for HarnessOptions.models and settings
Like env, models and settings may be a function returning the current value.
Generation, compaction, hooks and tools read it at each use (api.models at each
access), so a host can replace its model configuration without reopening the
Harness. A plain object still works.
2026-10-16 19:30:35 +00:00
David Brailovsky
698a2d23b8 fix(ai): retry more gateway upstream failure errors
Adds upstream_error, upstream_stream_read_error, interrupted stream, and
HTTP/2 stream failure wording to the retryable error patterns.

closes #10920
2026-10-16 17:12:24 +02:00
David Brailovsky
4dd2b149d1 fix(ai): treat whitespace-only tool output as empty
Whitespace-only tool results (e.g. a bare \r\n from bash) were sent verbatim
to OpenAI Completions, OpenAI Responses, and Google providers. Some providers
reject that with a 400, which then repeats on every request in the session.
They now use the same placeholder as empty output.

closes #8720
2026-10-16 14:06:06 +02:00
David Brailovsky
6fcb48670f
fix(coding-agent): remove fixed output limits from summary requests (#11036)
Compaction summaries were limited to 0.8 * compaction.reserveTokens (13107 by default), turn-prefix summaries to 0.5 * reserveTokens, and branch summaries to a hardcoded 4096. On providers where reasoning shares the output limit (OpenAI Responses, adaptive Anthropic), high thinking levels used most of that limit and compaction failed with "generation hit the token cap", even though the model allows far more output.

Tying the limit to reserveTokens assumed the summary request is as large as the full context, so its output had to fit in the reserved space. It is usually much smaller: recent messages kept by keepRecentTokens are not sent, a split turn goes to a separate request, tool results are truncated, and tool definitions and the normal system prompt are not included. Manual compaction can also run long before the context is full. The provider layer already sizes output from the actual request, using the model's output limit reduced to fit the remaining context, as for normal turns.

Summary requests now set no maxTokens and rely on that. compaction.reserveTokens only controls when compaction starts.

generateSummary() and generateSummaryWithUsage() now ignore the reserveTokens parameter.

closes #9512, closes #9075, closes #10908
2026-10-16 13:53:16 +02:00
David Brailovsky
90d863f7c1 fix(coding-agent): use mimo-v2.6-pro as Xiaomi default model
The generated Xiaomi catalogs no longer include mimo-v2.5-pro.
2026-10-16 12:51:37 +02:00
David Brailovsky
99fe148970 fix(ai): use mimo-v2.6 models in Xiaomi tests
The model catalog replaced mimo-v2.5 and mimo-v2.5-pro with mimo-v2.6-flash
and mimo-v2.6-pro, so tests referencing the old IDs failed type-checking.
2026-10-16 12:00:23 +02:00
David Brailovsky
0fbdbd3f8a fix(ai): retry node-fetch 'request to ... failed' errors
Google Vertex ADC token refresh failures are reported by node-fetch as
'request to <url> failed, reason: ...' and were never auto-retried.

fixes #10996
2026-10-16 10:48:22 +02:00
Mario Zechner
790271cd02 fix(durable): restore ToolControl.terminate changes dropped by c4cf7957b
c4cf7957b was built from a tree that predates 6085986e4 and reverted its
terminate type change, regression test, and changelog entries.
2026-10-16 08:20:58 +00:00
Mario Zechner
c4cf7957b4 feat(durable): per-model compaction settings via compaction.modelOverrides
Overrides keyed by provider/modelId apply at the threshold check, overflow
recovery, and compaction range selection.

closes #10942
2026-10-16 08:20:12 +00:00
Mario Zechner
6085986e4b fix(durable): type ToolControl.terminate as boolean
The type change and changelog entry landed in 1de1b98e7; this adds the
regression test for terminate: false.

closes #10858
2026-10-16 08:19:56 +00:00
David Brailovsky
4954d76050
feat: check the model catalog against the latest release before publishing (#11007)
pi.dev serves each published catalog to released pi >= MINIMUM_PI_VERSION.
Compile the latest release's pi-ai against its built-in models overlaid by
the new catalog, so a catalog it cannot handle (e.g. kimi-coding moving to
openai-completions) fails in CI instead of breaking released clients.
MINIMUM_PI_VERSION moves to scripts/model-catalog-minimum-version.mjs.
2026-10-15 21:21:57 +02:00
Armin Ronacher
ae7b16d43b Add [Unreleased] section for next cycle 2026-10-15 20:57:35 +02:00
Armin Ronacher
71023aec15 Release v1.3.0 2026-10-15 20:57:27 +02:00
Armin Ronacher
9800c96ffc docs(coding-agent): add changelog entry for #10999 2026-10-15 20:55:08 +02:00
Armin Ronacher
2cb2cfa79f docs: audit changelogs for release 2026-10-15 20:55:00 +02:00
Colin Mason
a4f67eb65e
fix(coding-agent): close own custom ui overlay (#10999)
done() from ctx.ui.custom({ overlay: true }) closed the overlay with
ui.hideOverlay(), which removes the topmost overlay instead of the one
that called done(). With a shell overlay open under a dialog overlay
from another extension, the shell's exit removed the dialog: the
finished shell overlay stayed on screen ignoring input and the dialog's
promise never resolved. Hide the overlay through its own handle.

closes #10648
2026-10-15 20:50:03 +02:00
Armin Ronacher
d05a73fb31 fix: keep the Nix model catalog pin buildable
The pin script discovered the catalog with the checkout's version, which on
main is the last release, so pi.dev answered with the catalog for released
clients after MINIMUM_PI_VERSION was raised. It now pins the newest
published catalog and treats the pin as stale when its provider/type/API
model groups differ. The release script pins the newest catalog and runs
the Nix build steps before tagging.

closes #10985
2026-10-15 20:16:03 +02:00
David Brailovsky
9113094291
fix(ai): drop thinking from other models instead of sending it as text (#11000)
When switching models, thinking blocks from earlier assistant messages
produced by a different model were sent as plain text. The new model saw
the old model's reasoning as part of its replies and could start writing
its own reasoning into the visible answer. These blocks are now dropped;
text and tool calls are kept.

closes #10995
2026-10-15 19:38:33 +02:00
Armin Ronacher
5ab7fe74c4 fix(ai): keep images of error tool results for Anthropic and Bedrock Claude
Anthropic and Claude on Bedrock reject error tool results that contain
images. Instead of replacing the images with a note, each image in the
result is now replaced with a placeholder and the images are sent after
all tool results of the turn, in the same user message, under a caption
naming the tool call. Successful results, error results without images,
and non-Claude Bedrock models are unchanged.

closes #10794
2026-10-15 16:49:50 +02:00
Armin Ronacher
eddebaeebf fix(coding-agent): append Node to PATH in the Nix wrapper
Shells started by the bash tool now keep the user's node/npm. Pi still
runs on the pinned Node, which stays available as an npm fallback.

closes #10519
2026-10-15 15:49:34 +02:00
David Brailovsky
a3f265b1c6 feat(ai): use Chat Completions for the kimi-coding provider
Switch kimi-coding to OpenAI Chat Completions at api.kimi.com/coding/v1,
the protocol the official Kimi Code client uses. K3, K3-256K, and Kimi For
Coding accept tools declared in later system messages, so tools loaded
mid-conversation (e.g. by tool_search) keep the prompt cache. Highspeed
rejects tool-bearing system messages and keeps added tools top-level.

Re-lands b06c1f2 (reverted in 6a1f799b6) with MINIMUM_PI_VERSION bumped
to 1.2.1. Released clients implement only Anthropic Messages for
kimi-coding and ignore a model's api, so they must keep receiving the
last catalog published under 0.80.7.

closes #10720
2026-10-15 15:29:11 +02:00
David Brailovsky
dfb03c3283 fix(coding-agent): use claude-sonnet-4.5 in model registry tests
anthropic/claude-sonnet-4 is no longer in the OpenRouter catalog.
2026-10-15 15:27:42 +02:00
David Brailovsky
568c2a82a7 fix(ai): use claude-sonnet-4.5 in OpenRouter tests
anthropic/claude-sonnet-4 is no longer in the OpenRouter catalog.
2026-10-15 15:23:31 +02:00
Christian Klotz
f7e3cb5433
feat(durable): support namespaced SQLite storage (#10937)
* feat(durable): namespace SQLite storage tables

Render migrations and runtime queries from one schema map, add optional prefixes, and simplify the Cloudflare Durable Object adapter.

* feat(durable): expose SQLite prefixes through storage helpers

* docs: explain shared Durable Object storage

* Update changelog
2026-10-15 14:02:27 +01:00
David Brailovsky
6a1f799b67 fix(ai): revert kimi-coding switch to Chat Completions
Reverts b06c1f2. The pi.dev model catalog is served to every client
since 0.80.7, so released clients received kimi-coding models with
api openai-completions and baseUrl https://api.kimi.com/coding/v1.
Their kimi-coding provider only implements Anthropic Messages and
ignores model.api, so requests went to /coding/v1/v1/messages and
failed with 404. The change will re-land together with a bump of the
catalog's minimum pi version.

refs #10720, refs #10985
2026-10-15 13:19:40 +02:00
Mario Zechner
4a5d372915 feat(chord,durable): move OutputBuffer and Progress to @earendil-works/chord/output
OutputBuffer, Progress, boundOutput, sanitizeOutput, characterEnd and the
output types move from Durable's internal harness/output.ts to the new
Chord subpath, with OutputSkip (the shape of Durable's ShellOutputSkip) and
utf8ByteLength. Durable imports them from Chord; its truncate.ts re-exports
Chord's utf8ByteLength instead of keeping a second copy.
2026-10-15 09:59:46 +00:00
David Brailovsky
dc939913f6 fix(ai): support off thinking level on Claude Haiku 5.5 and Opus 5
Both models accept thinking: {type: "disabled"}, but were treated like
Opus 5.5, which cannot turn thinking off. "off" now sends disabled
thinking without effort markers or block_binding, which Anthropic
rejects while thinking is disabled.

fixes #10753
2026-10-15 11:24:04 +02:00
David Brailovsky
550f1f3ecd fix(ai): retry "The service is temporarily unavailable" errors
closes #10965
2026-10-15 10:12:50 +02:00
Mario Zechner
9a3ca68bda fix(chord): remote references refuse a foreign ctx
A call through a remote reference checked the ctx against its own host,
so a ctx from another host, or an object not made by Chord, passed and
its root was carried over the link. It now runs the same checks as a
local reference and rejects with invalid/foreign_ctx.

closes #10959
2026-10-15 06:25:18 +00:00
David Brailovsky
b06c1f2cf1 feat(ai): use Chat Completions for the kimi-coding provider
Switch kimi-coding to OpenAI Chat Completions at api.kimi.com/coding/v1,
the protocol the official Kimi Code client uses. K3, K3-256K, and Kimi For
Coding accept tools declared in later system messages, so tools loaded
mid-conversation (e.g. by tool_search) keep the prompt cache. Highspeed
rejects tool-bearing system messages and keeps added tools top-level.

closes #10720
2026-10-14 22:23:59 +02:00
David Brailovsky
87f9a36419
fix(ai): report malformed final tool-call arguments instead of keeping the parsed prefix (#10944)
When a finished tool call's arguments text was not valid JSON, the
streaming parser kept only the fields before the error and the tool ran
with them. Finished calls are now parsed strictly (with the existing
string repair); on failure arguments are {} and argumentsError holds the
reason and raw text, which validateToolArguments reports to the model.

fixes #10897
2026-10-14 21:41:42 +02:00
Mario Zechner
b45e0ebcc5 feat(chord): references hydrate their state before use (protocol 4)
- an awaited get or a ready hold has every state member of its variant, local or remote
- holds subscribe to their variant's state; per-member opt-out with state: false
- remote binding keys use canonical identity; client holds carry an opaque origin
- shape frames no longer carry codeVersion
2026-10-14 14:29:58 +00:00
David Brailovsky
9fe3f37162 fix(coding-agent): keep empty quoted prompt template arguments
Empty quoted arguments ("" or '') were dropped, shifting later positional
arguments and preventing positional defaults from applying.

closes #10867
2026-10-14 15:35:39 +02:00
Ramiz Wachtler
910149912c
fix(coding-agent): normalize read line-range labels (#10938)
- share range formatting across the TUI, exports, and examples
- add regression coverage without changing execution arguments
- fixes #9887
2026-10-14 15:20:04 +02:00
David Brailovsky
5712b134ed fix(ai): use 500K context window for Codex GPT-6.1 Sol
The Codex models endpoint now returns context_window=500000 for
gpt-6.1-sol; other Codex models still return 272000.

fixes #10840
2026-10-14 15:19:01 +02:00
David Brailovsky
381a2d8eb6 fix(ai): update Xiaomi replay test for removed reasoning_effort
Xiaomi MiMo models no longer send reasoning_effort since 6374c2baf (#10818).
2026-10-14 14:58:07 +02:00
David Brailovsky
b39979799f feat(ai): remove unused assistant-message frame API
AssistantMessageFrameEncoder and reduceAssistantMessageFrames were only used by the removed experimental agent harness.
2026-10-14 14:37:14 +02:00
Mario Zechner
aa9cf15be4 feat(chord): init for state, typed principals, contract placement (protocol 3)
- self.state(name, schema, { init }) loads before the object goes live
- the principal type is a parameter; createHost self, connect and route principals are required
- remote contracts declare their host (hostNamed, hostFamily); get no longer takes at
2026-10-14 11:55:26 +00:00
David Brailovsky
6374c2baf4 fix(ai): send only thinking on/off toggle for Xiaomi MiMo models
MiMo Chat Completions rejects reasoning_effort "minimal" with a 400.
Xiaomi documents only thinking.type enabled/disabled and treats all effort
levels identically, so stop sending reasoning_effort and expose only the
off and high thinking levels.

fixes #10818
2026-10-14 13:13:16 +02:00
David Brailovsky
1692bba634 fix(ai): send thinkingLevel for Gemini 4 models
Gemini 4 Argon rejected thinkingBudget on Vertex and ignored the selected
thinking level on the Gemini API.

fixes #10890
2026-10-14 12:38:28 +02:00
David Brailovsky
63035734f2 fix(ai): order thinking before text when a completions chunk has both
Proxies such as LiteLLM can send reasoning_content and content in one
stream delta. Reasoning was handled after content, so the message ended
up as [text, thinking]. Handle reasoning fields and reasoning_details
before content and tool calls.

fixes #10926
2026-10-14 12:11:15 +02:00
Christian Klotz
d7f7e0dfee
fix(coding-agent): resolve model references through one provider selection policy (#10913)
* fix(coding-agent): resolve model references through one provider selection policy

Model references from --model, --models/enabledModels, /model, and auth credential printing now share one resolver. It collects every candidate before choosing a provider, so catalog order never decides, a :<thinking> suffix cannot change the provider, and an ambiguous exact match no longer falls through to a fuzzy match.

provider/id still prefers the named provider's exact or fuzzy match. A gateway exposing provider/id as a raw model id is used when the named provider has no match, or lacks credentials while the gateway has them. Several gateways without a unique authenticated one are reported as ambiguous.

fixes #10160

* docs(coding-agent): shorten model selection notes in CLI reference

* docs(coding-agent): condense #10160 changelog entry

* fix(coding-agent): move model reference resolution into model-resolver

* fix(coding-agent): warn when a model scope pattern matches several providers

* docs(coding-agent): trim model resolver comments to the reasons

* fix(coding-agent): build custom model ids from the resolver's not-found target
2026-10-14 11:00:21 +01:00
Mario Zechner
47fc5f38ec docs: add github-work skill pointing to the issue, PR, and wrap-up prompts 2026-10-14 09:47:25 +00:00
Mario Zechner
5713c9507c fix(durable): lead with the system baseline after a compaction that keeps assistant messages
Context derivation moved a system message to the front only when user messages
alone preceded it. After a compaction that keeps an assistant message, the
baseline written for the next run followed the kept history and the new input,
so Anthropic and OpenAI Codex requests had no initial prompt or tool set.

Derivation now identifies the harness baseline: the first pi.system entry after
the head marker, or of the transcript when no earlier entry carries a system
message, even one omitted later. Its message leads even past assistant
messages. Only the first system message ever moves, so replay is unchanged;
other system messages after an assistant message stay in place.

closes #10904
2026-10-14 09:47:25 +00:00
Mario Zechner
301617df7b feat(chord): lifetime "host" is checked by the type system
serve(Type, factory, { lifetime: "host" }) compiles only for a local type whose input has no required fields, and
not together with linger; the runtime check stays as a backstop. ServeOptions is a union (ReferencedServeOptions,
HostServeOptions), picked per contract by ServeOptionsFor<C>.
2026-10-14 09:43:42 +00:00
Mario Zechner
b042997178 fix(durable): encode base64 with btoa, without retaining concatenation trees
toBase64 grew each 8 KiB chunk a character at a time; V8 kept every
concatenation node until the final join, about 138 MB of heap for a
3 MiB image, beyond a Durable Object's 128 MB limit.

closes #10923
2026-10-14 09:41:45 +00:00