bai-agent
bai-agent answers Backend.AI questions from a WebUI checkout — the one you
are in, or the data copy bai-agent init synced — and points the user at the
WebUI page for what it found. The workflow contract is the generated
BAI-AGENT block: in a checkout it is in CLAUDE.md, and an installed copy
of this skill carries it as references/agent-block.md. Read it there, it is
not repeated here. This file is the parts the CLI cannot tell you: when to log
in, when to answer versus link, and which neighbour owns what.
Preflight
Run bai-agent doctor --brief once, from wherever you already are — never
cd first. It is the one-step preflight: checkout-vs-synced-data and
session/auth in one line each. Fall back to bai-agent doctor --json only
when you need a specific field out of it. Run bai-agent whoami only when
the auth check is warn.
The workflow contract is already loaded: in a checkout it is the BAI-AGENT
block in CLAUDE.md; installed, it is references/agent-block.md. Read
whichever applies — don't cat it unless the block is absent — and don't grep
for a CLAUDE.md outside a checkout; there isn't one.
When whoami says auth_required (exit 3):
- Get the endpoint and the account from the
webui-connection-info skill
in a checkout; elsewhere the endpoint is the one init recorded (doctor
prints it). Never ask the user for a password, and never put one in a
command.
- Browser on this machine:
bai-agent login --endpoint <url>, then confirm on
the /cli-login page it opens. That page is the WebUI's; in a checkout it
is the dev server, elsewhere the endpoint's own origin — pass
--webui <origin> when the UI lives somewhere else.
- Browser anywhere else, or a tunnelled/HTTPS tab:
bai-agent login --paste --endpoint <url> and paste the session id the page reveals.
bai-agent logout when you are done with a borrowed session.
search, docs show, schema show and explain need no session at all.
A "what does X mean" question never requires logging in — go straight to it.
Answer, or link
| The user wants |
Do this |
| to understand a status value ("what does status X mean") |
Try explain <Type>.<field>=<VALUE> first — e.g. explain ComputeSessionNode.status=PENDING, explain UserNode.status=before-verification. Fall back to explain <Type>.<field> (no value) or docs show for a term or field in general. |
| to understand a term or field |
explain (meaning) or docs show (the manual). Answer in the words the UI uses, and cite the deployed-docs url the CLI returned. |
| a count, a list, a value |
Start every live query from bai-agent cookbook <root field> (or --list) — never search the filesystem for the cookbook; a schema_mismatch error names the entry to read. Adapt it, never invent a shape. Summarise the rows; do not paste the raw envelope. |
| to see it, or act on it |
Give the webui_url (or webui_path) query already annotated onto the row, under data.links, so the user can open it themselves. Say so when the link carries requires — admin / superadmin / projectAdmin is the role that page gates on, so hand it over as "…, which is admin-only" rather than as a link that may bounce them; no requires means any signed-in account can open it. When you post-process the --json envelope yourself, also print data.links — the link must reach the user. Never describe a click path you could report directly. If data.links is empty for a result, say the resource has no addressable page — do not compose a path by hand, not even for a field whose rows are plainly the caller's own (myKeypairs gets no link because the only keypair list is the admin-only credentials tab); but a row carrying webui_link_hint instead means the id you selected cannot build one, so re-run selecting row_id. When several rows share a name, pick the link by id, never by name. |
| something destructive |
Give them the hint page from the refusal and stop. A mutation_refused (exit 4) is the answer, not an obstacle to route around. |
explain prints MISSING for a piece nothing curates. Say it is not documented
and offer the SDL entry — never fill the gap from memory. If the answer would be
better as a curated sentence, that is a mappings/<Type>.yaml change, not a
guess at runtime.
Neighbours
| Skill |
Owns |
Not this |
webui-connection-info |
Which dev server is up, its URL and port, the API endpoint, the test credentials. |
It does not read data — it tells you where to point login. |
backend-ai-guide |
Backend.AI architecture and product Q&A with no live data: what Sokovan is, how the agent talks to the manager. |
The moment the question is about this deployment's data or a schema field's meaning, it is bai-agent. |
docs-lead |
Writing and maintaining the user manual, terminology, translations, screenshots. |
Reading the manual to answer a question is bai-agent search / docs show. |
bai-cli (backend repo) |
./bai, the backend's own REST CLI, inside a backend.ai checkout. |
In this repo use bai-agent; ./bai does not exist here. |
Gotchas the CLI cannot warn you about
- Search in English UI terms. The index is English-only. A Korean or
Japanese query is normalised through the i18n stores, not translated, so
"Resource Group" beats "scaling group" and both beat a paraphrase.
- One pagination mode per connection.
first+after XOR last+before
XOR limit+offset. The local SDL accepts a mix; the *V2 connections
reject it at runtime (the checkout's .claude/rules/graphql-pagination.md).
--allow-mutation is not a bypass. The field must also be on the CLI's
mutation allow-list (src/mutation-allowlist.ts in the package). Widening
that list is a reviewed PR, never an in-session decision.
- Session detail views share one URL.
/session?sessionDetail=<id> is a
drawer, the only addressable surface — there is no per-row session link to
offer beyond that.
The block's RULES apply beyond these (session file, empty data.links, no
React source in a synced copy, never cd before doctor, and more) — read
them there rather than restated here.
Cookbook
bai-agent cookbook --list names every entry; bai-agent cookbook <n> and
bai-agent cookbook <root field> print one, prose and document. That command
is how you read it — it locates the file itself, so never search the
filesystem for a path and never cat one. The entries are 11 documents that
validate against the SDL, one per resource, plus the allow-listed mutation and
the refused destructive one; a test re-validates them, so a stale one fails CI,
not a user. Maintainers edit
packages/backend.ai-agent-cli/skill/references/query-cookbook.md.
Keeping this in sync (maintainers, in a checkout)
Re-run pnpm --filter backend.ai-agent-cli build && pnpm run bai-agent init --features agents --write after any change to the CLI, and re-sync the
BAI-AGENT block in CLAUDE.md. This directory ships in the npm package
as-is, so an installed copy updates on the next bai-agent init; it is not
a repository-level skill — install it with bai-agent init --skill. Rules
are linked from here, never copied: if you find
yourself restating what manifest --json, the block or --help already
says, delete it instead.
1---2name: bai-agent3description: Answer a Backend.AI question, or do a Backend.AI task, from this checkout with the `bai-agent` CLI — the manual, the GraphQL schema, the i18n stores and the live manager. Trigger on: what a Backend.AI concept, field or status value means ("what does session status PENDING mean", "what is a resource group", "what does this field mean"), "find it in the manual", "search the docs", "query the manager", "run a GraphQL query", "how many sessions are running", "show me my sessions / folders / agents / users", "give me the WebUI link for this session", "where do I see that folder in the WebUI", or "bai-agent". Use `backend-ai-guide` instead for platform architecture with no live data, and `docs-lead` for writing the manual rather than reading it.4---56# bai-agent78`bai-agent` answers Backend.AI questions from a WebUI checkout — the one you9are in, or the data copy `bai-agent init` synced — and points the user at the10WebUI page for what it found. The workflow contract is the generated11`BAI-AGENT` block: in a checkout it is in `CLAUDE.md`, and an installed copy12of this skill carries it as `references/agent-block.md`. Read it there, it is13not repeated here. This file is the parts the CLI cannot tell you: when to log14in, when to answer versus link, and which neighbour owns what.1516## Preflight1718Run `bai-agent doctor --brief` once, from wherever you already are — never19`cd` first. It is the one-step preflight: checkout-vs-synced-data and20session/auth in one line each. Fall back to `bai-agent doctor --json` only21when you need a specific field out of it. Run `bai-agent whoami` only when22the auth check is `warn`.2324The workflow contract is already loaded: in a checkout it is the `BAI-AGENT`25block in `CLAUDE.md`; installed, it is `references/agent-block.md`. Read26whichever applies — don't `cat` it unless the block is absent — and don't grep27for a CLAUDE.md outside a checkout; there isn't one.2829**When `whoami` says `auth_required` (exit 3):**3031- Get the endpoint and the account from the **`webui-connection-info`** skill32 in a checkout; elsewhere the endpoint is the one `init` recorded (`doctor`33 prints it). Never ask the user for a password, and never put one in a34 command.35- Browser on this machine: `bai-agent login --endpoint <url>`, then confirm on36 the `/cli-login` page it opens. That page is the WebUI's; in a checkout it37 is the dev server, elsewhere the endpoint's own origin — pass38 `--webui <origin>` when the UI lives somewhere else.39- Browser anywhere else, or a tunnelled/HTTPS tab: `bai-agent login --paste40 --endpoint <url>` and paste the session id the page reveals.41- `bai-agent logout` when you are done with a borrowed session.4243**`search`, `docs show`, `schema show` and `explain` need no session at all.**44A "what does X mean" question never requires logging in — go straight to it.4546## Answer, or link4748| The user wants | Do this |49| --- | --- |50| to understand a status value ("what does status X mean") | Try `explain <Type>.<field>=<VALUE>` first — e.g. `explain ComputeSessionNode.status=PENDING`, `explain UserNode.status=before-verification`. Fall back to `explain <Type>.<field>` (no value) or `docs show` for a term or field in general. |51| to understand a term or field | `explain` (meaning) or `docs show` (the manual). Answer in the words the UI uses, and cite the deployed-docs `url` the CLI returned. |52| a count, a list, a value | Start every live query from `bai-agent cookbook <root field>` (or `--list`) — never search the filesystem for the cookbook; a `schema_mismatch` error names the entry to read. Adapt it, never invent a shape. Summarise the rows; do not paste the raw envelope. |53| to see it, or act on it | Give the `webui_url` (or `webui_path`) `query` already annotated onto the row, under `data.links`, so the user can open it themselves. **Say so when the link carries `requires`** — `admin` / `superadmin` / `projectAdmin` is the role that page gates on, so hand it over as "…, which is admin-only" rather than as a link that may bounce them; no `requires` means any signed-in account can open it. When you post-process the `--json` envelope yourself, also print `data.links` — the link must reach the user. Never describe a click path you could report directly. If `data.links` is empty for a result, say the resource has no addressable page — do not compose a path by hand, not even for a field whose rows are plainly the caller's own (`myKeypairs` gets no link because the only keypair list is the admin-only credentials tab); but a row carrying `webui_link_hint` instead means the id you selected cannot build one, so re-run selecting `row_id`. When several rows share a name, pick the link by `id`, never by name. |54| something destructive | Give them the `hint` page from the refusal and stop. A `mutation_refused` (exit 4) is the answer, not an obstacle to route around. |5556`explain` prints `MISSING` for a piece nothing curates. Say it is not documented57and offer the SDL entry — never fill the gap from memory. If the answer would be58better as a curated sentence, that is a `mappings/<Type>.yaml` change, not a59guess at runtime.6061## Neighbours6263| Skill | Owns | Not this |64| --- | --- | --- |65| `webui-connection-info` | Which dev server is up, its URL and port, the API endpoint, the test credentials. | It does not read data — it tells you where to point `login`. |66| `backend-ai-guide` | Backend.AI architecture and product Q&A with no live data: what Sokovan is, how the agent talks to the manager. | The moment the question is about *this* deployment's data or a schema field's meaning, it is `bai-agent`. |67| `docs-lead` | Writing and maintaining the user manual, terminology, translations, screenshots. | Reading the manual to answer a question is `bai-agent search` / `docs show`. |68| `bai-cli` (backend repo) | `./bai`, the backend's own REST CLI, inside a `backend.ai` checkout. | In **this** repo use `bai-agent`; `./bai` does not exist here. |6970## Gotchas the CLI cannot warn you about7172- **Search in English UI terms.** The index is English-only. A Korean or73 Japanese query is normalised through the i18n stores, not translated, so74 "Resource Group" beats "scaling group" and both beat a paraphrase.75- **One pagination mode per connection.** `first`+`after` XOR `last`+`before`76 XOR `limit`+`offset`. The local SDL accepts a mix; the `*V2` connections77 reject it at runtime (the checkout's `.claude/rules/graphql-pagination.md`).78- **`--allow-mutation` is not a bypass.** The field must also be on the CLI's79 mutation allow-list (`src/mutation-allowlist.ts` in the package). Widening80 that list is a reviewed PR, never an in-session decision.81- **Session detail views share one URL.** `/session?sessionDetail=<id>` is a82 drawer, the only addressable surface — there is no per-row session link to83 offer beyond that.8485The block's RULES apply beyond these (session file, empty `data.links`, no86React source in a synced copy, never `cd` before `doctor`, and more) — read87them there rather than restated here.8889## Cookbook9091`bai-agent cookbook --list` names every entry; `bai-agent cookbook <n>` and92`bai-agent cookbook <root field>` print one, prose and document. That command93is how you read it — it locates the file itself, so never search the94filesystem for a path and never `cat` one. The entries are 11 documents that95validate against the SDL, one per resource, plus the allow-listed mutation and96the refused destructive one; a test re-validates them, so a stale one fails CI,97not a user. Maintainers edit98`packages/backend.ai-agent-cli/skill/references/query-cookbook.md`.99100## Keeping this in sync (maintainers, in a checkout)101102Re-run `pnpm --filter backend.ai-agent-cli build && pnpm run bai-agent init103--features agents --write` after any change to the CLI, and re-sync the104`BAI-AGENT` block in `CLAUDE.md`. This directory ships in the npm package105as-is, so an installed copy updates on the next `bai-agent init`; it is not106a repository-level skill — install it with `bai-agent init --skill`. Rules107are linked from here, never copied: if you find108yourself restating what `manifest --json`, the block or `--help` already109says, delete it instead.