Source Code:
src/gaia/ui/Import:
Overview
The Agent UI SDK is the Python backend that powers the GAIA Agent UI. It provides:- FastAPI REST server with session, chat, and document endpoints
- SQLite database for persistent sessions, messages, and document metadata
- SSE streaming for real-time chat responses
- RAG integration for document Q&A
- Pydantic models for request/response validation
4200 by default and serves both the Electron desktop app and browser-based clients.
Quick Start
Start the Server
Use the Database Directly
Core Classes
ChatDatabase
The persistence layer for all Agent UI data. Uses SQLite with WAL mode for concurrent read access.Session Methods
| Method | Signature | Description |
|---|---|---|
create_session | (title?, model?, system_prompt?, document_ids?) -> Dict | Create a new chat session |
get_session | (session_id) -> Optional[Dict] | Get session by ID with message count and document IDs |
list_sessions | (limit=50, offset=0) -> List[Dict] | List sessions ordered by most recently updated |
count_sessions | () -> int | Count total sessions |
update_session | (session_id, title?, system_prompt?) -> Optional[Dict] | Update session title and/or system prompt |
delete_session | (session_id) -> bool | Delete a session and its messages (cascading) |
touch_session | (session_id) -> None | Update the session’s updated_at timestamp |
Message Methods
| Method | Signature | Description |
|---|---|---|
add_message | (session_id, role, content, rag_sources?, tokens_prompt?, tokens_completion?) -> int | Add a message, returns message ID |
get_messages | (session_id, limit=100, offset=0) -> List[Dict] | Get messages oldest-first |
count_messages | (session_id) -> int | Count messages in a session |
Document Methods
| Method | Signature | Description |
|---|---|---|
add_document | (filename, filepath, file_hash, file_size?, chunk_count?) -> Dict | Add document to library (deduplicates by hash) |
get_document | (doc_id) -> Optional[Dict] | Get document by ID |
list_documents | () -> List[Dict] | List all documents |
delete_document | (doc_id) -> bool | Delete a document |
attach_document | (session_id, document_id) -> bool | Attach document to session |
detach_document | (session_id, document_id) -> bool | Detach document from session |
get_session_documents | (session_id) -> List[Dict] | Get all documents for a session |
Statistics
create_app()
Factory function that creates and configures the FastAPI application with all endpoints.app.state.db and is accessible in tests:
Pydantic Models
All request and response bodies use Pydantic models fromgaia.ui.models.
System
Sessions
Chat
Messages
Documents
REST API Endpoints
System
GET /api/system/status
GET /api/system/status
Check system readiness for the agent UI.Response:
GET /api/health
GET /api/health
Health check with database statistics.Response:
POST /api/system/load-model
POST /api/system/load-model
Trigger loading a model on the Lemonade server. Returns
Response (202):
202 immediately; loading proceeds in the background. Poll GET /api/system/status to detect when loading completes.Request:| Field | Type | Required | Description |
|---|---|---|---|
model_name | string | Yes | Name of the model to load. |
ctx_size | number | No | Context window size in tokens. Defaults to 32768. |
POST /api/system/download-model
POST /api/system/download-model
Trigger downloading a model via the Lemonade server. Returns
Response (202):
202 immediately; the download proceeds in the background. Poll GET /api/system/status to detect when the model becomes available. Set force to true to re-download even if the file already exists (repairs corrupted or incomplete downloads).Request:| Field | Type | Required | Description |
|---|---|---|---|
model_name | string | Yes | Name of the model to download. |
force | boolean | No | Re-download even if the model already exists. Defaults to false. |
GET /api/settings
GET /api/settings
Get current user settings including the custom model override and its status on the Lemonade server.Response:
| Field | Type | Description |
|---|---|---|
custom_model | string or null | HuggingFace model ID overriding the default, or null if using the default model. |
model_status | object or null | Status of the custom model on Lemonade. null when no custom model is set. Contains found (in catalog), downloaded (on disk), and loaded (currently active). |
PUT /api/settings
PUT /api/settings
Update user settings. Set
Response: Same shape as
custom_model to a model ID to override the default, or to an empty string / null to clear the override and revert to the default model.Request:| Field | Type | Required | Description |
|---|---|---|---|
custom_model | string or null | No | HuggingFace model ID to use instead of the default. Empty string or null clears the override. |
GET /api/settings.Sessions
POST /api/sessions
POST /api/sessions
Create a new chat session.Request:Response:
SessionResponseGET /api/sessions
GET /api/sessions
List all sessions, ordered by most recently updated.Query params:
limit (default 50), offset (default 0)Response: SessionListResponseGET /api/sessions/{session_id}
GET /api/sessions/{session_id}
Get session details including message count and attached document IDs.Response:
SessionResponsePUT /api/sessions/{session_id}
PUT /api/sessions/{session_id}
Update session title or system prompt.Request:
DELETE /api/sessions/{session_id}
DELETE /api/sessions/{session_id}
Delete a session and all its messages (cascading delete).
GET /api/sessions/{session_id}/messages
GET /api/sessions/{session_id}/messages
Get messages for a session, ordered oldest first.Query params:
limit (default 100), offset (default 0)Response: MessageListResponseGET /api/sessions/{session_id}/export
GET /api/sessions/{session_id}/export
Export a session to Markdown or JSON.Query params:
format (“markdown” or “json”, default “markdown”)Chat
POST /api/chat/send
POST /api/chat/send
Send a message and receive a response. Supports both streaming (SSE) and non-streaming modes.Request:Streaming response (SSE events):When
Tool Execution
Response Content
Stream Termination
Example stream showing a typical multi-step interaction:Non-streaming response:
stream: true, the server returns a text/event-stream response. Each line follows the SSE format data: <JSON>. The SSEOutputHandler (src/gaia/ui/sse_handler.py) bridges agent console events to the following typed events:Thinking and Progress| Event type | Fields | Description |
|---|---|---|
thinking | content (string) | Agent reasoning or progress message. Emitted when the agent starts processing, thinks through a problem, or begins a long-running operation. |
step | step (int), total (int), status (string) | Agent step progress. step is the current step number, total is the step limit, and status is "started". |
status | status (string), message (string) | General status update. status is one of "working", "complete", "warning", or "info". May also include steps (int) and elapsed (number) when status is "complete". |
plan | steps (string[]), current_step (int or null) | Agent execution plan. Each entry in steps is a human-readable description of a planned action. |
| Event type | Fields | Description |
|---|---|---|
tool_start | tool (string), detail (string) | Tool invocation started. tool is the tool function name (e.g., "query_documents", "search_file"). detail is a human-readable description of the operation. |
tool_args | tool (string), args (object), detail (string) | Tool arguments. args is the raw arguments dict passed to the tool. detail is a formatted human-readable summary of the arguments. |
tool_end | success (boolean) | Tool invocation completed. |
tool_result | title (string or null), summary (string), success (boolean), result_data (object or null), command_output (object or null) | Tool result with structured data. summary is a human-readable result. result_data contains typed results (see below). command_output contains shell command output (see below). |
result_data variants in tool_result:- File list:
{"type": "file_list", "files": [...], "total": int}— up to 20 file entries - Search results:
{"type": "search_results", "count": int, "scores": float[], "previews": string[]}— top 5 chunk previews (200 chars each)
command_output shape in tool_result:| Event type | Fields | Description |
|---|---|---|
chunk | content (string) | Incremental text fragment of the response, streamed as the LLM generates tokens. Raw tool-call JSON is automatically filtered out. |
answer | content (string), elapsed (number), steps (int), tools_used (int) | Final complete answer from the agent. elapsed is wall-clock seconds. steps and tools_used are execution totals. Double-escaped newlines/tabs from LLM output are automatically corrected. |
agent_error | content (string) | Error message from the agent. |
| Event type | Fields | Description |
|---|---|---|
done | message_id (int), content (string) | Signals the end of the stream. message_id is the database ID of the saved assistant message. content is the full response text. |
Documents
GET /api/documents
GET /api/documents
List all documents in the global library.Response:
POST /api/documents/upload-path
POST /api/documents/upload-path
Index a document by file path. The file is hashed for deduplication — if the same file was already indexed, the existing document is returned.Request:Response:
DocumentResponseDELETE /api/documents/{doc_id}
DELETE /api/documents/{doc_id}
Remove a document from the library and all session attachments.
POST /api/sessions/{session_id}/documents
POST /api/sessions/{session_id}/documents
Attach a document from the library to a session.Request:
DELETE /api/sessions/{session_id}/documents/{doc_id}
DELETE /api/sessions/{session_id}/documents/{doc_id}
Detach a document from a session (does not delete the document).
Files
POST /api/files/open
POST /api/files/open
Open a file or folder in the system file explorer. On Windows this launches Explorer, on macOS it uses
Response:Error responses:
open, and on Linux it uses xdg-open. Symbolic links are rejected for security.Request:| Field | Type | Description |
|---|---|---|
path | string | Absolute path to the file or folder to open. |
reveal | boolean | If true (default), reveal the file selected in its parent folder. If false, open the containing folder directly. Ignored when path is a directory. |
| Status | Condition |
|---|---|
400 | Invalid path (empty or contains null bytes), or path is a symbolic link |
404 | Path does not exist |
500 | Failed to launch the system file explorer |
Database Schema
The Agent UI uses SQLite with four tables:The
indexing_status, file_mtime, and agent_steps columns are added via migrations for databases created before these columns existed. New databases include them in the initial schema.Testing
Unit Testing with In-Memory Database
Database Testing
Integration with the Agent
The Agent UI server delegates to the GAIA Agent for LLM communication and tool execution:npm Package
GAIA Agent UI is also available as an npm package for quick installation:gaia-ui CLI command:
gaia-ui automatically installs the Python backend (uv, Python 3.12, amd-gaia) if not already present. On subsequent runs, it auto-updates if the version doesn’t match.
Package Contents
The npm package includes:| Path | Description |
|---|---|
bin/gaia-ui.mjs | CLI entry point (Node.js) |
dist/ | Pre-built frontend (React SPA) |
Release Management
The package version is sourced fromsrc/gaia/version.py (single source of truth for all of GAIA):
v* trigger the automated npm publish workflow.
Related
- User Guide — Desktop app usage, features, and troubleshooting
- Agent SDK — Core Agent SDK with memory and RAG
- RAG SDK — Document indexing and retrieval
- Desktop App Installation — Download and install instructions