@cnki_frontend/agent-chat

中文文档
0.3.10发布于 2026/11/10TypeScriptES Module近 30 天下载 2210

按场景驱动的可嵌入 AI 问答组件:流式过程编排、文档呈现、多实例隔离

原始使用文档
文档目录22 节
  1. 快速开始
  2. 会话写接口用 mock、其余走真实后端
  3. 本地联调示例(playground)
  4. 运行
  5. 两种调试视图
  6. 目录内容
  7. 作为使用者如何运行
  8. 开发约定(改本仓库前必读)
  9. 1. 引用文件 必须 使用相对路径
  10. 2. agent-chat 的业务代码 一律在本仓库内修改
  11. 嵌入到宿主项目
  12. 参数(AgentChatOptions)
  13. 宿主操作句柄(AgentChatHandle)
  14. 跨窗口消息协议(iframe 嵌入)
  15. 关键约定
  16. 接口契约
  17. 统一鉴权
  18. 文档链接 doc://<id>
  19. make-answer 结构化确认交互
  20. 路由即真相源
  21. 文档渲染器(按类型分流,不混用)
  22. 常用命令

Agent Chat

AI 问答前端:左侧会话历史 + 中间问答流 + 右侧过程/文档/溯源分栏,按场景(scene)驱动的多实例可嵌入组件。

核心特点:

  • 按 Agent 步骤编排 UI:一条 assistant 消息内部拆 thinking → tool_call → answer;流式过程中逐步展开,完成后过程区折叠成一行摘要(步数 / 工具数 / 耗时),可点开回看,回答正文常驻
  • 回答正文 / 过程 双区 + 文档呈现区:正文里的链接按需打开右侧面板,支持 Markdown / Word / PPT 内联预览、溯源清单,宽度可拖拽持久化
  • 单流控制:每个实例同一时刻只允许一条流在跑,启动新的会先中断旧的并标记 interrupted;支持用户中断、复制回答、失败重试、重新生成、溯源查看
  • 完全隔离的 scope:内部自建 pinia / router / api / 流控制器,不 app.use(),不占用宿主 URL(默认 memory history),同一页面可放多个实例互不干扰

快速开始

npm install
npm run dev          # http://localhost:5173

Demo(playground/APP.vue)复现宿主 src/views/chatView.vue 的接入方式(单实例 + 跨窗口 postMessage 协议),无需宿主工程即可联调。

Mock 开关走环境变量 VITE_USE_MOCK,默认 false(走真实接口):

$env:VITE_USE_MOCK = "true"; npm run dev        # PowerShell
VITE_USE_MOCK=true npm run dev                  # bash / zsh

打开 Mock 后接口走本地假数据,右侧呈现面板、过程动画、失败注入都可以脱离后端直接验证。

会话写接口用 mock、其余走真实后端

后端往往先出列表 / 详情 / 流式,而新建、重命名、删除后补。这时把 config.mockSessionApi 打开(默认 true): 新建 / 重命名 / 删除走本地假数据,会话列表(POST /dsh/session/pageList)、 详情(GET /dsh/session/upstreamHistory 历史回放)与提问流(POST dsh/chat/stream)都走真实后端。 后端写接口就绪后把它置为 false 即可,无需改代码。

<AgentChat scene="default" :config="{ mock: false, mockSessionApi: true }" />

本地联调示例(playground)

包内自带一个可独立运行的联调 demo(playground/),完整复现宿主 src/views/chatView.vue 的接入方式,便于不启动宿主工程就验证跨窗口协议、AgentChatHandle 会话桥与样式。该目录已纳入 files 白名单随包发布,安装后可在 node_modules/@cnki_frontend/agent-chat/playground/ 看到源码。

运行

npm run dev          # 启动 playground,默认 http://localhost:5173

npm run dev 走 vite.config.ts(已挂 @vitejs/plugin-vue 且根目录设为 playground),无需宿主工程。

两种调试视图

playground 通过同一个 import 语句 import AgentChat, { type AgentChatHandle } from '@cnki_frontend/agent-chat' 切换视图,由环境变量 AGENT_CHAT_USE_DIST 控制:

