Repository navigation
Description
Summary
A direct chat with a sub-agent instance cannot be stopped from the page. The instance surface exposes no cancel, and the global stop cannot reach one: it sends turn.cancel without a target, which the server documents as missing every direct turn. The backend can already do it -- turn.cancel accepts a target and cancels a direct lane correctly when one is passed.
Steps to reproduce
- Open a session, create or open a sub-agent instance, and send it something long-running from the instance composer.
- Look for a way to stop it, on the instance surface and with the global stop (the go button's other half, or Esc).
Expected behavior
A turn a person started can be stopped by that person. The main agent's turn can be, and a direct turn is started from the same composer with the same turn.send.
Actual behavior
Nothing stops it. The two halves of the same conversation are asymmetric:
| send | stop | |
|---|---|---|
| main agent | turn.send { session_key } |
turn.cancel { session_key } -- works |
| direct instance chat | turn.send { session_key, target: { agent, handle } } (ui-web/src/live/230-tabs.js:65) |
no call exists |
The instance surface in 230-tabs.js offers instanceHistory, instanceForget, instanceSend, instanceCreate, instanceMode, instanceSetMode, instanceSetModel. There is no cancel; stop, cancel, busy and cancellable do not appear in that file at all.
The global stop cannot substitute, for two separate reasons:
// ui-web/src/live/080-overrides.js:561
DS.composer.stop = function () {
if (!turn.cancellable()) return;
const owner = sessionCurrent();
...
rpc.call('turn.cancel', { session_key: owner })- No
targetis passed, and the server states what that costs: "targetnames which lane to cancel and must be resolved the same wayturn.sendresolves the lane it binds, or the lookup misses every direct turn: those are registered underdirect_lane(...), never under the bare session key." (raven/rpc/methods/turn.py:650) - The early
returnis silent, so on the path where the guard does not hold the reader gets no feedback at all -- the same nothing as a stop that ran and found nothing to stop.
The backend is not the gap
turn.cancel with a target works. Cancelling two live direct turns over /rpc today:
turn.cancel {"session_key": "<session>", "target": {"agent": "Raven-Design", "handle": "<handle>"}}
-> {"cancelled": true}
Both instances stopped, and a subsequent turn.send to the same handles started clean turns. So this is the page not wiring a capability that is already there and already shaped for it.
Environment
macOS, raven from the repo working tree, web UI at current main.
Note on scope
Whether the control belongs on the instance surface, or the global stop should resolve the lane the composer is currently addressing, is a design call for whoever owns the composer -- the second would also fix the silent return for free, since a direct turn would then be cancellable. Filing the defect rather than the fix.
Activity
fix(ui-web): let a direct sub-agent chat be stopped from its own surf…