From b8e6bab3fe443ee92180d047feef07132086bfed Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Sun, 15 Mar 2026 21:18:53 +0000 Subject: [PATCH] Memory: share runtime backend definitions --- .../embedding-runtime-backends.test.ts | 34 +++++++++++++++++++ .../embedding-runtime-backends.ts | 23 +++++++++++++ .../embedding-runtime-registry.ts | 14 +++----- src/extension-host/embedding-runtime.ts | 6 ++-- .../runtime-backend-catalog.test.ts | 13 ++++++- src/extension-host/runtime-backend-catalog.ts | 16 ++++----- 6 files changed, 81 insertions(+), 25 deletions(-) create mode 100644 src/extension-host/embedding-runtime-backends.test.ts create mode 100644 src/extension-host/embedding-runtime-backends.ts diff --git a/src/extension-host/embedding-runtime-backends.test.ts b/src/extension-host/embedding-runtime-backends.test.ts new file mode 100644 index 00000000000..5441ff96fbb --- /dev/null +++ b/src/extension-host/embedding-runtime-backends.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { + DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL, + EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS, + EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS, + isExtensionHostEmbeddingRuntimeBackendAutoSelectable, +} from "./embedding-runtime-backends.js"; + +describe("embedding-runtime-backends", () => { + it("keeps the built-in embedding backend order stable", () => { + expect(DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL).toContain("embeddinggemma"); + expect(EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS).toEqual([ + "openai", + "gemini", + "voyage", + "mistral", + ]); + expect(EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS).toEqual([ + "local", + "openai", + "gemini", + "voyage", + "mistral", + "ollama", + ]); + }); + + it("marks only local and remote embedding backends as auto-selectable", () => { + expect(isExtensionHostEmbeddingRuntimeBackendAutoSelectable("local")).toBe(true); + expect(isExtensionHostEmbeddingRuntimeBackendAutoSelectable("openai")).toBe(true); + expect(isExtensionHostEmbeddingRuntimeBackendAutoSelectable("mistral")).toBe(true); + expect(isExtensionHostEmbeddingRuntimeBackendAutoSelectable("ollama")).toBe(false); + }); +}); diff --git a/src/extension-host/embedding-runtime-backends.ts b/src/extension-host/embedding-runtime-backends.ts new file mode 100644 index 00000000000..7de07359def --- /dev/null +++ b/src/extension-host/embedding-runtime-backends.ts @@ -0,0 +1,23 @@ +import type { EmbeddingProviderId } from "./embedding-runtime-types.js"; + +export const DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL = + "hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf"; + +export const EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS = [ + "openai", + "gemini", + "voyage", + "mistral", +] as const satisfies readonly EmbeddingProviderId[]; + +export const EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS = [ + "local", + ...EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS, + "ollama", +] as const satisfies readonly EmbeddingProviderId[]; + +export function isExtensionHostEmbeddingRuntimeBackendAutoSelectable( + backendId: EmbeddingProviderId, +): boolean { + return backendId === "local" || EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS.includes(backendId); +} diff --git a/src/extension-host/embedding-runtime-registry.ts b/src/extension-host/embedding-runtime-registry.ts index 4a3c1efe782..d6e46d3395b 100644 --- a/src/extension-host/embedding-runtime-registry.ts +++ b/src/extension-host/embedding-runtime-registry.ts @@ -25,6 +25,10 @@ import { } from "../memory/embeddings-voyage.js"; import { importNodeLlamaCpp } from "../memory/node-llama.js"; import { resolveUserPath } from "../utils.js"; +import { + DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL, + EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS, +} from "./embedding-runtime-backends.js"; import type { EmbeddingProvider, EmbeddingProviderId, @@ -41,16 +45,6 @@ export type { VoyageEmbeddingClient, }; -export const DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL = - "hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf"; - -export const EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS = [ - "openai", - "gemini", - "voyage", - "mistral", -] as const satisfies readonly EmbeddingProviderId[]; - export function canAutoSelectExtensionHostLocalEmbedding( options: EmbeddingProviderOptions, ): boolean { diff --git a/src/extension-host/embedding-runtime.ts b/src/extension-host/embedding-runtime.ts index 04ebf0cd5a5..53094b6cbfb 100644 --- a/src/extension-host/embedding-runtime.ts +++ b/src/extension-host/embedding-runtime.ts @@ -1,7 +1,5 @@ -import { - DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL, - createExtensionHostEmbeddingProvider, -} from "./embedding-runtime-registry.js"; +import { DEFAULT_EXTENSION_HOST_LOCAL_EMBEDDING_MODEL } from "./embedding-runtime-backends.js"; +import { createExtensionHostEmbeddingProvider } from "./embedding-runtime-registry.js"; import type { EmbeddingProviderOptions, EmbeddingProviderResult, diff --git a/src/extension-host/runtime-backend-catalog.test.ts b/src/extension-host/runtime-backend-catalog.test.ts index c30671e6ed6..eddaf5633ac 100644 --- a/src/extension-host/runtime-backend-catalog.test.ts +++ b/src/extension-host/runtime-backend-catalog.test.ts @@ -1,7 +1,18 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -vi.mock("./embedding-runtime-registry.js", () => ({ +vi.mock("./embedding-runtime-backends.js", () => ({ + EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS: [ + "local", + "openai", + "gemini", + "voyage", + "mistral", + "ollama", + ], EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS: ["openai", "gemini", "voyage", "mistral"], + isExtensionHostEmbeddingRuntimeBackendAutoSelectable: vi.fn( + (backendId: string) => backendId !== "ollama", + ), })); vi.mock("./media-runtime-registry.js", () => ({ diff --git a/src/extension-host/runtime-backend-catalog.ts b/src/extension-host/runtime-backend-catalog.ts index 6de91699e38..3ccebd9fcb7 100644 --- a/src/extension-host/runtime-backend-catalog.ts +++ b/src/extension-host/runtime-backend-catalog.ts @@ -7,7 +7,10 @@ import { DEFAULT_IMAGE_MODELS, } from "../media-understanding/defaults.js"; import type { MediaUnderstandingCapability } from "../media-understanding/types.js"; -import { EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS } from "./embedding-runtime-registry.js"; +import { + EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS, + isExtensionHostEmbeddingRuntimeBackendAutoSelectable, +} from "./embedding-runtime-backends.js"; import type { EmbeddingProviderId } from "./embedding-runtime-types.js"; import { buildExtensionHostMediaUnderstandingRegistry, @@ -43,12 +46,6 @@ type ExtensionHostMediaRuntimeSubsystemId = Extract< "media.audio" | "media.image" | "media.video" >; -const EXTENSION_HOST_EMBEDDING_BACKEND_IDS = [ - "local", - ...EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS, - "ollama", -] as const satisfies readonly EmbeddingProviderId[]; - const EXTENSION_HOST_MEDIA_AUTO_PROVIDER_IDS: Record< MediaUnderstandingCapability, readonly string[] @@ -124,7 +121,7 @@ function resolveExtensionHostMediaRuntimeDefaultModelFromDefaults(params: { } export function listExtensionHostEmbeddingRuntimeBackendCatalogEntries(): readonly ExtensionHostRuntimeBackendCatalogEntry[] { - return EXTENSION_HOST_EMBEDDING_BACKEND_IDS.map((backendId, defaultRank) => ({ + return EXTENSION_HOST_EMBEDDING_RUNTIME_BACKEND_IDS.map((backendId, defaultRank) => ({ id: buildRuntimeBackendCatalogId("embedding", backendId), family: EXTENSION_HOST_RUNTIME_BACKEND_FAMILY, subsystemId: "embedding", @@ -134,8 +131,7 @@ export function listExtensionHostEmbeddingRuntimeBackendCatalogEntries(): readon selectorKeys: [backendId], capabilities: ["embed.query", "embed.batch"], metadata: { - autoSelectable: - backendId === "local" || EXTENSION_HOST_REMOTE_EMBEDDING_PROVIDER_IDS.includes(backendId), + autoSelectable: isExtensionHostEmbeddingRuntimeBackendAutoSelectable(backendId), }, })); }