Skip to content

Commit d9ee22e

Browse files
Copilotpelikhan
andauthored
fix: isolate copilot_sdk_driver test session state writes to prevent false-positive tool-denial issues
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
1 parent a1bd2e4 commit d9ee22e

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

actions/setup/js/copilot_sdk_driver.test.cjs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
import { describe, it, expect, vi } from "vitest";
1+
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
22
import { createRequire } from "module";
3+
import * as fs from "fs";
4+
import * as os from "os";
5+
import * as path from "path";
36

47
const require = createRequire(import.meta.url);
58
const { runWithCopilotSDK, parsePermissionConfigFromServerArgs } = require("./copilot_sdk_driver.cjs");
69

710
describe("copilot_sdk_driver.cjs", () => {
11+
let testSessionStateDir;
12+
beforeAll(() => {
13+
testSessionStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "gh-aw-test-session-state-"));
14+
process.env.GH_AW_SESSION_STATE_BASE_DIR = testSessionStateDir;
15+
});
16+
afterAll(() => {
17+
delete process.env.GH_AW_SESSION_STATE_BASE_DIR;
18+
fs.rmSync(testSessionStateDir, { recursive: true, force: true });
19+
});
20+
821
describe("runWithCopilotSDK", () => {
922
it("disconnects session and stops client on success", async () => {
1023
const disconnect = vi.fn().mockResolvedValue(undefined);

actions/setup/js/copilot_sdk_session.cjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ function extractPromptFromArgs(args) {
8282
* RuntimeConnection: typeof import("@github/copilot-sdk").RuntimeConnection,
8383
* approveAll: typeof import("@github/copilot-sdk").approveAll
8484
* },
85+
* sessionStateBaseDir?: string,
8586
* }} options
8687
* @returns {Promise<{exitCode: number, output: string, hasOutput: boolean, durationMs: number}>}
8788
*/
88-
async function runWithCopilotSDK({ sdkUri, prompt, logger, attempt = 0, model, connectionToken, provider, maxToolDenials, permissionConfig, coreLogger, sdkModule }) {
89+
async function runWithCopilotSDK({ sdkUri, prompt, logger, attempt = 0, model, connectionToken, provider, maxToolDenials, permissionConfig, coreLogger, sdkModule, sessionStateBaseDir }) {
8990
// Lazy-require to avoid loading the SDK when it is not needed.
9091
// The SDK is large and has side-effects on import (worker threads, etc.).
9192
const { CopilotClient, RuntimeConnection, approveAll } = sdkModule ?? require("@github/copilot-sdk");
@@ -106,7 +107,9 @@ async function runWithCopilotSDK({ sdkUri, prompt, logger, attempt = 0, model, c
106107

107108
// Session state directory — mirrors the target path used by unified_timeline.cjs.
108109
// /tmp/gh-aw/sandbox/agent/logs/copilot-session-state/{sessionId}/events.jsonl
109-
const sessionStateBase = path.join(os.tmpdir(), "gh-aw", "sandbox", "agent", "logs", "copilot-session-state");
110+
// GH_AW_SESSION_STATE_BASE_DIR may be set in tests to redirect writes to an isolated directory.
111+
const defaultSessionStateBase = path.join(os.tmpdir(), "gh-aw", "sandbox", "agent", "logs", "copilot-session-state");
112+
const sessionStateBase = sessionStateBaseDir ?? process.env.GH_AW_SESSION_STATE_BASE_DIR ?? defaultSessionStateBase;
110113

111114
/** @type {ReadonlyArray<NonNullable<import("@github/copilot-sdk").CopilotClientOptions["logLevel"]>>} */
112115
const VALID_LOG_LEVELS = ["none", "error", "warning", "info", "debug", "all"];

0 commit comments

Comments
 (0)