This commit is contained in:
102
lib/presentation/settings/knowledge_base_controller.dart
Normal file
102
lib/presentation/settings/knowledge_base_controller.dart
Normal file
@@ -0,0 +1,102 @@
|
||||
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';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user