mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 13:44:58 +00:00
fix(agents): avoid synthetic tool-result writes on idle-timeout cleanup
This commit is contained in:
@@ -817,6 +817,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
await flushPendingToolResultsAfterIdle({
|
||||
agent: session?.agent,
|
||||
sessionManager,
|
||||
clearPendingOnTimeout: true,
|
||||
});
|
||||
session.dispose();
|
||||
}
|
||||
|
||||
@@ -1338,6 +1338,7 @@ export async function runEmbeddedAttempt(
|
||||
await flushPendingToolResultsAfterIdle({
|
||||
agent: activeSession?.agent,
|
||||
sessionManager,
|
||||
clearPendingOnTimeout: true,
|
||||
});
|
||||
activeSession.dispose();
|
||||
throw err;
|
||||
@@ -1904,6 +1905,7 @@ export async function runEmbeddedAttempt(
|
||||
await flushPendingToolResultsAfterIdle({
|
||||
agent: session?.agent,
|
||||
sessionManager,
|
||||
clearPendingOnTimeout: true,
|
||||
});
|
||||
session?.dispose();
|
||||
releaseWsSession(params.sessionId);
|
||||
|
||||
@@ -4,6 +4,7 @@ type IdleAwareAgent = {
|
||||
|
||||
type ToolResultFlushManager = {
|
||||
flushPendingToolResults?: (() => void) | undefined;
|
||||
clearPendingToolResults?: (() => void) | undefined;
|
||||
};
|
||||
|
||||
export const DEFAULT_WAIT_FOR_IDLE_TIMEOUT_MS = 30_000;
|
||||
@@ -11,23 +12,27 @@ export const DEFAULT_WAIT_FOR_IDLE_TIMEOUT_MS = 30_000;
|
||||
async function waitForAgentIdleBestEffort(
|
||||
agent: IdleAwareAgent | null | undefined,
|
||||
timeoutMs: number,
|
||||
): Promise<void> {
|
||||
): Promise<boolean> {
|
||||
const waitForIdle = agent?.waitForIdle;
|
||||
if (typeof waitForIdle !== "function") {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const idleResolved = Symbol("idle");
|
||||
const idleTimedOut = Symbol("timeout");
|
||||
let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
|
||||
try {
|
||||
await Promise.race([
|
||||
waitForIdle.call(agent),
|
||||
new Promise<void>((resolve) => {
|
||||
timeoutHandle = setTimeout(resolve, timeoutMs);
|
||||
const outcome = await Promise.race([
|
||||
waitForIdle.call(agent).then(() => idleResolved),
|
||||
new Promise<symbol>((resolve) => {
|
||||
timeoutHandle = setTimeout(() => resolve(idleTimedOut), timeoutMs);
|
||||
timeoutHandle.unref?.();
|
||||
}),
|
||||
]);
|
||||
return outcome === idleTimedOut;
|
||||
} catch {
|
||||
// Best-effort during cleanup.
|
||||
return false;
|
||||
} finally {
|
||||
if (timeoutHandle) {
|
||||
clearTimeout(timeoutHandle);
|
||||
@@ -39,7 +44,15 @@ export async function flushPendingToolResultsAfterIdle(opts: {
|
||||
agent: IdleAwareAgent | null | undefined;
|
||||
sessionManager: ToolResultFlushManager | null | undefined;
|
||||
timeoutMs?: number;
|
||||
clearPendingOnTimeout?: boolean;
|
||||
}): Promise<void> {
|
||||
await waitForAgentIdleBestEffort(opts.agent, opts.timeoutMs ?? DEFAULT_WAIT_FOR_IDLE_TIMEOUT_MS);
|
||||
const timedOut = await waitForAgentIdleBestEffort(
|
||||
opts.agent,
|
||||
opts.timeoutMs ?? DEFAULT_WAIT_FOR_IDLE_TIMEOUT_MS,
|
||||
);
|
||||
if (timedOut && opts.clearPendingOnTimeout && opts.sessionManager?.clearPendingToolResults) {
|
||||
opts.sessionManager.clearPendingToolResults();
|
||||
return;
|
||||
}
|
||||
opts.sessionManager?.flushPendingToolResults?.();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user