(entry chatCompletionChunkEntry, w io.Writer, io *iostreams.IOStreams)
| 89 | } |
| 90 | |
| 91 | func renderLogEntry(entry chatCompletionChunkEntry, w io.Writer, io *iostreams.IOStreams) (bool, error) { |
| 92 | cs := io.ColorScheme() |
| 93 | var stop bool |
| 94 | for _, choice := range entry.Choices { |
| 95 | if choice.FinishReason == "stop" { |
| 96 | stop = true |
| 97 | } |
| 98 | |
| 99 | if len(choice.Delta.ToolCalls) == 0 { |
| 100 | if choice.Delta.Content != "" && choice.Delta.Role == "assistant" { |
| 101 | // Copilot message and we should display. |
| 102 | renderRawMarkdown(choice.Delta.Content, w, io) |
| 103 | } |
| 104 | continue |
| 105 | } |
| 106 | |
| 107 | // Since we don't want to clear-and-reprint live progress of events, we |
| 108 | // need to only process entries that correspond to a finished tool call. |
| 109 | // Such entries have a non-empty Content field. |
| 110 | if choice.Delta.Content == "" { |
| 111 | continue |
| 112 | } |
| 113 | |
| 114 | if choice.Delta.ReasoningText != "" { |
| 115 | // Note that this should be formatted as a normal "thought" message, |
| 116 | // without the heading. |
| 117 | renderRawMarkdown(choice.Delta.ReasoningText, w, io) |
| 118 | } |
| 119 | |
| 120 | for _, tc := range choice.Delta.ToolCalls { |
| 121 | name := tc.Function.Name |
| 122 | if name == "" { |
| 123 | continue |
| 124 | } |
| 125 | |
| 126 | args := tc.Function.Arguments |
| 127 | |
| 128 | switch name { |
| 129 | case "run_setup": |
| 130 | if v := unmarshal[runSetupToolArgs](args); v != nil { |
| 131 | renderToolCallTitle(w, cs, v.Name, "") |
| 132 | continue |
| 133 | } |
| 134 | case "view": |
| 135 | args := viewToolArgs{} |
| 136 | if err := json.Unmarshal([]byte(tc.Function.Arguments), &args); err != nil { |
| 137 | fmt.Fprintf(io.ErrOut, "\nfailed to parse 'view' tool call arguments: %v\n", err) |
| 138 | continue |
| 139 | } |
| 140 | renderToolCallTitle(w, cs, fmt.Sprintf("View %s", cs.Bold(relativeFilePath(args.Path))), "") |
| 141 | |
| 142 | content := stripDiffFormat(choice.Delta.Content) |
| 143 | |
| 144 | if err := renderFileContentAsMarkdown(args.Path, content, w, io); err != nil { |
| 145 | fmt.Fprintf(io.ErrOut, "\nfailed to render viewed file content: %v\n\n", err) |
| 146 | fmt.Fprintln(io.ErrOut, content) // raw fallback |
| 147 | } |
| 148 | case "bash": |
no test coverage detected