Skip to Content

Architecture

Architecture

Original file: ARCHITECTURE.mermaid
Type: MERMAID


```mermaid
---
title: SAM AI Base - System Architecture
---

graph TB
    subgraph "Frontend Layer (ai_sam module)"
        UI[JavaScript UI]
        WebSocket[WebSocket/SSE]
    end

    subgraph "Controller Layer (HTTP Endpoints)"
        ChatCtrl[sam_ai_chat_controller<br/>18 routes]
        CanvasCtrl[canvas_controller<br/>15 routes]
        MenuCtrl[menu_context_controller<br/>7 routes]
        SessionCtrl[sam_session_controller<br/>12 routes]
        OAuthCtrl[api_oauth_controller<br/>3 routes]
        DevCtrl[sam_developer_mode<br/>7 routes]
        VendorCtrl[vendor_registry_controller<br/>2 routes]
        ServiceCtrl[service_populator_controller<br/>1 route]
        MCPCtrl[mcp_download_controller<br/>3 routes]
        MemoryCtrl[memory_graph_controller<br/>9 routes]
    end

    subgraph "Business Logic Layer (Abstract Models)"
        AIService[ai.service<br/>API Integration]
        ContextBuilder[ai.context.builder<br/>The All-Knowing Brain]
        ContextAnalyzer[ai.context.analyzer<br/>Context Shift Detection]
        CostOptimizer[ai.cost.optimizer<br/>Provider Selection]
        VectorService[ai.vector.service<br/>ChromaDB]
        GraphService[ai.graph.service<br/>Apache AGE]
        MCPGenerator[mcp.server.generator<br/>MCP Server Generator]
    end

    subgraph "Data Layer - Conversation Management"
        Conversation[ai.conversation<br/>Conversation Threads]
        Message[ai.message<br/>Individual Messages]
        ConvTag[ai.conversation.tag<br/>Tags]
        ConvImport[ai.conversation.import<br/>Import Functionality]
    end

    subgraph "Data Layer - API Orchestration"
        Provider[api.service.provider<br/>Multi-API Orchestration]
        ProviderModel[ai.provider.model<br/>AI Models GPT-4, Claude]
        ServiceType[ai.service.type<br/>Service Types]
        Credentials[api.credentials<br/>API Keys OAuth Tokens]
    end

    subgraph "Data Layer - User Personalization"
        UserProfile[sam.user.profile<br/>User Relationship Data]
        UserSettings[sam.user.settings<br/>User Settings]
        SamBehavior[sam.behavior<br/>SAM Personality]
        ModeContext[sam.mode.context<br/>Mode-Specific Context]
        SamEnv[sam.environment<br/>Environment Detection]
    end

    subgraph "Data Layer - Cost Intelligence"
        TokenUsage[ai.token.usage<br/>Token Tracking]
        CostBudget[ai.cost.budget<br/>Budget Management]
        Benchmark[ai.provider.benchmark<br/>Performance Tracking]
        CostComparison[ai.service.cost.comparison<br/>Cost Dashboard]
    end

    subgraph "Data Layer - Agent Ecosystem"
        AgentDef[ai.agent.definition<br/>Agent Registry]
        AgentKnowledge[ai.agent.knowledge<br/>Training Data]
        AgentExec[ai.agent.execution<br/>Audit Trail]
        KnowledgeDomain[ai.knowledge.domain<br/>Knowledge Domains]
        KnowledgeSub[ai.knowledge.subcategory<br/>Subcategories]
    end

    subgraph "Data Layer - Memory System"
        MemoryConfig[ai.memory.config<br/>Memory Configuration]
        MemoryLog[ai.memory.search.log<br/>Search Logging]
    end

    subgraph "Data Layer - Canvas Platform"
        CanvasPlatform[canvas.platform<br/>Platform Config]
        Branches[ai.branches<br/>Conversation Branching]
        Workspace[ai.workspace<br/>Team Workspaces]
    end

    subgraph "Data Layer - Module Intelligence"
        ModuleIntel[ai.module.intelligence<br/>Module Training Data]
        DocumentExtractor[ai.document.extractor<br/>Document Extraction]
    end

    subgraph "Data Layer - MCP Server"
        MCPConfig[mcp.server.config<br/>MCP Server Config]
        MCPFeature[mcp.feature<br/>MCP Features]
    end

    subgraph "External Services"
        Anthropic[Anthropic Claude API]
        OpenAI[OpenAI API]
        Google[Google Cloud AI]
        Azure[Microsoft Azure AI]
        ChromaDB[(ChromaDB<br/>Vector Storage)]
        ApacheAGE[(Apache AGE<br/>Graph Database)]
    end

    %% Frontend connections
    UI --> ChatCtrl
    UI --> CanvasCtrl
    UI --> MenuCtrl
    UI --> SessionCtrl
    UI --> DevCtrl
    WebSocket --> ChatCtrl

    %% Controller to Business Logic
    ChatCtrl --> AIService
    ChatCtrl --> ContextBuilder
    ChatCtrl --> CostOptimizer

    CanvasCtrl --> ContextBuilder
    MenuCtrl --> ContextBuilder
    MenuCtrl --> ModuleIntel

    SessionCtrl --> UserProfile
    OAuthCtrl --> Credentials

    DevCtrl --> UserProfile
    MemoryCtrl --> VectorService
    MemoryCtrl --> GraphService

    %% Business Logic to Data
    AIService --> Provider
    AIService --> TokenUsage

    ContextBuilder --> ModuleIntel
    ContextBuilder --> Conversation
    ContextBuilder --> UserProfile

    CostOptimizer --> Provider
    CostOptimizer --> ProviderModel
    CostOptimizer --> Benchmark

    VectorService --> MemoryConfig
    VectorService --> MemoryLog

    GraphService --> MemoryConfig

    %% Data Layer Relationships
    Conversation --> Message
    Conversation --> UserProfile
    Conversation --> ConvTag
    Conversation --> AgentDef

    Provider --> ProviderModel
    Provider --> ServiceType
    Provider --> Credentials

    UserProfile --> UserSettings
    UserProfile --> ModeContext

    TokenUsage --> Provider
    TokenUsage --> ProviderModel
    TokenUsage --> Conversation
    TokenUsage --> CostBudget

    AgentDef --> AgentKnowledge
    AgentDef --> AgentExec

    KnowledgeDomain --> KnowledgeSub

    CanvasPlatform --> Workspace
    CanvasPlatform --> Branches

    MCPConfig --> MCPFeature
    MCPGenerator --> MCPConfig

    %% External Service Connections
    AIService -.->|API Calls| Anthropic
    AIService -.->|API Calls| OpenAI
    AIService -.->|API Calls| Google
    AIService -.->|API Calls| Azure

    VectorService -.->|Vector Operations| ChromaDB
    GraphService -.->|Graph Queries| ApacheAGE

    %% Styling
    classDef frontend fill:#e1f5ff,stroke:#01579b,stroke-width:2px
    classDef controller fill:#fff9c4,stroke:#f57f17,stroke-width:2px
    classDef logic fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    classDef data fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    classDef external fill:#ffebee,stroke:#b71c1c,stroke-width:2px,stroke-dasharray: 5 5

    class UI,WebSocket frontend
    class ChatCtrl,CanvasCtrl,MenuCtrl,SessionCtrl,OAuthCtrl,DevCtrl,VendorCtrl,ServiceCtrl,MCPCtrl,MemoryCtrl controller
    class AIService,ContextBuilder,ContextAnalyzer,CostOptimizer,VectorService,GraphService,MCPGenerator logic
    class Conversation,Message,ConvTag,ConvImport,Provider,ProviderModel,ServiceType,Credentials,UserProfile,UserSettings,SamBehavior,ModeContext,SamEnv,TokenUsage,CostBudget,Benchmark,CostComparison,AgentDef,AgentKnowledge,AgentExec,KnowledgeDomain,KnowledgeSub,MemoryConfig,MemoryLog,CanvasPlatform,Branches,Workspace,ModuleIntel,DocumentExtractor,MCPConfig,MCPFeature data
    class Anthropic,OpenAI,Google,Azure,ChromaDB,ApacheAGE external

Model Relationship Diagram

---
title: SAM AI Base - Data Model Relationships
---

erDiagram
    %% Conversation Management
    AI_CONVERSATION ||--o{ AI_MESSAGE : contains
    AI_CONVERSATION }o--|| RES_USERS : owned_by
    AI_CONVERSATION }o--o| AI_AGENT_DEFINITION : handled_by
    AI_CONVERSATION }o--o{ AI_CONVERSATION_TAG : tagged_with
    AI_CONVERSATION }o--|| ANY_MODEL : about

    %% API Orchestration
    API_SERVICE_PROVIDER ||--o{ AI_PROVIDER_MODEL : offers
    API_SERVICE_PROVIDER }o--|| AI_SERVICE_TYPE : provides
    API_SERVICE_PROVIDER }o--o| API_CREDENTIALS : authenticated_by

    %% User Personalization
    SAM_USER_PROFILE }o--|| RES_USERS : personalizes
    SAM_USER_PROFILE ||--o{ SAM_USER_SETTINGS : has_settings
    SAM_USER_PROFILE }o--o{ SAM_MODE_CONTEXT : uses_modes

    %% Cost Intelligence
    AI_TOKEN_USAGE }o--|| AI_CONVERSATION : tracks
    AI_TOKEN_USAGE }o--|| API_SERVICE_PROVIDER : used_provider
    AI_TOKEN_USAGE }o--|| AI_PROVIDER_MODEL : used_model
    AI_TOKEN_USAGE }o--o| AI_COST_BUDGET : within_budget

    AI_PROVIDER_BENCHMARK }o--|| API_SERVICE_PROVIDER : benchmarks
    AI_SERVICE_COST_COMPARISON }o--|| AI_SERVICE_TYPE : compares

    %% Agent Ecosystem
    AI_AGENT_DEFINITION ||--o{ AI_AGENT_KNOWLEDGE : trained_with
    AI_AGENT_DEFINITION ||--o{ AI_AGENT_EXECUTION : executes
    AI_AGENT_EXECUTION }o--|| RES_USERS : executed_by
    AI_AGENT_EXECUTION }o--o| AI_CONVERSATION : during_conversation

    AI_KNOWLEDGE_DOMAIN ||--o{ AI_KNOWLEDGE_SUBCATEGORY : categorizes
    AI_KNOWLEDGE_SUBCATEGORY }o--o{ AI_AGENT_KNOWLEDGE : organizes

    %% Memory System
    AI_MEMORY_CONFIG }o--|| RES_USERS : configures_for
    AI_MEMORY_SEARCH_LOG }o--|| RES_USERS : logs_for

    %% Canvas Platform
    CANVAS_PLATFORM ||--o{ AI_WORKSPACE : supports
    AI_WORKSPACE }o--o{ AI_CONVERSATION : shares
    AI_BRANCHES }o--|| AI_CONVERSATION : branches_from

    %% MCP Server
    MCP_SERVER_CONFIG ||--o{ MCP_FEATURE : provides

    %% Module Intelligence
    AI_MODULE_INTELLIGENCE }o--|| IR_MODULE_MODULE : describes

    %% Model Definitions
    AI_CONVERSATION {
        int id PK
        int user_id FK
        string name
        string context_model
        int context_id
        int agent_id FK
        datetime create_date
    }

    AI_MESSAGE {
        int id PK
        int conversation_id FK
        string role
        text content
        datetime timestamp
    }

    RES_USERS {
        int id PK
        string name
        string login
    }

    API_SERVICE_PROVIDER {
        int id PK
        string supplier
        string service_type
        string auth_type
        string api_key
        boolean is_template
        string vendor_key
    }

    AI_PROVIDER_MODEL {
        int id PK
        int provider_id FK
        string name
        float cost_per_1k_input
        float cost_per_1k_output
        int context_window
    }

    SAM_USER_PROFILE {
        int id PK
        int user_id FK
        string relationship_level
        int trust_score
        json personal_facts
        string memory_permission
        json approved_paths
    }

    AI_TOKEN_USAGE {
        int id PK
        int conversation_id FK
        int provider_id FK
        int model_id FK
        int input_tokens
        int output_tokens
        float total_cost
        datetime timestamp
    }

    AI_AGENT_DEFINITION {
        int id PK
        string name
        string technical_name
        text system_prompt
        json capabilities
    }

    AI_AGENT_KNOWLEDGE {
        int id PK
        int agent_id FK
        text content
        string category
    }

User Interaction Flow

---
title: SAM AI - User Interaction Flow
---

sequenceDiagram
    actor User
    participant UI as Frontend UI
    participant ChatCtrl as Chat Controller
    participant ContextBuilder as Context Builder
    participant UserProfile as User Profile
    participant AIService as AI Service
    participant Provider as API Provider
    participant TokenUsage as Token Usage
    participant Conversation as Conversation Model

    User->>UI: Opens SAM chat
    UI->>ChatCtrl: POST /sam_ai/chat/send
    Note over ChatCtrl: {message, context_data}

    ChatCtrl->>UserProfile: get_or_create_profile(user_id)
    UserProfile-->>ChatCtrl: user_context (permissions, preferences)

    ChatCtrl->>ContextBuilder: build_context_prompt(context_data)
    ContextBuilder->>ContextBuilder: Detect current menu/module/record
    ContextBuilder->>ContextBuilder: Load module intelligence
    ContextBuilder-->>ChatCtrl: formatted_context_prompt

    ChatCtrl->>Conversation: create_or_load_conversation()
    Conversation-->>ChatCtrl: conversation object

    ChatCtrl->>Conversation: add_message('user', message)

    ChatCtrl->>AIService: send_message(message, context, user_profile)
    AIService->>AIService: recommend_provider(service_type)
    AIService->>Provider: call_api(messages)
    Provider-->>AIService: API response

    AIService->>TokenUsage: track_usage(tokens, cost)
    AIService->>Conversation: add_message('assistant', response)
    AIService-->>ChatCtrl: assistant_message

    ChatCtrl->>UserProfile: propose_memory(learned_fact)
    Note over UserProfile: If memory_permission = 'ask_always'

    ChatCtrl-->>UI: {success, message, conversation_id}
    UI-->>User: Display SAM response

    alt Memory Permission Required
        UI->>User: "Should I save this to memory?"
        User->>UI: "yes"
        UI->>ChatCtrl: POST /sam/memory/approve
        ChatCtrl->>UserProfile: learn_fact(fact)
    end

Cost Optimization Flow

---
title: SAM AI - Cost Optimization Flow
---

flowchart TD
    Start([User sends message]) --> LoadProfile[Load User Profile]
    LoadProfile --> CheckBudget{Budget remaining?}

    CheckBudget -->|No budget| Warn[Warn user: Budget exceeded]
    CheckBudget -->|Budget OK| EstimateCost[Estimate token count]

    EstimateCost --> GetProviders[Get all providers for service_type]
    GetProviders --> CalcCost[Calculate cost per provider]

    CalcCost --> RankProviders[Rank by: cost, performance, availability]
    RankProviders --> SelectBest{Best provider available?}

    SelectBest -->|Yes| CallAPI[Call selected provider API]
    SelectBest -->|No| Fallback[Try fallback provider]

    CallAPI --> Success{API Success?}
    Success -->|Yes| TrackUsage[Track token usage & cost]
    Success -->|No| Fallback

    Fallback --> Retry{Retry count < 3?}
    Retry -->|Yes| SelectBest
    Retry -->|No| Error[Return error to user]

    TrackUsage --> UpdateBudget[Update budget remaining]
    UpdateBudget --> CheckThreshold{Budget threshold reached?}

    CheckThreshold -->|Yes| Alert[Send budget alert]
    CheckThreshold -->|No| Return[Return response to user]

    Alert --> Return
    Return --> End([End])

    Warn --> End
    Error --> End

    style Start fill:#e1f5ff
    style End fill:#e1f5ff
    style CallAPI fill:#c8e6c9
    style Error fill:#ffcdd2
    style Alert fill:#fff9c4

Memory Permission Flow

---
title: SAM AI - Memory Permission Flow
---

stateDiagram-v2
    [*] --> NewUser: User first login

    NewUser --> AskAlways: Default permission level

    state AskAlways {
        [*] --> DetectFact: SAM learns something
        DetectFact --> AskUser: Propose memory
        AskUser --> UserResponds: Wait for response

        UserResponds --> SaveFact: User says "yes"
        UserResponds --> DiscardFact: User says "no"
        UserResponds --> UpgradeToAutoWork: User says "always" (work facts)

        SaveFact --> [*]
        DiscardFact --> [*]
    }

    AskAlways --> AutoWork: User chooses "auto-save work info"

    state AutoWork {
        [*] --> CategorizeNew: SAM learns something
        CategorizeNew --> IsWorkFact{Work/technical fact?}

        IsWorkFact --> AutoSaveWork: Yes (auto-save)
        IsWorkFact --> AskPersonal: No (ask permission)

        AskPersonal --> UserRespondsPersonal: Wait for response
        UserRespondsPersonal --> SavePersonal: User says "yes"
        UserRespondsPersonal --> DiscardPersonal: User says "no"
        UserRespondsPersonal --> UpgradeToAutoAll: User says "always"

        AutoSaveWork --> [*]
        SavePersonal --> [*]
        DiscardPersonal --> [*]
    }

    AutoWork --> AutoAll: User chooses "auto-save everything"

    state AutoAll {
        [*] --> AutoSaveAll: SAM learns anything
        AutoSaveAll --> [*]: Save immediately
    }

    AutoAll --> AskAlways: User revokes trust
    AutoWork --> AskAlways: User revokes trust

    style NewUser fill:#e1f5ff
    style AskAlways fill:#fff9c4
    style AutoWork fill:#c8e6c9
    style AutoAll fill:#b2dfdb

Deployment Architecture

---
title: SAM AI - Deployment Architecture
---

graph TB
    subgraph "Client Layer"
        Browser[Web Browser]
        Mobile[Mobile App]
    end

    subgraph "Load Balancer"
        LB[Nginx / HAProxy]
    end

    subgraph "Odoo Application Servers"
        Odoo1[Odoo Instance 1<br/>ai_sam_base + ai_sam]
        Odoo2[Odoo Instance 2<br/>ai_sam_base + ai_sam]
        Odoo3[Odoo Instance 3<br/>ai_sam_base + ai_sam]
    end

    subgraph "Database Layer"
        PG_Primary[(PostgreSQL<br/>Primary)]
        PG_Replica1[(PostgreSQL<br/>Replica 1)]
        PG_Replica2[(PostgreSQL<br/>Replica 2)]
    end

    subgraph "Cache Layer"
        Redis[(Redis<br/>Session Cache)]
    end

    subgraph "Memory Systems"
        ChromaDB[(ChromaDB<br/>Vector Storage)]
        ApacheAGE[(Apache AGE<br/>Graph Database)]
    end

    subgraph "External AI Services"
        Anthropic[Anthropic API]
        OpenAI[OpenAI API]
        Google[Google Cloud AI]
    end

    subgraph "Monitoring"
        Sentry[Sentry<br/>Error Tracking]
        Grafana[Grafana<br/>Metrics Dashboard]
    end

    Browser --> LB
    Mobile --> LB

    LB --> Odoo1
    LB --> Odoo2
    LB --> Odoo3

    Odoo1 --> PG_Primary
    Odoo2 --> PG_Primary
    Odoo3 --> PG_Primary

    PG_Primary --> PG_Replica1
    PG_Primary --> PG_Replica2

    Odoo1 --> Redis
    Odoo2 --> Redis
    Odoo3 --> Redis

    Odoo1 --> ChromaDB
    Odoo2 --> ChromaDB
    Odoo3 --> ChromaDB

    Odoo1 --> ApacheAGE
    Odoo2 --> ApacheAGE
    Odoo3 --> ApacheAGE

    Odoo1 -.->|API Calls| Anthropic
    Odoo2 -.->|API Calls| OpenAI
    Odoo3 -.->|API Calls| Google

    Odoo1 --> Sentry
    Odoo2 --> Sentry
    Odoo3 --> Sentry

    Odoo1 --> Grafana
    Odoo2 --> Grafana
    Odoo3 --> Grafana

    style Browser fill:#e1f5ff
    style Mobile fill:#e1f5ff
    style LB fill:#fff9c4
    style PG_Primary fill:#c8e6c9
    style Redis fill:#ffccbc
    style ChromaDB fill:#d1c4e9
    style ApacheAGE fill:#d1c4e9

Note: These diagrams are written in Mermaid syntax and can be rendered in:
- GitHub (automatic rendering in .md files)
- GitLab (automatic rendering)
- VS Code (with Mermaid Preview extension)
- Online: https://mermaid.live

Last Updated: December 10, 2025

```

Was this helpful?