Operate
Operating
Running Omnesis once it is installed: the background services, checking health, the configuration file, model assignment, and what to do when something goes wrong. It is written for whoever looks after the gateway machine. Security and encryption live on Security; backups and updates on Backup & updates.
Services
On a Docker install the services are the containers, and omnesis service on
the host runs the docker compose equivalent of start,
stop, restart, status and
logs (--follow, --lines).
docker compose -f ~/.config/omnesis/docker-compose.yml works as well;
substitute your config directory if you chose another path. Installing and removing them
is the installer's; see Docker installation.
For a native install, the installer registers the gateway and
collector as user services: launchd LaunchAgents on macOS, systemd user units on Linux.
Both start at login and restart on failure. omnesis service install sets them
up on a machine where the installer did not. Name a component to install just one, for
example omnesis service install collector on a machine that only syncs.
The other verbs are start, stop, restart,
status, logs (-f to follow, -n for the
number of lines) and uninstall, which removes only the units (omnesis uninstall
removes the rest of the install too); a bare omnesis service shows status.
stop returns only once the daemon has exited and released its stores, and the
service stays down until start or the next login on macOS, so offline
maintenance such as omnesis restore can rely on it.
Every verb accepts --config-dir, which points the unit at another
configuration directory, and --instance <name>, which manages a
named instance: a second, parallel gateway or collector whose unit names
carry that suffix. install also takes --env KEY=VALUE
(repeatable) to add environment variables to the unit. Re-running
install rewrites the unit from the flags you pass, so pass the same ones the
service was installed with, then omnesis service restart it.
For demonstrations, set OMNESIS_DEMO=1 on the gateway and restart it. The
portal hides the test-gateway label, release-update card, and source-page cards offering
mobile apps, the browser extension, and external agents. This changes only presentation;
sources, update checks, and feature gates continue to work normally. Unset the variable or
set it to 0 to restore the cards.
❯ omnesis service status
COMPONENT UNIT STATE PID gateway omnesis-gateway.service running 41250 collector omnesis-collector.service running 41283
❯ omnesis service restart gateway
Restarted omnesis-gateway.service
A configuration directory belongs to one gateway at a time. The gateway records its
ownership in gateway.lock before it opens any store. A second gateway pointed
at the same directory, such as a manual omnesis gateway serve beside the
service, waits about a minute for a predecessor that is still shutting down, then refuses
to start and names the process that owns the directory. Run a second gateway only against
its own configuration directory.
During shutdown the gateway refuses new requests and disconnects WebSocket clients; requests already in flight get a short window to finish. Clients reconnect once it is back.
A collector whose event loop stops turning for five minutes (alive, but stuck and syncing
nothing) ends itself so its service restarts it. It first writes
Event loop stalled and the stack it was stuck in to its error log, which is
the line to include when you report the problem.
A collector killed outright, for example by the system when memory runs out, is started again within seconds on Linux and about ten seconds later on macOS. A collector that exits cleanly, such as one waiting to be re-paired, stays stopped until you start it.
An error thrown and not caught ends the collector so its service restarts it. An error an
asynchronous task reported to no one does not: the collector writes
Unhandled rejection (continuing) to its error log and keeps syncing. Include
that line when you report the problem.
The generated services create files owner-only (umask 077). On Linux the
systemd units also get a private temporary directory, a read-only view of the system and
home directories apart from Omnesis's own paths, no new privileges and restricted address
families, and loginctl lingering is enabled so the daemons survive logout and
reboot. On macOS the logs go to ~/Library/Logs/Omnesis/. To run the daemons
against encryption at rest, or to run the gateway under a dedicated account, see
Security.
Full Disk Access (macOS)
On macOS the collector reads Apple data (Contacts, Messages, Notes, Calendar, Safari) that
the system gates behind Full Disk Access. There is no prompt for it and no installer can
grant it. omnesis service install collector prints the procedure with the
exact node binary that runs the daemon. From a terminal it also opens System
Settings at the Full Disk Access pane and reveals that binary in Finder, so you can drag
it into the list (--no-open skips this). Grant it, then restart the
collector.
Until access is granted, each affected source reports the same procedure as its error
instead of syncing nothing: on the portal's Sources page as one card per collector naming
the binary and the sources waiting on it, under omnesis status as an “Access
Required” section, and in omnesis doctor. A Node upgrade changes the binary's
path and signature, so grant access again after one.
Monitoring
Three tools answer “is it working”: omnesis status for sources,
omnesis doctor for everything else, and the service logs for detail. On the
portal's Sources page and in the mobile apps, anything worth knowing about a source
appears as a small icon beside the device it concerns: an information mark for a standing
note, a warning mark for something partly broken, an error mark for a source that has
stopped. Select the icon to read what it means and what to do.
Status
omnesis status prints one row per source: sync state, document count, index
coverage, last sync, and the ingested and indexed date ranges. It ends with the gateway's
version and a count of how the paired devices compare to it (see
Version compatibility). Pass -w
to keep it open as a live view.
❯ omnesis status
Omnesis Status (on disk: 2.4 GB) Source State Count Idx Size Synced Int Ingested Range Indexed Range ✓ gmail:maya@example.com synced 48,213 emails 100% 610.2 MB 2m ago 15m 03/04/19-06/07/26 03/04/19-06/07/26 ⟳ whatsapp:+15550100123 syncing 12,940 messages 98% 128.7 MB 30s ago 5m 11/01/21-06/07/26 11/01/21-05/07/26 ✓ apple-notes synced 1,082 notes 100% 14.1 MB 8m ago 30m 02/06/15-04/07/26 02/06/15-04/07/26 Gateway 1.4.0 · devices: 3 current, 1 behind
A source can sync successfully while its deletion detection is incomplete, so Omnesis may
miss items removed upstream. The portal, omnesis status and
omnesis doctor show such a warning with when it was first seen and how to
recover. It survives gateway restarts and clears only when the affected collector confirms
recovery.
When the gateway does not have the memory to keep its semantic search index, the output adds a Semantic Search Degraded block with the reason; see Semantic search is degraded.
Doctor
omnesis doctor is a read-only health check across the gateway, pairing,
models, source authentication, the versions of paired devices, the index, disk space,
configuration and the running process, with a fix next to each finding. It exits non-zero
only when something is actually blocking, so it is safe to script. Once the gateway has
checked for releases, it also says whether a newer stable release exists. By default it
includes this host's security checks (--no-security
skips them).
Keyword search and indexing work without an embedding model; semantic search needs one.
Doctor therefore fails models.embedder when the embedder is disabled, as
after omnesis model assign embedder disabled, or when its local model file is
missing, while documents are still indexed for keyword search. Its hint says how to
install or assign the model that restores semantic search.
The same report is in the portal under Debug → System → Health. A collector's own report covers its configuration, source access, disk, process, keyring and service; run it from Settings → Devices by expanding the collector and choosing Run under Health, or Run health checks for every collector at once.
From a terminal, omnesis doctor --device <name> prints one collector's
report and omnesis doctor --fleet prints every collector's (--json
for the raw entries). A request to an offline collector waits until it reconnects.
Gateway-only checks show as N/A in a collector's report, and every fix in it names the
collector it runs on.
A collector's source-access check opens each local source's inputs read-only, without
reading their contents or running a sync. Missing inputs, incomplete scans and timeouts
are reported as unverified rather than healthy, and sources with nothing local to check
show N/A. On macOS the permission belongs to the collector's executable, so a file your
terminal can read may still be refused to the collector. The portal's checks only read;
omnesis doctor --fix-permissions, run on the affected host, is what restores
owner-only file modes under its configuration directory.
Event-loop stalls
The gateway answers every request on one event loop, so work that holds it for a moment
makes every client wait. The gateway watches the loop from a separate thread and records
each stall of 250 ms or more with the work that caused it. A stall of a second or more is
written to the gateway log as event loop stalled 2200ms in <activity>,
where the activity is a request (GET /search), a background task or a device
message. Doctor warns when stalls of a second or more add up to ten seconds or more in an
hour, and names the activity behind most of it.
omnesis stalls ranks the activities by how long they blocked the loop (--window
sets the minutes to look back) and lists the CPU profiles the gateway captured. When long
stalls recur, it profiles itself for a minute and keeps a summary under
diagnostics/stalls/ in its configuration directory, at most one every 15
minutes and the newest five; gateway.stalls configures both. A summary holds
function names, source file paths and line numbers, never data. Include the
omnesis stalls output when you report a slow gateway.
Reading the calendar
Debug → Cognition → Timeline combines structured dates supplied by sources (Source record), interpretations recorded by the agent (Agent interpretation), and date expressions found in document text (Date mention). Source records and agent interpretations form the agenda under Timed, All day & due, and Activities & visits, with up to four entries per row within each day’s category. Narrower screens show fewer columns. Date mentions are grouped by document in a collapsed section, with possible deadline mentions counted separately. A date mention does not establish that an event happened or that an obligation belongs to you.
Filter by origin; this choice is remembered in your browser. Upcoming shows deadlines, expiries and reminders in the same responsive card grid. Open an entry to see why it appears on that date, its supporting documents and available grounding passages. Hover over origin and kind pills for explanatory tooltips, including Activity for a dated episode. Dates and times use your browser's timezone. An active status does not confirm that an entry is happening now.
Logs
omnesis service logs gateway -f follows the gateway's log: the journal on
Linux, files under ~/Library/Logs/Omnesis/ on macOS. Two environment
variables control logging: OMNESIS_LOG_LEVEL (debug,
info, warn or error; default info) and
OMNESIS_LOG_FILE, which also writes a rotated copy to that file. Set them on
a service with omnesis service install --env.
Configuration
Everything you can edit lives in one file, ~/.config/omnesis/omnesis.json,
owned by the gateway; collectors fetch their configuration from it. Edit it with
omnesis config get / set / edit, in the portal's
Settings → Config tab, or directly in an editor: the gateway watches the
file, and every path goes through the same schema validation. An invalid edit while the
gateway runs leaves the last good configuration in effect, and
omnesis doctor reports the failed load. An invalid file at boot stops the
gateway; it is never silently replaced with defaults.
While the gateway on this machine is stopped, including one that fails on start,
omnesis config get / set / edit /
ls work on the file directly under the same validation, and the changes apply
at the next start. OMNESIS.md in the same directory is yours rather than the
gateway's: the agent's standing instructions, in plain Markdown (see
The agent → Standing instructions).
omnesis self set --name <name> --email <address> --phone
<number>
records who you are (--email and --phone repeat) under
self in the file. The gateway uses it at start to build the person that
represents you in the people graph; omnesis self shows the current values.
In the portal every field says whether it is set in the file or falls back to a default,
an inherited value or unset behaviour. Edits in the Structured and Raw JSON views are
staged: Save shows a diff, and only confirming it writes
omnesis.json; leaving the page discards them. Clearing a field or choosing
Reset to default removes that override. List settings also offer
Set an explicit empty list where an empty list differs from the default,
and Set in config filters the view to your own overrides.
{
"dataRetention": { "maxAge": "2y" },
"activityRetention": { "maxAge": "90d" },
"sources": {
"default": { "syncInterval": "15m" },
"gmail:maya@example.com": { "syncInterval": "5m" }
},
"search": {
"params": { "resultLimit": 10 },
"boosts": { "typeBoosts": { "note": 1.2 } }
}
}
sources.default holds the settings every source falls back to. A key naming a
source type, such as gmail, overrides them for every account of that type,
and a key naming one source, such as gmail:maya@example.com, overrides both
for that source alone. Resolution is per field, so a type-wide
extractAttachments still applies to an account that only sets its own
syncInterval.
omnesis config set /sources/default/syncInterval 10m takes a JSON Pointer or
a dot-path; omnesis config edit opens the file in $EDITOR and
validates it on save.
search.params holds the ranking settings: how many candidates each search
method contributes, how many results come back, and how keyword and semantic matches are
weighed against each other. search.boosts.typeBoosts multiplies the score of
a whole document type (above 1 promotes it, below demotes it).
search.defaultFilters adds filters to every query; list filters combine with
the query's own, and a date range in the query wins. search.temporal controls
the lane that reads time phrases in a query (see
Search → Time in queries). The defaults suit most
corpora.
dataRetention.maxAge limits how old ingested source data may be;
maxAge under a sources entry overrides it for those sources, in
the same order as every other source setting. activityRetention.maxAge is
separate: it removes expired operational history and unpinned agent conversations in small
background batches, never data ingested from sources, and never pinned, running or pending
work. Without it, activity is kept forever. Deleted data frees space inside the databases
for reuse, but a database file may not shrink on disk.
gateway.snapshotAbsence controls how cautiously Omnesis deletes items that a
source stops listing. Some sources report what they still have rather than what was
deleted, and a failed read (a locked database, a lapsed permission) looks the same as
everything having been deleted. So a missing item is removed only after
minObservations syncs (default 3) over at least minAge (default
24h) agree it is gone. Raise either for a flaky source; the cost is that real deletions
take longer to show.
The collector reads the operating system's region to interpret phone numbers written
without a country code. macOS uses your regional setting; Linux prefers
LC_TELEPHONE. A headless or container collector can set
OMNESIS_PHONE_REGION to a two-letter country code such as GB;
restart the collector after changing it.
The portal's Settings → Config tab lists every other key with its current
value and description. Two worth knowing: gateway.pushWakeRetry tunes how
long the gateway keeps retrying a failed phone wake (about an hour by default), and
gateway.analyticsStreamRekeyMaxRows (default 100000) caps how
large an analytics table may be when a source switches to per-device mode while the
gateway runs; a larger table waits until you raise the limit and restart the gateway.
gateway.memoryLimitMb (or the OMNESIS_MEMORY_LIMIT_MB
environment variable) is how much memory the gateway allows itself. Unset, it is the
container's memory limit when the gateway runs under one, otherwise the host's physical
memory; the gateway logs the figure and where it came from at start. Set it when other
services share the host's memory, such as other containers in the same virtual machine.
The analytics engine's default memory ceiling is a quarter of the budget, and semantic
search keeps its index in memory only while it fits (see
Semantic search is degraded). The budget also sizes the gateway's
worker threads, each of which takes 60 to 250 MB: below 16 GB the gateway starts fewer
read and search workers, and it keeps at most one compute worker per 4 GB, so it stays
resident beside the rest of a small machine. gateway.ioConcurrency,
gateway.searchWorker.concurrency and gateway.cpuConcurrency set
the counts explicitly.
Models
Every AI capability in Omnesis is a role that you assign a model to. Search and ingestion work with no role assigned: without an embedder, search ranks on keywords alone. A feature that needs a role says so when it is missing.
Settings → Models also reports repeated failures for each capability's assigned model. After three consecutive failed requests, an amber warning card identifies the capability, the model, and the kind of failure, such as exhausted quota, rejected credentials, an unreachable backend, or a timeout. Audio the gateway cannot decode is the recording's fault, not the transcriber's, so it never counts toward this warning. The Settings navigation item and its Models entry show a warning triangle that leads to these details, on the portal and mobile apps. A successful request clears the warning automatically; choosing another model or changing the backend configuration clears the old model's failure state. Warnings survive a gateway restart and remain visible until there is evidence of recovery or the configuration changes.
Capabilities and their uses
Choose a capability under Settings → Models to read its purpose and assign a model. Assignments are independent: choosing a decision model does not assign the Agent that answers questions and processes Tell Omnesis notes. You can assign the same compatible model to several roles.
| Role | What it does |
|---|---|
embedder |
Embeds document chunks and queries: the semantic half of hybrid search. Without it, search still ranks on keywords. |
agent |
Powers the agent in the portal and mobile apps, and the agent
that prepares Answer results for external agents. It also handles Apple Watch Ask
requests and every stage of Deep Research, and reads and acts on notes you capture
with Tell Omnesis from the portal, apps or CLI: task changes, document research,
memory and questions. No open chat is needed. With no Agent model available, or
with agent.noteAgent set to false, notes are saved and
indexed but not acted on. See
Voice and quick capture.
|
privacy-reviewer |
Reviews every Answer result (/answer and MCP Answer) against your
privacy policy before it leaves Omnesis. With
no reviewer assigned, every Answer result is held for your approval.
|
transcriber |
Speech-to-text, so voice notes and audio become searchable. Without one, voice
notes keep a placeholder that says no transcriber is available, the conversation
sources that carry audio count the notes waiting in their notice on the Sources
page, and omnesis doctor warns.
|
ocr |
Extracts text from images and image-only attachments. |
decision |
Makes bounded choices and scores, including Apple Watch complication routing between Ask and Tell, and email-date filtering for time queries. See Decision model for uses, setup and fallbacks. |
Additional capabilities and uses require experimental mode and are described only under Experimental → Model capabilities.
Decision model
The decision role answers a bounded question: yes or no, a score, or one
choice. It selects a route or judges significance; the agent role handles the
requested work that follows.
-
Apple Watch complication: Ask or Tell. After transcription, the
decision model chooses whether your words need an answer or immediate action
(Ask) or should be saved as a note for later processing
(Tell). Explicit Ask and Tell actions and Siri shortcuts bypass this
choice. The setting
inference.dictation.useDecisionGateForWatchdefaults on; the iPhone exposes it as Use decision gate for Apple Watch complication. Without an available decision model, the complication offers Ask and Tell. If routing fails after Send, or the intent is uncertain, it falls back to Ask. The transcript is sent to the decision backend. See Apple Watch for the capture flow. -
Email dates in time queries. When
enrichment.dates.worthGateis on (off by default), the model judges whether an email is worth recording so time queries can leave out dates in marketing and newsletters. It receives the subject, sender and first 2,000 characters. Attachments inherit their parent email's verdict. Without the model, this filtering is skipped; the email stays indexed either way. See Documents and the index.
Assigning a decision model does not enable every use automatically; each flow keeps its
own controls. It is served by TypeSafe Jev, a cloud model, and requires
Allow cloud inference. Add its key under
Settings → Models → Decision model or with
omnesis backend key set typesafe, then assign
omnesis model assign decision typesafe/jev-1.13.0. The iPhone and Android
apps show the assignment; change it from the portal or terminal.
Backend support depends on the capability. Available backend families are:
-
Local GGUF models, downloaded with
omnesis model installinto the configuration directory'smodels/folder and run by the gateway, fully offline. - Any OpenAI-compatible HTTP server, with presets for OpenAI, Google, Mistral, Groq, Cerebras, Together, Fireworks, DeepSeek, NVIDIA, xAI, Meta, Moonshot AI, Regolo AI and OpenRouter.
-
Anthropic, assigned as
anthropic/<model>. Add the API key in Settings → Models; the gateway then lists every model that key can use. The list refreshes at start, when the key changes, hourly, and on Refresh model list. Until a refresh succeeds a small built-in list is offered, and a failed refresh keeps the last good one. -
Codex, assigned as
codex/<model>, which runs agent-class roles on a ChatGPT subscription through OpenAI's Codex runtime. Sign in withomnesis codex loginor the portal's Codex backend settings, where you can copy the one-time login code with the copy button beside it.omnesis codex statusshows the runtime and sign-in state. Codex serves theagent,privacy-reviewerand image-capableocrroles from one login; it has no embedding or transcription models. -
Claude Code, assigned as
claude-code/<model>, which runs on a Claude subscription through theclaudecommand installed and signed in on the gateway host. Omnesis never signs it in: runclaude auth loginon that host, then refresh the backend under Settings → Models → Backends (Add backend → Claude Code → Check again before it is listed), or withomnesis claude-code refresh.omnesis claude-code statusshows the installation, sign-in state and the models the CLI offers. Claude Code serves theagent,privacy-reviewerand image-capableocrroles from one login; it has no embedding or transcription models. Sign-in and isolation are covered in The agent → Claude Code.
By default inference stays on this machine: cloud backends, including Anthropic, Codex and Claude Code, and HTTP backends that resolve to remote addresses require your permission. In the portal, turn on Allow cloud inference under Settings → Models and confirm. Choosing a cloud model while this setting is off also asks for confirmation before saving the assignment. The permission applies to all configured remote inference backends on this gateway. Depending on their roles, they receive messages, conversation context, relevant Omnesis data, tool results, document chunks, search queries, images, or recorded audio.
Turn off Allow cloud inference in the same place to disable it. Changes
take effect without restarting the gateway. From the CLI, set
inference.allowRemoteInference: true, or pass --allow-remote to
backend add.
❯ omnesis backend add openai --key sk-... --allow-remote
✔ Backend openai added (https://api.openai.com) with API key
❯ omnesis backend test openai
✔ openai: reachable
❯ omnesis model assign agent openai/gpt-4o
✔ Assigned agent = openai/gpt-4o
❯ omnesis model status
Active embedder Nomic Embed Text v1.5 (Q8_0) [ready] (139.8 MB) transcriber Whisper Small (multilingual) [ready] … Cognition agent HTTP: gpt-4o [ready] System …
Personal vocabulary hints for transcription are on by default. To turn them off, set
inference.transcriptionVocabulary.enabled to false in
omnesis.json. The gateway learns a small vocabulary from indexed documents,
prioritizing distinctive names and terms from the current conversation and its people
across sources. Sent and received text both contribute. Recent source-verified words you
authored receive an additional relevance weight of 4 by default, configurable with
inference.transcriptionVocabulary.authoredWeight; setting it to
0 removes this bonus. Authored evidence uses original message or capture
dates and decays with a 90-day half-life, so editing or reindexing an old document does
not make its wording recent. WhatsApp and iMessage supply your own written message text
and captions. Marked voice transcripts do not reinforce their own recognition errors.
Legacy evidence without a known written origin supplies no authored bonus. Gmail supplies
conservative unquoted plain-text prefixes of sent messages whose sender matches the
account. Tell Omnesis supplies your own entries, excluding agent captures and retained
webpage content. Unsupported or uncertain authorship supplies no bonus. Contextual terms
are compared with their prevalence across the corpus, with smoothing to avoid exaggerating
evidence from sparse conversations. Automated and bulk-distributed evidence receives a
lower weight until ordinary documents independently corroborate the same term,
configurable through machineEvidenceWeight (default 0.15);
contextPriorDocuments controls contextual smoothing strength (default
10). Global rarity and contextual lift refine support without crowding out
established self-authored vocabulary; authoredRarityWeight defaults to
0.5 and authoredContextLiftWeight to 0.25. These
apply only to verified self-authored evidence. Ordinary global, person and conversation
evidence retains full rarity and contextual discrimination so broadly repeated terms
cannot gain unbounded frequency advantage over relationship vocabulary. Both settings
accept values from 0 (ignore that discriminator) to 1 (full
strength). These settings live under inference.transcriptionVocabulary. These
defaults are initial calibration choices; they do not establish improved speech accuracy
for every corpus. Existing WhatsApp archives are reprojected in bounded pages without
resetting media; historical Gmail and iMessage evidence is not automatically replayed.
Historical Tell Omnesis written projections are refreshed at gateway startup when enabled;
untouched transcripts are excluded, while later manual edits may contribute. Common
calendar words, compounds, structural chat noise and low-confidence near-common spellings
receive filtering or reduced weight, with safeguards for names and acronyms. Structurally
marked metadata, transcripts, Markdown block quotes and fenced code blocks are excluded,
and structured OCR layouts contribute their readable text. Learned terms need at least two
distinct supporting documents. Repetition within one document does not count as
corroboration, although copies stored as separate documents can still count. Configured
and contact-curated names for the current people supply separate identity hints. Linking a
person to a document does not itself count as an occurrence of their name. Vocabulary
builds in bounded background batches; transcription does not wait for a full build, and
waits at most three seconds for its hints before transcribing without them. When an
extraction update requires a rebuild, the gateway temporarily supplies no hints while it
clears the old dictionary, then repopulates it incrementally. Evidence and spelling
refreshes enroll bounded pages without clearing the available dictionary. The gateway's
local Whisper model uses these hints, and so does an HTTP transcription backend on the
gateway's own machine; a transcription backend on another machine never receives them.
Paired mobile apps with bulk corpus read access can also fetch a small dictionary for
on-device speech recognition, independently of the gateway dictation setting. Apps keep
hints in memory, refresh due hints in the background on foreground or status activity
after 30 minutes, and stop using them after 24 hours without a successful refresh.
Recording never waits for a dictionary request. Setting the flag to
false stops vocabulary computation and hint lookup; connected apps clear
cached hints when they observe the change. Pairing changes also clear the cache. Switching
the flag back on resumes the backlog. Vocabulary entries may remain after their source
documents are edited or deleted.
The local engine depends on the role. The embedder runs a GGUF model in the
gateway through node-llama-cpp, on the GPU through Metal on Apple Silicon. The
transcriber runs whisper.cpp in a separate process, so a crash in the native
code cannot take the gateway down; it uses the GPU through Metal on Apple Silicon and the
CPU elsewhere. The ocr role has three local runtimes:
apple-vision (macOS, with the Swift toolchain installed),
tesseract (with the tesseract binary installed), and
gguf, a llama.cpp vision model you supply, run through
llama-mtmd-cli with its model and projector paths set under
inference.ocr.gguf. Each image gets 120 seconds of OCR by default; for a
backend that needs longer on dense pages, set
inference.ocr.requestTimeoutSeconds. The gateway stops the backend at that
deadline, and also when the collector that asked stops waiting. When OCR keeps timing out,
collectors pause it for a few minutes. The agent role does not run a local
GGUF model; to keep it on your machine, point it at a local OpenAI-compatible server such
as Ollama, llama-server or vLLM.
To transcribe on an NVIDIA or other GPU, run an OpenAI-compatible transcription server on
it, such as whisper.cpp's whisper-server built with CUDA or Vulkan, speaches,
vLLM serving a Whisper model, or llama.cpp's llama-server with Qwen3-ASR. Add
it as a backend and assign the transcriber role to
<backend>/<model>. The gateway decodes each recording and sends
it to the server's /v1/audio/transcriptions endpoint as a 16 kHz WAV file. A
server on another machine needs remote inference enabled. Whichever engine runs it, a
recording is sent in parts, ten minutes for Whisper and the transcription endpoint and a
minute for an audio language model, and each part gets its own time limit sized from its
length, up to 30 minutes. A long recording therefore gets more time the longer it is, up
to six hours in all: about two hours of audio from Whisper on a CPU, or about half an hour
from an audio language model on a CPU. A server that stops answering is given up within
one part's time, and the gateway stops the work when the collector that asked stops
waiting.
A backend serves the transcriber role only if it implements that endpoint: a
chat or embedding server that merely lists a model with a speech-like name does not. When
the role is assigned to an HTTP backend, the gateway first asks it to transcribe one
second of audio. A backend that answers it cannot, because the endpoint is missing or the
model is unknown to it, is refused with its answer, in the portal and from
omnesis model assign; a backend that gives no answer, because it is still
loading its model, is assigned and asked again until it does. The Models page marks a
model the backend has refused, and omnesis model status prints the reason.
A speech model served only through a chat API, such as Qwen3-ASR behind Ollama or
llama-server, or an audio language model on vLLM, works too: when a backend has no
transcription endpoint the check sends the same audio as a chat completion, and a backend
that transcribes it is used that way, a minute of audio per request. The hosted
transcription APIs of OpenAI, Groq and Mistral serve the role with remote inference
enabled. To pin the protocol or the chunk length for a backend, set
transcription on it:
"inference": {
"backends": {
"ollama": {
"type": "http",
"url": "http://127.0.0.1:11434",
"transcription": { "protocol": "chat-audio", "maxChunkSeconds": 45 }
}
}
}
❯ whisper-server -m ggml-large-v3-turbo.bin --inference-path /v1/audio/transcriptions
❯ omnesis backend add whisper-gpu http://127.0.0.1:8080
✔ Backend whisper-gpu added (http://127.0.0.1:8080)
❯ omnesis model assign transcriber whisper-gpu/whisper-large-v3-turbo
✔ Assigned transcriber = whisper-gpu/whisper-large-v3-turbo
omnesis model assign covers every role, so the terminal and the portal's
Settings → Models tab configure the same set. Assigning
ocr to a Codex or Claude Code model sends images and rasterised PDF pages to
it, which needs remote inference enabled.
Changing the embedder re-embeds the corpus in the background while search
keeps using the existing vectors. omnesis index rebuild does the same under
the current model, for when existing vectors are known to be stale (--hard
drops them at once and searches by keyword until it finishes).
Reasoning settings
Reasoning models accept settings that trade answer quality against latency and cost, and every provider spells them differently. Omnesis does not guess them from model names. Instead it looks up the exact provider and model a role is assigned to and offers only the settings that model publishes. There are three kinds:
| Setting | Choices | Config key |
|---|---|---|
| Reasoning | On or off | reasoningEnabled |
| Reasoning effort |
The provider's named levels for that model, for example minimal,
low, medium, high
|
reasoningEffort |
| Reasoning token budget |
A number of thinking tokens within the model's published range; some providers
also accept -1 for no enforced budget
|
reasoningBudgetTokens |
For HTTP backends the list comes from
Models.dev, an open
catalog of models and their options per inference provider. The same model can offer
different settings on different providers, so the lookup uses the backend's provider: a
preset name, or a URL that matches a preset's default address. Omnesis then keeps only the
settings it knows how to send to that provider's API. Reasoning settings are offered for
OpenAI, Google, Mistral, Groq, Cerebras, Together, DeepSeek, NVIDIA, Moonshot AI and
OpenRouter; which of the three kinds appear depends on the provider and the model. For
Codex, the effort levels come from the installed Codex runtime's own model list. For
Claude Code, they come from the installed CLI's catalog and are passed to it as
claude --effort.
Anthropic, local GGUF and other OpenAI-compatible servers show no reasoning settings, and
neither does a model that is missing from the catalog. Such a model still works; it runs
with its own defaults. Only the agent and privacy-reviewer roles
take reasoning settings.
The gateway ships with a Models.dev snapshot, so the settings are available offline. When
Settings → Models or a model picker opens, the gateway checks for a newer
catalog if the one it has is more than a day old. It keeps the downloaded copy in the
models-dev/ folder of the configuration directory, and keeps using its last
good copy when the check fails or returns an incomplete catalog. Provider logos in the
model pickers come from the same catalog, fetched once through the gateway.
Change them in the portal or the apps
Open a role's card in Settings → Models in the portal, or in Configure Models in the iOS and Android apps. The card shows the settings the assigned model offers, labelled in the provider's terms. Model default, the starting choice for every setting, sends nothing, so the provider's own default applies. A change saves on its own a moment after you make it, and the role's card summarises what is saved, for example Effort high.
Some settings exclude each other, and the card enforces that as you choose. Turning reasoning off clears any effort or budget. Google accepts only one of the three at a time, and OpenRouter either an effort or a budget. If another device saved the same role while you were choosing, your change is refused and the card reloads the saved values.
Change them from the CLI
There is no dedicated command. The settings live in the configuration under
inference.modelSettings, one entry per role, naming the assignment they
belong to. Set one with omnesis config set:
❯ omnesis config set /inference/modelSettings/agent '{"assignment":"openai/gpt-5","values":{"reasoningEffort":"high"}}'
# back to the model default
❯ omnesis config set /inference/modelSettings/agent null
assignment must be exactly the value the role was given with
omnesis model assign, for example openai/gpt-5. Unlike the
portal, config set checks only the shape of the entry, not whether the model
offers the setting. Check a value against the choices in
Settings → Models before saving it this way.
Which model a setting applies to
Settings are saved per role and tied to the model that role had when they were saved. Two roles that use the same model keep separate settings. Assigning a different model to a role starts it from the model default; the previous model's settings are ignored, not carried over.
A saved setting is never dropped quietly. If a catalog update removes an effort level or
narrows a budget range, the role's card says the saved choice is no longer offered: pick
another value or Reset to model default. Until then, the role's requests
to an HTTP backend fail with an error naming the setting, rather than running with
different reasoning than you chose. A positive token budget also raises the reply ceiling
to the budget plus 4,096 tokens; if the backend's declared
maxOutputTokens (below) is lower, requests fail with an error saying how many
tokens the budget needs.
Token limits and timeouts
OpenAI-compatible servers do not report token limits. If you know them, declare them under
the backend's modelLimits, keyed by the exact model id it serves:
{
"inference": {
"backends": {
"local-agent": {
"type": "http",
"url": "http://127.0.0.1:8080",
"agentTimeoutMs": 600000,
"modelLimits": {
"example-model": {
"maxInputTokens": 28672,
"contextWindowTokens": 65536,
"maxOutputTokens": 32768
}
}
}
}
}
}
maxInputTokens limits the request, contextWindowTokens limits
the request plus the reserved output, and maxOutputTokens caps the reply.
Omnesis applies only an entry whose key matches the assigned model exactly and never
guesses limits from model names. Without a limit it can report the tokens used but cannot
reject an oversized request before sending it.
Without a declared maxOutputTokens, agent requests ask for a 4,096-token
reply, or 16,384 once a model has shown it reasons at length. A reply cut off before any
answer is retried once with up to 32,768 tokens when maxOutputTokens allows.
Requests time out after two minutes, or ten for a model that reasons at length;
agentTimeoutMs overrides both for an HTTP backend.
When an OpenAI-compatible backend answers HTTP 429 (rate limited), Omnesis retries up to
twice, honouring Retry-After when the wait fits within 15 seconds and the
request's deadline. Answer requests run unattended, so their agent and reviewer calls
retry up to four times with up to three minutes of waiting, enough for a per-minute quota
to reset. A lower maxOutputTokens can also reduce what a provider reserves
per request.
Codex runtime and capacity
Omnesis manages a Codex runtime version tested with the installed release. In
Settings → Models → Backends, Refresh model list asks
the installed runtime for its models, and Update runtime installs the
tested version on the gateway host. Updating keeps the gateway's ChatGPT sign-in and every
assignment; new Codex work pauses while running turns finish, and a replacement that fails
verification is never activated. Newly available models are listed, but no assignment
changes on its own. omnesis update does not touch the Codex runtime.
# preview the exact action without changing the runtime
❯ omnesis codex update --dry-run
# update the Codex runtime on the gateway host
❯ omnesis codex update
# non-interactive shells need explicit consent
❯ omnesis codex update --yes
When OMNESIS_CODEX_COMMAND points at your own Codex executable, Omnesis
treats the runtime as externally managed: update it yourself, restart the gateway, then
refresh the model list. If the operating system denies starting the runtime, check execute
permissions and directory access for the configured executable.
Codex reserves separate capacity for three interactive turns, four background turns, and
two inference calls by default, and queues the rest. Tune this with
inference.codex.interactivePoolSize,
inference.codex.backgroundPoolSize (1–32), and
inference.codex.inferencePoolSize (or the
OMNESIS_CODEX_INTERACTIVE_POOL_SIZE,
OMNESIS_CODEX_BACKGROUND_POOL_SIZE, and
OMNESIS_CODEX_INFERENCE_POOL_SIZE environment variables, which win) and
restart the gateway. More slots use more memory, and every process shares the same ChatGPT
allowance.
A Codex turn that receives no model-stream activity for five minutes is interrupted,
releasing its runtime slot. Time spent executing Omnesis tools is excluded. Set
inference.codex.turnIdleTimeoutMs (1000–3600000 milliseconds), or
OMNESIS_CODEX_TURN_IDLE_TIMEOUT_MS to override it, and restart the gateway.
This limits silence rather than the total duration of an active turn.
Claude Code runtime and capacity
Omnesis does not install or update Claude Code. It needs Claude Code 2.1.259 or later and
finds the claude command on the gateway's PATH or where the
official installers put it: ~/.local/bin/claude,
~/.claude/local/claude, /opt/homebrew/bin/claude,
/usr/local/bin/claude or /usr/bin/claude. Set
OMNESIS_CLAUDE_CODE_COMMAND to use a different executable. Update it with
Claude Code's own updater, claude update, then refresh the backend;
omnesis update does not touch it. Omnesis turns off the CLI's background
auto-updater inside its own turns.
Every Claude Code turn is its own process, admitted per lane: up to three conversation turns at once, one background turn, and two single-shot calls such as privacy reviews and OCR. The rest queue. A turn started from inside another turn's tool, such as a sub-agent, is admitted on separate capacity for its nesting depth, so it never waits behind its parent. Every process shares the same Claude subscription's usage limits.
When a role uses Claude Code, omnesis doctor reports
models.claude-code: whether the CLI is installed, supported and signed in.
Troubleshooting
Start with omnesis doctor: it names most problems and the fix for each. Then
check sources, the daemons and their logs.
❯ omnesis doctor
# source state and indexing progress
❯ omnesis status
# confirm the daemons are running
❯ omnesis service status
# inspect the component that reported the problem
❯ omnesis service logs gateway -f
❯ omnesis service logs collector -f
| Symptom | Likely cause | Where to fix it |
|---|---|---|
| The installer prints log lines and exits instead of the welcome banner | The gateway did not become healthy | Fix what the log reports and run the installer again; it keeps what is installed |
omnesis status shows Semantic Search Degraded, or
the gateway keeps restarting while it builds its search index
|
The gateway does not have the memory for the semantic search index | Below |
| The gateway exits at start, naming a store | Another process holds the store, or the file is damaged | Below |
| A collector stopped syncing and its unit is stopped, not failed | The gateway revoked or no longer accepts its pairing | Bringing a revoked device back |
| A sync reports a gateway source-contract check timeout | The gateway did not answer its compatibility health check in time | The collector retries this read up to four attempts before failing the sync. Check the gateway logs for stalls or resource pressure, then use Sync now. |
| Apple sources on a Mac report “Access Required” | The collector's node binary lacks Full Disk Access |
Full Disk Access |
| A source asks you to sign in again, or its sign-in expired | Expired credentials, or the sign-in flow timed out | Below and Managing sources |
Google sign-in stops with access_denied or says the app has not
completed verification
|
Your Google OAuth client is still in testing and the account is not one of its test users | Publish the consent screen in your Google Cloud project, or add the account as a test user; see Google's OAuth client |
| “Can't reach this page” after approving Google sign-in | The browser is on a different machine from the collector | Collector setup |
| A Docker collector cannot complete an OAuth sign-in | Something else holds a callback port (3000–3003) | Docker limits |
| Search finds exact words but not related meaning | No embedder assigned, or documents not yet embedded | Models and Search |
The CLI reports Unauthorized on every command |
An OMNESIS_TOKEN in the environment overrides the saved token, and it
is revoked or belongs to another gateway
|
Unset it or replace it with a current token |
| The phone works at home but not away | The gateway is reachable only on the home network | Remote access |
| Phone data (health, location, calls) does not arrive | Permissions, background limits, or a stalled upload | When data doesn't arrive |
| Notifications never reach the phone | Push transport not configured or not registered | Notification status |
| A phone, agent or remote collector stops connecting after a certificate renewal | It pinned the old certificate's fingerprint | Clients that pinned the old certificate |
A collector reports Gateway upgrade required |
The collector is newer than the gateway | Updating |
| A device shows unsupported | Its build is older than the gateway supports | Version compatibility |
Semantic search is degraded
Semantic search keeps an index of every embedded passage in memory, so its size grows with
the corpus: about 1.4 times the size of the passages' vectors. The gateway loads or builds
it only when it fits in the gateway's memory budget with room left for everything else,
and saves and releases it if memory runs short later. Until it is back, search answers
from keywords alone: omnesis status shows
Semantic Search Degraded with the reason,
omnesis doctor warns under Index, and the gateway log has a
semantic search degraded line. Indexing goes on, and passages indexed
meanwhile join the semantic index when it returns.
The budget is gateway.memoryLimitMb when set, otherwise the container's
memory limit, otherwise the host's physical memory (see
Configuration). Give the gateway more memory: raise that
setting or the container's limit, or free memory on the host. Then restart the gateway. On
a host whose memory other services share, set gateway.memoryLimitMb to what
the gateway may really use, so it backs off before the system runs out. The in-memory copy
of the keyword index is not released when memory runs short; on a small host, set
search.bm25.memoryIndex to false to rank keywords from disk (see
Search).
The index is saved as it is built and as it changes, so a gateway that stops or is killed while building or updating it continues from the last save on its next start rather than building it again.
A store will not open
A gateway that exits during start names the store it could not open in
omnesis service logs gateway, quoting SQLite or DuckDB. For the analytics
store the two common messages are a conflicting lock (another process holds it: a gateway
still shutting down, a duplicate gateway, or a tool with the file open) and a damaged
block, which DuckDB reports as a key mismatch. Neither is a reason to delete the file: the
analytics store holds rows no other store can rebuild. Keep it and its .wal,
and restore from a backup or recover the file.
A gateway that finds another process owning its configuration directory says so and exits the same way.
A collector has stopped
A collector that notices the gateway refusing a credential that used to work records why
and stops, rather than retrying forever. omnesis service status on that host
reports it and prints both halves of the recovery: the
omnesis devices repair command to run on the gateway host, and the
omnesis pair command to run on the collector. On the gateway it shows as
needs-pairing in omnesis devices list.
Source errors and sign-in
The Sources page and omnesis status show each source's own fix for
authentication, permission and collector problems.
omnesis sources debug <id> shows a source's sync position and counts,
omnesis sources reauth <provider>:<account> signs an account in
again, and omnesis sources resync <id> rebuilds a source's data from
the start; use resync only when that is needed.
omnesis sources legacy-rows <id> lists, claims or drops the rows of a
shared analytics table that no account has claimed. Pages captured by the browser
extension cannot be resynced, because nothing holds their past copies to fetch again. See
Managing sources for every source action.
Re-authentication must sign in to the same account; add another account as a separate
source. A sign-in flow expires after 15 minutes without activity
(gateway.timings.authFlowTtl), and an expired or cancelled flow must be
started again.
CLI at a glance
The omnesis command groups below each have a home in these docs.
omnesis --help and omnesis <command> --help are the
complete, authoritative reference for every command and flag.
| Commands | What they do | Covered in |
|---|---|---|
search, show, lookup, recent,
trail, people, delete
|
Find and read documents and people | Search |
sql, analytics |
Query analytics tables | Search → SQL |
edges, graph |
Inspect links between documents |
Search → Beyond search;
--help
|
sources, creds, note |
Add and manage sources and provider credentials, from a terminal or a script; capture a note | Available sources; from a script |
devices, pair, tokens, whoami
|
Pair, list, revoke and repair devices; manage tokens | Setup |
connect, access, answer, agent
|
Connect external agents, set access levels, ask through Answer | Agents & MCP |
push |
Phone notification credentials and tests | Notifications |
service, status, doctor,
health, stalls
|
Run and check the daemons | Services, Monitoring |
config, self |
Edit configuration; set your own name, emails and phone numbers | Configuration |
model, backend, codex,
claude-code, index
|
Assign models, add inference backends, rebuild the vector index | Models |
secure, keyring, tls |
Encryption at rest and certificates | Security |
backup, restore, export,
update
|
Back up, restore, export and update | Backup & updates |
uninstall |
Remove Omnesis from this machine, all of it or the parts named | Uninstall |
gateway, collector |
Run a daemon in the foreground (what the services start) | Services |