@perstack/runtime 0.0.38 → 0.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -0
- package/dist/src/index.d.ts +20 -18
- package/dist/src/index.js +168 -305
- package/dist/src/index.js.map +1 -1
- package/package.json +16 -16
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# @perstack/runtime
|
|
2
|
+
|
|
3
|
+
The **Execution Engine** for Perstack agents.
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @perstack/runtime
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
The primary entry point is the `run` function. It takes a `RunSetting` object and an optional `RunOptions` object.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { run } from "@perstack/runtime"
|
|
19
|
+
import { type RunSetting } from "@perstack/core"
|
|
20
|
+
|
|
21
|
+
// Configure the run
|
|
22
|
+
const setting: RunSetting = {
|
|
23
|
+
runId: "run-123",
|
|
24
|
+
expertKey: "researcher",
|
|
25
|
+
input: { text: "Research quantum computing" },
|
|
26
|
+
// ... configuration for model, experts, etc.
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Execute the run
|
|
30
|
+
const finalCheckpoint = await run({ setting }, {
|
|
31
|
+
eventListener: (event) => {
|
|
32
|
+
console.log(`[${event.type}]`, event)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Event Object
|
|
38
|
+
|
|
39
|
+
The `eventListener` callback receives a `RunEvent` object, which provides granular details about the execution.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
type RunEvent = {
|
|
43
|
+
type: EventType // e.g., "startRun", "callTool"
|
|
44
|
+
id: string // Unique event ID
|
|
45
|
+
timestamp: number // Unix timestamp
|
|
46
|
+
runId: string // ID of the current run
|
|
47
|
+
stepNumber: number // Current step number
|
|
48
|
+
// ... plus payload specific to the event type
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
You can narrow down the event type to access specific properties:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
eventListener: (event) => {
|
|
56
|
+
if (event.type === "callTool") {
|
|
57
|
+
// event is now narrowed to the callTool event type
|
|
58
|
+
console.log(`Executing tool: ${event.toolCall.name}`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Package Responsibilities
|
|
64
|
+
|
|
65
|
+
1. **Expert Realization**: The engine that brings declaratively defined Experts to life, realizing the desired state described by the developer.
|
|
66
|
+
2. **Lifecycle**: Drives the main execution loop of the agent (Reasoning -> Act -> Observe, repeat).
|
|
67
|
+
3. **State Management**: Maintains the canonical state of an execution in the form of **Checkpoints**, enabling pause/resume and time-travel.
|
|
68
|
+
4. **Skill Provider**: Provides the client side of the **Model Context Protocol (MCP)** to securely execute tools.
|
|
69
|
+
5. **Expert Delegation**: Implements the protocol for **Expert-to-Expert delegation**, allowing agents to call each other.
|
|
70
|
+
|
|
71
|
+
## Architecture
|
|
72
|
+
|
|
73
|
+
The runtime orchestrates the interaction between the user's definition of an Expert and the actual execution environment.
|
|
74
|
+
|
|
75
|
+
```mermaid
|
|
76
|
+
graph TD
|
|
77
|
+
Author((Author)) -->|Defines| Def[Expert Definition]
|
|
78
|
+
User((User)) -->|Provides| Input[Input / Query]
|
|
79
|
+
|
|
80
|
+
subgraph Runtime [Runtime Engine]
|
|
81
|
+
subgraph Instance [Expert Instance]
|
|
82
|
+
State[State Machine]
|
|
83
|
+
Context[Execution Context]
|
|
84
|
+
|
|
85
|
+
subgraph Skills [Skill Layer]
|
|
86
|
+
SM[Skill Manager]
|
|
87
|
+
MCP[MCP Client]
|
|
88
|
+
MCPServer[MCP Server]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
subgraph External [External World]
|
|
94
|
+
LLM[LLM Provider]
|
|
95
|
+
Workspace[Workspace / FS]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
Def -->|Instantiates| Instance
|
|
99
|
+
Input -->|Starts| Instance
|
|
100
|
+
|
|
101
|
+
State -->|Reasoning| LLM
|
|
102
|
+
State -->|Act| SM
|
|
103
|
+
SM -->|Execute| MCP
|
|
104
|
+
MCP -->|Connect| MCPServer
|
|
105
|
+
MCPServer -->|Access| Workspace
|
|
106
|
+
|
|
107
|
+
SM -.->|Delegate| Instance2["Expert Instance (Delegate)"]
|
|
108
|
+
|
|
109
|
+
State ~~~ Context
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Core Concepts
|
|
113
|
+
|
|
114
|
+
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.
|
|
115
|
+
|
|
116
|
+
```mermaid
|
|
117
|
+
graph LR
|
|
118
|
+
subgraph Step1 [Step 1: The Process]
|
|
119
|
+
direction LR
|
|
120
|
+
E1(Event: Start) --> E2(Event: Reasoning) --> E3(Event: Act) --> CP1((Checkpoint 1))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
subgraph Step2 [Step 2: The Process]
|
|
124
|
+
direction LR
|
|
125
|
+
CP1 --> E4(Event: Start) --> E5(Event: Reasoning) --> CP2((Checkpoint 2))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
style CP1 fill:#f96,stroke:#333,stroke-width:4px
|
|
129
|
+
style CP2 fill:#f96,stroke:#333,stroke-width:4px
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 1. Events
|
|
133
|
+
**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".
|
|
134
|
+
|
|
135
|
+
### 2. Step
|
|
136
|
+
A **Step** is the continuous process that connects these events. It represents one atomic cycle of the agent's loop (Reasoning -> Act -> Observe, repeat).
|
|
137
|
+
|
|
138
|
+
### 3. Checkpoint
|
|
139
|
+
A **Checkpoint** is the immutable result at the end of a Step. It serves as the anchor point that:
|
|
140
|
+
- Finalizes the previous Step.
|
|
141
|
+
- Becomes the starting point for the next Step.
|
|
142
|
+
- Allows the execution to be paused, resumed, or forked from that exact moment.
|
|
143
|
+
|
|
144
|
+
## Internal State Machine
|
|
145
|
+
|
|
146
|
+
The runtime ensures deterministic execution through a strictly defined state machine.
|
|
147
|
+
|
|
148
|
+
```mermaid
|
|
149
|
+
stateDiagram-v2
|
|
150
|
+
[*] --> Init
|
|
151
|
+
Init --> PreparingForStep: startRun
|
|
152
|
+
PreparingForStep --> GeneratingToolCall: startGeneration
|
|
153
|
+
|
|
154
|
+
GeneratingToolCall --> CallingTool: callTool
|
|
155
|
+
GeneratingToolCall --> CallingInteractiveTool: callInteractiveTool
|
|
156
|
+
GeneratingToolCall --> CallingDelegate: callDelegate
|
|
157
|
+
GeneratingToolCall --> FinishingStep: retry
|
|
158
|
+
|
|
159
|
+
CallingTool --> ResolvingToolResult: resolveToolResult
|
|
160
|
+
CallingTool --> ResolvingThought: resolveThought
|
|
161
|
+
CallingTool --> ResolvingPdfFile: resolvePdfFile
|
|
162
|
+
CallingTool --> ResolvingImageFile: resolveImageFile
|
|
163
|
+
CallingTool --> GeneratingRunResult: attemptCompletion
|
|
164
|
+
|
|
165
|
+
ResolvingToolResult --> FinishingStep: finishToolCall
|
|
166
|
+
ResolvingThought --> FinishingStep: finishToolCall
|
|
167
|
+
ResolvingPdfFile --> FinishingStep: finishToolCall
|
|
168
|
+
ResolvingImageFile --> FinishingStep: finishToolCall
|
|
169
|
+
|
|
170
|
+
GeneratingRunResult --> Stopped: completeRun
|
|
171
|
+
GeneratingRunResult --> FinishingStep: retry
|
|
172
|
+
|
|
173
|
+
CallingInteractiveTool --> Stopped: stopRunByInteractiveTool
|
|
174
|
+
CallingDelegate --> Stopped: stopRunByDelegate
|
|
175
|
+
|
|
176
|
+
FinishingStep --> PreparingForStep: continueToNextStep
|
|
177
|
+
FinishingStep --> Stopped: stopRunByExceededMaxSteps
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Events
|
|
181
|
+
Events trigger state transitions. They are emitted by the runtime logic or external inputs.
|
|
182
|
+
|
|
183
|
+
- **Lifecycle**: `startRun`, `startGeneration`, `continueToNextStep`, `completeRun`
|
|
184
|
+
- **Tool Execution**: `callTool`, `resolveToolResult`, `finishToolCall`
|
|
185
|
+
- **Special Types**: `resolveThought`, `resolvePdfFile`, `resolveImageFile`
|
|
186
|
+
- **Interruption**: `stopRunByInteractiveTool`, `stopRunByDelegate`, `stopRunByExceededMaxSteps`
|
|
187
|
+
- **Error Handling**: `retry`
|
|
188
|
+
|
|
189
|
+
## Checkpoint Status
|
|
190
|
+
|
|
191
|
+
The `status` field in a Checkpoint indicates the current state of the execution.
|
|
192
|
+
|
|
193
|
+
- **init**: The run has been created but not yet started.
|
|
194
|
+
- **proceeding**: The run is currently active and executing steps.
|
|
195
|
+
- **completed**: The run has finished successfully.
|
|
196
|
+
- **stoppedByInteractiveTool**: The run is paused, waiting for user input (e.g., confirmation or parameter entry).
|
|
197
|
+
- **stoppedByDelegate**: The run is paused, waiting for a delegated sub-agent to complete.
|
|
198
|
+
- **stoppedByExceededMaxSteps**: The run stopped because it reached the maximum allowed steps.
|
|
199
|
+
- **stoppedByError**: The run stopped due to an unrecoverable error.
|
|
200
|
+
|
|
201
|
+
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import * as xstate from 'xstate';
|
|
2
|
-
import { SnapshotFrom, ActorRefFrom } from 'xstate';
|
|
3
1
|
import * as _perstack_core from '@perstack/core';
|
|
4
|
-
import {
|
|
2
|
+
import { ProviderConfig, ProviderName, Usage, RunParamsInput, RunSetting, Checkpoint, Step, RunEvent, RuntimeEvent, ToolDefinition, SkillType, McpStdioSkill, McpSseSkill, InteractiveSkill, Expert, SkillManagerParams, TextPart, ImageInlinePart, FileInlinePart } from '@perstack/core';
|
|
5
3
|
import { LanguageModel } from 'ai';
|
|
4
|
+
import * as xstate from 'xstate';
|
|
5
|
+
import { SnapshotFrom, ActorRefFrom } from 'xstate';
|
|
6
|
+
|
|
7
|
+
declare function getModel(modelId: string, providerConfig: ProviderConfig): LanguageModel;
|
|
8
|
+
declare function getContextWindow(providerName: ProviderName, modelId: string): number | undefined;
|
|
9
|
+
declare function calculateContextWindowUsage(usage: Usage, contextWindow: number): number;
|
|
10
|
+
|
|
11
|
+
declare function run(runInput: RunParamsInput, options?: {
|
|
12
|
+
shouldContinueRun?: (setting: RunSetting, checkpoint: Checkpoint, step: Step) => Promise<boolean>;
|
|
13
|
+
retrieveCheckpoint?: (checkpointId: string) => Promise<Checkpoint>;
|
|
14
|
+
storeCheckpoint?: (checkpoint: Checkpoint, timestamp: number) => Promise<void>;
|
|
15
|
+
eventListener?: (event: RunEvent | RuntimeEvent) => void;
|
|
16
|
+
}): Promise<Checkpoint>;
|
|
17
|
+
declare function getRunDir(runId: string): string;
|
|
6
18
|
|
|
7
19
|
declare class SkillManager {
|
|
8
20
|
protected _toolDefinitions: ToolDefinition[];
|
|
@@ -17,7 +29,9 @@ declare class SkillManager {
|
|
|
17
29
|
private _mcpClient?;
|
|
18
30
|
private _params;
|
|
19
31
|
private _env;
|
|
20
|
-
|
|
32
|
+
private _runId;
|
|
33
|
+
private _eventListener?;
|
|
34
|
+
constructor(params: SkillManagerParams, runId: string, eventListener?: (event: RunEvent | RuntimeEvent) => void);
|
|
21
35
|
init(): Promise<void>;
|
|
22
36
|
isInitialized(): boolean;
|
|
23
37
|
private _performInit;
|
|
@@ -5351,18 +5365,6 @@ declare const StateMachineLogics: Record<Exclude<RunSnapshot["value"], "Stopped"
|
|
|
5351
5365
|
type RunActor = ActorRefFrom<typeof runtimeStateMachine>;
|
|
5352
5366
|
type RunSnapshot = SnapshotFrom<typeof runtimeStateMachine>;
|
|
5353
5367
|
|
|
5354
|
-
declare
|
|
5355
|
-
shouldContinueRun?: (setting: RunSetting, checkpoint: Checkpoint, step: Step) => Promise<boolean>;
|
|
5356
|
-
retrieveCheckpoint?: (checkpointId: string) => Promise<Checkpoint>;
|
|
5357
|
-
storeCheckpoint?: (checkpoint: Checkpoint, timestamp: number) => Promise<void>;
|
|
5358
|
-
eventListener?: (event: RunEvent) => Promise<void>;
|
|
5359
|
-
}): Promise<Checkpoint>;
|
|
5360
|
-
declare function getRunDir(runId: string): string;
|
|
5361
|
-
|
|
5362
|
-
declare function getModel(modelId: string, providerConfig: ProviderConfig): LanguageModel;
|
|
5363
|
-
declare function getContextWindow(providerName: ProviderName, modelId: string): number | undefined;
|
|
5364
|
-
declare function calculateContextWindowUsage(usage: Usage, contextWindow: number): number;
|
|
5365
|
-
|
|
5366
|
-
declare function defaultEventListener(e: RunEvent): Promise<void>;
|
|
5368
|
+
declare const RUNTIME_VERSION: string;
|
|
5367
5369
|
|
|
5368
|
-
export { type RunActor, type RunSnapshot, StateMachineLogics, calculateContextWindowUsage,
|
|
5370
|
+
export { RUNTIME_VERSION, type RunActor, type RunSnapshot, StateMachineLogics, calculateContextWindowUsage, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };
|