mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 11:03:44 +00:00
Remove hook execution timeouts
- Remove timeout logic from HookRunner - Remove hookTimeout from Settings interface - Remove getHookTimeout/setHookTimeout methods - Update CHANGELOG.md and hooks.md Timeouts were inconsistently applied and caused issues with legitimate slow operations (LLM calls, user prompts). Users can use Ctrl+C to abort hung hooks.
This commit is contained in:
parent
bab343b8bc
commit
88e39471ea
5 changed files with 10 additions and 63 deletions
|
|
@ -25,11 +25,6 @@ import type {
|
|||
ToolResultEventResult,
|
||||
} from "./types.js";
|
||||
|
||||
/**
|
||||
* Default timeout for hook execution (30 seconds).
|
||||
*/
|
||||
const DEFAULT_TIMEOUT = 30000;
|
||||
|
||||
/**
|
||||
* Listener for hook errors.
|
||||
*/
|
||||
|
|
@ -38,20 +33,6 @@ export type HookErrorListener = (error: HookError) => void;
|
|||
// Re-export execCommand for backward compatibility
|
||||
export { execCommand } from "../exec.js";
|
||||
|
||||
/**
|
||||
* Create a promise that rejects after a timeout.
|
||||
*/
|
||||
function createTimeout(ms: number): { promise: Promise<never>; clear: () => void } {
|
||||
let timeoutId: NodeJS.Timeout;
|
||||
const promise = new Promise<never>((_, reject) => {
|
||||
timeoutId = setTimeout(() => reject(new Error(`Hook timed out after ${ms}ms`)), ms);
|
||||
});
|
||||
return {
|
||||
promise,
|
||||
clear: () => clearTimeout(timeoutId),
|
||||
};
|
||||
}
|
||||
|
||||
/** No-op UI context used when no UI is available */
|
||||
const noOpUIContext: HookUIContext = {
|
||||
select: async () => undefined,
|
||||
|
|
@ -71,24 +52,16 @@ export class HookRunner {
|
|||
private cwd: string;
|
||||
private sessionManager: SessionManager;
|
||||
private modelRegistry: ModelRegistry;
|
||||
private timeout: number;
|
||||
private errorListeners: Set<HookErrorListener> = new Set();
|
||||
private getModel: () => Model<any> | undefined = () => undefined;
|
||||
|
||||
constructor(
|
||||
hooks: LoadedHook[],
|
||||
cwd: string,
|
||||
sessionManager: SessionManager,
|
||||
modelRegistry: ModelRegistry,
|
||||
timeout: number = DEFAULT_TIMEOUT,
|
||||
) {
|
||||
constructor(hooks: LoadedHook[], cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry) {
|
||||
this.hooks = hooks;
|
||||
this.uiContext = noOpUIContext;
|
||||
this.hasUI = false;
|
||||
this.cwd = cwd;
|
||||
this.sessionManager = sessionManager;
|
||||
this.modelRegistry = modelRegistry;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -262,16 +235,7 @@ export class HookRunner {
|
|||
|
||||
for (const handler of handlers) {
|
||||
try {
|
||||
// No timeout for session_before_compact events (like tool_call, they may take a while)
|
||||
let handlerResult: unknown;
|
||||
|
||||
if (event.type === "session_before_compact") {
|
||||
handlerResult = await handler(event, ctx);
|
||||
} else {
|
||||
const timeout = createTimeout(this.timeout);
|
||||
handlerResult = await Promise.race([handler(event, ctx), timeout.promise]);
|
||||
timeout.clear();
|
||||
}
|
||||
const handlerResult = await handler(event, ctx);
|
||||
|
||||
// For session before_* events, capture the result (for cancellation)
|
||||
if (this.isSessionBeforeEvent(event.type) && handlerResult) {
|
||||
|
|
@ -348,9 +312,7 @@ export class HookRunner {
|
|||
for (const handler of handlers) {
|
||||
try {
|
||||
const event: ContextEvent = { type: "context", messages: currentMessages };
|
||||
const timeout = createTimeout(this.timeout);
|
||||
const handlerResult = await Promise.race([handler(event, ctx), timeout.promise]);
|
||||
timeout.clear();
|
||||
const handlerResult = await handler(event, ctx);
|
||||
|
||||
if (handlerResult && (handlerResult as ContextEventResult).messages) {
|
||||
currentMessages = (handlerResult as ContextEventResult).messages!;
|
||||
|
|
@ -387,9 +349,7 @@ export class HookRunner {
|
|||
for (const handler of handlers) {
|
||||
try {
|
||||
const event: BeforeAgentStartEvent = { type: "before_agent_start", prompt, images };
|
||||
const timeout = createTimeout(this.timeout);
|
||||
const handlerResult = await Promise.race([handler(event, ctx), timeout.promise]);
|
||||
timeout.clear();
|
||||
const handlerResult = await handler(event, ctx);
|
||||
|
||||
// Take the first message returned
|
||||
if (handlerResult && (handlerResult as BeforeAgentStartEventResult).message && !result) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue