Repository navigation
fix(chat): complete ACP initialization before session creation - #6314
Conversation
f1e1feb to
fcb19a0
Compare
Signed-off-by: The one -Niu <191000457+NIU-123370@users.noreply.github.com>
fcb19a0 to
297019c
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · xhigh
动机
通过本地已注册 ACP Agent 创建或恢复 Chat 会话的操作者及设置启动超时的调用方。 一些 provider 需要会话前通知且创建耗时超过默认30秒,原路径在真实首次使用报告超时;原调用方的 startup_timeout_sec 对 initialize 和会话阶段分别生效。 当前 head 在会话前发通知,并给 new/load/resume 至少45秒;合成慢启动及通知依赖路径可以创建和恢复,但显式较短上限也被覆盖。 本 PR 不新增凭据、工作区写权限、任意命令启动、持续 daemon 或真正 Qoder/模型计费资格。
改动思路
共享 ACP adapter 是已有 transport owner;默认或 provider 启动策略与调用方显式上限应分开,保留配置的拒绝边界。initialized 不能被说成所有 ACP v1 provider 都必需的协议通知。 本 PR 应交付已有 ACP 创建/恢复的兼容修复和有界默认启动策略,同时保留显式调用方上限、协议错误与清理;不需要广泛前端或语言重写。
独立产品依据为 docs/guides/personal-workspace-trial-guide.md,冻结修订 323c3053128e41e16df27e6b6498f83c37e81f5e 的 4. 多 Agent:已注册 ACP stdio endpoint 保留现有只读与预览确认边界;也检查同修订的 Chat continuation/recovery 和现有 controller → adapter 参数来源。判定以实际新建/恢复/失败边界为准,不以 author 的已认证 Qoder 成功报告代替独立执行。
ACP v1 Initialization 规定先完成 initialize 协商,没有列出 initialized 必需通知;Extensibility 的自定义方法/通知使用 _ 前缀并建议协商。官方 Python SDK bdb9ac7054fb2df76a922b60b356c3c65f8a8a64 的 router 也没有该通用 route,unknown notification 记录异常而不中断连接。因此可以讨论特定 provider 的兼容需要,不能以 smoke 新断言证明它是所有 ACP 的协议义务;本轮没有据此虚构 standard provider 连接失败。
具体改动
精确 head 297019c16c3c66f88479ad4141338cc2dda66d64;全 PR 2 文件 +16/-3:生产 chat_acp.py +10/-3,现有 smoke +6。完整差异、初始化/请求/清理与 runtime/HTTP 调用方均已读。
ACPStdioAdapter.start在成功协议版本协商后、new/load/resume 前_notify("initialized", {}),无 request id。错误版本仍在通知和 Session 请求前拒绝;现有 recovery 能力分支、Session ID 一致性和权限拒绝不改。- 新常量
ACP_SESSION_STARTUP_TIMEOUT_FLOOR_SEC=45.0用于三个会话分支;initialize 仍用 caller 值,idle/hard Turn 超时及 graceful process close 仍是原 owner。smoke 的合成 provider 在 new 前检查通知,保护其特定顺序。 - [P1] 会话阶段覆盖调用方显式启动上限。 chat_acp.py:158 无条件
max(startup_timeout_sec, 45),所以显式短值与默认值无法区分。独立相同真实 stdio/HTTP 场景:服务和 adapter 明确设startup_timeout_sec=0.1,provider 的 session/new 在0.4秒才回应;冻结 base 拒绝并关闭子进程,当前 head 成功创建持久会话201。不是仅看到计时更长:原来被预算拒绝的业务效果现在被接受。initialize 超时仍按0.1秒拒绝,使同一个设置在不同启动阶段含义分裂;一般较慢 endpoint 最多占用新的45秒而无法按调用方短限快速失败。请将较大的默认/provider 策略与显式上限分开,保留显式短配置,说明影响 new/load/resume。回归要同时证明31秒默认需求可成功、显式短限拒绝无 Session/进程遗留,以及更长配置原样保留。 - [P2] 修正通用协议表述和兼容性证据。 body 目前把
initialized称作 ACP 必需。请明确是观察到的 provider 兼容行为,并对 standard/no-notification-requirement peer 保留测试;不要把 provider 行为复制进 fake 然后称协议 conformance,或凭 Agent 名 substring 判定。若需要额外能力选择,放在已有 provider/negotiation owner;这不是要求新建通用框架。
对主干的风险
独立匹配 base/head 10 场景真实 stdin/stdout 子进程:通知依赖 new/load/resume 从协议拒绝到成功并实际 prompt 回答;standard tolerant peer 均成功;错误版本、无 recovery 能力、恢复错误 Session ID、initialize timeout 仍拒绝且自有子进程关闭。31.1 秒 session 响应在默认30秒的基线拒绝、当前成功,证明 floor 的有用方向;显式0.1秒场景证明它同时更改已配置的拒绝边界。所有子进程 lifetime 检查是自己的合成 fixture,不执行用户 provider。
另用实际 serve_chat 注册 endpoint、POST /api/chat/sessions 和实际 ChatSessionStore 做匹配 HTTP 对照:通知需要的 endpoint 基线424/current201;短限的 endpoint 基线400/current201。API 返回真实 Session、保存真实记录,合成只在上游协议 peer;静态资源使用显式测试 override,仅资格化当前 backend/API,没有宣称当前 packaged UI或 installed App 更新。此 PR 没有 UI改动,源默认/权限消费者都沿现有入口。前轮 #6315 模型选择的变化不包含在本头,也不继承其 verdict。
当前 ACP smoke、Ruff、semantic advisory 及 native premerge 5 direct +3 selected 通过;没有 CI查询。首次私有 probe 的 chmod相对路径及不存在 close 方法造成 setup失败,修正为真实 close_session 后重新完整跑匹配矩阵,原失败留证,不算产品缺陷或已通过覆盖。作者真实 Qoder约32.25秒及 controller成功仍是作者报告;本轮不借用凭据运行真实 Qoder、不跑付费模型。
新增数字常量是 provider启动策略,不是新状态 vocabulary。默认变化应由共享 timeout/provider owner公开,而不能把 caller 明确值静默抬高。已有 ACP关闭与请求错误 owner、read_only capability、权限cancelled response 和未知endpoint拒绝保持;通知和 timeout 不授予 execute。相邻精简应让默认策略与已配置限额语义分离,无需扩大重构或新增权限开关。
我的整体评价
REQUEST_CHANGES。通知需要的 provider 和默认慢启动方向有实际价值,显式上限的接受/拒绝契约仍被改变。共享 ACP adapter 是已有 transport owner;默认或 provider 启动策略与调用方显式上限应分开,保留配置的拒绝边界。initialized 不能被说成所有 ACP v1 provider 都必需的协议通知。 本 PR 应交付已有 ACP 创建/恢复的兼容修复和有界默认启动策略,同时保留显式调用方上限、协议错误与清理;不需要广泛前端或语言重写。 最小修复是同一 adapter/caller 参数 owner 保留显式短限并分离默认策略,补同源正反例;不要仅提高更多超时来资格化稳定工作。协议表述修正为非阻断建议,不能冒称通用 v1义务;真实 Qoder后续采用继续保持证据边界。本轮不合并或升级运行环境。
English verdict: REQUEST_CHANGES - 297019c; max(requested startup timeout,45s) overrides explicit caller session-phase limits, turning the same bounded HTTP/stdio refusal into an accepted durable Session. Ten matched base/head cases qualify notification-dependent recovery and31.1s default startup, but the short-limit invariant fails. Required local checks pass; initialized is not a universal ACP v1 requirement.
Signed-off-by: sakurahello1 <201035361+sakurahello1@users.noreply.github.com>
Signed-off-by: sakurahello1 <201035361+sakurahello1@users.noreply.github.com>
|
Addressed the exact-head review on new head
Validation: 56 focused pytest cases, ACP adapter smoke, Ruff, maintainability ratchet, and public/private scan passed. Please re-review the updated head. |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · xhigh
动机
通过已注册 ACP Agent 开始或恢复普通 Chat 对话的用户,以及显式设置启动上限的调用方。 相同31.1秒会话响应在基线超时,新 head 返回会话并可回答;旧版在显式0.1秒上限下接受0.35秒响应,新 head 拒绝且不保存新会话。 默认首次使用和兼容恢复可以完成,调用方明确的短限重新成为拒绝边界;原界面不增加配置步骤。 本 PR 不授予执行或写入权限,不新增账户和后台调度,也不证明真实 Qoder、付费模型或长期稳定性。
这解决的是已有聊天入口的首次使用与恢复失败:用户不必为原本能在三十到四十五秒内启动的 Agent 反复重试;明确设置短等待的调用方仍能拒绝超过预算的会话。没有以测试数或账户可用标志代替真实请求结果。
改动思路
共享 ACP adapter 持有启动等待策略,既有 CLI/HTTP/controller 保留调用方意图与 Session 生命周期;Python 属于稳定 transport IO,不增加平行控制面 owner。 当前 PR 交付已有会话的通知兼容及默认/显式启动等待修复;不扩展到模型发现、账户认证或整个恢复体系。
先保留原调用方的“未配置”和“明确配置”区别,再由已有 adapter 选择阶段默认值。仅添加通知仍无法处理默认三十秒以上的首次启动;统一改成四十五秒又会覆盖调用方上限,旧版正是这样。当前方案不用 Agent 名称匹配或另一套配置 owner,亦无数据迁移。把默认策略与显式上限分离是本次相关、有界的精简;继续抽 helper 或引入 provider 框架没有当前必要性。
具体改动
精确 head 6bfdb64c7d70d508cef6fcc982cf047b3588a8c3,基线 323c3053128e41e16df27e6b6498f83c37e81f5e;完整七文件 +217/-16 均已读。另独立比较旧评审 head 297019c16c3c66f88479ad4141338cc2dda66d64 到当前的修复,而不是沿用原结论。
关键代码讲解
ACPStdioAdapter.start(loopx/chat_acp.py)用 None 选择 initialize 30 秒、new/load/resume 45 秒;明确配置值原样用于各阶段。协商版本通过后发送无 request id 的initialized,错误版本、错误恢复 Session ID 和请求超时仍沿已有清理分支拒绝。ChatRuntimeController.__init__/_start_adapter(loopx/chat_runtime.py)保留 Codex 的数值30秒,将原始 None 或明确值交给 Kiro/custom ACP;现有 SessionStore 仍在成功取得会话之后落盘。不是另建 actor、额度或权限 owner。register_chat_and_dashboard_commands(support_control_chat.py)不再把省略参数提前补为30秒,现有 help 说明 Codex30/ACP会话45的默认差异;handle_support_control_command(support_control.py)继续保留已有 CLI 显式值0.1秒下限并向serve_chat传递省略值。chat_server.py仅同步已有服务参数类型/默认值,前端代码没有改变。现有 ACP smoke 增加该兼容通知顺序,新增 startup timeout 测试覆盖显式 new/load/resume 拒绝、进程回收和失败不保存 Session。
独立接受依据为 docs/guides/personal-workspace-trial-guide.md,冻结修订 323c3053128e41e16df27e6b6498f83c37e81f5e 的 4. 多 Agent:PW-4-ACP 已注册 stdio endpoint 的真实 CLI/HTTP、打包页发送及重启恢复成立;PW-4-READ-ONLY 原客户端 fs/terminal=false、权限请求取消与预览确认边界保持。另逐项核验旧评审5492365612要求的显式上限、默认慢启动、较长配置、三种会话分支及清理,当前均有独立对照。
ACP Initialization要求先 initialize 协商;没有把 initialized 列为通用必需通知。Extensibility另有扩展命名规则。因此本次仅按观察到的 provider 兼容行为核验;作者已修正表述。无需通知的标准容忍 peer 仍通过,不能据此宣称所有 ACP 实现都已认证。
对主干的风险
最强反例仍是“默认修好了,显式预算却失效”。同一独立 peer/驱动在冻结基线、旧297及当前6bf各执行 16 场景:通知依赖的 new/load/resume 从基线拒绝到当前成功并回答;默认31.1秒响应从基线超时到当前成功;明确0.1秒对0.35秒响应,旧版三个分支均接受,当前三个分支均拒绝。0.7秒配置、标准容忍 peer、initialize 短限、错误版本和错误恢复 ID 的原行为保持,所有自有子进程均清理。这里测的是请求阶段接受/拒绝;关闭进程的已有宽限也占墙钟时间,不承诺整个函数在0.1秒内返回。
再用真正 loopx chat CLI、生产 serve_chat、controller 和 ChatSessionStore 做三版本默认/显式短限、兼容/标准 peer 的 12 项 HTTP 对照。当前默认201,短限400且零新 Session;旧版同短限却201。基线兼容 peer 的协议拒绝发生在较晚 timeout 之前,保留其424优先顺序,未把错误码归一化成“都是失败”。打包页面通过既有 Runtime 下拉和 Enter 发消息,再优雅重启独立服务,实际 session/load 后沿同一 local/upstream Session 完成第二个 Turn,旧消息仍可见。
源码检查为 56 项 startup/redaction/queue +346 项既有 adapter/CORS/startup-isolation,合计402通过、无跳过;ACP smoke、Ruff、diff语义 advisory→完整 vocabulary/registry census、maintainability 通过。精确基线的原生 premerge 5 direct +5 selected 及公共边界检查通过,无 failure/manual hold;CQR cqr_787bc1095d93fffd0994 精确七文件 pass,未由评审者修改产品代码。按配置没有查询或等待 CI。
私有 HTTP 驱动最初错误排列重叠拒绝优先级、重复创建已存在夹具目录,以及浏览器等待使用了过严的正文重复计数,均留有失败记录。修正观测/夹具后才资格化;浏览器已有请求已完成,没有重复发送以刷绿。作者旧 canary 的依赖/旧基线失败仍属于原报告,不冒充本轮通过或被抹除。
语义与 CI 对齐
新增数字默认与可选参数属于原 transport 的局部策略,不是新状态闭集、共享 actor 生命周期或权限契约。默认变化已在 body/help 说明,调用方上限是机器拒绝条件。所有共享消费者已按显式/省略和非 ACP 分支核验;这里没有新 default-off 能力,不能凭空宣称一个不存在的隔离开关。现有 Chat 指令、权限、quota/scheduler 都未改变。
我的整体评价
APPROVE。本次有界启动修复达成,不继承旧 verdict。用户体验方向为 improved:原入口可以得到有用回答,重启恢复保留同一会话,不新增手工配置步骤。长程方向为 accepted_tradeoff:减少已复现的默认误超时,保留明确上限与清理,但无响应 ACP 的默认会话阶段最多多等15秒;这不等于 Agent 运算更快。实际用户成功率、长期成本和稳定性没有测量,不从402测试或两次回答推算收益。
此次采用收到的评审经验只是把普通任务走到打包页面、真实后台和恢复读回;不会把恢复 RFC 的全部未来验收加给这个 transport 修复,更不宣称 memory 导致评审质量提升。真实 Qoder 的32.25秒成功仍是作者报告,本轮没有借账户、付费模型、原生 OS App 或 native Windows 资格。严格拒绝未知通知的其他 peer 也未独立认证。当前无需阻断修改;批准与旧 review closeout、合并及本机升级分别读回,批准不授予这些操作权限。
English verdict: APPROVE - 6bfdb64; the explicit startup limit regression is repaired while omitted ACP session startup remains bounded at45s. Independent16-case base/prior/head stdio and12 real CLI/HTTP comparisons preserve timeout refusals, cleanup and recovery;402 tests, built Chat conversation/restart and native premerge pass. Default failed-session waiting may increase15s; actual Qoder/model-account and long-run utility remain unqualified.
Goal and source
Fix a Qoder ACP session-creation timeout reproduced during first real use of the LoopX Chat custom-Agent path.
Gap
The observed Qoder ACP provider waits for an
initializedcompatibility notification beforesession/new. Its first authenticated session also took longer than the previous 30-second default.The earlier revision unconditionally raised every caller-provided session timeout to 45 seconds. That changed an explicit timeout from an upper bound into a lower bound.
Delivered behavior
initializednotification after ACP initialization and before session creation or recovery. This is not described as a universal ACP v1 requirement.--startup-timeout-secondsorstartup_timeout_sec, preserve that value as the upper bound for initialize,session/new,session/load, andsession/resume.Validation
uv run --extra test python -m pytest -q tests/test_chat_acp_startup_timeout.py tests/test_chat_path_redaction.py tests/test_chat_queue_preparation.py— 56 passed.uv run --extra test python examples/loopx-chat-acp-adapter-smoke.py— passed.examples/control_plane/control-plane-maintainability-ratchet-smoke.py— passed.session/new,session/load, andsession/resume, reap the peer process, and do not persist a Chat Session. Default and explicitly larger windows accept the same delayed peer.upstream/main; direct diff/compile and public-boundary checks passed. Three unrelated repository checks did not qualify this old PR baseline: missing npm dev dependencies and existing CLI-output baseline drift.The earlier real authenticated Qoder evidence remains: ACP session creation through
ACPStdioAdaptersucceeded in about 32.25 seconds, and the custom endpoint succeeded throughChatRuntimeController.open_session. No credentials, session content, local paths, or generated logs are included.Future-facing refactor
The existing shared ACP adapter remains the correct transport owner. The bounded companion change separates default policy from explicit caller authority without adding a provider-name heuristic or a parallel timeout owner.