Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions python/copilot/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def __init__(self, options: Optional[CopilotClientOptions] = None):
if use_logged_in_user is None:
use_logged_in_user = False if github_token else True

self.options: CopilotClientOptions = {
self._options: CopilotClientOptions = {
"cli_path": default_cli_path,
"cwd": opts.get("cwd", os.getcwd()),
"port": opts.get("port", 0),
Expand All @@ -189,13 +189,13 @@ def __init__(self, options: Optional[CopilotClientOptions] = None):
"use_logged_in_user": use_logged_in_user,
}
if opts.get("cli_args"):
self.options["cli_args"] = opts["cli_args"]
self._options["cli_args"] = opts["cli_args"]
if opts.get("cli_url"):
self.options["cli_url"] = opts["cli_url"]
self._options["cli_url"] = opts["cli_url"]
if opts.get("env"):
self.options["env"] = opts["env"]
self._options["env"] = opts["env"]
if github_token:
self.options["github_token"] = github_token
self._options["github_token"] = github_token

self._process: Optional[subprocess.Popen] = None
self._client: Optional[JsonRpcClient] = None
Expand Down Expand Up @@ -448,7 +448,7 @@ async def create_session(self, config: SessionConfig) -> CopilotSession:
... })
"""
if not self._client:
if self.options["auto_start"]:
if self._options["auto_start"]:
await self.start()
else:
raise RuntimeError("Client not connected. Call start() first.")
Expand Down Expand Up @@ -620,7 +620,7 @@ async def resume_session(self, session_id: str, config: ResumeSessionConfig) ->
... })
"""
if not self._client:
if self.options["auto_start"]:
if self._options["auto_start"]:
await self.start()
else:
raise RuntimeError("Client not connected. Call start() first.")
Expand Down Expand Up @@ -1174,25 +1174,25 @@ async def _start_cli_server(self) -> None:
Raises:
RuntimeError: If the server fails to start or times out.
"""
cli_path = self.options["cli_path"]
cli_path = self._options["cli_path"]

# Verify CLI exists
if not os.path.exists(cli_path):
raise RuntimeError(f"Copilot CLI not found at {cli_path}")

# Start with user-provided cli_args, then add SDK-managed args
cli_args = self.options.get("cli_args") or []
cli_args = self._options.get("cli_args") or []
args = list(cli_args) + [
"--headless",
"--no-auto-update",
"--log-level",
self.options["log_level"],
self._options["log_level"],
]

# Add auth-related flags
if self.options.get("github_token"):
if self._options.get("github_token"):
args.extend(["--auth-token-env", "COPILOT_SDK_AUTH_TOKEN"])
if not self.options.get("use_logged_in_user", True):
if not self._options.get("use_logged_in_user", True):
args.append("--no-auto-login")

# If cli_path is a .js file, run it with node
Expand All @@ -1203,21 +1203,21 @@ async def _start_cli_server(self) -> None:
args = [cli_path] + args

# Get environment variables
env = self.options.get("env")
env = self._options.get("env")
if env is None:
env = dict(os.environ)
else:
env = dict(env)

# Set auth token in environment if provided
if self.options.get("github_token"):
env["COPILOT_SDK_AUTH_TOKEN"] = self.options["github_token"]
if self._options.get("github_token"):
env["COPILOT_SDK_AUTH_TOKEN"] = self._options["github_token"]

# On Windows, hide the console window to avoid distracting users in GUI apps
creationflags = subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0

# Choose transport mode
if self.options["use_stdio"]:
if self._options["use_stdio"]:
args.append("--stdio")
# Use regular Popen with pipes (buffering=0 for unbuffered)
self._process = subprocess.Popen(
Expand All @@ -1226,25 +1226,25 @@ async def _start_cli_server(self) -> None:
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
bufsize=0,
cwd=self.options["cwd"],
cwd=self._options["cwd"],
env=env,
creationflags=creationflags,
)
else:
if self.options["port"] > 0:
args.extend(["--port", str(self.options["port"])])
if self._options["port"] > 0:
args.extend(["--port", str(self._options["port"])])
self._process = subprocess.Popen(
args,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=self.options["cwd"],
cwd=self._options["cwd"],
env=env,
creationflags=creationflags,
)

# For stdio mode, we're ready immediately
if self.options["use_stdio"]:
if self._options["use_stdio"]:
return

# For TCP mode, wait for port announcement
Expand Down Expand Up @@ -1279,7 +1279,7 @@ async def _connect_to_server(self) -> None:
Raises:
RuntimeError: If the connection fails.
"""
if self.options["use_stdio"]:
if self._options["use_stdio"]:
await self._connect_via_stdio()
else:
await self._connect_via_tcp()
Expand Down
4 changes: 2 additions & 2 deletions python/copilot/generated/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,9 @@ def to_dict(self) -> dict:

class Mode(Enum):
"""The current agent mode.

The agent mode after switching.

The mode to switch to. Valid values: "interactive", "plan", "autopilot".
"""
AUTOPILOT = "autopilot"
Expand Down
12 changes: 6 additions & 6 deletions python/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def test_cli_url_with_cli_path(self):

def test_use_stdio_false_when_cli_url(self):
client = CopilotClient({"cli_url": "8080", "log_level": "error"})
assert not client.options["use_stdio"]
assert not client._options["use_stdio"]

def test_is_external_server_true(self):
client = CopilotClient({"cli_url": "localhost:8080", "log_level": "error"})
Expand All @@ -126,17 +126,17 @@ def test_accepts_github_token(self):
client = CopilotClient(
{"cli_path": CLI_PATH, "github_token": "gho_test_token", "log_level": "error"}
)
assert client.options.get("github_token") == "gho_test_token"
assert client._options.get("github_token") == "gho_test_token"

def test_default_use_logged_in_user_true_without_token(self):
client = CopilotClient({"cli_path": CLI_PATH, "log_level": "error"})
assert client.options.get("use_logged_in_user") is True
assert client._options.get("use_logged_in_user") is True

def test_default_use_logged_in_user_false_with_token(self):
client = CopilotClient(
{"cli_path": CLI_PATH, "github_token": "gho_test_token", "log_level": "error"}
)
assert client.options.get("use_logged_in_user") is False
assert client._options.get("use_logged_in_user") is False

def test_explicit_use_logged_in_user_true_with_token(self):
client = CopilotClient(
Expand All @@ -147,13 +147,13 @@ def test_explicit_use_logged_in_user_true_with_token(self):
"log_level": "error",
}
)
assert client.options.get("use_logged_in_user") is True
assert client._options.get("use_logged_in_user") is True

def test_explicit_use_logged_in_user_false_without_token(self):
client = CopilotClient(
{"cli_path": CLI_PATH, "use_logged_in_user": False, "log_level": "error"}
)
assert client.options.get("use_logged_in_user") is False
assert client._options.get("use_logged_in_user") is False

def test_github_token_with_cli_url_raises(self):
with pytest.raises(
Expand Down
Loading