Local AI Vision 🚀 Screen-Time App with Private AI
Discover a local AI vision model for a screen time app—private AI with Ollama & Gemma 4 E2B. Explore design trade-offs, then inspect the code.

A Screen-Time App With No Skip Button - and a Local AI Check
Most screen-time tools put the final decision back in your hands. You hit a limit, tap "one more day" or "15 more minutes," and move on. Technically, the app did what it promised - but the habit usually barely notices.
Outside Leash takes a different route. After a daily limit on sites like YouTube or Reddit, it swaps the current browser tab for a short outdoor "quest." To unlock the sites again, you snap a recent photo on your phone and submit it. A vision model running on your own laptop checks whether the image fits the quest. If it does, the sites reopen for 30 minutes.
The interesting part isn't just that it uses AI to look at a photo. It's how tightly the system is constrained: a Chrome extension, a small Python server, and Gemma 4 E2B running through Ollama - no cloud API, no GPU. It's a useful example of local AI applied to a small behavioral problem, with the added bonus of being fairly clear about what it can and can't enforce.
The product problem: a limit you can't dismiss
A screen-time limit only matters if it changes what happens after you hit it. A lot of apps treat the limit like a speed bump you can easily drive around: you've reached your allowance, but you can override it if you really want to. That makes sense for people who genuinely need some flexibility. It's less helpful if you already know you'll override it every single time.
Outside Leash is built around that exact failure mode. The creator describes a familiar pattern: screen-time apps add a "skip for today" option, and people use it. Instead of adding yet another reminder, the tool removes the quick escape route and inserts a small real-world task between the user and the blocked sites.
The flow is deliberately simple
The extension counts time while you're actively viewing a blocked site. The default limit is 20 minutes per day for sites like YouTube, Reddit, Instagram, Facebook, and X. When the limit is reached, it redirects the current tab to a quest page served from the laptop.
The page gives you a prompt - something like finding an unusually colored object outside. You open it on your phone, take a new photo using the phone's Camera app, and submit it. If the local vision model accepts it, the blocked sites unlock for 30 minutes, and the laptop sends you back to whatever page was open before the lock.
This isn't meant to be a full digital-wellbeing platform. It's a small piece of friction placed exactly where you'd normally click "ignore." The goal isn't perfect enforcement. It's to interrupt the autopilot behavior long enough to change the moment.
Why not just block the sites?
Blocking can work, but it brings practical issues. You may need those sites for work, research, or communication. Too-rigid a block can be disabled, or it can get in the way of legitimate use.
Outside Leash uses a temporary unlock instead of permanent denial. That's a conscious trade-off: you get back access for 30 minutes, but the tool doesn't pretend it can reliably tell "productive browsing" from "compulsive browsing." It's designed for one person's habits, not as a universal rulebook.
And honestly, that's fine. A useful intervention doesn't have to solve every version of the problem. It does need to be honest about what it targets - and what it doesn't try to do.
How the local AI system works
This setup has three parts: a Chrome extension, a Python server, and a vision model served locally through Ollama. The extension handles the browsing-time tracking and the tab redirect. The Python server serves the quest page, receives the photo, and asks the model whether the image satisfies a predefined check. Ollama runs Gemma 4 E2B on the same laptop.
The creator reports testing on a laptop with 16 GB of RAM and no GPU, which is part of the point: the workflow doesn't depend on a hosted vision API, API keys, or sending photos to a third party.
Tracking time and redirecting the tab
In the implementation, the extension wakes up every 30 seconds. It only adds time when the active tab is on a blocked site. It stores a per-day total locally. Once you hit the limit, it checks with the server for a recent successful quest. If there isn't a valid pass, it redirects the tab to the local quest page and includes the previous URL so the browser can return there after the unlock.
It's a straightforward design, but that simplicity has consequences. The timer isn't a forensic log of every second you've been online - it's a practical counter based on the active tab. And because the enforcement is in a browser extension, disabling the extension bypasses the lock. The project accepts that weakness because the intent is to create friction, not to build tamper-proof parental control.
Keeping the quest and the check aligned
In the first version, the model generated both the quest and the photo-checking question. During testing, that made things unpredictable: quests tended to cluster around leaves, and some check questions didn't actually verify that the photo matched the quest.
The implementation was changed so the code picks from a set of themes, then pairs each theme with a human-written check question. The model can phrase the quest in a natural, friendly way, but it doesn't get to define the acceptance criterion.
That separation helps. You can vary the user-facing prompt without changing the rule for success. It also reduces the risk that a generated question accidentally makes the task easier, harder, or just unrelated.
The quest also stays the same until it's completed. Refreshing the page doesn't generate a new, easier prompt. None of that is flashy AI work, but it's the kind of detail that determines whether the tool behaves consistently.
A phone is part of the design
The laptop shows the quest and provides an address you open on your phone. The phone captures and submits the image, and the server rejects uploads coming from the laptop itself or from its local network address.
The original idea was to capture the photo directly in the phone's browser. In practice, that caused browser crashes with low-memory errors. A gallery upload option might have been more flexible, but it would also make it easier to submit an old photo. The creator's approach is: take a photo in the Camera app, then upload it through one button. The page rejects files whose modification time is more than 10 minutes old.
This is a pragmatic compromise, not proof that the photo was taken outdoors. The timestamp check adds some freshness friction, but it doesn't establish location. That's the key distinction here: "useful deterrent" is not the same thing as "secure verification."
What the model can do - and where it fails
The model's job is intentionally narrow: look at an image and answer whether the main subject satisfies a fixed criterion. It doesn't need to write an essay or carry on a conversation. The implementation asks for a yes-or-no answer and caps generation at 10 tokens.
The creator tested Qwen3-VL 2B and Gemma 4 E2B. Qwen3-VL took about 47 seconds per photo. Gemma started around 31 seconds, largely because it produced reasoning before the final answer. When thinking mode was turned off, the reported check time dropped to roughly 3.4 seconds.
These numbers are based on this project's setup, not a general benchmark. Hardware, model versions, image handling, and prompt details can all change latency. Still, the takeaway holds: model choice isn't the only performance knob. The task definition and inference settings matter a lot too.
The model checks an image, not the real world
A photo can match a color-based quest without proving the user went outside. The creator found, for example, that a pink cloth on the floor at home could pass a color quest. The model evaluates pixels and prompt wording; it doesn't have reliable access to the circumstances around the photo.
It also struggled with a photo of a tree displayed on a screen. The creator tried adding instructions to reject screen images. One approach rejected a legitimate photo too, while a separate screen-detection question produced false positives. With only a small number of tests, there isn't a solid accuracy figure to report.
That restraint matters. A few successful examples don't prove accuracy, and a confident vision-model answer isn't evidence it verified context. The project leaves the spoofing weakness in place because, for this use case, rejecting a genuine quest photo would be worse than allowing an occasional bypass.
The actual security model is "speed bump"
The creator frames it as a speed bump, not a vault. That's the right mindset. You can bypass it by disabling the extension, stopping the local server, or fooling the image check. It can't prove you walked outside, and it isn't designed to stand up to a determined attacker.
For a personal habit tool, that's a reasonable trade. If the goal were enforcing restrictions on a child's device, meeting compliance requirements, or protecting access to sensitive systems, this architecture would be inadequate. The cost of a false pass - or a bypass - would be totally different, and so would the required safeguards.
A system should be judged against its threat model. Here, the target is you, trying to dismiss a reminder - not an adversary with time and motivation to defeat the software.
What this project shows about practical AI
Local inference is often talked about as a privacy win or a way to avoid API costs. Outside Leash gives those ideas something more concrete. Photos of surroundings can reveal details about your home, neighborhood, and routines. In this implementation, the phone talks to the laptop over the home Wi‑Fi network, and the photo check runs locally rather than being sent to a hosted model.
That doesn't automatically make the setup "secure." The server, local network, and devices still have to be trusted. But it does remove a third-party upload path for every quest photo. For a small personal tool, that's a meaningful architectural choice.
Local AI changes the cost and privacy calculation
A hosted vision API could be easier to integrate and might offer stronger image understanding. It would also add an external service, network dependency, and likely a per-request cost. The creator didn't test a hosted model, so there's no real basis for claiming local inference is more accurate - or universally cheaper.
A better way to think about the decision is trade-offs:
- Privacy: local processing keeps images on your devices in this design, instead of sending them to an external inference provider.
- Cost: there's no per-photo API charge, though you still pay in hardware and setup.
- Performance: the reported 3.4-second check was usable on the tested laptop, but results vary by machine and model.
- Capability: a hosted service may have different (possibly better) vision performance, but that needs testing for this specific task.
- Operations: the local server has to be running, and the extension has to stay enabled for the flow to work.
The right choice depends on what happens when the system fails. For a low-stakes personal prompt, local inference can be a good fit. For a business process where a false acceptance has real financial or safety consequences, you'd want a much higher bar.
Open-source tools make experimentation cheaper
Using Ollama and a locally runnable model makes it easier to compare alternatives without rebuilding the whole app. In this project, swapping the model name was enough to test Qwen3-VL against Gemma. That let the creator see a big latency difference and then adjust Gemma's inference settings.
It's a practical benefit of modularity. The product logic - quest selection, image upload, unlock duration - doesn't have to be tightly coupled to one model. If a better model shows up, you can evaluate it on the same task and replace the old one if the improvement is worth it.
The broader lesson for teams isn't "always run AI locally." It's: isolate the model behind a clear boundary, define what a successful output means, and measure performance on representative inputs. A model that's easy to swap is easier to test, but it still needs a reliable evaluation method.
For the original project and implementation details, see the Outside Leash repository and the original project write-up. For local model serving, see Ollama.
Conclusion
Outside Leash is a small project with a clear goal: make the moment after a screen-time limit harder to dismiss. It combines a browser extension, a local server, and a local vision model, while keeping the model's role narrow and the limits visible.
The most useful lesson isn't "AI can enforce better habits." It's that a modest AI component can support a specific product interaction when the task, risk, and trade-offs are clearly defined. Local inference can help avoid sending personal photos to a cloud service, but it doesn't fix spoofing, accuracy limits, or enforcement on its own.
If you're building something similar, start by defining what the model must decide, what a wrong answer costs, and what the system should do when it can't tell. Then test it with real inputs before treating it as reliable. Look through the Outside Leash code and judge the design against your use case - not against the fantasy of a perfect AI gatekeeper.