Python SDK for GitHub Copilot CLI
Project description
Copilot Python SDK
Python SDK for programmatic control of GitHub Copilot CLI via JSON-RPC.
Note: This SDK is in technical preview and may change in breaking ways.
Installation
pip install -e .
Quick Start
import asyncio
from copilot import CopilotClient
async def main():
# Create and start client
client = CopilotClient()
await client.start()
# Create a session
session = await client.create_session({"model": "gpt-5"})
# Wait for response using session.idle event
done = asyncio.Event()
def on_event(event):
if event.type.value == "assistant.message":
print(event.data.content)
elif event.type.value == "session.idle":
done.set()
session.on(on_event)
# Send a message and wait for completion
await session.send({"prompt": "What is 2+2?"})
await done.wait()
# Clean up
await session.destroy()
await client.stop()
asyncio.run(main())
Features
- ✅ Full JSON-RPC protocol support
- ✅ stdio and TCP transports
- ✅ Real-time streaming events
- ✅ Session history with
get_messages() - ✅ Type hints throughout
- ✅ Async/await native
API Reference
CopilotClient
client = CopilotClient({
"cli_path": "copilot", # Optional: path to CLI executable
"cli_url": None, # Optional: URL of existing server (e.g., "localhost:8080")
"log_level": "info", # Optional: log level (default: "info")
"auto_start": True, # Optional: auto-start server (default: True)
"auto_restart": True, # Optional: auto-restart on crash (default: True)
})
await client.start()
session = await client.create_session({"model": "gpt-5"})
def on_event(event):
print(f"Event: {event['type']}")
session.on(on_event)
await session.send({"prompt": "Hello!"})
# ... wait for events ...
await session.destroy()
await client.stop()
CopilotClient Options:
cli_path(str): Path to CLI executable (default: "copilot" orCOPILOT_CLI_PATHenv var)cli_url(str): URL of existing CLI server (e.g.,"localhost:8080","http://127.0.0.1:9000", or just"8080"). When provided, the client will not spawn a CLI process.cwd(str): Working directory for CLI processport(int): Server port for TCP mode (default: 0 for random)use_stdio(bool): Use stdio transport instead of TCP (default: True)log_level(str): Log level (default: "info")auto_start(bool): Auto-start server on first use (default: True)auto_restart(bool): Auto-restart on crash (default: True)
Tools
Define tools with automatic JSON schema generation using the @define_tool decorator and Pydantic models:
from pydantic import BaseModel, Field
from copilot import CopilotClient, define_tool
class LookupIssueParams(BaseModel):
id: str = Field(description="Issue identifier")
@define_tool(description="Fetch issue details from our tracker")
async def lookup_issue(params: LookupIssueParams) -> str:
issue = await fetch_issue(params.id)
return issue.summary
session = await client.create_session({
"model": "gpt-5",
"tools": [lookup_issue],
})
Note: When using
from __future__ import annotations, define Pydantic models at module level (not inside functions).
Low-level API (without Pydantic):
For users who prefer manual schema definition:
from copilot import CopilotClient, Tool
async def lookup_issue(invocation):
issue_id = invocation["arguments"]["id"]
issue = await fetch_issue(issue_id)
return {
"textResultForLlm": issue.summary,
"resultType": "success",
"sessionLog": f"Fetched issue {issue_id}",
}
session = await client.create_session({
"model": "gpt-5",
"tools": [
Tool(
name="lookup_issue",
description="Fetch issue details from our tracker",
parameters={
"type": "object",
"properties": {
"id": {"type": "string", "description": "Issue identifier"},
},
"required": ["id"],
},
handler=lookup_issue,
)
],
})
The SDK automatically handles tool.call, executes your handler (sync or async), and responds with the final result when the tool completes.
Streaming
Enable streaming to receive assistant response chunks as they're generated:
import asyncio
from copilot import CopilotClient
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({
"model": "gpt-5",
"streaming": True
})
# Use asyncio.Event to wait for completion
done = asyncio.Event()
def on_event(event):
if event.type.value == "assistant.message_delta":
# Streaming message chunk - print incrementally
delta = event.data.delta_content or ""
print(delta, end="", flush=True)
elif event.type.value == "assistant.reasoning_delta":
# Streaming reasoning chunk (if model supports reasoning)
delta = event.data.delta_content or ""
print(delta, end="", flush=True)
elif event.type.value == "assistant.message":
# Final message - complete content
print("\n--- Final message ---")
print(event.data.content)
elif event.type.value == "assistant.reasoning":
# Final reasoning content (if model supports reasoning)
print("--- Reasoning ---")
print(event.data.content)
elif event.type.value == "session.idle":
# Session finished processing
done.set()
session.on(on_event)
await session.send({"prompt": "Tell me a short story"})
await done.wait() # Wait for streaming to complete
await session.destroy()
await client.stop()
asyncio.run(main())
When streaming=True:
assistant.message_deltaevents are sent withdelta_contentcontaining incremental textassistant.reasoning_deltaevents are sent withdelta_contentfor reasoning/chain-of-thought (model-dependent)- Accumulate
delta_contentvalues to build the full response progressively - The final
assistant.messageandassistant.reasoningevents contain the complete content
Note: assistant.message and assistant.reasoning (final events) are always sent regardless of streaming setting.
Requirements
- Python 3.8+
- GitHub Copilot CLI installed and accessible
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file github_copilot_sdk-0.1.15rc0.tar.gz.
File metadata
- Download URL: github_copilot_sdk-0.1.15rc0.tar.gz
- Upload date:
- Size: 87.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
759fe9b1593f36d98fddfb74a1fd86d94a1bcfb7bfc209cdbe75c4745cc29f42
|
|
| MD5 |
c93a71db0d37c701bf834d21d60b193c
|
|
| BLAKE2b-256 |
2e9ad086324ff8b6776df2dc59eb7acf310c5e8f3ae1c02ae819a029bdf24586
|
Provenance
The following attestation bundles were made for github_copilot_sdk-0.1.15rc0.tar.gz:
Publisher:
publish.yml on github/copilot-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
github_copilot_sdk-0.1.15rc0.tar.gz -
Subject digest:
759fe9b1593f36d98fddfb74a1fd86d94a1bcfb7bfc209cdbe75c4745cc29f42 - Sigstore transparency entry: 836507617
- Sigstore integration time:
-
Permalink:
github/copilot-sdk@51f1933a01bcfdf0382d17a3593e5c82315c7145 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/github
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@51f1933a01bcfdf0382d17a3593e5c82315c7145 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file github_copilot_sdk-0.1.15rc0-py3-none-any.whl.
File metadata
- Download URL: github_copilot_sdk-0.1.15rc0-py3-none-any.whl
- Upload date:
- Size: 30.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b188d3143557177bff64412a1caca82c7a541227c6c1da5665c098af8ebb480
|
|
| MD5 |
5404b3b233506823c0eff05c38ed5e20
|
|
| BLAKE2b-256 |
d06b705bc2977947ab3bed55e19eb8d0b29f1ed97cf6bf80fa68b5ebf6bd1507
|
Provenance
The following attestation bundles were made for github_copilot_sdk-0.1.15rc0-py3-none-any.whl:
Publisher:
publish.yml on github/copilot-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
github_copilot_sdk-0.1.15rc0-py3-none-any.whl -
Subject digest:
7b188d3143557177bff64412a1caca82c7a541227c6c1da5665c098af8ebb480 - Sigstore transparency entry: 836507621
- Sigstore integration time:
-
Permalink:
github/copilot-sdk@51f1933a01bcfdf0382d17a3593e5c82315c7145 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/github
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@51f1933a01bcfdf0382d17a3593e5c82315c7145 -
Trigger Event:
workflow_dispatch
-
Statement type: