Service Layer Patterns

chevron-rightRelevant source fileshashtag

This document describes the architectural patterns used in the service layer of Automatos AI. The service layer sits between the API routes (see API Router Organization) and the database models (see Database Models), providing business logic, orchestration, and resource management.

For information about specific services like RAG, tools, or agents, see the dedicated sections: RAG Retrieval System, Tool Router & Execution, Agent Factory & Runtime.


Service Layer Architecture

The service layer implements the business logic tier in a three-layer architecture. Services consume database models, external APIs, and other services, while being consumed by API routes and other services.

spinner

Sources: orchestrator/consumers/chatbot/service.py:14-476, orchestrator/modules/agents/factory/agent_factory.py:503-517, orchestrator/modules/orchestrator/pipeline.py:134-279


Database Session Injection Pattern

Services receive a Session object in their constructor rather than creating their own connections. This enables transaction management, testing with mock sessions, and proper connection pooling.

Pattern Structure

spinner

Implementation Examples

ChatService receives session in constructor:

AgentFactory with fallback to SessionLocal:

StreamingChatService composes ChatService:

Sources: orchestrator/consumers/chatbot/service.py:191-216, orchestrator/modules/agents/factory/agent_factory.py:510-519


Service Composition Pattern

Services compose other services to delegate specialized functionality. This promotes separation of concerns and testability.

spinner

StreamingChatService Composition

The StreamingChatService delegates to specialized services:

Service
Responsibility
Initialization

ChatService

Database CRUD for chats/messages

PromptAnalyzer

Extract latest user text, detect fresh start

MemoryInjector

Retrieve/inject memories from Mem0

ToolRouter

Execute tool calls

StreamingHandler

Format AI SDK SSE events

AgentFactory

Activate agents

Sources: orchestrator/consumers/chatbot/service.py:456-475

EnhancedOrchestratorService Composition

The EnhancedOrchestratorService composes 9-stage pipeline components:

Sources: orchestrator/modules/orchestrator/service.py:68-109


Lazy Initialization Pattern

Services defer expensive operations (LLM provider creation, credential lookup) until first use. This prevents startup failures and improves performance.

spinner

LLMManager Lazy Provider

EnhancedOrchestratorService Lazy LLM

Sources: orchestrator/core/llm/manager.py:369-424, orchestrator/modules/orchestrator/service.py:111-123


Credential Resolution Pattern

The LLMManager implements a 6-level credential resolution strategy with multiple fallback mechanisms. This ensures robustness when credentials are named inconsistently or stored in different environments.

spinner

Resolution Levels

Level 0 - Explicit System Setting (MVP feature):

Level 1 - Standard Naming Pattern:

Level 2 - Name Variations:

Level 3 - Type-Based Lookup:

Level 4 - Development Fallback:

Level 5 - Environment Variables:

Credential Type Mapping

Provider
Credential Type
Primary Key Field

openai

openai_api

api_key

anthropic

anthropic_api

api_key

google

google_api

api_key

azure

azure_openai

api_key, endpoint_url

huggingface

huggingface_api

api_token

aws_bedrock

aws_bedrock_api

bedrock_api_key or aws_access_key_id

grok

xai_api

api_key

openrouter

openrouter_api

api_key

Sources: orchestrator/core/llm/manager.py:123-353, orchestrator/core/llm/manager.py:181-197


Service Settings Resolution

Services load configuration from system settings with fallback to environment variables. The SERVICE_CATEGORY_MAP maps service names to settings categories.

Service Category Mapping

spinner

Mapping definition: orchestrator/core/llm/manager.py:30-41

Settings Retrieval Flow

  1. Service nameCategory name via SERVICE_CATEGORY_MAP

  2. Query SystemSetting table: category = category_name, key = setting_key

  3. Fallback to config.py constants if not found

  4. Fallback to provider-specific defaults

Example for orchestrator service:

Sources: orchestrator/core/llm/manager.py:30-117


Manager Pattern: LLMManager

The LLMManager abstracts provider complexity and implements automatic fallback when models are unavailable.

Provider Abstraction

spinner

Automatic Model Fallback

When a configured model returns a "dead model" error (404, "no endpoints found", "model not found"), the manager automatically retries with a fallback model on the same provider.

