Skip to content

fix(agents): 修复 HIL 工具审批 interrupt 被误当 ask_user_question 处理#791

Open
xiangfei258 wants to merge 2 commits into
xerrors:mainfrom
xiangfei258:fix/hil-interrupt-payload-routing-v2
Open

fix(agents): 修复 HIL 工具审批 interrupt 被误当 ask_user_question 处理#791
xiangfei258 wants to merge 2 commits into
xerrors:mainfrom
xiangfei258:fix/hil-interrupt-payload-routing-v2

Conversation

@xiangfei258

Copy link
Copy Markdown
Contributor

说明

本 PR 是 #784 的干净重新提交。

#784 误夹带了与 HIL 修复无关的本地定制 commit(logo / 首页 / 登录页 / 配置等),已被关闭。本 PR 仅保留 HIL 工具审批相关的改动。

改动内容

后端

  • 修复 HIL 工具审批 interrupt 在后端三处被误当 ask_user_question 处理(agent_run_service / chat_service / run_worker)
  • 补充 test_agent_run_service / test_chat_stream_interrupt 单测

前端

  • 新增 HumanToolApprovalModal.vue 工具审批弹窗,支持 approve / reject / edit
  • 新增 approvalInterrupt.js,调整 useApproval.js / useAgentRunStream.js / AgentChatComponent.vue 接入审批弹窗

Supersedes #784

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for LangChain's HumanInTheLoopMiddleware tool approval interrupts, resolving issues where they were incorrectly handled as standard user questions. Key changes include backend routing of HIL interrupts to a new human_approval_required status, payload compacting whitelist updates, and frontend support via a new HumanToolApprovalModal component allowing users to approve, reject, or edit tool arguments. Feedback on the PR highlights a potential issue in HumanToolApprovalModal.vue where editing string-based or empty tool arguments could cause JSON.parse to fail, and suggests a more robust parsing implementation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +113 to +122
const parseEditedArgs = () => {
try {
const parsed = JSON.parse(editText.value)
editError.value = ''
return parsed
} catch (e) {
editError.value = `参数不是合法 JSON:${e.message}`
return null
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

当原始参数 args 是一个普通字符串(例如 "some_string")或者为空(null/undefined)时,点击“编辑参数”后,formatArgs 会将其转换为 "some_string"""。在提交编辑时,parseEditedArgs 会直接调用 JSON.parse,这会导致解析失败(抛出 SyntaxError),使用户无法成功提交编辑。\n\n建议:在 parseEditedArgs 中,先对空输入进行处理(默认返回 {}),并判断原始参数是否为字符串类型。如果是字符串类型,则直接返回编辑后的文本,而不需要进行 JSON.parse

const parseEditedArgs = () => {
  const trimmed = editText.value.trim()
  if (!trimmed) {
    editError.value = ''
    return {}
  }
  const originalArgs = props.actionRequests[0]?.args
  if (typeof originalArgs === 'string') {
    editError.value = ''
    return trimmed
  }
  try {
    const parsed = JSON.parse(trimmed)
    editError.value = ''
    return parsed
  } catch (e) {
    editError.value = '参数不是合法 JSON:' + e.message
    return null
  }
}

xiangchang_24 added 2 commits June 27, 2026 11:49
HumanInTheLoopMiddleware 触发的工具审批 interrupt 载荷为
action_requests/review_configs(HITLRequest),与 ask_user_question 的
questions 结构不同,原有逻辑在三处按 questions 假设导致 HIL 不可用:

1. check_and_handle_interrupts 无 questions 时塞默认空问题
   「请选择一个选项」,前端收到空弹窗。现按 payload 是否含
   action_requests 分流,HIL 中断发 human_approval_required 并携带
   action_requests/review_configs,ask_user_question 保持原有行为。
2. _compact_stream_chunk 的 verbose=false 精简白名单漏掉
   action_requests/review_configs,前端拿不到审批载荷。白名单补入
   这两个字段。
3. run_worker 的 interrupt 摘要只取 questions,HIL 摘要为空。
   _interrupt_summary 兼容两类载荷,HIL 摘要改为
   「操作需要确认: 工具名(参数)」。

补充单元测试覆盖 payload 分流、compact 字段保留与摘要生成。
前端按 interrupt 类型分流:
- human_approval_required 渲染新的 HumanToolApprovalModal,
  展示待审批工具名与参数,提供确认执行/编辑参数/拒绝三种决策,
  提交 { decisions: [{ type: "approve" | "reject" | "edit", ... }] }
  与后端 Command(resume=...) 恢复语义一致
- ask_user_question_required 仍走原有选项式弹窗,行为不变

useApproval 与 useAgentRunStream 的 hasPendingInterruptForRun
兼容 actionRequests(HIL 中断无 questions),避免弹窗一闪而过。
将 extractPendingInterrupt 抽到 approvalInterrupt.js 纯函数文件,
便于纯 node 单测。补充前端分流单测。
@xiangfei258 xiangfei258 force-pushed the fix/hil-interrupt-payload-routing-v2 branch from 2a31144 to 4fdaba5 Compare June 27, 2026 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant