Skip to content

Repository files navigation

⬡ LlamaGraph

Your AI. Your machine. Your rules.

License Next.js FastAPI Ollama Docker

LlamaGraph canvas — visual pipeline builder with nodes and wiring

An open-source, no-code AI workflow builder for local LLMs. Drag nodes onto a canvas, wire them into prompt chains or branching pipelines, and run them against any Ollama model — fully local, no API keys, no data ever leaving your machine.

⭐️ If you like this project, please star the repo on GitHub! Your support helps more people discover and improve this open source project.


Quick Start

Prerequisites:

ollama pull llama3

Run with Docker:

git clone https://github.com/dakshp26/llamagraph
cd llamagraph
docker compose up --build

Open http://localhost:3000.

LlamaGraph is intended for local use. Docker binds the frontend and backend to 127.0.0.1 only; do not expose these ports to your LAN or the public internet without separate authentication and network protection.

Manual setup (for development)

Prerequisites: Node.js 20+, pnpm, uv (installs a compatible Python if needed), Ollama running locally.

# 1. Clone and install JS deps
git clone https://github.com/dakshp26/llamagraph
cd llamagraph
pnpm install

# 2. Set up the backend with uv (creates .venv/ from pyproject.toml + uv.lock)
cd backend
uv sync --all-groups   # app deps + dev (pytest, ruff, httpx)

# 3. Start everything
cd ..
pnpm dev

The backend venv is created under backend/.venv so the root pnpm dev script can find Python. You can also run tools without activating the venv, for example: cd backend && uv run ruff check or uv run pytest.

Frontend runs on http://localhost:3000, backend on http://localhost:8000. Keep both services local-only unless you add separate protection such as authentication, firewall rules, or a private tunnel.


What it does

LlamaGraph gives you a node-based canvas to design, connect, and run AI workflows of any complexity — from a single prompt-to-output chain to multi-branch pipelines with conditional routing, data transformation, and chained LLM calls.

Each run streams execution updates in real time via Server-Sent Events: you see each node's status and output as it happens, not after the whole pipeline finishes.

Use it to:

  • Prototype complex prompt chains without writing code
  • Build conditional AI workflows that branch on LLM output
  • Chain multiple LLM calls with intermediate transformations
  • Test and iterate on pipelines visually before committing to code
  • Save and load pipeline configurations as portable .llamagraph.json files (see examples)

Why LlamaGraph?

Most local LLM tools give you a chat window. Most pipeline tools require writing code or sending your data to the cloud. LlamaGraph sits in between: a visual, code-free builder that runs entirely on your machine.

  • Private by design — no external API calls, no telemetry, no data leaving your machine
  • Visual, not verbal — build multi-step logic without prompting your way through it
  • Real-time feedback — watch each node execute and stream output as it happens
  • Composable — mix prompts, transforms, conditions, and multiple LLM calls in one graph
  • Portable — pipelines are plain JSON; version them, share them, load them anywhere

Node types

Nodes are composable: connect them in any order the DAG allows, fan out to parallel branches, or converge multiple streams into one.

Sources

Source nodes produce data. Every pipeline needs at least one. They have no required upstream connections.

Input — entry point, feeds text or data into the pipeline

The Input node is where every pipeline begins. You type (or paste) a value directly into the node; that value becomes the root output that downstream nodes receive.

  • Accepts any free-form text — a question, a document, a JSON snippet, a list
  • A pipeline can have multiple Input nodes to feed independent branches
  • No upstream connections are allowed; Input nodes are always sources, never sinks
  • The value is stored in the saved .llamagraph.json file so pipelines are self-contained and replayable
JSON API — fetches data from an external HTTP endpoint

