Files
wehub-resource-sync 555e282cc4
pi-agent-plugin checks / lint (push) Has been cancelled
pi-agent-plugin checks / test (20) (push) Has been cancelled
pi-agent-plugin checks / test (22) (push) Has been cancelled
pi-agent-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / check_changes (push) Has been cancelled
TypeScript SDK CI / changelog_check (push) Has been cancelled
ci / changelog_check (push) Has been cancelled
ci / check_changes (push) Has been cancelled
ci / build_mem0 (3.10) (push) Has been cancelled
ci / build_mem0 (3.11) (push) Has been cancelled
ci / build_mem0 (3.12) (push) Has been cancelled
CLI Node CI / lint (push) Has been cancelled
CLI Node CI / test (20) (push) Has been cancelled
CLI Node CI / test (22) (push) Has been cancelled
CLI Node CI / build (push) Has been cancelled
CLI Python CI / lint (push) Has been cancelled
CLI Python CI / test (3.10) (push) Has been cancelled
CLI Python CI / test (3.11) (push) Has been cancelled
CLI Python CI / test (3.12) (push) Has been cancelled
CLI Python CI / build (push) Has been cancelled
openclaw checks / lint (push) Has been cancelled
openclaw checks / test (20) (push) Has been cancelled
openclaw checks / test (22) (push) Has been cancelled
openclaw checks / build (push) Has been cancelled
opencode-plugin checks / build (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / build_ts_sdk (22) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (20) (push) Has been cancelled
TypeScript SDK CI / integration_ts_sdk (22) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:45 +08:00

241 lines
8.4 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
LLM_PROVIDERS,
EMBEDDER_PROVIDERS,
VECTOR_PROVIDERS,
KNOWN_EMBEDDER_DIMS,
buildOssLlmConfig,
buildOssEmbedderConfig,
buildOssVectorConfig,
collectionNameForDims,
validateOssFlags,
checkQdrantConnectivity,
checkOllamaConnectivity,
checkPgConnectivity,
} from "../cli/oss-wizard.ts";
describe("LLM_PROVIDERS", () => {
it("has 3 providers", () => {
expect(LLM_PROVIDERS).toHaveLength(3);
expect(LLM_PROVIDERS.map((p) => p.id)).toEqual(["openai", "ollama", "anthropic"]);
});
it("openai requires API key", () => {
const openai = LLM_PROVIDERS.find((p) => p.id === "openai")!;
expect(openai.needsApiKey).toBe(true);
expect(openai.defaultModel).toBe("gpt-5-mini");
});
it("ollama needs no API key but needs URL", () => {
const ollama = LLM_PROVIDERS.find((p) => p.id === "ollama")!;
expect(ollama.needsApiKey).toBe(false);
expect(ollama.needsUrl).toBe(true);
expect(ollama.defaultUrl).toBe("http://localhost:11434");
});
});
describe("EMBEDDER_PROVIDERS", () => {
it("has 2 providers", () => {
expect(EMBEDDER_PROVIDERS).toHaveLength(2);
});
});
describe("KNOWN_EMBEDDER_DIMS", () => {
it("maps default models to dims", () => {
expect(KNOWN_EMBEDDER_DIMS["text-embedding-3-small"]).toBe(1536);
expect(KNOWN_EMBEDDER_DIMS["nomic-embed-text"]).toBe(768);
});
});
describe("buildOssLlmConfig", () => {
it("builds openai config with API key", () => {
const result = buildOssLlmConfig("openai", { apiKey: "sk-test" });
expect(result).toEqual({
provider: "openai",
config: { model: "gpt-5-mini", apiKey: "sk-test" },
});
});
it("builds ollama config with custom URL and model", () => {
const result = buildOssLlmConfig("ollama", { url: "http://myhost:11434", model: "mistral" });
expect(result).toEqual({
provider: "ollama",
config: { model: "mistral", url: "http://myhost:11434" },
});
});
it("builds ollama config with default URL", () => {
const result = buildOssLlmConfig("ollama", {});
expect(result.config.url).toBe("http://localhost:11434");
});
it("ignores url for non-ollama providers", () => {
const result = buildOssLlmConfig("anthropic", { apiKey: "sk-ant", url: "http://ignored" });
expect(result.config).not.toHaveProperty("url");
expect(result.config).toHaveProperty("apiKey", "sk-ant");
});
});
describe("buildOssEmbedderConfig", () => {
it("builds openai embedder", () => {
const result = buildOssEmbedderConfig("openai", { apiKey: "sk-test" });
expect(result.config.model).toBe("text-embedding-3-small");
expect(result.dims).toBe(1536);
});
it("builds ollama embedder with url field", () => {
const result = buildOssEmbedderConfig("ollama", { url: "http://myhost:11434" });
expect(result.config.url).toBe("http://myhost:11434");
expect(result.config).not.toHaveProperty("ollama_base_url");
expect(result.config.model).toBe("nomic-embed-text");
expect(result.dims).toBe(768);
});
it("falls back to provider default dims for custom model", () => {
const result = buildOssEmbedderConfig("ollama", { model: "custom-embed" });
expect(result.dims).toBe(768);
});
});
describe("VECTOR_PROVIDERS", () => {
it("has 2 providers", () => {
expect(VECTOR_PROVIDERS).toHaveLength(2);
expect(VECTOR_PROVIDERS.map((p) => p.id)).toEqual(["qdrant", "pgvector"]);
});
it("qdrant requires server connection", () => {
const qdrant = VECTOR_PROVIDERS.find((p) => p.id === "qdrant")!;
expect(qdrant.needsConnection).toBe(true);
expect(qdrant.defaultUrl).toBe("http://localhost:6333");
expect(qdrant.setupHint).toContain("docker");
});
it("pgvector requires connection and has setup hint", () => {
const pg = VECTOR_PROVIDERS.find((p) => p.id === "pgvector")!;
expect(pg.needsConnection).toBe(true);
expect(pg.defaultPort).toBe(5432);
expect(pg.setupHint).toContain("pgvector");
});
});
describe("buildOssVectorConfig", () => {
it("builds qdrant with default url and dims", () => {
const result = buildOssVectorConfig("qdrant", { dims: 1536 });
expect(result.config.url).toBe("http://localhost:6333");
expect(result.config.onDisk).toBe(true);
expect(result.config.dimension).toBe(1536);
});
it("builds qdrant with custom url", () => {
const result = buildOssVectorConfig("qdrant", { url: "http://qdrant.local:6333", dims: 768 });
expect(result.config.url).toBe("http://qdrant.local:6333");
expect(result.config.onDisk).toBe(true);
expect(result.config.dimension).toBe(768);
});
it("builds qdrant with api key for cloud", () => {
const result = buildOssVectorConfig("qdrant", { url: "https://cloud.qdrant.io", apiKey: "qd-key", dims: 1536 });
expect(result.config.apiKey).toBe("qd-key");
expect(result.config.url).toBe("https://cloud.qdrant.io");
});
it("builds pgvector with connection details", () => {
const result = buildOssVectorConfig("pgvector", {
host: "db.local", port: "5432", user: "me", password: "pw", dbname: "mydb", dims: 512,
});
expect(result.config.host).toBe("db.local");
expect(result.config.dimension).toBe(512);
});
});
describe("collectionNameForDims", () => {
it("generates dimension-based collection name", () => {
expect(collectionNameForDims(1536)).toBe("mem0_1536d");
expect(collectionNameForDims(768)).toBe("mem0_768d");
expect(collectionNameForDims(384)).toBe("mem0_384d");
});
});
describe("buildOssVectorConfig dimension safety", () => {
it("sets both dimension and embeddingModelDims when dims provided", () => {
const result = buildOssVectorConfig("qdrant", { dims: 768 });
expect(result.config.dimension).toBe(768);
expect(result.config.embeddingModelDims).toBe(768);
});
it("sets collectionName based on dims", () => {
const result = buildOssVectorConfig("qdrant", { dims: 768 });
expect(result.config.collectionName).toBe("mem0_768d");
});
it("uses different collection names for different dims", () => {
const r1 = buildOssVectorConfig("qdrant", { dims: 1536 });
const r2 = buildOssVectorConfig("qdrant", { dims: 768 });
expect(r1.config.collectionName).not.toBe(r2.config.collectionName);
});
it("omits dimension fields when dims not provided", () => {
const result = buildOssVectorConfig("qdrant", {});
expect(result.config.dimension).toBeUndefined();
expect(result.config.embeddingModelDims).toBeUndefined();
expect(result.config.collectionName).toBeUndefined();
});
it("works with pgvector too", () => {
const result = buildOssVectorConfig("pgvector", {
host: "localhost", port: "5432", user: "me", password: "pw", dbname: "test", dims: 768,
});
expect(result.config.dimension).toBe(768);
expect(result.config.embeddingModelDims).toBe(768);
expect(result.config.collectionName).toBe("mem0_768d");
});
});
describe("checkQdrantConnectivity", () => {
it("returns error for unreachable host", async () => {
const result = await checkQdrantConnectivity("http://localhost:19999");
expect(result.ok).toBe(false);
expect(result.error).toContain("Cannot reach Qdrant");
});
});
describe("checkOllamaConnectivity", () => {
it("returns error for unreachable host", async () => {
const result = await checkOllamaConnectivity("http://localhost:19998");
expect(result.ok).toBe(false);
expect(result.error).toContain("Cannot reach Ollama");
});
});
describe("checkPgConnectivity", () => {
it("returns error for unreachable host", async () => {
const result = await checkPgConnectivity("localhost", 19997);
expect(result.ok).toBe(false);
expect(result.error).toContain("PostgreSQL not reachable");
});
});
describe("validateOssFlags", () => {
it("returns error when openai LLM has no key", () => {
const result = validateOssFlags({ ossLlm: "openai" });
expect(result.error).toContain("--oss-llm-key");
});
it("passes for ollama with no key", () => {
const result = validateOssFlags({ ossLlm: "ollama", ossEmbedder: "ollama", ossVector: "qdrant" });
expect(result.error).toBeUndefined();
});
it("returns error for unknown provider", () => {
const result = validateOssFlags({ ossLlm: "bogus" });
expect(result.error).toContain("Unknown LLM provider");
});
it("returns error when pgvector missing user", () => {
const result = validateOssFlags({
ossLlm: "ollama", ossEmbedder: "ollama", ossVector: "pgvector",
});
expect(result.error).toContain("--oss-vector-user");
});
});