@@ -128,6 +128,75 @@ export async function handleBenchmarksRoutes(req: Request, url: URL): Promise<Re
128128 }
129129 }
130130
131+ // POST /api/benchmarks/:name/expand-ids - Expand conversation/session patterns to question IDs
132+ const expandIdsMatch = pathname . match ( / ^ \/ a p i \/ b e n c h m a r k s \/ ( [ ^ / ] + ) \/ e x p a n d - i d s $ / )
133+ if ( method === "POST" && expandIdsMatch ) {
134+ const benchmarkName = expandIdsMatch [ 1 ]
135+
136+ try {
137+ const body = await req . json ( )
138+ const { patterns } = body as { patterns : string [ ] }
139+
140+ if ( ! patterns || ! Array . isArray ( patterns ) ) {
141+ return json ( { error : "patterns array is required" } , 400 )
142+ }
143+
144+ const benchmark = createBenchmark ( benchmarkName as any )
145+ await benchmark . load ( )
146+ const allQuestions = benchmark . getQuestions ( )
147+
148+ const expandedIds = new Set < string > ( )
149+ const patternResults : Record < string , string [ ] > = { }
150+
151+ for ( const pattern of patterns ) {
152+ const trimmed = pattern . trim ( )
153+ if ( ! trimmed ) continue
154+
155+ const expanded : string [ ] = [ ]
156+
157+ // Pattern 1: Conversation ID (e.g., "conv-26") - expand to all questions
158+ // Check if pattern ends with a number and doesn't have -q or -session suffix
159+ if ( / ^ [ a - z A - Z ] + - \d + $ / . test ( trimmed ) ) {
160+ const matchingQuestions = allQuestions . filter ( ( q ) =>
161+ q . questionId . startsWith ( trimmed + "-q" )
162+ )
163+ matchingQuestions . forEach ( ( q ) => {
164+ expanded . push ( q . questionId )
165+ expandedIds . add ( q . questionId )
166+ } )
167+ }
168+ // Pattern 2: Session ID (e.g., "conv-26-session_1" or "001be529-session-0")
169+ // Find all questions that reference this session
170+ else if ( trimmed . includes ( "-session" ) ) {
171+ const matchingQuestions = allQuestions . filter ( ( q ) =>
172+ q . haystackSessionIds . includes ( trimmed )
173+ )
174+ matchingQuestions . forEach ( ( q ) => {
175+ expanded . push ( q . questionId )
176+ expandedIds . add ( q . questionId )
177+ } )
178+ }
179+ // Pattern 3: Direct question ID - add as-is if it exists
180+ else {
181+ const exactMatch = allQuestions . find ( ( q ) => q . questionId === trimmed )
182+ if ( exactMatch ) {
183+ expanded . push ( trimmed )
184+ expandedIds . add ( trimmed )
185+ }
186+ }
187+
188+ patternResults [ pattern ] = expanded
189+ }
190+
191+ return json ( {
192+ expandedIds : Array . from ( expandedIds ) ,
193+ patternResults,
194+ } )
195+ } catch ( e ) {
196+ return json ( { error : e instanceof Error ? e . message : "Failed to expand IDs" } , 400 )
197+ }
198+ }
199+
131200 // GET /api/models - List available models
132201 if ( method === "GET" && pathname === "/api/models" ) {
133202 const openai = listModelsByProvider ( "openai" ) . map ( ( alias ) => ( {
0 commit comments