Guide
The collector
@adastracomputing/aer-auto-node instruments a Node agent without touching its source. It patches fetch, node:http(s) and node:child_process, adds semantic adapters for the OpenAI, Anthropic and Vercel AI SDKs, and streams events to AER live. Completion seals them into a signed record.
Install and run
npx @adastracomputing/aer init node --import @adastracomputing/aer-auto-node/register your-agent.js # or NODE_OPTIONS="--import @adastracomputing/aer-auto-node/register" your-start-command
Non-secret identity lives in aer.config.json (tenant, agent, environment, base URL). The only secret is AER_API_KEY, taken from the environment. Setting AER_DISABLE=1 installs nothing at all.
What is captured, and what never is
Adapters emit llm.requested, llm.completed and tool.selected from structured metadata only: model, token usage, stop reason and tool names. Streaming is covered on all three providers without ever reading chunk text. URLs are reduced to their host, process command lines to the executable name. Prompts, generated text, tool arguments, request bodies and headers are never captured, on any provider, streaming or not. The final collector.report event carries an activity summary and the capture policy, so the signed record itself shows what was and was not observed.
One known limitation: patch-based capture observes globalThis.fetch and default-import property access (cp.spawn(...)). A named import binds the original function before the patch applies and is not captured.
Session strategies
Set session.strategy in the config. process (the default) treats one process as one session, right for CLIs and one-shot agents. task opens a fresh session per withAerSession(...) call. server gives long-running apps no implicit session at all: wrap each agent run explicitly.
import { withAerSession } from '@adastracomputing/aer-auto-node';
app.post('/run', async (req, res) => {
const result = await withAerSession({ agentId: 'support-bot' }, async () => {
return runAgent(req.body);
});
res.json(result);
});Usage policies
An operator can set a usage policy per agent: allow or deny models by glob and cap calls and tokens per session. The collector fetches it at session open and enforces it in one of three modes: off, report (emit a policy.violation event, let the call proceed) or block (throw AerPolicyError before the SDK call is sent). This is a cost control, not a security boundary; the strong path is attestation scopes at a protected gateway.
Content commitments
With a customer-held key (AER_COMMITMENT_KEY, at least 32 bytes, 64-hex recommended) the collector commits to each LLM request and response as a one-way HMAC tag signed into the record. AER holds neither the key nor the plaintext, so it can neither open nor brute-force a tag. You can later prove offline, from your own key and retained plaintext, that a prompt or response is exactly what the signed record committed to. Without a key no commitments are emitted; there is deliberately no bare-hash fallback.
Attestation injection
List protected resources in the config and the collector attaches a short-lived X-AER-Attestation token to matching outbound requests, HTTPS only, never following a token across origins. An agent that does not run the collector has no token and is denied at the resource. See the admission control guide.