import type { Readable } from "node:stream"; import { type LocalInferenceProfileMode } from "./local-inference-profile.ts"; import { type ManagedRuntimeSpawn } from "./runtime-process.ts"; /** * Managed runtime for Pi's curated Prism 1-bit and ternary GGUF models. Q1_0 is available in * upstream llama.cpp, while the selected group-128 Q2_0 artifacts and paired DSpark acceleration * still require Prism's validated build. This module therefore owns the pinned runtime install, * GGUF downloads, and llama-server lifecycle. Mirrors local-runtime.ts's OllamaRuntime: injectable * seams for fetch/spawn/exists, pi-owned directories under agentDir (runtimes/, models/), * detached+tracked child processes, onProgress as best-effort UI feedback, honest error taxonomies * instead of silent fallbacks. * * The fork publishes precompiled per-platform archives on GitHub Releases (no local build): pin a * release tag, download the matching asset, extract it, and locate the `llama-server` binary once * at install time (release archive layouts vary — bin/ vs build/bin/ at the top level — so this is * a deterministic one-time scan, not a fallback). The found relative path and backend (cpu/cuda) * are persisted to a manifest so later `detect()`/`serve()` calls never need to re-scan. */ /** * Pinned Prism ML llama.cpp fork release — verified via * `GET https://api.github.com/repos/PrismML-Eng/llama.cpp/releases/tags/prism-b9594-38c66ad` on * 2026-07-18 (release exists, all assets referenced below are present on it). Bump here (and * re-verify with the same API call) when the provider ships new kernels. */ export declare const PRISM_LLAMACPP_PINNED_RELEASE = "prism-b9594-38c66ad"; export declare const PRISM_LLAMACPP_RELEASES_BASE_URL = "https://github.com/PrismML-Eng/llama.cpp/releases/download"; export interface PrismModelDescriptor { repo: string; file: string; mmprojFile?: string; displayName: string; architecture: "dense"; runtime: "prism-llamacpp"; family: "bonsai" | "ternary-bonsai"; parameterScale: "1.7B" | "4B" | "8B" | "27B"; weightFormat: "q1_0" | "q2_0"; matchedDrafter?: { kind: "dspark"; file: string; draftMax: 4; minimumContext: 16_384; validatedBackend: "cuda"; }; } /** Curated 27B descriptor shared by the full local execution catalog. */ export declare const BONSAI_27B: PrismModelDescriptor; export type PrismBackend = "cpu" | "cuda"; export type PrismAssetKind = "tar-gz" | "zip"; export interface PrismArchiveAsset { name: string; kind: PrismAssetKind; } export interface PrismLlamaAsset extends PrismArchiveAsset { backend: PrismBackend; companionAssets?: readonly PrismArchiveAsset[]; } /** * Maps a platform/arch/GPU triple to the exact Prism llama.cpp release asset for * {@link PRISM_LLAMACPP_PINNED_RELEASE} — verified against the real GitHub release, not guessed. * CPU asset by default; CUDA 12.4 is selected for x64 Linux or Windows with an NVIDIA GPU. The * pinned Windows build is incomplete without its matching `cudart-*` archive, so the resolver * returns both as one mandatory installation plan. Pure and exported so it's independently * testable. */ export declare function resolvePrismLlamaAsset(plat: string, architecture: string, hasNvidiaGpu: boolean): PrismLlamaAsset | undefined; export interface PrismDetectResult { runtimeInstalled: boolean; binaryPath?: string; release?: string; } export interface PrismDownloadResult { ok: boolean; path?: string; skipped?: boolean; error?: string; } export type PrismServeResult = { ok: true; baseUrl: string; } | { ok: false; error: string; }; export interface PrismProcessLifecycle { track(pid: number): void; untrack(pid: number): void; terminate(pid: number): void; } type PrismExtractArchiveFn = (input: Readable, destDir: string, kind: PrismAssetKind) => Promise<{ ok: boolean; error?: string; }>; export interface PrismLlamaCppDeps { fetchFn?: typeof fetch; spawnFn?: ManagedRuntimeSpawn; existsFn?: (path: string) => boolean; sleepFn?: (ms: number) => Promise; /** Whether a named command exists on PATH (nvidia-smi, tar — for zip extraction on Windows). */ hasCommand?: (command: string) => boolean; /** Decided once at install time and persisted as `backend` — serve() reads the persisted value * so `-ngl 99` reflects what was actually installed, not the host's current GPU state. */ hasNvidiaGpu?: () => boolean; platform?: () => string; arch?: () => string; /** Host capacity probes used once to derive the bounded local inference profile. */ totalMemoryBytes?: () => number; logicalCpuCount?: () => number; /** Runs the extraction step for a downloaded archive. Injectable so installManaged's * download->extract->scan orchestration is testable without a real tar/unzip pipeline; defaults * to the real spawn-based extractor. */ extractArchive?: PrismExtractArchiveFn; /** Health-poll bounds for serve(); default ~120s (240 * 500ms), both overridable for tests. */ healthPollAttempts?: number; healthPollIntervalMs?: number; processLifecycle?: PrismProcessLifecycle; } export declare class PrismLlamaCppRuntime { private readonly _agentDir; private readonly _fetch; private readonly _spawn; private readonly _exists; private readonly _sleep; private readonly _hasCommand; private readonly _hasNvidiaGpu; private readonly _platform; private readonly _arch; private readonly _extractArchiveFn; private readonly _healthPollAttempts; private readonly _healthPollIntervalMs; private readonly _profile; private readonly _processLifecycle; private _child; constructor(args: { agentDir: string; profileMode?: LocalInferenceProfileMode; deps?: PrismLlamaCppDeps; }); runtimeDir(): string; modelsDir(): string; private _binaryName; private _manifestPath; private _readManifest; private _writeManifest; detect(): Promise; /** One-time recursive scan for the `llama-server` binary inside a freshly extracted release * archive — layouts vary (bin/ vs build/bin/ at the top level) across platforms/backends, so * this locates it deterministically instead of assuming a fixed path, then the result is * persisted so later calls never need to re-scan. */ private _findBinaryRelPath; /** * Download the pinned release asset for this host and extract it (consent-gated by the caller, * same contract as OllamaRuntime#installManaged — this method only does the mechanical * download+extract+locate and reports the outcome honestly). No compiler toolchain required: * the fork ships prebuilt binaries. */ installManaged(onProgress?: (status: string) => void): Promise<{ ok: boolean; error?: string; }>; private _installArchive; private _extractArchive; private _extractTarGz; private _extractZip; private _remoteContentLength; /** * Stream a GGUF (or mmproj) file from Hugging Face into pi's owned models dir. Skips a re-download * when the local file already matches the remote size; verifies size when the response reports * `content-length` and deletes the partial file on any failure or mismatch — never leaves a * corrupt/truncated weight file behind for a later load to silently misread. */ downloadModel(args: { repo: string; file: string; }, onProgress?: (status: string) => void): Promise; /** * Spawn `llama-server` detached+tracked (killed on parent shutdown even if pi crashes without * calling stop()) and poll `/health` until ready. `-ngl 99` is only added when the installed * asset's persisted `backend` is `"cuda"`, not from the host's current GPU state. */ serve(args: { modelPath: string; modelAlias: string; mmprojPath?: string; port: number; numCtx: number; }): Promise; stop(): { stopped: boolean; }; isRunning(): boolean; } export {}; //# sourceMappingURL=llamacpp-runtime.d.ts.map