fix(FEEDBACK-0001): complete iteration 0 - harden context search

This commit is contained in:
Giancarmine Salucci
2026-03-27 01:25:46 +01:00
parent e7a2a83cdb
commit 16436bfab2
15 changed files with 1469 additions and 44 deletions

View File

@@ -1,14 +1,35 @@
import {
CodeListItemDto,
CodeSnippetJsonDto,
ContextRepositoryJsonDto,
ContextJsonResponseDto,
ContextVersionJsonDto,
InfoSnippetJsonDto,
LibrarySearchJsonResponseDto,
LibrarySearchJsonResultDto,
SnippetOriginJsonDto,
type SnippetJsonDto
} from '$lib/server/models/context-response.js';
import { LibrarySearchResult, SnippetSearchResult } from '$lib/server/models/search-result.js';
export interface ContextResponseMetadata {
localSource: boolean;
resultCount: number;
repository: {
id: string;
title: string;
source: 'github' | 'local';
sourceUrl: string;
branch: string | null;
} | null;
version: {
requested: string | null;
resolved: string | null;
id: string | null;
} | null;
snippetVersions: Record<string, string>;
}
export class ContextResponseMapper {
static toLibrarySearchJson(results: LibrarySearchResult[]): LibrarySearchJsonResponseDto {
return new LibrarySearchJsonResponseDto(
@@ -35,8 +56,24 @@ export class ContextResponseMapper {
);
}
static toContextJson(snippets: SnippetSearchResult[], rules: string[]): ContextJsonResponseDto {
static toContextJson(
snippets: SnippetSearchResult[],
rules: string[],
metadata?: ContextResponseMetadata
): ContextJsonResponseDto {
const mapped: SnippetJsonDto[] = snippets.map(({ snippet }) => {
const origin = metadata?.repository
? new SnippetOriginJsonDto({
repositoryId: snippet.repositoryId,
repositoryTitle: metadata.repository.title,
source: metadata.repository.source,
sourceUrl: metadata.repository.sourceUrl,
version: snippet.versionId ? metadata.snippetVersions[snippet.versionId] ?? null : null,
versionId: snippet.versionId,
isLocal: metadata.localSource
})
: null;
if (snippet.type === 'code') {
return new CodeSnippetJsonDto({
title: snippet.title ?? null,
@@ -50,7 +87,8 @@ export class ContextResponseMapper {
],
id: snippet.id,
tokenCount: snippet.tokenCount ?? null,
pageTitle: snippet.breadcrumb ? snippet.breadcrumb.split('>')[0].trim() || null : null
pageTitle: snippet.breadcrumb ? snippet.breadcrumb.split('>')[0].trim() || null : null,
origin
});
}
@@ -58,14 +96,34 @@ export class ContextResponseMapper {
text: snippet.content,
breadcrumb: snippet.breadcrumb ?? null,
pageId: snippet.id,
tokenCount: snippet.tokenCount ?? null
tokenCount: snippet.tokenCount ?? null,
origin
});
});
return new ContextJsonResponseDto({
snippets: mapped,
rules,
totalTokens: snippets.reduce((sum, result) => sum + (result.snippet.tokenCount ?? 0), 0)
totalTokens: snippets.reduce((sum, result) => sum + (result.snippet.tokenCount ?? 0), 0),
localSource: metadata?.localSource ?? false,
repository: metadata?.repository
? new ContextRepositoryJsonDto({
id: metadata.repository.id,
title: metadata.repository.title,
source: metadata.repository.source,
sourceUrl: metadata.repository.sourceUrl,
branch: metadata.repository.branch,
isLocal: metadata.localSource
})
: null,
version: metadata?.version
? new ContextVersionJsonDto({
requested: metadata.version.requested,
resolved: metadata.version.resolved,
id: metadata.version.id
})
: null,
resultCount: metadata?.resultCount ?? snippets.length
});
}
}