deerflow2/.planning/phases/07-phase-06-mention-upload/07-01-PLAN.md

10 KiB
Raw Blame History

phase plan type wave depends_on files_modified autonomous requirements must_haves
07-phase-06-mention-upload 01 execute 1
frontend/src/components/workspace/input-box.tsx
frontend/src/core/threads/hooks.ts
frontend/src/components/ai-elements/prompt-input.tsx
frontend/src/components/workspace/messages/message-list-item.tsx
frontend/src/core/i18n/locales/zh-CN.ts
frontend/src/core/i18n/locales/en-US.ts
frontend/src/core/i18n/locales/types.ts
frontend/src/core/threads/hooks.test.ts
frontend/tests/e2e/input-and-compose.spec.ts
true
P7-01
P7-02
P7-03
P7-04
truths artifacts key_links
发送到后端的文本会拼接优先使用…附件和…Skill但消息区仅展示用户原文。
拼接规则固定附件在前、Skill在后单类单出大小写不敏感去重。
按钮发送、回车发送、建议词自动发送三条入口行为一致。
path provides contains
frontend/src/core/threads/hooks.ts 提交态增强文本与展示态原文分离 payload text composition
path provides contains
frontend/src/components/workspace/input-box.tsx references + selectedSkills 元数据传递 handleSubmit
path provides contains
frontend/src/components/workspace/messages/message-list-item.tsx 人类消息渲染仍以原文为准 contentToDisplay
from to via pattern
frontend/src/components/workspace/input-box.tsx frontend/src/core/threads/hooks.ts PromptInputMessage 扩展字段 selectedSkills/references -> payload composition
from to via pattern
frontend/src/core/threads/hooks.ts frontend/src/components/workspace/messages/message-list-item.tsx optimistic content + persisted display consistency original text only
实现 Phase 7 决策:发送时将附件与 Skill 提示文案拼接进提交给后端的提示词,但消息区不展示拼接内容。

Purpose: 在不破坏既有 additional_kwargs.files 语义和输入体验的前提下,增强模型侧提示优先级。 Output: 形成稳定的“提交态增强文本/展示态原文”链路,并由单测 + E2E 回归覆盖。

<execution_context> @/home/mt/.codex/get-shit-done/workflows/execute-plan.md @/home/mt/.codex/get-shit-done/templates/summary.md </execution_context>

@.planning/ROADMAP.md @.planning/REQUIREMENTS.md @.planning/STATE.md @.planning/phases/07-phase-06-mention-upload/07-CONTEXT.md @.planning/phases/07-phase-06-mention-upload/07-RESEARCH.md @.planning/phases/07-phase-06-mention-upload/07-VALIDATION.md @frontend/src/components/workspace/input-box.tsx @frontend/src/core/threads/hooks.ts @frontend/src/components/ai-elements/prompt-input.tsx @frontend/src/components/workspace/messages/message-list-item.tsx @frontend/tests/e2e/input-and-compose.spec.ts From frontend/src/components/ai-elements/prompt-input.tsx: ```typescript export type PromptInputMessage = { text: string; files: FileUIPart[]; references?: PromptInputReference[]; }; ```

From frontend/src/core/threads/hooks.ts:

const sendMessage = async (threadId: string | undefined, message: PromptInputMessage) => {
  const text = message.text.trim();
  // optimistic human message + submit payload
};

From frontend/src/components/workspace/input-box.tsx:

