Skip to main content
Skip to content

会话恢复和持久性

本指南将指导你完成 SDK 的会话持久性功能 -- 如何暂停工作、稍后恢复工作和管理生产环境中的会话。

会话的工作原理

创建会话时,Copilot CLI 会维护会话历史记录、工具状态和规划上下文。 默认情况下,此状态位于内存中,并在会话结束时消失。 启用持久性后,可以在重启、容器迁移甚至不同的客户端实例之间恢复会话。

图示:显示所述过程的流程图。

州发生的情况
创建session_id 分配
激活发送提示、工具调用、响应
已暂停保存到磁盘的状态
Resume状态从磁盘加载

快速入门:创建可恢复会话

可恢复会话的关键在于提供你自己的 session_id。 如果没有 ID,SDK 将生成随机 ID,会话以后无法恢复。

TypeScript

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();

// Create a session with a meaningful ID
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
});

// Do some work...
await session.sendAndWait({ prompt: "Analyze my codebase" });

// Session state is automatically persisted
// You can safely close the client

Python

from copilot import CopilotClient
from copilot.session import PermissionHandler

client = CopilotClient()
await client.start()

# Create a session with a meaningful ID
session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5.2-codex", session_id="user-123-task-456")

# Do some work...
await session.send_and_wait("Analyze my codebase")

# Session state is automatically persisted

Go

ctx := context.Background()
client := copilot.NewClient(nil)

// Create a session with a meaningful ID
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
    SessionID: "user-123-task-456",
    Model:     "gpt-5.2-codex",
})

// Do some work...
session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Analyze my codebase"})

// Session state is automatically persisted

C# (.NET)

using GitHub.Copilot;

var client = new CopilotClient();

// Create a session with a meaningful ID
var session = await client.CreateSessionAsync(new SessionConfig
{
    SessionId = "user-123-task-456",
    Model = "gpt-5.2-codex",
});

// Do some work...
await session.SendAndWaitAsync(new MessageOptions { Prompt = "Analyze my codebase" });

// Session state is automatically persisted

恢复会话

稍后(分钟、小时甚至几天)可以从离开位置恢复会话。

使用会话文件系统记住的权限

配置自定义 sessionFs 提供程序时,由运行时管理的持久权限选项使用提供程序存储,而不是运行时主机的配置。 这些文件位于提供程序 sessionStatePath 下,并保留其现有格式:

  • permissions.json:保留现有allowed_directories和locations字段的顶级tool_approvals映射
  • settings.json:顶级sandbox,用于allowedUrlsURL 审批,approve-permanently用于已保存的沙盒首选项
  • config.json:用于已记住的文件夹信任的顶层sandboxOnboardingShown以及用于首次启用沙盒提示消息的trustedFolders

位置键是规范化的提供程序目录路径,例如 /workspace,没有添加前缀。 运行时使用提供程序路径约定以词法解析它们,而无需检查主机文件系统或发现主机 Git 存储库。 当工作目录为/workspace时,不会自动选择为/workspace/sub保存的审批。

基于提供程序的文件夹信任也使用词法路径:受信任的文件夹涵盖其自身及其子项,而不包括位于其他路径上的链接 Git 工作树。 显式信任这些工作树路径。

这些文件内没有额外的会话 ID 分区。 访问相同后备文件的会话共享记住的选项。 当会话或租户不得共享授权时,请使用单独的提供程序命名空间。 使用每个会话的命名空间时,永久选择在恢复该会话时仍然有效,但不会自动延续到新会话。 若要在恢复时还原会话中持久化的选项,请将其重新连接到同一命名空间。

同意更新在一个运行时进程中按提供程序终结点和文件序列化。 单独的端点不会相互阻塞。 如果不同的提供程序终结点或运行时进程共享后备文件,应用程序必须协调并发更新;运行时无法推断这些文件是共享的。

这些操作从不导入、更新或回退到主机的permissions-config.json、settings.json或config.json,包括提供程序读取或写入失败时。 直接读取通过提供方提供的现有格式的文件。

与主机配置一样,URL 审批仅从 settings.json 读取。 在 config.json 中的旧 allowedUrls 字段会被忽略;config.json 仍是全局状态文件,用于记住的文件夹信任和沙盒引导标记。

