Skip to content
Roboto
Esc
↑↓navigate↵open⌘Jpreview
On this page

roboto.ai.agent

Reusable, parameterized agent definitions.

An agent captures a parameterized StartAgentThreadRequest alongside the variables it declares, so the same workflow (triage, summary, etc.) can be re-invoked against new subjects without re-authoring the request. Variables appear as {{name}} placeholders in any string leaf of the request body and are substituted client-side before the request is sent — unresolved or unknown placeholders raise rather than reach the service.

Submodules

Package Contents

Agent

class roboto.ai.agent.Agent(record, roboto_client=None)#View Source

A reusable, parameterized factory for AgentThread.

An Agent captures a StartAgentThreadRequest body with {{name}} placeholders alongside the TemplateVariable declarations that those placeholders bind to. Invoking the agent substitutes caller-supplied values into the body, runs invoke-time existence checks for typed values (dataset ids, device ids), and starts a session via the same code path as AgentThread.start().

The wrapper is to AgentRecord what Action is to ActionRecord: the record carries the wire-shape data, this class carries the behaviors.

Parameters

Properties

Agent.agent_id

agent_id str #

Platform-issued agt_<short> handle. Stable across renames.

Return type: str

Agent.create()

classmethod create(name, request_template, variables=None, description=None, caller_org_id=None, roboto_client=None)#View Source

Persist a new agent in the caller’s organization.

The platform fills agent_id, org_id, created, created_by, modified, and modified_by from the caller’s identity. Every other field comes from this method’s arguments.

Parameters

name str

Human-readable display name. Unique per (org_id, name); a second agent with the same name in the same org is rejected with RobotoConflictException.

The StartAgentThreadRequest to clone at invoke time. Any string leaf may carry {{name}} placeholders; every referenced placeholder must appear in variables (and vice versa).

variables Optional[collections.abc.Sequence[roboto.ai.agent.record.TemplateVariable]]

TemplateVariable declarations. The set of names here must equal the set of placeholder names referenced anywhere in request_template; a mismatch fails server-side validation with a 400.

description Optional[str]

Free-form text rendered on the agent’s detail and library pages.

caller_org_id Optional[str]

Organization to create the agent in. If omitted and the caller belongs to exactly one organization, that organization is used; required when the caller belongs to multiple organizations.

roboto_client Optional[roboto.http.RobotoClient]

Optional RobotoClient instance. If omitted, the default client configuration is used.

Returns

The newly created Agent instance.

Raises

An agent with the same name already exists in the org.

request_template and variables disagree about the placeholder set, or a variable name is invalid.

The caller lacks permission to create agents in the target organization.

Usage

Create an agent with one dataset-typed variable:

from roboto.ai.agent import Agent, TemplateVariable, TemplateVariableType
from roboto.ai.agent_thread import StartAgentThreadRequest, AgentMessage
request_template = StartAgentThreadRequest(
    messages=[AgentMessage.text("Triage dataset {{dataset_id}}.")],
)
agent = Agent.create(
    name="triage",
    request_template=request_template,
    variables=[
        TemplateVariable(name="dataset_id", type=TemplateVariableType.DATASET_ID),
    ],
    description="Apply the triage label vocabulary to a dataset.",
)

Properties

Agent.created

created datetime.datetime #

Wall-clock time the agent was first persisted.

Return type: datetime.datetime

Agent.created_by

created_by str #

User id of the original author.

Return type: str

Agent.delete()

delete()#View Source

Permanently delete this agent.

Sessions previously launched from this agent are unaffected — their created_from_agent_id references this agent’s id independent of any foreign key, so they remain readable. Creating a new agent with the same name in the same org is allowed after deletion.

Raises

The agent has already been deleted.

The caller is not a member of this agent’s org_id.

Return type

None

Usage

agent = Agent.from_name("retired_triage")
agent.delete()

Properties

Agent.description

description str | None #

Free-form text rendered on the agent’s detail and library pages.

Return type: Optional[str]

Agent.for_org()

classmethod for_org(org_id=None, roboto_client=None)#View Source

Iterate every Agent declared in an organization.

Yields agents newest-first (by created) and paginates transparently; callers consume the generator without worrying about next_token.

Parameters

org_id Optional[str]

Organization to list agents for. If omitted and the caller belongs to exactly one organization, that organization is used.

roboto_client Optional[roboto.http.RobotoClient]

