关于 copilot-sdk
GitHub Copilot SDK 让开发者用四种语言构建可编程调用 GitHub Copilot 的应用。它封装 Copilot CLI,提供会话、流式响应、自定义工具、钩子和 MCP 服务集成。
主要功能
- 01支持 Node.js、Python、Go 和 .NET
- 02会话与消息管理
- 03流式响应和事件
- 04自定义工具与生命周期钩子
- 05MCP 服务配置
适用场景
- 01围绕 Copilot 会话构建应用
- 02在界面中流式显示 Copilot 响应
- 03为 Copilot 添加应用专属工具
- 04连接本地或远程 MCP 服务
MCP 相关
SDK 可为 Copilot 会话配置本地 stdio 和远程 HTTP MCP 服务,并设置请求头、环境变量、超时及工具筛选。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ skills --skill copilot-sdk安装后在 Claude Code 中输入/copilot-sdk确认已加载。
详细介绍
GitHub Copilot SDK
构建可通过编程方式与 GitHub Copilot 交互的应用。SDK 通过 JSON-RPC 封装 Copilot CLI,提供会话管理、自定义工具、钩子、MCP 服务集成,并支持在 Node.js、Python、Go 和 .NET 中进行流式传输。
前提条件
- 已安装并完成身份验证的 GitHub Copilot CLI(
copilot --version) - GitHub Copilot 订阅(Individual、Business 或 Enterprise)——BYOK 无需订阅
- 运行时: Node.js 18+ / Python 3.8+ / Go 1.21+ / .NET 8.0+
安装
| 语言 | 包 | 安装 |
|---|---|---|
| Node.js | @github/copilot-sdk | npm install @github/copilot-sdk |
| Python | github-copilot-sdk | pip install github-copilot-sdk |
| Go | github.com/github/copilot-sdk/go | go get github.com/github/copilot-sdk/go |
| .NET | GitHub.Copilot.SDK | dotnet add package GitHub.Copilot.SDK |
架构
SDK 通过 stdio(默认)或 TCP 上的 JSON-RPC 与 Copilot CLI 通信。CLI 负责管理模型调用、工具执行、会话状态和 MCP 服务生命周期。
Your App → SDK Client → [stdio/TCP] → Copilot CLI → Model Provider
↕
MCP Servers
传输模式:
| 模式 | 描述 | 使用场景 |
|---|---|---|
| Stdio(默认) | CLI 作为子进程,通过管道通信 | 本地开发、单进程 |
| TCP | CLI 作为网络服务 | 多客户端、后端服务 |
核心模式:客户端 → 会话 → 消息
所有 SDK 用法都遵循以下流程:创建客户端、创建会话、发送消息。
Node.js / TypeScript
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ model: "gpt-4.1" });
const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);
await client.stop();
Python
import asyncio
from copilot import CopilotClient
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session({"model": "gpt-4.1"})
response = await session.send_and_wait({"prompt": "What is 2 + 2?"})
print(response.data.content)
await client.stop()
asyncio.run(main())
Go
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil { log.Fatal(err) }
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2 + 2?"})
fmt.Println(*response.Data.Content)
.NET
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" });
var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
Console.WriteLine(response?.Data.Content);
流式响应
将 streaming: true 设为启用实时输出,并订阅增量事件。
Node.js
const session = await client.createSession({ model: "gpt-4.1", streaming: true });
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
session.on("session.idle", () => console.log());
await session.sendAndWait({ prompt: "Tell me a joke" });
Python
from copilot.generated.session_events import SessionEventType
session = await client.create_session({"model": "gpt-4.1", "streaming": True})
def handle_event(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
sys.stdout.write(event.data.delta_content)
sys.stdout.flush()
if event.type == SessionEventType.SESSION_IDLE:
print()
session.on(handle_event)
await session.send_and_wait({"prompt": "Tell me a joke"})
事件订阅
| 方法 | 描述 |
|---|---|
on(handler) | 订阅所有事件;返回取消订阅函数 |
on(eventType, handler) | 订阅特定事件类型(仅限 Node.js) |
调用返回的函数即可取消订阅。在 .NET 中,对返回的可释放对象调用 .Dispose()。
自定义工具
定义 Copilot 可调用的工具,以扩展其功能。
Node.js
import { CopilotClient, defineTool } from "@github/copilot-sdk";
const getWeather = defineTool("get_weather", {
description: "Get the current weather for a city",
parameters: {
type: "object",
properties: { city: { type: "string", description: "The city name" } },
required: ["city"],
},
handler: async ({ city }) => ({ city, temperature: "72°F", condition: "sunny" }),
});
const session = await client.createSession({
model: "gpt-4.1",
tools: [getWeather],
});
Python
from copilot.tools import define_tool
from pydantic import BaseModel, Field
class GetWeatherParams(BaseModel):
city: str = Field(description="The city name")
@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
return {"city": params.city, "temperature": "72°F", "condition": "sunny"}
session = await client.create_session({"model": "gpt-4.1", "tools": [get_weather]})
Go
type WeatherParams struct {
City string `json:"city" jsonschema:"The city name"`
}
getWeather := copilot.DefineTool("get_weather", "Get weather for a city",
func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
return WeatherResult{City: params.City, Temperature: "72°F"}, nil
},
)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
Tools: []copilot.Tool{getWeather},
})
.NET
using Microsoft.Extensions.AI;
using System.ComponentModel;
var getWeather = AIFunctionFactory.Create(
([Description("The city name")] string city) => new { city, temperature = "72°F" },
"get_weather", "Get the current weather for a city");
await using var session = await client.CreateSessionAsync(new SessionConfig {
Model = "gpt-4.1", Tools = [getWeather],
});
工具要求
- 处理程序必须返回可序列化为 JSON 的数据(不能是
undefined) - 参数必须符合 JSON Schema 格式
- 工具描述应清楚说明何时应使用该工具
钩子
在关键生命周期节点拦截并自定义会话行为。
| 钩子 | 触发时机 | 使用场景 |
|---|---|---|
onPreToolUse | 工具执行前 | 权限控制、修改参数 |
onPostToolUse | 工具执行后 | 转换结果、日志记录、脱敏 |
onUserPromptSubmitted | 用户发送消息时 | 修改提示词、过滤、注入上下文 |
onSessionStart | 会话开始时(新建或恢复) | 添加上下文、配置会话 |
onSessionEnd | 会话结束时 | 清理、分析、指标 |
onErrorOccurred | 发生错误时 | 自定义错误处理、重试逻辑、监控 |
工具执行前钩子
在工具执行前控制工具权限、修改参数或注入上下文。
const session = await client.createSession({
hooks: {
onPreToolUse: async (input) => {
if (["shell", "bash"].includes(input.toolName)) {
return { permissionDecision: "deny", permissionDecisionReason: "Shell access not permitted" };
}
return { permissionDecision: "allow" };
},
},
});
输入字段: timestamp、cwd、toolName、toolArgs
输出字段:
| 字段 | 类型 | 描述 |
|---|---|---|
permissionDecision | "allow" | "deny" | "ask" | 是否允许调用工具 |
permissionDecisionReason | string | 拒绝或询问的原因 |
modifiedArgs | object | 要传入的修改后参数 |
additionalContext | string | 对话的额外上下文 |
suppressOutput | boolean | 隐藏对话中的工具输出 |
工具执行后钩子
执行后转换结果、脱敏敏感数据或记录工具活动。
hooks: {
onPostToolUse: async (input) => {
// Redact sensitive data from results
if (typeof input.toolResult === "string") {
let redacted = input.toolResult;
for (const pattern of SENSITIVE_PATTERNS) {
redacted = redacted.replace(pattern, "[REDACTED]");
}
if (redacted !== input.toolResult) {
return { modifiedResult: redacted };
}
}
return null; // Pass through unchanged
},
}
输出字段: modifiedResult、additionalContext、suppressOutput
用户提示词提交钩子
在处理前修改或增强用户提示词。适用于提示词模板、上下文注入和输入验证。
hooks: {
onUserPromptSubmitted: async (input) => {
return {
modifiedPrompt: `[User from engineering team] ${input.prompt}`,
additionalContext: "Follow company coding standards.",
};
},
}
输出字段: modifiedPrompt、additionalContext、suppressOutput
会话生命周期钩子
hooks: {
onSessionStart: async (input, invocation) => {
// input.source: "startup" | "resume" | "new"
console.log(`Session ${invocation.sessionId} started (${input.source})`);
return { additionalContext: "Project uses TypeScript and React." };
},
onSessionEnd: async (input, invocation) => {
// input.reason: "complete" | "error" | "abort" | "timeout" | "user_exit"
await recordMetrics({ sessionId: invocation.sessionId, reason: input.reason });
return null;
},
}
错误处理钩子
hooks: {
onErrorOccurred: async (input) => {
// input.errorContext: "model_call" | "tool_execution" | "system" | "user_input"
// input.recoverable: boolean
if (input.errorContext === "model_call" && input.error.includes("rate")) {
return { errorHandling: "retry", retryCount: 3, userNotification: "Rate limited. Retrying..." };
}
return null; // Default error handling
},
}
输出字段: suppressOutput、errorHandling("retry" | "skip" | "abort")、retryCount、userNotification
Python 钩子示例
async def on_pre_tool_use(input_data, invocation):
if input_data["toolName"] in ["shell", "bash"]:
return {"permissionDecision": "deny", "permissionDecisionReason": "Not permitted"}
return {"permissionDecision": "allow"}
session = await client.create_session({
"hooks": {"on_pre_tool_use": on_pre_tool_use}
})
Go 钩子示例
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Hooks: &copilot.SessionHooks{
OnPreToolUse: func(input copilot.PreToolUseHookInput, inv copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) {
return &copilot.PreToolUseHookOutput{PermissionDecision: "allow"}, nil
},
},
})
MCP 服务集成
连接到 MCP(模型上下文协议)服务,使用预构建的工具功能。
本地 Stdio 服务
const session = await client.createSession({
mcpServers: {
filesystem: {
type: "local",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
tools: ["*"],
env: { DEBUG: "true" },
cwd: "./servers",
timeout: 30000,
},
},
});
远程 HTTP 服务
const session = await client.createSession({
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
headers: { Authorization: "Bearer ${TOKEN}" },
tools: ["*"],
},
},
});
MCP 配置字段
本地/Stdio:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
type | "local" | 否 | 默认为 local |
command | 字符串 | 是 | 可执行文件路径 |
args | 字符串[] | 是 | 命令参数 |
env | 对象 | 否 | 环境变量 |
cwd | 对象 | 否 | 工作目录 |
tools | 字符串[] | 否 | 所有工具使用 ["*"],不使用任何工具则用 [] |
timeout | 数字 | 否 | 超时时间,单位为毫秒 |
远程 HTTP:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
type | "http" | 是 | 服务类型 |
url | 字符串 | 是 | 服务 URL |
headers | 对象 | 否 | HTTP 标头 |
tools | 字符串[] | 否 | 工具筛选器 |
timeout | 数字 | 否 | 超时时间,单位为毫秒 |
MCP 调试
集成前单独测试 MCP 服务:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | /path/to/your/mcp-server
使用 MCP Inspector 进行交互式调试:
npx @modelcontextprotocol/inspector /path/to/your/mcp-server
常见 MCP 问题:
- 未显示工具 → 设置
tools: ["*"],并确认服务响应tools/list - 服务未启动 → 使用绝对命令路径,检查
cwd - 标准输出受干扰 → 调试输出必须写入标准错误,而非标准输出
身份验证
方法(按优先级排序)
- 显式令牌 — 构造函数中的
githubToken - HMAC 密钥 —
CAPI_HMAC_KEY或COPILOT_HMAC_KEY环境变量 - 直接 API 令牌 — 使用
COPILOT_API_URL的GITHUB_COPILOT_API_TOKEN - 环境变量 —
COPILOT_GITHUB_TOKEN→GH_TOKEN→GITHUB_TOKEN - 已存储的 OAuth — 来自
copilot auth login - GitHub CLI —
gh auth凭据
编程方式获取令牌
const client = new CopilotClient({ githubToken: process.env.GITHUB_TOKEN });
OAuth GitHub App
适用于用户使用 GitHub 登录的多用户应用:
const client = new CopilotClient({
githubToken: userAccessToken, // gho_ or ghu_ token from OAuth flow
useLoggedInUser: false, // Don't use stored CLI credentials
});
支持的令牌类型: gho_(OAuth)、ghu_(GitHub App)、github_pat_(细粒度 PAT)。
不支持: ghp_(经典 PAT — 已弃用)。
禁用自动登录
阻止 SDK 使用已存储的凭据:
const client = new CopilotClient({ useLoggedInUser: false });
BYOK(自带密钥)
使用自己的 API 密钥,无需 Copilot 订阅。CLI 仅充当 Agent 运行时。
提供商配置
OpenAI:
provider: { type: "openai", baseUrl: "https://api.openai.com/v1", apiKey: process.env.OPENAI_API_KEY }
Azure AI Foundry(兼容 OpenAI):
provider: {
type: "openai",
baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
apiKey: process.env.FOUNDRY_API_KEY,
wireApi: "responses", // Use "responses" for GPT-5 series, "completions" for others
}
Azure OpenAI(原生端点):
provider: {
type: "azure",
baseUrl: "https://my-resource.openai.azure.com", // Just the host — no /openai/v1
apiKey: process.env.AZURE_OPENAI_KEY,
azure: { apiVersion: "2024-10-21" },
}
Anthropic:
provider: { type: "anthropic", baseUrl: "https://api.anthropic.com", apiKey: process.env.ANTHROPIC_API_KEY }
Ollama(本地):
provider: { type: "openai", baseUrl: "http://localhost:11434/v1" }
提供商配置参考
| 字段 | 类型 | 描述 |
|---|---|---|
type | "openai" | "azure" | "anthropic" | 提供商类型 |
baseUrl | 字符串 | 必填。 API 端点 URL |
apiKey | 字符串 | API 密钥(本地提供商可选) |
bearerToken | 字符串 | Bearer 令牌身份验证(优先于 apiKey) |
wireApi | "completions" | "responses" | API 格式(默认:"completions") |
azure.apiVersion | 字符串 | Azure API 版本(默认:"2024-10-21") |
使用 BYOK 的 Azure 托管标识
使用 DefaultAzureCredential 为 Azure 部署获取短期有效的 Bearer 令牌:
from azure.identity import DefaultAzureCredential
from copilot import CopilotClient, ProviderConfig, SessionConfig
credential = DefaultAzureCredential()
token = credential.get_token("https://cognitiveservices.azure.com/.default").token
session = await client.create_session(SessionConfig(
model="gpt-4.1",
provider=ProviderConfig(
type="openai",
base_url=f"{foundry_url}/openai/v1/",
bearer_token=token,
wire_api="responses",
),
))
注意: Bearer 令牌会过期(约 1 小时)。对于长时间运行的应用,请在每个新会话开始前刷新令牌。SDK 不会自动刷新令牌。
BYOK 限制
- 仅支持静态凭据 — 不原生支持 Entra ID、OIDC 或托管身份
- 不会自动刷新 — 令牌过期后,需要创建新会话
- 密钥不会持久化 — 恢复会话时,必须重新提供
provider配置 - 模型可用性 — 受限于你的提供商所提供的模型
会话持久化
提供你自己的会话 ID,即可在重启后恢复会话。
// Create with explicit ID
const session = await client.createSession({
sessionId: "user-123-task-456",
model: "gpt-4.1",
});
// Resume later (even from a different client instance)
const resumed = await client.resumeSession("user-123-task-456");
await resumed.sendAndWait({ prompt: "What did we discuss?" });
会话管理
const sessions = await client.listSessions(); // List all
const lastId = await client.getLastSessionId(); // Get most recent
await client.deleteSession("user-123-task-456"); // Delete from storage
await session.destroy(); // Destroy active session
恢复选项
恢复会话时,你可以重新配置:model、systemMessage、availableTools、excludedTools、provider(BYOK 必需)、reasoningEffort、streaming、mcpServers、customAgents、skillDirectories、infiniteSessions。
会话 ID 最佳实践
| 模式 | 示例 | 用例 |
|---|---|---|
user-{userId}-{taskId} | user-alice-pr-review-42 | 多用户应用 |
tenant-{tenantId}-{workflow} | tenant-acme-onboarding | 多租户 SaaS |
{userId}-{taskType}-{timestamp} | alice-deploy-1706932800 | 基于时间的清理 |
持久化内容
会话状态会保存到 ~/.copilot/session-state/{sessionId}/:
| 数据 | 是否持久化? | 备注 |
|---|---|---|
| 对话历史 | ✅ 是 | 完整消息线程 |
| 工具调用结果 | ✅ 是 | 缓存以供上下文使用 |
| Agent 规划状态 | ✅ 是 | plan.md 文件 |
| 会话产物 | ✅ 是 | 位于 files/ 目录中 |
| 提供商/API 密钥 | ❌ 否 | 恢复时必须重新提供 |
| 内存中的工具状态 | ❌ 否 | 工具应设计为无状态 |
无限会话
对于可能超出上下文限制的长时间运行工作流,请启用自动压缩:
const session = await client.createSession({
infiniteSessions: {
enabled: true,
backgroundCompactionThreshold: 0.80, // Start background compaction at 80%
bufferExhaustionThreshold: 0.95, // Block and compact at 95%
},
});
阈值是上下文利用率比例(0.0–1.0),而非绝对令牌数。
自定义 Agent
定义专用 AI 角色:
const session = await client.createSession({
customAgents: [{
name: "pr-reviewer",
displayName: "PR Reviewer",
description: "Reviews pull requests for best practices",
prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",
}],
});
系统消息
控制 AI 的行为和个性:
const session = await client.createSession({
systemMessage: { content: "You are a helpful assistant. Always be concise." },
});
技能集成
加载技能目录以扩展 Copilot 的能力:
const session = await client.createSession({
skillDirectories: ["./skills/code-review", "./skills/documentation"],
disabledSkills: ["experimental-feature"],
});
技能可以与自定义 Agent 和 MCP 服务结合使用:
const session = await client.createSession({
skillDirectories: ["./skills/security"],
customAgents: [{ name: "auditor", prompt: "Focus on OWASP Top 10." }],
mcpServers: { postgres: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-postgres"], tools: ["*"] } },
});
权限与输入处理器
以编程方式处理工具权限和用户输入请求。SDK 使用默认拒绝权限模型 — 除非你提供处理器,否则所有权限请求都会被拒绝。
const session = await client.createSession({
onPermissionRequest: async (request) => {
if (request.kind === "shell") {
return { approved: request.command.startsWith("git") };
}
return { approved: true };
},
onUserInputRequest: async (request) => {
return { response: "yes" };
},
});
令牌用量跟踪
订阅用量事件,而不是使用 CLI /usage:
session.on("assistant.usage", (event) => {
console.log("Tokens:", { input: event.data.inputTokens, output: event.data.outputTokens });
});
部署模式
本地 CLI(默认)
SDK 会自动将 CLI 作为子进程启动。设置最简单,无需任何配置。
const client = new CopilotClient(); // Auto-manages CLI process
外部 CLI 服务端(后端服务)
以无头模式运行 CLI,通过 TCP 连接 SDK:
copilot --headless --port 4321
const client = new CopilotClient({ cliUrl: "localhost:4321" });
**多客户端支持:**多个 SDK 客户端可以共用一个 CLI 服务端。
捆绑 CLI(桌面应用)
将 CLI 二进制文件随应用一同发布:
const client = new CopilotClient({ cliPath: path.join(__dirname, "vendor", "copilot") });
Docker Compose
services:
copilot-cli:
image: ghcr.io/github/copilot-cli:latest
command: ["--headless", "--port", "4321"]
environment:
- COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN}
volumes:
- session-data:/root/.copilot/session-state
api:
build: .
environment:
- CLI_URL=copilot-cli:4321
depends_on: [copilot-cli]
volumes:
session-data:
会话隔离模式
| 模式 | 隔离级别 | 资源消耗 | 最适用场景 |
|---|---|---|---|
| 每个用户一个 CLI | 完全隔离 | 高 | 多租户 SaaS、合规要求 |
| 共用 CLI + 会话 ID | 逻辑隔离 | 低 | 内部工具 |
| 共用会话 | 无 | 低 | 团队协作(需要锁定) |
生产环境检查清单
- 会话清理:定期删除过期会话
- 健康检查:对 CLI 服务端执行 ping,无响应时重启
- 持久化存储:为容器挂载
~/.copilot/session-state/ - 密钥管理:使用 Vault/K8s Secrets 管理令牌
- 会话锁定:使用 Redis 或类似工具实现共享会话访问
- 平稳关闭:停止 CLI 前,先处理完活动会话
客户端配置
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
cliPath | string | 自动检测 | Copilot CLI 可执行文件的路径 |
cliUrl | string | — | 外部 CLI 服务的 URL |
githubToken | string | — | 用于身份验证的 GitHub 令牌 |
useLoggedInUser | boolean | true | 使用已存储的 CLI 凭据 |
logLevel | string | "none" | "none" | "error" | "warning" | "info" | "debug" |
autoRestart | boolean | true | CLI 崩溃时自动重启 |
useStdio | boolean | true | 使用 stdio 传输 |
会话配置
| 选项 | 类型 | 描述 |
|---|---|---|
model | string | 要使用的模型(例如,"gpt-4.1"、"claude-sonnet-4") |
sessionId | string | 可恢复会话的自定义 ID |
streaming | boolean | 启用流式响应 |
tools | Tool[] | 自定义工具 |
mcpServers | object | MCP 服务配置 |
hooks | object | 会话钩子 |
provider | object | BYOK 提供商配置 |
customAgents | object[] | 自定义 Agent 定义 |
systemMessage | object | 系统消息覆盖配置 |
skillDirectories | string[] | 加载技能的目录 |
disabledSkills | string[] | 要禁用的技能 |
reasoningEffort | string | 推理力度级别 |
availableTools | string[] | 限制可用工具 |
excludedTools | string[] | 排除特定工具 |
infiniteSessions | object | 自动压缩配置 |
workingDirectory | string | 工作目录 |
SDK 与 CLI 功能对比
✅ SDK 中可用
会话管理、消息处理(send/sendAndWait/abort)、消息历史记录(getMessages)、自定义工具、工具权限钩子、MCP 服务(本地 + HTTP)、流式处理、模型选择、BYOK 提供商、自定义 Agent、系统消息、技能、无限会话、权限处理程序、40 多种事件类型。
❌ 仅 CLI 提供的功能
会话导出(--share)、斜杠命令、交互式 UI、终端渲染、YOLO 模式、登录/登出流程、/compact(请改用 infiniteSessions)、/usage(请改用用量事件)、/review、/delegate。
替代方案:
- 会话导出 → 使用
session.on()+session.getMessages()手动收集事件 - 权限控制 → 使用
onPermissionRequest处理程序,而不是--allow-all-paths - 上下文压缩 → 使用
infiniteSessions配置,而不是/compact
调试
启用调试日志:
const client = new CopilotClient({ logLevel: "debug" });
自定义日志目录:
const client = new CopilotClient({ cliArgs: ["--log-dir", "/path/to/logs"] });
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
CLI not found | 未安装 CLI 或 CLI 不在 PATH 中 | 安装 CLI 或设置 cliPath |
Not authenticated | 没有有效凭据 | 运行 copilot auth login 或提供 githubToken |
Session not found | 在 destroy() 后使用会话 | 使用 listSessions() 检查有效 ID |
Connection refused | CLI 进程崩溃 | 启用 autoRestart: true,检查端口冲突 |
| MCP 工具缺失 | 服务初始化失败或未启用工具 | 设置 tools: ["*"],单独测试服务 |
连接状态
console.log("State:", client.getState()); // "connected" after start()
client.on("stateChange", (state) => console.log("Changed to:", state));
主要 API 摘要
| 语言 | 客户端 | 创建会话 | 发送 | 恢复 | 停止 |
|---|---|---|---|---|---|
| Node.js | new CopilotClient() | client.createSession() | session.sendAndWait() | client.resumeSession() | client.stop() |
| Python | CopilotClient() | client.create_session() | session.send_and_wait() | client.resume_session() | client.stop() |
| Go | copilot.NewClient(nil) | client.CreateSession() | session.SendAndWait() | client.ResumeSession() | client.Stop() |
| .NET | new CopilotClient() | client.CreateSessionAsync() | session.SendAndWaitAsync() | client.ResumeSessionAsync() | client.DisposeAsync() |