About the project
Inspiration
NoFetch started with a habit we kept noticing in developer tools: when something breaks, the first suggestion is often to search, install, or download. Sometimes that is necessary. A lot of the time, though, the answer is already sitting in an environment file, a virtual environment, the shell history, or Git's reflog.
That network-first habit is especially frustrating when data is expensive or the connection keeps dropping. We wanted an assistant that would slow down for a moment, inspect the evidence on the laptop, and try the smallest local fix first.
That became the rule behind NoFetch: repair locally, and fetch only when the evidence says the missing resource really is missing.
What it does
NoFetch takes a small JSON case with a scenario, a task, and a bounded list of evidence. For example, the evidence might show that .env.local contains a valid port while an empty process variable overrides it.
The assistant returns four lines:
FINDING: <local cause>
LOCAL ACTION: <one safe action>
VERIFY: <one local check>
FETCH STATUS: <no-fetch or needs-approval>
The model helps phrase the finding, but it does not control the repair. A JavaScript playbook chooses the action, the verification command, and whether fetching is allowed. If the model wanders away from that plan, NoFetch drops its response and uses the trusted local answer.
Everything runs through a llama.cpp server bound to the loopback interface. The client refuses remote hosts and redirects. It also rejects oversized input, extra fields, contradictory evidence, and malformed model output.
How we built it
We chose Qwen2.5-Coder 1.5B Instruct in the Q4_K_M GGUF format. It is small enough to run on a CPU, but still useful for short debugging explanations. llama.cpp runs the model in offline mode, and the command-line client uses Node.js platform APIs without external packages.
The most important part is the split between language and policy. The model can describe what appears to be wrong. Regular code decides what the user should do next.
We wrote a deterministic playbook for cases such as empty environment overrides, packages that already exist inside a virtual environment, reachable commits in Git's reflog, paths containing spaces, and genuinely missing tools. Ambiguous or conflicting evidence goes to manual review instead of forcing a guess.
We pinned the model download and llama.cpp source to exact revisions and verify the model with a SHA-256 checksum. The public repository also includes 22 tests and a shell verifier. The project page itself is a small static site built with HTML, CSS, and JavaScript.
Challenges we ran into
Getting a local model to produce an answer was the easy part. Deciding what it should be allowed to influence took much longer.
Prompt instructions were not enough. A model could still recommend an install, invent a command, or produce a convincing answer that did not match the evidence. We ended up shrinking its responsibility. Now it supplies a short finding, and NoFetch checks that finding against the trusted plan before showing it.
Performance also mattered. We were targeting the kind of laptop people already own, not a workstation with a discrete GPU. That meant using a quantized model, keeping requests short, and watching physical memory closely.
We had to stay honest about our measurements too. Our profiler run used a participant Mac, so the numbers are development evidence. They are not official challenge scores, and the standard Ubuntu validation still needs to happen.
Accomplishments that we're proud of
The current build runs on an Intel Core i5 laptop with no GPU. In our measured run, it generated 21.62 tokens per second and reached about 1.87 GB of peak physical memory. A 50-sample ARC-Easy run scored 0.66 acc_norm.
I'm proud that the failure path works too. If the local model times out, returns malformed text, or suggests something outside the trusted plan, the user still gets a useful local action. The system fails closed instead of improvising.
We also reached 22 passing tests covering the CLI, repair playbook, unsafe hosts, redirects, conflicting evidence, fallback behavior, and the landing page.
What we learned
Small models work better when the job has clear edges. NoFetch does not need the model to run the machine or make every decision. It needs a short explanation grounded in evidence.
We also learned that restraint can be useful output. "Do not install anything; use the package that is already inside .venv" may look less impressive than a long generated answer, but it is often the answer the developer actually needs.
The project changed how we think about offline AI. Running without a network connection is only one part of it. The tool also has to resist inventing reasons to reconnect.
What's next for NoFetch
Our immediate next step is the standard Ubuntu 22.04 laptop evaluation and the hidden accuracy test. That will give us results that can be compared fairly with other submissions.
After that, we want to add more repair cases based on problems developers repeatedly encounter, but each new case will need a narrow action and a clear way to verify it. We also want an interactive CLI that helps users assemble a case without hiding what evidence is being passed to the model.
The goal is still the same: check what is already there before asking the developer to fetch something new.
Log in or sign up for Devpost to join the conversation.