feat(EMBEDDINGS-0001): enable local embedder by default and overhaul settings page

- Wire local embedding provider as the default on startup when no profile is configured
- Refactor embedding settings into dedicated service, DTOs, mappers and models
- Rebuild settings page with profile management UI and live test feedback
- Expose index summary (indexed versions + embedding count) on repo endpoints
- Harden indexing pipeline and context search with additional test coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Giancarmine Salucci
2026-03-28 09:28:01 +01:00
parent d1381f7fc0
commit 781d224adc
30 changed files with 1419 additions and 313 deletions

View File

@@ -23,6 +23,42 @@ export class EmbeddingService {
private readonly profileId: string = 'local-default'
) {}
findSnippetIdsMissingEmbeddings(repositoryId: string, versionId: string | null): string[] {
if (versionId) {
const rows = this.db
.prepare<[string, string, string], { id: string }>(
`SELECT snippets.id
FROM snippets
LEFT JOIN snippet_embeddings
ON snippet_embeddings.snippet_id = snippets.id
AND snippet_embeddings.profile_id = ?
WHERE snippets.repository_id = ?
AND snippets.version_id = ?
AND snippet_embeddings.snippet_id IS NULL
ORDER BY snippets.id`
)
.all(this.profileId, repositoryId, versionId);
return rows.map((row) => row.id);
}
const rows = this.db
.prepare<[string, string], { id: string }>(
`SELECT snippets.id
FROM snippets
LEFT JOIN snippet_embeddings
ON snippet_embeddings.snippet_id = snippets.id
AND snippet_embeddings.profile_id = ?
WHERE snippets.repository_id = ?
AND snippets.version_id IS NULL
AND snippet_embeddings.snippet_id IS NULL
ORDER BY snippets.id`
)
.all(this.profileId, repositoryId);
return rows.map((row) => row.id);
}
/**
* Embed the given snippet IDs and store the results in snippet_embeddings.
*