Skip to content

WebSocket 消息转发机制

Agent 收到 WebSocket 消息后的处理流程

Plugin → Agent (WebSocket JSON)


getWSMessage(ws_data) → JSON.parse(data.toString())

    ├─ 记录 OpenTelemetry Span (message.id, message.command, message.sessionId)

    ├─ 根据 command 前缀路由到 Controller:
    │   ├─ "CODE:"    → CodeController
    │   ├─ "TALK:"    → TalkController
    │   ├─ "SQL:"     → SqlController
    │   ├─ "TEST:"    → TaskController
    │   ├─ "GIT:"     → TalkController (复用 ChatService)
    │   ├─ "DIALOG:"  → InlineChatController
    │   ├─ "USER:"    → UserController
    │   └─ "LOG:"     → LogController

    ├─ Controller.handleMessageEvent(msg)
    │   ├─ 检查路由配置 (routes[command])
    │   ├─ 检查 needLogin → 未登录发送 401 错误
    │   ├─ 注入 _scene, _recordDialog, _sendDialog 等上下文
    │   └─ 调用对应的 routeFunc

    ├─ Service 调用 HTTP API
    │   ├─ 构建请求: getBaseData() + 业务数据
    │   ├─ 注入 headers: Content-Type, token, traceparent
    │   ├─ 注入 abort signal
    │   └─ 发送 HTTPS 请求

    └─ 响应回传:
        ├─ 非流式: await response.json() → sendWSMessage(ws, data, id)
        └─ 流式: SSE 解析 → 逐段 sendWSMessage(ws, chunk, id)

Agent → Plugin 响应格式

json
{
  "id": "原始消息ID",
  "code": 200,
  "data": { ... },
  "msg": null
}

错误响应:

json
{
  "id": "原始消息ID",
  "code": 400,
  "msg": "错误消息",
  "data": { "code": "5001", "message": "..." }
}

SSL/TLS 配置

Agent 默认忽略 HTTPS 证书验证(agent.ignoreHttps 配置项默认 true):

javascript
// ServiceBase._getInitOpt
if (this.ignoreHttps && url.startsWith("https://")) {
  options.agent = new https.Agent({ rejectUnauthorized: false });
}

Agent WebSocket 服务端

连接验证

javascript
// Agent.onconnect
const url = request.url;
// 仅接受匹配 /ws/[^/]+$ 的路径
if (!/\/ws\/[^/]+$/.test(url)) {
  ws.close(); // 关闭非法连接
}
// 从 URL 提取 IDE 类型: /ws/idea → "idea"
const platform = url.split("/").pop();

初始化响应

新连接建立后,Agent 立即发送初始化消息:

json
{
  "id": "init",
  "code": 200,
  "data": {
    "clientId": "uuid",
    "version": "3.4.2",
    "tipinfo": []
  }
}

控制器注册

Agent 为每个连接实例化以下控制器:

Controller职责
TalkController对话、代码操作
CodeController代码补全
InlineChatController内联聊天
TaskController单元测试
UserController用户管理
SqlControllerSQL 操作
LogController日志
ActionController操作上报
DialogController对话管理
AbortController请求取消

Token 管理流程

1. Agent 启动 → 无 token
2. Plugin 发送 LOGIN/LOGIN_CHECK 命令
3. LoginService.toLogin():
   a. 尝试从本地缓存读取 token (nedb 数据库)
   b. 如果有缓存 token → validToken() 验证
   c. 如果验证成功 → loginSuccess()
   d. 如果验证失败 → 获取登录 URL (SSO)
4. SSO 登录流程:
   a. getSysUrl() → 获取 loginUrl
   b. 构建登录 URL: loginUrl + ?clientId=xxx
   c. 返回 URL 给 Plugin → WebView 打开浏览器
   d. 轮询 checkLoginStatus(clientId) → 等待登录完成
5. loginSuccess():
   a. 保存 token 到 ServiceBase.token
   b. 保存到本地 nedb 数据库 (持久化)
   c. 设置 OpenTelemetry 用户属性
   d. 广播 login 事件到其他进程
   e. 通过 WebSocket 发送 "login-info" 给 Plugin
6. 后续所有 HTTP 请求使用 token header
7. Token 失效 → 401 → 发送 401 错误到 Plugin → 重新登录

URL 路径规则

