跳转到主要内容

RPC(Remote Procedure Call)

在官方 SDK 中,近期的新功能都通过基于 api.schema.json 的自动代码生成来支持。Laravel 版参考生成后的其他语言版本,以相同方式实现。

ServerRpc

绑定到 Client 的 RPC 类。
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\Rpc\ModelList;

// 获取模型列表
// 返回值是 ModelList
$result = Copilot::client()->rpc()->models()->list();
// models 是 ModelInfo 的数组
$models = $result->models;

// 与最初就存在的 listModels() 几乎相同
// 返回值是 ModelInfo 的数组
Copilot::client()->listModels();
原来 SDK 就包含的功能,在自动代码生成版本中也再次加入。

方法列表

Copilot::client()->rpc()->ping();

// models
Copilot::client()->rpc()->models()->list();
// 使用每个会话独立的 GitHub token 获取
Copilot::client()->rpc()->models()->list(new ModelsListRequest(gitHubToken: $token));

// tools
Copilot::client()->rpc()->tools()->list();

// account
Copilot::client()->rpc()->account()->getQuota();
// 使用每个会话独立的 GitHub token 获取
Copilot::client()->rpc()->account()->getQuota(new AccountGetQuotaRequest(gitHubToken: $token));

// mcp config (MCP 服务器配置的管理)
Copilot::client()->rpc()->mcp()->list();
Copilot::client()->rpc()->mcp()->add(new McpConfigAddRequest(
    name: 'my-server',
    config: new McpServerValue(type: 'local', command: 'php', args: ['artisan', 'mcp']),
));
Copilot::client()->rpc()->mcp()->update(new McpConfigUpdateRequest(
    name: 'my-server',
    config: new McpServerValue(type: 'http', url: 'https://mcp.example.com'),
));
Copilot::client()->rpc()->mcp()->remove(new McpConfigRemoveRequest(name: 'my-server'));
// 启用 / 禁用 MCP 服务器(全局配置)
Copilot::client()->rpc()->mcp()->enable(new McpConfigEnableRequest(names: ['my-server']));
Copilot::client()->rpc()->mcp()->disable(new McpConfigDisableRequest(names: ['my-server']));

// mcp discover (MCP 服务器的自动发现)
Copilot::client()->rpc()->mcp()->discover(new McpDiscoverRequest(
    workingDirectory: '/path/to/project',
));
// 也可以不带参数执行
$result = Copilot::client()->rpc()->mcp()->discover();
// $result->servers is an array of DiscoveredMcpServer

// sessionFs (注册会话文件系统提供者)
Copilot::client()->rpc()->sessionFs()->setProvider(new SessionFsSetProviderRequest(
    initialCwd: '/path/to/project',
    sessionStatePath: '.copilot/sessions',
    conventions: 'posix',
));

// sessions (experimental: 会话的 fork)
Copilot::client()->rpc()->sessions()->fork(new SessionsForkRequest(
    sessionId: 'source-session-id',
    toEventId: 'evt-boundary', // 可选:只包含该 ID 之前的事件
));

// skills (服务器级的技能管理)
// 技能发现
$result = Copilot::client()->rpc()->skills()->discover();
// $result->skills 是 ServerSkill 的数组
// 可选地指定项目路径
$result = Copilot::client()->rpc()->skills()->discover(new SkillsDiscoverRequest(
    projectPaths: ['/path/to/project'],
    skillDirectories: ['/custom/skills'],
));

// 设置要禁用的技能
Copilot::client()->rpc()->skills()->config()->setDisabledSkills(
    new SkillsConfigSetDisabledSkillsRequest(disabledSkills: ['skill-name'])
);

SessionRpc

绑定到 Session 的 RPC 类。 也可以使用之前 SDK 无法使用的 plan 模式等。
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\Rpc\ModeSetRequest;
use Revolution\Copilot\Types\Rpc\PlanReadResult;

Copilot::start(function (CopilotSession $session) {
    $session->rpc()->mode()->set(new ModeSetRequest(mode: 'plan'));

    $response = $session->sendAndWait(prompt: '创建 ○○ 的计划');

    $result = $session->rpc()->plan()->read();
    dump($result->content);

    $session->rpc()->mode()->set(new ModeSetRequest(mode: 'autopilot'));

    $response = $session->sendAndWait(prompt: '按计划实现');
    dump($response->content());
});

