mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(copilot): defer background compaction hooks
This commit is contained in:
@@ -441,6 +441,38 @@ describe("runCopilotAttempt", () => {
|
||||
expect(beforeCompaction.mock.calls[0]?.[0]).not.toHaveProperty("messages");
|
||||
});
|
||||
|
||||
it("does not await background compaction hooks before returning a turn", async () => {
|
||||
const releaseBeforeCompaction = createDeferred<void>();
|
||||
const beforeCompaction = vi.fn(async () => releaseBeforeCompaction.promise);
|
||||
initializeGlobalHookRunner(
|
||||
createMockPluginRegistry([{ hookName: "before_compaction", handler: beforeCompaction }]),
|
||||
);
|
||||
let activeSession: FakeSession | undefined;
|
||||
const sdk = makeFakeSdk({
|
||||
onCreateSession: (session) => {
|
||||
activeSession = session;
|
||||
session.sendAndWait.mockImplementationOnce(async () => {
|
||||
session.emit("session.compaction_start", {});
|
||||
return makeAssistantMessageEvent("done");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const result = await runCopilotAttempt(makeParams(), { pool: makeFakePool(sdk) });
|
||||
|
||||
expect(result.timedOut).toBe(false);
|
||||
await vi.waitFor(() => {
|
||||
expect(beforeCompaction).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
expect(activeSession?.disconnect).not.toHaveBeenCalled();
|
||||
|
||||
releaseBeforeCompaction.resolve();
|
||||
activeSession?.emit("session.compaction_complete", { success: true });
|
||||
await vi.waitFor(() => {
|
||||
expect(activeSession?.disconnect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("returns a successful turn while background compaction remains observed", async () => {
|
||||
vi.useFakeTimers();
|
||||
const sdk = makeFakeSdk({
|
||||
|
||||
@@ -736,7 +736,6 @@ export async function runCopilotAttempt(
|
||||
}
|
||||
const result = await session.sendAndWait(messageOptions, input.timeoutMs);
|
||||
await bridge.awaitDeltaChain();
|
||||
await bridge.awaitCompactionChain();
|
||||
if (!bridge.recordSendResult(result) && !aborted) {
|
||||
// SDK sendAndWait returning undefined is treated as a timeout by the
|
||||
// capability inventory. Do not call session.abort() here: OpenClaw may
|
||||
@@ -778,7 +777,7 @@ export async function runCopilotAttempt(
|
||||
}
|
||||
} finally {
|
||||
settled = true;
|
||||
if (bridge?.isCompacting() && session && handle) {
|
||||
if (bridge?.hasObservedCompaction() && session && handle) {
|
||||
timedOutDuringCompaction ||= timedOut;
|
||||
const cleanupAbort = new AbortController();
|
||||
const abortCleanup = () => cleanupAbort.abort();
|
||||
|
||||
@@ -650,6 +650,7 @@ describe("attachEventBridge", () => {
|
||||
const completion = bridge.awaitCompactionCompletion();
|
||||
await flushAsync();
|
||||
|
||||
expect(bridge.hasObservedCompaction()).toBe(true);
|
||||
expect(complete).not.toHaveBeenCalled();
|
||||
session.emit(
|
||||
"session.compaction_complete",
|
||||
|
||||
@@ -70,6 +70,7 @@ export interface EventBridgeController {
|
||||
awaitCompactionChain(): Promise<void>;
|
||||
awaitCompactionCompletion(): Promise<void>;
|
||||
awaitDeltaChain(): Promise<void>;
|
||||
hasObservedCompaction(): boolean;
|
||||
isCompacting(): boolean;
|
||||
snapshot(): EventBridgeSnapshot;
|
||||
buildAssistantMessage(args: BuildAssistantMessageArgs): AssistantMessage | undefined;
|
||||
@@ -96,6 +97,7 @@ export function attachEventBridge(
|
||||
let startedCount = 0;
|
||||
let completedCount = 0;
|
||||
let activeCompactionCount = 0;
|
||||
let observedCompaction = false;
|
||||
let deltaQueue = Promise.resolve();
|
||||
let deltaChain = Promise.resolve();
|
||||
let compactionChain = Promise.resolve();
|
||||
@@ -182,6 +184,7 @@ export function attachEventBridge(
|
||||
});
|
||||
|
||||
registerListener(session, unsubscribeFns, "session.compaction_start", () => {
|
||||
observedCompaction = true;
|
||||
if (activeCompactionCount === 0) {
|
||||
compactionIdle = new Promise<void>((resolve) => {
|
||||
resolveCompactionIdle = resolve;
|
||||
@@ -248,6 +251,9 @@ export function attachEventBridge(
|
||||
awaitDeltaChain() {
|
||||
return deltaChain;
|
||||
},
|
||||
hasObservedCompaction() {
|
||||
return observedCompaction;
|
||||
},
|
||||
isCompacting() {
|
||||
return activeCompactionCount > 0;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user