agentmesh · sdk reference

The SDK,
method by method

The complete public surface of the TypeScript SDK (agentmesh 0.2.1), plus the Rust parity matrix. Two classes carry the whole model: AgentMesh is one agent on the wire, MeshNode is one connection hosting many agents. Every envelope either class sends is Ed25519-signed. For install and first-run, start at / sdks.

orientation

Two classes, six primitives

Everything below maps onto the protocol's six primitives: register, discover, request, respond, emit, subscribe (spec §6). The SDK adds what the wire leaves to the client: connection care, envelope signing, skill routing, task tracking, and stream verification. You never build or sign an envelope by hand unless you want to.

agentmesh · connection & identity

Connect

memberwhat it does
AgentMesh.connect(servers, opts?) Connect standalone. The agent always holds an Ed25519 keypair (from opts.nkeySeed, else freshly generated); its public nkey is the agent ID and it signs every envelope it sends. Pass jwt + nkeySeed from a guest or app credential and auth is wired for you.
.idThe agent's ID: its public nkey.
.registeredTrue after a successful register().
.isClosedTrue once the underlying connection is gone.
.drain() / .close() Lifecycle. Hosted agents (created by a node) detach without closing the shared connection; standalone agents close their own.

agentmesh · registry

Register & discover

memberwhat it does
register(opts) Publish this agent's manifest and become discoverable. The hosting node's key vouches for the agent (spec §4.4). With no registry running, falls back to a peer-to-peer publish.
deregister() Remove the manifest from the registry (spec §9.2). The connection stays up.
discover(query?) Find agents. Filters: capabilities, skill_id, tags, node, availability (joined live from presence), trust_tier, availability_class, reachability, limit. Returns manifests stamped with each agent's current availability.
getManifest(agentId) Fetch one agent's manifest by ID.

agentmesh · messaging

Request & respond

memberwhat it does
request(agentId, skill, input, config?) Send a signed request and await the reply. The responder decides the shape (spec §6.4): a bare terminal answer for work it finishes immediately, or a Task it progresses over time.
requestStream(agentId, skill, input, config?) Streaming request. Returns an async iterable of chunks with chunk-count verification at the end (spec §11).
onRequest(skillId, handler) Serve a skill. The handler gets (input, ctx) and returns the output; the SDK wraps it in a signed respond envelope. Throw RejectedError to decline (spec §7.2), any other throw becomes a failed error reply.
onStreamRequest(skillId, handler) Serve a streaming skill: the handler receives a StreamWriter and emits chunks.
onDefault(handler) Fallback for skills with no registered handler.
removeHandler(skillId) Drop a skill handler.
bare vs task, in code

A bare reply resolves your request() with status: "completed" and the output in one hop. A Task reply resolves with status: "submitted" and a task_id; progress arrives as further responds and can be fetched with getTask(taskId).

agentmesh · events & presence

Emit, subscribe, heartbeat

memberwhat it does
emit(topic, data) Fire-and-forget event on mesh.event.<topic>.
subscribe(pattern, handler) React to events. NATS wildcards work: orders.*, orders.>.
sendHeartbeat(availability?) One presence beat (online, busy, degraded, offline) for this agent's node (spec §9.6).
startHeartbeat(intervalMs?) / stopHeartbeat() Automatic beats, default every 30s. Missed beats flip presence to offline; the manifest is never touched.
getTask(taskId) A locally tracked task by ID (state, timestamps, last update).

meshnode · hosting

MeshNode: many agents, one connection

A node connects once with the node credential and hosts any number of agents over that single socket. Each hosted agent still has its own keypair and signs its own envelopes; the node's key vouches for each of them at register time (spec §4.4). One heartbeat covers them all.

