> This page is for Server SDKs.

> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes.

# SemanticGate

> A yes/no question about the call that must pass before a SWAIG function runs.

[define-tool]: /docs/server-sdks/reference/python/agents/agent-base/define-tool

[tool-decorator]: /docs/server-sdks/reference/python/agents/agent-base#tool

[datamap-gate]: /docs/server-sdks/reference/python/agents/data-map/gate

[functionresult]: /docs/server-sdks/reference/python/agents/function-result

[set-semantic-state]: /docs/server-sdks/reference/python/agents/function-result/set-semantic-state

[set-semantic-gates]: /docs/server-sdks/reference/python/agents/agent-base/set-semantic-gates

[swml-gates]: /docs/swml/reference/calling/ai/swaig/functions/gates

[semantic-gates-guide]: /docs/platform/ai/semantic-gates

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()`][define-tool] or the
[`@tool` decorator][tool-decorator], or with [`DataMap.gate()`][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()`][set-semantic-state] instead of asking for it.

> **Info**
>
> Gates map to the SWML [gate object][swml-gates]. For how to write questions and
> pick thresholds, see the [semantic gates guide][semantic-gates-guide]. Call-wide
> settings are on [`set_semantic_gates()`][set-semantic-gates].

> **Note**
>
> 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`** `str` — required

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`** `float` — required

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`][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 | None` — default: 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 | None` — default: None

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

---

**`false_means`** `str | None` — default: None

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

---

**`visual_input`** `bool | int | None` — default: 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

#### [to_dict](/docs/server-sdks/reference/python/agents/semantic-gate/to-dict)

Return the gate as the dictionary sent in the function definition.

## Examples

```python {6-16,20-21}
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()
```