Gates

Preconditions a tool call has to satisfy before it runs.

A gate is a precondition on a tool call. Until the gate is marked, the tool returns a message instead of running.

from agentino.safety.gates import GateRule, GateManager

rules = [GateRule(
    gate="invoice_listed",
    tools=["set_invoice_status"],
    message="Run list_invoices first so you've actually seen the IDs.",
)]

When the loop reaches set_invoice_status and invoice_listed has not been marked, the model gets the message back as the tool result. It reads as feedback, so the model does the prerequisite and tries again.

Why not just say so in the prompt

Because the prompt is advice and the gate is a rule. A model that has been told "list the invoices first" will usually do it, and the times it does not are exactly the times you find out by shipping a wrong status change to a customer.

Gates cost one line of config and remove the failure mode.

Every field

gateThe name that must be marked before the tools may run
toolsWhich tools this rule applies to
messageWhat the model gets back when the gate is not marked. It reads as feedback, so the model does the prerequisite and retries
conditionAnother gate. The rule is only enforced once that one is marked

condition is how a rule becomes conditional rather than absolute. A rule that requires a security check before sending mail need not apply to internal recipients — mark an external_recipient gate and make the rule conditional on it, and the check is enforced exactly where it matters.

A tool marks a gate when it completes:

gm = GateManager(rules)
gm.mark("invoice_listed")     # list_invoices calls this when it returns

Confirmation gates

The other common shape is a gate that requires a human:

gates:
  rules:
    - gate: confirm
      tools: [raise_purchase_order]
      message: "Raise this purchase order?"

The tool call is held, the user is asked, and the call proceeds only on a yes. Use this for anything that spends money, sends a message outside the company, or is hard to reverse.