first implementation

This commit is contained in:
Fabian Freund
2025-09-30 16:26:54 +02:00
parent c370767019
commit 68d0d5584c
5 changed files with 567 additions and 1 deletions
@@ -134,6 +134,45 @@ class GeckoInferenceRepository extends _$GeckoInferenceRepository {
return neighbors;
}
Future<List<List<String>>?> suggestClusters({
required List<String> unassignedDocumentsInput,
}) async {
if (!ref.read(
generalSettingsWithDefaultsProvider.select(
(settings) => settings.enableLocalAiFeatures,
),
)) {
return null;
}
final processedDocuments = <String, String>{};
final unassignedDocumentsProcessed = unassignedDocumentsInput.map((doc) {
final processed = preprocessText(doc);
if (processed != doc) {
processedDocuments[processed] = doc;
}
return processed;
}).toList();
final embeddings = await generateDocumentEmbeddings(
unassignedDocumentsProcessed,
);
final clusters = embeddings.mapNotNull(
(embeddings) => clusterEmbeddings(embeddings: embeddings.values.toList())
.map(
(cluster) =>
cluster.map((i) => embeddings.keys.elementAt(i)).toList(),
)
.toList(),
);
print(clusters);
return null;
}
Future<Map<String, List<double>>?> generateDocumentEmbeddings(
List<String> documents,
) async {
@@ -196,6 +235,32 @@ Future<String?> containerTopic(Ref ref, String containerId) async {
return topic;
}
@Riverpod()
Future<List<List<String>>?> suggestClusters(Ref ref) async {
final unassignedTitles = await ref.watch(
containerTabsDataProvider(null).selectAsync(
(tabData) => EquatableValue(
tabData
.where((tab) => tab.title.isNotEmpty)
.map((tab) => (tab.id, tab.title!))
.toSet(),
),
),
);
if (unassignedTitles.value.isNotEmpty) {
await ref
.read(geckoInferenceRepositoryProvider.notifier)
.suggestClusters(
unassignedDocumentsInput: unassignedTitles.value
.map((tab) => tab.$2)
.toList(),
);
}
return null;
}
@Riverpod()
Future<List<String>?> containerTabSuggestions(
Ref ref,
@@ -42,7 +42,7 @@ final class GeckoInferenceRepositoryProvider
}
String _$geckoInferenceRepositoryHash() =>
r'6099998a3f49fc4faf650878ab4afd6268c593e2';
r'1f08047bee912a475bfd0851f8a9868a41bca836';
abstract class _$GeckoInferenceRepository extends $Notifier<void> {
void build();
@@ -132,6 +132,47 @@ final class ContainerTopicFamily extends $Family
String toString() => r'containerTopicProvider';
}
@ProviderFor(suggestClusters)
const suggestClustersProvider = SuggestClustersProvider._();
final class SuggestClustersProvider
extends
$FunctionalProvider<
AsyncValue<List<List<String>>?>,
List<List<String>>?,
FutureOr<List<List<String>>?>
>
with
$FutureModifier<List<List<String>>?>,
$FutureProvider<List<List<String>>?> {
const SuggestClustersProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'suggestClustersProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$suggestClustersHash();
@$internal
@override
$FutureProviderElement<List<List<String>>?> $createElement(
$ProviderPointer pointer,
) => $FutureProviderElement(pointer);
@override
FutureOr<List<List<String>>?> create(Ref ref) {
return suggestClusters(ref);
}
}
String _$suggestClustersHash() => r'9d212158b80ba53afe305db938ab399b1e931d88';
@ProviderFor(containerTabSuggestions)
const containerTabSuggestionsProvider = ContainerTabSuggestionsFamily._();