feat(trail): add --debug-dir to tune for inspecting prompt and response · Entire
feat(trail): add --debug-dir to tune for inspecting prompt and response
5555d40→main·
Soph·3w ago·2 files·+48 added/-2 removed
`entire trail tune --debug-dir
and, in --run mode, the raw model response (response.txt) to
it possible to debug why a runner was skipped or tailored oddly: prompt.txt
shows exactly what signal the model received (the gathered-context block),
response.txt shows exactly what it returned before validation/parsing. Writes
are best-effort — failures warn rather than abort the run.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
7a31299a7258View transcript
Changes
2
cmd/entire/cli
Mtrail_tune_cmd.go+29/-2
Mtrail_tune_init_test.go+19
18 unmodified lines
19
20
21
22
23
24
25
3 unmodified lines
29
30
31
32
33
34
35
27 unmodified lines
63
64
65
66
67
68
69
8 unmodified lines
78
79
80
81
82
83
84
85
25 unmodified lines
111
112
113
114
115
116
117
118
119
120
3 unmodified lines
124
125
126
118
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
1 unmodified line
147
148
149
126
150
151
152
153
16 unmodified lines
170
171
172
173
174
175
176
177
178
18 unmodified lines
runner string // optional: limit to one runner (id, with or without "trail-")
run bool // headless apply vs. print prompt
assumeYes bool // skip the create-defaults confirmation
debugDir string // if set, dump prompt.txt (+ response.txt on --run) here
sources []string
limit int
insecureHTTP bool
3 unmodified lines
var (
run bool
assumeYes bool
debugDir string
sources []string
limit int
)
27 unmodified lines
runner: runner,
run: run,
assumeYes: assumeYes,
debugDir: debugDir,
sources: sources,
limit: limit,
insecureHTTP: trailInsecureHTTP(cmd),
8 unmodified lines
cmd.Flags().IntVar(&limit, "limit", 20, "How many recent PRs/issues/trails to sample")
cmd.Flags().BoolVarP(&assumeYes, "yes", "y", false,
"Skip the confirmation when creating the default runner set in a repo that has none")
cmd.Flags().StringVar(&debugDir, "debug-dir", "",
"Write the assembled prompt (prompt.txt) and, with --run, the raw model response (response.txt) to this directory for debugging")
return cmd
}
25 unmodified lines
brief := gatherTuningContext(ctx, errW, repoRoot, src, opts.limit, opts.insecureHTTP)
prompt := buildTunePrompt(brief, runners)
if opts.debugDir != "" {
writeTuneDebug(errW, opts.debugDir, "prompt.txt", prompt)
}
if !opts.run {
fmt.Fprintln(w, prompt)
if len(created) > 0 {
3 unmodified lines
return nil
}
return applyTuneWithAgent(ctx, w, errW, runners, prompt, created)
return applyTuneWithAgent(ctx, w, errW, runners, prompt, created, opts.debugDir)
}
// writeTuneDebug best-effort writes content to <dir>/<name> for debugging,
// reporting any failure as a warning rather than failing the command.
func writeTuneDebug(errW io.Writer, dir, name, content string) {
if err := os.MkdirAll(dir, 0o755); err != nil { //nolint:gosec // user-specified debug dir
fmt.Fprintf(errW, "warning: debug dir %s: %v\n", dir, err)
return
}
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte(content), 0o644); err != nil { //nolint:gosec // local debug artifact
fmt.Fprintf(errW, "warning: writing %s: %v\n", path, err)
return
}
fmt.Fprintf(errW, "debug: wrote %s\n", path)
}
// applyTuneWithAgent runs the prompt through the configured summary provider
1 unmodified line
// surgically rewrites each runner file's prompt.template in place. createdIDs
// are runners onboarding just scaffolded from defaults; any of those left
// un-tailored is flagged so it isn't committed as if it were repo-specific.
func applyTuneWithAgent(ctx context.Context, w, errW io.Writer, runners []tuneRunner, prompt string, createdIDs []string) error {
func applyTuneWithAgent(ctx context.Context, w, errW io.Writer, runners []tuneRunner, prompt string, createdIDs []string, debugDir string) error {
// Reuse the summary-provider resolution (selection + persistence), but pull
// the raw TextGenerator rather than provider.Generator: the latter is a
// summarize.Generator that turns a transcript Input into a checkpoint
16 unmodified lines
if err != nil {
return fmt.Errorf("agent run failed: %w", err)
}
if debugDir != "" {
writeTuneDebug(errW, debugDir, "response.txt", out)
}
templates, err := parseTuneOutput(out)
if err != nil {