Scripts run image models with the session's credentials, like
models.classify(). Results are base64 image blocks that image() attaches
to the codemode result; usage counts toward the session cost.
The top-level /login menu offers Sign in with Radius with its status,
with an animated shimmer on the Radius row and a short Radius intro.
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.
Co-authored-by: niloc <5925270+colindaymond@users.noreply.github.com>
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.
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.
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
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
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.
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.
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.
Built-in extensions (mcp, llama.cpp, codemode, tool-search) are now extension resources like files: the package manager resolves them as builtin:<name>, the extensions setting disables them with -builtin:<name> (per project too), pi config lists them, and --no-extensions turns them off unless loaded with -e builtin:<name>. They load after project trust is resolved and after file and package extensions.
Built-in extensions and tools are named builtin:<name> in errors, diagnostics, RPC source info, and bug reports.
Adds fullscreenWheelScrollLines ("auto" or 1-100). Auto keeps one line
per event in local macOS terminals and scales with wheel velocity
elsewhere, capped at six lines per event.
closes#9758
Theme previews re-render the whole transcript, and streaming re-renders
every frame, so per-line and per-session work dominated in long sessions.
- visibleWidth: fast path for ANSI-styled ASCII, allocation-free escape scanning
- Box: compare unpadded child lines and skip a second width measurement
- Markdown: reuse parsed tokens across invalidation
- footer: cache usage totals and context usage per session state
- bash results: cache the collapsed preview including the expand hint
- sanitizeBinaryOutput: single regex replace
Together no longer lists Kimi K2.6, which broke type checks against the hydrated catalog. Tests use Kimi K3 and the Together default model now points at it.