Commit graph

6672 commits

Author SHA1 Message Date
Armin Ronacher
c117a85d7a refactor(coding-agent): build the Radius login shimmer on ExtensionSelectorComponent
The Radius menu subclasses ExtensionSelectorComponent and only replaces the selected Radius row, instead of duplicating the selector. The Radius intro uses the existing description option.
2026-10-01 15:08:57 +02:00
Armin Ronacher
8847e9d6f1 fix(coding-agent): restrict the login shimmer to Radius
The Radius login selector is internal: the shimmer and intro are private to the module and only reachable through Radius-specific factories. Options render like ExtensionSelectorComponent, so they line up with the title.
2026-10-01 14:59:33 +02:00
Armin Ronacher
ff0fd62b63 fix(coding-agent): keep subscription label default in OAuthSelectorComponent
OAuth providers without the new subscription field keep the "subscription" label; only an explicit false shows "account".
2026-10-01 14:51:49 +02:00
Armin Ronacher
981f6138dd Merge branch 'main' into radius-login
# Conflicts:
#	packages/coding-agent/CHANGELOG.md
#	packages/coding-agent/src/modes/interactive/components/oauth-selector.ts
2026-10-01 14:48:35 +02:00
Mario Zechner
48dd1e2f0f feat(coding-agent): port the experimental client/server to pi-durable
Session workers now host a durable Harness over a per-session sqlite storage.
The server keeps each session in <sessionDir>/<id>/ with meta.json and
session.sqlite and never opens the storage itself. Workers hold retirement
while the Harness task graph has live tasks and resume interrupted work on
open.

Transcript serves the root conversation's durable view directly, Models
follows the conversation's agent document, and AgentController maps prompt,
steer, follow-up, queue cancellation, abort, and compaction onto the root
conversation, plus waitForPrompt. navigate, nextRun, and resume are dropped
(see experimental/services/README.md TODO). The durable TUI and the worker
share harness-setup.ts.

