Appearance
KimtAI
A private on-device AI chat that can drive your other apps
Overview
KimtAI is a private AI chat that runs a real language model inside your browser tab — not in the cloud. You download a small instruction-tuned LLM once, and from then on every message is answered on your own machine. Not a single token is ever sent to a server. It is part of the kimtos new-tab app suite.
KimtAI is more than a chatbot: it is the suite's agent. When you run a tool-capable model, it can call the tools that your other installed apps expose — search the web, save a note, add a task, read an image, and so on — then answer using the results.
Highlights
- A real LLM in your tab — a small instruction-tuned model runs locally via Transformers.js (
@huggingface/transformers), preferring WebGPU for speed and falling back to CPU (WASM) when no GPU is available. - Fully on-device — the conversation never leaves the browser. There is no backend, no account, and no network round-trip for chat.
- Model Library — download one or more models, see their size and measured speed on your device, and pick which one to chat with. Models are fetched on demand and cached, so each is downloaded only once.
- Streaming replies — tokens stream into the message bubble as they are generated, rendered as Markdown.
- Agent tools — a tool-capable model (Qwen / Llama) can call the tools of your installed apps plus built-in system tools (
web_search,open_app_store) in a loop, then answer from the results. - Per-chat tuning — set a system prompt (persona), creativity (temperature), and response length per conversation.
- Persistent history — conversations are saved locally; pin, rename, search, export to Markdown, or batch-delete with undo.
What runs where
Everything is local, but the work is split across two places in the browser:
- The model runs in a Web Worker (
homeai.worker.ts) so token-by-token streaming never blocks the UI. It loads the model with Transformers.js and streams tokens back to the app. - The tools run on the main thread (in
lib/agentTools.ts), because they read and write the same on-device IndexedDB and engines the app UIs use.
Privacy model
KimtAI writes only to local browser storage and never uploads your data:
- Chats (messages, title, per-chat config) are records in the shared IndexedDB (
chatscollection). - Model files are cached by Transformers.js in Cache Storage (
transformers-cache); which models you have downloaded is tracked in a small local key/value set (homeai:downloaded). - Chat itself makes no network calls. The two exceptions are explicit and user-triggered: downloading a model's files (one-time, then it runs offline), and the built-in
web_searchtool, which the agent uses only when a request needs fresh facts.
Getting Started
Open KimtAI from the dock. Before you can chat, you need a model on your device, so the first thing to do is open the Model Library and download one.
Download a model
Click Models in the header to open the Model Library. Each entry shows the model's parameters, download size, whether it needs WebGPU, and its measured speed on your device once you have used it. A Recommended model is highlighted — a small, fast chat model that runs even without a GPU.
- Download — fetches the model's files once and caches them; a progress bar shows the one-time download. You can close the overlay and it continues in the background.
- Use — makes a downloaded model the active one for chatting.
- Remove — frees that model's cached files (other models and other apps are untouched). You can download it again later.
Models are only ever downloaded when you ask; nothing is prefetched behind your back.
Start chatting
Type in the composer and press Enter (Shift+Enter for a newline). The first time you send in a session, the active model loads — you will see "Downloading model…", then "Warming up…", then replies stream in token by token.
- Stop — the Send button becomes Stop while generating; click it to interrupt.
- Retry — regenerate the last reply.
- Edit & resend — edit one of your own messages to branch the conversation from there.
- Copy — copy any reply.
If you have no model yet and try to send, KimtAI opens the Model Library for you.
GPU vs CPU
If your browser supports WebGPU, models run on the GPU (fast). If not, KimtAI falls back to CPU (WASM), which is much slower — so a small model is recommended there. The model chip in the header shows which the current model is using (· GPU or · CPU), and replies show a rough tokens/second rate.
To save memory, the resident model is freed automatically when idle (after a few minutes, or sooner when the tab is hidden) and reloaded on your next message.
Tune a chat
Click the sliders icon to adjust the current conversation:
- System prompt — the persona / behaviour for this chat (the default comes from the app's settings).
- Creativity — temperature, from Precise to Wild.
- Response length — Short, Medium, Long, or Max.
These are saved per conversation, so different chats can behave differently.
Manage conversations
The left sidebar lists your chats. Every conversation is saved locally as you go.
- New chat — start a fresh conversation.
- Pin / Rename — from a chat's menu.
- Export .md — download a conversation as a Markdown file.
- Search — filter chats by title.
- Delete — remove one, or multi-select to batch delete with an undo.
Using the agent (tools)
If you download a tool-capable model (a Qwen or Llama family model), KimtAI becomes an agent. Ask it to do something one of your installed apps can do — "save this as a note", "add a task", "what's the latest on…" — and it will call the matching tool, then confirm.
- It can only run tools of apps you have installed (and not locked behind a plan). For a capability whose app isn't installed, it tells you and offers to open the App Store instead of pretending.
- It has a built-in web search tool for fresh or factual questions, and will cite the URLs it used.
- Small chat models stay on plain chat (no tools); the tool loop is used only by models whose chat template is trained for function-calling.
Architecture
KimtAI has three parts: the app UI (chat thread, composer, Model Library), the engine that runs the model in a Web Worker, and the agent runtime that collects and runs the tools of your installed apps. The model runs off the main thread; the tools run on it. The code lives in extension/src/apps/homeai/ and extension/src/lib/.
Modules
| File | Role |
|---|---|
apps/homeai/meta.ts | The app's identity — id (homeai), name (KimtAI), accent, order, plan, and marketing copy. |
apps/homeai/index.ts | The app descriptor and UI — chat sidebar, thread, streaming composer, per-chat tuning, and the Model Library overlay. Decides per message whether to run plain chat or the agent loop, and persists chats via the local API (chats collection). |
lib/engines/homeai.ts | The on-device chat engine — the model catalog, the downloaded-models set, measured-speed tracking, cache add/remove, and createChat(), which spawns and talks to the worker. |
lib/engines/homeai.worker.ts | The Web Worker that loads the LLM with Transformers.js (@huggingface/transformers), prefers WebGPU and falls back to WASM, and streams tokens back to the app. |
lib/agentTools.ts | The agent runtime — collects each installed app's tools, builds the system prompt, parses the tool call the model emits, runs the tool on-device, feeds the result back, and loops (runAgent). Also defines the built-in web_search and open_app_store system tools. |
The agent-tools model
Every app in the suite exposes its capabilities to KimtAI as an MCP-shaped tools array on its descriptor. Each tool is { name, description, parameters (JSON-Schema), needs?, run(args, ctx) }, and run returns { ok, result, summary, artifact? } — where result is a compact string written for the model to read.
The runtime handles the rest:
availableTools()flattens thetoolsof every installed, entitled app and stamps each with its app id. A not-installed app, or a Pro app locked on the free plan, contributes no tools — so the agent can only ever drive apps you actually have.- System tools (
web_search,open_app_store) are always present regardless of which apps are installed.web_searchfetches results from the page (using the extension's host permissions);open_app_storesends you to install an app the agent doesn't have access to yet. - Because tools are auto-collected, adding a capability is just a new entry in an app's
toolsarray — there is no wiring in KimtAI itself.
Chat vs agent loop
For each message, index.ts decides how to answer:
- Plain chat — one streamed generation, no tools. Used for small models, and also as a safety-net fallback: if the agent loop ever fails, chat falls back to plain generation so a tool bug can't crash the conversation.
- Agent loop (
runAgent) — used when tools exist and the model supports native tool-calling (Qwen / Llama). The model is told about the tools, emits a call, the tool runs on-device, its result is fed back, and the loop repeats (bounded bymaxSteps) until the model gives a plain-text answer.
Flow
The model always runs in the worker; the app talks to it only through postMessage. Tools run on the main thread because they use the same on-device IndexedDB and engines as the app UIs. Nothing in this diagram crosses the network except the one-time model download and an explicit web_search.
Storage
- Chats live in the shared IndexedDB
chatscollection, saved through the suite's local API (getApi/jsonApi) — the same router the other apps use. - Model files are cached by Transformers.js in Cache Storage (
transformers-cache); removing a model deletes only that model's cache keys. - Which models are downloaded and their measured speeds are tracked in the shared key/value store (
homeai:downloaded,homeai:speed), and per-chat settings persist per conversation.