存储路由不会更改权限生存期、URL 拒绝优先级或会话策略行为。 单次批准和本次会话批准不会变成永久授权。

保存的沙盒首选项在创建和恢复时还原。 以后的显式 SDK options.update 调用可以更改实时沙盒配置,而无需重写保存的首选项。

在没有 sessionFs 的情况下,SDK 应用程序在 empty 和 copilot-cli 两种模式下将保留现有的主机支持的持久性。 这包括永久 URL 同意保存主机设置并在实时会话中授予访问权限的现有行为,但新的 SDK 会话不会自动加载主机 URL 允许列表。

请参阅 多租户与服务器部署 了解提供程序隔离责任。

转录文本恢复

继续选项 allowTranscriptRecovery 控制运行时从存储加载转录内容时的恢复。 在所有模式下,它默认为 true。 使用 false 时,丢弃损坏记录或移动 session.start 的负载会失败,并出现 JSON-RPC 错误 -32075,而无需重写转录内容。 接受不带换行符的完整最终记录。

在检查持久顺序时,为向前兼容性而跳过的记录仍会被计入。 如果此类记录位于 session.start 之前,恢复必须先将开始记录移到它们之后。 仅包含跳过记录的转录并非空白,没有有效的 session.start 就无法还原。

允许恢复时,返回的会话会提供 transcriptRecovery,包括无效的行号、session.start 是否移动以及计划的字节精确备份路径。 仅执行加载操作不会写入该备份;下一个持久追加执行修复并写入该备份。

注意

此选项适用于新的转录文本加载,不适用于会话的生存期。 重新连接到已驻留在运行时的会话会重复使用其实时历史记录,而无需重新验证存储或拒绝由先前恢复操作授权的恢复。 恢复报告描述的是执行恢复的负载项,而不是之后每一次重新连接。

图示:显示所述过程的流程图。

TypeScript

// Resume from a different client instance (or after restart)
const session = await client.resumeSession("user-123-task-456");

// Continue where you left off
await session.sendAndWait({ prompt: "What did we discuss earlier?" });

Python

# Resume from a different client instance (or after restart)
session = await client.resume_session("user-123-task-456", on_permission_request=PermissionHandler.approve_all)

# Continue where you left off
await session.send_and_wait("What did we discuss earlier?")

Go

ctx := context.Background()

// Resume from a different client instance (or after restart)
session, _ := client.ResumeSession(ctx, "user-123-task-456", nil)

// Continue where you left off
session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What did we discuss earlier?"})

C# (.NET)

// Resume from a different client instance (or after restart)
var session = await client.ResumeSessionAsync("user-123-task-456");

// Continue where you left off
await session.SendAndWaitAsync(new MessageOptions { Prompt = "What did we discuss earlier?" });

恢复选项

恢复会话时,可以选择重新配置许多设置。 如果需要更改模型、更新工具配置或修改行为,这非常有用。

选项Description
model更改已恢复的会话的模型
systemMessage覆盖或扩展系统提示
availableTools限制可用的工具
excludedTools禁用特定工具
provider重新提供 BYOK 凭据(这是 BYOK 会话所需的)
capi.autoTier覆盖已保存的自动路由偏好设置
capi.enableWebSocketResponses为已恢复的会话选择 Responses API 传输方式
reasoningEffort调整推理工作量级别
streaming启用/禁用流式处理响应
workingDirectory更改工作目录
configDir覆盖配置目录
mcpServers配置 MCP 服务器
customAgents配置自定义代理
agent按名称预先选择自定义代理
skillDirectories要从中加载技能的目录
disabledSkills禁用技能
infiniteSessions配置无限会话模式

自动层暂留

使用 model: "auto",可选 capi.autoTier 设置选择自动路由首选项: efficiency、 balance、 intelligence或 fast。 在 Python 中,使用 capi={"auto_tier": "balance"}。 此设置适用于 V2 自动路由;V1 自动请求保持不变。

启用运行时的默认关闭DYNAMIC_AUTO_TIERS功能后,会话的 model.list RPC 还会从提供程序的auto终结点返回可选/meta元数据。 使用启用的描述符结合 type: "auto" 来发现其他受支持的层标识符、显示名称、说明和排序。 现有的选择方法和 JSON 字段接受这些标识符。 发现失败不会回退到 /models,没有 auto 元数据的成功响应不提供可选择的自动层。