pi-server exports its own SessionMetadata and no longer depends on
pi-agent-core. Chord accepts readonly JSON types in service contracts without
walking them, which recursive JSON types like pi-ai's made too deep.
2026-10-01 14:45:01 +02:00
Mario Zechner
7fd478a2e8 feat(agent): remove the experimental harness from pi-agent-core
pi-agent-core now contains only Agent, the agent loop, the proxy stream, and
their types. Removed the harness, sessions and session storage, pico3, harness
tools, compaction, skills, prompt templates, telemetry schemas, search types,
and the uuidv7 and pi-telemetry re-exports, plus the ./node, ./harness/* and
./experimental/pico3 subpath exports. Durable sessions live in
@earendil-works/pi-durable.

Also removed packages/session-backends and the experimental mini and micro
coding-agent frontends, with their scripts and build configuration.
2026-10-01 14:45:01 +02:00
niloc
40d711cd5b
feat(coding-agent): animate Sign in with Radius and add Radius intro (#10295) 2026-10-01 14:44:39 +02:00
Armin Ronacher
f29ea3deb2 feat(coding-agent): add header-only quietStartup mode
quietStartup: "header" keeps the startup header with version and key hints
but hides the model scope line and loaded-resource listing.
2026-10-01 14:42:02 +02:00
Maximilian Blazek
409e808f58
fix(coding-agent): keep pastel palettes pastel in the system theme (#10293)
Palette colors now keep the bell-curve falloff and are
also capped at the palette color's OKLCH chroma times that falloff.
Lightness and hue are unchanged, so contrast is unchanged.

closes #10255
2026-10-01 13:40:36 +02:00
Armin Ronacher
c662ec7e37 fix(coding-agent): restore MCP tools loaded by tool_search on resume and reload
The session restored its tool loadout before MCP servers reconnected, so deferred tools that tool_search had loaded were dropped. Restored tools that are not registered yet now stay pending and are activated when they register, until a setActiveTools() call deactivates a tool or the next prompt starts.
2026-10-01 13:35:33 +02:00
Armin Ronacher
04c8ea9dbe feat(coding-agent): offer Radius sign-in and MCP setup in /login
The top-level /login menu offers Sign in with Radius with its status. After a Radius sign-in it offers to configure the Radius MCP server in the global mcp.json with auth.provider and reloads. Cancelling a login returns to the menu it was started from. OAuth sign-ins without a subscription are labeled as accounts.
2026-10-01 13:11:10 +02:00
Vegard Stikbakke
0f8740bb65 fix(coding-agent): rename unconfigured to not configured 2026-10-01 12:37:37 +02:00
Mario Zechner
e792ba131e fix(coding-agent): keep one copy of each rendered user message line
The user message's Markdown pads and colors its own background instead of
sitting in a Box that kept a second full-width copy of every line. The output
is identical.
2026-10-01 11:37:01 +02:00
Mario Zechner
54c19a2529 fix(tui): reduce memory retained per rendered message
Markdown holds its parsed tokens weakly: a token tree is about ten times its
source, and every transcript message keeps a Markdown component. The tokens
still survive bursts of re-renders such as theme previews. Markdown, Text, and
Box flatten their cached lines, which V8 otherwise keeps as trees of the
concatenated parts. A long assistant message keeps about a fifth of the heap.
2026-10-01 11:36:51 +02:00
Armin Ronacher
5806068c26 fix(coding-agent): store MCP OAuth credentials per server name and URL
Entries sharing a URL now keep separate accounts. Credentials stored by
URL alone move to the first server that loads them.

closes #10252
2026-10-01 11:20:59 +02:00
Armin Ronacher
a4715ec9bf test(coding-agent): run the official MCP client conformance suite in CI
Runs the pinned @modelcontextprotocol/conformance client scenarios for 2025-03-26, 2025-06-18, and 2025-11-25 against pi's MCP connection and OAuth sign-in, and fails on regressions against a committed check-level baseline.
2026-10-01 10:43:44 +02:00
Armin Ronacher
e529a82c98 fix(mcp): keep granted scopes on step-up authorization
A step-up sign-in requested only the scopes of the insufficient_scope challenge, so the new token lost the scopes granted before and other requests asked for sign-in again. Tokens now record their granted scope and step-up requests the union (SEP-2350).
2026-10-01 10:43:44 +02:00
David Brailovsky
0c453048bd fix(coding-agent): require --model when --provider is given
--provider without --model was ignored and the default model from
another provider ran instead. It now fails with an error. Also fixes
the outdated "(default: google)" in the --help text.

closes #10236
2026-10-01 10:25:16 +02:00
Mario Zechner
70c036211d feat(coding-agent): show the durable TUI's task panel by default 2026-10-01 10:07:19 +02:00
David Brailovsky
41169ba2af fix(coding-agent): make /mcp login sign-in URL clickable in the TUI
fixes #10186
2026-10-01 09:55:24 +02:00
Mario Zechner
5609b0d6c0 feat(coding-agent): experimental TUI coding agent on pi-durable
A small local agent in src/experimental/durable: pi's model runtime, settings,
system prompt, theme, and interactive components over a durable Harness with
SQLite storage. Streaming, tools, steer and follow-up, abort, model and
thinking selection, compaction, --continue with recovery of interrupted turns,
a subagent tool with /agents to switch to and talk to subagents, and a live
/tasks panel from the task graph view. The tsconfig path for
@earendil-works/pi-durable/* resolves subpaths to source.
2026-10-01 09:53:21 +02:00
Mario Zechner
49683a3647 feat(durable): lifecycle conformance and task graph view (Packages 22, 23)
Package 22: runtime.now() and report() throw after the invocation ended; a
migration-only commit is published; a failed Harness.open closes without the
caller's context and rethrows the open error; ConversationWatch alias. Tests
for close joining non-cooperative code, cancelled close, queued operations at
the seal, progress calls and viewers on a paused Harness, the Chord guide, and
the spec's usage examples.

Package 23: Harness.taskGraph() and watchTaskGraph() mount every live task with
its owner edge, committed status, flags, and owned conversations, advanced from
commit publications. Example 24 prints the checkout's tree.
2026-10-01 09:53:21 +02:00
Mario Zechner
5b5ccddfac docs(durable): settle lifecycle wording and specify the task graph view (Packages 22, 23)
Close ends states and watches at its seal, joins non-cooperative code, and a
cancelled close cancels only its wait. Conversation.abort() starts scheduling.
New section 9.5 specifies Harness.taskGraph() and watchTaskGraph(). The Chord
guide uses real imports and documents shutdown order.
2026-10-01 09:53:21 +02:00
Armin Ronacher
8ce69e9d2b fix(mcp): treat empty and null optional OAuth fields as absent
Empty or null optional fields in OAuth token and registration responses
(scope, refresh_token, id_token, client_secret) failed sign-in, and
expires_in: null marked tokens as expired. Also fall back to the server
origin when resource metadata has invalid URLs, skip empty scopes when
selecting the requested scope, and end pagination at an empty or null
nextCursor.

closes #10266
2026-10-01 02:05:35 +02:00
Mario Zechner
b56702ad34 feat(durable): extensions and per-conversation agents (Package 21)
- Registry of named extensions (tools, sections, hooks, wraps, tasks) with install/uninstall;
  defineExtension, defineTool, section, hook, wrapTool, wrapSection
- pi.agent document (model, thinking level, extensions, tools filter, instructions, cwd),
  configure(), Conversation.agent()/configure(), agent option on root/createConversation/fork,
  task-owned conversations copy their owner's agent
- Harness-wide HarnessSettings read at every use; env function built per use
- Hooks and the agent resolved per task phase; tool calls resolved with the tools filter applied
- ToolRegistration<TParameters, TDetails> types execute() args from parameters
- HarnessOptions.conversationCreated; Tx.submissionByRequest() and Tx.createSubmission()
- FileSystem.id; edit/write serialize per file system id and canonical path
- CodingTools extension (read, write, edit, bash)
- Examples 06-31 on the new API, README and CHANGELOG
2026-10-01 01:28:22 +02:00
Mario Zechner
4bae867759 docs(durable): specify extensions and per-conversation agents (Package 21)
Extensions installed by name, the rewindable pi.agent document with configure(),
Harness-wide live settings, env built per use, typed tool args with defineTool(),
HarnessOptions.conversationCreated, Tx submission methods, FileSystem.id for
edit/write serialization, and tool resolution with the tools filter applied.
2026-10-01 01:28:22 +02:00
Armin Ronacher
17f3dccbef fix(tui): preserve ANSI order at slice boundaries
Fixes color bleeding after mouse selection and search highlights in
fullscreen mode when a styled token ends at the highlight boundary.

closes #10169
2026-10-01 00:05:28 +02:00
Armin Ronacher
d850edee9c feat(coding-agent): add MCP oauth.authServerMetadataUrl and check RFC 9207 iss
The configured metadata document replaces discovery and is trusted as
configured. Authorization codes are only exchanged when the response's
iss parameter names the flow's authorization server.

closes #10172
2026-09-30 23:56:10 +02:00
Lucas Meijer
7a11fe1c72
feat(ai): add copy code login method to Anthropic OAuth (#10194)
Claude Code's OAuth client also accepts https://platform.claude.com/oauth/code/callback
as redirect_uri. That page shows the authorization code to copy, which works when
the browser runs on another machine than pi, where the localhost callback cannot load.
Anthropic login now asks for a method like OpenAI Codex login: browser (default)
or copy code (headless).
2026-09-30 23:17:13 +02:00
xu0o0
65117e31f2
fix(tui): complete slash commands after leading whitespace (#10218) 2026-09-30 23:13:01 +02:00
Armin Ronacher
b35af04f46 feat(coding-agent,tui): add a hidden easter egg to the header logo
Adds TuiAltScreen.getScreenLines(), which returns the lines of the last rendered frame.
2026-09-30 22:57:55 +02:00
Mario Zechner
d4d74eb19b Merge PR #10232 follow-up a0feabda7 (already included in ed391c4f0) 2026-09-30 22:32:47 +02:00
Mario Zechner
ed391c4f0a fix(durable): harden async SQLite adapter queue and close
- drop AsyncLocalStorage misuse guards from the Node adapter
- run calls immediately when the queue is idle; transactions publish their barrier before the callback starts
- SqliteStorage.close() waits for admitted multi-query reads and shares one close promise
2026-09-30 22:32:34 +02:00
Christian Klotz
a0feabda7c
refactor(durable): drop AsyncLocalStorage misuse detection from Node SQLite adapter 2026-09-30 20:38:41 +01:00
Mario Zechner
8f89293a26 Merge PR #10232: feat(durable): make SQLite storage asynchronous 2026-09-30 21:36:10 +02:00
Armin Ronacher
955cc6665e Add [Unreleased] section for next cycle 2026-09-30 21:12:42 +02:00
Armin Ronacher
005af57d88 Release v0.99.2 2026-09-30 21:12:28 +02:00
Christian Klotz
77ac62f22a
refactor(durable): simplify Node SQLite queue and bindings 2026-09-30 20:10:39 +01:00
Armin Ronacher
002c183e18 docs(ai,coding-agent): audit unreleased changelog entries
Add missing entries, contributor attribution, cross-package duplicates, and a New Features section.
2026-09-30 21:07:03 +02:00
Phil Freo
a9424cd43d
feat(ai): Anthropic workload identity federation (#10242)
Adds Anthropic workload identity federation from the SDK env vars
(ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
ANTHROPIC_IDENTITY_TOKEN_FILE, optional ANTHROPIC_SERVICE_ACCOUNT_ID and
ANTHROPIC_WORKSPACE_ID). Keys and ANTHROPIC_AUTH_TOKEN keep precedence.

The federation client is reused across requests so the SDK's token cache
avoids a token exchange per request, and the SDK's own credential chain is
disabled so pi's auth resolver stays the only source of credentials.

closes #10177
2026-09-30 20:58:37 +02:00
Christian Klotz
cd0ba2fabc
feat(durable): execute SQLite queries by SQL text and cache statements per connection
Replace prepare/SqliteStatement with run/get/all(sql, ...params) on the database and transaction handles. The Node adapter caches prepared statements per connection, so transactions reuse them instead of preparing again on every commit.

Read documents in one transaction so a concurrent commit cannot replace the base between the record and revision queries.
2026-09-30 19:49:55 +01:00
Armin Ronacher
91f9f3b5df feat(coding-agent): let MCP servers authenticate with a provider login
HTTP MCP servers can set "auth": { "provider": "<provider>" } to send the provider's current /login token as the bearer token instead of using MCP OAuth. The token is read on every request, so provider refreshes apply and nothing is copied to mcp-auth.json. Only allowed in the global mcp.json and from extensions, and requires https except on loopback hosts.
2026-09-30 20:41:58 +02:00
Armin Ronacher
b29db895c5 fix(coding-agent): align MCP tool names with codemode identifiers
MCP tool and namespace names now replace - with _ like Codex, so the
pi tool name is also the codemode identifier. Tools of a server whose
names collide all get a hash suffix, and server names that differ only
in - and _ are rejected.

closes #10239
2026-09-30 18:40:06 +02:00
Mario Zechner
ed0d6b91b6 feat(durable): compaction and overflow (Package 20)
Manual compact(), background and blocking threshold compaction, and overflow
compaction with one retry. Summaries are headed pi.compaction entries placed
through the inbox, or appended by a compaction the generation waits on; the
stale rule decides between concurrent summaries.
2026-09-30 18:23:25 +02:00
Mario Zechner
b72cf98ec7 docs(durable): specify compaction and overflow (Package 20) 2026-09-30 18:23:25 +02:00
Armin Ronacher
db6cc71dc7 feat(coding-agent): enable tools newly added to defaultTools on reload
When the session's initial tools come from defaultTools, /reload activates
names added to the resolved selection. Removals do not deactivate tools, and
explicit --tools/--no-tools/--no-builtin-tools keep overriding the setting.

closes #10245
2026-09-30 17:55:25 +02:00
Armin Ronacher
028c0ec56e fix(coding-agent): do not list codemode-hidden tools in the system prompt
In codemode.mode "only", tools whose declarations codemode hides were still
listed in the <tools> section. Drop their snippets so the list matches the
declared tools.

closes #10192
2026-09-30 17:46:43 +02:00
Armin Ronacher
0582d9c11d fix(coding-agent): limit codemode and MCP result previews to wrapped lines
Collapsed previews counted logical lines, so one long JSON line filled the
screen. Share a VisualLinePreview component with the bash renderer.
2026-09-30 17:25:07 +02:00
Armin Ronacher
e029c3ed0a feat(coding-agent): stop waiting for MCP servers on the first prompt
The first prompt waits only for servers with direct tools. Other servers
connect in the background; codemode scripts, tool_search, and the
resource tools wait for the servers they need. codemode and tool_search
are activated from the config.

Tool declarations no longer depend on connected servers: the codemode
description leaves out deferred tools, and the tool_search description
no longer lists sources. Servers are listed in an mcp_servers system
prompt section instead, set in before_agent_start from the config and
connected state, so changes are appended to the conversation.

describeNamespace() and searchTools() accept mcp__dev-radius,
mcp__dev_radius, dev-radius, and dev_radius.

closes #10212
2026-09-30 17:21:05 +02:00
David Brailovsky
2bbfcca437 fix(ai): use exponential backoff when Retry-After is unparseable
closes #9571
2026-09-30 15:31:30 +02:00