intellicrack.ui.confirmation_dialog

Tool confirmation dialog for Intellicrack.

This module provides a dialog for confirming tool calls before execution, allowing users to review and approve or deny potentially destructive operations.

A remembered answer is keyed by (tool_name, function_name, generation). The generation is what makes the answer honest for an externally-sourced tool: a third-party server can change what a tool does between one turn and the next, so an answer given about the old definition must not silently carry over to the new one. Bridge tools ship with the application and carry no generation, so their answers are keyed on the pair alone exactly as before.

Only an answer that carries a generation may be kept always. A persisted answer without one could never be invalidated, so for a bridge tool the longest an answer lasts is the rest of the session.

class ToolConfirmationDialog[source]

Bases: QDialog

Dialog for confirming tool calls.

Displays the tool name, function, originating source, and arguments for user review before executing potentially destructive operations.

Emits decision_made(approved: bool, remember_similar: bool) when the user accepts or rejects the call. Callers may connect to this signal to react to the decision instead of polling properties after exec().

The user chooses how long their answer applies: just this once, for the rest of the session, or always. A session answer is cached at class scope; an always answer is written to the installed approval store and survives a restart. Either way the key carries the tool’s generation, so a server that changes its tool definitions invalidates what was remembered about the old ones. Subsequent dialog instances for a remembered key short-circuit via exec(): they replay the cached decision through decision_made and finish immediately without presenting UI.

__init__(call, parent=None, *, generation=None, source_label=None)[source]

Initialize the ToolConfirmationDialog with the given tool call.

Parameters:
  • call (ToolCall) – The tool call to confirm.

  • parent (QWidget | None) – Parent widget.

  • generation (str | None) – Digest of the source’s current tool definitions, for an externally-sourced tool. None for a bridge tool.

  • source_label (str | None) – Human-readable origin of the tool, e.g. "MCP server 'files'". None for a bridge tool.

Return type:

None

classmethod set_approval_store(store)[source]

Install the store that persists always answers.

Until one is installed the dialog does not offer always at all, rather than offering it and quietly downgrading the answer to a session-scoped one.

Parameters:

store (ApprovalStore | None) – The store to write persistent answers to, or None to remove the current one.

Return type:

None

classmethod release_approval_store(store)[source]

Remove an installed store, unless another has replaced it since.

Parameters:

store (ApprovalStore) – The store its owner is withdrawing.

Return type:

None

classmethod remembered_decision(call, generation=None)[source]

Return the remembered decision for call, if any.

The session cache is consulted first, then the persistent store.

Parameters:
  • call (ToolCall) – The tool call to look up.

  • generation (str | None) – Digest of the source’s current tool definitions, or None for a bridge tool.

Returns:

True for remembered approval, False for remembered denial, or None when no decision is cached for the (tool_name, function_name, generation) triple.

Return type:

bool | None

classmethod can_remember_always(generation)[source]

Report whether an answer about a tool may be kept across restarts.

Parameters:

generation (str | None) – Digest of the source’s current tool definitions, or None for a bridge tool.

Returns:

True only when a persistent store is installed and the tool has a generation that a change would invalidate.

Return type:

bool

classmethod session_decisions()[source]

List every answer remembered for the rest of this session.

Returns:

(tool_name, function_name, generation, approved) for each answer, sorted.

Return type:

list[tuple[str, str, str | None, bool]]

classmethod forget_decision(tool_name, function_name, generation)[source]

Forget one remembered answer, for this session and for good.

Parameters:
  • tool_name (str) – The tool namespace the answer was about.

  • function_name (str) – The function the answer was about.

  • generation (str | None) – The generation it was recorded under, or None for a bridge tool.

Returns:

True when anything was forgotten.

Return type:

bool

classmethod clear_remembered_decisions()[source]

Clear all session-remembered decisions.

Intended for end-of-session teardown and test isolation. Persistent always answers are left alone, which is what makes them persistent.

Return type:

None

classmethod clear_decisions_for_source(namespace)[source]

Forget every decision remembered for one tool source.

Called when a source’s tool definitions change, so an answer given about the previous definitions is never replayed against the new ones.

Parameters:

namespace (str) – The source’s tool namespace, e.g. mcp-files.

Return type:

None

classmethod store_decision(call, *, approved, generation=None, scope=ApprovalScope.SESSION)[source]

Persist a remembered decision for the requested duration.

Parameters:
  • call (ToolCall) – The tool call whose decision is being remembered.

  • approved (bool) – True if the user approved, False if denied.

  • generation (str | None) – Digest of the source’s current tool definitions, or None for a bridge tool.

  • scope (ApprovalScope) – How long the answer applies. ONCE records nothing.

Return type:

None

property approved: bool

Whether the call was approved.

Returns:

True if user approved, False otherwise.

Return type:

bool

property remember_similar: bool

Whether to remember the choice for similar operations.

Returns:

True if the chosen scope outlives this single call.

Return type:

bool

property scope: ApprovalScope

How long the user’s answer applies.

Returns:

The scope the user selected.

Return type:

ApprovalScope

exec()[source]

Show the dialog modally, honoring any remembered decision.

If the user previously approved or denied this (tool_name, function_name, generation) triple with a scope that outlives the call, no UI is shown: the cached decision is replayed via the decision_made signal and the dialog finishes immediately with the same accepted/rejected result code as a normal execution.

Returns:

QDialog.DialogCode.Accepted on approval, otherwise QDialog.DialogCode.Rejected.

Return type:

int

set_remember_similar(*, value)[source]

Set the session-scope option programmatically.

Parameters:

value (bool) – True to remember the answer for this session, False to apply it to this call only.

Return type:

None

set_scope(scope)[source]

Select an approval scope programmatically.

Parameters:

scope (ApprovalScope) – The scope to select. ALWAYS is ignored when no persistent store is installed, or for a bridge tool whose answer nothing could ever invalidate.

Return type:

None

make_decision(*, approved)[source]

Apply an approve/deny decision and emit the corresponding signal.

This is the single entry point used by both the Approve and Deny button slots. It captures the selected scope, persists the answer for that scope, emits decision_made, and finalises the dialog with accept() or reject().

Parameters:

approved (bool) – True when the user approved the call, False when the user denied it.

Return type:

None