Table of Contents
llm_tools: chat tool registry
llm_tools is the function-calling registry for the chat
engine. When the model decides it needs live data to answer — the local
sub-board list, a BBS directory lookup, BBS-era history — it emits a tool
call; the registry runs the matching tool and feeds the result back to the
model. Tools are how the Guru answers from fact instead of from training
guesses.
The registry lives in exec/llm_tools.js; each tool is a separate file
under exec/llm_tools/.
How it works
On load, llm_tools.js reads every exec/llm_tools/*.js file in
alphabetical order and load()s it. Each tool file ends by calling
llm_tool_register(...) to publish itself. The engine then offers the
registered tools to the model on each turn and dispatches any tool calls the
model makes.
Adding a tool is drop-in: add a file, restart — no change to the engine, no recompile. A file that fails to load is warned-and-skipped, so one broken tool never disables the rest.
Bundled tools
| Tool | Purpose |
|---|---|
this_bbs | Queries the local host BBS: today's live counters and lifetime totals (stats), message groups/subs, file libraries/dirs, door sections/doors, and recent messages on a sub. Honors each caller's access level — it only lists what that caller could see. |
bbs_directory | Queries the Synchronet BBS directory (sbbslist). lookup returns one BBS by name/sysop/hostname plus a live finger probe and reliability summary; list returns a filtered/sorted list (by software, network, sysop, recency) and a total count. |
external_archives | A curated index of BBS-era history and culture (textfiles.com, bbsdocumentary.com, the BBS Timeline). The model is told to call it before answering history questions, because training-data answers about door games, lawsuits, and old software are often wrong. |
relay_message | Stores a message for deferred delivery to a named recipient the next time they speak. Validates the recipient against the channel roster, chat history, and user base; primarily useful to the IRC adapter, which delivers queued messages. |
Security model
Tools run with the BBS's privileges, so the registry enforces a strict read-only contract. Read this before writing a tool:
- Read-only only. No side-effecting methods on host objects (no saving, writing, or deleting) — property access and read-only enumeration only.
- No path / eval / shell pass-through. A tool receives only the arguments the model emitted, constrained by the tool's declared JSON Schema.
- Caller chat text is never forwarded into a tool. Arguments come solely from the model's structured tool-call payload, not from raw user input.
- Secret tripwire. A shared helper audits every returned object and throws if a field name looks like a credential (
password,api_key,token,secret, etc.), to catch accidental leaks.
Writing a tool
Create exec/llm_tools/<name>.js. Define an executor and register it:
function my_tool(args, env) { // args: the model's structured arguments (validated against def below) // env: per-call context (e.g. the speaker) supplied by the engine // Return an object (auto-JSON-encoded) or a string. READ-ONLY work only. return { ok: true, answer: "..." }; } llm_tool_register({ name: "my_tool", execute: my_tool, def: { // the model-facing tool specification type: "function", "function": { name: "my_tool", description: "What this tool does and exactly when to call it.", parameters: { type: "object", properties: { topic: { type: "string", description: "..." } }, required: ["topic"] } } } });
Notes:
- The
descriptionis the model's only guide to when to call the tool — be specific, list trigger phrases, and say when not to call it. The bundled tools' descriptions are good models. - Files whose names begin with
_load first, so put helpers shared by several tools in a_-prefixed file (the bundled_common.jsis the example). - Returning
{ error: “...” }lets the model recover gracefully and tell the caller what went wrong.
See Also
- chat_llm — the chat engine that calls these tools
- llm_index — RAG retrieval (complementary to tools)
- chat_llm_irc — delivers
relay_messagequeues - chat_llm.ini — engine configuration