Manifold – Architecture & Module Map
1. What this system does
- Purpose: Manifold is an AI workflow automation platform that lets operators define specialist agents, orchestrate tool-backed agents/workflows, observe every run, manage shared assets (projects/playground), and offer the surface via CLIs, HTTP/SSE APIs, Kafka orchestrations, and a web UI.
- Key capabilities / responsibilities:
- Autonomous chat-style agents that can route to specialists, orchestrate tool calls (local CLI, web search/fetch, patch updates, RAG helpers, TTS, Kafka, MCP), and optionally execute deterministic WARPP workflows.
- Long-lived persistent services (notably
agentd) exposing REST/SSE surfaces, authentication, project/playground management, RAG ingestion, MCP/OAuth hooks, Whisper STT, and observability/metrics. - Kafka-based orchestrator and helper CLI tooling (
agent,orchestrator,whisper-go,adk) covering single runs, workflow consumption, STT support, and future developer helpers. - SPA frontend (
web/agentd-ui) that drives the in-browser control plane, communicating with agentd’s HTTP endpoints.
2. High-level architecture
Manifold centers on a shared internal/agent.Engine that orchestrates LLM + tool loops. Each runtime (CLI, HTTP, Kafka) loads the same config/observability/LLM/providers/tool registry but swaps how intent is injected and how output is surfaced. The big picture combines:
- Configuration & observability (
internal/config,internal/observability,config.yaml,example.env) – every binary loads these to understand LLM providers, tool toggles, databases, OAuth hooks, Kafka/Redis endpoints, and telemetry settings. - Agent + tool layer (
internal/agent,internal/tools,internal/llm,internal/specialists,internal/mcpclient) – orchestrates message construction, LLM requests, tool dispatch/schema exposure, specialist routing (DB+YAML), and MCP tool registration. - Persistence & workflow helpers (
internal/persistence,internal/rag,internal/playground,internal/projects,internal/warpp) – provide storage for specialists, playground experiments, projects, WARPP workflows, RAG ingestion, and data retrieval. - Transports: CLI (
cmd/agent), HTTP daemon (cmd/agentd→internal/agentd), Kafka worker (cmd/orchestrator→internal/orchestrator), Whisper STT CLI (cmd/whisper-go), and placeholdercmd/adk. - Frontend & docs:
web/agentd-uiSPA served via agentd’s static handler or deployed separately; documentation/examples/deployments live underdocs/,examples/,deploy/.
Every major service eventually delegates to the same internal/agent.Engine and shared tool stack, but they differ on intent sources (CLI args vs HTTP requests vs Kafka messages) and sinks (stdout, HTTP response, Kafka response).
3. Modules and packages
- ./cmd/
- Purpose: Hosts Go binaries that bootstrap each runtime (agent CLI, agent daemon, Kafka orchestrator, Whisper STT CLI, and placeholder
adk). - Key entries:
cmd/agent/main.go– single LLM/agent run with tool registry, specialist seeding, optional WARPP mode, and CLI output.cmd/agentd/main.go→internal/agentd.Run()– HTTP/SSE server that composes tools, WARPP, specialists, playground, projects, auth, and MCP.cmd/orchestrator/main.go– Kafka WARPP worker with deduping via Redis and response publishing.cmd/whisper-go/main.go– speech-to-text CLI around vendoredwhisper.cpp.cmd/adk/– currently empty placeholder (TODO: define tooling).
- Interactions: Each binary calls into
internal/config,internal/observability,internal/llm,internal/tools,internal/specialists,internal/persistence, andinternal/warpp.
- Purpose: Hosts Go binaries that bootstrap each runtime (agent CLI, agent daemon, Kafka orchestrator, Whisper STT CLI, and placeholder
- ./internal/
- ./internal/agent/ – Core reasoning loop (
engine.go,steps.go), message formatting, memory summarization, WARPP helpers, and shared prompts. Depends oninternal/llm/internal/tools. - ./internal/agentd/ – HTTP server bootstrap, router, and handlers (chat, tools, playground, projects, auth, STT, specialists, WARPP, metrics). Ties to all other packages plus
internal/webui. - ./internal/orchestrator/ – Kafka consumer/dedupe logic, WARPP adapter, response publishing, and helper tools under
cmd/orchestrator/tools. - ./internal/warpp/ – Workflow loader/runner (guards, personalization, step publisher). Used by agent CLI WARPP mode, agentd workflows, and Kafka orchestrator.
- ./internal/tools/ – Registry plus concrete tools (
cli,web,patchtool,kafka,tts,specialists,llmtool,textsplitter,rag,warpptool,utility,multi_tool_use, etc.). Tools register per-process and expose tool schemas consumed by the engine. - ./internal/llm/ – Provider abstraction (OpenAI/Anthropic/Google/local), streaming/tracing support, logging hooks, and factories referenced by every runtime.
- ./internal/specialists/ – Registry/router for specialist agents (DB-backed or YAML). Populates tool registries and supports route overrides via config.
- ./internal/mcpclient/ – MCP server registration and tool bridging (Model Context Protocol servers register tools into the same registry).
- ./internal/persistence/ – Interfaces plus platform implementations (memory/Postgres) for chat history, playground, projects, WARPP, MCP, specialists, etc.
databases.Managerconstructs stores used by agentd & orchestrator. - ./internal/rag/ – Chunking, embeddings, ingestion, retrieval, and ingestion service used by RAG tools and persistence.
- ./internal/playground/ – Prompt/dataset/experiment storage and evaluation orchestration; agentd exposes APIs for editing/running experiments.
- ./internal/projects/ – Filesystem-backed project artifacts service; integrated with agentd APIs.
- ./internal/auth/ – OIDC/OAuth providers, session middleware, RBAC helpers for agentd routes.
- ./internal/config/ – Config loader structs referencing
config.yaml,config.yaml.example,example.envto unify every runtime. - ./internal/observability/ – Logger bootstrap, OTel tracer, HTTP client wrappers, payload filtering. Initialized by every binary.
- ./internal/webui/ – Static asset handler, dev proxy, and optional auth guard used by agentd for
/routes.
- ./internal/agent/ – Core reasoning loop (
- ./web/agentd-ui/
- Vite-based TypeScript SPA (Svelte/Vue-like) that calls agentd HTTP APIs for chat, tools, projects, playground, experiments, WARPP, etc. Built assets live under
web/agentd-ui/dist. Agentd serves them viainternal/webui.
- Vite-based TypeScript SPA (Svelte/Vue-like) that calls agentd HTTP APIs for chat, tools, projects, playground, experiments, WARPP, etc. Built assets live under
- ./docs/, ./examples/, ./deploy/, ./configs/, ./scripts/, ./tools/, ./external/, ./dist/:
- Provide onboarding/architecture guides (
docs/*), workflow samples (examples/workflows), deployment scaffolding (docker-compose, vector_db_local, configs), helper scripts, vendor code (external/whisper.cpp), and build artifacts.
- Provide onboarding/architecture guides (
4. Entrypoints & startup flow
./cmd/agent/main.go– single-run CLIinternal/config.Load()reads YAML/env to configure LLM, tools, specialists, WARPP, logging, observability, and timeouts.- Initializes logging/OTel via
internal/observability, builds HTTP client (with extra headers), configures global LLM logging, and seeds specialists frominternal/persistence/databases(reflecting DB overrides). - Builds the LLM provider via
internal/llm/providers, registers tools (CLI exec, web search/fetch, patch, text splitter, textbox, TTS,llm_transform, specialists, MCP registrations), and wraps them percfg.EnableTools/cfg.ToolAllowList. - Connects to MCP servers to register MCP tools.
- If
-warppis set, loads WARPP workflows (DB-backed), personalizes intent, and executes viainternal/warpp.Runner. Otherwise, optionally routes to a named specialist and ends. - Constructs
internal/agent.Enginewith prompts/summary rules and runsEngine.Run, respectingAgentRunTimeoutSeconds, printing final response.
./cmd/agentd/main.go→internal/agentd.Run()– HTTP daemon- Loads config/env, initializes logger/OTel/tracing, and builds shared HTTP client + LLM provider (plus summary provider).
- Constructs database manager (
internal/persistence/databases.NewManager) for chat, projects, playground, specialists, WARPP, MCP, etc., and creates specialist registry overlays. - Registers tools (CLI/web search/fetch, patch, text splitter, textbox, TTS, Kafka, RAG ingest/retrieve,
llm_transform, image tools, specialists, agent-wrappers, multi-tool). Applies global tool filters/allow lists to mirrorcfg.EnableTools. - Registers MCP clients, loads WARPP workflows (FS/DB), and prepares
internal/warpp.Runner. - Builds higher-level services: summary helpers, playground service (
internal/playground), project service, RAG ingestion/state, Whisper STT loader, auth provider, metrics reporter. - Wires HTTP routes (
router.go,handlers_*): chat, tools, specialists, playground, projects, WARPP, MCP OAuth, audio/STT, metrics, auth, static SPA assets (viainternal/webui), and SSE endpoints for progress. - Listens on configured port (default
:32180) serving API + SPA.
./cmd/orchestrator/main.go– Kafka WARPP worker- Loads Kafka brokers/topics, Redis dedupe settings, worker counts, timeouts, and logging config.
- Initializes Redis dedupe store, Kafka producer/admin, observability, HTTP client, LLM provider, and tool registry (CLI/web/patch/TTS/llm_transform/specialists/Kafka send). Applies tool filters per config.
- Registers MCP servers, loads WARPP workflows via
internal/warpp, wraps runner withinternal/orchestrator.NewWarppAdapter. - Ensures Kafka topics exist (command/response/DLQ), then starts
internal/orchestrator.StartKafkaConsumer. - Workers loop: read
CommandEnvelope, dedupe (Redis), map reply topic, execute workflows with the WARPP adapter (streaming steps via publisher), and publish success/errorResponseEnvelopeplus DLQs when needed.
Manifold – Runtime & Environments
1. Runtime overview
manifold is a long-lived service (cmd/agentd) that exposes a web UI on port 32180 and orchestrates agent workflows (agents, orchestrator, orchestrated prompts, workflows). The platform ships with supporting CLI utilities (e.g., scripts/dev.sh for fmt/vet/build checks, scripts/pre-commit hook) plus additional command binaries under cmd/orchestrator, cmd/agent, etc. The main runtime (agentd) runs as a Go server backed by the configuration loader (internal/config/loader.go), which merges .env, config.yaml, and defaults before wiring OpenAI/Google/Anthropic providers, databases, and metrics exporters.
2. Environments
- local (default) – development workstation. Uses
docker-compose.ymlto spin up the Go service, Postgres (pg-manifold), and optional observability stack (ClickHouse + OTEL collector). Configuration files (config.yaml,.env) are tailored for localhost connections, non-HTTPS auth (cookieSecure=false), and demo credentials. This environment is what the quickstart (QUICKSTART.md) walks through; it expects the host to run Docker, Node.js 20, pnpm, and a Chromium browser. - dev / custom – implied by configuration defaults (
obs.environmentdefaults todev,LlmClient.Providercan be set via env). Switchable by settingENVIRONMENT,OTEL_EXPORTER_OTLP_ENDPOINT, or alternative config files (SPECIALISTS_CONFIG). This allows pointing at staging/cloud endpoints (e.g., production Kafka brokers or ClickHouse DSNs) without code changes. Feature flags/toggles such asENABLE_TOOLS/SPECIALISTS_DISABLEDandAUTH.*can be changed per environment via.envoverrides.
3. Configuration
- Primary config files:
config.yaml(active) andconfig.yaml.example(template). The loader (internal/config/loader.go) first merges environment variables (viagodotenv.Overload()reading.env), then overlays the YAML file(s), and finally applies hard defaults..envis expected at repo root and is mounted into the Docker container (docker-compose.yml, servicemanifold). - Environment variables override YAML for every major area: OpenAI/GPT settings (
OPENAI_API_KEY,OPENAI_MODEL,LLM_PROVIDER), embedding service (EMBED_*), databases (DATABASE_URL,SEARCH_DSN, etc.), Kafka topics, observability exports (OTEL_SERVICE_NAME,CLICKHOUSE_*), TTS, tools toggles (ENABLE_TOOLS,SPECIALISTS_DISABLED), and runtime controls (timeout, log levels).Load()ensures required settings (OPENAI_API_KEY,WORKDIR) are present and resolvesWORKDIRto an absolute path. - Specialist definitions (agents/tools) can live in the same
config.yamlor an alternate file pointed to bySPECIALISTS_CONFIG; environment variables such asSPECIALISTS_DISABLEDor provider-specific vars (e.g.,GOOGLE_LLM_API_KEY) take precedence.
4. How to run locally
Prerequisites
- Docker – required to build containers, start Postgres, Redis, optional ClickHouse/OTEL.
- Node 20 – required for the UI (
web/agentd-ui). Usenvm use 20. - pnpm – install global or via package manager to install frontend deps.
- Chrome/Chromium – needed for web tools (Playwright MCP).
- GNU Make + Go toolchain –
scripts/dev.sh,make fmt,go buildrun from repo root.
Steps
cd ~/path/to/manifold # repo root (“./manifold” in prompt)
cp example.env .env # create env file (contains OPENAI_API_KEY placeholder)
cp config.yaml.example config.yaml # copy default configuration
# edit .env and config.yaml to provide OPENAI_API_KEY, WORKDIR, and any overrides
# e.g., replace OPENAI_API_KEY in .env with a real key; set WORKDIR to repo root
nvm use 20
cd web/agentd-ui
pnpm install
cd ../.. # back to repo root
touch manifold.log # optional, runtime writes to log
docker compose up -d manifold pg-manifold
Manifold – Data & Storage
1. Data stores overview
- PostgreSQL (primary relational store)
- Purpose: Long-lived persistence for authentication/RBAC, specialists registry, chat sessions/messages, MCP server configurations, WARPP workflows, playground prompts/datasets/exercises, and shared search/vector/graph backends (documents/chunks, embeddings, nodes/edges).
- Configuration:
internal/config/config.goexposesConfig.Databases→DBConfigstruct withDefaultDSNplus per-subsystemSearch,Vector,Graph, andChatconfigs.internal/persistence/databases/factory.goreadsDatabases.DBConfigand routes each subsystem to Postgres or an in-memory fallback.
- In-memory stores (development/testing fallback)
- Purpose: Provide zero-dependency persistence when Postgres is absent for chat, specialists, MCP, WARPP, and the search/vector/graph backends, keeping interfaces consistent for the rest of the app.
2. Core data models / entities
Authentication / RBAC (internal/auth/store.go)
| Model | Key fields | Relationships |
|---|---|---|
users |
id BIGSERIAL, unique email, provider, subject, name, picture, created_at, updated_at |
Linked from user_roles.user_id (RBAC) and sessions.user_id (session ownership). |
roles |
id BIGSERIAL, unique name, description |
user_roles.role_id joins users to roles. |
user_roles |
Composite PK (user_id, role_id) |
Many-to-many between users and roles, cascading on delete. |
sessions |
id TEXT PK, user_id FK, expires_at, id_token, created_at |
Stores OIDC/OAuth sessions; user_id ties sessions to their owner and enables logout flows. |
Playgrounds (internal/persistence/databases/playground_store.go)
| Table | Notes | Relationships |
|---|---|---|
playground_prompts |
Stores registry.Prompt JSON payloads, indexed by user_id. |
Versions stored in playground_prompt_versions. |
playground_prompt_versions |
History per prompt with created_at, per-user filtering. |
prompt_id references playground_prompts.id logically (no FK). |
playground_datasets |
Dataset metadata (JSONB) per user_id. |
Used as parent for snapshots. |
playground_snapshots |
Composite PK (dataset_id, id) with metadata payload. |
Each snapshot owns rows (playground_rows). |
playground_rows |
Rows for each snapshot keyed by (dataset_id, snapshot_id, row_id) to guarantee deterministic uniqueness. |
Cascaded/deleted by code before removing a dataset. |
playground_experiments |
Experiment specs stored as JSONB per user. | Linked to runs. |
playground_runs |
Run payloads (JSONB); FK enforced by experiment_id in code. |
Run results reference run_id. |
playground_run_results |
Results persisted via batched inserts (uses pgx.Batch). |
Owned by runs; deleted manually when experiments removed. |
Entity Relationships
3. Migrations and schema management
- Location: Every persistence module bootstraps its schema under
internal/persistence/databases/(e.g.,auth/store.go,specialists_store.go,chat_store_postgres.go,playground_store.go). - How applied:
databases.Manager.Initinstantiates each store and invokesInit/InitSchemamethods that executeCREATE TABLE IF NOT EXISTSstatements. - Ordering/versioning: Schema updates happen at runtime; there’s no explicit migration history. Each initializer runs in code order during startup.
Manifold – Interfaces & Workflows
1. Inbound interfaces overview
HTTP Server] Orch[cmd/orchestrator
Kafka Consumer] CLI[cmd/agent
CLI Tool] end subgraph Core [Internal Core Packages] Router[internal/agentd/router] Handlers[HTTP Handlers
chat/projects/warpp] Engine[internal/agent.Engine] OrchLib[internal/orchestrator] Tools[internal/tools.Registry] end subgraph Infra [Infrastructure Services] Kafka((Kafka)) Redis[(Redis Dedupe)] DB[(Persistence Stores)] LLM[LLM Providers] end AgentD --> Router Router --> Handlers Handlers --> Engine Handlers --> DB CLI --> Engine Orch --> Kafka Orch --> OrchLib OrchLib --> Redis OrchLib --> Tools Engine --> Tools Engine --> LLM Tools --> LLM
2. HTTP / RPC APIs
- Agentd surface (
internal/agentd)GET /healthz&GET /readyz– basic liveness/readiness endpoints./auth/*&/api/me– exposed when auth enabled./api/projects&/api/projects/{id}– CRUD/listing backed byinternal/projects.Service./api/runs,/api/chat/sessions– chat session management./agent/run+/agent/vision,/api/prompt– agent execution entrypoints./api/mcp/*– MCP server listing and OAuth endpoints.
- Playground API (
internal/httpapi)- Prompts (GET list
/api/v1/playground/prompts, POST create, GET/DELETE by ID). - Datasets and Experiments (
/api/v1/playground/experiments,/runs).
- Prompts (GET list
- CLI-to-internal APIs
- CLI agent runs call into
internal/agent.Enginedirectly but expose consistent configuration viacmd/agent/main.go.
- CLI agent runs call into
3. Key workflows
Agentd HTTP request → agent engine run
Triggered via POST /agent/run. The handler extracts context, builds prompt/history attributes, and calls agent.Engine.Run, which iterates the LLM reasoning loop.
Kafka command → WARPP workflow execution
Messages posted to the command topic are consumed by the orchestrator, deduped via Redis, and executed via the WARPP runner.