No API keys. No cloud. Just Ollama, Gemma 4, and an agent that browses the web, reads files, and runs shell commands — all on your hardware.


Most AI agent tools are designed around cloud APIs. You paste an Anthropic or OpenAI key, and your queries — including file contents, code snippets, and browser sessions — travel to a remote server to be processed. For many use cases that's fine. But if you work with sensitive code, confidential documents, or simply value keeping your data local, it's a meaningful constraint.

There's a growing class of open-weight models capable enough to power a real agent loop. Gemma 4, Google DeepMind's latest release, runs at 27 billion parameters on a single consumer GPU and handles multi-step reasoning, tool use, and long-context tasks well. The infrastructure to run it locally — Ollama — is mature and straightforward. What's been missing is a polished desktop application that wires all of this together.

halo-gemma is that application: a fork of the open-source hello-halo AI workstation, stripped down and rewired to run exclusively with Gemma 4 via Ollama.


What halo-gemma Is

hello-halo is an open-source Electron desktop app originally built for teams using cloud AI providers — Anthropic, OpenAI, DeepSeek, and others. It comes with a full agent loop, an embedded browser, web search, file management, and a scheduler for autonomous digital humans.

halo-gemma keeps the core of that infrastructure and makes one fundamental change: every cloud AI provider is replaced by a single local one. Ollama runs on your machine at http://localhost:11434. Gemma 4 handles all inference. Nothing leaves your network.

The agent loop itself is powered by Anthropic's Claude Code SDK — an Apache 2.0 licensed tool that runs as a local subprocess. No Anthropic API key is required. An in-process OpenAI-compatibility router translates the SDK's Anthropic-format requests to Ollama's local API, so the agent loop remains untouched while Gemma 4 does the actual work.


What the Agent Can Do

halo-gemma is not a chatbot. It's an agent that takes actions:


How the Architecture Works

The data flow through the app is straightforward once you see it laid out:

User input
    ↓
Claude Code SDK  (agent loop — tool dispatch, session history)
    ↓  Anthropic-format messages
OpenAI-compat router  (in-process translation layer)
    ↓  think: false  ·  max_tokens: 65536
Ollama  →  gemma4:27b
    ↓
Tool calls: web search · AI browser · file system · shell

The Claude Code SDK manages the multi-turn agent loop — tool dispatch, session management, and automatic compaction of long conversations as they approach Gemma's 131K context window. The OpenAI-compat router sits between the SDK and Ollama, translating formats and injecting Gemma-specific parameters.


The Engineering Challenges

Getting this combination to work reliably required solving several non-obvious problems. Three are worth explaining in detail.

Gemma's thinking tokens. Gemma 4 has been trained to generate <think> blocks — internal reasoning that precedes the actual response. When the model does this natively, the thinking can consume the entire output token budget and leave nothing for the real reply, producing an empty response on every turn. The fix is to inject "think": false into every Ollama request, suppressing native thinking generation. This is applied in the request converter so it's automatic.

There's a subtler version of the same problem: occasionally Gemma ignores think: false and generates only a thinking block with no text. The CC SDK sees this as an empty response and throws an error. The fix lives in the stream handler: when a response contains only thinking content, the thinking block is promoted and emitted as text. The model put its answer in the wrong place — the handler moves it to the right one.

Auto-compact token headroom. The CC SDK automatically compacts long conversations by summarizing them in-place. This summarization is itself a model call, and it needs enough output tokens to write a complete summary. Gemma 4's 131K context window with a default 8192 output limit was too tight — the CC SDK would start a summary and hit the limit mid-sentence. Setting maxOutputTokens to 65536 in the model capabilities config gives the compaction step enough room to work cleanly.

Bing bot detection and search quality. The web search component uses a hidden (not headless) Chromium browser — real GPU compositing, attached to the main app window at an off-screen position. This is less fingerprint-detectable than a fully separate hidden window. For queries with the site: operator, Bing sometimes returns a CAPTCHA page instead of results. The Bing engine now detects this and surfaces actionable guidance to the model: navigate directly to the search URL using the AI browser, screenshot the CAPTCHA, and solve it interactively. There's also a subtler issue: without double-quotes, Bing treats hyphens as word separators, so searching for hello-halo returns results for "hello" and "halo" separately. A note in the system prompt instructs the model to always quote exact project names in search queries.


Getting Started

You need Ollama running locally with Gemma 4 pulled, and Node.js 20+ with Yarn.

# Pull Gemma 4 (~17 GB recommended, ~8 GB for lighter hardware)
ollama pull gemma4:27b

# Clone and install
git clone https://github.com/wengjiyao/halo-gemma.git
cd halo-gemma
cp product.example.json product.json
yarn install
yarn dev

The app launches directly into the chat interface. No setup wizard, no API key prompt. It connects to Ollama at localhost:11434 automatically. To switch to a lighter model, change the model field in src/main/foundation/config.service.ts.


Why Open Source

The modifications to hello-halo are MIT-licensed, matching the upstream. The Claude Code SDK is Apache 2.0. Ollama and Gemma 4 are open-weight and free for personal use. The full stack is auditable.

The goal of releasing this publicly is to provide a starting point — not a finished product, but a working system. If you want a capable desktop AI agent running entirely on your own hardware, with a model you can inspect, on an app whose source code you can read and modify, this is a reasonable foundation to build from.

hello-halo upstream is actively maintained and receives regular updates — new tools, UI improvements, bug fixes. Staying close to its main branch means halo-gemma can pull in those improvements over time, with the Gemma-specific layer applied on top as patches.


What's Next

Three things are on the roadmap. First, a dynamic model list fetched from Ollama at startup — any locally pulled model becomes usable without code changes. Second, support for thinking-capable Ollama models like DeepSeek-R1 and QwQ, with thinking enabled rather than suppressed. Third, pre-built binary releases so installation requires nothing beyond downloading a file.

Contributions are welcome, especially around Ollama compatibility, search reliability, and installer simplicity. The project is at github.com/wengjiyao/halo-gemma.