Optional RobotoClient; defaults to the ambient configuration.

Yields

Agent instances, one per row, in newest-first order.

Return type

collections.abc.Generator[Agent, None, None]

Usage

Print every agent’s name:

for agent in Agent.for_org():
    print(agent.name)

Count agents in a specific org:

count = sum(1 for _ in Agent.for_org(org_id="og_abc123"))

Agent.from_id()

classmethod from_id(agent_id, roboto_client=None)#View Source

Load an Agent by its canonical id.

agent_id is platform-unique, so the SDK does not need the caller to declare which org the agent lives in — the route looks up the record and authorizes the caller against the record’s org_id.

Parameters

agent_id str

The platform-issued agt_<short> identifier.

roboto_client Optional[roboto.http.RobotoClient]

Optional RobotoClient; defaults to the ambient configuration.

Returns

The Agent instance.

Raises

The agent does not exist or belongs to an organization the caller cannot read.

Usage

agent = Agent.from_id("agt_abc123")

Agent.from_name()

classmethod from_name(name, roboto_client=None, owner_org_id=None)#View Source

Load an Agent by its (org_id, name) handle.

Mirrors from_name(): name + owning org are jointly unique, so this returns at most one agent. Unlike from_id() (which derives the org from the looked-up record), name lookup needs the org up-front and goes through the X-Roboto-Resource-Owner-Id header. agent_id (the canonical handle) stays stable across renames, so a script that pins by name follows renames; a script that pins by id does not.

Parameters

name str

The agent’s name.

roboto_client Optional[roboto.http.RobotoClient]

Optional RobotoClient; defaults to the ambient configuration.

owner_org_id Optional[str]

Organization that owns the agent. If omitted and the caller belongs to one organization, that organization is used.

Returns

The Agent instance.

Raises

No agent with that name exists in the resolved organization.

Usage

agent = Agent.from_name("triage")

Agent.launch()

launch(values=None, visibility=ThreadVisibility.ORG, analysis_scope=None)#View Source

Resolve placeholders and start an AgentThread.

The platform substitutes values into request_template, runs launch-time existence checks on typed values (DATASET_ID / DEVICE_ID), and creates a thread via the same code path as a bare AgentThread.start(). The resulting thread is owned by this agent’s org_id (not the caller’s default org), and its created_from_agent_id is stamped with this agent’s agent_id so the agent detail page can list “threads launched from here”.

Parameters

values Optional[dict[str, str]]

Variable name to caller-supplied value. Keys must match the names declared in variables; values are coerced to str before splicing into placeholders. Omit when every declared variable carries a default.

ThreadVisibility for the new thread. Defaults to ORG because agents exist to share workflows; the caller passes PRIVATE to opt out per launch. Overrides whatever the authored request_template carries.

analysis_scope Optional[roboto.ai.core.AnalysisScope]

Optional AnalysisScope for the new thread. When provided, it is zipper-merged onto whatever the authored request_template carries: each dimension the caller set wins, and the rest inherit from the template. When omitted, the template’s scope (usually none) is left untouched.

Returns

An AgentThread wrapping the freshly created thread. The thread is fully hydrated (messages, status, continuation token) and ready for AgentThread.run() or AgentThread.events().

Raises

values is missing a required variable, references an unknown variable, or a typed value (DATASET_ID / DEVICE_ID) names a resource that does not exist in the agent’s org.

This agent has been deleted since the wrapper was loaded.

The caller is not a member of this agent’s org_id or that org is not on a premium plan.

Usage

agent = Agent.from_name("triage")
thread = agent.launch(values={"dataset_id": "ds_abc123"})
thread.run()

Properties

Agent.modified

modified datetime.datetime #

Wall-clock time of the most recent successful update.

Return type: datetime.datetime

Agent.modified_by

modified_by str #

User id who applied the most recent update; equals created_by for records never edited since creation.

Return type: str

Agent.name

name str #

Human-readable display name; unique within org_id.

Return type: str

Agent.org_id

org_id str #

Organization that owns this agent.

Return type: str

Agent.record

Underlying AgentRecord.

Wire shape used in API requests; may evolve over time. Prefer the public Agent API unless you need direct record access.

Agent.request_template

Agent.to_dict()

to_dict()#View Source

Return the JSON-serializable form of the underlying record.

Return type

dict[str, Any]

Agent.update()

