File size: 2,654 Bytes
4f658bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eb89325
 
4f658bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// A document loaded into the demo
export interface Document {
  id: string; // filename-based
  title: string; // extracted from H1 or filename
  body: string; // full text content
  filepath: string; // e.g. "api-design-principles.md"
}

// A chunk of a document
export interface Chunk {
  docId: string;
  chunkIndex: number;
  text: string;
  startChar: number; // offset in original doc
  title: string; // parent doc title
}

// A chunk with its embedding vector
export interface EmbeddedChunk extends Chunk {
  embedding: Float32Array;
}

// Search result from BM25 or vector search
export interface ScoredChunk {
  chunk: Chunk;
  score: number;
  source: "bm25" | "vector";
}

// Result after RRF fusion
export interface RRFResult {
  docId: string;
  filepath: string;
  title: string;
  bestChunk: string;
  score: number;
  contributions: RRFContribution[];
}

export interface RRFContribution {
  source: "bm25" | "vector";
  queryType: "original" | "lex" | "vec" | "hyde";
  query: string;
  rank: number;
  weight: number;
  rrfContribution: number;
}

// Result after reranking
export interface RerankedResult extends RRFResult {
  rerankScore: number;
  blendedScore: number;
}

// Final result
export interface FinalResult {
  filepath: string;
  title: string;
  bestChunk: string;
  score: number; // blended score
  docId: string;
}

// Query expansion output
export interface ExpandedQuery {
  hyde: string; // hypothetical document snippet
  vec: string[]; // dense retrieval sentences
  lex: string; // BM25 keywords
  source?: "model" | "fallback" | "strong-signal";
  note?: string;
}

// Pipeline events for React UI
export type PipelineStage = "expansion" | "search" | "rrf" | "rerank" | "blend";
export type PipelineStatus = "idle" | "running" | "done" | "error";

export type PipelineEvent =
  | { stage: "expansion"; status: "running" }
  | { stage: "expansion"; status: "done"; data: ExpandedQuery }
  | { stage: "expansion"; status: "error"; error: string }
  | { stage: "search"; status: "running" }
  | {
      stage: "search";
      status: "done";
      data: { bm25Hits: ScoredChunk[]; vectorHits: ScoredChunk[] };
    }
  | { stage: "rrf"; status: "done"; data: { merged: RRFResult[] } }
  | { stage: "rerank"; status: "running" }
  | {
      stage: "rerank";
      status: "done";
      data: { before: RRFResult[]; after: RerankedResult[] };
    }
  | { stage: "blend"; status: "done"; data: { finalResults: FinalResult[] } };

// Model loading state
export interface ModelState {
  name: string;
  status: "pending" | "downloading" | "loading" | "ready" | "error";
  progress: number; // 0-1
  error?: string;
}