feat(chat): share live activity, interruption and turn steering - #4999
Conversation
Signed-off-by: Green hats <183933879+Green-hats@users.noreply.github.com>
Signed-off-by: Green hats <183933879+Green-hats@users.noreply.github.com>
Signed-off-by: luw2007 <luw2007@gmail.com>
Signed-off-by: luw2007 <luw2007@gmail.com>
`LIVE_SURFACE_PREFIXES` guarded `.github/workflows/` alone, so the files GitHub renders at a visitor or a reporter escaped the canonical-repository check entirely: the private-vulnerability entry in `SECURITY.md`, the four contact links in `ISSUE_TEMPLATE/config.yml` that GitHub prints on its own new-issue page, `SUPPORT.md`'s routing table, the PR template's guidance pointer, and the ruleset link `GOVERNANCE.md` itself calls live. Seventeen addresses named the pre-transfer owner, and they kept resolving only because the transfer left a redirect behind -- which is a courtesy, not an ownership fact. Point each of those at `loopx-project/loopx`. Governance's record of the initial public commit and of the issue that settled a roster entry keeps the address those events happened under, reviewed per path and use like the existing pull citations; the ruleset link does not, because the sentence around it calls it live. Only the widened prefix decides this, not a new rule: every classified use is an offender until a path-and-use exception reviews it, so the two citations had to be judged rather than inherited. The smoke now pins both directions -- the new-issue contact file is a live surface, and a dated commit citation under it stays tolerated. `LIVE_ADDRESS_USES` is removed: nothing referenced it, while its comment described a live-versus-citation split the implementation never applied, which is the easiest thing in this file to "fix" by editing a constant that does nothing. Signed-off-by: Yue Dai <54579099+yuedai-pbc@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…t owns the Turn A Turn whose receipt is bound to an autonomous replan obligation cannot hand its settlement to another Todo. The refusal reported that case as a plain selection conflict, calling the retained pending selection "the projection's current selection", and published neither the retained selection nor the obligation that owns the Turn, so a caller could not branch on either without parsing prose. The conflict now states that the requested Todo cannot replace the retained pending selection, names the autonomous replan obligation that owns the Turn, and publishes `retained_selection`, `retained_selection_todo_id` and `receipt_replan_obligation_id` in the failure payload. The recommended action points at settling that obligation instead of rebinding the retained selection. This is the last branch of the explicit-selection preflight that still carried no typed retention facts; the eligibility predicates are unchanged. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…facts-0924 fix(quota): name the retained selection and the replan obligation that owns the Turn
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Four atomic writers opened parent directories after os.replace, so Windows reported failure after persisting the file. Guard directory fsync by os.name and add a cross-platform Windows emulation test to the native Windows job. Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
…ce-20260924 feat(team): trace a correction through exact versioned work
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
The previous head still left active callers on a bare interpreter, so the original failure mode stayed reachable even with a compatible worktree environment present, and the static guard only recognized literal `python3`. Route the remaining callers through resolveTestPython(): the repository identity oracle in monitor_successor, the legacy fingerprint oracle in quota_monitor_poll_commit, and the tab-upgrade chat server smoke that arrived on main while this branch was open. Widen the guard to reject bare `python` and `python3` launches, fallbacks and assigned defaults, and add negative assertions so resolved paths such as `/usr/bin/python3` and validation argv data stay allowed. Validated with the full control-plane suite (3009 passed, 0 failed, 28 skipped), the guard and typecheck, and a restricted-PATH rerun where a bare `python` mutation fails monitor_successor while the selector passes both affected files. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: Jim-jimu <49069997+bmh201708@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…eter-discovery test: discover compatible Python for Node-driven smokes
…reshold Signed-off-by: Jim-jimu <49069997+bmh201708@users.noreply.github.com>
…-gate fix(chat): restore workspace choices for gated goals
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
release: prepare LoopX v1.2.0 package version
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
chore: repair v1.2.0 release hygiene gates
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…tion-command fix(turn): preserve complete signed host actions
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review). Reviewed exact head 47941d5b61588b0b31d85b7e1dba168811bfe945.
动机
共享管家/Goal 对话过去只显示笼统等待,用户看不到执行阶段,也无法在同一轮中断或追加指令。此 PR 让既有 Chat Session/Turn 的活动、控制动作和回执出现在同一时间线;对持续工作可见性有正向价值。但“临时失败后重试”目前会被持久失败回执卡住,因此可恢复的对话控制尚未交付完整。
改动思路
前端从 agent.phase 取最近活动,把中断/调整绑定到消息的 sourceTurnId;新的 /turns/{turn_id}/steer HTTP 路由复用现有 Chat runtime,以 client_ingress_id 为幂等键并校验预期轮次。正常路径中,匹配的执行器回执才显示“已接收”,原输出流继续,不创建第二轮。这避免另建队列。但失败路径必须区分“送达状态未知,重放同一编号”与“明确拒绝,允许安全地重新尝试”;当前前端把两者都保留成同一个编号。
具体改动
关键代码讲解
channel-timeline.tsx:31-43的MessageActivity.steer以草稿文字生成编号;任何异常都保留request.current,只有改文字或成功才换号。这里决定失败后的用户恢复能力。chat_runtime.py:904-1019的steer_active_turn持久化 ingress,核对会话、轮次与执行器;明确拒绝时将编号记为failed,以后同号只能返回live_steering_delivery_unresolved。chat_server.py:818-853暴露轮次级接口及身份回执;dashboard-page.tsx把匹配回执后的调整投影回会话,并仅中断当前轮次。活动、移动端表单、文档、合成截图和浏览器 smoke 覆盖了主路径。
对主干的风险
[P1] 明确拒绝后,原文重试被永久卡住。 我用 PR 自带的合成 Codex/HTTP fixture 启动活动轮次,暂时移走 adapter 后提交同一编号得到 409 live_steering_session_not_attached;恢复 adapter 后按 UI 的相同草稿/编号重试仍为 409 live_steering_delivery_unresolved,只有换新编号才得到 200 delivered。前端失败后既不更新编号,也没有“重新发起”动作,用户只能无提示地改写文字或刷新并丢失草稿。请用类型化结果区分确定失败与未知送达:未知状态沿用原号,已持久确认拒绝后可显式换号重试;增加“拒绝→执行器恢复→原文重试成功且仅送达一次”的 HTTP+浏览器回归。
独立验证:tests/test_chat_turn_steering.py 10/10、Dashboard npm run build、npm run smoke:personal-workspace 的 12 个浏览器场景均通过;上述恢复反例仍失败。当前 head 与最新 main 的浏览器 smoke 和 registry I/O manifest 还存在合并冲突,修复后需在新 exact head 重跑。此轮未以远端 CI 状态代替本地证据。
我的整体评价
正常路径是有价值且边界基本正确的增量:复用现有会话与 ingress,不需要第二个 authority;长期持续工作可见性改善。但用户体验在可恢复失败上退化成无提示死路,当前 head 也不能干净集成主干,故请求修改。最小修复是类型化处理明确失败与未知送达、补上述反例、解决冲突,再复核完整 PR 的正反路径。相关状态可做有界收敛,不应为此增设新队列。
English verdict: REQUEST_CHANGES - At exact head 47941d5, a confirmed failed steering ingress cannot be retried with unchanged draft after adapter recovery (409 → 409; fresh id → 200). Ten Python tests, dashboard build and 12 browser scenarios passed; add typed retry recovery coverage and resolve current-main conflicts.
…rator-provider fix(release): stabilize qualification on configured hosts
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ard-memory-preview fix(release): make v1.2.0 qualification host-independent
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…lay-proof fix(quota): replay unleased monitor poll receipts
Keep the v1.2.0 default-model release gate evidence-linked: close onboarding command IDs, scope the required-vision wait, and reject missing durable vision receipts with correctable feedback. Validated on the reviewed head: 65 focused tests, 18 premerge canaries, and 21 live scenarios plus 6 contrasts with no failures or skips. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Use the production-shaped compact quota packet for the release-only external-wait fallback decision probe. Keep the independent work, notification, and no-premature-close oracle, with focused negative tests and release documentation. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Repair installed-wheel deep doctor so it selects the invoked console script and identifies the wheel through an owned module in the distribution RECORD. Preserve source-checkout diagnostics and add a focused regression. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…diagnostics Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…eout-budget fix(release): bound vision closeout and runtime responses under load
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval). Reviewed exact head 19180e1f433f98dc9cc7641fd02f944fbce5d0c2 against main at 5a4617e6b96288eb2cbfbfe9ee97417c6c38f695. The previous exact-head P1 retry blocker is resolved. This is a reviewable increment; the wider conversation program remains open.
动机
管家、Goal 和直接 Agent 对话原先把真实执行压成笼统等待,用户无法从回答处看到当前活动、只中断指定回合或在原回合补充指令。按 Presentation RFC §8.8 与 Manager RFC A22–A23,本 PR 交付共享会话控件及可信的送达反馈。用户可以看到最近执行阶段;中断成功后保留部分输出并在原会话续聊。该增量改善长程任务中的纠偏与恢复,但尚未完成 Lark 实时展示、自适应答案和上下文亲和路由。
改动思路
前端仍从现有 Chat Session/Turn 和 agent.phase 事件取状态,不引入第二条执行队列。ChannelTimeline 为运行中的回答呈现当前阶段、折叠的最近六条活动,以及绑定 sourceTurnId 的中断和调整;既有运行、等待、提案的呈现规则继续独立。调整走原生 Codex Turn 的 /steer 路由:服务端先持久化 ingress 身份与预期 Turn,核对绑定和能力,再把指令送给同一执行器。匹配的回执只表示执行器接收,不表示任务完成。明确在送达前拒绝与送达状态未知分开处理:前者恢复后用新编号重试原文,后者保留旧编号避免重复。旧 Lark/LoopX-mode 调用不提供预期 Turn,保留原有请求形态。
具体改动
关键代码讲解
loopx/chat_ingress.py::ChatIngressStore.create_ingress_receipt(约第 11 行)把expected_turn_id纳入新 HTTP ingress 的持久请求身份;同号换 Turn 或换正文不能伪装成重放,旧无该字段的调用保持兼容。loopx/chat_runtime.py::ChatRuntimeController.steer_active_turn(约第 915 行)验证活动 Turn、attached 能力、适配器和上游 Turn;STEERING_NOT_DELIVERED_CODES(第 62 行)只覆盖调用 provider 之前的确定失败。已送达的同号重放返回原 Turn,未知送达继续拒绝盲目重投。loopx/chat_server.py::ChatRequestHandler._steer_turn(约第 824 行)校验请求、绑定 URL 内的 Turn,并返回not_delivered或unresolved的类型化错误;成功回执带 Session、Turn 与 ingress 身份。apps/presentation/dashboard/src/features/personal-workspace/channel-timeline.tsx::MessageActivity(约第 16 行)把运行阶段、调整草稿、回执与中断错误放在同一回答下;确认未送达时换新编号,未知状态沿用原编号。dashboard-page.tsx把控件接到管家与 Goal 对话,完成竞态不覆盖最终答案,成功中断保留部分输出。
另外更新了共享模型、样式、API 客户端和双语使用指南;七张合成截图提供桌面、移动与失败状态的审阅证据。浏览器场景和 Python HTTP/运行时回归覆盖主要正反路径,生成的 registry I/O manifest 只同步新行号,没有改登记规则。变更始终由现有 Session/Turn/ingress 所有者负责,未复制状态机到前端或新增守护进程。
对主干的风险
上次评审的 P1 反例是:适配器临时不可用时同号得到 409,适配器恢复后同文同号仍得到 409,页面没有安全恢复路径。相同的 Chat HTTP/文件存储脚本在基线 5a4617e6b 上读到新路由 404,在上次评审的 47941d5b6 上读到 409→live_steering_delivery_unresolved→新编号 200,在当前 head 上读到类型化 409→同号稳定 409→新编号 200 且只留一条指令;浏览器回归证明草稿保留、未知失败同号重试、确定失败换号重试。关闭中的 Turn、错 Turn、重复编号换正文、回执身份不匹配及中断与完成竞态都有负例。合入主干后 14 个集成浏览器场景,以及最终 head 的 67 个聚焦 Python 测试和开发与打包 Chat 场景、Dashboard 构建、9 个登记架构测试、Ruff、change-quality 回执和 16/16 premerge 检查通过;为验证共享运行时未破坏旧调用,我还在相同 fixture 上对 main 与 head 分别运行 LoopX-mode/Lark 的 111 个测试,均为 111/111。
仍有明确边界:草稿和未确认 ingress 编号只在当前页面内保存,刷新前需要用户自行保留;本 head 未做真实 Lark 端到端验收,也未在最终 head 上重跑付费真实模型(原行为 head 的真实 Sol 运行已通过)。本次审查按 Goal 配置只要求本地证据,远端 CI 仍在运行,不能把 pending 说成通过。上述边界已在 PR 正文和指南披露,并留在现有产品 Todo 中,不扩大本 PR 的权限或合并范围。没有发现阻塞当前限定增量的回归。
我的整体评价
APPROVE(限本 PR 的共享对话控件增量)。长期续接方面,同一 Session/Turn 的中断、重放与明确拒绝后恢复比旧行为更可靠;用户体验方面,活动、草稿、错误和接收回执在同一回答处可读,失败不自动生成另一任务。代码量与现有 Chat/API/Timeline 所有权相称;预期 Turn 是请求者的真实意图,不是第二份进度权威。下一步仍要完成真实前端/Lark 读回、刷新后续接、自适应可审阅答案和上下文亲和返回,不能用此 PR 代替整条用户旅程的验收。运行时与产品表面按仓库规则交给维护者合并,不自行 bypass。
English verdict: APPROVE - Exact head 19180e1f433f98dc9cc7641fd02f944fbce5d0c2 resolves the confirmed-rejection retry blocker and integrates cleanly with current main. Final-head focused HTTP/browser/build/premerge checks pass; shared LoopX-mode/Lark fixtures pass 111/111 on both base and head. Live Lark adoption and final-head paid-provider exercise remain outside this bounded increment; maintainer merge and remote CI remain pending.
|
Merge-readiness follow-up for exact head I compared this head with current Next: update the PR branch onto current main, rerun the focused runtime/browser/build/premerge validation on the new head, publish a review conclusion for that exact head, and rerun merge-readiness immediately before merge. This PR changes |
Problem and result
A running steward or Goal conversation previously collapsed real executor activity into a generic waiting label. The shared timeline now shows the latest reported phase, an expandable six-entry history, and controls to interrupt or adjust the exact active Turn. Successful interruption preserves partial output and the conversation; a completion race preserves the completed answer.
Native Codex steering binds the expected Turn and durable ingress id. A matching executor receipt is required before the UI says the adjustment was received. A confirmed pre-delivery rejection now reports
delivery_state: not_delivered, so the unchanged draft can safely use a new ingress id after recovery. An uncertain delivery retains its original id, preventing a blind duplicate. This resolves the prior exact-head review's “409 → 409 after recovery” blocker.Scope and remaining acceptance
The existing Chat Session/Turn, ingress receipt and frontend timeline own the behavior; no second queue or event store was added. Steward, Goal and directly selected Agent conversations share the controls. The HTTP endpoint rejects stale Turn identities, unsupported adapters and closing Turns. The frontend keeps a rejected or uncertain draft visible and does not silently submit a new Turn.
The wider reusable conversation program remains open: adaptive reviewable answers, context-affine delegation and live Lark presentation are separate acceptance gaps. This PR does not claim a live-provider browser or Lark end-to-end pass. The earlier disposable real Codex
gpt-6-solsteering/interruption check was on the original behavior head; the current head is qualified with the real Chat HTTP entrypoint and synthetic executor/browser fixtures.Validation
Tested final head:
19180e1f433f98dc9cc7641fd02f944fbce5d0c2, integrated withmainat5a4617e6b96288eb2cbfbfe9ee97417c6c38f695. No live Goal was mutated.cqr_54253738c33dc8f899f2; 16/16 selected premerge checks, zero failures or manual holds.Frontend evidence
Synthetic fixture screenshots: before · running desktop · mobile · interrupted · steering draft.
Attention review: one current phase and two scoped controls appear under the active reply. Activity history is collapsed by default, adjustment opens on demand, and failures stay beside the action. The opening viewport and primary navigation are unchanged.
Change type and boundaries
Changed surfaces: Chat runtime/API, shared dashboard conversation UI, public guide and browser fixture. The result is a reviewable A22–A23 increment, not closure of the cross-channel conversation Todo. All commits have DCO sign-off; public/private boundary scan is clean. Future-facing pass: retained the existing ingress/Turn owner and added only the typed refusal distinction needed for safe retry. This runtime/product PR is left for maintainer review and merge.