import { cpus } from "node:os"; import { commercialApiHold } from "./model-policy.js"; export function isLocalLlmDisabled(_env = process.env) { return true; } export function resolveLlamaGpuMode(_env = process.env) { return "cpu"; } export function isQwen3EmbeddingModel(modelUri) { return /qwen.*embed/i.test(modelUri) || /embed.*qwen/i.test(modelUri); } export function formatQueryForEmbedding(query, modelUri) { if (modelUri && isQwen3EmbeddingModel(modelUri)) { return `Instruct: Retrieve relevant documents for the given query\nQuery: ${query}`; } return `task: search result | query: ${query}`; } export function formatDocForEmbedding(text, title, modelUri) { if (modelUri && isQwen3EmbeddingModel(modelUri)) { return title ? `${title}\n${text}` : text; } return `title: ${title || "none"} | text: ${text}`; } export const LFM2_GENERATE_MODEL = "commercial-api-required"; export const LFM2_INSTRUCT_MODEL = "commercial-api-required"; export const DEFAULT_EMBED_MODEL_URI = "commercial-api:embedding-unconfigured"; export const DEFAULT_RERANK_MODEL_URI = "commercial-api:rerank-unconfigured"; export const DEFAULT_GENERATE_MODEL_URI = "commercial-api:generation-unconfigured"; export const DEFAULT_MODEL_CACHE_DIR = "commercial-api:no-local-cache"; export async function pullModels(_models, _options = {}) { throw commercialApiHold("local model downloads are disabled"); } function learnedModelHold(operation) { throw commercialApiHold(`${operation} requires an approved commercial API adapter`); } /** Historical SDK name retained as a fail-closed compatibility adapter. */ export class LlamaCpp { static EMBED_CONTEXT_SIZE = 2048; static RERANK_CONTEXT_SIZE = 2048; static RERANK_TARGET_DOCS_PER_CONTEXT = 32; static RERANK_TEMPLATE_OVERHEAD = 32; embedModelName; constructor(config = {}) { this.embedModelName = config.embedModel ?? process.env.QMD_EMBED_MODEL_ID ?? DEFAULT_EMBED_MODEL_URI; } async tokenize(_text) { return learnedModelHold("tokenization"); } async countTokens(_text) { return learnedModelHold("token counting"); } async detokenize(_tokens) { return learnedModelHold("detokenization"); } async embed(_text, _options = {}) { return learnedModelHold("embedding"); } async embedBatch(_texts, _options = {}) { return learnedModelHold("batch embedding"); } async generate(_prompt, _options = {}) { return learnedModelHold("generation"); } async modelExists(modelUri) { return { name: modelUri, exists: false }; } async expandQuery(_query, _options = {}) { return learnedModelHold("query expansion"); } async rerank(_query, _documents, _options = {}) { return learnedModelHold("reranking"); } async getDeviceInfo() { return { gpu: false, gpuOffloading: false, gpuDevices: [], cpuCores: cpus().length }; } async unloadIdleResources() { } async dispose() { } } export class SessionReleasedError extends Error { constructor(message = "LLM session has been released or aborted") { super(message); this.name = "SessionReleasedError"; } } class CommercialHoldSession { llm; released = false; controller = new AbortController(); constructor(llm, options = {}) { this.llm = llm; if (options.signal?.aborted) this.controller.abort(options.signal.reason); options.signal?.addEventListener("abort", () => this.controller.abort(options.signal?.reason), { once: true }); } get isValid() { return !this.released && !this.controller.signal.aborted; } get signal() { return this.controller.signal; } release() { this.released = true; this.controller.abort(new SessionReleasedError()); } assertValid() { if (!this.isValid) throw new SessionReleasedError(); } async embed(text, options) { this.assertValid(); return this.llm.embed(text, options); } async embedBatch(texts, options) { this.assertValid(); return this.llm.embedBatch(texts, options); } async expandQuery(query, options) { this.assertValid(); return this.llm.expandQuery(query, options); } async rerank(query, documents, options) { this.assertValid(); return this.llm.rerank(query, documents, options); } } let defaultLlamaCpp = null; export function getDefaultLlamaCpp() { defaultLlamaCpp ??= new LlamaCpp(); return defaultLlamaCpp; } export function setDefaultLlamaCpp(llm) { defaultLlamaCpp = llm; } export async function disposeDefaultLlamaCpp() { if (defaultLlamaCpp) await defaultLlamaCpp.dispose(); defaultLlamaCpp = null; } export async function withLLMSession(fn, options = {}) { return withLLMSessionForLlm(getDefaultLlamaCpp(), fn, options); } export async function withLLMSessionForLlm(llm, fn, options = {}) { const session = new CommercialHoldSession(llm, options); try { return await fn(session); } finally { session.release(); } } export function canUnloadLLM() { return true; }