@wil-works/evoke-chat AI 使用说明(v0.5.1)
本页由
packages/evoke-chat/scripts/gen-ai-docs.mjs自动生成,勿手改(改了会被构建门拦下)。
给 AI 读:先看「硬规则」,再按「任务配方」找 API,最后用逐组件表核对字段名。 完整散文文档见 对话窗口;同内容的结构化契约见 evoke-chat.components.json。
硬规则
- 组件只做呈现,任何请求都由宿主注入(transport / fetch / SDK),包内不发网络请求。
- 流式回写一律用
appendContent/appendThinkContent(自动转 streaming),不要自己拼字符串。 - 用户主动停止是
cancelled(cancelMessage),不是error;中断后迟到的事件会被拒绝。 - 工具调用按 id 操作(
startToolCall返回 id),子调用同样按 id,写操作自动递归。 - 文案随包走(
/locale),中英键位同构;宿主只覆盖,不改组件。 - 字段名以本文档的组件表为准;不确定就先查 JSON 契约,不要猜 prop 名。
任务配方
流式回写模型输出
API:useChatEngine.createAssistantMessage、appendContent、appendThinkContent、completeMessage
const engine = useChatEngine()
const msg = engine.createAssistantMessage()
// 逐片回写:appendContent 自动把消息转成 streaming 态(卡片露出光标)
engine.appendContent(msg.id, chunk)
engine.appendThinkContent(msg.id, reasoningChunk) // 思维链与正文分开
engine.completeMessage(msg.id) // 收尾:settle 耗时、转 done注意:
- 不要自己拼字符串后 setMessageContent——那样没有 streaming 光标与贴底
- 正文与思维链必须分开两个 API,混写会串行渲染
消息内交错(parts)
API:createAssistantMessage、appendContent、appendThinkContent、startToolCall
// appendContent / appendThinkContent / startToolCall 自动记录到达顺序(message.parts),
// 组件按 parts 交错渲染:正文 → 工具卡 → 正文。
engine.appendContent(msg.id, '查到近 6 个月的数据:')
engine.startToolCall(msg.id, { name: 'sql_query', label: '查询营收' })
engine.appendContent(msg.id, '对比行业均值来看…') // 工具卡之后的正文段
// content / thinkContent / toolCalls 是 parts 的平面投影:复制、朗读等平面消费照旧注意:
- parts 是真相:{ id, type: text/reasoning/tool, text?, toolCallId? };连续同型增量合并进尾部 part
- 落定覆写(assistant/message 的 content)只改投影不动 parts——渲染以 parts 为准
- 子调用(addSubToolCall)不占消息级位置:它渲染在父卡内部;无 parts 的老消息走固定顺序
停止生成(用户点停止 / 双击 Esc)
API:cancelMessage
// 组件侧:EbAiPromptBox / EbChatSender 的 stop 事件
function onStop() {
engine.cancelMessage(msg.id)
transport.cancel() // 后端协作式中断
}注意:
- 取消是 cancelled,不是 error:不要用 setMessageError 表达用户主动停止
- cancelMessage 会把思考态标记为「思考已中断」,并把在跑/等待的工具调用落 cancelled
- 中断后迟到的增量与收尾会被拒绝(appendContent / completeToolCall 返回空)
渲染工具调用(含流式输出)
API:startToolCall、appendToolCallArgs、appendToolCallResult、completeToolCall、failToolCall
const callId = engine.startToolCall(msg.id, { name: 'web_search', label: '联网检索' })
engine.appendToolCallArgs(msg.id, callId, '{"query":') // 入参也流式:JSON 文本逐片拼,卡片边收边显示
engine.appendToolCallArgs(msg.id, callId, '"Q3 营收"}')
engine.appendToolCallResult(msg.id, callId, '命中 3 条…') // 输出侧边跑边出
engine.completeToolCall(msg.id, callId) // 收尾:拼完的入参自动 parse 回对象注意:
- completeToolCall 第三参省略时保留流式输出,传空串才会清空
- 失败用 failToolCall(错误首行会摘要显示),不要走 completeToolCall
- 入参按 JSON 文本拼接,收尾自动 parse 回对象;半截 JSON parse 不动就保留原文(诚实展示)
工具调用里挂子步骤(并行派发 / PTC)
API:addSubToolCall、findToolCall
const parent = engine.startToolCall(msg.id, { name: 'fetch_page' })
const child = engine.addSubToolCall(msg.id, parent, { name: 'parse_html' }) // 返回子调用 id
engine.completeToolCall(msg.id, child, '解析出 3 个小节')注意:
- append/complete/fail 都按 id 递归作用到子层,无需手动找父节点
- 嵌套上限 16 层,超深返回 null
审批接管(危险操作前问一句)
API:EbChatApproval、useChatSession.respondApproval
<eb-chatbot :approval="approval" @approval-respond="onApprovalRespond" />
// 宿主侧
const answer = await askApproval({ id, toolName: 'web_search', reason: '需要联网' })
// answer: 'allowed-once' | 'rejected'
session.respondApproval('allowed-once')注意:
- 只有两种结论:allowed-once / rejected(没有「总是允许」——那属于会话级权限模式)
- 审批非空时输入台让位给审批面板,优先级高于提问
提问接管(干活前澄清口径)
API:EbChatQuestion、useChatSession.respondQuestion
<eb-chatbot :question="question" @question-respond="onQuestionRespond" />
const answer = await askQuestion({
id, items: [{ id: 'scope', question: '按哪个口径对比?', options: [{ key: 'mom', label: '环比', recommended: true }] }],
})
// answer: { status: 'answered' | 'cancelled', answers: [{ selected: ['mom'], custom, skipped }] }注意:
- 跳过算「已回答」(skipped: true),取消是整批作废(status: cancelled)
- 单选互斥、多选累加、自定义输入同题互斥
显示上下文占用
API:EbChatContextMeter、useChatSession.setContext
<eb-ai-console :context="{ used, capacity: 32000, breakdown: { system, tools, messages } }" />
// 或由事件驱动
session.setContext({ used: 12800, capacity: 32000 })注意:
- used 与 capacity 缺一不渲染——拿不到窗口容量时画环只会误导
- 百分比封顶 100%,75% 警告 / 90% 危险
展示本轮改了哪些文件
API:EbChatChanges、useChatEngine.setChanges
engine.setChanges(msg.id, {
total: 3, added: 96, deleted: 18,
files: [{ path: 'src/a.vue', display: 'a.vue', added: 88, deleted: 12 }, { path: 'assets/logo.png', binary: true }],
})注意:
- 单文件时标题直接给文件名;二进制/过大不给行数只给标记
- 列表默认露 4 行,超出收在「全部 N 个文件」
接真实后端(会话日志层:断线可恢复)
API:useChatSession、createSessionLog、applySessionEvent
const transport = {
open: ({ cursor, onEvent, onGap }) => subscribe({ cursor, onEvent, onGap }), // 长连/轮询均可
page: ({ from, limit }) => fetchRecords({ from, limit }), // 补页
send: (payload) => post(payload), cancel: () => abort(), // 发送与中断
approve: (outcome, request) => postApproval(outcome, request),
answerQuestion: (answer, request) => postAnswer(answer, request),
}
const session = useChatSession({ transport })
session.open({ cursor: 0, records: [] })注意:
- 事件信封 { type, seq, time, data, ignorable?, surfaceOp? };seq 必须连续,缺口会缓冲并回调 onGap
- 游标只被持久事件推进;瞬时事件(审批/提问/占用)不会推进也不会造成缺口
- 不可忽略的未知事件会标记 degraded,宿主应重拉整窗
- open() 必须在 submit 前调(忘调会自动补开但告警);切会话 = 再 open()(旧订阅迟到事件被代际守卫丢弃),彻底停用 dispose()
- 结构化进度走 assistant/progress 瞬时事件 { messageId, label, detail?, elapsedMs?, percent? },别把阶段进度拼进 think 文本
- 入参流式走 tool/args 瞬时事件 { messageId, callId, chunk };assistant/message 可带 model/provider(模型归属透传)
直接接 OpenAI / Anthropic
API:createChatTransport
const transport = createChatTransport({
provider: 'anthropic', // 'openai' | 'anthropic',或自定义 adapter 对象
apiKey, model: 'claude-sonnet-4-5', system: '你是运营助手',
tools: [{ name: 'web_search', description: '联网检索', parameters: {…} }],
contextWindow: 32000,
getMessages: () => session.messages.value,
onExtension: ({ event, data, json }) => { // RAG 引用/进度等非标准载荷
if (json?.type === 'citations') { session.receive(mapCitations(json)); return true }
},
})注意:
- 浏览器直连会暴露 key:生产走自己的后端代理(url 指到代理)
- 这两家没有 follow/补页协议,历史要宿主自己存
- 工具参数是分片 JSON,适配层已按 index 拼完再 parse
- onExtension 返回 true = 本帧已被扩展消费,跳过标准映射;自研后端可给 provider 传实现 createState/buildRequest/headersOf/frameToEvents/finalize 契约的对象,不必手写 transport
- 中断已接进 SSE 解析层:abort 解除挂起的 read 再补 turn/end(aborted),不会一直挂
正文行内引用(RAG 引用锚点)
API:anchorSource、EbChatSources、citation-click
// citations 是回合级语义(来源卡渲染在正文之后);行内关系用 source: 协议
engine.appendContent(msg.id, '根据' + anchorSource('doc-3', '3') + ' 篇文档…')
// 等价于正文里写 [3](source:doc-3):渲染成可点上标,点击 → EbChatSources 高亮对应卡片
// text 省略则按出现顺序自动编号;text 给数字则固定该序号注意:
- anchorSource(refId, text?) 返回 markdown 片段;refId 必须与 citations[].id 一一对应,否则点了没卡可高亮
- citations 是回合级(消息级字段、渲染在正文后),行内锚点才是"这句来自哪篇"的表达
- 纯文本 renderMode 下 source: 协议不渲染上标,只有 markdown 模式支持
内部流水线时间线(progressLog)
API:appendProgress、clearProgress、setProgress
// progress 是「当前一句话」;progressLog 是完整轨迹(理解→检索→核对→合成…)
engine.appendProgress(msg.id, { label: '检索知识库', detail: '命中 12 段', elapsedMs: 340 })
engine.appendProgress(msg.id, { label: '合成答案' })
// 追加联动更新当前行;历史阶段(≥2 条)收进「前 N 个阶段」折叠,展开是紧凑日志注意:
- setProgress 只更新当前行不记轨迹;appendProgress 记轨迹并联动当前行
- progressLog 是系统轨迹,别当 plan 用——给用户看的计划走 setPlan
- 收尾(completeMessage / cancelMessage / 出错)会清掉 progress;progressLog 默认也清(进度只属于进行中的轮),宿主要事后审计就用 useChatEngine({ keepProgressLog: true }) 或 clearProgress(id, { keepLog: true }) 留轨迹
记用量与模型归属
API:useChatEngine.setUsage
engine.setUsage(msg.id, {
promptTokens: 120, completionTokens: 380, totalTokens: 500,
cost: 0.0032, currency: '$', // 成本要价目表,是宿主业务数据;不给就不显示
segments: [{ label: '检索阶段', tokens: 320 }, { label: '生成阶段', tokens: 180 }],
})
// 模型归属是消息级字段:message.model / message.provider,底部读数行显示 provider/model
engine.updateMessage(msg.id, { model: 'claude-sonnet-4-5', provider: 'anthropic' })注意:
- usage 字段面:prompt/completion/totalTokens、cacheRead/cacheWrite/reasoningTokens、ttftMs、tokensPerSecond、cost、currency、segments
- segments 是分段记账(如检索 vs 生成),多条汇总时按 label 合并累加
- model / provider 只透传不解析:引擎不猜路由,多模型时由后端在 assistant/message 事件里带上
自定义工具卡的参数/结果渲染
API:EbChatToolCall 的 #args / #result 插槽
<eb-chat-tool-call :tool-call="call">
<template #result="{ toolCall }"><eb-json-viewer :data="toolCall.result" /></template>
</eb-chat-tool-call>注意:
- 默认是带环检测的 JSON <pre>;只要换成插槽就不会丢默认的折叠/状态语义
- resultType: text / json / image / file——image 认 { url, alt? }、file 认
- 非文本 URL 只放行 http/https/data(与正文图片同款白名单),其余退回文本
多语言
API:chatLabels、useChatLabels、@wil-works/evoke-chat/locale
import zhCN from '@wil-works/evoke-chat/locale/zh-CN'
app.use(EvokeChat, { locale: zhCN })注意:
- 文案随包走,中英键位必须同构(有测试守)
- 宿主自定义文案用 chatLabels 覆盖,不要 fork 组件
组件契约
EbChatbot
EbChatbot 之外的家族成员。绝大多数场景不需要直接用它们——EbChatbot 已经把这些组装好了。它们用于两种情形:只想要其中一块(比如独立渲染一段 Markdown),或要自己编排(ChatList + 自定义发送区)。
- 入口:
@wil-works/evoke-chat/chatbot源码:src/components/chatbot/Chatbot.vue文档:https://evoke-business-ui.wil-works.com/chat/chatbot - 插槽:
header、empty、message-header、message、message-content、tool-result、tool-args、sender-menu、sender-prepend、sender-toolbar、sender-append、tip
| prop | 类型 | 默认 |
|---|---|---|
modelValue | Array | () => [] |
placeholder | String | void 0 |
loading | Boolean | false |
disabled | Boolean | false |
showThinking | Boolean | true |
allowAttachments | Boolean | true |
maxAttachments | Number | 5 |
maxLength | Number | 2e3 |
showWordCount | Boolean | false |
sendOnEnter | Boolean | true |
actions | Array | () => [] |
editable | Boolean | false |
editMaxLength | Number | 0 |
feedback | Boolean | false |
feedbackReasons | Array | () => [] |
toolRetryable | Boolean | true |
speech | Boolean | false |
traceUrl | String | "" |
virtual | Boolean | false |
virtualThreshold | Number | 60 |
estimatedItemSize | Number | 120 |
accept | String | "" |
maxFileSize | Number | 0 |
allowDrop | Boolean | true |
queueable | Boolean | false |
menuOpen | Boolean | false |
height | [String | "600px" |
width | [String | "100%" |
avatarUser | String | "" |
avatarAssistant | String | "" |
userName | String | void 0 |
assistantName | String | void 0 |
showAvatar | [Boolean | true |
showName | [Boolean | true |
showTime | Boolean | true |
renderMode | String | "markdown" |
autoScroll | Boolean | true |
showTip | Boolean | true |
stoppable | Boolean | false |
approval | Object | null |
question | Object | null |
context | Object | null |
status | Object | null |
statusStoppable | Boolean | false |
inputValue | String | "" |
事件:send、stop、copy、regenerate、action、edit、feedback
EbChatList
消息滚动容器。负责自动贴底、role="log" 流式播报、回到底部钮、空态;不负责发送。
- 入口:
@wil-works/evoke-chat/chat-list源码:src/components/chatbot/ChatList.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
empty、message、message-content、tool-result、tool-args、header
| prop | 类型 | 默认 |
|---|---|---|
messages | Array | () => [] |
showThinking | Boolean | true |
avatarUser | String | "" |
avatarAssistant | String | "" |
userName | String | void 0 |
assistantName | String | void 0 |
showAvatar | [Boolean | true |
showName | [Boolean | true |
showTime | Boolean | true |
renderMode | String | "markdown" |
actions | Array | () => [] |
autoScroll | Boolean | true |
editable | Boolean | false |
editMaxLength | Number | 0 |
feedback | Boolean | false |
feedbackReasons | Array | () => [] |
toolRetryable | Boolean | true |
speech | Boolean | false |
traceUrl | String | "" |
virtual | Boolean | false |
virtualThreshold | Number | 60 |
estimatedItemSize | Number | 120 |
事件:copy、regenerate、action、edit、feedback、scroll
EbChatMessage
单条消息。按 role 分流:user / assistant 是对话气泡,system / notice 是居中弱化的系统提示(无头像、昵称、动作条)。
- 入口:
@wil-works/evoke-chat/chat-message源码:src/components/chatbot/ChatMessage.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
tool-result、tool-args、content
| prop | 类型 | 默认 |
|---|---|---|
message | null | — |
showThinking | Boolean | true |
avatarUser | String | "" |
avatarAssistant | String | "" |
userName | String | void 0 |
assistantName | String | void 0 |
renderMode | String | "markdown" |
showAvatar | [Boolean | true |
showName | [Boolean | true |
showTime | Boolean | true |
actions | Array | () => [] |
editable | Boolean | false |
editMaxLength | Number | 0 |
feedback | Boolean | false |
feedbackReasons | Array | () => [] |
toolRetryable | Boolean | true |
speech | Boolean | false |
traceUrl | String | "" |
事件:copy、regenerate、action、edit、feedback
EbChatSender
输入区:自增高、Enter 发送、IME 组字安全、附件(点选 / 拖拽 / 粘贴)、字数限制、发送↔停止变形。EbChatbot 内部用它。
- 入口:
@wil-works/evoke-chat/chat-sender源码:src/components/chatbot/ChatSender.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
toolbar - 实例方法(ref 调用):
focus、setCaret、blur、reset
| prop | 类型 | 默认 |
|---|---|---|
modelValue | String | "" |
placeholder | String | void 0 |
disabled | Boolean | false |
loading | Boolean | false |
allowAttachments | Boolean | true |
maxAttachments | Number | 5 |
maxLength | Number | 2e3 |
showWordCount | Boolean | false |
minRows | Number | 1 |
maxRows | Number | 6 |
sendOnEnter | Boolean | true |
stoppable | Boolean | false |
accept | String | "" |
maxFileSize | Number | 0 |
allowDrop | Boolean | true |
queueable | Boolean | false |
menuOpen | Boolean | false |
事件:send、stop
EbChatContent
面板外壳:固定尺寸、可选边框、头部/底部槽位。EbChatbot 用它包住消息区与输入区。
- 入口:
@wil-works/evoke-chat/chat-content源码:src/components/chatbot/ChatContent.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
header、默认、footer
| prop | 类型 | 默认 |
|---|---|---|
height | [String | "100%" |
width | [String | "100%" |
bordered | Boolean | false |
EbChatMarkdown
Markdown 渲染器:GFM 表格与任务列表、代码块工具条(语言标签 + 复制)、自定义协议引用芯片、source: 行内引用上标、流式拖尾。原文 HTML 一律转义为纯文本;图片 src 只放行 http / https / data。
- 入口:
@wil-works/evoke-chat/chat-markdown源码:src/components/chatbot/ChatMarkdown.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
content | String | "" |
streaming | Boolean | false |
EbChatThinking
思考过程折叠块。流式期间强制展开,结束后回到用户可控的折叠态。{ content, thinking, duration, interrupted }(duration 为思考耗时,显示成「(用时 X)」;消息上下文里取 message.thinkDuration;interrupted 为真时标题说「思考已中断」,用
- 入口:
@wil-works/evoke-chat/chat-thinking源码:src/components/chatbot/ChatThinking.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
content | String | "" |
thinking | Boolean | false |
duration | Number | 0 |
interrupted | Boolean | false |
EbChatLoading
三点起伏的打字指示。可选 text 文案。
- 入口:
@wil-works/evoke-chat/chat-loading源码:src/components/chatbot/ChatLoading.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
text | String | "" |
EbChatActionbar
消息动作条:复制(内置,含已复制回执)、重新生成(仅 assistant)、编辑(仅 user)、自定义动作。默认悬停显示,:focus-within 与触屏常显。自定义动作给了 icon 就是图标按钮,没给则回落成文字按钮;每颗按钮悬浮都出库内 Tooltip(Teleport 到 body,消息列表滚动时不会被裁切
- 入口:
@wil-works/evoke-chat/chat-actionbar源码:src/components/chatbot/ChatActionbar.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
message | null | — |
actions | Array | () => [] |
showCopy | Boolean | true |
showRegenerate | Boolean | true |
showEdit | Boolean | false |
showSpeech | Boolean | false |
traceUrl | String | "" |
事件:copy、regenerate、edit、action
EbChatAttachments
附件卡片列表:图片预览或按后缀匹配的专用图标(pdf / word / excel / ppt / zip / image / music / video / code / text,认不出退 MIME 大类、再退通用文档图标)、文件名、体积、移除钮;图标默认按类型染色(pdf 红 / word 蓝 / excel 绿
- 入口:
@wil-works/evoke-chat/chat-attachments源码:src/components/chatbot/ChatAttachments.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
attachments | Array | () => [] |
removable | Boolean | false |
colored | Boolean | true |
事件:remove
EbChatSuggestion
追问 chips。items 接受 string 或 { text, prompt? };layout 取 row(消息尾部)或 column(欢迎区);icon 传图标名则每枚前置。抛 pick({ text, prompt })。
- 入口:
@wil-works/evoke-chat/chat-suggestion源码:src/components/chatbot/ChatSuggestion.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
items | Array | () => [] |
layout | String | "row" |
icon | String | "" |
disabled | Boolean | false |
事件:pick
EbChatFeedback
点赞点踩。点赞立即提交;点踩展开结构化原因面板与备注。取消评价也会交出 { value: null }——否则宿主存下来的评价清不掉。
- 入口:
@wil-works/evoke-chat/chat-feedback源码:src/components/chatbot/ChatFeedback.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
value | String | null |
reasons | Array | () => [] |
showNote | Boolean | true |
disabled | Boolean | false |
事件:submit
EbChatMessageEdit
用户消息的原地编辑器。Esc 取消、Enter 保存、IME 安全、maxlength 生效。{ modelValue, placeholder, maxLength, sendOnEnter },抛 save(text) / cancel。
- 入口:
@wil-works/evoke-chat/chat-message-edit源码:src/components/chatbot/ChatMessageEdit.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
modelValue | String | "" |
placeholder | String | void 0 |
maxLength | Number | 0 |
sendOnEnter | Boolean | true |
事件:save、cancel
EbChatSources
EbChatSources
- 入口:
@wil-works/evoke-chat/chat-sources源码:src/components/chatbot/ChatSources.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
items | Array | () => [] |
collapsible | Boolean | true |
defaultOpen | Boolean | true |
EbChatToolCall
工具调用卡:状态标记(等待/执行/失败/完成/已停止)、耗时、参数与结果的折叠展开,失败态给重试钮。支持子调用:toolCall.subCalls 是同一形状的数组(并行派发 / PTC 子步),展开后按层级递归渲染、左侧细轨标出从属关系,折叠时头部给子调用计数;嵌套上限 16 层(引擎与组件两侧都设了,异常自引用数据
- 入口:
@wil-works/evoke-chat/chat-tool-call源码:src/components/chatbot/ChatToolCall.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
args、result
| prop | 类型 | 默认 |
|---|---|---|
toolCall | Object | () => ({}) |
expanded | Boolean | undefined |
retryable | Boolean | true |
depth | Number | 0 |
事件:toggle、retry
EbChatThreads
不想要 Console 那套编排时,EbChatThreads 可以单独用;#item 插槽整条接管,itemProps 用于回落默认渲染(与 ChatList#message 同款约定):
- 入口:
@wil-works/evoke-chat/chat-threads源码:src/components/chatbot/ChatThreads.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-threads - 插槽:
header、empty、item、footer
| prop | 类型 | 默认 |
|---|---|---|
threads | Array | () => [] |
active | String | "" |
streaming | Array | () => [] |
searchable | Boolean | true |
showCreate | Boolean | true |
groupByDate | Boolean | true |
renamable | Boolean | true |
removable | Boolean | true |
timeFormat | Function | null |
事件:select、create、rename、remove、pin、archive、search
EbChatWidget
导出名为 EbChatWidget。v-model 管开合;内容完全由你放——常见就是一颗 EbChatbot 或 EbAiConsole:
- 入口:
@wil-works/evoke-chat/chat-widget源码:src/components/chatbot/ChatWidget.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-widget - 插槽:
默认、disclaimer-actions、title、launcher
| prop | 类型 | 默认 |
|---|---|---|
modelValue | Boolean | false |
title | String | "" |
icon | String | "customer-service" |
launcherTooltip | String | "" |
badge | Number | null |
placement | String | "bottom-right" |
width | [String | 380 |
height | [String | 560 |
mobileMode | String | "drawer" |
drawerSize | [String | "80%" |
disclaimer | String | "" |
defaultConsented | Boolean | false |
appendToBody | Boolean | true |
事件:open、close、consent
EbChatPlan
EbChatPlan · EbChatConfirmation · EbChatArtifact
- 入口:
@wil-works/evoke-chat/chat-plan源码:src/components/chatbot/ChatPlan.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
step
| prop | 类型 | 默认 |
|---|---|---|
plan | Object | () => ({ steps: [] }) |
expanded | Boolean | undefined |
事件:toggle
EbChatConfirmation
EbChatPlan · EbChatConfirmation · EbChatArtifact
- 入口:
@wil-works/evoke-chat/chat-confirmation源码:src/components/chatbot/ChatConfirmation.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
confirmation | Object | () => ({}) |
事件:respond
EbChatApproval
审批面板:agent 要执行越权动作(跑命令、联网、改文件)时接管输入区——待审批期间发送台让位,用户只需做一个决定。{ id, toolName, reason?, detail?, status? }:给了 reason 就用它当标题,否则显示「工具 X 请求越权执行」;detail 常放被拦命令原文(等宽、限高可
- 入口:
@wil-works/evoke-chat/chat-approval源码:src/components/chatbot/ChatApproval.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
默认
| prop | 类型 | 默认 |
|---|---|---|
request | Object | () => ({}) |
answered | Boolean | undefined |
事件:respond
EbChatQuestion
提问面板:agent 需要澄清时接管输入区(审批优先——越权动作必须先答)。{ id, items: [{ id, question, header?, multiSelect?, allowCustom?, options: [{ key, label, recommended?, description? }] }
- 入口:
@wil-works/evoke-chat/chat-question源码:src/components/chatbot/ChatQuestion.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
request | Object | () => ({}) |
answered | Boolean | undefined |
事件:respond
EbChatContextMeter
输入台工具栏右侧的占用环(EbAiConsole 经 #toolbar-meta 传进输入台,不再占输入区一行):{ used, capacity, breakdown? },环 + 百分比,点开给「已用 / 窗口」与三段构成(系统提示词 / 工具定义 / 对话消息)。两侧缺一就不显示——拿不到窗口容量时画个环只会误导
- 入口:
@wil-works/evoke-chat/chat-context-meter源码:src/components/chatbot/ChatContextMeter.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
used | Number | 0 |
capacity | Number | 0 |
breakdown | Object | null |
EbChatChanges
本轮改动汇总卡:标题给「已编辑 N 个文件」(单文件时直接给文件名),右侧 +A -R;展开后逐行列文件,每行带自己的增删数,二进制 / 过大不给行数只给标记。超出 collapsedRows(默认 4)折叠,给「全部 N 个文件」。路径等宽、不折行(保住目录层级),过长省略并留 title;点行抛 select(宿主
- 入口:
@wil-works/evoke-chat/chat-changes源码:src/components/chatbot/ChatChanges.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
files | Array | () => [] |
summary | Object | null |
collapsedRows | Number | 4 |
defaultOpen | Boolean | false |
事件:select
EbChatStatusBar
「AI 现在在做什么」此前只能靠 aria-busy 猜。状态条把它变成一句话 + 一个可点的动作,常驻在输入台上方。
- 入口:
@wil-works/evoke-chat/chat-status-bar源码:src/components/chatbot/ChatStatusBar.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
status | Object | null |
stoppable | Boolean | false |
事件:stop
EbChatArtifact
EbChatPlan · EbChatConfirmation · EbChatArtifact
- 入口:
@wil-works/evoke-chat/chat-artifact源码:src/components/chatbot/ChatArtifact.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents - 插槽:
artifact
| prop | 类型 | 默认 |
|---|---|---|
artifacts | Array | () => [] |
copyable | Boolean | true |
事件:open、copy
EbChatDiff
吃标准统一 diff 文本(git diff 与各家 agent 输出的那种),按文件分组,头部给路径与 +N −M,行按增/删/上下文着色,带 old/new 双行号栅格。
- 入口:
@wil-works/evoke-chat/chat-diff源码:src/components/chatbot/ChatDiff.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
diff | String | "" |
showLineNumbers | Boolean | true |
collapsible | Boolean | true |
defaultOpen | Boolean | true |
maxHeight | [String | "360px" |
事件:toggle、copy
EbChatTerminal
命令输出卡:头部给命令与退出码,正文等宽渲染且不折行(保住终端列结构,横向滚动交给容器),status: 'running' 时末尾有光标。长输出只渲染尾部(默认 40 行),给省略数与展开入口——命令输出动辄上千行,全渲染会拖垮消息列。
- 入口:
@wil-works/evoke-chat/chat-terminal源码:src/components/chatbot/ChatTerminal.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
command | String | "" |
output | String | "" |
status | String | "done" |
exitCode | [Number | null |
collapsible | Boolean | true |
defaultOpen | Boolean | true |
maxHeight | [String | "320px" |
tailLines | Number | 40 |
事件:toggle、copy
EbChatFileTree
扁平路径列表 → 嵌套树。目录在前、名称升序;文件带类型图标、状态徽标(新增/修改/删除/重命名)与增删行数。目录默认展开,折叠状态 aria-expanded 完整。
- 入口:
@wil-works/evoke-chat/chat-file-tree源码:src/components/chatbot/ChatFileTree.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
files | Array | () => [] |
defaultExpandAll | Boolean | true |
事件:select、toggle
EbChatTestResults
EbChatTestResults · EbChatStackTrace。两张都是纯数据渲染,无额外依赖。
- 入口:
@wil-works/evoke-chat/chat-test-results源码:src/components/chatbot/ChatTestResults.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
results | Object | () => ({}) |
cases | Array | null |
expandStacks | Boolean | false |
EbChatStackTrace
吃 stack 字符串或已解析的 frames,认三种常见形态:
- 入口:
@wil-works/evoke-chat/chat-stack-trace源码:src/components/chatbot/ChatStackTrace.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
stack | [String | "" |
collapseDependencies | Boolean | true |
maxAppFrames | Number | 0 |
EbChatShare
收集「可见范围 + 有效期」,链接的生成与权限校验由你的服务端负责——组件不发请求;link 为空是配置态、非空是已创建态。
- 入口:
@wil-works/evoke-chat/chat-share源码:src/components/chatbot/ChatShare.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
modelValue | Boolean | false |
title | String | "" |
link | String | "" |
creating | Boolean | false |
scopes | Array | () => [] |
scope | String | "anyone" |
expiries | Array | () => [] |
expiry | String | "7d" |
appendToBody | Boolean | true |
事件:create、revoke、copy
EbChatSpeak
朗读(useSpeech · EbChatSpeak)
- 入口:
@wil-works/evoke-chat/chat-speak源码:src/components/chatbot/ChatSpeak.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
text | String | "" |
lang | String | "" |
rate | Number | 1 |
事件:start、stop、end
EbChatVoiceInput
口述(useSpeechInput · EbChatVoiceInput)
- 入口:
@wil-works/evoke-chat/chat-voice-input源码:src/components/chatbot/ChatVoiceInput.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
lang | String | "" |
continuous | Boolean | false |
emitInterim | Boolean | true |
事件:interim、result、error、start、end
EbChatQueue
input-prepend | 输入区顶部(状态条之上) | 待发送队列(EbChatQueue)、附件条这类贴着输入台的内容 |
- 入口:
@wil-works/evoke-chat/chat-queue源码:src/components/chatbot/ChatQueue.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
items | Array | () => [] |
事件:remove、clear、recall
EbChatCommandMenu
useTriggerMenu(判定)+ EbChatCommandMenu(渲染)+ 输入区让出键盘,三件拼起来。键盘不放在弹层里是刻意的——焦点始终在输入框,弹层不该抢走输入。
- 入口:
@wil-works/evoke-chat/chat-command-menu源码:src/components/chatbot/ChatCommandMenu.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
items | Array | () => [] |
highlight | Number | 0 |
visible | Boolean | false |
title | String | "" |
事件:select、hover
EbChatUsage
EbChatUsage 只展示宿主给的用量——成本要价目表,那是宿主的业务数据,组件与引擎都不猜。
- 入口:
@wil-works/evoke-chat/chat-usage源码:src/components/chatbot/ChatUsage.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
usage | Object | null |
items | Array | null |
size | String | "compact" |
bare | Boolean | true |
disclosure | Boolean | true |
EbChatSandbox
组件不执行代码,只把一个隔离 iframe 管起来:宿主给 HTML → 组件拼 bootstrap → srcdoc + sandbox 属性 → iframe;console 与错误经 postMessage 上来,组件只转发不解析。
- 入口:
@wil-works/evoke-chat/chat-sandbox源码:src/components/chatbot/ChatSandbox.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
html | String | "" |
src | String | "" |
title | String | "" |
height | [String | 260 |
autoHeight | Boolean | false |
extraSandbox | Array | () => [] |
allow | String | "" |
bootConsole | Boolean | true |
事件:console、error、ready、resize
EbChatWebPreview
iframe + 截图双模式。有一个绕不过去的硬限制:目标站返回 X-Frame-Options: DENY 或 frame-ancestors 时浏览器显示空白错误页,而跨域下脚本无法可靠区分「禁嵌的空白页」与「真的空白内容」——load 两种情况都触发。
- 入口:
@wil-works/evoke-chat/chat-web-preview源码:src/components/chatbot/ChatWebPreview.vue文档:https://evoke-business-ui.wil-works.com/chat/chat-subcomponents
| prop | 类型 | 默认 |
|---|---|---|
src | String | "" |
screenshot | String | "" |
embeddable | Boolean | null |
title | String | "" |
screenshotAlt | String | "" |
height | [String | 320 |
extraSandbox | Array | () => [] |
allow | String | "" |
EbAiPromptBox
EbAiPromptBox 侧同理走 #toolbar-extra。
- 入口:
@wil-works/evoke-chat/ai-prompt-box源码:src/components/ai-prompt-box/index.vue文档:https://evoke-business-ui.wil-works.com/chat/ai-prompt-box - 插槽:
toolbar-extra、toolbar-meta、scenes-append - 实例方法(ref 调用):
focus、clear
| prop | 类型 | 默认 |
|---|---|---|
modelValue | String | '' |
placeholder | String | void 0 |
disabled | Boolean | false |
loading | Boolean | false |
queueable | Boolean | false |
scenes | Array | () => [] |
scene | String | '' |
capabilities | Array | () => [] |
activeCapabilities | Array | () => [] |
models | Array | () => [] |
model | String | '' |
quota | [String | null |
showSettings | Boolean | false |
allowAttachments | Boolean | true |
maxAttachments | Number | 5 |
accept | String | '' |
maxFileSize | Number | 0 |
allowDrop | Boolean | true |
maxLength | Number | undefined |
showWordCount | Boolean | false |
maxRows | Number | 8 |
sendOnEnter | Boolean | true |
stoppable | Boolean | false |
事件:send、stop
EbAiConsole
EbChatbot / EbAiConsole 的 question prop 传了就接管输入区,响应经 question-respond(answer, request) 抛出;useChatSession 的 question + respondQuestion(answer) 已把链路接好(question/re
- 入口:
@wil-works/evoke-chat/ai-console源码:src/components/ai-console/index.vue文档:https://evoke-business-ui.wil-works.com/chat/ai-console - 插槽:
threads、empty、input-prepend、toolbar-extra、tip - 实例方法(ref 调用):
engine、clear、setDraft、send、focus
| prop | 类型 | 默认 |
|---|---|---|
engine | Object | null |
sessions | Object | null |
transport | Function | null |
welcome | Object | null |
examples | Array | () => [] |
exampleAction | String | 'send' |
placeholder | String | void 0 |
disabled | Boolean | false |
loading | Boolean | false |
scenes | Array | () => [] |
capabilities | Array | () => [] |
models | Array | () => [] |
quota | [String | null |
showSettings | Boolean | false |
allowAttachments | Boolean | true |
maxAttachments | Number | 5 |
maxLength | Number | 2000 |
sendOnEnter | Boolean | true |
stoppable | Boolean | false |
approval | Object | null |
question | Object | null |
context | Object | null |
status | Object | null |
statusStoppable | Boolean | false |
queueable | Boolean | false |
showThinking | Boolean | true |
renderMode | String | 'markdown' |
autoScroll | Boolean | true |
userName | String | void 0 |
assistantName | String | void 0 |
showAvatar | [Boolean | true |
showName | [Boolean | true |
showTime | Boolean | true |
avatarUser | String | '' |
avatarAssistant | String | '' |
actions | Array | () => [] |
editable | Boolean | false |
editMaxLength | Number | 0 |
feedback | Boolean | false |
feedbackReasons | Array | () => [] |
toolRetryable | Boolean | true |
speech | Boolean | false |
traceUrl | String | "" |
chatHeight | [Number | 420 |
showTip | Boolean | true |
事件:send、stop、copy、regenerate、action、edit、feedback