(report)
| 1623 | // ── Report ───────────────────────────────────────────────────────── |
| 1624 | |
| 1625 | function renderMarkdownReport(report) { |
| 1626 | const lines = [ |
| 1627 | '# Comet Execution Benchmark 报告', '', |
| 1628 | `- 生成时间: ${report.generatedAt}`, |
| 1629 | `- Dry run: ${report.dryRun ? '是' : '否'}`, |
| 1630 | `- 测试阶段: ${report.phase}`, |
| 1631 | `- 每组重复次数: ${report.repeats}`, |
| 1632 | `- 测试档位: ${report.tiers.join(', ')}`, '', |
| 1633 | ]; |
| 1634 | |
| 1635 | if (report.summary.l1) { |
| 1636 | const l1 = report.summary.l1; |
| 1637 | lines.push( |
| 1638 | '## L1: 设计阶段', '', |
| 1639 | `- Token 节省: ${l1.tokenSavings.totalTokens} (${l1.tokenSavings.percent}%)`, |
| 1640 | `- 输入 token 节省: ${l1.tokenSavings.inputTokens}`, '', |
| 1641 | '| 模式 | 平均总 tokens | 需求覆盖率 | 平均决策数 | 平均风险数 | 平均耗时(s) | 平均成本($) |', |
| 1642 | '| --- | ---: | ---: | ---: | ---: | ---: | ---: |', |
| 1643 | ); |
| 1644 | for (const mode of MODES) { |
| 1645 | const m = l1.modes[mode]; |
| 1646 | if (!m) continue; |
| 1647 | lines.push(`| ${mode} | ${m.avgTotalTokens} | ${round(m.avgCoverageRate * 100)}% | ${m.avgDecisionsCount} | ${m.avgRisksIdentified} | ${round(m.avgDurationMs / 1000)} | ${m.avgCostUsd} |`); |
| 1648 | } |
| 1649 | lines.push(''); |
| 1650 | } |
| 1651 | |
| 1652 | if (report.summary.l2) { |
| 1653 | const l2 = report.summary.l2; |
| 1654 | lines.push( |
| 1655 | '## L2: 构建阶段', '', |
| 1656 | `- Token 节省: ${l2.tokenSavings.totalTokens} (${l2.tokenSavings.percent}%)`, |
| 1657 | `- 输入 token 节省: ${l2.tokenSavings.inputTokens}`, '', |
| 1658 | '| 模式 | 平均总 tokens | 测试通过率 | 完成率 | 平均重试 | 平均耗时(s) | 平均成本($) |', |
| 1659 | '| --- | ---: | ---: | ---: | ---: | ---: | ---: |', |
| 1660 | ); |
| 1661 | for (const mode of MODES) { |
| 1662 | const m = l2.modes[mode]; |
| 1663 | if (!m) continue; |
| 1664 | lines.push(`| ${mode} | ${m.avgTotalTokens} | ${round(m.avgTestPassRate * 100)}% | ${round(m.completionRate * 100)}% | ${m.avgAttempts} | ${round(m.avgDurationMs / 1000)} | ${m.avgCostUsd} |`); |
| 1665 | } |
| 1666 | lines.push(''); |
| 1667 | |
| 1668 | // Tier breakdown for L2 |
| 1669 | lines.push('### L2 分档明细', '', |
| 1670 | '| 档位 | off 总 tokens | beta 总 tokens | Token 节省 | off 通过率 | beta 通过率 | off 完成率 | beta 完成率 |', |
| 1671 | '| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |', |
| 1672 | ); |
| 1673 | for (const tier of report.tiers) { |
| 1674 | const tierResults = report.results.filter((r) => r.tier === tier && r.phase === 'l2'); |
| 1675 | if (tierResults.length === 0) continue; |
| 1676 | const tierModes = {}; |
| 1677 | for (const mode of MODES) { |
| 1678 | const mr = tierResults.filter((r) => r.mode === mode); |
| 1679 | const c = mr.length || 1; |
| 1680 | const t = mr.reduce((acc, r) => { |
| 1681 | acc.totalTokens += r.usage.totalTokens; |
| 1682 | acc.testsPassed += r.testResult?.testsPassed ?? 0; |
no test coverage detected