Documentation

Chat Types

Types for agentic chat sessions and responses

ChatSessionContext

Context manager for session lifecycle (recommended pattern)

class ChatSessionContext:
"""Use via client.chat_session() - manages session creation and cleanup."""
# Properties (available after entering context)
session_id: str # The underlying session ID
session: ChatSession # Full session object
# Methods
async def send(
self,
message: str,
*,
force_detailed_analysis: bool = False,
) -> ChatResponse: ...
async def send_stream(
self,
message: str,
*,
force_detailed_analysis: bool = False,
) -> AsyncIterator[ChatToken]: ...
async def update_images(self, image_ids: list[str]) -> dict: ...
async def update_documents(self, document_ids: list[str]) -> dict: ...
async def approve_plan(self, plan_id: str) -> PlanActionResponse: ...
async def cancel_plan(self, plan_id: str) -> PlanActionResponse: ...
async def get_messages(self, *, limit: Optional[int] = None) -> list[ChatMessage]: ...
# Usage:
async with client.chat_session(title="Analysis") as session:
response = await session.send("Find damaged equipment")
followup = await session.send("Tell me more")
# Session automatically closed on exit

ChatResponse

Response from a chat message

@dataclass(frozen=True)
class ChatResponse:
message_id: str # Unique message identifier
session_id: str # Session this message belongs to
content: str # Response text (may contain [[...]] markup)
token_count: int = 0 # Tokens used
provider: str = "" # AI provider used
model: str = "" # Model used
processing_time_ms: int = 0 # Time to generate response
images: Optional[list[ImageReference]] = None # Images found or referenced
metadata: Optional[dict[str, Any]] = None # Additional response metadata
# Properties (computed)
@property
def resolved_content(self) -> str:
"""Content with all [[...]] markup replaced by plain text."""
@property
def references(self) -> ParsedReferences:
"""Structured parsed references from the content."""
@property
def result_refs(self) -> dict[str, ResultRefData]:
"""Count refs from metadata, parsed as ResultRefData objects."""
def as_collection(self) -> FileCollection:
"""Build a FileCollection from images."""
...
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ChatToken

Single token/event in streaming response

@dataclass(frozen=True)
class ChatToken:
type: ChatTokenType # See ChatTokenType enum for all values
content: Optional[str] = None # Text content (for token events)
data: Optional[dict[str, Any]] = None # Full event data
# Properties (only return values for COMPLETE tokens, None otherwise)
@property
def resolved_content(self) -> Optional[str]:
"""Content with markup replaced (COMPLETE tokens only)."""
@property
def references(self) -> Optional[ParsedReferences]:
"""Parsed references (COMPLETE tokens only)."""
@property
def result_refs(self) -> Optional[dict[str, ResultRefData]]:
"""Count refs (COMPLETE tokens only)."""
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ChatSession

Basic chat session information

@dataclass(frozen=True)
class ChatSession:
id: str # Session identifier
title: str # Session title
total_messages: int # Number of messages
total_tokens: int # Total tokens used
remaining_tokens: int # Tokens remaining
remaining_messages: int # Messages remaining
is_active: bool # Whether session is active
use_all_images: bool # Using all images as context
selected_image_count: int # Number of selected images
created_at: Optional[datetime]
updated_at: Optional[datetime]
last_message_at: Optional[datetime]
last_message_preview: Optional[str]
last_user_message: Optional[str]
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ChatSessionDetail

Detailed session with message history

@dataclass(frozen=True)
class ChatSessionDetail:
session: ChatSession # Basic session info
messages: list[ChatMessage] # List of messages
selected_image_ids: Optional[list[str]]
current_search_result_ids: Optional[list[str]]
def as_collection(self) -> FileCollection:
"""Build a FileCollection from search result IDs or selected images."""
...
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ChatMessage

A message in a chat session

@dataclass(frozen=True)
class ChatMessage:
id: str # Message identifier
role: MessageRole # USER, ASSISTANT, or SYSTEM
content: str # Message text (may contain [[...]] markup)
created_at: Optional[datetime] = None
token_count: int = 0
image_context: Optional[list[ImageReference]] = None
metadata: Optional[dict[str, Any]] = None
# Properties (computed)
@property
def resolved_content(self) -> str:
"""Content with all [[...]] markup replaced by plain text."""
@property
def references(self) -> ParsedReferences:
"""Structured parsed references from the content."""
@property
def result_refs(self) -> dict[str, ResultRefData]:
"""Count refs from metadata, parsed as ResultRefData objects."""
def as_collection(self) -> FileCollection:
"""Build a FileCollection from image_context."""
...
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ImageReference

