Adds support for Amazon Bedrock with Claude models including:
- Full streaming support via Converse API
- Reasoning/thinking support for Claude models
- Cross-region inference model ID handling
- Multiple AWS credential sources (profile, IAM keys, API keys)
- Image support in messages and tool results
- Unicode surrogate sanitization
Also adds 'Adding a New Provider' documentation to AGENTS.md and README.
Co-authored-by: nickchan2 <nickchan2@users.noreply.github.com>
Uses @anthropic-ai/sandbox-runtime to enforce filesystem and network
restrictions on bash commands (sandbox-exec on macOS, bubblewrap on Linux).
Features:
- Per-project config via .pi/sandbox.json
- Global config via ~/.pi/agent/sandbox.json
- Enabled by default with sensible defaults
- --no-sandbox flag to disable
- /sandbox command to view current config
When running with tsx in dev mode, jiti loads extensions in a separate
module cache. This caused the theme to be undefined in jiti's copy of
theme.ts since initTheme() was only called on tsx's copy.
Using globalThis with Symbol.for() ensures all module instances share
the same theme, regardless of which loader created them.
When running from source with tsx, the jiti aliases pointed to .js files
that don't exist (only .ts files exist). This caused jiti to fall back to
different module resolution, loading a separate instance of theme.ts where
initTheme() was never called, resulting in undefined theme.
Now checks if .js exists and falls back to .ts for dev mode compatibility.
Prevents undefined theme when extensions call ctx.ui.custom() in edge cases
where module resolution could cause the theme variable to be accessed before
initTheme() is called.
Breaking change: pi.getAllTools() now returns Array<{ name, description }>
instead of string[]. Extensions needing just names can use .map(t => t.name).
Removes redundant getToolInfo() method added in original PR.
Fixes#647
- Add SessionInfoEntry type for session metadata
- Add /name <name> command to set session display name
- Add pi.setSessionName() and pi.getSessionName() extension API
- Session selector shows name (in warning color) instead of first message when set
- Session name included in fuzzy search
- /session command displays name when set
closes#650
Claude models accessed through Google Cloud Code Assist API require
explicit id fields in both functionCall and functionResponse parts.
Without these IDs, the API returns 'tool_use.id: Field required' error.
Add requiresToolCallId() helper to centralize the Claude model detection
and include IDs in both tool call and tool result message conversions.
* Avoid cross-provider thought signatures
* Fix Google thought signature replay
Filter thought signatures to same provider with base64 validation and rename the transform helper for clarity.
- Renamed from /models to /scoped-models
- Changes are now session-only by default (Ctrl+S to persist to settings)
- Added search with fuzzy filtering
- Hotkeys: Enter toggle, Ctrl+A enable all, Ctrl+X clear all, Ctrl+P toggle provider
- Ctrl+C clears search (or exits if empty), Escape exits
- Enabled models shown at top of list
- No checkmarks when all models enabled (no scope)
- First toggle when unscoped clears all and selects that model
- Uses current session thinking level instead of settings default
- Reads from session state first (preserves session-only changes across /scoped-models invocations)
Builds on #626
- /resume and --resume now toggle between Current Folder and All sessions with Tab
- SessionManager.list() and listAll() are now async with optional progress callback
- Shows loading progress (e.g. Loading 5/42) while scanning sessions
- SessionInfo.cwd field shows session working directory in All view
- Lazy loading: All sessions only loaded when user presses Tab
closes#619
Co-authored-by: Thomas Mustier <mustierthomas@gmail.com>
Git uses atomic writes (temp file + rename) which changes the inode.
fs.watch on a file stops working after the inode changes.
Now watches the directory containing HEAD and filters for HEAD changes.
The 100ms timeout was causing Kitty protocol detection to fail when the
terminal response was delayed (e.g., due to event loop blocking during
startup). This resulted in shift+enter not working in some scenarios.
Changes:
- Remove timeout-based Kitty detection, process input immediately
- Detect Kitty response in stdinBuffer output (handles split data)
- Add modifyOtherKeys fallback for terminals without Kitty support
(matches xterm format \x1b[27;modifier;keycode~)
- New /models command with toggle UI for each available model
- Changes persist to enabledModels in settings.json
- Updates take effect immediately for Ctrl+P cycling
- Store thoughtSignature on text blocks during streaming (all 3 providers)
- Replay textSignature as thoughtSignature in convertMessages
- Remove redundant conditional since retainThoughtSignature handles undefined
Per Google docs, text part signatures are optional but recommended for
high-quality reasoning in multi-turn conversations.