TypeScript SDK reference.
The @cosmonapse/sdk surface - the idiomatic TypeScript port of the same protocol. Verified against packages/ts-sdk.
Axon - agent-side tool
The Axon wraps a neuronFn with the metadata and validation needed to put it on the bus. It never touches the Synapse; attach it to a Dendrite to participate.
AxonTurns raw Neuron output into protocol-valid signals: a normal return becomes AGENT_OUTPUT, a clarify() return becomes CLARIFICATION, a permissionRequest() return becomes PERMISSION, and a thrown error becomes ERROR.
interface AxonOptions { neuronId: string; neuronFn: NeuronFn; capabilities?: string[]; version?: string; neuronKind?: string; // REGISTER directed.type; default "neuron" contextFetcher?: ContextFetcher; outputParser?: OutputParser; // recognise CLARIFICATION / PERMISSION / ERROR engrams?: EngramBinding[]; // memory the Neuron may address by name } class Axon { readonly neuronId: string; readonly capabilities: string[]; readonly version: string | undefined; constructor(opts: AxonOptions); // Source-paired factories - create the Neuron and the Axon in one call: static openai(neuronId, opts, extra?): Axon; static anthropic(neuronId, opts, extra?): Axon; static ollama(neuronId, opts, extra?): Axon; static huggingface(neuronId, opts, extra?): Axon; static mcp(neuronId, opts, extra?): Axon; // Called by the Dendrite for each inbound TASK. Resolves // contextRef, runs neuronFn, returns AGENT_OUTPUT / CLARIFICATION / PERMISSION / ERROR. handleTask(task: Signal): Promise<Signal>; // Pre-task hook - transform / validate / reject the TASK input. beforeTask(fn: (input: Json) => unknown | Promise<unknown>); // Detectors over the Neuron's RAW output - named detects* to stay // distinct from the Dendrite's on* (which consume inbound Signals). // Return the intent's fields to match, null to fall through. // Precedence: error -> clarification -> permission -> output. detectsOutput(fn: Recogniser): Recogniser; detectsClarification(fn: Recogniser): Recogniser; detectsPermission(fn: Recogniser): Recogniser; detectsError(fn: Recogniser): Recogniser; // Inherited from LifecycleHooks: onConnect(fn); // after the hosting Dendrite emits REGISTER onRefresh(fn); // each heartbeat tick onSchedule(everyMs, fn); // periodic background task } // A Neuron is a plain function - sync or async. The optional third argument // carries the Engram helpers (recall / imprint) when engrams are bound: type NeuronFn = (input: Json, context: unknown[], helpers?: NeuronHelpers) => Promise<Json> | Json;
Constructor options
| Option | Type | Description |
|---|---|---|
| neuronId | string | The address other processes use to reach this Neuron. Unique within a namespace. |
| neuronFn | NeuronFn | The Neuron itself: (input, context) => Json | Promise<Json>. May return clarify(...). |
| capabilities? | string[] | Tags advertised in REGISTER for routing. Defaults to []. |
| version? | string | Optional version string surfaced in REGISTER. Defaults to undefined. |
| contextFetcher? | ContextFetcher | Resolver for payload.context_ref. Defaults to a no-op returning []. |
Source-paired factories
The second way to build an Axon. The static factories - Axon.ollama(), Axon.huggingface(), Axon.openai(), Axon.anthropic(), Axon.mcp() - create the provider-backed Neuron and the Axon in one call, mirroring Python’s classmethods. The signature is Axon.source(neuronId, sourceOpts, axonExtra?): source options go in the second argument, Axon options (capabilities, version, engrams, ...) in the third.
import { Axon } from "@cosmonapse/sdk"; // One call: Neuron factory + Axon wiring + recogniser. The third argument // (AxonExtra) carries the Axon-side options: capabilities, version, // neuronKind, contextFetcher, outputParser, engrams. const chat = Axon.huggingface("llama", { endpoint: "https://router.huggingface.co", model: "meta-llama/Llama-3.1-8B-Instruct", apiKey: process.env.HF_TOKEN, useChatApi: true }, { capabilities: ["chat"] }); const cloud = Axon.openai("gpt", { model: "gpt-4o" }); // apiKey falls back to OPENAI_API_KEY const local = Axon.ollama("chat", { model: "llama3" }); const claude = Axon.anthropic("claude", { model: "claude-sonnet-4-6" }); const files = Axon.mcp("files", { server: "filesystem", args: ["/data"] }); // Each factory wires the source family's recogniser (parseLlmIntents / // parseMcpIntents), so the model can signal CLARIFICATION / PERMISSION / // ERROR via a {"cosmo": ...} intent block - pass an explicit // outputParser (or none) in AxonExtra to override.
Example
import { Axon, clarify } from "@cosmonapse/sdk"; const axon = new Axon({ neuronId: "answerer", neuronFn: async (input, context) => { if (!input.q) return clarify("What should I answer?"); return { answer: String(input.q).toUpperCase() }; }, capabilities: ["text", "qa"], version: "1.2.0", });
Have a feature in mind?
The protocol, SDKs, and CLI are still pre-1.0. If something here is missing, ambiguous, or wrong - open an issue and propose a change. Every breaking change is debated in DECISIONS.md first.