Skip to content

Commit a033b83

Browse files
authored
🤖 fix: add elapsed_ms to bash_output to help detect busy loops (#1046)
## Problem After restarting the app, agents can get stuck in tight loops calling `bash_output` repeatedly on processes that no longer exist or have already exited. The agent has no way to detect that responses are returning immediately with no useful information. ## Solution 1. **Add `elapsed_ms` to bash_output response** - Shows how long the tool spent waiting for output. If this is very low (<10ms), it suggests no real waiting occurred. 2. **Add warning note for suspicious patterns** - When a response is fast (<10ms), empty, and the process has exited, add a note: "Process has exited and no new output. Avoid repeated polling of completed processes." This gives agents actionable feedback to break out of busy loops. ## Changes - `src/common/types/tools.ts`: Add `elapsed_ms` field to `BashOutputToolResult` - `src/node/services/backgroundProcessManager.ts`: Return `elapsed_ms` from `getOutput()` - `src/node/services/tools/bash_output.ts`: Add warning note for fast empty responses on exited processes - `src/node/services/backgroundProcessManager.test.ts`: Add test for `elapsed_ms` ## Testing All existing tests pass plus new test for `elapsed_ms` field. _Generated with `mux`_
1 parent bfdb809 commit a033b83

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

src/common/types/tools.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ export type BashOutputToolResult =
239239
output: string;
240240
exitCode?: number;
241241
note?: string; // Agent-only message (not displayed in UI)
242+
// Time spent waiting for output (helps agent detect/avoid busy loops)
243+
elapsed_ms: number;
242244
}
243245
| { success: false; error: string };
244246

src/node/services/backgroundProcessManager.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,25 @@ describe("BackgroundProcessManager", () => {
451451
expect(output.output).toContain("error message");
452452
});
453453

454+
it("should include elapsed_ms in response", async () => {
455+
const result = await manager.spawn(runtime, testWorkspaceId, "sleep 0.2; echo done", {
456+
cwd: process.cwd(),
457+
displayName: "test",
458+
});
459+
460+
expect(result.success).toBe(true);
461+
if (!result.success) return;
462+
463+
// Wait with timeout to ensure blocking
464+
const output = await manager.getOutput(result.processId, undefined, 1);
465+
expect(output.success).toBe(true);
466+
if (!output.success) return;
467+
468+
// elapsed_ms should be present and reflect the wait time
469+
expect(typeof output.elapsed_ms).toBe("number");
470+
expect(output.elapsed_ms).toBeGreaterThanOrEqual(0);
471+
});
472+
454473
it("should return error for non-existent process", async () => {
455474
const output = await manager.getOutput("bash_nonexistent");
456475
expect(output.success).toBe(false);

src/node/services/backgroundProcessManager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ export class BackgroundProcessManager extends EventEmitter<BackgroundProcessMana
421421
status: "running" | "exited" | "killed" | "failed";
422422
output: string;
423423
exitCode?: number;
424+
elapsed_ms: number;
424425
}
425426
| { success: false; error: string }
426427
> {
@@ -507,6 +508,7 @@ export class BackgroundProcessManager extends EventEmitter<BackgroundProcessMana
507508
currentStatus !== "running"
508509
? ((await this.getProcess(processId))?.exitCode ?? undefined)
509510
: undefined,
511+
elapsed_ms: Date.now() - startTime,
510512
};
511513
}
512514

src/node/services/tools/bash_output.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const createBashOutputTool: ToolFactory = (config: ToolConfiguration) =>
3131
if (!proc || proc.workspaceId !== config.workspaceId) {
3232
return {
3333
success: false,
34-
error: `Process not found: ${process_id}`,
34+
error: `Process not found: ${process_id}. The process may have exited or the app was restarted. Do not retry - use bash_background_list to see active processes.`,
3535
};
3636
}
3737

0 commit comments

Comments
 (0)