Brain
Brain
Responsibility
Brain is the NestJS service for generation records, character metadata, provider integrations, and Prisma-owned data in the fennec schema. It also provides reference image nudification (synthetic NSFW variant generation from SFW images) and a body-parts reference library used during character creation.
Under T-Bone, brain owns the workflow engine — the content framework that replaces hand-coded GenerationType branches: workflows, subworkflows, nodes, executions, contracts, and the per-provider inference adapters all live here and are served over an HTTP API (see Workflow engine below).
Runtime
Brain runs as a NestJS HTTP and gRPC service. It exposes a gRPC microservice consumed by sirloin through the generated Brain client and calls round over gRPC for model-serving work.
Primary Source Paths
- apps/brain/src/modules/
- apps/brain/src/modules/domain/workflow/ (T-Bone workflow engine: engine, nodes, contracts, executions)
- apps/brain/src/generated/
- apps/brain/prisma/schema.prisma
Contracts And Generated References
- Brain gRPC server setup lives in apps/brain/src/main.ts.
- Round generated client code lives under apps/brain/src/generated/round/.
- Sirloin consumes Brain through apps/sirloin/pkg/brain-client/.
Workflow engine
The T-Bone workflow engine lives under apps/brain/src/modules/domain/workflow/. It is the content framework that turns one-off, hand-coded generation types into framework-driven workflows. Core vocabulary:
- Workflow — a named, versioned graph (stored as JSON) describing end-to-end how one piece of media is generated, from raw inputs through provider inference to a stored result. Declares an input contract and an output contract, carries embedded pricing rules, and maps each execution to exactly one
Generationrow. Workflows are drafts until published, which freezes a numbered version. Identified byname+version. - Subworkflow — a reusable graph fragment that runs only inside a workflow (one-level nesting, enforced by the save validator). A workflow pins a specific subworkflow version.
- Node — the atomic step: a backend method wrapped by a base class that records start/end events, timing, inputs, outputs, and errors so each step is independently inspectable. Nodes live inside a workflow’s graph and are versioned with it.
- Engine — the runtime that interprets the graph. It auto-parallelizes independent nodes by topological depth, persists a per-node execution trace (for profiling and crash resume), and enforces cross-cutting behavior an author can’t skip (the moderation wrap on inference nodes). On boot it re-enqueues executions left RUNNING by a crash.
- Execution — a single run: RUNNING → COMPLETED or FAILED, with a per-node trace and exactly one resulting
Generation. The pinned graph is captured at start so a mid-flight edit can’t corrupt an in-progress run.
Contract and surfaces
A workflow’s contract (input_schema, pricing, output_schema) is HTTP-served and is the single source of truth that the UI surfaces render from and that sirloin re-evaluates pricing against:
- brisket — user-facing forms, dynamic pricing, result presentation.
- fennec — admin: the same forms plus executing DRAFT workflows, internal-only inputs, and per-node logs.
- flank — the visual workflow editor, re-pointed to read/write brain over HTTP.
- Foxy360 / AgentOS — the agent tool surface over the same verbs, ADMIN-gated.
Two HTTP surfaces: the “Beef” surface (@Controller('api/*'), API-key auth) is used by sirloin for service-to-service calls; the Clerk-authenticated /workflow/* controllers serve the human surfaces. Every workflow operation requires the ADMIN role.
Inference, moderation, pricing
- Adapters — one generic integration per inference provider (FAL, WaveSpeed, RunPod, OpenRouter, Hive); the model is an input on the inference node, not its own adapter. A model that breaks the per-provider assumption can get a model-specific adapter.
- Moderation wrap — Hive visual moderation on an inference node’s inputs and outputs, enforced by the engine; a workflow disables it only via an explicit flag when its semantics require it (e.g.
is_nsfw = true). - Pricing — rules are embedded in the contract, but the charge authority stays in sirloin; brisket shows the live price, sirloin re-evaluates server-side before deducting credits.
- Generation mapping — each execution produces exactly one
Generationwithgeneration_type = WORKFLOW,workflow_name, andworkflow_version, keyed by themedia_idin the trigger inputs, so existing galleries/UIs work unchanged.
Not in scope for v1: cancellation of in-flight executions, finer-grained auth beyond ADMIN, a first-class Templates concept, and brain-owned secrets management.
Related Flows
- Media Generation
- Character Creation (includes reference image nudification)
- Brain API — Body Parts Library & Reference Nudify
- Brain Inference Providers (provider inventory, fallback chains, traffic split)
Related Standards
Related Decisions
Generation and provider decisions live under docs/src/content/docs/decisions/ as they are migrated.
Operations
Brain uses BullMQ/Redis for async generation workflows and PostgreSQL via Prisma for the fennec schema.
Media generation paths that handle provider videos and source media use disk-backed temporary files instead of whole-file buffers where practical. The storage module owns temporary directory cleanup and bounded file I/O through TempFileService and FileIoLimiterService; video persistence, provider preupload, reference-video trimming, and first-frame extraction use path/stream APIs in apps/brain/src/modules/application/storage/services/ and apps/brain/src/modules/application/video/services/.
File I/O limiter state is exported as OpenTelemetry gauges for operations checks; see Observability.
Local Commands
- cd apps/brain && pnpm lint
- cd apps/brain && pnpm tsc
- cd apps/brain && pnpm test
- cd apps/brain && pnpm start:dev