1. kap-server 的定位
1.1 在 kimi-code 架构中的位置
packages/kap-server是 agent-core-v2 的 HTTP 外围服务层。它不是一个独立的应用——它是引擎的"外壳",将 DI x Scope 容器内的所有能力暴露为标准化的 REST + WebSocket 接口。在 kimi-code 系统的分层结构中,它位于以下位置:
┌───────────────────────────────────────────────────────────────────┐ │ 消费者层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │ │ │ kimi-web │ │kimi-inspect│ │ pi-tui │ │ kimi-code CLI │ │ │ │ (Web UI) │ │ (调试面板)│ │ (TUI) │ │ (web/daemon) │ │ │ └─────┬─────┘ └─────┬─────┘ └────┬────┘ └─────────┬─────────┘ │ │ │ │ │ │ │ │ │ HTTP + WebSocket │ process.fork() │ │ └──────────────┴──────────────┘ │ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────┐ ┌──────────────────────────┐ │ │ │ kap-server │ │ kimi-code CLI │ │ │ │ Fastify HTTP Server + WS │ │ (Embedding Host via SDK)│ │ │ │ │ │ startServer({hostIdentity,...})│ │ │ ┌──────────────────────────┐ │ └──────────────────────────┘ │ │ │ │ agent-core-v2 (Core) │ │ │ │ │ │ DI × Scope 容器 │ │ │ │ │ └──────────────────────────┘ │ │ │ └─────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘kap-server 是 kimi-web(Web 前端)和 kimi-inspect(调试面板)的后端。CLI 的kimi web命令本质上就是启动一个 kap-server 实例并将 web 静态资源挂载上去。每当用户在浏览器中打开 Web UI、提交 Prompt、查看会话记录、或者调试面板通过 RPC 调用引擎内部服务时,请求都先到达 kap-server。
1.2 核心职责
- 会话管理:创建、列表、更新、归档、fork、compact、undo、abort 会话
- Prompt 提交:接收用户输入、图片附件、文件引用,转发给引擎调度
- 事件广播:通过 WebSocket 实时推送会话事件(每个 token、工具调用、审批请求)
- 文件操作:上传/下载、工作空间文件系统浏览
- 审批与问题:工具审批流、Agent 问题交互
- 配置与模型:暴露 provider 和 model 目录、用户配置读写
- 认证与安全:Bearer Token 认证、Host/Origin 校验、速率限制
2. 技术栈全景
2.1 核心依赖
| 技术 | 角色 | 说明 |
|---|---|---|
| Fastify | HTTP 框架 | 高性能 Node.js Web 框架,内置日志(Pino)、Schema 验证、插件系统 |
| agent-core-v2 | 引擎核心 | DI x Scope 容器,提供 ISessionLifecycleService、IAgentPromptService 等全部引擎服务 |
| transcript | 会话数据层 | TranscriptStore 分级存储、WireRecord 持久化、实时增量投影 |
| @fastify/swagger | API 文档 | 从 Zod Schema 自动生成 OpenAPI 3.0 文档,暴露 /openapi.json |
| WebSocket (ws) | 实时通道 | 基于ws库的 WebSocket 服务器,noServer 模式与 Fastify 共享 HTTP Server |
| ulid | ID 生成 | 连接 ID、Server ID 的唯一标识 |
| Zod | 验证层 | 类型安全的请求/响应 Schema 验证,同时驱动 Swagger 文档生成 |
2.2 defineRoute:声明式路由定义
kap-server 没有使用 Fastify 原生的 AJV 验证。它通过自研的defineRoute中间件实现了一套声明式路由系统:一个对象同时声明 Zod Schema(运行时验证)和 OpenAPI Schema(Swagger 文档)。
// packages/kap-server/src/routes/prompts.ts const submitRoute = defineRoute( { method: 'POST', path: '/sessions/{session_id}/prompts', body: promptSubmissionSchema, // Zod — 运行时验证 params: sessionIdParamSchema, success: { data: promptSubmitResultSchema }, // 成功响应 errors: { 40001: { detailsSchema: z.array(/* ... */) }, // 校验失败 40401: {}, // 会话不存在 }, description: 'Submit a prompt to a session', tags: ['prompts'], }, async (req, reply) => { // req.body → PromptSubmission (自动推断) // req.params → { session_id: string } // ... }, ); app.post(submitRoute.path, submitRoute.options, submitRoute.handler);这套系统带来的好处:
- 类型安全:Handler 中的
req.body和req.params自动推断为正确的 Zod 类型 - 统一错误格式:200 响应中通过
oneOf包含成功信封和所有可能的错误信封 - 文档即代码:定义 route 的同时就完成了 OpenAPI 文档的声明
- 零运行时开销:验证只在 preHandler 层执行一次
2.3 统一信封格式
所有 REST 响应都包裹在统一的信封中:
// packages/kap-server/src/protocol/envelope.ts interface Envelope<T> { code: number; // 0 = 成功,4xxxx/5xxxx = 业务错误 msg: string; // 'success' 或错误描述 data: T | null; // 业务数据 request_id: string; // 请求追踪 ID details?: unknown; // 结构化错误详情 stack?: string; // 堆栈信息(仅错误时) }code=0 表示成功,非零值为业务错误码。这与 HTTP 状态码分离——所有 kap-server 响应都是 HTTP 200,真正的结果通过信封中的code字段传达。Fastify 的 access log 因此被禁用,由 kap-server 自有的请求日志替代。
3. REST API 路由体系
3.1 路由注册总览
所有路由通过registerApiV1Routes统一注册,挂载在/api/v1前缀下。
// packages/kap-server/src/routes/registerApiV1Routes.ts export async function registerApiV1Routes(app, core, opts) { await app.register(async (apiV1) => { registerHealthRoute(apiV1); // /healthz registerMetaRoute(apiV1); // /meta registerAuthRoute(apiV1, core); // /auth/* registerOAuthRoutes(apiV1, core); // /oauth/* registerConfigRoutes(apiV1, core); // /config/* registerModelCatalogRoutes(apiV1); // /models, /providers registerSessionsRoutes(apiV1, core); // /sessions registerPromptRoutes(apiV1, core); // /sessions/:id/prompts registerMessagesRoutes(apiV1, core); // /sessions/:id/messages registerApprovalsRoutes(apiV1, core); // /sessions/:id/approvals registerQuestionsRoutes(apiV1, core); // /sessions/:id/questions registerWorkspacesRoutes(apiV1); // /workspaces registerFilesRoutes(apiV1, core); // /files registerFsRoutes(apiV1, core); // /fs registerToolsRoutes(apiV1, core); // /tools registerTasksRoutes(apiV1, core); // /sessions/:id/tasks registerTerminalsRoutes(apiV1, core); // /terminals registerSkillsRoutes(apiV1, core); // /skills registerTranscriptRoutes(apiV1); // /sessions/:id/transcript registerSearchRoutes(apiV1, core); // /search // ... 调试、快照、shutdown 等 }, { prefix: '/api/v1' }); }3.2 核心路由详解
会话管理 —/api/v1/sessions
会话路由是 kap-server 最复杂的路由模块,实现了 v1 的完整 wire contract:
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /sessions | 创建新会话(需 workspace_id 或 metadata.cwd) |
| GET | /sessions | 列表会话(支持 before_id/after_id 游标分页、workspace_id/status 过滤) |
| GET | /sessions/:id | 获取单个会话 |
| POST | /sessions/:id/profile | 更新标题、metadata、agent_config |
| GET | /sessions/:id/children | 列出子会话 |
| POST | /sessions/:id/children | 创建子会话(fork + tag) |
| POST | /sessions/:id/fork | Fork 会话(复制上下文到新会话) |
| POST | /sessions/:id/compact | 触发上下文压缩 |
| POST | /sessions/:id/undo | 撤销最后 N 轮对话 |
| POST | /sessions/:id/abort | 取消当前正在运行的 turn |
| POST | /sessions/:id/archive | 归档会话 |
| POST | /sessions/:id/restore | 恢复已归档会话 |
| POST | /sessions/:id/btw | 启动后台 Agent(side-channel) |
这些 action 路由通过统一的/sessions/{tail}模式处理——parseActionSuffix从 tail 中解析出{ session_id, action },然后 dispatch 到对应的引擎服务。
Prompt 提交 —/api/v1/sessions/:id/prompts
Prompt 路由处理用户输入的全流程:
- 会话恢复:通过
resumeSessionById获取或冷加载会话 Scope - 图片处理:提取 ContentPart 中的 base64 图片、解析
kimi-file://URL、压缩为模型可接受的尺寸 - 权限与策略:应用
IAgentPermissionModeService和IAgentToolPolicyService - Profile 绑定:通过
IAgentProfileService解析系统提示、工具集、Skills - 调度执行:调用
IAgentPromptService.prompt()启动一次 turn - 事件广播:引擎产生的 token 流、工具调用、结果等事件通过 WebSocket 实时推送给前端
工作空间管理 —/api/v1/workspaces
工作空间路由负责目录注册和文件浏览:
GET /workspaces— 列表所有已注册的工作空间(从IWorkspaceService读取)POST /workspaces/register— 注册新目录为工作空间GET /workspaces/:id/files— 浏览工作空间目录树(folder picker)
4. WebSocket 实时通信
4.1 WebSocket 端点与升级流程
kap-server 在/api/v1/ws端点提供 WebSocket 实时通信。与传统的独立 WebSocket 服务器不同,它使用ws库的 noServer 模式——WebSocket 服务器不监听独立端口,而是挂载在 Fastify 的 HTTP Server 上,通过监听upgrade事件处理 WebSocket 握手。
// packages/kap-server/src/start.ts const wssV1 = registerWsV1(core, { validateCredential, registry: connectionRegistry, broadcaster, fsWatchBridge, logger, }); app.server.on('upgrade', (req, socket, head) => { void handleUpgrade(req, socket, head).catch((error) => logger.error({ err: error }, 'ws upgrade handler failed'), ); });升级流程中会执行与 HTTP 路由相同的安全检查:Host/Origin 校验、Bearer Token 认证。所有检查通过后,WebSocket 连接才被建立。
4.2 WsConnectionV1:连接级协议
每个 WebSocket 连接由WsConnectionV1实例管理,该实例实现了BroadcastTarget接口,能够接收来自SessionEventBroadcaster的事件并转发给客户端。
连接建立后,服务器立即发送server_hello帧:
// packages/kap-server/src/transport/ws/v1/wsConnectionV1.ts this.sendImmediateFrame( buildServerHello({ ws_connection_id: this.id, protocol_version: WS_PROTOCOL_VERSION, max_event_buffer_size: this.maxBufferSize, capabilities: { event_batching: false, compression: false }, }), );4.3 控制帧协议
客户端通过 JSON 帧与服务器通信,支持以下控制帧类型:
| 帧类型 | 方向 | 说明 |
|---|---|---|
| server_hello | Server→Client | 连接建立后立即发送,宣告协议版本和能力 |
| client_hello | Client→Server | 客户端握手,可携带 initial subscriptions 和 cursors |
| subscribe | Client→Server | 订阅会话事件,指定 session_id + agents + 事件游标 |
| subscribe_v2 | Client→Server | v2 订阅:按 transcript grade 分级订阅(text、tool_call、thinking 等) |
| unsubscribe | Client→Server | 取消订阅指定会话 |
| unsubscribe_v2 | Client→Server | 取消 v2 的分级订阅 |
| ack | Server→Client | 确认客户端的事件序列号 |
| resync_required | Server→Client | 服务器无法增量补齐事件,客户端需全量重同步 |
| watch_fs_add | Client→Server | 请求监听文件系统变更 |
| watch_fs_remove | Client→Server | 取消文件系统监听 |
4.4 事件广播机制
SessionEventBroadcaster是事件分发的核心。它维护一个持久化的事件日志(SessionEventJournal),每个会话事件被写入日志后广播给所有订阅该会话的连接。
事件分发分为两个通道:
- Global 通道:全局事件(session created/deleted、workspace 变更、配置更新)推送给所有已建立连接的客户端,无需订阅
- Subscription 通道:会话级事件(token 增量、工具调用、审批请求)仅推送给已订阅该会话的连接
4.5 事件缓冲与背压控制
高频事件(尤其是 token 级别的文本增量)如果逐帧发送会造成大量小包。WsConnectionV1 使用了一个发送缓冲区:
- 订阅事件的发送采用 16ms 刷新间隔(约 60fps),支持最多 64 帧的批量发送
- 立即帧(公共事件、控制帧响应)作为 FIFO 屏障,会先刷新缓冲区中的订阅帧
- 当
socket.bufferedAmount超过 1 MiB 时触发背压,延迟发送直到缓冲区清空
// 默认参数 const DEFAULT_FLUSH_INTERVAL_MS = 16; // 刷新间隔(约 60fps) const DEFAULT_MAX_BATCH_SIZE = 64; // 单批最大帧数 const DEFAULT_HIGH_WATER_MARK_BYTES = 1 << 20; // 1 MiB const DEFAULT_BACKPRESSURE_RETRY_MS = 5;4.6 Transcript 增量同步
connect_v2 的subscribe_v2帧引入了按Transcript Grade的分级订阅。客户端可以只订阅自己关心的 Grade(如text、tool_call、thinking),服务器只推送对应类型的事件。这大幅减少了不必要的数据传输,尤其是在长对话场景下。
TranscriptService为每个活跃会话维护一个TranscriptStore,引擎产生的每个 WireRecord 都会实时投影到 Store 中。当 WebSocket 客户端订阅某个 Grade 时,Store 会从客户端的游标位置开始增量推送,如果游标落后太多则发送resync_required要求客户端执行全量重同步。
5. 会话生命周期管理
5.1 会话创建流程
会话创建是 kap-server 中最关键的流程之一。从 REST 请求到引擎实例化,涉及多个步骤:
// packages/kap-server/src/routes/sessions.ts — POST /sessions async (req, reply) => { // 1. 解析 cwd:从 workspace_id 或 metadata.cwd 中获取工作目录 const workDir = workspaceId ? workspace.root : body.metadata.cwd; // 2. 注册工作空间(createOrTouch 是幂等的) const touched = await core.accessor.get(IWorkspaceService).createOrTouch(workDir); // 3. 获取工作空间的生命周期 handler const handler = await core.accessor.get(IWorkspaceLifecycleService).handlerFor({ root: workDir }); // 4. 通过 handler 的 SessionLifecycleService 创建会话 const handle = await handler.accessor.get(ISessionLifecycleService).create({ workDir }); // 5. 设置标题、读取元数据 await handle.accessor.get(ISessionMetadata).setTitle(body.title); const meta = await handle.accessor.get(ISessionMetadata).read(); // 6. 发布 session.created 事件(WebSocket 广播) core.accessor.get(IEventService).publish({ type: 'event.session.created', payload: { agentId: 'main', sessionId: session.id, session }, }); }5.2 Session Store 持久化
kap-server 的会话数据持久化完全委托给 agent-core-v2 引擎。在bootstrap()阶段,引擎通过IFileSystemStorageService将存储根路径设定为<homeDir>。所有会话相关的持久化:
- 元数据:通过
ISessionMetadata保存到 append-log 中(id、title、createdAt、custom metadata) - 会话索引:
ISessionIndex维护FileSessionIndex,按 recency 排序 - Wire Records:每个 Agent 的消息、工具调用、任务状态等以 JSONL 格式写入
agents/<agentId>/wire.jsonl - 二进制数据:上传的文件、图片等通过
IBlobStorageService存储
会话的cwd保存在ISessionMetadata的自定义字段中(gap G3 关闭)。即使工作空间被注销,会话仍然可以通过自有的 cwd 信息被列出和访问。
5.3 多 Agent 支持
kap-server 的会话模型支持多个 Agent 共存:
- Main Agent:每个会话默认有一个主 Agent,负责接收用户 Prompt 并生成回复
- Subagents / Side-channel:通过
POST /sessions/:id/btw启动后台 Agent,可以在不干扰主会话的情况下执行独立任务 - Children Sessions:通过
POST /sessions/:id/children创建子会话(fork + parent_tag)
每个 Agent 都是一个独立的 Scope 实例,拥有自己的上下文记忆(IAgentContextMemoryService)、工具集和生命周期。WebSocket 的subscribe帧通过agents字段指定订阅哪些 Agent 的事件。全局搜索扫描所有 Agent 的 WireRecord。
5.4 会话的暂停、恢复与 Fork
kap-server 中的会话并非始终在内存中。当连接断开或会话空闲时,会话 Scope 可以被释放;当客户端再次访问时,通过resumeSessionById从磁盘重建。
Fork 操作在ISessionLifecycleService.fork()中实现——它会创建一个新会话,复制源会话的上下文历史(作为系统消息注入),使新会话继承源会话的全部对话上下文但拥有独立的对话未来。
6. V2 引擎集成
6.1 引擎初始化
kap-server 在startServer()中通过agent-core-v2的bootstrap()函数创建 Core Scope:
// packages/kap-server/src/start.ts const { app: core } = bootstrap( { homeDir, configPath, clientIdentity: opts.hostIdentity, }, [ ...logSeed(logging), // 日志配置 ...hostRequestHeadersSeed(kimiHeaders), // HTTP 请求头 ...skillCatalogRuntimeOptionsSeed(skillDirs), // Skill 目录 ...hostIdentitySeed(opts.hostIdentity), // 宿主身份 ...(opts.seeds ?? []), // 额外配置 ], );bootstrap()返回的core是一个 App 级别的 Scope,它包含了所有引擎服务的注册。kap-server 的每个路由 handler 都通过core.accessor.get(ISomeService)获取需要的引擎服务实例。
6.2 DI x Scope 在服务层的应用
kap-server 不直接持有引擎状态——所有状态都在 Scope 层次结构中:
App Scope (core) ├── ISessionIndex — 全局会话索引 ├── IWorkspaceService — 工作空间注册表 ├── IConfigService — 配置读写 ├── IEventService — 事件总线 ├── IProviderDiscoveryService — Provider 发现 ├── IWorkspaceLifecycleService │ └── handlerFor(root) → Workspace Scope │ ├── ISessionLifecycleService — 会话的创建/fork/归档 │ │ └── create({ workDir }) → Session Scope │ │ ├── ISessionMetadata — 会话元数据 │ │ ├── ISessionContext — cwd、workspaceId │ │ ├── IAgentLifecycleService — Agent 生命周期 │ │ │ └── createMainAgent() → Agent Scope │ │ │ ├── IAgentPromptService — Prompt 处理 │ │ │ ├── IAgentContextMemoryService — 对话历史 │ │ │ ├── IAgentToolPolicyService — 工具策略 │ │ │ ├── IAgentLoopService — Agent 循环 │ │ │ └── ... │ │ └── ... │ └── ... └── ...这种三级嵌套 DI 的语义是:App 级别的服务是全局单例,Workspace 级别的服务在同一个工作空间的所有会话之间共享,Session 和 Agent 级别的服务是每个会话/Agent 独立的。kap-server 路由 handler 从 App Scope 进入,通过handlerFor、resumeSessionById、ensureMainAgent等函数逐步下沉到更细粒度的 Scope。
6.3 请求 → Agent → 响应的完整路径
以用户提交一个 Prompt 为例,完整路径如下:
POST /api/v1/sessions/abc/prompts (HTTP) │ ▼ registerPromptsRoutes → defineRoute (Zod 验证 body/params) │ ▼ resumeSessionById(core.accessor, sessionId) — 获取/冷加载 Session Scope │ ▼ ensureMainAgent(session) — 获取 Main Agent Scope │ ▼ IAgentPromptService.prompt(content, options) — 调度执行 │ ├─→ IAgentLoopService — Agent 循环(think → act → observe) │ │ │ ├─→ LLM 调用 → token 流 │ ├─→ Tool 调用 → Bash / File / Search ... │ └─→ 事件发射 → IEventService.publish(...) │ ▼ SessionEventBroadcaster — 事件持久化 + 广播 │ ├─→ SessionEventJournal — 写入事件日志 └─→ WebSocket 推送 — 分发给所有订阅的客户端 │ ▼ kimi-web / kimi-inspect — 实时渲染6.4 引擎事件的 WebSocket 转发
引擎的IEventService是事件源。kap-server 的SessionEventBroadcaster订阅引擎事件总线的session.*前缀事件:
- **agent.***:
agent.turn_started、agent.turn_ended、agent.text_delta、agent.tool_call等 — 推送给订阅了该会话的 WebSocket 连接 - **session.***:
session.created、session.meta.updated、session.archived— 全局广播 - **workspace.***:
workspace.created、workspace.deleted— 全局广播
TranscriptService在这些事件的基础上构建 TranscriptStore,将原始事件转换为结构化的 Transcript 操作(upsert、reset),供 REST transcript 端点和 WebSocket 的subscribe_v2使用。
7. 多引擎支持
7.1 V1 与 V2 的架构差异
kap-server 是 agent-core-v2 引擎的服务层,但 kimi-code 历史上还有一个基于agent-core(V1) 的服务器(packages/server)。两者的架构差异显著:
| 对比维度 | V1 Server (agent-core) | V2 Server (kap-server) |
|---|---|---|
| DI 容器 | IInstantiationService(扁平 DI) | DI × Scope(三级嵌套 DI) |
| 事件模型 | EventEmitter + wsGatewayService | IEventService + SessionEventBroadcaster |
| 会话存储 | SessionService(单文件) | ISessionMetadata + FileSessionIndex + WireRecord |
| Agent 模型 | 单一 Agent | 多 Agent(main + subagent + children) |
| Transcript | 无标准 Transcript | TranscriptStore + Grade 分级订阅 |
| 路由定义 | Express 风格 | defineRoute(Zod → Swagger) |
7.2 引擎切换机制
在 kimi-code CLI 中,引擎切换通过配置项控制:
- KIMI_CODE_USE_V2:环境变量,
"1"启用 V2 引擎 - config.json:配置文件中的
engine_version字段 - CLI flag:
--use-v2命令行参数
当 V2 引擎被激活时,CLI 的kimi web命令调用startServer启动 kap-server;否则启动 V1 Server。两者的/api/v1接口保持兼容,kimi-web 前端无需感知后端是哪个版本——它通过同一个 API 路径与任一引擎通信。
7.3 开发模式下的双引擎调试
在开发模式下,可以同时运行 V1 和 V2 引擎的服务器:
- V1 Server 默认在 58627 端口
- V2 (kap-server) 默认也在 58627 端口,使用 port+1 重试机制:如果端口被占用,自动尝试 58628、58629……最多重试 100 次
- 两个服务器通过
instanceRegistry独立注册在<homeDir>/server/instances/下,互不冲突
这种设计使得在迁移期间,前端可以同时连接两个后端进行对比测试。每个 kap-server 实例的注册信息(PID、host、port、启动时间、serverVersion)以 JSON 文件持久化,kimi server ps和kimi server kill命令可以列出和管理所有实例。
8. 调试接口
8.1 Debug RPC 接口
kap-server 提供了一套完整的调试 RPC 接口,挂载在/api/v1/debug/*路径下。该接口仅在以下条件同时满足时启用:
- 启动时传入
--debug-endpoints参数 - 服务器绑定在 loopback 地址(127.0.0.1)
- 请确保携带有效的 Bearer Token
// packages/kap-server/src/start.ts const debugEndpoints = exposureClass === 'loopback' && opts.debugEndpoints === true; // ... if (debugEndpoints === true) { registerDebugRoutes(apiV1, core); }这些限制确保了调试接口不会在非安全环境下暴露——它允许调用者访问引擎内部的所有 Service,是具有完全权限的管理接口。
8.2 DI 容器反射
Debug 路由实际注册的是registerServiceDispatcherRoutes——一个基于 DI 反射的 Service 调度器:
// packages/kap-server/src/transport/registerDebugRoutes.ts export function registerDebugRoutes(app, core) { registerServiceDispatcherRoutes(app, core, '/debug', { lookup: resolveAnyScopedServiceId, // 跨所有 Scope 查找 Service describe: describeAllChannels, // 列出所有可用的 RPC 通道 }); }resolveAnyScopedServiceId不仅能在 App Scope 中查找 Service,还能穿透 Session 和 Agent Scope——通过session_id和agent_id参数定位到正确的嵌套 Scope,然后从中取出目标 Service 实例。
describeAllChannels暴露了所有可调用服务通道的完整列表,包括每个通道的输入/输出 Schema 和描述信息。这实际上是一个运行时的 DI 容器反射 API。
8.3 Service 面板
kimi-inspect 调试面板正是通过这组 Debug RPC 接口与 kap-server 交互。它提供两种核心操作:
- **数据查询(GET)**:读取 Service 的当前状态。例如读取
IAgentContextMemoryService的对话历史、ISessionMetadata的元数据、IConfigService的当前配置 - **触发按钮(POST)**:调用 Service 的方法。例如触发 compaction、重置对话上下文、切换 permission mode
典型的 debug 请求路径为/api/v1/debug/<serviceId>/<method>,其中serviceId是 DI 注册的 Service 唯一标识,method是 Service 暴露的 RPC 方法名。
8.4 kimi-inspect 的消费模式
kimi-inspect 是一个独立的 Web 应用,它作为 kap-server 的客户端运行。它通过以下方式消费调试接口:
- 启动时:调用
describeAllChannels获取完整的 Service 清单,构建左侧导航树 - 选中 Service 时:自动调用该 Service 的只读方法来填充数据面板
- 用户点击按钮时:发送 POST 请求调用对应的 RPC 方法
- 实时更新:通过 WebSocket 订阅会话事件,面板中的数据实时刷新
这种设计使得 kimi-inspect 成为一个完全动态的调试工具——它不需要硬编码任何 Service 的名称或方法,所有能力都通过运行时的 DI 反射发现。