若要在尚无任何会话时填充模型选取器,可在运行时的环境中启用 DYNAMIC_AUTO_TIERS(例如 env 客户端选项)。 服务器级 models.list RPC(Node.js 中的 client.rpc.models.list())随后会从同一 /meta 响应中返回相同的 auto 元数据,并具有相同的无回退行为。 服务器级列表读取运行时在启动时解析的标志,而不是每个会话的功能标志或实验分配,因此请在启动运行时的位置设置该标志。 禁用标志后, models.list 未更改并省略 auto。

将层标识符视为可扩展值,而不是封闭枚举。 现有的命名值仍然可用;对于附加标识符,请在 Node.js 和 Python 中使用字符串,在 Go 中使用 AutoTier("premium-v2"),在 .NET 中使用 new AutoTier("premium-v2"),在 Rust 中使用 AutoTier::Custom,在 Java 中使用 AutoTier.fromValue。 提供程序的 defaultTier 配置描述其默认路由,而无需创建已提交的 SDK 首选项。

如果删除或禁用持久化层级,则继续会保留显式首选项,而不是将其替换为提供程序的默认值。 激活自动路由之前,请选择可用的替换项。

CLI 还会在启动期间保留设置派生的首选项,即使层不可用或动态发现被禁用也是如此。 然后,可以在模型选取器中选择替代项。 在操作成功之前,仍会验证显式 SDK 创建和恢复首选项,并且自动激活始终根据解析的发现模式验证可用性。

创建或恢复请求包括 expAssignments时,运行时会在验证显式自动首选项之前应用这些分配。 验证、发现和激活使用相同的已解析的功能判定结果。

fast是仅集成商延迟预设,不是第一方GitHub Copilot产品首选项。 配置会话时,不会根据 /meta 层目录对 Fast 进行验证。 SDK 不会决定是否符合 Fast 条件、检查客户端身份、将 Fast 设为默认选项,或在运行时不支持 Fast 时回退到其他层级——较旧的运行时会原样返回其原生错误。

运行时会保留所选层,因此应用程序无需在每次恢复时重新发送它:

  • 创建会话时省略层使用运行时的默认路由行为。
  • 冷恢复会还原暂留的层。 显式指定层级会覆盖新激活时恢复的值。
  • 恢复已驻留在运行时中的会话时,省略该层级会保留当前选择,而指定相同的层级则不会执行任何操作。 提供不同的层会请求一次安全切换,运行时会在恢复成功后应用该切换;它无法更改已在进行中的轮次。
  • 没有持久层的旧会话会保留默认路由行为。

层选择不是实时模型切换操作。 SDK 转发首选项;运行时拥有持久性和验证。

session.start 和 session.resume 事件会在其可选的 data.autoTier 字段中提供所选层级(在 Python 中为 data.auto_tier)。 如果未选择任何层,则省略该字段。

在会话期间更改自动层级

调用 setAutoTier 以在不更改所选模型的情况下更改实时会话上的路由首选项。 传入 null(Python None,Go nil)即可恢复为提供商默认的 Auto 路由。

const result = await session.setAutoTier("intelligence");
if (result.status === "pending") {
  // Accepted, but not yet in effect.
}

运行时不会立即应用首选项。 仅当以后用户使用 auto 模型成功从提供程序获取可用模型时,它才会记录请求并提交该请求。 因此,状态 pending 确认请求已接受,而不是它生效。 只有最新的请求会被保留:新请求会替换此前任何尚未被任何轮次认领的请求。

如果较旧的请求在较新的首选项请求或重置到达时仍在验证,则较旧的调用将失败,并出现“请求已被取代”错误,而不是替换较新的意图。

通过以下事件监视结果:

  • session.model_change 在首选项提交时。
  • session.auto_tier_switch_failed 未能执行时。 此事件是短暂的,因此运行时在恢复运行时既不会将其持久化,也不会重放该事件。 其 reason 字段的值为 policy_rejected、setup_failed、request_failed 或 unsupported 之一,且先前生效的首选项将继续生效。

