Embedding Arrival and capabilities
Embedding Arrival and capabilities
Section titled “Embedding Arrival and capabilities”The @inhuman.tools/arrival package exposes an asynchronous JavaScript entry point for running Scheme. Each top-level Scheme form produces one result, converted to a plain JavaScript value. The base roster (R7RS, SRFI, and polyglot forms) is assembled automatically; pass additional capabilities to expose host functionality.
Run a program
Section titled “Run a program”import { exec } from "@inhuman.tools/arrival";
const [result] = await exec(`(filter (lambda (x) (> x 5)) (list 1 3 7 9 2))`);// result: [7, 9]exec is convenient when you need the values. For persistent definitions or tracing, use execState; a caller can supply and reuse a LexicalScope across calls:
import { execState, LexicalScope, toJS } from "@inhuman.tools/arrival";
const scope = LexicalScope.fresh("agent-session");await execState(`(define (square x) (* x x))`, { scope });const { values: [value] } = await execState(`(square 7)`, { scope });toJS(value); // 49Expose a host tool
Section titled “Expose a host tool”A capability declares Scheme-visible symbols and their typed input/output contract. Define a capability, then pass it through the capabilities option:
import { exec, EnvCapability } from "@inhuman.tools/arrival";
const weather = EnvCapability.define("demo/weather", { symbols: (symbol, z) => ({ "forecast-for": symbol.rosetta`forecast-for: the current forecast for a city`( { input: [z.string], output: [z.string], provenance: "source" }, async (city) => `cloudy in ${city}`, ), }),});
const [forecast] = await exec( `(forecast-for "berlin")`, { capabilities: [weather] },);The contract is checked at the membrane boundary. A declared symbol also has a provenance role: source marks newly introduced external data, while a pure transform generally uses pipe to forward input lineage. source is the default role.
Capabilities are the explicit boundary for effects. Arrival does not provide ambient JavaScript globals to Scheme; host functions are available only when the host roots the corresponding capability. A capability can also declare dependencies on other capabilities rather than reaching into their internals.
Declared input data
Section titled “Declared input data”Use define/overridable to declare a typed program parameter with a default. Supply the runtime value in config.params; the declared shape is validated:
import { exec } from "@inhuman.tools/arrival";import { overridableCapability } from "@inhuman.tools/arrival/capabilities/overridable";
const [, answer] = await exec( `(define/overridable users (s/array (s/object (s/field/string "id") (s/field/number "priority"))) '()) (filter (lambda (u) (> (@ u :priority) 10)) users)`, { capabilities: [overridableCapability], config: { params: { users: [{ id: "alice", priority: 15 }] } }, },);// [{ id: "alice", priority: 15 }]If no value is supplied, the declared default is used. Invalid values are rejected with an error identifying the parameter and expected shape.
Optional loading capability
Section titled “Optional loading capability”Module loading is not ambient and is not included automatically. To use (require ...), root arrivalLoaderCapability from @inhuman.tools/arrival-modules and provide either fs or a configured loader and dirname. Its built-in resolver formats are .scm, .json, .ndjson, and .txt; YAML, TOML, and Handlebars require their optional subpath capability and peer dependency.
Source references
Section titled “Source references”arrival/packages/arrival/README.md(Quick Start; Tools; Data; Sessions; Membrane and provenance).arrival/packages/arrival-modules/README.md(loader capability and optional resolvers).