iop/apps/edge/internal/openai/hot_path_review.go

62 lines
2 KiB
Go

package openai
import (
"context"
"fmt"
"strings"
)
func (s *Server) advanceHotPathReview(
ctx context.Context,
requestID string,
phase hotPathLightPhase,
output normalizedStageOutput,
visible normalizedStageOutput,
outer *hotPathOuterTurn,
protocol string,
) (normalizedStageOutput, bool, error) {
kind, cleanup, err := classifyHotPathReviewOutput(requestID, phase, output)
if err != nil {
return normalizedStageOutput{}, false, err
}
if cleanup {
terminalOutput := output.StageResponseOverlay(visible)
if outer != nil {
terminalOutput = hotPathCompatibilityOutput(outer, terminalOutput, protocol)
}
intent := hotPathTerminalIntent{Output: terminalOutput}
mapped, err := s.lightFlows.beginCleanupWithOuter(ctx, requestID, s.edgeIDValue(), intent, outer, s.requestCoordinator)
if err != nil {
s.terminalPresetRequest(requestID, s.edgeIDValue())
return terminalOutput, true, nil
}
return mapped, true, nil
}
mapped, err := s.lightFlows.issueTools(ctx, requestID, s.edgeIDValue(), output, visible, kind, outer, s.requestCoordinator)
if err != nil {
return normalizedStageOutput{}, false, err
}
return mapped, true, nil
}
func classifyHotPathReviewOutput(requestID string, phase hotPathLightPhase, output normalizedStageOutput) (hotPathPendingKind, bool, error) {
if phase != hotPathPhaseReviewActive && phase != hotPathPhaseReviewRepair {
return "", false, fmt.Errorf("phase %q is not a review phase", phase)
}
if len(output.ToolCalls) == 0 {
if strings.TrimSpace(output.Content) == "" {
return "", false, fmt.Errorf("review terminal output must be non-empty")
}
return "", true, nil
}
paths := newReservedPaths(requestID)
for _, call := range output.ToolCalls {
for _, path := range reservedPathsFromToolCall(call) {
clean := cleanRelativePath(path)
if clean == cleanRelativePath(paths.PlanPath) || clean == cleanRelativePath(paths.ReviewPath) {
return hotPathPendingReviewInspection, false, nil
}
}
}
return hotPathPendingReviewRepair, false, nil
}