feat(collaboration): add semantic peer collaboration and durable Chat returns - #4675
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…wner 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>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval): reviewed exact head 15dba56962506de4d2c22b2ea44c44d003ef118d, no blocking finding. Required CI was still running when I reviewed (named below); real managed multi-round runs and packaged-frontend live data remain author-reported. Merge remains the maintainer's decision.
动机
多消息交办此前只把"最后一句"递给接收方:context_handoff 只有 {goal_id, agent_id},于是纠正、被否掉的方案、约束和验收要求全部丢失;同时 worker 没有办法就一件事请求同 Goal 的 peer 帮忙并可靠地把结论拿回来。这个切片(capable-manager-semantic-handoff 的 R3/G1 输入)把语义 brief 固化下来,让同 Goal 的已注册 Agent 能互相求援并回传结论,并把 brief、读取状态、接收方判断和回传状态放回原始会话旁边。它不关闭 G1/M2–M4,也不声称自治调度、跨主机或外部受众转发。
改动思路
关键判断是"传输不等于工作准入",所以做法是把能力放进已有的 manager-context 所有者里,而不是新建一套协作权威:
- brief 是类型化契约,不是 prose。
control_plane/collaboration/semantic_request.ts定义collaboration_brief_v0:精确键集合、逐字段长度上限、整体 16000 字节上限、inputs[].ref必须是相对工作区路径(拒绝绝对路径、\、:、./..、控制字符)、sha256必须是 64 位小写十六进制、acceptance非空。Python 侧inbox.normalize_request通过 effect runtime 调这个 TS handler,没有在 Python 里再写一份规则。 - 复用既有存储而不是第二份。
_entry/_receipt/record_read/pending/needs_conclusion/_now从capabilities/manager_context搬到control_plane/collaboration/inbox.py,manager 侧改为 re-export;.local/manager-context地址与ENTRY_SCHEMA保持不变,旧记录和旧 import 都还能用。 - peer 交换有稳定身份。
peers.request要求发送方与接收方是同一活跃 Goal 的已注册 Agent、二者不同、operation_id通过正则校验;锁的是 operation 而不是收件人,所以同一个 operation 换收件人重试会冲突。返回值明确写死todo_created/priority_changed/execution_interrupted = false。 - 结果必须显式消费。
returns()会一直重新提供结论,直到 requester 调用consume_return;消费前必须先有投递记录,防止"没读就签收"。 - 可选工具面。
loopx.collaboration_mcp是身份绑定的 stdio 工具(五个),每次调用重新读注册(撤销即时生效),不暴露 shell、sender 或 root;只有主机显式配置 dsh cordis patch 才会加载。
具体改动
45 个文件、+3100/-284:14 个产品运行时、7 个前端、6 个公开文档、14 个测试/示例、1 个构建配置。产品增量集中在 peers.py(382)、inbox.py(258)、collaboration_mcp.py(119)、semantic_request.ts(84),另有 manager-context 的等价搬迁(净变化接近零)、一个 Chat 读回卡片,以及一个可运行的三 Agent 演示与测试。
关键符号(行号在本 head 核对):
semantic_request.ts:28normalizeCollaborationBrief:类型校验的唯一所有者。inbox.py:62/75/114/226normalize_request/pending/acknowledge/record_result:请求、判断、读取、回传记录的唯一所有者;冲突替换被拒绝,"先有判断才能回传"保留。peers.py:43request:operation 身份、同 Goal 注册校验、外部受众请求不得转发给 peer。peers.py:222consume_return:投递记录 + 身份不一致即拒绝。collaboration_mcp.py:26create_server:身份绑定 + 每次调用check_scope()。presentation.py:9project_collaboration:只在 manager 会话、且该 turn 带交办回执时附加读回;展示串走redact_local_paths,私有原文仍留在 owner 私有存储;出错就原样返回消息,不破坏会话。
我实际复跑、可依赖的部分
tests/test_peer_collaboration.py、tests/test_collaboration_mcp.py、tests/test_collaboration_demo.py、tests/test_manager_context_handoff.py→ 29 passed;tests/control_plane_ts/semantic_request.test.ts→semantic collaboration contract passed。- 我逐行比对了搬迁前后的
_entry/_receipt/record_read/pending/needs_conclusion实现,验证与加锁逻辑没有在搬家过程中被削弱;test_manager_context_handoff.py原样通过,是这次重构的 parity 锚点。 - 反向路径我核到的是真实拒绝:换收件人重试冲突、逃逸/绝对路径被拒、
priority/authority这类操作性键被拒、peer 路由不会进入外部受众投影、损坏回执不能消费、停止的 Goal 仍可读但请求被拒。
对主干的风险
CI 在我评审时还没跑完,请不要读成绿灯。 gh pr checks 4675 当时 build、macOS/Windows desktop、changes、dependency-review、Sign-off、dashboard-acceptance、node forward/minimum 兼容、postgresql-authority(真实 server)、windows-powershell、stage2c e2e2/installed 已 pass,kernel-static-checks、stage2c e2e1/mutants、test-shard 1-4 仍 pending,暂无失败。我把 repository_required_checks 记为 unverified 而不是 pass。
需要明说的边界:
- 真实 managed dsh/provider 的多轮交办、打包前端在真实数据下的展示都是作者报告;我的端到端证据是仓库内 demo + 29 个聚焦 Python 测试 + TS 契约测试。
- demo 的两个测试在我这里先失败,原因不是 PR:本机 venv 的 editable 安装把
loopx指向主 checkout,而 demo 会在真实 git worktree 里再起子进程;把被审 worktree 放到PYTHONPATH后两个测试都 pass。谁在别的 worktree 里复跑要注意这一点。 - 本 PR 引入的 stdio 工具是默认关闭的(产品代码里除了 demo/测试没有引用),移除 worker cordis patch 重启即可禁用;manager prompt 版本 11→12 会让已有会话拿到新指令,但只带收件人的旧请求仍然合法。
一处非阻塞观察(P3)
apps/presentation/dashboard/src/features/personal-workspace/channel-timeline.tsx:81 的 <ReturnDeliveryStatus .../> 被留成 14 空格缩进,而相邻行是 10 空格——该 app 没有 formatter/lint 兜底,这类缩进漂移会一直留在代码里。建议顺手改掉,或把这个 app 纳入格式化检查。
我的整体评价
形状是对的:把"协作"当成既有 manager-context 所有者的一次扩展,而不是新造权威——规则留在 TS,Python 只做桥接;存储只保留一份地址,manager 侧退化为 re-export;peer 请求在类型层面就写明不产生 Todo、不改优先级、不打断执行;结果必须显式消费;外部受众投影显式排除 peer 路由。这种"删掉重复定义、把新能力接到既有 owner"的做法正是仓库规则要的方向。
我给出的是契约与传输这一半的批准结论:CI 跑绿之后即可进入合并判断。这条评论不构成合并许可。
English verdict: APPROVE — at 15dba56962506de4d2c22b2ea44c44d003ef118d a typed collaboration_brief_v0 plus a shared same-Goal peer request/return/consume owner is added by relocating the existing manager-context records into one owner (verified line-by-line for parity) instead of adding a second authority; 29 focused Python tests and the TS contract test pass locally, covering retarget conflicts, escaping inputs, operational-key rejection, corrupt-receipt consumption and peer routes never entering the external audience. Residual: required CI (kernel-static-checks, stage2c e2e1/mutants, test-shard 1-4) was still running, real managed/provider journeys and packaged-frontend live data are author-reported, and one P3 indentation slip in channel-timeline.tsx:81 is worth a follow-up.
|
CI readback for My review recorded required CI as unverified because it was still running. It has since completed: 25 required checks SUCCESS, 5 skipped, 0 failures, and the only non-pass entry is Re-qualified for that unchanged head: |
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
本条完成已经启动的全量审查,并补齐同 head 先前评审明确保留的两项证据:最终必需 CI 与本任务实际运行的 managed 协作/前端读回。先前评审的 P3 缩进建议已核对,为不影响渲染的格式建议,保留给后续触碰该行时处理;没有新增阻塞项。
Reviewed exact head: 15dba56962506de4d2c22b2ea44c44d003ef118d against 43a733fb92af170d36e6e47a0cc83d2dee20578a.
动机
按 #4574 R3 和 #4339 的语义交接合同审查:目标是让 managed Agent 实际接住带修订的工作、请求同伴帮助/复核、使用产物并回到原对话报告。原路径只有最新用户句子的转交和已有 owner 回传,没有这一套 Inbox 下的 peer 请求及明确消费。这里交付了完整的本地请求—产物—复核—回传闭环,是有依据的阶段增量;不把控制器驱动的 demo 算成完整 G1、跨日监督或跨主机协作。
真实复现中,builder 使用 analyst 的建模产物并接受 reviewer 的独立复核;增加预留库存和东区下限后重新求解、重新复核,最终向两个原始请求分别返回结论。独立穷举的固定预期从价值/成本 84/1000 变为 83/990,持久化的分配向量完全匹配。重复 drain 没有重复投递。最后还检查并处理了被拒绝但漏回报的旧请求,三个 Agent 均无待处理请求或未消费结果。
改动思路
最有力的反对意见是:这可能只是扩大 manager、复制调度权,或用一个控制器脚本冒充自主协作。代码和证据没有这样做:公共语义、Inbox 与 peer 关系位于 control_plane/collaboration,管家保留意图入口和 Chat/Lark 受众适配;stdio host adapter 位于根模块。创建/接入仍复用 Agent registry/onboarding,发现复用 directory,运行仍通过原 Turn/Todo/lease owner。任何注册 Agent 都能请求同伴并继续协调,结果返回直接请求者,父请求只传递上下文,不授予层级权限。
比较了原 manager-context 的存储、读取、decision、result 和 return pump 及其未修改调用方:通用函数实际移动至一个 owner,旧导入和存储地址为真实兼容保留;Chat/Lark 的权限及发送重试继续由原适配器负责。只补提示词无法解决真实 workspace-write 沙箱禁止共享 Inbox 写入的问题,也无法完成 peer 结果消费;新建团队调度器则超出这个已验证调用链。五个身份绑定 MCP 工具是这条真实路径所需的最小桥接,不提供 shell、任务写入或自动启动 worker。
新增 brief/parent 是显式语义意图,消费回执是不可从“已读”推导的事实;输入可用性和前端卡片由文件与既有回执计算,不另建工作状态。分页最多展示 20 条且声明 has_more;另外用真实 CLI 验证 25 条结果的稳定重读、消费后剩余 5 条可达和其他身份隔离。
具体改动
整份 diff 包含共享协作模块、manager/CLI/Chat 适配、原对话卡片及轮询关联、打包资源、真实 demo、独立 oracle、回归测试和中英文 RFC 检查点。截图是合成浏览器数据;真实模型输出和运行配置未提交。已有打包资源保留一代兼容。
关键代码讲解
normalizeCollaborationBrief:一套 TS 输入合同约束字段、16 KB 上限、相对文件引用与摘要;拒绝混入执行/优先级字段,legacy recipient-only 请求继续可用。request:同 Goal 注册身份、稳定 operation id、直接请求者和 parent 关系。按 operation 加锁,同 id 换内容/收件人会冲突;外部受众 parent 不进入本地 peer 转发。returns/consume_return:核对 route/entry/reply 身份,结论在明确消费前持续出现;未读、错身份或损坏回执不能完成消费。它们不改变 Todo 完成状态。create_server:可信 host 固定 Goal/Agent/workspace;模型参数不能改 sender/root,每次调用重新检查注册资格。peer 回传直接用共享 owner,原对话回传用 manager transport。project_collaboration:按原 session/client turn 提供交办、判断与回传事实;CollaborationCard在现有完整对话与紧凑对话中显示。新流式回答通过 turn id 补上消息映射,状态轮询无需刷新或新模型调用。
对主干的风险
最关键风险是旧版本批准被当成新验收,或错误身份的结论被路由到其他受众。最终测试覆盖不可变重试、错收件人、撤销身份、损坏结果/消费记录、旧摘要、工作树边界、特殊文件以及外部受众隔离。故意把结果 source_id 改错后,真实 CLI/return-pump 旅程失败;原始 final head 的同一旅程通过。没有靠“双方都返回成功”证明兼容。
旧行为的 63 项相同回归在 base/head 通过;最终组合套件 83 项通过。TS 合同和类型检查、Ruff、配置范围内 mypy、前端构建、wheel 内容核对和 packaged chat-recovery 通过。浏览器验证包含新流式回答、一次展开、接收方状态更新、390px 视口及原对话回传;真实独立 runtime 另有原对话读回。standard canary 的 19 项选择检查和 5 项直接检查全通过,无失败/跳过/manual hold,最终 diff 的严格质量回执 cqr_efed5f999fb0429d8d1e 有效:45 个文件,fingerprint efed5f999fb0429d8d1ea8a6250969f3b024a1148541c7b4c7354923240cfcbd;safe-fix 允许,本次最终审查未应用修补(0 次),blocker/warning/advisory 均为 0。
真实模型验证也揭示了边界:第一版 solver 和首次 reviewer 都漏了可选字段默认值,独立 oracle 才发现;修复后重新审阅当前需求/代码/输入/输出版本。失败的 native Turn 没有被改成成功。最终读回还发现旧拒绝请求未回传;真实 worker 补回并消费,保留了额外本地验证器路径错误的失败记录。系统负责持久暴露义务,当前控制器仍负责安排后续阶段,不能宣称已经有自主监督器。最终结论同时保留单位成本等示例解释范围。
语义与 CI 对齐
复用既有 request/assessment/result 含义,新增有界语义 brief;通用 Core 没有混入分配器业务词、模糊子串分类或另一个 work/lease 真相。manager 提示词从 recipient-only 改为保留语义 brief,并刷新 context version 12,这个默认变化已经在文档和 PR 明示。仅 stdio worker adapter 是显式 opt-in:不加载 Cordis patch 就没有这些工具;模块安装、目录可见或注册身份都不等于启动 worker。移除 patch 并重启即可停用,记录保留。机器强制的身份/幂等/输入/消费限制与 Agent 自主判断的边界明确。
必需 CI 已全部通过:merge-gate 为 SUCCESS,完整 pytest、kernel/dashboard、Node 最低版本、Stage 2C、Windows、PostgreSQL 实例以及平台构建均已通过。PR 条件下发布/部署任务按既有规则跳过;SonarCloud 在其工作流中明确 continue-on-error: true,当前仍运行,未把它记为已通过。
我的整体评价
支持合入这个有界的 R3 交付。它把上下文、同伴协作、真实产物验收和原对话体验连在一起,且共享 owner 对管家、worker 和嵌套协调者一视同仁。代码量中包含必要的旧存储迁移、验证/demo 和打包资源;已应用的相关简化是抽出通用持久化并把 host transport 留在外层,无需再引入工厂或工作流框架。
保留风险是模型仍可能漏测或漏回报,因此独立验收和收尾读回必须继续保留。未声称 live Lark peer、跨主机、lease 接管、24 小时或大规模资格。此批准仅针对上述 exact head 的完整 diff;运行时/产品变化按仓库规则由维护者合并。
English verdict: APPROVE - HEAD 15dba56962506de4d2c22b2ea44c44d003ef118d. Cohesive same-Goal semantic peer exchange with Agent-neutral ownership, scoped stdio access and original-conversation readback. Real managed dsh artifact/review/correction/return chain and independent oracle passed; stale rejection was explicitly returned and consumed. Legacy parity, exact-head tests, packaging/browser checks, standard canary and required CI are qualified (the explicitly non-blocking SonarCloud analysis remains pending); autonomous scheduling, cross-host/lease takeover and scale remain out of scope.
|
Correction to my readback above (queue delta, not a new finding).
|
Goal And Delivered Outcome
Related to #4574 (R3 / G1 inputs) and #4339; base:
main.A multi-message delegation previously delivered only the latest owner sentence, and a worker could not use this Inbox to request peer help and durably consume the answer. This change preserves a semantic brief, lets any registered same-Goal Agent coordinate peers, and returns their conclusions to the original conversation.
The existing conversation now shows the delegation, receiver decision and return status beside the original message. The shared collaboration owner supports worker → coordinator → specialist exchanges without a manager hop or fixed hierarchy level.
Scope And Continuation
control_plane/collaborationowns the typed brief and shared Inbox/peer exchange. Requests preserve corrections, constraints, relative artifact versions, acceptance and return requirements. Stable operation ids reject changed-content/retarget retries; results remain available until requester consumption.loopx.collaboration_mcpexposes five explicitly configured, identity-bound stdio tools to sandboxed workers. Registration is checked on every call. Creation/onboarding, directory, runtime binding, Turn/Todo/lease admission and scheduling retain their existing owners.manager-contextremains the Chat/Lark ingress and original-audience return adapter. Existing record addresses and Python imports are preserved. Its manager prompt now asks for a semantic brief; recipient-only legacy requests remain valid. No new machine setting, navigation item or Kanban layout is introduced.Complete within the bounded same-host, same-Goal exchange slice. The controller still selects demo phases and transfers explicit Git artifacts. Autonomous supervision, general amendment/cancellation, cross-host authority, external-audience peer forwarding, 24-hour continuity and hundred-Agent qualification remain with the existing #4574 / #4339 owners; this PR does not close G1 or M2–M4. Keeping transport separate from work admission makes this boundary independently reviewable and reversible.
Future-facing pass applied: extracted shared persistence from manager adapters, kept host routing outside the shared owner, reused one TypeScript validator, and retained only real compatibility imports. No new Agent factory or scheduler.
Validation
15dba56962506de4d2c22b2ea44c44d003ef118d; older unchanged-surface checks are identified below.npm run typecheck:control-plane, selected-path Ruff. Configured mypy passed on 22 modules; it does not claim full typing of dynamic adapters.turn run-once --host dshworkers, SDK 0.1.5rc1 / deepseek-v4-flash, use actual versioned files and peer results. Original full run completed two review cycles and two owner returns; current public-demo reproduction completed both rounds and the native final builder Turn.chat-recoveryon unchanged final frontend bytes: fresh streamed card, live receiver state without another model turn, original-conversation returns and 390px layout. Original full live run also read back through the packaged frontend.canary premerge --from-git-diff: 19 selected checks and 5 direct checks passed, no failures/skips/manual holds. Exact quality receiptcqr_efed5f999fb0429d8d1eis valid for this diff.Failures found and repaired are preserved: workspace-write correctly rejected direct shared-runtime CLI writes, motivating the scoped MCP adapter; the first public-demo solver missed optional defaults and its first peer review missed that defect, which the independent oracle caught. The demo contract now states those defaults. Review-request qualification now matches current requirements/code/input/output digests while preserving stale requests. Failed native Turns remain failed; a later artifact check never rewrites their receipts. Final inspection also found an assessed-but-unreturned stale rejection; its durable obligation remained visible and was explicitly returned/consumed through real worker sessions. All three demo Inboxes now have zero pending requests and zero unconsumed peer results. The ad hoc closeout validator initially resolved its root from the wrong working directory; its failed native receipt is retained, the independent readback was corrected, and the final requester Turn committed. Returned conclusions preserve residual scenario assumptions instead of claiming unrestricted optimizer correctness.
Coverage follows both caller paths and the real sandbox boundary. No live Lark sends, PostgreSQL provider promotion, cross-host execution, lease takeover or scale qualification is claimed. Remove the optional worker Cordis patch and restart to disable stdio tools; existing Inbox records remain. Runtime behavior changes are for maintainer merge after review.
Frontend / Visual Evidence
Type / Area / Direction
Boundary Checklist
Exact-head review and full final evidence: published review. Maintainer merge remains required.