wanghanlin
|
20d9a889ac
|
fix(sdk): 流式零内容时降级路径未渲染答案,界面永久停在「正在思考...」
问题:第三方页面反馈「对话框一直显示正在思考...,但控制台里请求与响应数据都正常」。
定位:服务端这次的流式响应只回了「开场 role 帧 + finish_reason=stop 帧 + [DONE]」三个控制帧、
零内容(服务端成因见后一个提交)。SDK 的 sendStreamMessage 在 onDone 里发现零内容时确实会
降级再发一次同步 /ai/chat,但该分支只写 `chatRequest(...).then(resolve)` —— 既不渲染气泡也不
收掉 loading;而 produceAIReply 的 streaming 分支把「渲染气泡 + 收 loading」全权委托给了
onChunk 回调,这条路径拿不到 onChunk。结果同步拿到的答案被静默丢弃、loading 永不消失。
- 降级路径补齐 hideLoading + renderAIBubble(复用 dom.ts 已有实现,终态与非流式分支一致)
- 同一函数另一处同类出口:首个 token 之前点「停止生成」时 loading 同样不会被收,且会把一条
空 AI 消息写进历史。补 hideLoading;并在 produceAIReply 加守卫:aiContent 为空串时不 push、
不落库、不派发 csk:newMessage(避免历史里多出空气泡)
- 流式零内容时上报 onError code=stream_empty,不再静默;README 补该错误码与触发方式说明
验证:用逐字复刻线上那 3 帧的 mock 流驱动真实 SDK(puppeteer)——降级拿到的答案被正常渲染成
气泡、「正在思考...」消失、onError 收到 stream_empty,请求序列与线上 HAR 一致;正常带内容的流
不受影响(errors 为空、syncFallbackCalls=0);首 token 前中止时 loading 消失且历史无空消息。
client 单测 92 个全绿。
(static/sdk/test.html 仅两条 link 顺序变化,hash 未变,属构建产物顺序抖动)
|
2 weeks ago |
wanghanlin
|
5a553ec813
|
feat(sdk): SDK 内置 Token 自动刷新,支持每请求前向宿主取 Token
问题:SDK Token 默认仅 2 小时有效,而 SDK 此前没有任何刷新入口 —— token 只能
在 init() 时传一次、只存内存,收到 401 只回调 onError 报错,想换 Token 只能
destroy() 重建整个 DOM,第三方页面长时间挂载必然掉线。
取 Token 的四种触发方式(client/src/token.ts)
- 临期主动刷新:阈值取「总寿命 10% 与 5 分钟」的较小值,需传 expiresIn
- 每请求前取:tokenStrategy: 'always',每个受保护请求发出前都向宿主取一次,
完全不推算过期时间(该模式下不排定时器、不认「返回同一 Token」的静默窗口)
- 401 兜底重试:换一次 Token 后自动重试原请求,UI 上不会闪错误
- 手动入口:ChatbotSDK.setToken(token, expiresIn?) / refreshToken()
取 Token 的两种来源(二选一,getToken 回调优先并明确告警)
- getToken 回调:由宿主实现,可复用其请求封装与鉴权头
- tokenUrl 地址:SDK 直接 GET,兼容 {token,expiresIn} 与
{success,token,expiresIn,roles};用 credentials: 'same-origin'(同源带
Cookie、跨域不带,避免把宿主站点 Cookie 泄露给别的域)
两者都让 API Key 留在宿主服务端,不进浏览器;后端零改动。
关键实现约束(均有单测覆盖)
- 临期阈值必须自适应:后端 clampExpirationMillis 允许的最短 ttl 恰为 300s,
固定 5 分钟会让它永远处于临期态,定时器延迟算成 0 退化成秒级无限刷新循环
- expiresIn 只做 24h 上界钳制、绝不做下界,避免把「只剩 20s 的 Token」当成
300s 而带着已过期 Token 发请求(上界同时防 setTimeout 溢出与毫秒误传)
- provider 调用自带 10s 超时,refreshPromise 在 finally 无条件清空:宿主回调
永不 settle 时,挂起会经 single-flight 传染给后续所有受保护请求
- setToken 自增 generation 但不碰 refreshPromise:既防止在途刷新返回的旧值
覆盖宿主刚推来的新值,又不破坏 single-flight
- 刷新失败统一进 60s 熔断窗口(判断在 refreshNow 内,不在 ensureFresh),窗口
内请求照常发出、由 401 兜底,避免宿主取 Token 挂死时每个请求多等一次超时
- isProtectedPath 改用 URL.pathname 判定并与后端 SdkAuthFilter.shouldNotFilter
逐字对齐;顺带修掉旧实现 endsWith('/feedback') 遇 query 参数漏注入、
/attachment/upload 注入了 Token 却不享受 401 处理的两处不一致
- 401 透明重试对写请求(POST /feedback、/attachment/upload、DELETE 会话)安全,
依据是 SdkAuthFilter 的 401 全部发生在 chain.doFilter 之前(401 ⇒ 业务逻辑
未执行);该前提已写入代码注释与 CLAUDE.md,改过滤器时需重新评估
顺带修复
- chat.ts:首 token 前点「停止生成」会反而多发一个同步 /ai/chat 请求
- tests/config.test.ts:2 条断言早已因窗口默认值改动而变红(不修平的话
npm test 无法充当回归门)
- 文档:修正 width 默认值 380->500、enableRag 默认值 false->true、roleId 幽灵
参数、「仅 console.error 输出」(控制台日志早已全量关闭)等过时描述,并补齐
token/expiresIn/getToken/tokenStrategy/tokenUrl 全部鉴权参数
验证
- client 单测 92 个全绿(新增 token.test.ts 60 个 + config 新增 9 个),
npx tsc --noEmit 通过
- npm run build(SDK)与 frontend npm run build 均通过,
mvn clean package -P prod 构建成功
- 浏览器端未实测(按项目惯例由用户在 IDEA 启动服务,避免抢占 9090 端口),
面板已加 TTL 输入与 tokenStrategy 选择开关供手工验证
|
2 weeks ago |
wanghanlin
|
9fe3ee6828
|
fix(sdk): 修复历史会话不显示图片附件
- MessageConverter 落库时持久化多模态 Media 到 metadata._media
- ConversationService 历史消息接口提取 _media 为顶层 images 字段
- SDK 前端历史映射补齐 images,复用 renderUserBubble 附件渲染
|
1 month ago |
wanghanlin
|
d5d392aca4
|
feat(sdk): 支持图片上传与多模态对话
SDK 前端新增图片附件上传与多模态对话能力,输入区新增附件按钮与图片预览,新增 allowImageUpload 配置项;/attachment/upload 鉴权改由 SdkAuthFilter 承担(移除方法级 @PreAuthorize),JwtAuthFilter/SecurityConfig 同步放行
|
1 month ago |
wanghanlin
|
83964afcfc
|
refactor(client): 外围组件原生化并清理死代码,缩小 SDK 体积
- t-select/t-dialog/t-alert/t-tag/t-button 替换为原生 DOM,删 5 条组件 import 与 omi 直接依赖,min 版缩小约 212KB
- 清理死代码:images.d.ts、失效测试、dist 残留、getMessages、死类型、showAdminPanel、未用 i18n key、t-tag 死 CSS
- 修复 i18n 缺失 confirm/cancel 翻译与自绘确认框 ESC 冲突
|
2 months ago |
wanghanlin
|
b56cea0c8c
|
fix(client): 历史会话时间智能分档显示并修复操作栏按钮 tooltip
历史会话列表时间由原始 ISO 字符串改为智能分档:今天/昨天显示 HH:mm,同年显示 MM-DD HH:mm,跨年显示 YYYY-MM-DD HH:mm。
操作栏按钮(重新生成/复制/点赞/点踩)补齐 hover 文字说明:修复 tooltip 浮层 z-index 低于聊天窗(9999)被遮挡,及 .t-tooltip 深色背景样式在 light DOM 浮层缺失的问题(globalCSS 只对 shadow DOM 生效)。
|
2 months ago |
wanghanlin
|
431b1f2b1d
|
fix(client): 修复第三方接入 SDK 后 markdown 排版与标签样式缺失
根因:tdesign-web-components 的聊天/markdown 变量(--td-chat-*/--td-chat-md-*/--td-chat-input-*)
定义在 globalCSS 的 constructable stylesheet 中,选择器为 :root;但 adoptedStyleSheets 里的
:root 不匹配 shadow root,导致这些变量无法进入渲染 markdown 的 shadow DOM,标题/列表/引用/
代码块回退为初始值。t-tag 是 light DOM 组件,其 .t-tag 样式同样只在 globalCSS 中、进不了 light DOM。
改动:
- styles.ts 新增 tdChatVars(),将聊天/markdown/input 变量自包含声明在 .csk-root 上
- styles.ts 补注入 .csk-root .t-tag 系列 light DOM 样式
- 配合此前 tdThemeVars() 的主题变量,SDK 样式完全自包含,不再依赖宿主页面
|
2 months ago |
wanghanlin
|
da031c6ff0
|
fix(client): 修复重新生成清空历史,优化引用来源/推荐问题与历史滚动
- 重新生成改为调用后端会话截断接口,同步前后端数据,避免历史回复被清空
- 引用来源折叠开关与推荐问题改用 t-button,风格对齐 ChatActionbar 操作栏
- 历史消息渲染后延迟滚动到底部,修复停在滚动条中间的问题
|
2 months ago |
wanghanlin
|
021dfa9199
|
回复内容自适应 SDK 弹窗宽度
|
2 months ago |
wanghanlin
|
97f8f1a8f0
|
回复内容自适应 SDK 弹窗宽度
|
2 months ago |
wanghanlin
|
e23b70ffca
|
feat(client): SDK 界面重构改用 TDesign Web Components 组件
- 聊天核心:消息气泡/输入框/操作栏/加载态改用 t-chat-message/t-chat-sender/t-chat-action/t-chat-loading
- 外围 UI:知识库下拉/推荐问题/离线横幅改用 t-select/t-tag/t-alert
- Markdown 渲染由 t-chat-item 内置 cherry-markdown 承担,移除自研 marked 渲染器与 marked.min.js
- 构建管线:引入 tdesign-web-components@1.2.10 按需打包,mermaid 用本地 stub 替换省约 1.2MB
- 清理重构后死代码与死样式(escapeHtml/getLocale/appendStreamingCaret/offlineBannerEl 等)
- 同步更新测试面板断言(T3/T6/T10 适配 t-chat-sender)与 README/CLAUDE.md
|
2 months ago |
wanghanlin
|
b9f91d0903
|
fix(sse): 修复 SSE 鉴权头覆盖问题并同步测试用例文档
- sse.ts authHeaders 仅当调用方未显式提供 Authorization 时才注入管理后台 token,避免覆盖测试面板传入的 SDK Token
- client/README.md、client/CLAUDE.md 同步测试用例数量 22 → 10
|
2 months ago |
wanghanlin
|
2f09b3fabf
|
feat(client): SDK 悬浮窗口对话视觉对齐 TDesign Chat 规范
- styles.ts 对齐气泡圆角/头像/时间戳/输入框/发送按钮/加载态/操作栏/来源卡片/快捷芯片视觉
- dom.ts 微调时间戳与操作栏相对位置
- 保持零依赖 IIFE、csk-* 类名零增删改、主色变量与暗色模式同步
|
2 months ago |
wanghanlin
|
6be019082e
|
docs: 同步对话接口迁移与 OpenAI SSE 格式说明
- README.md、SDK-INTEGRATION.md、client/README.md、client/CLAUDE.md 四处接口表更新为新路径 /ai/chat、/ai/chat/stream、/ai/chat/sources
- 补充流式接口 OpenAI Chat Completions SSE 格式说明(data: JSON chunk + data: [DONE])
- 删除废弃的 /ai/assistant_app/* 路径与 rag/sync 描述
|
2 months ago |
wanghanlin
|
b0319392a2
|
feat(client): 前端与 SDK 迁移新对话接口并支持 OpenAI SSE 解析
- 前端 chat.ts 合并为 chatSync/chatSSEUrl/ragSources 三个函数,统一走 /ai/chat、/ai/chat/stream、/ai/chat/sources,用 ChatOptions + enableRag 布尔参数统一普通/RAG 路径
- 前端 sse.ts 新增 extractOpenAIDelta 解析 choices[0].delta.content,识别 error chunk,JSON 解析失败回退纯文本,旧纯文本流向后兼容
- ChatPanel.vue 将 RAG sync/SSE/普通 sync/SSE 四分支合并为 sync/SSE 两分支
- SDK api.ts 迁移 URL 至 /ai/chat 系列,chatSSERequest 抽取 emitRawChunk 解析 OpenAI delta 与 error,正确处理 data: [DONE]
|
2 months ago |
wanghanlin
|
c22d044e5c
|
fix(sdk): 修复 marked 列表渲染异常导致回复挤成一行
marked v15 的 Parser.parse 按 token.type 做 switch 分发、无 list_item 分支,list(token) 用 this.parser.parse([item]) 会抛异常,被 renderMarkdown 降级为纯文本,导致换行折叠成一行、Markdown 全部失效。改为官方写法 this.listitem(item)。
- 修正 marked 版本注释 v18 → v15.0.12(与部署产物实际版本一致)
- 同步更新 client/CLAUDE.md 与 README.md 的 Markdown 模块说明与部署依赖
- .gitignore 忽略 sdk 构建产物目录
|
2 months ago |
wanghanlin
|
0953e9481b
|
chatsdk 对markdown解析器进行重构
|
2 months ago |
wanghanlin
|
7ce8028d73
|
重构客服角色管理页面排版
|
2 months ago |
wanghanlin
|
b5abf32530
|
迁移到 TDesign 架构时漏掉了文档上传路由和菜单入口
|
2 months ago |
wanghanlin
|
1fe6a19366
|
修复:TDesign <t-space> 内部 v-if 导致按钮动作错位
|
2 months ago |
wanghanlin
|
fe49bebadb
|
优化界面排版
|
2 months ago |
wanghanlin
|
bfb5a66393
|
AI回复增加推荐问题功能
|
2 months ago |
wanghanlin
|
7a44abed78
|
logo瘦身
|
2 months ago |
wanghanlin
|
03dd0ab557
|
chatsdk窗口增加水印功能
ChatbotSDK瘦身
|
2 months ago |
wanghanlin
|
532994ba20
|
chatsdk清空对话按钮改为新对话
|
2 months ago |
wanghanlin
|
ba933825d4
|
优化打包、编译速度
|
2 months ago |
wanghanlin
|
527d9e71b7
|
AI 对话执行链路流程图
|
2 months ago |
wanghanlin
|
4eb726a056
|
SDK 聊天窗口底部的保密声明
|
2 months ago |
wanghanlin
|
1a672fe128
|
调整默认sdk窗口大小值
|
2 months ago |
pyx
|
f511572618
|
修复 Markdown 标题、列表及表格渲染
|
2 months ago |
wanghanlin
|
a2950be98f
|
修复 SSE 流式回答每词独占一行的 bug
|
3 months ago |
wanghanlin
|
ae52cd8949
|
修改入口图标并修复拖拽相关问题
|
3 months ago |
wanghanlin
|
b9e14a2547
|
优化回答规则提示词并修复SSE流式换行丢失
|
3 months ago |
wanghanlin
|
0bc4b66e93
|
入口图标改造 + SDK 瘦身
|
3 months ago |
wanghanlin
|
215965efc2
|
添加窗口缩放功能和更换入口图标
|
3 months ago |
wanghanlin
|
1d1b4460a2
|
API Key 绑定客服角色
|
3 months ago |
wanghanlin
|
9e9d9aad94
|
支持图标拖拽固定-优化
|
3 months ago |
wanghanlin
|
4846852d26
|
支持图标拖拽固定
|
3 months ago |
wanghanlin
|
f8e5a1b59c
|
fix(安全): 修复多个安全漏洞和功能问题
安全修复:
- 修复会话管理 API 安全限制被完全解除的问题
- 移除 SecurityConfig 中会话接口的 permitAll() 配置
- 为 ConversationController 所有方法添加 @PreAuthorize 注解
- 新增 SDK 安全会话端点,内置账户归属校验
- 修复 verifyConversationOwnership 所有权绕过漏洞
- 强制要求至少提供 accountId 或 roleId 一个有效参数
- 防止通过空参数绕过归属校验
功能修复:
- 修复 Webhook 创建时 user_id 违反非空约束
- 从 SecurityContext 获取当前登录用户 ID
- 同步修复 ApiKeyController 的相同问题
- 修复 SDK 会话接口安全问题
- 新增 /ai/sdk/conversation/* 端点
- 实现 conversation_session 表归属校验
- SDK 前端代码迁移到新端点
影响范围:
- 会话管理接口现在需要 JWT 认证
- Webhook 和 API Key 创建功能恢复正常
- SDK 会话功能通过归属校验保证安全
安全等级:高危漏洞修复
涉及文件:8 个 Java 文件 + 3 个 SDK 文件
|
3 months ago |
wanghanlin
|
250f643a42
|
,修复了分块查询、状态切换和批量操作三个核心问题
|
3 months ago |
pyx
|
a6ba72053f
|
优化 SDK RAG 默认开启逻辑并调整测试页配置
|
3 months ago |
wanghanlin
|
cdaff49533
|
优化前端操作交互体验。
ai大模型配置错误不影响启动服务。
去除后台系统提示词,直接使用前端角色设定提示词。
|
3 months ago |
wanghanlin
|
f7eb0bfaf1
|
feat(P0): 完成阶段一全部需求 — 混合检索/内容安全/用户反馈/FAQ精准匹配
P0-001 混合检索+重排序引擎:
- HybridSearchService 支持 VECTOR/KEYWORD/HYBRID 三种检索模式
- RrfFusion RRF 融合算法 (k=60)
- RerankerService 支持 DashScope + OpenAI 兼容多提供商
- vector_store 新增 content_tsvector 列 + GIN 索引 + 触发器
- DocSearch.js 增加检索模式下拉选择
P0-004 内容安全过滤:
- ContentSafetyService DFA 字典树引擎(volatile + copy-on-write 线程安全)
- ContentSafetyAdvisor BaseAdvisor 实现,输入/输出双向审核
- SensitiveWordService 敏感词 CRUD + 批量导入 + 字典树热加载
- SensitiveWordManager.js 前端管理组件
P0-002 用户反馈系统:
- MessageFeedbackService upsert 语义反馈提交 + 统计 API
- ChatPanel.js 添加 👍/👎 反馈按钮
- Chat SDK handleFeedback() 对接后端 POST /feedback
- ConversationService 导出集成反馈信息
P0-003 意图识别+FAQ精准匹配:
- IntentRouter LLM 意图分类(FAQ/RAG/CHITCHAT)
- FaqMatchEngine 三级匹配(精确→关键词→向量语义,阈值 0.85)
- FaqService FAQ CRUD + 异步向量化
- FaqManager.js 前端管理(CRUD + 批量导入/导出 + 启用/禁用)
共享变更:
- DatabaseInitConfig 新增 5 张表 + 全文检索初始化
- api.js 新增反馈/敏感词/FAQ API 封装
- app.js 注册 SensitiveWordManager + FaqManager 组件
- application.yml 新增 knowledge.faq.semantic-threshold 配置
|
3 months ago |
wanghanlin
|
bc334a92b1
|
SDK 新增 6 项功能完善(类型导出/窗口配置/错误回调/测试/分组/通知)
1. 类型导出:tsconfig 开启 declaration,新增 build:types 脚本,index.ts re-export 公开类型
2. 窗口高度可配置 + 记忆位置:height 配置项(默认 520,最小 300),拖拽位置 localStorage 持久化
3. 错误监控回调:新增 onError/onReady/onMessage 三个生命周期回调
4. 自动化测试:引入 Vitest,4 个测试文件共 67 个用例(markdown/config/i18n/utils)
5. 会话分组:历史面板按今天/昨天/本周/更早分组渲染
6. 声音/桌面通知:Web Audio API 合成提示音 + Notification API 桌面通知
|
3 months ago |
wanghanlin
|
eafb41ff77
|
优化小图标样式
|
3 months ago |
wanghanlin
|
476e34f704
|
ChatSDK完善客服 SDK 的页面样式与交互功能。两轮共落地 13 项改进(快捷问题、暗色模式、停止生成、消息反馈、a11y等)
增加开发、生产配置文件
增加部署文档DEPLOY.md
|
3 months ago |
wanghanlin
|
cfe6fea93e
|
ChatSDK重写了 SDK 的视觉与交互
|
3 months ago |
wanghanlin
|
5714d01cbb
|
ChatSDK可在对话历史中选定继续会话
|
3 months ago |
wanghanlin
|
cfc1ca8650
|
ChatSDK P1/P2 功能已全部实现并修复了三个核心 bug(integrateId→roleId 映射、chatId
自动管理、对话历史从后端加载)
|
3 months ago |
wanghanlin
|
600f86a1c5
|
把嵌入模型支持从仅千问扩展到多厂商。前端限制、后端自动覆盖
|
3 months ago |