ai-code-battle/cmd/acb-evolver/internal/prompt/convert.go
jedarden ea04f4debb style: apply gofmt alignment fixes across codebase
Tab/space alignment consistency from running gofmt on all packages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 10:40:33 -04:00

116 lines
3.4 KiB
Go

// Package prompt assembles evolution prompts for the LLM ensemble.
package prompt
import (
evolverdb "github.com/aicodebattle/acb/cmd/acb-evolver/internal/db"
"github.com/aicodebattle/acb/cmd/acb-evolver/internal/meta"
"github.com/aicodebattle/acb/cmd/acb-evolver/internal/replay"
)
// FromReplayAnalysis converts a replay.Analysis to a prompt.MatchSummary.
// This allows the prompt builder to consume output from the replay analyzer.
func FromReplayAnalysis(a *replay.Analysis) MatchSummary {
if a == nil {
return MatchSummary{}
}
return MatchSummary{
MatchID: a.MatchID,
WinnerName: a.WinnerName,
LoserName: a.LoserName,
Condition: a.Condition,
TurnCount: a.TurnCount,
Scores: append([]int(nil), a.Scores...), // copy to avoid aliasing
KeyMoments: append([]string(nil), a.KeyMoments...),
Strategies: append([]string(nil), a.Strategies...),
Weaknesses: append([]string(nil), a.Weaknesses...),
}
}
// FromReplayAnalyses converts multiple replay analyses to match summaries.
func FromReplayAnalyses(analyses []*replay.Analysis) []MatchSummary {
if len(analyses) == 0 {
return nil
}
summaries := make([]MatchSummary, len(analyses))
for i, a := range analyses {
summaries[i] = FromReplayAnalysis(a)
}
return summaries
}
// FromMetaDescription converts a meta.Description to a prompt.MetaDescription.
// This allows the prompt builder to consume output from the meta builder.
func FromMetaDescription(d *meta.Description) MetaDescription {
if d == nil {
return MetaDescription{}
}
return MetaDescription{
TotalBots: d.TotalBots,
DominantStrategy: d.DominantStrategy,
NashMixture: d.NashMixture,
MetaWeaknesses: append([]string(nil), d.MetaWeaknesses...),
TopBots: FromBotInfos(d.TopBots),
IslandStats: FromIslandStatsMap(d.IslandStats),
}
}
// FromBotInfos converts meta.BotInfo slices to prompt.BotSummary slices.
func FromBotInfos(bots []meta.BotInfo) []BotSummary {
if len(bots) == 0 {
return nil
}
result := make([]BotSummary, len(bots))
for i, b := range bots {
result[i] = BotSummary{
Name: b.Name,
Rating: b.Rating,
Island: b.Island,
Evolved: b.Evolved,
}
}
return result
}
// FromIslandStatsMap converts meta island stats to prompt island stats.
func FromIslandStatsMap(stats map[string]meta.IslandStats) map[string]IslandStat {
if stats == nil {
return nil
}
result := make(map[string]IslandStat, len(stats))
for k, v := range stats {
result[k] = IslandStat{
Count: v.Count,
AvgFitness: v.AvgFitness,
TopFitness: v.TopFitness,
}
}
return result
}
// BuildRequest is a convenience function that assembles a prompt.Request
// from the standard evolution pipeline components.
//
// Parameters:
// - parents: programs selected as evolutionary parents (from tournament selection)
// - analyses: replay analyses from recent matches
// - metaDesc: meta-game description from the meta builder
// - island: target island for the new candidate
// - targetLang: programming language for the evolved bot
// - generation: current evolution generation number
func BuildRequest(
parents []*evolverdb.Program,
analyses []*replay.Analysis,
metaDesc *meta.Description,
island string,
targetLang string,
generation int,
) Request {
return Request{
Parents: parents,
Replays: FromReplayAnalyses(analyses),
Meta: FromMetaDescription(metaDesc),
Island: island,
TargetLang: targetLang,
Generation: generation,
}
}