Analysis of commit 0dffa81
Assignee: @copilot
Summary
The engine-specific ParseLogMetrics implementations all repeat the same block that finalizes tool call metrics (appending the last sequence, copying the tool call map into a slice, sorting it, and counting errors). Copilot, Codex, and Claude pipelines each copy this logic verbatim with only variable name changes.
Duplication Details
Pattern: Repeated tool call finalization logic in log parsers
- Severity: Medium
- Occurrences: 3
- Locations:
pkg/workflow/copilot_engine.go:492
pkg/workflow/codex_engine.go:407
pkg/workflow/claude_logs.go:340
- Code Sample:
if len(currentSequence) > 0 {
metrics.ToolSequences = append(metrics.ToolSequences, currentSequence)
}
metrics.TokenUsage = maxTokenUsage
metrics.Turns = turns
for _, toolInfo := range toolCallMap {
metrics.ToolCalls = append(metrics.ToolCalls, *toolInfo)
}
sort.Slice(metrics.ToolCalls, func(i, j int) bool {
return metrics.ToolCalls[i].Name < metrics.ToolCalls[j].Name
})
errorPatterns := e.GetErrorPatterns()
if len(errorPatterns) > 0 {
metrics.Errors = CountErrorsAndWarningsWithPatterns(logContent, errorPatterns)
}
Impact Analysis
- Maintainability: Updates to how sequences, sorting, or error aggregation work must be repeated in three places, increasing the chance of drift when adding new engines.
- Bug Risk: Any bug fixes to the metric finalization (e.g., changing how warnings are counted) must be manually mirrored everywhere; missing an occurrence yields inconsistent telemetry.
- Code Bloat: The repeated blocks add ~15 lines per engine and make the already large log parsing routines harder to scan.
Refactoring Recommendations
-
Extract shared helper
- Move the duplication into a helper such as
finalizeToolMetrics(metrics *LogMetrics, toolCallMap map[string]*ToolCallInfo, currentSequence []string, turns int, tokenUsage int, logContent string, getPatterns func() []ErrorPattern).
- Estimated effort: Medium (1-2h) because the helper can live in
pkg/workflow/log_parser.go and accept function pointers for engine-specific hooks.
- Benefits: Single source of truth for tool sequencing and error aggregation.
-
Standardize sequence tracking
- Consider wrapping the shared state (tool call map, current sequence, turns, token totals) in a struct so engines update fields but delegate finalization to one method.
- Benefits: Simplifies adding new engines like Claude variants without extra boilerplate.
Implementation Checklist
Analysis Metadata
- Analyzed Files: 3
- Detection Method: Serena semantic code analysis
- Commit: 0dffa81
- Analysis Date: 2025-11-15T21:06:44Z
AI generated by Duplicate Code Detector
Analysis of commit 0dffa81
Assignee:
@copilotSummary
The engine-specific
ParseLogMetricsimplementations all repeat the same block that finalizes tool call metrics (appending the last sequence, copying the tool call map into a slice, sorting it, and counting errors). Copilot, Codex, and Claude pipelines each copy this logic verbatim with only variable name changes.Duplication Details
Pattern: Repeated tool call finalization logic in log parsers
pkg/workflow/copilot_engine.go:492pkg/workflow/codex_engine.go:407pkg/workflow/claude_logs.go:340Impact Analysis
Refactoring Recommendations
Extract shared helper
finalizeToolMetrics(metrics *LogMetrics, toolCallMap map[string]*ToolCallInfo, currentSequence []string, turns int, tokenUsage int, logContent string, getPatterns func() []ErrorPattern).pkg/workflow/log_parser.goand accept function pointers for engine-specific hooks.Standardize sequence tracking
Implementation Checklist
Analysis Metadata