模式命令解析到用途
源码(默认)npm run dev别名 → ./index.ts改 src/ 实时热更,调试最新实现
打包产物AGENT_CHAT_USE_DIST=1 npm run dev别名 → ./dist验证「安装后的包」真实行为(需先 npm run build 出 dist)

与宿主 vite.config.ts 的 AGENT_CHAT_USE_DIST 开关一致:开发态引源码、生产态引 dist。

目录内容

  • playground/APP.vue:chatView.vue 的接入骨架——agentChatRef 接组件 defineExpose 句柄、挂载后写入 agentChatHandle、消费 pendingSessionId、监听 message(onHostMessage)、向父页 postMessage('ready')、401 时 postMessage('needLogin')。
  • playground/main.ts:引入 @cnki_frontend/agent-chat/style.css(别名已覆盖 source / dist 两种来源)。
  • playground/config/scenes/jgxkdmx.json:示例场景配置。

agentChatBridge 的两个变量(agentChatHandle / pendingSessionId)在 playground 里是就地内联的 ref,并未从宿主导入——它们只是两个响应式句柄,移交给宿主桥接层即可。

作为使用者如何运行

从 npm 安装本包后想直接跑这个 demo,需自行补上运行依赖(它们是包的 devDependencies,不随安装带入),二选一:

# 方案 A:在包目录内补装并运行
cd node_modules/@cnki_frontend/agent-chat
npm i -D vite @vitejs/plugin-vue
npm run dev

# 方案 B:把 playground/ 拷到自己的项目,再补装上述依赖后运行

开发约定(改本仓库前必读)

1. 引用文件必须使用相对路径

import type { AgentStep } from '../../types/session'   // ✅
import { useScopedSessionStore } from '../../scope/useScope'

import type { AgentStep } from '@/types/session'       // ❌ 不许用别名
import { XXX } from '@pkg/scope/useScope'              // ❌ 同上

具体写法:

  • 同一子树内部:./MessageList.vue、./useScope
  • 跨顶层目录(types / scope / stores / composables / api / utils / mocks):按文件所在深度取 ./ ../ ../../,最深只有两层
  • 不要绕到根再绕回来:components/chat/ 里引文档面板应写 ../document/DocumentPanel.vue,而不是 ../../components/document/DocumentPanel.vue
  • 代价是移动或新建文件要同步改导入,改完跑一次 npm run build

2. agent-chat 的业务代码一律在本仓库内修改

本仓库是唯一真源。 任何问答、过程、文档呈现、调用链路相关的改动,都在本仓库源码里做,改完再同步给宿主。 不要把 src/ 拷进宿主后就地改一版了事——下次同步会把这些改动直接覆盖掉。

宿主侧允许做的事只有三件:安装依赖、引入样式、通过 props(scene / config / routerMode / storage)做定制。场景级差异优先走 props 与 src/scope/scenes.ts 里新增场景配置,而不是在宿主里 fork 一份组件改。

嵌入到宿主项目

宿主工程只通过安装 @cnki_frontend/agent-chat 包的方式引入 agent-chat:npm i @cnki_frontend/agent-chat 后,在宿主侧 import AgentChat from '@cnki_frontend/agent-chat',并按下方「2)引入样式」在宿主入口 main.ts 引入样式即可。不要把 src/ 整坨拷进宿主——包内已自包含全部代码与资源,宿主零源码改造。

1)安装依赖(包本身不内置运行时依赖,相关库作为对等依赖由宿主提供):

npm i @cnki_frontend/agent-chat
# 以下为对等依赖,宿主需自行安装(版本见 @cnki_frontend/agent-chat 的 peerDependencies)
npm i vue pinia vue-router axios @microsoft/fetch-event-source markstream-vue vditor docx-vue-viewer pptx-vue-viewer

2)引入样式(宿主需自行安装 @cnki_frontend/agent-chat 包):

// 宿主 src/main.ts
import '@cnki_frontend/agent-chat/style.css'

切勿用 vite-plugin-lib-inject-css 做运行时内联注入:它对懒加载 chunk 的 CSS 会迟于首帧应用,导致 pptx-vue-viewer 这类「按容器尺寸自适应」的 viewer 在首帧 无样式状态下测量布局、触发 ResizeObserver 循环 → 页面持续闪烁(word 不受影响, 因其为静态文档、不做 fit-to-container)。本包的 exports 已暴露 ./style.css。

