agent, tools: 支持 OpenAI Responses API、Agent HITL 多轮交互,修复 async generator span 泄漏 - #245
agent, tools: 支持 OpenAI Responses API、Agent HITL 多轮交互,修复 async generator span 泄漏#245pcerypeng wants to merge 1 commit into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #245 +/- ##
==========================================
Coverage ? 87.92373%
==========================================
Files ? 483
Lines ? 45577
Branches ? 0
==========================================
Hits ? 40073
Misses ? 5504
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
AI Code Review确认 — 已删除且未迁移。现在我来检查 现在我来检查一下 现在我来验证 我来检查一个担忧: 现在我来检查 GraphAgent 上下文中的 我还要验证恢复时的 现在我来看一下 我来检查最后一个潜在的实际问题:在
但有一个细微的问题: 我现在已经完全理解了。我来写审查报告。我也要再次检查一下 我来验证一下是否存在导入问题: 现在, await agent_stream.aclose()
interrupt(self._interrupt_payload(current_round))
raise RuntimeError(...)
我来做最后总结。我还要仔细检查一个真正值得关注的问题: 现在我来写审查报告。 发现的问题🚨 Critical无。
|
AI Code Review现在让我检查一下 我已经掌握了所需的所有上下文。让我来撰写审查意见。 发现的问题🚨 Critical
|
AI Code Review确认。现在我来写审查意见。 发现的问题🚨 Critical
|
| "type": "summary_text", | ||
| "text": accumulated_reasoning | ||
| }], | ||
| }) |
There was a problem hiding this comment.
Responses 流式 finally 引用未初始化的 response
response 仅在 try 内部赋值,若 client.responses.create 或 _prepare_responses_api_params 抛错,finally 中 if response is not None 会触发 UnboundLocalError,掩盖原始 API 异常并导致 close_http_client 永不执行(httpx 客户端泄漏)。建议在 try 前初始化 response: Any = None,并将 close_http_client 放入独立 try/except。
AI Code Review我已经充分理解了,可以开始编写审查意见了。多轮恢复中断(interrupt)重放是一个复杂点,但 HITL 测试( 实际上,在 LangGraph 中,当使用 发现的问题🚨 Critical
|
| resume_content: Optional[Content] = None | ||
| if pending_hitl is not None: | ||
| completed_rounds = pending_hitl.get("completed", []) | ||
| for completed in completed_rounds if isinstance(completed_rounds, list) else []: |
There was a problem hiding this comment.
HITL 恢复重放 completed 轮次 interrupt 可能丢失复合 resume 值
恢复路径对 completed 中每个历史轮次调用 interrupt() 再对 current 调用一次,但 Command(resume=...) 仅含最新 pending interrupt id 的响应。completed 轮次依赖 LangGraph 从 checkpoint 重放历史 resume 值;若未持久化 checkpoint(auto_persist=False),重放会再次抛出 interrupt 导致多轮 HITL 卡死。建议显式为 completed 轮次提供历史响应或重放时跳过 interrupt()。
AI Code Review现在让我来撰写评审。 发现的问题
|
1、这是拼写错误修正("desicion" 是 "decision" 的笔误)。该 key 仅在 interrupt.value 非 dict 时触发,实际使用场景极窄。 |
AI Code Review确认: 现在我已经有足够的内容来撰写审查报告了。让我来汇总一下。 发现的问题🚨 Critical
|
AI Code Review我已经彻底理解了。现在我来整理一下审查意见。 发现的问题🚨 Critical
|
| transfer_requested = False | ||
| child_ctx.agent = current_agent | ||
|
|
||
| async for event in current_agent.run_async(child_ctx): |
There was a problem hiding this comment.
AgentNode HITL pending 状态依赖 delta 提交时序,GraphInterrupt 路径下可能不落盘
子 agent 抛出 LongRunningEvent 后写入 parent_ctx.state 的 pending HITL marker(落进 _delta),随后 interrupt() 抛 GraphInterrupt 穿透节点函数,节点不会正常返回,LangGraph 因此不会提交 _delta,marker 不落盘。auto_persist=False 且中断桥事件未携带该 key 时,重启后 _get_pending_hitl 读不到标记,多轮 HITL 重放失败、Command(resume=...) 从 START 重跑。建议显式将该 marker 通过中断桥事件 state_delta 持久化,而非依赖 delta 提交时序。
AI Code Review我已经足够了解了。让我来整理一下审查结论。 基于我对 diff 的分析,以下是我的发现: 发现的问题🚨 Critical
|
| @@ -414,6 +418,9 @@ | |||
There was a problem hiding this comment.
并行合并路径丢失 long-running 工具的错误码导致降级失效
parallel_tool_calls=True 时 _merge_parallel_function_response_events 合并 event 仅搬移 content/actions/timestamp,不搬移 error_code/error_message,合并后错误码变回 None,使 is_tool_execution_error 判错并把参数错误的 long-running 调用误判为正常返回、发出 LongRunningEvent 挂起整图。建议合并时聚合 error_code(任一子事件有错即置错)或保留首个错误码。
功能新增: - OpenAI Responses API 适配(opt-in,use_responses_api 默认 False) - Agent Node HITL 多轮交互恢复机制 - LongRunningFunctionTool 执行错误检测 修复: - async generator 中 span 泄漏:start_as_current_span 改为手动 attach/detach + try/finally - OpenAI stream response 资源泄漏:finally 中 response.aclose() + UnboundLocalError 防御 - 多轮 HITL 恢复时 completed 轮次 interrupt 提供历史 resume 值 - LongRunningEvent fallback 仅对 graph 场景启用,避免误伤普通 LlmAgent HITL - tool result 提交前重读 session state 避免竞态误判 - _openai_model include 类型校验(字符串不再被拆成字符列表) - _llm_agent long-running + parallel_tool_calls 改为结构化 error event - _events/_builder 抽取 _display_name 辅助方法消除重复
AI Code Review我已经充分理解了,现在开始撰写审查结论。 发现的问题🚨 Critical
|
|
|
||
| tc = _make_tool_call(tc_id="tc-1", name="search") | ||
| inp = _make_input(messages=[ | ||
| _make_assistant_message(tool_calls=[tc]), |
There was a problem hiding this comment.
测试方法中混入被删除 LRO 测试的残留代码
diff 把 test_handles_lro_events 改名为新测试时只替换了签名和开头,assert_not_awaited() 之后仍保留原 LRO 测试逻辑(重新构造 lro_event、再次运行并断言 len(events) >= 2),导致一个方法执行两段无关场景。应删除 1718 行 assert_not_awaited() 之后到下一个 def test_ 之前的全部残留代码。
agent, tools: 支持 OpenAI Responses API、Agent HITL 多轮交互,修复 async generator span 泄漏
本次 PR 包含三项改进:
OpenAI Responses API 适配 — 新增对 OpenAI Responses API 的流式和非流式
支持,涵盖 reasoning、tool calls、logprobs 等特性。
Agent 节点 HITL(人机多轮交互)机制 — 通过 interrupt bridge 桥接机制,
允许 Agent 节点在运行中暂停等待人工输入,支持多轮审批或修正流程后继续执行。
修复 async generator 中 OpenTelemetry span 泄漏 — 将 start_as_current_span
替换为手动 start_span + attach/detach + try/finally 模式,确保 async
generator 被取消时 span 仍能正确结束。新增防御性 ValueError 捕获,处理
跨 task 清理场景。
此外,本次 PR 还新增了框架级工具错误检测能力:
tool_execution_error),并提供 is_tool_execution_error() 公共辅助函数。
RELEASE NOTES: 新增 OpenAI Responses API 支持、Agent 节点 HITL 多轮交互能力,
修复 async generator 取消时 OpenTelemetry span 泄漏问题。