title: loosecanvas
emoji: πΈοΈ
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 7860
pinned: false
license: mit
short_description: Local AI that turns talk into a trust-tagged map
models:
- unsloth/gemma-4-26B-A4B-it-qat-GGUF
suggested_hardware: l4x1
startup_duration_timeout: 2h
tags:
- build-small-hackathon
- track:wood
- achievement:offgrid
- achievement:llama
- achievement:offbrand
- achievement:fieldnotes
- gradio
- knowledge-graph
- local-llm
- llama.cpp
- gemma
- cytoscape
- off-the-grid
loosecanvas πΈοΈ
Talk through an idea. Watch it become a map β and decide which connections are real.
The problem
LLMs assert. They hand you fluent text where a hard fact, a hedge, and a confident hallucination all look identical β so you can't tell what to trust, and the "knowledge" you build with them quietly rots. A knowledge graph an AI fills in on its own is just a prettier version of the same problem.
The value prop: an AI that proposes, but never decides
loosecanvas is a local, co-created understanding map. You chat; a small local
model proposes concepts and connections; you accept, reject, or edit every
single proposal. Each claim carries four independent trust fields that never
collapse into one β origin (frozen at birth), claim_type, support_state,
review_state β so a model's guess is permanently marked a guess until you say
otherwise. Export drops unreviewed model-inferred claims, so the map you take with
you is one you actually vouched for. Messy thinking in; a trustworthy, co-owned
map out.
TL;DR for judges
- Track: π² Thousand Token Wood β a small local model is the whole point.
- Off the grid: zero cloud API calls. 100% local inference via llama.cpp.
base_urlis hardcoded to localhost; the API key is a dummynot-needed. - Small model, load-bearing: Gemma 4 26B-A4B (~25B active params, GGUF, QAT) β no fine-tune, stock Unsloth weights. The small-model constraint forces the good UX: the human is in the loop because the model shouldn't be trusted blind.
- Off-brand UI: a real custom Svelte 5 + TypeScript Cytoscape.js Gradio component, not a chatbot with a decorative graph beside it.
- Field notes: a genuine build write-up ships with the submission (see links).
Features
- Magic build from a paragraph. Paste or write messy thoughts, press Send, and watch the graph assemble live as the model streams concepts and edges.
- Trust-tagged everything. Model proposals land with an amber "awaiting review" badge. Accept, reject, or edit β origin is never silently upgraded.
- Color the clusters. Community detection groups related ideas at a glance.
- Find a hidden connection. Ask the model to surface a surprising cross-domain link, articulated in plain language β then judge it.
- Trust-gated export. Unreviewed guesses are dropped on the way out.
Demo
- Live Space: https://huggingface.co/spaces/build-small-hackathon/loosecanvas (goes live when transferred to the org and made public)
- Demo video: TODO
Architecture / system flow
A turn is a negotiation, not autocomplete:
You chat ββΆ LangChain create_agent (local llama.cpp endpoint, streams tokens + tool calls)
ββΆ agent tools accumulate proposed actions
ββΆ validator + reducer DECIDE (pure: actions β GraphPatch + ScenePatch)
ββΆ graph repository + renderer adapter ββΆ RendererPatch ββΆ Cytoscape.js canvas
The LLM proposes; the validator and reducer decide. Rejected actions return a reason string the model can self-correct from. Three layers stay separate: the portable product artifact (graph + claims), the runtime/control plane, and the frontend (which owns positions and pan/zoom). The trust model is enforced in code, not by prompting.
Tech stack
| Layer | Choice |
|---|---|
| Model | Gemma 4 26B-A4B-it-qat (GGUF, ~25B active params) β stock Unsloth |
| Inference | llama.cpp OpenAI-compatible server, 100% local (127.0.0.1:8080) |
| Agent loop | LangChain create_agent, streaming tools |
| Backend | Python 3.13, FastAPI + Gradio, uvicorn (0.0.0.0:7860) |
| Frontend | Svelte 5 + TypeScript, Cytoscape.js β custom Gradio component |
| Deploy | Single self-contained Docker Space (llama-server + app, one image) |
Hackathon badges
| Tag | Why it's earned |
|---|---|
track:wood |
A small local model (Gemma 4 26B-A4B) is the core of the product. |
achievement:offgrid |
Zero cloud API calls; all inference is local llama.cpp. |
achievement:llama |
llama.cpp is the inference runtime. |
achievement:offbrand |
Real custom Svelte 5 + Cytoscape.js component, not default Gradio UI. |
achievement:fieldnotes |
A genuine published build write-up ships with the submission. |
Submission links
| Item | Link |
|---|---|
| Live Space | https://huggingface.co/spaces/build-small-hackathon/loosecanvas (on transfer) |
| Demo video | TODO |
| Social post | TODO |
| Field notes | submission/FIELD_NOTES.md (in source repo) |
| Source | GitHub β Joshua Sundance Bailey |
| Team | @joshuasundance |
Run it / deploy
This Space runs a single self-contained Docker image: llama-server loads the GGUF
in-container on 127.0.0.1:8080, and uvicorn serves the app on 0.0.0.0:7860. The
model repo (unsloth/gemma-4-26B-A4B-it-qat-GGUF) is public β no token needed.
suggested_hardware: l4x1 is advisory; pick Nvidia L4 in Space Settings to run
on GPU. startup_duration_timeout: 2h covers the runtime model download (~13.6 GB)
plus cold-GPU load. To run locally instead, see the source repo's README.md.
Built for the Build Small Hackathon β Thousand Token Wood track.