Problem
The system prompt for a request is generated once, from the settings at that moment, when the request is built (getSystemPrompt is awaited once in src/core/task/Task.ts). Tool-call validation during the streaming response does not reuse that moment: for every tool call it re-reads current settings. In src/core/assistant-message/presentAssistantMessage.ts, each tool call fetches fresh state (const state = await cline.providerRef.deref()?.getState() at presentAssistantMessage.ts:346), destructures disabledTools from it (presentAssistantMessage.ts:347), and converts it into the validation requirements passed to validateToolUse.
Observed in version v3.82.1
Consequence
Generating once and validating live makes the two moments diverge whenever settings change mid-request. If disabledTools gains an entry after the prompt was built, validation rejects a tool the prompt advertised, and the model gets a rejection for following its instructions. If an entry is removed mid-request, validation accepts a tool the prompt never advertised. Either way the effective tool policy differs between the prompt and the validator within a single request.
Desired behavior
Runtime validation during an in-flight request should consume the same policy snapshot the prompt for that request was generated from. This is a new property: on version v3.82.1 both layers read live state, and no request-scoped snapshot exists to share.
Acceptance criteria
- The request's policy snapshot is threaded through the streaming presentation chain as a required parameter, with no fallback re-read of live settings (terminal contract: callers that do not supply it fail fast rather than silently reverting to live reads).
- A
disabledTools change landing mid-request cannot change validation behavior for the in-flight request; it takes effect for the next request.
- Tests cover both directions with a mid-stream settings mutation: rejecting a tool the prompt advertised, and accepting a tool the prompt omitted.
Problem
The system prompt for a request is generated once, from the settings at that moment, when the request is built (
getSystemPromptis awaited once insrc/core/task/Task.ts). Tool-call validation during the streaming response does not reuse that moment: for every tool call it re-reads current settings. Insrc/core/assistant-message/presentAssistantMessage.ts, each tool call fetches fresh state (const state = await cline.providerRef.deref()?.getState()atpresentAssistantMessage.ts:346), destructuresdisabledToolsfrom it (presentAssistantMessage.ts:347), and converts it into the validation requirements passed tovalidateToolUse.Observed in version v3.82.1
Consequence
Generating once and validating live makes the two moments diverge whenever settings change mid-request. If
disabledToolsgains an entry after the prompt was built, validation rejects a tool the prompt advertised, and the model gets a rejection for following its instructions. If an entry is removed mid-request, validation accepts a tool the prompt never advertised. Either way the effective tool policy differs between the prompt and the validator within a single request.Desired behavior
Runtime validation during an in-flight request should consume the same policy snapshot the prompt for that request was generated from. This is a new property: on version v3.82.1 both layers read live state, and no request-scoped snapshot exists to share.
Acceptance criteria
disabledToolschange landing mid-request cannot change validation behavior for the in-flight request; it takes effect for the next request.