onSubmit?.({ ...message, references });
Task 1: 设计并接入“提交态增强文本”组装器 frontend/src/core/threads/hooks.ts, frontend/src/components/ai-elements/prompt-input.tsx - .planning/phases/07-phase-06-mention-upload/07-CONTEXT.md - frontend/src/core/threads/hooks.ts - frontend/src/components/ai-elements/prompt-input.tsx - frontend/src/core/threads/submit-files.ts 扩展 `PromptInputMessage` 以承载发送时需要的 Skill 名列表(例如 `selectedSkills?: Array<{ title: string }>`),并在 `hooks.ts` 中新增纯函数组装器:输入原文、附件名集合(上传文件名 + references 文件名、Skill 名集合输出“提交态增强文本”。规则必须写死为附件在前、Skill在后、单类单出、大小写不敏感去重、空集合不拼接。拼接模板使用 `优先使用【...】和【...】`。保持 `additional_kwargs.files` 现有逻辑不变,不新建并行 envelope。 - `PromptInputMessage` 新增可选 Skill 元数据字段,类型定义与调用点一致。 - `hooks.ts` 存在独立组装函数,且可单测验证 4 条决策规则(顺序、单类单出、去重、空值)。 - 原 `buildFilesForSubmit` 与 `additional_kwargs.files` 流程未被改写为新结构。 cd frontend && rg -n "selectedSkills\?:|build.*Priority|优先使用【" src/components/ai-elements/prompt-input.tsx src/core/threads/hooks.ts cd frontend && pnpm -s test -- --run src/core/threads/hooks.test.ts 提交链路具备可复用的“增强文本组装器”,且不破坏现有文件提交协议。 Task 2: InputBox 透传引用与 Skill 元数据,统一三类发送入口 frontend/src/components/workspace/input-box.tsx, frontend/src/app/workspace/chats/[thread_id]/page.tsx - .planning/phases/07-phase-06-mention-upload/07-CONTEXT.md - frontend/src/components/workspace/input-box.tsx - frontend/src/app/workspace/chats/[thread_id]/page.tsx - frontend/src/hooks/use-iframe-skill.ts 在 `InputBox.handleSubmit` 中把当前 `references` 与已选 `selectedSkills` 一并传给 `onSubmit` 消息对象,确保按钮发送、回车发送、建议词自动发送都经过同一条 `requestSubmit -> handleSubmit` 链路,避免分支漏传。禁止直接修改 textarea 展示文本来承载拼接文案;输入框显示始终保持用户原文。 - `onSubmit` 入参中包含 `references` 与 `selectedSkills`,且类型安全。 - `handleFollowupClick/confirmReplaceAndSend/confirmAppendAndSend` 最终提交均走相同 `handleSubmit` 透传逻辑。 - 输入框展示值不被拼接文案污染。 cd frontend && rg -n "selectedSkills|onSubmit\?\(\{\.\.\.message" src/components/workspace/input-box.tsx cd frontend && pnpm -s test -- --run src/components/workspace/input-box 所有发送入口都带齐元数据并保持展示态原文。 Task 3: 保证消息区仅展示原文并补齐回归 frontend/src/core/threads/hooks.ts, frontend/src/components/workspace/messages/message-list-item.tsx, frontend/tests/e2e/input-and-compose.spec.ts, frontend/src/core/i18n/locales/zh-CN.ts, frontend/src/core/i18n/locales/en-US.ts, frontend/src/core/i18n/locales/types.ts - .planning/phases/07-phase-06-mention-upload/07-CONTEXT.md - frontend/src/core/threads/hooks.ts - frontend/src/components/workspace/messages/message-list-item.tsx - frontend/tests/e2e/input-and-compose.spec.ts - frontend/src/core/i18n/locales/zh-CN.ts - frontend/src/core/i18n/locales/en-US.ts - frontend/src/core/i18n/locales/types.ts 在 `sendMessage` 中区分 `displayText`(原文)与 `submitText`(原文+拼接文案optimistic human message 和消息渲染侧使用 `displayText`,提交给 `thread.submit` 使用 `submitText`。若后端回流的人类消息可能带拼接文案,则在渲染层加最小且明确的剥离逻辑(仅剥离本阶段固定模板尾段),但不得依赖宽泛正则误伤用户内容。新增 i18n 文案键用于提示拼接规则相关错误(若需要)。补 E2E断言发送后消息区不出现“优先使用【”片段同时请求提交内容包含拼接片段可通过拦截请求或 mock 验证)。 - 发送请求文本包含拼接文案;消息区可见文本不包含拼接文案。 - 附件/Skill 名拼接顺序与去重规则符合 D-01~D-10。 - 新增回归测试覆盖“显示态与提交态分离”主路径。 cd frontend && pnpm -s test -- --run src/core/threads/hooks.test.ts cd frontend && pnpm -s test:e2e --grep "优先使用|input|compose" cd frontend && pnpm -s typecheck 端到端满足“拼接给模型但不展示给用户”的核心目标。

<threat_model>

Trust Boundaries

Boundary Description
输入框展示态 → 提交态 payload 同一条用户消息在展示与提交存在双态,若处理不当会造成信息泄露或行为不一致。
前端组装器 → 后端存档消息 拼接文案若回流到历史消息,会暴露内部引导提示并污染用户可见记录。

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-07-01 I frontend/src/core/threads/hooks.ts mitigate 明确区分 displayText/submitText,并通过测试验证消息区不回显拼接文本。
T-07-02 T frontend/src/components/workspace/input-box.tsx mitigate 强制三入口走同一提交链路,避免某入口漏传 references/skills 造成规则绕过。
T-07-03 R frontend/tests/e2e/input-and-compose.spec.ts mitigate 增加请求拦截断言,确保“显示态/提交态分离”可审计、可回归。
</threat_model>
- `cd frontend && pnpm -s lint` - `cd frontend && pnpm -s typecheck` - `cd frontend && pnpm -s test -- --run src/core/threads/hooks.test.ts` - `cd frontend && pnpm -s test:e2e --grep "input|compose|优先使用"`

<success_criteria>

  • 拼接模板与数据口径完全符合 1A/2A/3A/4A 决策。
  • 消息区不展示拼接附加文本,且不影响现有附件/引用渲染。
  • 三类发送入口行为一致并被自动化回归覆盖。 </success_criteria>
After completion, create `.planning/phases/07-phase-06-mention-upload/07-01-SUMMARY.md`