UNPKG

@posthog/agent

Version:

TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog

124 lines (121 loc) 4.6 kB
import { randomBytes } from 'node:crypto'; class TaskManager { executionStates = new Map(); defaultTimeout = 10 * 60 * 1000; // 10 minutes generateExecutionId() { return randomBytes(16).toString("hex"); } startExecution(taskId, mode, executionId = this.generateExecutionId()) { const executionState = { taskId, status: "running", mode, startedAt: Date.now(), abortController: new AbortController(), }; this.executionStates.set(executionId, executionState); this.scheduleTimeout(executionId); return executionState; } async waitForCompletion(executionId) { const execution = this.executionStates.get(executionId); if (!execution) { throw new Error(`Execution ${executionId} not found`); } if (execution.result && execution.status === "completed") { return execution.result; } return new Promise((resolve, reject) => { const checkInterval = setInterval(() => { const currentExecution = this.executionStates.get(executionId); if (!currentExecution) { clearInterval(checkInterval); reject(new Error(`Execution ${executionId} disappeared`)); return; } if (currentExecution.status === "completed" && currentExecution.result) { clearInterval(checkInterval); resolve(currentExecution.result); } else if (currentExecution.status === "failed" || currentExecution.status === "canceled" || currentExecution.status === "timeout") { clearInterval(checkInterval); reject(new Error(`Execution ${executionId} ${currentExecution.status}`)); } }, 100); }); } completeExecution(executionId, result) { const execution = this.executionStates.get(executionId); if (!execution) { throw new Error(`Execution ${executionId} not found`); } execution.status = "completed"; execution.result = result; execution.completedAt = Date.now(); } failExecution(executionId, error) { const execution = this.executionStates.get(executionId); if (!execution) { throw new Error(`Execution ${executionId} not found`); } execution.status = "failed"; execution.completedAt = Date.now(); execution.result = { error: error.message, status: "failed", }; } cancelExecution(executionId) { const execution = this.executionStates.get(executionId); if (!execution) { throw new Error(`Execution ${executionId} not found`); } execution.status = "canceled"; execution.completedAt = Date.now(); execution.abortController?.abort(); if (!execution.result) { execution.result = { status: "canceled", message: "Execution was canceled", }; } } getExecution(executionId) { return this.executionStates.get(executionId); } getAbortSignal(executionId) { return this.executionStates.get(executionId)?.abortController?.signal; } getAbortController(executionId) { return this.executionStates.get(executionId)?.abortController; } scheduleTimeout(executionId, timeout = this.defaultTimeout) { setTimeout(() => { const execution = this.executionStates.get(executionId); if (execution && execution.status === "running") { execution.status = "timeout"; execution.completedAt = Date.now(); execution.abortController?.abort(); if (!execution.result) { execution.result = { status: "timeout", message: "Execution timed out", }; } } }, timeout); } cleanup(olderThan = 60 * 60 * 1000) { const cutoff = Date.now() - olderThan; for (const [executionId, execution] of this.executionStates) { if (execution.completedAt && execution.completedAt < cutoff) { this.executionStates.delete(executionId); } } } } export { TaskManager }; //# sourceMappingURL=task-manager.js.map