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 exitChatResponse
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 nameUtility Functions
Standalone functions for working with reference markup
from aion import parse_references, resolve_content
# Replace all [[...]] markup with plain textplain_text = resolve_content(content, metadata)
# Parse into typed objectsrefs = parse_references(content, metadata)# refs.images -> list[ImageRef]# refs.documents -> list[DocumentRef]# refs.links -> list[LinkRef]# refs.counts -> dict[str, ResultRefData]