Repository navigation
feat(web): add personal Agent configuration and model entry - #103
Conversation
HappyAuratus
left a comment
There was a problem hiding this comment.
审查版本:725f550a77a8f45cb482d5f065a700a513ffbed7;新增网页切片相对已审 P3 2d8e497 核对。发现两项可复现的 P2 问题,需修复后复审。
已检查成员入口的延迟读取、个人 API 与统一连接库、选项 revision/selectionVersion/fingerprint、显式修复和清除、数字原文序列化及凭据的 write-only 通路。当前 head 后端/前端 CI 均通过;本地运行 agent-configurations、model-connections 和 plugins 相关 6 文件 / 41 测试通过,git diff --check 通过。额外通过生产 AgentConfigurationDialog、完整 provider 和 MSW HTTP 边界运行两项复现,均确认失败:已有 OpenCode 默认连接没有 API Key 控件;修改默认连接草稿后保存插件选项,草稿回到服务器原选择。现有测试主要直接挂载 Editor,未覆盖该对话框的保存后重建与 OpenCode 全局默认分支。
本轮未重复完整后端 PostgreSQL/race gate,也未执行真实浏览器或模型运行验收;P3 沿用 cloud#101 同 SHA 已有独立审查及 CI 证据。P4 真实执行仍由后续事项承接。合并顺序仍需先 cloud#101。
| {editor.confirmClear && <ClearAgentOptions editor={editor} />} | ||
| <AgentConnectionTools | ||
| context={props.context} | ||
| selected={connections.data?.find((connection) => connection.id === draft.connectionId)} |
There was a problem hiding this comment.
[P2] 为 OpenCode 的全局默认连接接入凭据入口。OpenCode 配置只返回 modelDefault,不保存 connectionId,所以这里按 draft.connectionId 查找会得到 undefined,AgentConnectionTools 因而不渲染 CredentialForm。打开已有默认连接的 OpenCode「我的配置」即可复现 API Key 控件缺失,且默认模型表单内切换连接也不会更新此目标。请将凭据管理的目标显式关联到全局默认编辑选择,同时保持选项 payload 不复制全局模型引用;补已有连接、未配置 Key 和切换选择的对话框测试。
| key={editor} | ||
| scope={scope} | ||
| context={query.data} | ||
| onSaved={() => setEditor((current) => current + 1)} |
There was a problem hiding this comment.
[P2] 保存选项时保留独立的默认模型草稿。此处递增 key 会卸载整个 AgentConfigurationEditor,包括独立的 ModelDefaultForm。复现:打开 OpenCode,默认连接原为 A;在默认表单选 B 但尚未保存默认模型;点击「保存我的配置」,成功后默认连接无提示回到 A。清除插件选项也经过同一 onSaved 路径。请只重置已保存的选项基线,保留默认选择草稿及其原有 CAS version;补从生产 Dialog 进入的保存与清除回归。
|
已按审查意见修复两项 P2,新 head
顺带( 验证:新增 5 个测试( 合并顺序仍需先 #101。P4 的真实运行能力与发布验收仍由 #336 承接,ADR 保持 |
360cf30 to
73d8296
Compare
HappyAuratus
left a comment
There was a problem hiding this comment.
复审 commit 02eed4391da41e48e4947db5efbe9717c71a6de5。此前两项 P2(OpenCode 默认连接凭据入口、插件选项保存/清除卸载独立默认模型草稿)已有修复,新增后台刷新凭据基线的回归也通过。本轮发现一项新的 P2:保存后的 refetch 会把另一编辑器的 revision 静默应用到旧草稿,使下次保存覆盖未核对的并发修改,详见行内意见。
证据:当前 SHA 后端 check 和 frontend CI 均通过;本地 agent-configurations、model-connections、plugins 共 7 文件的原有 47 个测试全部通过。额外在生产 AgentConfigurationDialog / 生成客户端 / MSW 边界加入并发复现:第一次 PUT 返回 revision 2,随后 GET 返回另一编辑器的 revision 3;再次点击保存,实际请求为 revision 3、settings.style='initial my edit',而非保持写响应 revision 2 或要求显式核对。新增断言失败,原有用例仍全部通过。临时复现测试已移除,审查 worktree 干净,git diff --check 通过。
未执行真实浏览器、实际模型运行或重复完整后端 PG/race 门禁,不把 jsdom 当作浏览器验收。#337 已关闭并移交,后续结论按交接记录到 circus#354。
| setDraft((current) => ({ ...current, revision: written.revision, requiresRepair: false })) | ||
| try { | ||
| const latest = await onSaved() | ||
| setDraft((current) => agentConfigurationDraft(latest, written.cleared ? undefined : current)) |
There was a problem hiding this comment.
[P2] 不要把 refetch 读到的并发 revision 静默拼到旧草稿。agentConfigurationDraft(latest, current) 保留当前 values,却把 revision、selectionVersion 和声明基线改成 latest:本次写返回 r2 后,另一编辑器抢先写入 r3,随后的刷新读到 r3,本页面仍显示旧草稿,但下次 PUT 已带 r3,可直接覆盖对方修改,不再触发 revision_conflict。生产对话框/MSW 复现已确认第二次请求为 {revision:3, settings:{style:'initial my edit', ...}}。只可自动采纳本次写入确实确认的基线;读取结果若超出该写响应或发行/声明上下文已变,应保留草稿并要求显式核对。请补写入成功与后续读取之间发生并发修改的对话框级测试。
A save advanced the option baseline to whatever revision the follow-up read returned, so a retained draft could be paired with another editor's later revision and overwrite it on the next save. Adopt the read in place only when it is the confirmed revision in the same release context; otherwise keep the draft and require explicit reconciliation.
Lifting the write confirmation and setting update into module helpers keeps useAgentEditor within the 100-line function limit without changing behavior.
HappyAuratus
left a comment
There was a problem hiding this comment.
复审 commit 2c76a574735f2fc80345d0d4c9f709a5dfb0e864:上一轮 P2 并发覆盖已修复,本轮未发现新的阻塞问题,Approve。
adoptWrite 只在后续读取与写响应确认的 revision、编辑时 selectionVersion、声明 fingerprint 全部一致时原地采用;其他情况保留草稿并进入显式核对,不能自动给旧草稿配上新 revision。已回查此前 OpenCode 默认连接凭据入口、选项保存/清除保留独立默认模型草稿与 CAS version 的修复;本次 merge 后选定发行 kind 的后端、OpenAPI、生成客户端和入口保持一致。
本地证据:生产 AgentConfigurationDialog、生成客户端、MSW 边界的相关正式测试 6 文件 / 42 测试通过;另外临时加入“清除后读到并发写入”和“revision 与写响应相同但 selectionVersion 改变”两项对话框级验证,与正式测试合跑 7 文件 / 44 测试通过。临时还原修复前 83a398f 的 editor-state.ts 后,正式并发回归与上述两项验证均因未出现核对面板而失败,另外两个正式对话框测试通过;恢复当前 head 后 44 项全部通过。临时测试已移除,工作区干净,git diff --check 通过。
依据:cloud PR 当前 head(已重新 fetch 并在提交 review 前核对);specs upstream/main 5a608567b86c2ca1df38e9b15bafdc948692bf9f 的 personal-agent-configurations ADR 仍为 approved,本 PR 仅交付网页部分,其余运行时与真实验收由 circus#354 承接。
范围限制:本轮未执行真实浏览器、真实模型调用或完整 PostgreSQL/race 门禁;Code Review CI 连接要求重新连接 GitHub,本轮未独立读取 CI 状态,作者汇报的 CI 通过不作为本地复测结论。此 Approve 仅针对 cloud#103 当前 SHA,不代表 #354 的其他 PR 或发布验收已完成。
Summary
OpenCode reuses the global default. Clearing options never deletes connections. Selected release kind comes from the frozen selection, not the newest catalog. Independent forms avoid nested HTML forms.
Base: #101 is merged. Merged with main
a9c5f20fcbe9a1ff5f3c51218230a189a418c551(after #81); the diff contains only the selected-release kind and personal configuration UI changes and adds no migration.ADR: personal-agent-configurations remains approved. This PR implements its web editing portion; runtime adapter delivery and final ADR implementation remain separate.
Refs ora-space/circus#337
Evidence
After: member entry, typed writes, CAS conflicts, explicit repair, clearing, inline connection creation and credential cache isolation are exercised through production clients and MSW.
npm run check: 142 files / 1160 tests passed; types, lint, coverage, module docs, documented exports, dead code, duplication and production build passed.npm run check:modules -- --base upstream/main: module hygiene OK for the 4 modules changed against upstream main; both READMEs ofagent-configurationsandmodel-connectionsare updated with this change.360cf30): the option baseline now advances in place from the write result plus a refetch instead of remounting the editor, so an unsaved default-model draft keeps its connection, model and CAS version across an option save or clear. OpenCode's credential controls follow the connection chosen in the global default draft (including one created inline) instead of the absent pluginconnectionId, and cover an existing configured connection and a connection without a key.agent-configurations/dialog.test.tsxdrives the production dialog for the save and clear scenarios;editor.test.tsxcovers the default-connection, missing-key and follow-the-draft cases. Both new dialog tests and all three credential tests fail against725f550and pass on this head.1c74995,2c76a57): a save adopts the follow-up read in place only when it is the revision that write confirmed, in the same selection and declaration context. A read showing another editor's later revision keeps the draft on the confirmed revision and opens the explicit comparison with saving disabled, so a retained draft can no longer be sent with a revision it was never compared against.dialog.test.tsxdrives the production dialog through the reviewer's sequence (save → concurrent revision 3 → comparison → adopt server → save with revision 3); the later commits only format the change and keepuseAgentEditorwithin the function-size limit.Merge Danger
Door: two-way
No migration beyond the prerequisite P3 stack. Backend still enforces ownership, revisions, declaration identity and runtime readiness.
Blast Radius: personal-configuration
The editor advances its baseline only after successful writes that a follow-up read confirms, or after explicit user reconciliation, and only the option baseline moves: the independent default-model editing session and its CAS version survive. API keys use the existing write-only boundary and never enter configuration payloads or query/mutation variables.
Numeric Settings and declaration defaults retain their original JSON literals through controls, request serialization and the reconciliation view, including large integers and precise decimals. The P3 replay fix is inherited from main.
New head CI provides the post-merge frontend/backend gates.
Refs ora-space/circus#354