docs: v2 spec for single AI button + inline prompt + drop mode
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2bac98d659
commit
50ba847659
@@ -0,0 +1,86 @@
|
|||||||
|
# Cell Toolbar Actions v2 — 单按钮 + inline 输入框 + 删除 mode
|
||||||
|
|
||||||
|
- 日期: 2026-07-23
|
||||||
|
- 状态: 已批准(用户于 2026-07-23 确认)
|
||||||
|
- 取代: v1(`2026-07-23-cell-toolbar-actions-design.md`,commit 9e7c36e)。本轮是 v1 的演进。
|
||||||
|
|
||||||
|
## 背景:v1 → v2
|
||||||
|
|
||||||
|
v1 把 `✨ 优化` / `🐛 排错` / `🪄 编辑` 三个按钮从 cell 底部 footer 迁到原生 cell toolbar。用户反馈 4 个问题,本轮一并解决:
|
||||||
|
|
||||||
|
1. **Settings 不生效** —— v1 只在 `settingRegistry.load(...).then(...)` 调一次 `setOpenCodeRuntime`,没订阅 `settings.changed`,Settings Editor 改了值后模块级 `_settings` 仍是旧的。
|
||||||
|
2. **单元格高度被压** —— v1 三个文字按钮让原生 cell toolbar 变高,把 code 编辑区挤小。
|
||||||
|
3. **三个按钮合并为一个** —— 用户选 "完全合并为一个动作(按输入语义判断)"。
|
||||||
|
4. **点击后 cell 内显示输入框** —— `design.md` v1 留的 inline prompt box,本轮实现。
|
||||||
|
|
||||||
|
同时用户给出两个架构边界(必须遵守):
|
||||||
|
- **前端调用后端时,只获取 cell 的 input/output/error,不做任何处理**(不决策 mode、不解析语义)
|
||||||
|
- **1 notebook → 1 session**(`SessionManager` 已保证,本轮不动)
|
||||||
|
|
||||||
|
## 决策
|
||||||
|
|
||||||
|
| 维度 | 决策 |
|
||||||
|
|---|---|
|
||||||
|
| 按钮 | 单个图标按钮(🪄) |
|
||||||
|
| 交互 | 点击 → cell 内 inline 输入框(textarea + 🚀 发送 + ✕ 取消) |
|
||||||
|
| `mode` 概念 | **彻底删除**。前端 request body 不再包含 `mode`;服务端 `EditHandler` 不再读 `mode`,响应体也不再回 `mode`;`MODE_SYSTEM_PROMPTS` 字典删除 |
|
||||||
|
| 服务端系统提示词 | 唯一一条统一提示词,LLM 根据用户自然语言 + context(含 traceback)自己判断优化/排错/编辑 |
|
||||||
|
| 成功时 | 前端 `cell.model.sharedModel.setSource(resp.finalSource)` 就地替换 cell 源码 + Notification |
|
||||||
|
| Settings 实时生效 | `index.ts` 订阅 `settings.changed` → 重灌 `setOpenCodeRuntime` |
|
||||||
|
| `providerId` / `modelId` | 仍从 JupyterLab settings 读 → 透传(用户配置,非"对 cell 数据的处理",保留) |
|
||||||
|
| 作用范围 | 仅 `CodeCell`;非 `CodeCell` → factory 返回空 `Widget` |
|
||||||
|
| 之前的 footer | 已删(v1) |
|
||||||
|
|
||||||
|
## 接口契约
|
||||||
|
|
||||||
|
**Request** `POST /opencode-bridge/edit`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"prompt": "用户在 inline 输入框里写的自然语言指令",
|
||||||
|
"context": {
|
||||||
|
"notebookPath": "analysis/demo.ipynb",
|
||||||
|
"cellId": "cell-3",
|
||||||
|
"language": "python",
|
||||||
|
"cellIndex": 3,
|
||||||
|
"totalCells": 5,
|
||||||
|
"source": "import matplotlib...",
|
||||||
|
"previousCode": "import pandas as pd",
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
"providerId": "anthropic",
|
||||||
|
"modelId": "claude-sonnet-4-20250514"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **无 `mode` 字段**
|
||||||
|
- `context.error` 非空时,服务端在 OpenCode parts 里自动加 `<traceback>` 段(原 `_build_request_body` 行为,保留)
|
||||||
|
- `<instruction>` 段:只要 `prompt` 非空就加(原条件 `mode == "edit"` 守卫删除)
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
```json
|
||||||
|
{ "ok": true, "finalSource": "import plotly...", "sessionId": "ses-abc", "notebookPath": "analysis/demo.ipynb" }
|
||||||
|
```
|
||||||
|
- **无 `mode` 字段**
|
||||||
|
|
||||||
|
**系统提示词(统一,常量)**:
|
||||||
|
```
|
||||||
|
你是一个代码编辑助手。基于提供的代码上下文(以及 traceback,如果有),按照用户的指令修改代码。返回只包含修改后完整代码的回复,不要任何解释或 markdown 围栏。
|
||||||
|
```
|
||||||
|
(刻意保留 v1 `'edit'` 提示词的核心子串 `"你是一个代码编辑助手"`,以便 `test_edit_handler` 的既有断言继续通过 —— 该测试只断言子串存在,不强耦合具体措辞。)
|
||||||
|
|
||||||
|
## 机制边界确认
|
||||||
|
|
||||||
|
- **前端**:`OpenCodeCellActions`(toolbar 里的单图标)+ `OpenCodeInlinePrompt`(cell 内的输入框 widget,`Widget.attach` 到 `cell.node`)。组件代码只做:渲染按钮 / 显示输入框 / 取 `cell.model.sharedModel.getSource()` / 取 outputs / 取 error / 拼 `context` / POST / 成功调 `setSource` / 失败 Notification。**不**做 mode 决策、**不**做语义判断、**不**管 session。
|
||||||
|
- **服务端**:拥有 `SessionManager`(1 notebook 1 sid,不动);`EditHandler` 唯一拥有的 "决策" 是 "是否包含 traceback"(由 `context.error` 决定,机械规则不算"处理");系统提示词选择(从前端决定的 mode 改为服务端的常量);调用 OpenCode Serve。Session 失效(404/not found)时 invalidate,前端重发。
|
||||||
|
- **OpenCode Serve**:按系统提示词 + 上下文 + 用户指令干活,自己判断优化/排错/编辑。
|
||||||
|
|
||||||
|
## 兼容性
|
||||||
|
|
||||||
|
- 后端 `mode` 字段(若调用方仍发)被忽略,不影响响应(为旧 API 兜底)。`MODE_SYSTEM_PROMPTS` 删除后,`'optimize'` 和 `'fix'` 提示词从默认路径不可达 —— 这是有意的(用户选择 "完全合并")。若以后需要可走专门 API。
|
||||||
|
- 前端 `OpenCodeMode` 类型别名删除;`OpenCodeRequest.mode` 字段删除;`OpenCodeSuccess.mode` 字段删除。引用了这些的测试 / 组件同步更新。
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
- `pytest opencode_bridge/tests/` 全过(含 `test_edit_handler`,改写后)
|
||||||
|
- `jlpm test` 全过(单测重写 `opencode_cell_actions.spec.ts`,`opencode_client.spec.ts` 去掉 `mode`)
|
||||||
|
- `jlpm build` 成功
|
||||||
|
- 手动:`jupyter lab` 打开 notebook,active cell 右上角出现单个 🪄 图标;点击 → cell 底部出现输入框(带 placeholder、无默认值);输入指令 → 发送 → cell 源码被替换;切 cell 按钮随之移动
|
||||||
Reference in New Issue
Block a user