7611ada001
Strictly opt-in, gated, with the deterministic features as the always-present floor: - GenerationEngine: WebLLM (Qwen2.5-1.5B, WebGPU, CDN-loaded) + BYO-key cloud (OpenAI-compatible); native stub. Pure grounding prompt builder (4 tests). - rag.askLectures: retrieve Phase-1 hits -> grounded prompt -> answer with citations; refuses when nothing relevant; falls back to search-only when no engine is available. Never sends raw audio/transcripts — only question + snippets. - aiStore (BYO key persisted in localStorage on web), Ask screen (answer + tappable citation chips that jump to the audio + honest "verify" disclaimer), Settings AI section (engine status + bring-your-own-key form). 279 tests green, 0 tsc errors, web export builds. ROADMAP phases 0-5 complete. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
// 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<boolean> {
|
|
return false;
|
|
},
|
|
async loadModel(): Promise<void> {
|
|
throw new Error('No generation engine is available.');
|
|
},
|
|
isLoaded(): boolean {
|
|
return false;
|
|
},
|
|
async generate(): Promise<string> {
|
|
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';
|