agents.md 4.5 KB

Agents.md

业务自滚动吸顶原则

  • 自动滚动的吸顶判断,应以“最后一条 AI 消息是否仍处于打字机动画中”为核心依据。
  • 不要仅依赖 isGenerating 之类的请求状态来决定是否吸顶;请求结束不等于内容展示结束。
  • 当自动滚动推进到最后一条 AI 消息顶部阈值时,应进入吸顶控制状态,避免打字机动画继续把内容顶出视口。
  • 吸顶状态应是阶段性的、可退出的;同一轮滚动中避免反复触发或抖动。
  • 用户发生手动滚动、触摸、鼠标滚轮或其他明确交互后,应重置吸顶状态,恢复默认滚动行为。
  • PC 和 Mobile 的滚动策略应保持一致,差异只应来自平台滚动容器本身,而不是业务规则分叉。
  • 调试阶段可以保留必要日志,用于判断吸顶是否触发、是否已停止自动滚动、当前滚动位置以及最后一条 AI 消息的打字状态。

会话切换与消息状态原则

  • 切换会话后,新会话应自动滚动到消息列表底部,保证用户直接看到最新上下文。
  • 历史消息和实时生成消息应复用同一套消息状态判断,避免同一种业务状态在不同来源下表现不一致。
  • AI 消息内容为空、被中断、请求取消,或只残留未完成的思考/查询 scope 时,应明确展示“请求已取消”。
  • “请求已取消”的展示不应影响正常生成中的消息,也不应打断仍在流式追加的代码或文本内容。

Scope 动画与布局原则

  • scopeContent 的进入、退出、淡入、淡出应交给 Vue Transition/TransitionGroup 管理,避免在业务逻辑中手写动画状态。
  • scopeContent 退场只需要 fade,不需要 translate;退场过程中不应重置光点坐标,视觉位置应保持连续。
  • scope 达到最大宽度前,标题、正文行和行列表应优先使用 ellipsis 隐藏换行内容;只有达到最大宽度后才允许自然换行。
  • scope-content-linescope-line-list 应遵循同一套宽度与换行规则,避免局部换行导致动画抖动。
  • scope 准备淡出时,不应通过临时 position: absolute 改变布局位置;布局稳定性应由外层高度锁定或过渡结构承担。

打字机与 Markdown 渲染原则

  • 文本打字机应由父级统一维护“当前可见行”和“当前正在打字的行”,避免多段文本同时竞争动画节奏。
  • 一条 AI 回复中,后段内容可以先进入数据队列,但 UI 上应按顺序释放可见文本,保证阅读节奏自然。
  • 请求流关闭不等于打字机结束;最后一个消息到达后,未完成的打字动画应继续执行直到文本全部展示完毕。
  • 打字机每 tick 应推进稳定数量的字符,避免速度忽快忽慢;当前约定以每 tick 2 个字作为基础节奏。
  • Markdown 内容在打字机过程中应尽量每 tick 实时 parse,使展示结构即时更新,减少纯文本与 Markdown 成品之间切换造成的抖动。
  • markdown-content.block-markdown 不应自行设置 min-height;高度稳定应由外层消息容器或业务记录容器维护。

消息高度稳定原则

  • 最后一条 AI 消息处于打字机动画时,应在 message-row.ai.is-last 上维护最小高度,而不是让内部 Markdown 节点自行锁高。
  • 该最小高度在打字机过程中只增不减,用来抵消 Markdown 重排、scope 淡出和文本接续造成的高度回缩。
  • 当最后一条 AI 消息仍在视口内时,应保持最小高度;只有当 business-record-body 的底边已经接触滚动容器底部时,才允许释放高度锁。
  • 高度锁应服务于滚动与动画稳定,不应成为永久布局样式。

流式分段与节奏原则

  • 流式解析应识别 </scope>\n 这样的自然边界,并在边界到达时立即 enqueue,避免 scope 结束后的正文被延迟到后续大段内容一起出现。
  • scope 内容、普通正文、Markdown 标题和 followup JSON 等不同片段应保持清晰边界,便于动画、取消态和最终态分别处理。
  • 流暂停输出 message 时,前端打字机仍应以自己的节奏继续推进;网络节奏不应直接决定文字动画是否流畅。

调试入口原则

  • 用于测试输入和 playMockStreamMessage 的按钮可以保留在 PC 端调试入口中,并应放在 actions-right 内、发送按钮左侧。
  • 调试按钮不应影响 Mobile 端正式输入区,也不应改变用户发送消息的主流程。