Reference to an image in chat context

@dataclass(frozen=True)
class ImageReference:
image_id: str # Unique image identifier
filename: str # Original filename
thumbnail_url: Optional[str] # URL to thumbnail
description: Optional[str] # Image description
confidence: Optional[float] # Description confidence
title: Optional[str] # Image title
stored_url: Optional[str] # URL to full image
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

SessionList

Paginated list of chat sessions

@dataclass(frozen=True)
class SessionList:
items: list[ChatSession] # List of sessions
total: int # Total number of sessions
has_more: bool # Whether more sessions exist
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

PlanActionResponse

Response from approving or cancelling an execution plan

@dataclass(frozen=True)
class PlanActionResponse:
success: bool # Whether the action was successful
plan_id: str # The plan identifier
message: str # Human-readable result message
action_taken: str # "approve" or "cancel"
results: Optional[dict[str, Any]] = None # Execution results (synchronous completions)
agent_results: Optional[list[dict[str, Any]]] = None # Detailed results from each agent
pending_actions: Optional[list[dict[str, Any]]] = None # Actions requiring further confirmation
status: Optional[str] = None # Async status ("accepted" for 202 responses)
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

ChatImageList

Paginated list of image IDs available for chat context

@dataclass(frozen=True)
class ChatImageList:
image_ids: list[str] # List of image ID strings
total_count: int # Total number of images available
has_more: bool # Whether more images exist beyond this page
def as_collection(self) -> FileCollection:
"""Build a FileCollection from image_ids."""
...
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

PlanPendingApprovalData

Data structure for plan_pending_approval server event (received as ChatTokenType.PLAN_PENDING_APPROVAL)

# When token.type == ChatTokenType.PLAN_PENDING_APPROVAL,
# token.data contains:
{
"type": "plan_pending_approval",
"plan_id": str, # Unique plan ID (use with approve_plan() / cancel_plan())
"description": str, # Human-readable description of the plan
"invocations": [ # List of agent operations in the plan
{
"agent_name": str, # e.g., "ImageSearchAgent", "FolderOrganizationAgent"
"description": str, # What this agent will do
"depends_on": list # IDs of invocations this depends on (for ordering)
}
],
"requires_approval": bool, # Always True for this event
"estimated_operations": int # Number of operations in the plan
}

Reference Types

Typed models for parsed [[...]] markup patterns in chat content. Available via from aion import ImageRef, DocumentRef, LinkRef, ParsedReferences.

ParsedReferences

Container returned by .references property and parse_references()

@dataclass(frozen=True)
class ParsedReferences:
images: list[ImageRef] # From [[img:ID|filename]] patterns
documents: list[DocumentRef] # From [[doc:ID|filename|p:N]] patterns
links: list[LinkRef] # From [[link:ID|title]] patterns
counts: dict[str, ResultRefData] # From [[ref:KEY]] patterns
@property
def has_references(self) -> bool:
"""True if any references were found."""

ImageRef

Parsed from [[img:ID|filename]]

@dataclass(frozen=True)
class ImageRef:
id_prefix: str # Short ID prefix from markup
filename: str # Display filename
full_id: Optional[str] # Full UUID (resolved from image_context)

DocumentRef

Parsed from [[doc:ID|filename]] or [[doc:ID|filename|p:5]]

@dataclass(frozen=True)
class DocumentRef:
id_prefix: str # Short ID prefix from markup
filename: str # Display filename
full_id: Optional[str] # Full UUID (resolved from tool_document_data)
page: Optional[int] # Single page (from p:N)
page_range: Optional[tuple[int, int]] # Page range (from pp:N-M)

LinkRef

Parsed from [[link:ID|title]]

@dataclass(frozen=True)
class LinkRef:
id_prefix: str # Short ID prefix from markup
title: str # Display title
full_id: Optional[str] # Full UUID (resolved from tool_link_data)
source_url: Optional[str] # Original URL
domain: Optional[str] # Domain name

Utility Functions

Standalone functions for working with reference markup

from aion import parse_references, resolve_content
# Replace all [[...]] markup with plain text
plain_text = resolve_content(content, metadata)
# Parse into typed objects
refs = parse_references(content, metadata)
# refs.images -> list[ImageRef]
# refs.documents -> list[DocumentRef]
# refs.links -> list[LinkRef]
# refs.counts -> dict[str, ResultRefData]