Commit graph

7333 commits

Author SHA1 Message Date
Mario Zechner
ec1be23eb9 fix(durable): review fixes for sleeping tasks and host timers
Due sleeps are picked up at every scheduling pass, so a pass that drops the timer cannot strand them.
Code mode drops a global's result after the script finished instead of reading an ended invocation's clock.
A foreground timer the host declines falls back to setTimeout; the default timer never fires early; Progress
rechecks its clock; an undelivered onWake is offered again. Spec, README, and tests follow.
2026-10-17 23:38:18 +00:00
Mario Zechner
26b5535a51 docs(durable): clarify the SQLite schema migration in the changelog 2026-10-17 23:25:11 +00:00
Mario Zechner
de47e488f2 docs(durable): changelog for sleeping tasks, timers, and wakeups 2026-10-17 23:08:06 +00:00
Mario Zechner
ea7c648430 feat(durable): workerd tests for Durable Object hosting
Runs the storage conformance suite, the schema migration, an alarm-woken sleep across an eviction, and a
turn recovered through the recovery alarm in workerd via @cloudflare/vitest-plugin (npm run test:workers).

fix(durable): decline background timers in Cloudflare Workers. With nodejs_compat, timers have an unref(),
so the idle-memory timers were armed and a pending one kept a Durable Object from hibernating or being evicted.
2026-10-17 23:02:48 +00:00
Mario Zechner
f75b3240ab feat(durable): durable sleeping state replaces runtime.sleep
Tasks end a phase asleep with runtime.sleepUntil() or { status: "sleeping", until, checkpoint }:
no invocation is held, the deadline survives restarts, and the task resumes at its checkpoint once due.
Generation retry/poll and compaction retry sleep this way. Harness.wake() and HarnessOptions.onWake let
a host such as a Durable Object wake the process itself. HarnessOptions.setTimer arms every Harness
timer, and chord Progress paces on an injectable clock. SQLite migrates to schema version 2 to admit
the sleeping status.
2026-10-17 22:29:26 +00:00
Mario Zechner
c268154ca1 feat(chord): move Durable's SQLite drivers into chord/sqlite 2026-10-17 16:48:29 +00:00
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