feat: language-aware PR descriptions with TL;DR for JS/TS
- Add language field to PrCommentFields interface in cf-api and cf-webapp
- For JS/TS PRs, extract first paragraph as a visible summary ("TL;DR")
and collapse the full explanation into a <details> block
- Use correct code block language (typescript vs python) for generated
test code in PR body
- Remove Python-specific comments from type definitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e18a111d2b
commit
a59eeff5b7
3 changed files with 42 additions and 4 deletions
|
|
@ -38,6 +38,7 @@ export interface PrCommentFields {
|
||||||
benchmark_details?: BenchmarkDetail[]
|
benchmark_details?: BenchmarkDetail[]
|
||||||
original_async_throughput?: string
|
original_async_throughput?: string
|
||||||
best_async_throughput?: string
|
best_async_throughput?: string
|
||||||
|
language?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependencies interface for easier testing
|
// Dependencies interface for easier testing
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ import { fileURLToPath } from "url"
|
||||||
import { PrCommentFields } from "./create-pr-from-diffcontents.js"
|
import { PrCommentFields } from "./create-pr-from-diffcontents.js"
|
||||||
import { OptimizationReview } from "../OptimizationReview.js"
|
import { OptimizationReview } from "../OptimizationReview.js"
|
||||||
|
|
||||||
|
function isJsTsLanguage(language?: string): boolean {
|
||||||
|
return language === "javascript" || language === "typescript"
|
||||||
|
}
|
||||||
|
|
||||||
export function generateOptimizationReviewTemplate(optimizationReview: string): string {
|
export function generateOptimizationReviewTemplate(optimizationReview: string): string {
|
||||||
// Return empty string if optimizationReview is empty
|
// Return empty string if optimizationReview is empty
|
||||||
if (!optimizationReview || optimizationReview === "") {
|
if (!optimizationReview || optimizationReview === "") {
|
||||||
|
|
@ -292,7 +296,39 @@ export function buildResultHeader(fields: PrCommentFields, isUnifiedReview?: boo
|
||||||
.replace(/\{num_runs}/g, fields.loop_count)
|
.replace(/\{num_runs}/g, fields.loop_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractTldr(explanation: string): { summary: string; details: string } {
|
||||||
|
// Remove leading markdown bold header like "**Optimization Explanation:**\n"
|
||||||
|
const cleaned = explanation.replace(/^\*\*[^*]+\*\*:?\s*\n?/, "").trim()
|
||||||
|
|
||||||
|
// Split on double newline to get paragraphs
|
||||||
|
const paragraphs = cleaned.split(/\n\n+/)
|
||||||
|
|
||||||
|
if (paragraphs.length <= 1) {
|
||||||
|
// Single paragraph — use first two sentences as summary
|
||||||
|
const sentences = cleaned.match(/[^.!?\n]+[.!?]+/g)
|
||||||
|
if (sentences && sentences.length > 2) {
|
||||||
|
const summary = sentences.slice(0, 2).join("").trim()
|
||||||
|
const rest = cleaned.slice(summary.length).trim()
|
||||||
|
return { summary, details: rest }
|
||||||
|
}
|
||||||
|
return { summary: cleaned, details: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use first paragraph as summary, rest as details
|
||||||
|
return { summary: paragraphs[0].trim(), details: paragraphs.slice(1).join("\n\n").trim() }
|
||||||
|
}
|
||||||
|
|
||||||
export function buildResultDetails(fields: PrCommentFields, isCollapsed: boolean = false): string {
|
export function buildResultDetails(fields: PrCommentFields, isCollapsed: boolean = false): string {
|
||||||
|
// For JS/TS: use TL;DR format with summary up front and details collapsed
|
||||||
|
if (isJsTsLanguage(fields.language)) {
|
||||||
|
const { summary, details } = extractTldr(fields.optimization_explanation)
|
||||||
|
let result = `#### 📝 Summary\n\n${summary}\n`
|
||||||
|
if (details) {
|
||||||
|
result += `\n<details>\n<summary>Full explanation and details</summary>\n\n${details}\n</details>\n`
|
||||||
|
}
|
||||||
|
return result + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
return isCollapsed
|
return isCollapsed
|
||||||
? getPrDetailsTemplateCollapsed().replace(
|
? getPrDetailsTemplateCollapsed().replace(
|
||||||
/\{optimization_explanation}/g,
|
/\{optimization_explanation}/g,
|
||||||
|
|
@ -392,8 +428,8 @@ export function buildResultTestReport(
|
||||||
const trimmedGeneratedTests = generatedTests.trim()
|
const trimmedGeneratedTests = generatedTests.trim()
|
||||||
// Check if generatedTests already contains backticks
|
// Check if generatedTests already contains backticks
|
||||||
if (!trimmedGeneratedTests.includes("`")) {
|
if (!trimmedGeneratedTests.includes("`")) {
|
||||||
// Wrap in Python markdown block
|
const codeBlockLang = isJsTsLanguage(fields.language) ? "typescript" : "python"
|
||||||
reportTableMd += "```python\n" + trimmedGeneratedTests + "\n```"
|
reportTableMd += "```" + codeBlockLang + "\n" + trimmedGeneratedTests + "\n```"
|
||||||
} else {
|
} else {
|
||||||
reportTableMd += trimmedGeneratedTests
|
reportTableMd += trimmedGeneratedTests
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,17 @@ export interface DiffContents {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrCommentFields {
|
export interface PrCommentFields {
|
||||||
file_path?: string // Likely the main Python file being optimized
|
file_path?: string
|
||||||
speedup_x?: string
|
speedup_x?: string
|
||||||
loop_count?: number
|
loop_count?: number
|
||||||
speedup_pct?: string
|
speedup_pct?: string
|
||||||
best_runtime?: string
|
best_runtime?: string
|
||||||
report_table?: Record<string, { failed: number; passed: number }>
|
report_table?: Record<string, { failed: number; passed: number }>
|
||||||
function_name?: string // The Python function optimized
|
function_name?: string
|
||||||
original_runtime?: string
|
original_runtime?: string
|
||||||
benchmark_details?: any
|
benchmark_details?: any
|
||||||
optimization_explanation?: string
|
optimization_explanation?: string
|
||||||
|
language?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExperimentMetadata {
|
export interface ExperimentMetadata {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue