Skip to content

Code Generation Pipeline

NinjaStack's code generation engine transforms an Agentic Schema Definition into runnable Python code.

Pipeline

flowchart LR
    ASD[schema.json] --> Engine[CodeGen Engine]
    Engine --> Models[Pydantic Models]
    Engine --> Agents[ADK Agents]
    Engine --> GQL[GraphQL Types]
    Engine --> App[FastAPI Shell]

How It Works

  1. Load the ASD from .ninjastack/schema.json
  2. Run Jinja2 templates for each generator
  3. Write generated files to _generated/ directory
  4. Diff against existing files (only write if changed)
from ninja_codegen.generators.models import generate_models
from ninja_codegen.generators.agents import generate_agents
from ninja_codegen.generators.graphql import generate_graphql

# Generate everything
model_paths = generate_models(schema.entities, output_dir)
agent_paths = generate_agents(schema.entities, schema.domains, output_dir)
gql_paths = generate_graphql(schema.entities, output_dir)

Generated Output

Models (_generated/models/)

One Pydantic model per entity with typed fields:

# AUTO-GENERATED by ninja-codegen — DO NOT EDIT
class Book(BaseModel):
    id: UUID
    title: str
    author: str
    price: float
    genre: str
    published_date: date | None = None
    in_stock: bool = True

Agents (_generated/agents/)

  • Data agentsDataAgent(entity=ENTITY) per entity
  • Domain agentsDomainAgent(domain=DOMAIN, data_agents=[...]) per domain
  • CoordinatorCoordinatorAgent(domain_agents=[...]) top-level

GraphQL (_generated/graphql/)

Strawberry types, inputs, queries, and mutations:

# AUTO-GENERATED by ninja-codegen — DO NOT EDIT
@strawberry.type
class BookType:
    id: UUID
    title: str
    author: str
    price: float

@strawberry.type
class BookQuery:
    @strawberry.field
    def book(self, id: UUID) -> BookType: ...

    @strawberry.field
    def books(self) -> list[BookType]: ...

Templates

Templates are Jinja2 files in libs/ninja-codegen/src/ninja_codegen/templates/:

Template Output
model.py.j2 Pydantic model class
data_agent.py.j2 ADK DataAgent instantiation
domain_agent.py.j2 ADK DomainAgent instantiation
coordinator_agent.py.j2 CoordinatorAgent wiring
gql_type.py.j2 Strawberry GraphQL type + resolvers
app_shell.py.j2 FastAPI application shell

Idempotent Generation

Running ninjastack sync multiple times produces identical output. The differ engine compares generated content against existing files and only writes when content has changed.