Initial commit: Discord-Claude Gateway with event-driven agent runtime

This commit is contained in:
2026-02-22 01:00:10 -05:00
parent b69e669638
commit ffcbcd874a

View File

@@ -1,4 +1,8 @@
import { execFile } from "node:child_process";
import { writeFile, unlink } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { randomUUID } from "node:crypto";
import type { Event, MessagePayload, HeartbeatPayload, CronPayload, HookPayload } from "./event-queue.js";
import type { MarkdownConfigLoader } from "./markdown-config-loader.js";
import type { SystemPromptAssembler } from "./system-prompt-assembler.js";
@@ -145,40 +149,53 @@ export class AgentRuntime {
}
}
private executeClaude(
private async executeClaude(
promptText: string,
systemPrompt: string,
sessionId?: string,
): Promise<ClaudeJsonResponse> {
// Write system prompt to a temp file to avoid CLI arg length limits
const tmpFile = join(tmpdir(), `aetheel-prompt-${randomUUID()}.txt`);
await writeFile(tmpFile, systemPrompt, "utf-8");
try {
return await this.runClaude(promptText, tmpFile, sessionId);
} finally {
unlink(tmpFile).catch(() => {});
}
}
private runClaude(
promptText: string,
systemPromptFile: string,
sessionId?: string,
): Promise<ClaudeJsonResponse> {
return new Promise((resolve, reject) => {
const args: string[] = [
"-p", promptText,
"--output-format", "json",
"--system-prompt", systemPrompt,
"--system-prompt-file", systemPromptFile,
"--dangerously-skip-permissions",
];
// Resume existing session
if (sessionId) {
args.push("--resume", sessionId);
}
// Allowed tools
if (this.config.allowedTools.length > 0) {
args.push("--allowedTools", ...this.config.allowedTools);
}
// Max turns to prevent runaway loops
args.push("--max-turns", "25");
console.log(`[DEBUG] Spawning Claude CLI: ${this.config.claudeCliPath} ${args.slice(0, 4).join(" ")} ... (${args.length} args total)`);
console.log(`[DEBUG] Spawning Claude CLI: ${this.config.claudeCliPath} -p "${promptText}" --output-format json --system-prompt-file ${systemPromptFile} ... (${args.length} args total)`);
const child = execFile(
this.config.claudeCliPath,
args,
{
timeout: this.config.queryTimeoutMs,
maxBuffer: 10 * 1024 * 1024, // 10MB
maxBuffer: 10 * 1024 * 1024,
encoding: "utf-8",
},
(error, stdout, stderr) => {