psadk 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/build/main/index.d.ts +5 -0
- package/build/main/index.js +7 -1
- package/build/main/lib/PSAI.d.ts +1 -1
- package/build/main/lib/PSAgent.d.ts +11 -0
- package/build/main/lib/PSAgent.js +59 -30
- package/build/main/lib/PSAgentConfig.d.ts +1 -1
- package/build/main/lib/PSAgentLogger.d.ts +7 -0
- package/build/main/lib/PSAgentLogger.js +20 -5
- package/build/main/lib/jwt.js +3 -1
- package/build/main/lib/tools/BraveWebSearchTool.d.ts +11 -0
- package/build/main/lib/tools/BraveWebSearchTool.js +89 -0
- package/build/main/lib/tools/PSCommandLineTool.d.ts +10 -0
- package/build/main/lib/tools/PSCommandLineTool.js +74 -0
- package/build/main/lib/tools/PSMemoryTool.d.ts +45 -0
- package/build/main/lib/tools/PSMemoryTool.js +485 -0
- package/build/main/lib/tools/PSReadFileTool.d.ts +10 -0
- package/build/main/lib/tools/PSReadFileTool.js +68 -0
- package/build/main/lib/tools/PSSubAgentTool.js +141 -14
- package/build/main/lib/tools/PSWriteFileTool.d.ts +10 -0
- package/build/main/lib/tools/PSWriteFileTool.js +74 -0
- package/build/main/lib/tools/ReadFileTool.d.ts +10 -0
- package/build/main/lib/tools/ReadFileTool.js +68 -0
- package/build/main/lib/tools/TodoTool.d.ts +57 -0
- package/build/main/lib/tools/TodoTool.js +220 -0
- package/build/main/lib/tools/WebSearchTool.d.ts +9 -0
- package/build/main/lib/tools/WebSearchTool.js +92 -0
- package/build/main/lib/tools/WriteFileTool.d.ts +10 -0
- package/build/main/lib/tools/WriteFileTool.js +74 -0
- package/build/main/lib/utils/debuglogger.d.ts +7 -0
- package/build/main/lib/utils/debuglogger.js +25 -0
- package/build/main/lib/utils/helpers.d.ts +4 -0
- package/build/main/lib/utils/helpers.js +41 -0
- package/build/module/index.d.ts +5 -0
- package/build/module/index.js +29 -7
- package/build/module/lib/PSAI.d.ts +4 -0
- package/build/module/lib/PSAI.js +101 -24
- package/build/module/lib/PSAgent.d.ts +21 -10
- package/build/module/lib/PSAgent.js +126 -85
- package/build/module/lib/PSAgentConfig.d.ts +23 -0
- package/build/module/lib/PSAgentConfig.js +3 -0
- package/build/module/lib/PSAgentLogger.d.ts +20 -0
- package/build/module/lib/PSAgentLogger.js +51 -0
- package/build/module/lib/PSAgentTask.d.ts +12 -0
- package/build/module/lib/PSAgentTask.js +33 -0
- package/build/module/lib/PSAgentTool.d.ts +56 -0
- package/build/module/lib/PSAgentTool.js +91 -0
- package/build/module/lib/jwt.d.ts +41 -0
- package/build/module/lib/jwt.js +75 -0
- package/build/module/lib/tools/BraveWebSearchTool.d.ts +11 -0
- package/build/module/lib/tools/BraveWebSearchTool.js +90 -0
- package/build/module/lib/tools/PSArtifactTool.d.ts +7 -0
- package/build/module/lib/tools/PSArtifactTool.js +79 -0
- package/build/module/lib/tools/PSCommandLineTool.d.ts +10 -0
- package/build/module/lib/tools/PSCommandLineTool.js +75 -0
- package/build/module/lib/tools/PSMemoryTool.d.ts +45 -0
- package/build/module/lib/tools/PSMemoryTool.js +487 -0
- package/build/module/lib/tools/PSReadFileTool.d.ts +10 -0
- package/build/module/lib/tools/PSReadFileTool.js +68 -0
- package/build/module/lib/tools/PSSubAgentTool.d.ts +20 -0
- package/build/module/lib/tools/PSSubAgentTool.js +289 -0
- package/build/module/lib/tools/PSWriteFileTool.d.ts +10 -0
- package/build/module/lib/tools/PSWriteFileTool.js +74 -0
- package/build/module/lib/tools/TodoTool.d.ts +57 -0
- package/build/module/lib/tools/TodoTool.js +224 -0
- package/build/module/lib/utils/debuglogger.d.ts +7 -0
- package/build/module/lib/utils/debuglogger.js +25 -0
- package/build/module/lib/utils/helpers.d.ts +4 -0
- package/build/module/lib/utils/helpers.js +41 -0
- package/package.json +1 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PSReadFileTool = void 0;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const v4_1 = require("zod/v4");
|
|
11
|
+
const PSAgentTool_1 = require("../PSAgentTool");
|
|
12
|
+
const helpers_1 = require("../utils/helpers");
|
|
13
|
+
class PSReadFileTool extends PSAgentTool_1.PSAgentTool {
|
|
14
|
+
static toolName = "read_file";
|
|
15
|
+
paths = [];
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super({
|
|
18
|
+
name: PSReadFileTool.toolName,
|
|
19
|
+
description: "Reads content of a 'file' from the repository identified by 'path'.",
|
|
20
|
+
type: "API",
|
|
21
|
+
local_execution: true,
|
|
22
|
+
hitl: true,
|
|
23
|
+
inputschema: {
|
|
24
|
+
url: `http://localhost/${PSReadFileTool.toolName}`,
|
|
25
|
+
method: "POST",
|
|
26
|
+
requestBody: v4_1.z.toJSONSchema(v4_1.z.object({
|
|
27
|
+
path: v4_1.z.string().meta({
|
|
28
|
+
title: "File_Path",
|
|
29
|
+
description: "The path of the file to be read. This should be a valid file path of files in the repository."
|
|
30
|
+
}),
|
|
31
|
+
}).meta({
|
|
32
|
+
title: `${PSReadFileTool.toolName}_request_body`,
|
|
33
|
+
description: `The request body parameters for the ${PSReadFileTool.toolName} tool.`,
|
|
34
|
+
}), { "io": "input" }),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
this.paths = options.paths || [];
|
|
38
|
+
}
|
|
39
|
+
run(input, log) {
|
|
40
|
+
if (!input.path || typeof input.path !== "string") {
|
|
41
|
+
throw new Error("Invalid file path provided.");
|
|
42
|
+
}
|
|
43
|
+
const logger = log || console;
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const filePath = path_1.default.resolve(...this.paths, input.path);
|
|
46
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
47
|
+
reject(new Error(`File not found at path: ${input.path}`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const stats = fs_1.default.statSync(filePath); // Ensure the file exists
|
|
51
|
+
if (stats.isFile()) {
|
|
52
|
+
logger.info(`📖 Reading file:\`${input.path}\` ${(0, helpers_1.formatFileSize)(stats.size)}`);
|
|
53
|
+
const content = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
54
|
+
// logger.info(`> Read ${stats.size} bytes from file.`);
|
|
55
|
+
return resolve({
|
|
56
|
+
status: 'success',
|
|
57
|
+
content,
|
|
58
|
+
size: stats.size,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
reject(new Error(`Path is not a file: ${input.path}`));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.PSReadFileTool = PSReadFileTool;
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNSZWFkRmlsZVRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xzL1BTUmVhZEZpbGVUb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHVEQUF1RDtBQUN2RCw0Q0FBb0I7QUFDcEIsZ0RBQXdCO0FBRXhCLCtCQUEyQjtBQUczQixnREFBNkM7QUFDN0MsOENBQWtEO0FBR2xELE1BQWEsY0FBZSxTQUFRLHlCQUFXO0lBQ3ZDLE1BQU0sQ0FBVSxRQUFRLEdBQUcsV0FBVyxDQUFDO0lBQ3RDLEtBQUssR0FBYSxFQUFFLENBQUM7SUFDN0IsWUFBWSxPQUVYO1FBQ0EsS0FBSyxDQUFDO1lBQ0wsSUFBSSxFQUFFLGNBQWMsQ0FBQyxRQUFRO1lBQzdCLFdBQVcsRUFBRSxxRUFBcUU7WUFDbEYsSUFBSSxFQUFFLEtBQUs7WUFDWCxlQUFlLEVBQUUsSUFBSTtZQUNyQixJQUFJLEVBQUUsSUFBSTtZQUNWLFdBQVcsRUFBRTtnQkFDWixHQUFHLEVBQUUsb0JBQW9CLGNBQWMsQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFdBQVcsRUFBRSxNQUFDLENBQUMsWUFBWSxDQUFDLE1BQUMsQ0FBQyxNQUFNLENBQUM7b0JBQ3BDLElBQUksRUFBRSxNQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO3dCQUNyQixLQUFLLEVBQUUsV0FBVzt3QkFDbEIsV0FBVyxFQUFFLCtGQUErRjtxQkFDNUcsQ0FBQztpQkFDRixDQUFDLENBQUMsSUFBSSxDQUFDO29CQUNQLEtBQUssRUFBRSxHQUFHLGNBQWMsQ0FBQyxRQUFRLGVBQWU7b0JBQ2hELFdBQVcsRUFBRSx1Q0FBdUMsY0FBYyxDQUFDLFFBQVEsUUFBUTtpQkFDbkYsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO2FBQ3RCO1NBQ0QsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBQ00sR0FBRyxDQUFDLEtBQTBCLEVBQUUsR0FBbUI7UUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ25ELE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsR0FBRyxJQUFJLE9BQU8sQ0FBQztRQUM5QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3RDLE1BQU0sUUFBUSxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsWUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUM5QixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsMkJBQTJCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzNELE9BQU87WUFDUixDQUFDO1lBQ0QsTUFBTSxLQUFLLEdBQUcsWUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLHlCQUF5QjtZQUM5RCxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLHFCQUFxQixLQUFLLENBQUMsSUFBSSxNQUFNLElBQUEsd0JBQWMsRUFBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRSxNQUFNLE9BQU8sR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDL0Msd0RBQXdEO2dCQUM1RCxPQUFPLE9BQU8sQ0FBQztvQkFDZCxNQUFNLEVBQUUsU0FBUztvQkFDakIsT0FBTztvQkFDUCxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7aUJBQ2hCLENBQUMsQ0FBQztZQUNKLENBQUM7aUJBQU0sQ0FBQztnQkFDUCxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsdUJBQXVCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQzs7QUFyREYsd0NBc0RDIn0=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AgentExecutionEvent, ExecutionEventBus } from "@a2a-js/sdk/server";
|
|
2
|
+
import { PSAgent } from "../PSAgent";
|
|
3
|
+
import { PSAgentTool } from "../PSAgentTool";
|
|
4
|
+
export declare class PSExecutionEventBus implements ExecutionEventBus {
|
|
5
|
+
listeners: {
|
|
6
|
+
[eventName: string]: ((event: AgentExecutionEvent) => void)[];
|
|
7
|
+
};
|
|
8
|
+
publish(event: AgentExecutionEvent): void;
|
|
9
|
+
on(eventName: 'event' | 'finished', listener: (event: AgentExecutionEvent) => void): this;
|
|
10
|
+
off(eventName: 'event' | 'finished', listener: (event: AgentExecutionEvent) => void): this;
|
|
11
|
+
once(eventName: 'event' | 'finished', listener: (event: AgentExecutionEvent) => void): this;
|
|
12
|
+
removeAllListeners(eventName?: 'event' | 'finished'): this;
|
|
13
|
+
finished(): void;
|
|
14
|
+
}
|
|
15
|
+
export declare class PSSubAgentTool extends PSAgentTool {
|
|
16
|
+
static TOOL_NAME: string;
|
|
17
|
+
private readonly sub_agents;
|
|
18
|
+
constructor(sub_agents: PSAgent[]);
|
|
19
|
+
run(input: Record<string, any>): Promise<Record<string, any>>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PSSubAgentTool = exports.PSExecutionEventBus = void 0;
|
|
4
|
+
const server_1 = require("@a2a-js/sdk/server");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const PSAgentTool_1 = require("../PSAgentTool");
|
|
7
|
+
class PSExecutionEventBus {
|
|
8
|
+
listeners = {};
|
|
9
|
+
publish(event) {
|
|
10
|
+
console.log(`Event published: ${JSON.stringify(event)}`);
|
|
11
|
+
}
|
|
12
|
+
on(eventName, listener) {
|
|
13
|
+
console.log(`Listener added for event: ${eventName}`);
|
|
14
|
+
if (!this.listeners[eventName]) {
|
|
15
|
+
this.listeners[eventName] = [];
|
|
16
|
+
}
|
|
17
|
+
this.listeners[eventName].push(listener);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
;
|
|
21
|
+
off(eventName, listener) {
|
|
22
|
+
console.log(`Listener removed for event: ${eventName}`);
|
|
23
|
+
if (!this.listeners[eventName])
|
|
24
|
+
return this;
|
|
25
|
+
this.listeners[eventName] = this.listeners[eventName].filter(l => l !== listener);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
once(eventName, listener) {
|
|
29
|
+
console.log(`Once listener added for event: ${eventName}`);
|
|
30
|
+
if (!this.listeners[eventName]) {
|
|
31
|
+
this.listeners[eventName] = [];
|
|
32
|
+
}
|
|
33
|
+
const onceListener = (event) => {
|
|
34
|
+
listener(event);
|
|
35
|
+
this.off(eventName, onceListener);
|
|
36
|
+
};
|
|
37
|
+
this.listeners[eventName].push(onceListener);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
removeAllListeners(eventName) {
|
|
41
|
+
if (eventName) {
|
|
42
|
+
console.log(`All listeners removed for event: ${eventName}`);
|
|
43
|
+
delete this.listeners[eventName];
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.log(`All listeners removed`);
|
|
47
|
+
this.listeners = {};
|
|
48
|
+
}
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
finished() {
|
|
52
|
+
this.listeners = {};
|
|
53
|
+
console.log(`Event bus finished`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.PSExecutionEventBus = PSExecutionEventBus;
|
|
57
|
+
class PSSubAgentTool extends PSAgentTool_1.PSAgentTool {
|
|
58
|
+
static TOOL_NAME = "subagent_tool";
|
|
59
|
+
sub_agents;
|
|
60
|
+
constructor(sub_agents) {
|
|
61
|
+
super({
|
|
62
|
+
name: PSSubAgentTool.TOOL_NAME,
|
|
63
|
+
description: generateDescription(sub_agents),
|
|
64
|
+
inputschema: {
|
|
65
|
+
url: `http://localhost/${PSSubAgentTool.TOOL_NAME}`,
|
|
66
|
+
method: "POST",
|
|
67
|
+
requestBody: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
sub_agents: {
|
|
71
|
+
type: "array",
|
|
72
|
+
title: "sub_agents",
|
|
73
|
+
description: "Array of sub agents to be invoked",
|
|
74
|
+
items: {
|
|
75
|
+
type: "object",
|
|
76
|
+
properties: {
|
|
77
|
+
name: {
|
|
78
|
+
type: "string",
|
|
79
|
+
title: "subagent name",
|
|
80
|
+
description: "The name of the sub agent",
|
|
81
|
+
},
|
|
82
|
+
input: {
|
|
83
|
+
type: "object",
|
|
84
|
+
title: "input",
|
|
85
|
+
description: "The input to the sub agent",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
required: ["name", "input"]
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
required: ["sub_agents"],
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
this.sub_agents = sub_agents || [];
|
|
97
|
+
}
|
|
98
|
+
async run(input) {
|
|
99
|
+
console.log(`Invoking ${PSSubAgentTool.TOOL_NAME} with input: ${JSON.stringify(input)}`);
|
|
100
|
+
const agentworkers = Array();
|
|
101
|
+
for (const sa_input of input.sub_agents) {
|
|
102
|
+
const sa = this.sub_agents.find(s => s.Name === sa_input.name);
|
|
103
|
+
if (!sa) {
|
|
104
|
+
return {
|
|
105
|
+
status: "error",
|
|
106
|
+
output: `Sub agent with name ${sa_input.name} not found`
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// TODO: validate input against sa.InputSchema
|
|
110
|
+
// if valid, invoke the sub agent
|
|
111
|
+
// else return error
|
|
112
|
+
// const validation = sa.validateInput(sa_input.input as any);
|
|
113
|
+
// if(!validation.valid) {
|
|
114
|
+
// return {
|
|
115
|
+
// status: "error",
|
|
116
|
+
// output: `Input validation failed for sub agent ${sa_input.name}: ${validation.errors?.map(e=>e.message).join(", ")}`
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
agentworkers.push(new Promise((resolve, reject) => {
|
|
120
|
+
try {
|
|
121
|
+
const taskId = (0, zod_1.uuidv4)().toString();
|
|
122
|
+
const userMessage = {
|
|
123
|
+
kind: "message",
|
|
124
|
+
messageId: (0, zod_1.uuidv4)().toString(),
|
|
125
|
+
parts: [
|
|
126
|
+
{
|
|
127
|
+
kind: "text",
|
|
128
|
+
text: JSON.stringify(sa_input.input, null, 2)
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
role: "user",
|
|
132
|
+
taskId
|
|
133
|
+
};
|
|
134
|
+
const reqContext = new server_1.RequestContext(userMessage, taskId, (0, zod_1.uuidv4)().toString());
|
|
135
|
+
console.log(userMessage, taskId, reqContext);
|
|
136
|
+
const eventBus = new PSExecutionEventBus();
|
|
137
|
+
sa.execute(reqContext, eventBus).then((result) => {
|
|
138
|
+
console.log(`Sub agent ${sa_input.name} completed with result: ${JSON.stringify(result)}`);
|
|
139
|
+
resolve({
|
|
140
|
+
status: "success",
|
|
141
|
+
output: result
|
|
142
|
+
});
|
|
143
|
+
}).catch((e) => {
|
|
144
|
+
console.error(`Sub agent ${sa_input.name} failed with error: ${e.message}`);
|
|
145
|
+
reject({
|
|
146
|
+
status: "error",
|
|
147
|
+
output: `Sub agent ${sa_input.name} invocation failed with error: ${e.message}`
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
reject({
|
|
153
|
+
status: "error",
|
|
154
|
+
output: `Sub agent ${sa_input.name} invocation failed with error: ${e.message}`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}));
|
|
158
|
+
const results = await Promise.all(agentworkers).then((results) => {
|
|
159
|
+
console.log(`All sub agents completed with results: ${JSON.stringify(results)}`);
|
|
160
|
+
return {
|
|
161
|
+
status: "success",
|
|
162
|
+
output: results
|
|
163
|
+
};
|
|
164
|
+
}).catch((e) => {
|
|
165
|
+
console.error(`One or more sub agents failed with error: ${e.message}`);
|
|
166
|
+
return {
|
|
167
|
+
status: "error",
|
|
168
|
+
output: `One or more sub agents invocation failed with error: ${e.message}`
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
return results;
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
status: "error",
|
|
175
|
+
output: `Not implemented yet`
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.PSSubAgentTool = PSSubAgentTool;
|
|
180
|
+
function generateDescription(sub_agents) {
|
|
181
|
+
//`Use this ${PSSubAgentTool.TOOL_NAME} one or more of sub agents available.
|
|
182
|
+
const description = `
|
|
183
|
+
Launch a new agent to handle complex, multi-step tasks autonomously.
|
|
184
|
+
|
|
185
|
+
Available agent types and the tools they have access to:
|
|
186
|
+
${sub_agents.map(sa => `- ${sa.Name}: ${sa.Description.replace(/\n/g, '\n ')}\n input schema for ${sa.Name} : ${JSON.stringify(sa.InputSchema)}\n`).join("\n")}
|
|
187
|
+
|
|
188
|
+
The input is a JSON array with each object in array having the following properties:
|
|
189
|
+
- 'name' (string) - the name of the sub agent to be created or modified.
|
|
190
|
+
- 'input' (object) - the input to the sub agent matching to its input schema.
|
|
191
|
+
The output will be a JSON array outputs from the agents.
|
|
192
|
+
|
|
193
|
+
Examples:
|
|
194
|
+
|
|
195
|
+
- <example>
|
|
196
|
+
Context: User wants to add a new feature to the support bot
|
|
197
|
+
user: "I want to add a feature that automatically detects when customers are asking about refunds and processes them"
|
|
198
|
+
assistant: "I'll use the requirements-analyzer agent to analyze this request and create an implementation plan"
|
|
199
|
+
<commentary>
|
|
200
|
+
The user has provided a feature request that needs analysis and planning before implementation.
|
|
201
|
+
</commentary>
|
|
202
|
+
|
|
203
|
+
</example>
|
|
204
|
+
- <example>
|
|
205
|
+
Context: User reports a vague issue
|
|
206
|
+
user: "The bot isn't working properly with some messages"
|
|
207
|
+
assistant: "Let me use the requirements-analyzer agent to explore this issue and determine what clarification is needed"
|
|
208
|
+
<commentary>
|
|
209
|
+
This is a vague issue report that needs exploration and likely clarification from the user.
|
|
210
|
+
</commentary>
|
|
211
|
+
</example>
|
|
212
|
+
- <example>
|
|
213
|
+
Context: User provides a clear, specific task
|
|
214
|
+
user: "Add logging to the message debouncer in start-bot.ts to track when messages are combined"
|
|
215
|
+
assistant: "I'll analyze this request with the requirements-analyzer agent to create an implementation plan"
|
|
216
|
+
<commentary>
|
|
217
|
+
Even clear requests benefit from analysis to ensure proper implementation planning.
|
|
218
|
+
</commentary>
|
|
219
|
+
</example> (Tools: Glob, Grep, LS, ExitPlanMode, Read, NotebookRead, WebFetch, TodoWrite, WebSearch, Bash)
|
|
220
|
+
- playwright-test-engineer: Use this agent when you need to create or improve Playwright E2E tests for web applications. Examples: <example>Context: User has a specification for a login form but hasn't implemented the UI yet. user: 'I need tests for a login form with email, password fields and a submit button that shows validation errors' assistant: 'I'll use the playwright-test-engineer agent to create test-first E2E tests based on your specification' <commentary>Since the user needs Playwright tests written before implementation, use the playwright-test-engineer agent to create semantic, specification-driven tests.</commentary></example> <example>Context: User has implemented a booking form component and wants comprehensive E2E tests. user: 'Here's my BookingForm.tsx component, can you write Playwright tests for it?' assistant: 'I'll analyze your BookingForm component and use the playwright-test-engineer agent to create comprehensive E2E tests' <commentary>Since the user has existing UI code and needs tests, use the playwright-test-engineer agent to inspect the component and write targeted tests.</commentary></example> (Tools: *)
|
|
221
|
+
|
|
222
|
+
When using the subagent tool, you must specify a subagent name parameter to select which agent to use.
|
|
223
|
+
|
|
224
|
+
When NOT to use the Sub Agent tool:
|
|
225
|
+
|
|
226
|
+
- If you want to read a specific file path, use the Read or Glob tool instead of the Agent tool, to find the match more
|
|
227
|
+
quickly
|
|
228
|
+
- If you are searching for a specific class definition like "class Foo", use the Glob tool instead, to find the match
|
|
229
|
+
more quickly
|
|
230
|
+
- If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Agent tool,
|
|
231
|
+
to find the match more quickly
|
|
232
|
+
- Other tasks that are not related to the agent descriptions above
|
|
233
|
+
|
|
234
|
+
Usage notes:
|
|
235
|
+
|
|
236
|
+
1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with
|
|
237
|
+
multiple tool uses
|
|
238
|
+
2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible
|
|
239
|
+
to the user. To show the user the result, you should send a text message back to the user with a concise summary of
|
|
240
|
+
the result.
|
|
241
|
+
3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent
|
|
242
|
+
be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed
|
|
243
|
+
task description for the agent to perform autonomously and you should specify exactly what information the agent
|
|
244
|
+
should return back to you in its final and only message to you.
|
|
245
|
+
4. The agent's outputs should generally be trusted
|
|
246
|
+
5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches,
|
|
247
|
+
etc.), since it is not aware of the user's intent
|
|
248
|
+
6. If the agent description mentions that it should be used proactively, then you should try your best to use it without
|
|
249
|
+
the user having to ask for it first. Use your judgement.
|
|
250
|
+
|
|
251
|
+
Example usage:
|
|
252
|
+
|
|
253
|
+
<example_agent_descriptions>
|
|
254
|
+
"code-reviewer": use this agent after you are done writing a signficant piece of code
|
|
255
|
+
"greeting-responder": use this agent when to respond to user greetings with a friendly joke
|
|
256
|
+
</example_agent_description>
|
|
257
|
+
|
|
258
|
+
<example>
|
|
259
|
+
user: "Please write a function that checks if a number is prime"
|
|
260
|
+
assistant: Sure let me write a function that checks if a number is prime
|
|
261
|
+
assistant: First let me use the Write tool to write a function that checks if a number is prime
|
|
262
|
+
assistant: I'm going to use the Write tool to write the following code:
|
|
263
|
+
<code>
|
|
264
|
+
function isPrime(n) {
|
|
265
|
+
if (n <= 1) return false
|
|
266
|
+
for (let i = 2; i * i <= n; i++) {
|
|
267
|
+
if (n % i === 0) return false
|
|
268
|
+
}
|
|
269
|
+
return true
|
|
270
|
+
}
|
|
271
|
+
</code>
|
|
272
|
+
<commentary>
|
|
273
|
+
Since a signficant piece of code was written and the task was completed, now use the code-reviewer agent to review the code
|
|
274
|
+
</commentary>
|
|
275
|
+
assistant: Now let me use the code-reviewer agent to review the code
|
|
276
|
+
assistant: Uses the Task tool to launch the with the code-reviewer agent
|
|
277
|
+
</example>
|
|
278
|
+
|
|
279
|
+
<example>
|
|
280
|
+
user: "Hello"
|
|
281
|
+
<commentary>
|
|
282
|
+
Since the user is greeting, use the greeting-responder agent to respond with a friendly joke
|
|
283
|
+
</commentary>
|
|
284
|
+
assistant: "I'm going to use the Task tool to launch the with the greeting-responder agent"
|
|
285
|
+
</example>
|
|
286
|
+
`;
|
|
287
|
+
return description;
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNTdWJBZ2VudFRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xzL1BTU3ViQWdlbnRUb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLCtDQUE0RjtBQUM1Riw2QkFBNkI7QUFHN0IsZ0RBQTZDO0FBSTdDLE1BQWEsbUJBQW1CO0lBQzVCLFNBQVMsR0FBc0UsRUFBRSxDQUFDO0lBQ2xGLE9BQU8sQ0FBQyxLQUEwQjtRQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBQ0QsRUFBRSxDQUFDLFNBQStCLEVBQUUsUUFBOEM7UUFDaEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN0RCxJQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2pDLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQSxDQUFDO0lBQ0YsR0FBRyxDQUFDLFNBQStCLEVBQUUsUUFBOEM7UUFDakYsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN4RCxJQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQSxFQUFFLENBQUEsQ0FBQyxLQUFHLFFBQVEsQ0FBQyxDQUFDO1FBQzlFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQUksQ0FBQyxTQUErQixFQUFFLFFBQThDO1FBQ2xGLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDM0QsSUFBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUEwQixFQUFFLEVBQUU7WUFDbEQsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQztRQUNGLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELGtCQUFrQixDQUFDLFNBQWdDO1FBQ2pELElBQUcsU0FBUyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQzdELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUN0QixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLEdBQUMsRUFBRSxDQUFDO1FBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNwQyxDQUFDO0NBQ0o7QUE3Q0Qsa0RBNkNDO0FBQ0QsTUFBYSxjQUFlLFNBQVEseUJBQVc7SUFDN0MsTUFBTSxDQUFDLFNBQVMsR0FBRyxlQUFlLENBQUM7SUFDbEIsVUFBVSxDQUFZO0lBQ3ZDLFlBQVksVUFBcUI7UUFDL0IsS0FBSyxDQUFDO1lBQ0osSUFBSSxFQUFFLGNBQWMsQ0FBQyxTQUFTO1lBQzlCLFdBQVcsRUFBRSxtQkFBbUIsQ0FBQyxVQUFVLENBQUM7WUFDNUMsV0FBVyxFQUFFO2dCQUNYLEdBQUcsRUFBRSxvQkFBb0IsY0FBYyxDQUFDLFNBQVMsRUFBRTtnQkFDbkQsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsV0FBVyxFQUFFO29CQUNYLElBQUksRUFBRSxRQUFRO29CQUNkLFVBQVUsRUFBRTt3QkFDVixVQUFVLEVBQUU7NEJBQ1YsSUFBSSxFQUFFLE9BQU87NEJBQ2IsS0FBSyxFQUFFLFlBQVk7NEJBQ25CLFdBQVcsRUFBRSxtQ0FBbUM7NEJBQ2hELEtBQUssRUFBRTtnQ0FDTCxJQUFJLEVBQUUsUUFBUTtnQ0FDZCxVQUFVLEVBQUU7b0NBQ1YsSUFBSSxFQUFFO3dDQUNKLElBQUksRUFBRSxRQUFRO3dDQUNkLEtBQUssRUFBRSxlQUFlO3dDQUN0QixXQUFXLEVBQUUsMkJBQTJCO3FDQUN6QztvQ0FDRCxLQUFLLEVBQUU7d0NBQ0wsSUFBSSxFQUFFLFFBQVE7d0NBQ2QsS0FBSyxFQUFFLE9BQU87d0NBQ2QsV0FBVyxFQUFFLDRCQUE0QjtxQ0FDMUM7aUNBQ0Y7Z0NBQ0QsUUFBUSxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQzs2QkFDNUI7eUJBQ0Y7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFLENBQUMsWUFBWSxDQUFDO2lCQUN6QjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLElBQUUsRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFFZSxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQTBCO1FBQ2xELE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxjQUFjLENBQUMsU0FBUyxnQkFBZ0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekYsTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFnQyxDQUFDO1FBQzNELEtBQUksTUFBTSxRQUFRLElBQUksS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQSxFQUFFLENBQUEsQ0FBQyxDQUFDLElBQUksS0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0QsSUFBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNQLE9BQU87b0JBQ0wsTUFBTSxFQUFFLE9BQU87b0JBQ2YsTUFBTSxFQUFFLHVCQUF1QixRQUFRLENBQUMsSUFBSSxZQUFZO2lCQUN6RCxDQUFBO1lBQ0gsQ0FBQztZQUNELDhDQUE4QztZQUM5QyxpQ0FBaUM7WUFDakMsb0JBQW9CO1lBQ3BCLDhEQUE4RDtZQUM5RCwwQkFBMEI7WUFDMUIsYUFBYTtZQUNiLHVCQUF1QjtZQUN2QiwySEFBMkg7WUFDM0gsTUFBTTtZQUNOLElBQUk7WUFDSixZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUNoRCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBQSxZQUFNLEdBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDbkMsTUFBTSxXQUFXLEdBQVM7d0JBQ3hCLElBQUksRUFBRSxTQUFTO3dCQUNmLFNBQVMsRUFBRSxJQUFBLFlBQU0sR0FBRSxDQUFDLFFBQVEsRUFBRTt3QkFDOUIsS0FBSyxFQUFFOzRCQUNMO2dDQUNFLElBQUksRUFBRSxNQUFNO2dDQUNaLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzs2QkFDOUM7eUJBQ0Y7d0JBQ0QsSUFBSSxFQUFFLE1BQU07d0JBQ1osTUFBTTtxQkFDUCxDQUFDO29CQUNGLE1BQU0sVUFBVSxHQUFHLElBQUksdUJBQWMsQ0FDbkMsV0FBVyxFQUNYLE1BQU0sRUFDTixJQUFBLFlBQU0sR0FBRSxDQUFDLFFBQVEsRUFBRSxDQUNwQixDQUFDO29CQUNGLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO29CQUMzQyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUMsRUFBRTt3QkFDOUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLFFBQVEsQ0FBQyxJQUFJLDJCQUEyQixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDM0YsT0FBTyxDQUFDOzRCQUNOLE1BQU0sRUFBRSxTQUFTOzRCQUNqQixNQUFNLEVBQUUsTUFBTTt5QkFDZixDQUFDLENBQUM7b0JBQ0wsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBSyxFQUFDLEVBQUU7d0JBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxRQUFRLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7d0JBQzVFLE1BQU0sQ0FBQzs0QkFDTCxNQUFNLEVBQUUsT0FBTzs0QkFDZixNQUFNLEVBQUUsYUFBYSxRQUFRLENBQUMsSUFBSSxrQ0FBa0MsQ0FBQyxDQUFDLE9BQU8sRUFBRTt5QkFDaEYsQ0FBQyxDQUFDO29CQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQUMsT0FBTSxDQUFLLEVBQUUsQ0FBQztvQkFDZCxNQUFNLENBQUM7d0JBQ0wsTUFBTSxFQUFFLE9BQU87d0JBQ2YsTUFBTSxFQUFFLGFBQWEsUUFBUSxDQUFDLElBQUksa0NBQWtDLENBQUMsQ0FBQyxPQUFPLEVBQUU7cUJBQ2hGLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNKLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUMsRUFBRTtnQkFDOUQsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pGLE9BQU87b0JBQ0wsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLE1BQU0sRUFBRSxPQUFPO2lCQUNoQixDQUFBO1lBQ0gsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBSyxFQUFDLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN4RSxPQUFPO29CQUNMLE1BQU0sRUFBRSxPQUFPO29CQUNmLE1BQU0sRUFBRSx3REFBd0QsQ0FBQyxDQUFDLE9BQU8sRUFBRTtpQkFDNUUsQ0FBQTtZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQztRQUNELE9BQU87WUFDTCxNQUFNLEVBQUUsT0FBTztZQUNmLE1BQU0sRUFBRSxxQkFBcUI7U0FDOUIsQ0FBQTtJQUNILENBQUM7O0FBNUhILHdDQTZIQztBQUNELFNBQVMsbUJBQW1CLENBQUMsVUFBcUI7SUFDaEQsNEVBQTRFO0lBRTlFLE1BQU0sV0FBVyxHQUFXOzs7O0VBSTFCLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFBLEVBQUUsQ0FBQSxLQUFLLEVBQUUsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLElBQUksTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQW9HNUosQ0FBQztJQUNBLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMifQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PSAgentLogger } from "../PSAgentLogger";
|
|
2
|
+
import { PSAgentTool } from "../PSAgentTool";
|
|
3
|
+
export declare class PSWriteFileTool extends PSAgentTool {
|
|
4
|
+
static readonly toolName = "write_file";
|
|
5
|
+
private paths;
|
|
6
|
+
constructor(options: {
|
|
7
|
+
paths?: string[];
|
|
8
|
+
});
|
|
9
|
+
run(input: Record<string, any>, log?: PSAgentLogger): Promise<Record<string, any>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PSWriteFileTool = void 0;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const v4_1 = require("zod/v4");
|
|
11
|
+
const PSAgentTool_1 = require("../PSAgentTool");
|
|
12
|
+
const helpers_1 = require("../utils/helpers");
|
|
13
|
+
class PSWriteFileTool extends PSAgentTool_1.PSAgentTool {
|
|
14
|
+
static toolName = "write_file";
|
|
15
|
+
paths = [];
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super({
|
|
18
|
+
name: PSWriteFileTool.toolName,
|
|
19
|
+
description: "Writes content to a file in repository identified by 'path'.",
|
|
20
|
+
type: "API",
|
|
21
|
+
local_execution: true,
|
|
22
|
+
hitl: true,
|
|
23
|
+
inputschema: {
|
|
24
|
+
url: `http://localhost/${PSWriteFileTool.toolName}`,
|
|
25
|
+
method: "POST",
|
|
26
|
+
requestBody: v4_1.z.toJSONSchema(v4_1.z.object({
|
|
27
|
+
path: v4_1.z.string().meta({
|
|
28
|
+
title: "File_Path",
|
|
29
|
+
description: "The path of the file to be write. This should be a valid file path in the repository."
|
|
30
|
+
}),
|
|
31
|
+
content: v4_1.z.string().meta({
|
|
32
|
+
title: "File_Content",
|
|
33
|
+
description: "The content to be written to the file. This should be a valid string content."
|
|
34
|
+
}),
|
|
35
|
+
}).meta({
|
|
36
|
+
title: `${PSWriteFileTool.toolName}_request_body`,
|
|
37
|
+
description: `The request body parameters for the ${PSWriteFileTool.toolName} tool.`,
|
|
38
|
+
}), { "io": "input" }),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
this.paths = options.paths || [];
|
|
42
|
+
}
|
|
43
|
+
run(input, log) {
|
|
44
|
+
if (!input.path || typeof input.path !== "string") {
|
|
45
|
+
throw new Error("Invalid file path provided.");
|
|
46
|
+
}
|
|
47
|
+
const logger = log || console;
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const filePath = path_1.default.resolve(...this.paths, input.path);
|
|
50
|
+
const content = input.content;
|
|
51
|
+
// if (!filePath.startsWith(run.srcDir))
|
|
52
|
+
// filePath = path.join(run.srcDir, lastevent.toolInput.request_body.path);
|
|
53
|
+
try {
|
|
54
|
+
logger.info(`📝 Writing ${(0, helpers_1.formatFileSize)(content.length)} to file:\`${input.path}\``);
|
|
55
|
+
fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
|
|
56
|
+
fs_1.default.writeFileSync(filePath, (0, helpers_1.unEscapeHTML)(content), 'utf-8');
|
|
57
|
+
// logger.info(`> Wrote ${content.length} bytes to file.`);
|
|
58
|
+
return resolve({
|
|
59
|
+
status: 'success'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (error instanceof Error) {
|
|
64
|
+
reject(new Error(`Failed to write file at path: ${input.path}. Error: ${error.message}`));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
reject(new Error(`Failed to write file at path: ${input.path}. Unknown error.`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.PSWriteFileTool = PSWriteFileTool;
|
|
74
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNXcml0ZUZpbGVUb29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi90b29scy9QU1dyaXRlRmlsZVRvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsdURBQXVEO0FBQ3ZELDRDQUFvQjtBQUNwQixnREFBd0I7QUFFeEIsK0JBQTJCO0FBRzNCLGdEQUE2QztBQUM3Qyw4Q0FBZ0U7QUFFaEUsTUFBYSxlQUFnQixTQUFRLHlCQUFXO0lBQ3hDLE1BQU0sQ0FBVSxRQUFRLEdBQUcsWUFBWSxDQUFDO0lBQ3ZDLEtBQUssR0FBYSxFQUFFLENBQUM7SUFDN0IsWUFBWSxPQUVYO1FBQ0EsS0FBSyxDQUFDO1lBQ0wsSUFBSSxFQUFFLGVBQWUsQ0FBQyxRQUFRO1lBQzlCLFdBQVcsRUFBRSw4REFBOEQ7WUFDM0UsSUFBSSxFQUFFLEtBQUs7WUFDWCxlQUFlLEVBQUUsSUFBSTtZQUNyQixJQUFJLEVBQUUsSUFBSTtZQUNWLFdBQVcsRUFBRTtnQkFDWixHQUFHLEVBQUUsb0JBQW9CLGVBQWUsQ0FBQyxRQUFRLEVBQUU7Z0JBQ25ELE1BQU0sRUFBRSxNQUFNO2dCQUNkLFdBQVcsRUFBRSxNQUFDLENBQUMsWUFBWSxDQUFDLE1BQUMsQ0FBQyxNQUFNLENBQUM7b0JBQ3BDLElBQUksRUFBRSxNQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO3dCQUNyQixLQUFLLEVBQUUsV0FBVzt3QkFDbEIsV0FBVyxFQUFFLHVGQUF1RjtxQkFDcEcsQ0FBQztvQkFDRixPQUFPLEVBQUUsTUFBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQzt3QkFDeEIsS0FBSyxFQUFFLGNBQWM7d0JBQ3JCLFdBQVcsRUFBRSwrRUFBK0U7cUJBQzVGLENBQUM7aUJBQ0YsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDUCxLQUFLLEVBQUUsR0FBRyxlQUFlLENBQUMsUUFBUSxlQUFlO29CQUNqRCxXQUFXLEVBQUUsdUNBQXVDLGVBQWUsQ0FBQyxRQUFRLFFBQVE7aUJBQ3BGLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQzthQUN0QjtTQUNELENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUNNLEdBQUcsQ0FBQyxLQUEwQixFQUFFLEdBQW1CO1FBQ3pELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNuRCxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUM7UUFDOUIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUN0QyxNQUFNLFFBQVEsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUM5Qix3Q0FBd0M7WUFDeEMsNEVBQTRFO1lBQzVFLElBQUksQ0FBQztnQkFDSixNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBQSx3QkFBYyxFQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztnQkFDdEYsWUFBRSxDQUFDLFNBQVMsQ0FBQyxjQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzFELFlBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLElBQUEsc0JBQVksRUFBQyxPQUFPLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDdkQsMkRBQTJEO2dCQUMvRCxPQUFPLE9BQU8sQ0FBQztvQkFDZCxNQUFNLEVBQUUsU0FBUztpQkFDakIsQ0FBQyxDQUFDO1lBQ0osQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2hCLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO29CQUM1QixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsaUNBQWlDLEtBQUssQ0FBQyxJQUFJLFlBQVksS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDM0YsQ0FBQztxQkFBTSxDQUFDO29CQUNQLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsS0FBSyxDQUFDLElBQUksa0JBQWtCLENBQUMsQ0FBQyxDQUFDO2dCQUNsRixDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQzs7QUExREYsMENBMkRDIn0=
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { PSAgentLogger } from "../PSAgentLogger";
|
|
2
|
+
import { PSAgentTool } from "../PSAgentTool";
|
|
3
|
+
export declare enum TodoStatus {
|
|
4
|
+
PENDING = "pending",
|
|
5
|
+
IN_PROGRESS = "in_progress",
|
|
6
|
+
COMPLETED = "completed"
|
|
7
|
+
}
|
|
8
|
+
export declare enum TodoPriority {
|
|
9
|
+
HIGH = "high",
|
|
10
|
+
MEDIUM = "medium",
|
|
11
|
+
LOW = "low"
|
|
12
|
+
}
|
|
13
|
+
export interface Todo {
|
|
14
|
+
id: string;
|
|
15
|
+
content: string;
|
|
16
|
+
status: TodoStatus;
|
|
17
|
+
priority: TodoPriority;
|
|
18
|
+
created_at: string;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
metadata?: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
export declare class TaskStore {
|
|
23
|
+
private lastModified;
|
|
24
|
+
private todos;
|
|
25
|
+
private filename?;
|
|
26
|
+
constructor(todos: Todo[], filename?: string);
|
|
27
|
+
get LastModified(): string;
|
|
28
|
+
get Todos(): Todo[];
|
|
29
|
+
set Todos(todos: Todo[]);
|
|
30
|
+
}
|
|
31
|
+
export interface TodoReadResponse {
|
|
32
|
+
todos: Todo[];
|
|
33
|
+
}
|
|
34
|
+
export interface TodoWriteParams {
|
|
35
|
+
todos: Array<Record<string, any>>;
|
|
36
|
+
}
|
|
37
|
+
export interface TodoWriteResponse {
|
|
38
|
+
success: boolean;
|
|
39
|
+
count: number;
|
|
40
|
+
}
|
|
41
|
+
export declare class PSTodoReadTool extends PSAgentTool {
|
|
42
|
+
static readonly toolName = "read_todo";
|
|
43
|
+
private store;
|
|
44
|
+
constructor(options: {
|
|
45
|
+
store: TaskStore;
|
|
46
|
+
});
|
|
47
|
+
run(_input: Record<string, any>, log?: PSAgentLogger): Promise<Record<string, any>>;
|
|
48
|
+
}
|
|
49
|
+
export declare class PSTodoWriteTool extends PSAgentTool {
|
|
50
|
+
static readonly toolName = "write_todo";
|
|
51
|
+
private store;
|
|
52
|
+
constructor(options: {
|
|
53
|
+
store: TaskStore;
|
|
54
|
+
});
|
|
55
|
+
get Todos(): Todo[];
|
|
56
|
+
run(input: Record<string, any>, log?: PSAgentLogger): Promise<Record<string, any>>;
|
|
57
|
+
}
|