7171 ShellCallOutcome ,
7272 ShellCommandOutput ,
7373 Tool ,
74+ ToolOrigin ,
75+ get_function_tool_origin ,
7476 invoke_function_tool ,
7577 maybe_invoke_function_tool_failure_error_function ,
7678 resolve_computer ,
@@ -1050,6 +1052,7 @@ async def on_invoke_tool(_ctx: ToolContext[Any], value: Any) -> Any:
10501052 on_invoke_tool = on_invoke_tool ,
10511053 strict_json_schema = True ,
10521054 is_enabled = True ,
1055+ _emit_tool_origin = False ,
10531056 )
10541057
10551058
@@ -1062,6 +1065,7 @@ async def resolve_approval_status(
10621065 context_wrapper : RunContextWrapper [Any ],
10631066 tool_namespace : str | None = None ,
10641067 tool_lookup_key : FunctionToolLookupKey | None = None ,
1068+ tool_origin : ToolOrigin | None = None ,
10651069 on_approval : Callable [[RunContextWrapper [Any ], ToolApprovalItem ], Any ] | None = None ,
10661070) -> tuple [bool | None , ToolApprovalItem ]:
10671071 """Build approval item, run on_approval hook if needed, and return latest approval status."""
@@ -1070,6 +1074,7 @@ async def resolve_approval_status(
10701074 raw_item = raw_item ,
10711075 tool_name = tool_name ,
10721076 tool_namespace = tool_namespace ,
1077+ tool_origin = tool_origin ,
10731078 tool_lookup_key = tool_lookup_key ,
10741079 )
10751080 approval_status = context_wrapper .get_approval_status (
@@ -1609,6 +1614,7 @@ async def _maybe_execute_tool_approval(
16091614 raw_item = raw_tool_call ,
16101615 tool_name = func_tool .name ,
16111616 tool_namespace = tool_namespace ,
1617+ tool_origin = get_function_tool_origin (func_tool ),
16121618 tool_lookup_key = tool_lookup_key ,
16131619 _allow_bare_name_alias = should_allow_bare_name_approval_alias (
16141620 func_tool ,
@@ -1649,6 +1655,7 @@ async def _maybe_execute_tool_approval(
16491655 tool_call ,
16501656 rejection_message = rejection_message ,
16511657 scope_id = self .tool_state_scope_id ,
1658+ tool_origin = get_function_tool_origin (func_tool ),
16521659 ),
16531660 )
16541661
@@ -1844,6 +1851,7 @@ def _build_function_tool_results(self) -> list[FunctionToolResult]:
18441851 output = result ,
18451852 raw_item = ItemHelpers .tool_call_output_item (tool_run .tool_call , result ),
18461853 agent = self .public_agent ,
1854+ tool_origin = get_function_tool_origin (tool_run .function_tool ),
18471855 )
18481856 else :
18491857 # Skip tool output until nested interruptions are resolved.
@@ -2060,14 +2068,22 @@ async def execute_approved_tools(
20602068 if isinstance (tool_name , str ) and tool_name :
20612069 tool_map [tool_name ] = tool
20622070
2063- def _append_error (message : str , * , tool_call : Any , tool_name : str , call_id : str ) -> None :
2071+ def _append_error (
2072+ message : str ,
2073+ * ,
2074+ tool_call : Any ,
2075+ tool_name : str ,
2076+ call_id : str ,
2077+ tool_origin : ToolOrigin | None = None ,
2078+ ) -> None :
20642079 append_approval_error_output (
20652080 message = message ,
20662081 tool_call = tool_call ,
20672082 tool_name = tool_name ,
20682083 call_id = call_id ,
20692084 generated_items = generated_items ,
20702085 agent = agent ,
2086+ tool_origin = tool_origin ,
20712087 )
20722088
20732089 async def _resolve_tool_run (
@@ -2095,14 +2111,25 @@ async def _resolve_tool_run(
20952111
20962112 call_id = extract_tool_call_id (tool_call )
20972113 if not call_id :
2114+ resolved_tool = tool_map .get (approval_key ) if approval_key is not None else None
2115+ if resolved_tool is None and tool_namespace is None :
2116+ resolved_tool = tool_map .get (tool_name )
20982117 _append_error (
20992118 message = "Tool approval item missing call ID." ,
21002119 tool_call = tool_call ,
21012120 tool_name = tool_name ,
21022121 call_id = "unknown" ,
2122+ tool_origin = (
2123+ get_function_tool_origin (resolved_tool )
2124+ if isinstance (resolved_tool , FunctionTool )
2125+ else None
2126+ ),
21032127 )
21042128 return None
21052129
2130+ resolved_tool = tool_map .get (approval_key ) if approval_key is not None else None
2131+ if resolved_tool is None and tool_namespace is None :
2132+ resolved_tool = tool_map .get (tool_name )
21062133 approval_status = context_wrapper .get_approval_status (
21072134 tool_name ,
21082135 call_id ,
@@ -2111,9 +2138,6 @@ async def _resolve_tool_run(
21112138 tool_lookup_key = tool_lookup_key ,
21122139 )
21132140 if approval_status is False :
2114- resolved_tool = tool_map .get (approval_key ) if approval_key is not None else None
2115- if resolved_tool is None and tool_namespace is None :
2116- resolved_tool = tool_map .get (tool_name )
21172141 message = REJECTION_MESSAGE
21182142 if isinstance (resolved_tool , FunctionTool ):
21192143 message = await resolve_approval_rejection_message (
@@ -2131,6 +2155,11 @@ async def _resolve_tool_run(
21312155 tool_call = tool_call ,
21322156 tool_name = tool_name ,
21332157 call_id = call_id ,
2158+ tool_origin = (
2159+ get_function_tool_origin (resolved_tool )
2160+ if isinstance (resolved_tool , FunctionTool )
2161+ else None
2162+ ),
21342163 )
21352164 return None
21362165
@@ -2140,12 +2169,15 @@ async def _resolve_tool_run(
21402169 tool_call = tool_call ,
21412170 tool_name = tool_name ,
21422171 call_id = call_id ,
2172+ tool_origin = (
2173+ get_function_tool_origin (resolved_tool )
2174+ if isinstance (resolved_tool , FunctionTool )
2175+ else None
2176+ ),
21432177 )
21442178 return None
21452179
2146- tool = tool_map .get (approval_key ) if approval_key is not None else None
2147- if tool is None and tool_namespace is None :
2148- tool = tool_map .get (tool_name )
2180+ tool = resolved_tool
21492181 if tool is None :
21502182 _append_error (
21512183 message = f"Tool '{ display_tool_name } ' not found." ,
0 commit comments