Skip to content

nodestep.middleware.interrupt

Tool approvals: ToolInterruptMiddleware, its rules and argument predicates.

See Interrupts.

Middleware

ToolInterruptMiddleware

ToolInterruptMiddleware(*, rules)

Pause tool calls that match a rule until a person answers.

Subclass of Middleware.

  • Interrupt id: "approve_" plus the tool call id, with each character other than a letter, digit, _ or - written as . and two hex digits per UTF-8 byte ("fc:1" becomes "approve_fc.3a1").
  • Payload: a ToolInterrupt.
  • Answer: True or ToolDecision(action="approve") runs the call; ToolDecision(action="edit", arguments=...) runs it with those keys replacing the call's; anything else denies. A dict works like a ToolDecision.
Parameters
ruleslist[InterruptRule]

Which tool calls need approval.

Methods

before_tool(ctx)

Ask for approval and apply the reviewer's decision.

before_tool(ctx) -> Replacement | None

Returns
Replacement or None

The edited arguments, or None to run the call as it is.

Raises
ValueError

If the call needs approval and has no tool_call_id.

ToolDeniedError

If the reviewer denies the call.

Rules and answers

InterruptRule

InterruptRule(*, tool, match=None)

Tool name (or "*") plus an optional argument predicate.

Attributes
toolstr

Name of the tool to review, or "*" for every tool; a Tool is turned into its name.

matchCallable[[Any], bool] | None

Called with the arguments; the call needs approval when it returns True or raises. None reviews every call.

ToolInterrupt

ToolInterrupt(*, kind='tool_interrupt', tool_name, tool_call_id=None, arguments={})

Interrupt payload asking a reviewer to approve a tool call.

Attributes
kindstr

Always "tool_interrupt", to tell the payload apart.

tool_namestr
tool_call_idstr | None

Id of the call under review.

argumentsdict[str, Any]

Arguments the tool would run with.

ToolDecision

ToolDecision(*, action, arguments=None, message=None)

A reviewer's answer to a tool approval.

Attributes
actionLiteral['approve', 'deny', 'edit']

Run the call, refuse it, or run it with arguments.

argumentsdict[str, Any] | None

With action="edit", keys that replace the call's arguments.

messagestr | None

Reason given to ToolDeniedError when the call is denied.

should_interrupt

should_interrupt(rules, tool, raw_input=None) -> bool

Check whether any rule requires approval for a tool call.

A predicate that raises counts as a match.

Parameters
rulesIterable[InterruptRule]
toolTool | str

The tool, or its name.

raw_inputAny

Tool arguments passed to the rule predicates.

Argument predicates

gt

gt(field, value) -> Callable[[Any], bool]

Predicate that matches when argument field > value.

Parameters
fieldstr

Argument name.

valueAny

A number, compared with number arguments but not bool; any other value needs an argument of its type.

Returns
callable

Raises LookupError, TypeError or ValueError for a missing, mistyped or NaN argument, which should_interrupt counts as a match.

ge

ge(field, value) -> Callable[[Any], bool]

Predicate that matches when argument field >= value.

Parameters
fieldstr

Argument name.

valueAny

A number, compared with number arguments but not bool; any other value needs an argument of its type.

Returns
callable

Raises LookupError, TypeError or ValueError for a missing, mistyped or NaN argument, which should_interrupt counts as a match.

lt

lt(field, value) -> Callable[[Any], bool]

Predicate that matches when argument field < value.

Parameters
fieldstr

Argument name.

valueAny

A number, compared with number arguments but not bool; any other value needs an argument of its type.

Returns
callable

Raises LookupError, TypeError or ValueError for a missing, mistyped or NaN argument, which should_interrupt counts as a match.

le

le(field, value) -> Callable[[Any], bool]

Predicate that matches when argument field <= value.

Parameters
fieldstr

Argument name.

valueAny

A number, compared with number arguments but not bool; any other value needs an argument of its type.

Returns
callable

Raises LookupError, TypeError or ValueError for a missing, mistyped or NaN argument, which should_interrupt counts as a match.

eq

eq(field, value) -> Callable[[Any], bool]

Predicate that matches when argument field == value.

Parameters
fieldstr

Argument name.

valueAny

A number, compared with number arguments but not bool; any other value needs an argument of its type.

Returns
callable

Raises LookupError, TypeError or ValueError for a missing, mistyped or NaN argument, which should_interrupt counts as a match.

matches

matches(field, pattern) -> Callable[[Any], bool]

Predicate that matches a string argument against a regular expression.

Parameters
fieldstr

Argument name.

patternstr

Regular expression, searched with re.search.

Returns
callable

Raises LookupError or TypeError for a missing or non-string argument, which should_interrupt counts as a match.

all_fields

all_fields(**patterns) -> Callable[[Any], bool]

Predicate that matches when every given string argument matches its pattern.

Parameters
**patternsstr

Regular expressions keyed by argument name.

Returns
callable

Checks every argument, and raises like matches for a missing or non-string one.

Raises
ValueError

If no pattern is given.

any_field

any_field(**patterns) -> Callable[[Any], bool]

Predicate that matches when at least one string argument matches its pattern.

Parameters
**patternsstr

Regular expressions keyed by argument name.

Returns
callable

Checks every argument, and raises like matches for a missing or non-string one.

Raises
ValueError

If no pattern is given.