DEV Community

Shivam Dwivedi
Shivam Dwivedi

Posted on Fully Autonomous

Sloth Inbox: let a tiny open model sort the notes you keep avoiding

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

A brain dump is very good at collecting things. Organizing those things is where it starts asking for a second job. 🦥

I built Sloth Inbox to take one small chore off that list: putting loose notes into sensible buckets. Paste a messy list, get suggested shelves, change anything that looks wrong, and leave with a tidy Markdown file.

The default shelves are Fix, Read, Buy, and Life. A broken login, an interesting paper, coffee beans, a dentist appointment: one pile in, a more useful list out. You can replace those shelves with your own names and descriptions.

The AI runs in the browser. There is no account, API key, or server waiting to read your notes. I started and completed this project on October 22, inside this challenge’s window.

Demo

Open Sloth Inbox on Render · Hugging Face mirror

  1. Click Try an example, then Sort my inbox.
  2. Wait for the first model download. The quantized weights are about 23 MB; runtime and tokenizer files are additional.
  3. Look through the suggested shelves. Anything uncertain stays in Needs review.
  4. Change a dropdown, preview the Markdown, then download or copy your list.

Sloth Inbox running the synthetic twelve-note example, with Fix, Read, Buy and Life suggestions and four notes marked for review.

Actual screenshot of the deployed app. All example notes are synthetic.

I tested the initial Hugging Face deployment with twelve notes. Its top shelf suggestion matched the intended category for all twelve, but the app assigned only eight automatically. Four remained in review because their similarity scores were low. The displayed processing time was 1.24 seconds after model loading in that run. The Render-hosted version also ran the same example successfully, with four notes held for review.

That difference matters. “Dentist appointment” got the intended Life suggestion at a similarity of only 0.15, so it stayed in review. I changed its dropdown to Life and checked that the Markdown preview moved it into the correct section.

This is a small functional check on deliberately straightforward examples, not an accuracy benchmark. The runtime figure excludes downloading and loading the model.

Code

Browse the complete GitHub source · Hugging Face source mirror

The project is Apache 2.0 licensed. It is plain HTML, CSS and JavaScript, with a worker for inference. No build step is needed. To run a downloaded copy with Python 3 installed:

python3 -m http.server 8000 --bind 127.0.0.1
Enter fullscreen mode Exit fullscreen mode

Open http://127.0.0.1:8000. The README includes the exact model revision, runtime, limits and dependency credits. node check.mjs runs ten checks covering input limits, shelf validation, ranking, ambiguous matches and corrected exports.

How I Built It

The core is all-MiniLM-L6-v2, an open embedding model, running with Transformers.js 3.8.1 and WebAssembly. I pinned the ONNX model revision rather than following a moving model branch.

An embedding turns a piece of text into a vector: a list of numbers representing aspects of its meaning. Each note gets one. Each shelf description gets one too. Mean pooling and normalization produce vectors with 384 numbers; comparing their dot products gives cosine similarity.

So a shelf is more than a label. This description gives the model something useful to match:

Fix: bugs, broken software, errors, debugging and repairs
Enter fullscreen mode Exit fullscreen mode

The app ranks the shelves for each note. If the best score is below 0.25, or its lead over the second-best shelf is below 0.04, the note stays in review. Those are simple heuristic defaults. They are not calibrated confidence guarantees.

Common mistake: treating similarity as certainty. A score of 0.35 does not mean “35% likely to be correct.” Making that number look like a confidence percentage would give the interface more authority than the model has earned.

I kept inference in a web worker so the model does not run on the main UI thread. Inputs are bounded to sixty notes, each at most 300 characters. There is no keyword fallback silently pretending the model worked: if model loading fails, the app reports an error.

Making releases less of a chore, too

I added a GitHub Actions workflow that checks input handling and export logic, runs the pinned open model on the twelve synthetic notes, and packages the static frontend. Each successful run saves the inference receipt and deployable files as a seven-day artifact. Here is a passing run.

That CPU inference check kept all twelve intended top suggestions but flagged five notes for review, compared with four in the browser. Scores close to the threshold can produce different review decisions across these runtimes. The check verifies the intended top suggestions without requiring identical floating-point scores.

Render hosts the live frontend. Its build runs the logic checks and copies an explicit list of frontend files into dist/; it does not need to install the inference-testing dependencies. I selected After CI Checks Pass for its deployment trigger. The model still executes in the visitor’s browser, so the hosting change does not send their notes to a server for inference.

Why Does Open Innovation Matter?

For this tool, the useful part of open innovation is control over where inference happens.

The model weights can be downloaded and executed in the visitor’s browser. The runtime and application code are inspectable. I can change the matching logic, the review thresholds or the shelf descriptions without depending on a hosted inference endpoint accepting those choices.

A closed API could also sort notes. This implementation gives me a different trade-off: a model download up front, then local inference without sending the notes to a model provider or supplying an inference credential. That is a practical fit for a scratchpad full of small personal tasks.

The lazy part is modest: the tool proposes the first pass through a pile of notes. The person still checks the shelves. I have not measured human time saved, so there is no invented “hours reclaimed” counter. Sometimes a useful automation just removes twelve tiny sorting decisions from the starting line.

Prize Categories

  • Best Use of Render: the working application frontend is deployed on Render, with a tested static build and browser-local inference.
  • Best Use of GitHub Copilot: this entry uses the GitHub Actions automation option listed in the challenge. The workflow runs the actual open model, checks sorting and export behavior, and saves a deployable build with its inference receipt.

References and Credits

AI disclosure

AI was used to draft the article.

Top comments (0)