Skip to content

samkeller-dev/dream-journal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dream-journal

A voice-memo → illustrated dream-journal pipeline orchestrated by n8n.

You drop a .wav voice memo at a webhook. The stack transcribes it with Whisper (self-hosted, faster-whisper), extracts dream themes, symbols, mood, and a text-to-image prompt as structured JSON via Ollama running Mistral 7B Instruct, and renders surreal cover art via a Stable Diffusion API. The result is a dated markdown entry plus an embedded image, written to ./journal/. A second cron-triggered workflow produces a weekly illustrated digest.

The whole stack runs under Docker + docker-compose.

Architecture

   POST audio                                                        ./journal/
      │                                                                  ▲
      ▼                                                                  │
  ┌────────┐    ┌──────────┐    ┌───────────┐    ┌──────────────┐        │
  │  n8n   │───▶│   STT    │───▶│  Ollama   │───▶│  Stable      │────────┘
  │ webhook│    │ FastAPI  │    │ Mistral   │    │  Diffusion   │
  │ + cron │    │ +faster- │    │ 7B JSON   │    │ (A1111 /     │
  │        │    │  whisper │    │           │    │  ComfyUI)    │
  └────────┘    └──────────┘    └───────────┘    └──────────────┘
   :5678          :8001          :11434              :7860 (host)

See docs/architecture.md for node-by-node detail.

Quickstart

Prereqs: Docker, an Ollama running on localhost:11434 with mistral:7b-instruct pulled (or use the bundled profile, see below), and a Stable Diffusion API endpoint (default expects A1111 on host:7860).

git clone https://github.com/samkeller-dev/dream-journal.git
cd dream-journal
cp .env.example .env
# Edit .env if your SD or Ollama lives somewhere non-default.
# Generate a real key:  openssl rand -hex 32  → N8N_ENCRYPTION_KEY
docker compose up -d --build

Wait until dj-stt is healthy and dj-n8n is up:

curl http://localhost:8001/health      # STT
curl http://localhost:5678/healthz     # n8n
curl http://localhost:11434/api/tags   # Ollama (host)

Visit http://localhost:5678, create the owner account, then import each JSON in workflows/ via the UI (+ → Import from File) or the REST API:

# After owner setup, log in via the UI once to seed your cookie, then:
curl -X POST http://localhost:5678/rest/workflows \
     -H 'Content-Type: application/json' \
     -b cookies.txt \
     --data @workflows/01_dream_capture.json

Activate workflow 01 Dream Capture (toggle in the UI) so its production webhook registers.

Triggering Workflow 1

curl -X POST -F "audio=@samples/sample_memo.wav" \
     http://localhost:5678/webhook/dream-capture
# → {"ok":true,"date":"2026-04-28","entry_path":"/journal/2026-04-28.md","image_path":"/journal/2026-04-28.png"}

A markdown entry and PNG land in ./journal/. See samples/expected_entry.md for a reference of what the entry looks like.

Triggering Workflow 2 (Weekly Digest)

By default it fires from the cron-style Schedule Trigger every Sunday at 09:00 local. To run it on demand, open the workflow in the n8n UI and click Execute Workflow — the bundled Manual Trigger node will fire it. The digest writes to ./journal/digests/{week_starting}.md plus a cover image.

If there are no entries in the past 7 days, the workflow short-circuits via the Has Entries? IF node and exits cleanly without calling the LLM.

Per-workflow walkthrough

Workflow 1: Dream Capture

  1. Webhook receives multipart audio upload.
  2. HTTP Request posts the binary to the in-network STT service (faster-whisper).
  3. Set assembles the system prompt and the user message.
  4. HTTP Request posts to Ollama with format: "json" to extract {date, transcript, themes, symbols, mood, summary, image_prompt}.
  5. Code parses + validates the JSON shape.
  6. HTTP Request posts to Stable Diffusion (/sdapi/v1/txt2img).
  7. Code decodes the base64 PNG, builds the markdown body, and emits one item with two binary properties.
  8. Two Read/Write Files from Disk writes — image and entry — both into /journal/.
  9. Respond to Webhook returns the resulting paths.