3)使用组件:

<script setup lang="ts">
import AgentChat from '@cnki_frontend/agent-chat'
</script>

<template>
  <!-- 父容器需要给定高度:组件根是 height:100% -->
  <div style="height: 100vh">
    <AgentChat scene="analysis" :config="{ placeholder: '输入你的问题' }" />
  </div>
</template>

不要在宿主 app 上 app.use(pinia) / app.use(router) 来"接管"组件:scope 内部的 pinia 与 router 都下发在其组件子树上,宿主全局实例与它互不感知,这是刻意设计。

参数(AgentChatOptions)

参数类型默认说明
scenestring必填业务场景标识,决定接口参数、文案与 mock 数据
scopeIdstring取 scene同场景同屏多实例时用于区分(影响 localStorage key)
routerMode'memory' | 'web''memory'memory 不占用宿主 URL(默认,多实例安全);web 读写地址栏,同页面只允许一个 web 实例(window.history 是浏览器单例,base 冲突时开发模式会告警)
basestringweb 模式为 /<scene>,否则 /router 基路径
configPartial<SceneConfig>—覆盖该场景的 title / placeholder / samples / apiBase / mock / mockSessionApi
storageStoragelocalStorage呈现区宽度等本地持久化介质的注入点
requestRequestOptions—请求定制:headers()(可 async)/ withCredentials / onError(统一异常出口,见「统一鉴权」)
apiPartial<ChatApi>—数据端口逃生舱,按 key 覆盖任意方法(见「接口契约」)

scene 是构造参数而非响应属性:运行时切换请给组件加 :key 重建实例。

宿主操作句柄(AgentChatHandle)

通过组件 ref 拿到操作句柄,只暴露方法、不暴露内部 store,宿主据此驱动会话而不耦合 agent-chat 的 Pinia 实例:

<script setup lang="ts">
  import { ref } from 'vue'
  import AgentChat, { type AgentChatHandle } from '@cnki_frontend/agent-chat'  // 也可直接引 './packages/agent-chat/AgentChat.vue'
  const agentChatRef = ref<AgentChatHandle | null>(null)
  // 组件挂载后即可通过 ref 操作;方法内部自行同步 store / 路由
</script>

<template>
  <div style="height: 100vh">
    <AgentChat ref="agentChatRef" scene="analysis" />
  </div>
</template>
方法返回说明
getSessions()Ref<Session[]>会话列表(响应式;宿主读 .value 随 agent-chat 内部变更实时更新)
getCurrentId()Ref<string | null>当前选中会话 id(null = 首页 / 新对话态)
getGeneratingIds()Ref<Set<string>>生成中会话 id 集合(远端轮询 ∪ 本地流 的并集);宿主侧边栏据此显示「忙」图标。问答 finish/fail/stop 时会立即触发一次轮询刷新,无需等下一周期
openSession(id)void打开指定会话(走 agent-chat 内部路由跳转)
startNew()void回首页 / 新对话态,清空当前会话
createSession(title?)Promise<Session | null>立即新建空会话并返回
loadMoreSessions()Promise<void>加载下一页(内部有 loading/hasMore 保护,重复调用无副作用)
deleteSession(id, title?)Promise<void>删除会话(调后端 + 本地清理 + 提示,同一套逻辑)
renameSession(id, title)Promise<void>重命名会话(同一套逻辑)
ask(input)void在当前会话发起一轮提问(与输入框同一条流式链路;sending 中调用被内部守卫忽略)
askNew(prompt, title?, model?)Promise<Session | null>传提示词自动新建会话(后端建会话须带 prompt + model)并进入该会话、流式补全首轮回答(链路同首页首问:createSession(prompt, model) → setPendingPrompt → 跳转由 ChatView 拉流)。model 省略用场景默认模型;可选 title 建完用 renameSession 补标题(库无「建会话带标题」API)。每次新建互不干扰,返回新建会话(失败 null)
getPaging()SessionPaging分页状态(hasMore / loading),用于「加载中 / 没有更多了」
setSearchKeyword(keyword)void设置会话列表标题筛选关键字;空串取消筛选、回到「最近生成」