还可以通过会话的 model.getCurrent RPC 方法随时读取权威状态;该方法会返回已提交的 autoTier、任何未被认领的 pendingAutoTier,以及正在进行的激活当前已认领的 activatingAutoTier。

SDK更改级别返回到提供程序默认路由
Node.jssession.setAutoTier("balance")session.setAutoTier(null)
Pythonsession.set_auto_tier("balance")session.set_auto_tier(None)
Gosession.SetAutoTier(ctx, &tier)session.SetAutoTier(ctx, nil)
.NETsession.SetAutoTierAsync(AutoTier.Balance)session.SetAutoTierAsync(null)
Rustsession.set_auto_tier(Some(AutoTier::Balance))session.set_auto_tier(None)
Javasession.setAutoTier(AutoTier.BALANCE)session.setAutoTier(null)

若要在一次调用中同时选择 auto 模型及其路由偏好,请改为在模型切换器上设置层级。 当模型不是 auto 时,运行时会拒绝此选项。

SDK通过切换暂存一个层重置为提供程序默认路由
Node.jssetModel("auto", { autoTier: "balance" })setModel("auto", { autoTier: null })
Pythonset_model("auto", auto_tier="balance")set_model("auto", auto_tier=None)
GoSetModelOptions{AutoTier: &tier}SetModelOptions{ResetAutoTier: true}
.NETnew SetModelOptions { AutoTier = AutoTier.Balance }new SetModelOptions { ResetAutoTier = true }
RustSetModelOptions::default().with_auto_tier(AutoTier::Balance)SetModelOptions::default().with_reset_auto_tier()
Javanew SetModelOptions().setModel("auto").setAutoTier(AutoTier.BALANCE)new SetModelOptions().setModel("auto").setResetAutoTier(true)

Node.js、Python和 Rust 以单个值表示所有三种状态:Node.js 和Python,因为null/None与省略的参数区分开来,Rust 是AutoTierPreference::Reset同一选项的不同变体。 Go、.NET 和 Java 无法在单个值中区分“重置”和“未设置”,因此它们会额外使用一个单独的重置标志。 省略两者始终意味着“仅保留当前首选项”。

恢复时传输响应

可选的 capi.enableWebSocketResponses 设置项用于为 CAPI 响应 API 选择传输方式。 它的默认值为 true,因此当所选模型声明了 ws:/responses 端点时,就会使用 WebSocket 传输。 将其设置为 false 将回退到 HTTP 传输。 在 Python 中,使用 capi={"enable_web_socket_responses": False}。

需要时,在恢复调用中提供它。 当 WebSocket 连接在代理后发生失败时,以及恢复的会话报告 400 input item ID does not belong to this connection(这是 WebSocket 传输特有的)时,建议设置此项。

const session = await client.resumeSession("user-123-task-456", {
  capi: { enableWebSocketResponses: false },
});

将其设置为 false 等效于 COPILOT_CLI_DISABLE_WEBSOCKET_RESPONSES 具有相反极性的环境变量。

示例:恢复时更改模型。

// Resume with a different model
const session = await client.resumeSession("user-123-task-456", {
  model: "claude-sonnet-4",  // Switch to a different model
  reasoningEffort: "high",   // Increase reasoning effort
});

将 BYOK(自带密钥)与已恢复的会话配合使用

使用自己的 API 密钥时,必须在恢复时重新提供提供程序配置。 出于安全原因,API 密钥永远不会保存到磁盘。

// Original session with BYOK
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,
    deploymentId: "my-gpt-deployment",
  },
});

// When resuming, you MUST re-provide the provider config
const resumed = await client.resumeSession("user-123-task-456", {
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,  // Required again
    deploymentId: "my-gpt-deployment",
  },
});

哪些内容会持久化?

会话状态保存到 ~/.copilot/session-state/{sessionId}/:

~/.copilot/session-state/
└── user-123-task-456/
    ├── checkpoints/           # Conversation history snapshots
    │   ├── 001.json          # Initial state
    │   ├── 002.json          # After first interaction
    │   └── ...               # Incremental checkpoints
    ├── plan.md               # Agent's planning state (if any)
    └── files/                # Session artifacts
        ├── analysis.md       # Files the agent created
        └── notes.txt         # Working documents