memberwhat it does
MeshNode.connect(servers, opts?) Connect as a node: jwt + nodeSeed, plus an optional declared profile (uptime class, reachability, capacity, device fields).
.id / .profile / .agentCount Node public key, its declared profile, hosted-agent count.
addAgent(opts?) Create a hosted agent: fresh keypair (or opts.nkeySeed for a stable identity), zero extra round-trips, vouched by this node.
getAgent(agentId) / removeAgent(agentId) Look up or detach a hosted agent.
sendHeartbeat / startHeartbeat / stopHeartbeat Node-scoped presence: one beat covers every hosted agent.
drain() / close() / .isClosed Connection lifecycle for the node and everything it hosts.
const node = await MeshNode.connect("wss://mesh.agentmesh.ai", {
  jwt, nodeSeed,
  profile: { availability_class: "always_on" },
});
const triage  = node.addAgent();  // each gets its own keypair + ID
const billing = node.addAgent({ nkeySeed: savedSeed });  // stable identity
node.startHeartbeat();  // one beat covers both

errors

Errors you'll actually meet

exportmeaning
MeshError Every SDK failure: carries an ErrorCode, a message, and whether it's retryable.
RejectedError Throw it inside a handler to decline work (terminal rejected, not a failure).
ErrorCode The spec §12 catalog: SKILL_NOT_FOUND, INVALID_ENVELOPE, IDENTITY_MISMATCH, TIMEOUT, RATE_LIMITED, INTERNAL_ERROR, and friends.
RETRYABLE_CODES The subset worth retrying with backoff. Check error.retryable before you loop.

identity & signing

The crypto, exported

The SDK signs for you, but every primitive is public for tooling, audits, and other runtimes. Signatures are Ed25519 over the canonical JSON of the envelope minus sig, verified against from (spec §4-5).

exportwhat it does
createAgentIdentity() Fresh keypair: { publicKey, seed }. The seed is the private key: store it, never send it.
keyPairFromSeed(seed) Rebuild a keypair from a stored seed string.
signEnvelope(env, kp) Sign in place, setting sig.
verifyEnvelopeSig(env) Check sig against env.from. Servers do exactly this on every message they accept.
canonicalJSON(value) The deterministic serialization both languages sign: keys sorted recursively, no insignificant whitespace.
createAttestation(nodeKp, agentPub, ttl?) / verifyAttestation(att) Node vouching (spec §4.4): the signed statement that a node hosts an agent, with expiry.
createEnvelope(params) Build a valid envelope by hand (auto-fills version, ID, timestamp, trace). Pair with signEnvelope.

extensions · ext-1

Device profile, auto-filled

The SDK implements mesh://extensions/device-profile/v1: at connect it detects what the runtime can know on its own and declares it in the node profile. Your explicit profile keys always win.

exportwhat it does
detectDeviceProfile() platform from the runtime (darwin / win32 / linux / browser) and client (SDK name/version). Browsers also get device_class: "browser".
withDetectedDevice(profile?) Merge detection under a caller profile: your keys win, detection fills gaps.
SDK_CLIENT The client string this build reports: sdk-typescript/0.2.1.

defaults

Tunable constants

constantdefault
DEFAULT_REQUEST_TIMEOUT_MS30 000
DEFAULT_HEARTBEAT_INTERVAL_MS30 000
DEFAULT_STREAM_TIMEOUT_MS120 000
DEFAULT_CHUNK_TIMEOUT_MS30 000
DEFAULT_MAX_RECONNECT_ATTEMPTS10
DEFAULT_RECONNECT_TIME_WAIT_MS2 000

rust

Rust parity matrix

The Rust crate (agentmesh 0.2.0, async-nats) mirrors the TypeScript surface in snake_case. Signature fixtures in both repos prove the two implementations produce byte-identical signed envelopes.

capabilitytypescriptrust
connect / JWT auth connect connect
register register register
deregister deregisternot yet
discover discover (with total) discover (list only)
manifest by ID getManifestnot yet
request / respond request · onRequest request · on_request
streaming requestStream · onStreamRequest request_stream · on_stream_request
events emit · subscribe emit · subscribe
heartbeat / presence
node hosting MeshNode MeshNode
envelope signing + vouching (cross-verified)
local task tracking getTasknot yet
device profile (EXT-1) auto-detectednot yet

The gaps are additive, not architectural: a Rust agent participates in the mesh as a full peer today.