先决条件
在创建云会话之前,请确保:
- 用户拥有 Copilot 访问权限,并享有云代理使用权益。
- 会话可以使用用户令牌,也可以使用已登录的 Copilot CLI 身份向 GitHub 进行身份验证。
- 可以将会话与GitHub存储库相关联。 这在 SDK 类型定义中是可选的,但建议提供,以便 Mission Control 和云代理能够获得仓库上下文。
- 组织策略允许从云图面进行远程控制和查看会话。
创建云会话
设置创建会话 cloud 选项以创建云会话。 可以包含存储库元数据,以便将云会话与GitHub存储库相关联。
TypeScript
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session = await client.createSession({
onPermissionRequest: async () => ({ kind: "approve-once" }),
cloud: {
repository: {
owner: "github",
name: "copilot-sdk",
branch: "main",
},
},
});
Python
from copilot import (
CloudSessionOptions,
CloudSessionRepository,
CopilotClient,
PermissionHandler,
)
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
cloud=CloudSessionOptions(
repository=CloudSessionRepository(
owner="github",
name="copilot-sdk",
branch="main",
)
),
)
Go
package main
import (
"context"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
_ = run(context.Background())
}
func run(ctx context.Context) error {
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
return err
}
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Cloud: &copilot.CloudSessionOptions{
Repository: &copilot.CloudSessionRepository{
Owner: "github",
Name: "copilot-sdk",
Branch: "main",
},
},
OnPermissionRequest: func(_ copilot.PermissionRequest, _ copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
_ = session
return err
}
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
return err
}
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Cloud: &copilot.CloudSessionOptions{
Repository: &copilot.CloudSessionRepository{
Owner: "github",
Name: "copilot-sdk",
Branch: "main",
},
},
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
_ = session
.NET
await using var client = new CopilotClient();
var session = await client.CreateSessionAsync(new SessionConfig
{
Cloud = new CloudSessionOptions
{
Repository = new CloudSessionRepository
{
Owner = "github",
Name = "copilot-sdk",
Branch = "main",
},
},
OnPermissionRequest = (req, inv) =>
Task.FromResult(PermissionDecision.ApproveOnce()),
});
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setCloud(new CloudSessionOptions()
.setRepository(new CloudSessionRepository()
.setOwner("github")
.setName("copilot-sdk")
.setBranch("main")))
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
}
Rust
use std::sync::Arc;
use github_copilot_sdk::{CloudSessionOptions, CloudSessionRepository, SessionConfig};
use github_copilot_sdk::handler::ApproveAllHandler;
let session = client.create_session(
SessionConfig::default()
.with_cloud(CloudSessionOptions::with_repository(
CloudSessionRepository::new("github", "copilot-sdk").with_branch("main"),
))
.with_permission_handler(Arc::new(ApproveAllHandler)),
).await?;
发送第一个提示词
云会话分两个阶段完成初始化:任务管控中心预留任务资源后,createSession 即完成解析,但远程 copilot-agent 工作进程还需耗时一两秒建立连接并发出 session.start。 若在此之前调用 session.send,运行时 RemoteSession.send 会抛出 "Remote session is still starting";不过架构封装层采用即发即弃机制,会静默捕获异常,同时仍向代码返回全新的 messageId 实例。 提示在服务器端被丢弃,永远不会到达工作进程。
为了确保可靠发送,请在发送前订阅事件,并等待第一个 producer 为 "copilot-agent" 的 session.start 事件:
import { CopilotClient, type CopilotSession } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session: CopilotSession = await client.createSession({
streaming: true, // required for assistant.message_delta to fire
cloud: { repository: { owner: "github", name: "copilot-sdk" } },
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
// Subscribe BEFORE sending so you don't miss the start event.
const ready = new Promise<void>((resolve) => {
const off = session.on("session.start", (event) => {
if (event.data?.producer === "copilot-agent") {
off();
resolve();
}
});
});
await ready;
await session.send({ prompt: "Summarize the README" });
一些说明:
- 在
createSession上设置streaming: true,从而使运行时发出assistant.message_delta事件。 如果没有它,你获得的唯一助手信号是最终assistant.message信号 -- 适合批量使用,但如果呈现实时 UI,聊天会呈现卡死状态。 请参阅“流式处理会话事件”。 - 仅首次
session.send调用会受此竞态问题影响。 在同一会话中的后续发送都会正常进行,因为运行时会使hasSessionStarted在整个会话期间保持已设置状态。 - 为
readyPromise 配置超时(例如 60 秒),防止任务管控中心资源配置卡死造成你的应用永久阻塞。 - 同一模式适用于每个 SDK 语言 - 订阅
session.start、检查producer === "copilot-agent"、然后调用send。
访问 Mission Control 的 URL
云会话天然是远程的:一旦工作器连接,Mission Control 就会在 https://github.com/copilot/tasks/{sessionId} 发布该会话,而运行时会发出一个 session.info 事件,并附带该 URL。
无需调用remote.enable() — 该 API 仅用于将本地会话提升到任务控制。
通过订阅 session.info 并按 infoType: "remote" 筛选来捕获 URL:
session.on("session.info", (event) => {
if (event.data?.infoType === "remote" && event.data.url) {
console.log("Open from web or mobile:", event.data.url);
// e.g. surface in your UI as a shareable link or QR code.
}
});
session.start 完成后很快就会触发该事件。 如果你的渲染组件在事件触发完成后才完成挂载,请将 URL 和会话记录一同保存在应用状态中,并在重新挂载时恢复数据——运行时不会自行重新发出 session.info。
有关通过 remote: true 提升的本地会话的相同连接逻辑,请参阅 远程会话。
存储库关联
cloud.repository 对象将云会话与GitHub存储库相关联:
| 领域 | 必选 | Description |
|---|---|---|
owner | 是的 | 存储库所有者或组织。 |
name | 是的 | 存储库名称。 |
branch | 否 | 要用于存储库上下文的分支。 省略它以允许运行时选择默认分支或当前存储库上下文。 |
存储库关联在 SDK 类型中是可选的,但只要应用知道目标存储库,就将其包含在内。 它有助于任务控制在正确的上下文中显示会话,并为云代理提供更清晰的起点。
当工作应从特定分支开始时使用 branch 。 如果你的应用依托拉取请求、工单分类流程或部署工作流创建会话,请传入和用户可见任务对应的分支。
恢复云会话
此选项 cloud 仅适用于创建新会话时。 若要恢复现有云会话,请使用 SDK 语言的标准恢复 API:
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session = await client.resumeSession("session-id", {
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
void session;
const session = await client.resumeSession("session-id", {
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
请勿在恢复时再次传递 cloud。 保存的会话元数据表明该会话由云端支持,并按正常的会话恢复流程进行恢复。
组织策略和权限
当用户或组织无权执行云代理或组织级策略阻止流时,云会话创建可能会失败。 具体而言,云沙盒的策略可以防止客户端创建云任务。
发生这种情况时,运行时会报告 "policy_blocked" 云任务创建失败原因。 将此视为授权或策略结果,而不是暂时性基础结构故障。
在 TypeScript 中,在重试之前检查原因:
import {
CopilotClient,
type CloudSessionRepository,
} from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const repository: CloudSessionRepository = {
owner: "github",
name: "copilot-sdk",
};
try {
await client.createSession({
cloud: { repository },
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
} catch (error) {
if ((error as { reason?: string }).reason === "policy_blocked") {
// Show an admin-facing message or link to org policy settings.
}
throw error;
}
try {
await client.createSession({ cloud: { repository } });
} catch (error) {
if ((error as { reason?: string }).reason === "policy_blocked") {
// Show an admin-facing message or link to org policy settings.
}
throw error;
}
在 SDK 错误以不同方式表示的语言中,检查显示的错误原因或代码并显式处理 "policy_blocked" 。 如果不进行策略更改,则重试不会成功。
集成 ID 和路由
云会话使用派生自 GITHUB_COPILOT_INTEGRATION_ID 环境变量的 Copilot-Integration-Id 标头进行标记。 此集成 ID 由任务控制用于路由、归因和集成专属行为。
有关多用户服务器指南和完整的集成 ID 详细信息,请参阅 多租户与服务器部署。
任务控制将 SDK 创建的云会话路由到 copilot-developer-sandbox 智能体数据域。 该名称是云端代理的内部路由标识,并不意味着该会话使用本地 Windows 沙盒环境。
高级:COPILOT_MC_BASE_URL
默认情况下,运行时会根据已配置的 Copilot API URL 推导出 Mission Control 的基础 URL。 仅当需要覆盖该任务控制终结点时才设置 COPILOT_MC_BASE_URL。
GitHub Enterprise Server 部署可能需要此操作。 在将其用于生产环境之前,请先与您的 GitHub 代表确认正确的值和支持状态。
COPILOT_MC_BASE_URL="https://example.com/agents"
云会话与远程会话
| Capability | 远程会话 | 云会话 |
|---|---|---|
| 执行位置 | 本地计算机或服务器 | GitHub托管的计算 |
| 任务控制角色 | 与 GitHub Web/mobile 共享本地会话 | 创建和路由托管会话 |
| SDK 选项 | ||
remote: true 在客户端或会话中 | ||
cloud: { ... } 创建会话时 | ||
| 恢复路径 | 标准简历 | 标准简历 |
| Windows 沙盒关系 | 无关 | 无关 |
当会话需要在已运行 SDK 运行时的环境中执行,并且还需要能够从 Mission Control 访问时,请使用远程会话。 在GitHub托管的计算上执行会话时,请使用云会话。
故障排除
| 症状 | 可能的原因 | 需要检查的事项 |
|---|---|---|
云会话创建返回 "policy_blocked" | 组织策略阻止从云流进行远程控制或查看 | 检查组织的 Copilot 策略和用户授权资格 |
| 会话是在没有存储库上下文的情况下创建的 | ||
cloud.repository 已省略 | 传递 owner、name,以及可选的 branch | |
恢复将忽略新 cloud 选项 | ||
cloud 仅适用于新会话 | 正常恢复现有会话 | |
| 沙箱设置相关疑难问题 | Windows沙盒和云会话是分开的 | 不要将 SANDBOX=true 用于云端执行 |
session.send 使用 messageId 进行解析,但没有触发 assistant.* 事件,任务控制也不显示命令提示 | session.send 早于来自远程工作进程的 session.start 执行;运行时吞掉了该提示 | 在发送之前,等待第一个带有 producer === "copilot-agent" 的 session.start 事件。 请参阅发送第一个提示词 |
| 尽管云端工作进程正在处理,实时界面却始终不更新 | 未在 createSession 上设置 streaming,因此只会发出最后一个 assistant.message | 在createSession上设置streaming: true,然后重新启动 |
| 云会话有效,但 UI 中未显示可共享 URL | 应用从未针对该 URL 订阅 session.info | 订阅 session.info 并筛选 infoType === "remote"。 请参阅 访问任务控制 URL |
另请参阅
- 远程会话:通过任务控制共享本地托管会话
-
[AUTOTITLE](/copilot/how-tos/copilot-sdk/features/streaming-events):订阅 `assistant.*` 增量以进行实时 UI 渲染 - 多租户与服务器部署:集成 ID 和服务器部署模式
- Authentication:为 SDK 会话配置GitHub身份验证