feat(FN-3195): document llama.cpp provider setup and onboarding

Docs(FN-3195): adds llama.cpp provider setup and onboarding documentation to the main and dashboard READMEs.

Fusion-Task-Id: FN-3195
This commit is contained in:
Fusion
2026-05-04 10:12:43 -07:00
committed by gsxdsm
parent 43c2b29575
commit 1e73863ac6
37 changed files with 1440 additions and 38 deletions

View File

@@ -0,0 +1,44 @@
import { describe, expect, it, vi } from "vitest";
import extension from "../../index.js";
vi.mock("../retriever.js", () => ({
isLlamaServerReady: vi.fn(),
listLlamaModels: vi.fn(),
}));
vi.mock("../resolver.js", () => ({
resolveLlamaServerUrl: vi.fn(),
resolveLlamaServerApiKey: vi.fn(),
}));
import { isLlamaServerReady, listLlamaModels } from "../retriever.js";
import { resolveLlamaServerApiKey, resolveLlamaServerUrl } from "../resolver.js";
describe("pi-llama-cpp extension", () => {
it("does not register provider when server is offline", async () => {
vi.mocked(isLlamaServerReady).mockResolvedValue(false);
const registerProvider = vi.fn();
await extension({ registerProvider } as never);
expect(registerProvider).not.toHaveBeenCalled();
});
it("registers llama-server provider when server is reachable", async () => {
vi.mocked(isLlamaServerReady).mockResolvedValue(true);
vi.mocked(resolveLlamaServerUrl).mockResolvedValue("http://127.0.0.1:8080");
vi.mocked(resolveLlamaServerApiKey).mockResolvedValue("abc");
vi.mocked(listLlamaModels).mockResolvedValue([{ id: "qwen" }]);
const registerProvider = vi.fn();
await extension({ registerProvider } as never);
expect(registerProvider).toHaveBeenCalledTimes(1);
expect(registerProvider).toHaveBeenCalledWith(
"llama-server",
expect.objectContaining({
api: "openai-completions",
baseUrl: "http://127.0.0.1:8080/v1",
apiKey: "abc",
}),
);
});
});

View File

@@ -0,0 +1,65 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
resetLlamaResolverCache,
resolveLlamaServerApiKey,
resolveLlamaServerUrl,
} from "../resolver.js";
const readFileMock = vi.fn();
vi.mock("node:fs/promises", () => ({
readFile: (...args: unknown[]) => readFileMock(...args),
}));
describe("resolveLlamaServerUrl", () => {
const originalEnv = process.env;
beforeEach(() => {
vi.resetAllMocks();
resetLlamaResolverCache();
process.env = { ...originalEnv };
delete process.env.LLAMA_SERVER_URL;
});
afterEach(() => {
process.env = originalEnv;
});
it("uses project config first", async () => {
readFileMock.mockResolvedValueOnce('{"url":"http://localhost:8081/"}');
const url = await resolveLlamaServerUrl("/tmp/project");
expect(url).toBe("http://localhost:8081");
});
it("falls back to env var", async () => {
readFileMock.mockRejectedValueOnce(new Error("missing"));
process.env.LLAMA_SERVER_URL = "http://localhost:9999/";
const url = await resolveLlamaServerUrl("/tmp/project");
expect(url).toBe("http://localhost:9999");
});
it("falls back to default", async () => {
readFileMock.mockRejectedValue(new Error("missing"));
const url = await resolveLlamaServerUrl("/tmp/project");
expect(url).toBe("http://127.0.0.1:8080");
});
});
describe("resolveLlamaServerApiKey", () => {
beforeEach(() => {
vi.resetAllMocks();
});
it("returns undefined when not configured", async () => {
readFileMock.mockRejectedValueOnce(new Error("missing"));
await expect(resolveLlamaServerApiKey()).resolves.toBeUndefined();
});
it("returns provider key for llama-server", async () => {
readFileMock.mockResolvedValueOnce(
JSON.stringify({
"llama-server": { type: "api_key", key: "secret-token" },
}),
);
await expect(resolveLlamaServerApiKey()).resolves.toBe("secret-token");
});
});