Workflow 2: Weekly Digest

  1. Schedule Trigger (cron 0 9 * * 0) or Manual Trigger.
  2. Code globs /journal/*.md, parses YAML frontmatter, filters to entries dated within the past 7 days. Computes week_starting as Monday of this week.
  3. IF short-circuits if zero entries.
  4. Set assembles the digest prompt.
  5. HTTP Request → Ollama for digest JSON {dominant_themes, recurring_symbols, emotional_arc, digest_text, cover_image_prompt}.
  6. Code parses + overrides week_starting with the locally computed Monday.
  7. HTTP Request → Stable Diffusion for the cover.
  8. Code decodes, builds digest markdown.
  9. Two Read/Write Files from Disk into /journal/digests/.

Environment variables

See .env.example for the canonical list.

Var Default Purpose
N8N_ENCRYPTION_KEY (required) n8n credential vault key. openssl rand -hex 32.
OLLAMA_BASE_URL http://host.docker.internal:11434 Where n8n reaches Ollama.
OLLAMA_MODEL mistral:7b-instruct Model name passed to /api/chat.
WHISPER_MODEL base.en faster-whisper model size. Try small.en for quality.
WHISPER_DEVICE cpu cpu or cuda.
WHISPER_COMPUTE_TYPE int8 int8, float16, float32.
SD_BACKEND a1111 a1111 (wired) or comfyui (documented).
SD_BASE_URL http://host.docker.internal:7860 Where n8n reaches Stable Diffusion.
SD_STEPS/SD_WIDTH/SD_HEIGHT/SD_SAMPLER 28 / 768 / 768 / Euler a Passed to /sdapi/v1/txt2img.

Stable Diffusion backend swap

The default workflow targets A1111 (POST /sdapi/v1/txt2img, sync, returns base64 inline). Swapping to ComfyUI is documented in docs/architecture.md — the short version: ComfyUI is async (POST /prompt returns a prompt_id, then poll /history/{id}), so the single Generate Image node has to be replaced with a small mini-flow. A minimal txt2img graph template lives at prompts/comfyui_txt2img.json.

Bundled Ollama (optional)

By default the stack expects Ollama running on the host (most users have one). To bundle it:

docker compose --profile bundled-ollama up -d
# then in .env:
OLLAMA_BASE_URL=http://ollama:11434

The ollama-init sidecar will pull ${OLLAMA_MODEL} on first start.

Repo layout

dream-journal/
├── README.md
├── docker-compose.yml
├── .env.example
├── .gitignore
├── workflows/
│   ├── 01_dream_capture.json     # n8n export
│   └── 02_weekly_digest.json
├── stt/                          # FastAPI + faster-whisper
│   ├── Dockerfile
│   ├── requirements.txt
│   └── server.py
├── prompts/                      # all prompt templates + ComfyUI graph
├── samples/                      # sample audio + expected_entry.md
├── docs/
│   ├── architecture.md
│   └── screenshots/
└── journal/                      # gitignored output dir
    └── digests/

Tests

tests/run.sh           # full suite (Python + Node)
tests/run.sh py        # FastAPI/STT + workflow-schema only
tests/run.sh node      # Code-node logic only

The runner spins up throwaway python:3.11-slim and node:20-alpine containers — no host pytest or Node needed. The suite covers:

  • STT server (tests/python/test_stt_server.py) — FastAPI surface with a stubbed faster_whisper.
  • Workflow JSON schema (tests/python/test_workflow_schema.py) — every node has a UUID + required fields, every connection target exists, no name collisions, every $env.X reference is documented in .env.example, and Code nodes are ASCII-safe (guards against the em-dash sandbox bug).
  • Code-node logic (tests/node/*.test.mjs) — extracts jsCode straight out of the workflow JSON and runs it against a faked $input / $() / $env context. Covers Parse Dream, Collect Entries, and Prepare Outputs.

Limitations / TODOs

  • No frontend — n8n's canvas is the UI.
  • No auth on the webhook. Local-dev only.
  • ComfyUI path is documented but not wired into the workflow JSON.
  • No retries on transient SD/Ollama failures.
  • The Code nodes use require('fs') to glob /journal/, which requires NODE_FUNCTION_ALLOW_BUILTIN=fs,path (set by the compose file).

Frameworks demonstrated

n8n workflow orchestration · Whisper STT (faster-whisper) · Ollama + Mistral 7B Instruct for JSON-schema extraction · Stable Diffusion image generation · Docker / docker-compose · Webhook + cron triggers · FastAPI for the STT microservice

About

Voice-memo to illustrated dream journal: n8n + Whisper + Ollama (Mistral 7B JSON) + Stable Diffusion, all on docker-compose.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors