Core Concepts
AgentVM has five building blocks. Understanding how they fit together is the key to using it well.
Kernel
The Kernel is the central orchestrator. Everything goes through it.
const kernel = new Kernel({ name: 'my-app' });The kernel manages the agent registry, process table, memory bus, tool router, message broker, and scheduler. It's the single object you pass around.
Agent
An Agent is a blueprint — a definition of what something can do. It's not running yet.
const agent = new Agent({
name: 'analyzer',
description: 'Analyzes data and produces reports',
tools: ['http_fetch', 'file_read'], // tools it can access
memory: { persistent: true }, // memory config
contract: { // input/output types
input: { type: 'string' },
output: { type: 'object' },
},
handler: async (ctx) => { // what it actually does
// ...
return { analysis: 'done' };
},
});Think of an Agent like a class definition, not an instance.
Process
A Process is a running instance of an agent. You can have multiple processes from the same agent.
kernel.register(agent);
const proc1 = await kernel.spawn('analyzer');
const proc2 = await kernel.spawn('analyzer'); // separate instance
// Each has its own memory, its own lifecycle
await kernel.execute(proc1.id, { task: 'analyze sales' });
await kernel.execute(proc2.id, { task: 'analyze inventory' });Processes have a lifecycle:
created → starting → running → paused → terminated
↓
crashedYou can pause, resume, and terminate processes:
await kernel.pause(proc.id);
await kernel.resume(proc.id);
await kernel.terminate(proc.id);ExecutionContext
When a process runs, its handler receives an ExecutionContext — the agent's window into the world:
handler: async (ctx) => {
ctx.processId; // this process's ID
ctx.agentName; // agent name
ctx.input; // the task input
ctx.memory.get('key'); // read from memory
ctx.memory.set('k', v); // write to memory
ctx.useTool('name', {}); // call a tool
ctx.publish('channel', data); // publish a message
ctx.emit('event', data); // emit an event
ctx.signal; // AbortSignal for cancellation
}Everything an agent needs is in the context. No global state, no singletons.
ExecutionResult
Every kernel.execute() returns a result:
const result = await kernel.execute(proc.id, { task: 'work' });
result.processId; // process that ran
result.agentName; // agent name
result.output; // whatever the handler returned
result.duration; // wall-clock milliseconds
result.tokensUsed; // LLM tokens (if applicable)
result.events; // structured events emitted during executionHow They Fit Together
register() spawn() execute()
Agent ──────────────→ Kernel ────────────→ Process ────────────→ Result
│ │
├── MemoryBus ├── ExecutionContext
├── ToolRouter │ ├── memory
├── MessageBroker │ ├── useTool
└── Scheduler │ ├── publish
│ └── emit
│
handler(ctx)
│
↓
return outputNext Steps
- Agents & Processes — Lifecycle management, metadata, events
- Tools — Register, permission, rate limit
- Memory — Backends, persistence, shared state
