@tyvm/knowhow 0.0.83 → 0.0.85
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/researcher/researcher.ts +1 -2
- package/src/agents/tools/aiClient.ts +48 -0
- package/src/agents/tools/list.ts +57 -0
- 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/clients/index.ts +91 -0
- package/src/clients/pricing/google.ts +81 -2
- package/src/clients/pricing/openai.ts +68 -0
- 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 +103 -5
- 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/clients/pricing.test.ts +144 -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/researcher/researcher.js +1 -1
- package/ts_build/src/agents/researcher/researcher.js.map +1 -1
- package/ts_build/src/agents/tools/aiClient.d.ts +3 -0
- package/ts_build/src/agents/tools/aiClient.js +31 -1
- package/ts_build/src/agents/tools/aiClient.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +48 -0
- package/ts_build/src/agents/tools/list.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/clients/gemini.d.ts +10 -10
- package/ts_build/src/clients/index.d.ts +10 -0
- package/ts_build/src/clients/index.js +58 -0
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/pricing/google.d.ts +10 -10
- package/ts_build/src/clients/pricing/google.js +74 -2
- package/ts_build/src/clients/pricing/google.js.map +1 -1
- package/ts_build/src/clients/pricing/openai.js +65 -0
- package/ts_build/src/clients/pricing/openai.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 +51 -2
- package/ts_build/src/types.js +73 -5
- 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/clients/pricing.test.d.ts +1 -0
- package/ts_build/tests/clients/pricing.test.js +90 -0
- package/ts_build/tests/clients/pricing.test.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
|
@@ -7,6 +7,7 @@ import { AgentContext } from "../agents/base/base";
|
|
|
7
7
|
|
|
8
8
|
export class AgentService {
|
|
9
9
|
private agents: Map<string, IAgent> = new Map();
|
|
10
|
+
private agentContext: AgentContext | null = null;
|
|
10
11
|
|
|
11
12
|
constructor(private tools: ToolsService, private events: EventService) {
|
|
12
13
|
this.wireUp();
|
|
@@ -57,6 +58,22 @@ export class AgentService {
|
|
|
57
58
|
this.agents.set(name, agent);
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Set the AgentContext that will be used when creating new agent instances.
|
|
63
|
+
* Should be called from cli.ts after all services are wired up (including LazyToolsService).
|
|
64
|
+
*/
|
|
65
|
+
public setAgentContext(context: AgentContext): void {
|
|
66
|
+
this.agentContext = context;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the current AgentContext. Falls back to a minimal context using this service's
|
|
71
|
+
* own tools/events if none has been explicitly set.
|
|
72
|
+
*/
|
|
73
|
+
public getAgentContext(): AgentContext {
|
|
74
|
+
return this.agentContext ?? { Tools: this.tools, Events: this.events };
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
public getAgent(name: string): IAgent {
|
|
61
78
|
const agent = this.agents.get(name);
|
|
62
79
|
if (!agent) {
|
|
@@ -10,6 +10,7 @@ import { watch } from "fs";
|
|
|
10
10
|
export interface FsSyncOptions {
|
|
11
11
|
taskId: string;
|
|
12
12
|
prompt: string;
|
|
13
|
+
agentName?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -51,6 +52,7 @@ export class AgentSyncFs {
|
|
|
51
52
|
await this.writeMetadata({
|
|
52
53
|
taskId: this.taskId,
|
|
53
54
|
prompt: options.prompt,
|
|
55
|
+
agentName: options.agentName || "unknown",
|
|
54
56
|
startTime: new Date().toISOString(),
|
|
55
57
|
status: "running",
|
|
56
58
|
});
|
|
@@ -125,6 +127,7 @@ export class AgentSyncFs {
|
|
|
125
127
|
|
|
126
128
|
metadata.threads = agent.getThreads();
|
|
127
129
|
metadata.totalCostUsd = agent.getTotalCostUsd();
|
|
130
|
+
metadata.agentName = agent.name;
|
|
128
131
|
metadata.inProgress = inProgress;
|
|
129
132
|
metadata.lastUpdate = new Date().toISOString();
|
|
130
133
|
|
|
@@ -1,30 +1,57 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
2
|
import { IAgent } from "../agents/interface";
|
|
3
3
|
|
|
4
|
+
export type EventHandlerFn = (...args: any[]) => any;
|
|
5
|
+
|
|
4
6
|
export interface EventHandler {
|
|
5
|
-
handler:
|
|
7
|
+
handler: EventHandlerFn;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ManagedListenerSpec {
|
|
11
|
+
key: string;
|
|
12
|
+
event: string;
|
|
13
|
+
once?: boolean;
|
|
14
|
+
blocking?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AgentLogEvent {
|
|
18
|
+
agentName: string;
|
|
19
|
+
message: string;
|
|
20
|
+
level: "info" | "warn" | "error";
|
|
21
|
+
timestamp: number;
|
|
22
|
+
taskId?: string | null;
|
|
6
23
|
}
|
|
7
24
|
|
|
25
|
+
type ManagedListenerRecord = {
|
|
26
|
+
key: string;
|
|
27
|
+
event: string;
|
|
28
|
+
handler: EventHandlerFn;
|
|
29
|
+
wrappedHandler: EventHandlerFn;
|
|
30
|
+
once: boolean;
|
|
31
|
+
blocking: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
8
34
|
export class EventService extends EventEmitter {
|
|
9
35
|
private blockingHandlers: Map<string, EventHandler[]> = new Map();
|
|
36
|
+
private managedListeners: Map<string, ManagedListenerRecord> = new Map();
|
|
10
37
|
|
|
11
38
|
eventTypes = {
|
|
12
39
|
agentMsg: "agent:msg",
|
|
13
40
|
agentsRegister: "agents:register",
|
|
14
41
|
agentsCall: "agents:call",
|
|
42
|
+
pluginLog: "plugin:log",
|
|
15
43
|
};
|
|
16
44
|
|
|
17
45
|
constructor() {
|
|
18
46
|
super();
|
|
47
|
+
this.setMaxListeners(100);
|
|
19
48
|
}
|
|
20
49
|
|
|
21
50
|
/**
|
|
22
|
-
* Register
|
|
23
|
-
*
|
|
24
|
-
* @param handler The event handler function
|
|
25
|
-
* @param isBlocking Whether this handler should be blocking
|
|
51
|
+
* Register a blocking handler.
|
|
52
|
+
* These run during emitBlocking / emitNonBlocking before normal EventEmitter listeners.
|
|
26
53
|
*/
|
|
27
|
-
onBlocking(event: string, handler:
|
|
54
|
+
onBlocking(event: string, handler: EventHandlerFn): void {
|
|
28
55
|
if (!this.blockingHandlers.has(event)) {
|
|
29
56
|
this.blockingHandlers.set(event, []);
|
|
30
57
|
}
|
|
@@ -33,10 +60,122 @@ export class EventService extends EventEmitter {
|
|
|
33
60
|
}
|
|
34
61
|
|
|
35
62
|
/**
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
63
|
+
* Remove a blocking handler.
|
|
64
|
+
*/
|
|
65
|
+
offBlocking(event: string, handler: EventHandlerFn): void {
|
|
66
|
+
const handlers = this.blockingHandlers.get(event);
|
|
67
|
+
if (!handlers) return;
|
|
68
|
+
|
|
69
|
+
const filtered = handlers.filter((entry) => entry.handler !== handler);
|
|
70
|
+
|
|
71
|
+
if (filtered.length === 0) {
|
|
72
|
+
this.blockingHandlers.delete(event);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.blockingHandlers.set(event, filtered);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Set a managed listener.
|
|
81
|
+
*
|
|
82
|
+
* Semantics:
|
|
83
|
+
* - key is unique
|
|
84
|
+
* - if a listener already exists for this key, it is removed first
|
|
85
|
+
* - supports normal or blocking listeners
|
|
86
|
+
* - supports once semantics
|
|
87
|
+
*/
|
|
88
|
+
setListener(spec: ManagedListenerSpec, handler: EventHandlerFn): void {
|
|
89
|
+
const { key, event, once = false, blocking = false } = spec;
|
|
90
|
+
|
|
91
|
+
this.removeManagedListener(key);
|
|
92
|
+
|
|
93
|
+
let wrappedHandler: EventHandlerFn;
|
|
94
|
+
|
|
95
|
+
if (once) {
|
|
96
|
+
wrappedHandler = (...args: any[]) => {
|
|
97
|
+
try {
|
|
98
|
+
handler(...args);
|
|
99
|
+
} finally {
|
|
100
|
+
this.managedListeners.delete(key);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
} else {
|
|
104
|
+
wrappedHandler = handler;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const record: ManagedListenerRecord = {
|
|
108
|
+
key,
|
|
109
|
+
event,
|
|
110
|
+
handler,
|
|
111
|
+
wrappedHandler,
|
|
112
|
+
once,
|
|
113
|
+
blocking,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (blocking) {
|
|
117
|
+
if (!this.blockingHandlers.has(event)) {
|
|
118
|
+
this.blockingHandlers.set(event, []);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.blockingHandlers.get(event)!.push({ handler: wrappedHandler });
|
|
122
|
+
} else {
|
|
123
|
+
if (once) {
|
|
124
|
+
super.once(event, wrappedHandler);
|
|
125
|
+
} else {
|
|
126
|
+
super.on(event, wrappedHandler);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.managedListeners.set(key, record);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Remove a managed listener by key.
|
|
135
|
+
*/
|
|
136
|
+
removeManagedListener(key: string): void {
|
|
137
|
+
const existing = this.managedListeners.get(key);
|
|
138
|
+
if (!existing) return;
|
|
139
|
+
|
|
140
|
+
if (existing.blocking) {
|
|
141
|
+
this.offBlocking(existing.event, existing.wrappedHandler);
|
|
142
|
+
} else {
|
|
143
|
+
super.removeListener(existing.event, existing.wrappedHandler);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.managedListeners.delete(key);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Remove all managed listeners whose key starts with the given prefix.
|
|
151
|
+
*/
|
|
152
|
+
removeManagedListenersByPrefix(prefix: string): void {
|
|
153
|
+
for (const key of Array.from(this.managedListeners.keys())) {
|
|
154
|
+
if (key.startsWith(prefix)) {
|
|
155
|
+
this.removeManagedListener(key);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Remove all managed listeners registered through setListener.
|
|
162
|
+
*/
|
|
163
|
+
clearManagedListeners(): void {
|
|
164
|
+
for (const key of Array.from(this.managedListeners.keys())) {
|
|
165
|
+
this.removeManagedListener(key);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Check whether a managed listener exists for the given key.
|
|
171
|
+
*/
|
|
172
|
+
hasManagedListener(key: string): boolean {
|
|
173
|
+
return this.managedListeners.has(key);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Emit a blocking event - if any blocking handler throws, execution stops.
|
|
178
|
+
* After blocking handlers succeed, normal EventEmitter listeners are emitted.
|
|
40
179
|
*/
|
|
41
180
|
async emitBlocking(event: string, ...args: any[]): Promise<any[]> {
|
|
42
181
|
const results: any[] = [];
|
|
@@ -45,14 +184,8 @@ export class EventService extends EventEmitter {
|
|
|
45
184
|
for (const { handler } of handlers) {
|
|
46
185
|
try {
|
|
47
186
|
const result = handler(...args);
|
|
48
|
-
|
|
49
|
-
const awaitedResult = await result;
|
|
50
|
-
results.push(awaitedResult);
|
|
51
|
-
} else {
|
|
52
|
-
results.push(result);
|
|
53
|
-
}
|
|
187
|
+
results.push(result instanceof Promise ? await result : result);
|
|
54
188
|
} catch (error) {
|
|
55
|
-
// If this is a blocking handler and it throws, stop execution
|
|
56
189
|
throw error;
|
|
57
190
|
}
|
|
58
191
|
}
|
|
@@ -62,23 +195,18 @@ export class EventService extends EventEmitter {
|
|
|
62
195
|
}
|
|
63
196
|
|
|
64
197
|
/**
|
|
65
|
-
* Emit a non-blocking event -
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @returns Promise that resolves with array of handler results when all handlers complete
|
|
198
|
+
* Emit a non-blocking event - blocking handlers still run first,
|
|
199
|
+
* but their errors are logged instead of thrown.
|
|
200
|
+
* Then normal EventEmitter listeners are emitted.
|
|
69
201
|
*/
|
|
70
202
|
async emitNonBlocking(event: string, ...args: any[]): Promise<any[]> {
|
|
71
203
|
const handlers = this.blockingHandlers.get(event) || [];
|
|
72
204
|
const results: any[] = [];
|
|
205
|
+
|
|
73
206
|
for (const { handler } of handlers) {
|
|
74
207
|
try {
|
|
75
208
|
const result = handler(...args);
|
|
76
|
-
|
|
77
|
-
const awaitedResult = await result;
|
|
78
|
-
results.push(awaitedResult);
|
|
79
|
-
} else {
|
|
80
|
-
results.push(result);
|
|
81
|
-
}
|
|
209
|
+
results.push(result instanceof Promise ? await result : result);
|
|
82
210
|
} catch (error) {
|
|
83
211
|
console.error(
|
|
84
212
|
`Non-blocking handler error for event '${event}':`,
|
|
@@ -100,4 +228,17 @@ export class EventService extends EventEmitter {
|
|
|
100
228
|
this.emit(this.eventTypes.agentsCall, { name, query, resolve, reject });
|
|
101
229
|
});
|
|
102
230
|
}
|
|
231
|
+
|
|
232
|
+
log(
|
|
233
|
+
source: string,
|
|
234
|
+
message: string,
|
|
235
|
+
level: "info" | "warn" | "error" = "info"
|
|
236
|
+
): void {
|
|
237
|
+
this.emit(this.eventTypes.pluginLog, {
|
|
238
|
+
source,
|
|
239
|
+
message,
|
|
240
|
+
level,
|
|
241
|
+
timestamp: Date.now(),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
103
244
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Session Manager Service - Handles agent session persistence and restoration
|
|
3
3
|
*/
|
|
4
4
|
import * as fs from "fs";
|
|
5
|
+
import * as fsPromises from "fs/promises";
|
|
5
6
|
import * as path from "path";
|
|
6
7
|
import { TaskInfo, ChatSession } from "../chat/types";
|
|
7
8
|
|
|
@@ -38,7 +39,9 @@ export class SessionManager {
|
|
|
38
39
|
|
|
39
40
|
const wordPart = words.join("-") || "task";
|
|
40
41
|
const epochSeconds = Math.floor(Date.now() / 1000);
|
|
41
|
-
|
|
42
|
+
const fullId = `${epochSeconds}-${wordPart}`;
|
|
43
|
+
// Truncate to 80 chars to avoid ENAMETOOLONG filesystem errors
|
|
44
|
+
return fullId.slice(0, 80);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
@@ -284,4 +287,51 @@ export class SessionManager {
|
|
|
284
287
|
|
|
285
288
|
console.log("─".repeat(80));
|
|
286
289
|
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Discover agents running in other processes via the filesystem.
|
|
293
|
+
* By default only returns agents that are NOT completed/killed.
|
|
294
|
+
*/
|
|
295
|
+
public async discoverFsAgents(
|
|
296
|
+
registeredIds: Set<string>,
|
|
297
|
+
includeCompleted: boolean = false
|
|
298
|
+
): Promise<Array<{ taskId: string; agentName: string; status: string; totalCostUsd?: number }>> {
|
|
299
|
+
const agentsDir = path.join(".knowhow", "processes", "agents");
|
|
300
|
+
if (!fs.existsSync(agentsDir)) return [];
|
|
301
|
+
|
|
302
|
+
const results: Array<{ taskId: string; agentName: string; status: string; totalCostUsd?: number }> = [];
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const entries = await fsPromises.readdir(agentsDir, { withFileTypes: true });
|
|
306
|
+
for (const entry of entries) {
|
|
307
|
+
if (!entry.isDirectory()) continue;
|
|
308
|
+
const taskId = entry.name;
|
|
309
|
+
if (registeredIds.has(taskId)) continue; // Already in-process
|
|
310
|
+
const metadataPath = path.join(agentsDir, taskId, "metadata.json");
|
|
311
|
+
try {
|
|
312
|
+
const raw = await fsPromises.readFile(metadataPath, "utf-8");
|
|
313
|
+
const metadata = JSON.parse(raw);
|
|
314
|
+
const status = metadata.status || "unknown";
|
|
315
|
+
|
|
316
|
+
// Skip completed/killed tasks unless explicitly requested
|
|
317
|
+
if (!includeCompleted && (status === "completed" || status === "killed")) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
results.push({
|
|
322
|
+
taskId,
|
|
323
|
+
agentName: metadata.agentName || "unknown",
|
|
324
|
+
status,
|
|
325
|
+
totalCostUsd: metadata.totalCostUsd,
|
|
326
|
+
});
|
|
327
|
+
} catch {
|
|
328
|
+
// Skip dirs without metadata
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch {
|
|
332
|
+
// agentsDir not readable
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return results;
|
|
336
|
+
}
|
|
287
337
|
}
|