Skip to content

Commit 497c8ad

Browse files
committed
🤖 fix: remove timeout from ask_user_question tool
The 30-minute timeout was too aggressive - users may step away and come back later. The tool now waits indefinitely for user input. It can still be canceled via: - User typing a chat message - Stream interruption (abort signal) - Workspace cleanup Signed-off-by: Thomas Kosiewski <[email protected]> --- _Generated with `mux`_ Change-Id: I3e5e5e9f697cc07ad8fb1cc854562d2e4b1111bf
1 parent 9647779 commit 497c8ad

File tree

2 files changed

+5
-40
lines changed

2 files changed

+5
-40
lines changed

src/node/services/askUserQuestionManager.test.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const QUESTIONS = [
1616

1717
describe("AskUserQuestionManager", () => {
1818
it("resolves when answered", async () => {
19-
const manager = new AskUserQuestionManager({ timeoutMs: 1000 });
19+
const manager = new AskUserQuestionManager();
2020

2121
const promise = manager.registerPending("ws", "tool-1", [...QUESTIONS]);
2222
manager.answer("ws", "tool-1", { "What should we do?": "A" });
@@ -27,7 +27,7 @@ describe("AskUserQuestionManager", () => {
2727
});
2828

2929
it("rejects when canceled", async () => {
30-
const manager = new AskUserQuestionManager({ timeoutMs: 1000 });
30+
const manager = new AskUserQuestionManager();
3131

3232
const promise = manager.registerPending("ws", "tool-1", [...QUESTIONS]);
3333

@@ -43,7 +43,7 @@ describe("AskUserQuestionManager", () => {
4343
});
4444

4545
it("tracks latest pending per workspace", async () => {
46-
const manager = new AskUserQuestionManager({ timeoutMs: 1000 });
46+
const manager = new AskUserQuestionManager();
4747

4848
const promise1 = manager.registerPending("ws", "tool-1", [...QUESTIONS]);
4949
await new Promise((r) => setTimeout(r, 5));
@@ -64,22 +64,4 @@ describe("AskUserQuestionManager", () => {
6464
expect(error1).toBeInstanceOf(Error);
6565
expect(error2).toBeInstanceOf(Error);
6666
});
67-
68-
it("times out and cleans up", async () => {
69-
const manager = new AskUserQuestionManager({ timeoutMs: 10 });
70-
71-
const promise = manager.registerPending("ws", "tool-1", [...QUESTIONS]);
72-
73-
let error: unknown;
74-
try {
75-
await promise;
76-
throw new Error("Expected promise to reject");
77-
} catch (err) {
78-
error = err;
79-
}
80-
81-
expect(error).toBeInstanceOf(Error);
82-
expect((error as Error).message).toContain("Timed out");
83-
expect(manager.getLatestPending("ws")).toBeNull();
84-
});
8567
});

src/node/services/askUserQuestionManager.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,10 @@ interface PendingAskUserQuestionInternal extends PendingAskUserQuestion {
1111
createdAt: number;
1212
resolve: (answers: Record<string, string>) => void;
1313
reject: (error: Error) => void;
14-
timeoutId: ReturnType<typeof setTimeout>;
1514
}
1615

1716
export class AskUserQuestionManager {
1817
private pendingByWorkspace = new Map<string, Map<string, PendingAskUserQuestionInternal>>();
19-
private readonly timeoutMs: number;
20-
21-
constructor(options?: { timeoutMs?: number }) {
22-
this.timeoutMs = options?.timeoutMs ?? 30 * 60 * 1000; // 30 minutes
23-
}
2418

2519
registerPending(
2620
workspaceId: string,
@@ -38,23 +32,12 @@ export class AskUserQuestionManager {
3832
);
3933

4034
return new Promise<Record<string, string>>((resolve, reject) => {
41-
const timeoutId = setTimeout(() => {
42-
this.cancel(workspaceId, toolCallId, "Timed out waiting for user answers");
43-
}, this.timeoutMs);
44-
4535
const entry: PendingAskUserQuestionInternal = {
4636
toolCallId,
4737
questions,
4838
createdAt: Date.now(),
49-
resolve: (answers) => {
50-
clearTimeout(timeoutId);
51-
resolve(answers);
52-
},
53-
reject: (error) => {
54-
clearTimeout(timeoutId);
55-
reject(error);
56-
},
57-
timeoutId,
39+
resolve,
40+
reject,
5841
};
5942

6043
workspaceMap.set(toolCallId, entry);

0 commit comments

Comments
 (0)