roboto.ai.agent_thread.record#

Module Contents#

type roboto.ai.agent_thread.record.AgentContent = AgentTextContent | AgentToolUseContent | AgentToolResultContent | AgentErrorContent#

Type alias for all possible content types within agent messages.

class roboto.ai.agent_thread.record.AgentContentType#

Bases: roboto.compat.StrEnum

Enumeration of different types of content within agent messages.

Defines the various content types that can be included in agent messages.

ERROR = 'error'#

Error information when message generation fails.

TEXT = 'text'#

Plain text content from users or AI responses.

TOOL_RESULT = 'tool_result'#

Results returned from tool executions.

TOOL_USE = 'tool_use'#

Tool invocation requests from the AI assistant.

class roboto.ai.agent_thread.record.AgentErrorContent(/, **data)#

Bases: pydantic.BaseModel

Error content within an agent message.

Used when message generation fails due to an error or is cancelled by the user.

Parameters:

data (Any)

content_type: Literal[AgentContentType]#
error_code: str | None = None#

Optional error code for programmatic handling.

error_message: str#

User-friendly error message describing what went wrong.

class roboto.ai.agent_thread.record.AgentGoalStatus#

Bases: roboto.compat.StrEnum

Lifecycle of a per-turn declared goal.

Goals begin PENDING when registered. They transition to ACHIEVED when the corresponding achieve-tool reports success, or to FAILED when the runner’s corrective re-prompt budget for the turn is exhausted (or when the worker cannot construct an achieve-tool for the goal).

ACHIEVED = 'achieved'#

Goal’s corresponding achieve-tool was invoked successfully.

FAILED = 'failed'#

Goal could not be achieved within the turn’s retry budget.

PENDING = 'pending'#

Goal has been registered but not yet completed.

class roboto.ai.agent_thread.record.AgentMessage(/, **data)#

Bases: pydantic.BaseModel

A single message within an agent thread.

Represents one message in the conversation, containing the sender role, content blocks, and generation status. Messages can contain multiple content blocks of different types (text, tool use, tool results).

Parameters:

data (Any)

content: list[AgentContent]#

List of content blocks that make up this message.

created: datetime.datetime = None#

Timestamp when this message was created.

is_complete()#

Check if message generation is complete.

Returns:

True if the message status is COMPLETED, False otherwise.

Return type:

bool

is_unsuccessful()#

Check if message generation failed or was cancelled.

Returns:

True if the message status is FAILED or CANCELLED, False otherwise.

Return type:

bool

role: AgentRole#

The role of the message sender (user, assistant, or roboto).

status: AgentMessageStatus#

Current generation status of this message.

classmethod text(text, role=AgentRole.USER)#

Create a simple text message.

Convenience method for creating a message containing only text content.

Parameters:
  • text (str) – The text content for the message.

  • role (AgentRole) – The role of the message sender. Defaults to USER.

Returns:

AgentMessage instance containing the text content.

Return type:

AgentMessage

class roboto.ai.agent_thread.record.AgentMessageStatus#

Bases: roboto.compat.StrEnum

Enumeration of possible message generation states.

Tracks the lifecycle of message generation from initiation to completion.

CANCELLED = 'cancelled'#

Message generation was cancelled by the user.

COMPLETED = 'completed'#

Message generation has finished and content is complete.

FAILED = 'failed'#

Message generation failed due to an error.

GENERATING = 'generating'#

Message content is currently being generated.

NOT_STARTED = 'not_started'#

Message has been queued but generation has not begun.

is_terminal()#

Check if the message generation is in a terminal state.

Returns:

True if the message is in a terminal state, False otherwise.

Return type:

bool

class roboto.ai.agent_thread.record.AgentRole#

Bases: roboto.compat.StrEnum

Enumeration of possible roles in an agent thread.

Defines the different participants that can send messages in a thread.

ASSISTANT = 'assistant'#

AI agent responding to user queries and requests.

ROBOTO = 'roboto'#

Roboto system providing tool results and system information.

USER = 'user'#

Human user sending messages to the agent.

class roboto.ai.agent_thread.record.AgentTextContent(/, **data)#

Bases: pydantic.BaseModel

