import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../llm/llm_service.dart'; import '../llm/mediapipe_llm_service.dart'; // ── Service singleton ───────────────────────────────────────────────────────── final llmServiceProvider = Provider((ref) { final service = MediapipeLlmService(); ref.onDispose(service.dispose); return service; }); // ── Model initialisation state ──────────────────────────────────────────────── final llmReadyProvider = FutureProvider((ref) async { await ref.watch(llmServiceProvider).initialise(); }); // ── Streaming response notifier ─────────────────────────────────────────────── class LlmResponseNotifier extends Notifier> { bool _cancelled = false; @override AsyncValue build() => const AsyncData(''); Future generate(String prompt) async { _cancelled = false; state = const AsyncLoading(); final service = ref.read(llmServiceProvider); final buffer = StringBuffer(); try { await for (final token in service.generateStream(prompt)) { if (_cancelled || !ref.mounted) break; buffer.write(token); state = AsyncData(buffer.toString()); } } catch (e, st) { if (!ref.mounted) return; state = AsyncError(e, st); } } void cancel() { _cancelled = true; state = const AsyncData(''); } void clear() => state = const AsyncData(''); } final llmResponseNotifierProvider = NotifierProvider.autoDispose>( LlmResponseNotifier.new);