Skip to main content
Version: latest (main)

Quick Start

This page takes you from nothing to a governed agent in a few minutes. Everything here is copy-paste; the snippets mirror the patterns the SDK's own test suite exercises.

1. Install​

pnpm add @agent-assembly/sdk

The package ships dual ESM/CJS entries and selects a prebuilt native binding for your platform during postinstall, so there is no extra build step for typical consumers.

Pre-1.0 / release candidate

The public surface (initAssembly, withAssembly) is stabilizing. It may change between pre-releases. Pin an exact version for reproducible installs:

npm install @agent-assembly/[email protected]

2. Make sure a gateway is reachable​

The SDK enforces policy by talking to an Agent Assembly gateway. You have two options:

  • Let the SDK auto-start a local gateway. If you have the aasm binary on your PATH (brew install ai-agent-assembly/tap/aasm, or curl -fsSL https://agent-assembly.com/install.sh | sh) and set AA_AUTO_START=1, a zero-config initAssembly() will probe http://localhost:7391 and start a local gateway for you if nothing is running. Auto-start is opt-in — without it, a missing gateway throws a ConfigurationError instead of spawning anything.
  • Point at a gateway you already run. Set AA_GATEWAY_URL (and AA_API_KEY if it requires auth), or pass gatewayUrl explicitly.
Local-mode transports: :7391 REST + :50051 gRPC

Starting the local gateway binds two loopback surfaces in one process:

aasm start --mode local

This exposes the REST API on http://localhost:7391 (what gatewayUrl points to, and what the SDK probes and, with AA_AUTO_START=1, auto-starts) and the gRPC AgentLifecycleService on 127.0.0.1:50051, which is the endpoint the native aa-sdk-client binding dials to register your agent. You don't configure :50051 yourself — registration dials it automatically — so a no-argument initAssembly() both connects and shows the agent in the dashboard once a gateway is reachable.

To confirm both surfaces are actually up rather than guessing from the SDK's behavior, check them directly:

curl http://localhost:7391/healthz # REST — real JSON: mode, storage, version, uptime_secs
nc -z localhost 50051 && echo "gRPC port open" # gRPC has no health endpoint yet; this only confirms the port accepts connections

See Configuration for the full resolution order.

3. Govern your first agent with withAssembly​

withAssembly wraps a map of tools so the local policy is enforced before each one runs: an allowed call executes normally, while a denied call throws a PolicyViolationError and the tool body never runs. Pick your framework below — each tab is the governance-wiring excerpt from that framework's runnable example, vendored into this repo and kept in lock-step with this page by a CI drift check — the check catches this page drifting from the vendored snippet, not the vendored snippet drifting from the upstream example. Copy the full, runnable script — imports, tools, and the agent run — from the linked example; the slice below is just the part that wires in governance.

LangChain.js is the validated path; the remaining frameworks are experimental. The excerpts are ESM / TypeScript; under CommonJS, swap the import for const { withAssembly } = require("@agent-assembly/sdk").

import { withAssembly } from "@agent-assembly/sdk";
import { createPolicyGatewayClient } from "./policy.js";
import { TOOLS } from "./tools.js";

const tools = withAssembly(
{
get_weather: {
execute: async (args: Record<string, unknown>) => TOOLS.get_weather(args).output
},
delete_file: {
execute: async (args: Record<string, unknown>) => TOOLS.delete_file(args).output
}
},
{ gatewayClient: createPolicyGatewayClient(), agentId: "langchain-js-example-agent" }
);
Version compatibility

Base tool abstractions like Tool moved out of the langchain monolith into @langchain/core when LangChain split the package in v0.1.0 (Jan 2024; @langchain/core first published to npm 2023-11-22).

  • langchain < 0.1.0: import { Tool } from "langchain/tools";
  • langchain / @langchain/core ≥ 0.1.0 (current): import { tool } from "@langchain/core/tools";

4. What to expect​

  • Allow. The tool runs normally and returns its result. A governance event is emitted, and where it goes depends on the gateway client: the native one hands it to the runtime's event channel, while the no-op one has no channel and drops it. Neither is an assurance the event was retained — the handoff is unacknowledged, so the SDK cannot report arrival. Downstream, AAASM-5783 is open on report_event payloads reaching neither the live stream nor the durable entry, so no SDK can claim ADR 0033 §6 Observed until it lands. initAssembly warns when the event is dropped and reports auditSink on the returned context (AAASM-5750).
  • Deny. The wrapped invoke() rejects with a PolicyViolationError whose message includes the tool name and the gateway's reason — the tool body never runs.
  • Pending (needs approval). The call waits up to langchain.approvalTimeoutMs (default applies if unset) for a human decision, then either proceeds or rejects.

That deny-on-policy behavior is the whole point: a denied tool call throws instead of executing. If you want to watch what would be blocked without actually blocking it while you tune policy, register the agent in observe mode:

const ctx = await initAssembly({
agentId: "demo",
enforcementMode: "observe", // dry-run: actions proceed, violations recorded as shadow events
langchain: { tools: { searchWeb } }
});

Next steps​

  • Guides — the full LangChain walkthrough, the low-level withAssembly wrapper, experimental frameworks, and how to handle allow/deny decisions and errors.
  • Configuration — every AssemblyConfig field and the gateway/API-key resolution precedence.
  • Core Concepts — what the native binding, the adapter registry, and the initAssembly lifecycle actually do.