Text content within an agent message.

Parameters:

data (Any)

text: str#

The actual text content of the message.

class roboto.ai.agent_thread.record.AgentThreadDelta(/, **data)#

Bases: pydantic.BaseModel

Incremental update to an agent thread.

Contains only the changes since the last synchronization, used for efficient real-time updates without transferring the entire thread history.

Parameters:

data (Any)

continuation_token: str#

Updated token for the next incremental synchronization.

goals: list[AgentThreadGoalRecord] | None = None#

Latest snapshot of every goal declared in the thread, ordered by allocation. None means there has been no change since the previous delta — clients should retain the snapshot they already hold. An empty list means the thread has no declared goals. A non-empty list is the authoritative current snapshot and replaces any prior value.

messages_by_idx: dict[int, AgentMessage]#

New or updated messages indexed by their position in the conversation.

status: AgentThreadStatus | None = None#

Updated status of the agent thread.

title: str | None = None#

Updated title of the agent thread.

class roboto.ai.agent_thread.record.AgentThreadGoalRecord(/, **data)#

Bases: pydantic.BaseModel

Customer-visible read shape of a goal declared on an agent thread.

Parameters:

data (Any)

concluded_at: datetime.datetime | None = None#

Timestamp when the goal transitioned to a terminal state (ACHIEVED or FAILED). None while the goal is still PENDING.

created: datetime.datetime#

Timestamp when the goal was registered.

goal_data: dict[str, Any]#

The validated goal payload as JSON. Use to_agent_goal() to recover the typed model the caller declared.

goal_type: str#

Discriminator selecting which AgentGoal model the goal_data payload conforms to (e.g. "dataset_summary").

message_sequence_num: int#

Index in the thread’s full messages list of the AgentRole.USER message that declared this goal. Use to render goals adjacent to the turn they were attached to.

status: AgentGoalStatus#

Current lifecycle state of the goal.

to_agent_goal()#

Re-hydrate goal_data into the typed AgentGoal the caller declared.

Returns:

The validated, discriminated AgentGoal instance — for "dataset_summary" rows, a DatasetSummaryAgentGoal; for "dataset_triage" rows, a DatasetTriageGoal; etc.

Return type:

roboto.ai.goals.AgentGoal

class roboto.ai.agent_thread.record.AgentThreadRecord(/, **data)#

Bases: pydantic.BaseModel

Complete record of an agent thread.

Contains all the persistent data for a thread including metadata, message history, and synchronization state.

Parameters:

data (Any)

continuation_token: str#

Token used for incremental updates and synchronization.

created: datetime.datetime#

Timestamp when this agent thread was created.

created_by: str#

User ID of the person who created this agent thread.

created_from_agent_id: str | None = None#

If this thread was started via the agent launch flow, the id of the agent that produced it. None for threads started directly through POST /v1/ai/threads. Forks do not inherit this field — a fork is its own thread.

forked_from_message_sequence_num: int | None = None#

Message sequence number in the source thread that this fork was taken from.

Populated in tandem with forked_from_thread_id; both are None for threads that were not created as a fork.

forked_from_thread_id: str | None = None#

If this thread was forked, the id of the source thread. None otherwise.

Deserialization also accepts the legacy forked_from_session_id spelling for backward compatibility.

goals: list[AgentThreadGoalRecord] | None = None#

Goals declared across this thread’s turns, ordered by the turn that declared them. None means goals were not loaded for this record; an empty list means they were loaded but the thread never declared any.

messages: list[AgentMessage] = None#

Complete list of messages in the conversation.

model_profile: str | None = None#

Model profile used for this agent thread (e.g., ‘standard’, ‘advanced’).

org_id: str#

Organization ID that owns this agent thread.

status: AgentThreadStatus#

Current status of this agent thread.

thread_id: str = None#

Unique identifier for this agent thread.

Deserialization also accepts the legacy session_id and chat_id spellings for backward compatibility; the canonical attribute name is thread_id.

title: str | None = None#

Title of this agent thread.

visibility: ThreadVisibility#

Who can read this thread. PRIVATE (the default) restricts reads to the created_by user and Roboto admins; ORG opens the thread to every member of org_id.

