From d82938b0acf6b79dea5499219ff31aca23d118cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:19:10 +0000 Subject: [PATCH 1/6] Initial plan From 0323020b8d4989bc52aee0e613579737ac3c4580 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:32:39 +0000 Subject: [PATCH 2/6] fix(codex): inject openai-proxy provider for api-proxy workflows Agent-Logs-Url: https://github.com/github/gh-aw/sessions/4da02a94-208f-4f00-9af7-b9b116a2ce1a Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- pkg/workflow/codex_engine_test.go | 50 +++++++++++++++++++++++++++++++ pkg/workflow/codex_mcp.go | 20 +++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index d939a76db6..66ad807764 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -310,6 +310,56 @@ func TestCodexEngineRenderMCPConfig(t *testing.T) { } } +func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { + engine := NewCodexEngine() + tools := map[string]any{"github": map[string]any{}} + mcpTools := []string{"github"} + + t.Run("injects openai-proxy provider when firewall is enabled", func(t *testing.T) { + var yaml strings.Builder + workflowData := &WorkflowData{ + Name: "test-workflow", + NetworkPermissions: &NetworkPermissions{ + Firewall: &FirewallConfig{Enabled: true}, + }, + } + + if err := engine.RenderMCPConfig(&yaml, tools, mcpTools, workflowData); err != nil { + t.Fatalf("RenderMCPConfig returned unexpected error: %v", err) + } + + result := yaml.String() + expectedLines := []string{ + "model_provider = \"openai-proxy\"", + "[model_providers.openai-proxy]", + "name = \"OpenAI AWF proxy\"", + "base_url = \"http://172.30.0.30:10000\"", + "env_key = \"OPENAI_API_KEY\"", + "supports_websockets = false", + } + + for _, expected := range expectedLines { + if !strings.Contains(result, expected) { + t.Errorf("Expected MCP config to contain %q, got:\n%s", expected, result) + } + } + }) + + t.Run("does not inject openai-proxy provider when firewall is disabled", func(t *testing.T) { + var yaml strings.Builder + workflowData := &WorkflowData{Name: "test-workflow"} + + if err := engine.RenderMCPConfig(&yaml, tools, mcpTools, workflowData); err != nil { + t.Fatalf("RenderMCPConfig returned unexpected error: %v", err) + } + + result := yaml.String() + if strings.Contains(result, "model_provider = \"openai-proxy\"") { + t.Errorf("Did not expect openai-proxy provider when firewall is disabled, got:\n%s", result) + } + }) +} + func TestCodexEngineExecutionAddsMountedMCPCLIPathSetup(t *testing.T) { engine := NewCodexEngine() workflowData := &WorkflowData{ diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 939006c6e3..16a076346a 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -9,6 +9,12 @@ import ( var codexMCPLog = logger.New("workflow:codex_mcp") +const ( + codexOpenAIProxyProviderID = "openai-proxy" + codexOpenAIProxyProviderName = "OpenAI AWF proxy" + codexOpenAIProxyProviderBaseURL = "http://172.30.0.30:10000" +) + // RenderMCPConfig generates MCP server configuration for Codex func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) error { if codexMCPLog.Enabled() { @@ -118,6 +124,9 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an shellPolicyDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_SHELL_POLICY", workflowData.FrontmatterHash) yaml.WriteString(" cat > \"/tmp/gh-aw/mcp-config/config.toml\" << " + shellPolicyDelimiter + "\n") e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") + if isFirewallEnabled(workflowData) { + e.renderOpenAIProxyProviderToml(yaml, " ") + } yaml.WriteString(" " + shellPolicyDelimiter + "\n") yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") if workflowData.EngineConfig != nil && strings.TrimSpace(workflowData.EngineConfig.Config) != "" { @@ -139,6 +148,17 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an return nil } +func (e *CodexEngine) renderOpenAIProxyProviderToml(yaml *strings.Builder, indent string) { + yaml.WriteString(indent + "\n") + yaml.WriteString(indent + "model_provider = \"" + codexOpenAIProxyProviderID + "\"\n") + yaml.WriteString(indent + "\n") + yaml.WriteString(indent + "[model_providers." + codexOpenAIProxyProviderID + "]\n") + yaml.WriteString(indent + "name = \"" + codexOpenAIProxyProviderName + "\"\n") + yaml.WriteString(indent + "base_url = \"" + codexOpenAIProxyProviderBaseURL + "\"\n") + yaml.WriteString(indent + "env_key = \"OPENAI_API_KEY\"\n") + yaml.WriteString(indent + "supports_websockets = false\n") +} + // renderCodexMCPConfigWithContext generates custom MCP server configuration for a single tool in codex workflow config.toml // This version includes workflowData to determine if localhost URLs should be rewritten func (e *CodexEngine) renderCodexMCPConfigWithContext(yaml *strings.Builder, toolName string, toolConfig map[string]any, workflowData *WorkflowData) error { From fa325a1a6e27f72a7304dc5cab9dc4b58483cb01 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:38:02 +0000 Subject: [PATCH 3/6] test: clarify codex openai-proxy provider injection coverage Agent-Logs-Url: https://github.com/github/gh-aw/sessions/4da02a94-208f-4f00-9af7-b9b116a2ce1a Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- pkg/workflow/codex_engine_test.go | 4 ++-- pkg/workflow/codex_mcp.go | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index 66ad807764..97f0182a7e 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -312,8 +312,8 @@ func TestCodexEngineRenderMCPConfig(t *testing.T) { func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { engine := NewCodexEngine() - tools := map[string]any{"github": map[string]any{}} - mcpTools := []string{"github"} + tools := map[string]any{} + mcpTools := []string{} t.Run("injects openai-proxy provider when firewall is enabled", func(t *testing.T) { var yaml strings.Builder diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 16a076346a..6e5580cc8f 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -10,8 +10,9 @@ import ( var codexMCPLog = logger.New("workflow:codex_mcp") const ( - codexOpenAIProxyProviderID = "openai-proxy" - codexOpenAIProxyProviderName = "OpenAI AWF proxy" + codexOpenAIProxyProviderID = "openai-proxy" + codexOpenAIProxyProviderName = "OpenAI AWF proxy" + // AWF's api-proxy sidecar is exposed inside the sandbox network at 172.30.0.30:10000 for OpenAI traffic. codexOpenAIProxyProviderBaseURL = "http://172.30.0.30:10000" ) From 4e82cf1681c0c227868cac421bb3d482768de3e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:53:12 +0000 Subject: [PATCH 4/6] chore: plan reviewer feedback fixes Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2499e570-be86-46ba-9447-652d4cf60c84 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 8 ++++++++ .github/workflows/changeset.lock.yml | 8 ++++++++ .github/workflows/codex-github-remote-mcp-test.lock.yml | 8 ++++++++ .github/workflows/daily-fact.lock.yml | 8 ++++++++ .github/workflows/daily-observability-report.lock.yml | 8 ++++++++ .github/workflows/duplicate-code-detector.lock.yml | 8 ++++++++ .github/workflows/grumpy-reviewer.lock.yml | 8 ++++++++ .github/workflows/issue-arborist.lock.yml | 8 ++++++++ .github/workflows/schema-feature-coverage.lock.yml | 8 ++++++++ .github/workflows/smoke-call-workflow.lock.yml | 8 ++++++++ .github/workflows/smoke-codex.lock.yml | 8 ++++++++ 11 files changed, 88 insertions(+) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index 2038ca3af9..82a3ae5474 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -749,6 +749,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_41a4d5c2d909bed6_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index bf28ff0201..c38d390195 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -768,6 +768,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_20aa83733790ce7c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/codex-github-remote-mcp-test.lock.yml b/.github/workflows/codex-github-remote-mcp-test.lock.yml index c883bf38fc..3d15ae34a1 100644 --- a/.github/workflows/codex-github-remote-mcp-test.lock.yml +++ b/.github/workflows/codex-github-remote-mcp-test.lock.yml @@ -443,6 +443,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GITHUB_PERSONAL_ACCESS_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_6ef9da006a49787c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 205736923e..7557ec734b 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -871,6 +871,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_252c56bd99e6f878_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index c55c79a382..a713c11553 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -799,6 +799,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_08284ac4f16ebe02_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 5ca433ba62..29e4466986 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -773,6 +773,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_5f2b419d8d1a0762_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index c748bbcf79..c9fa1c0e7b 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -796,6 +796,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_fd0494d129bb4dc0_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 2424608485..13ada317b2 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -806,6 +806,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_8df1e17e12a5553f_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/schema-feature-coverage.lock.yml b/.github/workflows/schema-feature-coverage.lock.yml index ef1b83b105..4c96b16c12 100644 --- a/.github/workflows/schema-feature-coverage.lock.yml +++ b/.github/workflows/schema-feature-coverage.lock.yml @@ -698,6 +698,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_12a1c9e5a4cc208c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index e653ad3238..0b419668b6 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -709,6 +709,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_2d745eed178272e7_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 1bab938487..cfc8101b09 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1217,6 +1217,14 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + + model_provider = "openai-proxy" + + [model_providers.openai-proxy] + name = "OpenAI AWF proxy" + base_url = "http://172.30.0.30:10000" + env_key = "OPENAI_API_KEY" + supports_websockets = false GH_AW_CODEX_SHELL_POLICY_71ae115a66db43bd_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" From c794dd1c196cb65321ccb73127a81f47bc70b477 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 00:06:18 +0000 Subject: [PATCH 5/6] fix(codex): address reviewer feedback on proxy config merge safety Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2499e570-be86-46ba-9447-652d4cf60c84 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 8 ----- .github/workflows/changeset.lock.yml | 8 ----- .../codex-github-remote-mcp-test.lock.yml | 8 ----- .github/workflows/daily-fact.lock.yml | 8 ----- .../daily-observability-report.lock.yml | 8 ----- .../duplicate-code-detector.lock.yml | 8 ----- .github/workflows/grumpy-reviewer.lock.yml | 8 ----- .github/workflows/issue-arborist.lock.yml | 8 ----- .../schema-feature-coverage.lock.yml | 8 ----- .../workflows/smoke-call-workflow.lock.yml | 8 ----- .github/workflows/smoke-codex.lock.yml | 8 ----- pkg/constants/constants.go | 3 ++ pkg/workflow/codex_engine_test.go | 14 +++++++-- pkg/workflow/codex_mcp.go | 31 +++++++++++++++---- 14 files changed, 39 insertions(+), 97 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index 82a3ae5474..2038ca3af9 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -749,14 +749,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_41a4d5c2d909bed6_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index c38d390195..bf28ff0201 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -768,14 +768,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_20aa83733790ce7c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/codex-github-remote-mcp-test.lock.yml b/.github/workflows/codex-github-remote-mcp-test.lock.yml index 3d15ae34a1..c883bf38fc 100644 --- a/.github/workflows/codex-github-remote-mcp-test.lock.yml +++ b/.github/workflows/codex-github-remote-mcp-test.lock.yml @@ -443,14 +443,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GITHUB_PERSONAL_ACCESS_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_6ef9da006a49787c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 7557ec734b..205736923e 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -871,14 +871,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_252c56bd99e6f878_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index a713c11553..c55c79a382 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -799,14 +799,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_08284ac4f16ebe02_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 29e4466986..5ca433ba62 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -773,14 +773,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_5f2b419d8d1a0762_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index c9fa1c0e7b..c748bbcf79 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -796,14 +796,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_fd0494d129bb4dc0_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 13ada317b2..2424608485 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -806,14 +806,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_8df1e17e12a5553f_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/schema-feature-coverage.lock.yml b/.github/workflows/schema-feature-coverage.lock.yml index 4c96b16c12..ef1b83b105 100644 --- a/.github/workflows/schema-feature-coverage.lock.yml +++ b/.github/workflows/schema-feature-coverage.lock.yml @@ -698,14 +698,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_12a1c9e5a4cc208c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index 0b419668b6..e653ad3238 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -709,14 +709,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_2d745eed178272e7_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index cfc8101b09..1bab938487 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1217,14 +1217,6 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] - - model_provider = "openai-proxy" - - [model_providers.openai-proxy] - name = "OpenAI AWF proxy" - base_url = "http://172.30.0.30:10000" - env_key = "OPENAI_API_KEY" - supports_websockets = false GH_AW_CODEX_SHELL_POLICY_71ae115a66db43bd_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 0645ae01ec..56e7d3b60d 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -74,6 +74,9 @@ const ExpressionBreakThreshold LineLength = 100 // for MCP servers, gateway services, and validation ranges. const ( + // AWFAPIProxyContainerIP is the fixed api-proxy sidecar address inside the AWF sandbox network. + AWFAPIProxyContainerIP = "172.30.0.30" + // DefaultMCPGatewayPort is the default port for the MCP gateway HTTP service DefaultMCPGatewayPort = 8080 diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index 97f0182a7e..eeda7e1914 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -312,10 +312,10 @@ func TestCodexEngineRenderMCPConfig(t *testing.T) { func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { engine := NewCodexEngine() - tools := map[string]any{} - mcpTools := []string{} t.Run("injects openai-proxy provider when firewall is enabled", func(t *testing.T) { + tools := map[string]any{} + mcpTools := []string{} var yaml strings.Builder workflowData := &WorkflowData{ Name: "test-workflow", @@ -333,7 +333,7 @@ func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { "model_provider = \"openai-proxy\"", "[model_providers.openai-proxy]", "name = \"OpenAI AWF proxy\"", - "base_url = \"http://172.30.0.30:10000\"", + fmt.Sprintf("base_url = \"http://%s:%d\"", constants.AWFAPIProxyContainerIP, constants.ClaudeLLMGatewayPort), "env_key = \"OPENAI_API_KEY\"", "supports_websockets = false", } @@ -343,9 +343,14 @@ func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { t.Errorf("Expected MCP config to contain %q, got:\n%s", expected, result) } } + if !strings.Contains(result, "awk '") { + t.Errorf("Expected firewall-enabled config append to use awk filtering, got:\n%s", result) + } }) t.Run("does not inject openai-proxy provider when firewall is disabled", func(t *testing.T) { + tools := map[string]any{} + mcpTools := []string{} var yaml strings.Builder workflowData := &WorkflowData{Name: "test-workflow"} @@ -357,6 +362,9 @@ func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { if strings.Contains(result, "model_provider = \"openai-proxy\"") { t.Errorf("Did not expect openai-proxy provider when firewall is disabled, got:\n%s", result) } + if strings.Contains(result, "awk '") { + t.Errorf("Did not expect awk filtering when firewall is disabled, got:\n%s", result) + } }) } diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 6e5580cc8f..896ea3a4c0 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -2,8 +2,11 @@ package workflow import ( "fmt" + "net" + "strconv" "strings" + "github.com/github/gh-aw/pkg/constants" "github.com/github/gh-aw/pkg/logger" ) @@ -12,8 +15,6 @@ var codexMCPLog = logger.New("workflow:codex_mcp") const ( codexOpenAIProxyProviderID = "openai-proxy" codexOpenAIProxyProviderName = "OpenAI AWF proxy" - // AWF's api-proxy sidecar is exposed inside the sandbox network at 172.30.0.30:10000 for OpenAI traffic. - codexOpenAIProxyProviderBaseURL = "http://172.30.0.30:10000" ) // RenderMCPConfig generates MCP server configuration for Codex @@ -129,7 +130,11 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an e.renderOpenAIProxyProviderToml(yaml, " ") } yaml.WriteString(" " + shellPolicyDelimiter + "\n") - yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") + if isFirewallEnabled(workflowData) { + e.renderAppendConvertedConfigWithoutOpenAIProxy(yaml) + } else { + yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") + } if workflowData.EngineConfig != nil && strings.TrimSpace(workflowData.EngineConfig.Config) != "" { customConfigDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_CUSTOM_CONFIG", workflowData.FrontmatterHash) yaml.WriteString(" \n") @@ -150,16 +155,30 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an } func (e *CodexEngine) renderOpenAIProxyProviderToml(yaml *strings.Builder, indent string) { - yaml.WriteString(indent + "\n") + yaml.WriteString("\n") yaml.WriteString(indent + "model_provider = \"" + codexOpenAIProxyProviderID + "\"\n") - yaml.WriteString(indent + "\n") + yaml.WriteString("\n") yaml.WriteString(indent + "[model_providers." + codexOpenAIProxyProviderID + "]\n") yaml.WriteString(indent + "name = \"" + codexOpenAIProxyProviderName + "\"\n") - yaml.WriteString(indent + "base_url = \"" + codexOpenAIProxyProviderBaseURL + "\"\n") + yaml.WriteString(indent + "base_url = \"" + e.getOpenAIProxyProviderBaseURL() + "\"\n") yaml.WriteString(indent + "env_key = \"OPENAI_API_KEY\"\n") yaml.WriteString(indent + "supports_websockets = false\n") } +func (e *CodexEngine) getOpenAIProxyProviderBaseURL() string { + return "http://" + net.JoinHostPort(constants.AWFAPIProxyContainerIP, strconv.Itoa(constants.ClaudeLLMGatewayPort)) +} + +func (e *CodexEngine) renderAppendConvertedConfigWithoutOpenAIProxy(yaml *strings.Builder) { + yaml.WriteString(" awk '\n") + yaml.WriteString(" BEGIN { skip_openai_proxy = 0 }\n") + yaml.WriteString(" /^[[:space:]]*model_provider[[:space:]]*=/ { next }\n") + yaml.WriteString(" /^\\[model_providers\\.openai-proxy\\][[:space:]]*$/ { skip_openai_proxy = 1; next }\n") + yaml.WriteString(" /^\\[/ { skip_openai_proxy = 0 }\n") + yaml.WriteString(" !skip_openai_proxy { print }\n") + yaml.WriteString(" ' \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") +} + // renderCodexMCPConfigWithContext generates custom MCP server configuration for a single tool in codex workflow config.toml // This version includes workflowData to determine if localhost URLs should be rewritten func (e *CodexEngine) renderCodexMCPConfigWithContext(yaml *strings.Builder, toolName string, toolConfig map[string]any, workflowData *WorkflowData) error { From 79137c79dfd140157cae4366577d7ed3417eb119 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 00:07:15 +0000 Subject: [PATCH 6/6] test(codex): cover openai proxy base URL helper Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2499e570-be86-46ba-9447-652d4cf60c84 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- pkg/workflow/codex_engine_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index eeda7e1914..751695691e 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -368,6 +368,15 @@ func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { }) } +func TestCodexEngineOpenAIProxyProviderBaseURL(t *testing.T) { + engine := NewCodexEngine() + expected := fmt.Sprintf("http://%s:%d", constants.AWFAPIProxyContainerIP, constants.ClaudeLLMGatewayPort) + + if actual := engine.getOpenAIProxyProviderBaseURL(); actual != expected { + t.Errorf("Expected OpenAI proxy provider base URL %q, got %q", expected, actual) + } +} + func TestCodexEngineExecutionAddsMountedMCPCLIPathSetup(t *testing.T) { engine := NewCodexEngine() workflowData := &WorkflowData{