@perstack/runtime 0.0.38 → 0.0.39

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 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
+
@@ -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 { ToolDefinition, SkillType, McpStdioSkill, McpSseSkill, InteractiveSkill, Expert, SkillManagerParams, TextPart, ImageInlinePart, FileInlinePart, RunSetting, Step, Checkpoint, RunEvent, RunParamsInput, ProviderConfig, ProviderName, Usage } from '@perstack/core';
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
- constructor(params: SkillManagerParams);
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 function run(runInput: RunParamsInput, options?: {
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, defaultEventListener, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };
5370
+ export { RUNTIME_VERSION, type RunActor, type RunSnapshot, StateMachineLogics, calculateContextWindowUsage, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };