Skip to content

Commit 9091a7a

Browse files
carderneTrigger.dev RepoOps
authored andcommitted
fix(dashboard-agent): replace fixed 30ms eval wait with deterministic poll
Mono-RevId: dd197d9c6b561976f0a005411fa44c4bdc8e799c
1 parent 1ac26a4 commit 9091a7a

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎internal-packages/dashboard-agent/src/test-support.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,26 @@ export function fakeEvalTrigger(): { trigger: DashboardAgentEvalTrigger; calls:
281281
};
282282
}
283283

284+
/**
285+
* Waits until `calls` has at least `count` entries, with a generous deadline.
286+
* Use this instead of a fixed setTimeout after sendMessage when asserting evals,
287+
* because onTurnComplete fires after the turn-complete chunk and the gap is not
288+
* bounded at 30 ms under load.
289+
*/
290+
export async function waitForEvals(
291+
calls: unknown[],
292+
count: number,
293+
timeoutMs = 5_000
294+
): Promise<void> {
295+
const deadline = Date.now() + timeoutMs;
296+
while (calls.length < count) {
297+
if (Date.now() > deadline) {
298+
throw new Error(`timed out waiting for ${count} eval(s); got ${calls.length}`);
299+
}
300+
await new Promise((r) => setTimeout(r, 10));
301+
}
302+
}
303+
284304
/** Stands in for the org opt-out check, so no test depends on a network call. */
285305
export function fakeEvalPolicy(allowed = true): DashboardAgentEvalPolicyCheck {
286306
return async () => allowed;

‎internal-packages/dashboard-agent/src/watch-actions.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
fakeEvalPolicy,
2727
fakeEvalTrigger,
2828
fakeStore,
29+
waitForEvals,
2930
finish,
3031
mockModel,
3132
savedPuts,
@@ -429,8 +430,7 @@ describe("watch wake narration", () => {
429430
await harness.sendAction(FAILED_RUN_WAKE);
430431
settlementDown = false;
431432
await harness.sendMessage(userMessage("what happened?"));
432-
// onTurnComplete enqueues after the turn-complete chunk, so give it a tick.
433-
await new Promise((r) => setTimeout(r, 30));
433+
await waitForEvals(evals, 1);
434434

435435
// The wake ran as a bounded small-model call; the typed turn ran uncapped.
436436
expect(calls[0]).toEqual({ tools: 0, maxOutputTokens: 300 });

0 commit comments

Comments
 (0)