@perstack/runtime 0.0.24 → 0.0.26
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/dist/index.d.ts +609 -1943
- package/dist/index.js +410 -1065
- package/dist/index.js.map +1 -1
- package/package.json +18 -13
package/dist/index.js
CHANGED
|
@@ -1,781 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { createId } from
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
var anthropicModelConfigs = [
|
|
21
|
-
{
|
|
22
|
-
modelId: "claude-opus-4-20250514",
|
|
23
|
-
default: true,
|
|
24
|
-
contextWindow: 2e5
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
modelId: "claude-sonnet-4-20250514",
|
|
28
|
-
default: false,
|
|
29
|
-
contextWindow: 2e5
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
modelId: "claude-3-7-sonnet-20250219",
|
|
33
|
-
default: false,
|
|
34
|
-
contextWindow: 2e5
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
modelId: "claude-3-5-sonnet-latest",
|
|
38
|
-
default: false,
|
|
39
|
-
contextWindow: 2e5
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
modelId: "claude-3-5-haiku-latest",
|
|
43
|
-
default: false,
|
|
44
|
-
contextWindow: 2e5
|
|
45
|
-
}
|
|
46
|
-
];
|
|
47
|
-
var googleModelConfigs = [
|
|
48
|
-
{
|
|
49
|
-
modelId: "gemini-2.5-pro",
|
|
50
|
-
default: false,
|
|
51
|
-
contextWindow: 1e6
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
modelId: "gemini-2.5-flash",
|
|
55
|
-
default: false,
|
|
56
|
-
contextWindow: 1e6
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
modelId: "gemini-2.5-flash-lite",
|
|
60
|
-
default: false,
|
|
61
|
-
contextWindow: 1e6
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
var openAIModelConfigs = [
|
|
65
|
-
{
|
|
66
|
-
modelId: "o4-mini",
|
|
67
|
-
default: false,
|
|
68
|
-
contextWindow: 2e5
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
modelId: "o3",
|
|
72
|
-
default: false,
|
|
73
|
-
contextWindow: 2e5
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
modelId: "o3-mini",
|
|
77
|
-
default: false,
|
|
78
|
-
contextWindow: 2e5
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
modelId: "gpt-4.1",
|
|
82
|
-
default: false,
|
|
83
|
-
contextWindow: 1e6
|
|
84
|
-
}
|
|
85
|
-
];
|
|
86
|
-
var modelConfigs = Object.fromEntries(
|
|
87
|
-
Array.from(/* @__PURE__ */ new Set([...anthropicModelConfigs, ...googleModelConfigs, ...openAIModelConfigs])).map(
|
|
88
|
-
(model) => [model.modelId, model]
|
|
89
|
-
)
|
|
90
|
-
);
|
|
91
|
-
function getDefaultModelName() {
|
|
92
|
-
const model = Object.values(modelConfigs).find((model2) => model2.default);
|
|
93
|
-
if (!model) {
|
|
94
|
-
throw new Error("No default model found");
|
|
95
|
-
}
|
|
96
|
-
return model.modelId;
|
|
97
|
-
}
|
|
98
|
-
function getModel(modelId) {
|
|
99
|
-
const unwrappedModelId = modelId ?? getDefaultModelName();
|
|
100
|
-
if (anthropicModelConfigs.some((model) => model.modelId === unwrappedModelId)) {
|
|
101
|
-
return anthropic(unwrappedModelId);
|
|
102
|
-
}
|
|
103
|
-
if (googleModelConfigs.some((model) => model.modelId === unwrappedModelId)) {
|
|
104
|
-
return google(unwrappedModelId);
|
|
105
|
-
}
|
|
106
|
-
if (openAIModelConfigs.some((model) => model.modelId === unwrappedModelId)) {
|
|
107
|
-
return openai(unwrappedModelId);
|
|
108
|
-
}
|
|
109
|
-
throw new Error(`Unsupported model: ${unwrappedModelId}`);
|
|
110
|
-
}
|
|
111
|
-
function getModelConfig(modelId) {
|
|
112
|
-
const modelConfig = modelConfigs[modelId];
|
|
113
|
-
if (!modelConfig) {
|
|
114
|
-
throw new Error(`Unsupported model: ${modelId}`);
|
|
115
|
-
}
|
|
116
|
-
return modelConfig;
|
|
117
|
-
}
|
|
118
|
-
function calculateWindowUsage(usage, contextWindow) {
|
|
119
|
-
return (usage.inputTokens + usage.cachedInputTokens + usage.outputTokens) / contextWindow;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/schemas/messages.ts
|
|
123
|
-
import { z } from "zod";
|
|
124
|
-
var BasePartSchema = z.object({
|
|
125
|
-
id: z.string()
|
|
126
|
-
});
|
|
127
|
-
var TextPartSchema = BasePartSchema.extend({
|
|
128
|
-
type: z.literal("textPart"),
|
|
129
|
-
text: z.string()
|
|
130
|
-
});
|
|
131
|
-
var ImageUrlPartSchema = BasePartSchema.extend({
|
|
132
|
-
type: z.literal("imageUrlPart"),
|
|
133
|
-
url: z.string().url(),
|
|
134
|
-
mimeType: z.string()
|
|
135
|
-
});
|
|
136
|
-
var ImageInlinePartSchema = BasePartSchema.extend({
|
|
137
|
-
type: z.literal("imageInlinePart"),
|
|
138
|
-
encodedData: z.string(),
|
|
139
|
-
mimeType: z.string()
|
|
140
|
-
});
|
|
141
|
-
var ImageBinaryPartSchema = BasePartSchema.extend({
|
|
142
|
-
type: z.literal("imageBinaryPart"),
|
|
143
|
-
data: z.string(),
|
|
144
|
-
mimeType: z.string()
|
|
145
|
-
});
|
|
146
|
-
var FileUrlPartSchema = BasePartSchema.extend({
|
|
147
|
-
type: z.literal("fileUrlPart"),
|
|
148
|
-
url: z.string().url(),
|
|
149
|
-
mimeType: z.string()
|
|
150
|
-
});
|
|
151
|
-
var FileInlinePartSchema = BasePartSchema.extend({
|
|
152
|
-
type: z.literal("fileInlinePart"),
|
|
153
|
-
encodedData: z.string(),
|
|
154
|
-
mimeType: z.string()
|
|
155
|
-
});
|
|
156
|
-
var FileBinaryPartSchema = BasePartSchema.extend({
|
|
157
|
-
type: z.literal("fileBinaryPart"),
|
|
158
|
-
data: z.string(),
|
|
159
|
-
mimeType: z.string()
|
|
160
|
-
});
|
|
161
|
-
var ToolCallPartSchema = BasePartSchema.extend({
|
|
162
|
-
type: z.literal("toolCallPart"),
|
|
163
|
-
toolCallId: z.string(),
|
|
164
|
-
toolName: z.string(),
|
|
165
|
-
args: z.unknown()
|
|
166
|
-
});
|
|
167
|
-
var ToolResultPartSchema = BasePartSchema.extend({
|
|
168
|
-
type: z.literal("toolResultPart"),
|
|
169
|
-
toolCallId: z.string(),
|
|
170
|
-
toolName: z.string(),
|
|
171
|
-
contents: z.array(z.union([TextPartSchema, ImageInlinePartSchema])),
|
|
172
|
-
isError: z.boolean().optional()
|
|
173
|
-
});
|
|
174
|
-
var BaseMessageSchema = z.object({
|
|
175
|
-
id: z.string()
|
|
176
|
-
});
|
|
177
|
-
var InstructionMessageSchema = BaseMessageSchema.extend({
|
|
178
|
-
type: z.literal("instructionMessage"),
|
|
179
|
-
contents: z.array(TextPartSchema),
|
|
180
|
-
cache: z.boolean().optional()
|
|
181
|
-
});
|
|
182
|
-
var UserMessageSchema = BaseMessageSchema.extend({
|
|
183
|
-
type: z.literal("userMessage"),
|
|
184
|
-
contents: z.array(
|
|
185
|
-
z.union([
|
|
186
|
-
TextPartSchema,
|
|
187
|
-
ImageUrlPartSchema,
|
|
188
|
-
ImageInlinePartSchema,
|
|
189
|
-
ImageBinaryPartSchema,
|
|
190
|
-
FileUrlPartSchema,
|
|
191
|
-
FileInlinePartSchema,
|
|
192
|
-
FileBinaryPartSchema
|
|
193
|
-
])
|
|
194
|
-
),
|
|
195
|
-
cache: z.boolean().optional()
|
|
196
|
-
});
|
|
197
|
-
var ExpertMessageSchema = BaseMessageSchema.extend({
|
|
198
|
-
type: z.literal("expertMessage"),
|
|
199
|
-
contents: z.array(z.union([TextPartSchema, ToolCallPartSchema])),
|
|
200
|
-
cache: z.boolean().optional()
|
|
201
|
-
});
|
|
202
|
-
var ToolMessageSchema = BaseMessageSchema.extend({
|
|
203
|
-
type: z.literal("toolMessage"),
|
|
204
|
-
contents: z.array(ToolResultPartSchema),
|
|
205
|
-
cache: z.boolean().optional()
|
|
206
|
-
});
|
|
207
|
-
var MessageSchema = z.union([
|
|
208
|
-
InstructionMessageSchema,
|
|
209
|
-
UserMessageSchema,
|
|
210
|
-
ExpertMessageSchema,
|
|
211
|
-
ToolMessageSchema
|
|
212
|
-
]);
|
|
213
|
-
|
|
214
|
-
// src/schemas/runtime.ts
|
|
215
|
-
var defaultTemperature = 0;
|
|
216
|
-
var defaultMaxSteps = void 0;
|
|
217
|
-
var defaultMaxRetries = 5;
|
|
218
|
-
var defaultTimeout = 5 * 1e3 * 60;
|
|
219
|
-
var expertNameRegex = /^(@[a-z0-9][a-z0-9_-]*\/)?[a-z0-9][a-z0-9_-]*$/;
|
|
220
|
-
var versionRegex = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\w.-]+)?(?:\+[\w.-]+)?$/;
|
|
221
|
-
var tagNameRegex = /^[a-z0-9][a-z0-9_-]*$/;
|
|
222
|
-
var expertKeyRegex = /^((?:@[a-z0-9][a-z0-9_\.-]*\/)?[a-z0-9][a-z0-9_\.-]*)(?:@((?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\w.-]+)?(?:\+[\w.-]+)?)|@([a-z0-9][a-z0-9_\.-]*))?$/;
|
|
223
|
-
var skillNameRegex = /^[a-z0-9][a-z0-9._-]*$/;
|
|
224
|
-
var maxNameLength = 214;
|
|
225
|
-
function parseExpertKey(expertKey) {
|
|
226
|
-
const match = expertKey.match(expertKeyRegex);
|
|
227
|
-
if (!match) {
|
|
228
|
-
throw new Error(`Invalid expert key format: ${expertKey}`);
|
|
229
|
-
}
|
|
230
|
-
const [key, name, version, tag] = match;
|
|
231
|
-
return {
|
|
232
|
-
key,
|
|
233
|
-
name,
|
|
234
|
-
version,
|
|
235
|
-
tag
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
var McpStdioSkillSchema = z2.object({
|
|
239
|
-
type: z2.literal("mcpStdioSkill"),
|
|
240
|
-
name: z2.string(),
|
|
241
|
-
description: z2.string().optional(),
|
|
242
|
-
rule: z2.string().optional(),
|
|
243
|
-
pick: z2.array(z2.string()).optional().default([]),
|
|
244
|
-
omit: z2.array(z2.string()).optional().default([]),
|
|
245
|
-
command: z2.string(),
|
|
246
|
-
packageName: z2.string().optional(),
|
|
247
|
-
args: z2.array(z2.string()).optional().default([]),
|
|
248
|
-
requiredEnv: z2.array(z2.string()).optional().default([])
|
|
249
|
-
});
|
|
250
|
-
var McpSseSkillSchema = z2.object({
|
|
251
|
-
type: z2.literal("mcpSseSkill"),
|
|
252
|
-
name: z2.string(),
|
|
253
|
-
description: z2.string().optional(),
|
|
254
|
-
rule: z2.string().optional(),
|
|
255
|
-
pick: z2.array(z2.string()).optional().default([]),
|
|
256
|
-
omit: z2.array(z2.string()).optional().default([]),
|
|
257
|
-
endpoint: z2.string()
|
|
258
|
-
});
|
|
259
|
-
var InteractiveToolSchema = z2.object({
|
|
260
|
-
name: z2.string(),
|
|
261
|
-
description: z2.string().optional(),
|
|
262
|
-
inputJsonSchema: z2.string()
|
|
263
|
-
});
|
|
264
|
-
var InteractiveSkillSchema = z2.object({
|
|
265
|
-
type: z2.literal("interactiveSkill"),
|
|
266
|
-
name: z2.string(),
|
|
267
|
-
description: z2.string().optional(),
|
|
268
|
-
rule: z2.string().optional(),
|
|
269
|
-
tools: z2.record(z2.string(), InteractiveToolSchema.omit({ name: true })).transform((tools) => {
|
|
270
|
-
return Object.fromEntries(
|
|
271
|
-
Object.entries(tools).map(([key, toolWithoutName]) => [
|
|
272
|
-
key,
|
|
273
|
-
InteractiveToolSchema.parse({ ...toolWithoutName, name: key })
|
|
274
|
-
])
|
|
275
|
-
);
|
|
276
|
-
})
|
|
277
|
-
});
|
|
278
|
-
var ExpertSchema = z2.object({
|
|
279
|
-
key: z2.string().regex(expertKeyRegex).min(1),
|
|
280
|
-
name: z2.string().regex(expertNameRegex).min(1).max(maxNameLength),
|
|
281
|
-
version: z2.string().regex(versionRegex),
|
|
282
|
-
description: z2.string().min(1).max(1024 * 2).optional(),
|
|
283
|
-
instruction: z2.string().min(1).max(1024 * 20),
|
|
284
|
-
skills: z2.record(
|
|
285
|
-
z2.string(),
|
|
286
|
-
z2.discriminatedUnion("type", [
|
|
287
|
-
McpStdioSkillSchema.omit({ name: true }),
|
|
288
|
-
McpSseSkillSchema.omit({ name: true }),
|
|
289
|
-
InteractiveSkillSchema.omit({ name: true })
|
|
290
|
-
])
|
|
291
|
-
).optional().default({
|
|
292
|
-
"@perstack/base": {
|
|
293
|
-
type: "mcpStdioSkill",
|
|
294
|
-
description: "Base skill",
|
|
295
|
-
command: "npx",
|
|
296
|
-
args: ["-y", "@perstack/base"],
|
|
297
|
-
pick: [],
|
|
298
|
-
omit: [],
|
|
299
|
-
requiredEnv: []
|
|
300
|
-
}
|
|
301
|
-
}).transform((skills) => {
|
|
302
|
-
return Object.fromEntries(
|
|
303
|
-
Object.entries(skills).map(([key, skillWithoutName]) => [
|
|
304
|
-
key,
|
|
305
|
-
z2.discriminatedUnion("type", [
|
|
306
|
-
McpStdioSkillSchema,
|
|
307
|
-
McpSseSkillSchema,
|
|
308
|
-
InteractiveSkillSchema
|
|
309
|
-
]).parse({ ...skillWithoutName, name: key })
|
|
310
|
-
])
|
|
311
|
-
);
|
|
312
|
-
}),
|
|
313
|
-
delegates: z2.array(z2.string().regex(expertKeyRegex).min(1)).optional().default([]),
|
|
314
|
-
tags: z2.array(z2.string().regex(tagNameRegex).min(1)).optional().default([])
|
|
315
|
-
});
|
|
316
|
-
var UsageSchema = z2.object({
|
|
317
|
-
inputTokens: z2.number(),
|
|
318
|
-
outputTokens: z2.number(),
|
|
319
|
-
reasoningTokens: z2.number(),
|
|
320
|
-
totalTokens: z2.number(),
|
|
321
|
-
cachedInputTokens: z2.number()
|
|
322
|
-
});
|
|
323
|
-
var CheckpointStatusSchema = z2.enum([
|
|
324
|
-
"init",
|
|
325
|
-
"proceeding",
|
|
326
|
-
"completed",
|
|
327
|
-
"stoppedByInteractiveTool",
|
|
328
|
-
"stoppedByDelegate",
|
|
329
|
-
"stoppedByExceededMaxSteps",
|
|
330
|
-
"stoppedByError"
|
|
331
|
-
]);
|
|
332
|
-
var CheckpointSchema = z2.object({
|
|
333
|
-
id: z2.string(),
|
|
334
|
-
runId: z2.string(),
|
|
335
|
-
status: CheckpointStatusSchema,
|
|
336
|
-
stepNumber: z2.number(),
|
|
337
|
-
messages: z2.array(MessageSchema),
|
|
338
|
-
expert: z2.object({
|
|
339
|
-
key: z2.string(),
|
|
340
|
-
name: z2.string(),
|
|
341
|
-
version: z2.string()
|
|
342
|
-
}),
|
|
343
|
-
delegateTo: z2.object({
|
|
344
|
-
expert: z2.object({
|
|
345
|
-
key: z2.string(),
|
|
346
|
-
name: z2.string(),
|
|
347
|
-
version: z2.string()
|
|
348
|
-
}),
|
|
349
|
-
toolCallId: z2.string(),
|
|
350
|
-
toolName: z2.string(),
|
|
351
|
-
query: z2.string()
|
|
352
|
-
}).optional(),
|
|
353
|
-
delegatedBy: z2.object({
|
|
354
|
-
expert: z2.object({
|
|
355
|
-
key: z2.string(),
|
|
356
|
-
name: z2.string(),
|
|
357
|
-
version: z2.string()
|
|
358
|
-
}),
|
|
359
|
-
toolCallId: z2.string(),
|
|
360
|
-
toolName: z2.string(),
|
|
361
|
-
checkpointId: z2.string()
|
|
362
|
-
}).optional(),
|
|
363
|
-
usage: UsageSchema,
|
|
364
|
-
contextWindow: z2.number(),
|
|
365
|
-
contextWindowUsage: z2.number()
|
|
366
|
-
});
|
|
367
|
-
var RunParamsSchema = z2.object({
|
|
368
|
-
setting: z2.object({
|
|
369
|
-
runId: z2.string().optional().transform((value) => value ?? createId()),
|
|
370
|
-
expertKey: z2.string().regex(expertKeyRegex).min(1),
|
|
371
|
-
input: z2.object({
|
|
372
|
-
text: z2.string().optional(),
|
|
373
|
-
interactiveToolCallResult: z2.object({
|
|
374
|
-
toolCallId: z2.string(),
|
|
375
|
-
toolName: z2.string(),
|
|
376
|
-
text: z2.string()
|
|
377
|
-
}).optional()
|
|
378
|
-
}),
|
|
379
|
-
experts: z2.record(z2.string().regex(expertKeyRegex).min(1), ExpertSchema.omit({ key: true })).optional().default({}).transform(
|
|
380
|
-
(experts) => Object.fromEntries(
|
|
381
|
-
Object.entries(experts).map(([key, expertWithoutKey]) => [
|
|
382
|
-
key,
|
|
383
|
-
ExpertSchema.parse({
|
|
384
|
-
...expertWithoutKey,
|
|
385
|
-
key
|
|
386
|
-
})
|
|
387
|
-
])
|
|
388
|
-
)
|
|
389
|
-
),
|
|
390
|
-
model: z2.string().optional().default(getDefaultModelName()),
|
|
391
|
-
temperature: z2.number().min(0).max(1).optional().default(defaultTemperature),
|
|
392
|
-
maxSteps: z2.number().min(1).optional().default(defaultMaxSteps),
|
|
393
|
-
maxRetries: z2.number().min(0).optional().default(defaultMaxRetries),
|
|
394
|
-
timeout: z2.number().min(0).optional().default(defaultTimeout),
|
|
395
|
-
workspace: z2.string().optional(),
|
|
396
|
-
startedAt: z2.number().optional().default(Date.now()),
|
|
397
|
-
updatedAt: z2.number().optional().default(Date.now())
|
|
398
|
-
}),
|
|
399
|
-
checkpoint: CheckpointSchema.optional()
|
|
400
|
-
});
|
|
401
|
-
function createEvent(type) {
|
|
402
|
-
return (setting, checkpoint, data) => {
|
|
403
|
-
return {
|
|
404
|
-
type,
|
|
405
|
-
id: createId(),
|
|
406
|
-
expertKey: checkpoint.expert.key,
|
|
407
|
-
timestamp: Date.now(),
|
|
408
|
-
runId: setting.runId,
|
|
409
|
-
stepNumber: checkpoint.stepNumber,
|
|
410
|
-
...data
|
|
411
|
-
};
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
var startRun = createEvent("startRun");
|
|
415
|
-
var startGeneration = createEvent("startGeneration");
|
|
416
|
-
var retry = createEvent("retry");
|
|
417
|
-
var callTool = createEvent("callTool");
|
|
418
|
-
var callInteractiveTool = createEvent("callInteractiveTool");
|
|
419
|
-
var callDelegate = createEvent("callDelegate");
|
|
420
|
-
var resolveToolResult = createEvent("resolveToolResult");
|
|
421
|
-
var resolveThought = createEvent("resolveThought");
|
|
422
|
-
var resolvePdfFile = createEvent("resolvePdfFile");
|
|
423
|
-
var resolveImageFile = createEvent("resolveImageFile");
|
|
424
|
-
var attemptCompletion = createEvent("attemptCompletion");
|
|
425
|
-
var finishToolCall = createEvent("finishToolCall");
|
|
426
|
-
var completeRun = createEvent("completeRun");
|
|
427
|
-
var stopRunByInteractiveTool = createEvent("stopRunByInteractiveTool");
|
|
428
|
-
var stopRunByDelegate = createEvent("stopRunByDelegate");
|
|
429
|
-
var stopRunByExceededMaxSteps = createEvent("stopRunByExceededMaxSteps");
|
|
430
|
-
var continueToNextStep = createEvent("continueToNextStep");
|
|
431
|
-
|
|
432
|
-
// src/default-store.ts
|
|
433
|
-
async function defaultRetrieveCheckpoint(runId, checkpointId) {
|
|
434
|
-
const runDir = getRunDir(runId);
|
|
435
|
-
const checkpointFiles = await readdir(runDir, { withFileTypes: true }).then(
|
|
436
|
-
(files) => files.filter((file) => file.isFile() && file.name.startsWith("checkpoint-"))
|
|
437
|
-
);
|
|
438
|
-
const checkpointFile = checkpointFiles.find((file) => file.name.endsWith(`-${checkpointId}.json`));
|
|
439
|
-
if (!checkpointFile) {
|
|
440
|
-
throw new Error(`checkpoint not found: ${runId} ${checkpointId}`);
|
|
441
|
-
}
|
|
442
|
-
const checkpointPath = `${runDir}/${checkpointFile.name}`;
|
|
443
|
-
const checkpoint = await readFile(checkpointPath, "utf8");
|
|
444
|
-
return CheckpointSchema.parse(JSON.parse(checkpoint));
|
|
445
|
-
}
|
|
446
|
-
async function defaultStoreCheckpoint(checkpoint, timestamp) {
|
|
447
|
-
const { id, runId, stepNumber } = checkpoint;
|
|
448
|
-
const runDir = getRunDir(runId);
|
|
449
|
-
const checkpointPath = `${runDir}/checkpoint-${timestamp}-${stepNumber}-${id}.json`;
|
|
450
|
-
await mkdir(runDir, { recursive: true });
|
|
451
|
-
await writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2));
|
|
452
|
-
}
|
|
453
|
-
async function defaultStoreEvent(event) {
|
|
454
|
-
const { timestamp, runId, stepNumber, type } = event;
|
|
455
|
-
const runDir = getRunDir(runId);
|
|
456
|
-
const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
|
|
457
|
-
await mkdir(runDir, { recursive: true });
|
|
458
|
-
await writeFile(eventPath, JSON.stringify(event, null, 2));
|
|
459
|
-
}
|
|
1
|
+
import { setup, assign, createActor } from 'xstate';
|
|
2
|
+
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
|
|
3
|
+
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
4
|
+
import { createAzure } from '@ai-sdk/azure';
|
|
5
|
+
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
6
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
7
|
+
import { knownModels, stopRunByDelegate, stopRunByInteractiveTool, resolveThought, attemptCompletion, resolvePdfFile, resolveImageFile, resolveToolResult, stopRunByExceededMaxSteps, continueToNextStep, retry, completeRun, callDelegate, callInteractiveTool, callTool, startRun, startGeneration, finishToolCall, runParamsSchema, checkpointSchema } from '@perstack/core';
|
|
8
|
+
import { createOllama } from 'ollama-ai-provider-v2';
|
|
9
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
10
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
11
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
12
|
+
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
14
|
+
import { generateText, tool, jsonSchema } from 'ai';
|
|
15
|
+
import { dedent } from 'ts-dedent';
|
|
16
|
+
import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
|
|
17
|
+
import { existsSync } from 'fs';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import { ApiV1Client } from '@perstack/api-client/v1';
|
|
460
20
|
|
|
461
|
-
//
|
|
462
|
-
|
|
463
|
-
name
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
".": "./src/index.ts"
|
|
471
|
-
},
|
|
472
|
-
publishConfig: {
|
|
473
|
-
exports: {
|
|
474
|
-
".": "./dist/index.js"
|
|
475
|
-
},
|
|
476
|
-
types: "./dist/index.d.ts"
|
|
477
|
-
},
|
|
478
|
-
files: [
|
|
479
|
-
"dist"
|
|
480
|
-
],
|
|
481
|
-
scripts: {
|
|
482
|
-
clean: "rm -rf dist",
|
|
483
|
-
dev: "tsup --watch --config ../../tsup.config.ts",
|
|
484
|
-
build: "npm run clean && tsup --config ../../tsup.config.ts",
|
|
485
|
-
prepublishOnly: "npm run clean && npm run build"
|
|
486
|
-
},
|
|
487
|
-
dependencies: {
|
|
488
|
-
"@ai-sdk/anthropic": "^2.0.1",
|
|
489
|
-
"@ai-sdk/google": "^2.0.2",
|
|
490
|
-
"@ai-sdk/openai": "^2.0.3",
|
|
491
|
-
"@modelcontextprotocol/sdk": "^1.17.1",
|
|
492
|
-
"@paralleldrive/cuid2": "^2.2.2",
|
|
493
|
-
ai: "^5.0.4",
|
|
494
|
-
"smol-toml": "^1.4.1",
|
|
495
|
-
"ts-dedent": "^2.2.0",
|
|
496
|
-
xstate: "^5.20.1",
|
|
497
|
-
zod: "^4.0.14"
|
|
498
|
-
},
|
|
499
|
-
devDependencies: {
|
|
500
|
-
"@tsconfig/node22": "^22.0.2",
|
|
501
|
-
"@types/node": "^24.2.0",
|
|
502
|
-
tsup: "^8.5.0",
|
|
503
|
-
typescript: "^5.9.2",
|
|
504
|
-
vitest: "^3.2.4"
|
|
505
|
-
},
|
|
506
|
-
engines: {
|
|
507
|
-
node: ">=22.0.0"
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
// src/events/default-event-listener.ts
|
|
512
|
-
var log = console.info;
|
|
513
|
-
var debug = console.debug;
|
|
514
|
-
var header = (e) => {
|
|
515
|
-
const t = (/* @__PURE__ */ new Date()).toISOString();
|
|
516
|
-
const stepNumber = e.stepNumber;
|
|
517
|
-
const key = e.expertKey;
|
|
518
|
-
return `${t} ${stepNumber} ${key}`;
|
|
519
|
-
};
|
|
520
|
-
async function defaultEventListener(e) {
|
|
521
|
-
await defaultStoreEvent(e);
|
|
522
|
-
switch (e.type) {
|
|
523
|
-
case "startRun": {
|
|
524
|
-
log(`${header(e)} Perstack@${package_default.version} started`);
|
|
525
|
-
break;
|
|
526
|
-
}
|
|
527
|
-
case "startGeneration": {
|
|
528
|
-
log(`${header(e)} Generating tool call`);
|
|
529
|
-
break;
|
|
530
|
-
}
|
|
531
|
-
case "retry": {
|
|
532
|
-
log(`${header(e)} Retrying tool call generation`);
|
|
533
|
-
debug(e.reason);
|
|
534
|
-
break;
|
|
535
|
-
}
|
|
536
|
-
case "callTool": {
|
|
537
|
-
log(`${header(e)} Calling tool`);
|
|
538
|
-
if (e.toolCall.skillName === "@perstack/base") {
|
|
539
|
-
switch (e.toolCall.toolName) {
|
|
540
|
-
case "think": {
|
|
541
|
-
const thought = e.toolCall.args.thought;
|
|
542
|
-
log(`${header(e)} Thought Updated:`);
|
|
543
|
-
debug(thought);
|
|
544
|
-
break;
|
|
545
|
-
}
|
|
546
|
-
case "readPdfFile": {
|
|
547
|
-
const path2 = e.toolCall.args.path;
|
|
548
|
-
log(`${header(e)} Reading PDF: ${path2}`);
|
|
549
|
-
break;
|
|
550
|
-
}
|
|
551
|
-
case "readImageFile": {
|
|
552
|
-
const path2 = e.toolCall.args.path;
|
|
553
|
-
log(`${header(e)} Reading Image: ${path2}`);
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
default: {
|
|
557
|
-
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
558
|
-
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
559
|
-
break;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
} else {
|
|
563
|
-
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
564
|
-
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
565
|
-
}
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
case "callInteractiveTool": {
|
|
569
|
-
log(`${header(e)} Calling interactive tool`);
|
|
570
|
-
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
571
|
-
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
572
|
-
break;
|
|
573
|
-
}
|
|
574
|
-
case "callDelegate": {
|
|
575
|
-
log(`${header(e)} Calling delegate`);
|
|
576
|
-
log(`${header(e)} Tool: ${e.toolCall.toolName}`);
|
|
577
|
-
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
578
|
-
break;
|
|
579
|
-
}
|
|
580
|
-
case "resolveToolResult": {
|
|
581
|
-
log(`${header(e)} Resolved Tool Result`);
|
|
582
|
-
if (e.toolResult.skillName === "@perstack/base") {
|
|
583
|
-
switch (e.toolResult.toolName) {
|
|
584
|
-
case "todo": {
|
|
585
|
-
const text = e.toolResult.result.find((r) => r.type === "textPart")?.text;
|
|
586
|
-
const { todos } = JSON.parse(text ?? "{}");
|
|
587
|
-
log(`${header(e)} Todo:`);
|
|
588
|
-
for (const todo of todos) {
|
|
589
|
-
debug(`${todo.completed ? "[x]" : "[ ]"} ${todo.id}: ${todo.title}`);
|
|
590
|
-
}
|
|
591
|
-
break;
|
|
592
|
-
}
|
|
593
|
-
default: {
|
|
594
|
-
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
595
|
-
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
596
|
-
break;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
} else {
|
|
600
|
-
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
601
|
-
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
602
|
-
}
|
|
603
|
-
break;
|
|
604
|
-
}
|
|
605
|
-
case "resolveThought": {
|
|
606
|
-
log(`${header(e)} Resolved Thought:`, e.toolResult);
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
609
|
-
case "resolvePdfFile": {
|
|
610
|
-
log(`${header(e)} Resolved PDF:`, e.toolResult);
|
|
611
|
-
break;
|
|
612
|
-
}
|
|
613
|
-
case "resolveImageFile": {
|
|
614
|
-
log(`${header(e)} Resolved Image:`, e.toolResult);
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
case "attemptCompletion": {
|
|
618
|
-
log(`${header(e)} Attempting completion`);
|
|
619
|
-
break;
|
|
21
|
+
// src/runtime-state-machine.ts
|
|
22
|
+
function getModel(modelId, providerConfig) {
|
|
23
|
+
switch (providerConfig.name) {
|
|
24
|
+
case "anthropic": {
|
|
25
|
+
const anthropic = createAnthropic({
|
|
26
|
+
apiKey: providerConfig.apiKey,
|
|
27
|
+
baseURL: providerConfig.baseUrl
|
|
28
|
+
});
|
|
29
|
+
return anthropic(modelId);
|
|
620
30
|
}
|
|
621
|
-
case "
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
31
|
+
case "google": {
|
|
32
|
+
const google = createGoogleGenerativeAI({
|
|
33
|
+
apiKey: providerConfig.apiKey,
|
|
34
|
+
baseURL: providerConfig.baseUrl
|
|
35
|
+
});
|
|
36
|
+
return google(modelId);
|
|
626
37
|
}
|
|
627
|
-
case "
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
38
|
+
case "openai": {
|
|
39
|
+
const openai = createOpenAI({
|
|
40
|
+
apiKey: providerConfig.apiKey,
|
|
41
|
+
baseURL: providerConfig.baseUrl,
|
|
42
|
+
organization: providerConfig.organization,
|
|
43
|
+
project: providerConfig.project
|
|
44
|
+
});
|
|
45
|
+
return openai(modelId);
|
|
631
46
|
}
|
|
632
|
-
case "
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
47
|
+
case "ollama": {
|
|
48
|
+
const ollama = createOllama({
|
|
49
|
+
baseURL: providerConfig.baseUrl
|
|
50
|
+
});
|
|
51
|
+
return ollama(modelId);
|
|
636
52
|
}
|
|
637
|
-
case "
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
53
|
+
case "azure-openai": {
|
|
54
|
+
const azure = createAzure({
|
|
55
|
+
apiKey: providerConfig.apiKey,
|
|
56
|
+
resourceName: providerConfig.resourceName,
|
|
57
|
+
apiVersion: providerConfig.apiVersion
|
|
58
|
+
});
|
|
59
|
+
return azure(modelId);
|
|
641
60
|
}
|
|
642
|
-
case "
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
61
|
+
case "amazon-bedrock": {
|
|
62
|
+
const amazonBedrock = createAmazonBedrock({
|
|
63
|
+
accessKeyId: providerConfig.accessKeyId,
|
|
64
|
+
secretAccessKey: providerConfig.secretAccessKey,
|
|
65
|
+
region: providerConfig.region,
|
|
66
|
+
sessionToken: providerConfig.sessionToken
|
|
67
|
+
});
|
|
68
|
+
return amazonBedrock(modelId);
|
|
648
69
|
}
|
|
649
70
|
}
|
|
650
71
|
}
|
|
651
|
-
function
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
`Reasoning: ${e.step.usage.reasoningTokens.toLocaleString()}`,
|
|
655
|
-
`Out: ${e.step.usage.outputTokens.toLocaleString()}`,
|
|
656
|
-
`Total: ${e.step.usage.totalTokens.toLocaleString()}`,
|
|
657
|
-
`Cache-read: ${e.step.usage.cachedInputTokens.toLocaleString()}`
|
|
658
|
-
].join(", ");
|
|
659
|
-
const usageByRun = [
|
|
660
|
-
`In: ${e.checkpoint.usage.inputTokens.toLocaleString()}`,
|
|
661
|
-
`Reasoning: ${e.checkpoint.usage.reasoningTokens.toLocaleString()}`,
|
|
662
|
-
`Out: ${e.checkpoint.usage.outputTokens.toLocaleString()}`,
|
|
663
|
-
`Total: ${e.checkpoint.usage.totalTokens.toLocaleString()}`,
|
|
664
|
-
`Cache-read: ${e.checkpoint.usage.cachedInputTokens.toLocaleString()}`
|
|
665
|
-
].join(", ");
|
|
666
|
-
log(`${header(e)} Tokens usage by step: ${usageByStep}`);
|
|
667
|
-
log(`${header(e)} Tokens usage by run: ${usageByRun}`);
|
|
72
|
+
function getContextWindow(providerName, modelId) {
|
|
73
|
+
const modelConfig = knownModels.find((model) => model.provider === providerName)?.models.find((model) => model.name === modelId);
|
|
74
|
+
return modelConfig?.contextWindow;
|
|
668
75
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
import { createId as createId2 } from "@paralleldrive/cuid2";
|
|
672
|
-
var RunEventEmitter = class {
|
|
673
|
-
listeners = [];
|
|
674
|
-
subscribe(listener) {
|
|
675
|
-
this.listeners.push(listener);
|
|
676
|
-
}
|
|
677
|
-
async emit(event) {
|
|
678
|
-
for (const listener of this.listeners) {
|
|
679
|
-
await listener({
|
|
680
|
-
...event,
|
|
681
|
-
id: createId2(),
|
|
682
|
-
timestamp: Date.now()
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
};
|
|
687
|
-
|
|
688
|
-
// src/schemas/api-registry.ts
|
|
689
|
-
import { z as z3 } from "zod";
|
|
690
|
-
var RegistryV1ExpertSchema = z3.object({
|
|
691
|
-
name: z3.string(),
|
|
692
|
-
version: z3.string(),
|
|
693
|
-
minRuntimeVersion: z3.string(),
|
|
694
|
-
description: z3.string(),
|
|
695
|
-
instruction: z3.string(),
|
|
696
|
-
skills: z3.record(
|
|
697
|
-
z3.string(),
|
|
698
|
-
z3.discriminatedUnion("type", [
|
|
699
|
-
McpStdioSkillSchema.omit({ name: true }),
|
|
700
|
-
McpSseSkillSchema.omit({ name: true }),
|
|
701
|
-
InteractiveSkillSchema.omit({ name: true })
|
|
702
|
-
])
|
|
703
|
-
),
|
|
704
|
-
delegates: z3.array(z3.string()),
|
|
705
|
-
tags: z3.array(z3.string()),
|
|
706
|
-
status: z3.string(),
|
|
707
|
-
owner: z3.object({ name: z3.string() }),
|
|
708
|
-
createdAt: z3.iso.datetime(),
|
|
709
|
-
updatedAt: z3.iso.datetime()
|
|
710
|
-
});
|
|
711
|
-
var RegistryV1ExpertsGetResponseSchema = z3.object({
|
|
712
|
-
data: z3.object({
|
|
713
|
-
expert: RegistryV1ExpertSchema
|
|
714
|
-
})
|
|
715
|
-
});
|
|
716
|
-
|
|
717
|
-
// src/api-clinent.ts
|
|
718
|
-
var Perstack = class {
|
|
719
|
-
baseUrl;
|
|
720
|
-
registry;
|
|
721
|
-
apiKey;
|
|
722
|
-
constructor(params) {
|
|
723
|
-
this.baseUrl = params?.baseUrl ?? process.env.PERSTACK_API_BASE_URL ?? "https://api.perstack.ai";
|
|
724
|
-
this.apiKey = params?.apiKey ?? process.env.PERSTACK_API_KEY;
|
|
725
|
-
this.registry = new RegistryClientV1(this);
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
var RegistryClientV1 = class {
|
|
729
|
-
client;
|
|
730
|
-
endpoint;
|
|
731
|
-
constructor(client) {
|
|
732
|
-
this.client = client;
|
|
733
|
-
this.endpoint = "/api/registry/v1/experts";
|
|
734
|
-
}
|
|
735
|
-
async get(expertKey) {
|
|
736
|
-
const safeExpertKey = encodeURIComponent(expertKey);
|
|
737
|
-
const url = new URL(`${this.endpoint}/${safeExpertKey}`, this.client.baseUrl);
|
|
738
|
-
const headers = {
|
|
739
|
-
"Content-Type": "application/json",
|
|
740
|
-
Authorization: `Bearer ${this.client.apiKey}`
|
|
741
|
-
};
|
|
742
|
-
const result = await fetch(url.toString(), { headers });
|
|
743
|
-
if (!result.ok) {
|
|
744
|
-
throw new Error(
|
|
745
|
-
`Registry returned non-200 status code: ${result.status}, reason: ${result.statusText}`
|
|
746
|
-
);
|
|
747
|
-
}
|
|
748
|
-
const json = await result.json();
|
|
749
|
-
return RegistryV1ExpertsGetResponseSchema.parse(json);
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
// src/resolve-expert-to-run.ts
|
|
754
|
-
async function resolveExpertToRun(expertKey, experts) {
|
|
755
|
-
if (experts[expertKey]) {
|
|
756
|
-
return experts[expertKey];
|
|
757
|
-
}
|
|
758
|
-
const client = new Perstack();
|
|
759
|
-
const { data } = await client.registry.get(expertKey);
|
|
760
|
-
const expert = ExpertSchema.parse({
|
|
761
|
-
...data.expert,
|
|
762
|
-
key: expertKey
|
|
763
|
-
});
|
|
764
|
-
experts[expertKey] = expert;
|
|
765
|
-
return expert;
|
|
76
|
+
function calculateContextWindowUsage(usage, contextWindow) {
|
|
77
|
+
return (usage.inputTokens + usage.cachedInputTokens + usage.outputTokens) / contextWindow;
|
|
766
78
|
}
|
|
767
|
-
|
|
768
|
-
// src/runtime-state-machine.ts
|
|
769
|
-
import { assign, setup } from "xstate";
|
|
770
|
-
|
|
771
|
-
// src/skill-manager.ts
|
|
772
|
-
import { Client as McpClient } from "@modelcontextprotocol/sdk/client/index.js";
|
|
773
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
774
|
-
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
775
|
-
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
776
|
-
import { createId as createId3 } from "@paralleldrive/cuid2";
|
|
777
|
-
import { jsonSchema, tool } from "ai";
|
|
778
|
-
import { ZodError } from "zod";
|
|
779
79
|
var SkillManager = class {
|
|
780
80
|
_toolDefinitions = [];
|
|
781
81
|
_initialized = false;
|
|
@@ -786,6 +86,7 @@ var SkillManager = class {
|
|
|
786
86
|
expert;
|
|
787
87
|
_mcpClient;
|
|
788
88
|
_params;
|
|
89
|
+
_env;
|
|
789
90
|
constructor(params) {
|
|
790
91
|
this._params = params;
|
|
791
92
|
this.type = params.type;
|
|
@@ -793,14 +94,17 @@ var SkillManager = class {
|
|
|
793
94
|
case "mcp":
|
|
794
95
|
this.name = params.skill.name;
|
|
795
96
|
this.skill = params.skill;
|
|
97
|
+
this._env = params.env;
|
|
796
98
|
break;
|
|
797
99
|
case "interactive":
|
|
798
100
|
this.name = params.interactiveSkill.name;
|
|
799
101
|
this.interactiveSkill = params.interactiveSkill;
|
|
102
|
+
this._env = {};
|
|
800
103
|
break;
|
|
801
104
|
case "delegate":
|
|
802
105
|
this.name = params.expert.name;
|
|
803
106
|
this.expert = params.expert;
|
|
107
|
+
this._env = {};
|
|
804
108
|
break;
|
|
805
109
|
}
|
|
806
110
|
}
|
|
@@ -821,7 +125,7 @@ var SkillManager = class {
|
|
|
821
125
|
}
|
|
822
126
|
}
|
|
823
127
|
async _initMcpSkill(params) {
|
|
824
|
-
this._mcpClient = new
|
|
128
|
+
this._mcpClient = new Client({
|
|
825
129
|
name: `${params.skill.name}-mcp-client`,
|
|
826
130
|
version: "1.0.0"
|
|
827
131
|
});
|
|
@@ -830,14 +134,16 @@ var SkillManager = class {
|
|
|
830
134
|
if (!params.skill.command) {
|
|
831
135
|
throw new Error(`Skill ${params.skill.name} has no command`);
|
|
832
136
|
}
|
|
137
|
+
const env = {};
|
|
138
|
+
const { requiredEnv } = params.skill;
|
|
139
|
+
for (const envName of requiredEnv) {
|
|
140
|
+
if (!this._env[envName]) {
|
|
141
|
+
throw new Error(`Skill ${params.skill.name} requires environment variable ${envName}`);
|
|
142
|
+
}
|
|
143
|
+
env[envName] = this._env[envName];
|
|
144
|
+
}
|
|
833
145
|
const { command, args } = this._getCommandArgs(params.skill);
|
|
834
|
-
const transport = new StdioClientTransport({
|
|
835
|
-
command,
|
|
836
|
-
args,
|
|
837
|
-
env: Object.fromEntries(
|
|
838
|
-
Object.entries(process.env).filter(([_, value]) => value !== void 0 && value !== "").map(([key, value]) => [key, value])
|
|
839
|
-
)
|
|
840
|
-
});
|
|
146
|
+
const transport = new StdioClientTransport({ command, args, env });
|
|
841
147
|
await this._mcpClient.connect(transport);
|
|
842
148
|
break;
|
|
843
149
|
}
|
|
@@ -948,13 +254,10 @@ var SkillManager = class {
|
|
|
948
254
|
{
|
|
949
255
|
type: "textPart",
|
|
950
256
|
text: `Error calling tool ${toolName}: ${error.message}`,
|
|
951
|
-
id:
|
|
257
|
+
id: createId()
|
|
952
258
|
}
|
|
953
259
|
];
|
|
954
260
|
}
|
|
955
|
-
if (error instanceof ZodError) {
|
|
956
|
-
return [{ type: "textPart", text: `Invalid tool call arguments: ${error}`, id: createId3() }];
|
|
957
|
-
}
|
|
958
261
|
throw error;
|
|
959
262
|
}
|
|
960
263
|
_convertToolResult(result, toolName, input) {
|
|
@@ -963,7 +266,7 @@ var SkillManager = class {
|
|
|
963
266
|
{
|
|
964
267
|
type: "textPart",
|
|
965
268
|
text: `Tool ${toolName} returned nothing with arguments: ${JSON.stringify(input)}`,
|
|
966
|
-
id:
|
|
269
|
+
id: createId()
|
|
967
270
|
}
|
|
968
271
|
];
|
|
969
272
|
}
|
|
@@ -973,9 +276,9 @@ var SkillManager = class {
|
|
|
973
276
|
switch (part.type) {
|
|
974
277
|
case "text":
|
|
975
278
|
if (!part.text || part.text === "") {
|
|
976
|
-
return { type: "textPart", text: "Error: No content", id:
|
|
279
|
+
return { type: "textPart", text: "Error: No content", id: createId() };
|
|
977
280
|
}
|
|
978
|
-
return { type: "textPart", text: part.text, id:
|
|
281
|
+
return { type: "textPart", text: part.text, id: createId() };
|
|
979
282
|
case "image":
|
|
980
283
|
if (!part.data || !part.mimeType) {
|
|
981
284
|
throw new Error("Image part must have both data and mimeType");
|
|
@@ -984,7 +287,7 @@ var SkillManager = class {
|
|
|
984
287
|
type: "imageInlinePart",
|
|
985
288
|
encodedData: part.data,
|
|
986
289
|
mimeType: part.mimeType,
|
|
987
|
-
id:
|
|
290
|
+
id: createId()
|
|
988
291
|
};
|
|
989
292
|
case "resource":
|
|
990
293
|
if (!part.resource) {
|
|
@@ -998,39 +301,36 @@ var SkillManager = class {
|
|
|
998
301
|
throw new Error(`Resource ${JSON.stringify(resource)} has no mimeType`);
|
|
999
302
|
}
|
|
1000
303
|
if (resource.text && typeof resource.text === "string") {
|
|
1001
|
-
return { type: "textPart", text: resource.text, id:
|
|
304
|
+
return { type: "textPart", text: resource.text, id: createId() };
|
|
1002
305
|
}
|
|
1003
306
|
if (resource.blob && typeof resource.blob === "string") {
|
|
1004
307
|
return {
|
|
1005
308
|
type: "fileInlinePart",
|
|
1006
309
|
encodedData: resource.blob,
|
|
1007
310
|
mimeType: resource.mimeType,
|
|
1008
|
-
id:
|
|
311
|
+
id: createId()
|
|
1009
312
|
};
|
|
1010
313
|
}
|
|
1011
314
|
throw new Error(`Unsupported resource type: ${JSON.stringify(resource)}`);
|
|
1012
315
|
}
|
|
1013
316
|
};
|
|
1014
|
-
async function getSkillManagers(expert, experts) {
|
|
317
|
+
async function getSkillManagers(expert, experts, setting) {
|
|
318
|
+
const { perstackBaseSkillArgs, env } = setting;
|
|
1015
319
|
const skillManagers = {};
|
|
1016
320
|
const { skills } = expert;
|
|
1017
321
|
if (!skills["@perstack/base"]) {
|
|
1018
|
-
|
|
1019
|
-
type: "mcpStdioSkill",
|
|
1020
|
-
name: "@perstack/base",
|
|
1021
|
-
description: "The base skill for Perstack",
|
|
1022
|
-
pick: [],
|
|
1023
|
-
omit: [],
|
|
1024
|
-
command: "npx",
|
|
1025
|
-
args: ["-y", "@perstack/base"],
|
|
1026
|
-
requiredEnv: []
|
|
1027
|
-
};
|
|
322
|
+
throw new Error("Base skill is not defined");
|
|
1028
323
|
}
|
|
1029
324
|
const mcpSkillManagers = await Promise.all(
|
|
1030
325
|
Object.values(skills).filter((skill) => skill.type === "mcpStdioSkill" || skill.type === "mcpSseSkill").map(async (skill) => {
|
|
326
|
+
if (perstackBaseSkillArgs && skill.type === "mcpStdioSkill" && skill.name === "@perstack/base") {
|
|
327
|
+
skill.packageName = void 0;
|
|
328
|
+
skill.args = ["-y", ...perstackBaseSkillArgs];
|
|
329
|
+
}
|
|
1031
330
|
const skillManager = new SkillManager({
|
|
1032
331
|
type: "mcp",
|
|
1033
|
-
skill
|
|
332
|
+
skill,
|
|
333
|
+
env
|
|
1034
334
|
});
|
|
1035
335
|
await skillManager.init();
|
|
1036
336
|
return skillManager;
|
|
@@ -1110,7 +410,7 @@ async function callingDelegateLogic({
|
|
|
1110
410
|
}
|
|
1111
411
|
const { id, toolName, args } = step.toolCall;
|
|
1112
412
|
const skillManager = await getSkillManagerByToolName(skillManagers, toolName);
|
|
1113
|
-
if (!skillManager
|
|
413
|
+
if (!skillManager.expert) {
|
|
1114
414
|
throw new Error(`Delegation error: skill manager "${toolName}" not found`);
|
|
1115
415
|
}
|
|
1116
416
|
if (!args || !args.query || typeof args.query !== "string") {
|
|
@@ -1137,8 +437,6 @@ async function callingDelegateLogic({
|
|
|
1137
437
|
}
|
|
1138
438
|
});
|
|
1139
439
|
}
|
|
1140
|
-
|
|
1141
|
-
// src/states/calling-interactive-tool.ts
|
|
1142
440
|
async function callingInteractiveToolLogic({
|
|
1143
441
|
setting,
|
|
1144
442
|
checkpoint,
|
|
@@ -1155,8 +453,6 @@ async function callingInteractiveToolLogic({
|
|
|
1155
453
|
}
|
|
1156
454
|
});
|
|
1157
455
|
}
|
|
1158
|
-
|
|
1159
|
-
// src/states/calling-tool.ts
|
|
1160
456
|
async function callingToolLogic({
|
|
1161
457
|
setting,
|
|
1162
458
|
checkpoint,
|
|
@@ -1189,9 +485,6 @@ async function callingToolLogic({
|
|
|
1189
485
|
}
|
|
1190
486
|
return resolveToolResult(setting, checkpoint, { toolResult });
|
|
1191
487
|
}
|
|
1192
|
-
|
|
1193
|
-
// src/states/finishing-step.ts
|
|
1194
|
-
import { createId as createId4 } from "@paralleldrive/cuid2";
|
|
1195
488
|
async function finishingStepLogic({
|
|
1196
489
|
setting,
|
|
1197
490
|
checkpoint,
|
|
@@ -1219,26 +512,19 @@ async function finishingStepLogic({
|
|
|
1219
512
|
},
|
|
1220
513
|
nextCheckpoint: {
|
|
1221
514
|
...checkpoint,
|
|
1222
|
-
id:
|
|
515
|
+
id: createId(),
|
|
1223
516
|
stepNumber: checkpoint.stepNumber + 1
|
|
1224
517
|
}
|
|
1225
518
|
});
|
|
1226
519
|
}
|
|
1227
|
-
|
|
1228
|
-
// src/states/generating-run-result.ts
|
|
1229
|
-
import { generateText } from "ai";
|
|
1230
|
-
|
|
1231
|
-
// src/messages/message.ts
|
|
1232
|
-
import { createId as createId5 } from "@paralleldrive/cuid2";
|
|
1233
|
-
import { dedent } from "ts-dedent";
|
|
1234
520
|
function createUserMessage(contents) {
|
|
1235
521
|
return {
|
|
1236
522
|
type: "userMessage",
|
|
1237
523
|
contents: contents.map((part) => ({
|
|
1238
524
|
...part,
|
|
1239
|
-
id:
|
|
525
|
+
id: createId()
|
|
1240
526
|
})),
|
|
1241
|
-
id:
|
|
527
|
+
id: createId()
|
|
1242
528
|
};
|
|
1243
529
|
}
|
|
1244
530
|
function createExpertMessage(contents) {
|
|
@@ -1246,9 +532,9 @@ function createExpertMessage(contents) {
|
|
|
1246
532
|
type: "expertMessage",
|
|
1247
533
|
contents: contents.map((part) => ({
|
|
1248
534
|
...part,
|
|
1249
|
-
id:
|
|
535
|
+
id: createId()
|
|
1250
536
|
})),
|
|
1251
|
-
id:
|
|
537
|
+
id: createId()
|
|
1252
538
|
};
|
|
1253
539
|
}
|
|
1254
540
|
function createToolMessage(contents) {
|
|
@@ -1258,11 +544,11 @@ function createToolMessage(contents) {
|
|
|
1258
544
|
...part,
|
|
1259
545
|
contents: part.contents.map((part2) => ({
|
|
1260
546
|
...part2,
|
|
1261
|
-
id:
|
|
547
|
+
id: createId()
|
|
1262
548
|
})),
|
|
1263
|
-
id:
|
|
549
|
+
id: createId()
|
|
1264
550
|
})),
|
|
1265
|
-
id:
|
|
551
|
+
id: createId()
|
|
1266
552
|
};
|
|
1267
553
|
}
|
|
1268
554
|
function messageToCoreMessage(message) {
|
|
@@ -1476,7 +762,7 @@ async function generatingRunResultLogic({
|
|
|
1476
762
|
)
|
|
1477
763
|
}
|
|
1478
764
|
]);
|
|
1479
|
-
const model = getModel(setting.model);
|
|
765
|
+
const model = getModel(setting.model, setting.providerConfig);
|
|
1480
766
|
const { messages } = checkpoint;
|
|
1481
767
|
let generationResult;
|
|
1482
768
|
try {
|
|
@@ -1506,7 +792,7 @@ async function generatingRunResultLogic({
|
|
|
1506
792
|
...checkpoint,
|
|
1507
793
|
messages: [...messages, ...newMessages],
|
|
1508
794
|
usage: sumUsage(checkpoint.usage, usage),
|
|
1509
|
-
contextWindowUsage:
|
|
795
|
+
contextWindowUsage: checkpoint.contextWindow ? calculateContextWindowUsage(usage, checkpoint.contextWindow) : void 0,
|
|
1510
796
|
status: "completed"
|
|
1511
797
|
},
|
|
1512
798
|
step: {
|
|
@@ -1519,20 +805,16 @@ async function generatingRunResultLogic({
|
|
|
1519
805
|
usage
|
|
1520
806
|
});
|
|
1521
807
|
}
|
|
1522
|
-
|
|
1523
|
-
// src/states/generating-tool-call.ts
|
|
1524
|
-
import { createId as createId6 } from "@paralleldrive/cuid2";
|
|
1525
|
-
import { generateText as generateText2 } from "ai";
|
|
1526
808
|
async function generatingToolCallLogic({
|
|
1527
809
|
setting,
|
|
1528
810
|
checkpoint,
|
|
1529
811
|
skillManagers
|
|
1530
812
|
}) {
|
|
1531
813
|
const { messages } = checkpoint;
|
|
1532
|
-
const model = getModel(setting.model);
|
|
814
|
+
const model = getModel(setting.model, setting.providerConfig);
|
|
1533
815
|
let result;
|
|
1534
816
|
try {
|
|
1535
|
-
result = await
|
|
817
|
+
result = await generateText({
|
|
1536
818
|
model,
|
|
1537
819
|
messages: messages.map(messageToCoreMessage),
|
|
1538
820
|
temperature: setting.temperature,
|
|
@@ -1592,7 +874,7 @@ async function generatingToolCallLogic({
|
|
|
1592
874
|
},
|
|
1593
875
|
usage
|
|
1594
876
|
};
|
|
1595
|
-
if (finishReason === "tool-calls") {
|
|
877
|
+
if (finishReason === "tool-calls" || finishReason === "stop") {
|
|
1596
878
|
switch (skillManager.type) {
|
|
1597
879
|
case "mcp":
|
|
1598
880
|
return callTool(setting, checkpoint, eventPayload);
|
|
@@ -1632,18 +914,14 @@ async function generatingToolCallLogic({
|
|
|
1632
914
|
id: toolCall.toolCallId,
|
|
1633
915
|
skillName: skillManager.name,
|
|
1634
916
|
toolName: toolCall.toolName,
|
|
1635
|
-
result: [{ type: "textPart", id:
|
|
917
|
+
result: [{ type: "textPart", id: createId(), text: reason }]
|
|
1636
918
|
},
|
|
1637
919
|
usage
|
|
1638
920
|
});
|
|
1639
921
|
}
|
|
1640
922
|
throw new Error(`Unexpected finish reason: ${finishReason}`);
|
|
1641
923
|
}
|
|
1642
|
-
|
|
1643
|
-
// src/messages/instruction-message.ts
|
|
1644
|
-
import { createId as createId7 } from "@paralleldrive/cuid2";
|
|
1645
|
-
import { dedent as dedent2 } from "ts-dedent";
|
|
1646
|
-
var metaInstruction = dedent2`
|
|
924
|
+
var metaInstruction = dedent`
|
|
1647
925
|
IMPORTANT:
|
|
1648
926
|
You are NOT an "interactive" AI agent.
|
|
1649
927
|
From the start of the agent loop until the completion of the task,
|
|
@@ -1661,33 +939,32 @@ var metaInstruction = dedent2`
|
|
|
1661
939
|
5. Notify Task Completion: Call the attemptCompletion tool to inform the user when the task is complete
|
|
1662
940
|
6. Generate Final Results: Produce a final result that clearly describes each task you performed, step by step
|
|
1663
941
|
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
-
|
|
1669
|
-
-
|
|
1670
|
-
-
|
|
1671
|
-
-
|
|
1672
|
-
-
|
|
1673
|
-
-
|
|
1674
|
-
-
|
|
942
|
+
Conditions for ending the agent loop:
|
|
943
|
+
If any of the following apply, **immediately call the attemptCompletion tool**.
|
|
944
|
+
When the agent loop must end, calling any tool other than attemptCompletion is highly dangerous.
|
|
945
|
+
Under all circumstances, strictly follow this rule.
|
|
946
|
+
- When the task is complete
|
|
947
|
+
- When the user's request is outside your expertise
|
|
948
|
+
- When the user makes an unethical request
|
|
949
|
+
- When the user's request is unintelligible
|
|
950
|
+
- When the request may pose security risks
|
|
951
|
+
- When the request may harm or inconvenience others
|
|
952
|
+
- When the request contains inappropriate or sexual content
|
|
1675
953
|
|
|
1676
954
|
Rules for requests outside your area of expertise:
|
|
1677
955
|
- Tell your area of expertise to the user in final results
|
|
1678
|
-
- In the Final Result, you can show the user how to create an expert that they might need; This can be done by running the \`parrot new\` (no arguments required) command.
|
|
1679
956
|
|
|
1680
|
-
|
|
1681
|
-
-
|
|
1682
|
-
-
|
|
1683
|
-
-
|
|
957
|
+
General approach and output quality rules:
|
|
958
|
+
- The user recognizes you as an expert in this domain
|
|
959
|
+
- As an expert, execute each step with thorough reasoning and high confidence
|
|
960
|
+
- As an expert, deliver output exceeding the user's expectations
|
|
1684
961
|
|
|
1685
962
|
Environment information:
|
|
1686
963
|
- Current time is ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1687
964
|
- Current working directory is ${process.cwd()}
|
|
1688
965
|
`;
|
|
1689
966
|
function createInstructionMessage(expert, experts) {
|
|
1690
|
-
const instruction =
|
|
967
|
+
const instruction = dedent`
|
|
1691
968
|
You are Perstack, an AI expert that tackles tasks requested by users by utilizing all available tools.
|
|
1692
969
|
|
|
1693
970
|
(The following information describes your nature and role as an AI, the mechanisms of the AI system, and other meta-cognitive aspects.)
|
|
@@ -1715,12 +992,12 @@ function createInstructionMessage(expert, experts) {
|
|
|
1715
992
|
type: "instructionMessage",
|
|
1716
993
|
contents: [
|
|
1717
994
|
{
|
|
1718
|
-
id:
|
|
995
|
+
id: createId(),
|
|
1719
996
|
type: "textPart",
|
|
1720
997
|
text: instruction
|
|
1721
998
|
}
|
|
1722
999
|
],
|
|
1723
|
-
id:
|
|
1000
|
+
id: createId(),
|
|
1724
1001
|
cache: true
|
|
1725
1002
|
};
|
|
1726
1003
|
}
|
|
@@ -1729,7 +1006,7 @@ function getSkillRules(expert) {
|
|
|
1729
1006
|
if (!skill.rule) {
|
|
1730
1007
|
return acc;
|
|
1731
1008
|
}
|
|
1732
|
-
return
|
|
1009
|
+
return dedent`
|
|
1733
1010
|
${acc}
|
|
1734
1011
|
|
|
1735
1012
|
"${skill.name}" skill rules:
|
|
@@ -1743,7 +1020,7 @@ function getDelegateRules(expert, experts) {
|
|
|
1743
1020
|
if (!delegate) {
|
|
1744
1021
|
return acc;
|
|
1745
1022
|
}
|
|
1746
|
-
return
|
|
1023
|
+
return dedent`
|
|
1747
1024
|
${acc}
|
|
1748
1025
|
|
|
1749
1026
|
About "${delegate.name}":
|
|
@@ -1801,8 +1078,6 @@ async function initLogic({
|
|
|
1801
1078
|
});
|
|
1802
1079
|
}
|
|
1803
1080
|
}
|
|
1804
|
-
|
|
1805
|
-
// src/states/preparing-for-step.ts
|
|
1806
1081
|
async function preparingForStepLogic({
|
|
1807
1082
|
setting,
|
|
1808
1083
|
checkpoint
|
|
@@ -1811,9 +1086,6 @@ async function preparingForStepLogic({
|
|
|
1811
1086
|
messages: checkpoint.messages
|
|
1812
1087
|
});
|
|
1813
1088
|
}
|
|
1814
|
-
|
|
1815
|
-
// src/states/resolving-image-file.ts
|
|
1816
|
-
import { readFile as readFile2 } from "fs/promises";
|
|
1817
1089
|
async function resolvingImageFileLogic({
|
|
1818
1090
|
setting,
|
|
1819
1091
|
checkpoint,
|
|
@@ -1838,7 +1110,7 @@ async function resolvingImageFileLogic({
|
|
|
1838
1110
|
continue;
|
|
1839
1111
|
}
|
|
1840
1112
|
const { path: path2, mimeType, size } = imageInfo;
|
|
1841
|
-
const file = await
|
|
1113
|
+
const file = await readFile(path2).then((buffer) => ({
|
|
1842
1114
|
encodedData: buffer.toString("base64"),
|
|
1843
1115
|
mimeType,
|
|
1844
1116
|
size
|
|
@@ -1862,9 +1134,6 @@ async function resolvingImageFileLogic({
|
|
|
1862
1134
|
]
|
|
1863
1135
|
});
|
|
1864
1136
|
}
|
|
1865
|
-
|
|
1866
|
-
// src/states/resolving-pdf-file.ts
|
|
1867
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
1868
1137
|
async function resolvingPdfFileLogic({
|
|
1869
1138
|
setting,
|
|
1870
1139
|
checkpoint,
|
|
@@ -1889,7 +1158,7 @@ async function resolvingPdfFileLogic({
|
|
|
1889
1158
|
continue;
|
|
1890
1159
|
}
|
|
1891
1160
|
const { path: path2, mimeType, size } = pdfInfo;
|
|
1892
|
-
const file = await
|
|
1161
|
+
const file = await readFile(path2).then((buffer) => ({
|
|
1893
1162
|
encodedData: buffer.toString("base64"),
|
|
1894
1163
|
mimeType,
|
|
1895
1164
|
size
|
|
@@ -1919,8 +1188,6 @@ async function resolvingPdfFileLogic({
|
|
|
1919
1188
|
]
|
|
1920
1189
|
});
|
|
1921
1190
|
}
|
|
1922
|
-
|
|
1923
|
-
// src/states/resolving-tool-result.ts
|
|
1924
1191
|
async function resolvingToolResultLogic({
|
|
1925
1192
|
setting,
|
|
1926
1193
|
checkpoint,
|
|
@@ -2037,10 +1304,7 @@ var runtimeStateMachine = setup({
|
|
|
2037
1304
|
...context.checkpoint,
|
|
2038
1305
|
messages: [...context.checkpoint.messages, event.newMessage],
|
|
2039
1306
|
usage: sumUsage(context.checkpoint.usage, event.usage),
|
|
2040
|
-
contextWindowUsage:
|
|
2041
|
-
event.usage,
|
|
2042
|
-
context.checkpoint.contextWindow
|
|
2043
|
-
)
|
|
1307
|
+
contextWindowUsage: context.checkpoint.contextWindow ? calculateContextWindowUsage(event.usage, context.checkpoint.contextWindow) : void 0
|
|
2044
1308
|
}),
|
|
2045
1309
|
step: ({ context, event }) => ({
|
|
2046
1310
|
...context.step,
|
|
@@ -2057,10 +1321,7 @@ var runtimeStateMachine = setup({
|
|
|
2057
1321
|
...context.checkpoint,
|
|
2058
1322
|
messages: [...context.checkpoint.messages, event.newMessage],
|
|
2059
1323
|
usage: sumUsage(context.checkpoint.usage, event.usage),
|
|
2060
|
-
contextWindowUsage:
|
|
2061
|
-
event.usage,
|
|
2062
|
-
context.checkpoint.contextWindow
|
|
2063
|
-
)
|
|
1324
|
+
contextWindowUsage: context.checkpoint.contextWindow ? calculateContextWindowUsage(event.usage, context.checkpoint.contextWindow) : void 0
|
|
2064
1325
|
}),
|
|
2065
1326
|
step: ({ context, event }) => ({
|
|
2066
1327
|
...context.step,
|
|
@@ -2077,10 +1338,7 @@ var runtimeStateMachine = setup({
|
|
|
2077
1338
|
...context.checkpoint,
|
|
2078
1339
|
messages: [...context.checkpoint.messages, event.newMessage],
|
|
2079
1340
|
usage: sumUsage(context.checkpoint.usage, event.usage),
|
|
2080
|
-
contextWindowUsage:
|
|
2081
|
-
event.usage,
|
|
2082
|
-
context.checkpoint.contextWindow
|
|
2083
|
-
)
|
|
1341
|
+
contextWindowUsage: context.checkpoint.contextWindow ? calculateContextWindowUsage(event.usage, context.checkpoint.contextWindow) : void 0
|
|
2084
1342
|
}),
|
|
2085
1343
|
step: ({ context, event }) => ({
|
|
2086
1344
|
...context.step,
|
|
@@ -2312,73 +1570,272 @@ var StateMachineLogics = {
|
|
|
2312
1570
|
CallingDelegate: callingDelegateLogic,
|
|
2313
1571
|
FinishingStep: finishingStepLogic
|
|
2314
1572
|
};
|
|
1573
|
+
async function defaultRetrieveCheckpoint(runId, checkpointId) {
|
|
1574
|
+
const runDir = getRunDir(runId);
|
|
1575
|
+
const checkpointFiles = await readdir(runDir, { withFileTypes: true }).then(
|
|
1576
|
+
(files) => files.filter((file) => file.isFile() && file.name.startsWith("checkpoint-"))
|
|
1577
|
+
);
|
|
1578
|
+
const checkpointFile = checkpointFiles.find((file) => file.name.endsWith(`-${checkpointId}.json`));
|
|
1579
|
+
if (!checkpointFile) {
|
|
1580
|
+
throw new Error(`checkpoint not found: ${runId} ${checkpointId}`);
|
|
1581
|
+
}
|
|
1582
|
+
const checkpointPath = `${runDir}/${checkpointFile.name}`;
|
|
1583
|
+
const checkpoint = await readFile(checkpointPath, "utf8");
|
|
1584
|
+
return checkpointSchema.parse(JSON.parse(checkpoint));
|
|
1585
|
+
}
|
|
1586
|
+
async function defaultStoreCheckpoint(checkpoint, timestamp) {
|
|
1587
|
+
const { id, runId, stepNumber } = checkpoint;
|
|
1588
|
+
const runDir = getRunDir(runId);
|
|
1589
|
+
const checkpointPath = `${runDir}/checkpoint-${timestamp}-${stepNumber}-${id}.json`;
|
|
1590
|
+
await mkdir(runDir, { recursive: true });
|
|
1591
|
+
await writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2));
|
|
1592
|
+
}
|
|
1593
|
+
async function defaultStoreEvent(event) {
|
|
1594
|
+
const { timestamp, runId, stepNumber, type } = event;
|
|
1595
|
+
const runDir = getRunDir(runId);
|
|
1596
|
+
const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
|
|
1597
|
+
await mkdir(runDir, { recursive: true });
|
|
1598
|
+
await writeFile(eventPath, JSON.stringify(event, null, 2));
|
|
1599
|
+
}
|
|
2315
1600
|
|
|
2316
|
-
//
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
}
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
1601
|
+
// package.json
|
|
1602
|
+
var package_default = {
|
|
1603
|
+
version: "0.0.26"};
|
|
1604
|
+
|
|
1605
|
+
// src/events/default-event-listener.ts
|
|
1606
|
+
var log = console.info;
|
|
1607
|
+
var debug = console.debug;
|
|
1608
|
+
var header = (e) => {
|
|
1609
|
+
const t = (/* @__PURE__ */ new Date()).toISOString();
|
|
1610
|
+
const stepNumber = e.stepNumber;
|
|
1611
|
+
const key = e.expertKey;
|
|
1612
|
+
return `${t} ${stepNumber} ${key}`;
|
|
1613
|
+
};
|
|
1614
|
+
async function defaultEventListener(e) {
|
|
1615
|
+
await defaultStoreEvent(e);
|
|
1616
|
+
switch (e.type) {
|
|
1617
|
+
case "startRun": {
|
|
1618
|
+
log(`${header(e)} Perstack@${package_default.version} started`);
|
|
1619
|
+
break;
|
|
1620
|
+
}
|
|
1621
|
+
case "startGeneration": {
|
|
1622
|
+
log(`${header(e)} Generating tool call`);
|
|
1623
|
+
break;
|
|
1624
|
+
}
|
|
1625
|
+
case "retry": {
|
|
1626
|
+
log(`${header(e)} Retrying tool call generation`);
|
|
1627
|
+
debug(e.reason);
|
|
1628
|
+
break;
|
|
1629
|
+
}
|
|
1630
|
+
case "callTool": {
|
|
1631
|
+
log(`${header(e)} Calling tool`);
|
|
1632
|
+
if (e.toolCall.skillName === "@perstack/base") {
|
|
1633
|
+
switch (e.toolCall.toolName) {
|
|
1634
|
+
case "think": {
|
|
1635
|
+
const thought = e.toolCall.args.thought;
|
|
1636
|
+
log(`${header(e)} Thought Updated:`);
|
|
1637
|
+
debug(thought);
|
|
1638
|
+
break;
|
|
1639
|
+
}
|
|
1640
|
+
case "readPdfFile": {
|
|
1641
|
+
const path2 = e.toolCall.args.path;
|
|
1642
|
+
log(`${header(e)} Reading PDF: ${path2}`);
|
|
1643
|
+
break;
|
|
1644
|
+
}
|
|
1645
|
+
case "readImageFile": {
|
|
1646
|
+
const path2 = e.toolCall.args.path;
|
|
1647
|
+
log(`${header(e)} Reading Image: ${path2}`);
|
|
1648
|
+
break;
|
|
1649
|
+
}
|
|
1650
|
+
default: {
|
|
1651
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
1652
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
1653
|
+
break;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
} else {
|
|
1657
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
1658
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
1659
|
+
}
|
|
1660
|
+
break;
|
|
1661
|
+
}
|
|
1662
|
+
case "callInteractiveTool": {
|
|
1663
|
+
log(`${header(e)} Calling interactive tool`);
|
|
1664
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
1665
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
1666
|
+
break;
|
|
1667
|
+
}
|
|
1668
|
+
case "callDelegate": {
|
|
1669
|
+
log(`${header(e)} Calling delegate`);
|
|
1670
|
+
log(`${header(e)} Tool: ${e.toolCall.toolName}`);
|
|
1671
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
1672
|
+
break;
|
|
1673
|
+
}
|
|
1674
|
+
case "resolveToolResult": {
|
|
1675
|
+
log(`${header(e)} Resolved Tool Result`);
|
|
1676
|
+
if (e.toolResult.skillName === "@perstack/base") {
|
|
1677
|
+
switch (e.toolResult.toolName) {
|
|
1678
|
+
case "todo": {
|
|
1679
|
+
const text = e.toolResult.result.find((r) => r.type === "textPart")?.text;
|
|
1680
|
+
const { todos } = JSON.parse(text ?? "{}");
|
|
1681
|
+
log(`${header(e)} Todo:`);
|
|
1682
|
+
for (const todo of todos) {
|
|
1683
|
+
debug(`${todo.completed ? "[x]" : "[ ]"} ${todo.id}: ${todo.title}`);
|
|
1684
|
+
}
|
|
1685
|
+
break;
|
|
1686
|
+
}
|
|
1687
|
+
default: {
|
|
1688
|
+
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
1689
|
+
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
1690
|
+
break;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
} else {
|
|
1694
|
+
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
1695
|
+
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
1696
|
+
}
|
|
1697
|
+
break;
|
|
1698
|
+
}
|
|
1699
|
+
case "resolveThought": {
|
|
1700
|
+
log(`${header(e)} Resolved Thought:`, e.toolResult);
|
|
1701
|
+
break;
|
|
1702
|
+
}
|
|
1703
|
+
case "resolvePdfFile": {
|
|
1704
|
+
log(`${header(e)} Resolved PDF:`, e.toolResult);
|
|
1705
|
+
break;
|
|
1706
|
+
}
|
|
1707
|
+
case "resolveImageFile": {
|
|
1708
|
+
log(`${header(e)} Resolved Image:`, e.toolResult);
|
|
1709
|
+
break;
|
|
1710
|
+
}
|
|
1711
|
+
case "attemptCompletion": {
|
|
1712
|
+
log(`${header(e)} Attempting completion`);
|
|
1713
|
+
break;
|
|
1714
|
+
}
|
|
1715
|
+
case "completeRun": {
|
|
1716
|
+
logUsage(e);
|
|
1717
|
+
log(`${header(e)} Completing run`);
|
|
1718
|
+
debug(`${header(e)} Result:`, e.text);
|
|
1719
|
+
break;
|
|
1720
|
+
}
|
|
1721
|
+
case "stopRunByInteractiveTool": {
|
|
1722
|
+
logUsage(e);
|
|
1723
|
+
log(`${header(e)} Stopping run by interactive tool`);
|
|
1724
|
+
break;
|
|
1725
|
+
}
|
|
1726
|
+
case "stopRunByDelegate": {
|
|
1727
|
+
logUsage(e);
|
|
1728
|
+
log(`${header(e)} Stopping run by delegate`);
|
|
1729
|
+
break;
|
|
1730
|
+
}
|
|
1731
|
+
case "stopRunByExceededMaxSteps": {
|
|
1732
|
+
logUsage(e);
|
|
1733
|
+
log(`${header(e)} Stopping run by exceeded max steps`);
|
|
1734
|
+
break;
|
|
1735
|
+
}
|
|
1736
|
+
case "continueToNextStep": {
|
|
1737
|
+
logUsage(e);
|
|
1738
|
+
log(`${header(e)} Continuing to next step`);
|
|
1739
|
+
if (e.checkpoint.contextWindowUsage) {
|
|
1740
|
+
log(`${header(e)} Context window usage: ${e.checkpoint.contextWindowUsage.toFixed(2)}%`);
|
|
1741
|
+
}
|
|
1742
|
+
break;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
function logUsage(e) {
|
|
1747
|
+
const usageByStep = [
|
|
1748
|
+
`In: ${e.step.usage.inputTokens.toLocaleString()}`,
|
|
1749
|
+
`Reasoning: ${e.step.usage.reasoningTokens.toLocaleString()}`,
|
|
1750
|
+
`Out: ${e.step.usage.outputTokens.toLocaleString()}`,
|
|
1751
|
+
`Total: ${e.step.usage.totalTokens.toLocaleString()}`,
|
|
1752
|
+
`Cache-read: ${e.step.usage.cachedInputTokens.toLocaleString()}`
|
|
1753
|
+
].join(", ");
|
|
1754
|
+
const usageByRun = [
|
|
1755
|
+
`In: ${e.checkpoint.usage.inputTokens.toLocaleString()}`,
|
|
1756
|
+
`Reasoning: ${e.checkpoint.usage.reasoningTokens.toLocaleString()}`,
|
|
1757
|
+
`Out: ${e.checkpoint.usage.outputTokens.toLocaleString()}`,
|
|
1758
|
+
`Total: ${e.checkpoint.usage.totalTokens.toLocaleString()}`,
|
|
1759
|
+
`Cache-read: ${e.checkpoint.usage.cachedInputTokens.toLocaleString()}`
|
|
1760
|
+
].join(", ");
|
|
1761
|
+
log(`${header(e)} Tokens usage by step: ${usageByStep}`);
|
|
1762
|
+
log(`${header(e)} Tokens usage by run: ${usageByRun}`);
|
|
1763
|
+
}
|
|
1764
|
+
var RunEventEmitter = class {
|
|
1765
|
+
listeners = [];
|
|
1766
|
+
subscribe(listener) {
|
|
1767
|
+
this.listeners.push(listener);
|
|
1768
|
+
}
|
|
1769
|
+
async emit(event) {
|
|
1770
|
+
for (const listener of this.listeners) {
|
|
1771
|
+
await listener({
|
|
1772
|
+
...event,
|
|
1773
|
+
id: createId(),
|
|
1774
|
+
timestamp: Date.now()
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
async function resolveExpertToRun(expertKey, experts, clientOptions) {
|
|
1780
|
+
console.log(experts);
|
|
1781
|
+
if (experts[expertKey]) {
|
|
1782
|
+
return experts[expertKey];
|
|
1783
|
+
}
|
|
1784
|
+
const client = new ApiV1Client({
|
|
1785
|
+
baseUrl: clientOptions.perstackApiBaseUrl,
|
|
1786
|
+
apiKey: clientOptions.perstackApiKey
|
|
1787
|
+
});
|
|
1788
|
+
const { expert } = await client.registry.experts.get({ expertKey });
|
|
1789
|
+
experts[expertKey] = toRuntimeExpert(expert);
|
|
1790
|
+
return experts[expertKey];
|
|
1791
|
+
}
|
|
1792
|
+
function toRuntimeExpert(expert) {
|
|
1793
|
+
const skills = Object.fromEntries(
|
|
1794
|
+
Object.entries(expert.skills).map(([name, skill]) => {
|
|
1795
|
+
switch (skill.type) {
|
|
1796
|
+
case "mcpStdioSkill":
|
|
1797
|
+
return [
|
|
1798
|
+
name,
|
|
1799
|
+
{
|
|
1800
|
+
...skill,
|
|
1801
|
+
name
|
|
1802
|
+
}
|
|
1803
|
+
];
|
|
1804
|
+
case "mcpSseSkill":
|
|
1805
|
+
return [
|
|
1806
|
+
name,
|
|
1807
|
+
{
|
|
1808
|
+
...skill,
|
|
1809
|
+
name
|
|
1810
|
+
}
|
|
1811
|
+
];
|
|
1812
|
+
case "interactiveSkill":
|
|
1813
|
+
return [
|
|
1814
|
+
name,
|
|
1815
|
+
{
|
|
1816
|
+
...skill,
|
|
1817
|
+
name
|
|
1818
|
+
}
|
|
1819
|
+
];
|
|
1820
|
+
}
|
|
2368
1821
|
})
|
|
2369
|
-
)
|
|
2370
|
-
|
|
1822
|
+
);
|
|
1823
|
+
return {
|
|
1824
|
+
...expert,
|
|
1825
|
+
skills
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
2371
1828
|
|
|
2372
1829
|
// src/runtime.ts
|
|
2373
1830
|
async function run(runInput, options) {
|
|
2374
|
-
const runParams =
|
|
1831
|
+
const runParams = runParamsSchema.parse(runInput);
|
|
2375
1832
|
const eventListener = options?.eventListener ?? defaultEventListener;
|
|
2376
1833
|
const retrieveCheckpoint = options?.retrieveCheckpoint ?? defaultRetrieveCheckpoint;
|
|
2377
1834
|
const storeCheckpoint = options?.storeCheckpoint ?? defaultStoreCheckpoint;
|
|
2378
1835
|
const eventEmitter = new RunEventEmitter();
|
|
2379
1836
|
eventEmitter.subscribe(eventListener);
|
|
2380
1837
|
let { setting, checkpoint } = runParams;
|
|
2381
|
-
const
|
|
1838
|
+
const contextWindow = getContextWindow(setting.providerConfig.name, setting.model);
|
|
2382
1839
|
if (setting.workspace) {
|
|
2383
1840
|
if (!path.isAbsolute(setting.workspace)) {
|
|
2384
1841
|
throw new Error(`Workspace path must be absolute: ${setting.workspace}`);
|
|
@@ -2389,7 +1846,7 @@ async function run(runInput, options) {
|
|
|
2389
1846
|
while (true) {
|
|
2390
1847
|
const { expertToRun, experts } = await setupExperts(setting);
|
|
2391
1848
|
printRunSetting(expertToRun.name, experts, setting);
|
|
2392
|
-
const skillManagers = await getSkillManagers(expertToRun, experts);
|
|
1849
|
+
const skillManagers = await getSkillManagers(expertToRun, experts, setting);
|
|
2393
1850
|
const runActor = createActor(runtimeStateMachine, {
|
|
2394
1851
|
input: {
|
|
2395
1852
|
setting: {
|
|
@@ -2398,10 +1855,10 @@ async function run(runInput, options) {
|
|
|
2398
1855
|
},
|
|
2399
1856
|
initialCheckpoint: checkpoint ? {
|
|
2400
1857
|
...checkpoint,
|
|
2401
|
-
id:
|
|
1858
|
+
id: createId(),
|
|
2402
1859
|
stepNumber: checkpoint.stepNumber + 1
|
|
2403
1860
|
} : {
|
|
2404
|
-
id:
|
|
1861
|
+
id: createId(),
|
|
2405
1862
|
runId: setting.runId,
|
|
2406
1863
|
expert: {
|
|
2407
1864
|
key: setting.expertKey,
|
|
@@ -2412,8 +1869,8 @@ async function run(runInput, options) {
|
|
|
2412
1869
|
status: "init",
|
|
2413
1870
|
messages: [],
|
|
2414
1871
|
usage: createEmptyUsage(),
|
|
2415
|
-
contextWindow
|
|
2416
|
-
contextWindowUsage: 0
|
|
1872
|
+
contextWindow,
|
|
1873
|
+
contextWindowUsage: contextWindow ? 0 : void 0
|
|
2417
1874
|
},
|
|
2418
1875
|
eventListener,
|
|
2419
1876
|
skillManagers
|
|
@@ -2542,9 +1999,13 @@ async function run(runInput, options) {
|
|
|
2542
1999
|
async function setupExperts(setting) {
|
|
2543
2000
|
const { expertKey } = setting;
|
|
2544
2001
|
const experts = { ...setting.experts };
|
|
2545
|
-
const
|
|
2002
|
+
const clientOptions = {
|
|
2003
|
+
perstackApiBaseUrl: setting.perstackApiBaseUrl,
|
|
2004
|
+
perstackApiKey: setting.perstackApiKey
|
|
2005
|
+
};
|
|
2006
|
+
const expertToRun = await resolveExpertToRun(expertKey, experts, clientOptions);
|
|
2546
2007
|
for (const delegateName of expertToRun.delegates) {
|
|
2547
|
-
const delegate = await resolveExpertToRun(delegateName, experts);
|
|
2008
|
+
const delegate = await resolveExpertToRun(delegateName, experts, clientOptions);
|
|
2548
2009
|
if (!delegate) {
|
|
2549
2010
|
throw new Error(`Delegate ${delegateName} not found`);
|
|
2550
2011
|
}
|
|
@@ -2573,12 +2034,12 @@ async function storeRunSetting(setting) {
|
|
|
2573
2034
|
const runDir = getRunDir(setting.runId);
|
|
2574
2035
|
if (existsSync(runDir)) {
|
|
2575
2036
|
const runSettingPath = path.resolve(runDir, "run-setting.json");
|
|
2576
|
-
const runSetting = JSON.parse(await
|
|
2037
|
+
const runSetting = JSON.parse(await readFile(runSettingPath, "utf-8"));
|
|
2577
2038
|
runSetting.updatedAt = Date.now();
|
|
2578
|
-
await
|
|
2039
|
+
await writeFile(runSettingPath, JSON.stringify(runSetting, null, 2), "utf-8");
|
|
2579
2040
|
} else {
|
|
2580
|
-
await
|
|
2581
|
-
await
|
|
2041
|
+
await mkdir(runDir, { recursive: true });
|
|
2042
|
+
await writeFile(
|
|
2582
2043
|
path.resolve(runDir, "run-setting.json"),
|
|
2583
2044
|
JSON.stringify(setting, null, 2),
|
|
2584
2045
|
"utf-8"
|
|
@@ -2588,123 +2049,7 @@ async function storeRunSetting(setting) {
|
|
|
2588
2049
|
function getRunDir(runId) {
|
|
2589
2050
|
return `${process.cwd()}/perstack/runs/${runId}`;
|
|
2590
2051
|
}
|
|
2591
|
-
async function parseConfig(config) {
|
|
2592
|
-
const toml = TOML.parse(config ?? "");
|
|
2593
|
-
return PerstackConfigSchema.parse(toml);
|
|
2594
|
-
}
|
|
2595
2052
|
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
var RunInputSchema = z5.object({
|
|
2599
|
-
expertKey: z5.string(),
|
|
2600
|
-
query: z5.string(),
|
|
2601
|
-
options: z5.object({
|
|
2602
|
-
config: z5.string().optional(),
|
|
2603
|
-
model: z5.string().optional(),
|
|
2604
|
-
temperature: z5.string().optional().transform((value) => {
|
|
2605
|
-
if (value === void 0) {
|
|
2606
|
-
return void 0;
|
|
2607
|
-
}
|
|
2608
|
-
const parsedValue = Number.parseFloat(value);
|
|
2609
|
-
if (Number.isNaN(parsedValue)) {
|
|
2610
|
-
return void 0;
|
|
2611
|
-
}
|
|
2612
|
-
return parsedValue;
|
|
2613
|
-
}),
|
|
2614
|
-
maxSteps: z5.string().optional().transform((value) => {
|
|
2615
|
-
if (value === void 0) {
|
|
2616
|
-
return void 0;
|
|
2617
|
-
}
|
|
2618
|
-
const parsedValue = Number.parseInt(value);
|
|
2619
|
-
if (Number.isNaN(parsedValue)) {
|
|
2620
|
-
return void 0;
|
|
2621
|
-
}
|
|
2622
|
-
return parsedValue;
|
|
2623
|
-
}),
|
|
2624
|
-
maxRetries: z5.string().optional().transform((value) => {
|
|
2625
|
-
if (value === void 0) {
|
|
2626
|
-
return void 0;
|
|
2627
|
-
}
|
|
2628
|
-
const parsedValue = Number.parseInt(value);
|
|
2629
|
-
if (Number.isNaN(parsedValue)) {
|
|
2630
|
-
return void 0;
|
|
2631
|
-
}
|
|
2632
|
-
return parsedValue;
|
|
2633
|
-
}),
|
|
2634
|
-
timeout: z5.string().optional().transform((value) => {
|
|
2635
|
-
if (value === void 0) {
|
|
2636
|
-
return void 0;
|
|
2637
|
-
}
|
|
2638
|
-
const parsedValue = Number.parseInt(value);
|
|
2639
|
-
if (Number.isNaN(parsedValue)) {
|
|
2640
|
-
return void 0;
|
|
2641
|
-
}
|
|
2642
|
-
return parsedValue;
|
|
2643
|
-
}),
|
|
2644
|
-
runId: z5.string().optional()
|
|
2645
|
-
})
|
|
2646
|
-
});
|
|
2647
|
-
export {
|
|
2648
|
-
CheckpointSchema,
|
|
2649
|
-
CheckpointStatusSchema,
|
|
2650
|
-
ExpertMessageSchema,
|
|
2651
|
-
ExpertSchema,
|
|
2652
|
-
FileBinaryPartSchema,
|
|
2653
|
-
FileInlinePartSchema,
|
|
2654
|
-
FileUrlPartSchema,
|
|
2655
|
-
ImageBinaryPartSchema,
|
|
2656
|
-
ImageInlinePartSchema,
|
|
2657
|
-
ImageUrlPartSchema,
|
|
2658
|
-
InstructionMessageSchema,
|
|
2659
|
-
InteractiveSkillSchema,
|
|
2660
|
-
InteractiveToolSchema,
|
|
2661
|
-
McpSseSkillSchema,
|
|
2662
|
-
McpStdioSkillSchema,
|
|
2663
|
-
MessageSchema,
|
|
2664
|
-
PerstackConfigSchema,
|
|
2665
|
-
RegistryV1ExpertsGetResponseSchema,
|
|
2666
|
-
RunInputSchema,
|
|
2667
|
-
RunParamsSchema,
|
|
2668
|
-
StateMachineLogics,
|
|
2669
|
-
TextPartSchema,
|
|
2670
|
-
ToolCallPartSchema,
|
|
2671
|
-
ToolMessageSchema,
|
|
2672
|
-
ToolResultPartSchema,
|
|
2673
|
-
UsageSchema,
|
|
2674
|
-
UserMessageSchema,
|
|
2675
|
-
attemptCompletion,
|
|
2676
|
-
callDelegate,
|
|
2677
|
-
callInteractiveTool,
|
|
2678
|
-
callTool,
|
|
2679
|
-
completeRun,
|
|
2680
|
-
continueToNextStep,
|
|
2681
|
-
createEvent,
|
|
2682
|
-
defaultEventListener,
|
|
2683
|
-
defaultMaxRetries,
|
|
2684
|
-
defaultMaxSteps,
|
|
2685
|
-
defaultTemperature,
|
|
2686
|
-
defaultTimeout,
|
|
2687
|
-
expertKeyRegex,
|
|
2688
|
-
expertNameRegex,
|
|
2689
|
-
finishToolCall,
|
|
2690
|
-
getRunDir,
|
|
2691
|
-
maxNameLength,
|
|
2692
|
-
parseConfig,
|
|
2693
|
-
parseExpertKey,
|
|
2694
|
-
resolveImageFile,
|
|
2695
|
-
resolvePdfFile,
|
|
2696
|
-
resolveThought,
|
|
2697
|
-
resolveToolResult,
|
|
2698
|
-
retry,
|
|
2699
|
-
run,
|
|
2700
|
-
runtimeStateMachine,
|
|
2701
|
-
skillNameRegex,
|
|
2702
|
-
startGeneration,
|
|
2703
|
-
startRun,
|
|
2704
|
-
stopRunByDelegate,
|
|
2705
|
-
stopRunByExceededMaxSteps,
|
|
2706
|
-
stopRunByInteractiveTool,
|
|
2707
|
-
tagNameRegex,
|
|
2708
|
-
versionRegex
|
|
2709
|
-
};
|
|
2053
|
+
export { StateMachineLogics, calculateContextWindowUsage, defaultEventListener, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };
|
|
2054
|
+
//# sourceMappingURL=index.js.map
|
|
2710
2055
|
//# sourceMappingURL=index.js.map
|