roboto.domain.triggers#
Triggers: fire on platform events or a schedule, filter with a condition, dispatch targets.
A trigger pairs a firing source — a subscription to one or more platform events (fired
at most once per the subscription’s once_per) or a cron schedule — with an optional
condition over the firing’s variable namespace and one or more targets to run on a match.
The event catalog describes what each event type exposes — payload model, namespace
roots, supported once_per values — and drives both save-time validation and evaluation.
Conditions reuse the Condition wire format; target templates
reuse the roboto.templating {{...}} placeholder syntax.
roboto.domain.actions.Trigger is the legacy model of the same thing (one action,
causes/for_each), deprecated and kept only for existing code; it cannot read a
trigger the current model added capabilities to. Trigger here reads them all.
Submodules#
- roboto.domain.triggers.conditions
- roboto.domain.triggers.dispatch
- roboto.domain.triggers.dry_run
- roboto.domain.triggers.namespace
- roboto.domain.triggers.operations
- roboto.domain.triggers.record
- roboto.domain.triggers.samples
- roboto.domain.triggers.sources
- roboto.domain.triggers.targets
- roboto.domain.triggers.trigger
- roboto.domain.triggers.validation
Package Contents#
- class roboto.domain.triggers.ConditionLeafTrace(/, **data)#
Bases:
pydantic.BaseModelOne leaf of the trigger’s condition, with the actual value it saw.
- Parameters:
data (Any)
- actual: Any | None = None#
The value the event’s namespace resolved for
field;Nonewhen the field did not resolve (missing entity, missing key).
- comparator: roboto.query.Comparator#
The leaf’s comparator.
- expected: Any | None = None#
The value the condition compares against.
- field: str#
The condition field, as stored on the trigger.
- passed: bool#
Whether this leaf held for the event.
- class roboto.domain.triggers.ConditionMatcher(namespace, default_root)#
Evaluates a trigger condition tree against an event namespace.
Reuses the query
Conditioncomparators unchanged; only the value source differs. Each leaf routes to the namespace root its field targets and matches against that root’s record, so roots hydrate lazily on first reference. A root whose record is missing evaluates to a non-match, soNOT_EXISTSandIS_NULLnever match against an entity that was deleted before evaluation.- Parameters:
namespace (roboto.domain.triggers.namespace.EventNamespace)
default_root (str)
- matches(condition)#
Return whether
conditionholds for the event. ANonecondition always matches.- Parameters:
condition (Optional[roboto.query.ConditionType])
- Return type:
bool
- class roboto.domain.triggers.CreateTriggerRequest(/, **data)#
Bases:
pydantic.BaseModelRequest payload to create a trigger.
The server assigns identity and audit fields, and runs
TriggerValidatorover the cross-field rules (exposed roots,once_perlegality, target placeholders) before persisting.Triggered work runs as the organization’s actions service user; a trigger cannot run its targets as anyone else.
- Parameters:
data (Any)
- condition: roboto.query.ConditionType | None = None#
Optional predicate over the firing’s namespace.
- enabled: bool = True#
Whether the trigger should be active immediately after creation.
- fires_on: roboto.domain.triggers.sources.TriggerSource#
an event subscription or a schedule.
- Type:
What makes the trigger fire
- name: str = None#
Trigger name. Unique within the caller’s organization.
- targets: list[roboto.domain.triggers.targets.TriggerTargetSpec]#
What the trigger dispatches when it fires. At least one.
- class roboto.domain.triggers.DispatchSlot#
One target of one trigger at one dedup token: the unit a dispatch claims.
At most one dispatch ever occupies a slot. It is the dispatch table’s primary key and the vocabulary every dispatch port speaks.
- idempotency_token: str#
- target_id: str#
- trigger_id: str#
- class roboto.domain.triggers.DispatchSlotTrace(/, **data)#
Bases:
pydantic.BaseModelThe state of one target’s dispatch slot at the dry run’s idempotency token.
- Parameters:
data (Any)
- occupied: bool#
Whether a dispatch row occupies the slot (the trigger already fired here).
- result_ref: str | None = None#
What the occupying dispatch produced (invocation id, thread id, Slack ts).
- status: roboto.domain.triggers.dispatch.TriggerDispatchStatus | None = None#
The occupying dispatch’s status, when one exists.
- target_id: str#
The target within the trigger.
- class roboto.domain.triggers.EventNamespace(event, source, *, trigger=None, _records=None)#
Resolves dotted variable paths against a platform event.
The one namespace with three consumers: condition evaluation (whole records via
record()), target template substitution (single paths viaresolve(), satisfying theVariableResolverprotocol), and idempotency projections. Entity-backed roots hydrate through theNamespaceSourceat most once each and are cached for the namespace’s lifetime — includingNoneresults. Theenvelope,changed, andtagroots are served from the event itself and never touch the source;triggeris served from the bound trigger (seebound_to()) and is otherwise absent.- Parameters:
source (NamespaceSource)
trigger (Optional[roboto.domain.triggers.record.TriggerRecord])
_records (Optional[dict[str, Optional[Mapping[str, Any]]]])
- bound_to(trigger)#
A view of this namespace for one trigger, in which
trigger.*resolves.One namespace is shared across every trigger evaluated for an event so each entity hydrates once; the trigger being evaluated is per-trigger state, so it lives on a view rather than on the shared object. The view delegates every other root to the same hydration cache – reading
dataset.namethrough it and through the parent costs one fetch in total.- Parameters:
trigger (roboto.domain.triggers.record.TriggerRecord) – The trigger whose templates and condition are being evaluated.
- Return type:
- get(path)#
Return the value at dotted
path(e.g.dataset.metadata.vehicle_id), orNone.The first path segment names the root; the rest walk nested mappings. Any missing segment yields
None.- Parameters:
path (str)
- Return type:
Any
- record(root)#
Return the whole record for namespace
root, hydrating it at most once.- Parameters:
root (str) – Namespace root to fetch.
envelopeyields the envelope fields;changedyields the changeset’s put fields;tagyields{"added": [...], "removed": [...]}; any other root delegates to the cachedNamespaceSource.- Returns:
The record as a mapping, or
Nonewhen the source cannot resolve the root.- Return type:
Optional[Mapping[str, Any]]
- resolve(name)#
Return the string form of the value at
namefor template substitution, orNone.- Parameters:
name (str)
- Return type:
Optional[str]
- class roboto.domain.triggers.EventSubscription(/, **data)#
Bases:
_SourceBaseFire when any of the subscribed platform events occurs.
Carries
once_perbecause it only means something here: it names what the event is about that the trigger fires at most once for, and a schedule has no such subject.- Parameters:
data (Any)
- events: list[roboto.domain.platform_events.PlatformEventType]#
Event types the trigger subscribes to. At least one; a condition may only reference namespace roots exposed by every subscribed event.
- fires_for(event_type)#
Return whether an event of
event_typeis one this subscription fires for.- Parameters:
event_type (roboto.domain.platform_events.PlatformEventType)
- Return type:
bool
- once_per: roboto.domain.platform_events.OncePer#
the occurrence, or an entity the event names. Must be legal for every subscribed event type.
- Type:
What the trigger fires at most once per
- type: Literal[TriggerSourceType]#
Discriminator for
TriggerSource.
- class roboto.domain.triggers.InvokeActionTarget(/, **data)#
Bases:
_TargetSpecBaseStored configuration for invoking an action when a trigger fires.
Spec only — dispatch behavior lives server-side. String leaves of
parameter_values,required_inputs, andadditional_inputsmay contain{{...}}placeholders resolved against the event namespace at dispatch time.- Parameters:
data (Any)
- action: roboto.domain.actions.action_record.ActionReference#
The action to invoke.
ownerdefaults to the trigger’s org when omitted anddigestto the action’s latest version.
- additional_inputs: list[str] | None = None#
Optional extra file patterns passed as invocation inputs beyond the required ones.
- compute_requirement_overrides: roboto.domain.actions.action_record.ComputeRequirements | None = None#
Optional compute requirement overrides for the invocation.
- container_parameter_overrides: roboto.domain.actions.action_record.ContainerParameters | None = None#
Optional container parameter overrides for the invocation.
- invocation_input: roboto.domain.actions.invocation_record.InvocationInput | None = None#
Optional query-based input selection (files, topics, sessions) resolved when the invocation runs. The way a schedule-fired trigger names its inputs, since a schedule fires with no file subject; may also accompany an event-fired trigger’s patterns.
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- parameter_values: dict[str, Any] = None#
Parameter values passed to the action; string leaves may be templated.
- referenced_placeholders()#
Return every
{{name}}placeholder referenced by this target’s templated fields.- Return type:
set[str]
- required_inputs: list[str] = None#
File patterns (e.g.
**/*.bag) that gate dispatch on the firing event’s files, for file- and dataset-scoped events. May be empty for events with no file subject (e.g. invocation events).
- subject_types: ClassVar[frozenset[roboto.uri.RobotoUriType] | None]#
The action runs against the event’s dataset, and a file event names its dataset too.
- target_id: str#
Stable id of this target within its trigger. Part of the dispatch idempotency key: the target’s once-per history is kept under this id, so renaming it (or replacing it with an identical target under a new id) starts a fresh history and the target fires again for subjects the old id already fired for.
- timeout: int | None = None#
Optional invocation timeout override, in minutes.
- type: Literal[TriggerTargetType]#
Discriminator for
TriggerTargetSpec.
- upload_destination: roboto.domain.actions.invocation_record.InvocationUploadDestination | None = None#
Optional destination for the invocation’s output files.
- roboto.domain.triggers.MAX_TRIGGER_NAME_LENGTH = 256#
Maximum trigger name length.
- class roboto.domain.triggers.NamespaceSource#
Bases:
ProtocolLazily hydrates entity-backed namespace roots for an event.
- record_for_root(root, event)#
Load the entity for namespace
rootas a JSON-able mapping.- Parameters:
root (str) – The namespace root to hydrate (
"dataset","file","invocation","event", …). Never a delta or reserved root: the namespace servesenvelope,trigger,schedule,changedandtagitself.event (roboto.domain.platform_events.PlatformEvent) – The event whose subject identifies the entity to load.
- Returns:
The entity as a mapping, or
Nonewheneventcannot resolve it (no such root for this event type, or the entity was deleted between emit and evaluation).- Return type:
Optional[Mapping[str, Any]]
- class roboto.domain.triggers.PlatformEventSample(/, **data)#
Bases:
pydantic.BaseModelOne event type, dereferenced: the envelope, every root it exposes, and the template paths that resolve against them.
- Parameters:
data (Any)
- event: dict[str, Any]#
id, type, time, org, and payload.
- Type:
The event envelope as it would arrive
- event_type: roboto.domain.platform_events.PlatformEventType#
The event type this sample illustrates.
- namespace: dict[str, dict[str, Any]]#
Every namespace root a condition or template may reference for this event type, keyed by root name, with the full record under each. Always includes
envelopeandtrigger; the rest are the catalog’s exposed roots for the type.
- class roboto.domain.triggers.PlatformEventSamplesResponse(/, **data)#
Bases:
pydantic.BaseModelWire shape of
GET /v1/triggers/events/samples: one sample per platform event type.- Parameters:
data (Any)
- samples: dict[roboto.domain.platform_events.PlatformEventType, PlatformEventSample]#
- class roboto.domain.triggers.SampleNamespaceSource#
A
NamespaceSourcethat hydrates every root from the sample scenario.Serves each root the way a real firing does — including
actionas the invocation’s provenance anduploadas the bare transaction id — so a sample carries exactly the roots a trigger would see.- record_for_root(root, event)#
- Parameters:
root (str)
- Return type:
Optional[collections.abc.Mapping[str, Any]]
- class roboto.domain.triggers.Schedule(/, **data)#
Bases:
_SourceBaseFire on a cron schedule, in UTC.
Each scheduled minute fires the trigger once (
once_per='occurrence'over the schedule tick). A missed minute is skipped rather than replayed later, so a delayed schedule never floods targets with backdated firings. Cron expressions are evaluated in UTC; a schedule cannot name a time zone.- Parameters:
data (Any)
- cron: str#
A five-field cron expression (
minute hour day-of-month month day-of-week), evaluated in UTC — e.g.0 9 * * 1for 09:00 UTC every Monday.
- fires_for(event_type)#
Return whether
event_typeis the schedule occurrence this source fires for.- Parameters:
event_type (roboto.domain.platform_events.PlatformEventType)
- Return type:
bool
- property once_per: roboto.domain.platform_events.OncePer#
A schedule always fires once per scheduled minute.
- Return type:
- type: Literal[TriggerSourceType]#
Discriminator for
TriggerSource.
- class roboto.domain.triggers.SendSlackMessageTarget(/, **data)#
Bases:
_TargetSpecBaseStored configuration for posting a Slack message when a trigger fires.
Spec only — dispatch behavior lives server-side. The channel must be on the org’s Slack outbound allowlist at dispatch time.
- Parameters:
data (Any)
- channel_id: str#
Slack channel to post to.
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- referenced_placeholders()#
Return every
{{name}}placeholder referenced by this target’s templated text.- Return type:
set[str]
- target_id: str#
Stable id of this target within its trigger; part of the dispatch idempotency key.
- text: str#
Message body; may contain
{{...}}placeholders resolved against the event namespace.
- type: Literal[TriggerTargetType]#
Discriminator for
TriggerTargetSpec.
- class roboto.domain.triggers.StartAgentTarget(/, **data)#
Bases:
_TargetSpecBaseStored configuration for starting an agent thread when a trigger fires.
Spec only — dispatch behavior lives server-side. Each value in
valuesis a template resolved against the event namespace, then handed to the agent’s own variable resolution as a plain value.- Parameters:
data (Any)
- agent_id: str#
The agent definition to launch.
- analysis_scope: roboto.ai.core.AnalysisScope | None = None#
Optional analysis scope for the resulting thread.
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- referenced_placeholders()#
Return every
{{name}}placeholder referenced by this target’s templated values.- Return type:
set[str]
- target_id: str#
Stable id of this target within its trigger; part of the dispatch idempotency key.
- type: Literal[TriggerTargetType]#
Discriminator for
TriggerTargetSpec.
- values: dict[str, str] = None#
Agent variable name to a template string resolved against the event namespace.
- visibility: roboto.ai.agent_thread.record.ThreadVisibility#
Visibility of the resulting agent thread.
- roboto.domain.triggers.TRIGGER_NAME_PATTERN = '[\\w\\-]+'#
word characters and hyphens.
- Type:
Legal trigger names
- class roboto.domain.triggers.TargetAcceptanceTrace(/, **data)#
Bases:
pydantic.BaseModelOne target’s prefilter decision.
- Parameters:
data (Any)
- accepted: bool#
Whether the target’s
acceptsprefilter passed.
- reason: str | None = None#
Why the target declined, where determinable (e.g. which required-input pattern had no matching file).
Nonewhen accepted or when no finer reason is known.
- target_id: str#
The target within the trigger.
- target_type: roboto.domain.triggers.targets.TriggerTargetType#
Kind of target.
- class roboto.domain.triggers.Trigger(record, roboto_client=None)#
A trigger: a firing source (event subscriptions or a schedule), an optional condition, and targets.
Triggers created through the older
causes/for_eachAPI (roboto.domain.actions.Trigger) are listed and loaded here too, projected onto this shape and markedengine == "v1"; they accept a narrower set of edits (seeupdate()).Examples
Start an agent whenever a dataset gains a
readytag:>>> from roboto.domain.platform_events import OncePer, PlatformEventType >>> from roboto.domain.triggers import StartAgentTarget, Trigger >>> trigger = Trigger.create( ... name="analyze-ready-datasets", ... targets=[StartAgentTarget(target_id="analyze", agent_id="ag_abc123")], ... events=[PlatformEventType.DatasetTagAdded], ... once_per=OncePer.Occurrence, ... )
Post to Slack every Monday at 09:00 UTC:
>>> from roboto.domain.triggers import SendSlackMessageTarget >>> weekly = Trigger.create( ... name="weekly-status", ... targets=[SendSlackMessageTarget(target_id="post", channel_id="C0123", text="Weekly check-in")], ... schedule="0 9 * * 1", ... )
- Parameters:
roboto_client (Optional[roboto.http.RobotoClient])
- property condition: roboto.query.ConditionType | None#
- Return type:
Optional[roboto.query.ConditionType]
- classmethod create(name, targets, *, events=None, once_per=None, schedule=None, fires_on=None, condition=None, enabled=True, caller_org_id=None, roboto_client=None)#
Create a trigger in the caller’s org.
- Parameters:
name (str) – Trigger name, unique within the org.
targets (list[roboto.domain.triggers.targets.TriggerTargetSpec]) – What to dispatch on a match. At least one.
events (Optional[list[roboto.domain.platform_events.PlatformEventType]]) – Platform event types to subscribe to (with
once_per). At least one.once_per (Optional[roboto.domain.platform_events.OncePer]) – What the trigger fires at most once per; must be legal for every subscribed event.
schedule (Optional[str]) – A cron expression (UTC) to fire on instead of events.
fires_on (Optional[roboto.domain.triggers.sources.TriggerSource]) – The firing source itself, as an alternative to the
events/once_perorscheduleshorthands.condition (Optional[roboto.query.ConditionType]) – Optional predicate over the firing’s namespace.
enabled (bool) – Whether the trigger is active immediately.
caller_org_id (Optional[str]) – Org to create the trigger in. Defaults to the caller’s org.
roboto_client (Optional[roboto.http.RobotoClient]) – Roboto client instance. Uses the default if not provided.
- Returns:
The created trigger.
- Raises:
RobotoInvalidRequestException – A cross-field validation rule fails (e.g. the condition references a root not exposed by every subscribed event).
RobotoConflictException – The name is already taken in the org.
- Return type:
- delete()#
Delete this trigger. Idempotent.
- Return type:
None
- dispatches(limit=100)#
Yield this trigger’s dispatch history, newest first.
A dispatch is one attempt to run one target for one matched event; only matches are recorded, so an empty history means the trigger never fired.
- Parameters:
limit (int) – Page size for the underlying requests.
- Return type:
collections.abc.Generator[roboto.domain.triggers.dispatch.TriggerDispatchRecord, None, None]
- dry_run(event=None, dataset_id=None, file_id=None, invocation_id=None, session_id=None, event_id=None, event_type=None, scheduled_for=None)#
Ask “would this trigger fire?” without dispatching anything.
Provide either a full
eventor exactly one entity reference, from which the server synthesizes an event (event_typeoptionally picks which kind). A schedule-fired trigger takes no reference: passscheduled_forto pick the minute, or nothing for the schedule’s next occurrence. The response is the evaluator’s gate-by-gate trace: subscribed, enabled, condition (with per-leaf actual values), target prefilter, already fired.Examples
>>> trace = trigger.dry_run(dataset_id="ds_abc123") >>> print(trace.verdict)
- Parameters:
event (Optional[roboto.domain.platform_events.PlatformEvent])
dataset_id (Optional[str])
file_id (Optional[str])
invocation_id (Optional[str])
session_id (Optional[str])
event_id (Optional[str])
event_type (Optional[roboto.domain.platform_events.PlatformEventType])
scheduled_for (Optional[datetime.datetime])
- Return type:
- property enabled: bool#
- Return type:
bool
- property engine: str#
"v2", or"v1"for a trigger created through the oldercauses/for_eachAPI.- Type:
Which trigger shape this trigger was created in
- Return type:
str
- property events: List[roboto.domain.platform_events.PlatformEventType] | None#
The subscribed event types, or
Nonefor a schedule-fired trigger.- Return type:
Optional[List[roboto.domain.platform_events.PlatformEventType]]
- property fires_on: roboto.domain.triggers.sources.TriggerSource#
an event subscription or a schedule.
- Type:
What makes the trigger fire
- Return type:
roboto.domain.triggers.sources.TriggerSource
- classmethod from_id(trigger_id, roboto_client=None)#
Load the trigger with the given id, whichever API created it.
- Parameters:
trigger_id (str)
roboto_client (Optional[roboto.http.RobotoClient])
- Return type:
- classmethod from_name(name, owner_org_id=None, roboto_client=None)#
Load the trigger with the given name, whichever API created it. Names are unique within an org.
- Parameters:
name (str)
owner_org_id (Optional[str])
roboto_client (Optional[roboto.http.RobotoClient])
- Return type:
- classmethod list(owner_org_id=None, roboto_client=None)#
Yield every trigger in the org, event-fired and scheduled, newest first, whichever API created it.
- Parameters:
owner_org_id (Optional[str])
roboto_client (Optional[roboto.http.RobotoClient])
- Return type:
collections.abc.Generator[Trigger, None, None]
- property name: str#
- Return type:
str
- property once_per: roboto.domain.platform_events.OncePer#
What the trigger fires at most once per; always
occurrence(one firing per minute) for a schedule.- Return type:
- property org_id: str#
- Return type:
str
- classmethod platform_event_samples(roboto_client=None)#
Fetch a realistic sample of every event type, dereferenced.
Each sample carries the event envelope, every namespace root the type exposes with a full record under it, and the
root.pathlist a condition field or{{ }}placeholder may name. Use it to see what a template will resolve to before writing one.Examples
>>> samples = Trigger.platform_event_samples() >>> samples[PlatformEventType.FileUploaded].paths[:3] ['envelope.id', 'envelope.type', 'envelope.time']
- Parameters:
roboto_client (Optional[roboto.http.RobotoClient])
- Return type:
dict[roboto.domain.platform_events.PlatformEventType, roboto.domain.triggers.samples.PlatformEventSample]
- property record: roboto.domain.triggers.record.TriggerRecord#
- Return type:
- property schedule: str | None#
The cron expression (UTC) the trigger fires on, or
Nonefor an event-fired trigger.- Return type:
Optional[str]
- set_enabled(enabled)#
Enable or disable this trigger.
- Parameters:
enabled (bool)
- Return type:
- property targets: List[roboto.domain.triggers.targets.TriggerTargetSpec]#
- Return type:
List[roboto.domain.triggers.targets.TriggerTargetSpec]
- to_dict()#
Return this trigger’s record as a JSON-able dict.
- Return type:
dict[str, Any]
- property trigger_id: str#
- Return type:
str
- update(*, fires_on=NotSet, events=NotSet, once_per=NotSet, schedule=NotSet, condition=NotSet, targets=NotSet, enabled=NotSet)#
Apply a partial update to this trigger and refresh this instance.
Only provided fields change;
condition=Noneclears the condition. The firing source is replaced whole: passfires_on, or theevents/once_per/scheduleshorthands, which are merged over the current source before being sent. A trigger withengine == "v1"accepts only edits its older shape can express — a single invoke-action target, event types that map onto it,once_peroffileordataset— and rejects the rest with a message naming what it cannot store.- Parameters:
fires_on (Union[roboto.domain.triggers.sources.TriggerSource, roboto.sentinels.NotSetType])
events (Union[List[roboto.domain.platform_events.PlatformEventType], roboto.sentinels.NotSetType])
once_per (Union[roboto.domain.platform_events.OncePer, roboto.sentinels.NotSetType])
schedule (Union[str, roboto.sentinels.NotSetType])
condition (Optional[Union[roboto.query.ConditionType, roboto.sentinels.NotSetType]])
targets (Union[List[roboto.domain.triggers.targets.TriggerTargetSpec], roboto.sentinels.NotSetType])
enabled (Union[bool, roboto.sentinels.NotSetType])
- Return type:
- class roboto.domain.triggers.TriggerDispatchRecord(/, **data)#
Bases:
pydantic.BaseModelWire-transmissible representation of one trigger dispatch.
A dispatch is one attempt to run one target of one trigger for one matched platform event, deduped at the trigger’s
OncePer. The triple (trigger_id,idempotency_token,target_id) is theDispatchSlot; at most one dispatch ever occupies a slot, which is what makes redelivered events safe.- Parameters:
data (Any)
- claimed_at: datetime.datetime#
When the slot was (most recently) claimed.
- dataset_id: str | None = None#
The dataset the subject belongs to (the subject itself for a dataset event), which is what a dataset’s page lists dispatches by.
Nonewhen the subject has no dataset, such as a session or an invocation.
- event_id: str#
Id of the platform event occurrence that most recently claimed this slot.
- event_type: roboto.domain.platform_events.PlatformEventType#
Type of the platform event that matched.
- finalized_at: datetime.datetime | None = None#
When the dispatch reached a terminal status;
Nonewhile claimed.
- idempotency_token: str#
Dedup token derived from the matched event at the trigger’s
once_per({event.type}|{once_per}:{projection}).
- org_id: str#
Organization that owns the trigger.
- result_ref: str | None = None#
an invocation id, an agent thread id, or a Slack message timestamp, per
target_type.- Type:
What a dispatched target produced
- property slot: DispatchSlot#
The slot this dispatch occupies.
- Return type:
- status: TriggerDispatchStatus#
Where this dispatch is in its lifecycle.
- status_detail: str | None = None#
Human-readable detail for
status, e.g. the error a failed target raised.
- subject: str#
The entity the matched platform event was about, as a
roboto://URI; the same value as the event’s ownsubject.
- property subject_uri: roboto.uri.RobotoUri#
subjectas a parsedRobotoUri.- Return type:
- target_id: str#
Which of the trigger’s targets this dispatch ran.
- target_type: roboto.domain.triggers.targets.TriggerTargetType#
Kind of target dispatched.
- trigger_id: str#
Trigger this dispatch belongs to.
- class roboto.domain.triggers.TriggerDispatchStatus#
Bases:
roboto.compat.StrEnumLifecycle state of one dispatch: one attempt to run one target for one matched event.
- Claimed = 'claimed'#
The dispatch slot is claimed and the target is about to run. A claim that neither finalizes nor is reclaimed within the redelivery grace period is presumed dead and may be claimed again, so delivery is at-least-once: a target may run twice for one event.
- Dispatched = 'dispatched'#
The target ran;
TriggerDispatchRecord.result_refpoints at what it produced.
- Failed = 'failed'#
The target raised; a redelivered event may claim the slot again.
- Unknown = 'unknown'#
The claim outlived every redelivery of its event without finalizing, so the outcome cannot be determined. Set by an operational sweep, never reclaimable.
- class roboto.domain.triggers.TriggerDryRunGate(/, **data)#
Bases:
pydantic.BaseModelOne gate’s result in a dry-run trace.
condition_leavesis populated only on theconditiongate,targetsonly ontarget_prefilter, andidempotency_token/dispatchesonly onalready_fired.- Parameters:
data (Any)
- condition_leaves: list[ConditionLeafTrace] | None = None#
Per-leaf results with actual values (
conditiongate only).
- detail: str | None = None#
Plain-English explanation of the outcome.
- dispatches: list[DispatchSlotTrace] | None = None#
Per-target dispatch-slot state at the token (
already_firedgate only).
- gate: TriggerDryRunGateName#
Which gate this is.
- idempotency_token: str | None = None#
The dedup token the event projects onto (
already_firedgate only).
- status: TriggerDryRunGateStatus#
Whether the gate passed, failed, or was short-circuited.
- targets: list[TargetAcceptanceTrace] | None = None#
Per-target prefilter decisions (
target_prefiltergate only).
- class roboto.domain.triggers.TriggerDryRunGateName#
Bases:
roboto.compat.StrEnumThe gates the evaluator runs, in evaluation order.
- AlreadyFired = 'already_fired'#
Is a dispatch slot still claimable at the trigger’s
once_per?
- Condition = 'condition'#
Does the trigger’s condition hold for the event?
- Enabled = 'enabled'#
Is the trigger enabled?
- Subscribed = 'subscribed'#
Is the trigger subscribed to the event’s type?
- TargetPrefilter = 'target_prefilter'#
Does at least one target accept the event (pathspec and precondition gates)?
- class roboto.domain.triggers.TriggerDryRunGateStatus#
Bases:
roboto.compat.StrEnumOutcome of one gate in a dry run.
- Failed = 'failed'#
- NotEvaluated = 'not_evaluated'#
An earlier gate failed, so this one was short-circuited.
- Passed = 'passed'#
- class roboto.domain.triggers.TriggerDryRunRequest(/, **data)#
Bases:
pydantic.BaseModelRequest payload for a trigger dry run.
Provide
event(a fully-formed platform event to evaluate) or a single reference (dataset_id,file_id,invocation_id,session_id,event_id, orscheduled_for), from which the server synthesizes an event. With an entity reference,event_typeoptionally picks which of the trigger’s subscribed event types to synthesize; the default is the trigger’s first subscribed event type compatible with the reference. A schedule-fired trigger needs no reference: the server synthesizes its next scheduled minute.- Parameters:
data (Any)
- dataset_id: str | None = None#
Synthesize an event about this dataset.
- event: roboto.domain.platform_events.PlatformEvent | None = None#
A platform event to evaluate as-is.
- event_id: str | None = None#
Synthesize a platform event about this event (the annotation on your data).
- event_type: roboto.domain.platform_events.PlatformEventType | None = None#
Which subscribed event type to synthesize for an entity reference.
- file_id: str | None = None#
Synthesize an event about this file.
- invocation_id: str | None = None#
Synthesize an event about this invocation.
- scheduled_for: datetime.datetime | None = None#
synthesize the occurrence for this scheduled minute (UTC). With no reference at all, a schedule-fired trigger is dry-run for its next scheduled minute.
- Type:
For a schedule-fired trigger
- session_id: str | None = None#
Synthesize an event about this session.
- class roboto.domain.triggers.TriggerDryRunResponse(/, **data)#
Bases:
pydantic.BaseModelThe structured trace a trigger dry run produces.
Gates appear in evaluation order. The first failed gate is why the trigger would not fire; every gate after it is
not_evaluated.- Parameters:
data (Any)
- event_type: roboto.domain.platform_events.PlatformEventType#
Type of the (given or synthesized) event that was evaluated.
- gates: list[TriggerDryRunGate]#
The gate-by-gate trace, in evaluation order.
- trigger_id: str#
The trigger that was dry-run.
- verdict: str#
One plain-English sentence summarizing the outcome.
- would_fire: bool#
Whether the trigger would dispatch at least one target for this event.
- class roboto.domain.triggers.TriggerRecord(/, **data)#
Bases:
pydantic.BaseModelWire-transmissible representation of a trigger.
A firing source (a platform event subscription or a schedule), an optional condition over the firing’s namespace, and the targets to dispatch on a match. Cross-field rules — exposed roots,
once_perlegality, template placeholders — are enforced when the trigger is saved, byTriggerValidator.Triggered work runs as the organization’s actions service user; a trigger cannot run its targets as anyone else.
- Parameters:
data (Any)
- condition: roboto.query.ConditionType | None = None#
Optional predicate over the firing’s namespace; the trigger fires only when it holds. Same
Conditionwire format the query system uses.
- created: datetime.datetime#
Timestamp when the trigger was created.
- created_by: str#
User ID who created the trigger.
- enabled: bool = True#
Whether the trigger is active.
- engine: str = 'v1'#
"v2"for the events/once_per/targets engine this module models (every trigger, once a deployment has cut over),"v1"for a trigger the oldercauses/for_eachengine still evaluates, projected onto this shape. Server-assigned and read-only; no request model carries it. Defaults to"v1"for a response that omits it, which is what a Roboto deployment older than the field sends.- Type:
Which engine evaluates this trigger
- fires_on: roboto.domain.triggers.sources.TriggerSource#
an
EventSubscription(which also carriesonce_per) or aSchedule.- Type:
What makes the trigger fire
- modified: datetime.datetime#
Timestamp when the trigger was last modified.
- modified_by: str#
User ID who last modified the trigger.
- org_id: str#
Organization that owns the trigger and whose events it sees.
- targets: list[roboto.domain.triggers.targets.TriggerTargetSpec]#
What the trigger dispatches when it fires, in order. At least one; each
target_idis unique within the trigger.
- trigger_id: str#
Unique identifier for the trigger.
- roboto.domain.triggers.TriggerSource#
A trigger’s firing source, discriminated on
type.
- class roboto.domain.triggers.TriggerSourceType#
Bases:
roboto.compat.StrEnumDiscriminator for
TriggerSource.- Events = 'events'#
The trigger fires when a subscribed platform event occurs.
- Schedule = 'schedule'#
The trigger fires on a cron schedule.
- roboto.domain.triggers.TriggerTargetSpec#
A trigger target spec, discriminated on
type.
- class roboto.domain.triggers.TriggerTargetType#
Bases:
roboto.compat.StrEnumThe kind of thing a trigger does when it fires.
- InvokeAction = 'invoke_action'#
Invoke a containerized action.
- SendSlackMessage = 'send_slack_message'#
Post a message to a Slack channel on the org’s allowlist.
- StartAgent = 'start_agent'#
Start an AI agent thread from a saved agent definition.
- class roboto.domain.triggers.TriggerValidator(catalog=DEFAULT_PLATFORM_EVENT_CATALOG)#
Save-time validation for triggers.
Enforces the cross-field rules that need the event catalog: a condition may only reference namespace roots exposed by every event the source fires for,
once_permust be legal for every subscribed event, every target must act on the kind of entity the subscription is about, and every target template placeholder must resolve to a shared exposed root (or a reservedenvelope./trigger.context). A schedule fires for exactly one occurrence type, so the same rules apply to it with that occurrence’s roots.Run before persistence so a trigger that could never fire — or could never resolve its templates — fails loudly with an actionable message instead of silently misbehaving at evaluation time.
- Parameters:
catalog (roboto.domain.platform_events.PlatformEventCatalog)
- validate(*, fires_on, condition, targets)#
Validate the cross-field rules for one trigger’s parts.
- Parameters:
fires_on (roboto.domain.triggers.sources.TriggerSource) – The trigger’s firing source.
condition (Optional[roboto.query.ConditionType]) – Optional predicate over the firing’s namespace.
targets (collections.abc.Sequence[roboto.domain.triggers.targets.TriggerTargetSpec]) – The trigger’s target specs.
- Raises:
ValueError – The first rule that fails, with a message naming the offending field, root, or event.
- Return type:
None
- validate_record(record)#
Validate a full trigger record.
- Raises:
ValueError – Any rule in
validate()fails.- Parameters:
- Return type:
None
- class roboto.domain.triggers.UpdateTriggerRequest(/, **data)#
Bases:
pydantic.BaseModelRequest payload to update a trigger.
Only fields explicitly provided are changed; the
NotSetTypesentinel distinguishes “field omitted” from “field set toNone”. The updated record must still satisfy everyTriggerValidatorrule.- Parameters:
data (Any)
- condition: roboto.query.ConditionType | roboto.sentinels.NotSetType | None#
New condition; explicit
Noneclears it.
- enabled: bool | roboto.sentinels.NotSetType#
New enabled status.
- fires_on: roboto.domain.triggers.sources.TriggerSource | roboto.sentinels.NotSetType#
an event subscription’s events and
once_perchange together, and a trigger may switch between events and a schedule.- Type:
New firing source. Replaces the whole source
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- targets: list[roboto.domain.triggers.targets.TriggerTargetSpec] | roboto.sentinels.NotSetType#
New target list. A target whose
target_idis referenced by existing dispatches must keep that id.
- roboto.domain.triggers.platform_event_sample(event_type, catalog=DEFAULT_PLATFORM_EVENT_CATALOG)#
Build the sample for one event type.
The
event,changedandtagroots are built by the sameEventNamespacethat serves them when a trigger fires; the entity roots are exactly the onescatalogexposes for the type.- Parameters:
- Return type:
- roboto.domain.triggers.platform_event_samples(catalog=DEFAULT_PLATFORM_EVENT_CATALOG)#
A sample for every event type in
catalog, in catalog order.- Parameters:
catalog (roboto.domain.platform_events.PlatformEventCatalog)
- Return type:
dict[roboto.domain.platform_events.PlatformEventType, PlatformEventSample]
- roboto.domain.triggers.sample_schedule_trigger()#
The schedule-fired trigger the
schedule.firedsample is evaluated for, so the sample’sscheduleroot carries thecrona template may name.- Return type:
- roboto.domain.triggers.sample_trigger()#
The trigger the sample is evaluated for; what
{{trigger.*}}sees.- Return type:
- roboto.domain.triggers.target_catalog_manifest()#
Which kinds of entity each target can act on, as the web UI’s target picker reads it.
target_catalog.jsonin this package is this function’s output, written byscripts/gen_trigger_manifests.pyand drift-checked by a test on each side.- Return type:
dict[str, Any]
- roboto.domain.triggers.template_paths(record, prefix)#
Every dotted path a template may reference under
prefix, in document order.Walks nested mappings only. A list is a leaf, because path resolution descends through mappings and stops at anything else:
dataset.tagsis addressable,dataset.tags.0is not.- Parameters:
record (collections.abc.Mapping[str, Any])
prefix (str)
- Return type:
list[str]