|
9 | 9 |
|
10 | 10 | "github.com/github/gh-aw/pkg/console" |
11 | 11 | "github.com/github/gh-aw/pkg/logger" |
12 | | -"github.com/github/gh-aw/pkg/workflow" |
13 | 12 | ) |
14 | 13 |
|
15 | 14 | varcopilotCodingAgentLog=logger.New("cli:copilot_agent") |
@@ -179,109 +178,3 @@ func readLogHeader(path string, maxBytes int) (string, error) { |
179 | 178 |
|
180 | 179 | returnstring(buffer[:n]), nil |
181 | 180 | } |
182 | | - |
183 | | -// ParseCopilotCodingAgentLogMetrics extracts metrics from GitHub Copilot coding agent logs |
184 | | -// This is different from Copilot CLI logs and requires specialized parsing |
185 | | -funcParseCopilotCodingAgentLogMetrics(logContentstring, verbosebool) workflow.LogMetrics { |
186 | | -copilotCodingAgentLog.Printf("Parsing GitHub Copilot coding agent log metrics: %d bytes", len(logContent)) |
187 | | - |
188 | | -varmetrics workflow.LogMetrics |
189 | | -varmaxTokenUsageint |
190 | | - |
191 | | -lines:=strings.Split(logContent, "\n") |
192 | | -toolCallMap:=make(map[string]*workflow.ToolCallInfo) |
193 | | -varcurrentSequence []string |
194 | | -turns:=0 |
195 | | - |
196 | | -// GitHub Copilot coding agent log patterns |
197 | | -// These patterns are designed to match the specific log format of the agent |
198 | | -turnPattern:=regexp.MustCompile(`(?i)task.*iteration|agent.*turn|step.*\d+`) |
199 | | -toolCallPattern:=regexp.MustCompile(`(?i)tool.*call|executing.*tool|calling.*(\w+)`) |
200 | | - |
201 | | -for_, line:=rangelines { |
202 | | -// Skip empty lines |
203 | | -ifstrings.TrimSpace(line) =="" { |
204 | | -continue |
205 | | - } |
206 | | - |
207 | | -// Count turns based on agent iteration patterns |
208 | | -ifturnPattern.MatchString(line) { |
209 | | -turns++ |
210 | | -// Start of a new turn, save previous sequence if any |
211 | | -iflen(currentSequence) >0 { |
212 | | -metrics.ToolSequences=append(metrics.ToolSequences, currentSequence) |
213 | | -currentSequence= []string{} |
214 | | - } |
215 | | - } |
216 | | - |
217 | | -// Extract tool calls from agent logs |
218 | | -ifmatches:=toolCallPattern.FindStringSubmatch(line); len(matches) >1 { |
219 | | -toolName:=extractToolName(line) |
220 | | -iftoolName!="" { |
221 | | -// Track tool call |
222 | | -if_, exists:=toolCallMap[toolName]; !exists { |
223 | | -toolCallMap[toolName] =&workflow.ToolCallInfo{ |
224 | | -Name: toolName, |
225 | | -CallCount: 0, |
226 | | - } |
227 | | - } |
228 | | -toolCallMap[toolName].CallCount++ |
229 | | - |
230 | | -// Add to current sequence |
231 | | -currentSequence=append(currentSequence, toolName) |
232 | | - |
233 | | -ifverbose { |
234 | | -copilotCodingAgentLog.Printf("Found tool call: %s", toolName) |
235 | | - } |
236 | | - } |
237 | | - } |
238 | | - |
239 | | -// Try to extract token usage from JSON format if available |
240 | | -jsonMetrics:=workflow.ExtractJSONMetrics(line, verbose) |
241 | | -ifjsonMetrics.TokenUsage>0||jsonMetrics.EstimatedCost>0 { |
242 | | -ifjsonMetrics.TokenUsage>maxTokenUsage { |
243 | | -maxTokenUsage=jsonMetrics.TokenUsage |
244 | | - } |
245 | | -ifjsonMetrics.EstimatedCost>0 { |
246 | | -metrics.EstimatedCost+=jsonMetrics.EstimatedCost |
247 | | - } |
248 | | - } |
249 | | - } |
250 | | - |
251 | | -// Add final sequence if any |
252 | | -iflen(currentSequence) >0 { |
253 | | -metrics.ToolSequences=append(metrics.ToolSequences, currentSequence) |
254 | | - } |
255 | | - |
256 | | -// Convert tool call map to slice |
257 | | -for_, toolInfo:=rangetoolCallMap { |
258 | | -metrics.ToolCalls=append(metrics.ToolCalls, *toolInfo) |
259 | | - } |
260 | | - |
261 | | -metrics.TokenUsage=maxTokenUsage |
262 | | -metrics.Turns=turns |
263 | | - |
264 | | -copilotCodingAgentLog.Printf("Parsed metrics: tokens=%d, cost=$%.4f, turns=%d", |
265 | | -metrics.TokenUsage, metrics.EstimatedCost, metrics.Turns) |
266 | | - |
267 | | -returnmetrics |
268 | | -} |
269 | | - |
270 | | -// extractToolName extracts a tool name from a log line |
271 | | -funcextractToolName(linestring) string { |
272 | | -// Try to extract tool name from various patterns |
273 | | -patterns:= []*regexp.Regexp{ |
274 | | -regexp.MustCompile(`(?i)tool[:\s]+([a-zA-Z0-9_-]+)`), |
275 | | -regexp.MustCompile(`(?i)calling[:\s]+([a-zA-Z0-9_-]+)`), |
276 | | -regexp.MustCompile(`(?i)executing[:\s]+([a-zA-Z0-9_-]+)`), |
277 | | -regexp.MustCompile(`(?i)using[:\s]+tool[:\s]+([a-zA-Z0-9_-]+)`), |
278 | | - } |
279 | | - |
280 | | -for_, pattern:=rangepatterns { |
281 | | -ifmatches:=pattern.FindStringSubmatch(line); len(matches) >1 { |
282 | | -returnstrings.TrimSpace(matches[1]) |
283 | | - } |
284 | | - } |
285 | | - |
286 | | -return"" |
287 | | -} |
0 commit comments