diff --git a/src/modules/search/domain/IVectorDatabase.ts b/src/modules/search/domain/IVectorDatabase.ts index e0554aa1..821781e3 100644 --- a/src/modules/search/domain/IVectorDatabase.ts +++ b/src/modules/search/domain/IVectorDatabase.ts @@ -4,12 +4,6 @@ import { UrlMetadataProps } from '../../cards/domain/value-objects/UrlMetadata'; export type IndexUrlParams = UrlMetadataProps; -export interface FindSimilarUrlsParams { - url: string; - limit: number; - threshold?: number; // Similarity threshold (0-1) - urlType?: UrlType; // Optional URL type to filter results -} export interface SemanticSearchUrlsParams { query: string; @@ -30,13 +24,6 @@ export interface IVectorDatabase { */ indexUrl(params: IndexUrlParams): Promise>; - /** - * Find URLs similar to the given URL - */ - findSimilarUrls( - params: FindSimilarUrlsParams, - ): Promise>; - /** * Find URLs similar to the given query string */ diff --git a/src/modules/search/domain/services/SearchService.ts b/src/modules/search/domain/services/SearchService.ts index b620531e..cf7863db 100644 --- a/src/modules/search/domain/services/SearchService.ts +++ b/src/modules/search/domain/services/SearchService.ts @@ -2,7 +2,7 @@ import { Result, ok, err } from '../../../../shared/core/Result'; import { URL } from '../../../cards/domain/value-objects/URL'; import { IMetadataService } from '../../../cards/domain/services/IMetadataService'; import { ICardQueryRepository } from '../../../cards/domain/ICardQueryRepository'; -import { IVectorDatabase, FindSimilarUrlsParams, UrlSearchResult } from '../IVectorDatabase'; +import { IVectorDatabase, UrlSearchResult } from '../IVectorDatabase'; import { UrlView } from '@semble/types/api/responses'; import { CardSortField, SortOrder } from '@semble/types/api/common'; import { @@ -78,16 +78,30 @@ export class SearchService { }, ): Promise> { try { - // 1. Find similar URLs from vector database - const findParams: FindSimilarUrlsParams = { - url: url.value, + // 1. Get metadata for the URL to extract title + description + const metadataResult = await this.metadataService.fetchMetadata(url); + if (metadataResult.isErr()) { + return err( + new Error( + `Failed to fetch metadata for similarity search: ${metadataResult.error.message}`, + ), + ); + } + + // 2. Create chunk from metadata to get searchable content + const chunk = Chunk.create(metadataResult.value); + const searchQuery = chunk.value || url.value; // Fallback to URL if no content + + // 3. Find similar URLs using the content as query + const searchParams: SemanticSearchUrlsParams = { + query: searchQuery, limit: options.limit * 2, // Get more results to account for filtering threshold: options.threshold, urlType: options.urlType, }; const similarResult = - await this.vectorDatabase.findSimilarUrls(findParams); + await this.vectorDatabase.semanticSearchUrls(searchParams); if (similarResult.isErr()) { return err( new Error(`Vector search failed: ${similarResult.error.message}`), diff --git a/src/modules/search/infrastructure/InMemoryVectorDatabase.ts b/src/modules/search/infrastructure/InMemoryVectorDatabase.ts index 592b01be..9e665d3c 100644 --- a/src/modules/search/infrastructure/InMemoryVectorDatabase.ts +++ b/src/modules/search/infrastructure/InMemoryVectorDatabase.ts @@ -2,7 +2,6 @@ import { Result, ok, err } from '../../../shared/core/Result'; import { IVectorDatabase, IndexUrlParams, - FindSimilarUrlsParams, SemanticSearchUrlsParams, UrlSearchResult, } from '../domain/IVectorDatabase'; @@ -68,28 +67,6 @@ export class InMemoryVectorDatabase implements IVectorDatabase { } } - async findSimilarUrls( - params: FindSimilarUrlsParams, - ): Promise> { - try { - // Get the query URL's content for comparison - const queryUrl = this.urls.get(params.url); - const queryContent = queryUrl?.content || params.url; - - return this.semanticSearchUrls({ - query: queryContent, - limit: params.limit, - threshold: params.threshold, - urlType: params.urlType, - }); - } catch (error) { - return err( - new Error( - `Failed to find similar URLs: ${error instanceof Error ? error.message : 'Unknown error'}`, - ), - ); - } - } async semanticSearchUrls( params: SemanticSearchUrlsParams, diff --git a/src/modules/search/infrastructure/UpstashVectorDatabase.ts b/src/modules/search/infrastructure/UpstashVectorDatabase.ts index c51e084f..e67e7672 100644 --- a/src/modules/search/infrastructure/UpstashVectorDatabase.ts +++ b/src/modules/search/infrastructure/UpstashVectorDatabase.ts @@ -3,7 +3,6 @@ import { Result, ok, err } from '../../../shared/core/Result'; import { IVectorDatabase, IndexUrlParams, - FindSimilarUrlsParams, SemanticSearchUrlsParams, UrlSearchResult, } from '../domain/IVectorDatabase'; @@ -62,28 +61,6 @@ export class UpstashVectorDatabase implements IVectorDatabase { } } - async findSimilarUrls( - params: FindSimilarUrlsParams, - ): Promise> { - try { - // Use the URL itself as the query data for now - // In a more sophisticated implementation, we could fetch the indexed data - const queryData = params.url; - - return this.semanticSearchUrls({ - query: queryData, - limit: params.limit, - threshold: params.threshold, - urlType: params.urlType, - }); - } catch (error) { - return err( - new Error( - `Failed to find similar URLs: ${error instanceof Error ? error.message : 'Unknown error'}`, - ), - ); - } - } async semanticSearchUrls( params: SemanticSearchUrlsParams,