Commit graph

7006 commits

Author SHA1 Message Date
Armin Ronacher
ea25697e91 fix(coding-agent): accept managed install markers with a UTF-8 BOM
Windows PowerShell 5.1 adds a BOM when it rewrites managed-install.json, which made pi update fail with "Managed install marker is missing or invalid".
2026-10-20 10:29:22 +02:00
Armin Ronacher
530015d93a fix(ai): only list announced removals as still unavailable
The incremental tools notice precedes the removal notice of the same message, so it now restates only removals announced by earlier messages. resolveTranscriptTools and hasNonAdditiveToolChanges share one scan for the last non-additive tool change.
2026-10-20 09:55:17 +02:00
Armin Ronacher
caa6967b62
fix(ai): keep the prompt cache across tool changes on Responses (#11142)
Models with additional_tools declare every tool in additional_tools items, starting with one at the head of the input, like Codex. A later item replaces same-name definitions from earlier items but cannot replace a top-level tool or remove a tool, so removals are announced as text and later updates restate the tools that are still unavailable.

Tool search and Kimi tool messages move the top-level tool list once per removal or redeclared name and keep later loads anchored, instead of resending the current tool list on every load after the first removal.

fixes #10940
2026-10-20 09:54:23 +02:00
Petr Houška
73f8de80bc fix(ai): recover from Copilot request-size overflow
Copilot rejects request bodies over its byte-size limit with HTTP 413 and a generic
'failed to parse request' body, so the existing token-count heuristics never matched.
Treat any HTTP 413 as request-size overflow regardless of provider or body text, so
the agent compacts and retries instead of surfacing a raw API error.

Validated against the live Copilot API (40MB image payload): main classifies the 413
as a plain error, this branch detects it as overflow.
2026-10-19 22:46:26 +02:00
Petr Houška
0ed1b04314 feat(tui): detect Rex terminal for OSC 8 hyperlinks
Rex supports OSC 8 but was treated as an unknown terminal, so links fell back to the `text (url)` format.

Detect it via TERM_PROGRAM=rex and enable hyperlinks and truecolor. Images stay off because Rex only partially implements the Kitty graphics protocol (no Unicode placeholders). The check runs before the outer-terminal checks so leaked variables like KITTY_WINDOW_ID don't win.

Closes #11131
2026-10-19 22:28:48 +02:00
Petr Houška
61060ddf8c fix(coding-agent): resolve Windows shells from installation directories
Use installation environment variables for PowerShell discovery and legacy WSL launcher detection.
2026-10-19 21:55:12 +02:00
Petr Houška
28bea006be fix(coding-agent): accept Windows Store shell aliases
Node's existsSync() can reject runnable Store aliases because its extra
Windows-only stat check fails with EACCES (nodejs/node#36790). Use
access(F_OK) for shell validation on all platforms instead, matching the
check harness-v2's async refactor settled on (617d8b317, now pathExists
in packages/durable/src/env/node.ts). On Unix this is a no-op: existsSync
is already access(F_OK) there, so shell search order and behavior stay
unchanged; on Windows runnable aliases now pass validation.
2026-10-19 21:24:10 +02:00
Mario Zechner
5c1736f82d feat: checkpointWhen is required on Durable document definitions
Breaking change: defineDoc and defineDocFamily now require an explicit checkpointWhen predicate; no default is supplied. Set policies on built-in documents, examples, tests, and triage state, and document the required API.
2026-10-19 18:17:42 +00:00
Mario Zechner
e86b054753 fix(ai): OpenRouter reasoning test uses deepseek-r1-0528, deepseek-r1 left the catalog 2026-10-19 16:54:15 +00:00
Mario Zechner
d9025a5f5e feat: SQLite telemetry store in Chord, shared TelemetryStore and trace renderer
- pi-telemetry: StoredSpan/StoredTrace/TelemetryStore (findTraces with name, attribute, error, time-window filters and
  cursor paging; getTrace; findMetrics), trace ids carried in carriers, renderTrace in the /render subpath; the in-memory
  adapter implements the store; the adapter contract trusts typed inputs (malformed-input conformance cases removed)
- chord: @earendil-works/chord/telemetry-sqlite over chord/sqlite: settled spans with inline events and links, metrics
  aggregated per series per 10 s, 1 s batched flush with retention, bounded queue (dropped and counted), store queries
2026-10-19 16:50:11 +00:00
David Brailovsky
d2e7d8b7c1 feat(ai): add MiniMax-M3.1-Flash and hide only old MiniMax models
Replace the direct minimax allowlist with a denylist of the older M2, M2.1,
M2.5, and M2.5-highspeed models, applied where MiniMax models are built.
MiniMax models with models.dev effort levels use adaptive thinking with
output_config.effort and mark thinking off as unsupported, since
MiniMax-M3.1-Flash rejects thinking.type=disabled.

closes #11121
2026-10-19 11:35:34 +02:00
David Brailovsky
e28e708049 ignore .pi/settings.json 2026-10-19 08:32:15 +00:00
Mario Zechner
2ec55d808d feat: Durable and pi-ai telemetry; Context.telemetry is always a span
- pi-ai: AI_TELEMETRY_SCHEMA; pi.ai.request and pi.ai.poll spans around Models requests via a lazyStream observer
  (no provider changes), first_chunk and block events (never per delta), usage/cost end attributes, provider_error
  status with a bounded message, aborted stays ok; duration, first-chunk, token and cost metrics; option renamed
  telemetryContext -> telemetry (a parent span)
- pi-telemetry: TelemetryContext carries readonly metrics and propagation capabilities on every span
- chord/context: Context.telemetry is always a TelemetrySpan (NOOP default); withTelemetry takes spans
- durable: DURABLE_TELEMETRY_SCHEMA; pi.durable.submit (inputs start their own trace linked to the caller) and
  pi.durable.phase spans for every task phase; stored carriers on submissions and tasks (TaskOptions.trace, links);
  entry, submission, checkpoint, replay and report events after commit; resumed tasks stay in their trace; phase
  duration, active task and report metrics; failed phases carry fixed categories with bounded messages
2026-10-19 06:26:02 +00:00
Mario Zechner
1402973a9d fix: chord boundary test allows pi-telemetry, the dependency of Context.telemetry 2026-10-18 20:43:39 +00:00
Mario Zechner
48909d987a feat: telemetry propagation, span links and metrics; telemetry member in chord/context
- pi-telemetry: TelemetryPropagation (inject/extract, opaque carriers), span links (SpanOptions.links, addLink),
  TelemetryMetrics (counter, up-down counter, histogram), typed metric schemas (createTypedMetrics), in-memory
  measurement log, conformance tests for propagation and metrics
- chord/context: fixed Context.telemetry member (NOOP default), withTelemetry, traceIn
- durable: HarnessOptions.telemetry option type (no instrumentation yet)
2026-10-18 20:36:08 +00:00
Mario Zechner
482c1381a0 fix(ai): update GLM-4.6V Coding Plan cache read price in test
models.dev now lists cache_read 0.05 for glm-4.6v, which the Coding Plan
entries take as their reference cost.
2026-10-18 02:15:33 +00:00
Mario Zechner
91b33cab3b feat(durable): ReportInfo says what happened, with typed reasons
onReport info is tagged by type (session_failed, task_faulted, task_parked,
migration_failed, task_outdated, task_error, extension_error, host_error,
listener_error). Task reports carry a ReportTask; restart-limit and outdated
definition reasons are typed fields instead of error.cause strings; host_error
names the failing HarnessOptions callback.
2026-10-18 01:58:07 +00:00
Mario Zechner
5ba1cbaf3d fix(durable): close keeps admitted aborts, reports name the extension that ran, review nits
- Close reads the records it writes back on the line, after admitted commits, so a queued abort mark survives.
- A task's report names the extension that installed the definition it ran, captured at reservation.
- Terminal and completing records drop the restart count; retryTask() ignores them.
- wake() counts a reconcile pass only when it has work, so a run's end sends no extra active wake.
- A failed agent resolution no longer breaks the tool result path that names a tool's extension.
- Spec §10.1 list, changelog sections, test cleanup of killed storages.
2026-10-18 01:00:42 +00:00
Mario Zechner
440a5fcdb8 fix(durable): review fixes for the crash-loop guard, reports, and blocked tasks
- A close writes the tasks it stopped back as pending, so only a crash counts a restart.
- An abort mark starts the count over; an abort handler cut off restartLimit times ends the task faulted.
- Only a changed state resets the count; raised and lowered limits reach the scheduler and the graph.
- wake() stays active while a reconcile pass is scheduled or underway; failed migrations recompute it.
- Reports name the extension whose code failed (hooks, wrappers, sections, tools, a task's installer),
  runtime.report() takes a source, and the parked report carries blocked: restart_limit.
- The task graph keeps only what blocked reasons read, and shows abandoned tasks waiting for a definition.
2026-10-18 00:53:14 +00:00
Mario Zechner
a30c2a81df feat(durable): crash-loop guard, report sources, inbox after failed runs, blocked tasks in the task graph
- Open counts restarts per task; at settings.restartLimit (default 5) a task is parked as blocked
  (restart_limit) until Harness.retryTask().
- onReport(error, info) with ReportInfo: session, task (faulted), extension, listener, host, timer, wake.
  Task faults are reported.
- settings.afterFailedRun: keep, continue, or withdraw the inputs queued behind a failed run.
- TaskGraphNode.blocked follows registry changes and failed migrations.
- README: fallback alarm before Harness.open in the Durable Object example.
2026-10-18 00:22:10 +00:00
Mario Zechner
e17e2e1055 fix(durable): release the second slow call when the first finished, not after 200 polls
The code mode ordering test released call 1 from an eventually() poll with a turn limit; on a loaded CI
runner the sandbox worker took more turns and the test hung until its timeout.
2026-10-17 23:54:43 +00:00
Christian Klotz
0b102787cd
docs(coding-agent): restore extension guide details (#11039) 2026-10-18 00:52:04 +01:00
Mario Zechner
00bf7193d6 fix(durable): arm before resume in the Durable Object example; timer wording
The README example and the test worker arm the recovery alarm before resume() in the constructor and in
alarm(). Timers should not fire early, and callers recheck; nativeTimer no longer needs a non-null assertion.
2026-10-17 23:41:24 +00:00
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