方法列表

// model
$session->rpc()->model()->getCurrent();
$session->rpc()->model()->switchTo(new ModelSwitchToRequest(modelId: 'gpt-4'));
// 指定 reasoningEffort 时(仅支持模型)
$session->rpc()->model()->switchTo(new ModelSwitchToRequest(modelId: 'claude-opus-4.7', reasoningEffort: ReasoningEffort::HIGH));
// 覆盖 modelCapabilities 时
$session->rpc()->model()->switchTo(new ModelSwitchToRequest(
    modelId: 'gpt-4',
    modelCapabilities: new ModelCapabilitiesOverride(
        supports: new ModelCapabilitiesOverrideSupports(vision: true),
    ),
));

// 使用 setModel() 辅助函数同样可以指定 reasoningEffort 和 modelCapabilities
$session->setModel('claude-opus-4.7', ReasoningEffort::HIGH);
$session->setModel('claude-opus-4.7', 'high'); // String is also supported
$session->setModel('gpt-4', modelCapabilities: ['supports' => ['vision' => true]]); // 也可以用数组指定

// mode
$session->rpc()->mode()->get();
$session->rpc()->mode()->set(new ModeSetRequest(mode: 'plan'));

// name
$session->rpc()->name()->get();
$session->rpc()->name()->set(new NameSetRequest(name: 'My Session'));

// plan
$session->rpc()->plan()->read();
$session->rpc()->plan()->update(new PlanUpdateRequest(content: '...'));
$session->rpc()->plan()->delete();

// workspaces
$session->rpc()->workspaces()->getWorkspace();
$session->rpc()->workspaces()->listFiles();
$session->rpc()->workspaces()->readFile(new WorkspacesReadFileRequest(path: 'file.txt'));
$session->rpc()->workspaces()->createFile(new WorkspacesCreateFileRequest(path: 'file.txt', content: '...'));

// instructions (获取会话的 instruction 来源)
$result = $session->rpc()->instructions()->getSources();
// $result->sources - InstructionsSources 的数组

// fleet
$session->rpc()->fleet()->start(new FleetStartRequest(prompt: '...'));
// 详情请参考 Fleet Mode

// agent
$session->rpc()->agent()->list();
$session->rpc()->agent()->getCurrent();
$session->rpc()->agent()->select(new AgentSelectRequest(agentId: '...'));
$session->rpc()->agent()->deselect();
$session->rpc()->agent()->reload();

// skills (experimental: 技能的管理)
$session->rpc()->skills()->list();
$session->rpc()->skills()->enable(new SkillsEnableRequest(name: 'skill-name'));
$session->rpc()->skills()->disable(new SkillsDisableRequest(name: 'skill-name'));
$session->rpc()->skills()->reload();

// mcp (experimental: MCP 服务器的管理)
$session->rpc()->mcp()->list();
$session->rpc()->mcp()->enable(new McpEnableRequest(serverName: 'server-name'));
$session->rpc()->mcp()->disable(new McpDisableRequest(serverName: 'server-name'));
$session->rpc()->mcp()->reload();
// MCP OAuth 登录(面向需要认证的 MCP 服务器)
$result = $session->rpc()->mcp()->login(new McpOauthLoginRequest(serverName: 'my-server'));
// $result->authorizationUrl - OAuth 流程的 URL(在需要认证时)

// plugins (experimental: 插件列表)
$session->rpc()->plugins()->list();

// extensions (experimental: 扩展的管理)
$session->rpc()->extensions()->list();
$session->rpc()->extensions()->enable(new ExtensionsEnableRequest(id: 'project:my-ext'));
$session->rpc()->extensions()->disable(new ExtensionsDisableRequest(id: 'project:my-ext'));
$session->rpc()->extensions()->reload();

// compaction → 更名为 history
$session->rpc()->history()->compact();
// 截断特定事件之后的历史
$session->rpc()->history()->truncate(new HistoryTruncateRequest(
    eventId: 'evt-123', // 该事件及其之后的所有事件都会被删除
));

// tools (协议 v3+: 响应 external_tool.requested 事件)
$session->rpc()->tools()->handlePendingToolCall(new ToolsHandlePendingToolCallRequest(
    requestId: '...',
    result: '工具的执行结果',
));