跨窗口下发提示词:agent-chat 库不内置入站 postMessage 监听;iframe / 新窗口场景下,宿主应在自己的 message 处理器里,对拿到的 AgentChatHandle 调用 askNew(prompt)(参考 playground/APP.vue 的 onHostMessage 写法)。

跨窗口消息协议(iframe 嵌入)

当 agent-chat 被放进 iframe 嵌入宿主页面时,双方用 window.postMessage 通信(不依赖 $bus/$emit,跨 window 无效)。

agent-chat / 嵌入页 → 宿主(父窗口):以下消息一律以 JSON 字符串 发出(JSON.stringify),宿主 window 监听后需 JSON.parse。注意宿主既有 _onMessage 对 typeof === 'object' 的消息直接 return,故 agent-chat 侧必须发字符串。

cmdpayload含义 / 宿主动作
agentChatSidebar{ cmd:'agentChatSidebar', source:'agent-chat', collapsed: boolean }agent-chat 内部会话侧边栏收起 / 展开;宿主可据此隐藏 / 显示自己的会话侧边栏,避免两套并列
needLogin{ source:'agent-chat', cmd:'needLogin' }401 时由嵌入页 dealError 发出;宿主应触发登录流程
ready{ source:'agent-chat', cmd:'ready' }嵌入页 onMounted 注册完 message 监听后发出;宿主收到后才可安全下发指令(见下)

宿主 → agent-chat(经嵌入页监听器):以下消息可为对象或字符串(嵌入页 onHostMessage 两者都解析);字段约定 source + cmd。

cmdpayload含义 / 动作
goHome{ source:'chat_web', cmd:'goHome' }触发 agentChatRef.startNew(),回首页(不重载 iframe,保留内存态)

握手(避免竞态):本应用 src/main.ts 有顶层 await loadRuntimeConfig(),app.mount() 在其后才执行,故嵌入页 onMounted(message 监听注册)晚于 iframe 的 load 事件。若宿主在自身 onMounted / @load 直接 postMessage,消息会在嵌入页监听就绪之前到达并被丢弃(postMessage 不缓存)。推荐做法:宿主监听 ready,收到 ready 后再下发 goHome;未就绪前的指令先排队,收到 ready 后补发——无论 iframe 加载多慢都 100% 收到。

关键约定

接口契约

组件对外部世界的唯一依赖是 ChatApi 这 6 个方法(定义在 src/api/index.ts),不含任何 HTTP / URL / 鉴权细节:

interface ChatApi {
  listSessions: () => Promise<Session[]>
  createSession: (title?: string) => Promise<Session>
  renameSession: (id: string, title: string) => Promise<void>
  deleteSession: (id: string) => Promise<void>
  fetchSessionDetail: (id: string) => Promise<SessionDetail>
  streamChat: (req: StreamChatRequest) => StreamHandle
}

默认实现:REST 走 axios(src/api/http.ts),流式走 @microsoft/fetch-event-source(src/api/sse.ts)。scene 不拼进 URL 路径,一律作参数(GET 走 query、写操作与流式走 body):

方法路径参数说明
POST{apiBase}/dsh/session/pageList{ pageNum, pageSize }会话列表
POST{apiBase}/sessions{ title }新建会话,由后端返回 id
PATCH{apiBase}/sessions/:id{ title }重命名
DELETE{apiBase}/sessions/:id—删除
GET{apiBase}/dsh/session/upstreamHistorysessionId / pageNum / pageSize详情 = 历史回放:一行一轮(question + answer),翻页合并后还原成 messages
POST{apiBase}/dsh/chat/streammultipart:prompt / sessionId / moduleCode / featureCode流式问答,返回 SSE 流

历史回放以 messages[].evens 为渲染源:里面存的是当时那帧 SSE(与实时流返回一致),逐条喂给与实时流同一个解析器(src/api/agentStream.ts),因此历史消息的步骤构成、步骤 id 与实时一致。

同行的 answer / artifacts 只是兜底:只有当 evens 缺失或一条都没回放出来(老会话没存事件)时才使用,避免用字段值覆盖掉事件里更完整的思考 / 工具过程。

