Architecture Overview
This document provides a comprehensive overview of Home Agent's architecture, including component relationships, data flow, and module structure.
Table of Contents
High-Level Architecture
Home Agent is built as a modular Home Assistant custom component that integrates with the native conversation platform. The architecture follows a layered design with clear separation of concerns.
graph TB
subgraph "Home Assistant"
HA[Home Assistant Core]
ConvPlatform[Conversation Platform]
Entities[Entity Registry]
Services[Services]
end
subgraph "Home Agent Core"
Agent[HomeAgent<br/>Main Orchestrator]
ContextMgr[ContextManager<br/>Context Injection]
ConvHistory[ConversationHistoryManager<br/>History Tracking]
ToolHandler[ToolHandler<br/>Tool Execution]
SessionMgr[ConversationSessionManager<br/>Persistent Sessions]
end
subgraph "Context Providers"
DirectProvider[DirectContextProvider<br/>Entity Filtering]
VectorDBProvider[VectorDBContextProvider<br/>Semantic Search]
MemoryProvider[MemoryContextProvider<br/>Long-term Memory]
end
subgraph "Tools"
HAControl[HomeAssistantControlTool<br/>Device Control]
HAQuery[HomeAssistantQueryTool<br/>State Queries]
ExternalLLM[ExternalLLMTool<br/>Delegate to Other LLM]
CustomTools[CustomToolHandler<br/>REST/Service Tools]
MemoryTools[Memory Tools<br/>Store/Recall]
end
subgraph "Storage & External"
MemoryMgr[MemoryManager<br/>Long-term Storage]
VectorDB[(ChromaDB<br/>Vector Storage)]
LLM[LLM Provider<br/>OpenAI/Ollama/etc]
HAStore[(Home Assistant<br/>Storage)]
end
ConvPlatform -->|process input| Agent
Agent --> ContextMgr
Agent --> ConvHistory
Agent --> ToolHandler
Agent --> SessionMgr
ContextMgr --> DirectProvider
ContextMgr --> VectorDBProvider
ContextMgr --> MemoryProvider
DirectProvider --> Entities
VectorDBProvider --> VectorDB
MemoryProvider --> MemoryMgr
ToolHandler --> HAControl
ToolHandler --> HAQuery
ToolHandler --> ExternalLLM
ToolHandler --> CustomTools
ToolHandler --> MemoryTools
HAControl --> Services
HAQuery --> Entities
CustomTools --> Services
MemoryTools --> MemoryMgr
Agent -->|API calls| LLM
ConvHistory --> HAStore
MemoryMgr --> HAStore
MemoryMgr --> VectorDB
SessionMgr --> HAStore
style Agent fill:#4CAF50
style ContextMgr fill:#2196F3
style ToolHandler fill:#FF9800
style MemoryMgr fill:#9C27B0
Key Components
- HomeAgent: Central orchestrator that coordinates all operations
- ContextManager: Manages entity context injection strategies
- ConversationHistoryManager: Tracks conversation history across turns
- ToolHandler: Registers and executes tools called by the LLM
- MemoryManager: Handles long-term memory storage and retrieval
- ConversationSessionManager: Manages persistent voice conversation sessions
Conversation Flow
This diagram shows the complete flow of a user conversation through the system, including context injection, tool calling, and memory extraction.
sequenceDiagram
participant User
participant HA as Home Assistant
participant Agent as HomeAgent
participant Context as ContextManager
participant Memory as MemoryManager
participant LLM as LLM Provider
participant Tools as ToolHandler
participant History as ConversationHistory
participant Session as SessionManager
User->>HA: Voice/Text Input
HA->>Agent: async_process(user_input)
Note over Agent: Ensure tools registered
Agent->>Session: get_conversation_id(user, device)
Session-->>Agent: conversation_id
Note over Agent,Memory: Context Assembly Phase
par Parallel Context Retrieval
Agent->>Context: get_formatted_context(user_input)
Context->>Context: get_context (entities)
Context->>Memory: get_context (memories)
end
Context-->>Agent: formatted_context
Agent->>History: get_history(conversation_id)
History-->>Agent: previous_messages
Note over Agent: Build System Prompt
Agent->>Agent: _build_system_prompt(context)
Note over Agent,Tools: LLM Interaction Loop (max 5 iterations)
loop Tool Calling Loop
Agent->>LLM: call_llm(messages, tools)
LLM-->>Agent: response (content + tool_calls)
alt Has Tool Calls
Agent->>Tools: execute_tool(name, params)
Tools->>Tools: validate_tool_call
alt Tool Type: ha_control
Tools->>HA: call_service(entity_id, action)
HA-->>Tools: result
else Tool Type: ha_query
Tools->>HA: get_state(entity_id)
HA-->>Tools: state
else Tool Type: custom
Tools->>HA: REST/Service call
HA-->>Tools: result
end
Tools-->>Agent: tool_result
Agent->>Agent: Add tool result to messages
else No Tool Calls
Note over Agent: Final response ready
end
end
Note over Agent,History: Save & Extract
Agent->>History: add_message(user + assistant)
History->>History: persist to storage
par Async Memory Extraction
Agent->>Agent: _extract_and_store_memories
Agent->>LLM: Extract memories from conversation
LLM-->>Agent: extracted_memories
Agent->>Memory: add_memory(content, type, importance)
Memory->>Memory: Check duplicates, store
end
Agent->>Session: update_activity(user, device)
Agent-->>HA: ConversationResult
HA-->>User: Response (voice/text)
Note over Agent: Emit Events
Agent->>HA: Fire conversation_finished event
Flow Stages
- Input Processing: User input received via Home Assistant conversation platform
- Session Management: Retrieve or create persistent conversation session
- Context Assembly: Parallel retrieval of entity context and memory context
- History Integration: Load previous conversation messages
- LLM Interaction: Iterative loop supporting multiple tool calls per turn
- Tool Execution: Execute tools based on LLM decisions
- Response Generation: Final response from LLM after all tool calls
- Persistence: Save conversation history and extract memories
- Event Emission: Fire Home Assistant events for observability
Module Structure
This diagram shows the directory layout and key classes within the Home Agent codebase.
graph TD
subgraph "custom_components/home_agent/"
Init["__init__.py<br/>• async_setup<br/>• async_setup_entry<br/>• Service registration"]
subgraph "agent/"
AgentCore["core.py<br/>HomeAgent<br/>• async_process<br/>• process_message<br/>• _process_conversation"]
AgentLLM["llm.py<br/>LLMMixin<br/>• _call_llm<br/>• _call_llm_streaming"]
AgentStream["streaming.py<br/>StreamingMixin<br/>• _async_process_streaming<br/>• _can_stream"]
AgentMemExt["memory_extraction.py<br/>MemoryExtractionMixin<br/>• _extract_and_store_memories"]
end
subgraph "context_providers/"
ProviderBase["base.py<br/>ContextProvider<br/>• Abstract interface"]
ProviderDirect["direct.py<br/>DirectContextProvider<br/>• Entity filtering"]
ProviderVectorDB["vector_db.py<br/>VectorDBContextProvider<br/>• Semantic search"]
ProviderMemory["memory.py<br/>MemoryContextProvider<br/>• Memory injection"]
end
subgraph "tools/"
ToolRegistry["registry.py<br/>ToolRegistry<br/>• Tool registration"]
ToolHAControl["ha_control.py<br/>HomeAssistantControlTool<br/>• turn_on/off/toggle"]
ToolHAQuery["ha_query.py<br/>HomeAssistantQueryTool<br/>• get_state"]
ToolExtLLM["external_llm.py<br/>ExternalLLMTool<br/>• Delegate queries"]
ToolCustom["custom.py<br/>CustomToolHandler<br/>• REST/Service tools"]
ToolMemory["memory_tools.py<br/>• StoreMemoryTool<br/>• RecallMemoryTool"]
end
subgraph "config/"
ConfigFlow["flow.py<br/>• Configuration UI flows"]
ConfigSchemas["schemas.py<br/>• Config validation schemas"]
ConfigValidators["validators.py<br/>• Field validators"]
end
ContextManager["context_manager.py<br/>ContextManager<br/>• get_formatted_context<br/>• Provider orchestration"]
Conversation["conversation.py<br/>ConversationHistoryManager<br/>• add_message<br/>• get_history<br/>• Persistence"]
ConvSession["conversation_session.py<br/>ConversationSessionManager<br/>• Session tracking<br/>• Auto-expiration"]
ToolHandlerMain["tool_handler.py<br/>ToolHandler<br/>• execute_tool<br/>• validate_tool_call<br/>• Metrics"]
MemoryManagerMain["memory_manager.py<br/>MemoryManager<br/>• add_memory<br/>• search_memories<br/>• Dual storage"]
VectorDBManager["vector_db_manager.py<br/>VectorDBManager<br/>• ChromaDB interface<br/>• Embeddings"]
Streaming["streaming.py<br/>OpenAIStreamingHandler<br/>• Stream transformation<br/>• Token usage tracking"]
ConfigFlowMain["config_flow.py<br/>HomeAgentConfigFlow<br/>• UI configuration<br/>• Options flow"]
Const["const.py<br/>• Constants<br/>• Defaults<br/>• Event names"]
Exceptions["exceptions.py<br/>• Custom exceptions"]
Helpers["helpers.py<br/>• Utility functions"]
end
Init --> AgentCore
Init --> MemoryManagerMain
Init --> VectorDBManager
Init --> ConvSession
AgentCore --> AgentLLM
AgentCore --> AgentStream
AgentCore --> AgentMemExt
AgentCore --> ContextManager
AgentCore --> Conversation
AgentCore --> ToolHandlerMain
AgentCore --> ConvSession
ContextManager --> ProviderBase
ProviderBase --> ProviderDirect
ProviderBase --> ProviderVectorDB
ProviderBase --> ProviderMemory
ProviderVectorDB --> VectorDBManager
ProviderMemory --> MemoryManagerMain
ToolHandlerMain --> ToolHAControl
ToolHandlerMain --> ToolHAQuery
ToolHandlerMain --> ToolExtLLM
ToolHandlerMain --> ToolCustom
ToolHandlerMain --> ToolMemory
ToolMemory --> MemoryManagerMain
AgentStream --> Streaming
ConfigFlowMain --> ConfigFlow
ConfigFlowMain --> ConfigSchemas
ConfigFlowMain --> ConfigValidators
style AgentCore fill:#4CAF50
style ContextManager fill:#2196F3
style ToolHandlerMain fill:#FF9800
style MemoryManagerMain fill:#9C27B0
Directory Organization
custom_components/home_agent/
├── agent/ # Main agent implementation (mixin-based)
│ ├── core.py # HomeAgent orchestrator class
│ ├── llm.py # LLM API communication
│ ├── streaming.py # Streaming response support
│ └── memory_extraction.py # Memory extraction logic
├── context_providers/ # Context injection strategies
│ ├── base.py # Abstract provider interface
│ ├── direct.py # Direct entity filtering
│ ├── vector_db.py # ChromaDB semantic search
│ └── memory.py # Memory-based context
├── tools/ # LLM-callable tools
│ ├── ha_control.py # Home Assistant control
│ ├── ha_query.py # Home Assistant queries
│ ├── external_llm.py # External LLM delegation
│ ├── custom.py # Custom REST/service tools
│ └── memory_tools.py # Memory operations
├── config/ # Configuration management
│ ├── flow.py # Config flow steps
│ ├── schemas.py # Validation schemas
│ └── validators.py # Field validators
├── context_manager.py # Context orchestration
├── conversation.py # History management
├── conversation_session.py # Session persistence
├── tool_handler.py # Tool execution
├── memory_manager.py # Long-term memory
├── vector_db_manager.py # ChromaDB interface
├── streaming.py # Streaming utilities
├── config_flow.py # UI configuration
└── const.py # Constants & defaults
Component Details
HomeAgent (Core)
Purpose: Central orchestrator for all conversation-related functionality
Responsibilities:
- Process user inputs through Home Assistant's conversation platform
- Build and manage conversation context (system prompts, entity states)
- Execute multi-turn conversations with tool calling support
- Coordinate between LLM, tools, and Home Assistant services
- Track conversation history and metrics
- Support both streaming and synchronous response modes
Key Methods:
async_process(): Main entry point from Home Assistantprocess_message(): Direct message processing_process_conversation(): Tool calling loop implementation_build_system_prompt(): Construct system prompt with context
Architecture: Uses mixin-based design inheriting from:
LLMMixin: LLM API communicationStreamingMixin: Real-time streaming responsesMemoryExtractionMixin: Automatic memory extractionAbstractConversationAgent: Home Assistant integration
ContextManager
Purpose: Manages context injection strategies for LLM conversations
Responsibilities:
- Orchestrate different context providers (direct, vector DB, memory)
- Optimize context size to stay within token limits
- Cache context when appropriate
- Fire events for observability
Context Modes:
- Direct Mode: Static entity list, always includes configured entities
- Vector DB Mode: Dynamic semantic search based on user query
- Memory Mode: Inject relevant long-term memories
Key Methods:
get_formatted_context(): Main entry point, returns optimized contextget_context(): Retrieve raw context from provider(s)_optimize_context_size(): Compress and truncate if neededset_provider(): Switch context strategyset_memory_provider(): Enable memory context
ConversationHistoryManager
Purpose: Maintain conversation history across multiple turns
Features:
- Per-conversation history tracking
- Message and token limits
- Persistent storage across Home Assistant restarts
- Debounced saves to reduce I/O
- Token estimation for context management
Storage Format:
{
"version": 1,
"conversations": {
"conversation_id": [
{"role": "user", "content": "...", "timestamp": 1234567890},
{"role": "assistant", "content": "..."}
]
}
}
Key Methods:
add_message(): Add message to historyget_history(): Retrieve recent messages with limitsclear_history(): Clear specific conversationestimate_tokens(): Estimate token usage
ToolHandler
Purpose: Manage tool registration, validation, and execution
Features:
- Tool registration and validation
- Timeout enforcement
- Parallel tool execution support
- Execution metrics tracking
- Tool progress events
Tool Interface: Each tool must implement:
name: Unique tool identifierexecute(**params): Async execution methodget_definition(): Return tool schemato_openai_format(): Format for LLM consumption
Key Methods:
register_tool(): Add tool to registryexecute_tool(): Execute with timeout and metricsget_tool_definitions(): Format all tools for LLMvalidate_tool_call(): Pre-execution validation
MemoryManager
Purpose: Long-term memory storage and retrieval system
Features:
- Dual storage: Home Assistant Store + ChromaDB
- Memory types: facts, preferences, context, events
- Importance scoring with decay
- Deduplication via semantic similarity
- TTL-based expiration
- Periodic cleanup
Memory Lifecycle:
- Extraction: Async extraction from conversations
- Validation: Filter out transient/low-quality content
- Deduplication: Check semantic similarity to existing memories
- Storage: Store in both HA Store and ChromaDB
- Retrieval: Semantic search based on user queries
- Decay: Importance score decreases over time
- Expiration: Remove based on TTL and importance
Key Methods:
add_memory(): Store new memory with deduplicationsearch_memories(): Semantic similarity searchapply_importance_decay(): Reduce importance over time_cleanup_expired_memories(): Remove expired memories
ConversationSessionManager
Purpose: Maintain persistent conversation sessions for voice interactions
Features:
- User/device-based session mapping
- Automatic expiration (configurable timeout)
- Persistent storage across restarts
- Session activity tracking
Use Case: Enables natural multi-turn voice conversations where follow-up questions maintain context without explicitly providing conversation IDs.
Example:
User: "What's the temperature in the living room?"
Agent: "The living room is 72°F"
[Later, same device]
User: "What about the bedroom?"
Agent: "The bedroom temperature is 68°F" # Maintains context
Data Flow Patterns
Context Injection Pattern
flowchart LR
Input[User Input] --> ContextMgr
subgraph Parallel Context Retrieval
ContextMgr --> EntityContext[Entity Context<br/>Direct or VectorDB]
ContextMgr --> MemoryContext[Memory Context<br/>If enabled]
end
EntityContext --> Combine
MemoryContext --> Combine
Combine[Combine Contexts] --> Optimize[Optimize Size<br/>Token limits]
Optimize --> SystemPrompt[System Prompt]
Tool Execution Pattern
flowchart TD
LLMResponse[LLM Response] --> CheckTools{Has Tool Calls?}
CheckTools -->|No| FinalResponse[Return Response]
CheckTools -->|Yes| ValidateTools[Validate Tool Calls]
ValidateTools --> ExecuteParallel[Execute Tools<br/>in Parallel]
ExecuteParallel --> Timeout[Apply Timeout]
Timeout --> Results[Collect Results]
Results --> AddToMessages[Add Results to Messages]
AddToMessages --> NextIteration[Next LLM Call]
NextIteration --> CheckTools
CheckTools -->|Max iterations<br/>reached| MaxError[Return Error]
Memory Storage Pattern
flowchart TD
ConvEnd[Conversation Ends] --> Extract[Extract Memories<br/>via LLM]
Extract --> Validate{Valid Memory?}
Validate -->|No - Transient| Skip[Skip]
Validate -->|Yes| CheckDup{Check Duplicates<br/>Semantic Similarity}
CheckDup -->|Duplicate Found| Merge[Merge with Existing<br/>Boost importance]
CheckDup -->|No Duplicate| CreateNew[Create New Memory]
Merge --> StoreHA[Store in HA Store]
CreateNew --> StoreHA
StoreHA --> StoreChroma[Store in ChromaDB<br/>with embedding]
StoreChroma --> CheckLimit{Over limit?}
CheckLimit -->|Yes| Prune[Prune low-importance<br/>memories]
CheckLimit -->|No| Done[Done]
Prune --> Done
Session Persistence Pattern
flowchart TD
Input[User Input] --> CheckSession{Session Exists<br/>for user/device?}
CheckSession -->|Yes| GetConvID[Get Conversation ID]
CheckSession -->|No| CreateConvID[Create New<br/>Conversation ID]
GetConvID --> CheckTimeout{Session<br/>Expired?}
CheckTimeout -->|Yes| CreateConvID
CheckTimeout -->|No| UseExisting[Use Existing Session]
CreateConvID --> StoreMapping[Store Session Mapping]
StoreMapping --> Process[Process Conversation]
UseExisting --> Process
Process --> UpdateActivity[Update Session Activity]
UpdateActivity --> Done[Done]
Integration Points
Home Assistant Integration
- Conversation Platform: Registers as
AbstractConversationAgent - Entity Registry: Accesses entity states and metadata
- Service Calls: Executes Home Assistant services via tools
- Storage: Uses
Storehelper for persistence - Events: Fires custom events for observability
- Config Flow: Provides UI configuration
External Integrations
- LLM Providers: OpenAI-compatible API (OpenAI, Ollama, LocalAI, etc.)
- ChromaDB: Vector database for semantic search and memory storage
- Embeddings: OpenAI embeddings API or Ollama for vector generation
Performance Considerations
Optimization Strategies
- Parallel Context Retrieval: Entity and memory context fetched simultaneously
- Context Caching: Cache context based on mode and input
- Debounced Saves: Reduce I/O with delayed persistence
- Token Optimization: Compress and truncate context to stay within limits
- Streaming Responses: ~10x faster response time for voice assistants
- Lazy Tool Registration: Defer registration until first use
Scalability
- Memory Limits: Configurable max memories (default: 1000)
- History Limits: Configurable max messages and tokens
- Tool Timeouts: Prevent hanging tool executions (default: 30s)
- Session Expiration: Automatic cleanup of inactive sessions (default: 1 hour)
- Periodic Cleanup: Background task for memory maintenance
Error Handling
Exception Hierarchy
HomeAgentError (base)
├── ContextInjectionError
├── ToolExecutionError
├── ValidationError
├── TokenLimitExceeded
└── LLMError
Fallback Strategies
- Streaming Failure: Falls back to synchronous mode
- ChromaDB Unavailable: Falls back to store-only mode for memory
- Context Too Large: Truncates with warning
- Tool Timeout: Returns error to LLM, continues conversation
- Memory Extraction Failure: Logs error, conversation continues
Event System
Home Agent emits events for observability and automation:
home_agent.conversation.startedhome_agent.conversation.finished(with metrics)home_agent.context.injectedhome_agent.context.optimizedhome_agent.tool.executedhome_agent.tool.progresshome_agent.errorhome_agent.streaming.errorhome_agent.memory.extractedhome_agent.history.saved
Events can be used for:
- Monitoring and alerting
- Triggering automations
- Collecting metrics (Prometheus, InfluxDB)
- Debugging and troubleshooting
Configuration Architecture
Configuration is managed through multiple layers:
- Config Entry: Primary configuration via UI
- Options Flow: Runtime reconfiguration via UI
- YAML Config: Custom tools and advanced settings
- Runtime Updates: Live config updates without restart
Configuration Flow
flowchart LR
UI[UI Configuration] --> ConfigEntry[Config Entry]
YAML[configuration.yaml] --> YAMLConfig[YAML Config]
ConfigEntry --> Merge[Merge Configs]
YAMLConfig --> Merge
Merge --> Agent[HomeAgent]
Merge --> Components[Components]
Agent --> Validate[Validate]
Components --> Validate
Validate --> Apply[Apply Config]
Security Considerations
- API Key Storage: Stored securely in Home Assistant config entry
- Entity Exposure: Respects Home Assistant's exposure settings
- Tool Validation: Validates all tool calls before execution
- Timeout Enforcement: Prevents runaway tool executions
- Template Sandboxing: Uses Home Assistant's template engine
- Service Call Security: Uses Home Assistant's permission system
Further Reading
- Configuration Reference
- Custom Tools Guide
- Memory System
- API Reference
- Development Standards