* Build a compact passage from a search result for cross-encoder scoring. * Keeps it short - cross-encoders are slow on long inputs.
(result: SearchResult)
| 116 | * Keeps it short - cross-encoders are slow on long inputs. |
| 117 | */ |
| 118 | function buildPassage(result: SearchResult): string { |
| 119 | const parts: string[] = []; |
| 120 | |
| 121 | // File path is critical signal |
| 122 | parts.push(`path: ${result.filePath.replace(/\\/g, '/')}`); |
| 123 | |
| 124 | // Component type / layer if available |
| 125 | if (result.componentType && result.componentType !== 'unknown') { |
| 126 | parts.push(`type: ${result.componentType}`); |
| 127 | } |
| 128 | if (result.layer && result.layer !== 'unknown') { |
| 129 | parts.push(`layer: ${result.layer}`); |
| 130 | } |
| 131 | |
| 132 | // Summary is the most information-dense field |
| 133 | if (result.summary) { |
| 134 | parts.push(result.summary); |
| 135 | } |
| 136 | |
| 137 | // Snippet: first ~500 chars (cross-encoder has 512-token context) |
| 138 | if (result.snippet) { |
| 139 | const trimmed = result.snippet.slice(0, 500); |
| 140 | parts.push(trimmed); |
| 141 | } |
| 142 | |
| 143 | return parts.join('\n'); |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Score a single (query, passage) pair using the cross-encoder. |