gates
functions[].gates attaches semantic gates to a SWAIG function. A semantic gate is a
yes/no question about the call that must come out yes before the function runs. When the AI calls
the function, a decision model reads the conversation and answers each of the function’s questions
first. If every gate passes, the function runs as usual. If any gate fails, the function doesn’t run,
and the AI gets the response you wrote for that gate in on_fail instead.
For when to use gates and how to write good questions, see the semantic gates guide.
Properties
functions[].gates
An array of 1 to 8 gates. Every gate is checked at once, and all must pass. When more than one fails, the first failing gate in the array supplies the on_fail response. A key not listed below is an error, not an ignored setting.
gates[].question
The yes/no question, at most 8 KB. Name what it’s about with the names of the inputs the decision model reads, in backticks: `conversation`, `semantic_state`, `proposed_function`, or `visual_input` (see What a gate reads). ${...} variables from global_data are expanded when the check runs; @{...} functions are not run.
gates[].threshold
The gate passes when the probability that the answer is yes is at or above this value. Above 0 and at most 1. Higher is stricter; use 0.9 or above for actions that are hard to undo.
gates[].on_fail
What the AI gets instead of the function’s result when this is the first gate that fails. Shaped like a data_map output, at most 8 KB.
on_fail.response
What the function returns to the AI. A non-empty string, or an object with tool_result (required, non-empty), what the AI sees as the function’s result, and tool_prompt (optional), an instruction placed right after it. Write it so the AI knows the action didn’t happen. Realtime (speech-to-speech) agents don’t use tool_prompt; on those, put everything the AI needs in tool_result.
on_fail.action
Actions to run, as a function’s response would. Must be an array, even for one action. The actions run as written: ${...} variables in them are not expanded, though a SWML action resolves the variables in its own document when it runs.
on_fail.post_process
Lets the AI take its turn before the actions run.
gates[].id
A name for the gate, reported in the call records: 1 to 64 letters, digits, or underscores, unique within the function.
gates[].criteria
What counts as yes and what counts as no, for the near misses the question alone leaves open. Set true, false, or both, each a non-empty string of at most 2 KB.
gates[].visual_input
How many of the caller’s newest video frames the gate looks at: true is 1, a whole number from 0 to 5, and false or 0 is none. Frames are taken when the check starts, at most one per second and none older than 8 seconds. A function’s gates are checked together, so each 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, so a gate with visual_input always fails when the post-prompt AI calls the function after the call.
Sizes are bytes of UTF-8 text. If any gate breaks a rule on this page, the function isn’t added to
the agent at all, and the rest of the agent works without it. A calling.error event with
error_reason invalid_semantic_gate names the function and the reason. For the rest of that ai
method, no other definition of that name and no MCP tool with that name is used either, so the
function can never run without its gates.
When a function name is defined more than once, the first definition wins, gates included. Functions
from includes load before SWAIG.functions, so an included definition of a name wins over an
inline one.
What a gate reads
The decision model reads these inputs, under these names, and nothing else:
The backticked names in a question aren’t variables, and nothing replaces them. They tell the
decision model which input to read, so that “in conversation” means the conversation it was
given, not the ordinary word. What a gate reads is captured when the check starts: something the
caller says while it runs doesn’t change the result.
When a function is blocked
A blocked function doesn’t run: your webhook isn’t called, the data_map doesn’t run, and nothing
is sent to an MCP server. The function’s wait_file doesn’t play, and the call doesn’t use up its
active count. If the AI keeps making the same blocked call, it’s refused on the third try.
When the check can’t be completed, because it timed out, the decision model failed or gave no usable
answer, or the AI’s arguments were missing or weren’t valid JSON, the function is blocked too, and
the AI gets There is a temporary problem and this could not be completed right now. Every outcome
other than a pass, a fail, or gates turned off also fires a calling.error event:
error_reason is the check’s outcome, and evaluation_id matches the record in the call’s
swaig_log.
Each checked call adds a semantic_gates record to its swaig_log entry, and the
post-prompt callback adds semantic_gates_blocked and a semantic_gates tally for
the call. When the post-prompt AI was blocked and wrote no summary, post_prompt_data reads
“<function> was not run.” for each blocked call.
Where gates apply
Gates work on webhook functions, data_map functions, and functions returned by includes. A
function you also serve from an MCP server keeps its gates.
Functions the post-prompt AI calls after the call ends are gated too.
These names can’t have gates: 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, and
pause_conversation. Built-in functions and MCP tools you haven’t defined yourself are never gated.
The amazon_bedrock and
ai_sidecar methods don’t check gates.
Examples
Require an explicit request
Check a recorded fact and the caller’s video
A gate can ask about what your application stored in global_data.semantic_state, and another can
look at the caller’s camera.