ParseCopilotCodingAgentLogMetrics extracts metrics from GitHub Copilot coding agent logs This is different from Copilot CLI logs and requires specialized parsing
(logContent string, verbose bool)
| 36 | // ParseCopilotCodingAgentLogMetrics extracts metrics from GitHub Copilot coding agent logs |
| 37 | // This is different from Copilot CLI logs and requires specialized parsing |
| 38 | func ParseCopilotCodingAgentLogMetrics(logContent string, verbose bool) workflow.LogMetrics { |
| 39 | copilotCodingAgentLog.Printf("Parsing GitHub Copilot coding agent log metrics: %d bytes", len(logContent)) |
| 40 | |
| 41 | var metrics workflow.LogMetrics |
| 42 | var maxTokenUsage int |
| 43 | |
| 44 | lines := strings.Split(logContent, "\n") |
| 45 | toolCallMap := make(map[string]*workflow.ToolCallInfo) |
| 46 | var currentSequence []string |
| 47 | turns := 0 |
| 48 | |
| 49 | for _, line := range lines { |
| 50 | // Skip empty lines |
| 51 | if strings.TrimSpace(line) == "" { |
| 52 | continue |
| 53 | } |
| 54 | |
| 55 | // Count turns based on agent iteration patterns |
| 56 | if agentTurnPattern.MatchString(line) { |
| 57 | turns++ |
| 58 | // Start of a new turn, save previous sequence if any |
| 59 | if len(currentSequence) > 0 { |
| 60 | metrics.ToolSequences = append(metrics.ToolSequences, currentSequence) |
| 61 | currentSequence = []string{} |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | // Extract tool calls from agent logs |
| 66 | if agentToolCallPattern.MatchString(line) { |
| 67 | toolName := extractToolName(line) |
| 68 | if toolName != "" { |
| 69 | // Track tool call |
| 70 | if _, exists := toolCallMap[toolName]; !exists { |
| 71 | toolCallMap[toolName] = &workflow.ToolCallInfo{ |
| 72 | Name: toolName, |
| 73 | CallCount: 0, |
| 74 | } |
| 75 | } |
| 76 | toolCallMap[toolName].CallCount++ |
| 77 | |
| 78 | // Add to current sequence |
| 79 | currentSequence = append(currentSequence, toolName) |
| 80 | |
| 81 | if verbose { |
| 82 | copilotCodingAgentLog.Printf("Found tool call: %s", toolName) |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | // Try to extract token usage from JSON format if available |
| 88 | jsonMetrics := workflow.ExtractJSONMetrics(line, verbose) |
| 89 | if jsonMetrics.TokenUsage > 0 || jsonMetrics.EstimatedCost > 0 { |
| 90 | if jsonMetrics.TokenUsage > maxTokenUsage { |
| 91 | maxTokenUsage = jsonMetrics.TokenUsage |
| 92 | } |
| 93 | if jsonMetrics.EstimatedCost > 0 { |
| 94 | metrics.EstimatedCost += jsonMetrics.EstimatedCost |
| 95 | } |