Fix Copilot SDK Python examples for current API (#2781)

* fix copilot sdk python examples

Update Python snippets for the released keyword-only SDK API, bundled runtime, and deterministic lifecycle cleanup.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* fix sdk runtime prerequisites

Limit the standalone Copilot CLI requirement to Go and align each language runtime version with the v1.0.11 package guides.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Chris Arendt <charendt@Chriss-MBP.home>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Chris Arendt
2026-08-25 06:31:12 +02:00
committed by GitHub
parent 54aac3e53f
commit c5c7219378
+69 -78
View File
@@ -13,10 +13,11 @@ The GitHub Copilot SDK exposes the same engine behind Copilot CLI: a production-
## Prerequisites ## Prerequisites
1. **GitHub Copilot CLI** installed and authenticated ([Installation guide](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli)) 1. **GitHub Copilot access** and an authenticated environment
2. **Language runtime**: Node.js 18+, Python 3.8+, Go 1.21+, or .NET 8.0+ 2. **Language runtime**: Node.js ^20.19.0 or >=22.12.0, Python 3.11+, Go 1.24+, or a .NET Standard 2.0-compatible implementation
3. **Go**: GitHub Copilot CLI installed and authenticated ([Installation guide](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli))
Verify CLI: `copilot --version` The TypeScript, Python, and .NET packages use a bundled Copilot runtime by default, so they do not need a separate CLI installation.
## Installation ## Installation
@@ -30,8 +31,13 @@ npm install @github/copilot-sdk tsx
### Python ### Python
```bash ```bash
pip install github-copilot-sdk pip install github-copilot-sdk
# Optional: pre-download the bundled runtime instead of downloading it on first use
python -m copilot download-runtime
``` ```
Published Python wheels include a pinned runtime version. The pre-download command caches that runtime locally; if skipped, the SDK attempts to download it automatically on first use.
### Go ### Go
```bash ```bash
mkdir copilot-demo && cd copilot-demo mkdir copilot-demo && cd copilot-demo
@@ -72,17 +78,13 @@ import asyncio
from copilot import CopilotClient, PermissionHandler from copilot import CopilotClient, PermissionHandler
async def main(): async def main():
client = CopilotClient() async with CopilotClient() as client:
await client.start() async with await client.create_session(
on_permission_request=PermissionHandler.approve_all,
session = await client.create_session({ model="gpt-4.1",
"on_permission_request": PermissionHandler.approve_all, ) as session:
"model": "gpt-4.1", response = await session.send_and_wait("What is 2 + 2?")
})
response = await session.send_and_wait({"prompt": "What is 2 + 2?"})
print(response.data.content) print(response.data.content)
await client.stop()
asyncio.run(main()) asyncio.run(main())
``` ```
@@ -178,15 +180,12 @@ from copilot import CopilotClient, PermissionHandler
from copilot.generated.session_events import SessionEventType from copilot.generated.session_events import SessionEventType
async def main(): async def main():
client = CopilotClient() async with CopilotClient() as client:
await client.start() async with await client.create_session(
on_permission_request=PermissionHandler.approve_all,
session = await client.create_session({ model="gpt-4.1",
"on_permission_request": PermissionHandler.approve_all, streaming=True,
"model": "gpt-4.1", ) as session:
"streaming": True,
})
def handle_event(event): def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content) sys.stdout.write(event.data.delta_content)
@@ -195,8 +194,7 @@ async def main():
print() print()
session.on(handle_event) session.on(handle_event)
await session.send_and_wait({"prompt": "Tell me a short joke"}) await session.send_and_wait("Tell me a short joke")
await client.stop()
asyncio.run(main()) asyncio.run(main())
``` ```
@@ -315,28 +313,22 @@ async def get_weather(params: GetWeatherParams) -> dict:
return {"city": city, "temperature": f"{temp}°F", "condition": condition} return {"city": city, "temperature": f"{temp}°F", "condition": condition}
async def main(): async def main():
client = CopilotClient() async with CopilotClient() as client:
await client.start() async with await client.create_session(
on_permission_request=PermissionHandler.approve_all,
session = await client.create_session({ model="gpt-4.1",
"on_permission_request": PermissionHandler.approve_all, streaming=True,
"model": "gpt-4.1", tools=[get_weather],
"streaming": True, ) as session:
"tools": [get_weather],
})
def handle_event(event): def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content) sys.stdout.write(event.data.delta_content)
sys.stdout.flush() sys.stdout.flush()
session.on(handle_event) session.on(handle_event)
await session.send_and_wait(
await session.send_and_wait({ "What's the weather like in Seattle and Tokyo?"
"prompt": "What's the weather like in Seattle and Tokyo?" )
})
await client.stop()
asyncio.run(main()) asyncio.run(main())
``` ```
@@ -500,16 +492,13 @@ async def get_weather(params: GetWeatherParams) -> dict:
return {"city": params.city, "temperature": f"{temp}°F", "condition": condition} return {"city": params.city, "temperature": f"{temp}°F", "condition": condition}
async def main(): async def main():
client = CopilotClient() async with CopilotClient() as client:
await client.start() async with await client.create_session(
on_permission_request=PermissionHandler.approve_all,
session = await client.create_session({ model="gpt-4.1",
"on_permission_request": PermissionHandler.approve_all, streaming=True,
"model": "gpt-4.1", tools=[get_weather],
"streaming": True, ) as session:
"tools": [get_weather],
})
def handle_event(event): def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA: if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content) sys.stdout.write(event.data.delta_content)
@@ -530,11 +519,9 @@ async def main():
break break
sys.stdout.write("Assistant: ") sys.stdout.write("Assistant: ")
await session.send_and_wait({"prompt": user_input}) await session.send_and_wait(user_input)
print("\n") print("\n")
await client.stop()
asyncio.run(main()) asyncio.run(main())
``` ```
@@ -558,16 +545,17 @@ const session = await client.createSession({
### Python ### Python
```python ```python
session = await client.create_session({ async with await client.create_session(
"on_permission_request": PermissionHandler.approve_all, on_permission_request=PermissionHandler.approve_all,
"model": "gpt-4.1", model="gpt-4.1",
"mcp_servers": { mcp_servers={
"github": { "github": {
"type": "http", "type": "http",
"url": "https://api.githubcopilot.com/mcp/", "url": "https://api.githubcopilot.com/mcp/",
}, },
}, },
}) ) as session:
...
``` ```
### Go ### Go
@@ -621,16 +609,17 @@ const session = await client.createSession({
### Python ### Python
```python ```python
session = await client.create_session({ async with await client.create_session(
"on_permission_request": PermissionHandler.approve_all, on_permission_request=PermissionHandler.approve_all,
"model": "gpt-4.1", model="gpt-4.1",
"custom_agents": [{ custom_agents=[{
"name": "pr-reviewer", "name": "pr-reviewer",
"display_name": "PR Reviewer", "display_name": "PR Reviewer",
"description": "Reviews pull requests for best practices", "description": "Reviews pull requests for best practices",
"prompt": "You are an expert code reviewer. Focus on security, performance, and maintainability.", "prompt": "You are an expert code reviewer. Focus on security, performance, and maintainability.",
}], }],
}) ) as session:
...
``` ```
## System Message ## System Message
@@ -650,13 +639,14 @@ const session = await client.createSession({
### Python ### Python
```python ```python
session = await client.create_session({ async with await client.create_session(
"on_permission_request": PermissionHandler.approve_all, on_permission_request=PermissionHandler.approve_all,
"model": "gpt-4.1", model="gpt-4.1",
"system_message": { system_message={
"content": "You are a helpful assistant for our engineering team. Always be concise.", "content": "You are a helpful assistant for our engineering team. Always be concise.",
}, },
}) ) as session:
...
``` ```
## External CLI Server ## External CLI Server
@@ -684,15 +674,16 @@ const session = await client.createSession({
#### Python #### Python
```python ```python
client = CopilotClient({ from copilot import CopilotClient, PermissionHandler, RuntimeConnection
"cli_url": "localhost:4321"
})
await client.start()
session = await client.create_session({ async with CopilotClient(
"on_permission_request": PermissionHandler.approve_all, connection=RuntimeConnection.for_uri("localhost:4321")
"model": "gpt-4.1", ) as client:
}) async with await client.create_session(
on_permission_request=PermissionHandler.approve_all,
model="gpt-4.1",
) as session:
...
``` ```
#### Go #### Go
@@ -725,7 +716,7 @@ await using var session = await client.CreateSessionAsync(new SessionConfig
}); });
``` ```
**Note:** When `cliUrl` is provided, the SDK will not spawn or manage a CLI process - it only connects to the existing server. **Note:** When configured to use an external server, the SDK manages only its connection and does not manage the external process.
## Event Types ## Event Types
@@ -879,7 +870,7 @@ const models = await client.getModels();
## Best Practices ## Best Practices
1. **Always cleanup**: Use `try-finally` or `defer` to ensure `client.stop()` is called 1. **Always clean up**: Use language-native context managers or disposal, or explicitly disconnect sessions and stop clients
2. **Set timeouts**: Use `sendAndWait` with timeout for long operations 2. **Set timeouts**: Use `sendAndWait` with timeout for long operations
3. **Handle events**: Subscribe to error events for robust error handling 3. **Handle events**: Subscribe to error events for robust error handling
4. **Use streaming**: Enable streaming for better UX on long responses 4. **Use streaming**: Enable streaming for better UX on long responses