loop: introduce StepContext — per-turn context object assembled once

This commit is contained in:
Levi Neely 2026-05-17 10:54:10 +02:00
parent fa88c89369
commit da36db8f2b
1 changed files with 19 additions and 7 deletions

View File

@ -65,19 +65,31 @@ func run(ctx context.Context, cfg agentConfig, state state) error {
// sync.Map is required because execOne may run in concurrent goroutines.
var resultCache sync.Map
// stepCtx carries per-turn context assembled once at the top of each iteration.
type StepContext struct {
Goal string
TaskState *TaskState
Recent []backend.Message // last N messages (hot window)
}
for {
sc := StepContext{
Goal: cfg.preamble,
TaskState: state.taskState(),
Recent: state.recentHistory(hotTailSize),
}
var history []backend.Message
if ts := state.taskState(); ts != nil {
// Structured mode: task state + recent tail only.
history = state.recentHistory(hotTailSize)
if sc.TaskState != nil {
history = sc.Recent
} else {
history = state.history()
}
if cfg.preamble != "" {
history = append([]backend.Message{{Role: "system", Content: cfg.preamble}}, history...)
if sc.Goal != "" {
history = append([]backend.Message{{Role: "system", Content: sc.Goal}}, history...)
}
if ts := state.taskState(); ts != nil {
if msg := ts.render(); msg != "" && len(history) > 0 {
if sc.TaskState != nil {
if msg := sc.TaskState.render(); msg != "" && len(history) > 0 {
// Insert after system prompt, before conversation.
history = append([]backend.Message{history[0], {Role: "user", Content: msg}}, history[1:]...)
}