| 58 | |
| 59 | // Research agent that validates a single question |
| 60 | async function validateQuestion(question: Question, schema: string): Promise<ValidationResult> { |
| 61 | console.log(`\n${'='.repeat(60)}`); |
| 62 | console.log(`Validating ${question.id}: ${question.question}`); |
| 63 | console.log(`Original answer: ${question.reference_answer}`); |
| 64 | console.log(`${'='.repeat(60)}`); |
| 65 | |
| 66 | // Step 1: Ask the model to generate SQL queries to validate |
| 67 | const sqlPlanResponse = await generateText({ |
| 68 | model: VALIDATION_MODEL, |
| 69 | system: `You are a data analyst validating reference answers for an eval dataset. |
| 70 | Given a question about GitHub data, generate 1-3 SQL queries that would help validate the reference answer. |
| 71 | |
| 72 | DATABASE SCHEMA: |
| 73 | ${schema} |
| 74 | |
| 75 | EXAMPLE QUERIES (use these patterns): |
| 76 | -- Count issues per repo: |
| 77 | SELECT repos.full_name, COUNT(*) as issue_count |
| 78 | FROM repos JOIN issues ON repos.id = issues.repo_id |
| 79 | GROUP BY repos.id ORDER BY issue_count DESC LIMIT 5; |
| 80 | |
| 81 | -- Find issues by text: |
| 82 | SELECT repos.full_name, issues.number, issues.title |
| 83 | FROM issues JOIN repos ON issues.repo_id = repos.id |
| 84 | WHERE issues.body LIKE '%keyword%'; |
| 85 | |
| 86 | -- Count by owner: |
| 87 | SELECT owner, COUNT(*) FROM repos GROUP BY owner ORDER BY COUNT(*) DESC LIMIT 10; |
| 88 | |
| 89 | -- PRs with merge status: |
| 90 | SELECT repos.full_name, pulls.number, pulls.title, pulls.merged |
| 91 | FROM pulls JOIN repos ON pulls.repo_id = repos.id |
| 92 | WHERE pulls.merged = 1; |
| 93 | |
| 94 | IMPORTANT RULES: |
| 95 | - ALWAYS use full table names (repos, issues, pulls, comments, events, users) |
| 96 | - NEVER use aliases like r, i, p - use repos, issues, pulls directly |
| 97 | - labels_json is a JSON array string like '["bug","enhancement"]' |
| 98 | - Use LIKE for text search in body/title fields |
| 99 | - merged column in pulls is 0/1 (not true/false) |
| 100 | - Filter bots with: author NOT LIKE '%[bot]%' AND author NOT LIKE '%bot' |
| 101 | |
| 102 | Return ONLY valid SQL queries, one per line. No explanation.`, |
| 103 | prompt: `Question: ${question.question} |
| 104 | Reference answer to validate: ${question.reference_answer} |
| 105 | |
| 106 | Generate SQL queries to verify this answer:`, |
| 107 | maxOutputTokens: 1000, |
| 108 | }); |
| 109 | |
| 110 | // Parse SQL queries - handle multi-line queries by splitting on semicolons |
| 111 | const sqlQueries = sqlPlanResponse.text |
| 112 | .split(';') |
| 113 | .map((q) => q.trim().replace(/\n/g, ' ').replace(/\s+/g, ' ')) |
| 114 | .filter((q) => q.toUpperCase().startsWith('SELECT') || q.toUpperCase().startsWith('WITH')) |
| 115 | .slice(0, 3); |
| 116 | |
| 117 | console.log(`\nGenerated ${sqlQueries.length} SQL queries`); |