wave-agent-sdk 0.0.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.
- package/README.md +32 -0
- package/dist/agent.d.ts +96 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +286 -0
- package/dist/hooks/executor.d.ts +56 -0
- package/dist/hooks/executor.d.ts.map +1 -0
- package/dist/hooks/executor.js +312 -0
- package/dist/hooks/index.d.ts +17 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +14 -0
- package/dist/hooks/manager.d.ts +90 -0
- package/dist/hooks/manager.d.ts.map +1 -0
- package/dist/hooks/manager.js +395 -0
- package/dist/hooks/matcher.d.ts +49 -0
- package/dist/hooks/matcher.d.ts.map +1 -0
- package/dist/hooks/matcher.js +147 -0
- package/dist/hooks/settings.d.ts +46 -0
- package/dist/hooks/settings.d.ts.map +1 -0
- package/dist/hooks/settings.js +100 -0
- package/dist/hooks/types.d.ts +80 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +59 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/managers/aiManager.d.ts +61 -0
- package/dist/managers/aiManager.d.ts.map +1 -0
- package/dist/managers/aiManager.js +415 -0
- package/dist/managers/backgroundBashManager.d.ts +27 -0
- package/dist/managers/backgroundBashManager.d.ts.map +1 -0
- package/dist/managers/backgroundBashManager.js +166 -0
- package/dist/managers/bashManager.d.ts +20 -0
- package/dist/managers/bashManager.d.ts.map +1 -0
- package/dist/managers/bashManager.js +66 -0
- package/dist/managers/mcpManager.d.ts +63 -0
- package/dist/managers/mcpManager.d.ts.map +1 -0
- package/dist/managers/mcpManager.js +378 -0
- package/dist/managers/messageManager.d.ts +85 -0
- package/dist/managers/messageManager.d.ts.map +1 -0
- package/dist/managers/messageManager.js +265 -0
- package/dist/managers/skillManager.d.ts +59 -0
- package/dist/managers/skillManager.d.ts.map +1 -0
- package/dist/managers/skillManager.js +317 -0
- package/dist/managers/slashCommandManager.d.ts +77 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -0
- package/dist/managers/slashCommandManager.js +208 -0
- package/dist/managers/toolManager.d.ts +23 -0
- package/dist/managers/toolManager.d.ts.map +1 -0
- package/dist/managers/toolManager.js +79 -0
- package/dist/services/aiService.d.ts +28 -0
- package/dist/services/aiService.d.ts.map +1 -0
- package/dist/services/aiService.js +180 -0
- package/dist/services/memory.d.ts +8 -0
- package/dist/services/memory.d.ts.map +1 -0
- package/dist/services/memory.js +128 -0
- package/dist/services/session.d.ts +54 -0
- package/dist/services/session.d.ts.map +1 -0
- package/dist/services/session.js +196 -0
- package/dist/tools/bashTool.d.ts +14 -0
- package/dist/tools/bashTool.d.ts.map +1 -0
- package/dist/tools/bashTool.js +351 -0
- package/dist/tools/deleteFileTool.d.ts +6 -0
- package/dist/tools/deleteFileTool.d.ts.map +1 -0
- package/dist/tools/deleteFileTool.js +67 -0
- package/dist/tools/editTool.d.ts +6 -0
- package/dist/tools/editTool.d.ts.map +1 -0
- package/dist/tools/editTool.js +168 -0
- package/dist/tools/globTool.d.ts +6 -0
- package/dist/tools/globTool.d.ts.map +1 -0
- package/dist/tools/globTool.js +113 -0
- package/dist/tools/grepTool.d.ts +6 -0
- package/dist/tools/grepTool.d.ts.map +1 -0
- package/dist/tools/grepTool.js +268 -0
- package/dist/tools/lsTool.d.ts +6 -0
- package/dist/tools/lsTool.d.ts.map +1 -0
- package/dist/tools/lsTool.js +160 -0
- package/dist/tools/multiEditTool.d.ts +6 -0
- package/dist/tools/multiEditTool.d.ts.map +1 -0
- package/dist/tools/multiEditTool.js +222 -0
- package/dist/tools/readTool.d.ts +6 -0
- package/dist/tools/readTool.d.ts.map +1 -0
- package/dist/tools/readTool.js +136 -0
- package/dist/tools/types.d.ts +35 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +4 -0
- package/dist/tools/writeTool.d.ts +6 -0
- package/dist/tools/writeTool.d.ts.map +1 -0
- package/dist/tools/writeTool.js +138 -0
- package/dist/types.d.ts +212 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/utils/bashHistory.d.ts +46 -0
- package/dist/utils/bashHistory.d.ts.map +1 -0
- package/dist/utils/bashHistory.js +236 -0
- package/dist/utils/commandArgumentParser.d.ts +34 -0
- package/dist/utils/commandArgumentParser.d.ts.map +1 -0
- package/dist/utils/commandArgumentParser.js +123 -0
- package/dist/utils/constants.d.ts +27 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +28 -0
- package/dist/utils/convertMessagesForAPI.d.ts +9 -0
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -0
- package/dist/utils/convertMessagesForAPI.js +189 -0
- package/dist/utils/customCommands.d.ts +14 -0
- package/dist/utils/customCommands.d.ts.map +1 -0
- package/dist/utils/customCommands.js +71 -0
- package/dist/utils/fileFilter.d.ts +26 -0
- package/dist/utils/fileFilter.d.ts.map +1 -0
- package/dist/utils/fileFilter.js +177 -0
- package/dist/utils/markdownParser.d.ts +27 -0
- package/dist/utils/markdownParser.d.ts.map +1 -0
- package/dist/utils/markdownParser.js +109 -0
- package/dist/utils/mcpUtils.d.ts +24 -0
- package/dist/utils/mcpUtils.d.ts.map +1 -0
- package/dist/utils/mcpUtils.js +51 -0
- package/dist/utils/messageOperations.d.ts +118 -0
- package/dist/utils/messageOperations.d.ts.map +1 -0
- package/dist/utils/messageOperations.js +334 -0
- package/dist/utils/path.d.ts +25 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +109 -0
- package/dist/utils/skillParser.d.ts +18 -0
- package/dist/utils/skillParser.d.ts.map +1 -0
- package/dist/utils/skillParser.js +147 -0
- package/dist/utils/stringUtils.d.ts +13 -0
- package/dist/utils/stringUtils.d.ts.map +1 -0
- package/dist/utils/stringUtils.js +44 -0
- package/package.json +51 -0
- package/src/agent.ts +405 -0
- package/src/hooks/executor.ts +440 -0
- package/src/hooks/index.ts +52 -0
- package/src/hooks/manager.ts +618 -0
- package/src/hooks/matcher.ts +187 -0
- package/src/hooks/settings.ts +129 -0
- package/src/hooks/types.ts +169 -0
- package/src/index.ts +24 -0
- package/src/managers/aiManager.ts +573 -0
- package/src/managers/backgroundBashManager.ts +203 -0
- package/src/managers/bashManager.ts +97 -0
- package/src/managers/mcpManager.ts +493 -0
- package/src/managers/messageManager.ts +415 -0
- package/src/managers/skillManager.ts +404 -0
- package/src/managers/slashCommandManager.ts +293 -0
- package/src/managers/toolManager.ts +106 -0
- package/src/services/aiService.ts +252 -0
- package/src/services/memory.ts +149 -0
- package/src/services/session.ts +265 -0
- package/src/tools/bashTool.ts +402 -0
- package/src/tools/deleteFileTool.ts +81 -0
- package/src/tools/editTool.ts +192 -0
- package/src/tools/globTool.ts +135 -0
- package/src/tools/grepTool.ts +326 -0
- package/src/tools/lsTool.ts +187 -0
- package/src/tools/multiEditTool.ts +268 -0
- package/src/tools/readTool.ts +165 -0
- package/src/tools/types.ts +47 -0
- package/src/tools/writeTool.ts +163 -0
- package/src/types.ts +260 -0
- package/src/utils/bashHistory.ts +303 -0
- package/src/utils/commandArgumentParser.ts +153 -0
- package/src/utils/constants.ts +37 -0
- package/src/utils/convertMessagesForAPI.ts +236 -0
- package/src/utils/customCommands.ts +85 -0
- package/src/utils/fileFilter.ts +202 -0
- package/src/utils/markdownParser.ts +156 -0
- package/src/utils/mcpUtils.ts +81 -0
- package/src/utils/messageOperations.ts +506 -0
- package/src/utils/path.ts +118 -0
- package/src/utils/skillParser.ts +188 -0
- package/src/utils/stringUtils.ts +50 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { MessageManager } from "./messageManager.js";
|
|
2
|
+
import type { AIManager } from "./aiManager.js";
|
|
3
|
+
import type { SlashCommand, CustomSlashCommand, Logger } from "../types.js";
|
|
4
|
+
export interface SlashCommandManagerOptions {
|
|
5
|
+
messageManager: MessageManager;
|
|
6
|
+
aiManager: AIManager;
|
|
7
|
+
workdir: string;
|
|
8
|
+
logger?: Logger;
|
|
9
|
+
}
|
|
10
|
+
export declare class SlashCommandManager {
|
|
11
|
+
private commands;
|
|
12
|
+
private customCommands;
|
|
13
|
+
private messageManager;
|
|
14
|
+
private aiManager;
|
|
15
|
+
private workdir;
|
|
16
|
+
private logger?;
|
|
17
|
+
constructor(options: SlashCommandManagerOptions);
|
|
18
|
+
private initializeBuiltinCommands;
|
|
19
|
+
/**
|
|
20
|
+
* Load custom commands from filesystem
|
|
21
|
+
*/
|
|
22
|
+
private loadCustomCommands;
|
|
23
|
+
/**
|
|
24
|
+
* Reload custom commands (useful for development)
|
|
25
|
+
*/
|
|
26
|
+
reloadCustomCommands(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Register new command
|
|
29
|
+
*/
|
|
30
|
+
private registerCommand;
|
|
31
|
+
/**
|
|
32
|
+
* Unregister command
|
|
33
|
+
*/
|
|
34
|
+
private unregisterCommand;
|
|
35
|
+
/**
|
|
36
|
+
* Get all available commands
|
|
37
|
+
*/
|
|
38
|
+
getCommands(): SlashCommand[];
|
|
39
|
+
/**
|
|
40
|
+
* Get command by ID
|
|
41
|
+
*/
|
|
42
|
+
getCommand(commandId: string): SlashCommand | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Execute command
|
|
45
|
+
*/
|
|
46
|
+
executeCommand(commandId: string, args?: string): Promise<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* Parse and validate a slash command input
|
|
49
|
+
* Returns whether the command is valid along with parsed commandId and args
|
|
50
|
+
*/
|
|
51
|
+
parseAndValidateSlashCommand(input: string): {
|
|
52
|
+
isValid: boolean;
|
|
53
|
+
commandId?: string;
|
|
54
|
+
args?: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Check if command exists
|
|
58
|
+
*/
|
|
59
|
+
hasCommand(commandId: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Get custom command details
|
|
62
|
+
*/
|
|
63
|
+
getCustomCommand(commandId: string): CustomSlashCommand | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Get all custom commands
|
|
66
|
+
*/
|
|
67
|
+
getCustomCommands(): CustomSlashCommand[];
|
|
68
|
+
/**
|
|
69
|
+
* Execute custom command in main agent instead of sub-agent
|
|
70
|
+
*/
|
|
71
|
+
private executeCustomCommandInMainAgent;
|
|
72
|
+
/**
|
|
73
|
+
* Interrupt the currently executing slash command
|
|
74
|
+
*/
|
|
75
|
+
abortCurrentCommand(): void;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=slashCommandManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAkB5E,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,0BAA0B;IAU/C,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAenB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IA2E7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAInC"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { loadCustomSlashCommands } from "../utils/customCommands.js";
|
|
2
|
+
import { substituteCommandParameters, parseSlashCommandInput, hasParameterPlaceholders, } from "../utils/commandArgumentParser.js";
|
|
3
|
+
import { parseBashCommands, replaceBashCommandsWithOutput, } from "../utils/markdownParser.js";
|
|
4
|
+
import { exec } from "child_process";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
export class SlashCommandManager {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.commands = new Map();
|
|
10
|
+
this.customCommands = new Map();
|
|
11
|
+
this.messageManager = options.messageManager;
|
|
12
|
+
this.aiManager = options.aiManager;
|
|
13
|
+
this.workdir = options.workdir;
|
|
14
|
+
this.logger = options.logger;
|
|
15
|
+
this.initializeBuiltinCommands();
|
|
16
|
+
this.loadCustomCommands();
|
|
17
|
+
}
|
|
18
|
+
initializeBuiltinCommands() {
|
|
19
|
+
// Register built-in clear command
|
|
20
|
+
this.registerCommand({
|
|
21
|
+
id: "clear",
|
|
22
|
+
name: "clear",
|
|
23
|
+
description: "Clear the chat session",
|
|
24
|
+
handler: () => {
|
|
25
|
+
this.messageManager.clearMessages();
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Load custom commands from filesystem
|
|
31
|
+
*/
|
|
32
|
+
loadCustomCommands() {
|
|
33
|
+
try {
|
|
34
|
+
const customCommands = loadCustomSlashCommands(this.workdir);
|
|
35
|
+
for (const command of customCommands) {
|
|
36
|
+
this.customCommands.set(command.id, command);
|
|
37
|
+
// Generate description: prioritize custom description, otherwise use default description
|
|
38
|
+
const description = command.description ||
|
|
39
|
+
`Custom command: ${command.name}${hasParameterPlaceholders(command.content) ? " (supports parameters)" : ""}`;
|
|
40
|
+
// Register as a regular command with a handler that executes the custom command
|
|
41
|
+
this.registerCommand({
|
|
42
|
+
id: command.id,
|
|
43
|
+
name: command.name,
|
|
44
|
+
description,
|
|
45
|
+
handler: async (args) => {
|
|
46
|
+
// Substitute parameters in the command content
|
|
47
|
+
const processedContent = hasParameterPlaceholders(command.content) && args
|
|
48
|
+
? substituteCommandParameters(command.content, args)
|
|
49
|
+
: command.content;
|
|
50
|
+
await this.executeCustomCommandInMainAgent(command.name, processedContent, command.config, args);
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
this.logger?.info(`Loaded ${customCommands.length} custom commands`);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.logger?.warn("Failed to load custom commands:", error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Reload custom commands (useful for development)
|
|
62
|
+
*/
|
|
63
|
+
reloadCustomCommands() {
|
|
64
|
+
// Clear existing custom commands
|
|
65
|
+
for (const commandId of this.customCommands.keys()) {
|
|
66
|
+
this.unregisterCommand(commandId);
|
|
67
|
+
}
|
|
68
|
+
this.customCommands.clear();
|
|
69
|
+
// Reload
|
|
70
|
+
this.loadCustomCommands();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Register new command
|
|
74
|
+
*/
|
|
75
|
+
registerCommand(command) {
|
|
76
|
+
this.commands.set(command.id, command);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Unregister command
|
|
80
|
+
*/
|
|
81
|
+
unregisterCommand(commandId) {
|
|
82
|
+
return this.commands.delete(commandId);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get all available commands
|
|
86
|
+
*/
|
|
87
|
+
getCommands() {
|
|
88
|
+
return Array.from(this.commands.values());
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get command by ID
|
|
92
|
+
*/
|
|
93
|
+
getCommand(commandId) {
|
|
94
|
+
return this.commands.get(commandId);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Execute command
|
|
98
|
+
*/
|
|
99
|
+
async executeCommand(commandId, args) {
|
|
100
|
+
const command = this.commands.get(commandId);
|
|
101
|
+
if (!command) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
await command.handler(args);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(`Failed to execute slash command ${commandId}:`, error);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Parse and validate a slash command input
|
|
115
|
+
* Returns whether the command is valid along with parsed commandId and args
|
|
116
|
+
*/
|
|
117
|
+
parseAndValidateSlashCommand(input) {
|
|
118
|
+
try {
|
|
119
|
+
const { command: commandId, args } = parseSlashCommandInput(input);
|
|
120
|
+
const isValid = this.hasCommand(commandId);
|
|
121
|
+
return {
|
|
122
|
+
isValid,
|
|
123
|
+
commandId: isValid ? commandId : undefined,
|
|
124
|
+
args: isValid ? args || undefined : undefined, // Convert empty string to undefined
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(`Failed to parse slash command input "${input}":`, error);
|
|
129
|
+
return { isValid: false };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if command exists
|
|
134
|
+
*/
|
|
135
|
+
hasCommand(commandId) {
|
|
136
|
+
return this.commands.has(commandId);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get custom command details
|
|
140
|
+
*/
|
|
141
|
+
getCustomCommand(commandId) {
|
|
142
|
+
return this.customCommands.get(commandId);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get all custom commands
|
|
146
|
+
*/
|
|
147
|
+
getCustomCommands() {
|
|
148
|
+
return Array.from(this.customCommands.values());
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Execute custom command in main agent instead of sub-agent
|
|
152
|
+
*/
|
|
153
|
+
async executeCustomCommandInMainAgent(commandName, content, config, args) {
|
|
154
|
+
try {
|
|
155
|
+
// Parse bash commands from the content
|
|
156
|
+
const { commands, processedContent } = parseBashCommands(content);
|
|
157
|
+
// Execute bash commands if any
|
|
158
|
+
const bashResults = [];
|
|
159
|
+
for (const command of commands) {
|
|
160
|
+
try {
|
|
161
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
162
|
+
cwd: this.workdir,
|
|
163
|
+
timeout: 30000, // 30 second timeout
|
|
164
|
+
});
|
|
165
|
+
bashResults.push({
|
|
166
|
+
command,
|
|
167
|
+
output: stdout || stderr || "",
|
|
168
|
+
exitCode: 0,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const execError = error;
|
|
173
|
+
bashResults.push({
|
|
174
|
+
command,
|
|
175
|
+
output: execError.stdout || execError.stderr || execError.message || "",
|
|
176
|
+
exitCode: execError.code || 1,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Replace bash command placeholders with their outputs
|
|
181
|
+
const finalContent = bashResults.length > 0
|
|
182
|
+
? replaceBashCommandsWithOutput(processedContent, bashResults)
|
|
183
|
+
: processedContent;
|
|
184
|
+
// Add custom command block to show the command being executed
|
|
185
|
+
const originalInput = args
|
|
186
|
+
? `/${commandName} ${args}`
|
|
187
|
+
: `/${commandName}`;
|
|
188
|
+
this.messageManager.addCustomCommandMessage(commandName, finalContent, originalInput);
|
|
189
|
+
// Execute the AI conversation with custom configuration
|
|
190
|
+
await this.aiManager.sendAIMessage({
|
|
191
|
+
model: config?.model,
|
|
192
|
+
allowedTools: config?.allowedTools,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.logger?.error(`Failed to execute custom command '${commandName}':`, error);
|
|
197
|
+
// Add error to message manager
|
|
198
|
+
this.messageManager.addErrorBlock(`Failed to execute custom command '${commandName}': ${error instanceof Error ? error.message : String(error)}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Interrupt the currently executing slash command
|
|
203
|
+
*/
|
|
204
|
+
abortCurrentCommand() {
|
|
205
|
+
// Abort the AI manager if it's running
|
|
206
|
+
this.aiManager.abortAIMessage();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ToolContext, ToolPlugin, ToolResult } from "../tools/types.js";
|
|
2
|
+
import { McpManager } from "./mcpManager.js";
|
|
3
|
+
import { ChatCompletionFunctionTool } from "openai/resources.js";
|
|
4
|
+
import type { Logger } from "../types.js";
|
|
5
|
+
export interface ToolManagerOptions {
|
|
6
|
+
mcpManager: McpManager;
|
|
7
|
+
logger?: Logger;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Tool Manager
|
|
11
|
+
*/
|
|
12
|
+
declare class ToolManager {
|
|
13
|
+
private tools;
|
|
14
|
+
private mcpManager;
|
|
15
|
+
private logger?;
|
|
16
|
+
constructor(options: ToolManagerOptions);
|
|
17
|
+
private initializeBuiltInTools;
|
|
18
|
+
execute(name: string, args: Record<string, unknown>, context: ToolContext): Promise<ToolResult>;
|
|
19
|
+
list(): ToolPlugin[];
|
|
20
|
+
getToolsConfig(): ChatCompletionFunctionTool[];
|
|
21
|
+
}
|
|
22
|
+
export { ToolManager };
|
|
23
|
+
//# sourceMappingURL=toolManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolManager.d.ts","sourceRoot":"","sources":["../../src/managers/toolManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAY7E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,kBAAkB;IAQvC,OAAO,CAAC,sBAAsB;IAqBxB,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC;IA2BtB,IAAI,IAAI,UAAU,EAAE;IAMpB,cAAc,IAAI,0BAA0B,EAAE;CAO/C;AAGD,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { bashTool, bashOutputTool, killBashTool } from "../tools/bashTool.js";
|
|
2
|
+
import { deleteFileTool } from "../tools/deleteFileTool.js";
|
|
3
|
+
import { editTool } from "../tools/editTool.js";
|
|
4
|
+
import { multiEditTool } from "../tools/multiEditTool.js";
|
|
5
|
+
import { writeTool } from "../tools/writeTool.js";
|
|
6
|
+
// New tools
|
|
7
|
+
import { globTool } from "../tools/globTool.js";
|
|
8
|
+
import { grepTool } from "../tools/grepTool.js";
|
|
9
|
+
import { lsTool } from "../tools/lsTool.js";
|
|
10
|
+
import { readTool } from "../tools/readTool.js";
|
|
11
|
+
import { SkillManager } from "./skillManager.js";
|
|
12
|
+
/**
|
|
13
|
+
* Tool Manager
|
|
14
|
+
*/
|
|
15
|
+
class ToolManager {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.tools = new Map();
|
|
18
|
+
this.mcpManager = options.mcpManager;
|
|
19
|
+
this.logger = options.logger;
|
|
20
|
+
// Initialize built-in tools
|
|
21
|
+
this.initializeBuiltInTools();
|
|
22
|
+
}
|
|
23
|
+
initializeBuiltInTools() {
|
|
24
|
+
const builtInTools = [
|
|
25
|
+
bashTool,
|
|
26
|
+
bashOutputTool,
|
|
27
|
+
killBashTool,
|
|
28
|
+
deleteFileTool,
|
|
29
|
+
editTool,
|
|
30
|
+
multiEditTool,
|
|
31
|
+
writeTool,
|
|
32
|
+
globTool,
|
|
33
|
+
grepTool,
|
|
34
|
+
lsTool,
|
|
35
|
+
readTool,
|
|
36
|
+
new SkillManager({ logger: this.logger }).createTool(),
|
|
37
|
+
];
|
|
38
|
+
for (const tool of builtInTools) {
|
|
39
|
+
this.tools.set(tool.name, tool);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async execute(name, args, context) {
|
|
43
|
+
// Check if it's an MCP tool first
|
|
44
|
+
if (this.mcpManager.isMcpTool(name)) {
|
|
45
|
+
return this.mcpManager.executeMcpToolByRegistry(name, args, context);
|
|
46
|
+
}
|
|
47
|
+
// Check built-in tools
|
|
48
|
+
const plugin = this.tools.get(name);
|
|
49
|
+
if (plugin) {
|
|
50
|
+
try {
|
|
51
|
+
return await plugin.execute(args, context);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
content: "",
|
|
57
|
+
error: error instanceof Error ? error.message : String(error),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
content: "",
|
|
64
|
+
error: `Tool '${name}' not found`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
list() {
|
|
68
|
+
const builtInTools = Array.from(this.tools.values());
|
|
69
|
+
const mcpTools = this.mcpManager.getMcpToolPlugins();
|
|
70
|
+
return [...builtInTools, ...mcpTools];
|
|
71
|
+
}
|
|
72
|
+
getToolsConfig() {
|
|
73
|
+
const builtInToolsConfig = Array.from(this.tools.values()).map((tool) => tool.config);
|
|
74
|
+
const mcpToolsConfig = this.mcpManager.getMcpToolsConfig();
|
|
75
|
+
return [...builtInToolsConfig, ...mcpToolsConfig];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Export tool registry class and types
|
|
79
|
+
export { ToolManager };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ChatCompletionMessageToolCall } from "openai/resources";
|
|
2
|
+
import { ChatCompletionMessageParam, ChatCompletionFunctionTool } from "openai/resources.js";
|
|
3
|
+
export interface CallAgentOptions {
|
|
4
|
+
messages: ChatCompletionMessageParam[];
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
abortSignal?: AbortSignal;
|
|
7
|
+
memory?: string;
|
|
8
|
+
workdir: string;
|
|
9
|
+
tools?: ChatCompletionFunctionTool[];
|
|
10
|
+
model?: string;
|
|
11
|
+
systemPrompt?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CallAgentResult {
|
|
14
|
+
content?: string;
|
|
15
|
+
tool_calls?: ChatCompletionMessageToolCall[];
|
|
16
|
+
usage?: {
|
|
17
|
+
prompt_tokens: number;
|
|
18
|
+
completion_tokens: number;
|
|
19
|
+
total_tokens: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare function callAgent(options: CallAgentOptions): Promise<CallAgentResult>;
|
|
23
|
+
export interface CompressMessagesOptions {
|
|
24
|
+
messages: ChatCompletionMessageParam[];
|
|
25
|
+
abortSignal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
export declare function compressMessages(options: CompressMessagesOptions): Promise<string>;
|
|
28
|
+
//# sourceMappingURL=aiService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiService.d.ts","sourceRoot":"","sources":["../../src/services/aiService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAEL,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAuC7B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC7C,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA2F1B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAmFjB"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import { FAST_MODEL_ID, AGENT_MODEL_ID } from "../utils/constants.js";
|
|
3
|
+
/**
|
|
4
|
+
* Get specific configuration parameters based on model name
|
|
5
|
+
* @param modelName Model name
|
|
6
|
+
* @param baseConfig Base configuration
|
|
7
|
+
* @returns Configured model parameters
|
|
8
|
+
*/
|
|
9
|
+
function getModelConfig(modelName, baseConfig = {}) {
|
|
10
|
+
const config = {
|
|
11
|
+
model: modelName,
|
|
12
|
+
stream: false,
|
|
13
|
+
...baseConfig,
|
|
14
|
+
};
|
|
15
|
+
// Configuration rules for specific models
|
|
16
|
+
if (modelName.includes("gpt-5-codex")) {
|
|
17
|
+
// gpt-5-codex model sets temperature to undefined
|
|
18
|
+
config.temperature = undefined;
|
|
19
|
+
}
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
// Initialize OpenAI client with environment variables
|
|
23
|
+
const openai = new OpenAI({
|
|
24
|
+
apiKey: process.env.AIGW_TOKEN,
|
|
25
|
+
baseURL: process.env.AIGW_URL,
|
|
26
|
+
});
|
|
27
|
+
export async function callAgent(options) {
|
|
28
|
+
const { messages, abortSignal, memory, workdir, tools, model, systemPrompt } = options;
|
|
29
|
+
try {
|
|
30
|
+
// Build system prompt content
|
|
31
|
+
let systemContent;
|
|
32
|
+
if (systemPrompt) {
|
|
33
|
+
// Use custom system prompt if provided
|
|
34
|
+
systemContent = systemPrompt;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Use default system prompt
|
|
38
|
+
systemContent = `You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
39
|
+
|
|
40
|
+
## Current Working Directory
|
|
41
|
+
${workdir}
|
|
42
|
+
`;
|
|
43
|
+
// If there is memory content, add it to the system prompt
|
|
44
|
+
if (memory && memory.trim()) {
|
|
45
|
+
systemContent += `\n\n## Memory Context\n\nThe following is important context and memory from previous interactions:\n\n${memory}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Add system prompt
|
|
49
|
+
const systemMessage = {
|
|
50
|
+
role: "system",
|
|
51
|
+
content: systemContent,
|
|
52
|
+
};
|
|
53
|
+
// ChatCompletionMessageParam[] is already in OpenAI format, add system prompt to the beginning
|
|
54
|
+
const openaiMessages = [systemMessage, ...messages];
|
|
55
|
+
// Get model configuration
|
|
56
|
+
const modelConfig = getModelConfig(model || AGENT_MODEL_ID, {
|
|
57
|
+
temperature: 0,
|
|
58
|
+
max_completion_tokens: 32768,
|
|
59
|
+
});
|
|
60
|
+
// Prepare API call parameters
|
|
61
|
+
const createParams = {
|
|
62
|
+
...modelConfig,
|
|
63
|
+
messages: openaiMessages,
|
|
64
|
+
};
|
|
65
|
+
// Only add tools if they exist
|
|
66
|
+
if (tools && tools.length > 0) {
|
|
67
|
+
createParams.tools = tools;
|
|
68
|
+
}
|
|
69
|
+
// Call OpenAI API (non-streaming)
|
|
70
|
+
const response = await openai.chat.completions.create(createParams, {
|
|
71
|
+
signal: abortSignal,
|
|
72
|
+
});
|
|
73
|
+
const finalMessage = response.choices[0]?.message;
|
|
74
|
+
const totalUsage = response.usage
|
|
75
|
+
? {
|
|
76
|
+
prompt_tokens: response.usage.prompt_tokens,
|
|
77
|
+
completion_tokens: response.usage.completion_tokens,
|
|
78
|
+
total_tokens: response.usage.total_tokens,
|
|
79
|
+
}
|
|
80
|
+
: undefined;
|
|
81
|
+
const result = {};
|
|
82
|
+
// Return content
|
|
83
|
+
if (finalMessage?.content) {
|
|
84
|
+
result.content = finalMessage.content;
|
|
85
|
+
}
|
|
86
|
+
// Return tool call
|
|
87
|
+
if (finalMessage?.tool_calls && finalMessage.tool_calls.length > 0) {
|
|
88
|
+
result.tool_calls = finalMessage.tool_calls;
|
|
89
|
+
}
|
|
90
|
+
// Return token usage information
|
|
91
|
+
if (totalUsage) {
|
|
92
|
+
result.usage = totalUsage;
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error.name === "AbortError") {
|
|
98
|
+
throw new Error("Request was aborted");
|
|
99
|
+
}
|
|
100
|
+
// // logger.error("Failed to call OpenAI:", error);
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function compressMessages(options) {
|
|
105
|
+
const { messages, abortSignal } = options;
|
|
106
|
+
// Get model configuration
|
|
107
|
+
const modelConfig = getModelConfig(FAST_MODEL_ID, {
|
|
108
|
+
temperature: 0.1,
|
|
109
|
+
max_tokens: 1500,
|
|
110
|
+
});
|
|
111
|
+
try {
|
|
112
|
+
const response = await openai.chat.completions.create({
|
|
113
|
+
...modelConfig,
|
|
114
|
+
messages: [
|
|
115
|
+
{
|
|
116
|
+
role: "system",
|
|
117
|
+
content: `You are an expert conversation history compression specialist. Your task is to create comprehensive yet concise summaries that preserve critical development context.
|
|
118
|
+
|
|
119
|
+
## Primary Request and Intent
|
|
120
|
+
Compress conversation history while maintaining all essential technical and procedural information.
|
|
121
|
+
|
|
122
|
+
## Key Technical Concepts
|
|
123
|
+
- Code modifications and file operations
|
|
124
|
+
- Tool executions and their results
|
|
125
|
+
- Error handling and debugging processes
|
|
126
|
+
- User requirements and assistant solutions
|
|
127
|
+
- Technical discussions and decisions
|
|
128
|
+
|
|
129
|
+
## Compression Strategy
|
|
130
|
+
1. **Preserve Critical Information**:
|
|
131
|
+
- All file paths, function names, and code examples
|
|
132
|
+
- Tool execution results and outcomes
|
|
133
|
+
- Error messages and resolution steps
|
|
134
|
+
- User requirements and implementation approaches
|
|
135
|
+
- Technical decisions and their reasoning
|
|
136
|
+
|
|
137
|
+
2. **Structure Organization**:
|
|
138
|
+
- Group related actions and discussions
|
|
139
|
+
- Maintain chronological flow for complex operations
|
|
140
|
+
- Separate different technical topics clearly
|
|
141
|
+
|
|
142
|
+
3. **Context Preservation**:
|
|
143
|
+
- Keep enough detail for future reference
|
|
144
|
+
- Maintain relationships between requests and solutions
|
|
145
|
+
- Preserve debugging context and error resolution paths
|
|
146
|
+
|
|
147
|
+
## Output Requirements:
|
|
148
|
+
- Use third-person narrative format
|
|
149
|
+
- Target 300-800 words (scale based on complexity)
|
|
150
|
+
- Maintain the original conversation language
|
|
151
|
+
- Structure with clear sections for multi-topic conversations
|
|
152
|
+
- Focus on actionable information and outcomes
|
|
153
|
+
|
|
154
|
+
## Format Template:
|
|
155
|
+
For technical conversations, structure as:
|
|
156
|
+
- **User Requests**: Key requirements and goals
|
|
157
|
+
- **Technical Implementation**: Code changes, file operations, tool usage
|
|
158
|
+
- **Problem Resolution**: Errors encountered and solutions applied
|
|
159
|
+
- **Outcomes**: Final results and current state`,
|
|
160
|
+
},
|
|
161
|
+
...messages,
|
|
162
|
+
{
|
|
163
|
+
role: "user",
|
|
164
|
+
content: `Please compress this conversation following the structured approach. Focus on preserving all technical details, file operations, and problem-solving context while creating a concise summary.`,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
}, {
|
|
168
|
+
signal: abortSignal,
|
|
169
|
+
});
|
|
170
|
+
return (response.choices[0]?.message?.content?.trim() ||
|
|
171
|
+
"Failed to compress conversation history");
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error.name === "AbortError") {
|
|
175
|
+
throw new Error("Compression request was aborted");
|
|
176
|
+
}
|
|
177
|
+
// // logger.error("Failed to compress messages:", error);
|
|
178
|
+
return "Failed to compress conversation history";
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const isMemoryMessage: (message: string) => boolean;
|
|
2
|
+
export declare const addMemory: (message: string, workdir: string) => Promise<void>;
|
|
3
|
+
export declare const ensureUserMemoryFile: () => Promise<void>;
|
|
4
|
+
export declare const addUserMemory: (message: string) => Promise<void>;
|
|
5
|
+
export declare const getUserMemoryContent: () => Promise<string>;
|
|
6
|
+
export declare const readMemoryFile: (workdir: string) => Promise<string>;
|
|
7
|
+
export declare const getCombinedMemoryContent: (workdir: string) => Promise<string>;
|
|
8
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,OAEjD,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,SAAS,MAAM,EACf,SAAS,MAAM,KACd,OAAO,CAAC,IAAI,CAoCd,CAAC;AAGF,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,IAAI,CAyBzD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAsBjE,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,MAAM,CAQ3D,CAAC;AAGF,eAAO,MAAM,cAAc,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAUpE,CAAC;AAGF,eAAO,MAAM,wBAAwB,GACnC,SAAS,MAAM,KACd,OAAO,CAAC,MAAM,CAoBhB,CAAC"}
|