Clarify teacher prompt button click affordance

This commit is contained in:
鲨鱼辣椒
2026-09-29 20:20:58 +08:00
parent dc8f766a77
commit 79b1dc1892
4 changed files with 29 additions and 7 deletions

View File

@@ -64,3 +64,12 @@
- Completed: prompt button minimum height 30px (was 36px), padding 4px/10px, 8px corners, no border, soft 2px/6px shadow and pale cream background. Font remains 13px/400.
- Verification: typecheck, lint (0 errors, 8 existing warnings), source/staged production builds and six 319/508px prompt/model/microphone layout scenarios passed. Existing checks now assert no border, a shadow and 30px height.
- Updated the production stylesheet link in the live trial, with new built assets/index installed for subsequent reload. No Renderer remount or Main restart; live JS behavior is unchanged. Native capture confirms 30px, zero border and soft shadow. All localStorage, input text, operation messages, teacher turn text and route remained byte-identical; window stayed unfocused.
## Click Affordance Follow-up
- Same-task ownership and existing planning context verified again at dc8f766; peer scope decisions remain compatible. Gate passed. User wants the compact borderless prompts to look unmistakably clickable.
- Plan: retain 30px/13px sizing, strengthen the warm fill and bottom shadow, add a small decorative chevron, and provide hover/pressed depth feedback with reduced-motion support. Update existing layout checks and hot-swap the built stylesheet in the trial, preserving live conversations.
- Completed: 30px borderless buttons now have a warmer pale-yellow fill, 2px bottom shadow and decorative chevron. Hover raises 1px and pressed state lowers 1px; reduced-motion keeps position stable. Exact configured text and accessible name unchanged.
- Verification: typecheck, lint (0 errors / 8 existing warnings), source and combined-stage production builds, and six focused browser cases passed. Existing cases now exercise hover, pressed and reduced-motion feedback as well as 319/508px layout and exact prompt sends.
- Trial stylesheet index-ydJGBX8O.css installed and activated without reload. Native screenshot inspected; computed height 30px, font 13px, border 0 and raised shadow confirmed. All storage, inputs, 14 operation messages, teacher message text and route unchanged; focused=false before/after. No cloud changes or live messages sent.

View File

@@ -183,7 +183,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,只添加真实工具能力、上下文边界和本轮界面协议。智能体名称叫“老师”“朋友”或“代码顾问”不改变调用路径或权限。
- 输入框为空时,在输入框外上方显示当前老师已发布的快捷提示;采用与回复正文一致的 13px 常规字重、无边框、浅色底与柔和阴影的小巧圆角按钮,横向排列并自动换行。按 Yuxi 中配置的顺序展示文案,点击直接发送该项实际提示词。Yuxi“编辑 → 快捷提示”支持最多 8 项,每项文案最多 40 字、提示词最多 6000 字;保存并发布后,目录更新即可生效,历史和未发送草稿保留。明确发布空列表隐藏全部按钮;缺少字段的历史版本保留“帮我整体看🧠”。多个长文案在限定高度内滚动,运行中禁止重复发送。上线需先更新 WS 登记接口,再更新 Yuxi 和客户端。
- 输入框为空时,在输入框外上方显示当前老师已发布的快捷提示;采用与回复正文一致的 13px 常规字重、无边框、浅色底与底部立体阴影的小巧圆角按钮,配有小箭头和悬停/按下反馈,横向排列并自动换行。按 Yuxi 中配置的顺序展示文案,点击直接发送该项实际提示词。Yuxi“编辑 → 快捷提示”支持最多 8 项,每项文案最多 40 字、提示词最多 6000 字;保存并发布后,目录更新即可生效,历史和未发送草稿保留。明确发布空列表隐藏全部按钮;缺少字段的历史版本保留“帮我整体看🧠”。多个长文案在限定高度内滚动,运行中禁止重复发送。上线需先更新 WS 登记接口,再更新 Yuxi 和客户端。
- `reply.ts` 只声明正文与快捷回复的输出格式,语言、长度、前缀与表达风格由所选智能体的云端配置决定。客户端不再发送选择、生成、转换或维护展示组件的指令。旧话题内的组件状态、快照和解析诊断作为不透明历史数据原样保留,不校验删除、不恢复交互;旧组件修改路由已移除。
- 当前输入是按预算截取的所选操作对话已完成分支文本、明确引用、咨询正文和快捷回复,并支持上述只读原文恢复;旧组件状态、快照和未解析原文不加入模型上下文或咨询历史读取结果。没有跨全部操作会话自动读取,也未向操作 Agent 注入咨询共识。提示词不声称看过未提供的画面或试玩过作品。Yuxi 话题经云端原生执行,旧版本地智能体由 Main 调用计费网关;均不创建本地 Pi 编程 worker。
- 智能体输入裁剪区分两种计量:本地模型以约每 2 个 UTF-8 字节估算 1 Token,并计入工具与读取预留;这不是精确分词或扣费依据,模型上限与实际 usage 仍由服务端拥有。云端沿用 query 字节上限,以完整 JSON 转义后的大小裁剪来源节选。智能体指令、当前问题和明确引用不会被静默裁掉;固定配置或回复协议超限时明确提示调整配置,避免让学生反复缩短短问题或新建话题。完整来源仍可由只读工具按需读取。

View File

