API Reference Ymer Node v#0.4.0

Copy Markdown View Source

Modules

This module is the map — what exists and why. Each entry defends a module's existence; how a module is designed lives in its own @moduledoc.

The MCP mount — the node's entire external surface.

The HTTP entry point: routes paths to YmerNode.Mcp, and answers 404 to everything else.

The instructions the node hands every MCP client at connect.

The four helpers a tool's action and format layers share, and nothing else.

Wymcp tool notebook — an open SQL surface over notebook.db, the node's own private store, together with the actions that keep it safe.

Action implementations for the notebook MCP tool (YmerNode.Mcp.Tools.Notebook, which calls run/2) — a thin boundary over YmerNode.Notebook and YmerNode.Notebook.Backup. This is a trust boundary: sql, table and id are guarded is_binary in each head because nothing downstream validates them — the MCP dispatch layer checks that a parameter is present but never what type it holds — so sql and table flow straight into SQLite and id flows into filename construction. Each action returns {:ok, data, hint_ctx} or {:error, {reason, ctx}} — and, where the error is one the caller can act on, {:error, {reason, ctx}, hint_ctx}, the three-element form that puts a follow-up hint on the error payload rather than only in its prose.

Translates YmerNode.Notebook and YmerNode.Notebook.Backup error reasons into LLM-readable messages. SQLite errors are surfaced verbatim so the agent can read and fix its own SQL; backup failures never are, because their detail carries filesystem paths the caller must not see.

Shapes YmerNode.Notebook and YmerNode.Notebook.Backup results into JSON-serialisable maps for MCP responses. Query results pass through as parallel columns/rows arrays (compact and order-preserving) rather than per-row maps.

Follow-up hints for the notebook tool, keyed off the hint_context maps YmerNode.Mcp.Tools.Notebook.Actions produces. After execute creates schema, the natural next steps are describing or querying it; after a capture the natural next step is confirming it. A completed restore needs no follow-up either, since the roll-back is already done — but a restore that failed recoverably does: the hint carries the id of the backup to restore, or of the restore to retry, so the recovery is one call away instead of a re-read of the error text. Everything else falls through to none — including every answer about a notebook that cannot take the call, whose next action is a person's and not another tool call, and a backup that will not open, whose next action is a different id this module has no way to choose.

Schema definitions for the notebook tool's actions. The :notes/:examples are the agent's primary documentation for sqlite-vec usage and the INTEGER-PRIMARY-KEY join discipline — they surface via the help tool.

Wymcp tool references — the registry of pointers at where knowledge lives.

Action implementations for the references tool — the boundary over the YmerNode.References context.

Translates the references tool's error reasons, optionally with context, into messages a worker can act on. Called by YmerNode.Mcp.Tools.References's Wymcp.Tool.handle_error/1.

Response shaping for the references tool.

Follow-up hints for the references tool, keyed off the hint_context maps YmerNode.Mcp.Tools.References.Actions produces.

Action schemas for the references tool. The notes surface through the help tool and are the worker-facing contract documentation — the mode contract, the duplicate rule, and the membrane.

Value validation for the references tool's params.

Wymcp tool schedules — adding, listing, updating and removing the standing instructions YmerNode.Schedules fires.

Action implementations for the schedules tool — the boundary over YmerNode.Schedules.

Translates the schedules tool's error reasons into messages a worker can act on. Called by YmerNode.Mcp.Tools.Schedules's Wymcp.Tool.handle_error/1.

Action schemas for the schedules tool. The notes surface through the help tool and are the worker-facing contract: what a cron expression and a lifetime look like, what add refuses rather than leaving to a firing, and what a firing skips.

Wymcp tool script_author — writing the scripts this node accepts.

Action implementations for the script_author tool — the boundary over YmerNode.Scripts's write verbs.

Translates the script_author tool's error reasons into messages a worker can act on. Called by YmerNode.Mcp.Tools.ScriptAuthor's Wymcp.Tool.handle_error/1.

Follow-up hints for the script_author tool, keyed off the hint_context maps YmerNode.Mcp.Tools.ScriptAuthor.Actions produces.

Action schemas for the script_author tool. The notes surface through the help tool and are the worker-facing contract of each call — what it does, what it refuses, what its flags mean. The script contract itself is not written here: scripts guide renders it from YmerNode.Script's own docs, and the notes of check and create point there.

Wymcp tool scripts — the scripts this node has accepted, and running one.

Action implementations for the scripts tool — the boundary over YmerNode.Scripts.

Translates the scripts tool's error reasons into messages a worker can act on. Called by YmerNode.Mcp.Tools.Scripts's Wymcp.Tool.handle_error/1.

Follow-up hints for the scripts tool, keyed off the hint_context maps YmerNode.Mcp.Tools.Scripts.Actions produces.

Action schemas for the scripts tool. The notes surface through the help tool and are the worker-facing contract: what a run costs, what acceptance means, and why describe is the call to make before run.

The notebook — notebook.db, a separate, portable SQLite store of user- and LLM-governed memories, working and long-term: agent-defined schema, open SQL, embeddings, backup and restore. Potentially precious (tutoring records, curated knowledge); the node's obligation is durability — governance stays with the user and the LLM. This module is its raw-SQL surface (via YmerNode.Notebook.Repo).

