Features & Routing¶
Routing (who gets notified) and Ttl (what happens if nobody responds in
time) are mandatory for every HITL — raise_interrupt fails validation
unless both resolve to a concrete value.
They resolve through a 3-scope cascade, lowest to highest priority: init()
→ @hitl_node → the raise_interrupt/raise_* call site. Each scope can set
channels, users, secondary_channels, secondary_users, ttl_seconds,
on_expiry, default_response, or pass a full features=RunFeatures(...);
a higher scope's value overrides a lower one field-by-field (e.g. a node can
override ttl_seconds while still inheriting channels from init()). Pass
hgateway_sdk.CLEAR_FEATURE for a field to explicitly unset whatever a lower
scope set, instead of inheriting it.
hgateway_sdk.RunFeatures
dataclass
¶
RunFeatures(routing: Optional[Routing] = None, ttl: Optional[Ttl] = None)
Container for optional per-interrupt feature overrides.
Pass an instance of this class as the features argument to
raise_interrupt() to control how the gateway handles the interrupt
(routing, deadline, escalation, etc.). __post_init__ runs
validate_features immediately so mis-configurations are caught at
construction time, not at wire time.
Usage example::
import hgateway_sdk as hg
features = hg.RunFeatures(
routing=hg.Routing(
primary=hg.Recipients(channels=["#ops-approvals"]),
),
ttl=hg.Ttl(seconds=1800, on_expiry="default-response",
default_response={"decision": "reject"}),
)
hg.raise_interrupt("deploy_approval", content, features=features)
Attributes:
| Name | Type | Description |
|---|---|---|
routing |
Optional[Routing]
|
Optional |
ttl |
Optional[Ttl]
|
Optional |
hgateway_sdk.Routing
dataclass
¶
Routing(primary: Recipients, secondary: Optional[Recipients] = None)
Bases: Feature
Feature that controls where a HITL interrupt is delivered.
Routing specifies a primary group of recipients (required) and an
optional secondary group used for escalation when a Ttl feature
with on_expiry=OnExpiry.FORWARD_TO_SECONDARY is also active.
Usage example::
import hgateway_sdk as hg
features = hg.RunFeatures(
routing=hg.Routing(
primary=hg.Recipients(channels=["#approvals"]),
secondary=hg.Recipients(users=["manager@example.com"]),
)
)
hg.raise_interrupt("deploy_approval", content, features=features)
Attributes:
| Name | Type | Description |
|---|---|---|
primary |
Recipients
|
The first-line |
secondary |
Optional[Recipients]
|
Optional fallback |
hgateway_sdk.Recipients
dataclass
¶
Recipients(channels: list[str] = list(), users: list[str] = list())
A group of notification targets (channels and/or named users).
Used as the primary and optional secondary targets inside a
Routing feature. At least one of channels or users must be
non-empty for a Recipients instance to be considered valid by
Routing.validate().
Usage example (nested inside Routing)::
import hgateway_sdk as hg
routing = hg.Routing(
primary=hg.Recipients(channels=["#ops-approvals"], users=["alice@example.com"]),
secondary=hg.Recipients(channels=["#escalations"]),
)
features = hg.RunFeatures(routing=routing)
Attributes:
| Name | Type | Description |
|---|---|---|
channels |
list[str]
|
List of notification channel identifiers (e.g. Slack channel names or IDs) to which the interrupt is delivered. Defaults to an empty list. |
users |
list[str]
|
List of individual user identifiers (e.g. email addresses or user IDs) to whom the interrupt is delivered. Defaults to an empty list. |
hgateway_sdk.Ttl
dataclass
¶
Ttl(seconds: int, on_expiry: OnExpiry, default_response: Optional[dict] = None)
Bases: Feature
Response deadline for a HITL interrupt; both seconds and on_expiry are mandatory.
on_expiry=DEFAULT_RESPONSE requires default_response to be set — validation raises otherwise. on_expiry=FORWARD_TO_SECONDARY requires a Routing feature with a non-empty secondary.
hgateway_sdk.Feature ¶
Bases: ABC
A run-overridable feature. Owns its own (intra-feature) validation, and may emit cross-feature rules that constrain other features.
hgateway_sdk.CrossFeatureRule ¶
Bases: ABC
A constraint one feature imposes on another. Owned by (returned from cross_rules() of) the trigger feature, and checked against the full feature set.
hgateway_sdk.HitlSpec
dataclass
¶
HitlSpec(hitl_key: str, content: HitlContent, runtime: RuntimeContext, features: RunFeatures = RunFeatures(), spec_version: str = constants.SPEC_VERSION)
Complete wire payload sent to the HITL gateway for a single interrupt.
The SDK serialises this dataclass to JSON and POSTs it to the gateway's
register endpoint. All fields are assembled automatically by the client
from the arguments passed to raise_interrupt().
Attributes:
| Name | Type | Description |
|---|---|---|
hitl_key |
str
|
Logical, stable name of this interrupt point in the agent
graph (e.g. Treat this as immutable once an interrupt point is in use. It is
part of the interrupt's dedup identity
( |
content |
HitlContent
|
The content object describing what the operator should do —
one of the 10 concrete |
runtime |
RuntimeContext
|
|
features |
RunFeatures
|
Optional |
spec_version |
str
|
Protocol version string embedded in every payload so the
gateway can handle schema evolution. Defaults to the SDK constant
|