-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_eval.go
More file actions
92 lines (82 loc) · 2.7 KB
/
Copy pathcommand_eval.go
File metadata and controls
92 lines (82 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package contexting
import (
"fmt"
"path/filepath"
"github.com/spf13/cobra"
)
func newEvalCommand() *cobra.Command {
var indexPath string
var casesPath string
var opts SearchOptions
var jsonOut bool
cmd := &cobra.Command{
Use: "eval",
Short: "Evaluate search quality against expected query/path cases",
RunE: func(cmd *cobra.Command, args []string) error {
var absConfigPath string
if configPath != "" {
var cfgErr error
absConfigPath, cfgErr = filepath.Abs(configPath)
if cfgErr != nil {
return fmt.Errorf("resolve config path: %w", cfgErr)
}
}
cfg, err := LoadContextingConfig(absConfigPath)
if err != nil {
return err
}
applyStringFlag(cmd, "index", &indexPath, cfg.Eval.IndexPath)
applyStringFlag(cmd, "cases", &casesPath, cfg.Eval.CasesPath)
applyIntFlag(cmd, "limit", &opts.Limit, cfg.Eval.Limit)
applyIntFlag(cmd, "min-score", &opts.MinScore, cfg.Eval.MinScore)
applyStringFlag(cmd, "type", &opts.TypeFilter, cfg.Eval.TypeFilter)
if cfg.Eval.Explain != nil {
applyBoolFlag(cmd, "explain", &opts.IncludeDebug, *cfg.Eval.Explain)
}
if cfg.Eval.JSON != nil {
applyBoolFlag(cmd, "json", &jsonOut, *cfg.Eval.JSON)
}
if !cmd.Flags().Changed("index") {
indexPath = resolveConfigPath(absConfigPath, indexPath)
}
if !cmd.Flags().Changed("cases") {
casesPath = resolveConfigPath(absConfigPath, casesPath)
}
if casesPath == "" {
return fmt.Errorf("--cases is required")
}
index, err := LoadContextIndex(indexPath)
if err != nil {
return err
}
cases, err := LoadCasesAuto(casesPath)
if err != nil {
return err
}
summary, results := EvaluateSearch(index, cases, opts)
if jsonOut {
type payload struct {
Summary EvalSummary `json:"summary"`
Cases []EvalResult `json:"cases"`
}
jsonStr, err := resultsToJSONEval(payload{Summary: summary, Cases: results})
if err != nil {
return err
}
fmt.Println(jsonStr)
return nil
}
printEvalSummary(summary)
printFailedCases(results)
return nil
},
}
cmd.Flags().StringVarP(&indexPath, "index", "i", ".ctxt/ctx_index.json", "Path to context JSON")
cmd.Flags().StringVar(&casesPath, "cases", "", "Path to eval cases JSON")
cmd.Flags().IntVarP(&opts.Limit, "limit", "n", 5, "Number of ranked search results per query")
cmd.Flags().IntVar(&opts.MinScore, "min-score", 1, "Minimum score required for candidate results")
cmd.Flags().StringVar(&opts.TypeFilter, "type", "all", "Filter result type: all|files|dirs")
cmd.Flags().BoolVar(&opts.IncludeDebug, "explain", false, "Include score breakdown in eval case results")
cmd.Flags().BoolVar(&jsonOut, "json", false, "Print full eval report as JSON")
return cmd
}