Perstack Runtime
npm install @perstack/runtimeThe Execution Engine for Perstack agents.
This package serves as the engine of Perstack. It orchestrates the lifecycle of an agent's execution, manages state, bridges the gap between LLMs and tools, and handles multi-agent coordination.
``bash`
npm install @perstack/runtime
The runtime can be executed as a standalone CLI:
`bash`
perstack-runtime run
| Option | Description |
| ----------------------- | ----------------------- |
| --config | Path to perstack.toml |--provider
| | LLM provider |--model
| | Model name |--max-steps
| | Maximum steps |--max-retries
| | Maximum retries |--timeout
| | Timeout in milliseconds |--job-id
| | Job ID |--run-id
| | Run ID |--env-path
| | Environment file paths |
`bash`
perstack-runtime run my-expert "What is the weather?" --config ./perstack.toml
Output is JSON events (one per line) to stdout.
The primary entry point is the run function. It takes a RunSetting object and an optional RunOptions object.
`typescript
import { run } from "@perstack/runtime"
import { type RunSetting } from "@perstack/core"
// Configure the run
const setting: RunSetting = {
model: "claude-sonnet-4-20250514",
providerConfig: { providerName: "anthropic", apiKey: "..." },
jobId: "job-123",
runId: "run-123",
expertKey: "researcher",
input: { text: "Research quantum computing" },
experts: { / ... / },
// ... other configuration
}
// Execute the job
const finalCheckpoint = await run({ setting }, {
eventListener: (event) => {
console.log([${event.type}], event)`
}
})
The eventListener callback receives a RunEvent object, which provides granular details about the execution.
`typescript`
type RunEvent = {
type: EventType // e.g., "startRun", "callTools"
id: string // Unique event ID
timestamp: number // Unix timestamp
jobId: string // ID of the Job
runId: string // ID of the current Run
stepNumber: number // Current step number within this Run
// ... plus payload specific to the event type
}
You can narrow down the event type to access specific properties:
`typescriptExecuting ${event.toolCalls.length} tools
eventListener: (event) => {
if (event.type === "callTools") {
// event is now narrowed to the callTools event type
console.log()`
}
}
1. Expert Realization: The engine that brings declaratively defined Experts to life, realizing the desired state described by the developer.
2. Lifecycle: Drives the main execution loop of the agent (Reasoning -> Act -> Observe, repeat).
3. State Management: Maintains the canonical state of an execution in the form of Checkpoints, enabling pause/resume and time-travel.
4. Skill Provider: Provides the client side of the Model Context Protocol (MCP) to securely execute tools.
5. Expert Delegation: Implements the protocol for Expert-to-Expert delegation, allowing agents to call each other.
The runtime manages skills through specialized Skill Managers. Each skill type has its own manager class:
| Type | Manager | Purpose |
| --------------- | ------------------------- | ----------------------------------- |
| MCP (stdio/SSE) | McpSkillManager | External tools via MCP protocol |InteractiveSkillManager
| Interactive | | User input tools (Coordinator only) |DelegateSkillManager
| Delegate | | Expert-to-Expert calls |
All managers extend BaseSkillManager which provides:init()
- — Initialize the skill (connect MCP servers, parse definitions)close()
- — Clean up resources (disconnect MCP servers)getToolDefinitions()
- — Get available toolscallTool()
- — Execute a tool call
Note: Interactive skills are only available to the Coordinator Expert. See Experts documentation for details.
`
getSkillManagers(expert, experts, setting)
│
├─► Initialize MCP skills (parallel)
│ └─► McpSkillManager × N
│
├─► Initialize Interactive skills (Coordinator only)
│ └─► InteractiveSkillManager × N
│
└─► Initialize Delegate skills (parallel)
└─► DelegateSkillManager × N
Result: Record
`
If any skill fails to initialize, all previously initialized skills are cleaned up before throwing.
The runtime orchestrates the interaction between the user's definition of an Expert and the actual execution environment.
`mermaid
graph TD
Author((Author)) -->|Defines| Def[Expert Definition]
User((User)) -->|Provides| Input[Input / Query]
subgraph Runtime [Runtime Engine]
subgraph Job [Job]
subgraph Run1 [Run: Coordinator]
State[State Machine]
Context[Execution Context]
subgraph Skills [Skill Layer]
SM[Skill Manager]
MCP[MCP Client]
MCPServer[MCP Server]
end
end
Run2["Run: Delegate A"]
Run3["Run: Delegate B"]
end
end
subgraph External [External World]
LLM[LLM Provider]
Workspace[Workspace / FS]
end
Def -->|Instantiates| Run1
Input -->|Starts| Run1
State -->|Reasoning| LLM
State -->|Act| SM
SM -->|Execute| MCP
MCP -->|Connect| MCPServer
MCPServer -->|Access| Workspace
SM -.->|Delegate| Run2
SM -.->|Delegate| Run3
`
``
Job (jobId)
├── Run 1 (Coordinator Expert)
│ └── Checkpoints...
├── Run 2 (Delegated Expert A)
│ └── Checkpoints...
└── Run 3 (Delegated Expert B)
└── Checkpoints...
| Concept | Description |
| -------------- | -------------------------------------------- |
| Job | Top-level execution unit. Contains all Runs. |
| Run | Single Expert execution. |
| Checkpoint | Snapshot at step end. Enables pause/resume. |
For details on step counting, Coordinator vs. Delegated Expert differences, and the full execution model, see Runtime.
The runtime's execution model can be visualized as a timeline where Events are points, Steps are the lines connecting them, and Checkpoints are the anchors.
`mermaid
graph LR
subgraph Step1 [Step 1: The Process]
direction LR
E1(Event: Start) --> E2(Event: Reasoning) --> E3(Event: Act) --> CP1((Checkpoint 1))
end
subgraph Step2 [Step 2: The Process]
direction LR
CP1 --> E4(Event: Start) --> E5(Event: Reasoning) --> CP2((Checkpoint 2))
end
style CP1 fill:#f96,stroke:#333,stroke-width:4px
style CP2 fill:#f96,stroke:#333,stroke-width:4px
`
#### 1. Events
Events are granular moments in time that occur during execution. They represent specific actions or observations, such as "started reasoning", "called tool", or "finished tool".
#### 2. Step
A Step is the continuous process that connects these events. It represents one atomic cycle of the agent's loop (Reasoning -> Act -> Observe, repeat).
#### 3. Checkpoint
A Checkpoint is the immutable result at the end of a Step. It serves as the anchor point that:
- Finalizes the previous Step.
- Becomes the starting point for the next Step.
- Allows the execution to be paused, resumed, or forked from that exact moment.
The runtime ensures deterministic execution through a strictly defined state machine.
`mermaid
stateDiagram-v2
[*] --> Init
Init --> PreparingForStep: startRun
Init --> ResumingFromStop: resumeFromStop
PreparingForStep --> GeneratingToolCall: startGeneration
ResumingFromStop --> CallingInteractiveTools: proceedToInteractiveTools
ResumingFromStop --> ResolvingToolResult: resolveToolResults
GeneratingToolCall --> CallingMcpTools: callTools
GeneratingToolCall --> FinishingStep: retry
GeneratingToolCall --> Stopped: stopRunByError
GeneratingToolCall --> Stopped: completeRun
CallingMcpTools --> ResolvingToolResult: resolveToolResults
CallingMcpTools --> GeneratingRunResult: attemptCompletion
CallingMcpTools --> CallingDelegates: finishMcpTools
CallingMcpTools --> Stopped: completeRun
CallingDelegates --> Stopped: stopRunByDelegate
CallingDelegates --> CallingInteractiveTools: skipDelegates
CallingInteractiveTools --> Stopped: stopRunByInteractiveTool
CallingInteractiveTools --> ResolvingToolResult: resolveToolResults
ResolvingToolResult --> FinishingStep: finishToolCall
GeneratingRunResult --> Stopped: completeRun
GeneratingRunResult --> FinishingStep: retry
GeneratingRunResult --> Stopped: stopRunByError
FinishingStep --> PreparingForStep: continueToNextStep
FinishingStep --> Stopped: stopRunByExceededMaxSteps
`
- Lifecycle: startRun, resumeFromStop, startGeneration, continueToNextStep, completeRuncallTools
- Tool Execution: , resolveToolResults, finishToolCall, finishMcpTools, attemptCompletionskipDelegates
- Delegation: (internal state transition)proceedToInteractiveTools
- Interactive: (for resuming to interactive tools)stopRunByInteractiveTool
- Interruption: , stopRunByDelegate, stopRunByExceededMaxSteps, stopRunByErrorretry
- Error Handling:
The status field in a Checkpoint indicates the current state:
- init, proceeding — Run lifecyclecompleted
- — Task finished successfullystoppedByInteractiveTool
- , stoppedByDelegate — Waiting for external inputstoppedByExceededMaxSteps
- , stoppedByError, stoppedByCancellation` — Run stopped
For stop reasons and error handling, see Error Handling.
- Runtime — Full execution model
- State Management — Jobs, Runs, and Checkpoints
- Running Experts — CLI usage