Przebudowanie aplikacji, usprawnione AI, dodanie combo buildera
Some checks failed
Build Linux App / build (push) Failing after 1m18s

This commit is contained in:
Kazimierz Ciołek
2026-07-06 23:44:17 +02:00
parent 9dcc4b87de
commit 6dd7213eb0
48 changed files with 3229 additions and 669 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:math' show sqrt;
import 'package:drift/drift.dart';
import 'package:trainhub_flutter/core/constants/ai_constants.dart';
import 'package:trainhub_flutter/data/database/app_database.dart';
import 'package:trainhub_flutter/data/database/daos/knowledge_chunk_dao.dart';
import 'package:trainhub_flutter/domain/repositories/note_repository.dart';
@@ -29,7 +30,11 @@ class NoteRepositoryImpl implements NoteRepository {
final now = DateTime.now().toIso8601String();
for (final chunk in chunks) {
final embedding = await _embeddingService.embed(chunk);
// Nomic v1.5 is trained with task prefixes — embedding without them
// noticeably degrades retrieval quality.
final embedding = await _embeddingService.embed(
'${AiConstants.nomicDocumentPrefix}$chunk',
);
await _dao.insertChunk(
KnowledgeChunksCompanion(
id: Value(_uuid.v4()),
@@ -47,19 +52,19 @@ class NoteRepositoryImpl implements NoteRepository {
final allRows = await _dao.getAllChunks();
if (allRows.isEmpty) return [];
final queryEmbedding = await _embeddingService.embed(query);
final queryEmbedding = await _embeddingService.embed(
'${AiConstants.nomicQueryPrefix}$query',
);
final scored = allRows.map((row) {
final emb =
(jsonDecode(row.embedding) as List<dynamic>)
.map((e) => (e as num).toDouble())
.toList();
final emb = (jsonDecode(row.embedding) as List<dynamic>)
.map((e) => (e as num).toDouble())
.toList();
return _Scored(
score: _cosineSimilarity(queryEmbedding, emb),
text: row.content,
);
}).toList()
..sort((a, b) => b.score.compareTo(a.score));
}).toList()..sort((a, b) => b.score.compareTo(a.score));
return scored.take(topK).map((s) => s.text).toList();
}
@@ -92,13 +97,11 @@ class NoteRepositoryImpl implements NoteRepository {
}
// Split long paragraph by sentence boundaries (. ! ?)
final sentences =
p.split(RegExp(r'(?<=[.!?])\s+'));
final sentences = p.split(RegExp(r'(?<=[.!?])\s+'));
var current = '';
for (final sentence in sentences) {
final candidate =
current.isEmpty ? sentence : '$current $sentence';
final candidate = current.isEmpty ? sentence : '$current $sentence';
if (candidate.length <= maxChars) {
current = candidate;
} else {