SlothWeaver:筆電休眠時暫停、醒來後接續工作的本機摘要工具
SlothWeaver: a local summarizer that naps when your laptop does (and picks up where it left off) 🦥
SlothWeaver 是一款桌面應用程式,使用 Ollama 本機執行的 Gemma 2 (9B),為 .txt 或 .md 檔案產生摘要及三個標籤,資料不會離開用戶的裝置。耐久模式以 Temporal 工作流程處理摘要;遇上 Ollama 停止、模型崩潰或筆電休眠時,系統會自動重試並接續工作。生成結果會以原子方式寫入 .summary.md,已有檔案則先備份。
Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥
This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3 — Slow and Steady.
What I Built
SlothWeaver is a desktop app for the most sloth-like workflow I know: pick a file, walk away, come back to a summary.
You choose a .txt or .md file. A local Gemma 2 (9B) model running in Ollama reads it and writes a short summary plus three tags to <file>.summary.md. Nothing leaves your machine.
It is deliberately slow and steady:
- It doesn't care if your laptop falls asleep. In durable mode, each summary runs as a Temporal workflow. If Ollama is down, the model crashes, or the lid closes mid-run, Temporal retries with backoff (5s, 10s, 20s… capped at 5 minutes) and resumes. You never re-click anything.
-
It never destroys your work. If a summary file already exists, the old one is backed up to
.backup, then.backup.1,.backup.2… and the new one is written atomically. A crash mid-write can't leave a half-written file. -
It's lazy about failure too. If the model rambles instead of returning JSON, that's caught and reported (to Sentry, if you set
SENTRY_DSN) instead of saving garbage.
Demo
Here's a real run against the project's own README, using gemma2:9b locally:
{
"status": "completed",
"summary": "SlothWeaver is a tool for generating durable document summaries using local AI models. It leverages Ollama for processing, Temporal for persistence, and Tauri for a desktop application...",
"tags": ["AI", "Summarization", "Local Development"]
}
Code
👉 https://github.com/Prekshabarjatya/slothweaver
How I Built It
Four small layers, each built test-first:
| Layer | What it does | Key test |
|---|---|---|
summarizer.py |
Calls Ollama with format: json, strips markdown fences, validates there's a summary
|
Garbage, fenced, and keyless model output all raise LLMError
|
file_ops.py |
Backup-then-atomic-write | A second save never clobbers the first backup |
workflows.py |
Temporal workflow + heartbeating activity | A flaky activity fails twice, then succeeds, on Temporal's time-skipping test server |
Tauri (src-tauri/) |
Rust command that shells out to the Python CLI | — |
The retry test was my favourite. Temporal's WorkflowEnvironment.start_time_skipping() fast-forwards the backoff timers, so a test that would "wait" 15 seconds for retries runs in about one:
@activity.defn(name="process_file_activity")
async def flaky(file_path: str) -> dict:
attempts.append(1)
if len(attempts) < 3:
raise RuntimeError("laptop went to sleep")
return {"status": "completed", "file": file_path}
One gotcha worth sharing: my first version was an async activity that called a blocking requests.post to Ollama. That stalls the worker's event loop for the whole generation. The fix was to make the activity a plain def and give the worker a small ThreadPoolExecutor. It's two threads, because the GPU is the bottleneck, not the CPU.
The LLM is mocked in unit tests so they run in about a second. A separate pytest -m integration hits real Ollama, and it passes in about 38s on my machine. CI runs the unit tests on every push.
I built this pairing with Claude Code (Claude Opus 5.5).
Why open innovation matters here
- Private by default. Notes, journals and work docs are exactly the files you don't want to upload. An open-weight model on localhost means they never leave the laptop.
- Free to be slow. There's no per-token bill, so retrying five times after a sleep costs nothing. That makes durable retries a sensible default rather than a luxury.
-
Swappable. The model is one env var (
SLOTH_MODEL). When a better open model ships, I change one line. - Open plumbing. Temporal, Tauri, and Ollama are all open source, so every layer is inspectable and replaceable.
Prize Categories
- Best Use of Gemma: Gemma 2 9B is the only model in the loop, running locally through Ollama.
- Best Use of Temporal: durable workflow with heartbeats, an exponential-backoff retry policy, and time-skipping tests that prove the retries work.
What I'd do next
- Watch a folder and summarize new files overnight. That's the ultimate sloth mode.
- Bundle Python as a Tauri sidecar so it ships as a single
.app.
來源:DEV Community · dev.to