fix(llama-cpp): report cleanup recovery to initiating request

Punchcard-Session: frost-brook-timber-mx
This commit is contained in:
Vincent Koc
2026-08-05 14:46:39 +08:00
parent 8b443bb34f
commit 2b0e1e579a
2 changed files with 20 additions and 6 deletions
@@ -768,11 +768,14 @@ describe("llama.cpp inference provider", () => {
rejectCleanup = reject;
});
mocks.contextDispose.mockImplementationOnce(async () => await cleanup);
await createTestStream({ prompt: "three" });
const failedSwitch = await createTestStream({ prompt: "three" });
await vi.waitFor(() => expect(mocks.contextDispose).toHaveBeenCalledTimes(2));
const unavailable = await createTestStream({ selectedModel: otherModel, prompt: "four" });
const disposing = inferenceRuntime.dispose();
rejectCleanup(new Error("context cleanup failed"));
await expect(failedSwitch.result()).resolves.toMatchObject({
errorMessage: expect.stringContaining("openclaw gateway restart"),
});
await expect(unavailable.result()).resolves.toMatchObject({
errorMessage: expect.stringContaining("openclaw gateway restart"),
});
@@ -784,7 +787,10 @@ describe("llama.cpp inference provider", () => {
it("records cleanup failure during partial model initialization", async () => {
mocks.model.createContext.mockRejectedValueOnce(new Error("context creation failed"));
mocks.modelDispose.mockRejectedValueOnce(new Error("model cleanup failed"));
await collectTestEvents();
const failedInitialization = await createTestStream();
await expect(failedInitialization.result()).resolves.toMatchObject({
errorMessage: expect.stringContaining("openclaw gateway restart"),
});
await expect(inferenceRuntime.dispose()).rejects.toThrow("model cleanup failed");
expectDisposeCalls(0, 1, 0);
});
+12 -4
View File
@@ -86,6 +86,12 @@ function buildMessage(params: {
};
}
function runtimeUnavailableErrorMessage(state: LlamaCppInferenceRuntimeState): string {
return state.cleanupFailure
? "llama.cpp runtime stopped after cleanup failed. Run `openclaw gateway restart` to recover."
: "llama.cpp runtime is stopping";
}
function runtimeUnavailableMessage(
state: LlamaCppInferenceRuntimeState,
model: Parameters<StreamFn>[0],
@@ -94,9 +100,7 @@ function runtimeUnavailableMessage(
model,
content: [],
stopReason: "error",
errorMessage: state.cleanupFailure
? "llama.cpp runtime stopped after cleanup failed. Run `openclaw gateway restart` to recover."
: "llama.cpp runtime is stopping",
errorMessage: runtimeUnavailableErrorMessage(state),
});
}
@@ -682,7 +686,11 @@ function createLlamaCppStreamFnForRuntime(
} catch (error) {
const aborted = generationAborted || options?.signal?.aborted === true;
const reason = aborted ? "aborted" : "error";
const errorMessage = aborted ? "Request was aborted" : formatLlamaCppSetupError(error);
const errorMessage = aborted
? "Request was aborted"
: state.cleanupFailure
? runtimeUnavailableErrorMessage(state)
: formatLlamaCppSetupError(error);
stream.push({
type: "error",
reason,