class roboto.ai.agent_thread.record.AgentThreadStatus#

Bases: roboto.compat.StrEnum

Enumeration of possible agent thread states.

Tracks the overall status of an agent thread from creation to termination.

CLIENT_TOOL_TURN = 'client_tool_turn'#

Client must execute pending tool uses and submit results.

GOALS_FAILED = 'goals_failed'#

The agent runner exhausted its corrective re-prompt budget without achieving every declared goal for the most-recent turn. Signals to clients that the thread needs human intervention before it can continue.

NOT_STARTED = 'not_started'#

Thread has been created but no messages have been sent.

ROBOTO_TURN = 'roboto_turn'#

Roboto is generating a message.

USER_TURN = 'user_turn'#

User has the turn to send a message.

class roboto.ai.agent_thread.record.AgentThreadSubject(/, **data)#

Bases: pydantic.BaseModel

Canonical record of an entity an AgentThread applies to.

Used to answer “which agent threads are about this dataset / file?” — the dataset detail page’s Agent Threads tab is one consumer; future surfaces that want to discover threads by entity will use the same record.

Parameters:

data (Any)

association_id: str#

Identifier of the entity the thread applies to — e.g. a dataset id or file id.

model_config#

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

note: str#

Short, free-form explanation of how the subject came to be attached (e.g. why this thread applies to that entity).

class roboto.ai.agent_thread.record.AgentToolDetailResponse(/, **data)#

Bases: pydantic.BaseModel

Unsanitized tool request and response details for an agent tool invocation.

Parameters:

data (Any)

tool_result: roboto.ai.core.record.AgentToolResultContent#
tool_use: roboto.ai.core.record.AgentToolUseContent#
class roboto.ai.agent_thread.record.AgentToolResultContent(/, **data)#

Bases: pydantic.BaseModel

Tool execution result content within an agent message.

Parameters:

data (Any)

content_type: Literal[AgentContentType]#
raw_response: dict[str, Any] | None = None#

Raw, unparsed response payload from tool execution.

runtime_ms: int#

Wall-clock execution time of the tool in milliseconds.

status: str#

Outcome of the tool execution (e.g. ‘success’, ‘error’).

tool_name: str#

Name of the tool that was executed.

tool_use_id: str#

Identifier of the tool invocation this result corresponds to.

class roboto.ai.agent_thread.record.AgentToolUseContent(/, **data)#

Bases: pydantic.BaseModel

Tool usage request content within an agent message.

Parameters:

data (Any)

content_type: Literal[AgentContentType]#
input: dict[str, Any] | None = None#

Parsed tool input parameters chosen by the LLM (provider-agnostic).

raw_request: dict[str, Any] | None = None#

Raw, unparsed request payload for this tool invocation.

tool_name: str#

Name of the tool the LLM is requesting to invoke.

tool_use_id: str#

Unique identifier for this tool invocation, used to correlate with its result.

class roboto.ai.agent_thread.record.AvailableSkillSpec(/, **data)#

Bases: pydantic.BaseModel

One entry in a thread’s explicit AI-invokable skill set.

Embedded in StartAgentThreadRequest.available_skills. Unlike InvokeSkillSpec — which seeds a skill into the opening transcript as a turn trigger — this struct only declares that a skill version is available for the AI to auto-invoke via its load_skill tool during the thread. The route layer resolves access (org visibility, private gating) and version selection; this struct only carries the caller’s choice.

Defined locally to avoid the roboto.ai <-> roboto.domain.skills import cycle.

Parameters:

data (Any)

skill_id: str#

Target skill’s ID. Must be visible to the caller — an org-shared skill, or the caller’s own private skill. A subscription is not required; the per-thread set bypasses subscription state entirely.

version: int | None = None#

Optional. If omitted, resolves to the skill’s latest (MAX(version)) row.

Pins the exact version exposed to the AI for this thread. Subscriptions and their per-user ai_version pins are ignored when a thread carries an explicit available_skills set.

class roboto.ai.agent_thread.record.ClientToolResult(/, **data)#

Bases: pydantic.BaseModel

Result of executing a client-side tool.

Parameters:

data (Any)

output: dict[str, Any] | None = None#

