Repository navigation
Conversation
runTurn read the session's mode once per prompt, so a switch made while the prompt was running was accepted but ignored: later tool calls kept the old mode's approval rules until the whole prompt ended. Moving from yolo or auto-accept back to normal still let the next commands and file edits run without a permission prompt. Read session.developmentMode live instead: for the tools offered on each model request, for the plan-mode fallback, and for every approval. A call the model already returned that the new mode no longer offers (e.g. an edit after switching to plan) is refused rather than run. A call that is already running is not interrupted. Closes Nano-Collective#1857
nc-review: comments — 1 important, 1 nit@addyCooks — a few things worth a look, none blocking. The PR correctly fixes the reported bug: 🟠 important · A refused tool call is never announced to the client when the model returned it on its own (the common one-call-per-response case). The new refusal block sits before the if (announcedBatch) {
await emitToolCallUpdate(session, conn, toolCall, 'failed', reason);
}
toolResults.push({...});
continue;
The batch path happens to work because the batch announcement loop ( The new spec Fix: emit the notification for the non-batch case as well — either move the refusal block below the ⚪ nit · The plan-mode if (
session.developmentMode === 'plan' && // live
!wrotePlan &&
availableNames.includes('write_plan') && // request-time
cleanedContent.trim().length > 0
) {
This errs in the safe direction (it does not write a plan artifact in a mode that does not offer one), and the next turn recovers because the request is then built in plan mode. It is only inconsistent rather than dangerous, so it is not worth blocking on — but computing both sides from the live mode (e.g. 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
…or the write_plan fallback
Description
A
session/set_modesent while a prompt was running was accepted ({}returned) but ignored:runTurnread the mode once at the start of the prompt, so later tool calls in the same prompt kept the old mode's availability and approval rules. Switching fromyoloorauto-acceptback tonormalstill let the next commands and file edits run without a permission prompt.session.developmentModeis now read live:write_planfallback;A call the model had already returned that the new mode no longer offers (for example an edit after switching to
plan) is refused withError: <tool> is not available in <mode> modeinstead of being run or put to the user. This only applies when the mode changed during the request. A call that is already running is not interrupted, and a permission request already pending stays valid for that call; the new mode applies from the next call.The TUI already behaves this way (it reads the mode from a ref on every tool call); this brings ACP in line.
Closes #1857
Type of Change
Changeset
pnpm changeset) describing this change for the changelogTesting
Automated Tests
.spec.ts/tsxfilespnpm test:allcompletes successfully)Manual Testing
Checklist