mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add second approval-required tool (set_stop_loss) to concurrent_builder_tool_approval sample (#4875)
* Add set_stop_loss tool to concurrent_builder_tool_approval sample Add a second approval-gated tool (set_stop_loss) to the concurrent workflow tool approval sample to demonstrate handling approval requests for different tools in the same concurrent workflow. Changes: - Add set_stop_loss(symbol, stop_price) with approval_mode='always_require' - Include new tool in both agents' tool lists - Update agent instructions and prompt to encourage stop-loss usage - Update docstring to reflect two approval-gated tools - Update sample output to show mixed approval requests Fixes #4874 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Print tool name and arguments in concurrent sample's process_event_stream (#4874) Align process_event_stream in concurrent_builder_tool_approval.py to print the tool name and arguments when collecting approval requests, matching the sample output comment and the sequential_builder_tool_approval.py pattern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add None-guard for function_call access in tool approval sample (#4874) Add explicit None-checks before accessing function_call.name and function_call.arguments in concurrent_builder_tool_approval.py. The function_call field is typed Content | None, so direct attribute access without a guard could raise AttributeError and required type: ignore comments. The None-guard is consistent with the pattern used in _agent_run.py and removes the suppression comments. Also add a regression test verifying that function_call defaults to None and that the None-guard pattern is safe. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply same function_call None-guard to sibling tool-approval samples (#4874) Apply the same fix to sequential_builder_tool_approval.py and group_chat_builder_tool_approval.py, which had the identical pattern of accessing function_call.name/arguments without a None-guard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
2c8036779c
commit
b6b191ad9c
@@ -664,6 +664,21 @@ def test_function_approval_serialization_roundtrip():
|
||||
# The Content union will need to be handled differently when we fully migrate
|
||||
|
||||
|
||||
def test_function_approval_request_function_call_none_guard():
|
||||
"""Test that accessing function_call attributes is safe when function_call is None."""
|
||||
# Construct a Content with type "function_approval_request" but no function_call.
|
||||
# This verifies the None-guard pattern used in samples to prevent AttributeError.
|
||||
content = Content("function_approval_request", id="req-none")
|
||||
assert content.function_call is None
|
||||
|
||||
# A proper approval request always has function_call set
|
||||
fc = Content.from_function_call(call_id="call-1", name="do_something", arguments={"a": 1})
|
||||
req = Content.from_function_approval_request(id="req-1", function_call=fc)
|
||||
assert req.function_call is not None
|
||||
assert req.function_call.name == "do_something"
|
||||
assert req.function_call.arguments == {"a": 1}
|
||||
|
||||
|
||||
def test_function_approval_accepts_mcp_call():
|
||||
"""Ensure FunctionApprovalRequestContent supports MCP server tool calls."""
|
||||
mcp_call = Content.from_mcp_server_tool_call(
|
||||
|
||||
Reference in New Issue
Block a user