Commit graph

6736 commits

Author SHA1 Message Date
Armin Ronacher
d78dc83d63 Release v1.0.3 2026-10-05 10:21:10 +02:00
Armin Ronacher
2a12fa4e88 docs(coding-agent): add new features to changelog 2026-10-05 10:13:51 +02:00
github-actions[bot]
0b7287ce77 chore: update Nix model catalog pin 2026-10-05 08:08:13 +00:00
Armin Ronacher
6100fe5a83 fix(tui): keep Home/End for the editor in fullscreen mode
Fullscreen transcript top/bottom moved to Ctrl+Home/Ctrl+End.

closes #10314
2026-10-05 09:53:54 +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
b2b5c42f61
fix(coding-agent): expect saved image label in codemode MCP test (#10463)
The codemode image() output now names the saved temp file before each
image, so the MCP integration test must expect the extra text item.
2026-10-05 00:58:33 +02:00
Armin Ronacher
4c6b724ea6 fix(coding-agent): do not report dead terminal stdin errors as crashes
When the terminal goes away, stdin reads and setRawMode fail with EIO (pi left in an orphaned background process group) or ENOTTY (revoked tty on macOS). These were uncaught, recorded in crashes.json, and prompted users to run /bug. Handle them on stdin like stdout/stderr and skip crash recording for dead terminal errors.
2026-10-05 00:41:56 +02:00
Armin Ronacher
1965a80693 fix(coding-agent,durable): fix CI test stub and macOS watch startup race
The bug report hint test stubbed InteractiveMode without the new
maybeShowInstallChangeWarning method.

On macOS fs.watch returns before libuv's FSEvents stream is live, so
changes made right after starting a watch could be lost. Rescan once
after installing native watchers there.
2026-10-05 00:02:59 +02:00
Armin Ronacher
d677d0ee71 feat(coding-agent): save codemode image() output to temp files
image() output is also written to a temp file and the result names the
path before each image, so later turns can reference generated images.
Output files are now created through one helper (still tmpdir()) and
are readable only by the user.

closes #10310
2026-10-04 23:32:43 +02:00
Mario Zechner
be882f3fa3 fix(durable): give watch conformance cases a timeout that covers polling latency 2026-10-04 23:15:37 +02:00
Mario Zechner
864777ba64 fix(durable): poll watches on Windows, where open watched directories block renaming their parents 2026-10-04 23:15:37 +02:00
Mario Zechner
a845108195 feat(durable): FileSystem.watch
- required watch(targets, onChange): missing targets, recursive targets
  with excludes, paths/overflow/error changes, native or polling mode
- NodeExecutionEnv: fs.watch events trigger rescans; changes are snapshot
  differences plus event paths; watchers for new directories before rescans;
  polling on network and FUSE file systems; directory budget
- conformance cases in native and polling mode
2026-10-04 23:15:37 +02:00
Mario Zechner
a19c09d9b7 feat(durable): bounded read tool via BinaryReader.scanLines
- BinaryReader.scanLines(): one pass inside the environment locates and
  measures a span of lines, decoded exactly like the whole file
- read detects images from the header and PNG chunk headers, scans once,
  and decodes only the head it shows; differential test against the
  whole-file algorithm
- StreamDecoder: Node's streaming TextDecoder dropped a U+FEFF after a chunk
  boundary in shell output and line readers
- fix the harness test to pick its tool result by call id
2026-10-04 23:15:37 +02:00
Mario Zechner
cdf79797b3 feat(durable): windowed shell output with counted skips
- ShellExecOptions.window and ShellOutputInfo.skipped: environments may omit
  output outside the retained tail and report exact counts
- ToolExecutionApi.outputWindow (tail limits and progress pace) and
  output(chunk, skipped); the bash tool passes both through
- OutputBuffer counts skips; property tests against the unskipped stream
- fix: progress snapshots no longer change which tail is kept
2026-10-04 23:15:37 +02:00
Mario Zechner
acfc60198e fix(durable): wait for killed Windows commands in env test cleanup; fix progress test status 2026-10-04 23:15:37 +02:00
Mario Zechner
674d64f091 feat(durable): configurable progress commit intervals
settings.progress.partialIntervalMs and outputIntervalMs replace the hardcoded
100 ms throttles for generation partials and running tool output.

refs #10357
2026-10-04 23:15:37 +02:00
Armin Ronacher
1b094148b9 fix(coding-agent): keep codemode working after the install is updated or removed
Resolve the QuickJS wasm path once and spawn the bundled codemode worker
from an in-memory data: URL. Show a restart hint when errors occur after
the install changed on disk.

closes #10439
2026-10-04 22:49:20 +02:00
Mario Zechner
f5d20047b3 fix(durable): retry temp dir removal in env conformance tests on Windows 2026-10-04 21:52:21 +02:00
Mario Zechner
4748c627ae feat(durable): bounded binary and directory readers, argv exec with stream info
- FileSystem.openBinaryReader(): positional reads of one opened regular file, noFollow
- FileSystem.openDirReader(): paged listings, vanished entries skipped
- Shell.exec() accepts an argv array (no shell); onOutput reports the stream
- Env conformance suite in /testing, run for NodeExecutionEnv
- Work-branch workflow running env tests on Linux, macOS and Windows
2026-10-04 21:52:21 +02:00
Mario Zechner
2e63fcdfbf docs(durable): changelog entry for Windows flushFile fix 2026-10-04 21:51:54 +02:00
Mario Zechner
1543dd8f63 fix(durable): make env tests and flushFile pass on Windows
- flushFile() on a directory returns is_directory on Windows too
- cwd tests check a marker file; Git Bash reports $PWD as an MSYS path
- retry temp dir removal while taskkill finishes killing descendants
- workflow running the env tests on Linux, macOS and Windows for durable-env-* branches
2026-10-04 21:51:54 +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
Mario Zechner
70eceaade6 fix(durable): persist provider session identities
Assign each conversation its own UUIDv7 and forward it to model requests for prompt-cache affinity. Lazily backfill legacy conversations and cover real Codex cache reuse.

Closes #10424
2026-10-04 00:59:08 +02:00
Armin Ronacher
83692682f0 fix: fetch full history before fast-forwarding stable in the Nix workflow
The shallow checkout did not contain the current stable commit, so git rejected the push to stable for v1.0.1 even though it was a fast-forward.
2026-10-03 15:23:44 +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
11449730c8 fix(coding-agent): render MCP tool calls before their server connects
Add pi.registerToolRenderer((toolName, next) => renderers), which chooses the
renderers for calls to any tool, including tools that are not registered.
Resolvers run in extension load order; next() returns what the remaining
resolvers, then the registered tool, would use. Interactive mode and HTML
export both resolve through it.

The MCP extension uses it to render every mcp__<server>__<tool> call with the
MCP renderers, so calls in a resumed session no longer render fully expanded
before their server connects, or for good if it never does.

closes #10285
2026-10-03 13:54:18 +02:00
Armin Ronacher
a276dabe57 fix(tui,coding-agent): convert non-PNG images for Kitty in Image
Kitty-protocol terminals only accept PNG. pi-tui now exposes
setImageTranscoder(); Image converts JPEG/GIF/WebP through it and shows
the text fallback without one. coding-agent registers a photon-based
transcoder, so images from extensions and all ToolExecutionComponent
hosts render.

closes #10292
2026-10-03 00:14:52 +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
9fba660cf1 chore: accept unfixable node-forge advisory in npm audit
The scheduled npm audit failed on GHSA-86w9-cpqp-85rv, which has no fixed node-forge release. node-forge is only reachable through gondolin in the private gondolin example extension, and gondolin only verifies certificates from its own CA with exponent 65537, so the low-exponent forgery does not apply. The audit now runs through scripts/npm-audit.mjs, which fails on any other advisory at or above moderate.
2026-10-02 18:49:34 +02:00
Armin Ronacher
672000c80c fix(tui): preserve WezTerm images while scrolling
closes #10319
2026-10-02 18:44:01 +02:00
Armin Ronacher
1387af7b42 feat(coding-agent): allow project mcp.json to override enabled and exposure of global servers
A .pi/mcp.json entry without command, url, or type overrides only enabled,
exposure, and toolExposure of the global server with the same name. /mcp can
enable or disable a global server for the trusted project, and pi mcp list
shows the override.

closes #10277
2026-10-02 18:34:49 +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
David Brailovsky
4665fafb4d fix(ai): keep models.dev pricing tiers for Amazon Bedrock models
Bedrock OpenAI models were costed at the short-context rate above 272k
input tokens because the generator dropped the models.dev tiers.

closes #10326
2026-10-02 18:25:43 +02:00
Armin Ronacher
319fecb89b fix(codemode): cap script output so print loops cannot exhaust host memory
text(), image(), and console.* fail the script with a RangeError past
MAX_OUTPUT_CHARS (16 Mi) characters or MAX_OUTPUT_ITEMS (100000) items.

closes #10283
2026-10-02 17:54:35 +02:00
David Brailovsky
eeac84ca92 fix(ai): fail Sign in with ChatGPT when the callback port is taken
When port 1455 was held by another pending login (another pi session
or the Codex CLI), login fell back to a paste prompt, but the browser
callback reached the other listener, which rejected it with "OAuth
state mismatch". Fail before opening the browser with a port-in-use
error instead.

fixes #10265
2026-10-02 17:44:05 +02:00
Armin Ronacher
581e7ba781 feat(coding-agent): remove npm shrinkwrap and recommend the managed installer
npm installs no longer pin transitive dependencies. Pinned installs come
from the pi.dev installer lockfile. pi update on global npm installs now
recommends migrating with the installer.

closes #5653
2026-10-02 17:16:56 +02:00
David Brailovsky
221cbcb02e docs(ai,coding-agent): document Cloudflare Clef classifiers
List @cf/cloudflare/clef and @cf/cloudflare/clef-flash under
cloudflare-workers-ai in the classifier models table and add changelog
entries crediting #10316 and #10322.
2026-10-02 16:58:49 +02:00
Nathan Disidore
4812cb268e
feat(ai): add Cloudflare Clef classifiers to Workers AI (#10316)
builds on https://github.com/earendil-works/pi/pull/10322 by @RealAlexandreAI
2026-10-02 16:52:58 +02:00
David Brailovsky
c10bfb0d79 fix(ai): use dashed Claude model IDs for Cloudflare AI Gateway
The gateway's /anthropic passthrough forwards the model ID to Anthropic
unchanged. models.dev lists the gateway's Claude models with dotted
versions (claude-opus-5.5), which Anthropic rejects with a 404. Convert
dots to dashes (claude-opus-5-5) when generating the catalog.
2026-10-02 16:12:00 +02:00
Armin Ronacher
1499466d85 feat(coding-agent): opt-in MCP OAuth client ID metadata documents
Adds oauth.clientRegistration: "cimd", which identifies pi with its Client ID Metadata Document on pi.dev instead of dynamic client registration, matching Codex: a shared document when the authorization server sends iss, otherwise a document and callback path specific to the MCP server. Authorization responses are only accepted on the exact redirect URI. Dynamic client registration stays the default.

closes #10302
2026-10-02 16:02:43 +02:00
Christian Klotz
de7e675de2
docs: update repo and CLI READMEs
Fixes #6907
2026-10-02 14:29:23 +01:00
David Brailovsky
9b3c19da5c fix(coding-agent): ignore empty entries in --models
A trailing comma in --models produced an empty pattern, which
matched every model by substring and added an extra model to
the model cycle.

fixes #10334
2026-10-02 13:42:38 +02:00
Armin Ronacher
b271b0a524 feat(ai): define Anthropic mid-conversation tools inline
Switch native Anthropic tool changes to the inline-tools-2026-09-15 beta. Later tools are defined by value in tool_addition blocks, so the top-level tool list stays fixed and same-name redefinitions no longer fall back to resending the full tool list. The deferred placeholder is kept.

Upgrade @anthropic-ai/sdk to 0.129.0 and deprecate hasToolRedefinitions().
2026-10-02 12:30:48 +02:00