csdn-private-ai
v0.0.4
Published
在 VS Code 侧边栏中复用 CSDN 私有 AI 对话接口。
Readme
CSDN Private AI
在 VS Code 侧边栏里复用 CSDN 博客右侧 AI 助手的私有接口。
功能
- 支持绑定一个
blog.csdn.net/.../article/details/{articleId}链接,或直接输入纯数字articleId - 手动保存完整 CSDN Cookie 到 VS Code
SecretStorage - 文章校验仍走:
GET /phoenix/web/v1/assistant/ai-config
- 当前聊天协议已切到浏览器真实在用的 smart chat 链路:
GET /aisearch/v2/api/smart/session/getBlogSessionIdPOST /aisearch/v2/api/stream/smart/chat/message/stream
- 侧边栏线程和消息仍只保存在本地
workspaceState - 插件不会主动调用远端历史读取或
submitAnswer之类的提交接口 - 当前协议本身带
sessionId,服务端是否内部维护会话状态由 CSDN 决定,插件不额外做远端历史同步 - 每条 AI 回复右上角提供“复制”按钮,可一键把当前答案写入系统剪贴板
- 支持直接引用当前编辑器选区提问,引用信息会带上文件路径、语言和行号范围
- 支持在编辑器里通过右键菜单或快捷键快速引用当前选中代码
- Windows / Linux:
Ctrl + Alt + Q - macOS:
Cmd + Alt + Q
- Windows / Linux:
- 顶部文章 / Cookie / 代理 / 操作区支持手动折叠展开,方便在连续对话时把空间让给消息区
- AI 回复现在支持 Markdown 渲染,包括标题、列表、引用块、表格、行内代码和链接
- 代码块高亮现在基于本地
highlight.js,不走 CDN markdown-it和highlight.js会作为运行时依赖一起打进 VSIX,由扩展宿主本地渲染后再发给 Webview- 带代码引用提问时,AI 回复中的代码块会显示
Apply- 优先替换最初引用的原始区间
- 如果原始区间已变化,会尝试重新定位
- 仍无法定位时,可回退为替换当前编辑器选区
- 每个 AI 代码块现在额外支持:
复制代码Apply,用于替换原始引用区间或当前选区插入到光标,用于直接插入到当前活动编辑器的光标位置
- 复制整条回答或单个代码块时,侧边栏不再强制把滚动条拉到最底部
- 活动栏图标已改为 VS Code 兼容的单色 SVG,不再使用带底色的大方块
- 当前固定不注入文章正文,上游请求里始终按通用问答模式发送:
docIds: ""webSearch: "1"
当前协议说明
- 当前插件不再走旧的
assistant/completion。 - 现在的请求体已对齐到浏览器文章右侧 AI 的真实格式:
inputs.docIdsinputs.modelIdinputs.platforminputs.urlinputs.webSearchqueryqueryIdsessionIdtrace_id
- URL 上的
sign现在按query + queryId + sessionId拼接后生成。 - 具体算法不是直接
md5(queryString),而是:- 先把拼好的 query string 按 UTF-8 转成 Base64
- 再做
md5(\[#${md5(base64Query)}#]`)`
- 网关签名使用当前浏览器 bundle 里的 smart chat AK/SK。
- GET 请求参与 HMAC 时,空 query 参数要按 CSDN 自己的
$y逻辑规范化:- 浏览器 URL 可以是
type= - 但签名串里实际参与计算的是
type
- 浏览器 URL 可以是
getBlogSessionId当前真实返回里,data可能不是纯字符串,而是{ sid, count }- SSE 解析按浏览器真实返回的事件流处理:
event: "message"追加文本event: "message_end"结束生成- 其他 workflow 事件默认只做状态判断,不直接拼进正文,避免重复输出
开发调试
npm installnpm run compile- 用 VS Code 打开当前项目根目录
- 按
F5,或者在“运行和调试”里选择运行 CSDN Private AI 插件 - 弹出
Extension Development Host后,打开左侧CSDN AI容器 - 点击
绑定链接 / ID- 可以输入完整的
blog.csdn.net/.../article/details/{articleId}链接 - 也可以在内网环境下直接输入纯数字
articleId
- 可以输入完整的
- 点击
更新 Cookie- 支持直接粘贴纯 Cookie 值
- 也支持直接粘贴带
Cookie:前缀的一整行 - 如果你复制的是多行请求头,插件会优先提取其中的
Cookie:行
- 开始对话
- 如果你想让 AI 基于当前代码回答:
- 先在编辑器里选中代码
- 然后点击侧边栏里的
引用当前选区 - 或直接在编辑器里右键执行
引用当前选中代码 - 或使用快捷键:
- Windows / Linux:
Ctrl + Alt + Q - macOS:
Cmd + Alt + Q
- Windows / Linux:
- 如果你是在让 AI 改代码,优先让它输出一个完整代码块
- 当 AI 回复中出现代码块时,可以直接点击代码块右上角的
Apply- 默认会优先覆盖最开始引用的那段代码
- 如果你中途改过文件,插件会先尝试按原文重新定位
- 实在定位不到时,再改为替换你当前重新选中的代码区间
- 如果你只想把代码塞到当前编辑位置,不想覆盖原始引用区间,可以点击
插入到光标 - 如果只是想拿走代码片段,不想立刻改文件,可以点击
复制代码
打包与发布
- 当前工程已经补好本地打包脚本,默认会把生成出来的
.vsix一起放进 npm 包。 - VSIX 打包和 npm 打包现在分开控制:
- VSIX 打包走
.vscodeignore - npm 打包走
.npmignore
- VSIX 打包走
- Marketplace 顶层扩展图标现在单独走
media/icon.png- 这是给 VS Code Marketplace 展示页用的 PNG 图标
- 侧边栏容器里继续使用
media/icon.svg
- 生成 VSIX:
npm run package:vsix- 默认产物路径:
artifacts/csdn-private-ai-<version>.vsix
- 生成 npm tarball:
npm run package:npm- 默认产物路径:
artifacts/csdn-private-ai-<version>.tgz
- 一次性同时生成 VSIX 和 npm tarball:
npm run release:local
- 发布到 VS Code Marketplace:
- 先把
package.json里的publisher从local改成你在 Marketplace 上真实创建的 publisher id - 再准备 Azure DevOps 的 Personal Access Token,并确保包含 Marketplace 的
Manage权限 - 本机可先执行
vsce login <publisher-id> - 或者直接设置环境变量
VSCE_PAT - 然后执行
npm run publish:marketplace
- 先把
- 如果你想先验证 Marketplace 发布前的打包结果,可先执行:
npm run package:vsix
- 实际发布到 npm:
- 先执行
npm login - 先确认
package.json里的name和version都是你要发布的值 - 再执行
npm run publish:npm
- 先执行
- 如果你只想先验证发布内容,不想真的发到 npm,可先执行:
npm publish --dry-run --access public --cache .npm-cache
publish:npm会在真正发布前自动先跑一次package:vsix,确保 npm 包里带的是最新版本的.vsix- 当前脚本默认依赖你本机已经全局安装好的
vsce - npm 打包和发布脚本固定使用项目内的
.npm-cache,避免受系统全局 npm 缓存权限影响 - 仓库当前已补
MIT许可证文件:LICENSE - 如果你后续要做 CI 发布,Marketplace 侧优先使用
VSCE_PAT,npm 侧优先使用NPM_TOKEN
超时说明
csdnPrivateAi.requestTimeoutMs对普通 JSON 请求仍表示单次请求超时。- 对 smart chat 流式对话,这个值现在表示“空闲超时”,不是整段生成的总时长上限。
- 只要 CSDN 还在持续返回 chunk,插件就不会因为回答太长而在 30 秒时被硬切断。
- 如果长回答仍然停在半截,优先把
csdnPrivateAi.requestTimeoutMs调大到60000或120000再观察。
调试配置
- 已提供
.vscode/launch.json - 已提供
.vscode/tasks.json - 默认调试入口:
运行 CSDN Private AI 插件监听并运行 CSDN Private AI 插件
F5 没反应时先检查
- 当前打开的是不是本项目根目录,而不是上级目录或其他工作区。
node_modules是否已安装完成。dist/extension.js是否已经生成。- “运行和调试”面板里是否选中了
运行 CSDN Private AI 插件。 - 如果第一次进来没有任务缓存,先手动执行一次
npm run compile再按F5。 - 如果能发请求但立刻提示鉴权失败,先检查 Cookie 是否过期,或者是不是复制错了账号的 Cookie。
- 现在插件会自动清洗
Cookie:前缀;如果还是鉴权失败,优先重新从已登录的 CSDN 页面复制最新 Cookie。 - 如果错误里出现
HMAC signature does not match或“网关签名失败”,优先检查:src/services/csdnSigner.tssrc/services/csdnClient.ts
- 如果错误里出现
400105,不要再先怀疑 Cookie。现在优先检查:- 浏览器里同账号同文章是否真的能打开右侧 AI
src/services/csdnClient.ts的 smart chat 协议是否仍和网页一致sessionId获取/创建流程是否变化
- 如果你刚改过代码或我刚帮你修过协议,记得先关闭旧的
Extension Development Host,再重新按一次F5,否则你看到的可能还是上一版编译产物。 - 如果要继续排查,打开 VS Code 输出面板,切到
CSDN Private AI,看插件记录的 HTTP 状态码和业务错误。 - 如果
Apply提示找不到可替换目标,优先检查:- 你是不是在引用后又改动了同一段代码,导致原始区间失效
- 当前活动编辑器是不是同一个文件
- 是否重新选中了最新代码后再点一次
Apply
- 如果你发现 Markdown 没有高亮,优先检查:
node_modules/highlight.jsnode_modules/markdown-it- 是否重新启动了
Extension Development Host
维护约定
- 后续每次改代码,都要同步更新 README。
- README 至少要同步三类信息:
- 本次改了什么功能或行为
- 调试方式有没有变化
- 已知风险、兼容性或使用前提有没有变化
- 如果改动影响用户使用路径,README 里的“开发调试”和“F5 没反应时先检查”也必须一起更新。
后续维护重点
- 这是基于 CSDN 当前前端 bundle 对齐出来的私有协议,后续如果 CSDN 更新 AK/SK 或网关签名规则,优先修改
src/services/csdnSigner.ts。 - 如果文章绑定规则变化,或后续不再允许用纯数字
articleId走兜底 URL,优先修改src/utils/article.ts,并同步更新侧边栏文案和 README。 - 如果 VSIX 打包失败,优先检查全局
vsce是否可用,以及.vscodeignore和package.json里的脚本是否还保持一致。 - 如果 Marketplace 发布失败,先检查:
package.json里的publisher是否还是默认的localVSCE_PAT或vsce login是否对应同一个 publishermedia/icon.png是否仍然存在,且是至少128x128的 PNG
- 如果 npm 包里没有带上
.vsix,优先检查.npmignore,以及发布前是否实际生成了artifacts/*.vsix。 - 如果 CSDN 修改了 smart chat 的 URL
sign计算规则,优先修改src/services/csdnSigner.ts。 - 如果再次出现“网关签名失败,但浏览器里同请求能用”,优先检查
src/services/csdnSigner.ts里的 querysign是否仍然是“UTF-8 Base64 + 双 MD5”。 - 如果只有
getBlogSessionId这类 GET 接口报401/HMAC signature does not match,优先检查src/services/csdnSigner.ts里空 query 参数是否仍按type而不是type=参与 HMAC。 - 如果
getBlogSessionId成功但会话没有被复用,优先检查src/services/csdnClient.ts是否还兼容当前的{ sid, count }返回结构。 - 如果长文本生成到一半就停,优先检查
src/services/csdnClient.ts的流式超时策略,不要再把流式请求当作“总时长超时”处理。 - 如果 CSDN 修改了
queryId/trace_id/sessionId的生成规则,优先修改:src/utils/request.tssrc/webview/sidebarViewProvider.ts
- 如果 CSDN 修改了聊天接口地址、请求体字段或 SSE 返回格式,优先修改
src/services/csdnClient.ts。 - 如果浏览器右侧 AI 还能用,但插件返回
400105,优先检查src/services/csdnClient.ts里的sessionId获取/创建流程和 smart chat 事件流解析。 - 如果 CSDN 修改了文章可用性判断逻辑,优先修改
src/services/csdnClient.ts里的validateArticle。 - 如果鉴权失败集中出现在用户首次配置阶段,先检查
src/utils/cookie.ts的 Cookie 清洗逻辑是否还适配当前复制方式。 - 如果服务端返回新的业务错误码,优先补
src/services/csdnClient.ts里的错误码映射,不要直接把所有错误都归因到 Cookie。 - 如果对话存储策略变了,优先修改
src/services/threadStore.ts。 - 如果侧边栏交互或消息协议变了,要同时修改:
src/webview/sidebarViewProvider.tsmedia/sidebar.jsmedia/sidebar.css
- 如果“引用当前选区 / 快捷键 / Apply”链路变了,要同时检查:
package.jsonsrc/extension.tssrc/types.tssrc/webview/sidebarViewProvider.tsmedia/sidebar.jsmedia/sidebar.css
- 如果 Markdown 渲染或代码高亮链路变了,要同时检查:
package.jsonpackage-lock.jsonsrc/services/markdownRenderer.tssrc/webview/sidebarViewProvider.tsmedia/sidebar.jsmedia/sidebar.css
- 如果复制按钮或剪贴板行为变了,要同时检查
src/webview/sidebarViewProvider.ts和media/sidebar.js的消息协议是否仍一致。 - 如果活动栏图标显示异常,优先检查
media/icon.svg是否仍然使用currentColor单色路径,而不是带背景色的大面积填充。 - 如果 Marketplace 展示图标显示异常,优先检查
media/icon.png和package.json顶层icon字段,不要只改media/icon.svg。 - 插件不会把 Cookie 透传给 Webview,也不会把 Cookie 打进日志,这条约束后续不要破坏。
当前实现变更记录
0.0.3
- 增加了“引用当前选区”能力,支持从侧边栏按钮、编辑器右键菜单和快捷键把当前选中代码带进提问上下文。
- 引用信息现在会保留文件路径、语言和行号范围,并在侧边栏输入区和用户消息里展示。
- 带引用提问时,会把引用代码包装成更适合改代码场景的 prompt,提示 AI 返回可直接替换原选区的完整代码块。
- 为 AI 回复中的代码块增加了
Apply按钮,支持把代码直接应用回编辑器。 Apply现在会优先命中原始引用区间;如果文件内容变化导致区间失效,会先尝试按原文重新定位,再回退到当前选区替换。- 回复渲染现在支持 Markdown,并对代码块接入了本地
highlight.js语法高亮。 markdown-it和highlight.js改为随扩展本地打包,Webview 不再依赖任何 CDN 资源。
0.0.1
- 初始化了桌面版 VS Code 扩展工程。
- 增加了侧边栏 Webview UI、文章绑定、Cookie 更新、停止生成、清空线程。
- 实现了
ai-config校验、私有签名、流式请求和 SSE 解析。 - 实现了按
articleId隔离的本地线程持久化。 - 增加了
.vscode/launch.json和.vscode/tasks.json,解决按F5没有调试入口的问题。 - 增加了 Cookie 归一化逻辑,兼容直接粘贴
Cookie:整行或多行请求头中的 Cookie 内容。 - 将
questionId/requestId生成规则对齐到 CSDN 官方前端实现。 - 增加了
400105业务错误提示,避免把业务拒绝误判成 Cookie 鉴权失败。 - 补充了调试宿主重启说明,避免修改代码后仍然看到旧版本提示文案。
- 增加了错误日志输出到
CSDN Private AI输出面板,并把401/403文案改成带 HTTP 状态码,方便区分真实鉴权失败和业务拒绝。 - 去掉了旧的统一鉴权失败文案;现在服务端业务消息里的鉴权类错误也会明确标成“服务端业务码 / 服务端业务消息”。
- 将旧的
completion请求从fetch切换为node:https.request,修复了真实请求里出现的HMAC signature does not match网关签名错误。 - 将聊天协议从旧的
assistant/completion切换到浏览器当前真实使用的smart/session + smart/chat/message/stream链路。 - 本地线程现在会持久化
sessionId,并在发送前先走getBlogSessionId对齐当前 smart chat 会话。 - SSE 解析现在按
message / message_end / workflow_finished事件处理,避免把 workflow 汇总字段重复拼进正文。 - 修正了 smart chat URL 上
sign的生成逻辑,改为和当前 CSDN bundle 一致的“UTF-8 Base64 + 双 MD5”,解决HTTP 401 / HMAC signature does not match。 - 修正了 GET 请求空 query 参数的 HMAC 规范化逻辑,和当前 CSDN bundle 保持一致,避免
getBlogSessionId因type=与type差异导致 401。 - 补上了
getBlogSessionId返回对象结构的兼容,避免服务端已返回真实sid时本地还退回随机 sessionId。 - 将流式请求从“整段请求总时长超时”改成“socket 空闲超时”,修复长代码生成到 30 秒左右被
aborted / ECONNRESET截断的问题。 - 为每条 AI 回复增加了一键复制按钮,复制动作由扩展宿主写入系统剪贴板,避免依赖 Webview 自身的 clipboard 权限。
- 将活动栏图标替换为适合 VS Code 侧边栏容器的单色 SVG,修复显示成白色正方形的问题。
- 文章绑定现在支持直接输入纯数字
articleId,不再强依赖先粘贴完整文章链接,适配内网环境下无法访问博客页面的场景。 - 增加了 VSIX 和 npm 发布脚本,支持生成
.vsix、生成 npm tarball,并在 npm 发布前自动把最新.vsix带进包里。 - 将 VSIX 和 npm 的打包规则拆分为
.vscodeignore与.npmignore两套,避免vsce因和 npm 文件白名单冲突而打包失败。 - 补充了 npm 发布前需要先
npm login的说明,并验证了npm publish --dry-run下 tarball 确实会包含生成出来的.vsix。 - 补充了
MIT许可证文件,消除了 VSIX 打包时缺少 LICENSE 的警告前提。 - 增加了
publish:marketplace脚本,并补上了 Marketplace 使用的 PNG 图标与发布说明。
