From edc294db4fcb987269cd53c9dd40eb90d30b8af2 Mon Sep 17 00:00:00 2001 From: Tobi Lutke Date: Sun, 21 Dec 2025 13:42:38 -0400 Subject: [PATCH] Don't dispose llama in tests - let process exit handle cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Metal backend crash happens regardless of whether we dispose or not. It's a known llama.cpp issue during process exit static destructor cleanup: https://github.com/ggml-org/llama.cpp/pull/17869 All 297 tests pass - the abort happens after tests complete. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/eval.test.ts | 5 ++--- src/llm.test.ts | 9 +++------ src/mcp.test.ts | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/eval.test.ts b/src/eval.test.ts index f4e7576..7b8fe57 100644 --- a/src/eval.test.ts +++ b/src/eval.test.ts @@ -392,8 +392,7 @@ describe("Hybrid Search (RRF)", () => { // Cleanup // ============================================================================= -afterAll(async () => { - // Dispose llama before process exit to properly free Metal resources - await disposeDefaultLlamaCpp(); +afterAll(() => { + // Don't dispose llama - let process exit handle Metal cleanup naturally rmSync(tempDir, { recursive: true, force: true }); }); diff --git a/src/llm.test.ts b/src/llm.test.ts index 8063065..b643056 100644 --- a/src/llm.test.ts +++ b/src/llm.test.ts @@ -12,6 +12,7 @@ import { LlamaCpp, getDefaultLlamaCpp, setDefaultLlamaCpp, + disposeDefaultLlamaCpp, type RerankDocument, } from "./llm.js"; @@ -20,9 +21,7 @@ import { // ============================================================================= describe("Default LlamaCpp Singleton", () => { - afterAll(() => { - setDefaultLlamaCpp(null); - }); + // Don't dispose - let process exit handle Metal cleanup naturally test("getDefaultLlamaCpp creates instance on first call", () => { setDefaultLlamaCpp(null); @@ -87,9 +86,7 @@ describe("LlamaCpp Integration", () => { llm = new LlamaCpp(); }); - afterAll(async () => { - await llm.dispose(); - }); + // Don't dispose - let process exit handle Metal cleanup naturally describe("embed", () => { test("returns embedding with correct dimensions", async () => { diff --git a/src/mcp.test.ts b/src/mcp.test.ts index 7d1031b..6f6477e 100644 --- a/src/mcp.test.ts +++ b/src/mcp.test.ts @@ -10,7 +10,7 @@ import { Database } from "bun:sqlite"; import * as sqliteVec from "sqlite-vec"; import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; -import { setDefaultLlamaCpp, LlamaCpp } from "./llm"; +import { setDefaultLlamaCpp, disposeDefaultLlamaCpp, LlamaCpp } from "./llm"; import { mkdtemp, writeFile, readdir, unlink, rmdir } from "node:fs/promises"; import { join } from "node:path"; import { tmpdir } from "node:os"; @@ -225,7 +225,7 @@ describe("MCP Server", () => { }); afterAll(async () => { - setDefaultLlamaCpp(null); + // Don't dispose llama - let process exit handle Metal cleanup naturally testDb.close(); try { require("fs").unlinkSync(testDbPath);