gamelan
v0.0.11
Published
Composable agent sessions for TypeScript — Rust kernel via WebAssembly
Maintainers
Readme
gamelan
Composable runtime for agent systems with a formally verified kernel.
The kernel (VM, session lifecycle, coordinator) is implemented in Rust, compiled to WebAssembly, and shipped as a single universal artifact inside this package — no per-platform native binaries, no install-time compilation, runs in Node / Bun / Deno without setup. This package provides the TypeScript runtime: async dispatch, source/check protocols, persistence, streaming, and multi-agent coordination.
Install
npm install gamelanQuick start
import { AgentSession } from "gamelan";
import { AnthropicSource } from "gamelan";
const session = new AgentSession({
sources: {
llm: new AnthropicSource({ model: "claude-sonnet-4-20250514" }),
},
});
const events = await session.turn("What is the reactor pattern?");With tools
import { AgentSession, ToolSource, toolText } from "gamelan";
import { AnthropicSource } from "gamelan";
const tools = new ToolSource();
tools.register("read_file", "Read a file from disk", {
type: "object",
properties: { path: { type: "string" } },
required: ["path"],
}, async (args) => toolText(readFileSync(args.path, "utf-8")));
const session = new AgentSession({
sources: {
llm: new AnthropicSource({ model: "claude-sonnet-4-20250514" }),
tools,
},
});
const events = await session.turn("Read the README");Multi-agent
import { NetworkClient, stdlib } from "gamelan";
const client = new NetworkClient(
{
parent: [parentDef, { llm: claude, tools: delegSource }],
child: [childDef, { llm: gpt, tools: searchSource }],
},
{
delegationRoutes: [["parent", "child"]],
entryPoint: "parent",
},
);
for await (const event of client.sendMessage("Research Rust ownership")) {
console.log(event);
}Sources are per-agent. Each agent carries its own AgentDef (declarative config) and source map (runtime bindings). Config is validated at construction per client.qnt.
Architecture
AgentSession (high-level convenience)
runTurn (turn driver with callbacks)
SessionRunner (pure fold — Rust kernel via NAPI)
NetworkClient (multi-agent)
NetworkRunner (coordinator fold)
AgentRunner per agent (turn loop + per-agent sources)- Kernel (Rust via NAPI): session fold, coordinator, VM, transducers
- Runtime (TypeScript): turn driver, sources, checks, delegation, streaming
- Spec:
executor.qnt(I/O contract),runner.qnt(turn loop),client.qnt(multi-agent config)
Extension model
AgentSession is the high-level API. For lower-level control, use turnDriver (async generator) or runTurn (callback-based):
import { turnDriver, runTurn } from "gamelan";
// Async generator — step-by-step control
const driver = turnDriver(session, resolveSource, tag, data);
for await (const step of driver) {
// handle DispatchReady, CheckNeeded, Complete
}
// Callback-based — convenience wrapper
const events = await runTurn(session, router, checks, tag, data, {
dispatch: myDispatch,
check: myCheck,
observe: myObserve,
});Observability
Optional OpenTelemetry integration emits invoke_agent and execute_tool spans following GenAI semantic conventions. Lives in the gamelan/otel subpath so apps that don't use it pay nothing in their bundle.
import { AgentRunner } from "gamelan";
import { withTracing, configureTracing } from "gamelan/otel";
await configureTracing({ serviceName: "my-agent" });
const runner = withTracing(
AgentRunner.fromSessionCreated(transducers, boot),
{ agentName: "researcher" },
);LLM-level chat spans come from upstream provider instrumentation — register TraceLoop's OpenLLMetry packages (@traceloop/instrumentation-anthropic, @traceloop/instrumentation-openai) before importing the SDK and they nest under invoke_agent automatically.
A complete runnable example exporting to a local OTLP collector lives at examples/otel-anthropic-e2e.mjs. See docs/observability.md for the full guide — install matrix, content-capture options, and troubleshooting.
License
Apache-2.0