Dead model detection patterns:

Fallback model resolution:

  1. Check user-configured fallback in system settings: {category}.fallback_model

  2. Use provider-specific default (e.g., gpt-4o-mini for OpenAI)

Fallback execution flow:

spinner

Implementation: orchestrator/core/llm/manager.py:643-691

Sources: orchestrator/core/llm/manager.py:355-728


Pipeline Executor Pattern

The WorkflowPipeline implements a composable stage executor that runs dynamic subsets of stages determined by configuration. This replaces monolithic execution functions with a flexible, testable pipeline.

Pipeline Architecture

spinner

Sources: orchestrator/modules/orchestrator/pipeline.py:134-279

Stage Registration

Services register stage functions by name:

WorkflowContext

Shared context object passed through the pipeline. Each stage reads from and writes to this context.

Key fields:

  • Workflow metadata: workflow_id, execution_id, workspace_id, task_description

  • Stage results: decomposition, agent_assignments, execution_results, aggregated_results

  • Infrastructure: db, execution, mem0_client, stage_tracker

  • Tracking: stage_results (list of StageResult)

Definition: orchestrator/modules/orchestrator/pipeline.py:62-101

Error Handling Strategies

Strategy
Behavior
Use Case

ABORT

Stop pipeline on any error

Critical workflows requiring atomicity

SKIP

Skip failed stage, continue

Non-critical stages with graceful degradation

RETRY

Retry once, then skip

Transient failures (network, rate limits)

REPLAN

Re-evaluate approach

Adaptive workflows

Enum definition: orchestrator/modules/orchestrator/pipeline.py:42-47

Error handling logic: orchestrator/modules/orchestrator/pipeline.py:223-261

Sources: orchestrator/modules/orchestrator/pipeline.py:42-279


Progress Tracking Pattern

Services emit progress events via protocol-based callbacks. This decouples progress reporting from business logic.

Progress Callback Protocol

spinner

Protocol definition: orchestrator/modules/orchestrator/pipeline.py:107-113

Default vs Custom Implementations

DefaultProgressCallback logs to console:

WorkflowStageTracker emits SSE events:

Sources: orchestrator/modules/orchestrator/pipeline.py:107-131, orchestrator/api/workflows.py:40-185


Tool Execution Deduplication Pattern

ToolExecutionTracker prevents infinite loops in tool calling by tracking exact and semantic duplicates.

Tracking Mechanisms

spinner

Deduplication Strategies

1. Exact Matching: Hash tool arguments, prevent identical calls

2. Semantic Similarity: For search tools, normalize queries and use fuzzy matching

3. Per-Tool Retry Limits: Different limits per tool type

Usage in StreamingChatService

The tracker is instantiated per conversation turn and checked before each tool execution:

Sources: orchestrator/consumers/chatbot/service.py:42-186


Service Instantiation Patterns

Constructor Injection

Services receive dependencies in constructor:

Example: orchestrator/consumers/chatbot/service.py:194-195

Factory Functions

Factory functions hide service creation complexity:

Examples: orchestrator/modules/agents/factory/agent_factory.py:38-48

Singleton Services

Some services use module-level singletons (e.g., RAG service, monitoring service):

Sources: orchestrator/modules/agents/factory/agent_factory.py:38-53


Best Practices Summary

Pattern
Benefit
When to Use

Database Session Injection

Transaction control, testability

All services that access database

Service Composition

Separation of concerns, reusability

Complex services needing specialized functionality

Lazy Initialization

Fast startup, fail gracefully

Expensive operations (LLM providers, credential lookup)

Credential Resolution

Robustness, flexibility

Services using external APIs

Manager Pattern

Provider abstraction, consistent interface

Services wrapping multiple implementations

Pipeline Executor

Composability, testability

Multi-stage workflows with dynamic execution

Progress Callbacks

Decoupled progress reporting

Long-running operations requiring real-time updates

Deduplication Tracking

Prevent infinite loops

Tool calling, search operations

Sources: orchestrator/consumers/chatbot/service.py:1-1300, orchestrator/modules/agents/factory/agent_factory.py:1-1300, orchestrator/core/llm/manager.py:1-800, orchestrator/modules/orchestrator/pipeline.py:1-306


Last updated