Commit graph

6919 commits

Author SHA1 Message Date
Christian Klotz
b9ab2a6238
docs(coding-agent): restructure NVIDIA RTX llama.cpp prerequisites 2026-10-13 15:04:38 +01:00
David Brailovsky
6f2f164ab7
fix(coding-agent): restore active tools on session resume (#10887)
The SDK always passed initial tools, so the constructor never restored the
loadout recorded in the transcript, and resumed sessions dropped tools activated
during the session. Sessions that use the default tools now restore the recorded
loadout, with --tools +name/-name entries applied to it.

fixes #10785
2026-10-13 15:55:12 +02:00
David Brailovsky
34a8bb38b2 fix(ai): drop images from Anthropic error tool results
Anthropic rejects error tool results whose content is not all text, which
stalled sessions after a failed codemode script that had shown images.
Images in error tool results are now replaced with a text note.

fixes #10794
2026-10-13 15:45:12 +02:00
Vegard Stikbakke
cea257439d feat(coding-agent): configure session share destination
closes #10870
2026-10-13 15:41:13 +02:00
David Brailovsky
4b994d5e5e fix(ai): repair invalid \u escapes in tool-call arguments
Invalid \u escapes such as \usepackage were treated as valid, so JSON
parsing failed and the partial-json fallback dropped the field and
everything after it. They are now kept as literal text like other
invalid escapes.

fixes #10868
2026-10-13 15:36:01 +02:00
Christian Klotz
746d995b88
docs(coding-agent): add NVIDIA RTX llama.cpp setup 2026-10-13 14:15:52 +01:00
Armin Ronacher
f13c00fb3a fix: pin internal dependencies to exact versions
Update release synchronization and dependency checks to enforce exact versions. Refresh both lockfiles and add regression coverage.

closes #10865
2026-10-13 14:28:15 +02:00
github-actions[bot]
a3a2ee8ec2 chore: approve contributors from issue #10870 2026-10-13 12:02:45 +00:00
Armin Ronacher
db6497c3d9 feat(chord): flow control links end to end and limit calls per link
Peers acknowledge processed frames (ack, announced with acks in hello). While a window of frames is unacknowledged, state frames wait at the sender, coalesced per subscription, instead of queuing in front of call results; slots that outgrow their bound become resets, or a downstream resubscription on relays. AcceptOptions gains maxCalls, answering calls beyond it with unavailable/too_many_calls. Link.send returns the encoded frame size.
2026-10-13 13:09:04 +02:00
Mario Zechner
a4d040d30f fix(chord): a forked child host no longer inherits its parent's CHORD2_LOCK
forkDriver spread process.env into the child, so a child host that forks its own children (or a test run inside a p2 worker) passed its lock on, and children without a lock of their own failed with "locked".
2026-10-13 10:05:19 +00:00
Mario Zechner
018c87ddcb feat(chord): deflate large frame payloads on links; relays forward them unread
Call args, results and state snapshots whose JSON exceeds 64K characters are deflated
(level 1): over IPC as z: [field, base64], over WebSockets as a binary message
(envelope plus deflated payload). A relaying host forwards the bytes as received; the
host that uses the payload inflates it. Browsers inflate with DecompressionStream in
order; the p2 TUI launcher turns packed messages back into text frames. Servers send
packed frames to clients but refuse them from clients.

On the 8b6ab5cc session: first view 523 KiB -> 78 KiB, all history 23.5 MB -> 4.9 MB.
2026-10-13 10:04:10 +00:00
Mario Zechner
90f17f59a9 fix(chord): declare wire frames once, as the schema that validates them
Frame, RootRef, WireError and the reload types are derived from FrameSchema instead of
being declared twice. Error codes, contract tokens (Description is now a schema in
contract.ts) and ops are checked as typed; ops stay unknown until the delta decoder
validates them.
2026-10-13 10:04:08 +00:00
David Brailovsky
e6220e1316 fix: keep NODE_EXTRA_CA_CERTS in test.sh
Network tests failed with self-signed certificate errors behind proxies that
inspect HTTPS (corporate proxies, sandboxes like Gondolin), because test.sh
starts tests with an empty environment.
2026-10-13 11:23:56 +02:00
Mario Zechner
7d75a0e3eb fix(chord): nodeLoader registers every facet root before importing any
A facet listed before another facet whose directory it imports from loaded a second copy of that module; register
all roots first so every facet of one load shares one copy, whatever the order.
2026-10-12 23:37:22 +00:00
Armin Ronacher
d6370b72d0 fix(env): make the listing cancel and platform tests hold in CI
- Give the listing cancel test 30 s: creating 10,000 files takes over 5 s
  on Windows CI.
- Accept an x64 daemon on arm64 macOS: the darwin-x64 release daemon runs
  through Rosetta in CI.
2026-10-13 01:23:33 +02:00
Mario Zechner
de022efd61 test(env): wait for the foreground job's name, not just any foreground process
The shell forks before it execs, so a poll could catch the forked shell (named sh) and fail the name check.
2026-10-12 23:19:48 +00:00
Armin Ronacher
0a8cfff4cb fix: drop chord and esbuild from the Nix package
The coding agent no longer depends on chord, so the install lock has
neither chord nor esbuild, and the v1.2.0 Nix build failed in the
install check that loads esbuild.
2026-10-13 01:16:21 +02:00
Armin Ronacher
cd6b2a555a fix(chord): keep the process lock socket path within sun_path on macOS
A deep TMPDIR, such as ./test.sh's below macOS's per-user one, made the
lock socket path exceed 104 bytes and listen() failed with EINVAL. Fall
back to a private per-user directory under /tmp when the path does not fit.
2026-10-13 01:16:21 +02:00
Mario Zechner
235e8886f2 chore: remove an accidentally committed node_modules symlink; ignore node_modules symlinks too
7f022043f added packages/chord/node_modules, a symlink from a local worktree. The ignore pattern matched only
directories, so a node_modules symlink could be committed; it now matches files and links too.
2026-10-12 23:07:16 +00:00
Mario Zechner
7f022043f5 fix(chord): never keep a connection whose link was already closed
A route that returned a dead link (a child that exited before its link was wrapped) left a closed connection in
the host, so every later call to that host name failed with unavailable until restart. Such a connection is not
added, closed children are skipped when routing by name, and no ping timer is started for it.
2026-10-12 23:06:39 +00:00
Armin Ronacher
d547949184 Add [Unreleased] section for next cycle 2026-10-13 00:47:08 +02:00
Armin Ronacher
06a4669355 Release v1.2.0 2026-10-13 00:46:55 +02:00
Armin Ronacher
0d79b74db1 docs: audit changelogs and add new features for next release 2026-10-13 00:36:49 +02:00
David Brailovsky
7bd01fb924 fix(ai): retry "The upstream provider returned an error"
closes #10842
2026-10-12 18:24:53 +02:00
David Brailovsky
3e477eab5f feat(coding-agent): add PI_CLIPBOARD_OSC52 to force OSC 52 copies
Sends copied text to the terminal with OSC 52 after the local clipboard
write, as over SSH, for remote clients without SSH variables such as
multiplexer attaches and remote IDE daemons.

closes #10826, closes #10835, closes #10114
2026-10-12 18:07:27 +02:00
Armin Ronacher
b6d505cd1f fix(codemode): reject // @options: lines that are not the first line
A misplaced options line was ignored, so its timeout_ms never applied and
the script ran without a deadline. parseCodemodeSource now throws
CodemodeSourceError before the script runs.

fixes #10631
2026-10-12 17:55:33 +02:00
Mario Zechner
55df12bf62 docs(durable,env): changelog entries for listFiles 2026-10-12 15:22:48 +00:00
Mario Zechner
b6fda579f4 feat(env): listFiles for remote and local environments, nodePlatform
RemoteExecutionEnv.listFiles resolves the path and lists through the
daemon; a daemon without the listFiles feature yields not_supported.
LocalExecutionEnv is NodeExecutionEnv plus listFiles through a daemon on
the same machine, so local and SSH sessions list with the same code.
nodePlatform maps hello's Rust names to Node's (windows -> win32,
macos -> darwin, x86_64 -> x64, aarch64 -> arm64).
2026-10-12 15:22:14 +00:00
Mario Zechner
aa499c2426 feat(env): listFiles operation in the pi-env daemon
Lists a directory tree like fd --hidden --exclude .git without following
symbolic links, with the ignore crate of fd and ripgrep for git's ignore
rules. Records travel as payload (kind byte, relative / path, NUL); the
listing stops at maxEntries, maxBytes or timeoutMs with truncated, and a
cancel stops it between entries. hello reports features: ["listFiles"]
so clients can tell older daemons apart.
2026-10-12 15:22:14 +00:00
Mario Zechner
abfe62928b feat(durable): optional ExecutionEnv.listFiles for tree listings
An environment may list the files, directories and symbolic links below a
directory: relative / paths, depth first in name order, without .git and
what git ignores in work trees, bounded with a truncated flag. Callers fall
back to their own walk when it is missing or fails with not_supported.
The env conformance suite checks it with the new listFiles option.
2026-10-12 15:22:14 +00:00
Armin Ronacher
d4d53612be fix(ai): fall back on Anthropic strict tool limits
Retry known strict tool capacity rejections once with preferred tools using their original non-strict schemas. Preserve required constraints and payload hooks, and never retry a started stream.

closes #10409
2026-10-12 17:20:36 +02:00
David Brailovsky
19cb534c3b fix(chord): add ws and @types/ws dev dependencies for websocket test types 2026-10-12 16:17:25 +02:00
David Brailovsky
e6fb2581df fix(coding-agent): retry transient Windows EPERM when acquiring auth lock
A just-removed auth.json.lock directory can stay delete-pending on Windows
while another process holds a handle, making mkdir fail with EPERM. Retry
this briefly (capped separately from ELOCKED) so real permission errors
still fail fast.

fixes #10801
2026-10-12 16:14:55 +02:00
David Brailovsky
441f5767c4 fix(coding-agent): warn and exit non-zero in print mode on truncated response
Print mode now writes a warning to stderr and exits 1 when the final
response stopped at the model's output token limit. The partial text
is still written to stdout.

fixes #10799
2026-10-12 16:06:42 +02:00
David Brailovsky
39badde840 fix: point pi-test.sh at packages/coding-agent/src/cli.ts 2026-10-12 16:05:49 +02:00
Mario Zechner
b0ac39687a build: retire Pi Mobile's APK workflow and hook; check apps/p2 instead
Pi Mobile (apps/mobile in pi-private) is replaced by p2 (apps/p2). The Android APK workflow and its pre-commit
check go; the hook runs p2's own check when apps/p2 exists (only in pi-private).
2026-10-12 13:57:43 +00:00
Armin Ronacher
da0eadf043 fix(mcp): do not retry cancelled HTTP requests after an authorization refresh
A tool call that was aborted or timed out while waiting for a shared OAuth
refresh was still retried by StreamableHttpTransport once the refresh
finished, so the server executed a call the caller had already given up on.

McpClient now passes a per-request signal to McpTransport.send(), aborted
once the request settles (cancelled, timed out, answered, or closed).
StreamableHttpTransport checks it before each dispatch. The shared refresh
itself is not aborted, so other requests waiting on it still succeed.

fixes #10598
2026-10-12 15:33:20 +02:00
Armin Ronacher
014873d7d5 feat(coding-agent): show elapsed and total time on codemode rows
The codemode row shows "Elapsed" while the script runs and "Took" once
it finishes, like bash rows. The timer logic moves from the bash renderer
to render-utils, and scripts send an initial update so the timer starts
before the first nested call.

closes #10708
2026-10-12 15:29:18 +02:00
David Brailovsky
11f9911450 fix(tui): let unhandled wheel input scroll the transcript under a focused overlay
Wheel events that no component handles now scroll the transcript instead
of reaching the focused overlay's handleInput as raw input. Overlays that
scroll with the wheel must implement handleMouse.

fixes #10769
2026-10-12 14:21:58 +02:00
Armin Ronacher
67996ab75c fix(mcp,coding-agent): accept any JSON value as tool structuredContent
MCP 2026-07-28 allows structuredContent to be any JSON value, including
arrays and null. callTool() rejected non-object values, failing the whole
tool call. CallToolResult.structuredContent is now unknown, and MCP tools
without an output schema declare structuredContent as unknown to codemode.

refs #10416
2026-10-12 14:16:35 +02:00
Armin Ronacher
f4cca2dc22 fix(coding-agent): stop listing MCP resources when connecting
Servers with resources registered no tools until resources/list and
resources/templates/list finished, so a slow listing (a large drive)
kept their tools out of the first prompt. The lists only fed counts in
/mcp and pi mcp list; both now show that a server offers resources.
The resource tools still list and read resources on demand.

fixes #10526
2026-10-12 14:15:21 +02:00
David Brailovsky
6a51a39d42 fix(coding-agent): expand ~ in resource setting patterns
Entries like !~/skills/pdf, +~/x and -~/x in the extensions, skills,
prompts, and themes settings were compared with a literal ~ and never
matched.

fixes #10765
2026-10-12 14:03:34 +02:00
Mario Zechner
6db4070f17 docs: describe only the current Chord, Durable, and coding-agent code
Chord: README rewritten for the new runtime; notes.md and requests.md removed, their open limits and
decisions folded into spec.md section 12; guide and spec status lines updated. Durable: drops the
pico-v5 handoff and delta findings, renames the Pico spec, and uses current Chord terms. Delta README,
issue categories, and PI_RADIUS_GATEWAY updated.
2026-10-12 10:47:09 +00:00
Mario Zechner
066ebe4ca1 docs(coding-agent): changelog entries for the chord runtime replacement
Adds packages/chord/CHANGELOG.md (and ships it with the package) and coding-agent's Removed entries.
2026-10-12 10:43:35 +00:00
Mario Zechner
0104fef1e9 feat(chord): replace the facet and service runtime with the chord2 host runtime
Moves chord2 (contracts, objects, cells, roots, plugins, hot reload, memory/IPC/WebSocket links)
from p2 into packages/chord, with its tests (now on vitest) and docs. The root export is the new
runtime plus the shared base (Context, JsonValue, JsonRepresentation, Draft, copyJson, isJsonValue,
replicatedState and its types). ./node now holds the host manager, child control, process locks,
and nodeLoader. ./context and ./delta are unchanged; ./bundler is removed.

replicatedState stays a standalone module with the same exports. It no longer exposes the exact-op
subscription the removed service provider used, so listener failures of mutable states are always
reported asynchronously. The package depends on typebox instead of esbuild. The wire format stays JSON.
2026-10-12 10:41:59 +00:00
Mario Zechner
7472cda0d6 feat(coding-agent): remove the experimental server stack and the client, protocol, and server packages
Deletes packages/client, packages/protocol (CBOR codec), packages/server, coding-agent's
src/experimental (except source-resolver.ts, which source runs still preload), src/cli/experimental,
src/client, the example plugin, and their tests. coding-agent no longer depends on @earendil-works/chord.
The installer lock drops esbuild, so its platform-package sanity check goes too.
2026-10-12 10:41:59 +00:00
Mario Zechner
2ee5c1e56d docs(durable): drop the Chord facet usage guide and its test
The guide and chord-guide.test.ts used Chord's facet and service runtime, which is being replaced.
2026-10-12 10:41:59 +00:00
Armin Ronacher
148622bc6f fix(coding-agent): describe pi mcp login --timeout as a limit on the whole sign-in
closes #10636
2026-10-12 12:16:11 +02:00
Mario Zechner
eb2fce43d2 fix(durable): reject waits that close a wait cycle
A wait is rejected when it closes a cycle in the wait-for graph: waits of
tasks that are not abort-marked, and holds of live ordinary owned work. The
rejection names the cycle. Replaces the owner-chain rule, so a background task
may wait on its conversation's owner. Approach and tests from #10533 by
@odysseus0.

fixes #10411
2026-10-12 10:15:26 +00:00
David Brailovsky
ee409a85f6
feat(ai,coding-agent): list only the OpenRouter models a key may use (#10672)
On each OpenRouter refresh, combine the catalog (built-in models plus a newer pi.dev catalog) with GET /models/user for the user's key: keep only the listed chat models and take their context size, max output and prices from it. Image and classifier models are kept. The combined list is saved and replaces the OpenRouter catalog, including offline.

- ai: add personalizeOpenRouterCatalog and RefreshModelsContext.baseUrl, so the request follows a base URL configured in models.json (regional endpoints)
- ai: share OpenRouter price conversion with the generator; negative prices (router models such as openrouter/auto) become 0
- coding-agent: add withPersonalizedCatalog next to withRemoteCatalog
- docs: OpenRouter section in providers.md

fixes #10353
2026-10-12 10:17:40 +02:00