@@ -52,13 +52,14 @@
.consultation-retry { display: inline-flex; align-items: center; justify-content: center; align-self: flex-start; min-height: 44px; max-width: 100%; padding: 8px 16px; border: 1.5px solid #e3ce8f; border-radius: 16px 16px 16px 6px; background: #fff2c9; color: #6f5127; box-shadow: 0 3px 0 #e7d7a6, inset 0 1px 0 #fff9e8; font-size: 14px; font-weight: 600; line-height: 24px; cursor: pointer; transition: background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; }
.consultation-retry:hover:not(:disabled) { background: #ffe9a9; border-color: #d6b76f; }
.consultation-retry:active:not(:disabled) { transform: translateY(2px); box-shadow: 0 1px 0 #e7d7a6, inset 0 1px 0 #fff9e8; }
.consultation-shortcuts { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; max-height: min(192px, 24vh); overflow-y: auto; margin-bottom: 10px; padding: 3px; }
.consultation-hint { display: inline-flex; align-items: center; max-width: 100%; min-height: 30px; padding: 4px 10px; border: 0; border-radius: 8px; background: #f8f1e2; box-shadow: 0 2px 6px #8b75491a; color: #5b503b; font-size: 13px; font-weight: 400; line-height: 22px; text-align: left; white-space: normal; overflow-wrap: anywhere; cursor: pointer; transition: background-color 160ms ease, border-color 160ms ease; }
.consultation-hint:hover:not(:disabled) { background: #f2e8d2; box-shadow: 0 3px 8px #8b754924; }
.consultation-hint:active:not(:disabled) { background: #eee3c7; }
.consultation-shortcuts { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; max-height: min(192px, 24vh); overflow-y: auto; margin-bottom: 10px; padding: 3px 4px 6px; }
.consultation-hint { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; min-height: 30px; padding: 4px 10px; border: 0; border-radius: 8px; background: #f8e6b7; box-shadow: 0 2px 0 #d8c492, 0 3px 6px #8b75491a; color: #65491f; font-size: 13px; font-weight: 400; line-height: 22px; text-align: left; white-space: normal; overflow-wrap: anywhere; cursor: pointer; transition: background-color 140ms ease, box-shadow 140ms ease, transform 140ms ease; }
.consultation-hint::after { content: ''; width: 5px; height: 5px; flex-shrink: 0; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); opacity: 0.7; }
.consultation-hint:hover:not(:disabled) { background: #f7dfa0; box-shadow: 0 3px 0 #d1b979, 0 5px 8px #8b754924; transform: translateY(-1px); }
.consultation-hint:active:not(:disabled) { background: #efd28b; box-shadow: 0 1px 0 #c7ad70; transform: translateY(1px); }
.consultation-hint:focus-visible { outline: 2px solid #7891af; outline-offset: 2px; }
.consultation-hint:disabled, .consultation-retry:disabled { cursor: not-allowed; opacity: 0.5; }
@media (prefers-reduced-motion: reduce) { .consultation-hint, .consultation-retry { transition: none; } .consultation-hint:active:not(:disabled), .consultation-retry:active:not(:disabled) { transform: none; } }
@media (prefers-reduced-motion: reduce) { .consultation-hint, .consultation-retry { transition: none; } .consultation-hint:hover:not(:disabled), .consultation-hint:active:not(:disabled), .consultation-retry:active:not(:disabled) { transform: none; } }
.consultation-pane button:focus-visible { outline: 2px solid #71845f; outline-offset: 3px; }
.consultation-suggestion { border-color: #e0e6d6; color: #718163; }
.consultation-suggestion:hover { border-color: #bac9aa; background: #f4f7ee; }

View File

@@ -66,6 +66,18 @@ for (const width of [319, 508]) {
expect((await row.boundingBox())!.y + (await row.boundingBox())!.height).toBeLessThan((await composer.boundingBox())!.y);
await shortcuts.first().focus();
await expect(shortcuts.first()).toHaveCSS('outline-style', 'solid');
await expect(shortcuts.first()).toHaveCSS('cursor', 'pointer');
await shortcuts.first().hover();
await expect(shortcuts.first()).toHaveCSS('transform', 'matrix(1, 0, 0, 1, 0, -1)');
await page.mouse.down();
await expect(shortcuts.first()).toHaveCSS('transform', 'matrix(1, 0, 0, 1, 0, 1)');
await page.mouse.move(0, 0);
await page.mouse.up();
await page.emulateMedia({ reducedMotion: 'reduce' });
await shortcuts.first().hover();
await expect(shortcuts.first()).toHaveCSS('transform', 'none');
await page.mouse.move(0, 0);
await page.emulateMedia({ reducedMotion: 'no-preference' });
const form = (await panel.locator('form').boundingBox())!;
expect(form.y + form.height).toBeLessThanOrEqual(800);
expect(await panel.evaluate(el => el.scrollWidth <= el.clientWidth)).toBe(true);
@@ -130,7 +142,7 @@ for (const width of [319, 508]) {
await expect(hint).toBeEnabled();
await expect(hint).toHaveText('帮我整体看🧠');
expect(await hint.evaluate(el => el.scrollWidth <= el.clientWidth && el.scrollHeight <= el.clientHeight)).toBe(true);
await expect(hint).toHaveCSS('background-color', 'rgb(248, 241, 226)');
await expect(hint).toHaveCSS('background-color', 'rgb(248, 230, 183)');
const initialSend = (await send.boundingBox())!;
const hintBounds = (await hint.boundingBox())!;
expect(hintBounds.x).toBeLessThan(initialSend.x);