fix: address Copilot review round 4

- runReport splits results by mode suffix into token/llm for PrintComparison
- backward compat fallback (ValidF1Count=0 -> TotalQuestions) only for
  non-LLM modes; LLM modes keep ValidF1Count=0 when all scores sentinel
- MaxRetries==0 means no retry; only negative falls back to default 3
- truncateStr uses []rune to avoid cutting multi-byte UTF-8 characters
- Complete() returns error on empty LLM response (vs silent empty string)
This commit is contained in:
BeaconCat 2026-04-13 13:05:52 +08:00
parent b36fef0e0c
commit bc64d9e708
4 changed files with 20 additions and 7 deletions

View file

@ -305,9 +305,10 @@ func SaveAggregated(results []EvalResult, outDir string) error {
func computeModeAgg(results []EvalResult) AggMetrics {
agg := AggMetrics{ByCategory: map[int]*CatMetrics{}}
for _, r := range results {
// Backward compat: old eval JSON without ValidF1Count → use TotalQuestions.
// Backward compat: old eval JSON (token mode) without ValidF1Count → use TotalQuestions.
// LLM modes may legitimately have ValidF1Count==0 (all failures).
vf1 := r.Agg.ValidF1Count
if vf1 == 0 && r.Agg.TotalQuestions > 0 {
if vf1 == 0 && r.Agg.TotalQuestions > 0 && !strings.HasSuffix(r.Mode, "-llm") {
vf1 = r.Agg.TotalQuestions
}
agg.OverallF1 += r.Agg.OverallF1 * float64(vf1)
@ -321,7 +322,7 @@ func computeModeAgg(results []EvalResult) AggMetrics {
agg.ByCategory[cat] = existing
}
cvf1 := cm.ValidF1Count
if cvf1 == 0 && cm.QuestionCount > 0 {
if cvf1 == 0 && cm.QuestionCount > 0 && !strings.HasSuffix(r.Mode, "-llm") {
cvf1 = cm.QuestionCount
}
existing.F1 += cm.F1 * float64(cvf1)

View file

@ -276,8 +276,9 @@ func countTotalQA(samples []LocomoSample) int {
func truncateStr(s string, maxLen int) string {
s = strings.ReplaceAll(s, "\n", " ")
if len(s) > maxLen {
return s[:maxLen] + "..."
runes := []rune(s)
if len(runes) > maxLen {
return string(runes[:maxLen]) + "..."
}
return s
}

View file

@ -38,7 +38,7 @@ func NewLLMClient(opts LLMClientOptions) *LLMClient {
opts.Timeout = 120 * time.Second
}
maxRetries := opts.MaxRetries
if maxRetries <= 0 {
if maxRetries < 0 {
maxRetries = 3
}
return &LLMClient{
@ -170,5 +170,8 @@ func (c *LLMClient) Complete(ctx context.Context, systemPrompt, userPrompt strin
if idx := strings.Index(content, "</think>"); idx >= 0 {
content = strings.TrimSpace(content[idx+len("</think>"):])
}
if content == "" {
return "", fmt.Errorf("empty LLM response")
}
return content, nil
}

View file

@ -272,7 +272,15 @@ func runReport(cmd *cobra.Command, args []string) error {
return fmt.Errorf("no eval results found in %s", flagOut)
}
PrintComparison(allResults, nil)
var tokenResults, llmResults []EvalResult
for _, r := range allResults {
if strings.HasSuffix(r.Mode, "-llm") {
llmResults = append(llmResults, r)
} else {
tokenResults = append(tokenResults, r)
}
}
PrintComparison(tokenResults, llmResults)
return nil
}