@perstack/runtime 0.0.62 → 0.0.63
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 +73 -44
- package/dist/src/index.d.ts +53 -33
- package/dist/src/index.js +424 -141
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -3
package/dist/src/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { readFile, mkdir, writeFile } from 'fs/promises';
|
|
3
|
+
import path2 from 'path';
|
|
4
|
+
import { jobSchema, runSettingSchema, checkpointSchema, knownModels, stopRunByDelegate, stopRunByInteractiveTool, resolveToolResults, attemptCompletion, callDelegate, callInteractiveTool, stopRunByExceededMaxSteps, continueToNextStep, retry, completeRun, callTools, startRun, resumeToolCalls, finishAllToolCalls, startGeneration, finishToolCall, runParamsSchema, createRuntimeEvent } from '@perstack/core';
|
|
1
5
|
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
|
|
2
6
|
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
3
7
|
import { createAzure } from '@ai-sdk/azure';
|
|
@@ -5,11 +9,8 @@ import { createDeepSeek } from '@ai-sdk/deepseek';
|
|
|
5
9
|
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
6
10
|
import { createVertex } from '@ai-sdk/google-vertex';
|
|
7
11
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
8
|
-
import { knownModels, stopRunByDelegate, stopRunByInteractiveTool, resolveToolResults, attemptCompletion, callDelegate, callInteractiveTool, stopRunByExceededMaxSteps, continueToNextStep, retry, completeRun, callTools, startRun, resumeToolCalls, finishAllToolCalls, startGeneration, finishToolCall, runParamsSchema, createRuntimeEvent, checkpointSchema, runSettingSchema } from '@perstack/core';
|
|
9
12
|
import { createOllama } from 'ollama-ai-provider-v2';
|
|
10
13
|
import { createId } from '@paralleldrive/cuid2';
|
|
11
|
-
import { readdir, readFile, mkdir, writeFile } from 'fs/promises';
|
|
12
|
-
import path from 'path';
|
|
13
14
|
import { setup, assign, createActor } from 'xstate';
|
|
14
15
|
import { generateText, tool, jsonSchema } from 'ai';
|
|
15
16
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
@@ -21,7 +22,208 @@ import { ApiV1Client } from '@perstack/api-client/v1';
|
|
|
21
22
|
|
|
22
23
|
// package.json
|
|
23
24
|
var package_default = {
|
|
24
|
-
version: "0.0.
|
|
25
|
+
version: "0.0.63"};
|
|
26
|
+
function getJobsDir() {
|
|
27
|
+
return `${process.cwd()}/perstack/jobs`;
|
|
28
|
+
}
|
|
29
|
+
function getJobDir(jobId) {
|
|
30
|
+
return `${getJobsDir()}/${jobId}`;
|
|
31
|
+
}
|
|
32
|
+
function storeJob(job) {
|
|
33
|
+
const jobDir = getJobDir(job.id);
|
|
34
|
+
if (!existsSync(jobDir)) {
|
|
35
|
+
mkdirSync(jobDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
const jobPath = path2.resolve(jobDir, "job.json");
|
|
38
|
+
writeFileSync(jobPath, JSON.stringify(job, null, 2));
|
|
39
|
+
}
|
|
40
|
+
function retrieveJob(jobId) {
|
|
41
|
+
const jobDir = getJobDir(jobId);
|
|
42
|
+
const jobPath = path2.resolve(jobDir, "job.json");
|
|
43
|
+
if (!existsSync(jobPath)) {
|
|
44
|
+
return void 0;
|
|
45
|
+
}
|
|
46
|
+
const content = readFileSync(jobPath, "utf-8");
|
|
47
|
+
return jobSchema.parse(JSON.parse(content));
|
|
48
|
+
}
|
|
49
|
+
function getAllJobs() {
|
|
50
|
+
const jobsDir = getJobsDir();
|
|
51
|
+
if (!existsSync(jobsDir)) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const jobDirNames = readdirSync(jobsDir, { withFileTypes: true }).filter((dir) => dir.isDirectory()).map((dir) => dir.name);
|
|
55
|
+
if (jobDirNames.length === 0) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const jobs = [];
|
|
59
|
+
for (const jobDirName of jobDirNames) {
|
|
60
|
+
const jobPath = path2.resolve(jobsDir, jobDirName, "job.json");
|
|
61
|
+
if (!existsSync(jobPath)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const content = readFileSync(jobPath, "utf-8");
|
|
66
|
+
jobs.push(jobSchema.parse(JSON.parse(content)));
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return jobs.sort((a, b) => b.startedAt - a.startedAt);
|
|
71
|
+
}
|
|
72
|
+
function createInitialJob(jobId, expertKey, maxSteps) {
|
|
73
|
+
return {
|
|
74
|
+
id: jobId,
|
|
75
|
+
status: "running",
|
|
76
|
+
coordinatorExpertKey: expertKey,
|
|
77
|
+
totalSteps: 0,
|
|
78
|
+
maxSteps,
|
|
79
|
+
usage: {
|
|
80
|
+
inputTokens: 0,
|
|
81
|
+
outputTokens: 0,
|
|
82
|
+
reasoningTokens: 0,
|
|
83
|
+
totalTokens: 0,
|
|
84
|
+
cachedInputTokens: 0
|
|
85
|
+
},
|
|
86
|
+
startedAt: Date.now()
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async function createDefaultFileSystem() {
|
|
90
|
+
const fs = await import('fs');
|
|
91
|
+
const fsPromises = await import('fs/promises');
|
|
92
|
+
return {
|
|
93
|
+
existsSync: fs.existsSync,
|
|
94
|
+
mkdir: async (p, options) => {
|
|
95
|
+
await fsPromises.mkdir(p, options);
|
|
96
|
+
},
|
|
97
|
+
readFile: fsPromises.readFile,
|
|
98
|
+
writeFile: fsPromises.writeFile
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function defaultGetRunDir(jobId, runId) {
|
|
102
|
+
return `${process.cwd()}/perstack/jobs/${jobId}/runs/${runId}`;
|
|
103
|
+
}
|
|
104
|
+
async function storeRunSetting(setting, fs, getRunDir = defaultGetRunDir) {
|
|
105
|
+
const fileSystem = fs ?? await createDefaultFileSystem();
|
|
106
|
+
const runDir = getRunDir(setting.jobId, setting.runId);
|
|
107
|
+
if (fileSystem.existsSync(runDir)) {
|
|
108
|
+
const runSettingPath = path2.resolve(runDir, "run-setting.json");
|
|
109
|
+
const runSetting = runSettingSchema.parse(
|
|
110
|
+
JSON.parse(await fileSystem.readFile(runSettingPath, "utf-8"))
|
|
111
|
+
);
|
|
112
|
+
runSetting.updatedAt = Date.now();
|
|
113
|
+
await fileSystem.writeFile(runSettingPath, JSON.stringify(runSetting), "utf-8");
|
|
114
|
+
} else {
|
|
115
|
+
await fileSystem.mkdir(runDir, { recursive: true });
|
|
116
|
+
await fileSystem.writeFile(
|
|
117
|
+
path2.resolve(runDir, "run-setting.json"),
|
|
118
|
+
JSON.stringify(setting),
|
|
119
|
+
"utf-8"
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function getAllRuns() {
|
|
124
|
+
const jobsDir = getJobsDir();
|
|
125
|
+
if (!existsSync(jobsDir)) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const jobDirNames = readdirSync(jobsDir, { withFileTypes: true }).filter((dir) => dir.isDirectory()).map((dir) => dir.name);
|
|
129
|
+
if (jobDirNames.length === 0) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
const runs = [];
|
|
133
|
+
for (const jobDirName of jobDirNames) {
|
|
134
|
+
const runsDir = path2.resolve(jobsDir, jobDirName, "runs");
|
|
135
|
+
if (!existsSync(runsDir)) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const runDirNames = readdirSync(runsDir, { withFileTypes: true }).filter((dir) => dir.isDirectory()).map((dir) => dir.name);
|
|
139
|
+
for (const runDirName of runDirNames) {
|
|
140
|
+
const runSettingPath = path2.resolve(runsDir, runDirName, "run-setting.json");
|
|
141
|
+
if (!existsSync(runSettingPath)) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const content = readFileSync(runSettingPath, "utf-8");
|
|
146
|
+
runs.push(runSettingSchema.parse(JSON.parse(content)));
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return runs.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/default-store.ts
|
|
155
|
+
function getCheckpointDir(jobId) {
|
|
156
|
+
return `${getJobDir(jobId)}/checkpoints`;
|
|
157
|
+
}
|
|
158
|
+
function getCheckpointPath(jobId, checkpointId) {
|
|
159
|
+
return `${getCheckpointDir(jobId)}/${checkpointId}.json`;
|
|
160
|
+
}
|
|
161
|
+
async function defaultRetrieveCheckpoint(jobId, checkpointId) {
|
|
162
|
+
const checkpointPath = getCheckpointPath(jobId, checkpointId);
|
|
163
|
+
if (!existsSync(checkpointPath)) {
|
|
164
|
+
throw new Error(`checkpoint not found: ${checkpointId}`);
|
|
165
|
+
}
|
|
166
|
+
const checkpoint = await readFile(checkpointPath, "utf8");
|
|
167
|
+
return checkpointSchema.parse(JSON.parse(checkpoint));
|
|
168
|
+
}
|
|
169
|
+
async function defaultStoreCheckpoint(checkpoint) {
|
|
170
|
+
const { id, jobId } = checkpoint;
|
|
171
|
+
const checkpointDir = getCheckpointDir(jobId);
|
|
172
|
+
await mkdir(checkpointDir, { recursive: true });
|
|
173
|
+
await writeFile(getCheckpointPath(jobId, id), JSON.stringify(checkpoint));
|
|
174
|
+
}
|
|
175
|
+
async function defaultStoreEvent(event) {
|
|
176
|
+
const { timestamp, jobId, runId, stepNumber, type } = event;
|
|
177
|
+
const runDir = defaultGetRunDir(jobId, runId);
|
|
178
|
+
const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
|
|
179
|
+
await mkdir(runDir, { recursive: true });
|
|
180
|
+
await writeFile(eventPath, JSON.stringify(event));
|
|
181
|
+
}
|
|
182
|
+
function getCheckpointsByJobId(jobId) {
|
|
183
|
+
const checkpointDir = getCheckpointDir(jobId);
|
|
184
|
+
if (!existsSync(checkpointDir)) {
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
const files = readdirSync(checkpointDir).filter((file) => file.endsWith(".json"));
|
|
188
|
+
const checkpoints = [];
|
|
189
|
+
for (const file of files) {
|
|
190
|
+
try {
|
|
191
|
+
const content = readFileSync(path2.resolve(checkpointDir, file), "utf-8");
|
|
192
|
+
checkpoints.push(checkpointSchema.parse(JSON.parse(content)));
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return checkpoints.sort((a, b) => a.stepNumber - b.stepNumber);
|
|
197
|
+
}
|
|
198
|
+
function getEventsByRun(jobId, runId) {
|
|
199
|
+
const runDir = defaultGetRunDir(jobId, runId);
|
|
200
|
+
if (!existsSync(runDir)) {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
return readdirSync(runDir).filter((file) => file.startsWith("event-")).map((file) => {
|
|
204
|
+
const [_, timestamp, stepNumber, type] = file.split(".")[0].split("-");
|
|
205
|
+
return { timestamp: Number(timestamp), stepNumber: Number(stepNumber), type };
|
|
206
|
+
}).sort((a, b) => a.stepNumber - b.stepNumber);
|
|
207
|
+
}
|
|
208
|
+
function getEventContents(jobId, runId, maxStepNumber) {
|
|
209
|
+
const runDir = defaultGetRunDir(jobId, runId);
|
|
210
|
+
if (!existsSync(runDir)) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
const eventFiles = readdirSync(runDir).filter((file) => file.startsWith("event-")).map((file) => {
|
|
214
|
+
const [_, timestamp, step, type] = file.split(".")[0].split("-");
|
|
215
|
+
return { file, timestamp: Number(timestamp), stepNumber: Number(step), type };
|
|
216
|
+
}).filter((e) => maxStepNumber === void 0 || e.stepNumber <= maxStepNumber).sort((a, b) => a.timestamp - b.timestamp);
|
|
217
|
+
const events = [];
|
|
218
|
+
for (const { file } of eventFiles) {
|
|
219
|
+
try {
|
|
220
|
+
const content = readFileSync(path2.resolve(runDir, file), "utf-8");
|
|
221
|
+
events.push(JSON.parse(content));
|
|
222
|
+
} catch {
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return events;
|
|
226
|
+
}
|
|
25
227
|
function getModel(modelId, providerConfig) {
|
|
26
228
|
switch (providerConfig.providerName) {
|
|
27
229
|
case "anthropic": {
|
|
@@ -142,6 +344,7 @@ function sumUsage(a, b) {
|
|
|
142
344
|
function createInitialCheckpoint(checkpointId, params) {
|
|
143
345
|
return {
|
|
144
346
|
id: checkpointId,
|
|
347
|
+
jobId: params.jobId,
|
|
145
348
|
runId: params.runId,
|
|
146
349
|
expert: {
|
|
147
350
|
key: params.expertKey,
|
|
@@ -185,6 +388,7 @@ function buildDelegationReturnState(currentSetting, resultCheckpoint, parentChec
|
|
|
185
388
|
interactiveToolCallResult: {
|
|
186
389
|
toolCallId,
|
|
187
390
|
toolName,
|
|
391
|
+
skillName: `delegate/${resultCheckpoint.expert.key}`,
|
|
188
392
|
text: delegateText.text
|
|
189
393
|
}
|
|
190
394
|
}
|
|
@@ -200,10 +404,11 @@ function buildDelegationReturnState(currentSetting, resultCheckpoint, parentChec
|
|
|
200
404
|
}
|
|
201
405
|
function buildDelegateToState(currentSetting, resultCheckpoint, currentExpert) {
|
|
202
406
|
const { delegateTo } = resultCheckpoint;
|
|
203
|
-
if (!delegateTo) {
|
|
407
|
+
if (!delegateTo || delegateTo.length === 0) {
|
|
204
408
|
throw new Error("delegateTo is required for buildDelegateToState");
|
|
205
409
|
}
|
|
206
|
-
const
|
|
410
|
+
const firstDelegation = delegateTo[0];
|
|
411
|
+
const { expert, toolCallId, toolName, query } = firstDelegation;
|
|
207
412
|
return {
|
|
208
413
|
setting: {
|
|
209
414
|
...currentSetting,
|
|
@@ -237,69 +442,6 @@ function buildDelegateToState(currentSetting, resultCheckpoint, currentExpert) {
|
|
|
237
442
|
}
|
|
238
443
|
};
|
|
239
444
|
}
|
|
240
|
-
async function createDefaultFileSystem() {
|
|
241
|
-
const fs = await import('fs');
|
|
242
|
-
const fsPromises = await import('fs/promises');
|
|
243
|
-
return {
|
|
244
|
-
existsSync: fs.existsSync,
|
|
245
|
-
mkdir: async (p, options) => {
|
|
246
|
-
await fsPromises.mkdir(p, options);
|
|
247
|
-
},
|
|
248
|
-
readFile: fsPromises.readFile,
|
|
249
|
-
writeFile: fsPromises.writeFile
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
function defaultGetRunDir(runId) {
|
|
253
|
-
return `${process.cwd()}/perstack/runs/${runId}`;
|
|
254
|
-
}
|
|
255
|
-
async function storeRunSetting(setting, fs, getRunDir = defaultGetRunDir) {
|
|
256
|
-
const fileSystem = fs ?? await createDefaultFileSystem();
|
|
257
|
-
const runDir = getRunDir(setting.runId);
|
|
258
|
-
if (fileSystem.existsSync(runDir)) {
|
|
259
|
-
const runSettingPath = path.resolve(runDir, "run-setting.json");
|
|
260
|
-
const runSetting = runSettingSchema.parse(
|
|
261
|
-
JSON.parse(await fileSystem.readFile(runSettingPath, "utf-8"))
|
|
262
|
-
);
|
|
263
|
-
runSetting.updatedAt = Date.now();
|
|
264
|
-
await fileSystem.writeFile(runSettingPath, JSON.stringify(runSetting), "utf-8");
|
|
265
|
-
} else {
|
|
266
|
-
await fileSystem.mkdir(runDir, { recursive: true });
|
|
267
|
-
await fileSystem.writeFile(
|
|
268
|
-
path.resolve(runDir, "run-setting.json"),
|
|
269
|
-
JSON.stringify(setting),
|
|
270
|
-
"utf-8"
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// src/default-store.ts
|
|
276
|
-
async function defaultRetrieveCheckpoint(runId, checkpointId) {
|
|
277
|
-
const runDir = defaultGetRunDir(runId);
|
|
278
|
-
const checkpointFiles = await readdir(runDir, { withFileTypes: true }).then(
|
|
279
|
-
(files) => files.filter((file) => file.isFile() && file.name.startsWith("checkpoint-"))
|
|
280
|
-
);
|
|
281
|
-
const checkpointFile = checkpointFiles.find((file) => file.name.endsWith(`-${checkpointId}.json`));
|
|
282
|
-
if (!checkpointFile) {
|
|
283
|
-
throw new Error(`checkpoint not found: ${runId} ${checkpointId}`);
|
|
284
|
-
}
|
|
285
|
-
const checkpointPath = `${runDir}/${checkpointFile.name}`;
|
|
286
|
-
const checkpoint = await readFile(checkpointPath, "utf8");
|
|
287
|
-
return checkpointSchema.parse(JSON.parse(checkpoint));
|
|
288
|
-
}
|
|
289
|
-
async function defaultStoreCheckpoint(checkpoint, timestamp) {
|
|
290
|
-
const { id, runId, stepNumber } = checkpoint;
|
|
291
|
-
const runDir = defaultGetRunDir(runId);
|
|
292
|
-
const checkpointPath = `${runDir}/checkpoint-${timestamp}-${stepNumber}-${id}.json`;
|
|
293
|
-
await mkdir(runDir, { recursive: true });
|
|
294
|
-
await writeFile(checkpointPath, JSON.stringify(checkpoint));
|
|
295
|
-
}
|
|
296
|
-
async function defaultStoreEvent(event) {
|
|
297
|
-
const { timestamp, runId, stepNumber, type } = event;
|
|
298
|
-
const runDir = defaultGetRunDir(runId);
|
|
299
|
-
const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
|
|
300
|
-
await mkdir(runDir, { recursive: true });
|
|
301
|
-
await writeFile(eventPath, JSON.stringify(event));
|
|
302
|
-
}
|
|
303
445
|
var RunEventEmitter = class {
|
|
304
446
|
listeners = [];
|
|
305
447
|
subscribe(listener) {
|
|
@@ -332,9 +474,11 @@ var BaseSkillManager = class {
|
|
|
332
474
|
skill;
|
|
333
475
|
interactiveSkill;
|
|
334
476
|
expert;
|
|
477
|
+
_jobId;
|
|
335
478
|
_runId;
|
|
336
479
|
_eventListener;
|
|
337
|
-
constructor(runId, eventListener) {
|
|
480
|
+
constructor(jobId, runId, eventListener) {
|
|
481
|
+
this._jobId = jobId;
|
|
338
482
|
this._runId = runId;
|
|
339
483
|
this._eventListener = eventListener;
|
|
340
484
|
}
|
|
@@ -385,8 +529,8 @@ var DelegateSkillManager = class extends BaseSkillManager {
|
|
|
385
529
|
type = "delegate";
|
|
386
530
|
lazyInit = false;
|
|
387
531
|
expert;
|
|
388
|
-
constructor(expert, runId, eventListener) {
|
|
389
|
-
super(runId, eventListener);
|
|
532
|
+
constructor(expert, jobId, runId, eventListener) {
|
|
533
|
+
super(jobId, runId, eventListener);
|
|
390
534
|
this.name = expert.name;
|
|
391
535
|
this.expert = expert;
|
|
392
536
|
}
|
|
@@ -418,8 +562,8 @@ var InteractiveSkillManager = class extends BaseSkillManager {
|
|
|
418
562
|
type = "interactive";
|
|
419
563
|
lazyInit = false;
|
|
420
564
|
interactiveSkill;
|
|
421
|
-
constructor(interactiveSkill, runId, eventListener) {
|
|
422
|
-
super(runId, eventListener);
|
|
565
|
+
constructor(interactiveSkill, jobId, runId, eventListener) {
|
|
566
|
+
super(jobId, runId, eventListener);
|
|
423
567
|
this.name = interactiveSkill.name;
|
|
424
568
|
this.interactiveSkill = interactiveSkill;
|
|
425
569
|
}
|
|
@@ -445,8 +589,8 @@ var McpSkillManager = class extends BaseSkillManager {
|
|
|
445
589
|
skill;
|
|
446
590
|
_mcpClient;
|
|
447
591
|
_env;
|
|
448
|
-
constructor(skill, env, runId, eventListener) {
|
|
449
|
-
super(runId, eventListener);
|
|
592
|
+
constructor(skill, env, jobId, runId, eventListener) {
|
|
593
|
+
super(jobId, runId, eventListener);
|
|
450
594
|
this.name = skill.name;
|
|
451
595
|
this.skill = skill;
|
|
452
596
|
this._env = env;
|
|
@@ -485,7 +629,7 @@ var McpSkillManager = class extends BaseSkillManager {
|
|
|
485
629
|
const startTime = Date.now();
|
|
486
630
|
const { command, args } = this._getCommandArgs(skill);
|
|
487
631
|
if (this._eventListener) {
|
|
488
|
-
const event = createRuntimeEvent("skillStarting", this._runId, {
|
|
632
|
+
const event = createRuntimeEvent("skillStarting", this._jobId, this._runId, {
|
|
489
633
|
skillName: skill.name,
|
|
490
634
|
command,
|
|
491
635
|
args
|
|
@@ -496,7 +640,7 @@ var McpSkillManager = class extends BaseSkillManager {
|
|
|
496
640
|
if (transport.stderr) {
|
|
497
641
|
transport.stderr.on("data", (chunk) => {
|
|
498
642
|
if (this._eventListener) {
|
|
499
|
-
const event = createRuntimeEvent("skillStderr", this._runId, {
|
|
643
|
+
const event = createRuntimeEvent("skillStderr", this._jobId, this._runId, {
|
|
500
644
|
skillName: skill.name,
|
|
501
645
|
message: chunk.toString().trim()
|
|
502
646
|
});
|
|
@@ -509,7 +653,7 @@ var McpSkillManager = class extends BaseSkillManager {
|
|
|
509
653
|
const connectTime = Date.now();
|
|
510
654
|
if (this._eventListener) {
|
|
511
655
|
const serverInfo = this._mcpClient.getServerVersion();
|
|
512
|
-
const event = createRuntimeEvent("skillConnected", this._runId, {
|
|
656
|
+
const event = createRuntimeEvent("skillConnected", this._jobId, this._runId, {
|
|
513
657
|
skillName: skill.name,
|
|
514
658
|
serverInfo: serverInfo ? { name: serverInfo.name, version: serverInfo.version } : void 0,
|
|
515
659
|
connectDurationMs: connectTime - connectStartTime,
|
|
@@ -545,7 +689,7 @@ var McpSkillManager = class extends BaseSkillManager {
|
|
|
545
689
|
if (this._mcpClient) {
|
|
546
690
|
await this._mcpClient.close();
|
|
547
691
|
if (this._eventListener && this.skill) {
|
|
548
|
-
const event = createRuntimeEvent("skillDisconnected", this._runId, {
|
|
692
|
+
const event = createRuntimeEvent("skillDisconnected", this._jobId, this._runId, {
|
|
549
693
|
skillName: this.skill.name
|
|
550
694
|
});
|
|
551
695
|
this._eventListener(event);
|
|
@@ -648,8 +792,8 @@ async function initSkillManagersWithCleanup(managers, allManagers) {
|
|
|
648
792
|
throw firstRejected.reason;
|
|
649
793
|
}
|
|
650
794
|
}
|
|
651
|
-
async function getSkillManagers(expert, experts, setting, eventListener) {
|
|
652
|
-
const { perstackBaseSkillCommand, env, runId } = setting;
|
|
795
|
+
async function getSkillManagers(expert, experts, setting, eventListener, options) {
|
|
796
|
+
const { perstackBaseSkillCommand, env, jobId, runId } = setting;
|
|
653
797
|
const { skills } = expert;
|
|
654
798
|
if (!skills["@perstack/base"]) {
|
|
655
799
|
throw new Error("Base skill is not defined");
|
|
@@ -676,20 +820,22 @@ async function getSkillManagers(expert, experts, setting, eventListener) {
|
|
|
676
820
|
return skill;
|
|
677
821
|
});
|
|
678
822
|
const mcpSkillManagers = mcpSkills.map((skill) => {
|
|
679
|
-
const manager = new McpSkillManager(skill, env, runId, eventListener);
|
|
823
|
+
const manager = new McpSkillManager(skill, env, jobId, runId, eventListener);
|
|
680
824
|
allManagers.push(manager);
|
|
681
825
|
return manager;
|
|
682
826
|
});
|
|
683
827
|
await initSkillManagersWithCleanup(mcpSkillManagers, allManagers);
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
828
|
+
if (!options?.isDelegatedRun) {
|
|
829
|
+
const interactiveSkills = Object.values(skills).filter(
|
|
830
|
+
(skill) => skill.type === "interactiveSkill"
|
|
831
|
+
);
|
|
832
|
+
const interactiveSkillManagers = interactiveSkills.map((interactiveSkill) => {
|
|
833
|
+
const manager = new InteractiveSkillManager(interactiveSkill, jobId, runId, eventListener);
|
|
834
|
+
allManagers.push(manager);
|
|
835
|
+
return manager;
|
|
836
|
+
});
|
|
837
|
+
await initSkillManagersWithCleanup(interactiveSkillManagers, allManagers);
|
|
838
|
+
}
|
|
693
839
|
const delegateSkillManagers = [];
|
|
694
840
|
for (const delegateExpertName of expert.delegates) {
|
|
695
841
|
const delegate = experts[delegateExpertName];
|
|
@@ -698,7 +844,7 @@ async function getSkillManagers(expert, experts, setting, eventListener) {
|
|
|
698
844
|
})));
|
|
699
845
|
throw new Error(`Delegate expert "${delegateExpertName}" not found in experts`);
|
|
700
846
|
}
|
|
701
|
-
const manager = new DelegateSkillManager(delegate, runId, eventListener);
|
|
847
|
+
const manager = new DelegateSkillManager(delegate, jobId, runId, eventListener);
|
|
702
848
|
allManagers.push(manager);
|
|
703
849
|
delegateSkillManagers.push(manager);
|
|
704
850
|
}
|
|
@@ -739,6 +885,10 @@ async function getToolSet(skillManagers) {
|
|
|
739
885
|
}
|
|
740
886
|
|
|
741
887
|
// src/states/calling-delegate.ts
|
|
888
|
+
async function getToolType(toolName, skillManagers) {
|
|
889
|
+
const skillManager = await getSkillManagerByToolName(skillManagers, toolName);
|
|
890
|
+
return skillManager.type;
|
|
891
|
+
}
|
|
742
892
|
async function callingDelegateLogic({
|
|
743
893
|
setting,
|
|
744
894
|
checkpoint,
|
|
@@ -748,35 +898,44 @@ async function callingDelegateLogic({
|
|
|
748
898
|
if (!step.pendingToolCalls || step.pendingToolCalls.length === 0) {
|
|
749
899
|
throw new Error("No pending tool calls found");
|
|
750
900
|
}
|
|
751
|
-
const
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
throw new Error("Delegation error: query is undefined");
|
|
901
|
+
const toolCallTypes = await Promise.all(
|
|
902
|
+
step.pendingToolCalls.map(async (tc) => ({
|
|
903
|
+
toolCall: tc,
|
|
904
|
+
type: await getToolType(tc.toolName, skillManagers)
|
|
905
|
+
}))
|
|
906
|
+
);
|
|
907
|
+
const delegateToolCalls = toolCallTypes.filter((t) => t.type === "delegate").map((t) => t.toolCall);
|
|
908
|
+
const nonDelegateToolCalls = toolCallTypes.filter((t) => t.type !== "delegate").map((t) => t.toolCall);
|
|
909
|
+
if (delegateToolCalls.length === 0) {
|
|
910
|
+
throw new Error("No delegate tool calls found");
|
|
762
911
|
}
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
912
|
+
const delegations = await Promise.all(
|
|
913
|
+
delegateToolCalls.map(async (tc) => {
|
|
914
|
+
const skillManager = await getSkillManagerByToolName(skillManagers, tc.toolName);
|
|
915
|
+
if (!skillManager.expert) {
|
|
916
|
+
throw new Error(`Delegation error: skill manager "${tc.toolName}" not found`);
|
|
917
|
+
}
|
|
918
|
+
if (!tc.args || !tc.args.query || typeof tc.args.query !== "string") {
|
|
919
|
+
throw new Error(`Delegation error: query is undefined for ${tc.toolName}`);
|
|
920
|
+
}
|
|
921
|
+
return {
|
|
770
922
|
expert: {
|
|
771
923
|
key: skillManager.expert.key,
|
|
772
924
|
name: skillManager.expert.name,
|
|
773
925
|
version: skillManager.expert.version
|
|
774
926
|
},
|
|
775
|
-
toolCallId: id,
|
|
776
|
-
toolName,
|
|
777
|
-
query: args.query
|
|
778
|
-
}
|
|
779
|
-
|
|
927
|
+
toolCallId: tc.id,
|
|
928
|
+
toolName: tc.toolName,
|
|
929
|
+
query: tc.args.query
|
|
930
|
+
};
|
|
931
|
+
})
|
|
932
|
+
);
|
|
933
|
+
return stopRunByDelegate(setting, checkpoint, {
|
|
934
|
+
checkpoint: {
|
|
935
|
+
...checkpoint,
|
|
936
|
+
status: "stoppedByDelegate",
|
|
937
|
+
delegateTo: delegations,
|
|
938
|
+
pendingToolCalls: nonDelegateToolCalls.length > 0 ? nonDelegateToolCalls : void 0,
|
|
780
939
|
partialToolResults: step.partialToolResults
|
|
781
940
|
},
|
|
782
941
|
step: {
|
|
@@ -844,9 +1003,9 @@ async function processFileToolResult(toolResult, toolName) {
|
|
|
844
1003
|
processedContents.push(part);
|
|
845
1004
|
continue;
|
|
846
1005
|
}
|
|
847
|
-
const { path:
|
|
1006
|
+
const { path: path4, mimeType } = fileInfo;
|
|
848
1007
|
try {
|
|
849
|
-
const buffer = await readFile(
|
|
1008
|
+
const buffer = await readFile(path4);
|
|
850
1009
|
if (toolName === "readImageFile") {
|
|
851
1010
|
processedContents.push({
|
|
852
1011
|
type: "imageInlinePart",
|
|
@@ -866,7 +1025,7 @@ async function processFileToolResult(toolResult, toolName) {
|
|
|
866
1025
|
processedContents.push({
|
|
867
1026
|
type: "textPart",
|
|
868
1027
|
id: part.id,
|
|
869
|
-
text: `Failed to read file "${
|
|
1028
|
+
text: `Failed to read file "${path4}": ${error instanceof Error ? error.message : String(error)}`
|
|
870
1029
|
});
|
|
871
1030
|
}
|
|
872
1031
|
}
|
|
@@ -889,7 +1048,7 @@ async function executeMcpToolCall(toolCall, skillManagers) {
|
|
|
889
1048
|
}
|
|
890
1049
|
return toolResult;
|
|
891
1050
|
}
|
|
892
|
-
async function
|
|
1051
|
+
async function getToolType2(toolCall, skillManagers) {
|
|
893
1052
|
const skillManager = await getSkillManagerByToolName(skillManagers, toolCall.toolName);
|
|
894
1053
|
return skillManager.type;
|
|
895
1054
|
}
|
|
@@ -917,7 +1076,7 @@ async function callingToolLogic({
|
|
|
917
1076
|
const toolCallTypes = await Promise.all(
|
|
918
1077
|
pendingToolCalls.map(async (tc) => ({
|
|
919
1078
|
toolCall: tc,
|
|
920
|
-
type: await
|
|
1079
|
+
type: await getToolType2(tc, skillManagers)
|
|
921
1080
|
}))
|
|
922
1081
|
);
|
|
923
1082
|
const mcpToolCalls = toolCallTypes.filter((t) => t.type === "mcp").map((t) => t.toolCall);
|
|
@@ -929,17 +1088,12 @@ async function callingToolLogic({
|
|
|
929
1088
|
);
|
|
930
1089
|
toolResults.push(...mcpResults);
|
|
931
1090
|
}
|
|
932
|
-
const remainingToolCalls = [...delegateToolCalls, ...interactiveToolCalls];
|
|
933
1091
|
if (delegateToolCalls.length > 0) {
|
|
934
|
-
const delegateToolCall = delegateToolCalls[0];
|
|
935
|
-
if (!delegateToolCall) {
|
|
936
|
-
throw new Error("No delegate tool call found");
|
|
937
|
-
}
|
|
938
1092
|
step.partialToolResults = toolResults;
|
|
939
|
-
step.pendingToolCalls =
|
|
1093
|
+
step.pendingToolCalls = [...delegateToolCalls, ...interactiveToolCalls];
|
|
940
1094
|
return callDelegate(setting, checkpoint, {
|
|
941
1095
|
newMessage: checkpoint.messages[checkpoint.messages.length - 1],
|
|
942
|
-
|
|
1096
|
+
toolCalls: delegateToolCalls,
|
|
943
1097
|
usage: step.usage
|
|
944
1098
|
});
|
|
945
1099
|
}
|
|
@@ -949,7 +1103,7 @@ async function callingToolLogic({
|
|
|
949
1103
|
throw new Error("No interactive tool call found");
|
|
950
1104
|
}
|
|
951
1105
|
step.partialToolResults = toolResults;
|
|
952
|
-
step.pendingToolCalls =
|
|
1106
|
+
step.pendingToolCalls = interactiveToolCalls;
|
|
953
1107
|
return callInteractiveTool(setting, checkpoint, {
|
|
954
1108
|
newMessage: checkpoint.messages[checkpoint.messages.length - 1],
|
|
955
1109
|
toolCall: interactiveToolCall,
|
|
@@ -1515,10 +1669,8 @@ async function initLogic({
|
|
|
1515
1669
|
if (!setting.input.interactiveToolCallResult) {
|
|
1516
1670
|
throw new Error("Interactive tool call result is undefined");
|
|
1517
1671
|
}
|
|
1518
|
-
const { toolCallId, toolName, text } = setting.input.interactiveToolCallResult;
|
|
1672
|
+
const { toolCallId, toolName, skillName, text } = setting.input.interactiveToolCallResult;
|
|
1519
1673
|
const pendingToolCalls = checkpoint.pendingToolCalls ?? [];
|
|
1520
|
-
const completedToolCall = pendingToolCalls.find((tc) => tc.id === toolCallId);
|
|
1521
|
-
const skillName = completedToolCall?.skillName ?? (checkpoint.status === "stoppedByDelegate" ? checkpoint.delegateTo?.expert.key : "") ?? "";
|
|
1522
1674
|
const newToolResult = {
|
|
1523
1675
|
id: toolCallId,
|
|
1524
1676
|
skillName,
|
|
@@ -1761,7 +1913,7 @@ var runtimeStateMachine = setup({
|
|
|
1761
1913
|
step: ({ context, event }) => ({
|
|
1762
1914
|
...context.step,
|
|
1763
1915
|
newMessages: [event.newMessage],
|
|
1764
|
-
toolCalls:
|
|
1916
|
+
toolCalls: event.toolCalls,
|
|
1765
1917
|
usage: sumUsage(context.step.usage, event.usage)
|
|
1766
1918
|
})
|
|
1767
1919
|
})
|
|
@@ -1992,7 +2144,7 @@ async function executeStateMachine(params) {
|
|
|
1992
2144
|
} else {
|
|
1993
2145
|
const event = await StateMachineLogics[runState.value](runState.context);
|
|
1994
2146
|
if ("checkpoint" in event) {
|
|
1995
|
-
await storeCheckpoint(event.checkpoint
|
|
2147
|
+
await storeCheckpoint(event.checkpoint);
|
|
1996
2148
|
}
|
|
1997
2149
|
await eventEmitter.emit(event);
|
|
1998
2150
|
if (shouldContinueRun) {
|
|
@@ -2081,10 +2233,15 @@ async function run(runInput, options) {
|
|
|
2081
2233
|
const contextWindow = getContextWindow(setting.providerConfig.providerName, setting.model);
|
|
2082
2234
|
const getRunDir = options?.getRunDir ?? defaultGetRunDir;
|
|
2083
2235
|
await storeRunSetting(setting, options?.fileSystem, getRunDir);
|
|
2236
|
+
let job = retrieveJob(setting.jobId) ?? createInitialJob(setting.jobId, setting.expertKey, setting.maxSteps);
|
|
2237
|
+
if (job.status !== "running") {
|
|
2238
|
+
job = { ...job, status: "running", finishedAt: void 0 };
|
|
2239
|
+
}
|
|
2240
|
+
storeJob(job);
|
|
2084
2241
|
while (true) {
|
|
2085
2242
|
const { expertToRun, experts } = await setupExperts(setting, options?.resolveExpertToRun);
|
|
2086
2243
|
if (options?.eventListener) {
|
|
2087
|
-
const initEvent = createRuntimeEvent("initializeRuntime", setting.runId, {
|
|
2244
|
+
const initEvent = createRuntimeEvent("initializeRuntime", setting.jobId, setting.runId, {
|
|
2088
2245
|
runtimeVersion: package_default.version,
|
|
2089
2246
|
expertName: expertToRun.name,
|
|
2090
2247
|
experts: Object.keys(experts),
|
|
@@ -2102,9 +2259,11 @@ async function run(runInput, options) {
|
|
|
2102
2259
|
expertToRun,
|
|
2103
2260
|
experts,
|
|
2104
2261
|
setting,
|
|
2105
|
-
options?.eventListener
|
|
2262
|
+
options?.eventListener,
|
|
2263
|
+
{ isDelegatedRun: !!checkpoint?.delegatedBy }
|
|
2106
2264
|
);
|
|
2107
2265
|
const initialCheckpoint = checkpoint ? createNextStepCheckpoint(createId(), checkpoint) : createInitialCheckpoint(createId(), {
|
|
2266
|
+
jobId: setting.jobId,
|
|
2108
2267
|
runId: setting.runId,
|
|
2109
2268
|
expertKey: setting.expertKey,
|
|
2110
2269
|
expert: expertToRun,
|
|
@@ -2119,11 +2278,21 @@ async function run(runInput, options) {
|
|
|
2119
2278
|
storeCheckpoint,
|
|
2120
2279
|
shouldContinueRun: options?.shouldContinueRun
|
|
2121
2280
|
});
|
|
2281
|
+
job = {
|
|
2282
|
+
...job,
|
|
2283
|
+
totalSteps: runResultCheckpoint.stepNumber,
|
|
2284
|
+
usage: runResultCheckpoint.usage
|
|
2285
|
+
};
|
|
2122
2286
|
switch (runResultCheckpoint.status) {
|
|
2123
2287
|
case "completed": {
|
|
2288
|
+
if (options?.returnOnDelegationComplete) {
|
|
2289
|
+
storeJob(job);
|
|
2290
|
+
return runResultCheckpoint;
|
|
2291
|
+
}
|
|
2124
2292
|
if (runResultCheckpoint.delegatedBy) {
|
|
2293
|
+
storeJob(job);
|
|
2125
2294
|
const parentCheckpoint = await retrieveCheckpoint(
|
|
2126
|
-
setting.
|
|
2295
|
+
setting.jobId,
|
|
2127
2296
|
runResultCheckpoint.delegatedBy.checkpointId
|
|
2128
2297
|
);
|
|
2129
2298
|
const result = buildDelegationReturnState(setting, runResultCheckpoint, parentCheckpoint);
|
|
@@ -2131,21 +2300,80 @@ async function run(runInput, options) {
|
|
|
2131
2300
|
checkpoint = result.checkpoint;
|
|
2132
2301
|
break;
|
|
2133
2302
|
}
|
|
2303
|
+
storeJob({ ...job, status: "completed", finishedAt: Date.now() });
|
|
2134
2304
|
return runResultCheckpoint;
|
|
2135
2305
|
}
|
|
2136
2306
|
case "stoppedByInteractiveTool": {
|
|
2307
|
+
storeJob({ ...job, status: "stoppedByInteractiveTool" });
|
|
2137
2308
|
return runResultCheckpoint;
|
|
2138
2309
|
}
|
|
2139
2310
|
case "stoppedByDelegate": {
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2311
|
+
storeJob(job);
|
|
2312
|
+
const { delegateTo } = runResultCheckpoint;
|
|
2313
|
+
if (!delegateTo || delegateTo.length === 0) {
|
|
2314
|
+
throw new Error("No delegations found in checkpoint");
|
|
2315
|
+
}
|
|
2316
|
+
if (delegateTo.length === 1) {
|
|
2317
|
+
const result = buildDelegateToState(setting, runResultCheckpoint, expertToRun);
|
|
2318
|
+
setting = result.setting;
|
|
2319
|
+
checkpoint = result.checkpoint;
|
|
2320
|
+
break;
|
|
2321
|
+
}
|
|
2322
|
+
const firstDelegation = delegateTo[0];
|
|
2323
|
+
const remainingDelegations = delegateTo.slice(1);
|
|
2324
|
+
const [firstResult, ...restResults] = await Promise.all(
|
|
2325
|
+
delegateTo.map(
|
|
2326
|
+
(delegation) => runDelegate(delegation, setting, runResultCheckpoint, expertToRun, options)
|
|
2327
|
+
)
|
|
2328
|
+
);
|
|
2329
|
+
const allResults = [firstResult, ...restResults];
|
|
2330
|
+
const aggregatedUsage = allResults.reduce(
|
|
2331
|
+
(acc, result) => sumUsage(acc, result.deltaUsage),
|
|
2332
|
+
runResultCheckpoint.usage
|
|
2333
|
+
);
|
|
2334
|
+
const maxStepNumber = Math.max(...allResults.map((r) => r.stepNumber));
|
|
2335
|
+
const restToolResults = restResults.map((result) => ({
|
|
2336
|
+
id: result.toolCallId,
|
|
2337
|
+
skillName: `delegate/${result.expertKey}`,
|
|
2338
|
+
toolName: result.toolName,
|
|
2339
|
+
result: [{ type: "textPart", id: createId(), text: result.text }]
|
|
2340
|
+
}));
|
|
2341
|
+
const processedToolCallIds = new Set(remainingDelegations.map((d) => d.toolCallId));
|
|
2342
|
+
const remainingToolCalls = runResultCheckpoint.pendingToolCalls?.filter(
|
|
2343
|
+
(tc) => !processedToolCallIds.has(tc.id) && tc.id !== firstDelegation.toolCallId
|
|
2344
|
+
);
|
|
2345
|
+
setting = {
|
|
2346
|
+
...setting,
|
|
2347
|
+
expertKey: expertToRun.key,
|
|
2348
|
+
input: {
|
|
2349
|
+
interactiveToolCallResult: {
|
|
2350
|
+
toolCallId: firstResult.toolCallId,
|
|
2351
|
+
toolName: firstResult.toolName,
|
|
2352
|
+
skillName: `delegate/${firstResult.expertKey}`,
|
|
2353
|
+
text: firstResult.text
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
};
|
|
2357
|
+
checkpoint = {
|
|
2358
|
+
...runResultCheckpoint,
|
|
2359
|
+
status: "stoppedByDelegate",
|
|
2360
|
+
delegateTo: void 0,
|
|
2361
|
+
stepNumber: maxStepNumber,
|
|
2362
|
+
usage: aggregatedUsage,
|
|
2363
|
+
pendingToolCalls: remainingToolCalls?.length ? remainingToolCalls : void 0,
|
|
2364
|
+
partialToolResults: [
|
|
2365
|
+
...runResultCheckpoint.partialToolResults ?? [],
|
|
2366
|
+
...restToolResults
|
|
2367
|
+
]
|
|
2368
|
+
};
|
|
2143
2369
|
break;
|
|
2144
2370
|
}
|
|
2145
2371
|
case "stoppedByExceededMaxSteps": {
|
|
2372
|
+
storeJob({ ...job, status: "stoppedByMaxSteps", finishedAt: Date.now() });
|
|
2146
2373
|
return runResultCheckpoint;
|
|
2147
2374
|
}
|
|
2148
2375
|
case "stoppedByError": {
|
|
2376
|
+
storeJob({ ...job, status: "stoppedByError", finishedAt: Date.now() });
|
|
2149
2377
|
return runResultCheckpoint;
|
|
2150
2378
|
}
|
|
2151
2379
|
default:
|
|
@@ -2162,10 +2390,65 @@ function getEventListener(options) {
|
|
|
2162
2390
|
listener(event);
|
|
2163
2391
|
};
|
|
2164
2392
|
}
|
|
2393
|
+
async function runDelegate(delegation, parentSetting, parentCheckpoint, parentExpert, options) {
|
|
2394
|
+
const { expert, toolCallId, toolName, query } = delegation;
|
|
2395
|
+
const delegateRunId = createId();
|
|
2396
|
+
const delegateSetting = {
|
|
2397
|
+
...parentSetting,
|
|
2398
|
+
runId: delegateRunId,
|
|
2399
|
+
expertKey: expert.key,
|
|
2400
|
+
input: { text: query }
|
|
2401
|
+
};
|
|
2402
|
+
const delegateCheckpoint = {
|
|
2403
|
+
id: createId(),
|
|
2404
|
+
jobId: parentSetting.jobId,
|
|
2405
|
+
runId: delegateRunId,
|
|
2406
|
+
status: "init",
|
|
2407
|
+
stepNumber: parentCheckpoint.stepNumber,
|
|
2408
|
+
messages: [],
|
|
2409
|
+
expert: {
|
|
2410
|
+
key: expert.key,
|
|
2411
|
+
name: expert.name,
|
|
2412
|
+
version: expert.version
|
|
2413
|
+
},
|
|
2414
|
+
delegatedBy: {
|
|
2415
|
+
expert: {
|
|
2416
|
+
key: parentExpert.key,
|
|
2417
|
+
name: parentExpert.name,
|
|
2418
|
+
version: parentExpert.version
|
|
2419
|
+
},
|
|
2420
|
+
toolCallId,
|
|
2421
|
+
toolName,
|
|
2422
|
+
checkpointId: parentCheckpoint.id
|
|
2423
|
+
},
|
|
2424
|
+
usage: createEmptyUsage(),
|
|
2425
|
+
contextWindow: parentCheckpoint.contextWindow
|
|
2426
|
+
};
|
|
2427
|
+
const resultCheckpoint = await run(
|
|
2428
|
+
{ setting: delegateSetting, checkpoint: delegateCheckpoint },
|
|
2429
|
+
{ ...options, returnOnDelegationComplete: true }
|
|
2430
|
+
);
|
|
2431
|
+
const lastMessage = resultCheckpoint.messages[resultCheckpoint.messages.length - 1];
|
|
2432
|
+
if (!lastMessage || lastMessage.type !== "expertMessage") {
|
|
2433
|
+
throw new Error("Delegation error: delegation result message is incorrect");
|
|
2434
|
+
}
|
|
2435
|
+
const textPart = lastMessage.contents.find((c) => c.type === "textPart");
|
|
2436
|
+
if (!textPart || textPart.type !== "textPart") {
|
|
2437
|
+
throw new Error("Delegation error: delegation result message does not contain text");
|
|
2438
|
+
}
|
|
2439
|
+
return {
|
|
2440
|
+
toolCallId,
|
|
2441
|
+
toolName,
|
|
2442
|
+
expertKey: expert.key,
|
|
2443
|
+
text: textPart.text,
|
|
2444
|
+
stepNumber: resultCheckpoint.stepNumber,
|
|
2445
|
+
deltaUsage: resultCheckpoint.usage
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2165
2448
|
|
|
2166
2449
|
// src/index.ts
|
|
2167
2450
|
var runtimeVersion = package_default.version;
|
|
2168
2451
|
|
|
2169
|
-
export { StateMachineLogics, calculateContextWindowUsage, getContextWindow, getModel, defaultGetRunDir as getRunDir, run, runtimeStateMachine, runtimeVersion };
|
|
2452
|
+
export { StateMachineLogics, calculateContextWindowUsage, createInitialJob, getAllJobs, getAllRuns, getCheckpointDir, getCheckpointPath, getCheckpointsByJobId, getContextWindow, getEventContents, getEventsByRun, getJobDir, getJobsDir, getModel, defaultGetRunDir as getRunDir, retrieveJob, run, runtimeStateMachine, runtimeVersion, storeJob };
|
|
2170
2453
|
//# sourceMappingURL=index.js.map
|
|
2171
2454
|
//# sourceMappingURL=index.js.map
|