fix(13-08): declined actions never re-prompt + timeout chain covers the human wait
Two more on-device UAT findings: 1. Deny-retry loop: the model, told 'the user declined', simply called the tool again — each retry minted a fresh pending and re-opened the dialog (T-13-50 habituation, mechanized). ToolExecCtx now remembers declined actions for the turn, keyed by confirm::action_key — the same canonical (tool_name, validated_args) identity the nonce binds — and execute_tool refuses a re-ask before the gate, minting nothing. Regression test declined_action_never_reprompts_same_turn. 2. Timeout chain: rpcClient's 15s default aborted every confirmable turn client-side while the node kept the pending alive — the next turn then re-announced it (modal over and over) and every wait read as 'timed out'. assistant.chat now rides a 420s timeout; AIUI's bridge goes 180s→430s so the host's error path (which also expires the dialog) always fires first. Declined ToolResult text now also tells the model to stop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
44c864ac14
commit
2d1f09d8c8
@@ -278,14 +278,17 @@ export const archyBridge = {
|
||||
text,
|
||||
})
|
||||
|
||||
// Matches the node's ASSISTANT_HTTP_TIMEOUT (180s) — the assistant
|
||||
// loop's tool-calling round trip can legitimately take that long.
|
||||
// Must cover the node's WHOLE turn: multiple model round trips
|
||||
// (ASSISTANT_HTTP_TIMEOUT 180s each) plus the confirm gate's
|
||||
// human-speed wait (CONFIRM_TIMEOUT 300s). Kept just ABOVE the host
|
||||
// page's own assistant.chat RPC timeout (420s) so the host's error
|
||||
// path — which also expires the confirm dialog — fires first.
|
||||
setTimeout(() => {
|
||||
if (pendingRequests.has(id)) {
|
||||
pendingRequests.delete(id)
|
||||
reject(new Error('Chat request timed out'))
|
||||
}
|
||||
}, 180000)
|
||||
}, 430000)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user