Leviathan & AI
<!-- GENERATED by ops/tools/skill-sync — do not edit by hand. Run pnpm skills:sync. -->
<!-- GENERATED by ops/tools/skill-sync — do not edit by hand. Run pnpm skills:sync. -->
Leviathan & AI — what you can do
/admin/d/ai · pillar ai
Program the agent - personas, reasoning maps, the tools it may call, MCP servers and skills.
Fetch this, never remember it
These change per install and per release. Call for them - a list written here would be a future lie.
| What | Call | Why |
|---|---|---|
| every tool that can be called here | GET /api/adapters/tools | the set is whatever this deployment loaded plus whatever apps are installed - it differs per install |
| which providers are available and which can use tools | GET /api/providers | availability depends on which keys and SDKs this install has; a missing key is not a missing feature |
| what the OPEN page currently offers | list_catalogs | the live capability registry is ephemeral by design - it is the globals plus the one page you are on |
| this operator's own MCP servers | GET /mcp/hosted | composed tool counts and compose warnings are computed per request, not stored |
How to actually do things here
Written by hand, because the order and the traps are the part no file can derive.
Create a chatbot the user can talk to
- Personalities.
list_personasfor what exists,select_personato open one. set_persona_fieldwrites the name and system prompt;set_providerchooses the model lane.bind_toolbankgives it server tools;bind_mapattaches the rules it must follow.save_personapersists - it is the only tool on this page that writes.
Trap: The per-persona tool policy (capabilities: {mode, tools}) is enforced SERVER-side when the turn runs, never in the widget - the widget is what builds the list it sends, so a widget filtering its own list is worth nothing. mode:"all", an unknown mode, and no policy at all are all identity.
Give the agent a tool it does not have yet
- Check first: every adapter this install loaded is ALREADY a callable tool.
GET /api/adapters/tools- if the name is there, skip to the last step. - Otherwise Function Calls: write the CONTRACT (name, description, and a JSON-Schema
parameters) and the BINDING (executor: {kind, ref, config}). - Test it in place before wiring it anywhere.
- Toolbanks: group the names into a bank. Personalities:
bind_toolbank. A bot holds NAMES, not definitions.
Trap: [critical] Not every executor kind binds in every host. A chatbot lane injects the adapter, action, grid-cell and integration runners ONLY - so mcp-tool, module-export and fabric bind to null for a bot and the tool silently does nothing, while the same row works from a workflow. Check where it will run before choosing a kind.
Stop the agent doing something
- Persona-wide: set the capability policy on the bot (
allowordenywith a list of tool names). - Rule-wide: Reasoning Maps.
add_ruleswith atextand awhy, so the model can apply the rule instead of pattern-matching it. - A map can also narrow the toolbox with its own tool policy, which applies to server tools too.
save_map, thenread_compiled_mapto see exactly what the model will be told.
Trap: Maps are injected AFTER the persona, so a rule can override a habit the persona described. Screen-bound maps fail CLOSED without a read check - the maps collection is member-writable, which makes it the prompt-injection lane.
Run a coding agent on the user's own project
- Register the project first:
POST /api/projectswith{name, kind}. A sandbox project is scaffolded for them; a local folder needs an explicit path and is refused outright on a hosted install. - Pick a provider that can actually use tools. Ask
GET /api/providersrather than assuming. POST /api/coding/runswith{message, projectId, provider}. It answers 202 with a run id and never blocks.- Follow it on
GET /api/coding/runs/:id/stream, or read it later under Runs.
Trap: [critical] A provider without tool support answers in prose and writes NO FILES, which reads exactly like a model that chose not to act. Shell access is off by default on a local project and must be turned on per project. A run with no key answers 402 - buy or bring one.
Let an app the user is building call Leumas capabilities
- The app declares what it needs:
permissions: ["adapters:<system>.<fn>"]on itsdefineLeumasApp. - The operator grants it at install. The facade then exposes EXACTLY those functions and nothing else.
- A sandboxed app calls out through the plugin proxy; a first-party one gets the facade directly.
- The reverse direction is free: an app's own actions become adapter functions, functioncalls and MCP tools from the same declaration.
Trap: An ungranted capability is ABSENT from the context object, not refused - so the failure looks like "undefined is not a function", not like a permission error. That is deliberate: it stops an app probing what an operator holds.
Tabs
Every one is a real URL. A tab with its own section below carries a real job.
| Tab | Path | Group | What it is for |
|---|---|---|---|
personalities | - | The agent | Who answers - provider, model, prompt, voice, tools, memory and the capability policy, one row per persona. |
reasoning-maps | - | The agent | The rule-sets a persona thinks with, and which surfaces each applies on. |
consensus | - | The agent | Groups of models that deliberate, cross-examine and vote, with a separate chairman. |
consensus (index) | - | The agent | Groups of models that deliberate, cross-examine and vote, with a separate chairman. |
consensus/chat | - | The agent | Talk to a whole panel at once. |
consensus/runs | - | The agent | What the panels decided, and how they voted. |
functioncalls | - | Its tools | Every tool that can be called, its argument contract, and what actually executes it. |
functioncalls (index) | - | Its tools | Every tool that can be called, its argument contract, and what actually executes it. |
functioncalls/capabilities | - | Its tools | What is registered LIVE right now versus what has merely been seen this session, plus the per-persona policy. |
functioncalls/demos | - | Its tools | A page that registers sample client tools so the mechanism can be watched working. |
toolbanks | - | Its tools | Named groups of functioncalls, so a persona is handed a set rather than a list. |
mcp | - | Its tools | Publish a selection of tools outward as a hosted MCP server that other agents can call. |
mcp (index) | - | Its tools | Publish a selection of tools outward as a hosted MCP server that other agents can call. |
mcp/gateway | - | Its tools | The whole install exposed as one server, for a client that wants everything. |
mcp/selectors | - | Its tools | Which tools a server actually exposes - selectors, not a copied list. |
skills | - | Its tools | Saved procedures an agent follows when a task matches. |
research | - | How it thinks | Ask a question and let it search, summarize and reflect until it has an answer. |
research (index) | - | How it thinks | Ask a question and let it search, summarize and reflect until it has an answer. |
research/runs | - | How it thinks | Past research runs and what they found. |
inventor | - | What it makes | One sentence to a manufacturable product - enclosure, board and firmware, cross-checked against each other. |
inventor/brief | - | What it makes | The sentence, turned into requirements. |
inventor/plan | - | What it makes | The plan across all three disciplines, editable before anything is built. |
inventor/mechanical | - | What it makes | The enclosure and the physical design. |
inventor/electronic | - | What it makes | The board. |
inventor/software | - | What it makes | The firmware and the software interfaces. |
inventor/integrate | - | What it makes | The cross-checks that prove the three halves fit each other. |
inventor/runs | - | What it makes | Past inventions and their stage output. |
flux | - | What it makes | The hardware workspace - circuit boards and firmware sketches, as projects. |
codex | - | What it makes | The coding agent, pointed at the user's own projects. |
games | - | What it makes | Build and play multiplayer 3D games on the Leumas engine. |
runs | - | What it did | What an agent actually did - runs, their events and their cost. |
runs (index) | - | What it did | What an agent actually did - runs, their events and their cost. |
runs/conversations | - | What it did | The threads those runs belong to; fork one to branch it. |
runs/local | - | What it did | Chat transcripts read off this machine rather than the server. |
Tabs in focus
personalities - Personalities
Who answers - provider, model, prompt, voice, tools, memory and the capability policy, one row per persona.
Read with: list_personas | get_persona | list_catalogs
Write with: select_persona | set_persona_field | set_provider | bind_toolbank | bind_map | save_persona
list_personas, thenselect_persona- everything else edits the selected draft.- Set fields, provider, toolbanks and maps in any order.
save_persona.
Trap: Only save_persona writes; every other tool moves a draft. Create and delete are deliberately absent from the tool set - they are the operator's.
reasoning-maps - Reasoning Maps
The rule-sets a persona thinks with, and which surfaces each applies on.
Read with: get_map_overview | list_rules | read_compiled_map | list_known_surfaces
Write with: add_rules | set_rule | remove_rule | set_map_surfaces | set_tool_policy | save_map
get_map_overview, thenlist_rules- never edit a map you have not read.add_rules; give each awhy, which is what lets a model apply it rather than match it.set_map_surfacesto bind it to screens;set_tool_policyto narrow the toolbox with it.save_map, thenread_compiled_mapto see the actual text.
Trap: A map bound to a surface is dropped entirely when no read check is supplied. That is fail-closed on purpose.
functioncalls - Function Calls
Every tool that can be called, its argument contract, and what actually executes it.
Read with: GET /api/adapters/tools
Trap: [critical] The schema key is parameters. input, inputSchema, schema and args are dropped on the way to the model, which then sees a tool it cannot pass anything to - and every guard still passes.
functioncalls/capabilities - Function Calls → Capabilities
What is registered LIVE right now versus what has merely been seen this session, plus the per-persona policy.
Read with: list_catalogs
Write with: add_rule
Trap: The live registry is EPHEMERAL by design - a page registers its tools on mount and removes them on unmount, which is correct, because a tool that edits a reasoning map must not be callable from the billing screen. Nothing is persisted, so a stale row reads exactly like a live one.
toolbanks - Toolbanks
Named groups of functioncalls, so a persona is handed a set rather than a list.
Trap: A bank holds tool NAMES. Renaming a functioncall leaves every bank pointing at nothing, with no error.
mcp - MCP Servers
Publish a selection of tools outward as a hosted MCP server that other agents can call.
Read with: GET /mcp/hosted
Trap: A hosted server IS an Imperium site with a callable mode, so it is authored in the site editor, not here. This tab reads what exists.
skills - Skills
Saved procedures an agent follows when a task matches.
Read with: GET /api/skills
Trap: Two sources share this page. Yours are editable; the built-in ones are derived from domains and installed apps, are rebuilt on every restart, and can only be switched off.
inventor - Inventor
One sentence to a manufacturable product - enclosure, board and firmware, cross-checked against each other.
Trap: Every stage here is an adapter call rather than a REST route, so the tool name is the API.
flux - Flux — Hardware
The hardware workspace - circuit boards and firmware sketches, as projects.
Read with: GET /api/projects
Write with: POST /api/projects
Trap: FLUX is a GALLERY, not an editor - it deliberately owns none, because Circuit Studio and the Arduino IDE already exist. Agent work on one runs through the coding-run lane with a hardware mode, not through this page.
codex - Codex — Code
The coding agent, pointed at the user's own projects.
Read with: GET /api/projects | GET /api/coding/conversations
Write with: POST /api/projects | POST /api/coding/runs
- Register or pick a project. Sandbox projects are scaffolded; local ones need a path and the file capability.
- Choose a provider that can use tools - check, do not assume.
POST /api/coding/runsreturns 202 immediately; follow the stream.
Trap: [critical] Two providers answer without being able to touch a file. If files were meant to change and none did, check the provider before debugging the prompt. A run carries the project MEMORY first, so what is written there shapes every run in that project.
runs - Agent Runs
What an agent actually did - runs, their events and their cost.
Read with: GET /api/coding/runs
runs/local - Agent Runs → Local chats
Chat transcripts read off this machine rather than the server.
Trap: Machine-local and admin-only. On a hosted install it is simply not there, which is not a fault.
Ways in
Declared cross-links. Every address is matched against the real route table by check:huds.
| From | Does | Go to |
|---|---|---|
ai/hub:personalities | Its tools | /admin/d/ai/toolbanks |
ai/hub:personalities | How it reasons | /admin/d/ai/reasoning-maps |
ai/hub:toolbanks | Define a call | /admin/d/ai/functioncalls |
ai/hub:inventor | The boards it made | /admin/d/ai/flux |
Tools an agent can call here
These are live page capabilities: they exist only while that surface is open, and they call the page's own mutators, so a change made through one is a change the operator can see. A tool missing from this list is not callable — reach for the API or an adapter instead.
ai:hud — AI console: …
Source: ai/hud/model/useAiHudCapabilities.js
What the page tells an agent about itself:
The user is on the AI console — a heads-up display over a live view of their own AI: a swipeable deck of every persona they own, the one they picked answering in the composer, and the section's tabs in the left rail. This section is the AGENT: personas, reasoning maps, functioncalls, toolbanks, the project agents and MCP. Triggers, actions, workflows, macros and the function index live in the DYNAMIC section (/admin/dynamic/...) — send the user there for those rather than looking for a tab here. What a bot can CALL is unaffected by that split; it is only where they are managed that differs. The persona you are editing may be the persona you ARE. Always call get_persona before reasoning about or changing anything, and say which persona you are changing when it is not the one talking. TWO LANES, do not confuse them: select_persona, set_persona_field, set_provider, bind_toolbank, bind_map and open_dial_panel change the DRAFT and persist nothing; save_persona is the only tool that writes. Make all your edits, then save once at the end. Never report work as done before save_persona has returned ok. A persona with no provider key answers every turn with the user's own message echoed back. That is the single most common "it does not work", it is invisible unless you look, and list_catalogs is where you look. Temperature and maxTokens are honoured only by the providers in samplingProviders. Setting them for any other provider is a promise the turn quietly breaks — say so rather than setting them. Use open_dial_panel to put what you are discussing in front of the user before you change it. Changing four fields in panels they never saw open is correct and unreadable. You cannot create or delete personas from here, by design. Point the user at Programmable Personality for either.
| Tool | Args | Does |
|---|---|---|
get_persona | — | Read the persona currently selected on this screen — its name, prompt, provider, model, sampling, bound toolbanks/function calls/reasoning maps, voice, tool policy, whether it is healthy, and whether there are unsaved changes. Call this FIRST, before reasoning about or changing it. |
list_personas | — | List every persona on this instance — { id, name, model, enabled }. Use the id with select_persona. |
list_catalogs | — | What this persona can be given: the LLM providers configured here (with whether each has a key), the toolbanks, the function calls and the reasoning maps. Read this before binding anything — an id that is not in these lists does not exist. |
select_persona | id | Centre a persona in the deck and make it the one this screen is about — who answers, and what the dial edits. DOES NOT SAVE anything; it changes what is selected. |
set_persona_field | key value | Change one field of the selected persona's DRAFT: name, description, system (the persona prompt), greeting, model, temperature, maxTokens, enabled. DOES NOT SAVE — call save_persona when the persona is right. |
set_provider | provider | Choose which LLM answers for this persona — an id from list_catalogs, or "auto" for whichever has a key. A provider with no key means every turn falls back to the stub echo, so check hasKey first. DOES NOT SAVE. |
bind_toolbank | id bound | Give this persona a toolbank, or take one away. A toolbank is a named bundle of functions the persona may call. DOES NOT SAVE. |
bind_map | id bound | Give this persona a reasoning map, or take one away. A map is a compact rule-set appended after the persona prompt on every turn. DOES NOT SAVE. |
open_dial_panel | panel | Open one of the dial's panels so the user is looking at what you are talking about: identity, mind (the prompt), reach (provider and sampling), tools, knowledge (reasoning maps), voice, terms. Pass an empty string to close it. |
save_persona | — | Write the draft to the server. This is the ONLY tool that persists anything — every other tool on this screen changes what is displayed and nothing else. Call it once, after all your edits. Never report work as done before this has returned ok. |
ai:map-editor — Reasoning map: …
Source: ai/model/useMapCapabilities.js
What the page tells an agent about itself:
The user is editing a REASONING MAP — a compact rule-set that an AI agent must comply with while doing a specific job. Each rule has a kind (must/never/prefer/context), one imperative sentence, and a reason. The reason is not decoration: a rule without one is followed literally and cannot be generalised from. Always call get_map_overview before reasoning about or changing the map — it carries the rule-kind vocabulary and any warnings. TWO LANES, do not confuse them: add_rules, set_rule, remove_rule, move_rule and set_map_meta change the DRAFT and persist nothing; save_map is the only tool that writes. Make all your edits, then save once at the end. Never report work as done before save_map has returned. Prefer few strong rules to many weak ones — a map is loaded for one task and costs every turn that uses it. Order matters: what must never be broken goes first. A map can also be BOUND TO SCREENS (set_map_surfaces): bound that way it is loaded for any turn taken while that screen is open, which is how a page gives you the rules for the thing on it. Binding is a real change to how the assistant behaves everywhere that screen is used — propose it and let the user decide rather than doing it unasked. The editor is a heads-up display: the map is drawn full-screen behind panels the user can close. Use open_map_panel and select_rule to put what you are discussing in front of them. A map does THREE things for a bot that carries hundreds of functioncalls, and they are separate: rules say what to do; set_rule_tools names the functions a rule routes to, which is guidance the agent reads while choosing; set_tool_policy narrows the offer itself so the model is never told about the rest. Reach for the third when a bot has too many tools to choose well among — that is the problem this exists to solve. link_rules records ORDER and DEPENDENCY between rules, which no amount of wording conveys on its own. A rule-set of more than about six rules almost always has some, and an agent given none has to guess.
| Tool | Args | Does |
|---|---|---|
get_map_overview | — | Read the open reasoning map: its name, purpose, description, rule count, roughly what it costs in tokens, any warnings, whether there are unsaved changes, and which rule is selected. Also returns the rule KINDS vocabulary you must use. Call this FIRST, before reasoning about or changing the map. |
list_rules | — | List this map's rules in order — { id, n, kind, text, why, example, source }. Up to ${MAX_LIST}. Use the id when editing, moving or removing one. |
read_compiled_map | — | Read the exact text this map compiles into — what an agent loading it actually receives. Use it to check that your edits read the way you intend before saving. |
add_rules | — | Add one or more rules to the draft. Each needs text (one short imperative sentence) and should have why (the reason — a rule without one is followed literally and cannot be generalised from). kind is one of must/never/prefer/context; omit it and it will be inferred from the wording. DOES NOT SAVE — call save_map when the map is right. |
set_rule | id text why kind example | Change one rule in the draft by id. Pass only the fields you are changing. DOES NOT SAVE. |
remove_rule | id | Remove one rule from the draft by id. DOES NOT SAVE. |
move_rule | id direction | Move a rule up or down. Order matters — an agent reads a map top to bottom, so put the rules that must never be broken first. DOES NOT SAVE. |
set_map_meta | name purpose description tags enabled | Change the map's name, purpose, description, tags or enabled flag in the draft. The purpose is one line saying what job this map is FOR — it is how a person picks the right map. DOES NOT SAVE. |
list_links | — | List the authored relations between this map's rules — { id, from, to, type }. Types: then (order), requires (dependency), refines (the specific case, which wins), conflicts (they pull against each other). Each one compiles into a sentence the agent reads, so they are instruction rather than drawing. |
link_rules | from to type | Relate two rules. Use then when order matters, requires when the first only applies once the second holds, refines when the first is the specific case of the second, conflicts when they pull against each other. Do not link a rule to itself. DOES NOT SAVE. |
unlink_rules | id | Remove one authored relation by its link id (from list_links). DOES NOT SAVE. |
set_rule_tools | id tools | Name the tools a rule routes to — the functions an agent should use to obey it. This is what makes a map useful to a bot carrying hundreds of functioncalls: the rule says what to do, these say what to do it with, and they compile onto the rule's own line. Use the TOOL NAME the model is offered (e.g. "a-text.Base64Encode", "send_email"), never a Studio selector like "adapter:…". Pass the full list you want; it replaces. DOES NOT SAVE. |
set_tool_policy | mode names | Narrow the toolbox itself. mode "all" = everything the bot has (the default); "allow" = the agent is offered ONLY the named tools while this map is loaded; "deny" = everything except them. This filters the OFFER server-side, so the model is never told about a withheld tool. It is the strongest thing a map does and it changes what the assistant can do everywhere the map loads — propose it rather than applying it unasked. DOES NOT SAVE. |
list_known_surfaces | — | List the SCREENS (capability scopes) this Studio session has seen, with the title of each — the ids you can bind a map to with set_map_surfaces. It is what has been visited since the tab loaded, not every screen that exists, so a screen the user has not opened will not appear. |
set_map_surfaces | surfaces | Bind this map to SCREENS. A map bound to a screen is loaded for any turn taken while that screen is open — this is how a UI hands an agent the rules for the thing on it, without an admin having to attach the map to every persona. Pass the FULL list you want (it replaces, it does not append); pass an empty list to unbind everything. Call list_known_surfaces first for the valid ids. DOES NOT SAVE. |
clear_map_layout | — | Release every node the user has dragged into place on the canvas, so the map lays itself out again. Only useful when the arrangement has gone wrong — it discards their placements. DOES NOT SAVE. |
save_map | — | Persist the draft. This is the ONLY tool that writes — every other change is local until you call it. Call it once, at the end, when the map reads the way you intend. |
select_rule | id | Open a rule in the editor so the user is looking at the one you are talking about. Pass no id to clear the selection. |
open_map_panel | panel | Open one of the editor panels so the user is looking at what you are talking about: "inspector" (the selected rule), "prompt" (what the map compiles to), "ai" (suggestions), "bindings" (which screens and personas load it). |
ai:map-editor — Reasoning map editor
Source: ai/pages/CapabilityRegistry.jsx
What the page tells an agent about itself:
Eight tools change the draft; only save_map writes.
| Tool | Args | Does |
|---|---|---|
add_rule | text kind | Add one rule to the open map. |
Traps
CRUD is /db/<collection> (chatbots, functioncalls, toolbanks, reasoning_maps, skills, projects); the VERBS are /api/<thing> (/api/coding/runs, /api/adapters/:system/:fn, /leviathan/chat). {kind, ref, config} is the one dispatch descriptor for everything callable, and an unbindable kind resolves to null rather than throwing - which is why a row can look saved and do nothing. Argument merging differs by kind and in opposite directions: an action merges its config AFTER the caller args (config wins), an integration merges its config BEFORE (caller wins). Every crossing into user code or another machine is a facade, not a token: apps get a capability object, sandboxed plugins get a fixed dispatch table, connected software goes through one pipeline, and hardware takes typed verbs - never a command line.