Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.19.0
title: BreadBuddy
emoji: π
colorFrom: yellow
colorTo: gray
sdk: gradio
sdk_version: 6.18.0
python_version: '3.11'
app_file: app.py
pinned: false
tags:
- track:backyard
- sponsor:openbmb
- sponsor:modal
- achievement:offbrand
- achievement:llama
- achievement:fieldnotes
BreadBuddy π
AI-powered bread baking assistant β diagnose what went wrong, get fixes, and learn to bake better.
Built over 10 days for the Hugging Face Γ Gradio Build Small Hackathon. All models β€ 32B, self-hosted, no proprietary APIs.
Features
| Feature | Description | Model Pipeline |
|---|---|---|
| π Photo + Text Diagnosis | Upload a bread photo with description β structured 3-part diagnosis (causes / fixes / recipes) | MiniCPM-V 4.6 β Gemma-4-12B |
| π¬ Follow-up Chat | Drill deeper on diagnosis results β multi-turn conversation with context memory | Gemma-4-12B |
| π Dark Mode | Full dark bakery theme with custom CSS/JS | Gradio 5.50.0 |
All responses streamed in real-time via SSE (Server-Sent Events). Reasoning content visible in a collapsible panel.
Architecture
User (Photo + Text)
β
βΌ
ββ Gradio Frontend (deploy/app.py) βββββββββββββββββββββββββββββββββββ
β Single-tab clinic UI Β· Dark bakery theme Β· Custom CSS/JS β
β Streams SSE: reasoning_content + content dual channels β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β POST /v1/chat/completions (OpenAI-compatible)
βΌ
ββ Modal Gateway (CPU, gateway.py) βββββββββββββββββββββββββββββββββββ
β Unified routing: has_image? β call_vision() : call_agent() β
β ReAct loop (OpenAI function calling) Β· SSE streaming β
ββββββββββββ¬ββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ
β β
has_image? no image
β β
βΌ β
ββββββββββββββββββββββββ β
β MiniCPM-V 4.6 β β
β Modal L4 GPU β β
β Vision analysis β β
ββββββββββββ¬ββββββββββββ β
β vision context β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Gemma 4 12B (GGUF Q4_K_M) Β· llama.cpp Β· Modal A10G β
β 8K context Β· 8 concurrent slots Β· OpenAI-compatible API Β· -n 4096 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Engineering Decisions
- Unified Gateway Pattern β single endpoint, stateless routing. Gateway on CPU (<2s cold start), models on GPU (independent scaling). Eliminates cross-service contract drift.
- ReAct Agent (Gateway-embedded) β OpenAI function calling directly in gateway, no LangGraph dependency. Reduced 3 fragile cross-service contracts to 1.
- llama.cpp with
-n 4096β discovered and fixed a server-side 1000-token hard limit that silently truncated output. Root cause debugging took 3 repair cycles across server/client/parser layers. - content + reasoning merge rendering β tolerant of non-deterministic LLM output. Reasoning often contains complete diagnosis even when content is truncated.
- Custom Gradio UI β deep CSS/JS override beyond default theme. Dark mode with localStorage persistence.
By the Numbers
| Development | 10 days (June 5β15, 2026) |
| Code | ~2,000 lines Python (deploy + modal) |
| Tests | 54 tests (41 unit + 13 E2E with Playwright) |
| Commits | 40+ |
| Deployments | 15+ modal deploy |
| Design docs | 25+ (architecture decisions, retrospectives, checklists) |
| Architecture decisions | 6 (2 revised from scratch) |
Challenges Solved
The most interesting bug: E2E tests passed locally but the recipe section never rendered in production. After 3 repair cycles across 4 agents, the root cause was traced to llama.cpp's default -n 1000 token limit β Gemma-4's reasoning consumed ~70% of the budget, starving the visible content. The fix chain: /no_think hack β server-side -n 4096 β content+reasoning merge rendering. Full retrospective: technical-retrospective.md
Gateway code rot β three independently-deployed services (Gateway / MiniCPM / Gemma) drifted apart: mismatched routes, wrong response keys, dead code path. Fixed by reducing interface contracts from 3 to 1.
Methodology
This project was built with two AI-assisted development frameworks:
- Harness (AGENTS.md + TDD + Skills + Memory) β project constitution, red-green-refactor, mandatory verification before success claims. AGENTS.md as a living document, 50+ cross-session memory entries.
- Architecture Loop (Judge/Builder separation) β frozen acceptance gates before implementation, "nobody grades their own work," mandatory builder disagreements. Evaluated and documented applicability boundaries (best for incremental changes, not greenfield prototypes).
Key lesson: Verify the premise before building. 30 minutes of Gemma function-calling compatibility tests saved 2 days of potential rework.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | Gradio 5.50.0, custom CSS/JS, dark mode |
| Text Model | Gemma 4 12B (GGUF Q4_K_M) via llama.cpp b9518 |
| Vision Model | MiniCPM-V 4.6 via Transformers |
| Gateway | FastAPI + Python 3.11, CPU-only, SSE streaming |
| GPU Cloud | Modal.com (A10G + L4, $250 credits) |
| Agent | ReAct loop, OpenAI function calling |
| Testing | pytest (41 unit) + Playwright (13 E2E), all against live API |
| Deployment | Hugging Face Spaces (Gradio) + Modal serverless |
Links
- π¬ Demo video: https://www.youtube.com/watch?v=QN4ZL1Q_kNA
- π¦ Social post: https://x.com/rockhighdev/status/2066432837075841399
License
MIT