update(name=NotSet, description=NotSet, request_template=NotSet, variables=NotSet)#View Source

Apply a partial update.

Each parameter defaults to NotSet so omitting a field leaves it untouched on the server, while passing None for description clears it. request_template and variables are co-validated server-side after the merge: the post-update placeholder set must equal the post-update variable set, even if only one of the two fields was supplied.

Parameters

Replace the display name. Subject to the same (org_id, name) uniqueness as create().

description Union[Optional[str], roboto.sentinels.NotSetType]

Replace the description. Pass None to clear; omit to leave unchanged.

variables Union[collections.abc.Sequence[roboto.ai.agent.record.TemplateVariable], roboto.sentinels.NotSetType]

Replace the variable declarations.

Returns

self, with record refreshed to the persisted state.

Raises

name collides with another agent in the same org.

The post-update placeholder set disagrees with the post-update variable set.

The agent has been deleted.

The caller is not a member of this agent’s org_id.

Usage

agent.update(description="Triages a dataset against the v2 label vocab.")

Clear the description:

agent.update(description=None)

Properties

Agent.variables

TemplateVariable declarations. The set of names here equals the set of placeholders referenced in request_template.

AgentRecord

class roboto.ai.agent.AgentRecord(/, **data)#View Source

Bases: pydantic.BaseModel

A pre-filled StartAgentThreadRequest plus declared variables.

An AgentRecord captures most of what an AgentThread needs 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 fixed label_vocabulary but 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 in request_template equals 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

Attributes

AgentRecord.agent_id

agent_id str #

Canonical handle. Generated server-side (agt_<short>); stable across renames.

AgentRecord.created

created datetime.datetime #

Wall-clock time the record was first persisted.

AgentRecord.created_by

created_by str #

User id of the agent’s original author.

AgentRecord.description

description str | None = None #

Free-form description rendered on the agents list and detail pages.

AgentRecord.modified

modified datetime.datetime #

Wall-clock time of the most recent successful update.

AgentRecord.modified_by

modified_by str #

User id who applied the most recent update; equals created_by on records that have not been edited since creation.

AgentRecord.name

name str #

Human-readable display name. Mutable. Unique per (org_id, name) - enforced at the persistence layer, not on the record.

AgentRecord.org_id

org_id str #

Organization that owns the agent. All CRUD and invoke calls must come from a member of this org.

AgentRecord.request_template

The body that will be cloned and resolved into a real StartAgentThreadRequest at invoke time. Any string leaf may contain {{name}} placeholders; non-string fields cannot be templated, because substitution visits string leaves only.

AgentRecord.variables

variables list[TemplateVariable] = None #

Declared variables. The set of names here must equal the set of placeholder names parsed from request_template.

AgentResolutionError

exception roboto.ai.agent.AgentResolutionError#View Source

Bases: ValueError

Base class for resolver-raised errors. Routes map subclasses to 4xx.

CreateAgentRequest

class roboto.ai.agent.CreateAgentRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Wire payload for POST /v1/ai/agents.

The server fills AgentRecord.agent_id, org_id, created_by, created, modified, and modified_by from the caller’s identity; everything else comes from this request.

Parameters

data Any

Attributes

CreateAgentRequest.description

description str | None = None #

CreateAgentRequest.name

name str #

CreateAgentRequest.request_template

CreateAgentRequest.variables

variables list[TemplateVariable] = None #

LaunchAgentRequest

class roboto.ai.agent.LaunchAgentRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Wire payload for POST /v1/ai/agents/<agent_id>/launch.

The route resolves the named agent, substitutes values into its body, and starts a new AgentThread whose visibility comes from visibility and whose created_from_agent_id points back at the source agent.

Parameters

data Any

Attributes

LaunchAgentRequest.analysis_scope

analysis_scope roboto.ai.core.AnalysisScope | None = None #

Optional AnalysisScope for the resulting thread. When provided, it is zipper-merged onto whatever the agent’s request_template.analysis_scope field carries: each dimension the caller set wins, and the rest inherit from the template. When None, the authored template’s scope (usually none) is left untouched.

LaunchAgentRequest.values

values dict[str, str] = None #

Variable name to caller-supplied value. Keys must match declared TemplateVariable names; values are coerced to str before being spliced into placeholders.

LaunchAgentRequest.visibility

Visibility of the resulting AgentThread. Invoke-time wins: this value overrides whatever the agent’s request_template.visibility field carries. Agents cannot pin visibility — authors who need to convey recommended visibility do so in the agent’s description. Defaults to ORG because agents exist to share workflows across teammates; PRIVATE is an explicit opt-out per invocation.

TemplateVariable

class roboto.ai.agent.TemplateVariable(/, **data)#View Source

Bases: pydantic.BaseModel

A named slot in an AgentRecord that 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 - see AgentRecord._validate_variables_match_placeholders().

Parameters

data Any

Attributes

TemplateVariable.collection_content_type

collection_content_type roboto.domain.collections.record.CollectionResourceType | None = None #

Only meaningful when type is TemplateVariableType.COLLECTION_ID: constrains the invoke-page collection picker to collections holding this resource type (e.g. event collections for a create-events goal). None leaves the picker unconstrained. Must be None for every other variable type — see _validate_resolvable().

TemplateVariable.default

default str | None = None #

Default value substituted when the caller omits the variable. Coerced to str; types are a UI concern.

TemplateVariable.description

description str | None = None #

Human-readable explanation rendered next to the input on the invoke page.

TemplateVariable.name

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.

TemplateVariable.required

required bool = True #

If True the resolver raises UnresolvedAgentVariablesError when no value is supplied and no default is set.

TemplateVariable.type

UI hint for the invoke page. See TemplateVariableType.

TemplateVariableType

class roboto.ai.agent.TemplateVariableType#View Source

Bases: roboto.compat.StrEnum

How a variable’s value is interpreted when an agent is launched.

Substitution itself is type-agnostic: every value is spliced in as a string. The type drives two things a caller can observe — the Roboto web app picks a richer input control (dataset picker, device picker), and a typed value is checked for existence when the agent is launched, so a bad id is rejected up front rather than inside the agent’s first tool call.

Attributes

TemplateVariableType.COLLECTION_ID

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.

TemplateVariableType.DATASET_ID

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.

TemplateVariableType.DEVICE_ID

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.

TemplateVariableType.STRING

STRING = 'string' #

Free-form text. The default; renders as a plain text input. No existence check (no entity to check against).

UnknownAgentVariablesError

exception roboto.ai.agent.UnknownAgentVariablesError(names)#View Source

Bases: AgentResolutionError

Caller supplied values for variables the agent no longer declares — almost always a stale invoke form. Mapped to 400 so the UI can refetch.

Parameters

names list[str]

Attributes

UnknownAgentVariablesError.names

names #

UnresolvedAgentVariablesError

exception roboto.ai.agent.UnresolvedAgentVariablesError(names)#View Source

Bases: AgentResolutionError

Required variables had no supplied value and no default. Mapped to 400 with the names so the invoke page can highlight the empty inputs.

Parameters

names list[str]

Attributes

UnresolvedAgentVariablesError.names

names #

UpdateAgentRequest

class roboto.ai.agent.UpdateAgentRequest(/, **data)#View Source

Bases: pydantic.BaseModel

Wire payload for PUT /v1/ai/agents/<agent_id>.

Uses the NotSetType sentinel to distinguish “field omitted” from “field explicitly set to None” so partial updates don’t accidentally null out unrelated fields.

Parameters

data Any

Attributes

UpdateAgentRequest.description

description str | None | roboto.sentinels.NotSetType #

UpdateAgentRequest.model_config

model_config #

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

UpdateAgentRequest.name

UpdateAgentRequest.request_template

UpdateAgentRequest.variables

extract_placeholders()

roboto.ai.agent.extract_placeholders(body)#View Source

Return every {{name}} placeholder referenced anywhere in body.

Walks the JSON form of the request rather than the Pydantic model so the traversal is type-agnostic - placeholders inside label_vocabulary values, 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.

resolve_agent()

roboto.ai.agent.resolve_agent(agent, values)#View Source

Substitute values into agent.request_template and return a fully-validated StartAgentThreadRequest.

Walks the body’s JSON form swapping every {{name}} occurrence in a string leaf. Embedded substitution is supported. Dict keys are never touched — placeholder syntax in keys is rejected at save time.

Parameters

values dict[str, str]

Raises

values contains keys not declared on the agent (typically a stale invoke form).

a required variable has neither a supplied value nor a default; carries the offending names.

pydantic.ValidationError

the substituted body failed StartAgentThreadRequest validation — e.g. a resolved value doesn’t match a field-level regex or enum.

Was this page helpful?