@vibgrate/cli 2026.727.3 → 2026.728.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baseline-MRUM2P6H.js +8 -0
- package/dist/{baseline-ATM5MXBZ.js.map → baseline-MRUM2P6H.js.map} +1 -1
- package/dist/chunk-3SDV6ADQ.js +78 -0
- package/dist/chunk-3SDV6ADQ.js.map +1 -0
- package/dist/{chunk-6JIKUDWM.js → chunk-6AXHLQBV.js} +219 -22
- package/dist/chunk-6AXHLQBV.js.map +1 -0
- package/dist/{chunk-K7REHDQS.js → chunk-6HX47EBL.js} +25 -19
- package/dist/chunk-6HX47EBL.js.map +1 -0
- package/dist/{chunk-Z7GP7XTJ.js → chunk-A2IYFNCQ.js} +26 -64
- package/dist/chunk-A2IYFNCQ.js.map +1 -0
- package/dist/{chunk-MAY5HLDH.js → chunk-GQTWDKMJ.js} +158 -161
- package/dist/chunk-GQTWDKMJ.js.map +1 -0
- package/dist/{chunk-OOIG3RUM.js → chunk-GYSOQH5C.js} +18 -79
- package/dist/chunk-GYSOQH5C.js.map +1 -0
- package/dist/{chunk-C66GOHYB.js → chunk-IWP7MYIA.js} +61 -23
- package/dist/chunk-IWP7MYIA.js.map +1 -0
- package/dist/{chunk-77LYGXBI.js → chunk-JRAGO6OB.js} +3 -3
- package/dist/{chunk-77LYGXBI.js.map → chunk-JRAGO6OB.js.map} +1 -1
- package/dist/{chunk-NDMDSPFX.js → chunk-KKRSQQ3A.js} +4 -3
- package/dist/chunk-KKRSQQ3A.js.map +1 -0
- package/dist/{chunk-FFWGT55D.js → chunk-NTW5UEKT.js} +3 -3
- package/dist/{chunk-FFWGT55D.js.map → chunk-NTW5UEKT.js.map} +1 -1
- package/dist/chunk-OSD546W7.js +167 -0
- package/dist/chunk-OSD546W7.js.map +1 -0
- package/dist/{chunk-3V24O47U.js → chunk-PVZBYZZR.js} +19 -9
- package/dist/chunk-PVZBYZZR.js.map +1 -0
- package/dist/{chunk-XPJZTSY7.js → chunk-R2QNFXE5.js} +3 -3
- package/dist/{chunk-XPJZTSY7.js.map → chunk-R2QNFXE5.js.map} +1 -1
- package/dist/{chunk-PXHNTC6D.js → chunk-SIPGDJT4.js} +3 -3
- package/dist/{chunk-PXHNTC6D.js.map → chunk-SIPGDJT4.js.map} +1 -1
- package/dist/chunk-UIOBFLE6.js +356 -0
- package/dist/chunk-UIOBFLE6.js.map +1 -0
- package/dist/chunk-UZJS7GMK.js +57 -0
- package/dist/chunk-UZJS7GMK.js.map +1 -0
- package/dist/{chunk-2VFWXNS5.js → chunk-WH2N22S3.js} +3 -3
- package/dist/{chunk-2VFWXNS5.js.map → chunk-WH2N22S3.js.map} +1 -1
- package/dist/{chunk-AVQSHIJ5.js → chunk-WY6DGTBP.js} +4 -4
- package/dist/{chunk-AVQSHIJ5.js.map → chunk-WY6DGTBP.js.map} +1 -1
- package/dist/{chunk-OFUC6RYN.js → chunk-YF43FOPP.js} +8 -101
- package/dist/chunk-YF43FOPP.js.map +1 -0
- package/dist/{chunk-Y23HMSWU.js → chunk-ZFTFCM7B.js} +14 -7
- package/dist/chunk-ZFTFCM7B.js.map +1 -0
- package/dist/cli.js +179 -213
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/{interactive-INGJNSON.js → interactive-36ZZ64WL.js} +48 -17
- package/dist/interactive-36ZZ64WL.js.map +1 -0
- package/dist/{llm-host-7GWDO6IX.js → llm-host-XYBT4267.js} +4 -4
- package/dist/{llm-host-7GWDO6IX.js.map → llm-host-XYBT4267.js.map} +1 -1
- package/dist/model-manager-OEPY4I7W.js +10 -0
- package/dist/{model-orchestrator-TVONAUPS.js.map → model-manager-OEPY4I7W.js.map} +1 -1
- package/dist/{model-orchestrator-TVONAUPS.js → model-orchestrator-4VSYP4J4.js} +3 -3
- package/dist/model-orchestrator-4VSYP4J4.js.map +1 -0
- package/dist/resolve-gguf-Y6FH3CNB.js +9 -0
- package/dist/{resolve-gguf-VPL4YQ6J.js.map → resolve-gguf-Y6FH3CNB.js.map} +1 -1
- package/dist/{runtime-session-4AMZIAAG.js → runtime-session-EJQZXANB.js} +5 -5
- package/dist/{runtime-session-4AMZIAAG.js.map → runtime-session-EJQZXANB.js.map} +1 -1
- package/dist/{session-M72522AP.js → session-ZJGENHKX.js} +6 -4
- package/dist/{session-M72522AP.js.map → session-ZJGENHKX.js.map} +1 -1
- package/dist/{stream-json-6ZBUA2L3.js → stream-json-Z5KC2DM3.js} +8 -6
- package/dist/stream-json-Z5KC2DM3.js.map +1 -0
- package/dist/{vgd-CVLKBS7K.js → vgd-3MHSB4KA.js} +4 -4
- package/dist/vgd-3MHSB4KA.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-ATM5MXBZ.js +0 -8
- package/dist/chunk-3V24O47U.js.map +0 -1
- package/dist/chunk-6JIKUDWM.js.map +0 -1
- package/dist/chunk-C66GOHYB.js.map +0 -1
- package/dist/chunk-K7REHDQS.js.map +0 -1
- package/dist/chunk-MAY5HLDH.js.map +0 -1
- package/dist/chunk-NDMDSPFX.js.map +0 -1
- package/dist/chunk-OFUC6RYN.js.map +0 -1
- package/dist/chunk-OOIG3RUM.js.map +0 -1
- package/dist/chunk-Y23HMSWU.js.map +0 -1
- package/dist/chunk-Z7GP7XTJ.js.map +0 -1
- package/dist/interactive-INGJNSON.js.map +0 -1
- package/dist/resolve-gguf-VPL4YQ6J.js +0 -8
- package/dist/stream-json-6ZBUA2L3.js.map +0 -1
- package/dist/vgd-CVLKBS7K.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/llm-host/binding.ts","../src/runtime/llm-host/embedded.ts","../src/runtime/llm-host/process-bridge.ts","../src/runtime/llm-host/index.ts"],"names":["path2"],"mappings":"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","file":"chunk-PXHNTC6D.js","sourcesContent":["/**\n * node-llama-cpp binding adapter — pure glue so embedded + process hosts share\n * one code path. The module is injected (from ensurePackage); never imported\n * statically so the published CLI stays free of native deps.\n */\n\nimport type { LlmChatMessage, LlmGenerateOptions } from './types.js';\n\nexport interface LlamaBindingGenerateInput {\n /** Loaded node-llama-cpp module (dynamic). */\n lib: unknown;\n modelPath: string;\n messages: LlmChatMessage[];\n opts?: LlmGenerateOptions;\n}\n\n/**\n * Run one chat completion via node-llama-cpp. Throws on binding/model errors\n * (callers wrap with redaction).\n */\nexport async function generateWithLlamaBinding(input: LlamaBindingGenerateInput): Promise<string> {\n const lib: any = input.lib;\n if (!lib || typeof lib.getLlama !== 'function') {\n throw new Error('llm-host: invalid node-llama-cpp module (getLlama missing)');\n }\n const llama = await lib.getLlama();\n const model = await llama.loadModel({ modelPath: input.modelPath });\n const ctx = await model.createContext();\n const { LlamaChatSession } = lib;\n if (typeof LlamaChatSession !== 'function') {\n throw new Error('llm-host: LlamaChatSession missing from node-llama-cpp module');\n }\n const chat = new LlamaChatSession({ contextSequence: ctx.getSequence() });\n const prompt = input.messages.map((m) => `${m.role}: ${m.content}`).join('\\n\\n');\n const temperature = input.opts?.temperature ?? 0;\n const maxTokens = input.opts?.maxTokens;\n // Grammar: pass through when binding supports it (future constrained PatchIR).\n const promptOpts: Record<string, unknown> = { temperature };\n if (typeof maxTokens === 'number') promptOpts.maxTokens = maxTokens;\n if (input.opts?.grammar) {\n // Best-effort: node-llama-cpp versions differ on the grammar API surface.\n promptOpts.grammar = input.opts.grammar;\n }\n const text: string = await chat.prompt(prompt, promptOpts);\n return typeof text === 'string' ? text : String(text ?? '');\n}\n","/**\n * Embedded llm-host (Approach B default) — same address space as the agent.\n *\n * Production path: warm session pool ({@link acquireHostSession}) so models are\n * not reloaded every chat turn. Binding is injected via {@link setBinding}.\n */\n\nimport { annotateUnknownIdentifiers } from '../identifier-mask.js';\nimport { generateWithLlamaBinding } from './binding.js';\nimport {\n acquireHostSession,\n generateOnSession,\n type HostGenerateReport,\n} from './session.js';\nimport type {\n LlmChatMessage,\n LlmGenerateOptions,\n LlmGenerateResult,\n LlmHost,\n LlmMemoryReport,\n} from './types.js';\n\nexport class EmbeddedLlmHost implements LlmHost {\n readonly isolation = 'embedded' as const;\n private modelRef: string | null = null;\n private loaded = false;\n private binding: unknown | null = null;\n private preferGrammar = false;\n private lastReport: HostGenerateReport | null = null;\n\n /** Attach the dynamically loaded node-llama-cpp module. */\n setBinding(lib: unknown): void {\n this.binding = lib;\n }\n\n /** Hint from MEP: attempt constrained decoding when grammar is supplied. */\n setPreferGrammar(on: boolean): void {\n this.preferGrammar = on;\n }\n\n /** Last generate metrics (KV plan, draft accept, warm start). */\n lastGenerateReport(): HostGenerateReport | null {\n return this.lastReport;\n }\n\n async load(modelRef: string): Promise<void> {\n this.modelRef = modelRef;\n this.loaded = true;\n // Eagerly warm the session when binding is already available.\n if (this.binding) {\n await acquireHostSession(this.binding, modelRef);\n }\n }\n\n async unload(): Promise<void> {\n this.modelRef = null;\n this.loaded = false;\n this.lastReport = null;\n }\n\n supportsConstrainedDecoding(): boolean {\n return this.preferGrammar && this.binding != null;\n }\n\n memoryReport(): LlmMemoryReport {\n return {\n isolation: this.isolation,\n modelRef: this.modelRef,\n loaded: this.loaded,\n };\n }\n\n async generate(messages: LlmChatMessage[], opts: LlmGenerateOptions = {}): Promise<LlmGenerateResult> {\n if (!this.loaded || !this.modelRef) {\n throw new Error('llm-host: no model loaded — orchestrator must call load() after resolve/install');\n }\n if (!this.binding) {\n throw new Error(\n 'llm-host: node-llama-cpp binding not attached — run `vg models install` for the llama-cpp provider, then retry',\n );\n }\n\n // Production path: pooled warm session.\n try {\n const session = await acquireHostSession(this.binding, this.modelRef);\n const report = await generateOnSession(session, messages, {\n grammar: opts.grammar,\n requireGrammar: opts.requireGrammar,\n identifierTrie: opts.identifierTrie,\n annotateUnknownIdentifiers: opts.annotateUnknownIdentifiers,\n draftCandidates: opts.draftCandidates,\n maxTokens: opts.maxTokens,\n temperature: opts.temperature,\n promptSegments: opts.promptSegments,\n });\n this.lastReport = report;\n return {\n text: report.text,\n model: report.model,\n isolation: report.isolation,\n constrained: report.constrained || !!(opts.grammar && this.preferGrammar),\n unknownIdentifiers: report.unknownIdentifiers,\n };\n } catch {\n // Fallback one-shot (tests / minimal bindings).\n let text = await generateWithLlamaBinding({\n lib: this.binding,\n modelPath: this.modelRef,\n messages,\n opts,\n });\n let unknownIdentifiers: string[] | undefined;\n if (opts.identifierTrie && opts.annotateUnknownIdentifiers !== false) {\n const ann = annotateUnknownIdentifiers(text, opts.identifierTrie);\n text = ann.text;\n unknownIdentifiers = ann.unknown.length ? ann.unknown : undefined;\n }\n return {\n text,\n model: this.modelRef,\n isolation: this.isolation,\n constrained: !!(opts.grammar && this.supportsConstrainedDecoding()),\n unknownIdentifiers,\n };\n }\n }\n}\n","/**\n * Process-isolation llm-host: client + server over a Unix/local socket.\n *\n * Management (Code Modes, fit, packs, install) stays in vgd / the CLI.\n * This process only loads weights and decodes (ADR-005).\n */\n\nimport * as fs from 'node:fs';\nimport * as net from 'node:net';\nimport * as path from 'node:path';\nimport { generateWithLlamaBinding } from './binding.js';\nimport { acquireHostSession, generateOnSession } from './session.js';\nimport type {\n LlmChatMessage,\n LlmGenerateOptions,\n LlmGenerateResult,\n LlmHost,\n LlmMemoryReport,\n} from './types.js';\n\nexport const LLM_HOST_IPC_SCHEMA = 'llm-host-ipc/0' as const;\n\nexport type LlmHostIpcRequest =\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'load'; modelRef: string }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'unload' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'generate'; messages: LlmChatMessage[]; opts?: LlmGenerateOptions }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'memory' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'capabilities' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'ping' };\n\nexport type LlmHostIpcResponse =\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'load' | 'unload' | 'ping' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'generate'; result: LlmGenerateResult }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'memory'; report: LlmMemoryReport }\n | {\n v: typeof LLM_HOST_IPC_SCHEMA;\n id: string;\n ok: true;\n op: 'capabilities';\n constrainedDecoding: boolean;\n isolation: 'process';\n }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: false; error: string };\n\n/** Request body without envelope — distribute Omit over the union (keyof union is only common keys). */\nexport type LlmHostIpcBody = LlmHostIpcRequest extends infer R\n ? R extends { v: typeof LLM_HOST_IPC_SCHEMA; id: string }\n ? Omit<R, 'v' | 'id'>\n : never\n : never;\n\nexport interface ProcessHostServerOptions {\n socketPath: string;\n /** node-llama-cpp module (optional until first generate). */\n binding?: unknown;\n onListen?: (socketPath: string) => void;\n}\n\n/**\n * Serve llm-host IPC on a local socket. Resolves when the server is listening;\n * call the returned `close` to stop.\n */\nexport function startProcessHostServer(options: ProcessHostServerOptions): Promise<{ close: () => Promise<void> }> {\n const state = {\n modelRef: null as string | null,\n loaded: false,\n binding: options.binding ?? null,\n };\n\n try {\n if (fs.existsSync(options.socketPath)) fs.unlinkSync(options.socketPath);\n } catch {\n /* ignore */\n }\n fs.mkdirSync(path.dirname(options.socketPath), { recursive: true });\n\n return new Promise((resolve, reject) => {\n const server = net.createServer((socket) => {\n let buf = '';\n socket.setEncoding('utf8');\n socket.on('data', (chunk: string) => {\n buf += chunk;\n let nl: number;\n while ((nl = buf.indexOf('\\n')) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n void handleLine(line, state, (resp) => {\n socket.write(`${JSON.stringify(resp)}\\n`);\n });\n }\n });\n });\n\n server.once('error', reject);\n server.listen(options.socketPath, () => {\n options.onListen?.(options.socketPath);\n resolve({\n close: () =>\n new Promise((res, rej) => {\n server.close((err) => {\n try {\n if (fs.existsSync(options.socketPath)) fs.unlinkSync(options.socketPath);\n } catch {\n /* ignore */\n }\n if (err) rej(err);\n else res();\n });\n }),\n });\n });\n });\n}\n\n/** Attach binding after server start (e.g. after ensurePackage). */\nexport type ProcessHostState = {\n modelRef: string | null;\n loaded: boolean;\n binding: unknown | null;\n};\n\nasync function handleLine(\n line: string,\n state: ProcessHostState,\n reply: (r: LlmHostIpcResponse) => void,\n): Promise<void> {\n let req: LlmHostIpcRequest;\n try {\n req = JSON.parse(line) as LlmHostIpcRequest;\n } catch {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: '?', ok: false, error: 'invalid JSON' });\n return;\n }\n if (req.v !== LLM_HOST_IPC_SCHEMA) {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: false, error: `unsupported schema ${String((req as { v?: string }).v)}` });\n return;\n }\n\n try {\n switch (req.op) {\n case 'ping':\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'ping' });\n return;\n case 'load':\n state.modelRef = req.modelRef;\n state.loaded = true;\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'load' });\n return;\n case 'unload':\n state.modelRef = null;\n state.loaded = false;\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'unload' });\n return;\n case 'memory':\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: true,\n op: 'memory',\n report: { isolation: 'process', modelRef: state.modelRef, loaded: state.loaded },\n });\n return;\n case 'capabilities':\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: true,\n op: 'capabilities',\n constrainedDecoding: state.binding != null,\n isolation: 'process',\n });\n return;\n case 'generate': {\n if (!state.loaded || !state.modelRef) {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: false, error: 'no model loaded' });\n return;\n }\n if (!state.binding) {\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: false,\n error: 'binding not loaded in host process — start host after vg models install',\n });\n return;\n }\n // Same warm session path as embedded (Approach B parity for enterprise isolation).\n let result: LlmGenerateResult;\n try {\n const session = await acquireHostSession(state.binding, state.modelRef);\n const report = await generateOnSession(session, req.messages, {\n grammar: req.opts?.grammar,\n requireGrammar: req.opts?.requireGrammar,\n identifierTrie: req.opts?.identifierTrie,\n annotateUnknownIdentifiers: req.opts?.annotateUnknownIdentifiers,\n draftCandidates: req.opts?.draftCandidates,\n maxTokens: req.opts?.maxTokens,\n temperature: req.opts?.temperature,\n promptSegments: req.opts?.promptSegments,\n });\n result = {\n text: report.text,\n model: state.modelRef,\n isolation: 'process',\n constrained: report.constrained,\n unknownIdentifiers: report.unknownIdentifiers,\n };\n } catch {\n const text = await generateWithLlamaBinding({\n lib: state.binding,\n modelPath: state.modelRef,\n messages: req.messages,\n opts: req.opts,\n });\n result = {\n text,\n model: state.modelRef,\n isolation: 'process',\n constrained: !!(req.opts?.grammar && state.binding),\n };\n }\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'generate', result });\n return;\n }\n default:\n reply({ v: LLM_HOST_IPC_SCHEMA, id: (req as { id: string }).id, ok: false, error: 'unknown op' });\n }\n } catch (e) {\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n}\n\n/** Client: full {@link LlmHost} over the process socket. */\nexport class ProcessLlmHost implements LlmHost {\n readonly isolation = 'process' as const;\n private seq = 0;\n\n constructor(private readonly socketPath: string) {}\n\n getEndpoint(): string {\n return this.socketPath;\n }\n\n supportsConstrainedDecoding(): boolean {\n return true; // host may apply grammar when binding is present\n }\n\n async load(modelRef: string): Promise<void> {\n await this.rpc({ op: 'load', modelRef });\n }\n\n async unload(): Promise<void> {\n await this.rpc({ op: 'unload' });\n }\n\n async generate(messages: LlmChatMessage[], opts?: LlmGenerateOptions): Promise<LlmGenerateResult> {\n const res = await this.rpc({ op: 'generate', messages, opts });\n if (!res.ok || res.op !== 'generate') {\n throw new Error(!res.ok ? res.error : 'unexpected response');\n }\n return res.result;\n }\n\n memoryReport(): LlmMemoryReport {\n // Sync surface required by LlmHost; use last known or empty (async memory via rpc elsewhere).\n return { isolation: 'process', modelRef: null, loaded: false };\n }\n\n async memoryReportAsync(): Promise<LlmMemoryReport> {\n const res = await this.rpc({ op: 'memory' });\n if (!res.ok || res.op !== 'memory') {\n throw new Error(!res.ok ? res.error : 'unexpected response');\n }\n return res.report;\n }\n\n private rpc(body: LlmHostIpcBody): Promise<LlmHostIpcResponse> {\n const id = `r${++this.seq}`;\n const req = { v: LLM_HOST_IPC_SCHEMA, id, ...body } as LlmHostIpcRequest;\n return new Promise((resolve, reject) => {\n const socket = net.createConnection(this.socketPath);\n let buf = '';\n const timer = setTimeout(() => {\n socket.destroy();\n reject(new Error(`llm-host IPC timeout (${this.socketPath})`));\n }, 120_000);\n socket.setEncoding('utf8');\n socket.on('connect', () => {\n socket.write(`${JSON.stringify(req)}\\n`);\n });\n socket.on('data', (chunk: string) => {\n buf += chunk;\n const nl = buf.indexOf('\\n');\n if (nl < 0) return;\n const line = buf.slice(0, nl).trim();\n clearTimeout(timer);\n socket.end();\n try {\n resolve(JSON.parse(line) as LlmHostIpcResponse);\n } catch (e) {\n reject(e);\n }\n });\n socket.on('error', (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n }\n}\n\n/** @deprecated use ProcessLlmHost */\nexport class ProcessBridgeLlmHost extends ProcessLlmHost {}\n","/**\n * Factory for the dual-mode llm-host (ADR-005).\n *\n * `createLlmHost({ isolation: 'embedded' })` — default Approach B.\n * `createLlmHost({ isolation: 'process', endpoint })` — enterprise shell.\n */\n\nimport * as path from 'node:path';\nimport { vibgrateRuntimeDir } from '../paths.js';\nimport { EmbeddedLlmHost } from './embedded.js';\nimport { ProcessLlmHost } from './process-bridge.js';\nimport type { LlmHost, LlmHostIsolation } from './types.js';\n\nexport type {\n LlmHost,\n LlmHostConfig,\n LlmHostIsolation,\n LlmChatMessage,\n LlmGenerateResult,\n LlmGenerateOptions,\n LlmMemoryReport,\n} from './types.js';\nexport { EmbeddedLlmHost } from './embedded.js';\nexport {\n ProcessLlmHost,\n ProcessBridgeLlmHost,\n LLM_HOST_IPC_SCHEMA,\n startProcessHostServer,\n} from './process-bridge.js';\nexport type { LlmHostIpcRequest, LlmHostIpcResponse, ProcessHostServerOptions } from './process-bridge.js';\nexport { generateWithLlamaBinding } from './binding.js';\nexport {\n acquireHostSession,\n generateOnSession,\n clearHostSessionPool,\n hostSessionPoolSize,\n listHostSessions,\n dropHostSession,\n evictIdleSessions,\n sessionKey,\n} from './session.js';\nexport type { HostGenerateExtras, HostGenerateReport, HostSessionInfo } from './session.js';\nexport { attachGrammar, assertGrammarOrThrow, allowGrammarStringFallback } from './grammar.js';\nexport type { GrammarAttachResult, GrammarAttachMethod } from './grammar.js';\nexport {\n buildIdentifierTokenBias,\n planNextCharMask,\n tokenCompatibleWithTrie,\n trieFingerprint,\n} from './logit-mask.js';\nexport type { LogitMaskBuildResult, SamplerHookMethod, BuildLogitMaskOptions } from './logit-mask.js';\nexport {\n createIdentStreamState,\n stepIdentStream,\n filterTokenTexts,\n attachDynamicIdentFilter,\n dynamicAllowedNextChars,\n} from './identifier-sampler.js';\nexport type { IdentStreamState, IdentStepResult } from './identifier-sampler.js';\nexport { probeBindingCapabilities, supportsDynamicIdentSampler, supportsKvPrefixEvaluate } from './binding-capabilities.js';\nexport type { BindingCapabilities, ProbeBindingOptions } from './binding-capabilities.js';\nexport { composePromptConstraints } from './compose-constraints.js';\nexport { rankDraftCandidates, pickBestDraft } from './speculative.js';\nexport type { RankedDraft } from './speculative.js';\n\nexport interface CreateLlmHostOptions {\n isolation?: LlmHostIsolation;\n /** Socket path when isolation is `process`. Defaults under vibgrate runtime dir. */\n endpoint?: string;\n /** Pre-attach binding for embedded hosts (avoids a second ensure). */\n binding?: unknown;\n preferGrammar?: boolean;\n}\n\nexport function createLlmHost(options: CreateLlmHostOptions = {}): LlmHost {\n const isolation = options.isolation ?? 'embedded';\n if (isolation === 'process') {\n return new ProcessLlmHost(options.endpoint ?? defaultProcessEndpoint());\n }\n const host = new EmbeddedLlmHost();\n if (options.binding) host.setBinding(options.binding);\n if (options.preferGrammar) host.setPreferGrammar(true);\n return host;\n}\n\n/** Default IPC socket path for the isolated llm-host process. */\nexport function defaultProcessEndpoint(env: NodeJS.ProcessEnv = process.env): string {\n return path.join(vibgrateRuntimeDir(env), 'llm-host.sock');\n}\n\n/** Resolve isolation from env / explicit override (MEP / config later). */\nexport function resolveInferenceIsolation(\n explicit?: LlmHostIsolation,\n env: NodeJS.ProcessEnv = process.env,\n): LlmHostIsolation {\n if (explicit === 'embedded' || explicit === 'process') return explicit;\n const v = (env.VIBGRATE_INFERENCE_ISOLATION || env.VG_INFERENCE_ISOLATION || '').toLowerCase();\n if (v === 'process' || v === 'isolated') return 'process';\n return 'embedded';\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime/llm-host/binding.ts","../src/runtime/llm-host/embedded.ts","../src/runtime/llm-host/process-bridge.ts","../src/runtime/llm-host/index.ts"],"names":["path2"],"mappings":";;;;;;;;AAoBA,eAAsB,yBAAyB,KAAA,EAAmD;AAChG,EAAA,MAAM,MAAW,KAAA,CAAM,GAAA;AACvB,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,CAAI,aAAa,UAAA,EAAY;AAC9C,IAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,QAAA,EAAS;AACjC,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,SAAA,CAAU,EAAE,SAAA,EAAW,KAAA,CAAM,WAAW,CAAA;AAClE,EAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,aAAA,EAAc;AACtC,EAAA,MAAM,EAAE,kBAAiB,GAAI,GAAA;AAC7B,EAAA,IAAI,OAAO,qBAAqB,UAAA,EAAY;AAC1C,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AACA,EAAA,MAAM,IAAA,GAAO,IAAI,gBAAA,CAAiB,EAAE,iBAAiB,GAAA,CAAI,WAAA,IAAe,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,MAAM,CAAA;AAC/E,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,EAAM,WAAA,IAAe,CAAA;AAC/C,EAAA,MAAM,SAAA,GAAY,MAAM,IAAA,EAAM,SAAA;AAE9B,EAAA,MAAM,UAAA,GAAsC,EAAE,WAAA,EAAY;AAC1D,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,EAAU,UAAA,CAAW,SAAA,GAAY,SAAA;AAC1D,EAAA,IAAI,KAAA,CAAM,MAAM,OAAA,EAAS;AAEvB,IAAA,UAAA,CAAW,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA;AAAA,EAClC;AACA,EAAA,MAAM,IAAA,GAAe,MAAM,IAAA,CAAK,MAAA,CAAO,QAAQ,UAAU,CAAA;AACzD,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC5D;;;ACvBO,IAAM,kBAAN,MAAyC;AAAA,EACrC,SAAA,GAAY,UAAA;AAAA,EACb,QAAA,GAA0B,IAAA;AAAA,EAC1B,MAAA,GAAS,KAAA;AAAA,EACT,OAAA,GAA0B,IAAA;AAAA,EAC1B,aAAA,GAAgB,KAAA;AAAA,EAChB,UAAA,GAAwC,IAAA;AAAA;AAAA,EAGhD,WAAW,GAAA,EAAoB;AAC7B,IAAA,IAAA,CAAK,OAAA,GAAU,GAAA;AAAA,EACjB;AAAA;AAAA,EAGA,iBAAiB,EAAA,EAAmB;AAClC,IAAA,IAAA,CAAK,aAAA,GAAgB,EAAA;AAAA,EACvB;AAAA;AAAA,EAGA,kBAAA,GAAgD;AAC9C,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,MAAM,KAAK,QAAA,EAAiC;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAEd,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,MAAM,kBAAA,CAAmB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC5B,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,EACpB;AAAA,EAEA,2BAAA,GAAuC;AACrC,IAAA,OAAO,IAAA,CAAK,aAAA,IAAiB,IAAA,CAAK,OAAA,IAAW,IAAA;AAAA,EAC/C;AAAA,EAEA,YAAA,GAAgC;AAC9B,IAAA,OAAO;AAAA,MACL,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,QAAQ,IAAA,CAAK;AAAA,KACf;AAAA,EACF;AAAA,EAEA,MAAM,QAAA,CAAS,QAAA,EAA4B,IAAA,GAA2B,EAAC,EAA+B;AACpG,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,KAAK,QAAA,EAAU;AAClC,MAAA,MAAM,IAAI,MAAM,sFAAiF,CAAA;AAAA,IACnG;AACA,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,MAAM,kBAAA,CAAmB,IAAA,CAAK,OAAA,EAAS,KAAK,QAAQ,CAAA;AACpE,MAAA,MAAM,MAAA,GAAS,MAAM,iBAAA,CAAkB,OAAA,EAAS,QAAA,EAAU;AAAA,QACxD,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,4BAA4B,IAAA,CAAK,0BAAA;AAAA,QACjC,iBAAiB,IAAA,CAAK,eAAA;AAAA,QACtB,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,aAAa,IAAA,CAAK,WAAA;AAAA,QAClB,gBAAgB,IAAA,CAAK;AAAA,OACtB,CAAA;AACD,MAAA,IAAA,CAAK,UAAA,GAAa,MAAA;AAClB,MAAA,OAAO;AAAA,QACL,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,aAAa,MAAA,CAAO,WAAA,IAAe,CAAC,EAAE,IAAA,CAAK,WAAW,IAAA,CAAK,aAAA,CAAA;AAAA,QAC3D,oBAAoB,MAAA,CAAO;AAAA,OAC7B;AAAA,IACF,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAI,IAAA,GAAO,MAAM,wBAAA,CAAyB;AAAA,QACxC,KAAK,IAAA,CAAK,OAAA;AAAA,QACV,WAAW,IAAA,CAAK,QAAA;AAAA,QAChB,QAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,IAAI,kBAAA;AACJ,MAAA,IAAI,IAAA,CAAK,cAAA,IAAkB,IAAA,CAAK,0BAAA,KAA+B,KAAA,EAAO;AACpE,QAAA,MAAM,GAAA,GAAM,0BAAA,CAA2B,IAAA,EAAM,IAAA,CAAK,cAAc,CAAA;AAChE,QAAA,IAAA,GAAO,GAAA,CAAI,IAAA;AACX,QAAA,kBAAA,GAAqB,GAAA,CAAI,OAAA,CAAQ,MAAA,GAAS,GAAA,CAAI,OAAA,GAAU,MAAA;AAAA,MAC1D;AACA,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,OAAO,IAAA,CAAK,QAAA;AAAA,QACZ,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,aAAa,CAAC,EAAE,IAAA,CAAK,OAAA,IAAW,KAAK,2BAAA,EAA4B,CAAA;AAAA,QACjE;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF;AC1GO,IAAM,mBAAA,GAAsB;AA0C5B,SAAS,uBAAuB,OAAA,EAA4E;AACjH,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,OAAA,EAAS,QAAQ,OAAA,IAAW;AAAA,GAC9B;AAEA,EAAA,IAAI;AACF,IAAA,IAAO,cAAW,OAAA,CAAQ,UAAU,GAAM,EAAA,CAAA,UAAA,CAAW,QAAQ,UAAU,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAG,EAAA,CAAA,SAAA,CAAe,aAAQ,OAAA,CAAQ,UAAU,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAElE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,MAAA,GAAa,GAAA,CAAA,YAAA,CAAa,CAAC,MAAA,KAAW;AAC1C,MAAA,IAAI,GAAA,GAAM,EAAA;AACV,MAAA,MAAA,CAAO,YAAY,MAAM,CAAA;AACzB,MAAA,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAkB;AACnC,QAAA,GAAA,IAAO,KAAA;AACP,QAAA,IAAI,EAAA;AACJ,QAAA,OAAA,CAAQ,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,IAAI,MAAM,CAAA,EAAG;AACpC,UAAA,MAAM,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AACnC,UAAA,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,EAAA,GAAK,CAAC,CAAA;AACtB,UAAA,IAAI,CAAC,IAAA,EAAM;AACX,UAAA,KAAK,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,CAAC,IAAA,KAAS;AACrC,YAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC;AAAA,CAAI,CAAA;AAAA,UAC1C,CAAC,CAAA;AAAA,QACH;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,MAAM,CAAA;AAC3B,IAAA,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,UAAA,EAAY,MAAM;AACtC,MAAA,OAAA,CAAQ,QAAA,GAAW,QAAQ,UAAU,CAAA;AACrC,MAAA,OAAA,CAAQ;AAAA,QACN,OAAO,MACL,IAAI,OAAA,CAAQ,CAAC,KAAK,GAAA,KAAQ;AACxB,UAAA,MAAA,CAAO,KAAA,CAAM,CAAC,GAAA,KAAQ;AACpB,YAAA,IAAI;AACF,cAAA,IAAO,cAAW,OAAA,CAAQ,UAAU,GAAM,EAAA,CAAA,UAAA,CAAW,QAAQ,UAAU,CAAA;AAAA,YACzE,CAAA,CAAA,MAAQ;AAAA,YAER;AACA,YAAA,IAAI,GAAA,MAAS,GAAG,CAAA;AAAA,iBACX,GAAA,EAAI;AAAA,UACX,CAAC,CAAA;AAAA,QACH,CAAC;AAAA,OACJ,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AASA,eAAe,UAAA,CACb,IAAA,EACA,KAAA,EACA,KAAA,EACe;AACf,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,KAAA,CAAM,EAAE,GAAG,mBAAA,EAAqB,EAAA,EAAI,KAAK,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,cAAA,EAAgB,CAAA;AAC3E,IAAA;AAAA,EACF;AACA,EAAA,IAAI,GAAA,CAAI,MAAM,mBAAA,EAAqB;AACjC,IAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,sBAAsB,MAAA,CAAQ,GAAA,CAAuB,CAAC,CAAC,IAAI,CAAA;AACzH,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,QAAQ,IAAI,EAAA;AAAI,MACd,KAAK,MAAA;AACH,QAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAA,CAAI,IAAI,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,CAAA;AAClE,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,KAAA,CAAM,WAAW,GAAA,CAAI,QAAA;AACrB,QAAA,KAAA,CAAM,MAAA,GAAS,IAAA;AACf,QAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAA,CAAI,IAAI,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,MAAA,EAAQ,CAAA;AAClE,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,KAAA,CAAM,QAAA,GAAW,IAAA;AACjB,QAAA,KAAA,CAAM,MAAA,GAAS,KAAA;AACf,QAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAA,CAAI,IAAI,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,QAAA,EAAU,CAAA;AACpE,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,KAAA,CAAM;AAAA,UACJ,CAAA,EAAG,mBAAA;AAAA,UACH,IAAI,GAAA,CAAI,EAAA;AAAA,UACR,EAAA,EAAI,IAAA;AAAA,UACJ,EAAA,EAAI,QAAA;AAAA,UACJ,MAAA,EAAQ,EAAE,SAAA,EAAW,SAAA,EAAW,UAAU,KAAA,CAAM,QAAA,EAAU,MAAA,EAAQ,KAAA,CAAM,MAAA;AAAO,SAChF,CAAA;AACD,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,KAAA,CAAM;AAAA,UACJ,CAAA,EAAG,mBAAA;AAAA,UACH,IAAI,GAAA,CAAI,EAAA;AAAA,UACR,EAAA,EAAI,IAAA;AAAA,UACJ,EAAA,EAAI,cAAA;AAAA,UACJ,mBAAA,EAAqB,MAAM,OAAA,IAAW,IAAA;AAAA,UACtC,SAAA,EAAW;AAAA,SACZ,CAAA;AACD,QAAA;AAAA,MACF,KAAK,UAAA,EAAY;AACf,QAAA,IAAI,CAAC,KAAA,CAAM,MAAA,IAAU,CAAC,MAAM,QAAA,EAAU;AACpC,UAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAA,CAAI,IAAI,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAmB,CAAA;AACjF,UAAA;AAAA,QACF;AACA,QAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,UAAA,KAAA,CAAM;AAAA,YACJ,CAAA,EAAG,mBAAA;AAAA,YACH,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,EAAA,EAAI,KAAA;AAAA,YACJ,KAAA,EAAO;AAAA,WACR,CAAA;AACD,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,MAAA;AACJ,QAAA,IAAI;AACF,UAAA,MAAM,UAAU,MAAM,kBAAA,CAAmB,KAAA,CAAM,OAAA,EAAS,MAAM,QAAQ,CAAA;AACtE,UAAA,MAAM,MAAA,GAAS,MAAM,iBAAA,CAAkB,OAAA,EAAS,IAAI,QAAA,EAAU;AAAA,YAC5D,OAAA,EAAS,IAAI,IAAA,EAAM,OAAA;AAAA,YACnB,cAAA,EAAgB,IAAI,IAAA,EAAM,cAAA;AAAA,YAC1B,cAAA,EAAgB,IAAI,IAAA,EAAM,cAAA;AAAA,YAC1B,0BAAA,EAA4B,IAAI,IAAA,EAAM,0BAAA;AAAA,YACtC,eAAA,EAAiB,IAAI,IAAA,EAAM,eAAA;AAAA,YAC3B,SAAA,EAAW,IAAI,IAAA,EAAM,SAAA;AAAA,YACrB,WAAA,EAAa,IAAI,IAAA,EAAM,WAAA;AAAA,YACvB,cAAA,EAAgB,IAAI,IAAA,EAAM;AAAA,WAC3B,CAAA;AACD,UAAA,MAAA,GAAS;AAAA,YACP,MAAM,MAAA,CAAO,IAAA;AAAA,YACb,OAAO,KAAA,CAAM,QAAA;AAAA,YACb,SAAA,EAAW,SAAA;AAAA,YACX,aAAa,MAAA,CAAO,WAAA;AAAA,YACpB,oBAAoB,MAAA,CAAO;AAAA,WAC7B;AAAA,QACF,CAAA,CAAA,MAAQ;AACN,UAAA,MAAM,IAAA,GAAO,MAAM,wBAAA,CAAyB;AAAA,YAC1C,KAAK,KAAA,CAAM,OAAA;AAAA,YACX,WAAW,KAAA,CAAM,QAAA;AAAA,YACjB,UAAU,GAAA,CAAI,QAAA;AAAA,YACd,MAAM,GAAA,CAAI;AAAA,WACX,CAAA;AACD,UAAA,MAAA,GAAS;AAAA,YACP,IAAA;AAAA,YACA,OAAO,KAAA,CAAM,QAAA;AAAA,YACb,SAAA,EAAW,SAAA;AAAA,YACX,aAAa,CAAC,EAAE,GAAA,CAAI,IAAA,EAAM,WAAW,KAAA,CAAM,OAAA;AAAA,WAC7C;AAAA,QACF;AACA,QAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAA,CAAI,EAAA,EAAI,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,UAAA,EAAY,MAAA,EAAQ,CAAA;AAC9E,QAAA;AAAA,MACF;AAAA,MACA;AACE,QAAA,KAAA,CAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAK,GAAA,CAAuB,IAAI,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,YAAA,EAAc,CAAA;AAAA;AACpG,EACF,SAAS,CAAA,EAAG;AACV,IAAA,KAAA,CAAM;AAAA,MACJ,CAAA,EAAG,mBAAA;AAAA,MACH,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,EAAA,EAAI,KAAA;AAAA,MACJ,OAAO,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC;AAAA,KACjD,CAAA;AAAA,EACH;AACF;AAGO,IAAM,iBAAN,MAAwC;AAAA,EAI7C,YAA6B,UAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAA,EAAqB;AAAA,EAArB,UAAA;AAAA,EAHpB,SAAA,GAAY,SAAA;AAAA,EACb,GAAA,GAAM,CAAA;AAAA,EAId,WAAA,GAAsB;AACpB,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,2BAAA,GAAuC;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,QAAA,EAAiC;AAC1C,IAAA,MAAM,KAAK,GAAA,CAAI,EAAE,EAAA,EAAI,MAAA,EAAQ,UAAU,CAAA;AAAA,EACzC;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC5B,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,EAAE,EAAA,EAAI,UAAU,CAAA;AAAA,EACjC;AAAA,EAEA,MAAM,QAAA,CAAS,QAAA,EAA4B,IAAA,EAAuD;AAChG,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,GAAA,CAAI,EAAE,EAAA,EAAI,UAAA,EAAY,QAAA,EAAU,IAAA,EAAM,CAAA;AAC7D,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,GAAA,CAAI,OAAO,UAAA,EAAY;AACpC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAC,IAAI,EAAA,GAAK,GAAA,CAAI,QAAQ,qBAAqB,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,GAAA,CAAI,MAAA;AAAA,EACb;AAAA,EAEA,YAAA,GAAgC;AAE9B,IAAA,OAAO,EAAE,SAAA,EAAW,SAAA,EAAW,QAAA,EAAU,IAAA,EAAM,QAAQ,KAAA,EAAM;AAAA,EAC/D;AAAA,EAEA,MAAM,iBAAA,GAA8C;AAClD,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,IAAI,EAAE,EAAA,EAAI,UAAU,CAAA;AAC3C,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,GAAA,CAAI,OAAO,QAAA,EAAU;AAClC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAC,IAAI,EAAA,GAAK,GAAA,CAAI,QAAQ,qBAAqB,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,GAAA,CAAI,MAAA;AAAA,EACb;AAAA,EAEQ,IAAI,IAAA,EAAmD;AAC7D,IAAA,MAAM,EAAA,GAAK,CAAA,CAAA,EAAI,EAAE,IAAA,CAAK,GAAG,CAAA,CAAA;AACzB,IAAA,MAAM,MAAM,EAAE,CAAA,EAAG,mBAAA,EAAqB,EAAA,EAAI,GAAG,IAAA,EAAK;AAClD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,MAAA,GAAa,GAAA,CAAA,gBAAA,CAAiB,IAAA,CAAK,UAAU,CAAA;AACnD,MAAA,IAAI,GAAA,GAAM,EAAA;AACV,MAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,QAAA,MAAA,CAAO,OAAA,EAAQ;AACf,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAA,CAAK,UAAU,GAAG,CAAC,CAAA;AAAA,MAC/D,GAAG,IAAO,CAAA;AACV,MAAA,MAAA,CAAO,YAAY,MAAM,CAAA;AACzB,MAAA,MAAA,CAAO,EAAA,CAAG,WAAW,MAAM;AACzB,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC;AAAA,CAAI,CAAA;AAAA,MACzC,CAAC,CAAA;AACD,MAAA,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAkB;AACnC,QAAA,GAAA,IAAO,KAAA;AACP,QAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAC3B,QAAA,IAAI,KAAK,CAAA,EAAG;AACZ,QAAA,MAAM,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AACnC,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,MAAA,CAAO,GAAA,EAAI;AACX,QAAA,IAAI;AACF,UAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAuB,CAAA;AAAA,QAChD,SAAS,CAAA,EAAG;AACV,UAAA,MAAA,CAAO,CAAC,CAAA;AAAA,QACV;AAAA,MACF,CAAC,CAAA;AACD,MAAA,MAAA,CAAO,EAAA,CAAG,OAAA,EAAS,CAAC,CAAA,KAAM;AACxB,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,MAAA,CAAO,CAAC,CAAA;AAAA,MACV,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AACF;AAGO,IAAM,oBAAA,GAAN,cAAmC,cAAA,CAAe;AAAC;;;ACpPnD,SAAS,aAAA,CAAc,OAAA,GAAgC,EAAC,EAAY;AACzE,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,UAAA;AACvC,EAAA,IAAI,cAAc,SAAA,EAAW;AAC3B,IAAA,OAAO,IAAI,cAAA,CAAe,OAAA,CAAQ,QAAA,IAAY,wBAAwB,CAAA;AAAA,EACxE;AACA,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,EAAA,IAAI,OAAA,CAAQ,OAAA,EAAS,IAAA,CAAK,UAAA,CAAW,QAAQ,OAAO,CAAA;AACpD,EAAA,IAAI,OAAA,CAAQ,aAAA,EAAe,IAAA,CAAK,gBAAA,CAAiB,IAAI,CAAA;AACrD,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,sBAAA,CAAuB,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAa;AACnF,EAAA,OAAYA,IAAA,CAAA,IAAA,CAAK,kBAAA,CAAmB,GAAG,CAAA,EAAG,eAAe,CAAA;AAC3D;AAGO,SAAS,yBAAA,CACd,QAAA,EACA,GAAA,GAAyB,OAAA,CAAQ,GAAA,EACf;AAClB,EAAA,IAAI,QAAA,KAAa,UAAA,IAAc,QAAA,KAAa,SAAA,EAAW,OAAO,QAAA;AAC9D,EAAA,MAAM,KAAK,GAAA,CAAI,4BAAA,IAAgC,GAAA,CAAI,sBAAA,IAA0B,IAAI,WAAA,EAAY;AAC7F,EAAA,IAAI,CAAA,KAAM,SAAA,IAAa,CAAA,KAAM,UAAA,EAAY,OAAO,SAAA;AAChD,EAAA,OAAO,UAAA;AACT","file":"chunk-SIPGDJT4.js","sourcesContent":["/**\n * node-llama-cpp binding adapter — pure glue so embedded + process hosts share\n * one code path. The module is injected (from ensurePackage); never imported\n * statically so the published CLI stays free of native deps.\n */\n\nimport type { LlmChatMessage, LlmGenerateOptions } from './types.js';\n\nexport interface LlamaBindingGenerateInput {\n /** Loaded node-llama-cpp module (dynamic). */\n lib: unknown;\n modelPath: string;\n messages: LlmChatMessage[];\n opts?: LlmGenerateOptions;\n}\n\n/**\n * Run one chat completion via node-llama-cpp. Throws on binding/model errors\n * (callers wrap with redaction).\n */\nexport async function generateWithLlamaBinding(input: LlamaBindingGenerateInput): Promise<string> {\n const lib: any = input.lib;\n if (!lib || typeof lib.getLlama !== 'function') {\n throw new Error('llm-host: invalid node-llama-cpp module (getLlama missing)');\n }\n const llama = await lib.getLlama();\n const model = await llama.loadModel({ modelPath: input.modelPath });\n const ctx = await model.createContext();\n const { LlamaChatSession } = lib;\n if (typeof LlamaChatSession !== 'function') {\n throw new Error('llm-host: LlamaChatSession missing from node-llama-cpp module');\n }\n const chat = new LlamaChatSession({ contextSequence: ctx.getSequence() });\n const prompt = input.messages.map((m) => `${m.role}: ${m.content}`).join('\\n\\n');\n const temperature = input.opts?.temperature ?? 0;\n const maxTokens = input.opts?.maxTokens;\n // Grammar: pass through when binding supports it (future constrained PatchIR).\n const promptOpts: Record<string, unknown> = { temperature };\n if (typeof maxTokens === 'number') promptOpts.maxTokens = maxTokens;\n if (input.opts?.grammar) {\n // Best-effort: node-llama-cpp versions differ on the grammar API surface.\n promptOpts.grammar = input.opts.grammar;\n }\n const text: string = await chat.prompt(prompt, promptOpts);\n return typeof text === 'string' ? text : String(text ?? '');\n}\n","/**\n * Embedded llm-host (Approach B default) — same address space as the agent.\n *\n * Production path: warm session pool ({@link acquireHostSession}) so models are\n * not reloaded every chat turn. Binding is injected via {@link setBinding}.\n */\n\nimport { annotateUnknownIdentifiers } from '../identifier-mask.js';\nimport { generateWithLlamaBinding } from './binding.js';\nimport {\n acquireHostSession,\n generateOnSession,\n type HostGenerateReport,\n} from './session.js';\nimport type {\n LlmChatMessage,\n LlmGenerateOptions,\n LlmGenerateResult,\n LlmHost,\n LlmMemoryReport,\n} from './types.js';\n\nexport class EmbeddedLlmHost implements LlmHost {\n readonly isolation = 'embedded' as const;\n private modelRef: string | null = null;\n private loaded = false;\n private binding: unknown | null = null;\n private preferGrammar = false;\n private lastReport: HostGenerateReport | null = null;\n\n /** Attach the dynamically loaded node-llama-cpp module. */\n setBinding(lib: unknown): void {\n this.binding = lib;\n }\n\n /** Hint from MEP: attempt constrained decoding when grammar is supplied. */\n setPreferGrammar(on: boolean): void {\n this.preferGrammar = on;\n }\n\n /** Last generate metrics (KV plan, draft accept, warm start). */\n lastGenerateReport(): HostGenerateReport | null {\n return this.lastReport;\n }\n\n async load(modelRef: string): Promise<void> {\n this.modelRef = modelRef;\n this.loaded = true;\n // Eagerly warm the session when binding is already available.\n if (this.binding) {\n await acquireHostSession(this.binding, modelRef);\n }\n }\n\n async unload(): Promise<void> {\n this.modelRef = null;\n this.loaded = false;\n this.lastReport = null;\n }\n\n supportsConstrainedDecoding(): boolean {\n return this.preferGrammar && this.binding != null;\n }\n\n memoryReport(): LlmMemoryReport {\n return {\n isolation: this.isolation,\n modelRef: this.modelRef,\n loaded: this.loaded,\n };\n }\n\n async generate(messages: LlmChatMessage[], opts: LlmGenerateOptions = {}): Promise<LlmGenerateResult> {\n if (!this.loaded || !this.modelRef) {\n throw new Error('llm-host: no model loaded — orchestrator must call load() after resolve/install');\n }\n if (!this.binding) {\n throw new Error(\n 'llm-host: node-llama-cpp binding not attached — run `vg models install` for the llama-cpp provider, then retry',\n );\n }\n\n // Production path: pooled warm session.\n try {\n const session = await acquireHostSession(this.binding, this.modelRef);\n const report = await generateOnSession(session, messages, {\n grammar: opts.grammar,\n requireGrammar: opts.requireGrammar,\n identifierTrie: opts.identifierTrie,\n annotateUnknownIdentifiers: opts.annotateUnknownIdentifiers,\n draftCandidates: opts.draftCandidates,\n maxTokens: opts.maxTokens,\n temperature: opts.temperature,\n promptSegments: opts.promptSegments,\n });\n this.lastReport = report;\n return {\n text: report.text,\n model: report.model,\n isolation: report.isolation,\n constrained: report.constrained || !!(opts.grammar && this.preferGrammar),\n unknownIdentifiers: report.unknownIdentifiers,\n };\n } catch {\n // Fallback one-shot (tests / minimal bindings).\n let text = await generateWithLlamaBinding({\n lib: this.binding,\n modelPath: this.modelRef,\n messages,\n opts,\n });\n let unknownIdentifiers: string[] | undefined;\n if (opts.identifierTrie && opts.annotateUnknownIdentifiers !== false) {\n const ann = annotateUnknownIdentifiers(text, opts.identifierTrie);\n text = ann.text;\n unknownIdentifiers = ann.unknown.length ? ann.unknown : undefined;\n }\n return {\n text,\n model: this.modelRef,\n isolation: this.isolation,\n constrained: !!(opts.grammar && this.supportsConstrainedDecoding()),\n unknownIdentifiers,\n };\n }\n }\n}\n","/**\n * Process-isolation llm-host: client + server over a Unix/local socket.\n *\n * Management (Code Modes, fit, packs, install) stays in vgd / the CLI.\n * This process only loads weights and decodes (ADR-005).\n */\n\nimport * as fs from 'node:fs';\nimport * as net from 'node:net';\nimport * as path from 'node:path';\nimport { generateWithLlamaBinding } from './binding.js';\nimport { acquireHostSession, generateOnSession } from './session.js';\nimport type {\n LlmChatMessage,\n LlmGenerateOptions,\n LlmGenerateResult,\n LlmHost,\n LlmMemoryReport,\n} from './types.js';\n\nexport const LLM_HOST_IPC_SCHEMA = 'llm-host-ipc/0' as const;\n\nexport type LlmHostIpcRequest =\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'load'; modelRef: string }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'unload' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'generate'; messages: LlmChatMessage[]; opts?: LlmGenerateOptions }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'memory' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'capabilities' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; op: 'ping' };\n\nexport type LlmHostIpcResponse =\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'load' | 'unload' | 'ping' }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'generate'; result: LlmGenerateResult }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: true; op: 'memory'; report: LlmMemoryReport }\n | {\n v: typeof LLM_HOST_IPC_SCHEMA;\n id: string;\n ok: true;\n op: 'capabilities';\n constrainedDecoding: boolean;\n isolation: 'process';\n }\n | { v: typeof LLM_HOST_IPC_SCHEMA; id: string; ok: false; error: string };\n\n/** Request body without envelope — distribute Omit over the union (keyof union is only common keys). */\nexport type LlmHostIpcBody = LlmHostIpcRequest extends infer R\n ? R extends { v: typeof LLM_HOST_IPC_SCHEMA; id: string }\n ? Omit<R, 'v' | 'id'>\n : never\n : never;\n\nexport interface ProcessHostServerOptions {\n socketPath: string;\n /** node-llama-cpp module (optional until first generate). */\n binding?: unknown;\n onListen?: (socketPath: string) => void;\n}\n\n/**\n * Serve llm-host IPC on a local socket. Resolves when the server is listening;\n * call the returned `close` to stop.\n */\nexport function startProcessHostServer(options: ProcessHostServerOptions): Promise<{ close: () => Promise<void> }> {\n const state = {\n modelRef: null as string | null,\n loaded: false,\n binding: options.binding ?? null,\n };\n\n try {\n if (fs.existsSync(options.socketPath)) fs.unlinkSync(options.socketPath);\n } catch {\n /* ignore */\n }\n fs.mkdirSync(path.dirname(options.socketPath), { recursive: true });\n\n return new Promise((resolve, reject) => {\n const server = net.createServer((socket) => {\n let buf = '';\n socket.setEncoding('utf8');\n socket.on('data', (chunk: string) => {\n buf += chunk;\n let nl: number;\n while ((nl = buf.indexOf('\\n')) >= 0) {\n const line = buf.slice(0, nl).trim();\n buf = buf.slice(nl + 1);\n if (!line) continue;\n void handleLine(line, state, (resp) => {\n socket.write(`${JSON.stringify(resp)}\\n`);\n });\n }\n });\n });\n\n server.once('error', reject);\n server.listen(options.socketPath, () => {\n options.onListen?.(options.socketPath);\n resolve({\n close: () =>\n new Promise((res, rej) => {\n server.close((err) => {\n try {\n if (fs.existsSync(options.socketPath)) fs.unlinkSync(options.socketPath);\n } catch {\n /* ignore */\n }\n if (err) rej(err);\n else res();\n });\n }),\n });\n });\n });\n}\n\n/** Attach binding after server start (e.g. after ensurePackage). */\nexport type ProcessHostState = {\n modelRef: string | null;\n loaded: boolean;\n binding: unknown | null;\n};\n\nasync function handleLine(\n line: string,\n state: ProcessHostState,\n reply: (r: LlmHostIpcResponse) => void,\n): Promise<void> {\n let req: LlmHostIpcRequest;\n try {\n req = JSON.parse(line) as LlmHostIpcRequest;\n } catch {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: '?', ok: false, error: 'invalid JSON' });\n return;\n }\n if (req.v !== LLM_HOST_IPC_SCHEMA) {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: false, error: `unsupported schema ${String((req as { v?: string }).v)}` });\n return;\n }\n\n try {\n switch (req.op) {\n case 'ping':\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'ping' });\n return;\n case 'load':\n state.modelRef = req.modelRef;\n state.loaded = true;\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'load' });\n return;\n case 'unload':\n state.modelRef = null;\n state.loaded = false;\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'unload' });\n return;\n case 'memory':\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: true,\n op: 'memory',\n report: { isolation: 'process', modelRef: state.modelRef, loaded: state.loaded },\n });\n return;\n case 'capabilities':\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: true,\n op: 'capabilities',\n constrainedDecoding: state.binding != null,\n isolation: 'process',\n });\n return;\n case 'generate': {\n if (!state.loaded || !state.modelRef) {\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: false, error: 'no model loaded' });\n return;\n }\n if (!state.binding) {\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: false,\n error: 'binding not loaded in host process — start host after vg models install',\n });\n return;\n }\n // Same warm session path as embedded (Approach B parity for enterprise isolation).\n let result: LlmGenerateResult;\n try {\n const session = await acquireHostSession(state.binding, state.modelRef);\n const report = await generateOnSession(session, req.messages, {\n grammar: req.opts?.grammar,\n requireGrammar: req.opts?.requireGrammar,\n identifierTrie: req.opts?.identifierTrie,\n annotateUnknownIdentifiers: req.opts?.annotateUnknownIdentifiers,\n draftCandidates: req.opts?.draftCandidates,\n maxTokens: req.opts?.maxTokens,\n temperature: req.opts?.temperature,\n promptSegments: req.opts?.promptSegments,\n });\n result = {\n text: report.text,\n model: state.modelRef,\n isolation: 'process',\n constrained: report.constrained,\n unknownIdentifiers: report.unknownIdentifiers,\n };\n } catch {\n const text = await generateWithLlamaBinding({\n lib: state.binding,\n modelPath: state.modelRef,\n messages: req.messages,\n opts: req.opts,\n });\n result = {\n text,\n model: state.modelRef,\n isolation: 'process',\n constrained: !!(req.opts?.grammar && state.binding),\n };\n }\n reply({ v: LLM_HOST_IPC_SCHEMA, id: req.id, ok: true, op: 'generate', result });\n return;\n }\n default:\n reply({ v: LLM_HOST_IPC_SCHEMA, id: (req as { id: string }).id, ok: false, error: 'unknown op' });\n }\n } catch (e) {\n reply({\n v: LLM_HOST_IPC_SCHEMA,\n id: req.id,\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n}\n\n/** Client: full {@link LlmHost} over the process socket. */\nexport class ProcessLlmHost implements LlmHost {\n readonly isolation = 'process' as const;\n private seq = 0;\n\n constructor(private readonly socketPath: string) {}\n\n getEndpoint(): string {\n return this.socketPath;\n }\n\n supportsConstrainedDecoding(): boolean {\n return true; // host may apply grammar when binding is present\n }\n\n async load(modelRef: string): Promise<void> {\n await this.rpc({ op: 'load', modelRef });\n }\n\n async unload(): Promise<void> {\n await this.rpc({ op: 'unload' });\n }\n\n async generate(messages: LlmChatMessage[], opts?: LlmGenerateOptions): Promise<LlmGenerateResult> {\n const res = await this.rpc({ op: 'generate', messages, opts });\n if (!res.ok || res.op !== 'generate') {\n throw new Error(!res.ok ? res.error : 'unexpected response');\n }\n return res.result;\n }\n\n memoryReport(): LlmMemoryReport {\n // Sync surface required by LlmHost; use last known or empty (async memory via rpc elsewhere).\n return { isolation: 'process', modelRef: null, loaded: false };\n }\n\n async memoryReportAsync(): Promise<LlmMemoryReport> {\n const res = await this.rpc({ op: 'memory' });\n if (!res.ok || res.op !== 'memory') {\n throw new Error(!res.ok ? res.error : 'unexpected response');\n }\n return res.report;\n }\n\n private rpc(body: LlmHostIpcBody): Promise<LlmHostIpcResponse> {\n const id = `r${++this.seq}`;\n const req = { v: LLM_HOST_IPC_SCHEMA, id, ...body } as LlmHostIpcRequest;\n return new Promise((resolve, reject) => {\n const socket = net.createConnection(this.socketPath);\n let buf = '';\n const timer = setTimeout(() => {\n socket.destroy();\n reject(new Error(`llm-host IPC timeout (${this.socketPath})`));\n }, 120_000);\n socket.setEncoding('utf8');\n socket.on('connect', () => {\n socket.write(`${JSON.stringify(req)}\\n`);\n });\n socket.on('data', (chunk: string) => {\n buf += chunk;\n const nl = buf.indexOf('\\n');\n if (nl < 0) return;\n const line = buf.slice(0, nl).trim();\n clearTimeout(timer);\n socket.end();\n try {\n resolve(JSON.parse(line) as LlmHostIpcResponse);\n } catch (e) {\n reject(e);\n }\n });\n socket.on('error', (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n }\n}\n\n/** @deprecated use ProcessLlmHost */\nexport class ProcessBridgeLlmHost extends ProcessLlmHost {}\n","/**\n * Factory for the dual-mode llm-host (ADR-005).\n *\n * `createLlmHost({ isolation: 'embedded' })` — default Approach B.\n * `createLlmHost({ isolation: 'process', endpoint })` — enterprise shell.\n */\n\nimport * as path from 'node:path';\nimport { vibgrateRuntimeDir } from '../paths.js';\nimport { EmbeddedLlmHost } from './embedded.js';\nimport { ProcessLlmHost } from './process-bridge.js';\nimport type { LlmHost, LlmHostIsolation } from './types.js';\n\nexport type {\n LlmHost,\n LlmHostConfig,\n LlmHostIsolation,\n LlmChatMessage,\n LlmGenerateResult,\n LlmGenerateOptions,\n LlmMemoryReport,\n} from './types.js';\nexport { EmbeddedLlmHost } from './embedded.js';\nexport {\n ProcessLlmHost,\n ProcessBridgeLlmHost,\n LLM_HOST_IPC_SCHEMA,\n startProcessHostServer,\n} from './process-bridge.js';\nexport type { LlmHostIpcRequest, LlmHostIpcResponse, ProcessHostServerOptions } from './process-bridge.js';\nexport { generateWithLlamaBinding } from './binding.js';\nexport {\n acquireHostSession,\n generateOnSession,\n clearHostSessionPool,\n hostSessionPoolSize,\n listHostSessions,\n dropHostSession,\n evictIdleSessions,\n sessionKey,\n} from './session.js';\nexport type { HostGenerateExtras, HostGenerateReport, HostSessionInfo } from './session.js';\nexport { attachGrammar, assertGrammarOrThrow, allowGrammarStringFallback } from './grammar.js';\nexport type { GrammarAttachResult, GrammarAttachMethod } from './grammar.js';\nexport {\n buildIdentifierTokenBias,\n planNextCharMask,\n tokenCompatibleWithTrie,\n trieFingerprint,\n} from './logit-mask.js';\nexport type { LogitMaskBuildResult, SamplerHookMethod, BuildLogitMaskOptions } from './logit-mask.js';\nexport {\n createIdentStreamState,\n stepIdentStream,\n filterTokenTexts,\n attachDynamicIdentFilter,\n dynamicAllowedNextChars,\n} from './identifier-sampler.js';\nexport type { IdentStreamState, IdentStepResult } from './identifier-sampler.js';\nexport { probeBindingCapabilities, supportsDynamicIdentSampler, supportsKvPrefixEvaluate } from './binding-capabilities.js';\nexport type { BindingCapabilities, ProbeBindingOptions } from './binding-capabilities.js';\nexport { composePromptConstraints } from './compose-constraints.js';\nexport { rankDraftCandidates, pickBestDraft } from './speculative.js';\nexport type { RankedDraft } from './speculative.js';\n\nexport interface CreateLlmHostOptions {\n isolation?: LlmHostIsolation;\n /** Socket path when isolation is `process`. Defaults under vibgrate runtime dir. */\n endpoint?: string;\n /** Pre-attach binding for embedded hosts (avoids a second ensure). */\n binding?: unknown;\n preferGrammar?: boolean;\n}\n\nexport function createLlmHost(options: CreateLlmHostOptions = {}): LlmHost {\n const isolation = options.isolation ?? 'embedded';\n if (isolation === 'process') {\n return new ProcessLlmHost(options.endpoint ?? defaultProcessEndpoint());\n }\n const host = new EmbeddedLlmHost();\n if (options.binding) host.setBinding(options.binding);\n if (options.preferGrammar) host.setPreferGrammar(true);\n return host;\n}\n\n/** Default IPC socket path for the isolated llm-host process. */\nexport function defaultProcessEndpoint(env: NodeJS.ProcessEnv = process.env): string {\n return path.join(vibgrateRuntimeDir(env), 'llm-host.sock');\n}\n\n/** Resolve isolation from env / explicit override (MEP / config later). */\nexport function resolveInferenceIsolation(\n explicit?: LlmHostIsolation,\n env: NodeJS.ProcessEnv = process.env,\n): LlmHostIsolation {\n if (explicit === 'embedded' || explicit === 'process') return explicit;\n const v = (env.VIBGRATE_INFERENCE_ISOLATION || env.VG_INFERENCE_ISOLATION || '').toLowerCase();\n if (v === 'process' || v === 'isolated') return 'process';\n return 'embedded';\n}\n"]}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { isPackageInstalled, ensurePackage } from './chunk-OSD546W7.js';
|
|
2
|
+
import { isWeightCached, lookupCatalog } from './chunk-GYSOQH5C.js';
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
// src/runtime/model-install-plan.ts
|
|
6
|
+
var MODEL_INSTALL_PLAN_SCHEMA_VERSION = "model-install-plan/0";
|
|
7
|
+
function runtimeDepsForBackend(backend) {
|
|
8
|
+
const b = backend.toLowerCase();
|
|
9
|
+
if (b === "llama.cpp" || b === "llama-cpp" || b === "vibgrate") {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
id: "node-llama-cpp",
|
|
13
|
+
kind: "npm-runtime",
|
|
14
|
+
spec: "node-llama-cpp@^3",
|
|
15
|
+
reason: "in-process llama.cpp binding for the first-party / llama-cpp provider"
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
if (b === "ollama") {
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
id: "ollama",
|
|
23
|
+
kind: "native-binary",
|
|
24
|
+
binary: "ollama",
|
|
25
|
+
reason: "Ollama on PATH (install from https://ollama.com \u2014 third-party apps are not auto-installed)"
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
function weightsChannelForBackend(backend, opts) {
|
|
32
|
+
const b = backend.toLowerCase();
|
|
33
|
+
if (b === "ollama") return "ollama";
|
|
34
|
+
if (b === "llama.cpp" || b === "llama-cpp" || b === "vibgrate") {
|
|
35
|
+
if (opts?.downloadUrl || opts?.weightsRef && lookupCatalog(opts.weightsRef)) return "vibgrate";
|
|
36
|
+
return "local-path";
|
|
37
|
+
}
|
|
38
|
+
if (b === "lm-studio" || b === "lmstudio" || b === "foundry-local") return "manual";
|
|
39
|
+
return "manual";
|
|
40
|
+
}
|
|
41
|
+
function weightsInstalled(ref, installedNames) {
|
|
42
|
+
const want = ref.toLowerCase();
|
|
43
|
+
return installedNames.some((n) => {
|
|
44
|
+
const have = n.toLowerCase();
|
|
45
|
+
return have === want || have.includes(want) || want.includes(have);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function buildModelInstallPlan(input) {
|
|
49
|
+
const hasBinary = input.hasBinary ?? (() => false);
|
|
50
|
+
const pkgInstalled = input.isPackageInstalled ?? isPackageInstalled;
|
|
51
|
+
const installedNames = input.installedNames ?? [];
|
|
52
|
+
const offline = !!input.offline;
|
|
53
|
+
const backend = input.backend;
|
|
54
|
+
const provider = providerLabel(backend);
|
|
55
|
+
const runtimeDeps = runtimeDepsForBackend(backend).map((dep) => {
|
|
56
|
+
if (dep.kind === "npm-runtime" && dep.spec) {
|
|
57
|
+
return { ...dep, status: pkgInstalled(dep.spec) ? "satisfied" : "missing" };
|
|
58
|
+
}
|
|
59
|
+
if (dep.kind === "native-binary" && dep.binary) {
|
|
60
|
+
return { ...dep, status: hasBinary(dep.binary) ? "satisfied" : "unmanaged" };
|
|
61
|
+
}
|
|
62
|
+
return { ...dep, status: "unmanaged" };
|
|
63
|
+
});
|
|
64
|
+
const channel = weightsChannelForBackend(backend, {
|
|
65
|
+
downloadUrl: input.downloadUrl,
|
|
66
|
+
weightsRef: input.weightsRef
|
|
67
|
+
});
|
|
68
|
+
const weightCached = (input.isWeightCached ?? isWeightCached)(input.weightsRef);
|
|
69
|
+
const catalog = lookupCatalog(input.weightsRef);
|
|
70
|
+
const downloadUrl = input.downloadUrl ?? catalog?.url;
|
|
71
|
+
let weightsStatus = "missing";
|
|
72
|
+
if (channel === "ollama") {
|
|
73
|
+
weightsStatus = weightsInstalled(input.weightsRef, installedNames) ? "satisfied" : "missing";
|
|
74
|
+
} else if (channel === "vibgrate") {
|
|
75
|
+
weightsStatus = weightCached || weightsInstalled(input.weightsRef, installedNames) || !!input.modelPath ? "satisfied" : "missing";
|
|
76
|
+
} else if (channel === "local-path") {
|
|
77
|
+
weightsStatus = weightsInstalled(input.weightsRef, installedNames) || !!input.modelPath || weightCached ? "satisfied" : "manual";
|
|
78
|
+
} else {
|
|
79
|
+
weightsStatus = weightsInstalled(input.weightsRef, installedNames) ? "satisfied" : "manual";
|
|
80
|
+
}
|
|
81
|
+
const alreadySatisfied = [];
|
|
82
|
+
const willInstall = [];
|
|
83
|
+
const willDownload = [];
|
|
84
|
+
const blocked = [];
|
|
85
|
+
for (const dep of runtimeDeps) {
|
|
86
|
+
if (dep.status === "satisfied") {
|
|
87
|
+
alreadySatisfied.push(dep.id);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (dep.kind === "npm-runtime" && dep.spec && dep.status === "missing") {
|
|
91
|
+
if (offline) {
|
|
92
|
+
blocked.push({ id: dep.id, reason: `${dep.spec} needed but --local/offline forbids install` });
|
|
93
|
+
} else {
|
|
94
|
+
willInstall.push(dep.spec);
|
|
95
|
+
}
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (dep.kind === "native-binary" && dep.status === "unmanaged") {
|
|
99
|
+
blocked.push({
|
|
100
|
+
id: dep.id,
|
|
101
|
+
reason: dep.reason
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (weightsStatus === "satisfied") {
|
|
106
|
+
alreadySatisfied.push(`weights:${input.weightsRef}`);
|
|
107
|
+
} else if (weightsStatus === "missing" && (channel === "ollama" || channel === "vibgrate")) {
|
|
108
|
+
if (offline) {
|
|
109
|
+
blocked.push({ id: `weights:${input.weightsRef}`, reason: "weights missing and --local/offline forbids download" });
|
|
110
|
+
} else if (channel === "ollama" && runtimeDeps.some((d) => d.id === "ollama" && d.status === "unmanaged")) {
|
|
111
|
+
willDownload.push(input.weightsRef);
|
|
112
|
+
} else if (channel === "vibgrate" && !downloadUrl) {
|
|
113
|
+
blocked.push({
|
|
114
|
+
id: `weights:${input.weightsRef}`,
|
|
115
|
+
reason: `no first-party download URL for ${input.weightsRef} \u2014 place a gguf in the weight store or pass --model-path`
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
willDownload.push(input.weightsRef);
|
|
119
|
+
}
|
|
120
|
+
} else if (weightsStatus === "manual" || weightsStatus === "missing") {
|
|
121
|
+
blocked.push({
|
|
122
|
+
id: `weights:${input.weightsRef}`,
|
|
123
|
+
reason: channel === "local-path" ? `point --model-path at a local gguf for ${input.weightsRef}, or run install when a first-party URL is catalogued` : `install or link weights for ${input.weightsRef} via the backend app`
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const effectiveWillInstall = offline ? [] : willInstall;
|
|
127
|
+
const effectiveWillDownload = offline ? [] : willDownload;
|
|
128
|
+
const offlineBlocked = offline && blocked.some((b) => /offline|forbids/i.test(b.reason));
|
|
129
|
+
const allRuntimeOk = runtimeDeps.every((d) => d.status === "satisfied");
|
|
130
|
+
const fullyReady = allRuntimeOk && weightsStatus === "satisfied" && blocked.length === 0;
|
|
131
|
+
return {
|
|
132
|
+
schemaVersion: MODEL_INSTALL_PLAN_SCHEMA_VERSION,
|
|
133
|
+
provider,
|
|
134
|
+
backend,
|
|
135
|
+
model: input.weightsRef,
|
|
136
|
+
mode: input.mode,
|
|
137
|
+
packId: input.packId,
|
|
138
|
+
license: input.license,
|
|
139
|
+
promise: input.promise,
|
|
140
|
+
fit: input.fit,
|
|
141
|
+
runtimeDeps,
|
|
142
|
+
weights: {
|
|
143
|
+
channel,
|
|
144
|
+
ref: input.weightsRef,
|
|
145
|
+
status: weightsStatus,
|
|
146
|
+
downloadUrl: channel === "vibgrate" ? downloadUrl : void 0
|
|
147
|
+
},
|
|
148
|
+
alreadySatisfied,
|
|
149
|
+
willInstall: effectiveWillInstall,
|
|
150
|
+
willDownload: effectiveWillDownload,
|
|
151
|
+
blocked,
|
|
152
|
+
offlineBlocked,
|
|
153
|
+
ready: fullyReady
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function providerLabel(backend) {
|
|
157
|
+
const b = backend.toLowerCase();
|
|
158
|
+
if (b === "llama.cpp" || b === "llama-cpp") return "llama-cpp";
|
|
159
|
+
if (b === "vibgrate") return "vibgrate";
|
|
160
|
+
if (b === "lm-studio" || b === "lmstudio") return "lmstudio";
|
|
161
|
+
if (b === "foundry-local") return "foundry-local";
|
|
162
|
+
return b === "ollama" ? "ollama" : backend;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/runtime/model-manager.ts
|
|
166
|
+
var LABELS = {
|
|
167
|
+
vibgrate: {
|
|
168
|
+
label: "Vibgrate",
|
|
169
|
+
note: "Code Mode \xB7 first-party model manager (embedded inference)"
|
|
170
|
+
},
|
|
171
|
+
ollama: {
|
|
172
|
+
label: "Ollama",
|
|
173
|
+
note: "Custom local \xB7 Ollama"
|
|
174
|
+
},
|
|
175
|
+
lmstudio: {
|
|
176
|
+
label: "LM Studio",
|
|
177
|
+
note: "Custom local \xB7 LM Studio"
|
|
178
|
+
},
|
|
179
|
+
"foundry-local": {
|
|
180
|
+
label: "Foundry Local",
|
|
181
|
+
note: "Custom local \xB7 Foundry Local"
|
|
182
|
+
},
|
|
183
|
+
openrouter: {
|
|
184
|
+
label: "OpenRouter",
|
|
185
|
+
note: "Custom hosted \xB7 OpenRouter"
|
|
186
|
+
},
|
|
187
|
+
litellm: {
|
|
188
|
+
label: "LiteLLM",
|
|
189
|
+
note: "Custom hosted \xB7 LiteLLM"
|
|
190
|
+
},
|
|
191
|
+
openai: {
|
|
192
|
+
label: "OpenAI",
|
|
193
|
+
note: "Custom hosted \xB7 OpenAI"
|
|
194
|
+
},
|
|
195
|
+
together: {
|
|
196
|
+
label: "Together",
|
|
197
|
+
note: "Custom hosted \xB7 Together"
|
|
198
|
+
},
|
|
199
|
+
mock: {
|
|
200
|
+
label: "Mock",
|
|
201
|
+
note: "Scripted offline provider"
|
|
202
|
+
},
|
|
203
|
+
other: {
|
|
204
|
+
label: "Custom",
|
|
205
|
+
note: "Custom model backend"
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
function managerFromProviderId(providerId) {
|
|
209
|
+
const id = (providerId ?? "").toLowerCase().trim();
|
|
210
|
+
if (id === "llama-cpp" || id === "llama.cpp" || id === "vibgrate" || id === "vibgrate-store") return "vibgrate";
|
|
211
|
+
if (id === "ollama") return "ollama";
|
|
212
|
+
if (id === "lmstudio" || id === "lm-studio") return "lmstudio";
|
|
213
|
+
if (id === "foundry-local" || id === "foundry") return "foundry-local";
|
|
214
|
+
if (id === "openrouter") return "openrouter";
|
|
215
|
+
if (id === "litellm") return "litellm";
|
|
216
|
+
if (id === "openai") return "openai";
|
|
217
|
+
if (id === "together") return "together";
|
|
218
|
+
if (id === "mock" || id === "scripted") return "mock";
|
|
219
|
+
return "other";
|
|
220
|
+
}
|
|
221
|
+
function managerBadge(id) {
|
|
222
|
+
const meta = LABELS[id] ?? LABELS.other;
|
|
223
|
+
return {
|
|
224
|
+
id,
|
|
225
|
+
label: meta.label,
|
|
226
|
+
badge: `[${meta.label}]`,
|
|
227
|
+
note: meta.note
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function formatManagerBadgeLine(id, model) {
|
|
231
|
+
const b = managerBadge(id);
|
|
232
|
+
const modelPart = model ? ` \xB7 ${model}` : "";
|
|
233
|
+
return `${b.badge} ${b.note}${modelPart}`;
|
|
234
|
+
}
|
|
235
|
+
function defaultHasBinary(name) {
|
|
236
|
+
const res = spawnSync(name, ["--version"], { stdio: "ignore", encoding: "utf8" });
|
|
237
|
+
if (res.status === 0) return true;
|
|
238
|
+
const which = spawnSync(process.platform === "win32" ? "where" : "which", [name], {
|
|
239
|
+
stdio: "ignore",
|
|
240
|
+
encoding: "utf8"
|
|
241
|
+
});
|
|
242
|
+
return which.status === 0;
|
|
243
|
+
}
|
|
244
|
+
async function ensureManagerRuntime(opts) {
|
|
245
|
+
const manager = managerFromProviderId(opts.providerId);
|
|
246
|
+
const badge = managerBadge(manager);
|
|
247
|
+
const installed = [];
|
|
248
|
+
const pulled = [];
|
|
249
|
+
const messages = [];
|
|
250
|
+
const ensure = opts.ensurePackage ?? ensurePackage;
|
|
251
|
+
const hasBinary = opts.hasBinary ?? defaultHasBinary;
|
|
252
|
+
if (manager === "openrouter" || manager === "litellm" || manager === "openai" || manager === "together" || manager === "mock") {
|
|
253
|
+
return { ok: true, manager, badge, installed, pulled, messages };
|
|
254
|
+
}
|
|
255
|
+
if (manager === "lmstudio" || manager === "foundry-local") {
|
|
256
|
+
messages.push(
|
|
257
|
+
manager === "lmstudio" ? "LM Studio must already be running with a model loaded (we never install the app)" : "Foundry Local must already be running (we never install the app)"
|
|
258
|
+
);
|
|
259
|
+
return { ok: true, manager, badge, installed, pulled, messages };
|
|
260
|
+
}
|
|
261
|
+
const backend = manager === "vibgrate" ? "llama.cpp" : manager === "ollama" ? "ollama" : opts.providerId;
|
|
262
|
+
const deps = runtimeDepsForBackend(backend);
|
|
263
|
+
for (const dep of deps) {
|
|
264
|
+
if (dep.kind === "npm-runtime" && dep.spec) {
|
|
265
|
+
if (isPackageInstalled(dep.spec)) {
|
|
266
|
+
messages.push(`${dep.id} already installed`);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (opts.offline) {
|
|
270
|
+
return {
|
|
271
|
+
ok: false,
|
|
272
|
+
manager,
|
|
273
|
+
badge,
|
|
274
|
+
installed,
|
|
275
|
+
pulled,
|
|
276
|
+
messages,
|
|
277
|
+
error: `${dep.spec} needed but offline/--local forbids install`
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
if (!opts.consent) {
|
|
281
|
+
return {
|
|
282
|
+
ok: false,
|
|
283
|
+
manager,
|
|
284
|
+
badge,
|
|
285
|
+
installed,
|
|
286
|
+
pulled,
|
|
287
|
+
messages,
|
|
288
|
+
error: `${dep.spec} needed \u2014 pass --yes or run \`vg models install\` once`
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
opts.onProgress?.(`installing ${dep.spec}`);
|
|
292
|
+
const ensureOpts = {
|
|
293
|
+
consent: true,
|
|
294
|
+
local: false,
|
|
295
|
+
interactive: false
|
|
296
|
+
};
|
|
297
|
+
const res = await ensure(dep.spec, ensureOpts);
|
|
298
|
+
if (!res.module) {
|
|
299
|
+
return {
|
|
300
|
+
ok: false,
|
|
301
|
+
manager,
|
|
302
|
+
badge,
|
|
303
|
+
installed,
|
|
304
|
+
pulled,
|
|
305
|
+
messages,
|
|
306
|
+
error: `couldn't install ${dep.spec}`
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
installed.push(dep.spec);
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (dep.kind === "native-binary" && dep.binary) {
|
|
313
|
+
if (!hasBinary(dep.binary)) {
|
|
314
|
+
return {
|
|
315
|
+
ok: false,
|
|
316
|
+
manager,
|
|
317
|
+
badge,
|
|
318
|
+
installed,
|
|
319
|
+
pulled,
|
|
320
|
+
messages,
|
|
321
|
+
error: dep.reason || `${dep.binary} is not on PATH \u2014 install it once, then re-run (vg never auto-installs third-party apps)`
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
messages.push(`${dep.binary} on PATH`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (manager === "ollama" && opts.model && opts.consent && !opts.offline) {
|
|
328
|
+
const list = spawnSync("ollama", ["list"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
329
|
+
const have = list.status === 0 && (list.stdout ?? "").split("\n").slice(1).some((line) => {
|
|
330
|
+
const name = line.trim().split(/\s+/)[0]?.toLowerCase();
|
|
331
|
+
return name === opts.model.toLowerCase() || name?.startsWith(`${opts.model.toLowerCase()}:`);
|
|
332
|
+
});
|
|
333
|
+
if (!have) {
|
|
334
|
+
opts.onProgress?.(`pulling ${opts.model}`);
|
|
335
|
+
const pull = opts.ollamaPull ?? ((name) => spawnSync("ollama", ["pull", name], { stdio: "ignore" }).status ?? 1);
|
|
336
|
+
const status = pull(opts.model);
|
|
337
|
+
if (status !== 0) {
|
|
338
|
+
return {
|
|
339
|
+
ok: false,
|
|
340
|
+
manager,
|
|
341
|
+
badge,
|
|
342
|
+
installed,
|
|
343
|
+
pulled,
|
|
344
|
+
messages,
|
|
345
|
+
error: `ollama pull ${opts.model} failed (exit ${status})`
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
pulled.push(opts.model);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return { ok: true, manager, badge, installed, pulled, messages };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export { buildModelInstallPlan, ensureManagerRuntime, formatManagerBadgeLine, managerBadge, managerFromProviderId };
|
|
355
|
+
//# sourceMappingURL=chunk-UIOBFLE6.js.map
|
|
356
|
+
//# sourceMappingURL=chunk-UIOBFLE6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/model-install-plan.ts","../src/runtime/model-manager.ts"],"names":[],"mappings":"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","file":"chunk-UIOBFLE6.js","sourcesContent":["/**\n * Model install plan — pure dependency closure for a provider + pack/weights.\n *\n * Used by `vg models install` / `pull` (and hosts that mirror them). Planning is\n * side-effect free; execution lives in `model-install.ts`.\n *\n * schemaVersion: model-install-plan/0\n */\n\nimport { isPackageInstalled } from '../code/ensure.js';\nimport type { PackWeightsRef } from './model-orchestrator.js';\nimport { isWeightCached, lookupCatalog } from './weight-store.js';\n\nexport const MODEL_INSTALL_PLAN_SCHEMA_VERSION = 'model-install-plan/0' as const;\n\nexport type RuntimeDepKind = 'npm-runtime' | 'native-binary' | 'weights';\n\n/** Dep/weight readiness: `manual` = user must supply path/app (we do not auto-fetch). */\nexport type DepStatus = 'satisfied' | 'missing' | 'unmanaged' | 'manual';\n\nexport interface ProviderRuntimeDep {\n id: string;\n kind: RuntimeDepKind;\n /** npm install spec, e.g. `node-llama-cpp@^3`. */\n spec?: string;\n /** PATH binary name for native-binary deps. */\n binary?: string;\n /** One-line human reason. */\n reason: string;\n /** When true, npm install may need scripts (surfaced in plan only). */\n requiresInstallScripts?: boolean;\n}\n\nexport interface PlannedDep extends ProviderRuntimeDep {\n status: DepStatus;\n}\n\nexport interface ModelInstallPlan {\n schemaVersion: typeof MODEL_INSTALL_PLAN_SCHEMA_VERSION;\n provider: string;\n backend: string;\n model: string;\n mode?: string;\n packId?: string;\n license?: string;\n promise?: string;\n fit?: string;\n runtimeDeps: PlannedDep[];\n weights: {\n channel: 'ollama' | 'local-path' | 'manual' | 'vibgrate';\n ref: string;\n status: DepStatus;\n /** First-party or pack download URL when channel is vibgrate. */\n downloadUrl?: string;\n };\n /** Ids already present (runtime + weights). */\n alreadySatisfied: string[];\n /** npm specs / binary ids we will install (never third-party apps). */\n willInstall: string[];\n /** Weight refs we will download via the backend channel. */\n willDownload: string[];\n /** Things the user must fix outside vg (e.g. install Ollama.app). */\n blocked: Array<{ id: string; reason: string }>;\n offlineBlocked: boolean;\n /** True when nothing remains to install/download and nothing is blocked. */\n ready: boolean;\n}\n\nexport interface BuildInstallPlanInput {\n backend: PackWeightsRef['backend'] | string;\n weightsRef: string;\n license?: string;\n mode?: string;\n packId?: string;\n promise?: string;\n fit?: string;\n /** Discovered local model names (Ollama / LM Studio / gguf). */\n installedNames?: string[];\n /** When true, network install/download is forbidden. */\n offline?: boolean;\n /** Injectable binary probe (defaults: which/where style via injected map). */\n hasBinary?: (name: string) => boolean;\n /** Injectable npm package probe. */\n isPackageInstalled?: (spec: string) => boolean;\n /** Optional local GGUF path (llama.cpp) — when set, weights are satisfied. */\n modelPath?: string;\n /** Pack/catalog HTTPS URL for first-party GGUF download. */\n downloadUrl?: string;\n /** Optional sha256 for first-party download. */\n sha256?: string;\n /** Injectable weight-cache probe (tests). */\n isWeightCached?: (ref: string) => boolean;\n}\n\n/** Runtime deps declared per backend (not third-party app installers). */\nexport function runtimeDepsForBackend(backend: string): ProviderRuntimeDep[] {\n const b = backend.toLowerCase();\n if (b === 'llama.cpp' || b === 'llama-cpp' || b === 'vibgrate') {\n return [\n {\n id: 'node-llama-cpp',\n kind: 'npm-runtime',\n spec: 'node-llama-cpp@^3',\n reason: 'in-process llama.cpp binding for the first-party / llama-cpp provider',\n },\n ];\n }\n if (b === 'ollama') {\n return [\n {\n id: 'ollama',\n kind: 'native-binary',\n binary: 'ollama',\n reason: 'Ollama on PATH (install from https://ollama.com — third-party apps are not auto-installed)',\n },\n ];\n }\n // LM Studio / Foundry / other: weights managed externally; no auto deps.\n return [];\n}\n\nexport function weightsChannelForBackend(\n backend: string,\n opts?: { downloadUrl?: string; weightsRef?: string },\n): ModelInstallPlan['weights']['channel'] {\n const b = backend.toLowerCase();\n if (b === 'ollama') return 'ollama';\n if (b === 'llama.cpp' || b === 'llama-cpp' || b === 'vibgrate') {\n // Prefer first-party store when we have a catalog/pack URL for this ref.\n if (opts?.downloadUrl || (opts?.weightsRef && lookupCatalog(opts.weightsRef))) return 'vibgrate';\n return 'local-path';\n }\n if (b === 'lm-studio' || b === 'lmstudio' || b === 'foundry-local') return 'manual';\n return 'manual';\n}\n\nfunction weightsInstalled(ref: string, installedNames: string[]): boolean {\n const want = ref.toLowerCase();\n return installedNames.some((n) => {\n const have = n.toLowerCase();\n return have === want || have.includes(want) || want.includes(have);\n });\n}\n\n/**\n * Build a side-effect-free install plan for a backend + weight ref.\n */\nexport function buildModelInstallPlan(input: BuildInstallPlanInput): ModelInstallPlan {\n const hasBinary = input.hasBinary ?? (() => false);\n const pkgInstalled = input.isPackageInstalled ?? isPackageInstalled;\n const installedNames = input.installedNames ?? [];\n const offline = !!input.offline;\n const backend = input.backend;\n const provider = providerLabel(backend);\n\n const runtimeDeps: PlannedDep[] = runtimeDepsForBackend(backend).map((dep) => {\n if (dep.kind === 'npm-runtime' && dep.spec) {\n return { ...dep, status: pkgInstalled(dep.spec) ? 'satisfied' : 'missing' };\n }\n if (dep.kind === 'native-binary' && dep.binary) {\n // Present → satisfied; absent → unmanaged (we never install third-party apps).\n return { ...dep, status: hasBinary(dep.binary) ? 'satisfied' : 'unmanaged' };\n }\n return { ...dep, status: 'unmanaged' as const };\n });\n\n const channel = weightsChannelForBackend(backend, {\n downloadUrl: input.downloadUrl,\n weightsRef: input.weightsRef,\n });\n const weightCached = (input.isWeightCached ?? isWeightCached)(input.weightsRef);\n const catalog = lookupCatalog(input.weightsRef);\n const downloadUrl = input.downloadUrl ?? catalog?.url;\n\n let weightsStatus: DepStatus = 'missing';\n if (channel === 'ollama') {\n weightsStatus = weightsInstalled(input.weightsRef, installedNames) ? 'satisfied' : 'missing';\n } else if (channel === 'vibgrate') {\n weightsStatus =\n weightCached || weightsInstalled(input.weightsRef, installedNames) || !!input.modelPath ? 'satisfied' : 'missing';\n } else if (channel === 'local-path') {\n // Satisfied only when caller reports the model (path) already discoverable.\n weightsStatus = weightsInstalled(input.weightsRef, installedNames) || !!input.modelPath || weightCached ? 'satisfied' : 'manual';\n } else {\n weightsStatus = weightsInstalled(input.weightsRef, installedNames) ? 'satisfied' : 'manual';\n }\n\n const alreadySatisfied: string[] = [];\n const willInstall: string[] = [];\n const willDownload: string[] = [];\n const blocked: Array<{ id: string; reason: string }> = [];\n\n for (const dep of runtimeDeps) {\n if (dep.status === 'satisfied') {\n alreadySatisfied.push(dep.id);\n continue;\n }\n if (dep.kind === 'npm-runtime' && dep.spec && dep.status === 'missing') {\n if (offline) {\n blocked.push({ id: dep.id, reason: `${dep.spec} needed but --local/offline forbids install` });\n } else {\n willInstall.push(dep.spec);\n }\n continue;\n }\n if (dep.kind === 'native-binary' && dep.status === 'unmanaged') {\n blocked.push({\n id: dep.id,\n reason: dep.reason,\n });\n }\n }\n\n if (weightsStatus === 'satisfied') {\n alreadySatisfied.push(`weights:${input.weightsRef}`);\n } else if (weightsStatus === 'missing' && (channel === 'ollama' || channel === 'vibgrate')) {\n if (offline) {\n blocked.push({ id: `weights:${input.weightsRef}`, reason: 'weights missing and --local/offline forbids download' });\n } else if (channel === 'ollama' && runtimeDeps.some((d) => d.id === 'ollama' && d.status === 'unmanaged')) {\n willDownload.push(input.weightsRef);\n } else if (channel === 'vibgrate' && !downloadUrl) {\n blocked.push({\n id: `weights:${input.weightsRef}`,\n reason: `no first-party download URL for ${input.weightsRef} — place a gguf in the weight store or pass --model-path`,\n });\n } else {\n willDownload.push(input.weightsRef);\n }\n } else if (weightsStatus === 'manual' || weightsStatus === 'missing') {\n blocked.push({\n id: `weights:${input.weightsRef}`,\n reason:\n channel === 'local-path'\n ? `point --model-path at a local gguf for ${input.weightsRef}, or run install when a first-party URL is catalogued`\n : `install or link weights for ${input.weightsRef} via the backend app`,\n });\n }\n\n // Under offline, do not claim we will download/install — those land in blocked.\n const effectiveWillInstall = offline ? [] : willInstall;\n const effectiveWillDownload = offline ? [] : willDownload;\n const offlineBlocked = offline && blocked.some((b) => /offline|forbids/i.test(b.reason));\n\n const allRuntimeOk = runtimeDeps.every((d) => d.status === 'satisfied');\n const fullyReady = allRuntimeOk && weightsStatus === 'satisfied' && blocked.length === 0;\n\n return {\n schemaVersion: MODEL_INSTALL_PLAN_SCHEMA_VERSION,\n provider,\n backend,\n model: input.weightsRef,\n mode: input.mode,\n packId: input.packId,\n license: input.license,\n promise: input.promise,\n fit: input.fit,\n runtimeDeps,\n weights: {\n channel,\n ref: input.weightsRef,\n status: weightsStatus,\n downloadUrl: channel === 'vibgrate' ? downloadUrl : undefined,\n },\n alreadySatisfied,\n willInstall: effectiveWillInstall,\n willDownload: effectiveWillDownload,\n blocked,\n offlineBlocked,\n ready: fullyReady,\n };\n}\n\nfunction providerLabel(backend: string): string {\n const b = backend.toLowerCase();\n if (b === 'llama.cpp' || b === 'llama-cpp') return 'llama-cpp';\n if (b === 'vibgrate') return 'vibgrate';\n if (b === 'lm-studio' || b === 'lmstudio') return 'lmstudio';\n if (b === 'foundry-local') return 'foundry-local';\n return b === 'ollama' ? 'ollama' : backend;\n}\n","/**\n * Model manager identity + runtime ensure.\n *\n * **Code Modes** always use the first-party **Vibgrate** manager (embedded\n * llama.cpp / vgd host-broker + weight store). Custom local/hosted backends\n * (Ollama, LM Studio, OpenRouter, …) are explicit user choices; when chosen we\n * silently install *our* installable runtime packages for that path (npm\n * bindings), never third-party desktop apps. The user sees a short badge for\n * which manager ran.\n */\n\nimport { spawnSync } from 'node:child_process';\nimport { ensurePackage, isPackageInstalled, type EnsureOptions } from '../code/ensure.js';\nimport { runtimeDepsForBackend } from './model-install-plan.js';\n\n/** Durable manager ids surfaced in badges and JSON. */\nexport type ModelManagerId =\n | 'vibgrate'\n | 'ollama'\n | 'lmstudio'\n | 'foundry-local'\n | 'openrouter'\n | 'litellm'\n | 'openai'\n | 'together'\n | 'mock'\n | 'other';\n\nexport interface ManagerBadge {\n id: ModelManagerId;\n /** Short product label, e.g. \"Vibgrate\". */\n label: string;\n /** Compact badge for CLI/UI, e.g. \"[Vibgrate]\". */\n badge: string;\n /** One-line after-run note. */\n note: string;\n}\n\nconst LABELS: Record<ModelManagerId, { label: string; note: string }> = {\n vibgrate: {\n label: 'Vibgrate',\n note: 'Code Mode · first-party model manager (embedded inference)',\n },\n ollama: {\n label: 'Ollama',\n note: 'Custom local · Ollama',\n },\n lmstudio: {\n label: 'LM Studio',\n note: 'Custom local · LM Studio',\n },\n 'foundry-local': {\n label: 'Foundry Local',\n note: 'Custom local · Foundry Local',\n },\n openrouter: {\n label: 'OpenRouter',\n note: 'Custom hosted · OpenRouter',\n },\n litellm: {\n label: 'LiteLLM',\n note: 'Custom hosted · LiteLLM',\n },\n openai: {\n label: 'OpenAI',\n note: 'Custom hosted · OpenAI',\n },\n together: {\n label: 'Together',\n note: 'Custom hosted · Together',\n },\n mock: {\n label: 'Mock',\n note: 'Scripted offline provider',\n },\n other: {\n label: 'Custom',\n note: 'Custom model backend',\n },\n};\n\n/** Map a provider id (`llama-cpp`, `ollama`, …) to a manager badge. */\nexport function managerFromProviderId(providerId: string | undefined | null): ModelManagerId {\n const id = (providerId ?? '').toLowerCase().trim();\n if (id === 'llama-cpp' || id === 'llama.cpp' || id === 'vibgrate' || id === 'vibgrate-store') return 'vibgrate';\n if (id === 'ollama') return 'ollama';\n if (id === 'lmstudio' || id === 'lm-studio') return 'lmstudio';\n if (id === 'foundry-local' || id === 'foundry') return 'foundry-local';\n if (id === 'openrouter') return 'openrouter';\n if (id === 'litellm') return 'litellm';\n if (id === 'openai') return 'openai';\n if (id === 'together') return 'together';\n if (id === 'mock' || id === 'scripted') return 'mock';\n return 'other';\n}\n\nexport function managerBadge(id: ModelManagerId): ManagerBadge {\n const meta = LABELS[id] ?? LABELS.other;\n return {\n id,\n label: meta.label,\n badge: `[${meta.label}]`,\n note: meta.note,\n };\n}\n\nexport function formatManagerBadgeLine(id: ModelManagerId, model?: string): string {\n const b = managerBadge(id);\n const modelPart = model ? ` · ${model}` : '';\n return `${b.badge} ${b.note}${modelPart}`;\n}\n\nexport interface EnsureManagerRuntimeOptions {\n /** Provider id that will run (llama-cpp, ollama, …). */\n providerId: string;\n /** Model id for weight pull when the backend supports it. */\n model?: string;\n /** `--local` / offline — no network install. */\n offline?: boolean;\n /**\n * Consent to install npm runtime packages (and ollama pull when binary is\n * present). True when the user chose a custom provider/model or passed --yes.\n */\n consent?: boolean;\n /** Injectable ensure (tests). */\n ensurePackage?: typeof ensurePackage;\n /** Injectable PATH binary probe. */\n hasBinary?: (name: string) => boolean;\n /** Injectable ollama pull. */\n ollamaPull?: (name: string) => number;\n onProgress?: (line: string) => void;\n}\n\nexport interface EnsureManagerRuntimeResult {\n ok: boolean;\n manager: ModelManagerId;\n badge: ManagerBadge;\n /** npm specs installed this call. */\n installed: string[];\n /** Weight refs pulled (e.g. ollama pull). */\n pulled: string[];\n /** Non-fatal notes (e.g. app already present). */\n messages: string[];\n error?: string;\n}\n\nfunction defaultHasBinary(name: string): boolean {\n const res = spawnSync(name, ['--version'], { stdio: 'ignore', encoding: 'utf8' });\n // Some CLIs use subcommands; try bare which-style.\n if (res.status === 0) return true;\n const which = spawnSync(process.platform === 'win32' ? 'where' : 'which', [name], {\n stdio: 'ignore',\n encoding: 'utf8',\n });\n return which.status === 0;\n}\n\n/**\n * Silently install *installable* runtime deps for the chosen manager.\n * Never installs third-party desktop apps (Ollama.app, LM Studio) — those\n * remain user-managed; we only install npm packages into the Vibgrate runtime\n * cache and pull weights when the backend binary is already on PATH.\n */\nexport async function ensureManagerRuntime(\n opts: EnsureManagerRuntimeOptions,\n): Promise<EnsureManagerRuntimeResult> {\n const manager = managerFromProviderId(opts.providerId);\n const badge = managerBadge(manager);\n const installed: string[] = [];\n const pulled: string[] = [];\n const messages: string[] = [];\n const ensure = opts.ensurePackage ?? ensurePackage;\n const hasBinary = opts.hasBinary ?? defaultHasBinary;\n\n // Hosted OpenAI-compatible backends: no local packages.\n if (\n manager === 'openrouter' ||\n manager === 'litellm' ||\n manager === 'openai' ||\n manager === 'together' ||\n manager === 'mock'\n ) {\n return { ok: true, manager, badge, installed, pulled, messages };\n }\n\n // LM Studio / Foundry: HTTP clients only — no auto app install (ADR-005).\n if (manager === 'lmstudio' || manager === 'foundry-local') {\n messages.push(\n manager === 'lmstudio'\n ? 'LM Studio must already be running with a model loaded (we never install the app)'\n : 'Foundry Local must already be running (we never install the app)',\n );\n return { ok: true, manager, badge, installed, pulled, messages };\n }\n\n const backend =\n manager === 'vibgrate' ? 'llama.cpp' : manager === 'ollama' ? 'ollama' : opts.providerId;\n const deps = runtimeDepsForBackend(backend);\n\n for (const dep of deps) {\n if (dep.kind === 'npm-runtime' && dep.spec) {\n if (isPackageInstalled(dep.spec)) {\n messages.push(`${dep.id} already installed`);\n continue;\n }\n if (opts.offline) {\n return {\n ok: false,\n manager,\n badge,\n installed,\n pulled,\n messages,\n error: `${dep.spec} needed but offline/--local forbids install`,\n };\n }\n if (!opts.consent) {\n return {\n ok: false,\n manager,\n badge,\n installed,\n pulled,\n messages,\n error: `${dep.spec} needed — pass --yes or run \\`vg models install\\` once`,\n };\n }\n opts.onProgress?.(`installing ${dep.spec}`);\n const ensureOpts: EnsureOptions = {\n consent: true,\n local: false,\n interactive: false,\n };\n const res = await ensure(dep.spec, ensureOpts);\n if (!res.module) {\n return {\n ok: false,\n manager,\n badge,\n installed,\n pulled,\n messages,\n error: `couldn't install ${dep.spec}`,\n };\n }\n installed.push(dep.spec);\n continue;\n }\n if (dep.kind === 'native-binary' && dep.binary) {\n if (!hasBinary(dep.binary)) {\n return {\n ok: false,\n manager,\n badge,\n installed,\n pulled,\n messages,\n error:\n dep.reason ||\n `${dep.binary} is not on PATH — install it once, then re-run (vg never auto-installs third-party apps)`,\n };\n }\n messages.push(`${dep.binary} on PATH`);\n }\n }\n\n // Optional: when user chose a custom Ollama model, pull weights if missing.\n if (manager === 'ollama' && opts.model && opts.consent && !opts.offline) {\n const list = spawnSync('ollama', ['list'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });\n const have =\n list.status === 0 &&\n (list.stdout ?? '')\n .split('\\n')\n .slice(1)\n .some((line) => {\n const name = line.trim().split(/\\s+/)[0]?.toLowerCase();\n return name === opts.model!.toLowerCase() || name?.startsWith(`${opts.model!.toLowerCase()}:`);\n });\n if (!have) {\n opts.onProgress?.(`pulling ${opts.model}`);\n const pull = opts.ollamaPull ?? ((name: string) => spawnSync('ollama', ['pull', name], { stdio: 'ignore' }).status ?? 1);\n const status = pull(opts.model);\n if (status !== 0) {\n return {\n ok: false,\n manager,\n badge,\n installed,\n pulled,\n messages,\n error: `ollama pull ${opts.model} failed (exit ${status})`,\n };\n }\n pulled.push(opts.model);\n }\n }\n\n return { ok: true, manager, badge, installed, pulled, messages };\n}\n"]}
|