From 53d5b6ba5bfcbf1228fe4435f129913e9b950fee Mon Sep 17 00:00:00 2001 From: brother7 <7brother7@gmail.com> Date: Tue, 29 Sep 2026 17:04:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8C=89=E8=80=81=E5=B8=88=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=85=8D=E7=BD=AE=E6=B8=B2=E6=9F=93=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20260929-teacher-shortcuts-ml-8ce941d7.md | 46 +++++++++++++++++ README.md | 1 + shared/coding-teacher.ts | 6 +++ src/pages/Chat/TeacherChatPanel.tsx | 12 +++-- tests/e2e/fixtures/teacher-reply-api.ts | 6 +++ tests/e2e/teacher-reply-layout.spec.ts | 29 +++++++++++ tests/unit/coding-teacher-ui.test.tsx | 50 +++++++++++++++++++ 7 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 .project-docs/30-worklog/tasks/20260929-teacher-shortcuts-ml-8ce941d7.md diff --git a/.project-docs/30-worklog/tasks/20260929-teacher-shortcuts-ml-8ce941d7.md b/.project-docs/30-worklog/tasks/20260929-teacher-shortcuts-ml-8ce941d7.md new file mode 100644 index 00000000..ceb23974 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260929-teacher-shortcuts-ml-8ce941d7.md @@ -0,0 +1,46 @@ +# Task: Render and send published teacher shortcuts + +## Identity + +- Task ID: 20260929-teacher-shortcuts-ml-8ce941d7 +- Mode: Feature +- Branch: codex/20260929-teacher-shortcuts-ml-8ce941d7-teacher-shortcuts +- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260929-teacher-shortcuts-ml-8ce941d7 +- Base commit: 4103754b80b57b67b787ab4a6bc24bbf8591be4d +- Owner: codex +- Status: Ready for Integration + +## Scope + +- Render and send published teacher shortcuts. One linked worktree per repository; this feature is separate from already merged teacher publication work. Primary and peer files remain unchanged. + +## Intent And Constraints + +- Concurrent/Planning Gates passed through official scripts before implementation, with canonical teacher context loaded and peer scopes assessed. Historical incomplete peer records stay unknown; no concrete dependency conflict. +- User requested ordered shortcuts with separate display label and actual prompt, edited in Yuxi and activated through explicit publish. Limits: 8 entries, label 1–40 and prompt 1–6000 after trim. Explicit [] hides all buttons; missing historical field keeps old entry. No new table, migration, dependency or runtime model path. +- User authorized one fresh independent reviewer and feature commits for this task. Merge, push, production writes and worktree deletion are not authorized for this new feature. + +## Outcome + +- Implementation and verification complete. Fresh independent Reviewer passed the complete three-end feature; no actionable findings. Ready for Integration after feature commit. +- Yuxi owns draft/default/editing; publication snapshot owns frozen list; WS persists/delivers versioned JSON; Makelore renders label and sends prompt as an ordinary question. Existing stable teacher identity, catalog refresh, in-flight questions and historical messages retain their existing paths. + +## Verification + +- Changed shared TeacherDefinition accepts optional/null ordered shortcuts. Composer renders current published labels and sends actual prompts via ordinary question path, preserves old missing-field suggestions entry, hides explicit empty list, disables while busy/running and keeps buttons hidden for nonempty text. +- UI unit: node node_modules/vitest/vitest.mjs run tests/unit/coding-teacher-ui.test.tsx: 73 passed. New tests prove label/prompt separation/order, same-prompt uncertain retry identity, different prompt independent identity, catalog refresh preserves existing chat/draft and clear hides buttons. +- TypeScript --noEmit and changed-file ESLint passed. Vite production compile including Renderer/Main/Preload/utility passed. No dependencies added or changed; installed primary dependencies linked for build. +- Existing Playwright browser layout suite tests/e2e/teacher-reply-layout.spec.ts: 21 passed, including new 319px/508px cases for eight long configured shortcuts, exact prompt sends, empty list and existing hint send-position regression. This suite uses real components/Chromium with explicit fixture API, not production Electron cloud transport. +- Local real-component browser .tmp/check-shortcuts.mjs additionally verified 340px fit, reaching/clicking last shortcut and [] clear. Detected large list pushing actions below viewport; capped shortcut area at 192px with scrolling and kept send position stable. Screenshots .tmp/teacher-shortcuts-client.png and teacher-shortcuts-client-narrow.png; retained ignored local evidence. +- README updated for configuration and rollout. git diff --check passed. Not verified: production deployment, signed installer or real teacher model invocation; existing Main request path unchanged. + +- Independent Reviewer teacher_shortcuts_review_replacement (fresh fork, no inherited development history) passed. Reviewer inspected all diffs/new files, cross-end boundaries, tests and real-browser evidence; independently ran WS publication 10 tests, Makelore UI 73 tests and Yuxi shortcut validation probes. Reviewer records: 20260929-teacher-shortcuts-review-ws-b6f3, 20260929-teacher-shortcuts-review-yx-d92a, 20260929-teacher-shortcuts-review-ml-e7c1; their official drift/complete passed. Production deployment/model provider and signed package remain outside this evidence. + +## Follow-ups + +- Feature result is ready for a future explicitly authorized integration. No merge/push/deploy requested for this feature. +- Rollout: WS registration accepts shortcuts, then Yuxi publishes it, then upgraded Makelore renders it. Existing teachers can edit default or clear then publish. Draft-only save has no student effect. + +## Promotion Candidates + +- Target: canonical teacher architecture/domain decision and current-state. Proposal: Yuxi-owned ordered label/prompt shortcuts with explicit publish; optional legacy snapshot field and [] hiding; stable chat and per-question latest config continue. Evidence: tests/browser results above. Future impact: one configuration source, no new synchronization path or migration. Semantic conflicts: none identified with accepted explicit-publication decision. Human confirmation: behavior already requested; canonical promotion requires a future authorized integration task. \ No newline at end of file diff --git a/README.md b/README.md index 45fc0edb..920532b6 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ Pi 正式包必须继续运行 `pnpm run verify:artifact:pi`、`pnpm run smoke:p - 咨询正文支持 Markdown 标题、列表、表格、代码围栏、HTTP(S) 链接/图片和数学公式,长代码与表格在栏内横向滚动,不执行 HTML。云端正文维持 string 合同,未知对象不会猜测转成回答。工具活动只从云端主线程的类型化工具事件及 Main 本地读取过程获得,按本次问题/工具调用身份合并名称和状态,跨云端暂停、续接仍只计一次;暂停读取不算失败,状态以实际读取结果或问题终态为准,单独折叠显示;参数、结果原文和内部错误不混入回复,思考内容不作为正文。客户端仅保存自己实际收到的工具状态,不能补回旧历史或断线期间已经过期的事件。 - 云端咨询在 local_context 声明 read_protocol=2;需先部署配套 Yuxi API 和 worker,再升级客户端。云端持久累计读取字节及批次,每轮告知模型剩余额度;预算耗尽后消费最后一批结果,并以 tool_choice=none 要求根据现有证据形成答案和说明缺口。Main 限制实际返回量并拒绝第十三批读取,区分读取达到上限、上下文失效及格式无效。服务端对未声明协议的已安装旧客户端保留原工具参数与六批边界。 - 智能体人设、职责、提示词和 Skills 由发布配置决定。Main 不追加固定教学基线、不生成“小麦”、不清空所选智能体的 Skills,只添加真实工具能力、上下文边界和本轮界面协议。智能体名称叫“老师”“朋友”或“代码顾问”不改变调用路径或权限。 +- 输入框为空时显示当前老师已发布的快捷提示,按 Yuxi 中配置的顺序展示文案,点击直接发送该项实际提示词。Yuxi“编辑 → 快捷提示”支持最多 8 项,每项文案最多 40 字、提示词最多 6000 字;保存并发布后,目录更新即可生效,历史和未发送草稿保留。明确发布空列表隐藏全部按钮;缺少字段的历史版本保留“继续看看👀”。多个长文案在限定高度内滚动,运行中禁止重复发送。上线需先更新 WS 登记接口,再更新 Yuxi 和客户端。 - `reply.ts` 只声明正文与快捷回复的输出格式,语言、长度、前缀与表达风格由所选智能体的云端配置决定。客户端不再发送选择、生成、转换或维护展示组件的指令。旧话题内的组件状态、快照和解析诊断作为不透明历史数据原样保留,不校验删除、不恢复交互;旧组件修改路由已移除。 - 当前输入是按预算截取的所选操作对话已完成分支文本、明确引用、咨询正文和快捷回复,并支持上述只读原文恢复;旧组件状态、快照和未解析原文不加入模型上下文或咨询历史读取结果。没有跨全部操作会话自动读取,也未向操作 Agent 注入咨询共识。提示词不声称看过未提供的画面或试玩过作品。Yuxi 话题经云端原生执行,旧版本地智能体由 Main 调用计费网关;均不创建本地 Pi 编程 worker。 - 智能体输入裁剪区分两种计量:本地模型以约每 2 个 UTF-8 字节估算 1 Token,并计入工具与读取预留;这不是精确分词或扣费依据,模型上限与实际 usage 仍由服务端拥有。云端沿用 query 字节上限,以完整 JSON 转义后的大小裁剪来源节选。智能体指令、当前问题和明确引用不会被静默裁掉;固定配置或回复协议超限时明确提示调整配置,避免让学生反复缩短短问题或新建话题。完整来源仍可由只读工具按需读取。 diff --git a/shared/coding-teacher.ts b/shared/coding-teacher.ts index 818fa7c9..5875c44c 100644 --- a/shared/coding-teacher.ts +++ b/shared/coding-teacher.ts @@ -6,6 +6,11 @@ export const TEACHER_CHECK_IN_INTERVAL_MS = 5 * 60 * 1000; export const TEACHER_UNCHANGED_CHECK_IN_INTERVAL_MS = 15 * 60 * 1000; export type TeacherRequestIntent = 'question' | 'suggestions' | 'guided-help' | 'check-in'; +export interface TeacherShortcut { + label: string; + prompt: string; +} + export interface TeacherDefinition { config_id?: string; runtime?: 'local' | 'yuxi'; @@ -18,6 +23,7 @@ export interface TeacherDefinition { icon_url?: string | null; welcome_message: string; suggested_questions: string[]; + shortcuts?: TeacherShortcut[] | null; system_prompt: string; skills: Array<{ id: string; diff --git a/src/pages/Chat/TeacherChatPanel.tsx b/src/pages/Chat/TeacherChatPanel.tsx index d451b901..75880ad9 100644 --- a/src/pages/Chat/TeacherChatPanel.tsx +++ b/src/pages/Chat/TeacherChatPanel.tsx @@ -595,9 +595,15 @@ function ProjectTeacherChatPanel({