前缀用途代理规则
/api/starspark/v1/agent/*AI 服务直连
/api/starspark/v1/platform/*平台服务直连
/api/starspark/v1/chat/user/*用户认证直连
/api/starspark/v1/user/*用户信息直连
/api/usercenter/v1/*用户中心直连
/api/ragserver/v1/*RAG 搜索直连
/restapi/ragserver/v1/*RAG 内部直连
/restapi/unit/v1/*批量单测直连

baseURL 从 config.json 中的 agent.url 读取,默认 https://saas.api.example.com。可通过环境变量 BASE_URL 覆盖。

完整 API 汇总表

#APIS KeyURLMethodStreamTimeout
1loginByAccount/api/usercenter/v1/user/common/loginPOSTNo10s
2validToken/api/starspark/v1/chat/user/validPOSTNo10s
3loginStatus/api/starspark/v1/user/authorizationQueryGETNo10s
4exitLogin/api/starspark/v1/chat/user/logOutPOSTNo10s
5getUrls/api/starspark/v1/agent/authSetting/queryGETNo10s
6checkUpdate/api/starspark/v1/agent/authSetting/queryPluginLinkPOSTNo10s
7getPermission/api/starspark/v1/agent/permission/queryUserPermissionPackageInfoPOSTNo10s
8getFuncModelList/api/starspark/v1/agent/permission/queryUserFuncModelListPOSTNo10s
9generalSetting/api/starspark/v1/agent/pluginSetting/queryGlobalSettingGETNo-
10tokenConfig/api/starspark/v1/agent/pluginSetting/queryTokenSettingGETNo-
11getChatPromptTemplate/api/starspark/v1/agent/prompt/queryPOSTNo-
12getWordWriterConfig/api/starspark/v1/agent/wordWriter/configGETNo10s
13getUserPackage/api/starspark/v1/user/packageQueryPOSTNo10s
14talkAsk/api/starspark/v1/agent/chat/async/askPOSTYes-
15talkAskSync/api/starspark/v1/agent/chat/sync/askPOSTNo-
16codeGenerate/api/starspark/v1/agent/code/codeCompletePOSTNo120s
17codeAssist/api/starspark/v1/platform/code/assistPOSTYes-
18serverResourceInfo/api/starspark/v1/agent/code/queryUnitTestQueueInfoPOSTNo-
19recommendations/api/starspark/v1/agent/chat/recommendationsPOSTNo-
20review/api/starspark/v1/agent/chat/reviewPOSTYes-
21generateCommitMessage/api/starspark/v1/agent/chat/generateCommitMessagePOSTYes-
22generateSql/api/starspark/v1/agent/chat/generateSqlPOSTYes-
23generateSqlDM/api/starspark/v1/agent/chat/sync/generateSqlPOSTNo-
24optimizeSql/api/starspark/v1/agent/chat/optimizeSqlPOSTYes-
25optimizeSqlDM/api/starspark/v1/agent/chat/sync/optimizeSqlPOSTNo-
26transDaMengDDL/api/starspark/v1/agent/chat/convertDmTableDDLPOSTNo-
27inlineChat/api/starspark/v1/agent/chat/inline/chatPOSTYes-
28testCase/api/starspark/v1/agent/code/generateUnitTestCaseTemplatePOSTNo120s
29testCode/api/starspark/v1/agent/code/generateUnitTestPOSTNo120s
30batchUnitTestCreate/restapi/unit/v1/createUnitTaskPOSTNo-
31batchUnitTestList/restapi/unit/v1/queryUnitTaskPOSTNo-
32batchUnitTestDownload/restapi/unit/v1/exportByTaskIdGETNo-
33batchUnitTestCancel/restapi/unit/v1/cancelUnitTaskPOSTNo-
34batchUnitTestDelete/restapi/unit/v1/deleteUnitTaskPOSTNo-
35batchUnitTestInProgress/restapi/unit/v1/isPendingTaskPOSTNo-
36chatEvaluation/api/starspark/v1/agent/chat/evaluatePOSTNo-
37chatFeedback/api/starspark/v1/agent/chat/feedbackPOSTNo-
38chatDataReport/api/starspark/v1/agent/collect/chatDataContentPOSTNo-
39codeReport/api/starspark/v1/agent/collect/codeAcceptPOSTNo-
40codeReject/api/starspark/v1/agent/action/rejectCodePOSTNo-
41recordCommitInfo/api/starspark/v1/agent/collect/commitCodeDataPOSTNo-
42unitTestCollection/api/starspark/v1/agent/collect/unitTestStatisticsPOSTNo-
43unitTestCollectionGenerate/api/starspark/v1/agent/collect/generateUnitTestDataPOSTNo-
44unitTestCollectionCommit/api/starspark/v1/agent/collect/commitUnitTestDataPOSTNo-
45requestTimeAnalysis/api/starspark/v1/agent/collect/uploadRequestTimePOSTNo-
46userAction/api/starspark/v1/agent/action/saveUserActionPOSTNo-
47queryCategory/api/starspark/v1/agent/feedback/queryCategoryPOSTNo-
48gitRepos/api/ragserver/v1/code/getUserReposPOSTNo-
49gitLangList/api/ragserver/v1/code/getLanguagesPOSTNo-
50gitCodeSearch/api/ragserver/v1/code/searchPOSTNo-
51ragBatchLoad/api/ragserver/v1/rag/incbatchloadPOSTNo-
52searchInRepo/restapi/ragserver/v1/code/searchInRepoPOSTNo-
53searchInDoc/restapi/ragserver/v1/doc/searchPOSTNo-
54searchInWebSearch/api/ragserver/v1/code/onlineSearchPOSTNo-
55parseWebDocument/api/ragserver/v1/web/parseurlPOSTNo-
56knowledgeList/restapi/ragserver/v1/doc/knowledgeListPOSTNo-
57codeKnowledgeStatus/restapi/ragserver/v1/rag/codeK/personal/init/statusPOSTNo-
58authPersonalCodeKnowledge/restapi/ragserver/v1/rag/codeK/personal/authPOSTNo-
59codeKnowledgeReVectorized/restapi/ragserver/v1/codeknowledge/reVectorizedPOSTNo-
60codeKnowledgeUpdateGitToken/restapi/ragserver/v1/rag/codeK/updateGitTokenPOSTNo-
61codeKnowledgeList/restapi/ragserver/v1/rag/codeK/codeKnowledgeListPOSTNo-
62repoKeyEnable/restapi/ragserver/v1/rag/repoKeyEnablePOSTNo-
63repoLangExtEnable/restapi/ragserver/v1/rag/repoLangExtEnableGETNo-
64repoSearchReady/restapi/ragserver/v1/rag/repoKeyDialogEnablePOSTNo-

64 个 API 端点

本项目仅供学习研究,逆向分析内容归原厂商所有。