Docs/Architecture
/Core Module Catalogue
Core Module Catalogue
The backend is a modular monolith: core/pom.xml is a pure
aggregator/BOM (packaging=pom, no source of its own) over 40 Maven
modules plus two auxiliary components (mcp-data,
mcp-stdio-proxy), assembled into one Spring Boot deployable
(core/app) and two specialised assemblies
(app-worker, app-jobs). Maven itself enforces the
dependency boundaries — a module that reaches across a boundary is a compile
error, not a code-review nit. Descriptions below are taken from each module's
own pom.xml.
flowchart TD
subgraph leaf["Leaf modules (no core deps)"]
audit["audit"] & crypto["crypto"] & storage["storage"] & speech["speech"] & evalM["eval"]
end
subgraph mid["Platform & tenancy"]
security["security"] --> admin["admin"] --> sharing["sharing"]
crypto --> secrets["secrets"]
crypto --> providers["providers"]
admin --> tenancy["tenancy"]
providers --> chat["chat"]
tenancy --> eventbus["eventbus"]
end
subgraph top["Agent runtime & channels"]
approval["approval"] --> guardrails["guardrails"]
knowledge["knowledge"] --> agents["agents"]
agents --> omnichannel["omnichannel"]
agents --> voice["voice"]
eventbus --> workflow["workflow"]
end
omnichannel & workflow & agents --> app["app
(REST deployable)"]
app --> worker["app-worker
(Temporal worker)"]
app --> jobs["app-jobs
(scheduled jobs)"]
Module catalogue
Platform, tenancy & infrastructure
| Module | Purpose |
security | Keycloak OAuth2 resource-server config, TenantContext + servlet filter. Leaf. |
tenancy | Tenant/AppUser entities, schema-per-tenant Hibernate multi-tenancy, signup/provisioning, Flyway migration-per-schema. Depends on admin, billing, security, storage. |
admin | Keycloak Admin REST client for user management (UserAdminController). Depends on audit, security. |
platform | Cross-tenant "Ecosystem Maintenance" API for super-admins: hosted LLM pool, plan overrides, platform observability, health/metrics aggregation. Gated by /api/platform/** → ROLE_platform-admin. |
billing | Billing-gateway abstraction (Razorpay adapter) + GST invoicing, used by hosted operators; plan gating is off by default (NEXT_PUBLIC_BILLING_ENABLED). Depends only on security. |
crypto | EncryptionService — AES-256-GCM at-rest encryption for provider keys and channel tokens. JDK javax.crypto only; leaf. |
secrets | Consumer secrets vault: named encrypted secrets referenced as {{secret.NAME}}, resolved only inside the tool-execution boundary. |
storage | FileStorageService — S3-API object storage (SeaweedFS in the Full tier, local disk in Lite, or any S3 API via config). Leaf. |
eventbus | Kafka-backed event backbone (WorkflowEvent envelope, transactional outbox, relay). Inert unless configured; depends only on tenancy. |
Agent runtime & LLM
| Module | Purpose |
agents | Agent entity + chat orchestration and the tool-call plumbing (old "tools" package) in one module — a verified circular dependency (AgentToolProvider needs Agent; AgentChatService needs AgentToolProvider) made splitting them a real code change. |
chat | Spring AI ChatClient factories/registry per provider, LlmMetricsAdvisor, llm_call_log, pricing catalog, LLM gateway. Depends on providers. |
providers | LLM provider credential abstraction (BYOK, encrypted at rest), ProviderName, ProviderCredentialResolver, ProviderValidator. Depends on crypto (+ sarvam for credential resolution). |
mcp | MCP server registry — DB-backed metadata, encrypted connection env vars, dynamic STDIO/remote connection management. Depends on crypto, security. |
mcpserver | Inbound MCP hosting: exposes a curated tenant tool set (call_agent, call_workflow, search_knowledge) to external MCP clients over STREAMABLE HTTP at /mcp. |
codeintel | Code-intelligence ToolCallbacks: search a tenant's indexed codebase, walk its deterministic code graph, get cited answers. Thin HTTP client over the code-intel service. |
sdlc | E2B sandbox integration scaffold: E2bCredential BYOK storage + E2bSandboxClient (create/list/kill sandboxes). Leaf-shaped; no tool callbacks yet. |
Automation
| Module | Purpose |
workflow | WorkflowDefinition/WorkflowRun persistence, OrchestratorService (structural validation + runtime governance over sensitive nodes), WorkflowExecutionEngine. |
approval | Human-in-the-loop approval gate, policy overrides, retry job. Depends on audit, tenancy. |
eventbus | (Also listed under platform — the Kafka backbone the workflow designer publishes trigger events through.) |
Knowledge & memory
| Module | Purpose |
knowledge | Hierarchical multi-modal knowledge base (RAG): sidecar client, ingestion jobs, ToolCallbacks, hybrid vector+FTS search. Depends on tenancy, crypto. |
graphmemory | Graph-based agent memory on Apache AGE (a Postgres extension, not a separate database) — RememberFactToolCallback / GraphRecallToolCallback. |
Governance & quality
| Module | Purpose |
guardrails | Tool step ceiling, allow-list, output sanitisation, GuardedToolCallback; content-moderation policy packs, external-classifier seam, human review queue. Depends on approval, audit, tenancy. |
audit | Audit log: AuditLogEntry/Service/Controller. Leaf. |
eval | Standalone golden-dataset prompt-regression CLI harness. Deliberately touches no DB or tenant context; runs in its own CI workflow, never in mvn verify. |
quality | Agent response quality scoring across dimensions (helpfulness, accuracy, tone, length, relevance, safety) with historical trend tracking. |
rl | In-core RL subsystem: reward capture, per-turn trajectory recording, contextual bandit (Thompson sampling over Beta posteriors) for safe non-side-effecting choices. |
sharing | Cross-user resource sharing: resource_grant table + ResourceAccessService (RUNNER/VIEWER/EDITOR, anti-enumeration 404-on-denial). No dependency on agents/workflow — owner lookup goes through a ResourceOwnerLookup SPI. |
Media, channels & integrations
| Module | Purpose |
omnichannel | Channel adapters and inbound webhooks (Twilio WhatsApp/SMS/voice, Meta, Telegram, Slack, Discord, Teams, email), channel sessions/pairing, operator handoff, signature validation. |
voice | Self-hosted in-app voice/video calling via LiveKit WebRTC + push-to-talk STT→AgentChatService→TTS pipeline. Independent of omnichannel's Twilio PSTN bridge. |
speech | SpeechTextNormalizer — rewrites LLM text into something a TTS engine should say (strip markdown/emoji, speak URLs as "a link"). Shared by elevenlabs and sarvam. Leaf. |
sarvam | Sarvam AI across 22 Indian languages: chat, translation, STT, TTS, transliteration, language ID. Own credential table. |
elevenlabs | ElevenLabs voice cloning + TTS, tenant BYOK key in its own credential table (not LlmProviderCredential). |
imagegen | Image generation (Flux / GPT-Image) with own entity/service/controller/tool-callback surface. |
documentgen | Event-driven document generation: DOCX/PDF/XLSX/PPTX/CSV/TXT/MD/JSON. |
google | Google Workspace: one platform-level OAuth app (Drive/Gmail/Calendar/Sheets), per-tenant encrypted refresh tokens. |
devices | Device-pairing backend: pair an external device client as a channel (the device app is not in this repository); workflow "Device Control" node depends on it. |
Assemblies & auxiliary
| Module | Purpose |
app | The Spring Boot application: CoreApplication, cross-cutting glue (GlobalExceptionHandler, WebConfig), application*.yml and db/migration/**. |
app-config | Shared Spring configuration resources (application.yml + profile files) for every executable assembly. |
app-worker | Temporal workflow-worker deployable: same modules via app-config, booted as WorkerApplication — no REST controllers, no @Scheduled, no Flyway. |
app-jobs | Background-jobs deployable: JobsApplication — no REST controllers, @Scheduled ON, no Flyway, no per-tenant startup work. |
templates | Community template gallery: sanitised moderated catalogue of agent/workflow designs (community_template, control-plane schema). |
mcp-data | Auxiliary MCP data component (not in the main reactor build). |
mcp-stdio-proxy | Node.js sidecar that executes dynamic STDIO MCP servers outside the JVM (MCP_STDIO_SIDECAR_* envs). |
REST surface — controller distribution
Approximately 193 @RestController classes ship in
the core assembly. The distribution is deliberately uneven — channel and agent
administration dominate:
| Module | ≈ Controllers | What they cover |
omnichannel | ~36 | Per-channel webhook endpoints, channel config CRUD, pairing, operator inbox, health |
agents | ~34 | Agent CRUD/config, chat endpoints, tools, memory, jobs |
tenancy | ~18 | Tenant management, signup, provisioning, user self-service |
app / common | ~11 | Cross-cutting endpoints assembled with the application |
platform | ~9 | Platform-admin maintenance, hosted pool, observability |
billing | ~7 | Plans, checkout, invoices, usage |
workflow | ~7 | Definitions, runs, triggers |
chat | ~6 | LLM usage/logs, model catalog, gateway policy |
Why "common" is not a module
GlobalExceptionHandler and WebConfig live in
app, not a shared module: the exception handler has an
@ExceptionHandler for nearly every module's custom exceptions —
it depends on almost everything and nothing depends on it. That is
cross-cutting glue, not shared low-level code.
Dependency rules that will bite you
- New capability = new leaf module depending on
crypto/security/tenancy only — the established "sarvam shape". Nothing upstream may depend back on it.
providers → sarvam is a real dependency (credential resolution); the reactor builds sarvam first regardless of <modules> order.
agents and tools are merged — do not attempt to re-split without breaking the verified AgentToolProvider↔AgentChatService cycle first.
eval is a true standalone leaf — never let it gain a dependency on tenancy or the database.