Rules and the tool list follow the declared tools (active minus
hiddenDeclarations). The skills hint names no tool when the reader is
hidden. Codemode shows each tool's prompt guidelines with its
declaration, via the new ToolLoadout.getPromptGuidelines().
closes#10343
close() now aborts a per-connection signal that closes the in-flight
client, cancels the retry wait, and waits for the connect attempt to
settle before returning.
closes#10249
Freeze built-ins and make built-in globals read-only before the script
runs, keeping instance overrides working via accessors. Validate all
worker payloads on the host and fail malformed ones as sandbox errors
instead of crashing the host process.
closes#10444
--tools no longer removes MCP tools unless an entry starts with mcp__, so
pi --tools codemode can reach MCP servers. Unnamed MCP tools are never
declared directly; only tool_search can load them. --no-tools still
removes everything.
--tools and --exclude-tools accept * patterns, for example
--tools read,codemode,'mcp__radius__*'. --no-mcp disables the built-in
MCP support for one run.
OpenID Connect authorization servers treat a registration without application_type as a web client and reject http loopback redirect URIs. Derive it from redirect_uris when unset (MCP SEP-837): native for loopback hosts and custom schemes, otherwise web.
closes#10493
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
- connectSsh detects the remote system, deploys the packaged daemon
verified by SHA-256 before it runs, and connects over ssh with strict
host keys under a fixed alias; scanHostKey and acceptHostKey
- Windows detection and deployment through PowerShell
- release builds the daemon for every supported remote system and
ships them in @earendil-works/pi-env's bin/
- end-to-end tests against a disposable sshd
- RemoteExecutionEnv: a Durable ExecutionEnv on another machine whose
results match NodeExecutionEnv there; Connection to the pi-env daemon
- packages/env/daemon: the Rust daemon for Linux, macOS, Android and
Windows, following Node and libuv semantics
- env.yml runs Durable's env tests, the daemon's checks and pi-env's
conformance and differential tests on Linux, macOS and Windows
* fix(coding-agent): keep syntax colors on multiline tokens
- format each line of a highlighted span separately
- add regression test for python docstrings
- fixes#10143
* fix(coding-agent): use text color for string interpolations
- map highlight.js `subst` scope to text color
* 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>
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.
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.
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
- 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
- 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
- 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
settings.progress.partialIntervalMs and outputIntervalMs replace the hardcoded
100 ms throttles for generation partials and running tool output.
refs #10357
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
- 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
- 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