Data持久化?笔记
对话历史记录
✅ 是的完整消息线程
工具调用结果
✅ 是的为提供上下文而缓存
代理规划状态
✅ 是的
plan.md 文件
会话项目
✅ 是的在 files/ 目录中
提供者/API 密钥
❌ 否安全性:必须重新提供
内存中工具状态
❌ 否工具应为无状态

会话 ID 最佳实践

选择能编码拥有者和用途的会话 ID。 这使得审核和清理更加容易。

Pattern示例用例
❌abc123随机 ID难以审核,没有所有权信息
✅user-{userId}-{taskId}user-alice-pr-review-42多用户应用
✅tenant-{tenantId}-{workflow}tenant-acme-onboarding多租户软件即服务
✅{userId}-{taskId}-{timestamp}alice-deploy-1706932800基于时间的清理

结构化 ID 的优点:

  • 易于审核:“显示用户 alice 的所有会话”
  • 便于清理:“删除所有早于 X 的会话”
  • 自主访问控制:从会话 ID 解析用户 ID

示例:生成会话 ID

function createSessionId(userId: string, taskType: string): string {
  const timestamp = Date.now();
  return `${userId}-${taskType}-${timestamp}`;
}

const sessionId = createSessionId("alice", "code-review");
// → "alice-code-review-1706932800000"
import time

def create_session_id(user_id: str, task_type: str) -> str:
    timestamp = int(time.time())
    return f"{user_id}-{task_type}-{timestamp}"

session_id = create_session_id("alice", "code-review")
# → "alice-code-review-1706932800"

管理会话生命周期

列出活动会话

// List all sessions
const sessions = await client.listSessions();
console.log(`Found ${sessions.length} sessions`);

for (const session of sessions) {
  console.log(`- ${session.sessionId} (created: ${session.createdAt})`);
}

// Filter sessions by repository
const repoSessions = await client.listSessions({ repository: "owner/repo" });

清理旧会话

async function cleanupExpiredSessions(maxAgeMs: number) {
  const sessions = await client.listSessions();
  const now = Date.now();
  
  for (const session of sessions) {
    const age = now - new Date(session.createdAt).getTime();
    if (age > maxAgeMs) {
      await client.deleteSession(session.sessionId);
      console.log(`Deleted expired session: ${session.sessionId}`);
    }
  }
}

// Clean up sessions older than 24 hours
await cleanupExpiredSessions(24 * 60 * 60 * 1000);

断开会话连接(disconnect)

任务完成后,显式断开会话连接,而非等待超时。 这会释放内存中资源,但 会保留磁盘上的会话数据,以便以后仍可以恢复会话:

try {
  // Do work...
  await session.sendAndWait({ prompt: "Complete the task" });
  
  // Task complete — release in-memory resources (session can be resumed later)
  await session.disconnect();
} catch (error) {
  // Clean up even on error
  await session.disconnect();
  throw error;
}

每个 SDK 还提供惯用的自动清理模式:

语言Pattern示例
TypeScriptSymbol.asyncDisposeawait using session = await client.createSession(config);
Pythonasync with 上下文管理器async with await client.create_session(on_permission_request=handler) as session:
C#IAsyncDisposableawait using var session = await client.CreateSessionAsync(config);
Godeferdefer session.Disconnect()

注意

destroy() 已弃用,改用 disconnect()。 现有使用destroy()的代码将继续工作,但应迁移。

永久删除会话 (deleteSession)

若要永久删除会话及其所有数据(会话历史记录、规划状态、项目),请使用 deleteSession。 这是不可逆转的 — 删除后 无法 恢复会话:

// Permanently remove session data
await client.deleteSession("user-123-task-456");

disconnect() vs deleteSession():disconnect() 释放内存中资源,但保留磁盘上的会话数据以供以后恢复。 deleteSession() 永久删除所有内容,包括磁盘上的文件。

自动清理:空闲超时

默认情况下,会话没有空闲超时限制,并且会无限期持续存在,直到被显式断开连接或删除。 您可以选择通过 CopilotClientOptions.sessionIdleTimeoutSeconds 配置服务器级空闲超时:

const client = new CopilotClient({
  sessionIdleTimeoutSeconds: 30 * 60, // 30 minutes
});

配置了超时时间后,在该时长内无活动的会话会被自动清理。 设置为 0 或省略以禁用。

注意

