Commit graph

773 commits

Author SHA1 Message Date
Christian Klotz
13aa6b159c
docs(coding-agent): improve MCP server guide (#10199) 2026-09-30 01:20:50 +01:00
Armin Ronacher
1ef250772e feat(coding-agent): split MCP deferred exposure into tool_search and codemode modes
deferred MCP servers now activate tool_search instead of codemode, so their tools load as declared tools without codemode. The previous behavior is available as codemode-deferred. The unreachable-tools warning now accepts an active tool_search as reaching undeclared MCP tools.
2026-09-29 08:03:12 +02:00
Armin Ronacher
a1fa315f8f feat(coding-agent): add MCP resources, per-tool exposure, and output limits
Servers with resources are reached through Codex's list_mcp_resources, list_mcp_resource_templates, and read_mcp_resource tools; MCP App resources and icons are left out. toolExposure sets the exposure of single tools by name or pattern. Tool annotations are passed on to ToolDefinition and ToolInfo for permission extensions. MCP text over 20KB is cut in the middle like in Codex and saved to a temp file. OAuth takes scope and a Codex-style callbackUrl, and stdio servers expand ~ in command, args, and cwd. Also fixes the !command header example in the MCP docs.
2026-09-29 07:49:19 +02:00
Armin Ronacher
715f2eccac feat(coding-agent): use -l/--local for project servers in pi mcp add/remove
Replaces --project to match pi install and pi remove.
2026-09-29 01:24:27 +02:00
Armin Ronacher
e78aece136 feat(coding-agent): add pi mcp add/remove and log server messages to mcp.log
pi mcp add writes stdio or HTTP server entries to the global or project mcp.json, pi mcp remove deletes them. Log messages servers send with notifications/message are appended to mcp.log in the agent directory, rotated at 5 MB.
2026-09-29 01:03:19 +02:00
Armin Ronacher
0cc77a1c10 Merge branch 'main' into codemode-and-mcp
# Conflicts:
#	packages/coding-agent/docs/extensions.md
#	packages/coding-agent/src/core/agent-session.ts
#	packages/coding-agent/src/core/extensions/loader.ts
#	packages/coding-agent/src/core/extensions/types.ts
#	packages/coding-agent/src/core/model-registry.ts
#	packages/coding-agent/src/index.ts
2026-09-28 23:54:27 +02:00
Armin Ronacher
540e174c72
feat(coding-agent): Virtual models (#10035)
This adds experimental support for virtual models. A virtual model is a catalog entry that an extension registers with pi.registerVirtualModel(). It does not talk to a provider itself; for every request it picks a physical model and thinking level. The motivation is to make routing policies pluggable: plan on a strong model and implement on a cheap one, pick a model with a classifier, or move to a larger window when the context grows. Today this needs model switching by hand or hacks in prepareRequest.

The selection stays virtual: model_change records it, resume restores it, and each response records the physical model and thinking level that produced it. Router state can be stored on the session branch, so it follows /tree and forks and survives compaction. Context limits, compaction and image sizing use the physical model a request was routed to. examples/extensions/jev-router.ts shows a full router that uses the Jev classifier to pick Sol or Terra for planning and hands off to Luna after the first edit. docs/virtual-models.md describes the API.
2026-09-28 23:30:45 +02:00
Christian Klotz
fd889a2741
fix(coding-agent,tui): paste Finder file paths instead of icons (#10136)
Read Finder file URLs before icon image data on macOS. Quote paths in
bash mode and reject terminal control characters before rendering.

Fixes #9999

Co-authored-by: 1dustycy <onedustycy@gmail.com>
2026-09-28 20:59:29 +01:00
Armin Ronacher
04efdfc380
feat(ai): Discount jev (#10119)
Add the llama-cpp-classify classifier API. Each question becomes one chat prompt with single-token answer labels; llama-server's pre-sampling next-token log-probabilities give the softmax over those labels. Missing labels are retried with deeper readouts and then reported as errors.
2026-09-28 14:19:07 +02:00
Armin Ronacher
a6bc4036d7 feat(coding-agent): let extensions register MCP servers
pi.registerMcpServer(name, config) adds a server for the session with the mcp.json config shape; pi.unregisterMcpServer() removes it and pi.getMcpServers() lists registrations. Servers registered while loading connect on session_start, later ones right away. A server in mcp.json with the same name takes precedence and /mcp shows the override. Changes to registered servers in /mcp apply to the session only.

The mcp_servers_change event lets any MCP extension connect registered servers; when none handles it, registrations are reported as extension errors.
2026-09-27 23:50:53 +02:00
Armin Ronacher
e94c9763db feat(codemode,coding-agent): rename the exec tool back to codemode
The tool is named codemode again and scripts configure it with a first-line // @options: {...} instead of the // @exec: pragma. yield_time_ms is gone; max_output_tokens and timeout_ms remain. Comments, docs, and tests no longer describe the tool in terms of another agent.
2026-09-27 23:22:48 +02:00
Armin Ronacher
74393661e9 fix(coding-agent): let extensions replace built-in MCP, codemode, and tool search
Built-in extensions marked replaceable are left out when another extension registers the same tool, command, or flag name, so third-party MCP extensions such as pi-mcp-adapter take over /mcp instead of both connecting the same servers.

MCP only activates the codemode exec tool, not another extension's tool named exec, and the first prompt waits at most 10 seconds for startup connections.
2026-09-27 22:41:51 +02:00
Armin Ronacher
779f67895c feat(coding-agent): add pi mcp list, login, and logout commands
pi mcp list connects to every enabled server and reports its state, tools, and errors, exiting with 1 when anything fails, so agents can verify an mcp.json they wrote. pi mcp login runs the OAuth sign-in through the browser, and pi mcp logout deletes stored credentials. Running sessions reconnect servers waiting for a sign-in at the next turn when their credentials changed.

The system prompt points MCP questions to docs/mcp.md, which now covers setting up servers: which file to edit, rules that are easy to get wrong, converting entries from other clients, and verifying with pi mcp list.
2026-09-27 22:01:25 +02:00
Armin Ronacher
4951dcc376 feat(coding-agent): open an MCP server manager from /mcp
/mcp in the TUI lists every configured server with its state, tool count, exposure, and scope, servers that need attention first, and updates while they connect. Selecting a server shows its command or URL, config file, and full error, and offers the actions for its state: sign in (with a paste field for the redirect URL), tools, reconnect, sign out, exposure, and enable or disable. Exposure and enabled are saved to the mcp.json that defines the server.

Startup problems are reported once in the transcript, pointing to /mcp. Outside the TUI, /mcp prints the status, and /mcp login, logout, and the new reconnect subcommand stay available.
2026-09-27 21:40:00 +02:00
Armin Ronacher
2498ca492e refactor(agent,coding-agent): isolate codemode, tool search, and MCP from the core
The agent loop is back to main's tool execution: it only exports runToolCall(), honors isError results, and passes structuredContent through afterToolCall. Nested calls (ctx.executeTool, ids, events with parentToolCallId, the nestedCalls record) live in coding-agent and start on the first call.

AgentSession no longer knows exec or tool_search. Tools adjust the declared loadout through a generic prepareLoadout hook, and codemode and tool_search use it like any other tool.

exec and tool_search move to built-in extensions under src/extensions/ and register inactive (defaultActive: false). The CLI loads them with MCP; SDK sessions add createCodemodeExtension(), createToolSearchExtension(), and createMcpExtension(). Extensions gain pi.getSettings() and model catalog and classifier access on ModelRegistry.
2026-09-27 21:15:56 +02:00
Armin Ronacher
377cef09de fix(agent,coding-agent): simplify tool result contracts from the codemode review
- structuredContent after tool_result/afterToolCall: providing it replaces it; replacing content without it drops it. No more key-presence checks.
- Tools run outside a session get a ToolContext (loop services plus optional extension fields) instead of a context typed as a full ExtensionToolContext.
- Document that nested calls get synthesized <parent>/<n> tool call ids that never appear in the transcript.
- The exec description no longer mentions yield_time_ms, which is accepted and ignored.
- The sandbox abort test waits for the tool call instead of a fixed delay.
2026-09-27 19:31:57 +02:00
Armin Ronacher
42933fdb50 feat(ai,agent,coding-agent): emit events for nested tool calls and record them
Calls a tool makes through executeTool (for example from exec scripts) now emit tool_execution_start/update/end with parentToolCallId, for extensions and telemetry. Interactive mode keeps showing them inside the parent's row, and Agent.pendingToolCalls only tracks model-issued calls.

The model-issued call's tool result message carries nestedCalls, a bounded record like Codex's ExecutedToolCalls: name, arguments, status, duration, and error, never results. Arguments over 8 KiB per call or 32 KiB in total are omitted, at most 256 calls are kept, and complete is false when anything was lost or still running. Compaction and branch summaries count files touched by nested read/edit/write calls, and HTML exports list nested calls.
2026-09-27 19:14:50 +02:00
Armin Ronacher
188d3a4bd0 feat(coding-agent): add codemode.mode to present tools like Codex's tool modes
While exec is active, codemode.mode on (default) appends the exec declaration to declared tools that scripts can call and lists only non-direct tools in the exec description. codemode.mode only lists every callable tool in the exec description and hides active direct tools from requests. The hiding is a request projection, so the transcript still declares the active set and /tree and resume keep it.

The exec listing depends on exposure, not on the active set, so tool_search loads do not redeclare exec.
2026-09-27 19:07:25 +02:00
Armin Ronacher
fe07d21dde feat(coding-agent): add tool discovery for exec and a tool_search tool
- The exec description spends at most codemode.inlineBudget (default 3000) estimated tokens on tool declarations, filled round-robin across namespaces, cheapest first. Every namespace is listed with its tool count, and the listing says COMPLETE or PARTIAL.
- Scripts find omitted and deferred tools with searchTools(query, { limit, namespace }) and describeTool(name).
- tool_search, an optional built-in modeled on Codex, searches codemode and deferred tools and declares the matches for the next model call through the active tool set, so loads are recorded on the branch.
- Both use a BM25 ranker over Codex's search text (name, description, schema properties, namespace) behind a ToolRanker interface.
2026-09-27 18:48:47 +02:00
Armin Ronacher
3de4babe50 feat(codemode,coding-agent): make codemode a Codex-compatible exec tool
The codemode tool is now exec and follows the exec tool of OpenAI Codex, so scripts written for Codex run unchanged:

- // @exec: pragma with yield_time_ms, max_output_tokens (default 10000 tokens) and the pi addition timeout_ms; Codex's grammar and error messages
- text(), image() (data URLs, { image_url }, MCP ImageContent), exit(), ALL_TOOLS, tools under normalized identifiers; console and return values append text
- Results start with Script completed/failed and the wall time; failed scripts return an error result that keeps partial output and appends Script error
- Output over the token budget keeps its start and end like Codex; the full text is spilled to a temp file
- MCP tools resolve to their CallToolResult (isError resolves) and are declared as CallToolResult<T>; bash resolves to { output, exit_code, wall_time_seconds }, also for non-zero exits
- The description uses Codex's layout: helper list, deferred-tool guidance, shared MCP types, one section per tool grouped by namespace (MCP servers, with their instructions)
2026-09-27 18:00:33 +02:00
Armin Ronacher
4ccdc212e7 feat(agent,coding-agent): replace nestedOnly with tool exposure
AgentTool.nestedOnly is replaced by AgentContext.nestedTools, the tools callable through executeTool. Tool definitions declare an exposure (direct, model-only, codemode, deferred, hidden). The active set is now the declared set; codemode and deferred tools are callable from codemode whenever registered, so tree navigation, resume and fork cannot drop them.

MCP servers accept deferred and hidden exposure, withdraw tools by re-registering them as hidden, and mcp.json gains autoEnableCodemode.
2026-09-27 17:38:48 +02:00
Armin Ronacher
b9bbc35844 fix(coding-agent): make MCP connections and OAuth refresh reliable
- Share one OAuth refresh between concurrent requests and skip it when the
  token was already replaced, so rotating refresh tokens do not sign the
  user out; refresh tokens before they expire
- Treat insufficient_scope as needs-sign-in and request the new scope on
  /mcp login instead of refreshing
- Only list tools for servers that declare the tools capability
- Retry HTTP connects that fail transiently; show dropped connections as
  disconnected
- Deactivate tools a server withdraws on list_changed and restore them
- Keep sanitized tool names unique; default missing input properties
2026-09-27 12:41:07 +02:00
Armin Ronacher
6e6c5a9fe3 Merge branch 'main' into codemode-and-mcp
# Conflicts:
#	packages/coding-agent/install-lock/package-lock.json
#	packages/coding-agent/npm-shrinkwrap.json
2026-09-27 12:26:43 +02:00
Armin Ronacher
bf8e4b9531
feat(coding-agent,tui): System theme (#10067)
* feat(coding-agent,tui): add system theme derived from terminal colors

The new default system theme builds pi's colors from the terminal's reported foreground, background, and ANSI palette. Tokens take their hue and relative saturation from a palette slot; lightness is placed by OKLab lightness difference and WCAG 2 contrast minimums. Terminals that report only a background get built-in hues, and terminals that report nothing get ANSI indices with faint secondary text.

The TUI queries OSC 10, 11, and 4 in one burst ended by DA1, so replies complete in one round trip, and reports replies that arrive after the timeout. Startup never waits: the system theme starts in grayscale and updates when colors arrive. Light/dark detection now uses the reported colors instead of the ?996 query; mode 2031 notifications trigger a new query.

* fix(coding-agent): wait for terminal colors before building the startup header

The header and startup notices bake theme colors into their text. When the color replies arrived after they were built, as in Windows Terminal, they stayed grayscale. Startup now waits for the first color query, which ends at the DA1 reply or after 100 ms.

* fix(coding-agent): rebuild header and notices on theme changes

The startup header, loaded resources, and chat notices baked theme colors into their text, so they kept the old colors after a theme switch or when the system theme received the terminal's colors. They now use ThemedText, which rebuilds its text from a function whenever the UI is invalidated.

* fix(tui): keep focus on components that forward mouse events to children

A component that forwards a mouse event to a child it hosts, such as SettingsList with an open submenu, left keyboard focus on the child. When the host removed the child, focus stayed on a detached component and all keys were lost. The forwarding component now keeps focus, like delegating containers do.

* feat(coding-agent): describe the system theme in the theme selector

* feat(coding-agent): list the system theme above automatic in the theme selector

* refactor(coding-agent,tui): remove leftovers of the light/dark startup detection

Theme detection only reports dark or light now; the source and confidence fields only served saving the detected theme. The first-time setup no longer shows the detected appearance. Removes the TUI's unused queryTerminalColorScheme(), queryTerminalBackgroundColor(), queryTerminalForegroundColor(), and parseOsc11BackgroundColor(); queryTerminalColors() covers them.

* feat(coding-agent): match the reviewed system and light/dark theme design

The system theme now follows the reviewed design: color families with OKHSL saturation curves, palette slots per family, contrast rules per token and panel, relaxation for mid-gray backgrounds, and the terminal foreground for body text. Each contrast level is a target-lightness curve fitted to the reviewed output. The built-in dark and light themes use the reviewed Pi dark and light colors.

* feat(coding-agent): show the pi logo in the startup header

A two-line pixel logo replaces the app name. Its first line carries the version, its second line the first line of key hints.

* feat(tui,coding-agent): support OKHSL colors in themes

parseColor() accepts okhsl(H S L), and okhslColor() and colorToOkhsl() construct and read OKHSL colors. OKHSL saturation is relative to the sRGB gamut, so every value is in gamut. Theme files accept okhsl() values; HTML exports convert them to hex. The OKHSL code moves from coding-agent into pi-tui, where colors.ts now shares its Oklab conversion instead of keeping a second copy.

* refactor(coding-agent): write the built-in themes in OKHSL

The built-in dark and light themes use okhsl() values, with variables for colors that several roles share, so they read as color families and serve as editable templates. Near-identical values collapsed into one; no color changes visibly.

* refactor(coding-agent,tui): simplify terminal color and theme code

Share the terminal color query between startup and the theme controller, merge the query's resolve/late-reply state into one callback, keep a single global for terminal colors, use oklab.ts arrays directly in colors.ts, and drop leftover helpers and exports.

* fix(coding-agent): use one terminal light/dark decision everywhere

Theme pairs, the system theme, and Theme.appearance now share getTerminalTheme(): the reported background decides, then the terminal's light/dark report, then COLORFGBG, then dark.

COLORFGBG is classified by palette index like Vim (0-6 and 8 dark) and only reads the last field, so rxvt's "default" no longer picks up the foreground index.

Simplify the tests added on this branch.

* fix(ai): use an OpenRouter model that still exists in beta test

OpenRouter removed anthropic/claude-3-haiku, which broke type checking in CI after model regeneration.
2026-09-26 13:33:47 +02:00
Armin Ronacher
362e2bdc80 feat(coding-agent): spill truncated codemode results to a JSON temp file
Like bash output, a codemode result over 50KB or 2000 lines keeps its head in the tool result and writes the full return value as JSON to a pi-codemode-<id>.json temp file, referenced in the output and in details.fullOutputPath.
2026-09-25 15:02:51 +02:00
Armin Ronacher
350aa4674d feat(coding-agent): expose the model catalog and classifiers to codemode
Scripts get models.getModelsOfType/getAvailableOfType/getModelOfType/classify, mirroring ModelRuntime. The host resolves models by provider and id so scripts cannot redirect credentials, strips headers from listed models, and runs at most four classifications per script at once. pi-codemode gains namespaced globals, spread arguments, and explicit signatures.
2026-09-25 15:02:51 +02:00
Armin Ronacher
9163a000f2 feat(coding-agent): add @options source format and session store to codemode
Codemode input is now the script itself, optionally starting with a // @options {"timeout": N} line, and the tool declares a Lark grammar so capable models write raw JavaScript. Scripts can keep JSON values with store()/load(); successful writes are appended as codemode-store custom entries and read back from the current branch.
2026-09-25 15:02:51 +02:00
Armin Ronacher
8cd0ed48de feat(coding-agent): add OAuth sign-in for remote MCP servers
HTTP servers without an Authorization header use OAuth. Connections send the stored token and refresh it after a 401; /mcp login runs the browser authorization code flow (PKCE, dynamic client registration) with a loopback callback or a pasted redirect URL, and /mcp logout removes the credentials. Tokens are stored per server URL in mcp-auth.json. Pre-registered clients are configured with the oauth block.
2026-09-25 15:02:51 +02:00
Armin Ronacher
27d2914457 feat(coding-agent): connect MCP servers and expose them through codemode
Adds a built-in mcp extension that reads mcp.json (agent dir, and .pi/mcp.json for trusted projects) in the common mcpServers format, connects stdio and streamable HTTP servers at session start, and registers their tools as mcp__<server>__<tool>. Calls go through the regular tool pipeline, so hooks and permission extensions apply. /mcp shows server status.

By default a server's tools are codemode-only: the new nestedOnly tool flag keeps them executable for other tools but out of the model's tool declarations, and pi activates the codemode tool for them. "exposure": "direct" declares them to the model as well. structuredContent from tools with an outputSchema reaches codemode scripts as data.
2026-09-25 15:02:51 +02:00
Armin Ronacher
138771cd8a feat(coding-agent): add codemode tool
Adds a built-in, opt-in codemode tool that runs model-written JavaScript in the codemode sandbox. Scripts call the other active tools as tools.<name>(args), including concurrently with Promise.all; only the return value, console output, and images attached with image() reach the model.

Nested calls run through the agent loop via a new AgentToolContext (5th execute argument, ctx.executeTool for extension tools), so argument validation and the beforeToolCall/afterToolCall hooks apply. Hooks and tool_call/tool_result events carry the parent call id.

Tools can declare outputSchema and return structuredContent; codemode passes that to scripts and falls back to text content otherwise. The codemode package gains globals, declaration rendering from JSON Schema, and optional deadlines.
2026-09-25 15:02:51 +02:00
David Brailovsky
e473b5cd8b feat(coding-agent): report prompt disposition in RPC responses
Successful RPC prompt, steer, and follow_up responses include
data.disposition ("handled", "queued", or "started" for prompt), so clients
know whether to wait for agent_settled.

fixes #9098
2026-09-25 14:53:11 +02:00
Armin Ronacher
5674690966
feat(tui,coding-agent): add color values and theme styling (#8398)
Expose theme colors as values and add theme.style() for combined styling.

- @earendil-works/pi-tui gains a Color type (palette index, sRGB, OKLCH) with parseColor(), mixColors(), colorToHex(), colorToRgb(), styleText() and related helpers.
- Theme JSON accepts #rgb and oklch(...) values and an optional appearance ("dark" or "light"), detected from the theme colors when omitted.
- theme.style() combines tokens or concrete colors with text attributes; theme.colors exposes concrete colors, including the terminal's reported default colors (OSC 10/11) for tokens set to "".
- Terminals with TERM=*-direct are detected as truecolor.
2026-09-24 14:42:22 +02:00
Armin Ronacher
a328aa89ad
feat(ai,coding-agent): unify image and classifier model infrastructure (#9948) 2026-09-23 17:41:19 +02:00
David Brailovsky
002fc83852
feat: expose provider stream events to extensions (#9901)
Add onProviderStreamEvent through pi-ai and agent core, and surface
provider_stream_event to coding-agent extensions.

Closes #9784
2026-09-23 16:03:30 +02:00
Armin Ronacher
8d897edaa6 fix(coding-agent): prevent duplicate extension runtimes (closes #9863) 2026-09-23 15:33:56 +02:00
Christian Klotz
25cc5c7bf4
docs(coding-agent): refresh documentation (#9898)
* docs(coding-agent): improve getting started documentation

* docs(coding-agent): correct getting started details

* docs(coding-agent): clarify SDK entry point

* docs(coding-agent): restructure guides and references

* docs(coding-agent): improve getting started guides

* docs(coding-agent): refresh integration guides

* docs(coding-agent): improve terminal and CLI guides

* docs(coding-agent): refresh customisation guides

* docs(coding-agent): clarify project trust terminology

* docs(coding-agent): simplify customisation guidance

* docs(coding-agent): improve runtime and reference guidance

* Fix settings reference

* feat(coding-agent): add Crowdin documentation sync

* docs(coding-agent): separate CLI and slash command references

* docs(coding-agent): correct compaction reference

* docs(coding-agent): streamline package documentation

* docs(coding-agent): split RPC reference documentation

* Update configuration docs

* Shorten config docs

* docs(coding-agent): refine configuration references

* docs(coding-agent): streamline settings reference

* docs(coding-agent): clarify configuration reference

* docs(coding-agent): clarify project trust exception

* docs(coding-agent): simplify keybindings reference

* docs(coding-agent): remove Crowdin integration

* docs(coding-agent): turn themes reference into guide

* docs(coding-agent): consolidate model and authentication docs

* docs(tui): require Component.invalidate() (fixes #9358)

* docs(coding-agent): document offline catalog behavior (fixes #8684)

* docs(coding-agent): preserve established documentation routes

* docs(coding-agent): reorganize documentation navigation

* docs(coding-agent): correct audited behavior

Clarify provider, session, local-model, Termux, TUI, SDK, debug, and extension behavior. Simplify the documentation audit to report only clear user-visible contradictions.

* docs(coding-agent): fix broken documentation links
2026-09-22 16:48:19 +02:00
Armin Ronacher
aef5fc429b
fix(coding-agent): keep prompt and tool state across context handlers (#9846)
Since 0.86 the prompt and tool declarations live in transcript system
messages, so a context handler that filters or slices messages could drop
them. After extension-driven compaction this sent requests without built-in
tools and made Codex emit raw tool-call text.

context handlers now see the conversation only. An unchanged list keeps the
transcript as is; a changed list gets the replayed prompt sections and tool
declarations as one leading system message. Handler-added system messages
are kept after it.

Add context_with_system, which runs after every context handler on the full
transcript and sends its result verbatim, for extensions that need to edit
system messages per request. Dropping the leading system message is reported
as an extension error.

closes #9789, closes #9822
2026-09-21 17:14:22 +02:00
Mario Zechner
466db0fecd feat: add canonical session context boundaries
Make SessionManager projections authoritative for provider requests, add append-only context edits and actionable turn boundaries, and preserve existing queue scheduling during continuation and recovery.
2026-09-21 16:59:20 +02:00
Armin Ronacher
f5c946480c feat(ai,coding-agent): add image input limits (closes #9631) 2026-09-20 22:59:16 +02:00
Alexey Zaytsev
b73412a378
feat(ai,coding-agent): add Meta provider with Muse subscription OAuth (#9096)
Device authorization flow against auth.meta.com mints a Model API key via the Muse Code key-mint endpoint. Identity token stored as refresh, minted key as access; daily re-mint via the standard OAuth scheduler. Identity is non-renewable (no refresh grant), so mint 401/403 directs to /login meta. Models sourced from models.dev; default muse-spark-1.3.
2026-09-20 11:13:43 +02:00
Armin Ronacher
c596d09d9c
feat(coding-agent): add prompt cache warming (#9668) 2026-09-19 21:18:15 +02:00
Armin Ronacher
4d38031fbd feat(ai): ship Radius model catalog 2026-09-19 19:23:31 +02:00
Armin Ronacher
3c75b27479 feat(coding-agent): add bug reporting 2026-09-19 17:55:49 +02:00
Ramiz Wachtler
46c9de402b
feat(coding-agent): add event handler unsubscribe (#9630) 2026-09-17 21:44:26 +02:00
Armin Ronacher
16292398af fix(coding-agent): send forced system prompts without recording them
Remove SystemMessage.replace. A prompt forced from before_agent_start is a rendering
of the current prompt for the run, not conversation state: persisting it as a
replacing system message wrote the full prompt and tool list on every change,
lost the structured sections while forced, and disabled mid-conversation system
messages for the rest of the session once a replacement existed.

The transcript now always records section patches. AgentSession wraps
transformContext and, when a forced prompt is active, collapses the system
messages into one head carrying the forced text and the current tools. Providers
receive the same request as before; nothing is persisted and the projection ends
with the run.

The evals harness validated the without_docs variant from the transcript, which
relied on the persisted replacement. Its transform extension now records the
prompt it forced and validates that instead.
2026-09-17 20:02:23 +02:00
Armin Ronacher
e4c75a7322 fix(coding-agent): replace the system prompt when a handler forces it
Add SystemMessage.replace: replaying a system message with the flag discards the
accumulated prompt content, sections, and tools before applying it, and providers
collapse the transcript into one leading system message whenever a later message
replaces it.

A forced prompt from before_agent_start is opaque, so it is persisted as a replace
message holding the text in content with no sections (the agent loop fills in the
full tool set). Leaving force mode persists another replace message with the
structured sections. Previously the forced prompt became a preamble section patch,
so models with native mid-conversation system messages kept the original prompt
as their leading system prompt and received the forced one as a later update.
2026-09-16 23:35:01 +02:00
Christian Klotz
509ee2bd0b
fix(coding-agent): fail closed on user bash hook errors (#9662)
* fix(coding-agent): fail closed on user bash hook errors

Prevent failed execution-routing hooks from falling back to the local shell.

Fixes #9068

* fix(coding-agent): validate user bash hook results

* docs(coding-agent): clarify user bash result semantics

* docs(coding-agent): streamline user bash semantics

* fix(coding-agent): strengthen user bash regressions

* docs(coding-agent): clarify user bash breaking change
2026-09-16 17:21:17 +01:00
Armin Ronacher
9e05370b29
Mid conversation system messages (#9548)
This change makes system prompt text and tool changes part of the transcript rather than silently rewriting its starting conditions. This lets Pi record when instructions changed or tools became available, restore that state after resuming or navigating branches, and preserve cached prompt prefixes where the upstream supports it.
2026-09-16 15:54:07 +02:00
David Brailovsky
b03a367a4f feat(coding-agent): allow configuring Anthropic fallback models
Allow models.json overrides to replace or disable server-side fallback metadata.

Fixes #9294
2026-09-16 10:50:24 +02:00
Vegard Stikbakke
d92eb8d4b1 feat(ai): enable Fireworks Messages deferred tool loading 2026-09-10 21:18:35 +02:00