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
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.
* add usage info to branch summary entries
* add usage to compaction entries
* allow custom tools to report llm usage in tool results
* allow observing and patching usage in tool_result hooks
* agent-harness: save usage in entries
for compaction, branch summaries and tool results
Move provider auth and OAuth flows onto pi-ai Models, compose models.json and extension overlays through ModelRuntime, and retain ModelRegistry as an extension compatibility facade.
Use visibleWidth/truncateToWidth for footer path and stats truncation so wide Unicode text cannot overflow terminal width.
Add regression tests for wide session/model/provider names and document the fix in changelog.
closes#1833