Running a Nodofi AI Worker
Run an AI model on your own machine with Ollama and make it available over the relay — to Studio's Agentic AI and Assistant, robot missions, Flows and published services. No public address, no open port.
Overview
The AI Worker is a small Node.js program that runs next to Ollama.
It connects out to a Nodofi relay under a name (for example JozieAILLM2) and answers prompts sent
to that name. Ollama only ever talks to the worker on localhost; it is never exposed to the internet or a browser.
Studio / a Flow / a robot ──▶ relay ──▶ AI Worker "JozieAILLM2" ──HTTP──▶ Ollama (gemma4)
◀── answer ◀──
What uses it
| Who | What it asks | Worker name |
|---|---|---|
| Studio's Agentic AI | Its planner: which Flow or robot skill to run next (Agentic AI) | JozieAILLM2 — the Studio planner agent |
| Studio's AI Assistant | Code help in the editor (Assistant settings → Ollama) | NodofiOllamaCoder by default |
| Robot missions, cloud planner | Each step of a mission (Missions on the robot) | the name set in Mission on a robot |
| Published services | JozieAI.ask(name, prompt, callback) | any |
| Flows | The Call relay worker block with { "function": "prompt", "prompt": "…" } | any |
To serve both the planner and the Assistant, run two copies with different WORKER_NAMEs; they can
share one Ollama.
Install & run
- Install Ollama and pull a model:
ollama pull gemma4(ollama listshows what you have). - Extract the download (or use the
ollama-coderfolder of the Studio repository) and runnpm install(Node.js 18+). - Copy
.env.exampleto.env; setRELAY_URLandWORKER_NAME. - Run
npm start. It printsConnected to <relay> — joining as "<name>". - In Studio's Agentic AI pane set the same Relay URL, Studio planner agent and Planner model, and try a goal.
Run it on whichever machine has the GPU (a desktop, a server, a Jetson); it only needs outbound access to the relay.
Start at boot
# /etc/systemd/system/nodofi-ai-worker.service
[Unit]
Description=Nodofi AI Worker
After=network-online.target
Wants=network-online.target
[Service]
WorkingDirectory=/opt/nodofi-ai-worker
ExecStart=/usr/bin/node src/worker.js
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now nodofi-ai-worker. On Windows, use a service wrapper such as NSSM, or Task Scheduler.
Configuration (.env)
| Setting | Default | Description |
|---|---|---|
RELAY_URL | required | The relay to join — the same one Studio, your Flows and robots use. |
WORKER_NAME | NodofiOllamaCoder | The name callers reach it by; unique on the relay. |
OLLAMA_HOST | http://127.0.0.1:11434 | Where Ollama runs. Keep it on localhost unless you protected a remote Ollama yourself. |
OLLAMA_MODEL | gemma4 | The model when a request doesn't name one (Studio's planner and Assistant always name theirs). |
Protocol
A request is a relay message to the worker's name; the reply goes back to the sender.
function | Fields | Reply |
|---|---|---|
prompt, chat | prompt (text, or [{ role, content }]), model, format ("json": Ollama's JSON mode), think (false: no reasoning pass) | { result: true, content, thinking? } |
generate | prompt, model, think | { result: true, content } |
embedding | prompt, model (e.g. embeddinggemma) | { result: true, embedding } |
const reply = await NodoRequestAsync('JozieAILLM2', {
function: 'prompt', functionType: 'async',
prompt: 'Summarize: …', model: 'gemma4', think: false
}, 'https://relay.nodofi.com');
console.log(reply.content);
Errors reply { result: false, message }. With a thinking model such as gemma4,
think: false is several times faster; Studio's planner also sends format: "json" so its replies are always valid JSON.
Monitoring
On a Studio Design map, add an AI Worker component with the worker's name as its Address / ID and press Monitor: it is green while the worker is connected to the relay and red when it isn't — see Monitoring your network.
Troubleshooting
The Agentic AI says the planner "did not answer"
The worker isn't running, or it joined a different relay or name than the one set in the Agentic AI pane. Its log shows joining as "…".
"Could not reach Ollama"
Ollama isn't running at OLLAMA_HOST, or the model isn't pulled (ollama list).
"Relay rejected this worker name"
That name belongs to a registered node on the relay; choose another WORKER_NAME.
Slow answers
Use a smaller model or a GPU machine, and send think: false with thinking models.