Skip to content

Backend Overview

The backend is a Python monorepo managed with Poetry. It contains deployable FastAPI services, Cloud Run jobs, command-line tools, the hosted Rose MCP service, and reusable packages shared across those applications.

Architecture

flowchart TB subgraph Applications Search[Search API] Admin[Admin API] Knowledge[Knowledge API] Worker[Knowledge content worker] Integrations[Integrations API] Vector[IXVector API] MCP[Rose MCP] Jobs[Cloud Run jobs] end subgraph AgentCore[Agent and knowledge core] ixchat[ixchat] ixskills[ixskills] ixknowledge[ixknowledge] ixscraping[ixscraping] ixgeo[ixgeo] ixtagging[ixtagging] end subgraph Shared[Shared infrastructure] ixrag[ixrag] ixllm[ixllm] ixconfig[ixconfig] ixmongo[ixmongo] ixneo4j[ixneo4j] ixdata[ixdata] ixweb[ixweb] ixinfra[ixinfra] ixapi[ixapi_helpers] end Search --> ixchat ixchat --> ixskills & ixrag & ixllm Admin --> Knowledge Knowledge --> ixknowledge Worker --> ixknowledge & ixscraping Jobs --> ixknowledge & ixrag & ixtagging ixrag --> ixmongo & ixneo4j & ixllm Applications --> ixconfig & ixinfra & ixapi

Repository Structure

backend/
├── apps/
│   ├── api/
│   │   ├── search/                   # Website Agent HTTP/SSE API
│   │   ├── admin/                    # Authenticated backoffice BFF
│   │   ├── knowledge/                # Knowledge workflow control plane
│   │   ├── knowledge_content_worker/ # Discovery, scrape, and clean worker
│   │   ├── integrations/             # HubSpot and integration endpoints
│   │   └── ixvector/                 # Identity/enrichment webhook API
│   ├── jobs/                         # Cloud Run jobs
│   ├── mcp/                          # Hosted Rose MCP server
│   ├── cli/                          # Operational CLIs
│   └── scraping/                     # Scraping application boundary
├── packages/                         # Shared Python packages
└── justfile                          # Backend commands

Deployable Services

Service Responsibility
Search API Public Website Agent requests, streaming, resume, and enrichment boundaries
Admin API Authorize staff/backoffice operations and call private services with OIDC
Knowledge API Own durable ingestion state, guarded transitions, dispatch, recovery, and status
Knowledge content worker Execute bounded content stages and write immutable GCS artifacts
Integrations API HubSpot OAuth, CRM webhooks, email-capture tasks, and integration operations
IXVector API Ingest identity and enrichment webhooks
Rose MCP Brand conversations, vendor discovery and reply cards in Claude/ChatGPT
R4A MCP Signed-in buyer tools for vendor questions, alternatives, offers, trials and purchases

See Cloud Run services for service name patterns, access boundaries and deployment owners, including the support function and Factory relay.

The Knowledge API is the workflow source of truth. Cloud Tasks and Cloud Run deliver work but do not own workflow state. See Knowledge ingestion control plane.

Core Packages

Package Responsibility
ixchat Website Agent LangGraph, streaming, memory, and response routing
ixskills LLM selection plus deterministic application of global/client skills
ixrag LightRAG retrieval, chunk processing, reranking, and tenant context
ixllm Provider clients, model routing, retries, and observability
ixknowledge Knowledge operation, work-item, snapshot, and ingestion contracts
ixscraping Website mapping, selection, scraping, and content-cleaning logic
ixconfig Typed unified configuration models and resolver
ixmongo / ixneo4j Tenant-aware LightRAG storage adapters
ixdata Supabase and external data access
ixweb FastAPI-facing web components and request models
ixinfra Environment loading, logging, networking, and shared utilities
ixapi_helpers Reusable API authentication and middleware
ixgeo Generated GEO content and publishing pipeline
ixtagging Conversation classification and scoring
ixevaluation Evaluation datasets and LLM/classifier tooling

Website Agent Core

ixchat powers the Website Agent. Its LangGraph starts retrieval, enrichment, profiling, and routing work concurrently, then streams from the selected answer, redirect, or booking path. Model selection is role-based: different tasks use Cerebras, Azure OpenAI, OpenAI, or Mistral, with fallbacks. See Model residency for the EU-only route policy.

The IXChat package page embeds a graph generated directly from ixchat/graph_structure.py; use it instead of hand-maintained node diagrams.

Model residency

Provider deployments live in ixllm/ixllm/deployments.toml. Package routing modules reference them with deployment_route("<id>"); add a catalogue entry before routing to a new model. is_eu_eligible treats a deployment as EU (EEA + Switzerland) when it has a European endpoint and is not a Global deployment type; Azure deployments also need reviewed deployment_type and reviewed_on metadata. Mistral is pinned to api.eu.mistral.ai.

resolve_chat_use_case accepts a standard | eu_only residency and otherwise inherits the request-scoped value set by residency_scope(...). Under eu_only, derive_eu_policy keeps only the policy's EU-eligible legs in primary→fallback order, unless the policy sets an explicit eu_override. It raises EUResidencyUnavailableError when no eligible leg remains and EUResidencyViolationError when an override points at an ineligible deployment.

Today only rose-chat --eu-residency and rose-eval --eu-residency enter the eu_only scope, and only registered chat routes are filtered. Embeddings, ixtagging and Admin generation build their clients directly. A per-client setting is planned in IX-5094 (plan: docs/plans/2026-09-19-strict-eu-residency.md).

Retrieval and Storage

ixrag uses a shared LightRAG instance with tenant identity injected per request. Storage remains shared but every document, node, and relationship is scoped by tenantId:

Store Data Isolation
MongoDB Chunks, vectors, key-value state, document status tenantId filters and composite IDs
Neo4j Knowledge graph nodes and relationships tenantId property constraints
Redis LangGraph checkpoints, caches, and locks Environment and tenant-aware keys
Supabase Product, analytics, config, and workflow state RLS/domain authorization; one shared production project

Unified Configuration

Per-site behavior is resolved through typed client_configs data plus generated Python and TypeScript contracts. The old agent_config-centric model is not the current authoring interface. See the Unified Config System for namespaces, precedence, validation, and rollout rules.

Cloud Run Jobs

Job Responsibility
document-loader Controlled writer from approved source snapshots to LightRAG stores
tagging Conversation classification and scoring
website-mapping Website mapping refresh
posthog-batch-processor Production analytics batch materialization
hubspot-contacts-sync CRM synchronization
geo-run GEO pipeline for one workspace, started from the backoffice

Quick Commands

cd backend

just dev staging                   # Start the development API
poetry run pytest                  # Run all backend tests
poetry run pytest -m unit          # Unit tests only
poetry run pytest -m integration   # Integration tests only

See Backend Setup for environment setup and service-specific commands.