The JSON API node makes a GET request to any public HTTP/HTTPS URL and passes the response body downstream as text. Use it to pull live data — REST APIs, JSON feeds, public datasets — into your pipeline before processing it with a Prompt or Transform node.

  • Enter a URL directly, or use {{handle}} placeholders to inject values from upstream nodes (e.g. https://api.example.com/posts/{{post_id}})
  • Add any number of key/value query params and headers — placeholders work in those fields too
  • The full response body (up to 500 KB) is passed downstream; pair it with a Transform node to extract a specific field before feeding it to an LLM
  • Requests to private or internal addresses (192.168.x.x, 10.x.x.x, 169.254.x.x, localhost) are blocked to prevent accidental internal network access
  • A live curl preview updates as you type so you can verify the exact request before running

See examples/json_api_example.llamagraph.json for a working pipeline that fetches a post from a public API, extracts its body field, and has an LLM translate it.

PDF Input — uploads a PDF and feeds its text content into the pipeline

The PDF Input node lets you upload a PDF file and inject its extracted text as a source in the pipeline. The backend converts the file to Markdown using MarkItDown and passes the result downstream — no external service required.

  • Upload a PDF (up to 50 MB) directly from the node using the Upload file button
  • Previously uploaded files are remembered and selectable from the dropdown
  • A Markdown preview of the extracted text is displayed inline on the node (first 500 characters, expandable)
  • Files are stored server-side in backend/files/; pipelines reference files by name so the .llamagraph.json is portable across machines that have the same file available
  • Pair with a Prompt node to build document Q&A, summarisation, or extraction pipelines
DOCX Input — uploads a Word document and feeds its text content into the pipeline

The DOCX Input node works identically to the PDF Input node but accepts .docx files (Microsoft Word format). The document is converted to Markdown server-side and passed downstream as plain text.

  • Upload any .docx file up to 50 MB
  • Headings, paragraphs, and lists from the Word document are preserved as Markdown structure
  • Useful for feeding reports, templates, or reference documents into an LLM without manual copy-paste
PPT Input — uploads a PowerPoint presentation and feeds its text content into the pipeline

The PPT Input node accepts .ppt and .pptx files (Microsoft PowerPoint format) and extracts slide text, which is converted to Markdown and passed downstream.

  • Upload any .ppt or .pptx file up to 50 MB
  • Slide titles and body text are extracted and presented as Markdown
  • Useful for summarising decks, answering questions about presentation content, or feeding slide copy into a rewriting pipeline

Processing

Processing nodes transform or route data. Most require at least one upstream connection — Prompt nodes only require one if the template contains a {{placeholder}}.

Prompt — Jinja-style template that injects upstream values into a prompt

The Prompt node assembles a final prompt string by interpolating values from connected upstream nodes into a template. It is the primary way to craft LLM instructions dynamically.

  • Uses {{ variable_name }} syntax (Jinja2-style) to reference upstream node outputs by name
  • Multiple upstream nodes can be referenced in a single template
  • Supports multi-line templates — useful for system prompts, few-shot examples, or structured instructions
  • The rendered string is passed downstream as-is; connect it to an LLM node to execute it, or to a Transform node for further processing
  • Template rendering happens on the backend so the final prompt is never partially sent
Transform — regex or field-extract operations on text

The Transform node manipulates text before or after an LLM call without invoking a model. It is useful for cleaning output, extracting structured values, or reshaping data for the next stage.

  • Regex extract — applies a regular expression and emits the first capture group (or the full match)
  • Field extract — parses key-value output (e.g. Label: value) and pulls out a named field
  • Operates entirely on the backend — no model call, no latency beyond string processing
  • Can be chained: run a Transform after an LLM node to normalize its output before feeding it into a Condition or another LLM node
Condition — branches the graph based on a rule, true/false routing

The Condition node evaluates its upstream input against a rule and routes execution down either a true branch or a false branch. Branches that are not taken are marked as skipped — their nodes are bypassed entirely rather than receiving empty input.

  • Rules are simple string comparisons: equals, contains, starts with, ends with, or matches regex
  • Each Condition node has exactly two outgoing edges, labelled true and false
  • Skipped branches are visible in the UI with a distinct status so you can see exactly which path was taken
  • Conditions can be nested: the output of one branch can feed another Condition node for multi-level routing
  • The executor tracks skipped node IDs and propagates the skip state through all transitive dependents

Intelligence

Intelligence nodes invoke a local language model. They require at least one upstream connection providing the prompt text.

LLM — calls a local Ollama model and streams the response

The LLM node sends its upstream input to a locally running Ollama model and streams the response token by token back to the frontend via Server-Sent Events.

  • Select any model that Ollama has pulled (ollama pull <model>) — the node lists available models at runtime
  • Streaming is incremental: tokens appear in the UI as they are generated, not after the full response finishes
  • The backend wraps the Ollama HTTP API; the frontend never calls Ollama directly
  • LLM nodes can be chained — pipe one model's output into a Prompt node, then into a second LLM node for multi-stage reasoning
  • If Ollama is unreachable, the node surfaces a clear error rather than hanging

Output

Output — terminal node, displays final results

The Output node is the sink of the pipeline. It receives the final value from its upstream node and renders it in the canvas panel.

  • A pipeline can have multiple Output nodes — useful when parallel branches each produce a result
  • The displayed value is the raw string passed by the upstream node (LLM response, transformed text, etc.)
  • Output nodes have no outgoing edges; they are always leaves in the DAG
  • Results persist in the UI until the next run so you can inspect and copy them after execution completes

Canvas

Canvas nodes are annotations and organisational aids. They are not part of pipeline execution and carry no data connections.

Note — freeform sticky note for annotating the canvas

The Note node is a resizable text area you can place anywhere on the canvas to document your pipeline, leave reminders, or label sections of a complex graph. It has no handles and is never executed.

  • Type anything — intent, assumptions, TODO items, section labels
  • Resize the text area by dragging its bottom-right corner
  • Notes are saved in the .llamagraph.json file alongside the rest of the graph
  • Right-click any Note node to copy or delete it via the context menu

Project structure

llamagraph/
├── frontend/
│   ├── app/           # Next.js App Router pages
│   ├── components/    # canvas/, nodes/, debug/, ui/
│   ├── store/         # Zustand: pipelineStore, executionStore, validationStore
│   └── lib/           # sseClient, pipelineFile, API client, graph utils
├── backend/
│   ├── routers/       # FastAPI route handlers
│   ├── services/      # graph.py, executor.py, node_handlers.py, ollama_client.py
│   └── models/        # Pydantic schemas
├── examples/          # Sample .llamagraph.json pipelines
└── docker-compose.yml

Architecture

The UI continuously polls POST /pipeline/validate and surfaces errors in real time. On run, POST /pipeline/run validates and topologically sorts the DAG, then executes nodes one by one — skipping branches marked unreachable by condition nodes. LLM nodes stream tokens back via SSE; the frontend never calls Ollama directly.

API:

Method Path Purpose
GET /ollama/health Ollama connectivity check
GET /ollama/models Available model list
POST /pipeline/validate Graph validation
POST /pipeline/run Pipeline execution — SSE stream
GET /files List uploaded files (filter by extension)
POST /files/upload Upload a PDF, DOCX, or PPT file (max 50 MB)
GET /files/preview/{filename} Convert a file to Markdown and return a preview

Tech stack

Frontend Next.js 16, React 19, XYFlow, Zustand, Tailwind CSS 4
Backend Python 3.11, FastAPI, Uvicorn, Ollama, uv (package manager)

Contributing

Contributions are welcome — bug fixes, new node types, UI improvements, docs.

  1. Open an issue first for anything beyond a small fix so we can align on direction before you invest time.
  2. Fork the repo and create a feature branch.
  3. Make your changes and add tests where applicable.
  4. Open a PR with a clear description of what changed and why.
# Lint and test before opening a PR
pnpm --filter frontend lint
pnpm --filter frontend build

cd backend
uv run ruff check
uv run pytest

Good first issues: look for the good first issue label in the issue tracker.

License

MIT — see LICENSE.

About

Visual drag-and-drop AI pipeline builder that runs on local Ollama LLMs. Built with Next.js, FastAPI, Ollama, and React.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Packages

Used by

Contributors

Languages