Commit graph

6931 commits

Author SHA1 Message Date
Mario Zechner
47fc5f38ec docs: add github-work skill pointing to the issue, PR, and wrap-up prompts 2026-10-14 09:47:25 +00:00
Mario Zechner
5713c9507c fix(durable): lead with the system baseline after a compaction that keeps assistant messages
Context derivation moved a system message to the front only when user messages
alone preceded it. After a compaction that keeps an assistant message, the
baseline written for the next run followed the kept history and the new input,
so Anthropic and OpenAI Codex requests had no initial prompt or tool set.

Derivation now identifies the harness baseline: the first pi.system entry after
the head marker, or of the transcript when no earlier entry carries a system
message, even one omitted later. Its message leads even past assistant
messages. Only the first system message ever moves, so replay is unchanged;
other system messages after an assistant message stay in place.

closes #10904
2026-10-14 09:47:25 +00:00
Mario Zechner
301617df7b feat(chord): lifetime "host" is checked by the type system
serve(Type, factory, { lifetime: "host" }) compiles only for a local type whose input has no required fields, and
not together with linger; the runtime check stays as a backstop. ServeOptions is a union (ReferencedServeOptions,
HostServeOptions), picked per contract by ServeOptionsFor<C>.
2026-10-14 09:43:42 +00:00
Mario Zechner
b042997178 fix(durable): encode base64 with btoa, without retaining concatenation trees
toBase64 grew each 8 KiB chunk a character at a time; V8 kept every
concatenation node until the final join, about 138 MB of heap for a
3 MiB image, beyond a Durable Object's 128 MB limit.

closes #10923
2026-10-14 09:41:45 +00:00
David Brailovsky
7efebff189 fix(ai): retry gateway 'Unable to forward upstream stream' errors
closes #10920
2026-10-14 11:14:38 +02:00
David Brailovsky
60ac3bcc3b
feat(ai): keep the prompt cache when changing thinking level on OpenAI GPT-6 (#10930)
With an API key, GPT-6 models on the openai provider now keep reasoning.effort
fixed and send the thinking level as configuration_update input items. Each
reply records its level, so earlier items are rebuilt unchanged on every request.
Controlled by compat.supportsMidConvoEffort; skipped for Sign in with ChatGPT
and thinking off.

closes #10853
2026-10-14 10:56:20 +02:00
David Brailovsky
195120a915 fix(ai): move OpenCode providers to inference endpoints
- Use opencode.ai/inference and opencode.ai/inference/go base URLs; /zen/go has no Gemini route (404)
- Add google-generative-ai support to the OpenCode Go provider
- Use Anthropic Messages for OpenCode Go minimax-m2.7; openai-completions now returns ModelProtocolUnsupported
- Remove test for opencode-go deepseek-v4-flash, which is no longer listed
2026-10-14 10:10:28 +02:00
Mario Zechner
39294a5e95 fix(chord): a failed IPC write ends the link instead of raising an unhandled error
A host that wrote to a peer process which had just exited (an ack timer firing after the worker's exit, before the
channel's disconnect) got EPIPE as an unhandled 'error' event. IpcLink now passes a send callback and ends the link on
failure; host-manager control messages to a gone peer are dropped (its exit reports it).
2026-10-14 08:07:35 +00:00
Mario Zechner
00d8d04955 fix(chord): reload and retirement correctness across hosts; no leaked code generations
- A child that says hello during a cluster reload is fenced at once and reconciled after the reload ends, to the
  committed code version (it was marked in sync without voting); a running reconciliation also waits for the reload.
- A child retires a code version only after its parent did (spec section 12): the coordinator retires before it
  prepares, and children learn already retired versions at hello and before a reconciliation's prepare.
- Forced retirement aborts the leftover roots of the old code version, relayed calls included, before it closes the
  resources only that code used.
- A task's replacement starts after the old run has ended, at most taskStopDeadline later.
- A kept resource adopts the newest declaration's close at commit.
- Disposed objects and old code generations are released: Ref bindings are weak, finished disposals leave the dying
  table, stopped tasks are dropped, and contexts link abort signals without AbortSignal.any (which kept linked signals
  and their listeners reachable).
- Facets get FacetApi.signal, aborted when their run is replaced, removed, aborted or the host closes.
- Regression tests for each, including a garbage-collection test of old code generations.
2026-10-14 07:08:02 +00:00
Mario Zechner
d20c6e9662 refactor(chord): declarations by name, void and no-argument methods, per-cell state versions
- self.state(name, schema, initial, { version?, migrate? }) returns the cell; the state version and migration live on
  the cell (ServeOptions.state is gone). self.derive(sources, fn) has no name and is recomputed at commit.
  self.resource(name, { version, deps?, exclusive?, open, close? }) (rev is version). self.task(fn). self.on(name,
  source, [select,] handler) replaces listen/listener. cell(), derivation(), resource(), listener() and the
  declaration maps are gone; a name declared twice in one factory run is an error.
- A listener on state receives the current value at start and after every reload: handlers must reconcile.
- method(args?, result?): an omitted result is void, omitted arguments make a no-argument method called as
  ref.name(ctx) and implemented as (ctx) => ...; the wire omits both.
2026-10-14 06:12:23 +00:00
Mario Zechner
2688aba7dc refactor(chord): name things after the concepts; object variants; link protocol version; object lifetimes
- References are Ref<C> (was Handle<C>), objects ObjectImpl (record.ts is object.ts), ImplementationOf<C> (was
  BehaviorOf<C>), ResourceDeclaration (was ResourceSpec); epochs are code versions (codeVersion in Ctx, RootOptions,
  Shape, Host, frames and reload reports). Docs say object and reference.
- A remote object's variant is named variant (was kind): factories return { variant }, references expose ref.variant.
- Links announce a protocol version (PROTOCOL_VERSION = 2) in hello; peers of different versions close the link with
  reason protocol-version <n> and report it through LinkOptions.onProtocolMismatch.
- ServeOptions.lifetime ("referenced" | "host") replaces eager: a host-lifetime object is local, has an empty input,
  exists once per host and lives until the host closes; awaitEager is awaitHostObjects. A reload that makes a type
  referenced releases the host's own reference.
2026-10-14 05:34:14 +00:00
Armin Ronacher
3daa20280f fix(coding-agent): keep codemode cancellation prompt and bounded
Refs #10748
2026-10-13 18:17:31 +02:00
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