fix(consult): record a tool call the tool never received
staging 手测 run 951a841e 第一次工具调用发出 tool.failed 后重试成功,但回执里 steps 只有 skill 与那次成功的 tool,stepBudget.used 为 2——失败的那次完全不存在。 客户端看见失败过一次,回执说没有,两边都查不到为什么。 工具的 inputSchema 是 strict 的,模型参数不合法时 Mastra 在调用 execute 之前就拒了, 于是工具体内一切都没跑:调用不计数、失败步不记录、连 chart-calculation 活动事件都没 发出(这也是本次定位的证据——失败那次没有任何 activity,重试那次有)。工具无法记录 一次它从未收到的调用。叠加两处:safeToolError 把非超时非取消的错误全塌成 calculation_failed,而即使失败落进工具体的 catch,consultationWorkflowFailureCode 对非 ConsultationWorkflowError 返回 undefined、append 处又写成可选省略,于是最需要 解释的那条记录恰好是唯一没有原因的记录。 改为在流层补记:流是唯一能观测到全部工具失败的位置,无论失败在 schema 这侧还是 execute 那侧,且它持有 startedAt 因而能给出时长。tool-error 分支比对「流已见的错误数」 与「state 里已有的失败 tool 步数」,只在前者更多时补一条,工具仍记录它能看见的失败, 两者不重复计。另新增 consultationToolFailureCode,令每个错误都解析出一个码。 failureCode 刻意仍不进公开回执:白名单与「the public receipt never carries the internal failure classification」是刻意约束,workflow_rate_limited 这类后端内情不该 上线到客户端。原因走可观测日志的 toolCalls[].failureCode。客户端能看到「有一步失败」, 运维能在日志里看到为什么。 另记入 BUG-268 的线上实测值:单领域 referenceReads 两次均为 2,多领域为 0——不是 从不读方法,而是最需要方法的多领域路径一份都没打开。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -699,7 +699,7 @@ def _attach_local_consultation_layers(handler, chart: dict, birth_payload: dict,
|
||||
#
|
||||
# The gate must also not be weaker than what the product tells the user it will use. The frontend
|
||||
# domain registry declares each domain's layers for its evidence preview, and every entry there that
|
||||
# names a real section is required here too; a test pins that intersection (BUG-269). The registry
|
||||
# names a real section is required here too; a test pins that intersection (BUG-270). The registry
|
||||
# additionally names human-facing items ('7th house/lord', 'negative holdout gate') and D11, which
|
||||
# the engine does not build at all — those are deliberately not requirements.
|
||||
_ROUTE_REQUIRED_LAYERS = {
|
||||
|
||||
@@ -53,7 +53,7 @@ CORE_PYTEST_TARGETS = [
|
||||
"tests/test_external_oracle_sanity_closure.py",
|
||||
# The staging gate runs the quick profile, so a guard absent from this list never runs in CI.
|
||||
# These pin the answer-truth contract every product consultation is built on, and their failure
|
||||
# mode is silent widening — nothing errors when they regress (BUG-267, BUG-269).
|
||||
# mode is silent widening — nothing errors when they regress (BUG-267, BUG-270).
|
||||
"tests/test_consultation_consumer_context.py",
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user