@amd-gaia/gaia 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,93 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@amd-gaia/gaia` are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this package adheres
5
+ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.1] — unreleased
8
+
9
+ First working release. `npx @amd-gaia/gaia` is now the single command that gets a
10
+ user running GAIA: it fetches and verifies everything GAIA needs and drops them
11
+ into the terminal UI. Before this there was no packaged path at all — the flagship
12
+ agent had to be run from a repo checkout with a Python environment, and reaching
13
+ the terminal UI meant building it from source.
14
+
15
+ ### Added
16
+
17
+ - **`503` from `/query` at session capacity.** When every retained session
18
+ slot is busy and none is idle enough to evict, starting a new session
19
+ returns `503` with the reason in `detail` — retryable, distinct from a
20
+ bug-shaped `500`. See SPEC §5.2.
21
+ - **Per-turn skill-body selection.** A loaded skill stays loaded, but its body
22
+ only renders in the prompt on turns whose query matches its description; the
23
+ rest collapse to a one-line menu the model re-activates with `load_skill`.
24
+ `GAIA_DYNAMIC_SKILLS=0` turns the selection off, `GAIA_DYNAMIC_SKILLS_TAU`
25
+ overrides the match threshold, and an embedder outage disables it for the
26
+ session (every body renders — capability is never lost to a failed match).
27
+ - **`gaia run` (the default command)** — resolves the host platform, fetches and
28
+ SHA-256 verifies both binaries, then launches the terminal UI and propagates its
29
+ exit code. Arguments after a bare `--` are forwarded to the TUI verbatim.
30
+ - **Dual-binary delivery.** The package installs two published artifacts: the
31
+ frozen agent sidecar (`gaia-agent`), published by this package's own release,
32
+ and the terminal UI (`gaia-tui`), which is the published **`terminal-hub`**
33
+ component. The TUI is consumed, not rebuilt — it is byte-for-byte the binary a
34
+ full GAIA install runs as `gaia tui`, so an npm user and a core user cannot end
35
+ up on terminal UIs that behave differently. A second build under this package's
36
+ own lane would have been the same bytes at a different version under a third
37
+ naming convention, and the two would have drifted.
38
+ - **`binaries.lock.json` `schemaVersion` 3.0** — a component-keyed checksum
39
+ manifest where **each component carries its own `componentVersion`, `baseUrl`
40
+ and `platforms`**. Component-first rather than the email agent's flat `binaries`
41
+ map because the two differ in every dimension: hub lane, version, and platform
42
+ coverage (terminal-hub covers arm64 Linux and arm64 Windows; the PyInstaller
43
+ sidecar does not). A single shared base URL cannot address two lanes, so a
44
+ `1.x`- or `2.x`-shaped lock is rejected at load with an error naming the schema.
45
+ - **Terminal-hub artifact naming is handled in data.** That lane names its Windows
46
+ builds `gaia-win-x64.exe` / `gaia-win-arm64.exe`, while platform keys come from
47
+ `process.platform` and say `win32`. The lock keeps the `win32-*` key and carries
48
+ the hub's spelling in `filename`, so nothing branches on platform to construct a
49
+ URL. The mapping is asserted on both sides (`TUI_ARTIFACT_NAMES` in
50
+ `src/platform.ts` and in the lock generator) because a wrong name there is not a
51
+ build failure anywhere — it is a 404 on a user's first run.
52
+ - **Mandatory SHA-256 verification.** Every download is hashed and compared
53
+ against the lock before it is written. A mismatch deletes the download and
54
+ raises `IntegrityError` naming expected vs actual. A placeholder hash blocks the
55
+ fetch before any network call. There is no flag that relaxes either.
56
+ - **`gaia fetch`** — download and verify without launching; prints JSON. Supports
57
+ `--component` and `--platform` for cross-platform staging in CI.
58
+ - **`gaia serve`** — run the agent sidecar alone on `127.0.0.1:8141` for
59
+ integrators who want the REST surface without a daemon or a UI. Health-polls
60
+ `GET /health`, checks the contract version, and tree-kills on exit. Port `4001`
61
+ is refused.
62
+ - **`gaia version`** — prints, per component, its version, the URL it is fetched
63
+ from, and its platform matrix.
64
+ - **Programmatic exports** — `fetchAll`, `startSidecar`, `shutdown`, `runTui`, the
65
+ platform helpers, and the typed error classes, for embedding GAIA in another
66
+ app.
67
+
68
+ ### Notes
69
+
70
+ - The sidecar is installed into `~/.gaia/agents/gaia/`, the GAIA daemon's own
71
+ cache directory. The daemon spawns and supervises the sidecar; putting an
72
+ already-verified binary where it looks turns its fetch into a cache hit instead
73
+ of a second large download. `run` therefore does not spawn a sidecar itself —
74
+ the terminal UI reaches agents through the daemon relay and never holds a
75
+ sidecar token, so a second process would only contend for the port. `serve` is
76
+ the direct path for callers who do want to own it.
77
+ - The TUI is installed as `gaia-tui`, never as `gaia`, so it cannot shadow the
78
+ `gaia` bin shim npm places on `PATH` — the terminal-hub artifact itself is named
79
+ `gaia-<platform>`, which is why the lock separates `filename` from `executable`.
80
+ - Because the TUI comes from the `terminal-hub` lane, this package cannot be
81
+ released until that component is published at the version the lock pins. The
82
+ release fails loudly naming the required version; it never falls back to
83
+ building its own TUI. Each terminal-hub artifact is additionally cross-checked
84
+ against the hub's own server-side SHA-256 before its hash enters the lock.
85
+ - Requires Node.js 18+ (built-in `fetch`), a running Lemonade Server for
86
+ inference, and the `gaia` Python CLI on `PATH` for the daemon the TUI starts.
87
+ - The sidecar has no arm64 Linux or arm64 Windows build. On those platforms the
88
+ run stops with an error naming the platform and the supported set rather than
89
+ launching a UI with no agent behind it.
90
+ - `gaia_agent` 0.1.1 has no caller-auth token, so unlike
91
+ `@amd-gaia/agent-email` this package mints and sends none.
92
+ - Tracks sidecar contract `apiVersion` **2.12**; a differing major raises
93
+ `VersionMismatchError`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (C) 2024-2025 ADVANCED MICRO DEVICES
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,202 @@
1
- # @amd-gaia/gaia — placeholder
1
+ # @amd-gaia/gaia
2
2
 
3
- This `0.0.0` publish exists only to create the package so a **trusted publisher
4
- (OIDC)** can be configured on npmjs.com. npm cannot create a package from OIDC,
5
- so the first version has to be published with a token.
3
+ One command gets you a working GAIA:
6
4
 
7
- Nothing here is usable. The real CLI ships from `0.1.0` onward, published from
8
- `.github/workflows/release_agent_gaia.yml` with provenance.
5
+ ```bash
6
+ npx @amd-gaia/gaia
7
+ ```
8
+
9
+ That fetches the two binaries GAIA needs — the agent sidecar and the terminal UI —
10
+ verifies both against a checksum manifest that ships inside this package, and drops
11
+ you into the terminal UI. No Python to install, no repo to clone, no build step.
12
+ Everything runs locally on your machine; nothing you type or index leaves it.
13
+
14
+ The terminal UI you get here is the published **`terminal-hub`** component — the
15
+ exact same binary a full GAIA install runs as `gaia tui`, not a separate build. So
16
+ however you arrive at the terminal UI, it behaves identically.
17
+
18
+ ## What it actually does
19
+
20
+ 1. **Resolves your platform** — `win32-x64`, `darwin-arm64`, `darwin-x64`,
21
+ `linux-x64` (plus `linux-arm64` / `win32-arm64` for the terminal UI).
22
+ 2. **Reads `binaries.lock.json`**, the checksum manifest published with this exact
23
+ package version. It records, per binary, which hub lane it comes from and what
24
+ it must hash to.
25
+ 3. **Downloads and SHA-256 verifies both binaries.** A hash that does not match is
26
+ a hard failure — the download is deleted and the run stops. There is no
27
+ "continue anyway" path and no unverified fallback.
28
+ 4. **Launches the terminal UI**, which brings up the GAIA daemon and the agent
29
+ sidecar and hands you the chat. Its exit code becomes ours.
30
+
31
+ ## Requirements
32
+
33
+ - **Node.js 18+** (for the built-in `fetch`).
34
+ - **[Lemonade Server](https://amd-gaia.ai/docs/reference/dev)** running locally —
35
+ it hosts the model the agent thinks with. GAIA tells you if it isn't up.
36
+ - The `gaia` Python CLI on `PATH` for the daemon the terminal UI starts. Install it
37
+ with `curl -fsSL https://amd-gaia.ai/install.sh | sh` (Windows:
38
+ `irm https://amd-gaia.ai/install.ps1 | iex`).
39
+
40
+ ## Supported platforms
41
+
42
+ The terminal UI is Go and cross-compiles everywhere. The agent sidecar is a frozen
43
+ Python build, produced on the machine it targets, and **has no arm64 Linux or arm64
44
+ Windows build**. On those two platforms `npx @amd-gaia/gaia` stops with an error
45
+ naming your platform and the ones that do work — it will not start a UI with no
46
+ agent behind it.
47
+
48
+ | Platform key | Agent sidecar | Terminal UI |
49
+ | -------------- | :-----------: | :---------: |
50
+ | `win32-x64` | ✅ | ✅ |
51
+ | `darwin-arm64` | ✅ | ✅ |
52
+ | `darwin-x64` | ✅ | ✅ |
53
+ | `linux-x64` | ✅ | ✅ |
54
+ | `linux-arm64` | — | ✅ |
55
+ | `win32-arm64` | — | ✅ |
56
+
57
+ `npx @amd-gaia/gaia version` prints this matrix, plus the version and source URL of
58
+ each binary, for the release you have installed.
59
+
60
+ ## Commands
61
+
62
+ ```
63
+ gaia [run] [options] [-- <tui args>] Fetch + verify both binaries, then launch the TUI
64
+ gaia fetch [options] Download + verify only; print JSON and exit
65
+ gaia serve [options] Run the agent sidecar alone (REST API, no TUI)
66
+ gaia version Print the lock manifest and this host's platform
67
+ gaia help Show help
68
+ ```
69
+
70
+ Anything after a bare `--` goes to the terminal UI untouched:
71
+
72
+ ```bash
73
+ npx @amd-gaia/gaia -- --debug
74
+ ```
75
+
76
+ Common options:
77
+
78
+ | Flag | Meaning |
79
+ | --------------------- | ------------------------------------------------------------- |
80
+ | `--base-url <url>` | Override the download base URL from `binaries.lock.json` |
81
+ | `--cache-dir <dir>` | Where to cache the terminal UI binary |
82
+ | `--sidecar-dir <dir>` | Where to install the agent sidecar (default `~/.gaia/agents/gaia`) |
83
+ | `--platform <key>` | Fetch for another platform (`fetch` only) |
84
+ | `--force` | Re-download even when a verified binary is already cached |
85
+ | `--port <n>` | Sidecar bind port for `serve` (default `8141`) |
86
+
87
+ Set `DEBUG=gaia` for download, spawn, and sidecar output on stderr. Diagnostics
88
+ never touch stdout, which the terminal UI owns.
89
+
90
+ ## Where things land
91
+
92
+ | What | Path |
93
+ | --------------- | ---------------------------------------- |
94
+ | Agent sidecar | `~/.gaia/agents/gaia/gaia-agent[.exe]` |
95
+ | Terminal UI | `~/.gaia/npm-cache/gaia-<version>/gaia-tui[.exe]` |
96
+
97
+ The sidecar goes into the GAIA daemon's own cache directory on purpose: the daemon
98
+ is what spawns and supervises it, and it does its own SHA-256 check on the way. By
99
+ putting an already-verified binary there we save a second download rather than
100
+ racing one.
101
+
102
+ The terminal UI is installed as `gaia-tui`, **never** as `gaia` — a file named
103
+ `gaia` in a cache directory would shadow the `gaia` shim npm puts on your `PATH`.
104
+
105
+ ## Ports
106
+
107
+ | Service | Port |
108
+ | ------------- | --------------------------------- |
109
+ | Agent sidecar | `8141` on `127.0.0.1` |
110
+ | GAIA daemon | assigned at start, recorded in `~/.gaia/host/instance.json` |
111
+
112
+ Port **4001 is reserved repo-wide** and is refused with an error if you pass it.
113
+ Both services bind loopback only — this agent speaks for your documents and memory
114
+ and has no business on a LAN interface.
115
+
116
+ ## Running the sidecar on its own
117
+
118
+ `gaia serve` skips the terminal UI and gives you the REST surface directly, for
119
+ integrating GAIA into your own app:
120
+
121
+ ```bash
122
+ npx @amd-gaia/gaia serve --port 8141
123
+ curl http://127.0.0.1:8141/health
124
+ ```
125
+
126
+ It waits for `GET /health`, checks the contract version, and tears the whole
127
+ process tree down on Ctrl+C. See [`SPEC.md`](./SPEC.md) for the endpoints.
128
+
129
+ ## Programmatic use
130
+
131
+ ```ts
132
+ import { randomUUID } from "node:crypto";
133
+ import { fetchAll, startSidecar, shutdown } from "@amd-gaia/gaia";
134
+
135
+ const { sidecar } = await fetchAll(); // both binaries, SHA-256 verified
136
+ const proc = await startSidecar({ binaryPath: sidecar.binaryPath });
137
+
138
+ const sessionId = randomUUID(); // reuse across the whole conversation, see below
139
+
140
+ const res = await fetch(`${proc.baseUrl}/v1/gaia/query`, {
141
+ method: "POST",
142
+ headers: { "content-type": "application/json" },
143
+ body: JSON.stringify({
144
+ query: "summarize my notes",
145
+ run_id: randomUUID(),
146
+ session_id: sessionId,
147
+ context: [],
148
+ }),
149
+ });
150
+
151
+ await shutdown(proc);
152
+ ```
153
+
154
+ `/v1/gaia/query` streams Server-Sent Events terminated by exactly one `final` or
155
+ `error`. `fetchAll()` also returns the TUI's path if you would rather launch that.
156
+
157
+ **Reuse the same `session_id` for every turn in a conversation.** It is what
158
+ lets a document you had it index, or a skill you had it load, survive to the
159
+ next question — drop it (or mint a new one per call) and the agent still
160
+ answers, but it forgets everything from the previous turn. See
161
+ [`SPEC.md` §5.2](./SPEC.md#52-session_id-and-agent-retention) for the retry
162
+ and eviction behavior.
163
+
164
+ Every failure throws a typed error (`IntegrityError`, `PlatformError`,
165
+ `HealthTimeoutError`, `VersionMismatchError`, `BinaryNotFoundError`) with a message
166
+ that names what failed and what to do about it.
167
+
168
+ ## Where the binaries come from
169
+
170
+ The two binaries ship from two different places, and `binaries.lock.json` records a
171
+ version and a source URL for each:
172
+
173
+ | Binary | Published as | Built by |
174
+ | ------------- | ----------------------------------------- | -------------------------------- |
175
+ | Agent sidecar | the `gaia` agent, at this package's version | this package's release |
176
+ | Terminal UI | the `terminal-hub` component, at its own version | the core GAIA release |
177
+
178
+ The terminal UI is **consumed, not rebuilt**. It is byte-for-byte the `gaia tui`
179
+ binary a core install ships, so there is no second copy that could lag behind or
180
+ behave differently — which is the entire reason it is sourced this way.
181
+
182
+ ## Integrity
183
+
184
+ `binaries.lock.json` is the single source of truth for what gets downloaded and
185
+ what it must hash to. The release pipeline regenerates it from the artifacts
186
+ actually being served — the sidecars it just published, and the terminal-hub
187
+ artifacts it downloaded and cross-checked against the hub's own recorded hashes.
188
+
189
+ Between releases the lock carries `PENDING-replace-with-real-sha256` placeholders.
190
+ **A placeholder blocks the fetch outright** — before any network call — so an
191
+ unverifiable binary can never be downloaded, let alone executed. If you need to run
192
+ against a locally built binary, build it yourself and point the lifecycle helpers
193
+ at it directly; the fetcher will not be talked into it.
194
+
195
+ ## Links
196
+
197
+ - Guide: <https://amd-gaia.ai/docs/guides/gaia>
198
+ - Technical reference: [`SPEC.md`](./SPEC.md)
199
+ - Changes: [`CHANGELOG.md`](./CHANGELOG.md)
200
+ - Issues: <https://github.com/amd/gaia/issues>
201
+
202
+ MIT licensed. © 2024-2026 Advanced Micro Devices, Inc.