@perstack/runtime 0.0.19 → 0.0.21
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 +740 -3998
- package/dist/index.js +292 -172
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -33,30 +33,29 @@ var AnthropicModels = [
|
|
|
33
33
|
// "claude-3-haiku-20240307", - No pdf support
|
|
34
34
|
];
|
|
35
35
|
var GoogleModels = [
|
|
36
|
-
"gemini-2.5-pro-preview-05-06",
|
|
37
|
-
"gemini-2.5-pro-exp-03-25",
|
|
38
|
-
"gemini-2.5-flash-preview-04-17",
|
|
39
|
-
"gemini-2.0-pro-exp-02-05",
|
|
40
|
-
"gemini-2.0-flash-thinking-exp-01-21",
|
|
41
|
-
"gemini-2.0-flash",
|
|
42
|
-
"gemini-2.0-flash-001",
|
|
43
|
-
"gemini-2.0-flash-live-001",
|
|
44
|
-
"gemini-2.0-flash-lite",
|
|
45
|
-
"gemini-2.0-flash-exp",
|
|
46
|
-
"gemini-1.5-pro",
|
|
47
|
-
"gemini-1.5-pro-latest",
|
|
48
|
-
"gemini-1.5-pro-001",
|
|
49
|
-
"gemini-1.5-pro-002",
|
|
50
36
|
"gemini-1.5-flash",
|
|
51
37
|
"gemini-1.5-flash-latest",
|
|
52
38
|
"gemini-1.5-flash-001",
|
|
53
39
|
"gemini-1.5-flash-002",
|
|
54
40
|
"gemini-1.5-flash-8b",
|
|
55
41
|
"gemini-1.5-flash-8b-latest",
|
|
56
|
-
"gemini-1.5-flash-8b-001"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
42
|
+
"gemini-1.5-flash-8b-001",
|
|
43
|
+
"gemini-1.5-pro",
|
|
44
|
+
"gemini-1.5-pro-latest",
|
|
45
|
+
"gemini-1.5-pro-001",
|
|
46
|
+
"gemini-1.5-pro-002",
|
|
47
|
+
"gemini-2.0-flash",
|
|
48
|
+
"gemini-2.0-flash-001",
|
|
49
|
+
"gemini-2.0-flash-live-001",
|
|
50
|
+
"gemini-2.0-flash-lite",
|
|
51
|
+
"gemini-2.0-pro-exp-02-05",
|
|
52
|
+
"gemini-2.0-flash-thinking-exp-01-21",
|
|
53
|
+
"gemini-2.0-flash-exp",
|
|
54
|
+
"gemini-2.5-pro",
|
|
55
|
+
"gemini-2.5-flash",
|
|
56
|
+
"gemini-2.5-flash-lite",
|
|
57
|
+
"gemini-2.5-pro-exp-03-25",
|
|
58
|
+
"gemini-2.5-flash-preview-04-17"
|
|
60
59
|
];
|
|
61
60
|
var OpenAIModels = [
|
|
62
61
|
"o4-mini",
|
|
@@ -301,7 +300,10 @@ var ExpertSchema = z2.object({
|
|
|
301
300
|
type: "mcpStdioSkill",
|
|
302
301
|
description: "Base skill",
|
|
303
302
|
command: "npx",
|
|
304
|
-
args: ["-y", "@perstack/base"]
|
|
303
|
+
args: ["-y", "@perstack/base"],
|
|
304
|
+
pick: [],
|
|
305
|
+
omit: [],
|
|
306
|
+
requiredEnv: []
|
|
305
307
|
}
|
|
306
308
|
}).transform((skills) => {
|
|
307
309
|
return Object.fromEntries(
|
|
@@ -393,7 +395,8 @@ var RunParamsSchema = z2.object({
|
|
|
393
395
|
model: z2.string().optional().default(getDefaultModelName()),
|
|
394
396
|
temperature: z2.number().min(0).max(1).optional().default(0.3),
|
|
395
397
|
maxSteps: z2.number().min(1).optional(),
|
|
396
|
-
maxRetries: z2.number().min(0).optional().default(
|
|
398
|
+
maxRetries: z2.number().min(0).optional().default(5),
|
|
399
|
+
timeout: z2.number().min(0).optional().default(1e3 * 60),
|
|
397
400
|
workspace: z2.string().optional(),
|
|
398
401
|
startedAt: z2.number().optional().default(Date.now()),
|
|
399
402
|
updatedAt: z2.number().optional().default(Date.now())
|
|
@@ -463,7 +466,7 @@ async function defaultStoreEvent(event) {
|
|
|
463
466
|
// package.json
|
|
464
467
|
var package_default = {
|
|
465
468
|
name: "@perstack/runtime",
|
|
466
|
-
version: "0.0.
|
|
469
|
+
version: "0.0.21",
|
|
467
470
|
description: "PerStack Runtime",
|
|
468
471
|
author: "Wintermute Technologies, Inc.",
|
|
469
472
|
license: "Apache-2.0",
|
|
@@ -487,23 +490,23 @@ var package_default = {
|
|
|
487
490
|
prepublishOnly: "npm run clean && npm run build"
|
|
488
491
|
},
|
|
489
492
|
dependencies: {
|
|
490
|
-
"@ai-sdk/anthropic": "^
|
|
491
|
-
"@ai-sdk/google": "^
|
|
492
|
-
"@ai-sdk/openai": "^
|
|
493
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
493
|
+
"@ai-sdk/anthropic": "^2.0.1",
|
|
494
|
+
"@ai-sdk/google": "^2.0.2",
|
|
495
|
+
"@ai-sdk/openai": "^2.0.3",
|
|
496
|
+
"@modelcontextprotocol/sdk": "^1.17.1",
|
|
494
497
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
495
|
-
ai: "^
|
|
496
|
-
"smol-toml": "^1.
|
|
498
|
+
ai: "^5.0.4",
|
|
499
|
+
"smol-toml": "^1.4.1",
|
|
497
500
|
"ts-dedent": "^2.2.0",
|
|
498
|
-
xstate: "^5.
|
|
499
|
-
zod: "^
|
|
501
|
+
xstate: "^5.20.1",
|
|
502
|
+
zod: "^4.0.14"
|
|
500
503
|
},
|
|
501
504
|
devDependencies: {
|
|
502
505
|
"@tsconfig/node22": "^22.0.2",
|
|
503
|
-
"@types/node": "^24.0
|
|
506
|
+
"@types/node": "^24.2.0",
|
|
504
507
|
tsup: "^8.5.0",
|
|
505
|
-
typescript: "^5.
|
|
506
|
-
vitest: "^3.2.
|
|
508
|
+
typescript: "^5.9.2",
|
|
509
|
+
vitest: "^3.2.4"
|
|
507
510
|
},
|
|
508
511
|
engines: {
|
|
509
512
|
node: ">=22.0.0"
|
|
@@ -523,7 +526,7 @@ async function defaultEventListener(e) {
|
|
|
523
526
|
await defaultStoreEvent(e);
|
|
524
527
|
switch (e.type) {
|
|
525
528
|
case "startRun": {
|
|
526
|
-
log(`${header(e)}
|
|
529
|
+
log(`${header(e)} Perstack@${package_default.version} started`);
|
|
527
530
|
const { inputMessages } = e;
|
|
528
531
|
for (const message of inputMessages) {
|
|
529
532
|
if (message.type === "userMessage") {
|
|
@@ -535,122 +538,122 @@ async function defaultEventListener(e) {
|
|
|
535
538
|
break;
|
|
536
539
|
}
|
|
537
540
|
case "startGeneration": {
|
|
538
|
-
log(`${header(e)}
|
|
541
|
+
log(`${header(e)} Generating tool call`);
|
|
539
542
|
break;
|
|
540
543
|
}
|
|
541
544
|
case "retry": {
|
|
542
545
|
logUsage(e);
|
|
543
|
-
log(`${header(e)}
|
|
546
|
+
log(`${header(e)} Retrying tool call generation`);
|
|
544
547
|
break;
|
|
545
548
|
}
|
|
546
549
|
case "callTool": {
|
|
547
550
|
logUsage(e);
|
|
548
|
-
log(`${header(e)}
|
|
551
|
+
log(`${header(e)} Calling tool`);
|
|
549
552
|
if (e.toolCall.skillName === "@perstack/base") {
|
|
550
553
|
switch (e.toolCall.toolName) {
|
|
551
554
|
case "think": {
|
|
552
555
|
const thought = e.toolCall.args.thought;
|
|
553
|
-
log(`${header(e)}
|
|
556
|
+
log(`${header(e)} Thought Updated:`);
|
|
554
557
|
debug(thought);
|
|
555
558
|
break;
|
|
556
559
|
}
|
|
557
560
|
case "readPdfFile": {
|
|
558
561
|
const path2 = e.toolCall.args.path;
|
|
559
|
-
log(`${header(e)}
|
|
562
|
+
log(`${header(e)} Reading PDF: ${path2}`);
|
|
560
563
|
break;
|
|
561
564
|
}
|
|
562
565
|
case "readImageFile": {
|
|
563
566
|
const path2 = e.toolCall.args.path;
|
|
564
|
-
log(`${header(e)}
|
|
567
|
+
log(`${header(e)} Reading Image: ${path2}`);
|
|
565
568
|
break;
|
|
566
569
|
}
|
|
567
570
|
default: {
|
|
568
|
-
log(`${header(e)}
|
|
569
|
-
|
|
571
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
572
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
570
573
|
break;
|
|
571
574
|
}
|
|
572
575
|
}
|
|
573
576
|
} else {
|
|
574
|
-
log(`${header(e)}
|
|
575
|
-
|
|
577
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
578
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
576
579
|
}
|
|
577
580
|
break;
|
|
578
581
|
}
|
|
579
582
|
case "callInteractiveTool": {
|
|
580
583
|
logUsage(e);
|
|
581
|
-
log(`${header(e)}
|
|
582
|
-
log(`${header(e)}
|
|
583
|
-
|
|
584
|
+
log(`${header(e)} Calling interactive tool`);
|
|
585
|
+
log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
|
|
586
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
584
587
|
break;
|
|
585
588
|
}
|
|
586
589
|
case "callDelegate": {
|
|
587
590
|
logUsage(e);
|
|
588
|
-
log(`${header(e)}
|
|
589
|
-
log(`${header(e)}
|
|
590
|
-
|
|
591
|
+
log(`${header(e)} Calling delegate`);
|
|
592
|
+
log(`${header(e)} Tool: ${e.toolCall.toolName}`);
|
|
593
|
+
debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
|
|
591
594
|
break;
|
|
592
595
|
}
|
|
593
596
|
case "resolveToolResult": {
|
|
594
|
-
log(`${header(e)}
|
|
597
|
+
log(`${header(e)} Resolved Tool Result`);
|
|
595
598
|
if (e.toolResult.skillName === "@perstack/base") {
|
|
596
599
|
switch (e.toolResult.toolName) {
|
|
597
600
|
case "todo": {
|
|
598
601
|
const text = e.toolResult.result.find((r) => r.type === "textPart")?.text;
|
|
599
602
|
const { todos } = JSON.parse(text ?? "{}");
|
|
600
|
-
log(`${header(e)}
|
|
603
|
+
log(`${header(e)} Todo:`);
|
|
601
604
|
for (const todo of todos) {
|
|
602
605
|
debug(`${todo.completed ? "[x]" : "[ ]"} ${todo.id}: ${todo.title}`);
|
|
603
606
|
}
|
|
604
607
|
break;
|
|
605
608
|
}
|
|
606
609
|
default: {
|
|
607
|
-
log(`${header(e)}
|
|
608
|
-
|
|
610
|
+
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
611
|
+
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
609
612
|
break;
|
|
610
613
|
}
|
|
611
614
|
}
|
|
612
615
|
} else {
|
|
613
|
-
log(`${header(e)}
|
|
614
|
-
|
|
616
|
+
log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
|
|
617
|
+
debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
|
|
615
618
|
}
|
|
616
619
|
break;
|
|
617
620
|
}
|
|
618
621
|
case "resolveThought": {
|
|
619
|
-
log(`${header(e)}
|
|
622
|
+
log(`${header(e)} Resolved Thought:`, e.toolResult);
|
|
620
623
|
break;
|
|
621
624
|
}
|
|
622
625
|
case "resolvePdfFile": {
|
|
623
|
-
log(`${header(e)}
|
|
626
|
+
log(`${header(e)} Resolved PDF:`, e.toolResult);
|
|
624
627
|
break;
|
|
625
628
|
}
|
|
626
629
|
case "resolveImageFile": {
|
|
627
|
-
log(`${header(e)}
|
|
630
|
+
log(`${header(e)} Resolved Image:`, e.toolResult);
|
|
628
631
|
break;
|
|
629
632
|
}
|
|
630
633
|
case "attemptCompletion": {
|
|
631
|
-
log(`${header(e)}
|
|
634
|
+
log(`${header(e)} Attempting completion`);
|
|
632
635
|
break;
|
|
633
636
|
}
|
|
634
637
|
case "completeRun": {
|
|
635
638
|
logUsage(e);
|
|
636
|
-
log(`${header(e)}
|
|
637
|
-
|
|
639
|
+
log(`${header(e)} Completing run`);
|
|
640
|
+
debug(`${header(e)} Result:`, e.text);
|
|
638
641
|
break;
|
|
639
642
|
}
|
|
640
643
|
case "stopRunByInteractiveTool": {
|
|
641
|
-
log(`${header(e)}
|
|
644
|
+
log(`${header(e)} Stopping run by interactive tool`);
|
|
642
645
|
break;
|
|
643
646
|
}
|
|
644
647
|
case "stopRunByDelegate": {
|
|
645
|
-
log(`${header(e)}
|
|
648
|
+
log(`${header(e)} Stopping run by delegate`);
|
|
646
649
|
break;
|
|
647
650
|
}
|
|
648
651
|
case "stopRunByExceededMaxSteps": {
|
|
649
|
-
log(`${header(e)}
|
|
652
|
+
log(`${header(e)} Stopping run by exceeded max steps`);
|
|
650
653
|
break;
|
|
651
654
|
}
|
|
652
655
|
case "continueToNextStep": {
|
|
653
|
-
log(`${header(e)}
|
|
656
|
+
log(`${header(e)} Continuing to next step`);
|
|
654
657
|
break;
|
|
655
658
|
}
|
|
656
659
|
}
|
|
@@ -660,19 +663,19 @@ function logUserMessage(message) {
|
|
|
660
663
|
const contents = message.contents;
|
|
661
664
|
for (const content of contents) {
|
|
662
665
|
if (content.type === "textPart") {
|
|
663
|
-
log(`${t}
|
|
666
|
+
log(`${t} User: ${content.text}`);
|
|
664
667
|
} else if (content.type === "imageUrlPart") {
|
|
665
|
-
log(`${t}
|
|
668
|
+
log(`${t} User: ${content.url}`);
|
|
666
669
|
} else if (content.type === "imageInlinePart") {
|
|
667
|
-
log(`${t}
|
|
670
|
+
log(`${t} User: Inline image`);
|
|
668
671
|
} else if (content.type === "imageBinaryPart") {
|
|
669
|
-
log(`${t}
|
|
672
|
+
log(`${t} User: Binary image`);
|
|
670
673
|
} else if (content.type === "fileUrlPart") {
|
|
671
|
-
log(`${t}
|
|
674
|
+
log(`${t} User: ${content.url}`);
|
|
672
675
|
} else if (content.type === "fileInlinePart") {
|
|
673
|
-
log(`${t}
|
|
676
|
+
log(`${t} User: Inline file`);
|
|
674
677
|
} else if (content.type === "fileBinaryPart") {
|
|
675
|
-
log(`${t}
|
|
678
|
+
log(`${t} User: Binary file`);
|
|
676
679
|
}
|
|
677
680
|
}
|
|
678
681
|
}
|
|
@@ -684,9 +687,9 @@ function logToolMessage(message) {
|
|
|
684
687
|
const { contents: contents2 } = content;
|
|
685
688
|
for (const content2 of contents2) {
|
|
686
689
|
if (content2.type === "textPart") {
|
|
687
|
-
log(`${t}
|
|
690
|
+
log(`${t} Tool Result: ${content2.text}`);
|
|
688
691
|
} else if (content2.type === "imageInlinePart") {
|
|
689
|
-
log(`${t}
|
|
692
|
+
log(`${t} Tool Result: Inline image`);
|
|
690
693
|
}
|
|
691
694
|
}
|
|
692
695
|
}
|
|
@@ -700,7 +703,7 @@ function logUsage(e) {
|
|
|
700
703
|
`Cache-read: ${e.usage.cacheReadInputTokens.toLocaleString()}`,
|
|
701
704
|
`Cache-write: ${e.usage.cacheCreationInputTokens.toLocaleString()}`
|
|
702
705
|
].join(", ");
|
|
703
|
-
log(`${header(e)}
|
|
706
|
+
log(`${header(e)} Tokens usage: ${usageByGeneration}`);
|
|
704
707
|
const usageByRun = [
|
|
705
708
|
`In: ${e.usage.promptTokens.toLocaleString()}`,
|
|
706
709
|
`Out: ${e.usage.completionTokens.toLocaleString()}`,
|
|
@@ -708,7 +711,7 @@ function logUsage(e) {
|
|
|
708
711
|
`Cache-read: ${e.usage.cacheReadInputTokens.toLocaleString()}`,
|
|
709
712
|
`Cache-write: ${e.usage.cacheCreationInputTokens.toLocaleString()}`
|
|
710
713
|
].join(", ");
|
|
711
|
-
log(`${header(e)}
|
|
714
|
+
log(`${header(e)} Total usage: ${usageByRun}`);
|
|
712
715
|
}
|
|
713
716
|
|
|
714
717
|
// src/events/event-emitter.ts
|
|
@@ -749,8 +752,8 @@ var RegistryV1ExpertSchema = z3.object({
|
|
|
749
752
|
tags: z3.array(z3.string()),
|
|
750
753
|
status: z3.string(),
|
|
751
754
|
owner: z3.object({ name: z3.string() }),
|
|
752
|
-
createdAt: z3.
|
|
753
|
-
updatedAt: z3.
|
|
755
|
+
createdAt: z3.iso.datetime(),
|
|
756
|
+
updatedAt: z3.iso.datetime()
|
|
754
757
|
});
|
|
755
758
|
var RegistryV1ExpertsGetResponseSchema = z3.object({
|
|
756
759
|
data: z3.object({
|
|
@@ -818,7 +821,7 @@ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
|
818
821
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
819
822
|
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
820
823
|
import { createId as createId3 } from "@paralleldrive/cuid2";
|
|
821
|
-
import { jsonSchema } from "ai";
|
|
824
|
+
import { jsonSchema, tool } from "ai";
|
|
822
825
|
import { ZodError } from "zod";
|
|
823
826
|
var SkillManager = class {
|
|
824
827
|
_toolDefinitions = [];
|
|
@@ -895,11 +898,11 @@ var SkillManager = class {
|
|
|
895
898
|
}
|
|
896
899
|
}
|
|
897
900
|
const { tools } = await this._mcpClient.listTools();
|
|
898
|
-
this._toolDefinitions = tools.map((
|
|
901
|
+
this._toolDefinitions = tools.map((tool2) => ({
|
|
899
902
|
skillName: params.skill.name,
|
|
900
|
-
name:
|
|
901
|
-
description:
|
|
902
|
-
inputSchema:
|
|
903
|
+
name: tool2.name,
|
|
904
|
+
description: tool2.description,
|
|
905
|
+
inputSchema: tool2.inputSchema,
|
|
903
906
|
interactive: false
|
|
904
907
|
}));
|
|
905
908
|
this._initialized = true;
|
|
@@ -921,11 +924,11 @@ var SkillManager = class {
|
|
|
921
924
|
return { command, args: newArgs };
|
|
922
925
|
}
|
|
923
926
|
async _initInteractiveSkill(params) {
|
|
924
|
-
this._toolDefinitions = Object.values(params.interactiveSkill.tools).map((
|
|
927
|
+
this._toolDefinitions = Object.values(params.interactiveSkill.tools).map((tool2) => ({
|
|
925
928
|
skillName: params.interactiveSkill.name,
|
|
926
|
-
name:
|
|
927
|
-
description:
|
|
928
|
-
inputSchema: JSON.parse(
|
|
929
|
+
name: tool2.name,
|
|
930
|
+
description: tool2.description,
|
|
931
|
+
inputSchema: JSON.parse(tool2.inputJsonSchema),
|
|
929
932
|
interactive: true
|
|
930
933
|
}));
|
|
931
934
|
this._initialized = true;
|
|
@@ -958,7 +961,7 @@ var SkillManager = class {
|
|
|
958
961
|
if (this._params.type === "mcp") {
|
|
959
962
|
const omit = this._params.skill.omit ?? [];
|
|
960
963
|
const pick = this._params.skill.pick ?? [];
|
|
961
|
-
return this._toolDefinitions.filter((
|
|
964
|
+
return this._toolDefinitions.filter((tool2) => omit.length > 0 ? !omit.includes(tool2.name) : true).filter((tool2) => pick.length > 0 ? pick.includes(tool2.name) : true);
|
|
962
965
|
}
|
|
963
966
|
return this._toolDefinitions;
|
|
964
967
|
}
|
|
@@ -1133,10 +1136,10 @@ async function getToolSet(skillManagers) {
|
|
|
1133
1136
|
for (const skillManager of Object.values(skillManagers)) {
|
|
1134
1137
|
const toolDefinitions = await skillManager.getToolDefinitions();
|
|
1135
1138
|
for (const toolDefinition of toolDefinitions) {
|
|
1136
|
-
tools[toolDefinition.name] = {
|
|
1139
|
+
tools[toolDefinition.name] = tool({
|
|
1137
1140
|
description: toolDefinition.description,
|
|
1138
|
-
|
|
1139
|
-
};
|
|
1141
|
+
inputSchema: jsonSchema(toolDefinition.inputSchema)
|
|
1142
|
+
});
|
|
1140
1143
|
}
|
|
1141
1144
|
}
|
|
1142
1145
|
return tools;
|
|
@@ -1401,42 +1404,42 @@ function imageUrlPartToCoreImagePart(part) {
|
|
|
1401
1404
|
return {
|
|
1402
1405
|
type: "image",
|
|
1403
1406
|
image: part.url,
|
|
1404
|
-
|
|
1407
|
+
mediaType: part.mimeType
|
|
1405
1408
|
};
|
|
1406
1409
|
}
|
|
1407
1410
|
function imageInlinePartToCoreImagePart(part) {
|
|
1408
1411
|
return {
|
|
1409
1412
|
type: "image",
|
|
1410
1413
|
image: part.encodedData,
|
|
1411
|
-
|
|
1414
|
+
mediaType: part.mimeType
|
|
1412
1415
|
};
|
|
1413
1416
|
}
|
|
1414
1417
|
function imageBinaryPartToCoreImagePart(part) {
|
|
1415
1418
|
return {
|
|
1416
1419
|
type: "image",
|
|
1417
1420
|
image: part.data,
|
|
1418
|
-
|
|
1421
|
+
mediaType: part.mimeType
|
|
1419
1422
|
};
|
|
1420
1423
|
}
|
|
1421
1424
|
function fileUrlPartToCoreFilePart(part) {
|
|
1422
1425
|
return {
|
|
1423
1426
|
type: "file",
|
|
1424
1427
|
data: part.url,
|
|
1425
|
-
|
|
1428
|
+
mediaType: part.mimeType
|
|
1426
1429
|
};
|
|
1427
1430
|
}
|
|
1428
1431
|
function fileInlinePartToCoreFilePart(part) {
|
|
1429
1432
|
return {
|
|
1430
1433
|
type: "file",
|
|
1431
1434
|
data: part.encodedData,
|
|
1432
|
-
|
|
1435
|
+
mediaType: part.mimeType
|
|
1433
1436
|
};
|
|
1434
1437
|
}
|
|
1435
1438
|
function fileBinaryPartToCoreFilePart(part) {
|
|
1436
1439
|
return {
|
|
1437
1440
|
type: "file",
|
|
1438
1441
|
data: part.data,
|
|
1439
|
-
|
|
1442
|
+
mediaType: part.mimeType
|
|
1440
1443
|
};
|
|
1441
1444
|
}
|
|
1442
1445
|
function toolCallPartToCoreToolCallPart(part) {
|
|
@@ -1444,31 +1447,29 @@ function toolCallPartToCoreToolCallPart(part) {
|
|
|
1444
1447
|
type: "tool-call",
|
|
1445
1448
|
toolCallId: part.toolCallId,
|
|
1446
1449
|
toolName: part.toolName,
|
|
1447
|
-
|
|
1450
|
+
input: part.args
|
|
1448
1451
|
};
|
|
1449
1452
|
}
|
|
1450
1453
|
function toolResultPartToCoreToolResultPart(part) {
|
|
1454
|
+
const content = part.contents[0];
|
|
1455
|
+
const output = content.type === "textPart" ? {
|
|
1456
|
+
type: "text",
|
|
1457
|
+
value: content.text
|
|
1458
|
+
} : {
|
|
1459
|
+
type: "content",
|
|
1460
|
+
value: [
|
|
1461
|
+
{
|
|
1462
|
+
type: "media",
|
|
1463
|
+
data: content.encodedData,
|
|
1464
|
+
mediaType: content.mimeType
|
|
1465
|
+
}
|
|
1466
|
+
]
|
|
1467
|
+
};
|
|
1451
1468
|
return {
|
|
1452
1469
|
type: "tool-result",
|
|
1453
1470
|
toolCallId: part.toolCallId,
|
|
1454
1471
|
toolName: part.toolName,
|
|
1455
|
-
|
|
1456
|
-
experimental_content: part.contents.map((part2) => {
|
|
1457
|
-
switch (part2.type) {
|
|
1458
|
-
case "textPart":
|
|
1459
|
-
return {
|
|
1460
|
-
type: "text",
|
|
1461
|
-
text: part2.text
|
|
1462
|
-
};
|
|
1463
|
-
case "imageInlinePart":
|
|
1464
|
-
return {
|
|
1465
|
-
type: "image",
|
|
1466
|
-
data: part2.encodedData,
|
|
1467
|
-
mimeType: part2.mimeType
|
|
1468
|
-
};
|
|
1469
|
-
}
|
|
1470
|
-
}),
|
|
1471
|
-
isError: part.isError
|
|
1472
|
+
output
|
|
1472
1473
|
};
|
|
1473
1474
|
}
|
|
1474
1475
|
|
|
@@ -1491,9 +1492,9 @@ function usageFromGenerateTextResult(result) {
|
|
|
1491
1492
|
cacheReadInputTokens = anthropicMetadata.cacheReadInputTokens || 0;
|
|
1492
1493
|
}
|
|
1493
1494
|
return {
|
|
1494
|
-
promptTokens: result.usage.
|
|
1495
|
-
completionTokens: result.usage.
|
|
1496
|
-
totalTokens: result.usage.totalTokens,
|
|
1495
|
+
promptTokens: result.usage.inputTokens || 0,
|
|
1496
|
+
completionTokens: result.usage.outputTokens || 0,
|
|
1497
|
+
totalTokens: result.usage.totalTokens || 0,
|
|
1497
1498
|
cacheCreationInputTokens,
|
|
1498
1499
|
cacheReadInputTokens
|
|
1499
1500
|
};
|
|
@@ -1531,12 +1532,32 @@ async function generatingRunResultLogic({
|
|
|
1531
1532
|
]);
|
|
1532
1533
|
const model = getModel(setting.model);
|
|
1533
1534
|
const { messages } = checkpoint;
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1535
|
+
let generationResult;
|
|
1536
|
+
try {
|
|
1537
|
+
generationResult = await generateText({
|
|
1538
|
+
model,
|
|
1539
|
+
messages: [...messages, toolMessage].map(messageToCoreMessage),
|
|
1540
|
+
temperature: setting.temperature,
|
|
1541
|
+
maxRetries: setting.maxRetries,
|
|
1542
|
+
abortSignal: AbortSignal.timeout(setting.timeout)
|
|
1543
|
+
});
|
|
1544
|
+
} catch (error) {
|
|
1545
|
+
if (error instanceof Error) {
|
|
1546
|
+
return retry(setting, checkpoint, {
|
|
1547
|
+
newMessages: [
|
|
1548
|
+
toolMessage,
|
|
1549
|
+
createUserMessage([
|
|
1550
|
+
{
|
|
1551
|
+
type: "textPart",
|
|
1552
|
+
text: JSON.stringify({ error: error.name, errorMessage: error.message })
|
|
1553
|
+
}
|
|
1554
|
+
])
|
|
1555
|
+
],
|
|
1556
|
+
usage: checkpoint.usage
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1559
|
+
throw error;
|
|
1560
|
+
}
|
|
1540
1561
|
const usage = usageFromGenerateTextResult(generationResult);
|
|
1541
1562
|
const { text } = generationResult;
|
|
1542
1563
|
const newMessages = [toolMessage, createExpertMessage(text ? [{ type: "textPart", text }] : [])];
|
|
@@ -1567,14 +1588,33 @@ async function generatingToolCallLogic({
|
|
|
1567
1588
|
}) {
|
|
1568
1589
|
const { messages } = checkpoint;
|
|
1569
1590
|
const model = getModel(setting.model);
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1591
|
+
let result;
|
|
1592
|
+
try {
|
|
1593
|
+
result = await generateText2({
|
|
1594
|
+
model,
|
|
1595
|
+
messages: messages.map(messageToCoreMessage),
|
|
1596
|
+
temperature: setting.temperature,
|
|
1597
|
+
maxRetries: setting.maxRetries,
|
|
1598
|
+
tools: await getToolSet(skillManagers),
|
|
1599
|
+
toolChoice: "required",
|
|
1600
|
+
abortSignal: AbortSignal.timeout(setting.timeout)
|
|
1601
|
+
});
|
|
1602
|
+
} catch (error) {
|
|
1603
|
+
if (error instanceof Error) {
|
|
1604
|
+
return retry(setting, checkpoint, {
|
|
1605
|
+
newMessages: [
|
|
1606
|
+
createUserMessage([
|
|
1607
|
+
{
|
|
1608
|
+
type: "textPart",
|
|
1609
|
+
text: JSON.stringify({ error: error.name, errorMessage: error.message })
|
|
1610
|
+
}
|
|
1611
|
+
])
|
|
1612
|
+
],
|
|
1613
|
+
usage: checkpoint.usage
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
throw error;
|
|
1617
|
+
}
|
|
1578
1618
|
const usage = usageFromGenerateTextResult(result);
|
|
1579
1619
|
const { text, toolCalls, finishReason } = result;
|
|
1580
1620
|
const toolCall = toolCalls[0];
|
|
@@ -1602,7 +1642,7 @@ async function generatingToolCallLogic({
|
|
|
1602
1642
|
type: "toolCallPart",
|
|
1603
1643
|
toolCallId: toolCall.toolCallId,
|
|
1604
1644
|
toolName: toolCall.toolName,
|
|
1605
|
-
args: toolCall.
|
|
1645
|
+
args: toolCall.input
|
|
1606
1646
|
}
|
|
1607
1647
|
]),
|
|
1608
1648
|
createToolMessage([
|
|
@@ -1626,7 +1666,7 @@ async function generatingToolCallLogic({
|
|
|
1626
1666
|
type: "toolCallPart",
|
|
1627
1667
|
toolCallId: toolCall.toolCallId,
|
|
1628
1668
|
toolName: toolCall.toolName,
|
|
1629
|
-
args: toolCall.
|
|
1669
|
+
args: toolCall.input
|
|
1630
1670
|
}
|
|
1631
1671
|
];
|
|
1632
1672
|
if (text) {
|
|
@@ -1642,7 +1682,7 @@ async function generatingToolCallLogic({
|
|
|
1642
1682
|
id: toolCall.toolCallId,
|
|
1643
1683
|
skillName: skillManager.name,
|
|
1644
1684
|
toolName: toolCall.toolName,
|
|
1645
|
-
args: toolCall.
|
|
1685
|
+
args: toolCall.input
|
|
1646
1686
|
},
|
|
1647
1687
|
usage
|
|
1648
1688
|
};
|
|
@@ -1776,33 +1816,61 @@ async function initLogic({
|
|
|
1776
1816
|
const { expertKey, experts } = setting;
|
|
1777
1817
|
const expert = experts[expertKey];
|
|
1778
1818
|
switch (checkpoint.status) {
|
|
1779
|
-
case "init":
|
|
1819
|
+
case "init": {
|
|
1820
|
+
if (!setting.input.text) {
|
|
1821
|
+
throw new Error("Input message is undefined");
|
|
1822
|
+
}
|
|
1780
1823
|
return startRun(setting, checkpoint, {
|
|
1781
1824
|
initialCheckpoint: checkpoint,
|
|
1782
|
-
inputMessages: [
|
|
1825
|
+
inputMessages: [
|
|
1826
|
+
createInstructionMessage(expert, experts),
|
|
1827
|
+
createUserMessage([{ type: "textPart", text: setting.input.text }])
|
|
1828
|
+
]
|
|
1783
1829
|
});
|
|
1784
|
-
|
|
1830
|
+
}
|
|
1831
|
+
case "proceeding": {
|
|
1832
|
+
if (!setting.input.text) {
|
|
1833
|
+
throw new Error("Input message is undefined");
|
|
1834
|
+
}
|
|
1785
1835
|
return startRun(setting, checkpoint, {
|
|
1786
1836
|
initialCheckpoint: checkpoint,
|
|
1787
|
-
inputMessages: [
|
|
1837
|
+
inputMessages: [createUserMessage([{ type: "textPart", text: setting.input.text }])]
|
|
1788
1838
|
});
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1839
|
+
}
|
|
1840
|
+
case "stoppedByDelegate": {
|
|
1841
|
+
if (!setting.input.interactiveToolCallResult) {
|
|
1842
|
+
throw new Error("Interactive tool call result is undefined");
|
|
1843
|
+
}
|
|
1844
|
+
return startRun(setting, checkpoint, {
|
|
1845
|
+
initialCheckpoint: checkpoint,
|
|
1846
|
+
inputMessages: [
|
|
1847
|
+
createUserMessage([
|
|
1848
|
+
{ type: "textPart", text: setting.input.interactiveToolCallResult.text }
|
|
1849
|
+
])
|
|
1850
|
+
]
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1853
|
+
case "stoppedByInteractiveTool": {
|
|
1854
|
+
if (!setting.input.interactiveToolCallResult) {
|
|
1855
|
+
throw new Error("Interactive tool call result is undefined");
|
|
1802
1856
|
}
|
|
1803
|
-
|
|
1857
|
+
return startRun(setting, checkpoint, {
|
|
1858
|
+
initialCheckpoint: checkpoint,
|
|
1859
|
+
inputMessages: [
|
|
1860
|
+
createToolMessage([
|
|
1861
|
+
{
|
|
1862
|
+
type: "toolResultPart",
|
|
1863
|
+
toolCallId: setting.input.interactiveToolCallResult.toolCallId,
|
|
1864
|
+
toolName: setting.input.interactiveToolCallResult.toolName,
|
|
1865
|
+
contents: [{ type: "textPart", text: setting.input.interactiveToolCallResult.text }]
|
|
1866
|
+
}
|
|
1867
|
+
])
|
|
1868
|
+
]
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
default:
|
|
1872
|
+
throw new Error(`Unexpected checkpoint status: ${checkpoint.status}`);
|
|
1804
1873
|
}
|
|
1805
|
-
throw new Error("Input message is undefined");
|
|
1806
1874
|
}
|
|
1807
1875
|
|
|
1808
1876
|
// src/states/preparing-for-step.ts
|
|
@@ -1969,6 +2037,13 @@ var runtimeStateMachine = setup({
|
|
|
1969
2037
|
context: ({ input }) => ({
|
|
1970
2038
|
setting: input.setting,
|
|
1971
2039
|
checkpoint: input.initialCheckpoint,
|
|
2040
|
+
step: {
|
|
2041
|
+
stepNumber: input.initialCheckpoint.stepNumber,
|
|
2042
|
+
inputMessages: [],
|
|
2043
|
+
newMessages: [],
|
|
2044
|
+
usage: createEmptyUsage(),
|
|
2045
|
+
startedAt: Date.now()
|
|
2046
|
+
},
|
|
1972
2047
|
eventListener: input.eventListener,
|
|
1973
2048
|
skillManagers: input.skillManagers
|
|
1974
2049
|
}),
|
|
@@ -1982,6 +2057,13 @@ var runtimeStateMachine = setup({
|
|
|
1982
2057
|
...event.initialCheckpoint,
|
|
1983
2058
|
messages: [...event.initialCheckpoint.messages, ...event.inputMessages],
|
|
1984
2059
|
status: "proceeding"
|
|
2060
|
+
}),
|
|
2061
|
+
step: ({ event }) => ({
|
|
2062
|
+
stepNumber: event.initialCheckpoint.stepNumber,
|
|
2063
|
+
inputMessages: event.inputMessages,
|
|
2064
|
+
newMessages: [],
|
|
2065
|
+
usage: createEmptyUsage(),
|
|
2066
|
+
startedAt: event.timestamp
|
|
1985
2067
|
})
|
|
1986
2068
|
})
|
|
1987
2069
|
}
|
|
@@ -1994,6 +2076,7 @@ var runtimeStateMachine = setup({
|
|
|
1994
2076
|
actions: assign({
|
|
1995
2077
|
step: ({ context, event }) => ({
|
|
1996
2078
|
stepNumber: context.checkpoint.stepNumber,
|
|
2079
|
+
inputMessages: context.step.inputMessages,
|
|
1997
2080
|
newMessages: [],
|
|
1998
2081
|
usage: createEmptyUsage(),
|
|
1999
2082
|
startedAt: event.timestamp
|
|
@@ -2188,6 +2271,21 @@ var runtimeStateMachine = setup({
|
|
|
2188
2271
|
},
|
|
2189
2272
|
GeneratingRunResult: {
|
|
2190
2273
|
on: {
|
|
2274
|
+
retry: {
|
|
2275
|
+
target: "FinishingStep",
|
|
2276
|
+
actions: assign({
|
|
2277
|
+
checkpoint: ({ context, event }) => ({
|
|
2278
|
+
...context.checkpoint,
|
|
2279
|
+
messages: [...context.checkpoint.messages, ...event.newMessages],
|
|
2280
|
+
usage: sumUsage(context.checkpoint.usage, event.usage)
|
|
2281
|
+
}),
|
|
2282
|
+
step: ({ context, event }) => ({
|
|
2283
|
+
...context.step,
|
|
2284
|
+
newMessages: event.newMessages,
|
|
2285
|
+
usage: sumUsage(context.step.usage, event.usage)
|
|
2286
|
+
})
|
|
2287
|
+
})
|
|
2288
|
+
},
|
|
2191
2289
|
completeRun: {
|
|
2192
2290
|
target: "Stopped",
|
|
2193
2291
|
actions: assign({
|
|
@@ -2225,7 +2323,10 @@ var runtimeStateMachine = setup({
|
|
|
2225
2323
|
target: "PreparingForStep",
|
|
2226
2324
|
actions: assign({
|
|
2227
2325
|
checkpoint: ({ event }) => event.nextCheckpoint,
|
|
2228
|
-
step: ({ event }) =>
|
|
2326
|
+
step: ({ event }) => ({
|
|
2327
|
+
...event.step,
|
|
2328
|
+
inputMessages: void 0
|
|
2329
|
+
})
|
|
2229
2330
|
}),
|
|
2230
2331
|
reenter: true
|
|
2231
2332
|
},
|
|
@@ -2233,7 +2334,10 @@ var runtimeStateMachine = setup({
|
|
|
2233
2334
|
target: "Stopped",
|
|
2234
2335
|
actions: assign({
|
|
2235
2336
|
checkpoint: ({ event }) => event.checkpoint,
|
|
2236
|
-
step: ({ event }) =>
|
|
2337
|
+
step: ({ event }) => ({
|
|
2338
|
+
...event.step,
|
|
2339
|
+
inputMessages: void 0
|
|
2340
|
+
})
|
|
2237
2341
|
})
|
|
2238
2342
|
}
|
|
2239
2343
|
}
|
|
@@ -2265,6 +2369,7 @@ var PerstackConfigSchema = z4.object({
|
|
|
2265
2369
|
temperature: z4.number().optional(),
|
|
2266
2370
|
maxSteps: z4.number().optional(),
|
|
2267
2371
|
maxRetries: z4.number().optional(),
|
|
2372
|
+
timeout: z4.number().optional(),
|
|
2268
2373
|
experts: z4.record(
|
|
2269
2374
|
z4.string(),
|
|
2270
2375
|
z4.object({
|
|
@@ -2322,6 +2427,9 @@ async function run(runInput, options) {
|
|
|
2322
2427
|
const eventEmitter = new RunEventEmitter();
|
|
2323
2428
|
eventEmitter.subscribe(eventListener);
|
|
2324
2429
|
let { setting, checkpoint } = runParams;
|
|
2430
|
+
if (checkpoint) {
|
|
2431
|
+
checkpoint.status = "proceeding";
|
|
2432
|
+
}
|
|
2325
2433
|
if (setting.workspace) {
|
|
2326
2434
|
if (!path.isAbsolute(setting.workspace)) {
|
|
2327
2435
|
throw new Error(`Workspace path must be absolute: ${setting.workspace}`);
|
|
@@ -2340,17 +2448,9 @@ async function run(runInput, options) {
|
|
|
2340
2448
|
experts
|
|
2341
2449
|
},
|
|
2342
2450
|
initialCheckpoint: checkpoint ? {
|
|
2451
|
+
...checkpoint,
|
|
2343
2452
|
id: createId7(),
|
|
2344
|
-
|
|
2345
|
-
expert: {
|
|
2346
|
-
key: setting.expertKey,
|
|
2347
|
-
name: expertToRun.name,
|
|
2348
|
-
version: expertToRun.version
|
|
2349
|
-
},
|
|
2350
|
-
stepNumber: checkpoint.stepNumber + 1,
|
|
2351
|
-
status: "proceeding",
|
|
2352
|
-
messages: checkpoint.messages,
|
|
2353
|
-
usage: checkpoint.usage
|
|
2453
|
+
stepNumber: checkpoint.stepNumber + 1
|
|
2354
2454
|
} : {
|
|
2355
2455
|
id: createId7(),
|
|
2356
2456
|
runId: setting.runId,
|
|
@@ -2384,6 +2484,18 @@ async function run(runInput, options) {
|
|
|
2384
2484
|
await storeCheckpoint(event.checkpoint, event.timestamp);
|
|
2385
2485
|
}
|
|
2386
2486
|
await eventEmitter.emit(event);
|
|
2487
|
+
if (options?.shouldContinueRun) {
|
|
2488
|
+
const shouldContinue = await options.shouldContinueRun(
|
|
2489
|
+
runState.context.setting,
|
|
2490
|
+
runState.context.checkpoint,
|
|
2491
|
+
runState.context.step
|
|
2492
|
+
);
|
|
2493
|
+
if (!shouldContinue) {
|
|
2494
|
+
runActor.stop();
|
|
2495
|
+
resolve(runState.context.checkpoint);
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2387
2499
|
runActor.send(event);
|
|
2388
2500
|
}
|
|
2389
2501
|
} catch (error) {
|
|
@@ -2420,8 +2532,7 @@ async function run(runInput, options) {
|
|
|
2420
2532
|
};
|
|
2421
2533
|
checkpoint = {
|
|
2422
2534
|
...await retrieveCheckpoint(setting.runId, checkpointId),
|
|
2423
|
-
|
|
2424
|
-
stepNumber: runResultCheckpoint.stepNumber + 1,
|
|
2535
|
+
stepNumber: runResultCheckpoint.stepNumber,
|
|
2425
2536
|
usage: runResultCheckpoint.usage
|
|
2426
2537
|
};
|
|
2427
2538
|
break;
|
|
@@ -2444,10 +2555,8 @@ async function run(runInput, options) {
|
|
|
2444
2555
|
}
|
|
2445
2556
|
};
|
|
2446
2557
|
checkpoint = {
|
|
2447
|
-
|
|
2448
|
-
runId: setting.runId,
|
|
2558
|
+
...runResultCheckpoint,
|
|
2449
2559
|
status: "init",
|
|
2450
|
-
stepNumber: runResultCheckpoint.stepNumber + 1,
|
|
2451
2560
|
messages: [],
|
|
2452
2561
|
expert: {
|
|
2453
2562
|
key: expert.key,
|
|
@@ -2492,13 +2601,14 @@ async function setupExperts(setting) {
|
|
|
2492
2601
|
return { expertToRun, experts };
|
|
2493
2602
|
}
|
|
2494
2603
|
function printRunSetting(expertName, experts, setting) {
|
|
2495
|
-
console.log("
|
|
2604
|
+
console.log("Starting Perstack");
|
|
2496
2605
|
console.log(`Expert To Run: ${expertName}`);
|
|
2497
2606
|
console.log(`Experts: ${Object.keys(experts).join(", ")}`);
|
|
2498
2607
|
console.log(`Model: ${setting.model}`);
|
|
2499
2608
|
console.log(`Temperature: ${setting.temperature}`);
|
|
2500
2609
|
console.log(`Max Steps: ${setting.maxSteps}`);
|
|
2501
2610
|
console.log(`Max Retries: ${setting.maxRetries}`);
|
|
2611
|
+
console.log(`Timeout: ${setting.timeout}`);
|
|
2502
2612
|
if (setting.input.text) {
|
|
2503
2613
|
console.log(`Query: ${setting.input.text}`);
|
|
2504
2614
|
}
|
|
@@ -2570,6 +2680,16 @@ var RunInputSchema = z5.object({
|
|
|
2570
2680
|
}
|
|
2571
2681
|
return parsedValue;
|
|
2572
2682
|
}),
|
|
2683
|
+
timeout: z5.string().optional().transform((value) => {
|
|
2684
|
+
if (value === void 0) {
|
|
2685
|
+
return void 0;
|
|
2686
|
+
}
|
|
2687
|
+
const parsedValue = Number.parseInt(value);
|
|
2688
|
+
if (Number.isNaN(parsedValue)) {
|
|
2689
|
+
return void 0;
|
|
2690
|
+
}
|
|
2691
|
+
return parsedValue;
|
|
2692
|
+
}),
|
|
2573
2693
|
runId: z5.string().optional()
|
|
2574
2694
|
})
|
|
2575
2695
|
});
|