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.
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.
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>
A new session was only written to disk once the first assistant message
existed. If pi exited during the first turn (Ctrl+C twice while streaming,
or the process was killed), the user's prompt was lost and the session
never appeared in /resume.
The file is now created as soon as the session has a user or assistant
message. A session with only setup entries (model, thinking level) still
stays in memory, so starting pi and quitting without chatting leaves no
file. Forking uses the same rule through a shared helper, so the two paths
cannot drift apart and write the header twice (#1672).
closes#10000
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
Strict tool schemas make models send null for omitted optional fields.
The read renderer only treated undefined as missing, so full-file reads
rendered as "path:1".
fixes#9996
Temporary git extensions (-e git:...@ref) were cached in a folder keyed
only by host and repo path. After changing the pinned ref, pi reused the
old checkout without refreshing it and kept loading the first downloaded
commit. Include the ref in the temporary folder hash so each ref gets
its own checkout. Unpinned sources keep their existing folder.
closes#9982
Separate conversation content from instructions and replace prefix/suffix wording with continuation-oriented summarization guidance.
Hopefully this avoids the refusals.
Fixes#9652
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
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.
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.
Fall back to the latest safe assistant boundary when trailing tool results exceed the retained-token budget, allowing older history to compact before the next provider request.
Closes#9740
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.
Map signal termination to conventional nonzero exit codes and reject null exit codes from custom shell operations while preserving partial output.
fixes#9577
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.
* 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
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.