Files
notebook-ai-extension/docs/superpowers/specs/2026-07-23-cell-toolbar-actions-v3-design.md

6.2 KiB

Cell Toolbar Actions v3 — 启动时配置 + 动态模型选择器

  • 日期: 2026-07-23
  • 状态: 已批准(用户于 2026-07-23 确认,v3-final: settings 一项不留)
  • 取代: v2 OpenCodeSettings 类型 + v1/v2 全部 JupyterLab plugin settings。opencode_bridge 插件本轮完全不再使用 JupyterLab Settings Editor:所有连接配置走启动环境变量,模型选择完全动态(每次 inline 输入框里挑)。

背景

v2 之后用户提了 2 个调整:

  1. opencodeServerUrl / User / Password / requestTimeoutSeconds 不再在 JupyterLab Settings Editor 里配 —— 全部在启动 jupyter server 时通过环境变量指定。随后用户进一步要求:opencodeProvider / opencodeModel 这两项 settings 也不保留 —— 模型选择器完全动态,每次在 inline 输入框里挑,没有"设置默认值"的概念。结果:schema/plugin.jsonproperties 变为 {}(只剩非 settings 的 schema 注释 jupyter.lab.toolbars 贡献)。
  2. inline 输入框增加模型选择器 —— 从 GET /opencode-bridge/providers 启动时拉取并缓存;每次请求时用户挑一个 provider/model;无任何 settings 默认。

决策

维度 决策
启动 env(4 个) OPENCODE_BRIDGE_URL / _USER / _PASSWORD / _TIMEOUT(秒,默认 120);jupyter lab 启动前 export;config.py resolve_configos.environ.get(ENV) or DEFAULT,完全不再从 JupyterLab settings 兜底(没有 settings 可读)
JupyterLab Settings schema/plugin.json properties: {};opencode_bridge 插件不再 optional: [ISettingRegistry];settingRegistry.load(...) / setOpenCodeRuntime({settings}) 整段删除
前端 OpenCodeSettings 类型 删除整个类型;DEFAULT_OPENCODE_SETTINGS / readOpenCodeSettings 删除;opencode_bridge.spec.ts 中相关测试删除
setOpenCodeRuntime 改名为 setOpenCodeServerSettings(serverSettings),只接收 ServerConnection.ISettings(Jupyter 自己的 serverSettings,用于 callOpenCodeEdit 拼 URL);不再有 _settings 模块级
index.ts optional: [IToolbarWidgetRegistry](去掉 ISettingRegistry);激活时:注册 toolbar factory + 拉 providers 写缓存(无 settings block)
模型选择器 UI inline 面板顶部加一行 模型: <select>(单个下拉),选项 label provider / model,value providerId|modelId(| 分隔,IDs 不含此字符);textarea 在其下方
默认选中 下拉框第一项(无 settings 可作默认)
提交覆盖 prompt 的 onSubmit(text, providerId, modelId) 把当前选中带回去;actions 用它作为 request body 的 providerId/modelId(无 settings 兜底,prompt 必须有选择)
Providers 数据来源 GET /opencode-bridge/providersindex.ts 启动时拉取;通过新 setOpenCodeProviders(p) 写到 opencode_cell_actions.ts 模块级 _providers 缓存;inline prompt 构造时读
Providers 拉取失败 缓存为 null,inline prompt 不渲染 select;提交时 providerId/modelIdundefined不发这两个字段(OpenCode Serve 用它自己的默认)。优雅降级
schema jupyter.lab.toolbars 顶层 jupyter.lab.toolbars: { "Cell": [{ "name": "opencode-cell-actions", "rank": 100 }] } 保留(toolbar item 仍需 schema 贡献)

接口契约

前端 OpenCodeRequest:与 v2 相同(无 mode):

{ "prompt": "...", "context": { ... }, "providerId": "...", "modelId": "..." }
  • providerId / modelId 可选;只在 inline 选择器有选中项时发;providers 拉取失败时不发。

后端:与 v2 相同。config.py 新增:

ENV_TIMEOUT = "OPENCODE_BRIDGE_TIMEOUT"
DEFAULT_REQUEST_TIMEOUT = 120

resolve_config 4 个字段全部走 os.environ.get(ENV) or DEFAULTrequestTimeoutSeconds 是 server-side(OpenCodeClient → OpenCode Serve 的 httpx timeout),与前端无关。

环境变量清单:

变量 默认 说明
OPENCODE_BRIDGE_URL http://127.0.0.1:4096 OpenCode Serve 地址
OPENCODE_BRIDGE_USER opencode HTTP Basic Auth 用户名
OPENCODE_BRIDGE_PASSWORD ""(无 auth) HTTP Basic Auth 密码
OPENCODE_BRIDGE_TIMEOUT 120 请求 OpenCode Serve 超时(秒,整数)

机制

  • 前端:
    • opencode_cell_actions.ts 模块级:_providers(setOpenCodeProviders 写入)、_serverSettings(setOpenCodeServerSettings 写入)。 _settings
    • OpenCodeInlinePrompt 构造接收 providers(必填,可能为 null);无 defaultProviderId/defaultModelId 参数;默认选中第一项。
    • 点击提交 → prompt 回调 (text, providerId?, modelId?);actions 用回传的 provider/model 写进 OpenCodeRequest(undefined → 不发)。
  • 服务端:config.py 不再读 JupyterLab settings 字典(handler.settings.get("opencode_bridge", {}) 返回 {});SessionManager / EditHandler 不变。
  • OpenCode:与 v2 相同。

兼容性

  • opencode_bridge 插件不再读 JupyterLab settings;之前在 Settings Editor 设过 6 个字段(opencodeServerUrl / User / Password / requestTimeoutSeconds / opencodeProvider / opencodeModel)的用户:全部失效,需改用环境变量(连接类)或在 inline 输入框里挑(模型)。行为变更,需在 release note 标注
  • 4 个 env 变量 + 默认值覆盖之前 6 个 settings 字段的所有功能;模型选择器替代 opencodeProvider/opencodeModel settings 的"默认"作用(但完全由用户每次手选,无持久默认)。
  • OpenCodeSettings / DEFAULT_OPENCODE_SETTINGS / readOpenCodeSettings 类型/常量/函数整组删除;opencode_bridge.spec.ts 中相关测试删除。
  • setOpenCodeRuntime 重命名为 setOpenCodeServerSettings(签名 { serverSettings }),所有调用方更新。

验证

  • pytest opencode_bridge/tests/ 全过
  • jlpm test 全过(单测覆盖: select 渲染 N 项 / 默认第一项 / submit 覆盖 / providers 降级)
  • jlpm build 成功
  • 手动:export OPENCODE_BRIDGE_URL=... && jupyter lab → active cell 右上角单按钮 → inline 面板顶部 模型: [select](列出 provider/model,默认第一项) → 切换选择 → 发送 → request 带新 provider/model;Settings Editor 中 opencode_bridge 无任何字段