System Architecture
Understand the Clouisle tech stack, request flows, scalability, and security boundaries
Clouisle uses a layered architecture separating frontend, backend, and infrastructure: a Next.js frontend for UI and SSR, a FastAPI backend for Agents/Workflows/Knowledge Base, Celery for async tasks, and PostgreSQL, Redis, and Qdrant for business data, caching/queues, and vector retrieval.
Technology Stack
| Layer | Components | Notes |
|---|---|---|
| Frontend | Next.js 16 (App Router), TypeScript, Tailwind CSS 4 + shadcn/ui, Bun | The container runs the Next.js standalone server (node server.js) and does not include Nginx; deploy/nginx/default.conf is only an optional external reverse-proxy example |
| Backend | FastAPI (Python 3.13), Tortoise ORM + asyncpg, Celery + Redis | LangChain adapters (chat/embeddings/text splitting); self-built WorkflowOrchestrator for workflow execution; LangGraph is declared but not used at runtime; MarkItDown for document conversion |
| Infrastructure | PostgreSQL 17 (pg_search full-text), Redis 7 (cache/Celery broker/SSE event buffer/rate-limit and lockout counters), Qdrant (vectors) | Vectors are stored in a dedicated collection per embedding dimension ({prefix}_{dimension}), determined by the selected embedding model |
Request Flows & Execution Lifecycle
1. Basic Request Flow
Browser → (optional external reverse proxy / Ingress) → Next.js SSR (node server.js) → FastAPI API → PostgreSQL → Response2. Chat Request Flow & Asynchronous AgentRun Lifecycle
Clouisle implements a durable, decoupled AgentRun execution architecture for conversational agents:
User Message ──► FastAPI (POST /api/v1/agents/{agent_id}/chat/runs) ──► Redis Queue (Celery agent)
│ (202 Accepted, run_id) │
▼ ▼
SSE Stream Celery Worker (run_agent_task)
(GET /api/v1/agents/{agent_id}/chat/runs/{id}/stream) │
▲ Acquires Conversation Lock
│ │
Redis Event Buffer ◄──────────────────────────── AgentLoop ReAct Cycle
(SSE Event Pub/Sub) │
┌──────────┴──────────┐
▼ ▼
Tool Calling / Context Compaction
RAG Retrieval (Micro & Macro)
│ │
▼ ▼
[ask_user pause] Watermarked Summary
(Status: WAITING) (Tokens kept in budget)- Durable AgentRun: Starting a run dispatches a Celery task and immediately returns
202 Acceptedwith arun_id. The task is routed to theagentqueue and consumed by the main worker; if you rewrite the worker's-Qand dropagent, runs stay inqueuedforever without any error, and users only see "queued" (queue mapping: Deployment Architecture). The client establishes an SSE stream (/chat/runs/{run_id}/stream) and can disconnect or reconnect (from_sequence) without interrupting background tool execution. Tasks on theagentqueue set no automatic retries — model calls and tool execution have side effects, so a retry would execute them twice; runs interrupted by a dead worker are reclaimed by the Beat-scheduledsweep-lost-agent-runs(every 2 minutes) and markedinterruptedrather than replayed. - AgentLoop ReAct Engine: Manages iterative reasoning and tool-calling cycles (
max_iterations, timeouts, and credential injection). - Three-Level Context Compaction:
- Micro Compaction: Automatically truncates and summarizes oversized tool output payloads and raw base64 data to preserve token budgets.
- Macro Compaction: When conversation tokens cross the configured trigger budget, the engine computes turn boundaries, runs an LLM summarization over older messages, inserts a
context_summarymessage with watermark tracking, and retains recent turns in verbatim form. - Preflight & Recovery Guards: Token headroom reservations and automatic retries on context-length provider errors.
- Human-in-the-Loop (
ask_user) Suspension & Resumption: Whenask_useris called,AgentLoopentersAgentRunStatus.WAITINGwith pending question metadata. Submitting answers viaPOST /chat/runs/{run_id}/answerstakes an ORM row lock, validates payloads, and resumes the active run seamlessly.
3. Workflow Engine Execution Flow
Trigger Event / User Input ──► FastAPI (POST /workflows/{id}/runs) ──► Celery Queue (workflow)
│
▼
WorkflowOrchestrator
│
Parse DAG Graph Definition
(ExecutionPlan, filter comments)
│
Execute Node Pipeline
(LLM, Code, Condition,
Iteration, Pause...)
│
┌───────────────────────┴───────────────────────┐
▼ ▼
Node Execution Pause Request
(ExecutionContext Flow) (Status: WAITING)
│ │
▼ ▼
Completed Result Resume with Feedback- Graph Topological Planner (
ExecutionPlan): Validates DAG dependencies, resolves parallel executable batches, and strips non-executable canvas documentation nodes (NON_EXECUTABLE_NODE_TYPES = {"comment"}). - Modular Node Executors: Handlers for
llm,condition,code(Sandbox),iteration/loop,template,variable_aggregator,knowledge_retrieval,tool,agent, andsub_workflow. - Pause & Resume Handlers: Nodes requiring human review (
pause) persist aWorkflowPauseRequestand suspend execution until approved or filled via/runs/{id}/pause-requests/{req_id}/submit.
Scalability
The frontend and API are stateless and scale horizontally. The main worker (python main.py worker -c 4 -Q default,agent,knowledge,workflow) consumes all four of default, agent, knowledge, and workflow; to scale one queue independently, start an extra worker subscribed to a single queue (for example -Q agent), but a worker must consume default and agent at all times, otherwise notifications, cleanup tasks, and Agent conversations silently pile up in the queue. The code sandbox is a separate fifth queue, sandbox, consumed by the dedicated sandbox-worker; scaling it does not affect knowledge base or workflow processing. Celery Beat must run exactly one replica — it is a bare scheduler without a database lock, and multiple replicas would deliver scheduled tasks repeatedly. For the full queue mapping, periodic Beat tasks, and scaling commands, see Deployment Architecture.
Security and Multi-tenancy
- Authentication: password (bcrypt), SSO (OAuth2/OIDC/SAML/CAS), API Keys (
clou_prefix +Authorization: Bearer). - Authorization: JWT validation + permission checks (
resource:action/admin:resource:action); Super Admin bypasses. - Data isolation: resources belong to a team, queries are filtered by team membership automatically; regular users only see their own conversations (see Teams & Security).
- Audit: records the actor, operation, and before/after snapshots, with retention days and archiving.
Performance and Caching
User sessions default to 30 days (controlled by the session_timeout_days site setting), with a 8-day JWT fallback token; site settings are not cached and are read directly from the database on every lookup.
There is no single global rate-limiting middleware: each protection is implemented per scenario, with its own boundary:
| Mechanism | Limit | Where it lives |
|---|---|---|
| Login failure lockout | After max_login_attempts (default 5) consecutive failures, the account is locked for lockout_duration_minutes (default 15) minutes | Account fields + site settings |
| TOTP verification | 5 failures within a 300-second window lock verification for 900 seconds | Redis counter |
| Admin bulk email | 100 messages per hour per sender | Redis counter (TTL 3600s) |
| Per-recipient email | 5 messages per day per address | Redis counter (TTL 86400s) |
| API Key requests per minute | rate_limit field defaults to 1000/min, 0 meaning unlimited — stored but not enforced today | Metadata field |
Do not treat the API Key rate_limit as an active abuse control, and do not assume captcha alone stops brute force: what actually blocks sign-in attempts is the account lockout and the TOTP lockout (see Teams & Security).
Health Checks
/api/v1/health— public basic health check (used by the container HEALTHCHECK)./api/v1/admin/observability/system/health— admin observability health (CPU/memory/disk/database/Redis/worker), requiresadmin:dashboard:access.
See also:
- Deployment Architecture — 3 images / 5 services topology and volumes
- Agent, Workflow, Knowledge Base — core resource concepts
- Teams & Security — multi-tenancy and permission boundaries
- Environment Variables Reference — startup-level configuration
How is this guide?