Repository navigation
feat(chat): discover ACP Agent models before sessions - #6315
Conversation
Signed-off-by: The one -Niu <191000457+NIU-123370@users.noreply.github.com>
Signed-off-by: The one -Niu <191000457+NIU-123370@users.noreply.github.com>
Signed-off-by: The one -Niu <191000457+NIU-123370@users.noreply.github.com>
Signed-off-by: The one -Niu <191000457+NIU-123370@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · xhigh
动机
在 Goal、项目或 Manager Chat 中选择执行 Agent 和模型的用户。 原界面只提供 Agent 选择,ACP(Agent Client Protocol,上游 Agent 的会话协议)模型能力没有可见选择入口。 本 PR 增加模型发现和选择,并把选项送到会话;普通 Fast 模型可真正采用,但发现接口列出的合法模型值会被存储拒绝,刷新后模型显示也会与仍在运行的会话不一致。 本 PR 不授予任意程序启动、新增凭据或更宽工作区权限,不改变已有审批边界,也不完成 Qoder 本身或正式 App 安装的资格化。
改动思路
保留现有 endpoint registry、adapter 与 Session store,但模型值必须按 ACP 配置值验证,界面当前选择必须回读所属会话;不应复用实体 ID 的文件名约束或另建内存选择权威。 本 PR 应完整交付“发现 → 选择 → 创建/恢复会话 → 实际采用 → 刷新后真实显示”的同一用户任务;会话的模型值与当前显示修复应在同一批完成。
独立依据:docs/development/frontend-delivery.md,冻结修订 297019c16c3c66f88479ad4141338cc2dda66d64 的 Compare the journey、Choose the owner and composition、Walk the actual product 和 Deliver and read back,以及同修订 docs/development/design.md 的 whole-viewport 要求。当前可发现性与普通 flat model 调用已实现;Walk the actual product / Deliver and read back 的实际采用与后续真实显示尚未满足。ACP session config options 允许配置选项值为字符串,并允许分组选项与非固定的配置 ID;实体文件名 grammar 不能替代该值的协议契约。这里独立验证产品旅程,不以 author 预览声明替代读回或新增人为审批门槛。
具体改动
精确 head be7967df77ccdb56706e91568fc484eb508916fd,全 PR 13 文件 +280/-13。真实 PR 基线是 stacked dependency #6314 的 297019c16c3c66f88479ad4141338cc2dda66d64(codex/fix-qoder-acp-initialized),不是 main;其初始化修复不计入本 PR 交付。最初 queue head 18aa5667db3bf03a0b85aed1a0a289d8d06a75e7 在审查前已更新,原生 packet 拒绝后重新获取当前计划、全差异和验证;新增 delta 是 Codex/Claude catalog 与 Claude --model,未沿用旧结论。
data/chat.ts增加 discovery DTO、POST 与会话 model 参数;channel-header.tsx自动发现所选 Agent 的可用模型,AbortController 防止迟到响应,呈现 loading/error 和选择器。workspace model/page 与 dashboard 的三类会话创建入口传递模型;chooseAgentModel使当前上下文下次新建会话。chat_server.py加 loopback discovery handler/输入与响应投影;chat_runtime.py::inspect_agent_model_options为 ACP 创建临时 adapter 并关闭,Codex 读取其 model catalog,Claude 提供 catalog。_start_adapter与_ensure_adapter向 Codex/Claude/ACP 转发并恢复选择;chat_providers.py加 Claude--model。chat_session_open.py/chat_manager.py转发不同 Chat 上下文;chat_store.py持久化agent_model_id,已有会话 model 不同则新建而保留历史。chat_acp.py解析session/new/load配置并在新会话设置所选值;smoke 新增 flat-options/setter 场景。没有改 provider credential 或工作区权限规则。- [P1] 已发现且上游接受的模型值在持久化时被拒绝,并留下未受管理的 adapter。 chat_store.py:308 用
_opaque_id的[A-Za-z0-9._-]grammar 校验模型值。实际 HTTP discovery 返回vendor/model-fast,实际 ACP peer 的session/set_config_option也接受它;POST 创建会话却 400agent_model_id must be a compact opaque id。open_sessionchat_runtime.py:774 已先启动并完成上游设置,store 抛错后 adapter 尚未加入self.adapters,自己的合成子进程仍存活。最小修复:单独的有界模型值校验,保留精确协议字符串;启动前校验,持久化异常确保关闭已启动 adapter。回归必须通过真实 HTTP/stdio 和进程读回,覆盖/、其他合法协议值、未知选项拒绝及不泄漏;不要放宽 Session/Agent 实体 ID。 - [P1] 刷新后显示 discovery 默认模型,而实际恢复的是另一模型。 channel-header.tsx:90 在未有内存选择时使用临时 discovery Session 的
currentValue;dashboard-page.tsx:1409 每次页面加载将 model map 初始化为空,不从当前会话回填。实际构建 UI 中选 Fast、发送消息,上游回复 Fast、store 保存 Fast;整页刷新后标题变 Safe,恢复的原会话仍为 Fast,下一消息也走 Fast。最小修复:按当前上下文/Agent 的 durable 会话或明确的新会话意图恢复真实选择,区分可用 catalog 默认值与正在使用的模型。回归为选择 → 发送 → reload/resume → 标题和实际采用一致,跨上下文切换保留各自绑定与旧历史。
对主干的风险
已执行真正的 serve_chat、当前 compiled Chat bundle 和 stdio ACP transport,使用可丢弃的合成 registry/Goal/模型 peer;不是把模型结果预置到浏览器。Fast 的 setter、实际 prompt response、native Session 持久化、Ego UI 选择/重载及桌面 whole viewport 共同复现;390px narrow viewport 无横向溢出。脚本式 peer 不证明真实模型权重、计费、Qoder 实时服务或完整 installed App 行为,这些没有冒称通过。
discovery 没有新增 LoopX Session,正常临时进程已关闭;未知/缺失 endpoint 保留现有拒绝,普通不传模型的真实 API 在冻结 base/head 都 201,原审批/权限与 managed binding 由同一 owner 保持。当前 53 项 adjacent tests 与冻结基线同样通过,ACP adapter smoke、bundle build/source integrity 通过。现有 smoke 只有 flat、固定 model ID 与简单值,无法否证上述两个问题。额外实际 API 还观察到合法 grouped options 被丢空、category=model 但 ID 非 model 的配置不可发现;修复时应明确兼容范围,不声称本轮已经资格化全部 ACP provider。
当前 native premerge 的 5 direct +8 selected 返回失败(3 次失败调用,2 个独立问题):chat_runtime.py 2137→2219 行超出既有 module budget,且 chat_server.py 的四条 registry IO manifest 位点 stale。冻结 297019c16c3c66f88479ad4141338cc2dda66d64 的同一 maintainability ratchet 与 semantic vocabulary smoke 均通过,当前失败归因本 PR,不归因 CI。请在同 PR 里按 repo budget decision guide 做有证据的相邻 provider helper 归属或预算决策,并重新生成/审阅 IO 清单;不为绿色结果机械截断语义或任意放宽预算。首次误猜 pytest 文件名造成 no-tests setup diagnostics,已从实际文件清单恢复到上述完整 53 项;没有将这些 setup 失败算作产品缺陷。未查询或等待 CI。
类型/默认/权限审查:新增发现 schema 是 Chat 的投影;optional agent_model_id 是实际持久化选择,不能靠静态 catalog 或内存 map 推导正在运行的 Session。自动发现所选已注册 endpoint 是新增默认读路径,会创建上游临时会话;它不授予任意命令启动,不是自动采用该模型。一般 no-model API/权限边界保持;模型 catalog 的自动发现并非显式 default-off 功能,不用“可用”推出执行许可。Python 部分落在既有 provider transport/Session owner,TS 前端复用现有 Chat 入口;不要求无关全量语言迁移。机器 setter/存储约束是义务,UI提示是投影;无 substring denylist 或 benchmark-specific 通用控制面规则。
我的整体评价
REQUEST_CHANGES。入口与普通模型调用有实际增量,但可选择值不能端到端保存、显示不能反映恢复后实际会话,用户任务尚未完整。保留现有 endpoint registry、adapter 与 Session store,但模型值必须按 ACP 配置值验证,界面当前选择必须回读所属会话;不应复用实体 ID 的文件名约束或另建内存选择权威。 本 PR 应完整交付“发现 → 选择 → 创建/恢复会话 → 实际采用 → 刷新后真实显示”的同一用户任务;会话的模型值与当前显示修复应在同一批完成。 相邻精简应移除重复模型选择权威,并将 catalog/provider IO 留在最近 owner;先解决这两个实际边界与当前必需验证,不加宽泛框架或付费模型资格化要求。修复后在新 exact head 重跑完整模型选择/恢复/失败清理旅程;本轮没有合并、部署或升级本机。
English verdict: REQUEST_CHANGES - be7967d; an advertised legal ACP model value is rejected after upstream session creation and leaks its adapter, while reloaded UI shows the discovery default instead of the persisted active model. Real compiled UI/HTTP/stdio reproduction, 53 adjacent passes and matched baseline checks establish the defects; current module-budget and registry-IO checks also regress.
|
修复已推送到当前 head
验证:ACP adapter smoke(含 |
fa5424d to
7d5ebc4
Compare
Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
7d5ebc4 to
093cd3d
Compare
|
身份更正:修复提交已由当前 PR 作者账号 |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=xhigh
评审 head:093cd3d7b0bc9218d2fef5c3bf9ee3faa7552199。旧的普通选择/刷新问题已经独立证实修好,完整旅程仍有阻塞。
动机
在 Goal 对话里选择 Agent 和模型的用户,需要刷新或恢复后仍看见实际正在使用的模型。旧版只选 Agent;本 PR 增加模型选择,新 head 已修复普通模型选择和刷新,但合法分组选项仍不可选,上游恢复为 Safe 时标题仍显示 Fast。 模型决定用户对回答质量和费用的预期;如果标题只重复曾经的选择,恢复后的实际模型变化就被隐藏,用户会在后续对话持续依赖错误信息。实际构建页面选择 Fast、发送消息及普通 reload 均正确;真实 ACP session/load 报告 Safe 后实际回答也是 Safe,当前标题和持久字段仍为 Fast。分组/非固定配置ID在真实HTTP/stdio路径被丢空或拒绝。 本轮只验现有 Chat 的完整模型选择/恢复边界,不新增任意程序启动、账户、权限、沙箱或全新运行循环;不把合成 ACP peer 当真实模型/App安装。
改动思路
保留现有 Session store、ACP provider 和 TS header;合并真实配置读回,避免目录默认或持久意图成为第二个“实际模型”权威。同一发现→选择→创建/恢复→实际采用→真实显示旅程;相邻预算/IO清单在本PR内修正,不增加宽泛框架。改变选择开启不同会话并保留旧历史是合适的边界;恢复时尊重上游配置也是合理的,但应同步实际状态,而不是继续显示旧意图。模型目录只能证明可选项,不证明当前会话用了哪一个。现有 provider Python 与前端 TS 归属可以保留,不要求无关语言迁移或付费模型资格化。
具体改动
独立依据为 docs/development/frontend-delivery.md(冻结修订 297019c16c3c66f88479ad4141338cc2dda66d64)及同修订 design.md。Compare the journey 已实现普通发现/选择/发送及无额外确认的刷新;Choose the owner and composition 与 Walk the actual product 仍未满足实际恢复配置与真实显示一致,以及合法选项可完成选择;Deliver and read back 的源码/构建和失败边界本轮分别记录。协议依据为 ACP Session Config Options:select options 支持平铺或分组,配置ID是设置的真实标识,category只是语义提示;new/load/setter/update 的实际当前值不能由此前选择替代。
全 PR 从 stacked #6314 的 297019c16c3c66f88479ad4141338cc2dda66d64 判断,14文件 +343/-31;初始化修复属于依赖,不计本PR交付。另对旧评审 head be7967df77ccdb56706e91568fc484eb508916fd 复核 delta:新增模型值规范化和启动前校验、持久化失败关闭 adapter、按上下文/Agent从会话恢复 UI 选择,均有当前独立证据。
关键代码讲解
chat_acp.py::_session_config_options/model_options 将上游配置投影给模型控件,但只读取顶层 value、且只找固定 model ID;合法分组值消失、非固定配置ID无法设置。ACPStdioAdapter.start 在 new 上应用显式选择,在 load 上读取上游配置并避免无依据重新设置;问题是实际值没有再投影到 Session/header。chat_runtime.py::open_session/_ensure_adapter 已在启动前检查值,存储异常关闭进程;chat_store.py::normalize_agent_model_id 保留 vendor/model-fast,实体ID仍按原语法约束。dashboard-page.tsx::recordSessionAdmission/chooseAgentModel 以 context+Agent隔离意图,普通刷新正确,却仍把持久意图当恢复后的实际模型。
其余完整表面:chat.ts新 discovery DTO/POST及 optional model字段;ChannelHeader有loading/error/AbortController及既有WorkspaceSelect;workspace model/page透传回调;Goal/project/manager opening及三种provider透传选择;Claude argv增加model,Codex读取本机catalog;smoke和输入测试扩充。未改未知程序注册、账户、权限或Core quota。
对主干的风险
[P1] 合法 ACP 选项仍无法完整发现/采用。 同一个真正 stdio peer按协议报告分组Safe/Fast时,HTTP discovery为200且supported=true,却得到options=[];尝试Fast被拒绝,零Session落盘。category=model但ID=engine时,model=null,设置仍被固定model ID拦下。最小修复是同一parser规范化合法平铺/分组结构、保留正确配置ID并走同一个setter;不能以改名字或只加flat成功测试关闭此项。用实际HTTP/stdio覆盖选择→持久化→prompt及未知选项拒绝。
[P1] 恢复后的实际模型与标题仍不一致。 构建页面选择Fast、发送、普通reload均显示/使用Fast,旧问题确实关闭。之后合成上游按协议在session/load报告Safe,实际adapter的currentValue与新prompt都是Safe;Session字段和页面标题仍Fast,桌面与390px窄屏均读回这一差异。修复须区分用户意图和实际配置,消费new/load/setter/update的配置读回,经现有Session owner同步真实模型/可解释变化;不必擅自重新设置上游或增加另一份选择权威。回归覆盖正常恢复、缺少readback时的unknown、provider fallback/update及不同上下文旧历史。
[P2 / 当前必需检查] IO清单与预算仍过期。 当前native套件632pass/2fail;相同两个失败节点在冻结base为2pass47.30秒。四条chat_server registry IO位点metadata stale,runtime2137→2226、store1985→2006超出当前已评审ceilings;不是CI待完成或外部故障。按既有budget decision guide判断同域provider/read-model提取或有证据的预算决策,并生成/审查IO清单,保留语义后重跑,不能仅改上限/删断言。
另有14项store输入测试、ACP smoke、仓库范围Ruff、TypeScript/Chat build及source verify通过;独立原基线/旧评审/当前真实stdio/store对照确认slash值与旧泄漏已修,invalid-before-start零进程、未知值/存储失败进程清理通过。20个authority-derived背景、10Goals均在隔离状态测试模型选择;不代表这些真实领域/Agent已使用此功能。当前本机Codex catalog真正命令及JSON可用,Claude未安装,未冒称其live路径。浏览器使用Ego、真正production HTTP和当前构建bundle;未用浏览器mock替代采用规则,390px无横向溢出,键盘Escape与整个viewport已核。脚本peer不证明实际模型权重/收费、Qoder服务或signed App安装。未读取、等待CI;临时浏览器和本轮fixture服务均关闭。
语义与 CI 对齐
新模型意图/发现DTO扩展现有Chat合同,provider读回应是派生投影;没有新Core状态机或Agent authority。diff advisory在完整semantic前执行,但空词表建议不替代四条IO清单的实际失败;精确base/head检查和消费者证据保留。原no-model普通路径仍工作,read-only来源不执行新discovery;自动读取所选registered endpoint是新增默认读路径,明确有上游临时Session/进程成本,并非default-off或自动采用授权。
我的整体评价
REQUEST_CHANGES。普通选择和普通刷新有正向增量,归属和整体规模可以接受;长程效果及完整体验仍是not_yet_proven,因为合法选项无法到达结果,恢复后实际模型变化也不可被信任地看见,当前必需验证还失败。保留同一Session/provider/TS owner并补真实观察,能减少后续手动纠偏和重复选择;无需扩大成通用配置框架或要求完整父路线图。本轮未来重构检查指出catalog/provider IO与current read model是有价值的相邻边界,预算决策需带当前证据。源码测试、公开review和经验context不证明自然长期净收益;修复上述现有旅程与required节点后按新exact head复核,不能继承本次或旧批准。
English verdict: REQUEST_CHANGES - 093cd3d; ordinary legal model selection, persistence cleanup and reload are independently repaired, but grouped/non-fixed ACP options remain unusable and resumed provider Safe is still displayed as prior Fast. Real compiled UI/HTTP/stdio/store counterfactuals,632 passing tests / 2 PR-caused required failures, 14 input tests and bundle/Ruff evidence were recorded. Live model/installed App/long-run utility remains unqualified.
Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
|
Addressed the three requested changes on head
Validation: real loopback HTTP → stdio ACP discovery and Session creation; ACP smoke for grouped model, persistence, recovery, provider fallback update, unknown selection and missing readback; 87 focused Python tests; Chat HTTP smoke; Ruff; TypeScript and packaged Chat bundle build/source verification; packaged Runtime/API/UI changes remain for maintainer review; no self-merge is requested. Please re-review this exact head and its CI result. |
Signed-off-by: sakurahello1 <201035361+sakurahello1@users.noreply.github.com>
Signed-off-by: sakurahello1 <201035361+sakurahello1@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=xhigh
Exact head: dcd25fe9280e300ce97338dad89ce9d233c451b8; immutable stacked base: 297019c16c3c66f88479ad4141338cc2dda66d64 (#6314), not main. 本轮重新判断完整PR,不继承093cd3d verdict。
动机
在现有 Chat 选择模型、继续或恢复对话的用户。
当前已修好分组/engine配置ID和实际恢复读回;合法模型值仍在HTTP入口被改写,重选相同当前模型会无谓开启新会话。
实际分组/engine选择、Fast发送、同会话恢复Safe和unknown显示通过;两个真实HTTP/打包UI反例仍阻塞完整使用。
不新增账户、任意程序或工作区权限;合成ACP peer不证明真实模型权重、费用、Qoder或installed App。
须修HTTP精确值保留和相同当前模型的无操作选择;长期净收益仍未测。
改动思路
保留原ACP provider、Session store和TS header归属;入口复用模型值owner,真正变化才开启新会话,移除重复解释或无意效果。
同一发现→选择→实际采用→恢复/更新→真实显示的有界旅程;修正两个当前caller边界,不扩大成通用配置框架。
什么也不改会继续缺模型选择及恢复后的真实信息;只改header文案无法采用模型;新配置框架会重复既有provider/Session权威。当前整体机制与实际需求匹配,剩余两处修复都在原caller中完成,无需额外设置、手工同步或付费模型资格化。
具体改动
依据修改前 docs/development/frontend-delivery.md @ 297019c16c3c66f88479ad4141338cc2dda66d64、同revision design.md及 ACP Session Config Options。原规格逐项:
Compare the journey:not_met,相同模型重选无意开启新Session。Choose the owner and composition:implemented,现有provider/Session/TS header分别拥有IO、状态与展示。Walk the actual product:not_met,目录里的一个合法精确值不能通过HTTP采用。Deliver and read back:implemented,有当前source/build与真实HTTP/stdio/Session/页面读回,失败及真实安装未验分开。
全16文件+436/-47及093→dcd delta已读:五个frontend文件增加discovery DTO、模型控件、context+Agent选择和Session回填/Turn后刷新;ACPsmoke扩充分组、setter、load/update/unknown;预算record、provider/catalog、runtime、server、manager/session opening、store、I/O清单及inputtests完成同一链路。#6314初始化/timeout属于依赖,不计作本PR修复;未查CI。
关键代码讲解
ACPStdioAdapter._session_config_options/model_options/set_config_values展开group,保留真实engine ID、走setter并消费完整配置;load不擅自重设旧意图,update投影实际模型。ChatRuntimeController.open_session/_ensure_adapter先验证、存储失败关闭adapter、恢复时同步actual值;ChatSessionStore.normalize_agent_model_id/update_session保留有界协议字符串并维持实体ID独立约束。ChannelHeader/recordSessionAdmission使实际Safe或unknown显示替代发现默认,Turn后回读仍通过原Session owner。_create_session却还用prose compactor处理模型值;chooseAgentModel在setState返回同值时仍无条件清Session引用,这两处是本轮问题。
对主干的风险
前轮分组/非固定ID、恢复actual显示、I/O坐标和module budget已逐项重验修好。相同当前stdio peer在冻结base/旧093/current分别运行:base正常无模型参数可用;旧group/engine拒绝,current均真正采用Fast。Ego使用当前compiled bundle和真实serve_chat/stdio/store,选择Fast发送后真实回复Fast;重启同一隔离service,使上游load返回Safe,同Session持久字段、header和下一回复均Safe。缺配置load为None,页面显示当前模型未知。390px无横向溢出、键盘可开关模型菜单,但unknown按钮文本被截短为“当…”;建议在窄屏使用可辨识“未知”短标签。这里只是受控protocol peer,不是实际模型权重、费用或Qoder服务。
[P2,阻塞] HTTP保留精确的已提供模型值。 discovery200原样提供vendor/model fast,新Session请求经过chat_server.py:595的_compact_text变成单空格vendor/model fast,真实ACP allowed-values检查424拒绝,零目标Session写入。既有store normalizer及provider保留原值;同一隔离真实HTTP/stdio私有候选只在入口复用该normalizer,就201并持久化精确值,engine/普通slash对照仍通过。请在HTTP边界验证并保留协议字符串,别以文案压缩规则解释模型标识;覆盖合法空格/slash/组/ID与超长/controls拒绝、无泄漏。私有候选没有修改公开head。
[P2,阻塞] 相同当前模型重选应保持当前Session。 在actual Safe Session的编译页面重选当前Safe,chooseAgentModel虽不改model state,仍删除session ref、标记new;下一消息实际mode=new,Session数量2→3、当前ID改变,实际模型仍Safe。旧历史保留,没有声称删历史或测出真实模型上下文损失;新的upstream会话/setup和无意会话切换已观测。请在当前TS选择owner对已绑定相同有效值先返回,真正模型变化才建立不同Session;以完整UI/HTTP/持久读回区分no-op与真正change,不能只测model字符串相等。
当前355 focused tests、ACP smoke、source build/verify和5direct/19selected native检查通过,0advisory;额外20个不同职责的隔离合成上下文均经实际stdio/Session采用并退出清理;未在真实角色、业务Goal或账户中安装或执行模型。invalid-before-start零进程,unknown/store失败零Session且无泄漏。作者87或旧632不算本轮执行。
预算按真实增量核对:runtime2137→2202、store1985→2006;Codex catalog33行进入已有provider IO,剩余65/21行服务发现、真实读回与持久化,2210/2015仍为邻近增长上限,未缩语义或删除失败断言。四处I/O坐标同步/分类保持;当前CQR written fail明确保留HTTP精确值required失败,不称整个质量gate通过。source test、合成进程与可见UI不证明installed App/Lark/Windows/nativeweights/长期净效用。作者声明first-screen已获owner认可,本轮独立查看当前viewport但不认证那次私有审批或获得merge权限。
语义与 CI 对齐
模型DTO/可选Session字段扩展本地Chat/provider合同,实际配置是派生readback而非新增actor lifecycle。省略模型的旧路径与权限保留;header自动发现所选registered endpoint是新增默认IO,会启动再关闭临时upstream Session,明确不是default-off或授权扩大。read-only source按现有label guard跳过discovery,外部source切换未单独实测;catalog默认不等于正在使用的模型。义务在typed值/Session与作用边界,提示不能替代实际采用。前瞻整理保留现有provider提取;应顺手使frontend discovery id类型对齐实际engine字符串,避免后续caller假定只有model,但这不是当前setter另一个运行失败。
我的整体评价
REQUEST_CHANGES,justified_increment。旧P1与required记录已实际修好,模型状态可信度和普通选择方向为正;当前HTTP精确值失败与无操作重选的新会话却会增加反复选择、setup和上下文切换成本。两处原owner的窄修复足够,不要求额外框架、父路线图或付费评测;修正后按新完整head核验。long_horizon/user_experience在受影响分支为regression,自然长期净益未测,不能由355测试或20背景推断。须修HTTP精确值保留和相同当前模型的无操作选择;长期净收益仍未测。
English verdict: REQUEST_CHANGES - dcd25fe. Grouped/engine options, actual resumed/fallback model readback, unknown state and required IO/budget checks are independently repaired. The HTTP entry rewrites an advertised valid model string and refuses it; reselecting the unchanged active model starts another Session.355 focused tests, real compiled UI/HTTP/stdio/store,20 isolated authority-derived contexts and native checks were recorded; private minimal HTTP fix is not the public head, and native/live-model/sustained utility remains unqualified.
Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
…d' into codex/agent-model-discovery Signed-off-by: NIU-123370 <191000457+NIU-123370@users.noreply.github.com>
|
Fixed the two blockers from the latest review on head
Integrated the latest #6314 dependency ( Validation after integration: 27 focused Python tests (HTTP model boundary, store validation, ACP startup limits), ACP stdio smoke, Chat HTTP smoke, real HTTP → grouped The adjacent contract pass aligned the DTO's ID with provider readback; no new configuration owner or abstraction was added. Please re-review this head. The PR remains open for maintainer review. |
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=xhigh
Exact head: 9c7db8c794545785d31c57f9c6a219f39867d73d;当前 GitHub merge-base 323c3053128e41e16df27e6b6498f83c37e81f5e,初始化依赖 head 6bfdb64c7d70d508cef6fcc982cf047b3588a8c3。本轮判断完整22文件 +800/-64,不继承 dcd25fe verdict。
动机
在现有 Chat 选择模型、继续或恢复对话的用户。
当前修好合法模型值被 HTTP 改写及重选相同模型另开会话的问题;选择不同模型才明确建立新会话,原历史保留。
当前真实 HTTP、ACP 子进程、持久 Session 和打包页面均读回所选模型;服务重启后同会话改用上游实际 Safe,页面和下一回复同步。
不新增账户、任意程序或工作区权限;协议替身不证明真实模型权重、费用、Qoder、安装 App 或各领域长期净收益。
旧行为的实际代价是反复重选和无意的新会话/setup;本次对协议与会话连续性有正向证据,尚无自然长期效果或费用对照。发现目录只代表可选值,不能当成真实模型正在使用。
改动思路
保留原 ACP provider、Session store 和 TS 选择 owner,HTTP 复用既有值校验,重复选择在 TS owner 先返回;无须第二配置系统。
同一发现、选择、采用、恢复及真实显示的有界旅程;依赖初始化修复另归 #6314,当前主干冲突和安装采用分开判断。
只做静态菜单无法实际采用模型;新增通用配置框架会重复现有 authority。所选 ACP endpoint 的目录需要一个临时上游 Session,带来有界启动成本;它会关闭、不落地 LoopX Session,普通默认发送路径仍保留。真正变化才开始新 Session,相同当前值不增加操作。
具体改动
依据修改前 docs/development/frontend-delivery.md @ 323c3053128e41e16df27e6b6498f83c37e81f5e,文本与上一接受规格 blob 相同;ACP Session Config Options 提供外部字符串和真实配置 ID 的依据。当前规格逐项:
Compare the journey:通过;同模型第二消息保留原 ID/数量,不多填配置或确认。Choose the owner and composition:通过;原 provider、Session store、TS header 分别负责 IO、实际状态和可选意图。Implement and challenge:通过;实际 HTTP 连续空格/错误值、同值重选/真正变化、恢复上游实际值反例。Walk the actual product:通过;当前构建桌面/390px页面,经真实 HTTP、子进程 ACP、持久 Session 完成操作和后续消息;只替换模型协议对端。Review the task before the diff narrative:通过;先评估有用选择、恢复与继续工作的效果;不把目录或测试数当体验。Deliver and read back:通过;本次源码、构建和独立状态读回有记录,尚未合并/安装。
全22文件及 dcd→9c7 delta已读。五个 frontend 文件连通 discovery DTO、模型菜单、context+Agent意图、Session回填和Turn后读回;ACP/provider/runtime/server/manager/session-open/store 完成 flat/grouped/engine 发现、setter及实际采用/恢复/update。三个相关测试文件和两个 browser 文件覆盖有用负例,原 ACP smoke 扩展真实子进程。CLI startup-help 与 timeout tests 属于集成的 #6314依赖;metric ratchet 和 I/O census 同步现有 owner。无私有状态或第二模型配置系统。
_session_config_options/model_options/set_config_values 用真实 engine ID、完整 setter 回读和外部值;normalize_agent_model_id 保留 HTTP 原值,拒绝不安全/超长输入;open_session/_ensure_adapter 在持久失败时关闭 adapter,恢复时保存实际值或 unknown;chooseAgentModel 当前值相等时先返回,recordSessionAdmission/ChannelHeader 显示持久 actual 值。DTO ID 已从固定 model 改为 string,匹配实际 provider。
对主干的风险
没有当前阻塞性发现。此前两个阻塞已逐项验证:合法 vendor/model fast 通过真实 HTTP 返回201并原样持久化;真实打包页面重选当前 Safe 后第二消息仍用原 Session。真正切换 Fast 恰好新增一个 Session并保留旧历史;重启隔离服务使上游恢复 Safe,同一个新 Session的状态、header和下一实际回复均 Safe。
当前执行406 focused tests、原 ACP/Chat HTTP smokes、原 agent-model-selection 打包回归、source build/verify、Ruff,通过;5direct/19selected原生 canary 和严格 CQR 有效,0failure/0advisory。当前全部10Goal/20注册Agent职责数据逐项带入独立合成场景,20选择路径和非法输入/未知值/store失败清理通过;这只覆盖协议,不等于这些角色实际运行或领域效果。新注册endpoint可发现,未知/逃逸名称返回400、不生成Session。官方 Claude model configuration 当前确认所列 sonnet/opus/fable 为合法别名;账户可用性和真实provider费用未认证。
冻结323c基线未发 initialized 时协议对端退出,这属于 #6314既有初始化缺口;冻结6bf初始化依赖基线可以正常使用默认模型,但尚无本PR发现/选择。当前 flat/grouped/engine均实际选择Fast;不能把依赖修复计成本PR模型能力收益。先前 dcd 的 HTTP424及无意Session2→3原证据保留;当前源码、消费者、平台、依赖与claim失效矩阵重新判断,9对blob相同、13对变化或新增。
最初测试/build路径拼错未执行产品检查,按实际仓库入口修正;CQR scope字段超长修正声明后通过。恢复验证器最初在异步 admission结束前就检查,随后独立同Session/持久状态/下一消息证明恢复;未知endpoint的初版探针错误期待424,实际通用错误400且零Session,已保留原失败和精确读回。没有删除断言或改当前PR代码。
model/Session字段扩展本地Chat合同,旧省略模型请求继续合法;目录发现是明确的新默认IO,未伪称default-off。安装、目录、model可选值不授予Goal/Todo或账户权限。当前小型前瞻整理已落实HTTP normalizer复用、TS同值无操作及DTO real ID;没有必要再增加共享框架。预算增加保留有用决策和原next-turn成本边界,未以压缩语义换绿检查。
原完整 browser suite、installed App、nativeWindows、Lark、真实Qoder/付费模型/长期净效用未测;专项检查不代表全树health。当前分支与新main冲突是独立合并资格,更新后须重新失效判定并评审对应head。作者既有first-screen approval声明不由本轮认证,本次未修改/push展示。
我的整体评价
APPROVE。保留原 ACP provider、Session store 和 TS 选择 owner,HTTP 复用既有值校验,重复选择在 TS owner 先返回;无须第二配置系统。 同一发现、选择、采用、恢复及真实显示的有界旅程;依赖初始化修复另归 #6314,当前主干冲突和安装采用分开判断。 受控体验由“目录可见但值被拒绝/相同选择另开会话”变为“所选值真实采用、相同选择无操作、恢复后可继续并显示实际模型”,减少反复选择和无意setup。目录临时启动新增成本与实际模型长期净收益应独立测量,不能从406测试或20背景数量推断。当前完整有界模型旅程可以批准;分支整合、历史讨论、合并权限和安装采用分别判断。
English verdict: APPROVE - 9c7db8c. Exact offered values reach the real HTTP/ACP/Session path unchanged; equal-current selection retains Session identity, actual changes preserve prior history, and restart recovery reports/uses the upstream actual model in the same Session.406 focused tests, original packaged regression, real compiled UI/HTTP/stdio/store,20 isolated authority-derived contexts and native quality checks pass. Live model/installed App/sustained utility and latest-main integration remain unqualified; approval grants no merge authority.
Signed-off-by: huangruiteng <huangrt01@163.com> # Conflicts: # examples/loopx-chat-acp-adapter-smoke.py # loopx/semantics/project_registry_io_manifest_v1.json
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (maintainer review)
Reviewer: model_agent (self_reported); model=DeepSeek V4 Flash; provider=DeepSeek.
评审 #6315 feat(chat): discover ACP Agent models before sessions
Review exact head: efbda2741710189ddb221aba49e1771434886362;PR base main:896fec6a52e29390994976569bf4af5e29190734(此前评审 head 9c7db8c7)。
动机
一个在 LoopX Chat 里使用 ACP Agent(例如 Qoder)的操作者会遇到这个问题:他想在已注册的端点上挑选模型。在此之前,dashboard 无法发现端点提供的模型目录,Session 也没有记录实际采用的模型,界面可能显示一个陈旧或只是「意图」的值;本 PR 之后,选择一个已注册的 ACP 端点会展示其分组模型目录(含 provider 真实的 config id),HTTP 原样保留所报的值并在启动前校验,选择通过 ACP setter 执行并把返回结果读回持久 Session,恢复与 provider 更新都会刷新同一值,dashboard 显示实际在用模型或明确的未知状态。边界:本 PR 不授予新的凭据或工作区权限;发现只启动被选中的内建或 owner 注册端点。
改动思路
模型选择沿用既有 ACP adapter、endpoint registry、Chat session store 与 Chat HTTP 表面,Python runtime 只编排、dashboard 只投影,不新增平行选择源或配置 owner。本 PR 只把既有 ACP 端点的模型发现、精确值选择与持久回读补齐,不新增凭据、工作区权限或新的执行入口。loopx/chat_acp.py 新增 _session_config_options/model_options/set_config_values,把 ACP configOptions 的分组结构拍平成 {config_id → options},发现只暴露一个小投影(label/category/selected/options),provider 特有字段不外泄;session/set_config_option 的完整回读会覆盖 live 状态,config_option_update 通知也被消费。loopx/chat_providers.py 承接 Codex 目录解析(codex_model_options),loopx/chat_runtime.py 用它实现 inspect_agent_model_options(只启动被选中的已注册端点、返回前关闭临时会话),并在建会话时绑定 agent_model_id:模型不同则开新 Session。loopx/chat_store.py 增加 agent_model_id 与 normalize_agent_model_id,loopx/chat_server.py 增加 /api/chat/agent-model-options 与建会话时的模型校验,前端在既有 selector 上复用同一数据。
具体改动
19 文件 +583/−48(相对当前 main):loopx/chat_acp.py(目录归一化、精确 setter、update 消费)、loopx/chat_providers.py(Codex 目录投影)、loopx/chat_runtime.py(发现 + 会话绑定 + 不同模型开新会话)、loopx/chat_store.py(agent_model_id 持久化与校验)、loopx/chat_server.py(新 HTTP 端点与输入边界)、loopx/chat_manager.py/chat_session_open.py(模型透传)、dashboard chat.ts/personal-workspace-model.ts/channel-header.tsx/personal-workspace-page.tsx/dashboard-page.tsx(发现与显示)、examples/loopx-chat-acp-adapter-smoke.py 与 examples/personal-workspace-browser/agent-model-selection.mjs(合成 ACP 与打包浏览器场景)、module_metric_baseline.json 与 project_registry_io_manifest_v1.json(复核上限与生成账本)、以及两个新测试文件。
本 head 是 maintainer 为解决与 main 冲突所做的 sync merge。冲突有两个:examples/loopx-chat-acp-adapter-smoke.py(两侧都加了 client_initialized/initialized 分支,PR 另加 current_model+config_options() 夹具,保留 PR 侧即可,因为同文件 session/new、session/load 都调用它)与生成文件 loopx/semantics/project_registry_io_manifest_v1.json(用生成器在以并集为 previous 的合并树上重新生成,302 sites / 0 unclassified,--check 与 census 测试通过)。
对主干的风险
最危险的反例有三类。第一类是「悄悄换模型」:建会话时只有 agent_model_id 与 latest 会话记录不一致才开新 Session,同值复用保持原 Session 身份(test_chat_agent_model_http.py 与打包场景断言「改模型只产生一个新 Session、旧的仍在」)。第二类是「非法值穿透到启动」:HTTP 侧在 adapter 启动前用既有 normalize_agent_model_id 校验,超长/控制字符被拒(test_chat_store_input_validation.py),ACP setter 只接受目录里存在的值,未知值返回 unsupported_configuration。第三类是「显示意图而非事实」:模型只认 provider 回读,缺失回读记为未知;恢复(session/load)时不会用存储的旧值覆盖真实配置,config_option_update 也会刷新同一字段。发现路径只对已注册且可用的端点启动临时会话并在返回前关闭,未注册/不可用端点直接拒绝。
已知局限:验证使用合成 ACP peer 与真实 loopback HTTP→stdio fixture,不证明付费模型权重、真实 Qoder 服务或已安装 App 的行为;PR 明确声明不以此主张。维护性预算:chat_runtime.py 与 chat_store.py 的 reviewed 上限被提高(2210/2015,Any 37),我先复核了增长确为真实的发现/回读/持久化行并确认 ratchet smoke unreviewed: 0 / stale_exceptions: 0 / magnitude_regressions: 0,属证据驱动的预算调整而非为绿而放宽。
我的整体评价
这个切片值得合并:它把「模型发现 + 精确值选择 + 持久回读」补成一个完整且可回滚的能力,复用既有 ACP adapter/session/HTTP owner,没有新增凭据、权限或第二选择源,失败路径(非法值、缺失回读、未知目录)都失败关闭或显式记未知。交付边界如实:合成 peer 与本地 loopback 证据,不宣称线上模型或已安装 App。冲突解决只触及一个样例夹具与生成账本,并已用生成器与 census 测试复核。无阻断项。
English verdict: APPROVE - head efbda27: ACP model discovery flattens grouped select options while keeping the provider's real config id, selection uses session/set_config_option and reads the result back into the durable Session, the HTTP layer preserves and validates the exact offered value before startup, and unchanged model selections keep the same Session; my sync merge resolved one smoke-fixture conflict plus the generated registry-I/O census (302 sites, 0 unclassified), and the merged tree passes 331 focused chat/model Python tests, the ACP stdio smoke, the packaged Chat bundle build, the maintainability ratchet, the census test, Ruff, mypy and the 19-check premerge gate.
Maintainer merge recordMerged at exact head Why bypass was needed. The Changed surfaces
Merge resolution. Two conflicts: the ACP smoke fixture (both sides added the Checks run at this head
Failures / skips / holds
Coverage sufficiency. The change extends the existing ACP adapter, endpoint |
Summary
Complete Agent model discovery and adoption in LoopX Chat. A selected, registered ACP endpoint exposes its model catalog, including grouped options and provider-specific configuration IDs. HTTP preserves the exact offered value, including
vendor/model fast, and validates it before startup. Selection uses the ACP setter and reads its result back into the durable Session. Recovery and provider updates refresh that same value, so the dashboard displays the active model or an explicit unknown state.This keeps endpoint registration, Session storage and the existing dashboard selector as the owners. Reselecting the current model preserves the same Session; changing models creates a distinct Session and preserves earlier history. Discovery launches only the selected built-in or owner-registered endpoint; it grants no new credential or workspace authority.
Dependency
This PR targets #6314 (
codex/fix-qoder-acp-initialized), which supplies the ACP initialization and startup timeout repair. Merge #6314 first.Validation
enginemodel config,fixture/fastsetter, persisted response, recovery to the provider's actual default,config_option_updatefallback, unknown value rejection and missing readback.engineoptions; creating a Session withvendor/model fastreturned and persisted the exact value. Oversized and control-character values were rejected before startup.agent-model-selectionscenario passed: selecting the same model preserves Session identity; a real change creates exactly one new Session and retains the old one. This scenario uses synthetic HTTP storage; separate real HTTP/stdio checks validate provider adoption. An earlier full multi-scenario personal-workspace browser suite exceeded a 120-second local run and was not claimed as passed.The module metric ratchet was originally red at 2137→2202 lines in
chat_runtime.pyand 1985→2006 inchat_store.py. Codex catalog parsing was moved to the existing provider module; the remaining new runtime/Session paths serve discovery, actual model readback and persistence. Reviewed ceilings are now 2210/2015 lines and runtimeAnycount 37, with the ratchet passing. These are regression budgets, not transport limits.Validation uses synthetic ACP peers; it does not qualify paid model weights, a live Qoder service or installed App behavior. Runtime, API and UI changes require maintainer review and are not self-merged.