{
  "version": "21.8",
  "updated_at": "2026-09-21T14:28:59+08:00",
  "components": {
    "widget": {
      "version": "v21.7",
      "file": "widget_v16.js",
      "note": "主动弹出持续降频：前3次10秒不变 / 4-6次60秒 / 7-9次120秒 / 10次起300秒；AI 接手（用户已说话）后停止自动弹出"
    },
    "backend": {
      "version": "v7.6",
      "note": "修复来源校验白名单缺 qfskill.cn：学历站(qfskill.cn)浏览器请求被判 origin_blocked / referer_blocked 返回 403 导致客服不回复；ALLOWED_DOMAINS 补 qfskill.cn，referer 分支统一走 _is_allowed_origin"
    },
    "stats_server": {
      "version": "v2.0",
      "note": "SQLite 优先 + JSON 回退，6 个分析端点"
    },
    "db": {
      "version": "1.0",
      "note": "smart_kf.db 171KB+, Python 2 subprocess 驱动"
    }
  },
  "widget_cache": "v21.8_20260921_1428",
  "changelog": [
    {
      "version": "v21.8",
      "date": "2026-09-21",
      "time": "14:28",
      "type": "feature",
      "major": false,
      "title": "客服主动弹出持续降频 + AI接手后停止弹出（三站同步）",
      "details": [
        "现象：客服窗口被关闭后每 10 秒又自动弹出，连续 10 次才降到 30 秒，打扰过重",
        "改动1（autoPopup.intervals 四档降频）：第1-3次维持 10 秒不变 → 第4-6次 60 秒 → 第7-9次 120 秒 → 第10次起 300 秒",
        "改动2（scheduleReopen 新增 AI 接手保护）：STATE.userHasSpoken 为真（用户已发消息、AI 已接管）时不再自动弹出，关闭即安静",
        "覆盖范围：千锋主站群（test-kf.qfedu.com / qfedu.com / mobiletrain.org 共用副本）+ qfskill.com（AI站）+ qfskill.cn（学历站）",
        "验证：本地 3 份文件 node 语法检查 + 12 档位逻辑模拟全绿；线上三站 md5/字节数 + CDN 刷新后复验"
      ]
    },
    {
      "version": "v21.7",
      "date": "2026-09-13",
      "time": "21:05",
      "type": "fix",
      "major": false,
      "title": "修复学历站（qfskill.cn）客服不回复 — 来源校验缺域名导致 403",
      "details": [
        "现象：学历站页面发消息后 AI 不回复；Nginx access log 为 POST /test/smart-kf/api/chat/stream → 403（Referer=https://www.qfskill.cn/cs/ZZY/）",
        "根因：app.py 的 ALLOWED_DOMAINS 只含 qfskill.com（ai-train-seo），漏了 qfskill.cn（学历站主域）；referer 分支另有一份硬编码白名单同样缺 qfskill.cn",
        "修复1：ALLOWED_DOMAINS 增加 'qfskill.cn'（_is_allowed_origin 按域名后缀匹配，自动覆盖 www 及各级子域）",
        "修复2：referer 分支由硬编码列表改为统一调用 _is_allowed_origin()，杜绝今后两处白名单不同步",
        "注：此前 curl 直连测试之所以通过，是因为 curl 不带 Origin/Referer，绕过了这道校验；浏览器请求必带，故只有真人访问才暴露",
        "回归验证：Origin=qfskill.cn→200、仅 Referer=qfskill.cn→200、qfedu.com→200、qfskill.com→200、外部域名→403（安全策略不退化）"
      ]
    },
    {
      "version": "v21.6",
      "date": "2026-09-13",
      "time": "20:00",
      "type": "feature",
      "major": true,
      "title": "客服分站化：学历站独立话术 + 后端按站点分流提示词",
      "details": [
        "widget（学历站独立副本）：人设「升学学姐」、问候语、侧边栏 8 个提升方式入口、信息引擎文案、快捷问题、动态按钮、兜底回复、留资表单（提升意向+当前学历）全部改为学历内容",
        "widget：新增 kf-theme-edu 主题，对齐学历站主色 #2563eb（浅色教育风），替换原 neon 暗紫",
        "widget：chat/stream、submit-lead、session、trigger-push 请求体新增 site_id",
        "backend：新增 SITE_PROMPTS 与 XUELI_SYSTEM_PROMPT；get_or_create_session(site_id) 绑定站点提示词，build_api_messages 按会话取用；未传 site_id 的请求行为完全不变",
        "backend：学历站跳过 course_from_url 的 IT 课程 URL 推断，避免把 /cs/CK/ 之类路径误判成想学 Java",
        "部署：备份(.bak-20260913-1955) → 上传 → restart.sh 重启 → 双站端到端验证 → 刷新 qfskill.cn CDN"
      ]
    },
    {
      "version": "v7.4",
      "date": "2026-08-02",
      "time": "19:05",
      "type": "fix",
      "note": "SSE流式连接关闭修复：widget发消息正常回复"
    },
    {
      "version": "v7.2",
      "date": "2026-07-27",
      "time": "19:19",
      "type": "fix",
      "note": "后端模型deepseek-v4-flash改为固定deepseek-chat(不再进入深度思考导致不回复)；SSE解析器兼容reasoning_content；超时放宽到60s；修复Python3.6 subprocess参数不兼容"
    },
    {
      "version": "v21.5",
      "date": "2026-07-22",
      "time": "12:38",
      "type": "fix",
      "major": false,
      "title": "修复右侧sidebar宽度溢出+左右头部高度对齐",
      "details": [
        "sidebar-section/cta/course/cta-btn 全部添加 box-sizing: border-box + 容器加 width:100%，消除默认content-box下padding撑爆200px边栏导致的溢出",
        "skf-sidebar-poster: min-height:73px → height:73px，确保与左侧header 73px固定高度严格对齐",
        "smart-kf-header: 新增 height:73px + box-sizing:border-box，左右红色区域底部边界保持同一水平线"
      ]
    },
    {
      "version": "v21.4",
      "date": "2026-07-09",
      "time": "21:58",
      "type": "fix",
      "major": true,
      "title": "修复分站session分裂+推送格式回退+Nginx超时",
      "details": [
        "widget: 新增__SMART_KF_LOADED__防重复加载guard，防止旧加载器(ydtswt_pc_yd.js)和新加载器(global.js)同时加载导致多实例session分裂",
        "push_service: 修复推送格式语法错误，聊天记录移到来源前面(与app.py一致)，补当前状态+搜索关键词拆分",
        "nginx: test-kf.qfedu.com proxy_read_timeout 60s→120s，防止DeepSeek响应慢时SSE被中断导致session_id丢失",
        "global.js: WIDGET_URL缓存参数v=21.2→v=21.4，强制浏览器重新请求widget"
      ]
    },
    {
      "version": "v21.3",
      "date": "2026-07-09",
      "time": "21:15",
      "type": "fix",
      "major": false,
      "title": "增强信息提取减少重复索要",
      "details": [
        "姓名提取增加手机号后跟姓名模式(如18321850475 卢小姐)",
        "姓名提取增加XX小姐/XX先生/XX女士后缀模式",
        "课程关键词补全: 无人机方向增加航测/遥感/测绘",
        "修复日志中重复索要姓名的边缘案例(用户一条消息同时给多个信息时)"
      ]
    },
    {
      "version": "v21.0",
      "date": "2026-07-07",
      "time": "14:30",
      "type": "architecture",
      "major": true,
      "title": "原子化传输重构 + 延迟叠加消除",
      "details": [
        "架构重构：SSE失败不再降级XHR（杜绝同消息双发），失败时显示部分回复或友好提示",
        "删除锁防机制：_pendingRequestText 30s锁、_handled回调防重、30s历史扫描去重 — 全部移除",
        "删除人为延迟叠加：REPLY_DELAY从3-6s改为SSE=0-0.3s/XHR=1-2s，前端minDisplayDelay 3s删除",
        "删除ANTI_RACE_DELAY 0.8s：session锁已处理并发，锁内sleep反而阻塞其他请求",
        "SSE首字到达立即显示流式气泡，不再强制等3秒",
        "保留工程安全：_finished防重入（回调多路安全）、5s时间窗去重"
      ]
    },
    {
      "version": "v20.9",
      "date": "2026-07-07",
      "time": "13:45",
      "type": "fix",
      "major": true,
      "title": "修复用户停止输入后 AI 持续回复的问题",
      "details": [
        "根因1：单次用户消息因流式失败降级XHR，SSE和XHR可能都成功，导致同一条消息请求两次后端",
        "根因2：完整信息后AI每次回复都带收尾话术",
        "根因3：页面刷新后restoreSession不恢复历史",
        "修复：_pendingRequestText锁+_finished防重入+SYSTEM_PROMPT改收尾策略+/session返回history"
      ]
    },
    {
      "version": "v20.8",
      "date": "2026-07-07",
      "time": "13:25",
      "type": "fix",
      "major": true,
      "title": "修复AI记忆反馈系统：已有信息不再被重复索要",
      "details": [
        "context改为注入到最后一条user消息前面",
        "temperature从0.7降到0.5"
      ]
    },
    {
      "version": "v20.7",
      "date": "2026-07-06",
      "type": "fix",
      "major": false,
      "title": "修复非11位手机号误判",
      "details": [
        "phone_candidate模式识别非11位数字",
        "build_system_context提示AI引导补全"
      ]
    },
    {
      "version": "v20.5",
      "date": "2026-07-06",
      "type": "backend",
      "major": false,
      "title": "优化AI对话策略",
      "details": [
        "已提供意向课程时不再重复问方向"
      ]
    },
    {
      "version": "v20.0",
      "date": "2026-07-06",
      "type": "architecture",
      "major": true,
      "title": "架构重构：双引擎（信息引擎 + AI自由对话）",
      "details": [
        "前端信息引擎每60秒循环推送预设提醒",
        "用户说话后信息引擎停止AI接管",
        "SYSTEM_PROMPT纯正面引导零'不要'句式"
      ]
    },
    {
      "version": "v21.1",
      "date": "2026-07-09",
      "time": "16:35",
      "type": "feature",
      "major": true,
      "title": "URL课程自动映射 + AI上下文注入 + 推送自动补填",
      "details": [
        "新增 URL_COURSE_MAP 和 course_from_url()：根据用户访问的页面URL自动推断意向课程",
        "build_system_context() 注入 current_page + URL推断课程：AI知道用户在哪个页面，可自然引导方向",
        "推送自动补填：用户没提课程时，从current_page推断并标注（页面推断）",
        "sanitize_user_info 补充URL课程推断：聊天消息无关键词时从URL推断课程"
      ]
    },
    {
      "date": "2026-07-09",
      "version": "v21.2",
      "changes": [
        "widget: extractSearchKeyword添加神马(sm.cn)/知乎(zhihu.com)关键词参数解析",
        "widget: detectSource添加神马搜索/知乎搜索/360搜索+关键词/Bing搜索+关键词",
        "widget: decodeURIComponent异常保护(catch(e2)返回原始kw)",
        "backend: build_system_context注入访问来源(source)信息到AI上下文",
        "backend: 推送格式拆分来源引擎+搜索关键词独立显示"
      ]
    }
  ]
}