feat: add prediction and omit empty Buy/Sell

This commit is contained in:
ytshih committed 2026-09-07 09:04:34 +08:00
1 parent 521588f992
commit ba63c5deb0
5 files changed
+99 -54

No files matched your search

+38 -17
View File
@@ -67,22 +67,35 @@ func Save(cfg config.ArchiveConfig, run Run, now time.Time) (string, error) {
return dir, nil
}
// LoadLatest reads back the most recent previously-archived run's
// report.md, for the prompt to dedup the next briefing against. Returns
// ("", nil) if no prior run exists yet (e.g. first-ever run) — callers
// should treat that as "no previous report" rather than an error.
func LoadLatest(cfg config.ArchiveConfig) (string, error) {
// RecentRun is one previously-archived run's timestamp and report text, as
// returned by LoadRecent.
type RecentRun struct {
When time.Time
Report string
}
// runDirLayout is the timestamp format run directories are named with (see
// Save), used by LoadRecent to recover each run's time.
const runDirLayout = "20060102T150405Z"
// LoadRecent reads back up to the last n previously-archived runs' report.md
// contents, oldest first, for the prompt to dedup the next briefing against
// a rolling window of recent history. Returns (nil, nil) if no prior run
// exists yet (e.g. first-ever run) — callers should treat that as "no
// previous reports" rather than an error. Runs whose report.md is missing or
// unreadable are skipped rather than failing the whole call.
func LoadRecent(cfg config.ArchiveConfig, n int) ([]RecentRun, error) {
base, err := resolveDir(cfg)
if err != nil {
return "", err
return nil, err
}
entries, err := os.ReadDir(base)
if err != nil {
if os.IsNotExist(err) {
return "", nil
return nil, nil
}
return "", fmt.Errorf("archive: list %q: %w", base, err)
return nil, fmt.Errorf("archive: list %q: %w", base, err)
}
var runDirs []string
@@ -92,19 +105,27 @@ func LoadLatest(cfg config.ArchiveConfig) (string, error) {
}
}
if len(runDirs) == 0 {
return "", nil
return nil, nil
}
sort.Strings(runDirs) // timestamp-named dirs sort chronologically
latest := runDirs[len(runDirs)-1]
data, err := os.ReadFile(filepath.Join(base, latest, "report.md"))
if err != nil {
if os.IsNotExist(err) {
return "", nil
}
return "", fmt.Errorf("archive: read previous report: %w", err)
if len(runDirs) > n {
runDirs = runDirs[len(runDirs)-n:]
}
return string(data), nil
var runs []RecentRun
for _, name := range runDirs {
when, err := time.Parse(runDirLayout, name)
if err != nil {
continue
}
data, err := os.ReadFile(filepath.Join(base, name, "report.md"))
if err != nil {
continue
}
runs = append(runs, RecentRun{When: when.UTC(), Report: string(data)})
}
return runs, nil
}
// resolveDir returns cfg.Dir (or defaultDir if empty) with "~" expanded.