Skip to content

Commit f4b44e9

Browse files
Add debug logging to engine implementations and safe-outputs features (#3723)
1 parent c7daf1d commit f4b44e9

5 files changed

Lines changed: 66 additions & 0 deletions

File tree

pkg/workflow/codex_engine.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import (
99
"time"
1010

1111
"github.com/githubnext/gh-aw/pkg/constants"
12+
"github.com/githubnext/gh-aw/pkg/logger"
1213
)
1314

15+
var codexEngineLog = logger.New("workflow:codex_engine")
16+
1417
// Pre-compiled regexes for Codex log parsing (performance optimization)
1518
var (
1619
codexToolCallOldFormat = regexp.MustCompile(`\] tool ([^(]+)\(`)
@@ -43,6 +46,7 @@ func NewCodexEngine() *CodexEngine {
4346
}
4447

4548
func (e *CodexEngine) GetInstallationSteps(workflowData *WorkflowData) []GitHubActionStep {
49+
codexEngineLog.Printf("Generating installation steps for Codex engine: workflow=%s", workflowData.Name)
4650
var steps []GitHubActionStep
4751

4852
// Add secret validation step - Codex supports both CODEX_API_KEY and OPENAI_API_KEY as fallback
@@ -76,6 +80,13 @@ func (e *CodexEngine) GetDeclaredOutputFiles() []string {
7680

7781
// GetExecutionSteps returns the GitHub Actions steps for executing Codex
7882
func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile string) []GitHubActionStep {
83+
model := ""
84+
if workflowData.EngineConfig != nil && workflowData.EngineConfig.Model != "" {
85+
model = workflowData.EngineConfig.Model
86+
}
87+
codexEngineLog.Printf("Building Codex execution steps: workflow=%s, model=%s, has_agent_file=%v",
88+
workflowData.Name, model, workflowData.AgentFile != "")
89+
7990
// Handle custom steps if they exist in engine config
8091
steps := InjectCustomEngineSteps(workflowData, e.convertStepToYAML)
8192

@@ -269,6 +280,10 @@ func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools
269280
}
270281

271282
func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) {
283+
if codexEngineLog.Enabled() {
284+
codexEngineLog.Printf("Rendering MCP config for Codex: mcp_tools=%v, tool_count=%d", mcpTools, len(tools))
285+
}
286+
272287
yaml.WriteString(" cat > /tmp/gh-aw/mcp-config/config.toml << EOF\n")
273288

274289
// Add history configuration to disable persistence
@@ -325,6 +340,8 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an
325340

326341
// ParseLogMetrics implements engine-specific log parsing for Codex
327342
func (e *CodexEngine) ParseLogMetrics(logContent string, verbose bool) LogMetrics {
343+
codexEngineLog.Printf("Parsing Codex log metrics: log_size=%d bytes, lines=%d", len(logContent), len(strings.Split(logContent, "\n")))
344+
328345
var metrics LogMetrics
329346
var totalTokenUsage int
330347

@@ -395,6 +412,9 @@ func (e *CodexEngine) ParseLogMetrics(logContent string, verbose bool) LogMetric
395412
metrics.Errors = CountErrorsAndWarningsWithPatterns(logContent, errorPatterns)
396413
}
397414

415+
codexEngineLog.Printf("Parsed Codex metrics: turns=%d, token_usage=%d, tool_calls=%d, errors=%d",
416+
metrics.Turns, metrics.TokenUsage, len(metrics.ToolCalls), len(metrics.Errors))
417+
398418
return metrics
399419
}
400420

pkg/workflow/create_agent_task.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ package workflow
22

33
import (
44
"fmt"
5+
6+
"github.com/githubnext/gh-aw/pkg/logger"
57
)
68

9+
var createAgentTaskLog = logger.New("workflow:create_agent_task")
10+
711
// CreateAgentTaskConfig holds configuration for creating GitHub Copilot agent tasks from agent output
812
type CreateAgentTaskConfig struct {
913
BaseSafeOutputConfig `yaml:",inline"`
@@ -14,6 +18,7 @@ type CreateAgentTaskConfig struct {
1418
// parseAgentTaskConfig handles create-agent-task configuration
1519
func (c *Compiler) parseAgentTaskConfig(outputMap map[string]any) *CreateAgentTaskConfig {
1620
if configData, exists := outputMap["create-agent-task"]; exists {
21+
createAgentTaskLog.Print("Parsing create-agent-task configuration")
1722
agentTaskConfig := &CreateAgentTaskConfig{}
1823
agentTaskConfig.Max = 1 // Default max is 1
1924

@@ -49,6 +54,9 @@ func (c *Compiler) buildCreateOutputAgentTaskJob(data *WorkflowData, mainJobName
4954
return nil, fmt.Errorf("safe-outputs.create-agent-task configuration is required")
5055
}
5156

57+
createAgentTaskLog.Printf("Building create-agent-task job: workflow=%s, main_job=%s, base=%s",
58+
data.Name, mainJobName, data.SafeOutputs.CreateAgentTasks.Base)
59+
5260
var steps []string
5361

5462
// Step 1: Checkout repository for gh CLI to work

pkg/workflow/create_issue.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ package workflow
33
import (
44
"fmt"
55
"strings"
6+
7+
"github.com/githubnext/gh-aw/pkg/logger"
68
)
79

10+
var createIssueLog = logger.New("workflow:create_issue")
11+
812
// CreateIssuesConfig holds configuration for creating GitHub issues from agent output
913
type CreateIssuesConfig struct {
1014
BaseSafeOutputConfig `yaml:",inline"`
@@ -17,6 +21,7 @@ type CreateIssuesConfig struct {
1721
// parseIssuesConfig handles create-issue configuration
1822
func (c *Compiler) parseIssuesConfig(outputMap map[string]any) *CreateIssuesConfig {
1923
if configData, exists := outputMap["create-issue"]; exists {
24+
createIssueLog.Print("Parsing create-issue configuration")
2025
issuesConfig := &CreateIssuesConfig{}
2126
issuesConfig.Max = 1 // Default max is 1
2227

@@ -68,6 +73,11 @@ func (c *Compiler) buildCreateOutputIssueJob(data *WorkflowData, mainJobName str
6873
return nil, fmt.Errorf("safe-outputs.create-issue configuration is required")
6974
}
7075

76+
if createIssueLog.Enabled() {
77+
createIssueLog.Printf("Building create-issue job: workflow=%s, main_job=%s, assignees=%d, labels=%d",
78+
data.Name, mainJobName, len(data.SafeOutputs.CreateIssues.Assignees), len(data.SafeOutputs.CreateIssues.Labels))
79+
}
80+
7181
// Build custom environment variables specific to create-issue
7282
var customEnvVars []string
7383

pkg/workflow/create_pull_request.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import (
55
"strings"
66

77
"github.com/githubnext/gh-aw/pkg/constants"
8+
"github.com/githubnext/gh-aw/pkg/logger"
89
)
910

11+
var createPRLog = logger.New("workflow:create_pull_request")
12+
1013
// CreatePullRequestsConfig holds configuration for creating GitHub pull requests from agent output
1114
type CreatePullRequestsConfig struct {
1215
BaseSafeOutputConfig `yaml:",inline"`
@@ -24,6 +27,15 @@ func (c *Compiler) buildCreateOutputPullRequestJob(data *WorkflowData, mainJobNa
2427
return nil, fmt.Errorf("safe-outputs.create-pull-request configuration is required")
2528
}
2629

30+
if createPRLog.Enabled() {
31+
draftValue := true // Default
32+
if data.SafeOutputs.CreatePullRequests.Draft != nil {
33+
draftValue = *data.SafeOutputs.CreatePullRequests.Draft
34+
}
35+
createPRLog.Printf("Building create-pull-request job: workflow=%s, main_job=%s, draft=%v, reviewers=%d",
36+
data.Name, mainJobName, draftValue, len(data.SafeOutputs.CreatePullRequests.Reviewers))
37+
}
38+
2739
// Build pre-steps for patch download, checkout, and git config
2840
var preSteps []string
2941

@@ -133,9 +145,11 @@ func (c *Compiler) buildCreateOutputPullRequestJob(data *WorkflowData, mainJobNa
133145
func (c *Compiler) parsePullRequestsConfig(outputMap map[string]any) *CreatePullRequestsConfig {
134146
// Check for singular form only
135147
if _, exists := outputMap["create-pull-request"]; !exists {
148+
createPRLog.Print("No create-pull-request configuration found")
136149
return nil
137150
}
138151

152+
createPRLog.Print("Parsing create-pull-request configuration")
139153
configData := outputMap["create-pull-request"]
140154
pullRequestsConfig := &CreatePullRequestsConfig{}
141155
pullRequestsConfig.Max = 1 // Always max 1 for pull requests

pkg/workflow/custom_engine.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ package workflow
33
import (
44
"fmt"
55
"strings"
6+
7+
"github.com/githubnext/gh-aw/pkg/logger"
68
)
79

10+
var customEngineLog = logger.New("workflow:custom_engine")
11+
812
// CustomEngine represents a custom agentic engine that executes user-defined GitHub Actions steps
913
type CustomEngine struct {
1014
BaseEngine
@@ -34,6 +38,12 @@ func (e *CustomEngine) GetInstallationSteps(workflowData *WorkflowData) []GitHub
3438

3539
// GetExecutionSteps returns the GitHub Actions steps for executing custom steps
3640
func (e *CustomEngine) GetExecutionSteps(workflowData *WorkflowData, logFile string) []GitHubActionStep {
41+
stepCount := 0
42+
if workflowData.EngineConfig != nil {
43+
stepCount = len(workflowData.EngineConfig.Steps)
44+
}
45+
customEngineLog.Printf("Building custom engine execution steps: workflow=%s, custom_steps=%d", workflowData.Name, stepCount)
46+
3747
var steps []GitHubActionStep
3848

3949
// Generate each custom step if they exist, with environment variables
@@ -219,6 +229,7 @@ func (e *CustomEngine) renderAgenticWorkflowsMCPConfig(yaml *strings.Builder, is
219229
// ParseLogMetrics implements basic log parsing for custom engine
220230
// For custom engines, try both Claude and Codex parsing approaches to extract turn information
221231
func (e *CustomEngine) ParseLogMetrics(logContent string, verbose bool) LogMetrics {
232+
customEngineLog.Printf("Parsing custom engine log metrics: log_size=%d bytes", len(logContent))
222233
var metrics LogMetrics
223234

224235
// First try Claude-style parsing to see if the logs are Claude-format
@@ -228,6 +239,7 @@ func (e *CustomEngine) ParseLogMetrics(logContent string, verbose bool) LogMetri
228239
claudeMetrics := claudeEngine.ParseLogMetrics(logContent, verbose)
229240
if claudeMetrics.Turns > 0 || claudeMetrics.TokenUsage > 0 || claudeMetrics.EstimatedCost > 0 {
230241
// Found structured data, use Claude parsing
242+
customEngineLog.Print("Using Claude-style parsing for custom engine logs")
231243
if verbose {
232244
fmt.Println("Custom engine: Using Claude-style parsing for logs")
233245
}
@@ -241,6 +253,7 @@ func (e *CustomEngine) ParseLogMetrics(logContent string, verbose bool) LogMetri
241253
codexMetrics := codexEngine.ParseLogMetrics(logContent, verbose)
242254
if codexMetrics.Turns > 0 || codexMetrics.TokenUsage > 0 {
243255
// Found some data, use Codex parsing
256+
customEngineLog.Print("Using Codex-style parsing for custom engine logs")
244257
if verbose {
245258
fmt.Println("Custom engine: Using Codex-style parsing for logs")
246259
}
@@ -249,6 +262,7 @@ func (e *CustomEngine) ParseLogMetrics(logContent string, verbose bool) LogMetri
249262
}
250263

251264
// Fall back to basic parsing if neither Claude nor Codex approaches work
265+
customEngineLog.Print("Using basic fallback parsing for custom engine logs")
252266
if verbose {
253267
fmt.Println("Custom engine: Using basic fallback parsing for logs")
254268
}

0 commit comments

Comments
 (0)