@tyvm/knowhow 0.0.57 → 0.0.60
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/package.json +3 -3
- package/src/agents/base/base.ts +87 -43
- package/src/agents/tools/execCommand.ts +17 -14
- package/src/agents/tools/googleSearch.ts +1 -0
- package/src/agents/tools/index.ts +1 -0
- package/src/agents/tools/lazy/definitions.ts +65 -0
- package/src/agents/tools/lazy/disableTools.ts +16 -0
- package/src/agents/tools/lazy/enableTools.ts +16 -0
- package/src/agents/tools/lazy/index.ts +3 -0
- package/src/agents/tools/lazy/listAvailableTools.ts +14 -0
- package/src/agents/tools/list.ts +2 -0
- package/src/agents/tools/mcp/connectMcpServer.ts +40 -0
- package/src/agents/tools/mcp/definitions.ts +67 -0
- package/src/agents/tools/mcp/disconnectMcpServer.ts +40 -0
- package/src/agents/tools/mcp/index.ts +3 -0
- package/src/agents/tools/mcp/listAvailableMcpServers.ts +28 -0
- package/src/agents/tools/writeFile.ts +4 -1
- package/src/chat/CliChatService.ts +8 -3
- package/src/chat/modules/AgentModule.ts +74 -296
- package/src/cli.ts +33 -10
- package/src/plugins/GitPlugin.ts +30 -24
- package/src/plugins/language.ts +95 -18
- package/src/processors/ToolResponseCache.ts +98 -79
- package/src/processors/tools/grepToolResponse.ts +99 -0
- package/src/processors/tools/index.ts +21 -0
- package/src/processors/tools/jqToolResponse.ts +124 -0
- package/src/processors/tools/listStoredToolResponses.ts +83 -0
- package/src/processors/tools/tailToolResponse.ts +75 -0
- package/src/services/AgentService.ts +1 -1
- package/src/services/AgentSynchronization.ts +291 -0
- package/src/services/EventService.ts +8 -2
- package/src/services/KnowhowClient.ts +141 -1
- package/src/services/LazyToolsService.ts +142 -0
- package/src/services/Mcp.ts +171 -4
- package/src/services/SessionManager.ts +287 -0
- package/src/services/TaskRegistry.ts +108 -0
- package/src/services/Tools.ts +2 -0
- package/src/services/index.ts +7 -0
- package/src/services/script-execution/ScriptExecutor.ts +7 -5
- package/src/types.ts +1 -0
- package/src/utils/InputQueueManager.ts +91 -57
- package/src/utils/errors.ts +0 -0
- package/src/utils/index.ts +11 -0
- package/tests/compressor/bigstring.test.ts +100 -0
- package/tests/compressor/bigstring.txt +1 -0
- package/tests/plugins/language/languagePlugin-content-triggers.test.ts +13 -5
- package/tests/plugins/language/languagePlugin-integration.test.ts +22 -7
- package/tests/plugins/language/languagePlugin.test.ts +11 -4
- package/tests/processors/ToolResponseCache.test.ts +128 -0
- package/tests/unit/InputQueueManager.test.ts +174 -0
- package/ts_build/package.json +3 -3
- package/ts_build/src/agents/base/base.d.ts +10 -0
- package/ts_build/src/agents/base/base.js +66 -34
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/tools/execCommand.js +1 -9
- package/ts_build/src/agents/tools/execCommand.js.map +1 -1
- package/ts_build/src/agents/tools/github/index.d.ts +1 -1
- package/ts_build/src/agents/tools/googleSearch.d.ts +1 -0
- package/ts_build/src/agents/tools/googleSearch.js +1 -0
- package/ts_build/src/agents/tools/googleSearch.js.map +1 -1
- package/ts_build/src/agents/tools/index.d.ts +1 -0
- package/ts_build/src/agents/tools/index.js +1 -0
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/lazy/definitions.d.ts +5 -0
- package/ts_build/src/agents/tools/lazy/definitions.js +60 -0
- package/ts_build/src/agents/tools/lazy/definitions.js.map +1 -0
- package/ts_build/src/agents/tools/lazy/disableTools.d.ts +9 -0
- package/ts_build/src/agents/tools/lazy/disableTools.js +15 -0
- package/ts_build/src/agents/tools/lazy/disableTools.js.map +1 -0
- package/ts_build/src/agents/tools/lazy/enableTools.d.ts +9 -0
- package/ts_build/src/agents/tools/lazy/enableTools.js +15 -0
- package/ts_build/src/agents/tools/lazy/enableTools.js.map +1 -0
- package/ts_build/src/agents/tools/lazy/index.d.ts +3 -0
- package/ts_build/src/agents/tools/lazy/index.js +20 -0
- package/ts_build/src/agents/tools/lazy/index.js.map +1 -0
- package/ts_build/src/agents/tools/lazy/listAvailableTools.d.ts +11 -0
- package/ts_build/src/agents/tools/lazy/listAvailableTools.js +15 -0
- package/ts_build/src/agents/tools/lazy/listAvailableTools.js.map +1 -0
- package/ts_build/src/agents/tools/list.js +2 -0
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/agents/tools/mcp/connectMcpServer.d.ts +5 -0
- package/ts_build/src/agents/tools/mcp/connectMcpServer.js +31 -0
- package/ts_build/src/agents/tools/mcp/connectMcpServer.js.map +1 -0
- package/ts_build/src/agents/tools/mcp/definitions.d.ts +2 -0
- package/ts_build/src/agents/tools/mcp/definitions.js +62 -0
- package/ts_build/src/agents/tools/mcp/definitions.js.map +1 -0
- package/ts_build/src/agents/tools/mcp/disconnectMcpServer.d.ts +5 -0
- package/ts_build/src/agents/tools/mcp/disconnectMcpServer.js +31 -0
- package/ts_build/src/agents/tools/mcp/disconnectMcpServer.js.map +1 -0
- package/ts_build/src/agents/tools/mcp/index.d.ts +3 -0
- package/ts_build/src/agents/tools/mcp/index.js +10 -0
- package/ts_build/src/agents/tools/mcp/index.js.map +1 -0
- package/ts_build/src/agents/tools/mcp/listAvailableMcpServers.d.ts +14 -0
- package/ts_build/src/agents/tools/mcp/listAvailableMcpServers.js +23 -0
- package/ts_build/src/agents/tools/mcp/listAvailableMcpServers.js.map +1 -0
- package/ts_build/src/agents/tools/writeFile.js +4 -1
- package/ts_build/src/agents/tools/writeFile.js.map +1 -1
- package/ts_build/src/chat/CliChatService.js +3 -1
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.d.ts +4 -3
- package/ts_build/src/chat/modules/AgentModule.js +71 -265
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/cli.d.ts +1 -1
- package/ts_build/src/cli.js +17 -4
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/plugins/GitPlugin.d.ts +1 -0
- package/ts_build/src/plugins/GitPlugin.js +26 -19
- package/ts_build/src/plugins/GitPlugin.js.map +1 -1
- package/ts_build/src/plugins/language.d.ts +3 -0
- package/ts_build/src/plugins/language.js +55 -13
- package/ts_build/src/plugins/language.js.map +1 -1
- package/ts_build/src/processors/ToolResponseCache.d.ts +7 -4
- package/ts_build/src/processors/ToolResponseCache.js +47 -88
- package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
- package/ts_build/src/processors/tools/grepToolResponse.d.ts +10 -0
- package/ts_build/src/processors/tools/grepToolResponse.js +71 -0
- package/ts_build/src/processors/tools/grepToolResponse.js.map +1 -0
- package/ts_build/src/processors/tools/index.d.ts +4 -0
- package/ts_build/src/processors/tools/index.js +16 -0
- package/ts_build/src/processors/tools/index.js.map +1 -0
- package/ts_build/src/processors/tools/jqToolResponse.d.ts +3 -0
- package/ts_build/src/processors/tools/jqToolResponse.js +115 -0
- package/ts_build/src/processors/tools/jqToolResponse.js.map +1 -0
- package/ts_build/src/processors/tools/listStoredToolResponses.d.ts +21 -0
- package/ts_build/src/processors/tools/listStoredToolResponses.js +51 -0
- package/ts_build/src/processors/tools/listStoredToolResponses.js.map +1 -0
- package/ts_build/src/processors/tools/tailToolResponse.d.ts +6 -0
- package/ts_build/src/processors/tools/tailToolResponse.js +55 -0
- package/ts_build/src/processors/tools/tailToolResponse.js.map +1 -0
- package/ts_build/src/services/AgentService.d.ts +1 -1
- package/ts_build/src/services/AgentSynchronization.d.ts +27 -0
- package/ts_build/src/services/AgentSynchronization.js +168 -0
- package/ts_build/src/services/AgentSynchronization.js.map +1 -0
- package/ts_build/src/services/EventService.d.ts +5 -0
- package/ts_build/src/services/EventService.js +7 -2
- package/ts_build/src/services/EventService.js.map +1 -1
- package/ts_build/src/services/KnowhowClient.d.ts +41 -1
- package/ts_build/src/services/KnowhowClient.js +42 -0
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/LazyToolsService.d.ts +29 -0
- package/ts_build/src/services/LazyToolsService.js +94 -0
- package/ts_build/src/services/LazyToolsService.js.map +1 -0
- package/ts_build/src/services/Mcp.d.ts +18 -1
- package/ts_build/src/services/Mcp.js +119 -4
- package/ts_build/src/services/Mcp.js.map +1 -1
- package/ts_build/src/services/SessionManager.d.ts +15 -0
- package/ts_build/src/services/SessionManager.js +220 -0
- package/ts_build/src/services/SessionManager.js.map +1 -0
- package/ts_build/src/services/TaskRegistry.d.ts +15 -0
- package/ts_build/src/services/TaskRegistry.js +58 -0
- package/ts_build/src/services/TaskRegistry.js.map +1 -0
- package/ts_build/src/services/Tools.d.ts +2 -0
- package/ts_build/src/services/Tools.js.map +1 -1
- package/ts_build/src/services/index.d.ts +4 -0
- package/ts_build/src/services/index.js +4 -0
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/script-execution/ScriptExecutor.js +7 -5
- package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
- package/ts_build/src/types.d.ts +1 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/utils/InputQueueManager.d.ts +9 -2
- package/ts_build/src/utils/InputQueueManager.js +54 -40
- package/ts_build/src/utils/InputQueueManager.js.map +1 -1
- package/ts_build/src/utils/errors.d.ts +0 -0
- package/ts_build/src/utils/errors.js +1 -0
- package/ts_build/src/utils/errors.js.map +1 -0
- package/ts_build/src/utils/index.d.ts +1 -0
- package/ts_build/src/utils/index.js +5 -1
- package/ts_build/src/utils/index.js.map +1 -1
- package/ts_build/tests/compressor/bigstring.test.d.ts +1 -0
- package/ts_build/tests/compressor/bigstring.test.js +66 -0
- package/ts_build/tests/compressor/bigstring.test.js.map +1 -0
- package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +6 -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 +9 -7
- package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -1
- package/ts_build/tests/plugins/language/languagePlugin.test.js +7 -4
- package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
- package/ts_build/tests/processors/ToolResponseCache.test.js +107 -0
- package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
- package/ts_build/tests/unit/InputQueueManager.test.d.ts +1 -0
- package/ts_build/tests/unit/InputQueueManager.test.js +104 -0
- package/ts_build/tests/unit/InputQueueManager.test.js.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tyvm/knowhow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.60",
|
|
4
4
|
"description": "ai cli with plugins and agents",
|
|
5
5
|
"main": "ts_build/src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"test": "jest --testTimeout 300000",
|
|
11
11
|
"test:debug": "node --inspect-brk ../../node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --testTimeout 300000",
|
|
12
12
|
"compile": "tsc",
|
|
13
|
-
"start": "npm run compile && node ts_build/src/server/index.js",
|
|
13
|
+
"start": "npm run compile && node --no-node-snapshot ts_build/src/server/index.js",
|
|
14
14
|
"dataset:diffs:generate": "ts-node src/dataset/diffs/generate.ts",
|
|
15
15
|
"dataset:diffs:jsonl": "ts-node src/dataset/diffs/jsonl.ts",
|
|
16
16
|
"prepublishOnly": "npm run compile",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"jira-client": "^8.2.2",
|
|
63
63
|
"marked": "^10.0.0",
|
|
64
64
|
"marked-terminal": "^6.2.0",
|
|
65
|
-
"minimatch": "^10.
|
|
65
|
+
"minimatch": "^10.1.2",
|
|
66
66
|
"morgan": "^1.10.0",
|
|
67
67
|
"node-fetch": "^3.2.3",
|
|
68
68
|
"node-jq": "^6.0.1",
|
package/src/agents/base/base.ts
CHANGED
|
@@ -41,7 +41,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
41
41
|
abstract name: string;
|
|
42
42
|
abstract description: string;
|
|
43
43
|
|
|
44
|
-
private status = "
|
|
44
|
+
private status = "not_started";
|
|
45
45
|
private lastHealthCheckTime: number = 0;
|
|
46
46
|
protected provider = "openai";
|
|
47
47
|
protected modelName: string = Models.openai.GPT_4o;
|
|
@@ -70,11 +70,19 @@ export abstract class BaseAgent implements IAgent {
|
|
|
70
70
|
costUpdate: "cost_update",
|
|
71
71
|
toolCall: "tool:pre_call",
|
|
72
72
|
toolUsed: "tool:post_call",
|
|
73
|
+
notStarted: "not_started",
|
|
74
|
+
inProgress: "in_progress",
|
|
73
75
|
done: "done",
|
|
74
76
|
pause: "pause",
|
|
75
77
|
kill: "kill",
|
|
76
78
|
unpause: "unpause",
|
|
79
|
+
agentMsg: "agent:msg",
|
|
80
|
+
userSay: "user:say",
|
|
81
|
+
agentSay: "agent:say",
|
|
82
|
+
agentNewTask: "agent:newTask",
|
|
83
|
+
agentTaskComplete: "agent:taskComplete",
|
|
77
84
|
};
|
|
85
|
+
|
|
78
86
|
public tools: ToolsService;
|
|
79
87
|
public events: EventService;
|
|
80
88
|
public messageProcessor: MessageProcessor;
|
|
@@ -97,12 +105,17 @@ export abstract class BaseAgent implements IAgent {
|
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
// Subscribe to "agent:msg" events for dynamic context loading
|
|
100
|
-
this.events.on(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
this.events.on(this.eventTypes.agentMsg, (eventData: any) => {
|
|
109
|
+
if (
|
|
110
|
+
this.status === this.eventTypes.inProgress ||
|
|
111
|
+
this.status === this.eventTypes.pause
|
|
112
|
+
) {
|
|
113
|
+
const message = {
|
|
114
|
+
role: "user",
|
|
115
|
+
content: JSON.stringify(eventData),
|
|
116
|
+
} as Message;
|
|
117
|
+
this.addPendingMessage(message);
|
|
118
|
+
}
|
|
106
119
|
});
|
|
107
120
|
}
|
|
108
121
|
|
|
@@ -124,14 +137,14 @@ export abstract class BaseAgent implements IAgent {
|
|
|
124
137
|
this.taskBreakdown = "";
|
|
125
138
|
this.summaries = [];
|
|
126
139
|
this.totalCostUsd = 0;
|
|
127
|
-
this.status =
|
|
140
|
+
this.status = this.eventTypes.inProgress;
|
|
128
141
|
this.turnCount = 0;
|
|
129
142
|
this.startTimeMs = Date.now();
|
|
130
143
|
this.currentTaskId = taskId || this.startTimeMs.toString();
|
|
131
144
|
|
|
132
145
|
// Emit event for plugin integration
|
|
133
146
|
const id = taskId || this.startTimeMs.toString();
|
|
134
|
-
this.events.emit(
|
|
147
|
+
this.events.emit(this.eventTypes.agentNewTask, {
|
|
135
148
|
taskId: id,
|
|
136
149
|
});
|
|
137
150
|
}
|
|
@@ -319,6 +332,9 @@ export abstract class BaseAgent implements IAgent {
|
|
|
319
332
|
logMessages(messages: Message[]) {
|
|
320
333
|
for (const message of messages) {
|
|
321
334
|
if (message.role === "assistant" && message.content) {
|
|
335
|
+
this.agentEvents.emit(this.eventTypes.agentSay, {
|
|
336
|
+
message: message.content,
|
|
337
|
+
});
|
|
322
338
|
console.log("\n", "💬 " + message.content, "\n");
|
|
323
339
|
}
|
|
324
340
|
}
|
|
@@ -429,7 +445,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
429
445
|
unpause() {
|
|
430
446
|
console.log("Unpausing agent");
|
|
431
447
|
this.agentEvents.emit(this.eventTypes.unpause, this);
|
|
432
|
-
this.status =
|
|
448
|
+
this.status = this.eventTypes.inProgress;
|
|
433
449
|
}
|
|
434
450
|
|
|
435
451
|
async unpaused() {
|
|
@@ -457,6 +473,10 @@ export abstract class BaseAgent implements IAgent {
|
|
|
457
473
|
}
|
|
458
474
|
|
|
459
475
|
async call(userInput: string, _messages?: Message[]) {
|
|
476
|
+
if (this.status === this.eventTypes.notStarted) {
|
|
477
|
+
this.status = this.eventTypes.inProgress;
|
|
478
|
+
}
|
|
479
|
+
|
|
460
480
|
if (this.status === this.eventTypes.pause) {
|
|
461
481
|
await this.unpaused();
|
|
462
482
|
}
|
|
@@ -560,6 +580,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
560
580
|
"pre_tools"
|
|
561
581
|
);
|
|
562
582
|
|
|
583
|
+
this.updateCurrentThread(messages);
|
|
584
|
+
|
|
563
585
|
for (const toolCall of toolCalls) {
|
|
564
586
|
const toolMessages = await this.processToolMessages(toolCall);
|
|
565
587
|
// Add the tool responses to the thread
|
|
@@ -576,7 +598,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
576
598
|
|
|
577
599
|
if (finalMessage) {
|
|
578
600
|
// Emit task completion event for plugins (like GitPlugin)
|
|
579
|
-
this.events.emit(
|
|
601
|
+
this.events.emit(this.eventTypes.agentTaskComplete, {
|
|
580
602
|
taskId:
|
|
581
603
|
this.currentTaskId ||
|
|
582
604
|
this.startTimeMs?.toString() ||
|
|
@@ -654,41 +676,13 @@ export abstract class BaseAgent implements IAgent {
|
|
|
654
676
|
|
|
655
677
|
if (["assistant", "tool"].includes(messages[messages.length - 1].role)) {
|
|
656
678
|
// sometimes the agent just says a message and doesn't call a tool, or compression ends on a tool message
|
|
657
|
-
console.log(
|
|
658
|
-
"Agent continuing to the next iteration, reminding agent how to terminate"
|
|
659
|
-
);
|
|
660
|
-
|
|
661
|
-
const remainingTime =
|
|
662
|
-
this.maxRunTimeMs && this.startTimeMs
|
|
663
|
-
? this.maxRunTimeMs - (Date.now() - this.startTimeMs)
|
|
664
|
-
: null;
|
|
665
|
-
|
|
666
|
-
const remainingTurns = this.maxTurns
|
|
667
|
-
? this.maxTurns - this.turnCount
|
|
668
|
-
: null;
|
|
669
|
-
|
|
670
|
-
const timeRemainsingMsg = remainingTime
|
|
671
|
-
? `You have approximately ${Math.floor(
|
|
672
|
-
remainingTime / 1000
|
|
673
|
-
)} seconds remaining for this task. `
|
|
674
|
-
: "";
|
|
675
|
-
|
|
676
|
-
const turnsRemainingMsg = remainingTurns
|
|
677
|
-
? `You have ${remainingTurns} turns remaining. `
|
|
678
|
-
: "";
|
|
679
679
|
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
: null;
|
|
683
|
-
const budgetRemainingMsg = remainingBudget
|
|
684
|
-
? `You have $${remainingBudget.toFixed(4)} remaining in your budget.`
|
|
685
|
-
: "";
|
|
680
|
+
const statusMessage = this.getStatusMessage();
|
|
681
|
+
this.logStatus();
|
|
686
682
|
|
|
687
683
|
const continuation = `<Workflow>
|
|
688
684
|
workflow continues until you call one of ${this.requiredToolNames}.\n
|
|
689
|
-
${
|
|
690
|
-
${turnsRemainingMsg}
|
|
691
|
-
${budgetRemainingMsg}
|
|
685
|
+
${statusMessage}
|
|
692
686
|
</Workflow>`;
|
|
693
687
|
|
|
694
688
|
messages.push({
|
|
@@ -719,14 +713,64 @@ export abstract class BaseAgent implements IAgent {
|
|
|
719
713
|
}
|
|
720
714
|
}
|
|
721
715
|
|
|
722
|
-
|
|
716
|
+
getStatusMessage() {
|
|
717
|
+
const remainingTime =
|
|
718
|
+
this.maxRunTimeMs && this.startTimeMs
|
|
719
|
+
? this.maxRunTimeMs - (Date.now() - this.startTimeMs)
|
|
720
|
+
: null;
|
|
721
|
+
|
|
722
|
+
const remainingTurns = this.maxTurns
|
|
723
|
+
? this.maxTurns - this.turnCount
|
|
724
|
+
: null;
|
|
725
|
+
|
|
726
|
+
const timeRemainingMsg = remainingTime
|
|
727
|
+
? `You have approximately ${Math.floor(
|
|
728
|
+
remainingTime / 1000
|
|
729
|
+
)} seconds remaining for this task. `
|
|
730
|
+
: "";
|
|
731
|
+
|
|
732
|
+
const turnsRemainingMsg = remainingTurns
|
|
733
|
+
? `You have ${remainingTurns} turns remaining. `
|
|
734
|
+
: "";
|
|
735
|
+
|
|
736
|
+
const remainingBudget = this.maxSpend
|
|
737
|
+
? this.maxSpend - this.totalCostUsd
|
|
738
|
+
: null;
|
|
739
|
+
const budgetRemainingMsg = remainingBudget
|
|
740
|
+
? `You have $${remainingBudget.toFixed(4)} remaining in your budget.`
|
|
741
|
+
: "";
|
|
742
|
+
|
|
743
|
+
const statusMessage = `${timeRemainingMsg}\n${turnsRemainingMsg}\n${budgetRemainingMsg}`;
|
|
744
|
+
return statusMessage;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
logStatus() {
|
|
748
|
+
const statusMessage = this.getStatusMessage();
|
|
749
|
+
console.log(
|
|
750
|
+
`\n● ${this.name} status: $${this.getTotalCostUsd().toPrecision(
|
|
751
|
+
3
|
|
752
|
+
)}\n${statusMessage}`
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
addPendingMessage(message: Message) {
|
|
723
757
|
if (this.status === this.eventTypes.done) {
|
|
724
758
|
console.warn("Agent is done, cannot take more messages");
|
|
725
759
|
} else {
|
|
760
|
+
const pendingMessages = this.pendingUserMessages.map((m) => m.content);
|
|
761
|
+
if (pendingMessages.includes(message.content)) {
|
|
762
|
+
// Ignore messages we already have queue'd up
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
726
765
|
this.pendingUserMessages.push(message);
|
|
727
766
|
}
|
|
728
767
|
}
|
|
729
768
|
|
|
769
|
+
addPendingUserMessage(message: Message) {
|
|
770
|
+
this.addPendingMessage(message);
|
|
771
|
+
this.events.emit(this.eventTypes.userSay, message.content);
|
|
772
|
+
}
|
|
773
|
+
|
|
730
774
|
getMessagesLength(messages: Message[]) {
|
|
731
775
|
return JSON.stringify(messages).split(" ").length;
|
|
732
776
|
}
|
|
@@ -42,19 +42,19 @@ function commandNameFrom(cmd: string) {
|
|
|
42
42
|
|
|
43
43
|
function makeLogPath(cmd: string, customFileName?: string) {
|
|
44
44
|
// Use custom filename if provided, otherwise derive from command
|
|
45
|
-
let baseName = customFileName
|
|
45
|
+
let baseName = customFileName
|
|
46
46
|
? customFileName.replace(/[^\w.-]+/g, "_")
|
|
47
47
|
: commandNameFrom(cmd);
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
let logPath = path.join(PROCESSES_DIR, `${baseName}.txt`);
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
// If file already exists, append epoch seconds to ensure uniqueness
|
|
52
52
|
if (fs.existsSync(logPath)) {
|
|
53
53
|
const epochSeconds = Math.floor(Date.now() / 1000);
|
|
54
54
|
baseName = `${baseName}_${epochSeconds}`;
|
|
55
55
|
logPath = path.join(PROCESSES_DIR, `${baseName}.txt`);
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
return logPath;
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -282,15 +282,18 @@ export const execCommand = async (
|
|
|
282
282
|
: "";
|
|
283
283
|
|
|
284
284
|
const lines = output.split("\n");
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
285
|
+
/*
|
|
286
|
+
*const maxLines = 1000;
|
|
287
|
+
*const maxChars = 40000;
|
|
288
|
+
*const trimmed = (lines.length > maxLines ? lines.slice(0, maxLines) : lines)
|
|
289
|
+
* .join("\n")
|
|
290
|
+
* .slice(0, maxChars);
|
|
291
|
+
*const trimmedMsg =
|
|
292
|
+
* lines.length > maxLines
|
|
293
|
+
* ? ` (${lines.length - maxLines} results trimmed)`
|
|
294
|
+
* : "";
|
|
295
|
+
*/
|
|
294
296
|
|
|
295
|
-
return `$ ${command}${statusMsg}\n${trimmed}${trimmedMsg}`;
|
|
297
|
+
// return `$ ${command}${statusMsg}\n${trimmed}${trimmedMsg}`;
|
|
298
|
+
return `$ ${command}${statusMsg}\n${output}`;
|
|
296
299
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Tool } from "../../../clients/types";
|
|
2
|
+
|
|
3
|
+
export const listAvailableToolsDefinition: Tool = {
|
|
4
|
+
type: "function",
|
|
5
|
+
function: {
|
|
6
|
+
name: "listAvailableTools",
|
|
7
|
+
description:
|
|
8
|
+
"List all available tools in the system, showing which are currently enabled and disabled. Use this to discover what tools exist before enabling them.",
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object",
|
|
11
|
+
positional: true,
|
|
12
|
+
properties: {},
|
|
13
|
+
required: [],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const enableToolsDefinition: Tool = {
|
|
19
|
+
type: "function",
|
|
20
|
+
function: {
|
|
21
|
+
name: "enableTools",
|
|
22
|
+
description:
|
|
23
|
+
"Enable tools matching glob patterns. Examples: ['read*'] enables all tools starting with 'read', ['mcp_*_browser_*'] enables all browser MCP tools, ['*File'] enables all tools ending with 'File'. Pass an array of pattern strings.",
|
|
24
|
+
parameters: {
|
|
25
|
+
type: "object",
|
|
26
|
+
positional: true,
|
|
27
|
+
properties: {
|
|
28
|
+
patterns: {
|
|
29
|
+
type: "array",
|
|
30
|
+
items: { type: "string" },
|
|
31
|
+
description:
|
|
32
|
+
"Array of glob patterns to match tool names.",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
required: ["patterns"],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const disableToolsDefinition: Tool = {
|
|
41
|
+
type: "function",
|
|
42
|
+
function: {
|
|
43
|
+
name: "disableTools",
|
|
44
|
+
description:
|
|
45
|
+
"Disable tools matching glob patterns. This removes tools from the available tool list to stay within provider limits. Pass an array of pattern strings.",
|
|
46
|
+
parameters: {
|
|
47
|
+
type: "object",
|
|
48
|
+
positional: true,
|
|
49
|
+
properties: {
|
|
50
|
+
patterns: {
|
|
51
|
+
type: "array",
|
|
52
|
+
items: { type: "string" },
|
|
53
|
+
description: "Array of glob patterns to match tool names for disabling.",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: ["patterns"],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const definitions = [
|
|
62
|
+
listAvailableToolsDefinition,
|
|
63
|
+
enableToolsDefinition,
|
|
64
|
+
disableToolsDefinition,
|
|
65
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LazyToolsService } from "../../../services/LazyToolsService";
|
|
2
|
+
import { ToolsService } from "../../../services/Tools";
|
|
3
|
+
|
|
4
|
+
export async function disableTools(
|
|
5
|
+
this: ToolsService,
|
|
6
|
+
patterns: string[]
|
|
7
|
+
) {
|
|
8
|
+
if (!(this instanceof LazyToolsService)) {
|
|
9
|
+
return {
|
|
10
|
+
error: "This tool requires LazyToolsService",
|
|
11
|
+
message: "disableTools is only available when using LazyToolsService",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return this.disableTools(patterns);
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LazyToolsService } from "../../../services/LazyToolsService";
|
|
2
|
+
import { ToolsService } from "../../../services/Tools";
|
|
3
|
+
|
|
4
|
+
export async function enableTools(
|
|
5
|
+
this: ToolsService,
|
|
6
|
+
patterns: string[]
|
|
7
|
+
) {
|
|
8
|
+
if (!(this instanceof LazyToolsService)) {
|
|
9
|
+
return {
|
|
10
|
+
error: "This tool requires LazyToolsService",
|
|
11
|
+
message: "enableTools is only available when using LazyToolsService",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return this.enableTools(patterns);
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LazyToolsService } from "../../../services/LazyToolsService";
|
|
2
|
+
import { ToolsService } from "../../../services/Tools";
|
|
3
|
+
|
|
4
|
+
export async function listAvailableTools(this: ToolsService) {
|
|
5
|
+
if (!(this instanceof LazyToolsService)) {
|
|
6
|
+
return {
|
|
7
|
+
error: "This tool requires LazyToolsService",
|
|
8
|
+
message:
|
|
9
|
+
"listAvailableTools is only available when using LazyToolsService",
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return this.listAvailableTools();
|
|
14
|
+
}
|
package/src/agents/tools/list.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as github from "./github/definitions";
|
|
|
6
6
|
import * as asana from "./asana/definitions";
|
|
7
7
|
import * as ycmd from "./ycmd/definitions";
|
|
8
8
|
import * as language from "./language/definitions";
|
|
9
|
+
import * as mcp from "./mcp/definitions";
|
|
9
10
|
import { googleSearchDefinition } from "./googleSearch";
|
|
10
11
|
import { executeScriptDefinition } from "./executeScript/definition";
|
|
11
12
|
import { startAgentTaskDefinition } from "./startAgentTask";
|
|
@@ -795,4 +796,5 @@ export const includedTools = [
|
|
|
795
796
|
...ycmd.definitions,
|
|
796
797
|
...github.definitions,
|
|
797
798
|
...language.definitions,
|
|
799
|
+
...mcp.definitions,
|
|
798
800
|
] as Tool[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { services } from "../../../services";
|
|
2
|
+
import { McpService } from "../../../services/Mcp";
|
|
3
|
+
import { ToolsService } from "../../../services/Tools";
|
|
4
|
+
|
|
5
|
+
export async function connectMcpServer(
|
|
6
|
+
serverName: string,
|
|
7
|
+
timeout: number = 30000
|
|
8
|
+
) {
|
|
9
|
+
const toolService = (
|
|
10
|
+
this instanceof ToolsService ? this : services().Tools
|
|
11
|
+
) as ToolsService;
|
|
12
|
+
|
|
13
|
+
const context = toolService.getContext();
|
|
14
|
+
const Mcp = context.Mcp;
|
|
15
|
+
|
|
16
|
+
if (!Mcp) {
|
|
17
|
+
return {
|
|
18
|
+
success: false,
|
|
19
|
+
error: "MCP service not available in context",
|
|
20
|
+
toolsAdded: [],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!serverName) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
error: "serverName parameter is required",
|
|
28
|
+
toolsAdded: [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const result = await Mcp.connectSingle(serverName, timeout);
|
|
33
|
+
|
|
34
|
+
// If connection was successful and tools were added, register them with the ToolsService
|
|
35
|
+
if (result.success && result.toolsAdded.length > 0) {
|
|
36
|
+
await Mcp.addTools(toolService);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Tool } from "../../../clients/types";
|
|
2
|
+
|
|
3
|
+
const listAvailableMcpServersDefinition: Tool = {
|
|
4
|
+
type: "function",
|
|
5
|
+
function: {
|
|
6
|
+
name: "listAvailableMcpServers",
|
|
7
|
+
description:
|
|
8
|
+
"List all configured MCP servers and their connection status. Shows which servers are connected, which are disconnected, and how many tools each provides.",
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object",
|
|
11
|
+
positional: true,
|
|
12
|
+
properties: {},
|
|
13
|
+
required: [],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const connectMcpServerDefinition: Tool = {
|
|
19
|
+
type: "function",
|
|
20
|
+
function: {
|
|
21
|
+
name: "connectMcpServer",
|
|
22
|
+
description:
|
|
23
|
+
"Connect to a specific MCP server on-demand. This is useful for servers configured with autoConnect: false, or to reconnect a disconnected server. Once connected, the server's tools will be available for use.",
|
|
24
|
+
parameters: {
|
|
25
|
+
type: "object",
|
|
26
|
+
positional: true,
|
|
27
|
+
properties: {
|
|
28
|
+
serverName: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "The name of the MCP server to connect to",
|
|
31
|
+
},
|
|
32
|
+
timeout: {
|
|
33
|
+
type: "number",
|
|
34
|
+
description:
|
|
35
|
+
"Connection timeout in milliseconds (optional, default: 30000)",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["serverName"],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const disconnectMcpServerDefinition: Tool = {
|
|
44
|
+
type: "function",
|
|
45
|
+
function: {
|
|
46
|
+
name: "disconnectMcpServer",
|
|
47
|
+
description:
|
|
48
|
+
"Disconnect from a specific MCP server. This will close the connection and remove the server's tools from the available tools list.",
|
|
49
|
+
parameters: {
|
|
50
|
+
type: "object",
|
|
51
|
+
positional: true,
|
|
52
|
+
properties: {
|
|
53
|
+
serverName: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "The name of the MCP server to disconnect from",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
required: ["serverName"],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const definitions = [
|
|
64
|
+
listAvailableMcpServersDefinition,
|
|
65
|
+
connectMcpServerDefinition,
|
|
66
|
+
disconnectMcpServerDefinition,
|
|
67
|
+
];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { services } from "../../../services";
|
|
2
|
+
import { McpService } from "../../../services/Mcp";
|
|
3
|
+
import { ToolsService } from "../../../services/Tools";
|
|
4
|
+
|
|
5
|
+
export async function disconnectMcpServer(serverName: string) {
|
|
6
|
+
const toolService = (
|
|
7
|
+
this instanceof ToolsService ? this : services().Tools
|
|
8
|
+
) as ToolsService;
|
|
9
|
+
|
|
10
|
+
const context = toolService.getContext();
|
|
11
|
+
const Mcp = context.Mcp;
|
|
12
|
+
|
|
13
|
+
if (!Mcp) {
|
|
14
|
+
return {
|
|
15
|
+
success: false,
|
|
16
|
+
error: "MCP service not available in context",
|
|
17
|
+
toolsRemoved: [],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!serverName) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
error: "serverName parameter is required",
|
|
25
|
+
toolsRemoved: [],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result = await Mcp.disconnectSingle(serverName);
|
|
30
|
+
|
|
31
|
+
// If disconnection was successful and tools were removed, update the ToolsService
|
|
32
|
+
if (result.success && result.toolsRemoved.length > 0) {
|
|
33
|
+
// Remove tools from the current ToolsService instance
|
|
34
|
+
toolService.tools = toolService.tools.filter(
|
|
35
|
+
(tool) => !result.toolsRemoved.includes(tool.function.name)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { services } from "../../../services";
|
|
2
|
+
import { McpService } from "../../../services/Mcp";
|
|
3
|
+
import { ToolsService } from "../../../services/Tools";
|
|
4
|
+
|
|
5
|
+
export async function listAvailableMcpServers() {
|
|
6
|
+
const toolService = (
|
|
7
|
+
this instanceof ToolsService ? this : services().Tools
|
|
8
|
+
) as ToolsService;
|
|
9
|
+
|
|
10
|
+
const context = toolService.getContext();
|
|
11
|
+
const Mcp = context.Mcp;
|
|
12
|
+
|
|
13
|
+
if (!Mcp) {
|
|
14
|
+
return {
|
|
15
|
+
error: "MCP service not available in context",
|
|
16
|
+
servers: [],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const servers = Mcp.getAvailableServers();
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
servers,
|
|
24
|
+
summary: `Found ${servers.length} configured MCP server(s). ${
|
|
25
|
+
servers.filter((s) => s.connected).length
|
|
26
|
+
} connected, ${servers.filter((s) => !s.connected).length} disconnected.`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -25,7 +25,10 @@ export async function writeFileChunk(
|
|
|
25
25
|
|
|
26
26
|
if (!filePath || content === undefined) {
|
|
27
27
|
throw new Error(
|
|
28
|
-
|
|
28
|
+
`File path and content are both required. We received: ${JSON.stringify({
|
|
29
|
+
filePath,
|
|
30
|
+
content,
|
|
31
|
+
})}. Make sure you write small chunks of content, otherwise you will hit output limits, resulting in content being empty.`
|
|
29
32
|
);
|
|
30
33
|
}
|
|
31
34
|
|