Structured output returned by the tool.

runtime_ms: int#

Wall-clock execution time of the tool in milliseconds.

status: ClientToolResultStatus#

Outcome of the tool execution.

tool_name: str#

Name of the tool that was executed.

tool_use_id: str#

Identifier of the tool invocation this result corresponds to.

class roboto.ai.agent_thread.record.ClientToolResultStatus#

Bases: roboto.compat.StrEnum

Outcome of executing a client-side tool.

DECLINED = 'declined'#
ERROR = 'error'#
SUCCESS = 'success'#
class roboto.ai.agent_thread.record.ClientToolSpec(/, **data)#

Bases: pydantic.BaseModel

Declarative specification for a client-side tool.

Unlike AgentTool (which is an ABC with a __call__ method for server-side execution), ClientToolSpec is a plain data model. The backend includes it in the LLM’s tool list but never executes it — the client is responsible for execution and submitting the result.

Parameters:

data (Any)

description: str#
input_schema: dict[str, Any]#
name: str#
class roboto.ai.agent_thread.record.ForkAgentThreadRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload for forking an agent thread at a specific message.

Parameters:

data (Any)

message_sequence_num: int#

Highest message sequence number (inclusive) to copy into the new thread.

class roboto.ai.agent_thread.record.InvokeSkillSpec(/, **data)#

Bases: pydantic.BaseModel

Spec for invoking a skill as part of a turn trigger.

Embedded in SendMessageRequest and StartAgentThreadRequest. The route layer resolves access (org visibility, private gating) and version selection; this struct only carries the caller’s choice.

Defined locally to avoid the roboto.airoboto.domain.skills import cycle.

Parameters:

data (Any)

skill_id: str#

Target skill’s ID. Must be visible to the caller (own private skill or an org-shared skill); the route layer rejects unauthorized invocations before the spec reaches the service.

version: int | None = None#

Optional. If omitted, resolves to the skill’s latest (MAX(version)) row.

Note this is the structural latest, not the caller’s pinned ai_version: a manually-invoked chip runs MAX(version) regardless of what the caller’s AI auto-invoke is pinned to. Use Skill.set_ai_version() to control the pin separately.

class roboto.ai.agent_thread.record.SendMessageRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload for sending a message to an agent thread.

Contains the message content and optional context for the AI assistant.

Parameters:

data (Any)

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

Optional replacement analysis scope. When provided, overwrites the thread’s current analysis scope; the new scope takes effect for this turn’s tool invocations and every turn thereafter. When None, the thread’s existing analysis scope is left untouched (there is currently no wire-format way to clear a scope via send).

client_context: roboto.ai.core.ClientViewingContext | None = None#

Optional ClientViewingContext describing what the client was viewing when this message was composed. Wire field is client_context; the legacy context alias is accepted during the migration window and will be dropped in a future release.

client_tools: list[roboto.ai.core.record.ClientToolSpec] | None = None#

Optional client-side tools available for this invocation.

goals: list[roboto.ai.goals.AgentGoal] | None = None#

it gates a per-turn achieve-tool against each goal and re-prompts until every goal is satisfied or a per-turn retry budget is exhausted. May be omitted; when present, message becomes optional. Capped at MAX_GOALS_PER_TURN entries (see the constant for rationale).

Type:

Goals declared for this turn. The agent runner enforces achievement

invoke_skills: list[InvokeSkillSpec] = None#

Skills to invoke as part of this turn, in order. The server fabricates one LoadSkillTool tool_use + tool_result pair per entry and appends them to the transcript after message (if any). When message is empty and no goals are declared, the fabricated pairs become the turn trigger themselves — useful for chip-only invocations that don’t carry a typed prompt. Pass a single-element list for the common “invoke one skill” case.

message: roboto.ai.core.record.AgentMessage | None = None#

Message content to send. May be omitted when at least one goal is declared in goals; in that case the server synthesizes a minimal user message so the LLM has a turn-initiating prompt.

class roboto.ai.agent_thread.record.StartAgentThreadRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload for starting a new agent thread.

Contains the initial messages and configuration for creating a new conversation.

Parameters:

data (Any)

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