// permissions (协议 v3+: 响应 permission.requested 事件)
$session->rpc()->permissions()->handlePendingPermissionRequest(new PermissionDecisionRequest(
    requestId: '...',
    result: PermissionRequestResultKind::approveOnce(),
));
// 自动批准会话内所有的权限请求
$session->rpc()->permissions()->setApproveAll(new PermissionsSetApproveAllRequest(enabled: true));
// 重置会话作用域的权限批准
$session->rpc()->permissions()->resetSessionApprovals();

// commands: 响应命令调用事件
$session->rpc()->commands()->handlePendingCommand(new CommandsHandlePendingCommandRequest(
    requestId: '...',
));

// ui: 响应 UI elicitation 请求
$session->rpc()->ui()->elicitation(new UIElicitationRequest(
    message: '向用户提问',
    requestedSchema: ['type' => 'object', 'properties' => [...]],
));

// ui: 响应待处理的 elicitation 请求(经由 elicitation.requested 事件)
$session->rpc()->ui()->handlePendingElicitation(new UIHandlePendingElicitationRequest(
    requestId: '...',
    result: ['action' => 'accept', 'content' => ['name' => 'John']],
));

// log: 将消息记录到会话时间线
$session->rpc()->log()->log(new LogRequest(message: '开始处理'));
$session->rpc()->log()->log(new LogRequest(message: '磁盘用量较多', level: LogLevel::WARNING));
$session->rpc()->log()->log(new LogRequest(message: '发生了错误', level: LogLevel::ERROR));
$session->rpc()->log()->log(new LogRequest(message: '调试信息', ephemeral: true));

// shell: 在会话内执行 shell 命令
$result = $session->rpc()->shell()->exec(new ShellExecRequest(command: 'ls -la'));
// 通过 $result->processId 获取进程 ID 用于 kill 或输出追踪

$session->rpc()->shell()->exec(new ShellExecRequest(
    command: 'npm test',
    cwd: '/path/to/project',
    timeout: 60000, // 毫秒
));

// 停止运行中的 shell 进程
$session->rpc()->shell()->kill(new ShellKillRequest(
    processId: $result->processId,
    signal: 'SIGTERM', // SIGTERM(默认), SIGKILL, SIGINT
));

// usage (experimental: 会话使用量指标)
$metrics = $session->rpc()->usage()->getMetrics();
// $metrics->totalPremiumRequestCost - premium 请求的总成本
// $metrics->totalUserRequests - 用户请求总数
// $metrics->codeChanges - 代码变更指标(新增行数、删除行数、变更文件数)
// $metrics->modelMetrics - 每个模型的 token 使用量和请求数
// $metrics->currentModel - 当前的模型标识

// auth: 获取会话的认证状态
$status = $session->rpc()->auth()->getStatus();
// $status->isAuthenticated - 是否已认证
// $status->authType - 认证类型(AuthInfoType enum: gh-cli, token, env 等)
// $status->login - GitHub 登录名
// $status->host - GitHub host
// $status->copilotPlan - Copilot 套餐(individual, business 等)
// $status->statusMessage - 认证状态的消息

SessionFS 回调类型

为会话作用域的文件系统操作定义了回调类型(Request/Result)。这些是 Copilot CLI 向客户端回调时的请求 / 响应类型。
类型类用途
SessionFsReadFileRequest / SessionFsReadFileResult文件读取
SessionFsWriteFileRequest文件写入
SessionFsAppendFileRequest文件追加
SessionFsExistsRequest / SessionFsExistsResult文件存在性检查
SessionFsStatRequest / SessionFsStatResult获取文件元数据
SessionFsMkdirRequest创建目录
SessionFsReaddirRequest / SessionFsReaddirResult目录列表
SessionFsReaddirWithTypesRequest / SessionFsReaddirWithTypesResult带类型的目录列表
SessionFsRmRequest删除文件 / 目录
SessionFsRenameRequest重命名文件 / 目录
这些类型类位于 src/Types/Rpc/

以数组形式指定参数

参数和返回值都使用专用类,但参数也可以用数组指定。
$session->rpc()->mode()->set(['mode' => 'plan']);

测试

由于无法使用 Copilot::fake() 的 mock,请使用 Copilot::expects('client')Copilot::expects('start') 进行 mock。
最新信息请参考 GitHub 仓库
最后修改于 2026年7月13日