Content-generation capabilities
Aether's pattern for long-running provider calls — text, images, or music — is
a wasm guest component a substrate loads on demand (ADR-0159). The component
runs the pure request/response logic but holds no key and owns no socket,
subprocess, or disk: it reaches the network through aether.http, a local CLI
through aether.process, and artifact staging through aether.fs, addressing
each edge capability by mail.
No provider component currently ships in the workspace. The earlier ones left the workspace unused, and git history holds them; a new provider starts from the current actor API and the edges below.
Provider access is opt-in. The default chassis composition carries no provider component; a workload that wants one uploads and loads it like any other component (see Components). A pure-rendering or CI substrate links none of the provider machinery at boot.
Edges a provider mails
Each request/reply flow is the ADR-0139 send_with_context / take_context
two-handler shape. The request handler builds the provider request body,
stashes the caller's reply handle as a context, and dispatches one edge request;
the reply handler recovers the context, parses the edge reply, and replies the
provider's own _result kind to the original caller.
- HTTP APIs ride
aether.http.fetch. The component sets no key header:aether.httpattaches the operator's secret binding for that host to the fetch (ADR-0235). Egress is bounded per-sender at theaether.httpedge (ADR-0158), so the component queues nothing itself. See HTTP. - A local CLI backend rides
aether.process.run. The process allowlist is deny-by-default and must admit the binary; an allowlist that omits it yields a typed refusal rather than a hang. Invocation is argv-array only, so guest prompts stay data rather than shell fragments. No API key rides this path. - Artifact staging (a provider returning binary media) rides
aether.fs.writeto thesavenamespace; the reply carries the staged path.
A large response can approach the aether.http body cap
(AETHER_HTTP_MAX_BODY_BYTES, 16 MB default) and the RPC frame budget
(AETHER_MAX_FRAME_SIZE), since the artifact bytes ride the fetch reply and then
mail; raise those knobs for multi-megabyte payloads.
Output staging
Binary media does not ride inline in reply mail. A generating provider writes
under its configured staging directory and returns relative paths such as
gen/<uuid>.png — never a literal save:// address. Treat the returned path as
an engine-side artifact reference:
- it is not automatically a path on the MCP client's machine;
- with a staging directory under the
savenamespace, a later consumer reads it throughaether.fsusing thesavenamespace and the returned relative path; - cleanup and retention policy belong to the configured staging directory;
- never interpolate a generated path into a shell command.
Keys and secrets
A provider key is not component configuration (ADR-0235, superseding ADR-0159
§5). The operator puts it in a named file under the engine's --secrets-dir
and binds it on aether.http as --http-secrets <host>/<header>=<secret-name>;
the http cap reads it once at boot and attaches it to each HTTPS fetch to that
exact host. The component never holds, reads, or names it, so the plaintext key
is never in guest memory, a kind, mail, or the journal. With no binding the
vendor answers 401, which a provider should surface as a typed authorization
error. See the Supplying secrets recipe.
Change route
- Edge capabilities a provider mails:
crates/aether-http/,crates/aether-process/,crates/aether-fs/ - Decision: ADR-0159 (guest-hosted providers), ADR-0050 (kind vocabulary), ADR-0139 (reply correlation), ADR-0158 (egress bound), ADR-0235 (secrets)
- Configuration: Configuration