mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 14:58:36 +00:00
fix(agents): default non-finite run wait timeouts
This commit is contained in:
@@ -252,6 +252,22 @@ describe("waitForAgentRun", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("defaults non-finite wait timeouts before sending agent.wait", async () => {
|
||||
callGatewayMock.mockResolvedValue({ status: "ok" });
|
||||
|
||||
const result = await waitForAgentRun({ runId: "run-nan", timeoutMs: Number.NaN });
|
||||
|
||||
expect(result).toEqual({ status: "ok" });
|
||||
expect(callGatewayMock).toHaveBeenCalledWith({
|
||||
method: "agent.wait",
|
||||
params: {
|
||||
runId: "run-nan",
|
||||
timeoutMs: 1,
|
||||
},
|
||||
timeoutMs: 2_001,
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves timing metadata from agent.wait", async () => {
|
||||
callGatewayMock.mockResolvedValue({
|
||||
status: "ok",
|
||||
@@ -457,4 +473,22 @@ describe("waitForAgentRunsToDrain", () => {
|
||||
expectAgentWaitRequest(requireRequestAt(requests, 0), "run-1", 1_000);
|
||||
expectAgentWaitRequest(requireRequestAt(requests, 1), "run-2", 1_000);
|
||||
});
|
||||
|
||||
it("defaults non-finite drain timeouts before computing the deadline", async () => {
|
||||
callGatewayMock.mockResolvedValue({ status: "ok" });
|
||||
let activeRunIds = ["run-1"];
|
||||
|
||||
const result = await waitForAgentRunsToDrain({
|
||||
timeoutMs: Number.NaN,
|
||||
getPendingRunIds: () => {
|
||||
const current = activeRunIds;
|
||||
activeRunIds = [];
|
||||
return current;
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.timedOut).toBe(false);
|
||||
expect(Number.isFinite(result.deadlineAtMs)).toBe(true);
|
||||
expectAgentWaitRequest(requireRequestAt(gatewayWaitRequests(), 0), "run-1", 1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { normalizeBlockedLivenessWaitStatus } from "../shared/agent-liveness.js";
|
||||
import { parseFiniteNumber } from "../shared/number-coercion.js";
|
||||
import { AGENT_RUN_ABORTED_ERROR, isAbortedAgentStopReason } from "./run-termination.js";
|
||||
import {
|
||||
normalizeAgentRunTimeoutPhase,
|
||||
@@ -19,6 +20,10 @@ let runWaitDeps: {
|
||||
callGateway: GatewayCaller;
|
||||
} = defaultRunWaitDeps;
|
||||
|
||||
function resolveRunWaitTimeoutMs(value: number | undefined): number {
|
||||
return Math.max(1, Math.floor(parseFiniteNumber(value) ?? 1));
|
||||
}
|
||||
|
||||
export type AssistantReplySnapshot = {
|
||||
text?: string;
|
||||
fingerprint?: string;
|
||||
@@ -176,7 +181,7 @@ export async function waitForAgentRun(params: {
|
||||
timeoutMs: number;
|
||||
callGateway?: GatewayCaller;
|
||||
}): Promise<AgentWaitResult> {
|
||||
const timeoutMs = Math.max(1, Math.floor(params.timeoutMs));
|
||||
const timeoutMs = resolveRunWaitTimeoutMs(params.timeoutMs);
|
||||
try {
|
||||
const wait = await (params.callGateway ?? runWaitDeps.callGateway)({
|
||||
method: "agent.wait",
|
||||
@@ -246,7 +251,7 @@ export async function waitForAgentRunsToDrain(params: {
|
||||
callGateway?: GatewayCaller;
|
||||
}): Promise<AgentRunsDrainResult> {
|
||||
const deadlineAtMs =
|
||||
params.deadlineAtMs ?? Date.now() + Math.max(1, Math.floor(params.timeoutMs ?? 0));
|
||||
params.deadlineAtMs ?? Date.now() + resolveRunWaitTimeoutMs(params.timeoutMs);
|
||||
|
||||
// Runs may finish and spawn more runs, so refresh until no pending IDs remain.
|
||||
let pendingRunIds = new Set<string>(
|
||||
|
||||
Reference in New Issue
Block a user