Repository navigation
Recognize direct exec results in the trajectory tool inventory - #8104
Conversation
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). 未发现阻断性代码问题;以下是对 8e9946dd7e6efabcae60c68abb2812e1712db374 的独立审查,合并权限另行判断。
动机 / Motivation
受影响的是用已有轨迹注册命令核对工具输入量的研究者。同一条静态命令仅因省去结果变量,旧版便把返回文本留在未归类项中;新版将两种完整的直接返回写法计入对应操作。真实 CLI 注册和存储回读确认了这项变化,混合脚本仍不归类,关闭统计时原有结果逐字段相同。本次不扩大到任意 JavaScript,不执行捕获命令,也不把字节比例换算成计费或研究收益。这解决的是已记录输入量的漏归类:它使相同调用写法的统计更一致,不证明系统整体效率或成本改善。
改动思路 / Approach
将语法识别留在已有捕获 IO 适配器,复用同一个标量解码器和 shell 分词器,操作与计数判断继续由既有 TypeScript owner 负责。当前 PR 仅补齐两种完整的直接返回表达式及其真实调用回归验证,不新增命令、持久化字段或执行权限。注册命令仍读取用户明确选定的捕获文件,Python 只提取静态参数和文本长度,再由现有 TypeScript reducer 做操作归类、去重与分母计算,最后存入原有 pack 并供原生读取接口使用。无法完整解释的脚本保持未归类;不会为了填满统计而执行源代码。保留旧的结果变量写法有真实的历史捕获消费者。要求用户改写捕获文件会增加手工操作,完整 JS 解析器或执行器则超出已证明的需求;本次在现有函数中共享调用表达式是合适的边界。
具体改动 / Changes
规范依据是 docs/reference/trajectory-assessment.md,固定 revision aa82591fb0a129f3ea9cc5e67343e742899c7ccd 的 Captured tool context inventory;以下四个名称是本审查对原文条款的映射标签:inventory-opt-in 已实现,省略开关时保留原有注册与投影;literal-only 已实现,混合或动态脚本不归类;input-byte-accounting 已实现,UTF-8 字节、同一次调用的重复记录及不同调用的相同内容分别处理;evidence-unit-boundary 已实现,保留 provider 计数与字节统计的单位区别。
关键代码讲解
_literal_exec_argv第 35 行 将一个共享的调用表达式嵌入三种完整写法。每个分支先做整段匹配,再经过原有标量 JSON 属性读取、重复键拒绝及 shell 分词。直接返回工具结果和直接取.output都走这个相同边界,没有另设命令分类器。project_tool_context第 81 行 仍只读取原生response_item,输出调用标识、字节数和摘要,忽略镜像记录及模型叙述。新分支只影响 argv 是否可识别,不复制原始返回文本到展示层。summarizeTrajectoryToolContext第 25 行 是未改动的计数 owner:同一调用的重复输出只计一次,不同调用返回相同内容仍各自计入。真实 CLI 的注册、既有存储和inspect_pack回读已连接到它,测试没有替这个 owner 伪造预期结果。
整个差异是三个文件 +56/-14,其中生产代码 +13/-6,其余为两个现有测试模块的扩展。没有增加持久化字段、CLI 参数、配置或语义枚举。
对主干的风险 / Risks
最强反例是正则跨过第二条命令或混入额外输出,却仍把整段返回归给 LoopX。我通过独立的完整捕获文件走真实注册与存储回读,检查了多调用、追加表达式、模板字符串、spread、重复 cmd、复合 shell,以及重复输出和相同内容的独立调用;不支持的形式仍未归类,捕获中的 sentinel 命令没有执行。十二个固定案例在 base/head、开关启用/省略四种组合中共执行 48 次注册和原生存储回读。中文加符号返回恰为 9 个 UTF-8 字节,加上 4 字节用户输入,分母为 13;重复同一回复不翻倍,两次独立调用则按 18/22 计数。24 次关闭统计的回读逐字段相同,provider 计数也完全相同,原始文件未改变,job/result 均为空。
PASS:22 个 Python 捕获测试、47 个现有 TypeScript 轨迹测试、三个改动文件 Ruff/编译、仓库配置的 17 文件 mypy、双语 RFC/空白/module ceiling、semantic vocabulary、权限策略和公开边界扫描。FAIL 保留:扩展路径 mypy 在两版均有 70 个错误、相同十个文件,完整诊断仅对未改动注解的行号 81→74 做 Git 对应;原始 maintainability ratchet 在两版均报告同一个未改动 interaction_contract 函数 62/60 决策点,完整结构报告除检出根路径外相同。它们按独立 base/head 运行和完整失败身份作可选诊断归因,没有把失败改写成通过,也没有豁免必需检查。首次 premerge 因缺少精确范围 CQR 被挡住,随后才基于这些独立证据记录质量凭据。再次执行时 CQR 为 valid、六个 direct 检查通过、三个 selected 检查无阻断性失败,但仍为 manual_review_required,整体退出码仍为 1;这里保留人工审查门槛,不声称整体 premerge 或合并就绪已通过。
语义与 CI 对齐
这是既有观测语法的有限扩展,复用原有 vocabulary 和 typed owner;识别出一条回复不代表命令成功、不必要恢复或执行授权。入口仍须显式开启统计,捕获文件存在或 UI 可用不会激活它。当前策略不查询、轮询或等待远端 CI,因此 CI 状态保持未知;没有跑全量 pytest、跨平台原生执行或已安装 App。字节统计仍不代表实际计费、完整上下文重放或因果收益。
我的整体评价 / Verdict
本次局部修复达到其已证明的目标,归类的改善通过实际调用和持久化回读可观察。long_horizon 为 preserved:没有增加调度、重试、状态同步或模型执行;user_experience 为 improved:原有输入和一次命令就获得正确读数,无需额外确认或改写证据。检查了现有 Research 来源与用量消费者;本次只改变可选输入统计的归类,不改变页面布局、文字、导航或交互,因此没有适用的视觉改动。未重新运行页面渲染、已安装 App 或实际模型推理;这些不属于本次静态捕获解析修复的验收范围。
将语法识别留在已有捕获 IO 适配器,复用同一个标量解码器和 shell 分词器,操作与计数判断继续由既有 TypeScript owner 负责。当前 PR 仅补齐两种完整的直接返回表达式及其真实调用回归验证,不新增命令、持久化字段或执行权限。这也完成了同域可逆简化的判断:共享调用表达式已足够,不需要新的抽象或语言迁移。剩余限制是有意保守的语法覆盖,以及尚未测量的实际模型消费和完整成本;不能从本审查外推研究收益。质量凭据、当前 head 的回读及 approval closeout 分别核对,公开审查结论不授予合并、安装或发布权限。
English verdict: APPROVE — the bounded capture fix is independently validated; optional baseline failures remain disclosed, and merge authorization is separate.
A captured Codex tool call can return a literal shell command directly to the client. The trajectory inventory previously recognized the same command only when the script assigned its result to a variable. This caused an otherwise identical output to lose its LoopX operation label.
This change recognizes two complete direct-return expressions while reusing the existing scalar option reader, shell parser and TypeScript operation inventory. A second command, a dynamic expression or mixed output remains unassigned. The capture reader executes no JavaScript. The opt-in inventory counts appended text bytes. Provider token and cost accounting follow their existing evidence requirements.
Verified through the public trajectory-pack registration command and stored pack readback with a synthetic capture. The direct call records one five-byte status reply. Running without a tool produces an empty inventory. The Python capture and inventory suites passed 22 tests, and the four TypeScript counter, input and inventory suites passed 30 tests.