diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 56fb88d..d66593b 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -9,13 +9,13 @@ import { initializeDatabase } from '$lib/server/db/index.js'; import { getClient } from '$lib/server/db/client.js'; import { initializePipeline } from '$lib/server/pipeline/startup.js'; -import { - EMBEDDING_CONFIG_KEY, - createProviderFromConfig, - defaultEmbeddingConfig -} from '$lib/server/embeddings/factory.js'; +import { createProviderFromProfile } from '$lib/server/embeddings/registry.js'; import { EmbeddingService } from '$lib/server/embeddings/embedding.service.js'; -import type { EmbeddingConfig } from '$lib/server/embeddings/factory.js'; +import { + EmbeddingProfileEntity, + type EmbeddingProfileEntityProps +} from '$lib/server/models/embedding-profile.js'; +import { EmbeddingProfileMapper } from '$lib/server/mappers/embedding-profile.mapper.js'; import type { Handle } from '@sveltejs/kit'; // --------------------------------------------------------------------------- @@ -26,37 +26,20 @@ try { initializeDatabase(); const db = getClient(); - - // Load persisted embedding configuration (if any). - const configRow = db - .prepare<[string], { value: string }>(`SELECT value FROM settings WHERE key = ?`) - .get(EMBEDDING_CONFIG_KEY); + const activeProfileRow = db + .prepare<[], EmbeddingProfileEntityProps>( + 'SELECT * FROM embedding_profiles WHERE is_default = 1 AND enabled = 1 LIMIT 1' + ) + .get(); let embeddingService: EmbeddingService | null = null; - if (configRow) { - try { - const config: EmbeddingConfig = - typeof configRow.value === 'string' - ? JSON.parse(configRow.value) - : (configRow.value as EmbeddingConfig); - - if (config.provider !== 'none') { - const provider = createProviderFromConfig(config); - embeddingService = new EmbeddingService(db, provider); - } - } catch (err) { - console.warn( - `[hooks.server] Could not load embedding config: ${err instanceof Error ? err.message : String(err)}` - ); - } - } else { - // Use the default (noop) config so the pipeline is still wired up. - const config = defaultEmbeddingConfig(); - if (config.provider !== 'none') { - const provider = createProviderFromConfig(config); - embeddingService = new EmbeddingService(db, provider); - } + if (activeProfileRow) { + const activeProfile = EmbeddingProfileMapper.fromEntity( + new EmbeddingProfileEntity(activeProfileRow) + ); + const provider = createProviderFromProfile(activeProfile); + embeddingService = new EmbeddingService(db, provider, activeProfile.id); } initializePipeline(db, embeddingService); diff --git a/src/lib/components/RepositoryCard.svelte b/src/lib/components/RepositoryCard.svelte index dcc959c..8cbdb84 100644 --- a/src/lib/components/RepositoryCard.svelte +++ b/src/lib/components/RepositoryCard.svelte @@ -1,13 +1,25 @@
Indexing failed. Check jobs for details.
{/if} diff --git a/src/lib/components/RepositoryCard.svelte.test.ts b/src/lib/components/RepositoryCard.svelte.test.ts index ee2be10..34a5511 100644 --- a/src/lib/components/RepositoryCard.svelte.test.ts +++ b/src/lib/components/RepositoryCard.svelte.test.ts @@ -12,6 +12,8 @@ describe('RepositoryCard.svelte', () => { description: 'A JavaScript library for building user interfaces', state: 'indexed', totalSnippets: 1234, + embeddingCount: 1200, + indexedVersions: ['main', 'v18.3.0'], trustScore: 9.7, stars: 230000, lastIndexedAt: null @@ -23,5 +25,8 @@ describe('RepositoryCard.svelte', () => { await expect .element(page.getByRole('link', { name: 'Details' })) .toHaveAttribute('href', '/repos/%2Ffacebook%2Freact'); + + await expect.element(page.getByText('1,200 embeddings')).toBeInTheDocument(); + await expect.element(page.getByText('Indexed: main, v18.3.0')).toBeInTheDocument(); }); }); \ No newline at end of file diff --git a/src/lib/dtos/embedding-settings.ts b/src/lib/dtos/embedding-settings.ts new file mode 100644 index 0000000..f35c85f --- /dev/null +++ b/src/lib/dtos/embedding-settings.ts @@ -0,0 +1,41 @@ +import type { EmbeddingProviderKind } from '$lib/types'; + +export interface EmbeddingProfileConfigEntryDto { + key: string; + value: string; + redacted: boolean; +} + +export interface EmbeddingProfileDto { + id: string; + providerKind: string; + title: string; + enabled: boolean; + isDefault: boolean; + model: string; + dimensions: number; + config: RecordConfigure TrueRef embedding and indexing options
+ This is the profile used for semantic indexing and retrieval right now. +
+ + {#if activeProfile} +{activeProfile.title}
+Profile ID: {activeProfile.id}
+Provider configuration
++ These are the provider-specific settings currently saved for the active profile. +
+ + {#if activeConfigEntries.length > 0} ++ No provider-specific configuration is stored for this profile. +
++ For OpenAI-compatible profiles, edit the + settings in the Embedding Provider form + below. The built-in Local Model profile + does not currently expose extra configurable fields. +
+ {/if} +Profiles stored in the database and available for activation.
+{profile.title}
+{profile.id}
+Embeddings enable semantic search. Without them, only keyword search (FTS5) is used.
- {#if loading} -Loading current configuration…
- {:else} -