feat(agent): add /btw one-off side-question command#2502
feat(agent): add /btw one-off side-question command#2502lxowalle wants to merge 15 commits intosipeed:mainfrom
Conversation
fix(agent): route /btw replies through the active agent Reset /btw priority replies against the routed agent instead of the default one so busy-turn responses are not suppressed in multi-agent flows. Also stop onboarding from copying legacy workspace template files so the generated workspace matches the current structured layout and checks stay green. fix(agent): suppress duplicate replies across agents fix(agent): isolate /btw replies from busy-turn sends
| media = append([]string(nil), opts.Media...) | ||
| activeSkills = activeSkillNames(agent, *opts) | ||
|
|
||
| if !opts.NoHistory { |
There was a problem hiding this comment.
/btw loses the live session context.
This implementation only reassembles the session summary and then calls BuildMessages with nil history, so the /btw request does not see the current conversation state unless it has already been compacted into the summary.
That creates a real behavior gap for the feature as described. A side question such as “what did we decide above?” or “can you expand on the previous point?” may fail during an active turn because the recent turns are still in history, not in the summary. In contrast, the normal turn path includes both history and summary, so /btw is now operating on materially less context than the main conversation.
I think /btw needs to preserve the same read context as the active session while only skipping persistence of the /btw exchange itself. Otherwise this will produce inconsistent and confusing answers in exactly the situations where users are most likely to use the command.
| } | ||
| } | ||
|
|
||
| callProvider := func(ctx context.Context, provider providers.LLMProvider, model string) (*providers.LLMResponse, error) { |
There was a problem hiding this comment.
/btw bypasses the normal tool and hook pipeline.
This path calls provider.Chat directly with nil tools, which means /btw no longer behaves like a normal agent turn. Side questions cannot use the agent’s configured tools, and any logic enforced in the standard turn pipeline (for example LLM hooks, policy checks, request mutation, or approval gates) is skipped entirely.
That is a much larger semantic change than “do not persist /btw in session history”. It effectively introduces a second execution model for the same agent, with different capabilities and different enforcement points. Even if the no-history behavior is intentional, bypassing tools and hooks is likely to create hard-to-debug inconsistencies between a normal prompt and the same prompt sent through /btw.
Unless /btw is explicitly intended to be a stripped-down raw-model query, I think this should be routed through the normal agent execution path with a “do not persist” option, rather than calling the provider directly.
There was a problem hiding this comment.
/btw no need to call the tool; it's currently just for quick Q&A.
| // Handle priority commands (e.g. /btw) immediately instead of queueing them. | ||
| if handled, response := al.tryHandlePriorityCommand(ctx, msg); handled { | ||
| if response != "" { | ||
| al.bus.PublishOutbound(ctx, bus.OutboundMessage{ |
There was a problem hiding this comment.
Immediate /btw replies drop reply metadata.
The fast path publishes an outbound message with only Channel, ChatID, and Content. It does not preserve ReplyToMessageID or the normalized outbound context used by the regular response path.
On reply-capable channels, that can cause the /btw response to be posted as a detached top-level message instead of replying to the triggering message/thread. This looks like a regression in delivery behavior even if the text content itself is correct.
Keep /btw aligned with the standard LLM hook pipeline so side questions do not bypass request and response interception. Clarify across docs that /btw remains an immediate, no-tool query that does not persist session history.
📝 Description
Summary
/btw <question>built-in command for one-off side questions/btwthrough a priority command path so it can bypass the normal queued turn flow and reply immediately/btwrequests and replies out of persisted session history while preserving routed agent/session metadata on immediate replies/btwWhy
This adds a lightweight way to ask a quick side question while another turn is busy, without appending the
/btwrequest or reply to the active session history.Behavior Notes
/btwis a temporary side-question message, not part of the main session turn flow./btwdoes not persist into the active session history./btwis independent from/use: pending skill overrides armed by/use <skill>apply to the next regular session message, not to/btw.Changes
/btwin the built-in command registry/btwcommand handler and runtime hook/btwas a priority command in the steering path/btwimmediately instead of enqueueing it behind the current turn/btwexchange out of persisted session history/btwrepliesTesting
/btwcommand handling🗣️ Type of Change
🤖 AI Code Generation
🔗 Related Issue
📚 Technical Context (Skip for Docs)
🧪 Test Environment
📸 Evidence (Optional)
Click to view Logs/Screenshots
☑️ Checklist