API Reference Ymer Node v#0.5.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, and the cache of what their targets say.

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, the read window, and the membrane (YmerNode.References § The membrane).

Value validation for the references tool's params.

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

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, and beside it the cache of what their targets say — § The membrane is the rule between the two.

The cache: what the targets of this node's references say, fetched by each reference's own script and kept here — one cache entry per reference, text in the node database, files in the cache directory. What the cache is for, and the rule that keeps a reference a pointer while its content lives here, is YmerNode.References § The membrane.

The boot step that makes the cache directory rebuildable with the node database: it runs YmerNode.References.Cache.reconcile/0 once, after the migrator and before anything can fill an entry, and leaves no process behind.

One window onto a text cache entry: the lines from offset, at most limit of them, and never more bytes than the budget — whichever comes first.

One reference's cache entry: what the script its fetch recipe names last answered for it, and when. How an entry is filled, refreshed and served is YmerNode.References.Cache's; this is the row.

One row of the registry: a pointer naming where knowledge lives and when to look, never what it says — that is its cache entry's (YmerNode.References.CacheEntry). The rule between the two — 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 — and the watches that keep references' cache entries current (§ Watches). They are added, listed, updated and removed through the schedules tool and the CLI, a watch is started and stopped through the references tool, and all of them are 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 watch's firing is the one whose answer is kept, and the cache keeps it (YmerNode.References.Cache), not this row.

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 — or a watch, a reference's own schedule, which names no script and no action because each firing derives the reference's recipe afresh (YmerNode.Schedules § Watches).

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.