@adhd/apigen-engine-runtime
v0.3.2
Published
Runtime executor for apigen - dispatch derived operations with pluggable concurrency and transports
Maintainers
Readme
@adhd/apigen-engine-runtime
The apigen dispatch runtime — the single canonical call path every plugin and every generated server uses to turn an inbound request into a function call. Pure TypeScript, platform: shared.
Part of apigen. For end-to-end usage see ../cli.
Public API
import { dispatch, buildFnTable, describeParams, needsEnvelopeField, dataParamNames, createLogger, defineMiddleware, createApiPackage, EventBus, wireObservers, buildContext, invokeBatch } from '@adhd/apigen-engine-runtime';
import type { Logger, LogFormat, CreateLoggerOptions, ParamInfo, AnyFn, BatchOptions, BatchItemResult } from '@adhd/apigen-engine-runtime';dispatch(fns, ctx, schema, fnName, envelope, data)— the one dispatch path. No plugin inlines this; all import it here.buildFnTable(mod)— normalize an imported module into a callable table, recursively unwrappingdefault/ CommonJSmodule.exportslayers and keying functions by their.nameso default- and CJS-wrapped exports resolve (closes ledger finding F28).describeParams(schema)→ParamInfo[]— extract the parameter list for route/tool logging and CLI flag generation.needsEnvelopeField/dataParamNames— envelope + param helpers (single source).createLogger({ level, format, destination })— pino-based logger; defaults to stderr so MCP stdio stdout stays protocol-clean.format: 'json' | 'pretty'.invokeBatch(invoke, operationId, items, opts, batchOpts)— fan out N calls through the realinvokepath (viacreateInvoker's composed Layer stack) with controlled concurrency, error handling, and per-item timeouts. ReturnsPromise<BatchItemResult[]>. See@adhd/apigen-plugin-batchfor mount wiring.defineMiddleware/createApiPackage/EventBus/wireObservers/buildContext— middleware + observer wiring.buildToolDescription(schema, ...)— builds the human-facing description shown for a mounted tool/operation, appending a schema-synthesized worked example (via@adhd/apigen-base-logical'srenderExampleNote) after the envelope-convention note. The same function backs bothapigen-plugin-cli-output's static codegen andapigen-plugin-mcp's dynamic server, so every apigen-mounted tool's description carries a concrete example of its own real shape, not just a generic convention sentence.
Validation error messages are actionable
The validate-Layer's AJV validation-failure errors (invalid_argument) are built so a
caller — including an LLM — can correct the call in one round-trip:
additionalPropertiesnames the offending key, lists the keys that would have been accepted, and adds a nearest-key "did you mean" hint — e.g.unknown key 'agge' at data; allowed keys: name, age (did you mean 'age'?).requirednames the missing key and the accepted set.enumechoes the rejected value and lists the allowed values.
This closes the discoverability gap where AJV's raw message was the bare
"must NOT have additional properties" — which named neither the offending key nor the
accepted set, so a caller could only guess again. Violations are listed one per line and
capped (with an …and N more tail) rather than concatenated into an unreadable run.
The message still appends the schema-synthesized worked example described above,
except when that example would synthesize to nested empty objects (an all-optional
input, e.g. {"data":{"input":{}}}) — then it is dropped rather than shown, because it
reads as "pass an empty object" and teaches nothing.
Requires AJV
verbose: true: the formatter readsparentSchema(the accepted-key set) anddata(the rejected value) off eachErrorObject, neither of which is present on AJV's default error shape.
Request envelope
Inbound payloads are wrapped: { "data": { ...params }, ...envelope }. dispatch validates
the envelope fields a function requires (e.g. a session added by middleware) and passes
data to the function.
Develop
npx nx build apigen-engine-runtime
npx nx test apigen-engine-runtimenx test runs only the cheap in-process *.spec.ts lane (and is what
nx affected -t test / the git hooks run). The resource-consuming self-tests
(real git subprocesses, a real node:http server) live in sibling
*.e2e.ts files and run on demand only:
npx nx run apigen-engine-runtime:e2eBoth .e2e.ts suites are currently describe.skip'd (CPU-THRASH-SKIP,
owner-requested); *.spec.ts stubs at the original paths hold their mocked
it.todo inventory.
