roboto.ai.agent.record#
Module Contents#
- class roboto.ai.agent.record.AgentRecord(/, **data)#
Bases:
pydantic.BaseModelA pre-filled
StartAgentThreadRequestplus declared variables.An
AgentRecordcaptures most of what anAgentThreadneeds to start - system prompt, model profile, seeded messages, declared goals - and leaves a small set of named holes that callers must fill at invoke time. The canonical example is a triage agent whose goal carries a fixedlabel_vocabularybut a{{dataset.id}}placeholder, so the same agent can be re-run against many datasets without re-declaring the vocabulary.The record’s main invariant - enforced by
_validate_variables_match_placeholders()- is that the set of{{...}}placeholders found anywhere inrequest_templateequals exactly{v.name for v in variables}. A mismatch fails at save time so stale invoke forms can’t paper over typos.- Parameters:
data (Any)
- agent_id: str#
Canonical handle. Generated server-side (
agt_<short>); stable across renames.
- created: datetime.datetime#
Wall-clock time the record was first persisted.
- created_by: str#
User id of the agent’s original author.
- description: str | None = None#
Free-form description rendered on the agents list and detail pages.
- modified: datetime.datetime#
Wall-clock time of the most recent successful update.
- modified_by: str#
User id who applied the most recent update; equals
created_byon records that have not been edited since creation.
- name: str#
Human-readable display name. Mutable. Unique per
(org_id, name)- enforced at the persistence layer, not on the record.
- org_id: str#
Organization that owns the agent. All CRUD and invoke calls must come from a member of this org.
- request_template: roboto.ai.agent_thread.record.StartAgentThreadRequest#
The body that will be cloned and resolved into a real
StartAgentThreadRequestat invoke time. Any string leaf may contain{{name}}placeholders; non-string fields cannot be templated in v1 (the substitution engine never visits them).
- variables: list[TemplateVariable] = None#
Declared variables. The set of names here must equal the set of placeholder names parsed from
request_template.
- class roboto.ai.agent.record.CreateAgentRequest(/, **data)#
Bases:
pydantic.BaseModelWire payload for
POST /v1/ai/agents.The server fills
AgentRecord.agent_id,org_id,created_by,created,modified, andmodified_byfrom the caller’s identity; everything else comes from this request.- Parameters:
data (Any)
- description: str | None = None#
- name: str#
- request_template: roboto.ai.agent_thread.record.StartAgentThreadRequest#
- variables: list[TemplateVariable] = None#
- class roboto.ai.agent.record.LaunchAgentRequest(/, **data)#
Bases:
pydantic.BaseModelWire payload for
POST /v1/ai/agents/<agent_id>/launch.The route resolves the named agent, substitutes
valuesinto its body, and starts a newAgentThreadwhose visibility comes fromvisibilityand whosecreated_from_agent_idpoints back at the source agent.- Parameters:
data (Any)
- values: dict[str, str] = None#
Variable name to caller-supplied value. Keys must match declared
TemplateVariablenames; values are coerced tostrbefore being spliced into placeholders.
- visibility: roboto.ai.agent_thread.record.ThreadVisibility#
Visibility of the resulting
AgentThread. Invoke-time wins: this value overrides whatever the agent’srequest_template.visibilityfield carries. Agents cannot pin visibility — authors who need to convey recommended visibility do so in the agent’sdescription. Defaults toORGbecause agents exist to share workflows across teammates;PRIVATEis an explicit opt-out per invocation.
- class roboto.ai.agent.record.TemplateVariable(/, **data)#
Bases:
pydantic.BaseModelA named slot in an
AgentRecordthat must be filled before the agent can be invoked.Variables are declared up-front rather than inferred from the body so that the invoke UI can render typed inputs (dataset pickers, etc.) and so that a typo in the body (
{{dataste.id}}) surfaces as a save-time validation error rather than a silent extra prompt at invoke time. The declared set and the set of placeholders parsed from the body must match exactly - seeAgentRecord._validate_variables_match_placeholders().- Parameters:
data (Any)
- collection_content_type: roboto.domain.collections.record.CollectionResourceType | None = None#
constrains the invoke-page collection picker to collections holding this resource type (e.g.
eventcollections for a create-events goal).Noneleaves the picker unconstrained. Must beNonefor every other variable type — see_validate_resolvable().- Type:
Only meaningful when
typeisTemplateVariableType.COLLECTION_ID
- default: str | None = None#
Default value substituted when the caller omits the variable. Coerced to
str; types are a UI concern.
- description: str | None = None#
Human-readable explanation rendered next to the input on the invoke page.
- name: str#
Lookup key for substitution. Must match
_VARIABLE_NAME_RE; see that pattern for the dotted-name namespace convention. Two variables sharing a prefix (dataset.id+dataset.name) without an upstream expander produce two unlinked inputs at invoke time — that’s a UI-authoring footgun, not an SDK contract.
- required: bool = True#
If
Truethe resolver raisesUnresolvedAgentVariablesErrorwhen no value is supplied and nodefaultis set.
- type: TemplateVariableType#
UI hint for the invoke page. See
TemplateVariableType.
- class roboto.ai.agent.record.TemplateVariableType#
Bases:
roboto.compat.StrEnumHow a variable is interpreted by the invoke-page UI and the invoke-time existence validator.
The substitution engine itself is type-agnostic: every value gets spliced in as a string. The type drives two separate consumers: the UI picks a richer input control (dataset picker, device picker), and the service-side invoke handler runs an existence check on typed values so a bad id fails at the invoke boundary instead of inside the agent’s first tool call. See
roboto_service.routes.ai_router._VALUE_VALIDATORS.- COLLECTION_ID = 'collection_id'#
A Roboto collection identifier. UI renders a collection picker; invoke-time validator asserts the collection exists in the caller’s org.
- DATASET_ID = 'dataset_id'#
A Roboto dataset identifier. UI renders a dataset picker; invoke-time validator asserts the dataset exists in the caller’s org.
- DEVICE_ID = 'device_id'#
A Roboto device identifier. UI renders a device picker; invoke-time validator asserts the device is registered in the caller’s org.
- STRING = 'string'#
Free-form text. The default; renders as a plain text input. No existence check (no entity to check against).
- class roboto.ai.agent.record.UpdateAgentRequest(/, **data)#
Bases:
pydantic.BaseModelWire payload for
PUT /v1/ai/agents/<agent_id>.Uses the
NotSetTypesentinel to distinguish “field omitted” from “field explicitly set toNone” so partial updates don’t accidentally null out unrelated fields.- Parameters:
data (Any)
- description: str | None | roboto.sentinels.NotSetType#
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str | roboto.sentinels.NotSetType#
- request_template: roboto.ai.agent_thread.record.StartAgentThreadRequest | roboto.sentinels.NotSetType#
- variables: list[TemplateVariable] | roboto.sentinels.NotSetType#
- roboto.ai.agent.record.extract_placeholders(body)#
Return every
{{name}}placeholder referenced anywhere inbody.Walks the JSON form of the request rather than the Pydantic model so the traversal is type-agnostic - placeholders inside
label_vocabularyvalues, message text, system prompt, etc. all get picked up without needing per-field logic. Only string values are scanned; dict keys are intentionally ignored so key-collision footguns never arise.- Parameters:
body (roboto.ai.agent_thread.record.StartAgentThreadRequest)
- Return type:
set[str]