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.
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.
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.
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).
--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
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.
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
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
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
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.
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
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
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
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
Reject extension commands without a non-empty string name or a handler
at registration, instead of letting them crash the editor when typing /.
fixes#10054
getBranchSelection looked up the model catalog once per assistant message,
which made prompt submission scale with session length. Walk the branch
backward instead: only the last model_change can hold against later
responses, so at most that model needs a lookup.
closes#10198
Adds oauth.clientName (and pi mcp add --oauth-client-name) to set the
client_name sent during dynamic client registration. Defaults to pi.
closes#10226
MCP codemode exposure no longer lists tools, tool counts, or server
instructions in the codemode description. Servers are listed by name and
an optional mcp.json description; scripts find tools with searchTools()
and read instructions with describeNamespace(). codemode-deferred is an
alias for codemode.
refs #10212
image() now rejects malformed base64 and data without a PNG, JPEG, GIF,
or WebP signature, and derives the MIME type from the signature. Invalid
image blocks were persisted and made every later provider request fail.
closes#10215
registerNativeProvider() did not update the auth snapshot, so the provider
stayed unconfigured until an async refresh saved a snapshot that included it.
At startup that refresh can resolve before its result is saved, so initial
model selection saw the provider as unconfigured and fell back to another
provider or warned that no models are available.
Share registerProvider's provisional entry through markProvisionallyConfigured()
so native providers with a stored credential or a models.json apiKey are
configured immediately.
fixes#9962
The lazy OAuth entry list in the bundle build was missing openai-chatgpt,
so /login with OpenAI failed with a missing module error. Also fail the
build if any importOAuthModule() target in load.ts has no lazy entry.
Add gpt-6.1-sol to the OpenAI, Azure OpenAI Responses, and OpenAI Codex
providers with official pricing ($2 input, $0.10 cached input, $2.50
cache writes, $10 output, long-context tier above 272k). The model
rejects reasoning.effort "none", so off is unsupported and clamps to
the lowest effort.
Addresses GHSA-82fw-gwwq-j7x9 (vitest mocker path traversal) and
GHSA-3wwx-pv8p-q78v (undici 6.x permessage-deflate DoS). Both are
dev/example-only; the shipped coding-agent shrinkwrap is unchanged.
Structured bash results now hold the full output up to 1 MiB instead of the
model-facing 2000 lines or 50KB, keeping the first and last 512 KiB of longer
output, and add truncated and full_output_path.
Codemode sums the usage of models.classify() calls into its tool result and shows each call's cost. Usage of tools called through ctx.executeTool() is added to the calling tool's result usage instead of being dropped.
Vercel evaluation models are generated from the AI Gateway catalog and
routed through its TypeSafe-compatible /typesafe/v1/systemone endpoint.
OpenCode Zen's jev-1.13 and jev-1.13-free are routed through
/zen/v1/systemone.
Tools without a custom call renderer now show their arguments as key=value
pairs when collapsed and one key: value line per argument when expanded.
MCP tools get a server/tool title and results that collapse to 5 lines.
Entries of only +name/-name modify the inherited tool selection, so
"defaultTools": ["+codemode"] enables codemode without repeating the
defaults. Project entries layer on top of user settings. Document how to
enable codemode without MCP and how to use classifier models from it.
Anthropic, OpenAI Codex, OpenRouter, and Radius now use one loopback callback server in pi-ai. MCP sign-in renders the same browser page through a new renderPage option on the pi-mcp callback server.