流式请求走 SSE,事件名在 event: 上(服务端不发 event 名时退回 payload 的 type 字段)。解析器(src/api/agentStream.ts)先把三种帧形态归一成 {type, data} 再分发:旧 {payload:{event:{type,data}}}、整体序列化 {type,data}、新 event:<名称> + 帧体即负载。

eventdata落到哪里
start{ session_id }顶层:记录会话 id
assistant/message{ step, message:{content:[…]} }一条 assistant 快照:reasoning/thinking → 思考 step、text → 回答正文、tool-call → 工具调用 step
tool/call{ step, callId, name, arguments }工具调用(补全 assistant/message 里缺的工具名 / 入参)
tool/result{ callId, result|result_summary, isError }工具回包:落到对应 tool_call step 的 toolOutput,isError 时置 error
todo/write{ todos:[{ content, status }] }任务清单 → todo step
subagent/catalog{ childId, mode, label }子代理身份,挂到最近一次 subagent 工具调用上
session/title{ title }会话标题
step/end{ step }步骤边界:把该 step 分组的 step 标记 done
compaction/start | compaction/end—上下文过长自动压缩的提示(notice)
make-answerMakeAnswerData结构化确认卡 → make_question step(见「make-answer 结构化确认交互」)
done{ final_response?, artifacts|deliverables? }顶层:final_response 为最终答案,产物名单写入 message 级注册表,随后收尾
error{ code, detail, http_status }顶层:置 error 态,出现重试入口
server/queued—顶层:实例繁忙排队提示

另有仅识别、不产出 step 的流水事件:user/message、system/message、agent/inbox/spliced、request/header、request/context、session.status、turn/start、turn/end、step/start、tool/error(工具错误走 tool/result 的 isError)。

后端形状对不上时,用 props 注入自己的实现,而不是把源码拷过去改:

<AgentChat
  scene="analysis"
  :request="{
    headers: async () => ({ Authorization: `Bearer ${await getToken()}` }),
    withCredentials: true,
    onError: (err) =>
      (err.status === 401 || err.status === 403) && router.push('/login'),
  }"
  :api="{ listSessions: myList, streamChat: mySse }"
/>

api 是按 key 覆盖(partial),未列出的方法仍走默认 HTTP 实现;流式要回调的领域事件见 src/api/sse.ts:onStep、onStepUpdate、onDocuments、onTraces、onDone、onError。

请求 / 流失败统一归一为 ApiError(带 status / url / payload),不需要宿主认识 axios / SSE 的结构。

store 侧的写操作统一走「乐观更新 → 调接口 → 失败回滚」:重命名/删除失败会自动还原,新建失败不会跳进一个后端并不存在的会话 URL。

统一鉴权

组件不内置任何凭证逻辑,鉴权全部由 request props 注入,而且只有一个出口:

interface RequestOptions {
  /** 每次请求前调用,返回要附加的 header;支持 async(便于过期再取 / 刷新 token) */
  headers?: () => Record<string, string> | Promise<Record<string, string>>
  /** 跨域请求携带 cookie */
  withCredentials?: boolean
  /**
   * 统一异常出口:所有请求 / 流失败(含 401 / 403、网络失败、服务端 error 帧)
   * 归一为 ApiError 后回调,由宿主统一处理(跳登录 / 刷新凭证 / 全局提示)。
   */
  onError?: (err: ApiError) => void
}
  • REST:axios 请求拦截器注入(见 src/api/http.ts)
  • SSE:fetch-event-source 内部自建 fetch、不过拦截器,但取的是同一个 buildHeaders() 钩子

因此不会出现「REST 带了 token、流式没带」这类漂移。每个 scope 一个 axios 实例(不用全局默认实例),多实例之间互不污染。

文档链接 doc://<id>

assistant 正文中的链接会被事件委托拦截并打开右侧呈现区,支持三种写法(src/utils/docLink.ts):

  • doc://<id>:从本轮消息的 documents 注册表取实体
  • 带扩展名的 URL:按扩展名推断类型(.md/.txt → markdown,.docx → word,.pptx → ppt)
  • 其它:降级为「打开/下载」

