GAIA — the flagship agent
GAIA is the agent a new user meets first. One agent handles the everyday work you’d otherwise spread across four: talking things through, answering questions about your own documents, poking at a spreadsheet, and reading the web. It remembers across sessions, and every inference runs locally on your machine through Lemonade.GAIA is built on top of the Chat agent — same document Q&A prompt, same
RAG discovery, same session persistence. What it adds is breadth: the data, web, and
filesystem capabilities Chat leaves off by default, plus a home for add-on skills.
What it does
- Conversation with memory — facts you tell it persist to an on-device store and come back in later sessions. It can also search your own past conversations.
- Document Q&A over your files — index a file or a whole folder, then ask questions. PDF, Word, PowerPoint, and plain text; the prompt tells the agent to name which document each fact came from rather than blending sources.
- Data exploration — load a CSV or Excel file into a local SQL scratchpad table and query it, so “which region grew fastest” becomes a real query rather than a guess from a truncated preview.
- Web research — search the web, fetch and read pages, download files.
- Files — read, search by name or content, and walk directory trees inside your allowed scope. Writing and editing are available too, behind an explicit confirmation (see Tools that need your approval).
- Images — describe a local image or answer a question about it, using the local vision model. It can also generate one from a description with local Stable Diffusion; that swaps the resident model, so the reply after an image takes an extra moment while the chat model reloads.
- Skills — short playbooks loaded into the agent’s own prompt. One ships always-on; the rest are opt-in. See Skills below for what this release ships.
Requirements
Install Lemonade, download the model, and start the server:
/query endpoint rejects any request naming a provider other than lemonade with HTTP 400.
Install and launch
- One command (npx)
- From source
@amd-gaia/gaia is published on the Agent Hub, and the terminal UI (gaia tui) now boots straight into this agent — there is nothing to browse or pick.Check it’s ready before you ask it anything
GET /v1/gaia/init is a read-only preflight: it probes Lemonade, compares its version against the 10.2.0 floor, and confirms the model is downloaded. It never pulls or loads a model.
hint naming the fix — Lemonade unreachable, Lemonade too old, or model not downloaded. Liveness alone is GET /health, which never touches the model server.
A 401 here means the sidecar wants a caller token —
/v1/gaia/* requires one, while
/health and /version don’t. That’s the normal state for the sidecar the daemon
spawns. See Authenticating your requests.Tool surface
The default construction registers 71 tools — the 55 of the Chat agent’sfull profile, plus 7 skill-library tools, 4 code-search tools, 3 image-generation tools, remember_skill_lesson, and the load_tools escape hatch. Grouped by what they’re for:
That count is what the agent can do, not what it sees at once: per-turn tool selection sends the model a subset of the registry on any one call, and
load_tools is the escape hatch it calls mid-turn to pull in a bundle the selector missed. No capability is lost either way.
run_shell_command is restricted to a read-only command allowlist (ls, cat, grep, find, stat, df, uname, and similar) and rate-limited. Anything that writes, installs, or executes an arbitrary binary is refused.
Image generation costs you a model reload. Drawing a picture pulls Stable Diffusion into Lemonade and evicts the resident chat model, so the first reply after an image waits for the chat model to load again. The trade is worth it on the flagship, which is general-purpose; the Chat agent’s doc and file profiles leave the sd tool mixin off for exactly that reason.
Tools that need your approval
Seven tools mutate your machine and are gated behind an explicit confirmation:write_file, edit_file, run_shell_command, execute_python_file, notify_desktop (on Windows it spawns a PowerShell child to draw the notification), and — because installing a skill writes third-party code under ~/.gaia/skills and removing one deletes it — install_skill and remove_skill. Everything else — reading, indexing, querying, web fetching, memory — runs without asking.
File access scope
The agent’s file, document, and data tools are confined to a set of allowed paths. By default that set is your home directory. That’s the honest scope for a personal document agent — “ask questions about my files” means your files — and it is still a real boundary: system directories, program files, and other users’ home directories fall outside it and are refused. The check runs against the resolved path, so a symlink pointing out of the allowed set doesn’t get around it; you get an explicitAccess denied to path: error naming both the requested and the resolved path.
The allowed set is not the whole story, and shouldn’t be treated as one. Two denylists apply inside it, because “in scope” and “safe” are different questions:
- Secrets are never read back.
.env,id_rsa,credentials.json,.netrc, any.pem/.key, and everything under~/.ssh,~/.aws,~/.gnupg,~/.kubeare refused on read even when they sit in an allowed directory — otherwise “summarise this folder” is a credential exfiltration primitive. - Files that run on their own are never written. Shell startup files (
.bashrc,.zshrc,.profile), PowerShell profiles,~/.config/autostart/*, systemd user units,LaunchAgents, and anything inside a repo’s.git/— hooks and config alike. Writing to one of those isn’t editing a document, it’s arranging for the agent’s output to execute at your next login.
In v0.1.1 this is a construction-time setting only — the packaged sidecar exposes no
flag or environment variable for it, so narrowing the scope means embedding the agent in
your own Python process.
Memory
Memory is on by default and lives on-device. The agent writes facts you ask it to remember, recalls them in later sessions, and can search prior conversations.forget and update_memory let you correct or drop what it holds.
The mechanism, storage location, and how to disable it are covered in the Memory guide.
Skills
Agent Skills are short playbooks an agent loads into its own prompt, grouped into named skill sets — exactly one set is active per launch. GAIA is built to host them: its own bundled skill directory is the highest-precedence discovery root, so a skill shipped with the agent wins over a same-named user copy. One skill ships enabled:gaia-voice. It is declared in the manifest’s always-on skills: list, so it is in the prompt on every call — 676 tokens of it, and it registers no tools. It isn’t a task recipe but the agent’s honesty floor: don’t claim work you didn’t do, don’t present empty output as a result, don’t substitute a near-miss and report success. Those failures spoil an answer whatever the task is, which is why it can’t sit in a bundle you have to opt into.
No skill set loads by default, and v0.1.1 declares none. Loading several skill bodies into every prompt costs tokens and shrinks the room left for an answer, and no eval has measured that trade for this agent yet. The manifest’s skill-set declarations ship commented out; enabling them is uncommenting two blocks, with no code change.
Once a release declares sets, you select one at launch:
Driving it over HTTP
The agent runs as a sidecar — a self-contained HTTP service the GAIA daemon spawns, health-checks, and tree-kills. It binds127.0.0.1:8141 by default and is never exposed on a LAN interface: it speaks for your documents and your memory.
/query implements the shared canonical SSE contract (API version 2.12), so every stream is terminated by exactly one final or error event — the guarantee that lets the daemon relay and the terminal UI treat every GAIA agent identically. A few details worth knowing when you write a client:
- You mint the
run_id, not the server. Cancellation keys off it, so it has to exist before the request rather than arrive in the stream. - Conversation context is pushed in the body, never pulled. Pass
session_idtoo — the agent persists its indexed-document set per session, and without it the agent forgets a document between the turn that indexed it and the next question. - Set
can_answer_questions: falsefor one-shot runs. With nobody there to answer, the agent resolves ambiguity itself instead of parking on a question that reads as a hang. - Idle streams emit
: keepalivecomments every 10 seconds so a long tool call doesn’t look like a dead connection. - Confirmation-gated tools end the run with a refusal — see Tools that need your approval.
Authenticating your requests
Binding to loopback is not access control — this agent has shell and file tools, so an open port would let any page you visit drive it. Three checks guard the sidecar:- A per-session bearer token. Every
/v1/gaia/*request must carryAuthorization: Bearer <token>; without it you get 401. The process that spawned the sidecar supplies the token, either asGAIA_GAIA_SIDECAR_TOKEN_FILE— a path to a0600, owner-only file, so the secret never sits in the environment — or directly asGAIA_GAIA_SIDECAR_TOKEN. When the GAIA daemon runs the agent, it mints the token and uses the file channel. - A loopback
Hostallowlist. AHostheader that isn’t127.0.0.1,localhost, or::1is 400 — this is what defeats DNS rebinding. - Origin rejection. A request carrying a non-loopback browser
Originis 403. Non-browser clients send noOriginand are unaffected.
GET /health, GET /version, and GET /v1/gaia/version skip the token — they’re the probes a host polls before any token is in play, and none of them exposes your data. Host and Origin still apply to them.
If neither token variable is set, the sidecar starts with the token check off and says so loudly in its log; Host and Origin stay enforced. That’s a local development convenience — a sidecar you started by hand — not something to build on. Full details, including how to supply a token when you spawn the sidecar yourself, are in the package’s SPEC.md §5.4.
Troubleshooting
”Local Lemonade Server is not reachable”
The model server isn’t running. Rungaia init to install and start it, or point the agent at one you already have with LEMONADE_BASE_URL. GET /v1/gaia/init tells you which of the three preconditions failed (reachable / version / model present) rather than making you guess.
”The model … is not downloaded”
”Access denied to path”
The file resolves outside the allowed paths — by default, outside your home directory. Move the file inside the scope, or construct the agent with anallowed_paths list that covers it (see File access scope).
The sidecar won’t start
The daemon redirects the sidecar’s output to~/.gaia/agents/gaia/logs/sidecar-<port>.log. Check that file first; a failed start also surfaces the log tail in the error. gaia daemon agents shows id, mode, pid, port, and contract version for everything currently running.
Limitations (v0.1.1)
- No skill sets declared — the skill machinery is wired and tested, and
gaia-voiceships always-on, but no set does; see Skills. - Narrowing file scope requires embedding the agent — no sidecar flag for
allowed_pathsyet. - No server-side confirmation flow — over
/query, all seven confirmation-gated tools end the run with a refusal instead of prompting over the stream. - Image generation evicts the chat model — the SD model has to be resident to draw, so the first reply after an image waits for the chat model to reload. Ask for pictures at a natural pause, not mid-thread.