Optional analysis scope for the thread. Delivered to every tool invocation on the server side; individual tools opt in to honoring it. None means no scope.

available_skills: list[AvailableSkillSpec] | None = None#

Explicit set of skills the AI may auto-invoke during this thread, replacing the subscription-derived load_skill registry.

Tri-state:

  • None (the default) — the AI’s load_skill registry is derived per turn from the caller’s skill subscriptions, as usual.

  • [] — the AI has no auto-invokable skills for this thread.

  • a non-empty list — exactly these skill versions are auto-invokable; the caller’s subscriptions and per-user ai_version pins are ignored.

Each entry may reference any org-shared skill or the caller’s own private skill (visibility only — no subscription required), at any version. One version per skill: duplicate skill_id entries are rejected. Resolved once at thread start and frozen onto the thread; later subscription changes and skill-body edits do not propagate into it. Capped at MAX_AVAILABLE_SKILLS entries.

Distinct from invoke_skills: available_skills configures what the AI can reach for, while invoke_skills seeds skill bodies into the opening transcript as a turn trigger. It is configuration, not a trigger — a request carrying only available_skills and no messages / goals / invoke_skills is still rejected.

client_context: roboto.ai.core.ClientViewingContext | None = None#

Optional ClientViewingContext describing what the client was viewing when this thread was started. Wire field is client_context; the legacy context alias is accepted during the migration window and will be dropped in a future release.

client_tools: list[roboto.ai.core.record.ClientToolSpec] | None = None#

Optional client-side tools available for this invocation.

goals: list[roboto.ai.goals.AgentGoal] | None = None#

it gates a per-turn achieve-tool against each goal and re-prompts until every goal is satisfied or a per-turn retry budget is exhausted. May be omitted; when present, messages may be empty. Capped at MAX_GOALS_PER_TURN entries (see the constant for rationale).

Type:

Goals declared for the first turn. The agent runner enforces achievement

invoke_skills: list[InvokeSkillSpec] = None#

Skills to invoke at thread start, in order. The server fabricates one LoadSkillTool tool_use + tool_result pair per entry and appends them to the transcript after any seeded messages. When messages is empty and no goals are declared, the fabricated pairs become the thread seed. Pass a single-element list for the common “invoke one skill” case.

messages: list[roboto.ai.core.record.AgentMessage] = None#

Initial messages to start the conversation with. May be empty when at least one goal is declared in goals; in that case the server synthesizes a minimal user message so the LLM has a turn-initiating prompt.

model_profile: str | None = None#

Optional model profile ID for the thread (e.g. ‘standard’, ‘advanced’).

system_prompt: str | None = None#

Optional system prompt to customize AI assistant behavior.

visibility: roboto.ai.core.record.ThreadVisibility#

Who may read the resulting thread after it is created. PRIVATE (the default) restricts reads to the creator and Roboto admins; ORG lets any member of the thread’s org read it and makes the thread visible to org members on POST /v1/ai/threads/search. The default is PRIVATE so that a thread started via POST /v1/ai/threads does not leak to the rest of the org until the caller opts in; threads created through the agent launch flow default to ORG instead, since agents exist to share workflows across teammates.

class roboto.ai.agent_thread.record.SubmitToolResultsRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload for submitting client-side tool execution results.

Parameters:

data (Any)

client_tools: list[roboto.ai.core.record.ClientToolSpec] | None = None#

Optional updated client-side tools for the next invocation.

tool_results: list[ClientToolResult]#

Tool results from client-side execution.

class roboto.ai.agent_thread.record.ThreadVisibility#

Bases: roboto.compat.StrEnum

Read-scope for an AgentThreadRecord.

Set at thread creation time and immutable for the life of the thread. Import as roboto.ai.agent_thread.ThreadVisibility.

ORG = 'org'#

Any member of the thread’s organization (and Roboto admins) may read the thread.

Default for threads produced by the agent launch flow, since agents exist to share workflows across teammates. Forks of an ORG thread do not inherit visibility — every fork lands as PRIVATE.

PRIVATE = 'private'#

Only the creating user (and Roboto admins) may read the thread.

Default for threads created via POST /v1/ai/threads so an in-flight experiment does not leak to the rest of the org until the caller opts in.