回答末尾的产物列表每行带「预览 / 下载」两个按钮(components/chat/AssistantMessage.vue):预览走与正文链接同一条路(锁定该产物后打开右侧呈现区),下载走 utils/download.ts(先 fetch 成 blob 再落盘,保证用原始文件名;地址不可 fetch 时退回直接打开)。后端没返回 url 的产物两个按钮都禁用。

make-answer 结构化确认交互

后端可在流里发一个 make-answer 事件,让助手在生成前先与用户确认细节。前端把它渲染成一张确认卡(src/components/chat/MakeAnswerCard.vue),常驻在正文区、不进折叠过程区:

  • 载荷 MakeAnswerData:title(引导文案)、fields:[{label,value}](课程/章节/题型/知识点等键值明细)、selectLabel(可选项标题)、options:[{id,label}](可选项)、skipText(动作按钮文案)、multiple(是否多选,默认 true)、answerPrefix(确认提问前缀)、skipPrompt(跳过提问文案)
  • 交互:chips 多选 + 单个动作按钮(无独立确认按钮)。点按钮即发起一轮新问答:有选中 → 新问题为 {answerPrefix}选中{label、label}(如 知识点选中需求曲线);未选 → 新问题为 {skipPrompt}(默认 跳过)。answerPrefix 缺省时从 selectLabel 推导(去括号、去尾部「范围」,如 知识点范围(可多选) → 知识点)
  • 接线:make-answer 在 src/api/agentStream.ts 解析为 kind:'make_question' 的 step(载荷落 AgentStep.makeAnswer);AssistantMessage.vue 渲染卡片并经 ask() 以 prompt 文本通道发起新一轮(后端当前只有 prompt 这一个文本通道)
  • Mock:src/mocks/stream.json 的 makeAnswer 即该卡演示数据,首轮提问会出现

路由即真相源

/ 首页,/chat/:id? 问答页(id 为空时自动落到会话并 replace 成带 id 的 URL)。store 单向跟随路由同步,不反向决定路由。

文档渲染器(按类型分流,不混用)

位置渲染器原因
回答正文(历史消息)markstream-vue需要流式增量渲染
呈现区 Markdown 文档vditor(ir 即时渲染)所见即所得,可直接在渲染结果上编辑
呈现区 Word 文档docx-vue-viewer 的 WordEditorDOCX 内联预览 / 编辑
呈现区 PPT 文档pptx-vue-viewer 的 PowerPointViewerPPTX 内联预览
呈现区 JSON<pre> 纯文本(JsonPreview.vue)缩进后原样铺开,不做树形 / 高亮

常用命令

npm run dev       # 开发服务器
npm run build     # vue-tsc --noEmit && vite build
npm run preview   # 预览构建产物

版本与发布记录

@cnki_frontend/agent-chat 共发布 16 个版本,首次发布于 2026/11/05;过去 12 个月发布了 16 个版本。

版本发布日期距今
0.3.10latest2026/11/10今天
0.3.92026/11/09今天
0.3.82026/11/063 天前
0.3.72026/11/063 天前
0.3.62026/11/054 天前
0.0.0-stage2026/11/054 天前

关于 @cnki_frontend/agent-chat 的常见问题

@cnki_frontend/agent-chat 是什么?

按场景驱动的可嵌入 AI 问答组件:流式过程编排、文档呈现、多实例隔离

如何安装 @cnki_frontend/agent-chat?

在项目目录运行 npm install @cnki_frontend/agent-chat,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:vue(^3.4.0)、pinia(^2.1.0)、vditor(^4.0.0)、vue-i18n(^11.0.0)、vue-router(^4.2.0)、markstream-vue(^2.0.0)、docx-vue-viewer(^1.1.0)、pptx-vue-viewer(^4.58.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cnki_frontend/agent-chat 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cnki_frontend/agent-chat 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cnki_frontend/agent-chat 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cnki_frontend/agent-chat 可以商用吗?

@cnki_frontend/agent-chat 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@cnki_frontend/agent-chat 的下载量有多少?

根据 npm 官方下载统计,@cnki_frontend/agent-chat 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,210 次,日均约 74 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cnki_frontend/agent-chat 还在维护吗?

最新版本 0.3.10 发布于 2026/11/10(今天);至今共发布 16 个版本,其中过去 12 个月发布了 16 个;首次发布于 2026/11/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。