Skip to navigation
Agents

SemanticGate

View as MarkdownOpen in Claude

A semantic gate is a yes/no question about the call that must pass before a SWAIG function runs. Attach gates with gates= on define_tool() or the @tool decorator, or with DataMap.gate(). A function takes 1 to 8 gates. A decision model checks all of them together right before the function would run. If any gate fails, the function doesn’t run, and the AI gets the on_fail output of the first failing gate in list order.

The decision model reads conversation (the recent dialogue), semantic_state (the call’s global_data.semantic_state, or {}), and proposed_function (the function’s name, description, and the arguments the AI is calling it with), plus visual_input (the caller’s newest video frames) when a gate sets visual_input. Name what each question is about with those names in backticks. They label what the decision model reads; nothing is substituted. The decision model reads literally and doesn’t do arithmetic or compare dates, so put a computed result in the state with set_semantic_state() instead of asking for it.

Gates map to the SWML gate object. For how to write questions and pick thresholds, see the semantic gates guide. Call-wide settings are on set_semantic_gates().

The SDK checks gates when the tool is defined and raises ValueError for anything the platform would refuse. That includes gates on these function names: startup_hook, hangup_hook, check_for_input, end_call, hangup, check_time, wait_for_user, wait_seconds, adjust_response_latency, next_step, change_context, gather_submit, get_visual_input, get_ideal_strategy, pause_conversation.

Parameters

question
strRequired

The yes/no question, at most 8 KB (UTF-8). ${...} variables from the call’s global data are expanded when the gate is checked; @{...} functions are not.

threshold
floatRequired

Above 0 and at most 1. The gate passes when the decision model’s probability of “yes” is at or above this value.

on_fail
str | FunctionResult | dict[str, Any]Required

What the AI gets when this is the first gate that fails, at most 8 KB. A string is the response text. A FunctionResult contributes its response, actions, and post_process. A dict is used as written, in the data_map output shape (response, optional action). Say that the function didn’t run: ValueError is raised when there’s no response. Actions run as written, without ${...} expansion. Realtime (speech-to-speech) agents don’t use tool_prompt, so put everything in tool_result for them.

id
str | NoneDefaults to None

Keyword-only. 1 to 64 letters, digits, or underscores, unique within the function. Defaults to gate_1, gate_2, and so on, by position.

true_means
str | NoneDefaults to None

Keyword-only. What “yes” means, at most 2 KB. Sent as criteria.true.

false_means
str | NoneDefaults to None

Keyword-only. What “no” means, at most 2 KB. Sent as criteria.false.

visual_input
bool | int | NoneDefaults to None

Keyword-only. How many of the caller’s newest video frames the decision model sees with this gate, as visual_input: True is 1, False or 0 is none, or a whole number up to 5. Every gate on a function sees as many frames as the gate that asks for the most. If the call has no video frame to show, the gate fails without being asked. Omitted by default. Requires SDK 3.7.1 or later.

Methods

Examples

from signalwire import AgentBase, FunctionResult, SemanticGate
agent = AgentBase(name="account-agent", route="/account")
agent.set_prompt_text("You help callers manage their account.")
explicit_request = SemanticGate(
"Has the caller explicitly asked to cancel their account in `conversation`?",
threshold=0.95,
on_fail=FunctionResult(
tool_result="cancel_account was not run.",
tool_prompt="Ask the caller to confirm that they want to cancel.",
),
id="explicit_request",
true_means="The caller says they want to cancel.",
false_means="The caller asked about cancelling, or said something else.",
)
@agent.tool(
description="Cancel the caller's account",
gates=[explicit_request],
gate_fillers={"en-US": ["One moment."]},
)
def cancel_account(args, raw_data):
return FunctionResult("The account is cancelled. Tell the caller.")
agent.serve()