[UPDATE] If you want to just grab from docker here's the url: https://hub.docker.com/r/sudoname/pendantic2
Look, we get it: You're a dev with big automation dreams, but the cloud overlords want your firstborn (or at least your credit card) for every ping. Enter Pedantic2 β the agentic workflow builder that's so stubbornly local, it runs in your bathroom server rack or just your laptop. No subscriptions, no vendor lock-in, no "unexpected bill" therapy sessions. Just you, your code, and a visual editor that's prettier than your last breakup.
Why "Pedantic2"? Because the first one was too forgiving. This version nags you about timeouts, sandboxes your wild Python dreams, and color-codes your nodes like a passive-aggressive mood ring. Build workflows that fetch APIs, crunch data, branch like a choose-your-own-adventure novel, and log errors without ghosting you.
TL;DR: Visual drag-and-drop for agents, code for the masochists, all offline. Deploy? Pfft, as if.
New in Latest Version:
- Simple Docker Launch: That is if you want to go that way. Blamo!
- Skip During Execution: Mark any node to skip during workflow execution while preserving data flow
- EndLoop nodes: Proper ForEach loop termination and data aggregation
- Auto-arrange: Column-based layout (5 nodes per column) with special handling for ForEach loops
- Help icon: Opens documentation viewer with anchor link support
- Database maintenance panel: Workflow/node management, backup, and optimization
- Custom nodes: Save, reuse, export, and import node templates
- HTML Viewer: Auto-detect and render HTML content (similar to Markdown Viewer)
- JSON Viewer: Auto-detect and format JSON with filtered/full view tabs
- Image Viewer: Auto-detect and display images (base64, files, URLs) with zoom/pan controls
- Browser Node: Playwright automation with headless/headful, stealth mode, session persistence, and multiple output formats
- OCR Node: Extract text from images using Tesseract OCR
- Right-click context menu: Delete nodes via right-click context menu (prevents accidental deletion)
- Start/End node timing: Start node shows execution start time, End node shows total execution duration
- Improved execution timeline: Real-time status with execution times
- Case-insensitive workflow names: Workflow name matching is now case-insensitive
- Vector Database Support: SQLite with sqlite-vec extension for local RAG workflows
- Visual Node Shenanigans: Drag, drop, connect β React Flow canvas with glassmorphic flair. Nodes glow like they're judging your life choices (green: success; red: "fix your crap").
- Code Nodes for Showoffs:
- Python: Sandboxed via RestrictedPython. Write
def run(input): return input + " but snarkier". Timeouts? We got 'em, because infinite loops are for amateurs. - TypeScript: Async via Bun subprocess.
async function run(input): Promise<any> { return input; /* Add your async regret here */ }. Monaco Editor included β because Notepad++ called, it wants its dignity back.
- Python: Sandboxed via RestrictedPython. Write
- Config Nodes for the Lazy Genius:
- HTTP calls with templating:
{user_id}? Boom, dynamic AF. - File ops (read/write/delete) in
/tmp/workflow_files/β because your root dir isn't a playground. - Conditionals: Branch if
data.salty > 10(spoiler: it always is). - SQLite queries: Parameterized, because SQL injection is so 2010.
- LLM AI Assistant: Full dialog with provider/model selection, dynamic model fetching, API key management.
- Embedding Node: Generate vector embeddings using sentence-transformers for semantic search and RAG.
- Markdown Viewer: Auto-detect and render markdown with anchor support.
- HTML Viewer: Auto-detect and render HTML content.
- JSON Viewer: Auto-detect and format JSON with filtered/full view tabs and content key selection.
- Image Viewer: Auto-detect and display images (base64, files, URLs) with zoom/pan controls and download.
- Browser Node: Playwright automation with headless/headful toggle, stealth mode, session persistence, wait conditions, and multiple output formats (HTML, screenshot, PDF, JSON).
- Vector Database Support: SQLite with sqlite-vec extension for local vector search (RAG workflows). Requires
pysqlite3-binaryand sqlite-vec extension file. - Fancy Bits:
- Skip During Execution: Mark nodes to skip during execution (useful for debugging or temporary disabling)
- Auto-arrange nodes with intelligent zigzag layout (staggered for visibility)
- Real-time execution logs (stdout/stderr/errors β the full therapy session)
- Import/export JSON like you're sharing breakup playlists
- Help icon opens documentation in markdown viewer with anchor link support
- Database maintenance panel for cleanup, backup, and optimization
- Custom nodes: Save, reuse, export, and import node templates
- Lock functionality to prevent accidental edits during execution
- Save As with overwrite confirmation (case-insensitive workflow names)
- Execution timeline shows real-time status with execution times
- ForEach loops with serial/parallel execution and EndLoop aggregation
- Right-click context menu: Delete nodes via right-click (with confirmation dialog)
- Start/End node timing: Start node displays "Started: [time]" and End node displays "Completed: [duration]" during execution
- Headless Mode: Run via API or CLI. Schedule with cron/launchd/Task Scheduler. Because who needs a UI for 3 AM regrets?
- Security? We Pretend: Timeouts, memory caps, localhost-only. Your secrets stay secret... unless you
print(password)in a Python node. Rookie.
Pro Tip: Custom nodes? Save configs as templates. Reuse that "scrape cat memes" workflow without the shame.
One-command bliss:
git clone https://github.com/williamrhancock/Pedantic2.git
cd Pedantic2/docker
docker-compose upPrerequisites (or suffer the postinstall script's wrath):
- Node.js 18+ (grab it)
- Bun (curl -fsSL https://bun.sh/install | bash β Windows? PowerShell that noise.)
- Python 3.11+ (check: python --version; pip upgrade if it's cranky.)
-
Clone this bad boy:
git clone https://github.com/williamrhancock/Pedantic2.git cd Pedantic2 -
Npm the dependencies (Python deps auto-install, because magic):
npm install
-
Install Python dependencies (if not auto-installed):
cd api pip install -r requirements.txt cd ..
Note for Vector Database Support: The standard Python
sqlite3module doesn't support loading extensions. For vector database workflows (RAG), you need extension loading support.Recommended Method (macOS/Linux): Build pysqlite3 from source with a specific SQLite version. See docs/INSTALL_PYSQLITE3.md for detailed instructions based on Simon Willison's guide.
Quick Method (macOS with Homebrew):
brew install sqlite export LDFLAGS="-L$(brew --prefix sqlite)/lib" export CPPFLAGS="-I$(brew --prefix sqlite)/include" pip install pysqlite3
Linux (Debian/Ubuntu):
sudo apt-get install libsqlite3-dev pip install pysqlite3
Linux (RHEL/CentOS):
sudo yum install sqlite-devel pip install pysqlite3
For complete installation instructions, troubleshooting, and alternative methods, see docs/INSTALL_PYSQLITE3.md.
Alternative: Try
pysqlite3-binaryfirst (may not work on all platforms):pip install pysqlite3-binary
After installation, restart the FastAPI server. The code will automatically detect and use the extension-capable sqlite3 module.
Note: If extension loading isn't available, regular database operations still work. Only vector database features (sqlite-vec) require extension support.
Note for Browser Node: Playwright requires browser binaries to be installed separately:
pip install playwright playwright install
The
playwright installcommand downloads browser binaries (Chromium, Firefox, WebKit) needed for browser automation. This is a required step - the browser node will not work without it. -
Set up API keys (required for LLM and external API nodes):
# Copy the example environment file cp .env.example .env # Edit .env and add your actual API keys # Required for LLM nodes: OPENROUTER_API_KEY (or provider-specific keys) # Required for stock workflow: POLYGON_API_KEY # See .env.example for all available options
Important: Never commit
.envfiles! They're gitignored for a reason. -
Fire it up:
npm run dev
- Frontend: http://localhost:3000 (ooh, shiny!)
- Backend: http://localhost:8000 (the brains, quietly judging)
Manual Python drama? cd api; python -m venv venv; source venv/bin/activate; pip install -r requirements.txt. Weep if needed.
Prefer containers? There's a single Docker image that runs both the Next.js frontend and the FastAPI backend.
Platform support:
- Image is built and tested for Linux x86_64/amd64 (including Docker Desktop on macOS/Windows using a linux/amd64 engine).
- Vector DB (sqlite-vec) inside Docker uses the Linux x86_64 loadable extension only.
- Native Linux arm64 (aarch64) containers are not guaranteed to have a working sqlite-vec extension yet. Everything else (Browser, OCR, HTTP, LLM, etc.) still works on arm64, but vector search may be disabled or noisy there.
From the repo root:
docker build -f docker/Dockerfile -t pedantic2 .This will:
- Build the Next.js frontend in a Node builder stage
- Install Python dependencies (FastAPI backend)
- Install Playwright browsers and Tesseract OCR
- Bundle everything into a single runtime image
Minimal run (expects .env for API keys in the host working directory):
docker run --env-file .env -p 3000:3000 pedantic2- Frontend: http://localhost:3000
- Backend (inside container): http://localhost:8000 (exposed if you map it)
If you want direct access to the FastAPI API from the host:
docker run --env-file .env -p 3000:3000 -p 8000:8000 pedantic2In the docker/ folder:
cd docker
docker-compose up --buildThat will:
- Build the
pedantic2image fromdocker/Dockerfile - Start the app as
pedantic2-app - Map:
3000:3000for the frontend8000:8000for the API
- Mount volumes:
workflow_filesβ/tmp/workflow_filesworkflow_dbsβ/tmp/workflow_dbs
- All file operations still live under
/tmp/workflow_files/inside the container. With volumes, that data persists across restarts. - SQLite DBs live under
/tmp/workflow_dbs/when using the DB node. Again, volumes keep them around. - API keys and provider settings are still controlled via environment variables (
OPENROUTER_API_KEY,OPENAI_API_KEY, etc.) β never bake secrets into images.
- Open localhost:3000. Start node auto-spawns. Lazy much?
- Toolbar β Add Node:
- Code? Pick Python/TS, paste snark in Monaco.
- Config? JSON editor validates your typos live.
- Drag connections. Data flows like gossip.
- Hit Execute. Watch nodes light up (or explode β logs will tell).
- Save as JSON. Share with friends who owe you favors.
Example Workflow: "Procrastinator's API Fetch"
- Start β HTTP (GET /cats) β Python (
return data + " meow snark") β Condition (if funny?) β File Write β End. - Boom: Local cat facts, zero AWS bills.
Example Workflow: "Bearer Token Authentication"
- Start β Prepare Credentials β Authenticate β Extract Token β Use Token in API Request β End.
- Perfect for OAuth2, API key exchange, or username/password authentication. See Bearer Token Authentication Guide for details.
Using API Keys in Workflows:
- LLM Nodes: Use
api_key_namein config (e.g.,"api_key_name": "OPENROUTER_API_KEY") or set per-node override - HTTP Nodes: Use Python node to inject keys from environment:
os.getenv('API_KEY_NAME')β{API_KEY_NAME}placeholder - Never hardcode keys in workflow JSON files - use environment variables instead
- See SECURITY.md for detailed security guidelines
Headless? POST to /run with workflow JSON. Or npm run run-workflow -- 42 (ID from DB). Schedule it to run while you nap.
- Complete Workflow Nodes Guide - Detailed documentation for all node types
- Workflow Examples - Comprehensive guide to all example workflows
- LLM Workflow Generation Guide - For LLMs generating workflows (and for wiring up automatic workflow generation)
- Bearer Token Authentication Guide - Complete guide to authentication patterns and bearer token workflows
If you want an LLM (or any external tool) to generate Pedantic2 workflows for you, point it at
https://github.com/williamrhancock/Pedantic2/blob/main/docs/LLM_WORKFLOW_GENERATION_GUIDE.md and tell it to strictly follow that spec.
At a minimum, your prompt to the LLM should say something like:
You are generating workflows for Pedantic2.
Only produce JSON that matches the attached rule.
Do not invent new node types or fields.
Use unique, descriptive node and connection IDs.
Return ONLY valid JSON, no commentary.
[Enter your wishlist workflow and watch it cook!]
Then:
- Save it to someplace you want to keep your workflows and load it via the UI.
The guide already documents:
- Full JSON schema for workflows
- All node types, fields, and constraints
- Critical rules (EndLoop after ForEach, connection IDs, required nodes)
Treat it as the single source of truth for any automated workflow generator.
DB woes? Maintenance panel: Delete, backup, compact. Because SQLite bloat is real.
- Frontend: Next.js 15, React Flow, Tailwind + shadcn/ui. tRPC for chatty vibes.
- Backend: FastAPI (Python), Bun (TS exec). SQLite (
data.dev.db) stores your masterpieces. - No Docs Folder? Shh, it's "embedded" in MDs. Pull requests for a real one? Yes pls.
- File ops locked to
/tmp/workflow_files/. Escape? PR it. - Windows? PowerShell everything. Unix envy included.
- Infinite loops? Timeouts slap you. Cry less.
- Prod? Scale your own bathroom rack.
Puppeteer/Chrome DevTools Protocol Node (lighter alternative to Playwright)
Email Nodes (IMAP + SMTP)
- "Watch Inbox" trigger (poll or future webhook)
- "Send Email" with attachments from previous nodes
- "Parse Email" (extract body, attachments, links)
- Instantly enables 70% of real-world business automations.
WebSocket Client Node
- Because half the interesting internet now speaks WebSockets (LiveKit, Binance, Twitter Spaces, etc.)
OCR Node (Tesseract or Windows OCR / macOS Vision / easyocr)
- Take a screenshot/PDF β extract text. The moment you add this + Browser node = unbeatable.
- β Already implemented! (Tesseract OCR)
Spreadsheet Node (read/write/manipulate XLSX, CSV, Google Sheets local cache)
- Built-in Pandas mini-mode: filter, pivot, groupby via simple UI
- "Sheet β Rows β ForEach" pattern becomes trivial
SSH / Remote Command Node
- Run commands on your VPS, NAS, or Raspberry Pi cluster. Local-first doesn't mean single-machine-only.
Git Node
- Clone, commit+push, create PR, read file from repo at tag/branch
- Bonus: "Deploy this workflow to my server" one-click pattern
Cron / Schedule Trigger Node (visual cron UI inside the canvas)
- Turns Pedantic2 into a real cron replacement with visual debugging.
Webhook Trigger Node
- Expose
http://localhost:3000/webhook/my_cool_triggerβ Start node. Instantly you have Zapier/Make at home.
Local LLM Node (Ollama / llama.cpp / LM Studio / OpenAI-compatible endpoint)
- You already have cloud LLM, but a first-class "pick a local model" node with model auto-discovery would be legendary.
Audio Transcription Node (Whisper.cpp or faster-whisper)
- Drop an audio file β get text + timestamps + speaker diarization option.
Image Generation / Editing Node (Stable Diffusion Automatic1111 API or ComfyUI API)
- The moment you can chain "describe image with LLaVA β edit prompt β SD" locally, people will tattoo your name somewhere.
Cache / Memoize Node
- "Only run this expensive subgraph if inputs changed" with TTL. Saves hours when doing RAG or API calls.
Merge / Join Node (SQL-style joins on arrays of objects)
- Currently people do this in Python nodes β giving them a visual join would be chef's kiss.
Rate Limiter / Throttle Node
- "Only let max 5 items through per minute" β critical for not getting banned.
Human-in-the-Loop Node
- Pauses execution, shows data, waits for user input/approval in the UI (with optional timeout β default branch).
Telegram / Discord / Slack Bots
- Send message, wait for reply, react to messages, etc.
Crypto / Wallet Node
- Sign transactions, check balances (EVM & Solana). The degen crowd will flood your repo.
Time Travel / Version Node
- "Run this workflow as it existed 3 days ago" using the DB history. Mind-bending debugging superpower.
- Delay / Sleep Node (with "smart delay until next minute/hour" option)
- Random Node (random int, choice from list, UUID, fake data)
- CSV β JSON Converter Node
- Regex Extract / Replace Node
- JWT Encode/Decode Node
- Crypto (hash, encrypt/decrypt with key from env)
- Tail File Node (watch log file like
tail -f) - MQTT Client
- Bluetooth LE Scanner
- Home Assistant Node
- Obsidian Vault Read/Write
Want to implement one of these? Fork, code, PR. We'll shower you with gratitude (and merge it faster than you can say "local-first").
Fork, fix, PR. Tests? Add 'em. Docs? Flesh 'em. Moar nodes? Yes.
Business Source License 1.1 (free for personal & non-commercial use)
Commercial production use, SaaS, or resale requires a paid license.
β Details: LICENSE.md β’ Commercial pricing
Β© William R. Hancock. Use it, abuse it, attribute it. Or don't β karma's a workflow.
- Alex Garcia (asg017) for the excellent sqlite-vec project and
vec0binaries that make local vector search possible.
@williamrhancock on GitHub. Issues? File 'em. Stars? Shower 'em. Clouds? Keep walking.
Built with love, snark, and zero VC funding. Because independence > invoices.
