尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Kimi Code CLI Web Sessions API 全解析:从 REST 接口到源码实现

Kimi Code CLI Web Sessions API 全解析:从 REST 接口到源码实现 Kimi Code CLI Web Sessions API 全解析从 REST 接口到源码实现【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cliKimi Code CLI本仓库即其核心代码内置了一个基于 FastAPI 的 Web 界面而SessionsApi正是该 Web 界面用于管理会话Session的完整 REST API 集合。本文以web/src/lib/api/docs/SessionsApi.md为骨架结合后端路由实现 src/kimi_cli/web/api/sessions.py、数据模型 src/kimi_cli/web/models.py 与前端 TypeScript 客户端 web/src/lib/api/apis/SessionsApi.ts逐接口讲解会话的创建、查询、更新、删除、文件读写、git 变更统计与 AI 标题生成帮助你在自己的应用或脚本中直接对接这套会话管理能力。一、API 总览10 个端点覆盖会话全生命周期SessionsApi 的所有请求都相对http://localhost发起统一挂载在/api/sessions/前缀之下。后端由 src/kimi_cli/web/api/sessions.py 中的APIRouter(prefix/api/sessions, tags[sessions])提供路由完整端点如下MethodHTTP requestDescriptioncreateSessionApiSessionsPostPOST/api/sessions/Create a new sessiondeleteSessionApiSessionsSessionIdDeleteDELETE/api/sessions/{session_id}Delete a sessiongenerateSessionTitleApiSessionsSessionIdGenerateTitlePostPOST/api/sessions/{session_id}/generate-titleGenerate session title using AIgetSessionApiSessionsSessionIdGetGET/api/sessions/{session_id}Get sessiongetSessionFileApiSessionsSessionIdFilesPathGetGET/api/sessions/{session_id}/files/{path}Get file or list directory from session work_dirgetSessionGitDiffApiSessionsSessionIdGitDiffGetGET/api/sessions/{session_id}/git-diffGet git diff statsgetSessionUploadFileApiSessionsSessionIdUploadsPathGetGET/api/sessions/{session_id}/uploads/{path}Get uploaded file from session uploadslistSessionsApiSessionsGetGET/api/sessions/List all sessionsupdateSessionApiSessionsSessionIdPatchPATCH/api/sessions/{session_id}Update sessionuploadSessionFileApiSessionsSessionIdFilesPostPOST/api/sessions/{session_id}/filesUpload file to session从功能上可以划分为四组会话生命周期创建POST/、查询单个GET/{session_id}、列表GET/、更新PATCH/{session_id}、删除DELETE/{session_id}工作目录文件访问读取/列目录GET/{session_id}/files/{path}、上传文件POST/{session_id}/files、读取上传文件GET/{session_id}/uploads/{path}git 仓库状态获取工作目录 diff 统计GET/{session_id}/git-diffAI 辅助基于首轮对话生成会话标题POST/{session_id}/generate-title。所有接口的Accept均为application/json其中创建、生成标题、更新接口的Content-Type为application/json上传文件接口为multipart/form-data。除 200Successful Response外所有接口都可能返回422 Validation Error对应 FastAPI/Pydantic 的请求体校验失败。二、环境与前置如何启动 Web 服务SessionsApi 运行在 kimi-cli 自带的 Web 服务进程内服务入口为 src/kimi_cli/web/app.py路由注册在 src/kimi_cli/web/api/sessions.py。启动后通过kimi web类命令拉起 FastAPI 应用默认监听本地端口Base URL 即http://localhost。从 src/kimi_cli/web/store/sessions.py 的设计说明可以看出该存储层采用cache-aside 模式读时缓存首次读取填充缓存后续读直接命中写时失效所有 API 变更操作都会调用invalidate_sessions_cache()清空缓存TTL 兜底缓存默认CACHE_TTL 5.0秒过期作为外部变更的安全网。该设计适用于单 worker 进程部署例如不带-w参数的 uvicorn所有变更都经由同一套 API 完成偶发的陈旧数据最多 5 秒是可接受的。三、会话生命周期创建、查询、列表、更新与删除3.1 创建会话POST /api/sessions/import { Configuration, SessionsApi, } from ; import type { CreateSessionApiSessionsPostRequest } from ; async function example() { const api new SessionsApi(); const body { // CreateSessionRequest (optional) createSessionRequest: { workDir: /path/to/project, createDir: false, }, } satisfies CreateSessionApiSessionsPostRequest; try { const data await api.createSessionApiSessionsPost(body); console.log(data); } catch (error) { console.error(error); } }请求体 CreateSessionRequest可选对应后端src/kimi_cli/web/api/sessions.py中CreateSessionRequest模型见 sessions.py#L358-L362字段类型说明默认值workDirstring会话工作目录支持~展开用户主目录Path.home()createDirboolean目录不存在时是否自动创建false后端行为细节sessions.py#L299-L355若work_dir不存在且create_dirFalse返回404Directory does not exist若create_dirTrue则自动mkdir(parentsTrue)权限不足返回 403其他OSError返回 400work_dir不是目录时返回 400Path is not a directory会话底层由KimiCLISession.create(work_dir...)创建session_dir落在该工作目录的会话目录中返回的 Session 包含session_id、title、lastUpdated、isRunning、status、workDir、sessionDir、archived等字段定义见 models.py#L64-L74。3.2 查询单个会话GET /api/sessions/{session_id}const body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, } satisfies GetSessionApiSessionsSessionIdGetRequest; const data await api.getSessionApiSessionsSessionIdGet(body);后端sessions.py#L285-L296按 UUID 加载会话并用 runner 中的进程状态实时回填is_running与statusSessionStatus 的state取值见 models.py#L11为stopped | idle | busy | restarting | error。会话不存在时返回null。3.3 列表查询GET /api/sessions/const body { limit: 100, // number, optional, default 100, max 500 offset: 0, // number, optional, default 0 q: kimi, // string, optional, 按 title 或 work_dir 过滤 archived: true, // boolean, optional } satisfies ListSessionsApiSessionsGetRequest; const data await api.listSessionsApiSessionsGet(body);参数语义后端见 sessions.py#L249-L282参数类型说明默认值/约束limitnumber返回的最大会话数默认 100最大 5000时回退到 100offsetnumber跳过的会话数默认 0负数钳制为 0qstring按标题或工作目录搜索可选archivedboolean归档过滤None不传只返回未归档true只返回归档可选列表接口还有两个值得注意的后端行为每次调用都会在后台触发run_auto_archive()内部节流最多每 5 分钟执行一次将超过AUTO_ARCHIVE_DAYS 15天的会话自动归档见 store/sessions.py#L39返回前会遍历每个会话用 runner 的运行态填充is_running和status因此列表天然携带实时状态。3.4 更新会话PATCH /api/sessions/{session_id}const body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, updateSessionRequest: { title: 重构认证模块, archived: true, }, } satisfies UpdateSessionApiSessionsSessionIdPatchRequest; const data await api.updateSessionApiSessionsSessionIdPatch(body);请求体 UpdateSessionRequest后端模型见 models.py#L77-L81字段类型约束说明titlestring可选min_length1, max_length200重命名会话标题archivedboolean可选归档/取消归档后端实现sessions.py#L586-L626通过load_session_state/save_session_state持久化设置title时同时标记title_generatedTrue避免后续 AI 标题覆盖手动命名归档时记录archived_at并清除auto_archive_exempt取消归档则重置并标记为免除自动归档。更新成功返回刷新后的Session。注意updateSessionRequest在文档参数表中标记为必填而sessionId为路径参数。另外该接口会先校验会话是否 busy见 3.5 的get_editable_session。3.5 删除会话DELETE /api/sessions/{session_id}const body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, } satisfies DeleteSessionApiSessionsSessionIdDeleteRequest; const data await api.deleteSessionApiSessionsSessionIdDelete(body); // any删除是物理删除后端见 sessions.py#L565-L583先停止关联的 runner 进程若该会话是该工作目录的last_session_id则清空元数据引用最后shutil.rmtree删除整个session_dir并失效会话缓存。删除与更新共用get_editable_sessionsessions.py#L110-L128——当会话正在运行busy时会返回 400Session is busy避免在任务执行中修改或删除会话。四、文件与上传工作目录访问的完整闭环4.1 读取文件或列出目录GET /api/sessions/{session_id}/files/{path}const body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, path: src/main.py, // 相对 work_dir 的路径 } satisfies GetSessionFileApiSessionsSessionIdFilesPathGetRequest; const data await api.getSessionFileApiSessionsSessionIdFilesPathGet(body);行为后端见 sessions.py#L463-L547若path指向文件返回文件内容Content-Type由mimetypes.guess_type推断并通过Content-Disposition: attachment下载若path指向目录返回 JSON 数组每项为{name, type: directory|file, size}按「目录优先、名称升序」排序size仅文件有路径解析经过resolve()后必须仍在 work_dir 内否则返回 400Invalid path: path traversal not allowed防目录穿越。4.2 上传文件POST /api/sessions/{session_id}/filesconst body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, file: BINARY_DATA_HERE, // Blob, multipart/form-data } satisfies UploadSessionFileApiSessionsSessionIdFilesPostRequest; const data await api.uploadSessionFileApiSessionsSessionIdFilesPost(body);返回 UploadSessionFileResponsepath、filename、size。后端关键实现sessions.py#L379-L413文件保存到会话目录下的uploads/子目录单文件上限 100MBMAX_UPLOAD_SIZE 100 * 1024 * 1024超限返回413File too large (max 100MB)文件名经过sanitize_filename清洗仅保留字母数字与._-字符并拼接 UUID 前缀如report_3f2a9b.pdf避免冲突与恶意文件名上传前同样经过 busy 校验。4.3 读取上传文件GET /api/sessions/{session_id}/uploads/{path}const body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, path: report_3f2a9b.pdf, } satisfies GetSessionUploadFileApiSessionsSessionIdUploadsPathGetRequest; const data await api.getSessionUploadFileApiSessionsSessionIdUploadsPathGet(body);后端sessions.py#L416-L460将path解析后限制在uploads/目录内同样防目录穿越以inline方式内联返回文件便于前端直接预览图片、PDF 等。4.4 公开访问安全策略重要实现细节getSessionFile在restrict_sensitive_apis开启时会叠加多层防护sessions.py#L159-L191路径深度限制相对路径深度超过DEFAULT_MAX_PUBLIC_PATH_DEPTH 6返回 403敏感路径拦截路径中出现.ssh、.aws、.kube、id_rsa、credentials等关键词或.pem、.key、.p12等敏感扩展名时返回 403符号链接检查路径任一组件是 symlink 则拒绝防止绕过目录限制敏感家目录检测解析后若落入~/.ssh、~/.gnupg、~/.aws、~/.kube等位置返回 403。列目录时也会过滤掉上述敏感条目避免泄露凭证类文件。五、Git 变更统计GET /api/sessions/{session_id}/git-diffconst body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, } satisfies GetSessionGitDiffApiSessionsSessionIdGitDiffGetRequest; const data await api.getSessionGitDiffApiSessionsSessionIdGitDiffGet(body);返回 GitDiffStatsisGitRepo、hasChanges、totalAdditions、totalDeletions、files: GitFileDiff[]、error其中 GitFileDiff 包含path、additions、deletions、statusadded|modified|deleted|renamed见 models.py#L42-L50。后端实现sessions.py#L1131-L1245本质上是把git命令行封装成 API工作目录没有.git时返回is_git_repoFalse通过git rev-parse --verify HEAD判断仓库是否有提交有 HEAD 时执行git diff --numstat HEAD同时覆盖已暂存与未暂存变更解析/-行数并推断文件状态只有增量为added、只有删除为deleted、否则modified再执行git ls-files --others --exclude-standard收集未跟踪的新文件以statusadded追加行数记为 0每个 git 子进程都设置了5 秒超时超时返回errorGit command timed out无 HEAD 时只汇报未跟踪文件。该接口非常适合在 Web 界面里渲染「AI 改动概览」无需本地安装额外依赖前端拿到聚合后的增减行数与文件级明细即可直接展示。六、AI 会话标题生成POST /api/sessions/{session_id}/generate-titleconst body { sessionId: 38400000-8cf0-11bd-b23e-10b96e4ef00d, // GenerateTitleRequest (optional) - 不传时后端自动从 wire.jsonl 读取首轮对话 generateTitleRequest: { userMessage: 帮我重构认证模块, assistantResponse: 好的我将从以下几个方面开始重构……, }, } satisfies GenerateSessionTitleApiSessionsSessionIdGenerateTitlePostRequest; const data await api.generateSessionTitleApiSessionsSessionIdGenerateTitlePost(body);请求体 GenerateTitleRequestuserMessage、assistantResponse均可选与响应 GenerateTitleResponsetitle的后端模型见 models.py#L84-L98。核心逻辑在 sessions.py#L749-L901去重保护若会话状态中title_generated已为真直接返回现有标题避免重复消耗 token内容兜底请求体缺参时通过extract_first_turn_from_wiresessions.py#L629-L681解析会话目录下的wire.jsonl提取首轮TurnBegin的用户输入与ContentPart文本作为候选拿不到用户消息时返回Untitled文本截断兜底将用户消息压缩为单行并用shorten(text, width50)截断到 50 字符作为 fallback 标题AI 生成使用配置的默认模型config.default_model走kosong.generatecreate_llm系统提示要求输出不超过 50 字符、无引号无解释的纯标题prompt 截取首轮对话各 300 字符对 Kimi 提供商还会用SESSION_TITLE_MAX_COMPLETION_TOKENS 512限制生成 token 数并与配置的max_completion_tokens取较小值失败重试AI 调用失败不抛错title_generate_attempts递增连续失败 3 次后直接采用截断的 fallback 标题并标记title_generatedTrue并发安全LLM 调用期间若其他请求已定稿标题则以最新状态为准read-modify-write 重新加载 state避免覆盖手动重命名。AI 成功生成时返回 AI 标题超 50 字符会被截断失败但未达 3 次时返回 fallback 标题不标记 generated允许下次重试。七、数据模型一览以下模型文档均位于 web/src/lib/api/docs与后端 Pydantic 定义models.py一一对应模型关键字段说明SessionsessionId, title, lastUpdated, isRunning, status, workDir, sessionDir, archivedWeb UI 会话元数据SessionStatussessionId, state, seq, workerId, reason, detail, updatedAt运行时状态state ∈ {stopped, idle, busy, restarting, error}CreateSessionRequestworkDir, createDir创建会话请求体UpdateSessionRequesttitle, archived更新会话请求体GenerateTitleRequestuserMessage, assistantResponseAI 标题生成请求体可空GenerateTitleResponsetitleAI 标题生成响应GitDiffStatsisGitRepo, hasChanges, totalAdditions, totalDeletions, files, error工作目录 git diff 统计GitFileDiffpath, additions, deletions, status单文件 diff 统计UploadSessionFileResponsepath, filename, size上传响应八、前端集成方式SessionsApi TypeScript 客户端web/src/lib/api/apis/SessionsApi.ts是 OpenAPI Generator 自动生成的 TypeScript 客户端561 行每个端点对应一个强类型方法如createSessionApiSessionsPost、listSessionsApiSessionsGet并预定义了形如CreateSessionApiSessionsPostRequest的请求接口SessionsApi.ts#L46-L80。前端可直接import { SessionsApi } from ../apis; import { Configuration } from ../runtime; const api new SessionsApi(new Configuration({ basePath: http://localhost })); const sessions await api.listSessionsApiSessionsGet({ limit: 50, q: kimi });结合本文第四、五节的接口一个典型的「会话浏览器」页面可以这样组织数据流listSessionsApiSessionsGet渲染会话列表标题、更新时间、运行状态、归档过滤选中会话后getSessionApiSessionsSessionIdGet拉取详情getSessionGitDiffApiSessionsSessionIdGitDiffGet展示该会话工作目录的代码改动统计getSessionFileApiSessionsSessionIdFilesPathGet浏览/预览工作目录文件generateSessionTitleApiSessionsSessionIdGenerateTitlePost为新会话自动生成标题updateSessionApiSessionsSessionIdPatch/deleteSessionApiSessionsSessionIdDelete完成重命名、归档与清理。九、错误码速查与注意事项所有接口统一的响应码状态码说明200Successful Response含Session、any、数组等400参数/状态非法路径穿越、会话 busy、目录不是文件夹等403敏感文件/符号链接/目录深度超限公开模式404会话不存在、文件不存在、目录不存在413上传文件超过 100MB422Pydantic 校验失败参数类型/范围错误如limit500会被后端钳制而非报错使用时的关键约束路径参数session_id为 UUID 格式文档示例为38400000-8cf0-11bd-b23e-10b96e4ef00d非法 UUID 会触发 422busy 会话只读更新、删除、上传、生成标题前都会检查会话是否正在运行忙碌时返回 400目录穿越防护files/{path}与uploads/{path}均经过resolve()归一化校验越界即 400多进程部署注意会话存储的 cache-aside 设计面向单 worker 进程多进程部署时缓存一致性需自行评估见 store/sessions.py 头部注释。十、小结SessionsApi 是 kimi-cli Web 界面的会话中枢它以 10 个 REST 端点完整覆盖「创建—运行—读取—更新—删除」的会话生命周期并额外提供工作目录文件浏览、上传下载、git diff 统计与 AI 标题生成等增强能力。配合后端的 FastAPI 路由sessions.py、Pydantic 模型models.py与 TypeScript 客户端SessionsApi.ts无论是构建自定义前端、编写自动化脚本还是深度定制会话管理都能找到直接可用的接口与清晰的实现参考。【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表