API Reference oapi_codemode v#0.5.0

Copy Markdown View Source

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.

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.