Capture and restore for notebook.db — the node's one durable obligation.

Singleton mutex serializing YmerNode.Notebook.Backup operations — capture and restore.

Ecto repo for notebook.db — the node's one deliberate local store.

One-shot boot probe that aborts application start when the sqlite-vec vec0 extension did not load into YmerNode.Notebook.Repo.

The registry of pointers at where knowledge lives, served to LLM workers as the references tool; it holds references, never copies of what they point at (the membrane).

One row of the registry: a pointer naming where knowledge lives and when to look, never what it says. The rule that keeps it a pointer — the membrane — is stated in YmerNode.References.

The find surface — two composable layers on one call.

Derives a reference's source and fetch recipe from its uri, at read time and never from storage.

Ecto repo for node.db — the node database, and the rebuildable half of what the node stores.

The node's schedules: standing instructions to run one action of one accepted script, with fixed args, on a cron expression in the node's time zone, until each one's lifetime ends. They are added, listed, updated and removed through the schedules tool and the CLI, and fired by YmerNode.Schedules.Scheduler.

A schedule's cron expression: which ones the node accepts, and when one comes due next in the node's time zone. The crontab package parses and walks them; this module decides only what that package leaves open.

Which schedules have a run in flight right now, and until when at the latest — a process registry of its own, unique by schedule, whose entry a firing takes for as long as its run lasts.

What a schedule's row keeps of its last run: the moment the firing that started it came due, one of four outcomes, the runner's own message, and how long the run took. Nothing before it — there is no run history, and a skipped firing leaves no trace — because the node is a script runner, not a reliable scheduler. What a script produces goes where the script puts it; anything it wants kept beyond one line, it writes to the notebook.

A schedule's lifetime — how far into the future it keeps firing — read from what a caller gives add or update into the one instant it ends.

A standing instruction for the node to run one action of one accepted script, with fixed args, on a cron expression in the node time zone, until its lifetime ends.

The process that fires schedules: once a minute, on the minute, it reads the active schedules and starts a firing for each one due in that minute — each in a task of its own under YmerNode.Schedules.FiringSupervisor, so a long run never holds the next minute back.

The contract a script implements — its description, its actions and their read/write marks, its declarations — and the version use YmerNode.Script stamps into its row.

What the node hands every run — Req, JSON, the notebook, secrets, the throttles it declares, the node's time zone, the files directory, the Typst renders and browser calls — provided by the node rather than declared by the script.

What a VM running script code outside the node needs, for a test or a live run: the processes a script's run reaches for, and the three configuration keys the node's own environments would otherwise set.

Testing a script in a repository of its own: an ExUnit setup callback and the functions a script test calls, over YmerNode.Script.Harness. Nothing is used — as with Req.Test, a test module names what it wants in setup.

The scripts this node has accepted, and every door they arrive and leave through — the context both script tools wrap and the node's own callers use.

The node's half of the browser service: the Node program in browser-service/ that a user starts on their own machine, outside the node, which runs Playwright code a script sends it — each browser call in a fresh browser context — and keeps the storage states.

A browser call's failure — the exception YmerNode.Script.Context.playwright/3 answers as {:error, exception}, the way YmerNode.Scripts.Throttle.Error is what YmerNode.Script.Context.request/2 answers for a refused request: a script matches on kind, or hands the exception back unchanged and the run's answer shows its message.

The operator's verbs, run on the machine the node runs on — the node's own human door, beside the client's approval.

Turns a script's code into a loaded module tree, or into a refusal that names what is wrong with it.

The text scripts guide renders — the script contract and the batteries a script is handed — read at the call from the docs the release keeps.

Owns the VM's script module trees: every compile and every purge goes through this process, and it remembers what each one produced.

A promised package's own documentation, rendered from this release — what scripts info <name> answers.

One run — one execution of one action of one accepted script, whoever started it — and what is checked before it, the process it happens in, and the shape of every answer that comes back.

An Elixir module stored as a row in the node database — its code, the hash of that code and the hash this node has accepted — compiled into the VM and reachable through the scripts tool and by the node itself; Script.<Name>, named after its module.

One throttle on this node: the process that holds its bucket, its breaker and the requests waiting on it — and the two request steps that put a request naming it through that process.

A throttle's token bucket as a value: a rate per minute, a burst, the tokens it holds and the instant it last counted them.

A throttle's refusal of a request — the exception YmerNode.Script.Context.request/2 answers as {:error, exception} when a request never left the node.

The values a script resolves by name — one file of NAME=value lines, outside every database.

Mix Tasks

Runs the browser service's own tests — node --test in browser-service/, against the real Chromium its pinned Playwright drives.

Build the release image and tag it with the commit it was built from.

A subprocess's output reaching the terminal as it is produced — faithful for valid UTF-8, with anything unreadable shown as �, and unable to stop the task that runs it, whatever bytes it carries.

Proves the way a script author's own repository takes the node: a project depending on this checkout under runtime: false, where none of the node's applications start, tests a script through YmerNode.Script.Test and starts the run tree through YmerNode.Script.Harness.

Deploy: move the checkout's committed main into the install — name the rollback target, build, carry the compose file, recreate the install's container on the image, and verify it came up on it.