Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions src/core/pinecone/rerank.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ const sampleMerged: MergedHit[] = [
{ _id: '1', _score: 0.5, chunk_text: 'hello', metadata: { k: 'v' } },
];

function makePc(rerank: ReturnType<typeof vi.fn>) {
return { inference: { rerank } } as Parameters<typeof rerankResults>[0];
}

describe('rerankResults', () => {
it('returns empty outcome when there are no merged hits', async () => {
const pc = {} as Parameters<typeof rerankResults>[0];
Expand All @@ -23,7 +27,7 @@ describe('rerankResults', () => {
},
],
});
const pc = { inference: { rerank } } as Parameters<typeof rerankResults>[0];
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

Expand All @@ -37,7 +41,7 @@ describe('rerankResults', () => {

it('returns unreranked slice with degraded when rerank throws', async () => {
const rerank = vi.fn().mockRejectedValue(new Error('rerank unavailable'));
const pc = { inference: { rerank } } as Parameters<typeof rerankResults>[0];
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

Expand All @@ -47,4 +51,64 @@ describe('rerankResults', () => {
expect(out.results[0]?.reranked).toBe(false);
expect(out.results[0]?.content).toBe('hello');
});

it('returns empty reranked results with degraded=false when data is an empty array', async () => {
const rerank = vi.fn().mockResolvedValue({ data: [] });
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

expect(out.results).toEqual([]);
expect(out.degraded).toBe(false);
expect(out.degradation_reason).toBeUndefined();
});

it('returns empty reranked results with degraded=false when data is absent', async () => {
const rerank = vi.fn().mockResolvedValue({});
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

expect(out.results).toEqual([]);
expect(out.degraded).toBe(false);
});

it('maps a rerank item with no document to an empty id/content result instead of throwing', async () => {
const rerank = vi.fn().mockResolvedValue({
data: [{ score: 0.42 }],
});
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

expect(out.degraded).toBe(false);
expect(out.results).toHaveLength(1);
expect(out.results[0]?.id).toBe('');
expect(out.results[0]?.content).toBe('');
expect(out.results[0]?.metadata).toEqual({});
expect(out.results[0]?.reranked).toBe(true);
expect(out.results[0]?.score).toBeCloseTo(0.42);
});

it('maps duplicate documents in the rerank output to one result per data item', async () => {
const document = { _id: '1', chunk_text: 'hello', metadata: { k: 'v' } };
const rerank = vi.fn().mockResolvedValue({
data: [
{ score: 0.9, document },
{ score: 0.8, document },
],
});
const pc = makePc(rerank);

const out = await rerankResults(pc, 'm', 'q', sampleMerged, 5);

expect(out.degraded).toBe(false);
expect(out.results).toHaveLength(2);
expect(out.results.map((r) => r.id)).toEqual(['1', '1']);
expect(out.results.map((r) => r.content)).toEqual(['hello', 'hello']);
expect(out.results[0]?.metadata).toEqual({ k: 'v' });
expect(out.results[0]?.score).toBeCloseTo(0.9);
expect(out.results[1]?.score).toBeCloseTo(0.8);
expect(out.results.every((r) => r.reranked === true)).toBe(true);
});
});