@tyvm/knowhow 0.0.83 → 0.0.84
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 +4 -2
- package/src/agents/base/base.ts +72 -62
- package/src/agents/index.ts +30 -14
- package/src/agents/tools/startAgentTask.ts +3 -1
- package/src/chat/CliChatService.ts +20 -4
- package/src/chat/modules/AgentModule.ts +399 -357
- package/src/chat/modules/CustomCommandsModule.ts +0 -1
- package/src/chat/modules/InternalChatModule.ts +18 -2
- package/src/chat/modules/RendererModule.ts +109 -0
- package/src/chat/modules/SessionsModule.ts +854 -0
- package/src/chat/modules/SetupModule.ts +6 -8
- package/src/chat/modules/index.ts +1 -0
- package/src/chat/renderer/CompactRenderer.ts +209 -0
- package/src/chat/renderer/ConsoleRenderer.ts +141 -0
- package/src/chat/renderer/FancyRenderer.ts +421 -0
- package/src/chat/renderer/index.ts +5 -0
- package/src/chat/renderer/loadRenderer.ts +314 -0
- package/src/chat/renderer/messagesToRenderEvents.ts +96 -0
- package/src/chat/renderer/types.ts +88 -0
- package/src/chat/types.ts +5 -0
- package/src/chat.ts +69 -5
- package/src/cli.ts +24 -5
- package/src/config.ts +15 -0
- package/src/plugins/AgentsMdPlugin.ts +1 -1
- package/src/plugins/GitPlugin.ts +20 -20
- package/src/plugins/PluginBase.ts +11 -0
- package/src/plugins/SkillsPlugin.ts +150 -0
- package/src/plugins/asana.ts +4 -4
- package/src/plugins/embedding.ts +3 -5
- package/src/plugins/exec.ts +3 -3
- package/src/plugins/figma.ts +3 -7
- package/src/plugins/github.ts +18 -29
- package/src/plugins/jira.ts +2 -2
- package/src/plugins/language.ts +4 -4
- package/src/plugins/linear.ts +4 -4
- package/src/plugins/notion.ts +6 -8
- package/src/plugins/plugins.ts +29 -3
- package/src/plugins/url.ts +2 -2
- package/src/plugins/vim.ts +4 -3
- package/src/services/AgentService.ts +17 -0
- package/src/services/AgentSyncFs.ts +3 -0
- package/src/services/EventService.ts +168 -27
- package/src/services/KnowhowClient.ts +1 -0
- package/src/services/SessionManager.ts +51 -1
- package/src/services/SyncedAgentWatcher.ts +397 -0
- package/src/services/SyncerService.ts +147 -0
- package/src/services/index.ts +2 -0
- package/src/services/modules/index.ts +14 -3
- package/src/types.ts +25 -0
- package/src/worker.ts +80 -2
- package/src/workers/auth/PasskeySetup.ts +185 -0
- package/src/workers/auth/WorkerPasskeyAuth.ts +190 -0
- package/src/workers/auth/types.ts +58 -0
- package/src/workers/tools/getChallenge.ts +33 -0
- package/src/workers/tools/index.ts +8 -0
- package/src/workers/tools/lock.ts +31 -0
- package/src/workers/tools/unlock.ts +116 -0
- package/tests/unit/modules/moduleLoading.test.ts +226 -0
- package/tests/unit/plugins/pluginLoading.test.ts +151 -0
- package/ts_build/package.json +4 -2
- package/ts_build/src/agents/base/base.d.ts +4 -3
- package/ts_build/src/agents/base/base.js +54 -30
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/index.d.ts +3 -0
- package/ts_build/src/agents/index.js +21 -11
- package/ts_build/src/agents/index.js.map +1 -1
- package/ts_build/src/agents/tools/startAgentTask.js +2 -1
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
- package/ts_build/src/chat/CliChatService.js +16 -5
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.d.ts +34 -17
- package/ts_build/src/chat/modules/AgentModule.js +248 -258
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/chat/modules/CustomCommandsModule.js.map +1 -1
- package/ts_build/src/chat/modules/InternalChatModule.d.ts +3 -0
- package/ts_build/src/chat/modules/InternalChatModule.js +16 -1
- package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -1
- package/ts_build/src/chat/modules/RendererModule.d.ts +16 -0
- package/ts_build/src/chat/modules/RendererModule.js +76 -0
- package/ts_build/src/chat/modules/RendererModule.js.map +1 -0
- package/ts_build/src/chat/modules/SessionsModule.d.ts +33 -0
- package/ts_build/src/chat/modules/SessionsModule.js +582 -0
- package/ts_build/src/chat/modules/SessionsModule.js.map +1 -0
- package/ts_build/src/chat/modules/SetupModule.d.ts +3 -3
- package/ts_build/src/chat/modules/SetupModule.js +4 -6
- package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
- 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/renderer/CompactRenderer.d.ts +23 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js +167 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js.map +1 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.d.ts +22 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js +110 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js.map +1 -0
- package/ts_build/src/chat/renderer/FancyRenderer.d.ts +23 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js +328 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js.map +1 -0
- package/ts_build/src/chat/renderer/index.d.ts +5 -0
- package/ts_build/src/chat/renderer/index.js +29 -0
- package/ts_build/src/chat/renderer/index.js.map +1 -0
- package/ts_build/src/chat/renderer/loadRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/loadRenderer.js +246 -0
- package/ts_build/src/chat/renderer/loadRenderer.js.map +1 -0
- package/ts_build/src/chat/renderer/messagesToRenderEvents.d.ts +15 -0
- package/ts_build/src/chat/renderer/messagesToRenderEvents.js +72 -0
- package/ts_build/src/chat/renderer/messagesToRenderEvents.js.map +1 -0
- package/ts_build/src/chat/renderer/types.d.ts +75 -0
- package/ts_build/src/chat/renderer/types.js +3 -0
- package/ts_build/src/chat/renderer/types.js.map +1 -0
- package/ts_build/src/chat/types.d.ts +5 -0
- package/ts_build/src/chat.js +46 -4
- package/ts_build/src/chat.js.map +1 -1
- package/ts_build/src/cli.js +18 -5
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/config.d.ts +1 -0
- package/ts_build/src/config.js +17 -1
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/plugins/AgentsMdPlugin.js +1 -1
- package/ts_build/src/plugins/AgentsMdPlugin.js.map +1 -1
- package/ts_build/src/plugins/GitPlugin.js +20 -20
- package/ts_build/src/plugins/GitPlugin.js.map +1 -1
- package/ts_build/src/plugins/PluginBase.d.ts +1 -0
- package/ts_build/src/plugins/PluginBase.js +13 -0
- package/ts_build/src/plugins/PluginBase.js.map +1 -1
- package/ts_build/src/plugins/SkillsPlugin.d.ts +13 -0
- package/ts_build/src/plugins/SkillsPlugin.js +149 -0
- package/ts_build/src/plugins/SkillsPlugin.js.map +1 -0
- package/ts_build/src/plugins/asana.js +4 -4
- package/ts_build/src/plugins/asana.js.map +1 -1
- package/ts_build/src/plugins/embedding.js +3 -3
- package/ts_build/src/plugins/embedding.js.map +1 -1
- package/ts_build/src/plugins/exec.js +3 -3
- package/ts_build/src/plugins/exec.js.map +1 -1
- package/ts_build/src/plugins/figma.js +3 -3
- package/ts_build/src/plugins/figma.js.map +1 -1
- package/ts_build/src/plugins/github.js +18 -18
- package/ts_build/src/plugins/github.js.map +1 -1
- package/ts_build/src/plugins/jira.js +2 -2
- package/ts_build/src/plugins/jira.js.map +1 -1
- package/ts_build/src/plugins/language.js +4 -4
- package/ts_build/src/plugins/language.js.map +1 -1
- package/ts_build/src/plugins/linear.js +4 -4
- package/ts_build/src/plugins/linear.js.map +1 -1
- package/ts_build/src/plugins/notion.js +6 -6
- package/ts_build/src/plugins/notion.js.map +1 -1
- package/ts_build/src/plugins/plugins.d.ts +3 -0
- package/ts_build/src/plugins/plugins.js +18 -3
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/plugins/url.js +2 -2
- package/ts_build/src/plugins/url.js.map +1 -1
- package/ts_build/src/plugins/vim.js +2 -2
- package/ts_build/src/plugins/vim.js.map +1 -1
- package/ts_build/src/services/AgentService.d.ts +3 -0
- package/ts_build/src/services/AgentService.js +7 -0
- package/ts_build/src/services/AgentService.js.map +1 -1
- package/ts_build/src/services/AgentSyncFs.d.ts +1 -0
- package/ts_build/src/services/AgentSyncFs.js +2 -0
- package/ts_build/src/services/AgentSyncFs.js.map +1 -1
- package/ts_build/src/services/EventService.d.ts +25 -2
- package/ts_build/src/services/EventService.js +92 -14
- package/ts_build/src/services/EventService.js.map +1 -1
- package/ts_build/src/services/KnowhowClient.d.ts +1 -0
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/SessionManager.d.ts +6 -0
- package/ts_build/src/services/SessionManager.js +39 -1
- package/ts_build/src/services/SessionManager.js.map +1 -1
- package/ts_build/src/services/SyncedAgentWatcher.d.ts +101 -0
- package/ts_build/src/services/SyncedAgentWatcher.js +312 -0
- package/ts_build/src/services/SyncedAgentWatcher.js.map +1 -0
- package/ts_build/src/services/SyncerService.d.ts +30 -0
- package/ts_build/src/services/SyncerService.js +72 -0
- package/ts_build/src/services/SyncerService.js.map +1 -0
- package/ts_build/src/services/index.d.ts +2 -0
- package/ts_build/src/services/index.js +2 -0
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/modules/index.js +10 -2
- package/ts_build/src/services/modules/index.js.map +1 -1
- package/ts_build/src/types.d.ts +19 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/worker.d.ts +2 -0
- package/ts_build/src/worker.js +59 -4
- package/ts_build/src/worker.js.map +1 -1
- package/ts_build/src/workers/auth/PasskeySetup.d.ts +10 -0
- package/ts_build/src/workers/auth/PasskeySetup.js +131 -0
- package/ts_build/src/workers/auth/PasskeySetup.js.map +1 -0
- package/ts_build/src/workers/auth/WorkerPasskeyAuth.d.ts +35 -0
- package/ts_build/src/workers/auth/WorkerPasskeyAuth.js +129 -0
- package/ts_build/src/workers/auth/WorkerPasskeyAuth.js.map +1 -0
- package/ts_build/src/workers/auth/types.d.ts +36 -0
- package/ts_build/src/workers/auth/types.js +3 -0
- package/ts_build/src/workers/auth/types.js.map +1 -0
- package/ts_build/src/workers/tools/getChallenge.d.ts +9 -0
- package/ts_build/src/workers/tools/getChallenge.js +27 -0
- package/ts_build/src/workers/tools/getChallenge.js.map +1 -0
- package/ts_build/src/workers/tools/index.d.ts +6 -0
- package/ts_build/src/workers/tools/index.js +10 -0
- package/ts_build/src/workers/tools/index.js.map +1 -1
- package/ts_build/src/workers/tools/lock.d.ts +9 -0
- package/ts_build/src/workers/tools/lock.js +27 -0
- package/ts_build/src/workers/tools/lock.js.map +1 -0
- package/ts_build/src/workers/tools/unlock.d.ts +18 -0
- package/ts_build/src/workers/tools/unlock.js +78 -0
- package/ts_build/src/workers/tools/unlock.js.map +1 -0
- package/ts_build/tests/unit/modules/moduleLoading.test.d.ts +1 -0
- package/ts_build/tests/unit/modules/moduleLoading.test.js +187 -0
- package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -0
- package/ts_build/tests/unit/plugins/pluginLoading.test.d.ts +1 -0
- package/ts_build/tests/unit/plugins/pluginLoading.test.js +123 -0
- package/ts_build/tests/unit/plugins/pluginLoading.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.84",
|
|
4
4
|
"description": "ai cli with plugins and agents",
|
|
5
5
|
"main": "ts_build/src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -40,14 +40,15 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
42
42
|
"@aws-sdk/client-s3": "^3.588.0",
|
|
43
|
-
"@tyvm/knowhow-tunnel": "0.0.3",
|
|
44
43
|
"@google/genai": "^0.14.1",
|
|
45
44
|
"@inquirer/editor": "^4.2.18",
|
|
46
45
|
"@linear/sdk": "^12.0.0",
|
|
47
46
|
"@modelcontextprotocol/sdk": "^1.13.3",
|
|
48
47
|
"@notionhq/client": "^2.2.14",
|
|
49
48
|
"@octokit/rest": "^20.0.2",
|
|
49
|
+
"@simplewebauthn/server": "^13.3.0",
|
|
50
50
|
"@types/react": "^19.1.8",
|
|
51
|
+
"@tyvm/knowhow-tunnel": "0.0.3",
|
|
51
52
|
"asana": "^3.0.16",
|
|
52
53
|
"axios": "^1.5.0",
|
|
53
54
|
"cheerio": "^1.0.0",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"ink": "^6.0.1",
|
|
62
63
|
"isolated-vm": "^5.0.4",
|
|
63
64
|
"jira-client": "^8.2.2",
|
|
65
|
+
"jiti": "^2.6.1",
|
|
64
66
|
"marked": "^10.0.0",
|
|
65
67
|
"marked-terminal": "^6.2.0",
|
|
66
68
|
"minimatch": "^10.1.2",
|
package/src/agents/base/base.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
1
|
+
import { EventEmitter } from "events"; // kept for reference; agentEvents now uses EventService
|
|
2
2
|
import {
|
|
3
3
|
GenericClient,
|
|
4
4
|
Message,
|
|
@@ -64,13 +64,15 @@ export abstract class BaseAgent implements IAgent {
|
|
|
64
64
|
protected summaries = [] as string[];
|
|
65
65
|
protected currentTaskId: string | null = null;
|
|
66
66
|
|
|
67
|
-
public agentEvents = new
|
|
67
|
+
public agentEvents = new EventService();
|
|
68
68
|
public eventTypes = {
|
|
69
69
|
newThread: "new_thread",
|
|
70
70
|
threadUpdate: "thread_update",
|
|
71
71
|
costUpdate: "cost_update",
|
|
72
|
+
agentLog: "agent:log",
|
|
72
73
|
toolCall: "tool:pre_call",
|
|
73
74
|
toolUsed: "tool:post_call",
|
|
75
|
+
agentStatus: "agent:status",
|
|
74
76
|
notStarted: "not_started",
|
|
75
77
|
inProgress: "in_progress",
|
|
76
78
|
done: "done",
|
|
@@ -106,7 +108,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
// Subscribe to "agent:msg" events for dynamic context loading
|
|
109
|
-
|
|
111
|
+
// Use setListener with a key so re-creating the agent doesn't double-subscribe
|
|
112
|
+
this.events.setListener({ key: `agent:msg:${this.constructor.name}`, event: this.eventTypes.agentMsg }, (eventData: any) => {
|
|
110
113
|
if (
|
|
111
114
|
this.status === this.eventTypes.inProgress ||
|
|
112
115
|
this.status === this.eventTypes.pause
|
|
@@ -120,6 +123,16 @@ export abstract class BaseAgent implements IAgent {
|
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
protected log(message: string, level: "info" | "warn" | "error" = "info"): void {
|
|
127
|
+
this.agentEvents.emit(this.eventTypes.agentLog, {
|
|
128
|
+
agentName: this.name,
|
|
129
|
+
message,
|
|
130
|
+
level,
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
taskId: this.currentTaskId,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
123
136
|
setMaxTurns(maxTurns: number | null) {
|
|
124
137
|
this.maxTurns = maxTurns;
|
|
125
138
|
}
|
|
@@ -196,12 +209,12 @@ export abstract class BaseAgent implements IAgent {
|
|
|
196
209
|
getClient() {
|
|
197
210
|
if (!this.client) {
|
|
198
211
|
if (this.provider) {
|
|
199
|
-
|
|
212
|
+
this.log(`Getting client for provider ${this.provider}`);
|
|
200
213
|
this.client = this.clientService.getClient(this.provider)?.client;
|
|
201
214
|
}
|
|
202
215
|
|
|
203
216
|
if (!this.client) {
|
|
204
|
-
|
|
217
|
+
this.log(`Getting client for model ${this.modelName}`);
|
|
205
218
|
this.client = this.clientService.getClient(
|
|
206
219
|
undefined,
|
|
207
220
|
this.modelName
|
|
@@ -246,17 +259,17 @@ export abstract class BaseAgent implements IAgent {
|
|
|
246
259
|
private checkLimits(): boolean {
|
|
247
260
|
// Check turn limit
|
|
248
261
|
if (this.maxTurns !== null && this.turnCount >= this.maxTurns) {
|
|
249
|
-
|
|
262
|
+
this.log(`Turn limit reached: ${this.turnCount}/${this.maxTurns}`, "warn");
|
|
250
263
|
return true;
|
|
251
264
|
}
|
|
252
265
|
|
|
253
266
|
// Check spend limit
|
|
254
267
|
if (this.maxSpend !== null && this.totalCostUsd >= this.maxSpend) {
|
|
255
|
-
|
|
268
|
+
this.log(
|
|
256
269
|
`Spend limit reached: $${this.totalCostUsd.toFixed(
|
|
257
270
|
4
|
|
258
271
|
)}/$${this.maxSpend.toFixed(4)}`
|
|
259
|
-
);
|
|
272
|
+
, "warn");
|
|
260
273
|
return true;
|
|
261
274
|
}
|
|
262
275
|
|
|
@@ -264,8 +277,9 @@ export abstract class BaseAgent implements IAgent {
|
|
|
264
277
|
if (this.maxRunTimeMs !== null && this.startTimeMs !== null) {
|
|
265
278
|
const currentRunTimeMs = this.runTime();
|
|
266
279
|
if (currentRunTimeMs >= this.maxRunTimeMs) {
|
|
267
|
-
|
|
268
|
-
`Runtime limit reached: ${currentRunTimeMs}ms/${this.maxRunTimeMs}ms
|
|
280
|
+
this.log(
|
|
281
|
+
`Runtime limit reached: ${currentRunTimeMs}ms/${this.maxRunTimeMs}ms`,
|
|
282
|
+
"warn"
|
|
269
283
|
);
|
|
270
284
|
return true;
|
|
271
285
|
}
|
|
@@ -343,7 +357,6 @@ export abstract class BaseAgent implements IAgent {
|
|
|
343
357
|
this.agentEvents.emit(this.eventTypes.agentSay, {
|
|
344
358
|
message: message.content,
|
|
345
359
|
});
|
|
346
|
-
console.log("\n", "💬 " + message.content, "\n");
|
|
347
360
|
}
|
|
348
361
|
}
|
|
349
362
|
}
|
|
@@ -385,7 +398,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
385
398
|
});
|
|
386
399
|
return true;
|
|
387
400
|
} catch (e) {
|
|
388
|
-
|
|
401
|
+
this.log(String(e), "error");
|
|
389
402
|
return false;
|
|
390
403
|
}
|
|
391
404
|
}
|
|
@@ -417,10 +430,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
417
430
|
return false;
|
|
418
431
|
}
|
|
419
432
|
|
|
420
|
-
|
|
421
|
-
`Required tool: [${this.requiredToolNames}] not available, checking for finalAnswer
|
|
422
|
-
this.getEnabledToolNames(),
|
|
423
|
-
this.requiredToolNames
|
|
433
|
+
this.log(
|
|
434
|
+
`Required tool: [${this.requiredToolNames}] not available, checking for finalAnswer. Enabled: ${this.getEnabledToolNames().join(", ")}`
|
|
424
435
|
);
|
|
425
436
|
|
|
426
437
|
// Otherwise we're missing the required tool, lets use finalAnswer if we have it
|
|
@@ -430,9 +441,9 @@ export abstract class BaseAgent implements IAgent {
|
|
|
430
441
|
|
|
431
442
|
// We have the final answer tool, but it wasn't required
|
|
432
443
|
if (hasFinalAnswer && !requiredFinalAnswer) {
|
|
433
|
-
|
|
444
|
+
this.log(
|
|
434
445
|
"Required tool not available, setting finalAnswer as required tool"
|
|
435
|
-
);
|
|
446
|
+
, "warn");
|
|
436
447
|
this.requiredToolNames.push("finalAnswer");
|
|
437
448
|
return false;
|
|
438
449
|
}
|
|
@@ -445,22 +456,22 @@ export abstract class BaseAgent implements IAgent {
|
|
|
445
456
|
}
|
|
446
457
|
|
|
447
458
|
pause() {
|
|
448
|
-
|
|
459
|
+
this.log("Pausing agent");
|
|
449
460
|
this.agentEvents.emit(this.eventTypes.pause, this);
|
|
450
461
|
this.status = this.eventTypes.pause;
|
|
451
462
|
}
|
|
452
463
|
|
|
453
464
|
unpause() {
|
|
454
|
-
|
|
465
|
+
this.log("Unpausing agent");
|
|
455
466
|
this.agentEvents.emit(this.eventTypes.unpause, this);
|
|
456
467
|
this.status = this.eventTypes.inProgress;
|
|
457
468
|
}
|
|
458
469
|
|
|
459
470
|
async unpaused() {
|
|
460
471
|
return new Promise((resolve) => {
|
|
461
|
-
|
|
472
|
+
this.log("Waiting for agent to unpause");
|
|
462
473
|
this.agentEvents.once(this.eventTypes.unpause, () => {
|
|
463
|
-
|
|
474
|
+
this.log("Agent resumed");
|
|
464
475
|
resolve(true);
|
|
465
476
|
});
|
|
466
477
|
this.agentEvents.once(this.eventTypes.done, () => {
|
|
@@ -470,7 +481,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
470
481
|
}
|
|
471
482
|
|
|
472
483
|
async kill() {
|
|
473
|
-
|
|
484
|
+
this.log("Killing agent");
|
|
474
485
|
this.agentEvents.emit(this.eventTypes.kill, this);
|
|
475
486
|
this.status = this.eventTypes.kill;
|
|
476
487
|
|
|
@@ -550,15 +561,15 @@ export abstract class BaseAgent implements IAgent {
|
|
|
550
561
|
});
|
|
551
562
|
|
|
552
563
|
if (response?.usd_cost === undefined) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
564
|
+
this.log(
|
|
565
|
+
`Response cost is undefined: ${JSON.stringify(response, null, 2)}`,
|
|
566
|
+
"warn"
|
|
556
567
|
);
|
|
557
568
|
const error = response as any;
|
|
558
569
|
if ("response" in error && "data" in error.response) {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
570
|
+
this.log(
|
|
571
|
+
`Response data: ${JSON.stringify(error.response.data, null, 2)}`,
|
|
572
|
+
"warn"
|
|
562
573
|
);
|
|
563
574
|
}
|
|
564
575
|
}
|
|
@@ -650,7 +661,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
650
661
|
const error = `Required tool: ${JSON.stringify(
|
|
651
662
|
this.requiredToolNames
|
|
652
663
|
)} not available, options are ${this.getEnabledToolNames().join(", ")}`;
|
|
653
|
-
|
|
664
|
+
this.log(error, "error");
|
|
654
665
|
this.status = this.eventTypes.done;
|
|
655
666
|
this.agentEvents.emit(this.eventTypes.done, error);
|
|
656
667
|
return error;
|
|
@@ -661,7 +672,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
661
672
|
this.pendingUserMessages.length === 0 &&
|
|
662
673
|
this.status === this.eventTypes.kill
|
|
663
674
|
) {
|
|
664
|
-
|
|
675
|
+
this.log("Agent killed, stopping execution");
|
|
665
676
|
this.status = this.eventTypes.done;
|
|
666
677
|
this.agentEvents.emit(this.eventTypes.done, firstMessage.content);
|
|
667
678
|
return firstMessage.content;
|
|
@@ -672,11 +683,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
672
683
|
messages.length > 30
|
|
673
684
|
) {
|
|
674
685
|
const taskBreakdown = await this.getTaskBreakdown(messages);
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
this.getMessagesLength(messages),
|
|
678
|
-
"exceeds",
|
|
679
|
-
compressThreshold
|
|
686
|
+
this.log(
|
|
687
|
+
`Compressing messages: ${this.getMessagesLength(messages)} exceeds ${compressThreshold}`
|
|
680
688
|
);
|
|
681
689
|
messages = await this.compressMessages(messages, startIndex, endIndex);
|
|
682
690
|
this.startNewThread(messages);
|
|
@@ -722,9 +730,9 @@ export abstract class BaseAgent implements IAgent {
|
|
|
722
730
|
|
|
723
731
|
if (isRetriable && retryCount < 3) {
|
|
724
732
|
const delay = 1000 * Math.pow(2, retryCount);
|
|
725
|
-
|
|
726
|
-
`Agent request failed (attempt ${retryCount + 1}/3), retrying in ${delay}ms
|
|
727
|
-
|
|
733
|
+
this.log(
|
|
734
|
+
`Agent request failed (attempt ${retryCount + 1}/3), retrying in ${delay}ms: ${e.message}`,
|
|
735
|
+
"warn"
|
|
728
736
|
);
|
|
729
737
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
730
738
|
return this.call(userInput, _messages, retryCount + 1);
|
|
@@ -732,12 +740,12 @@ export abstract class BaseAgent implements IAgent {
|
|
|
732
740
|
|
|
733
741
|
}
|
|
734
742
|
|
|
735
|
-
|
|
743
|
+
this.log(`Agent failed: ${e}`, "error");
|
|
736
744
|
|
|
737
745
|
if ("response" in e && "data" in e.response) {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
746
|
+
this.log(
|
|
747
|
+
`Error response data: ${JSON.stringify(e.response.data, null, 2)}`,
|
|
748
|
+
"error"
|
|
741
749
|
);
|
|
742
750
|
}
|
|
743
751
|
|
|
@@ -783,14 +791,26 @@ export abstract class BaseAgent implements IAgent {
|
|
|
783
791
|
|
|
784
792
|
logStatus() {
|
|
785
793
|
const statusMessage = this.getStatusMessage();
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
794
|
+
this.agentEvents.emit(this.eventTypes.agentStatus, {
|
|
795
|
+
agentName: this.name,
|
|
796
|
+
taskId: this.currentTaskId,
|
|
797
|
+
statusMessage,
|
|
798
|
+
details: {
|
|
799
|
+
totalCostUsd: this.getTotalCostUsd(),
|
|
800
|
+
elapsedMs: this.runTime(),
|
|
801
|
+
remainingTimeMs: this.maxRunTimeMs && this.startTimeMs
|
|
802
|
+
? this.maxRunTimeMs - (Date.now() - this.startTimeMs)
|
|
803
|
+
: undefined,
|
|
804
|
+
remainingTurns: this.maxTurns ? this.maxTurns - this.turnCount : undefined,
|
|
805
|
+
remainingBudget: this.maxSpend ? this.maxSpend - this.totalCostUsd : undefined,
|
|
806
|
+
},
|
|
807
|
+
timestamp: Date.now(),
|
|
808
|
+
});
|
|
789
809
|
}
|
|
790
810
|
|
|
791
811
|
addPendingMessage(message: Message) {
|
|
792
812
|
if (this.status === this.eventTypes.done) {
|
|
793
|
-
|
|
813
|
+
this.log("Agent is done, cannot take more messages", "warn");
|
|
794
814
|
} else {
|
|
795
815
|
const pendingMessages = this.pendingUserMessages.map((m) => m.content);
|
|
796
816
|
if (pendingMessages.includes(message.content)) {
|
|
@@ -839,7 +859,7 @@ export abstract class BaseAgent implements IAgent {
|
|
|
839
859
|
|
|
840
860
|
this.adjustTotalCostUsd(response.usd_cost);
|
|
841
861
|
|
|
842
|
-
|
|
862
|
+
this.log(String(response));
|
|
843
863
|
|
|
844
864
|
this.taskBreakdown = response.choices[0].message.content;
|
|
845
865
|
return this.taskBreakdown;
|
|
@@ -850,13 +870,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
850
870
|
startIndex: number,
|
|
851
871
|
endIndex: number
|
|
852
872
|
) {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
startIndex,
|
|
856
|
-
"to",
|
|
857
|
-
endIndex,
|
|
858
|
-
"total messages:",
|
|
859
|
-
messages.length
|
|
873
|
+
this.log(
|
|
874
|
+
`Compressing messages from ${startIndex} to ${endIndex}, total messages: ${messages.length}`
|
|
860
875
|
);
|
|
861
876
|
const toCompress = messages.slice(startIndex, endIndex);
|
|
862
877
|
const toCompressPrompt = `We are compressing our conversation to save memory.
|
|
@@ -921,13 +936,8 @@ export abstract class BaseAgent implements IAgent {
|
|
|
921
936
|
100
|
|
922
937
|
).toFixed(2);
|
|
923
938
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
oldLength,
|
|
927
|
-
"to",
|
|
928
|
-
newLength,
|
|
929
|
-
compressionRatio + "%",
|
|
930
|
-
"reduction in size"
|
|
939
|
+
this.log(
|
|
940
|
+
`Compressed messages from ${oldLength} to ${newLength}, ${compressionRatio}% reduction in size`
|
|
931
941
|
);
|
|
932
942
|
|
|
933
943
|
return newMessages;
|
package/src/agents/index.ts
CHANGED
|
@@ -16,21 +16,37 @@ export * from "./researcher/researcher";
|
|
|
16
16
|
export * as tools from "./tools";
|
|
17
17
|
export { includedTools } from "./tools/list";
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
export type AgentName = "Developer" | "Patcher" | "Researcher" | "Setup";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Registry of agent constructors (not instances).
|
|
23
|
+
* Use createAgent() to get a fresh instance per task, avoiding stale event listener issues.
|
|
24
|
+
*/
|
|
25
|
+
export const agentConstructors: Record<AgentName, new (context: AgentContext) => any> = {
|
|
26
|
+
Developer: DeveloperAgent,
|
|
27
|
+
Patcher: PatchingAgent,
|
|
28
|
+
Researcher: ResearcherAgent,
|
|
29
|
+
Setup: SetupAgent,
|
|
24
30
|
};
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
32
|
+
/**
|
|
33
|
+
* Create a fresh agent instance by name.
|
|
34
|
+
* Always returns a new instance to avoid shared state / stale listeners between tasks.
|
|
35
|
+
*/
|
|
36
|
+
export function createAgent(agentName: AgentName, agentContext: AgentContext = services()) {
|
|
37
|
+
const AgentClass = agentConstructors[agentName];
|
|
38
|
+
if (!AgentClass) {
|
|
39
|
+
throw new Error(`Agent "${agentName}" not found. Available agents: ${Object.keys(agentConstructors).join(", ")}`);
|
|
34
40
|
}
|
|
35
|
-
return
|
|
41
|
+
return new AgentClass(agentContext);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @deprecated Use createAgent() for per-task instances to avoid event listener leaks */
|
|
45
|
+
export function agents(agentContext: AgentContext = services()) {
|
|
46
|
+
return {
|
|
47
|
+
Developer: new DeveloperAgent(agentContext),
|
|
48
|
+
Patcher: new PatchingAgent(agentContext),
|
|
49
|
+
Researcher: new ResearcherAgent(agentContext),
|
|
50
|
+
Setup: new SetupAgent(agentContext),
|
|
51
|
+
};
|
|
36
52
|
}
|
|
@@ -32,7 +32,9 @@ function generateTaskId(prompt: string): string {
|
|
|
32
32
|
.slice(0, 9);
|
|
33
33
|
const wordPart = words.join("-") || "task";
|
|
34
34
|
const epochSeconds = Math.floor(Date.now() / 1000);
|
|
35
|
-
|
|
35
|
+
const fullId = `${epochSeconds}-${wordPart}`;
|
|
36
|
+
// Truncate to 80 chars to avoid ENAMETOOLONG filesystem errors
|
|
37
|
+
return fullId.slice(0, 80);
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/**
|
|
@@ -317,13 +317,29 @@ export class CliChatService implements ChatService {
|
|
|
317
317
|
console.log("Commands:", commandNames.join(", "));
|
|
318
318
|
|
|
319
319
|
while (true) {
|
|
320
|
+
// Recompute available commands each iteration so mode changes are reflected in autocomplete
|
|
321
|
+
const currentCommandNames = this.getCommandsForActiveModes().map((cmd) => `/${cmd.name}`);
|
|
322
|
+
|
|
323
|
+
// Check active modes for a promptText first, then fall back to context.promptText, then default
|
|
324
|
+
const activeModeWithPrompt = this.modes
|
|
325
|
+
.filter((m) => m.active && m.promptText)
|
|
326
|
+
.slice(-1)[0]; // last active mode with a promptText wins
|
|
327
|
+
|
|
328
|
+
let modePrompt: string | undefined;
|
|
329
|
+
if (activeModeWithPrompt?.promptText) {
|
|
330
|
+
const p = activeModeWithPrompt.promptText;
|
|
331
|
+
modePrompt = typeof p === "function" ? p() : p;
|
|
332
|
+
}
|
|
333
|
+
|
|
320
334
|
const promptText =
|
|
321
|
-
|
|
335
|
+
modePrompt ||
|
|
336
|
+
this.context.promptText ||
|
|
337
|
+
(this.context.agentMode && this.context.currentAgent
|
|
322
338
|
? `\nAsk knowhow ${this.context.currentAgent}: `
|
|
323
|
-
: `\nAsk knowhow:
|
|
339
|
+
: `\nAsk knowhow: `);
|
|
324
340
|
try {
|
|
325
341
|
// Pass command names as autocomplete options
|
|
326
|
-
const input = await this.getInput(promptText,
|
|
342
|
+
const input = await this.getInput(promptText, currentCommandNames);
|
|
327
343
|
|
|
328
344
|
if (input.trim() === "") {
|
|
329
345
|
continue;
|
|
@@ -336,7 +352,7 @@ export class CliChatService implements ChatService {
|
|
|
336
352
|
// Default chat behavior - this would be handled by a chat module
|
|
337
353
|
const interaction = {
|
|
338
354
|
input,
|
|
339
|
-
output: `I didn't understand that command. Available commands: ${
|
|
355
|
+
output: `I didn't understand that command. Available commands: ${currentCommandNames.join(
|
|
340
356
|
", "
|
|
341
357
|
)}`,
|
|
342
358
|
} as ChatInteraction;
|