Tavotto
AI drew your research figure. Tavotto makes it publication-ready: edit matplotlib figures on a canvas, lay out in mm, check journal rules. Free, open source.
Dānā is an autonomous CAD orchestrator: deterministic verification, topological lineage through destructive operations, and self-healing scripts — offline-first, on your machine.
AI translation
Dānā is an autonomous CAD orchestrator: deterministic verification, topological lineage through destructive operations, and self-healing scripts — offline-first, on your machine.
DesignPython · TypeScriptGitHub @Cascade-RouterOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Personal Fully Offline Assistant (Powered by OLLAMA)
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Dānā — an agentic CAD engineer that turns sketches into FreeCAD models Dānā is an open-source, multi-step LLM agent that designs mechanical parts. You describe a part, or hand it a drawing. It plans the build, drives a real FreeCAD kernel through ~90 typed tools, checks its own geometry, and exports a standalone FreeCAD macro that rebuilds the part without the agent. It began as a commercial product and is now published as an engineering portfolio piece. The README focuses on the four engineering problems that took the most work, with links to the code that solves each one.Read the full README ↗
Dānā is an open-source, multi-step LLM agent that designs mechanical parts. You describe a part, or hand it a drawing. It plans the build, drives a real FreeCAD kernel through ~90 typed tools, checks its own geometry, and exports a standalone FreeCAD macro that rebuilds the part without the agent.
It began as a commercial product and is now published as an engineering portfolio piece. The README focuses on the four engineering problems that took the most work, with links to the code that solves each one.
| Stack | Python 3.11 · FastAPI + WebSockets · React/TypeScript (Tauri desktop shell) · FreeCAD (headless FreeCADCmd) · Ollama · Jinja2 |
| Models | Cloud: DeepSeek (primary), Gemini, OpenRouter, Groq · Local: qwen2.5-coder:14b (tools), qwen2.5vl:7b (vision) |
| Tests | 1,479 pytest cases, blocking in CI, no live model or GPU needed · Playwright UI tests against a mock backend |
Problem. A multi-step CAD session mixes very different turns. Some make precise geometry calls, where a wrong argument corrupts the model. Others are cheap bookkeeping, such as a catalog lookup. Letting "whatever model is configured" handle every turn wasted money and let small local models slip wrong parameters into the geometry.
Solution. Each turn's model chain is a pure function of config plus turn state, with no randomness and no LLM-judged routing:
routing_config.yaml, parsed by dana/core/llm_router.py). Each entry is a provider, model, priority, context window and cost. API keys are referenced by env-var name and never stored in the file.context_window × safety_margin fits the turn's estimated token count. Eligible entries are tried in priority order, with a configured terminal fallback (local Qwen) always last.allow_cloud: false) returns only Ollama entries, with no silent escape to the cloud.dana/core/react_dispatch.py pins Turn 0 (create_plan) to a cloud model.report_fleet_entry_failure) and the chain falls through to the next one. The whole router can be removed: without the YAML file, the legacy .env resolution runs unchanged.In practice, DeepSeek handles planning and geometry, local Qwen handles bookkeeping and full-offline mode, and every routing decision can be reproduced from config.
Problem. Vision models are good at recognizing what is in a drawing and bad at how big it is. A 7B VLM returns JSON that is structurally valid but numerically wrong: all-zero boxes, invented part IDs.
Solution. A staged pipeline where every step that touches numbers is deterministic:
dana/plugins/vision/ocr_grounding.py). EasyOCR reads the printed dimensions from each orthographic view. They are passed to the VLM as hard constraints, and they alone determine the bounding box.dana/plugins/vision/image_analysis.py). Pass 1 extracts primitives (box, cylinder, sphere and their dimensions). Pass 2 extracts relationships and joints given pass 1's output. Each pass tries a local model first and falls back to the cloud, and a JSON decode failure moves on to the next provider instead of aborting.parent_id/child_id references fail loudly. A fabricated blueprint never reaches the CAD kernel as ok: true.dana/plugins/freecad/ir.py). One step-dict schema (box, cylinder, boolean, edge ops, …) is shared by three consumers that used to generate FreeCAD script text separately: live tool execution, session replay, and the composite-skill compiler.dana/plugins/freecad/py_export.py + templates/macro_export.py.jinja2). The session's call log, including boolean cut/union/intersect steps, is rendered into one standalone .py macro that rebuilds the part in stock FreeCAD.dana/tools/cad_vision.py). After every mutating CAD call, the viewport is captured headlessly and a VLM reads it back, so the agent checks what it actually built.No GPU? Set DANA_VISION_MOCK_FALLBACK=1. When no vision model is reachable, the pipeline then continues on a clearly flagged placeholder blueprint ("mocked": true) instead of stopping. It is off by default because it is fabricated geometry.
What a chat session gives you besides the conversation:
dana/plugins/freecad/rebuild.py). Every CAD call is recorded and replayed through the same Universal CAD IR the macro export uses. The Parameters tab lists the model's dimensions; change one and Apply & Rebuild re-runs the recorded steps with no LLM call. On FreeCAD the steps render into a scratch document that replaces the live one only on success; on the mock engine (CI, the hosted demo) the call log is replayed through the mock driver..py, with a provenance header listing the editable parameters and how many LLM calls vs. free rebuilds built it), STEP/STL, the 2D blueprint and a costed BOM with tip-over stability — none of them cost tokens.dana/api/session_state.py). The plan, object registry, topology, call log and token/cost totals are saved with the chat, and the FreeCAD document is snapshotted with its SHA-256; resuming restores both. Approvals, auto-approve and API keys are never written to disk.Problem. An earlier deploy broke even though CI was green, because CI only imported a single module. The fix was to make CI run the real code in the same kind of environment it ships to.
Solution (.github/workflows/build.yml):
xvfb, with --strict-markers and a per-test timeout. Failures are parsed out of the JUnit XML into GitHub ::error annotations, so they show on the PR without opening the log.app.py from the exact payload deploy/stage_space.sh ships, with the pinned Gradio version.tsc && vite build that Vercel runs.workflow_run only after Build succeeds.tests/conftest.py). Every module-level path into freecad_output/, exports/ or agent_workspace/ is redirected to the test's tmp_path (found by sweeping the loaded modules, so a new one is covered automatically), every per-session registry is cleared before and after each test, and the run fails if the real workspace changed at all. TTS/audio hardware calls go to fakes. They block mid-test .env reloads (a real leak that once overrode test env vars) and force auto-approve and context distillation off. DANA_HEADLESS=true and DANA_OS_DRY_RUN=1 keep FreeCAD's GUI and physical input out of CI.tests/e2e/). Playwright drives the real UI against the real server with the mock CAD engine, a scripted model and a throwaway workspace (tests/e2e/mock_backend.py): streaming, the cost bar, macro export, the BOM popover and a parametric rebuild. Run with cd frontend && npx playwright test.Problem. The agent keeps a persistent "core memory" of user preferences, project constraints and learned workflows. It is injected into every system prompt and survives restarts. Nothing limited its size, so over weeks of use it would grow without limit into every turn's context.
Solution (dana/plugins/memory/core_memory.py):
React/Tauri UI ──WebSocket /ws/chat──▶ FastAPI (dana/api/server.py)
│
ReAct loop (dana/core/react_dispatch.py)
plan → tool call → observe → verify
│
┌──────────────────────────────┼──────────────────────────────┐
▼ ▼ ▼
LLM router (llm_router.py) Tool registry (~90 tools) Core memory (2k, FIFO)
DeepSeek / Gemini / OpenRouter CAD · vision · web · OS · skills + session call log
/ Groq → local Qwen fallback │
▼
FreeCAD plugin (dana/plugins/freecad/)
Universal IR → FreeCADCmd (headless)
→ .FCStd session doc · STEP/STL/URDF · .py macro
Requires Python 3.11, FreeCAD 1.0+, Ollama, and Node 20+ for the UI.
git clone https://github.com/Cascade-Router/Dana.git && cd Dana
python -m venv .venv && source .venv/bin/activate # Windows: .\.venv\Scripts\activate
pip install -r requirements.txt -r requirements-dev.txt
cp .env.example .env # OLLAMA_URL defaults to http://localhost:11434
cp routing_config.yaml.example routing_config.yaml # optional: enables the deterministic router
ollama pull qwen2.5-coder:14b # local tool-calling fallback
ollama pull qwen2.5vl:7b # local vision (or set DANA_VISION_MOCK_FALLBACK=1)
(cd frontend && npm install)
./launch_dana.sh # Windows: powershell -File launch_dana.ps1
With no cloud keys set, Dānā runs fully locally on Ollama. Add DEEPSEEK_API_KEY (or another provider's key) to .env to enable cloud routing.
Run the test suite (no GPU, model server or API key needed):
DANA_HEADLESS=true DANA_OS_DRY_RUN=1 python -m pytest
cd frontend && npx playwright install chromium && npx playwright test # UI tests, no FreeCAD or API key
A two-minute walkthrough of the pipeline is scripted in DEMO_SCRIPT.md.
| Path | What lives there |
|---|---|
dana/api/ | FastAPI server, WebSocket chat protocol, sessions, model registry |
dana/core/ | ReAct loop, LLM router, model providers, context management |
dana/plugins/freecad/ | FreeCAD engine, universal IR, Jinja2 templates, macro/TechDraw export |
dana/plugins/vision/ | OCR grounding and two-pass blueprint extraction |
dana/plugins/memory/ | Persistent core memory |
frontend/ | React + TypeScript UI (Tauri desktop shell) |
tests/ | pytest suite (mirrors the dana/ layout) |
docs/ | Architecture notes and design write-ups (ARCHITECTURE.md) |
AGPL-3.0. See CONTRIBUTING.md and SECURITY.md.