psadk 1.1.0 → 1.1.1

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.
Files changed (62) hide show
  1. package/README.md +6 -0
  2. package/build/main/index.d.ts +5 -0
  3. package/build/main/index.js +7 -1
  4. package/build/main/lib/PSAI.d.ts +1 -1
  5. package/build/main/lib/PSAgent.d.ts +11 -0
  6. package/build/main/lib/PSAgent.js +59 -30
  7. package/build/main/lib/PSAgentConfig.d.ts +1 -1
  8. package/build/main/lib/PSAgentLogger.d.ts +7 -0
  9. package/build/main/lib/PSAgentLogger.js +19 -4
  10. package/build/main/lib/jwt.js +3 -1
  11. package/build/main/lib/tools/BraveWebSearchTool.d.ts +11 -0
  12. package/build/main/lib/tools/BraveWebSearchTool.js +89 -0
  13. package/build/main/lib/tools/PSCommandLineTool.d.ts +10 -0
  14. package/build/main/lib/tools/PSCommandLineTool.js +74 -0
  15. package/build/main/lib/tools/PSReadFileTool.d.ts +10 -0
  16. package/build/main/lib/tools/PSReadFileTool.js +68 -0
  17. package/build/main/lib/tools/PSSubAgentTool.js +141 -14
  18. package/build/main/lib/tools/PSWriteFileTool.d.ts +10 -0
  19. package/build/main/lib/tools/PSWriteFileTool.js +74 -0
  20. package/build/main/lib/tools/ReadFileTool.d.ts +10 -0
  21. package/build/main/lib/tools/ReadFileTool.js +68 -0
  22. package/build/main/lib/tools/TodoTool.d.ts +57 -0
  23. package/build/main/lib/tools/TodoTool.js +220 -0
  24. package/build/main/lib/tools/WebSearchTool.d.ts +9 -0
  25. package/build/main/lib/tools/WebSearchTool.js +92 -0
  26. package/build/main/lib/tools/WriteFileTool.d.ts +10 -0
  27. package/build/main/lib/tools/WriteFileTool.js +74 -0
  28. package/build/main/lib/utils/helpers.d.ts +4 -0
  29. package/build/main/lib/utils/helpers.js +41 -0
  30. package/build/module/index.d.ts +5 -0
  31. package/build/module/index.js +29 -7
  32. package/build/module/lib/PSAI.d.ts +4 -0
  33. package/build/module/lib/PSAI.js +101 -24
  34. package/build/module/lib/PSAgent.d.ts +21 -10
  35. package/build/module/lib/PSAgent.js +126 -85
  36. package/build/module/lib/PSAgentConfig.d.ts +23 -0
  37. package/build/module/lib/PSAgentConfig.js +3 -0
  38. package/build/module/lib/PSAgentLogger.d.ts +20 -0
  39. package/build/module/lib/PSAgentLogger.js +51 -0
  40. package/build/module/lib/PSAgentTask.d.ts +12 -0
  41. package/build/module/lib/PSAgentTask.js +33 -0
  42. package/build/module/lib/PSAgentTool.d.ts +56 -0
  43. package/build/module/lib/PSAgentTool.js +91 -0
  44. package/build/module/lib/jwt.d.ts +41 -0
  45. package/build/module/lib/jwt.js +75 -0
  46. package/build/module/lib/tools/BraveWebSearchTool.d.ts +11 -0
  47. package/build/module/lib/tools/BraveWebSearchTool.js +90 -0
  48. package/build/module/lib/tools/PSArtifactTool.d.ts +7 -0
  49. package/build/module/lib/tools/PSArtifactTool.js +79 -0
  50. package/build/module/lib/tools/PSCommandLineTool.d.ts +10 -0
  51. package/build/module/lib/tools/PSCommandLineTool.js +75 -0
  52. package/build/module/lib/tools/PSReadFileTool.d.ts +10 -0
  53. package/build/module/lib/tools/PSReadFileTool.js +68 -0
  54. package/build/module/lib/tools/PSSubAgentTool.d.ts +20 -0
  55. package/build/module/lib/tools/PSSubAgentTool.js +289 -0
  56. package/build/module/lib/tools/PSWriteFileTool.d.ts +10 -0
  57. package/build/module/lib/tools/PSWriteFileTool.js +74 -0
  58. package/build/module/lib/tools/TodoTool.d.ts +57 -0
  59. package/build/module/lib/tools/TodoTool.js +224 -0
  60. package/build/module/lib/utils/helpers.d.ts +4 -0
  61. package/build/module/lib/utils/helpers.js +41 -0
  62. package/package.json +1 -1
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PSCommandLineTool = void 0;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const child_process_1 = require("child_process");
6
+ const v4_1 = require("zod/v4");
7
+ const PSAgentTool_1 = require("../PSAgentTool");
8
+ const helpers_1 = require("../utils/helpers");
9
+ class PSCommandLineTool extends PSAgentTool_1.PSAgentTool {
10
+ static toolName = "run_commandline";
11
+ cwd;
12
+ constructor(options) {
13
+ super({
14
+ name: PSCommandLineTool.toolName,
15
+ description: "executes a shell command in the command shell like bash.",
16
+ type: "API",
17
+ local_execution: true,
18
+ hitl: true,
19
+ inputschema: {
20
+ url: "http://localhost/run_commandline",
21
+ method: "POST",
22
+ requestBody: v4_1.z.toJSONSchema(v4_1.z.object({
23
+ command: v4_1.z.string().meta({
24
+ title: "command",
25
+ description: "The command to run in the bash command shell."
26
+ }),
27
+ }).meta({
28
+ title: "run_commandline_request_body",
29
+ description: "The request body parameters for the run_commandline tool.",
30
+ }), { "io": "input" }),
31
+ },
32
+ });
33
+ this.cwd = options.cwd || process.cwd();
34
+ }
35
+ run(input, log) {
36
+ if (!input.command || typeof input.command !== "string") {
37
+ throw new Error("Invalid command provided.");
38
+ }
39
+ const logger = log || console;
40
+ return new Promise((resolve, reject) => {
41
+ const command = (0, helpers_1.unEscapeHTML)(input.command);
42
+ try {
43
+ logger.info(`🛠️ Running command: \`${command}\``);
44
+ const output = (0, child_process_1.execSync)(command, { cwd: this.cwd, encoding: 'utf-8' });
45
+ logger.info("```bash\n"
46
+ + `> ${command}\n`
47
+ + `${output}\n`
48
+ + "```\n\n");
49
+ return resolve({
50
+ status: 'success',
51
+ output: output || "Command executed successfully with no output.",
52
+ });
53
+ }
54
+ catch (error) {
55
+ console.error(error);
56
+ const sperr = error;
57
+ if (error instanceof Error) {
58
+ reject(new Error(`Failed to execute command: ${command}. Error: ${error.message}`));
59
+ }
60
+ else if (sperr) {
61
+ if (sperr.stderr !== '' && sperr.stderr !== undefined && sperr.stdout !== undefined) {
62
+ reject(new Error(`${sperr.stderr}\n${sperr.stdout}\nexit code: ${sperr.status}`));
63
+ }
64
+ else
65
+ reject(new Error(`Failed to execute command: ${command}. Exit code: ${sperr.status}, Error: ${sperr.stderr}`));
66
+ }
67
+ else {
68
+ reject(new Error(`Failed to execute command: ${command}. Unknown error.`));
69
+ }
70
+ }
71
+ });
72
+ }
73
+ }
74
+ exports.PSCommandLineTool = PSCommandLineTool;
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNDb21tYW5kTGluZVRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xzL1BTQ29tbWFuZExpbmVUb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUF1RDtBQUN2RCxpREFBMEQ7QUFFMUQsK0JBQTJCO0FBRzNCLGdEQUE2QztBQUM3Qyw4Q0FBZ0Q7QUFHaEQsTUFBYSxpQkFBa0IsU0FBUSx5QkFBVztJQUMxQyxNQUFNLENBQVUsUUFBUSxHQUFHLGlCQUFpQixDQUFDO0lBQzVDLEdBQUcsQ0FBUztJQUNwQixZQUFZLE9BRVg7UUFDQSxLQUFLLENBQUM7WUFDTCxJQUFJLEVBQUUsaUJBQWlCLENBQUMsUUFBUTtZQUNoQyxXQUFXLEVBQUUsMERBQTBEO1lBQ3ZFLElBQUksRUFBRSxLQUFLO1lBQ1gsZUFBZSxFQUFFLElBQUk7WUFDckIsSUFBSSxFQUFFLElBQUk7WUFDVixXQUFXLEVBQUU7Z0JBQ1osR0FBRyxFQUFFLGtDQUFrQztnQkFDdkMsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsV0FBVyxFQUFFLE1BQUMsQ0FBQyxZQUFZLENBQUMsTUFBQyxDQUFDLE1BQU0sQ0FBQztvQkFDcEMsT0FBTyxFQUFFLE1BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUM7d0JBQ3hCLEtBQUssRUFBRSxTQUFTO3dCQUNoQixXQUFXLEVBQUUsK0NBQStDO3FCQUM1RCxDQUFDO2lCQUNGLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ1AsS0FBSyxFQUFFLDhCQUE4QjtvQkFDckMsV0FBVyxFQUFFLDJEQUEyRDtpQkFDeEUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO2FBQ3RCO1NBQ0QsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBQ00sR0FBRyxDQUFDLEtBQTBCLEVBQUUsR0FBbUI7UUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksT0FBTyxLQUFLLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsR0FBRyxJQUFJLE9BQU8sQ0FBQztRQUM5QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3RDLE1BQU0sT0FBTyxHQUFHLElBQUEsc0JBQVksRUFBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDO2dCQUNKLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLE9BQU8sSUFBSSxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sTUFBTSxHQUFHLElBQUEsd0JBQVEsRUFBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDdkUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXO3NCQUNyQixLQUFLLE9BQU8sSUFBSTtzQkFDWixHQUFHLE1BQU0sSUFBSTtzQkFDYixTQUFTLENBQUMsQ0FBQztnQkFFakIsT0FBTyxPQUFPLENBQUM7b0JBQ2QsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLE1BQU0sRUFBRSxNQUFNLElBQUksK0NBQStDO2lCQUNqRSxDQUFDLENBQUM7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDWixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQixNQUFNLEtBQUssR0FBRyxLQUFpQyxDQUFDO2dCQUNwRCxJQUFJLEtBQUssWUFBWSxLQUFLLEVBQUUsQ0FBQztvQkFDNUIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDhCQUE4QixPQUFPLFlBQVksS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDckYsQ0FBQztxQkFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO29CQUNiLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBRyxFQUFFLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBRyxTQUFTLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBRyxTQUFTLEVBQUUsQ0FBQzt3QkFDOUUsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsTUFBTSxnQkFBZ0IsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDcEYsQ0FBQzs7d0JBQU0sTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDhCQUE4QixPQUFPLGdCQUFnQixLQUFLLENBQUMsTUFBTSxZQUFZLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVILENBQUM7cUJBQU0sQ0FBQztvQkFDRixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsOEJBQThCLE9BQU8sa0JBQWtCLENBQUMsQ0FBQyxDQUFDO2dCQUM3RSxDQUFDO1lBQ04sQ0FBQztRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQzs7QUE3REYsOENBOERDIn0=
@@ -0,0 +1,10 @@
1
+ import { PSAgentLogger } from "../PSAgentLogger";
2
+ import { PSAgentTool } from "../PSAgentTool";
3
+ export declare class PSReadFileTool extends PSAgentTool {
4
+ static readonly toolName = "read_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,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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNTdWJBZ2VudFRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xzL1BTU3ViQWdlbnRUb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLCtDQUE0RjtBQUM1Riw2QkFBNkI7QUFHN0IsZ0RBQTZDO0FBSTdDLE1BQWEsbUJBQW1CO0lBQzVCLFNBQVMsR0FBc0UsRUFBRSxDQUFDO0lBQ2xGLE9BQU8sQ0FBQyxLQUEwQjtRQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBQ0QsRUFBRSxDQUFDLFNBQStCLEVBQUUsUUFBOEM7UUFDaEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN0RCxJQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2pDLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQSxDQUFDO0lBQ0YsR0FBRyxDQUFDLFNBQStCLEVBQUUsUUFBOEM7UUFDakYsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN4RCxJQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQSxFQUFFLENBQUEs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
@@ -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
+ }