@perstack/runtime 0.0.20 → 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 +553 -3826
- package/dist/index.js +223 -151
- 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
|
};
|
|
@@ -1797,6 +1837,19 @@ async function initLogic({
|
|
|
1797
1837
|
inputMessages: [createUserMessage([{ type: "textPart", text: setting.input.text }])]
|
|
1798
1838
|
});
|
|
1799
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
|
+
}
|
|
1800
1853
|
case "stoppedByInteractiveTool": {
|
|
1801
1854
|
if (!setting.input.interactiveToolCallResult) {
|
|
1802
1855
|
throw new Error("Interactive tool call result is undefined");
|
|
@@ -2218,6 +2271,21 @@ var runtimeStateMachine = setup({
|
|
|
2218
2271
|
},
|
|
2219
2272
|
GeneratingRunResult: {
|
|
2220
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
|
+
},
|
|
2221
2289
|
completeRun: {
|
|
2222
2290
|
target: "Stopped",
|
|
2223
2291
|
actions: assign({
|
|
@@ -2301,6 +2369,7 @@ var PerstackConfigSchema = z4.object({
|
|
|
2301
2369
|
temperature: z4.number().optional(),
|
|
2302
2370
|
maxSteps: z4.number().optional(),
|
|
2303
2371
|
maxRetries: z4.number().optional(),
|
|
2372
|
+
timeout: z4.number().optional(),
|
|
2304
2373
|
experts: z4.record(
|
|
2305
2374
|
z4.string(),
|
|
2306
2375
|
z4.object({
|
|
@@ -2358,6 +2427,9 @@ async function run(runInput, options) {
|
|
|
2358
2427
|
const eventEmitter = new RunEventEmitter();
|
|
2359
2428
|
eventEmitter.subscribe(eventListener);
|
|
2360
2429
|
let { setting, checkpoint } = runParams;
|
|
2430
|
+
if (checkpoint) {
|
|
2431
|
+
checkpoint.status = "proceeding";
|
|
2432
|
+
}
|
|
2361
2433
|
if (setting.workspace) {
|
|
2362
2434
|
if (!path.isAbsolute(setting.workspace)) {
|
|
2363
2435
|
throw new Error(`Workspace path must be absolute: ${setting.workspace}`);
|
|
@@ -2376,17 +2448,9 @@ async function run(runInput, options) {
|
|
|
2376
2448
|
experts
|
|
2377
2449
|
},
|
|
2378
2450
|
initialCheckpoint: checkpoint ? {
|
|
2451
|
+
...checkpoint,
|
|
2379
2452
|
id: createId7(),
|
|
2380
|
-
|
|
2381
|
-
expert: {
|
|
2382
|
-
key: setting.expertKey,
|
|
2383
|
-
name: expertToRun.name,
|
|
2384
|
-
version: expertToRun.version
|
|
2385
|
-
},
|
|
2386
|
-
stepNumber: checkpoint.stepNumber + 1,
|
|
2387
|
-
status: "proceeding",
|
|
2388
|
-
messages: checkpoint.messages,
|
|
2389
|
-
usage: checkpoint.usage
|
|
2453
|
+
stepNumber: checkpoint.stepNumber + 1
|
|
2390
2454
|
} : {
|
|
2391
2455
|
id: createId7(),
|
|
2392
2456
|
runId: setting.runId,
|
|
@@ -2468,8 +2532,7 @@ async function run(runInput, options) {
|
|
|
2468
2532
|
};
|
|
2469
2533
|
checkpoint = {
|
|
2470
2534
|
...await retrieveCheckpoint(setting.runId, checkpointId),
|
|
2471
|
-
|
|
2472
|
-
stepNumber: runResultCheckpoint.stepNumber + 1,
|
|
2535
|
+
stepNumber: runResultCheckpoint.stepNumber,
|
|
2473
2536
|
usage: runResultCheckpoint.usage
|
|
2474
2537
|
};
|
|
2475
2538
|
break;
|
|
@@ -2492,10 +2555,8 @@ async function run(runInput, options) {
|
|
|
2492
2555
|
}
|
|
2493
2556
|
};
|
|
2494
2557
|
checkpoint = {
|
|
2495
|
-
|
|
2496
|
-
runId: setting.runId,
|
|
2558
|
+
...runResultCheckpoint,
|
|
2497
2559
|
status: "init",
|
|
2498
|
-
stepNumber: runResultCheckpoint.stepNumber + 1,
|
|
2499
2560
|
messages: [],
|
|
2500
2561
|
expert: {
|
|
2501
2562
|
key: expert.key,
|
|
@@ -2540,13 +2601,14 @@ async function setupExperts(setting) {
|
|
|
2540
2601
|
return { expertToRun, experts };
|
|
2541
2602
|
}
|
|
2542
2603
|
function printRunSetting(expertName, experts, setting) {
|
|
2543
|
-
console.log("
|
|
2604
|
+
console.log("Starting Perstack");
|
|
2544
2605
|
console.log(`Expert To Run: ${expertName}`);
|
|
2545
2606
|
console.log(`Experts: ${Object.keys(experts).join(", ")}`);
|
|
2546
2607
|
console.log(`Model: ${setting.model}`);
|
|
2547
2608
|
console.log(`Temperature: ${setting.temperature}`);
|
|
2548
2609
|
console.log(`Max Steps: ${setting.maxSteps}`);
|
|
2549
2610
|
console.log(`Max Retries: ${setting.maxRetries}`);
|
|
2611
|
+
console.log(`Timeout: ${setting.timeout}`);
|
|
2550
2612
|
if (setting.input.text) {
|
|
2551
2613
|
console.log(`Query: ${setting.input.text}`);
|
|
2552
2614
|
}
|
|
@@ -2618,6 +2680,16 @@ var RunInputSchema = z5.object({
|
|
|
2618
2680
|
}
|
|
2619
2681
|
return parsedValue;
|
|
2620
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
|
+
}),
|
|
2621
2693
|
runId: z5.string().optional()
|
|
2622
2694
|
})
|
|
2623
2695
|
});
|