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