(ctx context.Context)
| 69 | } |
| 70 | |
| 71 | func (a *Agent) loop(ctx context.Context) (string, error) { |
| 72 | var finalText strings.Builder |
| 73 | |
| 74 | for turn := 0; turn < a.MaxTurns; turn++ { |
| 75 | before := a.messages |
| 76 | if compacted, err := a.Compactor.Compact(ctx, before); err != nil { |
| 77 | fmt.Printf("%scompaction error: %v (continuing without)\n", a.LogPrefix, err) |
| 78 | debug.Recordp("compact", debug.LevelError, |
| 79 | fmt.Sprintf("%s: %v", a.compactorName(), err), |
| 80 | api.RenderTranscript(before)) |
| 81 | } else { |
| 82 | if len(compacted) != len(before) { |
| 83 | summary := fmt.Sprintf("%s: %d → %d msgs", a.compactorName(), len(before), len(compacted)) |
| 84 | payload := "--- before (" + fmt.Sprint(len(before)) + " msgs) ---\n" + |
| 85 | api.RenderTranscript(before) + |
| 86 | "\n--- after (" + fmt.Sprint(len(compacted)) + " msgs) ---\n" + |
| 87 | api.RenderTranscript(compacted) |
| 88 | debug.Recordp("compact", debug.LevelInfo, summary, payload) |
| 89 | } |
| 90 | if a.Verbose && len(compacted) != len(before) { |
| 91 | fmt.Printf("--- compaction: %d → %d ---\n", len(before), len(compacted)) |
| 92 | fmt.Print(api.RenderTranscript(before)) |
| 93 | fmt.Println("---") |
| 94 | fmt.Print(api.RenderTranscript(compacted)) |
| 95 | fmt.Println("---") |
| 96 | } |
| 97 | a.messages = compacted |
| 98 | } |
| 99 | |
| 100 | resp, err := a.Provider.Send(ctx, a.messages, a.Tools.Definitions()) |
| 101 | if err != nil { |
| 102 | return finalText.String(), err |
| 103 | } |
| 104 | |
| 105 | a.messages = append(a.messages, api.Message{Role: api.RoleAssistant, Content: resp.Content}) |
| 106 | |
| 107 | var toolResults []api.Block |
| 108 | var hasToolCall bool |
| 109 | |
| 110 | for _, b := range resp.Content { |
| 111 | switch b.Type { |
| 112 | case api.BlockText: |
| 113 | if b.Text == "" { |
| 114 | continue |
| 115 | } |
| 116 | if !a.Quiet { |
| 117 | fmt.Println(b.Text) |
| 118 | } |
| 119 | finalText.WriteString(b.Text) |
| 120 | finalText.WriteString("\n") |
| 121 | case api.BlockToolUse: |
| 122 | hasToolCall = true |
| 123 | result, isErr := a.executeTool(ctx, b.ToolName, b.ToolInput) |
| 124 | toolResults = append(toolResults, api.Block{ |
| 125 | Type: api.BlockToolResult, |
| 126 | ToolUseID: b.ToolUseID, |
| 127 | ToolResult: result, |
| 128 | IsError: isErr, |
no test coverage detected