此选项仅适用于 SDK 生成运行时进程时。 通过 cliUrl 连接到现有服务器时,将采用服务器自身的超时配置。

图示:显示所述过程的流程图。

具有活动工作(正在运行的命令、后台智能体)的会话始终受到空闲清理保护,无论超时设置如何。

监听空闲事件以响应会话不活动:

session.on("session.idle", (event) => {
  console.log(`Session idle for ${event.idleDurationMs}ms`);
});

部署模式

最适合:强隔离、多租户环境、Azure动态会话。

图示:显示所述过程的流程图。

**好处:**✅ 完全隔离 | ✅ 简单安全性 | ✅ 轻松缩放

模式 2:共享 CLI 服务器(资源高效)

最适用于:内部工具、可信环境、资源受限的部署环境。

图示:显示所述过程的流程图。

要求:

  • ⚠️ 每个用户的唯一会话 ID
  • ⚠️ 应用程序级访问控制
  • ⚠️ 操作前的会话 ID 验证
// Application-level access control for shared CLI
async function resumeSessionWithAuth(
  client: CopilotClient,
  sessionId: string,
  currentUserId: string
): Promise<Session> {
  // Parse user from session ID
  const [sessionUserId] = sessionId.split("-");
  
  if (sessionUserId !== currentUserId) {
    throw new Error("Access denied: session belongs to another user");
  }
  
  return client.resumeSession(sessionId);
}

Azure动态会话

对于容器可以重启或迁移的无服务器/容器部署:

装载永久性存储

会话状态目录必须装载到永久性存储:

# Azure Container Instance example
containers:
  - name: copilot-agent
    image: my-agent:latest
    volumeMounts:
      - name: session-storage
        mountPath: /home/app/.copilot/session-state

volumes:
  - name: session-storage
    azureFile:
      shareName: copilot-sessions
      storageAccountName: myaccount

图示:显示所述过程的流程图。

会话在容器重启后仍然存在!

长时间运行的工作流的无限会话

如果工作流可能超出上下文限制,请启用自动压缩以支持无限会话:

const session = await client.createSession({
  sessionId: "long-workflow-123",
  infiniteSessions: {
    enabled: true,
    backgroundCompactionThreshold: 0.80,  // Start compaction at 80% context
    bufferExhaustionThreshold: 0.95,      // Block at 95% if needed
  },
});

注意

阈值是上下文利用率(0.0-1.0),而不是绝对令牌计数。 有关详细信息,请参阅 SDK 和 CLI 兼容性 。

限制和注意事项

LimitationDescription缓解措施
BYOK 重新身份验证API 密钥不会持久化将密钥存储在机密管理器中;在恢复时提供
可写存储~/.copilot/session-state/ 必须可写在容器中装载永久性卷
无会话锁定对同一会话的并发访问未定义实现应用程序级锁定或队列
工具状态未持久化内存中的工具状态已丢失将工具设计为无状态或保留其自己的状态

处理并发访问

SDK 不提供内置会话锁定。 如果多个客户端可能访问同一会话:

// Option 1: Application-level locking with Redis
import Redis from "ioredis";

const redis = new Redis();

async function withSessionLock<T>(
  sessionId: string,
  fn: () => Promise<T>
): Promise<T> {
  const lockKey = `session-lock:${sessionId}`;
  const acquired = await redis.set(lockKey, "locked", "NX", "EX", 300);
  
  if (!acquired) {
    throw new Error("Session is in use by another client");
  }
  
  try {
    return await fn();
  } finally {
    await redis.del(lockKey);
  }
}

// Usage
await withSessionLock("user-123-task-456", async () => {
  const session = await client.resumeSession("user-123-task-456");
  await session.sendAndWait({ prompt: "Continue the task" });
});

总结

功能使用方法
创建可恢复会话提供你自己的 sessionId
恢复会话client.resumeSession(sessionId)
BYOK 简历重新提供 provider 配置
列表会话client.listSessions(filter?)
断开与活动会话的连接session.disconnect()- 释放内存中资源;保留磁盘上的会话数据以恢复
永久删除会话client.deleteSession(sessionId)— 永久删除磁盘中的所有会话数据;无法恢复
容器化部署装载 ~/.copilot/session-state/ 到永久性存储

后续步骤