Commit graph

159 commits

Author SHA1 Message Date
Sviatoslav Abakumov
5c61d6bc92
fix(coding-agent): queue messages during branch summarization (#1803)
Messages submitted while a branch summary was being generated were
processed immediately instead of being queued. This happened because
isCompacting only checked compaction abort controllers, not the branch
summary abort controller.

Include _branchSummaryAbortController in the isCompacting getter so all
existing guards (message queueing, reload blocking) also apply during
branch summarization.
2026-03-04 08:55:30 +01:00
Mario Zechner
6b4b920425 fix(coding-agent): stop overflow auto-compaction cascades
fixes #1319
2026-03-03 17:19:42 +01:00
Mario Zechner
8903299074 fix(coding-agent): close retry wait race across queued events (from #1726) 2026-03-02 23:20:16 +01:00
Mario Zechner
8d4a49487a fix(coding-agent): add tool promptGuidelines support fixes #1720 2026-03-02 22:50:08 +01:00
Mario Zechner
bc2fa8d6d0 fix(coding-agent): support dynamic tool registration and tool prompt snippets closes #1720 2026-03-02 22:32:07 +01:00
Mario Zechner
dfc779faab fix(coding-agent): serialize session event handling to preserve message order (fixes #1717) 2026-03-02 20:48:22 +01:00
Sumeet Agarwal
ff5148e7cc
feat(extensions): forward message and tool execution events to extensions (#1375)
The extension system currently only forwards agent_start, agent_end,
turn_start, and turn_end events. This means extensions cannot access
streaming text (token-by-token), message lifecycle, or tool execution
progress — all of which are available to internal subscribers.

This adds forwarding for the remaining 6 agent event types:
- message_start, message_update, message_end
- tool_execution_start, tool_execution_update, tool_execution_end

These follow the exact same pattern as the existing forwarded events:
new interfaces in types.ts, exports in index.ts, and else-if blocks
in _emitExtensionEvent(). The new types are included in ExtensionEvent
and automatically flow through RunnerEmitEvent (they're not in the
exclusion list).

This enables extensions to build real-time UIs, streaming WebSocket
bridges, and other integrations that need fine-grained event access.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-02-12 20:30:46 +01:00
Mario Zechner
7eb969ddb1 fix(coding-agent): show unknown context usage after compaction, fix multi-compaction boundary
After compaction, context token count is unknown until the next LLM
response. Instead of showing stale pre-compaction values or heuristic
estimates, the footer now shows ?/200k.

ContextUsage.tokens and ContextUsage.percent are now number | null
(breaking change). Removed usageTokens, trailingTokens, lastUsageIndex
from ContextUsage (internal details).

Also fixed _checkCompaction() using .find() (first compaction) instead
of getLatestCompactionEntry() (latest), which caused incorrect overflow
detection with multiple compactions.

Closes #1382
2026-02-12 18:35:09 +01:00
Mario Zechner
afb7e5ed4c feat(coding-agent): show tool input schema in /export HTML
Include tool parameter names, types, descriptions in a collapsible
section under each tool in the export HTML. Also adds parameters to
pi.getAllTools() return value.

closes #1407, closes #1416
2026-02-08 22:58:46 +01:00
Mario Zechner
b050c582a1 fix(agent,coding-agent): resume queued messages after auto-compaction 2026-02-06 11:36:19 +01:00
Aliou Diallo
b315abf998 fix(coding-agent): forward images through steer/followUp during streaming
prompt() computed currentImages but never passed them to _queueSteer()
or _queueFollowUp() in the streaming branch. Both methods only accepted
text and built content as [{ type: 'text', text }], dropping images.

- _queueSteer/_queueFollowUp now accept optional ImageContent[]
- streaming branch in prompt() passes currentImages through
- public steer()/followUp() accept and forward optional images
- RPC types, handler, and client updated for steer/follow_up images
- rpc.md: document images on steer/follow_up, fix ImageContent examples
2026-02-05 02:37:42 +01:00
Mario Zechner
fcfbc82ec2 fix(coding-agent): reload global settings fixes #1241 2026-02-04 14:14:52 +01:00
Mario Zechner
13ac63c3cd fix(coding-agent): fork writes to new session file, not parent (fixes #1242)
- Store previousSessionFile before creating branched session
- Update sessionFile after writing new branch file
- Pass parentSession when forking from first message
- Add --local to git config in tests to prevent repo escape
2026-02-04 13:22:43 +01:00
Mario Zechner
e1e4e593c0 fix(coding-agent): persist thinking level defaults 2026-02-03 17:17:38 +01:00
Mario Zechner
e54dff7efb fix(coding-agent): rename SlashCommandSource "template" to "prompt" for consistency
BREAKING CHANGE: RPC get_commands response and SlashCommandSource type
now use "prompt" instead of "template" to match the rest of the codebase.
2026-02-03 12:27:45 +01:00
warren
2613754c47 feat(coding-agent): add ExtensionAPI.getCommands() 2026-02-03 12:18:52 +01:00
Michael Renner
f7c03ef6a2
fix(coding-agent): handle scoped models after logout (#1194) 2026-02-02 18:05:15 +01:00
Mario Zechner
3b8d0a8921 feat(coding-agent): add resources_discover hook 2026-02-01 02:20:35 +01:00
Mario Zechner
030a61d88c feat: add maxDelayMs setting to cap server-requested retry delays
When a provider (e.g., Google Gemini CLI) requests a retry delay longer
than maxDelayMs (default: 60s), the request fails immediately with an
informative error instead of waiting silently for hours.

The error is then handled by agent-level auto-retry, which shows the
delay to the user and allows aborting with Escape.

- Add maxRetryDelayMs to StreamOptions (packages/ai)
- Add maxRetryDelayMs to AgentOptions (packages/agent)
- Add retry.maxDelayMs to settings (packages/coding-agent)
- Update _isRetryableError to match 'retry delay' errors

fixes #1123
2026-02-01 00:50:41 +01:00
Mario Zechner
7eae0a7d30 fix(coding-agent): make setThinkingLevel idempotent
switchSession() was appending spurious thinking_level_change entries
to session log on resume because setThinkingLevel() unconditionally
persisted. Now only persists if the level actually changes.

fixes #1118
2026-02-01 00:14:49 +01:00
Mario Zechner
99281e5913 feat(coding-agent): add ctx.getSystemPrompt() to extension context
Adds a method to access the effective system prompt (after any per-turn
extension modifications) from the extension context.

Implementation:
- Add systemPrompt getter to AgentSession reading from agent.state.systemPrompt
- Wire getSystemPrompt through ExtensionContextActions to ExtensionRunner
- Add getSystemPrompt to interactive-mode's shortcut context
- Update docs with ctx.getSystemPrompt() section
- Add system-prompt-header.ts example
- Add example to docs reference table

Closes #1098
2026-01-30 17:44:25 +01:00
Daniel Nouri
e20583aac8
feat(coding-agent): add set_session_name RPC command (#1075)
- Add set_session_name command with empty name validation
- Expose sessionName in get_state response
- Add setSessionName() to AgentSession and RpcClient
- Document in docs/rpc.md
2026-01-30 01:41:58 +01:00
Mario Zechner
4f004adefa fix(coding-agent): reset retry counter after each successful LLM response
Previously, within a single tool-use turn, rate limit retries would
accumulate across separate LLM calls. For example, if each of 3 tool
calls hit a 429 and retried once, the counter would show '3/3' and fail
even though each individual retry succeeded.

Now the counter resets immediately when a successful (non-error)
assistant message arrives, so each LLM call gets a fresh set of retries.

Fixes #1019
2026-01-29 01:12:29 +01:00
Mario Zechner
5ef79459dc Closes #1041, incorrect .md file name in warning messages. 2026-01-29 00:16:50 +01:00
Mario Zechner
f86e3c3103 fix(coding-agent): sync agent state after newSession setup callback
Move setup callback handling from interactive/rpc modes into AgentSession.newSession().
After setup() runs, sync agent state via replaceMessages() so the LLM has context
and the UI renders the messages properly.

fixes #968
2026-01-26 22:25:09 +01:00
Mario Zechner
88f184f433 fix: point auth error messages to docs/authentication.md 2026-01-25 23:55:00 +01:00
Mario Zechner
177c694406 feat: custom provider support with streamSimple
- Add resetApiProviders() to clear and re-register built-in providers
- Add createAssistantMessageEventStream() factory for extensions
- Add streamSimple support in ProviderConfig for custom API implementations
- Call resetApiProviders() on /reload to clean up extension providers
- Add custom-provider.md documentation
- Add custom-provider.ts example with full Anthropic implementation
- Update extensions.md with streamSimple config option
2026-01-24 23:15:11 +01:00
Mario Zechner
f9eb190ef9 refactor(coding-agent): simplify AgentSession 2026-01-24 01:38:58 +01:00
Mario Zechner
50c8323590 feat(coding-agent): package deduplication and collision detection
- Package deduplication: same package in global+project, project wins
- Collision detection for skills, prompts, and themes with ResourceCollision type
- PathMetadata tracking with parent directory lookup for file paths
- Display improvements: section headers, sorted groups, accent colors for packages
- pi list shows full paths below package names
- Extension loader discovers files in directories without index.ts
- In-memory SettingsManager properly tracks project settings

fixes #645
2026-01-24 00:35:19 +01:00
Mario Zechner
7868b25a2b feat(coding-agent): make skill invocation messages collapsible
- Add ParsedSkillBlock interface and parseSkillBlock() function
- Change skill expansion to use XML-style <skill> tags
- Add SkillInvocationMessageComponent for collapsible display
- Collapsed: single line with skill name and expand hint
- User message rendered separately after skill block

Fixes #894
2026-01-22 22:29:24 +01:00
Mario Zechner
f54e71999f fix(coding-agent): simplify extension error listener to single instance
There's only ever one bindings instance per session, so the Set/Array
approach was unnecessary. Changed from Set<ExtensionErrorListener> to
optional single listener.
2026-01-22 22:03:17 +01:00
Mario Zechner
9b84857b83 fix(coding-agent): add 'terminated' to retryable error patterns
Codex API can send 'terminated' error mid-stream, which should be
retried like other transient server errors.
2026-01-22 21:32:56 +01:00
Mario Zechner
b846a4bfcf feat(coding-agent): ResourceLoader, package management, and /reload command (#645)
- Add ResourceLoader interface and DefaultResourceLoader implementation
- Add PackageManager for npm/git extension sources with install/remove/update
- Add session.reload() and session.bindExtensions() APIs
- Add /reload command in interactive mode
- Add CLI flags: --skill, --theme, --prompt-template, --no-themes, --no-prompt-templates
- Add pi install/remove/update commands for extension management
- Refactor settings.json to use arrays for skills, prompts, themes
- Remove legacy SkillsSettings source flags and filters
- Update SDK examples and documentation for ResourceLoader pattern
- Add theme registration and loadThemeFromPath for dynamic themes
- Add getShellEnv to include bin dir in PATH for bash commands
2026-01-22 13:49:38 +01:00
Dave
d6bb66a494
fix(coding-agent): prevent crash on OAuth authentication failure (#849)
Detect OAuth authentication failures (expired credentials, offline) and provide helpful error message instead of crashing with generic 'No API key found' error.

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-01-19 15:59:45 +01:00
Mario Zechner
9d3f8117a4 feat(coding-agent): add extension compaction helpers 2026-01-17 11:40:39 +01:00
Mario Zechner
20f5fcc79d fix(coding-agent): handle auto-compaction failures gracefully
When auto-compaction fails (e.g., quota exceeded), emit the error via
the auto_compaction_end event instead of throwing. The UI now displays
the error message, allowing users to take action (switch models, wait
for quota reset, etc.) instead of crashing.

fixes #792
2026-01-16 23:13:26 +01:00
Mario Zechner
fbb74bb29e fix(ai): filter empty error assistant messages in transformMessages
When 429/500 errors occur during tool execution, empty assistant messages
with stopReason='error' get persisted. These break the tool_use -> tool_result
chain for Claude/Gemini APIs.

Added centralized filtering in transformMessages to skip assistant messages
with empty content and no tool calls. Provider-level filters remain for
defense-in-depth.
2026-01-16 22:35:50 +01:00
Armin Ronacher
6b6707f30c Improve navigateTree API 2026-01-16 21:37:25 +01:00
Mario Zechner
c08801e4c5 Add retry logic to OpenAI Codex provider
Fixes #733
2026-01-16 03:15:59 +01:00
Mario Zechner
b4a05cbcab Move skill command handling to AgentSession, update docs
- Skill commands (/skill:name) now expanded in AgentSession instead of
  interactive mode, enabling them in RPC and print modes
- Input event can now intercept /skill:name before expansion
- Updated extensions.md with clearer input event docs and processing order
- Updated rpc.md: hook -> extension terminology, added skill expansion mentions
- Added PR attribution to changelog entries for #761
2026-01-16 03:01:08 +01:00
Nico Bailon
3e5d91f287
feat(coding-agent): add input event for extension input interception (#761)
* feat(coding-agent): add input event for extension input interception

Extensions can now intercept, transform, or handle user input before the
agent processes it. Three result types: continue (pass through), transform
(modify text/images), handled (respond without LLM). Handlers chain
transforms and short-circuit on handled. Source field identifies origin.

* fix: make source public, use if/else over ternary

* fix: remove response field, extension handles own UI
2026-01-16 02:41:56 +01:00
Aliou Diallo
0c6ac46646
feat(coding-agent): Custom tool export rendering in export (#702)
* coding-agent: add ANSI-to-HTML converter for export

* coding-agent: add getToolDefinition method to ExtensionRunner

* coding-agent: add tool HTML renderer factory for custom tools

* coding-agent: add custom tool pre-rendering to HTML export

* coding-agent: render pre-rendered custom tools in HTML export

* coding-agent: integrate tool renderer in exportToHtml
2026-01-16 00:32:31 +01:00
Mario Zechner
fb6d464edc Fix auto-retry for fetch failed errors 2026-01-14 12:00:55 +01:00
Danila Poyarkov
9e4ae98358
Improve Google Cloud Code Assist error handling (#665)
* Improve Cloud Code Assist error messages

- Extract just the message from verbose JSON error responses
- Extract cause from generic 'fetch failed' errors for better diagnostics

* Make 'other side closed' network error retryable

* Make 'other side closed' network error retryable
2026-01-13 00:41:20 +01:00
Mario Zechner
1367a76ee8 Change getAllTools() to return ToolInfo[] instead of string[]
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
2026-01-12 17:18:43 +01:00
Mario Zechner
df3f5f41c0 Rename /branch command to /fork
- RPC: branch -> fork, get_branch_messages -> get_fork_messages
- SDK: branch() -> fork(), getBranchMessages() -> getForkMessages()
- AgentSession: branch() -> fork(), getUserMessagesForBranching() -> getUserMessagesForForking()
- Extension events: session_before_branch -> session_before_fork, session_branch -> session_fork
- Settings: doubleEscapeAction 'branch' -> 'fork'

fixes #641
2026-01-11 23:12:31 +01:00
Carlos Gutierrez
49acd8e648 Add /models command for enabling/disabling Ctrl+P model cycling
- 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
2026-01-11 19:36:36 +01:00
Marc Krenn
c41714662a feat(coding-agent): add model_select extension hook
Fires when model changes via setModel(), cycleModel(), or session restore.
Includes source field ("set" | "cycle" | "restore") and previous model.
2026-01-11 18:12:09 +01:00
Mario Zechner
af2d8509e6 Fix --no-skills flag not preventing skills from loading
The --no-skills flag set options.skills = [] in main.ts, but the
interactive mode UI would rediscover skills anyway because it called
loadSkills() directly instead of using the already-loaded skills.

Changes:
- Add AgentSession.skills and AgentSession.skillWarnings properties
- discoverSkills() now returns { skills, warnings } instead of Skill[]
- Interactive mode uses session.skills instead of calling loadSkills()
- Update SDK docs and examples for new return type

Fixes #577
2026-01-08 23:41:54 +01:00
Mario Zechner
121823c74d feat(coding-agent): add user_bash event and theme API extensions
- user_bash event for intercepting ! and !! commands (#528)
- Extensions can return { operations } or { result } to redirect/replace
- executeBashWithOperations() for custom BashOperations execution
- session.recordBashResult() for extensions handling bash themselves
- Theme API: getAllThemes(), getTheme(), setTheme() on ctx.ui
- mac-system-theme.ts example: sync with macOS dark/light mode
- Updated ssh.ts to use user_bash event
2026-01-08 21:50:56 +01:00