Modules
OpenAPI search-and-execute for LLM agents, Cloudflare-codemode style.
Per-API registration config. Everything the spec cannot know.
Host-implemented credential resolution, library-implemented attachment.
The output of OapiCodemode.Ingest.decompose/1: one document taken apart
into the pieces a SpecStore persists, with nothing dereferenced inline.
The sandbox contract — the entire interface a TS execution environment must satisfy. Deliberately minimal: run code with globals and callbacks, return the value and console output.
Subprocess Deno executor — the alternative to the recommended
OapiCodemode.Executor.SafeJS, and the only one that dispatches a
guest's Promise.all requests concurrently. The costs against SafeJS:
a deno 2.x binary must be on PATH in every image that runs it, and
V8 has no hard memory cap (an ArrayBuffer bomb walks past
--max-old-space-size). Its :timeout, unlike SafeJS's, is a
wall-clock deadline that already includes host-callback time.
Test executor: the "sandbox" is an Elixir function you set per test. Exercises the plumbing (globals in, callbacks out, results back) without a JS runtime.
The recommended executor: in-process on
ex_safejs, the QuickJS-NG engine
embedded as a Rustler NIF (our hard fork of lpgauth/quicksand). A hex
dependency with precompiled binaries is the whole deployment story — no
runtime binary in the image, no subprocess, no container config — and
QuickJS's own allocator is the sole memory authority, so a guest's live
memory is genuinely capped: typed-array/ArrayBuffer bombs, the vector
that escapes V8's heap limit, come back as a structured out-of-memory
error. The engine is complete and mature (regex included — global match,
named groups, lookaheads) with O(1) container access, so searching a
multi-MB spec as data is not pathological.
In-process executor on ex_zapcode,
a pure-Rust TypeScript-subset interpreter shipped as a NIF. Like
OapiCodemode.Executor.SafeJS it deploys as nothing but a hex dependency
— no subprocess, no runtime binary in the image, no container config —
and bounds live guest memory (limits: %{max_memory: bytes}).
Pure pipeline from raw spec source to something storable.
Resolves all same-document $refs inline, in one pass over a whole document.
Extracts a flat operation list from a spec, deriving stable readable ids
where operationId is missing (the oaskit cards_freeze_ALTIJVI lesson:
never trust upstream ids to exist or be usable).
Parses raw YAML/JSON into a map and checks it is an OpenAPI 3.x document.
One HTTP operation extracted from a spec, ready for matching and validation.
Same-document JSON pointer resolution ("#/components/schemas/Pet").
The validating, credential-injecting request pipeline: match -> policy -> resolve -> validate -> credentials -> execute -> normalize.
Matches an intercepted (method, path) against the operation index. On failure, suggests the nearest operations so the model can self-correct without another search round-trip.
Serializes query parameters honoring the spec's style/explode declarations (the ele lesson: default serializers silently mismatch backend expectations). Supported: form (explode true/false), deepObject, spaceDelimited, pipeDelimited. Anything else falls back to form+explode.
Validates an intercepted request against the operation's dereferenced schema.
Binds api names to {store, ref} plus per-API config, in ETS. No
persistence: hosts re-register at boot from wherever their specs live.
One registration as the proxy and the tool layer read it: where the
spec lives (store and the projection ref), the host's config, and
cache — the registration-time cache described in
OapiCodemode.Registry.
Read-time $ref resolution: one stored operation row plus the store, in,
one usable operation out.
The seam between the library and wherever specs actually live.
The OapiCodemode.SpecStore the library ships with: one ETS table.
What the registry needs to know about a spec at registration time, and nothing else: one read, then no spec bytes are held.
One entry of the slim search index, in struct form.
The OapiCodemode.SpecStore conformance suite.
Emits the two codemode tools as data plus handlers. Transport-agnostic: hosts wrap these into their own tool layers (gentility's CloudLoop.Tool, ele's UserMCP.Tool, or a gen_mcp server).
Assembles search/execute tool descriptions from registry state. The description IS the documentation — every global the sandbox actually receives must be declared here, with real names, or the model has to guess at them.
JSON-encodes tool results with a budget cap and an instructive trailer.