Repository navigation
feat(chat): discover existing private bound Sessions - #6822
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@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=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
已经在私聊中工作、随后从 Web 入口继续的用户,需要找到那一段既有会话,避免仅因更换入口而新开一段会话并丢失上下文。
原先会话列表不能按原私聊绑定发现已存在会话,客户端可能只能新建;现在带精确绑定的查询返回原来的 Session 身份,关闭历史仍可读,失效、群聊或冲突来源明确拒绝,不退回无筛选列表。
真实 HTTP 的项目/管家路径及 File、SQLite 均返回原会话且没有启动工作;独立 wheel 安装的 52 项验证由生产源码逐字节一致确认仍适用,当前提交完整六模块 146 项通过。历史失败保留,并不据此宣称前端或真实 provider 旅程完成。
这是既有会话发现 API 的前置能力;不新增执行授权,不完成 Web 选择/接续界面,也不宣称真实 Lark 协作、原线程结果返回或整项产品验收已经完成。
剩余产品缺口是既有前端的发现与选择旅程,以及在真实 provider 下接续原线程和返回结果;这些仍由现有原会话接续工作项及其拥有者承担。
改动思路
把读取到的原生会话交给既有 TypeScript 绑定决策,再在发布锁内重读当前绑定与项目;Python 只做外部观察和 HTTP 传输,避免第二份绑定规则或持锁等待 provider。
当前切片是可独立验证的原会话发现 API,不创建或恢复 Session,也不入队;后续写入仍须经过原有绑定和队列入口的当次授权。
普通列表与精确发现必须可区分:无 selector 时走旧列表,显式查询时只接受一个非空绑定参数,并在结果中回显它。这样独立升级的客户端可以发现“旧服务虽然返回 200,却忽略筛选”的情况。关闭的原会话作为历史保留,并不变成可以派发新工作的当前目标。已知绑定由现有 owner 提供,没有让用户复制上下文或额外确认的理由;后续界面仍需由既有工作项交付。
具体改动
完整九路径 +298/-12:会话 GET、绑定观察器、TypeScript 原决策复用和 RPC 注册、HTTP/TS 边界测试,以及成对 App RFC。不可变基线的 App conversation/async inbox RFC 中original-thread(原线程)、authority(授权)、readback(历史读回)与 staged-journey(分阶段验收)分别映射,原上下文和 fresh admission 仍是判断依据;当前 RFC 新增 API 前置阶段没有替代前端、真实 provider、接收采用和原线程结果返回的验收。没有 UI 变更或新的视觉证据要求,也没有据此宣称整条用户旅程完成。
关键代码讲解
_get_sessions区分无筛选与显式绑定发现;空值、重复或混合条件 400,绑定失败 409,成功回显绑定,不退回普通列表。local_sessions把 provider 观察和 Session inventory 放在发布锁之外,在锁内重新读取绑定与项目,再交给原 typed owner;撤销不会被慢 IO 阻塞,重复观察也不会先被字典去重掩盖。listLocalBoundSessions复用resolveBoundConversation和抽出的原项目规则,核对私聊、Goal/项目、channel、executor、context/source;历史关闭与当前目标分开,没有另一份 Python eligibility 判断。
对主干的风险
独立当前原生 HTTP 52 项、既有绑定 Python 32 项、TypeScript 40 项全部通过,覆盖 File/SQLite、项目/管家、原 Session、不启动工作、普通列表、关闭历史、群聊、撤销、冲突、重复观察、发布锁外 IO、原写入/FIFO/重放。实际不可变基线在同一四个项目/管家×store 正例上全部触发独立 marker 断言失败:旧接口忽略查询且不回显绑定。当前 source 与正常构建的非 editable wheel 均通过同一 52 项;使用 python -I,四个生产模块与精确 head 字节相同,source overlay 为 false。这证明安装包里的发现与原写入边界,不代表安装后的桌面 App 或真实 Lark 协作。
当前精确 head 的完整同序六模块独立运行 146/146 通过;标准 premerge 六项直接与 11 项选中检查也全部通过,无跳过或手工 validation hold。新增的第九个路径仅修整一个测试 helper:它的受控 stream 停止后,不再向真实 listener 的 finally/refresh 宣告仍有 synthetic profile,避免该一次性 fixture 在退出后留下替代 consumer。原 callback 数、stop/replay 行为断言、3 秒 startup deadline 和生产代码均未变。完整 loopx 生产树与前一次验证逐字节相同,所以当前 HTTP、typed owner、普通列表及非 editable wheel 的既有证据可以复用;新增 fixture 的完整六模块已在新提交重跑。root 类型、mypy17、变更 Python Ruff、正常 frontend/wheel 构建证据也按同一生产边界核验。
保留所有失败历史:我之前在 a04 和不可变 target 各跑一次完整六模块,分别145/146与121/122,都是相同 initialize timeout,122 个共同用例的其它121项一致通过;原作者 Python3.14首次143/3另有 listener freeze identity、thread/resume 与 always/no-replay 三个失败。当前 fixture 清理和完整146是本次有效证据,不把旧失败记录覆盖,也不声称已独立解释所有历史 startup 根因。作者给出的 deterministic lifecycle trap 属于作者证据;我自己核对了源码、未变的行为断言、生产树一致性及当前整套执行。
当前作者精确范围质量回执 cqr_bf5a63b9dc6c58e3eb95 已实际读回:scope 为本提交、decision=pass、无 unresolved blocker;它取代前一次 author required-regression hold,旧失败回执仍保留。独立共享 Core 两断言(37/39)及 checkpoint-retention Ruff 的基线/head 相同失败另列,相关生产/测试因果文件未被本 PR 改动,不能把它们写成通过,也不能拿旧 quality hold 冒充当前状态。未查询 CI;原生 merge readiness 在发布后单独读回,批准本身不授予合并权限。初始测试路径与重复 conftest 装载错误属于评审脚手架问题,已在真实测试前修正并保留。
我的整体评价
APPROVE,精确 head 3b0074c421214248eff6e717c532115484c08b68。这个阶段有真实调用者、原生与安装包正反证据,原绑定决策复用和锁边界合适;保留为原会话发现 API,后续写入仍走原入口。前端选择、真实 provider 采用和原线程结果返回仍是现有工作项的剩余验收。当前完整146与质量回执通过,历史失败不删除;Core/Ruff 的独立红色观察、GitHub和原生 readiness 分别处理,批准不授权合并。
English verdict: APPROVE — 3b0074c. Current complete six-module146 and premerge pass after a scoped listener-fixture cleanup. Exact production-tree equality retains the independent real File/SQLite HTTP, typed owner and noneditable wheel evidence; the actual immutable-base selector counterfactual remains discriminating. Historical failures stay recorded, current exact author quality passes, and shared Core/Ruff observations, merge readiness and frontend/live-provider acceptance remain separate.
After #6815 enabled local input to an existing private bound Session, clients still need a trustworthy way to find that Session. Extend the existing API with
GET /api/chat/sessions?conversation_binding_id=<binding_id>. The TypeScript binding owner rechecks the current App, operator, workspace and canonical Session identity; Python observes provider/store IO outside the publication fence. Callers must require the matching responseconversation_binding_idto distinguish older servers that ignore the query.Discovery retains the original Session/channel and a project's null Goal. Invalid, group, revoked, changed or ambiguous sources refuse without an unfiltered fallback. Closed history remains stored; ordinary listing adds no provider IO. The companion refactor shares the existing workspace validator and preserves duplicate observations for Core validation.
This nine-file Core/API prerequisite (+298/-12) enables the existing frontend owner to select the original conversation. Packaged frontend discovery, live shared-provider adoption, project-recipient collaboration and original-conversation result return retain their existing acceptance; that full journey is still open.
Validation at
3b0074c421214248eff6e717c532115484c08b68:finally/refreshpath started replacement consumers and raced the callback assertion. Removing that profile when its controlled stream stops fixes the fixture lifecycle. Startup deadlines (3 seconds), permissions, stop/replay assertions and production behavior are unchanged.Exact-scope author quality
cqr_bf5a63b9dc6c58e3eb95now passes against comparison base3cf8fb958. The old required-regression hold is resolved by the fixture repair and full rerun. Independent review and GitHub checks for this new head remain separate gates; this proposal requests no merge or live installation.