Skip to content

Assistant Service — Workload Architecture

assistant-service is one image deployed as several workloads (the image's CMD or the chart's command/args selects which app runs). They share the src/shared/ base and the same assistant-service-secret + config, but play distinct roles and talk to each other over in-cluster service DNS.

flowchart TB
    subgraph EXT["External / shared (in-cluster)"]
        CS["core-service<br/>:80"]
        PG["core-pg-rw<br/>:5432"]
        RD["assistant-service-redis-master<br/>:6379"]
        HE["hatchet-engine<br/>:7070"]
        FD["Foundry / LLM<br/>(dummy for now)"]
        KMS["knowledge-management-service"]
    end

    ING["Ingress<br/>api.ask.mod.auh1.dev.dir<br/>/ask71/v2/astsvc"] --> A

    A["<b>assistant-service</b> (assistants)<br/>:8002 — API, conversations,<br/>triggers, webhooks · OWNS THE DB"]
    I["<b>assistant-service-intelligence</b><br/>:8003 — RAG, agents,<br/>LangGraph orchestration"]
    T["<b>assistant-service-tooling</b><br/>:8001 — MCP tools, OAuth,<br/>connectors (ToolBus)"]
    W["<b>assistant-service-generic-worker</b><br/>(no port) — Hatchet async jobs"]
    M["<b>assistant-service-migration</b><br/>(Job) — alembic upgrade head"]

    A -->|"intelligence_base_url :8003"| I
    A -->|"tooling_base_url :8001"| T
    I -->|"toolbus_base_url :8001"| T
    T -->|"TOOLING_INTELLIGENCE_BASE_URL :8003"| I

    A -.->|SQLAlchemy| PG
    I -.-> PG
    T -.-> PG
    A -.-> RD
    I -.-> RD
    W -->|"register + run workflows"| HE
    M ==>|"creates schema/tables (PreSync-ish)"| PG

    A & I & T -->|"auth / IAM"| CS
    I -->|"LLM / embeddings / rerank"| FD
    T -->|"knowledge base"| KMS

    style A fill:#1e3a5f,stroke:#4a90d9,color:#fff
    style I fill:#1e5f3a,stroke:#4ad98a,color:#fff
    style T fill:#5f4a1e,stroke:#d9a94a,color:#fff
    style W fill:#5f1e3a,stroke:#d94a8a,color:#fff
    style M fill:#3a1e5f,stroke:#a94ad9,color:#fff
    style EXT fill:#222,stroke:#666,color:#ddd

What each workload does

assistant-service (the "assistants" / main API)

  • Role: the public API — assistants, conversations, messages, triggers, webhooks. Owns the database (Alembic models live here).
  • Port: 8002 (Service exposes :80 → the Ingress routes /ask71/v2/astsvc here).
  • Talks to: core-service (auth/IAM), core-pg (its tables), redis (cache), intelligence (to run agent/RAG pipelines), tooling (to invoke tools).
  • Entry: the image's default app (src/assistants/app.py).

assistant-service-intelligence

  • Role: the "brain" — RAG, agents, LangGraph orchestration pipelines. Calls the LLM gateway.
  • Port: 8003. Higher memory limits (LLM work); HPA scales on memory.
  • Talks to: Foundry/LLM (chat, embeddings, reranker — dummy endpoint for now), tooling (toolbus_base_url — to execute tools the agent decides to call), core-pg, redis. (Qdrant/memory omitted in air-gap.)
  • Entry: shared image, command/args start src/intelligence/app.py.

assistant-service-tooling (ToolBus)

  • Role: the MCP tool layer — gmail/calendar/knowledge-base tools, OAuth flows, connector activation, the MCP server registry.
  • Port: 8001. Health on /health/mcp.
  • Config quirk: uses its own pydantic-settings (ToolsSettings) that reads env vars directly (not the Dynaconf TOML) — needs AI71_FOUNDRY_ENDPOINT, KMS_BASE_URL, AI71_FOUNDRY_KEY as env (see Deployment Guide §4d).
  • Talks to: KMS (knowledge base), Foundry (tool LLM calls), intelligence (TOOLING_INTELLIGENCE_BASE_URL), external MCP servers (gmail/calendar — SaaS, mostly inactive air-gapped), core-pg, redis.
  • Entry: shared image, command/args start src/tooling/app.py.

assistant-service-generic-worker

  • Role: Hatchet async worker — runs background workflows (e.g. usage-count refresh, bulk ops). No HTTP port.
  • Talks to: hatchet-engine:7070 (registers + executes workflows), core-pg, redis.
  • ⚠️ Hard dep: builds the Hatchet client at import → needs a real JWT HATCHET__CLIENT_TOKEN (from hatchet-client-config), or the pod crashes at startup. (The notifications-worker is a sibling, disabled by default.)
  • Entry: python -m src.hatchet_workers.workers.generic_worker.

assistant-service-migration (one-shot Job)

  • Role: runs alembic upgrade head against the assistant-service DB on core-pg, creating the assistant_service schema + tables. Runs before the app workloads (sync-wave) and the app also re-checks migrations at startup.
  • Talks to: core-pg only. Needs the same config env (APP_ENV, DATABASE__PASSWORD, secret) as the apps — it imports src.config.
  • Lifecycle: completes and exits; not a long-running pod.

Inter-service call map (who calls whom)

From To URL / target Why
Ingress assistant-service :8002 (svc :80) public API entry
assistant-service intelligence http://assistant-service-intelligence:8003 run agent/RAG pipelines
assistant-service tooling http://assistant-service-tooling:8001 invoke tools
intelligence tooling toolbus_base_url:8001 agent executes a chosen tool
tooling intelligence TOOLING_INTELLIGENCE_BASE_URL:8003 tool needs orchestration
all 3 apps core-service http://core-service.ask.svc.cluster.local/api/v1 auth / IAM / shared data
intelligence Foundry/LLM foundry.endpoint (dummy now) LLM, embeddings, rerank
tooling KMS kms.base_url knowledge-base tool
generic-worker hatchet-engine :7070 (TLS none) async workflows
all workloads core-pg / redis core-pg-rw:5432 / assistant-service-redis-master:6379 data + cache

Dependency summary per workload

Workload Hard deps (must exist to start) Lazy/runtime deps
migration core-pg, config env
assistant-service core-pg, redis, config+secret core-service, intelligence, tooling (per-request)
intelligence core-pg, redis, config+secret Foundry (dummy), tooling, core-service
tooling core-pg, redis, env vars (AI71_FOUNDRY_ENDPOINT, KMS_BASE_URL, AI71_FOUNDRY_KEY) KMS, Foundry, intelligence, MCP servers
generic-worker hatchet-engine + real JWT token, core-pg, redis

Why intelligence/tooling/workers share the main image

All non-gateway workloads run the same assistant-service image; the chart's command/args select which app.py to launch. So a release bumps one image tag (in the devops overlay) and every workload updates together. Only assistant-service-mcp-gateway is a separate image (and is disabled by default).