From 8ddf00c224ac40c12b2e72d289f8895d53913fe2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:11:23 +0000 Subject: [PATCH 1/5] Initial plan From 12eb056f7ed6fcefd05fb0cd8847c7b5db9892a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:38:02 +0000 Subject: [PATCH 2/5] Fix daily issues report Copilot SDK driver runtime Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/daily-issues-report.lock.yml | 14 +++++++------- .github/workflows/daily-issues-report.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index 68f4940638b..d5fb7f83680 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9ee41e0c27e71c78baa29bde731bb2c6cf6cbd8a6fc19e88d4f1ca23240b719a","body_hash":"8065600d5985942c6244ea718124624fa2bb26f83e9512ff8295e3f81027dbd8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71","copilot-sdk":"1.0.7"},"agent_image_runner":"aw-gpu-runner-T4"} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"908c64e076a3e8949823514beffb10a4883914f3058d262e3f9d18850fa171b5","body_hash":"8065600d5985942c6244ea718124624fa2bb26f83e9512ff8295e3f81027dbd8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.71","copilot-sdk":"1.0.7"},"agent_image_runner":"aw-gpu-runner-T4"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/setup-python","sha":"ece7cb06caefa5fff74198d8649806c4678c61a1","version":"v6.3.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37","digest":"sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37","digest":"sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37","digest":"sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37","digest":"sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -773,8 +773,8 @@ jobs: GH_HOST: github.com - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.37 --rootless - - name: Install GitHub Copilot SDK (Python) - run: cd "${GITHUB_WORKSPACE}" && python3 -m pip install --disable-pip-version-check github-copilot-sdk==1.0.7 + - name: Install GitHub Copilot SDK (Node.js) + run: cd "${GITHUB_WORKSPACE}" && npm install --ignore-scripts --no-save @github/copilot-sdk@1.0.7 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -1115,7 +1115,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_WORKSPACE_NODE_MODULES="${GITHUB_WORKSPACE:-$PWD}/node_modules"; if [ -d "$GH_AW_WORKSPACE_NODE_MODULES" ]; then export NODE_PATH="${GH_AW_WORKSPACE_NODE_MODULES}${NODE_PATH:+:${NODE_PATH}}"; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs python3 "${GITHUB_WORKSPACE}/.github/drivers/copilot_sdk_driver_sample_python.py" /usr/local/bin/copilot' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_WORKSPACE_NODE_MODULES="${GITHUB_WORKSPACE:-$PWD}/node_modules"; if [ -d "$GH_AW_WORKSPACE_NODE_MODULES" ]; then export NODE_PATH="${GH_AW_WORKSPACE_NODE_MODULES}${NODE_PATH:+:${NODE_PATH}}"; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs "$GH_AW_NODE_EXEC" "${GITHUB_WORKSPACE}/.github/drivers/copilot_sdk_driver_sample_node.cjs" /usr/local/bin/copilot' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -1956,8 +1956,8 @@ jobs: GH_HOST: github.com - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.37 - - name: Install GitHub Copilot SDK (Python) - run: cd "${GITHUB_WORKSPACE}" && python3 -m pip install --disable-pip-version-check github-copilot-sdk==1.0.7 + - name: Install GitHub Copilot SDK (Node.js) + run: cd "${GITHUB_WORKSPACE}" && npm install --ignore-scripts --no-save @github/copilot-sdk@1.0.7 - name: Execute GitHub Copilot CLI if: always() continue-on-error: true @@ -1998,7 +1998,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_WORKSPACE_NODE_MODULES="${GITHUB_WORKSPACE:-$PWD}/node_modules"; if [ -d "$GH_AW_WORKSPACE_NODE_MODULES" ]; then export NODE_PATH="${GH_AW_WORKSPACE_NODE_MODULES}${NODE_PATH:+:${NODE_PATH}}"; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs python3 "${GITHUB_WORKSPACE}/.github/drivers/copilot_sdk_driver_sample_python.py" /usr/local/bin/copilot' 2>&1 | tee -a /tmp/gh-aw/evals/evals.log + -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_WORKSPACE_NODE_MODULES="${GITHUB_WORKSPACE:-$PWD}/node_modules"; if [ -d "$GH_AW_WORKSPACE_NODE_MODULES" ]; then export NODE_PATH="${GH_AW_WORKSPACE_NODE_MODULES}${NODE_PATH:+:${NODE_PATH}}"; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs "$GH_AW_NODE_EXEC" "${GITHUB_WORKSPACE}/.github/drivers/copilot_sdk_driver_sample_node.cjs" /usr/local/bin/copilot' 2>&1 | tee -a /tmp/gh-aw/evals/evals.log env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE diff --git a/.github/workflows/daily-issues-report.md b/.github/workflows/daily-issues-report.md index 2d168381fd5..ac0f2b4e0bb 100644 --- a/.github/workflows/daily-issues-report.md +++ b/.github/workflows/daily-issues-report.md @@ -13,7 +13,7 @@ permissions: engine: id: copilot copilot-sdk: true - driver: .github/drivers/copilot_sdk_driver_sample_python.py + driver: .github/drivers/copilot_sdk_driver_sample_node.cjs runs-on: aw-gpu-runner-T4 strict: true tracker-id: daily-issues-report From 876ccdf2dffc6c6eb2fc4bfb24e020248c929097 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 18:56:41 +0000 Subject: [PATCH 3/5] fix compiler/runtime python copilot sdk packaging for copilot-sdk drivers Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/copilot_engine_execution.go | 17 +++++++ pkg/workflow/copilot_engine_installation.go | 3 +- pkg/workflow/copilot_engine_test.go | 50 +++++++++++++++++++-- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/pkg/workflow/copilot_engine_execution.go b/pkg/workflow/copilot_engine_execution.go index 83dac99da39..4f8b36bfa30 100644 --- a/pkg/workflow/copilot_engine_execution.go +++ b/pkg/workflow/copilot_engine_execution.go @@ -115,6 +115,7 @@ const nodePathSetupCommand = `GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null | const nodeRuntimeResolutionCommand = `GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; ` + nodePathSetupCommand + `; "$GH_AW_NODE_EXEC"` const nodePathSetupCommandForCopilotSDK = `GH_AW_WORKSPACE_NODE_MODULES="${GITHUB_WORKSPACE:-$PWD}/node_modules"; if [ -d "$GH_AW_WORKSPACE_NODE_MODULES" ]; then export NODE_PATH="${GH_AW_WORKSPACE_NODE_MODULES}${NODE_PATH:+:${NODE_PATH}}"; fi; ` + nodePathSetupCommand const nodeRuntimeResolutionCommandForCopilotSDK = `GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; ` + nodePathSetupCommandForCopilotSDK + `; "$GH_AW_NODE_EXEC"` +const copilotSDKPythonPathExpression = "${{ github.workspace }}/.gh-aw/copilot-sdk/python" // copilotSDKDriverExecArgs returns the runtime command and driver path argument for the // given SDK driver filename. @@ -146,6 +147,17 @@ func copilotSDKDriverExecArgs(driverName string) (runtimeCmd, driverArg string) } } +func copilotSDKRuntimeID(workflowData *WorkflowData) string { + if workflowData == nil || workflowData.EngineConfig == nil { + return "node" + } + command := workflowData.EngineConfig.Command + if command == "" && workflowData.EngineConfig.Driver != "" { + command = sdkDriverInstallCommand(workflowData.EngineConfig.Driver) + } + return detectRuntimeFromCopilotCommand(command) +} + // GetExecutionSteps returns the GitHub Actions steps for executing GitHub Copilot CLI func (e *CopilotEngine) GetExecutionSteps(workflowData *WorkflowData, logFile string) []GitHubActionStep { copilotExecLog.Printf("Generating execution steps for Copilot: workflow=%s, firewall=%v", workflowData.Name, isFirewallEnabled(workflowData)) @@ -630,6 +642,11 @@ func (e *CopilotEngine) addCopilotSDKStepEnv(env map[string]string, workflowData env[constants.CopilotSDKDriverEnvVar] = "1" env[constants.CopilotSDKServerArgsEnvVar] = copilotSDKServerArgsJSON copilotExecLog.Printf("copilot-sdk driver mode: set %s and %s", constants.CopilotSDKDriverEnvVar, constants.CopilotSDKServerArgsEnvVar) + if copilotSDKRuntimeID(workflowData) == "python" { + if _, exists := env["PYTHONPATH"]; !exists { + env["PYTHONPATH"] = copilotSDKPythonPathExpression + } + } } func (e *CopilotEngine) buildCopilotExecutionStep(workflowData *WorkflowData, command string, env map[string]string, timeoutValue string) GitHubActionStep { diff --git a/pkg/workflow/copilot_engine_installation.go b/pkg/workflow/copilot_engine_installation.go index 5760eb5c6bf..e0b5d7ccf83 100644 --- a/pkg/workflow/copilot_engine_installation.go +++ b/pkg/workflow/copilot_engine_installation.go @@ -33,6 +33,7 @@ type copilotSDKInstallSpec struct { } const workspaceCommandPrefix = `cd "${GITHUB_WORKSPACE}" && ` +const copilotSDKPythonTargetDir = `"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python"` // getWorkspaceCommandPrefixFor returns the shell cd prefix for engine command generation. // When engine.cwd is configured it returns a prefix that changes to ${GH_AW_ENGINE_CWD} @@ -203,7 +204,7 @@ func getCopilotSDKInstallSpec(command string) copilotSDKInstallSpec { switch runtimeID { case "python": spec.stepName = "Install GitHub Copilot SDK (Python)" - spec.command = workspaceCommandPrefix + "python3 -m pip install --disable-pip-version-check github-copilot-sdk==" + version + spec.command = workspaceCommandPrefix + "mkdir -p " + copilotSDKPythonTargetDir + " && python3 -m pip install --disable-pip-version-check --target " + copilotSDKPythonTargetDir + " github-copilot-sdk==" + version case "typescript": spec.stepName = "Install GitHub Copilot SDK (TypeScript)" spec.command = workspaceCommandPrefix + "npm install --ignore-scripts --no-save @github/copilot-sdk@" + version + " ts-node typescript" diff --git a/pkg/workflow/copilot_engine_test.go b/pkg/workflow/copilot_engine_test.go index 06feb003b98..96460a3a801 100644 --- a/pkg/workflow/copilot_engine_test.go +++ b/pkg/workflow/copilot_engine_test.go @@ -2191,7 +2191,7 @@ func TestCopilotEngineInstallationWithCommandAndCopilotSDK(t *testing.T) { name: "python command uses pip sdk install", command: "python3 main.py", expectedName: "name: Install GitHub Copilot SDK (Python)", - expectedRun: "python3 -m pip install --disable-pip-version-check github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), + expectedRun: "python3 -m pip install --disable-pip-version-check --target \"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python\" github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), expectedSteps: 1, }, { @@ -2240,14 +2240,14 @@ func TestCopilotEngineInstallationWithCommandAndCopilotSDK(t *testing.T) { name: "env wrapper command is detected", command: "env FOO=bar python script.py", expectedName: "name: Install GitHub Copilot SDK (Python)", - expectedRun: "python3 -m pip install --disable-pip-version-check github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), + expectedRun: "python3 -m pip install --disable-pip-version-check --target \"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python\" github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), expectedSteps: 1, }, { name: "custom command with firewall keeps awf and sdk installs", command: "python script.py", expectedName: "name: Install GitHub Copilot SDK (Python)", - expectedRun: "python3 -m pip install --disable-pip-version-check github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), + expectedRun: "python3 -m pip install --disable-pip-version-check --target \"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python\" github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), withFirewall: true, expectedSteps: 2, }, @@ -2311,7 +2311,7 @@ func TestCopilotEngineInstallationWithCopilotSDKDriver(t *testing.T) { name: "python driver uses pip sdk install", driver: "my_driver.py", expectedName: "name: Install GitHub Copilot SDK (Python)", - expectedRun: "python3 -m pip install --disable-pip-version-check github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), + expectedRun: "python3 -m pip install --disable-pip-version-check --target \"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python\" github-copilot-sdk==" + string(constants.DefaultCopilotSDKVersion), }, { name: "typescript driver installs ts-node toolchain and sdk", @@ -2358,6 +2358,48 @@ func TestCopilotEngineInstallationWithCopilotSDKDriver(t *testing.T) { } } +func TestCopilotEngineCopilotSDKPythonDriverSetsPythonPath(t *testing.T) { + engine := NewCopilotEngine() + + t.Run("python driver sets PYTHONPATH", func(t *testing.T) { + workflowData := &WorkflowData{ + EngineConfig: &EngineConfig{ + CopilotSDK: true, + Driver: ".github/drivers/copilot_sdk_driver_sample_python.py", + }, + } + + steps := engine.GetExecutionSteps(workflowData, "/tmp/gh-aw/test.log") + if len(steps) != 1 { + t.Fatalf("Expected 1 execution step, got %d", len(steps)) + } + + stepContent := strings.Join(steps[0], "\n") + if !strings.Contains(stepContent, "PYTHONPATH: ${{ github.workspace }}/.gh-aw/copilot-sdk/python") { + t.Fatalf("Expected PYTHONPATH to include python Copilot SDK target path, got:\n%s", stepContent) + } + }) + + t.Run("node driver does not set PYTHONPATH", func(t *testing.T) { + workflowData := &WorkflowData{ + EngineConfig: &EngineConfig{ + CopilotSDK: true, + Driver: ".github/drivers/copilot_sdk_driver_sample_node.cjs", + }, + } + + steps := engine.GetExecutionSteps(workflowData, "/tmp/gh-aw/test.log") + if len(steps) != 1 { + t.Fatalf("Expected 1 execution step, got %d", len(steps)) + } + + stepContent := strings.Join(steps[0], "\n") + if strings.Contains(stepContent, "PYTHONPATH: ${{ github.workspace }}/.gh-aw/copilot-sdk/python") { + t.Fatalf("Did not expect PYTHONPATH override for node driver, got:\n%s", stepContent) + } + }) +} + // TestGenerateCopilotSessionFileCopyStep verifies the generated step copies session state files. func TestGenerateCopilotSessionFileCopyStep(t *testing.T) { step := generateCopilotSessionFileCopyStep() From ee58922caecaf6b442193ef4364cfea7cfbf2ad6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:07:12 +0000 Subject: [PATCH 4/5] refactor python copilot sdk install command generation and env guard Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/copilot_engine_execution.go | 25 +++++++++++++++------ pkg/workflow/copilot_engine_installation.go | 9 ++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/pkg/workflow/copilot_engine_execution.go b/pkg/workflow/copilot_engine_execution.go index 4f8b36bfa30..f761c34e05c 100644 --- a/pkg/workflow/copilot_engine_execution.go +++ b/pkg/workflow/copilot_engine_execution.go @@ -147,15 +147,28 @@ func copilotSDKDriverExecArgs(driverName string) (runtimeCmd, driverArg string) } } +// copilotSDKRuntimeID returns the runtime ID used by Copilot SDK driver execution. +// It returns one of: python, typescript, ruby, or node (default/fallback). +// engine.command takes precedence; otherwise runtime is inferred from engine.driver extension. func copilotSDKRuntimeID(workflowData *WorkflowData) string { if workflowData == nil || workflowData.EngineConfig == nil { return "node" } command := workflowData.EngineConfig.Command - if command == "" && workflowData.EngineConfig.Driver != "" { - command = sdkDriverInstallCommand(workflowData.EngineConfig.Driver) + if command != "" { + return detectRuntimeFromCopilotCommand(command) + } + ext := strings.ToLower(filepath.Ext(workflowData.EngineConfig.Driver)) + switch ext { + case ".py": + return "python" + case ".ts", ".mts": + return "typescript" + case ".rb": + return "ruby" + default: + return "node" } - return detectRuntimeFromCopilotCommand(command) } // GetExecutionSteps returns the GitHub Actions steps for executing GitHub Copilot CLI @@ -642,10 +655,8 @@ func (e *CopilotEngine) addCopilotSDKStepEnv(env map[string]string, workflowData env[constants.CopilotSDKDriverEnvVar] = "1" env[constants.CopilotSDKServerArgsEnvVar] = copilotSDKServerArgsJSON copilotExecLog.Printf("copilot-sdk driver mode: set %s and %s", constants.CopilotSDKDriverEnvVar, constants.CopilotSDKServerArgsEnvVar) - if copilotSDKRuntimeID(workflowData) == "python" { - if _, exists := env["PYTHONPATH"]; !exists { - env["PYTHONPATH"] = copilotSDKPythonPathExpression - } + if currentPythonPath, exists := env["PYTHONPATH"]; copilotSDKRuntimeID(workflowData) == "python" && (!exists || currentPythonPath == "") { + env["PYTHONPATH"] = copilotSDKPythonPathExpression } } diff --git a/pkg/workflow/copilot_engine_installation.go b/pkg/workflow/copilot_engine_installation.go index e0b5d7ccf83..8d8e98f5c97 100644 --- a/pkg/workflow/copilot_engine_installation.go +++ b/pkg/workflow/copilot_engine_installation.go @@ -17,6 +17,7 @@ package workflow import ( + "fmt" "path/filepath" "strings" @@ -33,7 +34,7 @@ type copilotSDKInstallSpec struct { } const workspaceCommandPrefix = `cd "${GITHUB_WORKSPACE}" && ` -const copilotSDKPythonTargetDir = `"${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python"` +const copilotSDKPythonTargetDir = `${GITHUB_WORKSPACE}/.gh-aw/copilot-sdk/python` // getWorkspaceCommandPrefixFor returns the shell cd prefix for engine command generation. // When engine.cwd is configured it returns a prefix that changes to ${GH_AW_ENGINE_CWD} @@ -204,7 +205,11 @@ func getCopilotSDKInstallSpec(command string) copilotSDKInstallSpec { switch runtimeID { case "python": spec.stepName = "Install GitHub Copilot SDK (Python)" - spec.command = workspaceCommandPrefix + "mkdir -p " + copilotSDKPythonTargetDir + " && python3 -m pip install --disable-pip-version-check --target " + copilotSDKPythonTargetDir + " github-copilot-sdk==" + version + spec.command = workspaceCommandPrefix + fmt.Sprintf( + `mkdir -p "%[1]s" && python3 -m pip install --disable-pip-version-check --target "%[1]s" github-copilot-sdk==%[2]s`, + copilotSDKPythonTargetDir, + version, + ) case "typescript": spec.stepName = "Install GitHub Copilot SDK (TypeScript)" spec.command = workspaceCommandPrefix + "npm install --ignore-scripts --no-save @github/copilot-sdk@" + version + " ts-node typescript" From a74c9d6159e0b3c82f7b8896b3e6416e90ac8c33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Jul 2026 03:56:12 +0000 Subject: [PATCH 5/5] Recompile after merging main Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../workflows/smoke-call-workflow.lock.yml | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index 15a3ed21b8c..eacad788ec7 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -619,6 +619,11 @@ jobs: "inputSchema": { "additionalProperties": false, "properties": { + "aw_context": { + "default": "", + "description": "Agent caller context (used internally by Agentic Workflows).", + "type": "string" + }, "payload": { "description": "Input parameter 'payload' for workflow smoke-workflow-call", "type": "string" @@ -1104,15 +1109,25 @@ jobs: needs: safe_outputs if: needs.safe_outputs.outputs.call_workflow_name == 'smoke-workflow-call' # Imported from called workflow "smoke-workflow-call" because GitHub requires the caller job to grant permissions requested by reusable workflow jobs. - # Review the called workflow's frontmatter permissions in ./.github/workflows/smoke-workflow-call.md. + # Review the called workflow's job-level permissions in ./.github/workflows/smoke-workflow-call.lock.yml. permissions: + actions: read contents: read - pull-requests: read + issues: write + pull-requests: write uses: ./.github/workflows/smoke-workflow-call.lock.yml with: + aw_context: ${{ fromJSON(needs.safe_outputs.outputs.call_workflow_payload).aw_context }} payload: ${{ needs.safe_outputs.outputs.call_workflow_payload }} task-description: ${{ fromJSON(needs.safe_outputs.outputs.call_workflow_payload)['task-description'] }} - secrets: inherit + secrets: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} + GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} + GH_AW_OTEL_GRAFANA_AUTHORIZATION: ${{ secrets.GH_AW_OTEL_GRAFANA_AUTHORIZATION }} + GH_AW_OTEL_GRAFANA_ENDPOINT: ${{ secrets.GH_AW_OTEL_GRAFANA_ENDPOINT }} + GH_AW_OTEL_SENTRY_AUTHORIZATION: ${{ secrets.GH_AW_OTEL_SENTRY_AUTHORIZATION }} + GH_AW_OTEL_SENTRY_ENDPOINT: ${{ secrets.GH_AW_OTEL_SENTRY_ENDPOINT }} conclusion: needs: