103 lines
3.0 KiB
Dart
103 lines
3.0 KiB
Dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:trainhub_flutter/domain/repositories/note_repository.dart';
|
|
import 'package:trainhub_flutter/injection.dart';
|
|
import 'package:trainhub_flutter/presentation/settings/knowledge_base_state.dart';
|
|
|
|
part 'knowledge_base_controller.g.dart';
|
|
|
|
@riverpod
|
|
class KnowledgeBaseController extends _$KnowledgeBaseController {
|
|
late NoteRepository _repo;
|
|
|
|
@override
|
|
KnowledgeBaseState build() {
|
|
_repo = getIt<NoteRepository>();
|
|
// Load the current chunk count asynchronously after first build.
|
|
_loadCount();
|
|
return const KnowledgeBaseState();
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Load chunk count
|
|
// -------------------------------------------------------------------------
|
|
|
|
Future<void> _loadCount() async {
|
|
try {
|
|
final count = await _repo.getChunkCount();
|
|
state = state.copyWith(chunkCount: count);
|
|
} catch (_) {
|
|
// Non-fatal — UI stays at 0.
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Save note
|
|
// -------------------------------------------------------------------------
|
|
|
|
/// Chunks [text], generates embeddings via Nomic, and stores the result.
|
|
Future<void> saveNote(String text) async {
|
|
if (text.trim().isEmpty) return;
|
|
|
|
state = state.copyWith(
|
|
isLoading: true,
|
|
successMessage: null,
|
|
errorMessage: null,
|
|
);
|
|
|
|
try {
|
|
await _repo.addNote(text.trim());
|
|
final count = await _repo.getChunkCount();
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
chunkCount: count,
|
|
successMessage: 'Saved! Knowledge base now has $count chunks.',
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
errorMessage: _friendlyError(e),
|
|
);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Clear knowledge base
|
|
// -------------------------------------------------------------------------
|
|
|
|
Future<void> clearKnowledgeBase() async {
|
|
state = state.copyWith(
|
|
isLoading: true,
|
|
successMessage: null,
|
|
errorMessage: null,
|
|
);
|
|
try {
|
|
await _repo.clearAll();
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
chunkCount: 0,
|
|
successMessage: 'Knowledge base cleared.',
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
isLoading: false,
|
|
errorMessage: _friendlyError(e),
|
|
);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Helper
|
|
// -------------------------------------------------------------------------
|
|
|
|
String _friendlyError(Object e) {
|
|
final msg = e.toString();
|
|
if (msg.contains('Connection refused') ||
|
|
msg.contains('SocketException')) {
|
|
return 'Cannot reach the embedding server. '
|
|
'Make sure AI models are downloaded and the app has had time to '
|
|
'start the inference servers.';
|
|
}
|
|
return 'Error: $msg';
|
|
}
|
|
}
|