Install any skill in seconds. Free to start, no credit card required.
Get Started Free →ai-shifu/chat-element-streaming
当 ai-shifu 聊天流从 block 粒度向 element 粒度演进,或历史记录与 SSE 渲染一致性出现问题时使用本技能。统一 element_bid 渲染键、兼容旧字段并收敛 AskBlock 归并逻辑。
Passed 21 of 22 test cases with the skill, and 9 of 22 without it.
and 21 more in the full report
14 fixed8 passed either way0 still failing1 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 13 test cases the skill fixed. Same model, same prompt, with and without the skill.
In an SSE event consumer for AI Shifu, when an event with `type=element` arrives matching an existing item key, developers usually concatenate the new chunk onto the existing message content string. What is the standard update strategy?
| Checked | Without skill | With skill |
|---|---|---|
| The reducer overwrites the existing item matching the element_bid key rather than appending text. | Missed | Passed |
The instructions your model reads when the skill loads.
element_bid 作为聊天项稳定渲染 key。generated_block_bid、parent_block_bid 兼容字段。contentList。type=element 时按 element_bid 覆盖更新,不做重复拼接。element_type=answer,让 AskBlock 按答案流增量更新。element_type=ask/answer 时,归并到 anchor_element_bid 对应的 AskBlock.ask_list。sequence)为准,不强制锚定在 anchor 内容后。type=element + type=done,需按 element_bid 覆盖更新元素项,并将 done 作为唯一收尾信号。type/event_type 与 content/data 两套命名,避免后端灰度期间前端丢流。done 但出现多个 element_bid 时,以“新 element 到达”作为前一个 element 的结束信号,并立即补一个追问块(like-status/ask入口)。type=done 时,优先读取 done.is_terminal 判断它是“当前分段结束”还是“真正终态”;字段缺失时才回退到旧的前端推断。done 收尾补追问块时,锚点应取“最近的可操作 element(content 或 interaction)”,否则最后一项为 interaction 时会漏补追问块。done 与后续 element 乱序,边界判定不能只依赖 streaming ref,需增加“从当前列表尾部推断上一个可操作 element”的兜底逻辑,避免中间 element 漏补追问块。done.is_terminal=true,则必须停止续拉。type=done 时,不要默认立即 stopPreview;仅当 done.is_terminal=true 才关闭当前预览流。关闭后若最后一个可操作块不是 interaction,应继续拉取下一段流。ai-shifu 本地稳定复现 run SSE 问题时,优先在 getRunMessage 层增加显式调试开关;mock_run_sse_fixture=stuck 回放由 data.json 截断得到的卡住 fixture,mock_run_sse_fixture=test 回放 mock-fixtures/test/data.json 的完整测试流,并保持 message/readystatechange/close 契约不变;不要把页面组件改成只兼容 mock 数据。run 流若在 3 秒内没有任何新事件,前端应在消费层主动判定为超时:关闭当前流与 loading 状态、向 items/elementList 追加 type=error 的错误项,并复用同一份国际化文案弹 destructive toast。Slide 遇到超时错误时,只把它当作“关闭内部 loading overlay”的信号,不要把错误项渲染成单独一页;用户侧错误提示统一交给 toast。html 视觉 marker 更新时容易把 loading 插到两个 element 的视觉边界之间;但当 loading 思考占位仍在列表中时,不要同时显示点状 loading。markdown-flow-ui 的 ContentRender 打开打字机效果,应只对“非历史记录、且 element_type === text”的实时正文块开启;html、interaction 和历史正文继续即时渲染,优先在 ContentBlock 这类渲染包装层集中判断,不要把条件散落到列表组装逻辑里。element 被 done 或“下一个 element 到达”收尾时,要同步把本地 ChatContentItem.is_final 置为 true;不要让列表状态长期停留在早先 SSE 快照里的 false。NewChatComp 上层维护 readModeItems 的可见列表缓存和按 element_bid 存储的打字机完成态;只有前一个 text 同时满足“is_final=true 且当前 content 的打字机回调已完成”时,才放行下一个 element。element 收尾时给正文 content 追加追问按钮或把块改成 isHistory=true,不要让这个“收尾态 content”继续复用同一条 typewriter gate 缓存;否则缓存会因 content 变化被重置成未完成,而 ContentRender 又因为不再启用打字机而不会补发 onTypeFinished,最终把后续 element 永久卡住。isHistory 只表示“来自学习记录/历史回放的数据”,不要把它当作运行时 UI 控制位复用;run SSE 覆盖已有历史项时,也不要从 previousItem 继承 isHistory,否则实时流会被误判成历史数据。elementList 可见性 gate 不要直接依赖 isHistory;应使用独立的 typewriter 候选标记,仅让“真正参与实时打字机的 text element”进入缓存与阻塞链路,避免历史首块被 SSE 覆盖后误拦住后续 element。done 或“下一个 element 到达”把某个元素标记为 is_final=true,后续同 element_bid 的 SSE element 快照不能再用旧的 is_final=false/undefined 覆盖回去;本地 finalize 语义优先级应高于早先快照字段。custom-button-after-content 只允许作为“打字结束后的静态尾部 UI”出现;打字机阶段传给渲染器的 content 必须先剥掉这段 markup,避免把追问按钮当正文逐字输出。text 的富内容块(如 html、svg、sandbox 相关内容)若需要尾部追问按钮,不要依赖内容字符串内部的 custom-button-after-content 首屏渲染;应把按钮从 content 中剥离后在外层独立渲染,避免正文未稳定时按钮先于正文或以异常结构闪现。StudyRecordItem 这类共享记录类型被 SSE、历史记录和渲染层共同消费,就必须把 is_final 等流式收尾字段声明在共享接口里;不要仅在局部 UI 类型上兜底,否则 next build 很容易在跨层调用处报类型缺失。cache.isFinished 决定同一个 element_bid 是否继续打字;若当前归一化 content 已经比缓存快照更长,即使旧 cache 标记过完成,也必须继续给 ContentRender 打开 typewriter,否则后续增量首帧会直接整段落地。test cases passed, vs 9 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.