@agenomics/action-runtime
v0.1.0
Published
AEP action-definition runtime: Result type, ok/err constructors, wrap helper, and the defineAction builder used by AEP capabilities.
Maintainers
Readme
@agenomics/action-runtime
A tiny Result type and defineAction builder for AEP capability handlers.
The runtime contract for capabilities advertised in an AEP capability
manifest (ADR-060). Provides a typed Result<T, E> discriminated union
with ok / err constructors, a wrap helper that converts any
Promise-returning function into a Result-returning one (so
exceptions never escape the action boundary), and a defineAction
builder that takes a plain async handler and produces an Action with
a uniform run(input) shape. Zero runtime dependencies — drop it into
any AEP capability without pulling Solana code into the action surface.
Install
npm install @agenomics/action-runtimeNot yet on npm; pre-publish 0.1.0. See docs/SDK_PUBLISH.md for the publish path.
Quick example
import { defineAction, ok, err } from "@agenomics/action-runtime";
import type { Result } from "@agenomics/action-runtime";
const addAction = defineAction({
name: "add",
description: "Adds two numbers",
handler: async (input: { a: number; b: number }) => input.a + input.b,
});
const result: Result<number, Error> = await addAction.run({ a: 3, b: 4 });
if (result.ok) {
console.log("sum:", result.value); // sum: 7
} else {
console.error("failed:", result.error.message);
}
// Manual constructors when you don't need a wrapped handler:
const success: Result<string> = ok("done");
const failure: Result<never, Error> = err(new Error("nope"));Key exports
Result<T, E = Error>— discriminated union:{ ok: true; value: T } | { ok: false; error: E }. Narrows cleanly viaresult.ok.ok(value)/err(error)— single-line constructors for the two variants.wrap(fn)— runs a() => Promise<T>, captures any throw, and returnsPromise<Result<T, ActionError>>. The thrown value is never returned verbatim: it is converted to a redactedActionError(see Security boundary).ActionSpec<TInput, TOutput>—{ name, description, validate?, handler }.Action<TInput, TOutput>—{ name, description, run: (input: unknown) => Promise<Result<TOutput, Error>> }.defineAction(spec)— builds anActionfrom a spec. The handler is wrapped withwrap, sorunnever throws.ActionError—extends Error, adds a stable machinecode. The only error type that ever crosses the action boundary back to a caller.ValidationError— throw fromvalidatefor invalid input; surfaces asActionErrorwithcode: "VALIDATION_ERROR".setInternalErrorSink(fn)— register a trusted server-side logger that receives the raw, unredacted error. Never wire this anywhere reachable by an untrusted caller.
Security boundary (SDK-F3 — cycle-4 audit)
defineAction is a capability runtime, not a validator. Two contracts are
now explicit:
No implicit input validation. Without a
validatehook the handler receives whatever the (possibly untrusted) caller passed —TInputis erased at runtime. For any handler that moves funds or touches signing material, supplyvalidate; it runs beforehandlerand mustthrow(e.g.ValidationError) on bad input.Error redaction. RPC URLs, filesystem (keypair) paths, and key/secret-shaped blobs are stripped from the
error.messagereturned to callers; the message is length-bounded; the rawError/.stackis never returned; non-Errorthrows are reduced to a type tag (no value leak). The unredacted error is delivered only tosetInternalErrorSinkif one is registered.
Related packages
@agenomics/client— call on-chain reads (e.g.fetchProfile,fetchVault) inside an action handler; throws inside the handler become typederrresults.@agenomics/idl— pull cluster-keyed program IDs into the same handler when you need to dispatch by network.@agenomics/capability-manifest-validator— declare eachdefineActionyou ship in your published manifest'scapabilities[]array; the validator confirms the manifest matches the on-chain commitment.@agenomics/sas-resolver— fetch reputation context for the requesting agent before running the action handler.
Status
0.1.0 — pre-publish; private until license + READMEs land per docs/SDK_PUBLISH.md.
