Initial commit: Discord-Claude Gateway with event-driven agent runtime
This commit is contained in:
92
src/hook-manager.ts
Normal file
92
src/hook-manager.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import type { Event, HookType } from "./event-queue.js";
|
||||
|
||||
export interface HookConfig {
|
||||
startup?: string;
|
||||
agent_begin?: string;
|
||||
agent_stop?: string;
|
||||
shutdown?: string;
|
||||
}
|
||||
|
||||
export interface AgentRuntimeLike {
|
||||
processEvent(event: Event): Promise<any>;
|
||||
}
|
||||
|
||||
type EnqueueFn = (event: Omit<Event, "id" | "timestamp">) => Event | null;
|
||||
|
||||
export class HookManager {
|
||||
private config: HookConfig = {};
|
||||
|
||||
parseConfig(content: string): HookConfig {
|
||||
const config: HookConfig = {};
|
||||
const lines = content.split("\n");
|
||||
|
||||
let inHooksSection = false;
|
||||
let currentHookType: HookType | null = null;
|
||||
|
||||
for (const line of lines) {
|
||||
const h2Match = line.match(/^##\s+(.+)$/);
|
||||
if (h2Match) {
|
||||
if (inHooksSection) {
|
||||
// Another ## heading ends the Hooks section
|
||||
break;
|
||||
}
|
||||
if (h2Match[1].trim() === "Hooks") {
|
||||
inHooksSection = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inHooksSection) continue;
|
||||
|
||||
const h3Match = line.match(/^###\s+(.+)$/);
|
||||
if (h3Match) {
|
||||
const name = h3Match[1].trim();
|
||||
if (name === "startup" || name === "agent_begin" || name === "agent_stop" || name === "shutdown") {
|
||||
currentHookType = name;
|
||||
} else {
|
||||
currentHookType = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const instructionMatch = line.match(/^Instruction:\s*(.+)$/);
|
||||
if (instructionMatch && currentHookType !== null) {
|
||||
config[currentHookType] = instructionMatch[1].trim();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
return config;
|
||||
}
|
||||
|
||||
fire(hookType: HookType, enqueue: EnqueueFn): void {
|
||||
const instruction = this.config[hookType];
|
||||
|
||||
enqueue({
|
||||
type: "hook",
|
||||
payload: {
|
||||
hookType,
|
||||
...(instruction !== undefined ? { instruction } : {}),
|
||||
},
|
||||
source: "hook-manager",
|
||||
});
|
||||
}
|
||||
|
||||
async fireInline(hookType: HookType, runtime: AgentRuntimeLike): Promise<void> {
|
||||
const instruction = this.config[hookType];
|
||||
|
||||
const event: Event = {
|
||||
id: 0,
|
||||
type: "hook",
|
||||
payload: {
|
||||
hookType,
|
||||
...(instruction !== undefined ? { instruction } : {}),
|
||||
},
|
||||
timestamp: new Date(),
|
||||
source: "hook-manager-inline",
|
||||
};
|
||||
|
||||
await runtime.processEvent(event);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user