// Public entry point for the optional generative ("ask your lectures") layer. // // `./engineImpl` is resolved by Metro to engineImpl.web.ts or // engineImpl.native.ts by platform extension; the base engineImpl.ts re-export // (web) is what TypeScript resolves for typechecking. Consumers call // getGenerationEngine() and stay platform-agnostic. // // IMPORTANT: relative imports only inside src/lib (vitest has no '@/*' alias). import type { CloudConfig, GenerationEngine } from './engine'; import { createCloudEngine } from './cloud'; import { webllm } from './engineImpl'; /** * An engine that does nothing useful — represents "no generation backend here". * isAvailable() is always false; generate()/loadModel() throw. Callers should * check isAvailable() and fall back to the search-only path (no fake answers). */ export const noneEngine: GenerationEngine = { kind: 'none', label: 'No model', async isAvailable(): Promise { return false; }, async loadModel(): Promise { throw new Error('No generation engine is available.'); }, isLoaded(): boolean { return false; }, async generate(): Promise { throw new Error('No generation engine is available.'); }, }; /** * Pick the generation engine. * * - If a cloud config WITH an apiKey is given, use the BYO-key cloud engine. * - Otherwise return the platform on-device (webllm) engine. On a device without * WebGPU (web) or on native, that engine's isAvailable() resolves false, which * is how the "none" state is represented in practice — callers MUST check * isAvailable() before loading/generating, and fall back to search-only. */ export function getGenerationEngine(cloud?: CloudConfig): GenerationEngine { if (cloud?.apiKey) return createCloudEngine(cloud); return webllm; } export { createCloudEngine, webllm }; export * from './engine';