HelixLLM is a layered monolith with modal distribution. A single Go binary compiles all layers together and uses a mode system to activate the appropriate subsystems at runtime.
- Single binary, multiple modes: One build, one test suite, deployable as a monolith or distributed across hosts
- Go + Gin Gonic: Type safety, native concurrency, single binary deployment
- Containers first: Podman preferred, Docker as fallback, auto-detected
- HTTP/3 primary: QUIC for lower latency, HTTP/2 fallback via ALPN negotiation
- Zero overhead in full mode: Direct function calls between layers, no serialization or network hops
+-----------------------------------------------------------+
| Gateway Layer |
| HTTP/3 Server, OpenAI/Anthropic APIs, Auth, Streaming |
+-----------------------------------------------------------+
| Brain Layer |
| LLM Routing, llama.cpp, OpenAI, Anthropic, Optimization |
+-----------------------------------------------------------+
| Knowledge Layer |
| RAG Pipeline, Embeddings, Vector Store, Chunking |
+-----------------------------------------------------------+
| Agents Layer |
| ReAct Loop, Tools, Conversation Context, RAG Hook |
+-----------------------------------------------------------+
| Control Plane Layer |
| Host Probing, Scheduling, Deployment, Monitoring |
+-----------------------------------------------------------+
| Shared Foundation |
| Config, Events, Logging, Observability, Health |
+-----------------------------------------------------------+
The mode is set via HELIX_MODE environment variable or --mode CLI flag:
| Mode | Layers Active | Use Case |
|---|---|---|
full |
All | Single-host development and production |
gateway |
Gateway + Shared | Dedicated API frontend |
brain |
Brain + Shared | Dedicated LLM inference node |
knowledge |
Knowledge + Shared | Dedicated RAG pipeline |
agents |
Agents + Shared | Dedicated agent workers |
control |
Control + Shared | Cluster management node |
Mode parsing is in internal/mode/mode.go. The main function in cmd/helixllm/main.go always initializes all layers in the current implementation (full mode). In distributed deployment, each host runs the binary in a specific mode.
All layers are in the same process. They communicate through direct Go function calls:
Gateway Handler -> brain.Brain.ChatCompletion() -> direct return
No serialization, no network, no latency overhead.
When layers run on separate hosts, communication uses:
- gRPC streaming (
digital.vasic.streaming): Real-time inter-layer calls - Kafka messaging (
digital.vasic.messaging): Async events with durability - EventBus (
digital.vasic.eventbus): In-process pub/sub within each host
Client
|
v
Gateway (router.go)
| Auth middleware (API key validation)
| Rate limiting middleware
| Security headers middleware
| Content negotiation middleware
|
v
HandleChatCompletions (openai.go)
| Parse OpenAI-format request
| Convert to internal types
|
v
Brain (brain.go)
| Route to provider (by model name, capability, cost)
|
v
Provider (llamacpp.go | openai_provider.go | anthropic_provider.go)
| Send to LLM backend
| Receive response
|
v
Gateway
| Convert to OpenAI-format response
| Compress (Brotli/gzip)
| Stream via SSE if requested
|
v
Client
Client
|
v
Agent API (api.go)
| Load session history (if session_id provided)
| Append new messages
|
v
Agent (agent.go) -- ReAct Loop
| 1. RAG hook: augment with knowledge context
| 2. Send to Brain for reasoning
| 3. Check response for tool calls
| If tool call: execute tool, append observation, loop
| If final answer: break
| 4. Repeat (max 10 turns)
|
v
Agent API
| Save to session context
| Return response
|
v
Client
Client
|
v
Knowledge API (api.go)
| Validate request (content, collection not empty)
|
v
Pipeline (pipeline.go)
| 1. Chunk document (FixedSizeChunker)
| 2. Embed each chunk (Embedder)
| 3. Store vectors (VectorStore)
|
v
Client <- IngestResult (id, collection, chunk count)
The server (internal/server/server.go) runs two transports simultaneously:
- HTTP/3: QUIC over UDP via
quic-go/http3 - HTTP/2: TLS over TCP via standard
net/http
Both serve the same Gin engine. The Alt-Svc header advertises HTTP/3 on every response so clients can upgrade.
TLS 1.3 is the minimum version. ALPN negotiation supports h3, h2, and http/1.1.
Standard middleware applied to all requests:
gin.Recovery()-- panic recoverymiddleware.RequestID()-- unique request ID generationmiddleware.Compression()-- Brotli/gzip response compression
Defined in internal/gateway/:
- router.go -- Registers
/v1/*routes with auth, rate limiting, security headers, and content negotiation middleware - openai.go -- OpenAI-compatible handlers (chat completions, completions, models, embeddings)
- anthropic.go -- Anthropic-compatible handler (messages)
- streaming.go -- SSE streaming utilities
All /v1/* routes go through:
APIKeyAuth-- validatesAuthorization: BearertokensRateLimit-- sliding-window rate limiting per IPSecurityHeaders-- sets security-related HTTP headersContentNegotiation-- handles Accept/Content-Type for TOON/JSON
Defined in internal/brain/:
- brain.go -- Orchestrator that holds providers and routes requests
- router.go -- Intelligent routing by model name, capability, cost, latency
- provider.go -- Common provider interface
- llamacpp.go -- llama.cpp HTTP client adapter
- openai_provider.go -- OpenAI API client
- anthropic_provider.go -- Anthropic API client
The Brain creates provider instances at startup based on configuration. When a key is provided, that provider is registered. The router uses the model name in each request to select the provider.
Defined in internal/knowledge/:
- pipeline.go -- Orchestrates ingestion and query flows
- api.go -- HTTP handlers for
/internal/knowledge/* - embedder.go -- Embedding interface and hash-based implementation
- store.go -- VectorStore interface and in-memory implementation
- chunker.go -- Document chunking (fixed-size with overlap)
Defined in internal/agents/:
- agent.go -- ReAct loop implementation
- api.go -- HTTP handlers for
/v1/agents/* - tool.go -- Tool interface and registry
- context.go -- Conversation session management
- tools/ -- Built-in tool implementations (echo, time, knowledge_query)
Defined in internal/control/:
- api.go -- HTTP handlers for
/internal/cluster/*and ControlPlane orchestrator - prober.go -- SSH-based host capability detection
- scheduler.go -- Service placement with 5 strategies
- deployer.go -- Container deployment via SSH
- monitor.go -- Continuous cluster health monitoring
- types.go -- HostProfile, ServiceRequirement, PlacementResult, etc.
Defined in internal/shared/:
- config/ -- Configuration loading from environment variables with struct tag defaults
- events/ -- EventBus setup with typed topics (ServerStarted, ServerStopped)
- health/ -- Health checker with aggregated status reporting
- logging/ -- Structured logger with level and format configuration
- observability/ -- OpenTelemetry tracer setup with multiple exporters
Public types live in pkg/:
- pkg/api/ -- OpenAI and Anthropic request/response types
- pkg/types/ -- Internal message and response types shared across layers
43 Git submodules in submodules/ provide the production infrastructure. They are referenced via replace directives in go.mod:
replace digital.vasic.config => ./submodules/Config
replace digital.vasic.eventbus => ./submodules/EventBus
...
This allows local development against all modules while maintaining them as independent repositories.