@tyvm/knowhow 0.0.68 → 0.0.70
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/docs/shell-commands.md +174 -0
- package/package.json +2 -2
- package/src/agents/base/base.ts +1 -3
- package/src/agents/developer/developer.ts +21 -16
- package/src/agents/tools/agentCall.ts +4 -2
- package/src/agents/tools/fileSearch.ts +5 -1
- package/src/agents/tools/list.ts +41 -37
- package/src/agents/tools/startAgentTask.ts +131 -22
- package/src/chat/CliChatService.ts +57 -11
- package/src/chat/modules/AgentModule.ts +72 -12
- package/src/chat/modules/CustomCommandsModule.ts +79 -0
- package/src/chat/modules/InternalChatModule.ts +11 -1
- package/src/chat/modules/ShellCommandModule.ts +96 -0
- package/src/chat/modules/index.ts +1 -0
- package/src/chat/types.ts +14 -2
- package/src/chat.ts +16 -13
- package/src/cli.ts +16 -6
- package/src/clients/anthropic.ts +88 -91
- package/src/clients/gemini.ts +495 -94
- package/src/clients/index.ts +125 -0
- package/src/clients/knowhow.ts +81 -0
- package/src/clients/openai.ts +256 -145
- package/src/clients/pricing/anthropic.ts +90 -0
- package/src/clients/pricing/google.ts +65 -0
- package/src/clients/pricing/index.ts +4 -0
- package/src/clients/pricing/openai.ts +134 -0
- package/src/clients/pricing/xai.ts +62 -0
- package/src/clients/types.ts +170 -1
- package/src/clients/xai.ts +275 -46
- package/src/config.ts +61 -15
- package/src/embeddings.ts +9 -1
- package/src/microphone.ts +15 -16
- package/src/migrations.ts +151 -0
- package/src/plugins/AgentsMdPlugin.ts +118 -0
- package/src/plugins/PluginBase.ts +8 -0
- package/src/plugins/downloader/downloader.ts +5 -6
- package/src/plugins/embedding.ts +10 -8
- package/src/plugins/exec.ts +70 -0
- package/src/plugins/github.ts +120 -74
- package/src/plugins/language.ts +11 -13
- package/src/plugins/plugins.ts +25 -4
- package/src/plugins/tmux.ts +132 -0
- package/src/plugins/types.ts +1 -0
- package/src/plugins/vim.ts +14 -1
- package/src/server/index.ts +2 -0
- package/src/services/AgentSyncFs.ts +417 -0
- package/src/services/{AgentSynchronization.ts → AgentSyncKnowhowWeb.ts} +2 -2
- package/src/services/EventService.ts +0 -1
- package/src/services/KnowhowClient.ts +106 -0
- package/src/services/index.ts +4 -2
- package/src/types.ts +57 -4
- package/src/worker.ts +25 -2
- package/tests/manual/modalities/README.md +157 -0
- package/tests/manual/modalities/google.modalities.test.ts +335 -0
- package/tests/manual/modalities/openai.modalities.test.ts +329 -0
- package/tests/manual/modalities/streaming.test.ts +260 -0
- package/tests/manual/modalities/xai.modalities.test.ts +307 -0
- package/tests/plugins/language/languagePlugin-content-triggers.test.ts +5 -5
- package/tests/plugins/language/languagePlugin-integration.test.ts +1 -1
- package/tests/plugins/language/languagePlugin.test.ts +17 -8
- package/ts_build/package.json +2 -2
- package/ts_build/src/agents/base/base.js +1 -1
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/developer/developer.js +21 -15
- package/ts_build/src/agents/developer/developer.js.map +1 -1
- package/ts_build/src/agents/tools/agentCall.js +4 -2
- package/ts_build/src/agents/tools/agentCall.js.map +1 -1
- package/ts_build/src/agents/tools/executeScript/index.d.ts +1 -1
- package/ts_build/src/agents/tools/fileSearch.js +2 -1
- package/ts_build/src/agents/tools/fileSearch.js.map +1 -1
- package/ts_build/src/agents/tools/github/index.d.ts +1 -1
- package/ts_build/src/agents/tools/list.js +41 -37
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/agents/tools/startAgentTask.d.ts +2 -1
- package/ts_build/src/agents/tools/startAgentTask.js +118 -17
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
- package/ts_build/src/chat/CliChatService.d.ts +4 -0
- package/ts_build/src/chat/CliChatService.js +39 -5
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.d.ts +4 -1
- package/ts_build/src/chat/modules/AgentModule.js +49 -11
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/chat/modules/CustomCommandsModule.d.ts +9 -0
- package/ts_build/src/chat/modules/CustomCommandsModule.js +58 -0
- package/ts_build/src/chat/modules/CustomCommandsModule.js.map +1 -0
- package/ts_build/src/chat/modules/InternalChatModule.d.ts +2 -0
- package/ts_build/src/chat/modules/InternalChatModule.js +10 -0
- package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -1
- package/ts_build/src/chat/modules/ShellCommandModule.d.ts +8 -0
- package/ts_build/src/chat/modules/ShellCommandModule.js +83 -0
- package/ts_build/src/chat/modules/ShellCommandModule.js.map +1 -0
- package/ts_build/src/chat/modules/index.d.ts +1 -0
- package/ts_build/src/chat/modules/index.js +3 -1
- package/ts_build/src/chat/modules/index.js.map +1 -1
- package/ts_build/src/chat/types.d.ts +11 -1
- package/ts_build/src/chat.js +16 -13
- package/ts_build/src/chat.js.map +1 -1
- package/ts_build/src/cli.js +10 -3
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/anthropic.d.ts +6 -1
- package/ts_build/src/clients/anthropic.js +47 -92
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/gemini.d.ts +81 -2
- package/ts_build/src/clients/gemini.js +362 -79
- package/ts_build/src/clients/gemini.js.map +1 -1
- package/ts_build/src/clients/index.d.ts +9 -1
- package/ts_build/src/clients/index.js +65 -0
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/knowhow.d.ts +9 -1
- package/ts_build/src/clients/knowhow.js +43 -0
- package/ts_build/src/clients/knowhow.js.map +1 -1
- package/ts_build/src/clients/openai.d.ts +9 -1
- package/ts_build/src/clients/openai.js +201 -133
- package/ts_build/src/clients/openai.js.map +1 -1
- package/ts_build/src/clients/pricing/anthropic.d.ts +17 -0
- package/ts_build/src/clients/pricing/anthropic.js +93 -0
- package/ts_build/src/clients/pricing/anthropic.js.map +1 -0
- package/ts_build/src/clients/pricing/google.d.ts +73 -0
- package/ts_build/src/clients/pricing/google.js +68 -0
- package/ts_build/src/clients/pricing/google.js.map +1 -0
- package/ts_build/src/clients/pricing/index.d.ts +4 -0
- package/ts_build/src/clients/pricing/index.js +14 -0
- package/ts_build/src/clients/pricing/index.js.map +1 -0
- package/ts_build/src/clients/pricing/openai.d.ts +7 -0
- package/ts_build/src/clients/pricing/openai.js +137 -0
- package/ts_build/src/clients/pricing/openai.js.map +1 -0
- package/ts_build/src/clients/pricing/xai.d.ts +26 -0
- package/ts_build/src/clients/pricing/xai.js +59 -0
- package/ts_build/src/clients/pricing/xai.js.map +1 -0
- package/ts_build/src/clients/types.d.ts +135 -0
- package/ts_build/src/clients/xai.d.ts +9 -1
- package/ts_build/src/clients/xai.js +178 -46
- package/ts_build/src/clients/xai.js.map +1 -1
- package/ts_build/src/config.d.ts +1 -0
- package/ts_build/src/config.js +45 -16
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/embeddings.js +8 -1
- package/ts_build/src/embeddings.js.map +1 -1
- package/ts_build/src/microphone.js +7 -9
- package/ts_build/src/microphone.js.map +1 -1
- package/ts_build/src/migrations.d.ts +17 -0
- package/ts_build/src/migrations.js +86 -0
- package/ts_build/src/migrations.js.map +1 -0
- package/ts_build/src/plugins/AgentsMdPlugin.d.ts +13 -0
- package/ts_build/src/plugins/AgentsMdPlugin.js +118 -0
- package/ts_build/src/plugins/AgentsMdPlugin.js.map +1 -0
- package/ts_build/src/plugins/PluginBase.d.ts +1 -0
- package/ts_build/src/plugins/PluginBase.js +3 -0
- package/ts_build/src/plugins/PluginBase.js.map +1 -1
- package/ts_build/src/plugins/downloader/downloader.js +5 -5
- package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
- package/ts_build/src/plugins/embedding.js +9 -8
- package/ts_build/src/plugins/embedding.js.map +1 -1
- package/ts_build/src/plugins/exec.d.ts +10 -0
- package/ts_build/src/plugins/exec.js +56 -0
- package/ts_build/src/plugins/exec.js.map +1 -0
- package/ts_build/src/plugins/github.js +93 -51
- package/ts_build/src/plugins/github.js.map +1 -1
- package/ts_build/src/plugins/language.js +14 -11
- package/ts_build/src/plugins/language.js.map +1 -1
- package/ts_build/src/plugins/plugins.d.ts +1 -0
- package/ts_build/src/plugins/plugins.js +19 -1
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/plugins/tmux.d.ts +14 -0
- package/ts_build/src/plugins/tmux.js +108 -0
- package/ts_build/src/plugins/tmux.js.map +1 -0
- package/ts_build/src/plugins/types.d.ts +1 -0
- package/ts_build/src/plugins/vim.js +11 -1
- package/ts_build/src/plugins/vim.js.map +1 -1
- package/ts_build/src/server/index.js.map +1 -1
- package/ts_build/src/services/AgentSyncFs.d.ts +34 -0
- package/ts_build/src/services/AgentSyncFs.js +325 -0
- package/ts_build/src/services/AgentSyncFs.js.map +1 -0
- package/ts_build/src/services/AgentSyncKnowhowWeb.d.ts +29 -0
- package/ts_build/src/services/AgentSyncKnowhowWeb.js +178 -0
- package/ts_build/src/services/AgentSyncKnowhowWeb.js.map +1 -0
- package/ts_build/src/services/AgentSynchronization.d.ts +1 -1
- package/ts_build/src/services/AgentSynchronization.js +3 -3
- package/ts_build/src/services/AgentSynchronization.js.map +1 -1
- package/ts_build/src/services/EventService.js.map +1 -1
- package/ts_build/src/services/KnowhowClient.d.ts +9 -1
- package/ts_build/src/services/KnowhowClient.js +58 -0
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/index.d.ts +2 -1
- package/ts_build/src/services/index.js +2 -1
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/types.d.ts +26 -1
- package/ts_build/src/types.js +45 -4
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/utils/PersistentInputManager.d.ts +28 -0
- package/ts_build/src/utils/PersistentInputManager.js +293 -0
- package/ts_build/src/utils/PersistentInputManager.js.map +1 -0
- package/ts_build/src/worker.js +11 -2
- package/ts_build/src/worker.js.map +1 -1
- package/ts_build/tests/manual/modalities/google.modalities.test.d.ts +1 -0
- package/ts_build/tests/manual/modalities/google.modalities.test.js +252 -0
- package/ts_build/tests/manual/modalities/google.modalities.test.js.map +1 -0
- package/ts_build/tests/manual/modalities/openai.modalities.test.d.ts +1 -0
- package/ts_build/tests/manual/modalities/openai.modalities.test.js +252 -0
- package/ts_build/tests/manual/modalities/openai.modalities.test.js.map +1 -0
- package/ts_build/tests/manual/modalities/streaming.test.d.ts +1 -0
- package/ts_build/tests/manual/modalities/streaming.test.js +206 -0
- package/ts_build/tests/manual/modalities/streaming.test.js.map +1 -0
- package/ts_build/tests/manual/modalities/xai.modalities.test.d.ts +1 -0
- package/ts_build/tests/manual/modalities/xai.modalities.test.js +226 -0
- package/ts_build/tests/manual/modalities/xai.modalities.test.js.map +1 -0
- package/ts_build/tests/manual/persistent-input-test.d.ts +1 -0
- package/ts_build/tests/manual/persistent-input-test.js +35 -0
- package/ts_build/tests/manual/persistent-input-test.js.map +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +5 -5
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -1
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.js +1 -1
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -1
- package/ts_build/tests/plugins/language/languagePlugin.test.js +17 -7
- package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import {
|
|
6
6
|
ChatService,
|
|
7
7
|
ChatContext,
|
|
8
|
+
CommandResult,
|
|
8
9
|
ChatCommand,
|
|
9
10
|
ChatMode,
|
|
10
11
|
InputMethod,
|
|
@@ -112,6 +113,10 @@ export class CliChatService implements ChatService {
|
|
|
112
113
|
return this.context;
|
|
113
114
|
}
|
|
114
115
|
|
|
116
|
+
getTools() {
|
|
117
|
+
return this.context.selectedAgent?.tools;
|
|
118
|
+
}
|
|
119
|
+
|
|
115
120
|
setContext(context: Partial<ChatContext>): void {
|
|
116
121
|
this.context = { ...this.context, ...context };
|
|
117
122
|
// Keep chatHistory reference synchronized
|
|
@@ -144,6 +149,37 @@ export class CliChatService implements ChatService {
|
|
|
144
149
|
return this.commands;
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Get commands available in the current mode
|
|
154
|
+
*/
|
|
155
|
+
getCommandsForMode(mode: string): ChatCommand[] {
|
|
156
|
+
return this.commands.filter(
|
|
157
|
+
(cmd) => !cmd.modes || cmd.modes.length === 0 || cmd.modes.includes(mode)
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getCommandsForActiveModes(): ChatCommand[] {
|
|
162
|
+
const activeModes = this.modes
|
|
163
|
+
.filter((mode) => mode.active)
|
|
164
|
+
.map((mode) => mode.name);
|
|
165
|
+
return this.commands.filter(
|
|
166
|
+
(cmd) =>
|
|
167
|
+
!cmd.modes ||
|
|
168
|
+
cmd.modes.length === 0 ||
|
|
169
|
+
cmd.modes.some((mode) => activeModes.includes(mode))
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
setMode(mode: string): void {
|
|
174
|
+
this.modes.forEach((m) => {
|
|
175
|
+
if (m.name !== "default" && m.name !== mode) {
|
|
176
|
+
m.active = false;
|
|
177
|
+
} else if (m.name === mode) {
|
|
178
|
+
m.active = true;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
147
183
|
getModes(): ChatMode[] {
|
|
148
184
|
return this.modes;
|
|
149
185
|
}
|
|
@@ -154,16 +190,28 @@ export class CliChatService implements ChatService {
|
|
|
154
190
|
|
|
155
191
|
async processInput(input: string): Promise<boolean> {
|
|
156
192
|
// Note: Input is added to history via setOnNewHistoryEntry callback when user presses Enter
|
|
157
|
-
// Note: this actually sends all commands to modules
|
|
193
|
+
// Note: this actually sends all commands to modules if not handled by a command
|
|
158
194
|
|
|
159
195
|
// Check if input is a command
|
|
160
196
|
if (input.startsWith("/")) {
|
|
161
197
|
const [commandName, ...args] = input.slice(1).split(" ");
|
|
162
|
-
const
|
|
198
|
+
const availableCommands = this.getCommandsForActiveModes();
|
|
199
|
+
const command = availableCommands.find((cmd) => cmd.name === commandName);
|
|
163
200
|
|
|
164
201
|
if (command) {
|
|
165
|
-
await command.handler(args);
|
|
166
|
-
|
|
202
|
+
const result = await command.handler(args);
|
|
203
|
+
|
|
204
|
+
// If handler returns a CommandResult and it's not handled, pass to modules
|
|
205
|
+
if (result && typeof result === "object" && "handled" in result) {
|
|
206
|
+
if (result.handled) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
// Not handled, use contents if provided or original input
|
|
210
|
+
input = result.contents || input;
|
|
211
|
+
} else {
|
|
212
|
+
// Old-style void handler, consider it handled
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
167
215
|
}
|
|
168
216
|
}
|
|
169
217
|
|
|
@@ -198,7 +246,7 @@ export class CliChatService implements ChatService {
|
|
|
198
246
|
|
|
199
247
|
async getInput(
|
|
200
248
|
prompt: string = "> ",
|
|
201
|
-
options: string[] = []
|
|
249
|
+
options: string[] = []
|
|
202
250
|
): Promise<string> {
|
|
203
251
|
if (this.context.inputMethod) {
|
|
204
252
|
return await this.context.inputMethod.getInput(prompt);
|
|
@@ -264,8 +312,9 @@ export class CliChatService implements ChatService {
|
|
|
264
312
|
|
|
265
313
|
async startChatLoop(): Promise<void> {
|
|
266
314
|
// Display available commands like the original
|
|
267
|
-
const
|
|
268
|
-
|
|
315
|
+
const availableCommands = this.getCommandsForActiveModes();
|
|
316
|
+
const commandNames = availableCommands.map((cmd) => `/${cmd.name}`);
|
|
317
|
+
console.log("Commands:", commandNames.join(", "));
|
|
269
318
|
|
|
270
319
|
while (true) {
|
|
271
320
|
const promptText =
|
|
@@ -274,10 +323,7 @@ export class CliChatService implements ChatService {
|
|
|
274
323
|
: `\nAsk knowhow: `;
|
|
275
324
|
try {
|
|
276
325
|
// Pass command names as autocomplete options
|
|
277
|
-
const input = await this.getInput(
|
|
278
|
-
promptText,
|
|
279
|
-
commandNames,
|
|
280
|
-
);
|
|
326
|
+
const input = await this.getInput(promptText, commandNames);
|
|
281
327
|
|
|
282
328
|
if (input.trim() === "") {
|
|
283
329
|
continue;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Agent Chat Module - Handles agent interactions
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
AgentSyncKnowhowWeb,
|
|
6
|
+
AgentSyncFs,
|
|
6
7
|
SessionManager,
|
|
7
8
|
TaskRegistry,
|
|
8
9
|
} from "../../services/index";
|
|
@@ -35,13 +36,15 @@ export class AgentModule extends BaseChatModule {
|
|
|
35
36
|
// Service instances for task management, session management, and synchronization
|
|
36
37
|
private taskRegistry: TaskRegistry;
|
|
37
38
|
private sessionManager: SessionManager;
|
|
38
|
-
private
|
|
39
|
+
private webSync: AgentSyncKnowhowWeb;
|
|
40
|
+
private fsSync: AgentSyncFs;
|
|
39
41
|
|
|
40
42
|
constructor() {
|
|
41
43
|
super();
|
|
42
44
|
this.taskRegistry = new TaskRegistry();
|
|
43
45
|
this.sessionManager = new SessionManager();
|
|
44
|
-
this.
|
|
46
|
+
this.webSync = new AgentSyncKnowhowWeb();
|
|
47
|
+
this.fsSync = new AgentSyncFs();
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
getCommands(): ChatCommand[] {
|
|
@@ -95,6 +98,7 @@ export class AgentModule extends BaseChatModule {
|
|
|
95
98
|
context.agentMode = false;
|
|
96
99
|
context.selectedAgent = undefined;
|
|
97
100
|
context.currentAgent = undefined;
|
|
101
|
+
this.chatService.disableMode("agent");
|
|
98
102
|
}
|
|
99
103
|
console.log("Agent mode disabled. Switched to chat mode.");
|
|
100
104
|
return;
|
|
@@ -122,7 +126,9 @@ export class AgentModule extends BaseChatModule {
|
|
|
122
126
|
// so /model and /provider commands show accurate information
|
|
123
127
|
context.currentModel = selectedAgent.getModel();
|
|
124
128
|
context.currentProvider = selectedAgent.getProvider();
|
|
129
|
+
this.chatService.setMode("agent");
|
|
125
130
|
}
|
|
131
|
+
|
|
126
132
|
console.log(
|
|
127
133
|
`Agent mode enabled. Selected agent: ${agentName}. Type your task to get started.`
|
|
128
134
|
);
|
|
@@ -399,7 +405,7 @@ Please continue from where you left off and complete the original request.
|
|
|
399
405
|
`;
|
|
400
406
|
|
|
401
407
|
console.log("🚀 Session resuming...");
|
|
402
|
-
const context = this.chatService?.getContext()
|
|
408
|
+
const context = this.chatService?.getContext();
|
|
403
409
|
const allAgents = agents();
|
|
404
410
|
const selectedAgent =
|
|
405
411
|
allAgents[session.agentName] || allAgents[context.currentAgent];
|
|
@@ -462,6 +468,7 @@ Please continue from where you left off and complete the original request.
|
|
|
462
468
|
agentName: string;
|
|
463
469
|
input: string;
|
|
464
470
|
messageId?: string;
|
|
471
|
+
syncFs?: boolean;
|
|
465
472
|
existingKnowhowTaskId?: string;
|
|
466
473
|
provider?: string;
|
|
467
474
|
model?: string;
|
|
@@ -469,6 +476,7 @@ Please continue from where you left off and complete the original request.
|
|
|
469
476
|
maxSpendLimit?: number; // in dollars
|
|
470
477
|
chatHistory?: ChatInteraction[];
|
|
471
478
|
run?: boolean; // whether to run immediately
|
|
479
|
+
taskId?: string; // optional pre-generated taskId
|
|
472
480
|
}) {
|
|
473
481
|
const allAgents = agents();
|
|
474
482
|
|
|
@@ -485,7 +493,7 @@ Please continue from where you left off and complete the original request.
|
|
|
485
493
|
|
|
486
494
|
let done = false;
|
|
487
495
|
let output = "Done";
|
|
488
|
-
const taskId = this.sessionManager.generateTaskId(input);
|
|
496
|
+
const taskId = options.taskId || this.sessionManager.generateTaskId(input);
|
|
489
497
|
let knowhowTaskId: string | undefined;
|
|
490
498
|
|
|
491
499
|
try {
|
|
@@ -521,8 +529,12 @@ Please continue from where you left off and complete the original request.
|
|
|
521
529
|
this.saveSession(taskId, taskInfo, []);
|
|
522
530
|
|
|
523
531
|
// Create Knowhow chat task if messageId provided
|
|
524
|
-
if (
|
|
525
|
-
|
|
532
|
+
if (
|
|
533
|
+
options.messageId &&
|
|
534
|
+
!options.existingKnowhowTaskId &&
|
|
535
|
+
!options.syncFs
|
|
536
|
+
) {
|
|
537
|
+
knowhowTaskId = await this.webSync.createChatTask({
|
|
526
538
|
messageId: options.messageId,
|
|
527
539
|
prompt: input,
|
|
528
540
|
});
|
|
@@ -533,8 +545,24 @@ Please continue from where you left off and complete the original request.
|
|
|
533
545
|
this.taskRegistry.register(taskId, taskInfo);
|
|
534
546
|
|
|
535
547
|
// Set up event-based synchronization with Knowhow API
|
|
536
|
-
await this.
|
|
548
|
+
await this.webSync.setupAgentSync(agent, knowhowTaskId);
|
|
537
549
|
}
|
|
550
|
+
} else if (!options.messageId || options.syncFs) {
|
|
551
|
+
// Use filesystem sync when no messageId is provided or syncFs is explicitly enabled
|
|
552
|
+
console.log(
|
|
553
|
+
`📁 Using filesystem-based synchronization for task: ${taskId}`
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
const fsTaskId = await this.fsSync.createTask({
|
|
557
|
+
taskId,
|
|
558
|
+
prompt: input,
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
// Update TaskInfo with the fs sync info
|
|
562
|
+
taskInfo.knowhowTaskId = fsTaskId;
|
|
563
|
+
this.taskRegistry.register(taskId, taskInfo);
|
|
564
|
+
|
|
565
|
+
await this.fsSync.setupAgentSync(agent, fsTaskId);
|
|
538
566
|
}
|
|
539
567
|
|
|
540
568
|
// Set up session update listener
|
|
@@ -642,10 +670,15 @@ Please continue from where you left off and complete the original request.
|
|
|
642
670
|
|
|
643
671
|
// Wait for AgentSync to finish before resolving
|
|
644
672
|
if (knowhowTaskId) {
|
|
645
|
-
console.log(
|
|
646
|
-
|
|
647
|
-
|
|
673
|
+
console.log(
|
|
674
|
+
"🎯 [AgentModule] Waiting for web sync finalization..."
|
|
675
|
+
);
|
|
676
|
+
await this.webSync.waitForFinalization();
|
|
677
|
+
console.log("🎯 [AgentModule] Web sync finalization complete");
|
|
648
678
|
}
|
|
679
|
+
console.log("🎯 [AgentModule] Waiting for fs sync finalization...");
|
|
680
|
+
await this.fsSync.waitForFinalization();
|
|
681
|
+
console.log("🎯 [AgentModule] Fs sync finalization complete");
|
|
649
682
|
|
|
650
683
|
if (taskInfo) {
|
|
651
684
|
taskInfo.status = "completed";
|
|
@@ -778,7 +811,25 @@ Please continue from where you left off and complete the original request.
|
|
|
778
811
|
let agentFinalOutput: string | undefined;
|
|
779
812
|
|
|
780
813
|
// Define available commands
|
|
781
|
-
|
|
814
|
+
// Set mode to agent:attached so custom commands are available
|
|
815
|
+
if (this.chatService) {
|
|
816
|
+
this.chatService.setMode("agent:attached");
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// Get mode-specific commands for autocomplete
|
|
820
|
+
const modeCommands =
|
|
821
|
+
this.chatService
|
|
822
|
+
?.getCommandsForMode("agent:attached")
|
|
823
|
+
.map((cmd) => `/${cmd.name}`) || [];
|
|
824
|
+
|
|
825
|
+
const commands = [
|
|
826
|
+
...modeCommands,
|
|
827
|
+
"/pause",
|
|
828
|
+
"/unpause",
|
|
829
|
+
"/kill",
|
|
830
|
+
"/detach",
|
|
831
|
+
"/done",
|
|
832
|
+
];
|
|
782
833
|
const history: string[] = [];
|
|
783
834
|
|
|
784
835
|
// Set up the event listener BEFORE starting the agent to avoid race condition
|
|
@@ -836,6 +887,10 @@ Please continue from where you left off and complete the original request.
|
|
|
836
887
|
break;
|
|
837
888
|
case "/detach":
|
|
838
889
|
console.log("Detached from agent");
|
|
890
|
+
// Reset mode back to default when detaching
|
|
891
|
+
if (this.chatService) {
|
|
892
|
+
this.chatService.setMode("default");
|
|
893
|
+
}
|
|
839
894
|
return { result: true, finalOutput: agentFinalOutput };
|
|
840
895
|
default:
|
|
841
896
|
agent.addPendingUserMessage({
|
|
@@ -852,6 +907,11 @@ Please continue from where you left off and complete the original request.
|
|
|
852
907
|
}
|
|
853
908
|
}
|
|
854
909
|
|
|
910
|
+
// Reset mode back to default when exiting loop
|
|
911
|
+
if (this.chatService) {
|
|
912
|
+
this.chatService.setMode("default");
|
|
913
|
+
}
|
|
914
|
+
|
|
855
915
|
// Update final task status and save session
|
|
856
916
|
const finalTaskInfo = this.taskRegistry.get(taskId);
|
|
857
917
|
if (finalTaskInfo) {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { BaseChatModule } from "./BaseChatModule";
|
|
2
|
+
import { ChatCommand, ChatService, CommandResult } from "../types";
|
|
3
|
+
import { getLanguageConfig } from "../../config";
|
|
4
|
+
import { services } from "../../services";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CustomCommandsModule - Loads `/command`-style keys from the language config
|
|
8
|
+
* and registers them as chat commands. When invoked, the resolved language
|
|
9
|
+
* sources are sent to the active agent via addPendingUserMessage.
|
|
10
|
+
*/
|
|
11
|
+
export class CustomCommandsModule extends BaseChatModule {
|
|
12
|
+
name = "custom-commands";
|
|
13
|
+
description =
|
|
14
|
+
"Dynamically registered commands from language config /command keys";
|
|
15
|
+
|
|
16
|
+
public getCommands(): ChatCommand[] {
|
|
17
|
+
// Commands are loaded asynchronously; return empty here and register dynamically in initialize
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getPlugins() {
|
|
22
|
+
return this.chatService.getTools()?.getContext()?.Plugins;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async initialize(service: ChatService): Promise<void> {
|
|
26
|
+
this.chatService = service;
|
|
27
|
+
|
|
28
|
+
// Load language config and register /command-style keys
|
|
29
|
+
try {
|
|
30
|
+
const languageConfig = await getLanguageConfig();
|
|
31
|
+
const commandKeys = Object.keys(languageConfig).filter((key) =>
|
|
32
|
+
key.trim().startsWith("/")
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
for (const commandKey of commandKeys) {
|
|
36
|
+
// Strip the leading slash to get the command name
|
|
37
|
+
const commandName = commandKey.trim().slice(1);
|
|
38
|
+
|
|
39
|
+
console.log(
|
|
40
|
+
`CUSTOM-COMMANDS: Registering command /${commandName} from language config`
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const command: ChatCommand = {
|
|
44
|
+
name: commandName,
|
|
45
|
+
description: `Custom command: ${commandKey}`,
|
|
46
|
+
modes: ["agent:attached", "agent"],
|
|
47
|
+
handler: async (args: string[]): Promise<CommandResult> => {
|
|
48
|
+
const config = languageConfig[commandKey];
|
|
49
|
+
const result = await this.getPlugins().call("language", commandKey);
|
|
50
|
+
|
|
51
|
+
// If handled is true, call the language plugin and display output but don't send to agent
|
|
52
|
+
if (config.handled === true) {
|
|
53
|
+
try {
|
|
54
|
+
console.log(result);
|
|
55
|
+
return {
|
|
56
|
+
handled: true,
|
|
57
|
+
contents: result,
|
|
58
|
+
};
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(`Error executing command ${commandKey}:`, error);
|
|
61
|
+
return { handled: true };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// By default (handled: false or undefined), return unhandled so agent module processes it
|
|
66
|
+
return {
|
|
67
|
+
handled: false,
|
|
68
|
+
contents: commandKey + " => " + result,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
this.chatService.registerCommand(command);
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error("CUSTOM-COMMANDS: Error loading language config:", error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -7,6 +7,8 @@ import { SearchModule } from "./SearchModule";
|
|
|
7
7
|
import { VoiceModule } from "./VoiceModule";
|
|
8
8
|
import { SystemModule } from "./SystemModule";
|
|
9
9
|
import { SetupModule } from "./SetupModule";
|
|
10
|
+
import { CustomCommandsModule } from "./CustomCommandsModule";
|
|
11
|
+
import { ShellCommandModule } from "./ShellCommandModule";
|
|
10
12
|
|
|
11
13
|
export class InternalChatModule implements ChatModule {
|
|
12
14
|
private chatService?: CliChatService;
|
|
@@ -20,6 +22,8 @@ export class InternalChatModule implements ChatModule {
|
|
|
20
22
|
private voiceModule = new VoiceModule();
|
|
21
23
|
private systemModule = new SystemModule();
|
|
22
24
|
private setupModule = new SetupModule();
|
|
25
|
+
private customCommandsModule = new CustomCommandsModule();
|
|
26
|
+
private shellCommandModule = new ShellCommandModule();
|
|
23
27
|
|
|
24
28
|
async initialize(chatService: CliChatService): Promise<void> {
|
|
25
29
|
this.chatService = chatService;
|
|
@@ -34,7 +38,9 @@ export class InternalChatModule implements ChatModule {
|
|
|
34
38
|
await this.voiceModule.initialize(chatService);
|
|
35
39
|
await this.systemModule.initialize(chatService);
|
|
36
40
|
await this.setupModule.initialize(chatService);
|
|
37
|
-
|
|
41
|
+
await this.customCommandsModule.initialize(chatService);
|
|
42
|
+
await this.shellCommandModule.initialize(chatService);
|
|
43
|
+
|
|
38
44
|
// Register our own commands (exit and multi) - not duplicated by BaseChatModule
|
|
39
45
|
chatService.registerCommand({
|
|
40
46
|
name: "exit",
|
|
@@ -62,6 +68,8 @@ export class InternalChatModule implements ChatModule {
|
|
|
62
68
|
...this.voiceModule.getCommands(),
|
|
63
69
|
...this.systemModule.getCommands(),
|
|
64
70
|
...this.setupModule.getCommands(),
|
|
71
|
+
...this.customCommandsModule.getCommands(),
|
|
72
|
+
...this.shellCommandModule.getCommands(),
|
|
65
73
|
{
|
|
66
74
|
name: "exit",
|
|
67
75
|
description: "Exit the chat",
|
|
@@ -84,6 +92,8 @@ export class InternalChatModule implements ChatModule {
|
|
|
84
92
|
...this.voiceModule.getModes(),
|
|
85
93
|
...this.systemModule.getModes(),
|
|
86
94
|
...this.setupModule.getModes(),
|
|
95
|
+
...this.customCommandsModule.getModes(),
|
|
96
|
+
...this.shellCommandModule.getModes(),
|
|
87
97
|
];
|
|
88
98
|
}
|
|
89
99
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { BaseChatModule } from "./BaseChatModule";
|
|
2
|
+
import { ChatCommand, ChatContext, CommandResult } from "../types";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ShellCommandModule - Handles /! and /!! commands for executing shell commands
|
|
7
|
+
* /! - Execute command and display output in console (interactive if needed)
|
|
8
|
+
* /!! - Execute command and send output to the AI agent
|
|
9
|
+
*/
|
|
10
|
+
export class ShellCommandModule extends BaseChatModule {
|
|
11
|
+
name = "shell-command";
|
|
12
|
+
description = "Execute shell commands with /! and /!!";
|
|
13
|
+
|
|
14
|
+
public getCommands(): ChatCommand[] {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
name: "!",
|
|
18
|
+
description: "Execute a shell command (interactive)",
|
|
19
|
+
modes: ["agent", "agent:attached"],
|
|
20
|
+
handler: async (args: string[]): Promise<CommandResult> => {
|
|
21
|
+
const command = args.join(" ");
|
|
22
|
+
if (!command) {
|
|
23
|
+
console.log("Usage: /! <command>");
|
|
24
|
+
return { handled: true };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
console.log(`Executing: ${command}`);
|
|
29
|
+
// Execute the command and inherit stdio for interactivity
|
|
30
|
+
const result = execSync(command, {
|
|
31
|
+
encoding: "utf8",
|
|
32
|
+
stdio: "inherit",
|
|
33
|
+
cwd: process.cwd(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return { handled: true };
|
|
37
|
+
} catch (error: any) {
|
|
38
|
+
console.error(`Command failed: ${error.message}`);
|
|
39
|
+
if (error.stderr) {
|
|
40
|
+
console.error(error.stderr);
|
|
41
|
+
}
|
|
42
|
+
return { handled: true };
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "!!",
|
|
48
|
+
description: "Execute a shell command and send output to AI",
|
|
49
|
+
modes: ["agent", "agent:attached"],
|
|
50
|
+
handler: async (args: string[]): Promise<CommandResult> => {
|
|
51
|
+
const command = args.join(" ");
|
|
52
|
+
if (!command) {
|
|
53
|
+
console.log("Usage: /!! <command>");
|
|
54
|
+
return { handled: true };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
console.log(`Executing: ${command}`);
|
|
59
|
+
const result = execSync(command, {
|
|
60
|
+
encoding: "utf8",
|
|
61
|
+
cwd: process.cwd(),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
console.log(result);
|
|
65
|
+
|
|
66
|
+
// Return unhandled with the command output so it gets sent to the agent
|
|
67
|
+
return {
|
|
68
|
+
handled: false,
|
|
69
|
+
contents: `Command output from \`${command}\`:\n\`\`\`\n${result}\n\`\`\``,
|
|
70
|
+
};
|
|
71
|
+
} catch (error: any) {
|
|
72
|
+
const errorMessage = error.message;
|
|
73
|
+
const stderr = error.stderr || "";
|
|
74
|
+
const stdout = error.stdout || "";
|
|
75
|
+
|
|
76
|
+
console.error(`Command failed: ${errorMessage}`);
|
|
77
|
+
if (stderr) {
|
|
78
|
+
console.error(stderr);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Send error output to agent as well
|
|
82
|
+
return {
|
|
83
|
+
handled: false,
|
|
84
|
+
contents: `Command \`${command}\` failed:\n\`\`\`\n${stdout}\n${stderr}\n${errorMessage}\n\`\`\``,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async handleInput(input: string, context: ChatContext): Promise<boolean> {
|
|
93
|
+
// This module only handles commands registered above
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/chat/types.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core Types for Modular Chat System
|
|
3
3
|
*/
|
|
4
|
-
import { ChatInteraction } from "../types";
|
|
4
|
+
import { ChatInteraction, Config } from "../types";
|
|
5
5
|
import { BaseAgent } from "../agents/base/base";
|
|
6
|
+
import { ToolsService } from "src/services";
|
|
6
7
|
|
|
7
8
|
export interface ChatContext {
|
|
8
9
|
debugMode?: boolean;
|
|
@@ -15,6 +16,8 @@ export interface ChatContext {
|
|
|
15
16
|
currentProvider?: string;
|
|
16
17
|
inputMethod?: InputMethod;
|
|
17
18
|
selectedAgent?: BaseAgent;
|
|
19
|
+
plugins: string[];
|
|
20
|
+
|
|
18
21
|
[key: string]: any;
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -24,10 +27,16 @@ export interface ChatMode {
|
|
|
24
27
|
active: boolean;
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
export interface CommandResult {
|
|
31
|
+
handled: boolean;
|
|
32
|
+
contents?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
export interface ChatCommand {
|
|
28
36
|
name: string;
|
|
29
37
|
description: string;
|
|
30
|
-
handler: (args: string[]) => Promise<void>;
|
|
38
|
+
handler: (args: string[]) => Promise<void | CommandResult>;
|
|
39
|
+
modes?: string[]; // Commands can specify which modes they're available in
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
export interface InputMethod {
|
|
@@ -38,12 +47,15 @@ export interface InputMethod {
|
|
|
38
47
|
|
|
39
48
|
export interface ChatService {
|
|
40
49
|
getContext(): ChatContext;
|
|
50
|
+
getTools(): ToolsService | undefined;
|
|
41
51
|
setContext(context: Partial<ChatContext>): void;
|
|
42
52
|
setInputMethod(method: InputMethod): void;
|
|
43
53
|
resetInputMethod(): void;
|
|
44
54
|
registerCommand(command: ChatCommand): void;
|
|
45
55
|
registerMode(mode: ChatMode): void;
|
|
46
56
|
getCommands(): ChatCommand[];
|
|
57
|
+
getCommandsForMode(mode: string): ChatCommand[];
|
|
58
|
+
setMode(mode: string): void;
|
|
47
59
|
getModes(): ChatMode[];
|
|
48
60
|
getMode(name: string): ChatMode | undefined;
|
|
49
61
|
enableMode(name: string): void;
|
package/src/chat.ts
CHANGED
|
@@ -20,23 +20,26 @@ async function main() {
|
|
|
20
20
|
configError
|
|
21
21
|
);
|
|
22
22
|
config = {
|
|
23
|
-
plugins:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
plugins: {
|
|
24
|
+
enabled: [
|
|
25
|
+
"embeddings",
|
|
26
|
+
"language",
|
|
27
|
+
"vim",
|
|
28
|
+
"github",
|
|
29
|
+
"asana",
|
|
30
|
+
"jira",
|
|
31
|
+
"linear",
|
|
32
|
+
"download",
|
|
33
|
+
"figma",
|
|
34
|
+
"url",
|
|
35
|
+
],
|
|
36
|
+
disabled: [],
|
|
37
|
+
},
|
|
35
38
|
};
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
// Create chat service with plugins
|
|
39
|
-
const chatService = new CliChatService(config.plugins);
|
|
42
|
+
const chatService = new CliChatService(config.plugins.enabled);
|
|
40
43
|
|
|
41
44
|
// Load internal chat module (includes all core functionality)
|
|
42
45
|
const internalModule = new InternalChatModule();
|