@@ -523,6 +523,130 @@ def test_execute_code_tool_updates_approval_with_managed_tools() -> None:
523523 assert execute_code .approval_mode == "always_require"
524524
525525
526+ @pytest .mark .parametrize ("entry_point" , [HyperlightExecuteCodeTool , HyperlightCodeActProvider ])
527+ @pytest .mark .parametrize ("register_later" , [False , True ])
528+ @pytest .mark .parametrize (
529+ "properties" ,
530+ [
531+ {"source_integrity" : "untrusted" },
532+ {"confidentiality" : "private" },
533+ {"max_allowed_confidentiality" : "public" },
534+ {"max_allowed_confidentiality" : None },
535+ {"accepts_untrusted" : False },
536+ {"standing_guidance" : []},
537+ {"agent_framework.security.principals" : []},
538+ {"_agent_framework_internal_security_tool" : object ()},
539+ {"_mcp_trust_server_ifc" : False },
540+ ],
541+ )
542+ def test_codeact_warns_for_fides_tool_metadata (
543+ entry_point : type [HyperlightExecuteCodeTool ] | type [HyperlightCodeActProvider ],
544+ register_later : bool ,
545+ properties : dict [str , Any ],
546+ caplog : pytest .LogCaptureFixture ,
547+ ) -> None :
548+ @tool (additional_properties = properties )
549+ def annotated_tool (value : int ) -> int :
550+ return value
551+
552+ with caplog .at_level ("WARNING" , logger = "agent_framework" ):
553+ codeact = entry_point (tools = None if register_later else annotated_tool , _registry = _FakeRuntime ())
554+ if register_later :
555+ codeact .add_tools (annotated_tool )
556+
557+ records = [
558+ record for record in caplog .records if "FIDES is not supported with CodeAct providers." in record .message
559+ ]
560+ assert len (records ) == 1
561+ assert records [0 ].levelname == "WARNING"
562+ assert records [0 ].args == ("annotated_tool" ,)
563+ assert codeact .get_tools ()[0 ] is annotated_tool
564+ assert annotated_tool .additional_properties == properties
565+ assert annotated_tool .invocation_count == annotated_tool .invocation_exception_count == 0
566+
567+
568+ @pytest .mark .parametrize ("entry_point" , [HyperlightExecuteCodeTool , HyperlightCodeActProvider ])
569+ @pytest .mark .parametrize ("properties" , [None , {}, {"custom_property" : False }])
570+ def test_codeact_does_not_warn_for_unannotated_tools (
571+ entry_point : type [HyperlightExecuteCodeTool ] | type [HyperlightCodeActProvider ],
572+ properties : dict [str , Any ] | None ,
573+ caplog : pytest .LogCaptureFixture ,
574+ ) -> None :
575+ @tool (additional_properties = properties )
576+ def plain_tool (value : int ) -> int :
577+ return value
578+
579+ with caplog .at_level ("WARNING" , logger = "agent_framework" ):
580+ codeact = entry_point (tools = plain_tool , _registry = _FakeRuntime ())
581+
582+ assert "FIDES" not in caplog .text
583+ assert codeact .get_tools ()[0 ] is plain_tool
584+
585+
586+ def test_run_snapshot_warns_for_fides_metadata_added_after_registration (caplog : pytest .LogCaptureFixture ) -> None :
587+ @tool
588+ def annotated_tool (value : int ) -> int :
589+ return value
590+
591+ codeact = HyperlightExecuteCodeTool (tools = annotated_tool , _registry = _FakeRuntime ())
592+ assert annotated_tool .additional_properties is not None
593+ annotated_tool .additional_properties ["accepts_untrusted" ] = False
594+
595+ with caplog .at_level ("WARNING" , logger = "agent_framework" ):
596+ run_tool = codeact .create_run_tool ()
597+
598+ assert "FIDES is not supported with CodeAct providers." in caplog .text
599+ assert run_tool .get_tools ()[0 ] is annotated_tool
600+ assert annotated_tool .invocation_count == annotated_tool .invocation_exception_count == 0
601+
602+
603+ @pytest .mark .parametrize ("entry_point" , [HyperlightExecuteCodeTool , HyperlightCodeActProvider ])
604+ def test_codeact_does_not_repeat_fides_warning_for_unrelated_registration (
605+ entry_point : type [HyperlightExecuteCodeTool ] | type [HyperlightCodeActProvider ],
606+ caplog : pytest .LogCaptureFixture ,
607+ ) -> None :
608+ @tool (additional_properties = {"source_integrity" : "untrusted" })
609+ def annotated_tool (value : int ) -> int :
610+ return value
611+
612+ @tool
613+ def plain_tool (value : int ) -> int :
614+ return value
615+
616+ with caplog .at_level ("WARNING" , logger = "agent_framework" ):
617+ codeact = entry_point (tools = annotated_tool , _registry = _FakeRuntime ())
618+ caplog .clear ()
619+ codeact .add_tools (plain_tool )
620+
621+ assert "FIDES" not in caplog .text
622+ assert codeact .get_tools () == [annotated_tool , plain_tool ]
623+
624+
625+ @pytest .mark .parametrize ("entry_point" , [HyperlightExecuteCodeTool , HyperlightCodeActProvider ])
626+ def test_codeact_warns_once_for_annotated_tool_replacement (
627+ entry_point : type [HyperlightExecuteCodeTool ] | type [HyperlightCodeActProvider ],
628+ caplog : pytest .LogCaptureFixture ,
629+ ) -> None :
630+ @tool (name = "shared" )
631+ def original_tool (value : int ) -> int :
632+ return value
633+
634+ @tool (name = "shared" , additional_properties = {"accepts_untrusted" : False })
635+ def replacement_tool (value : int ) -> int :
636+ return value
637+
638+ codeact = entry_point (tools = original_tool , _registry = _FakeRuntime ())
639+ with caplog .at_level ("WARNING" , logger = "agent_framework" ):
640+ codeact .add_tools (replacement_tool )
641+
642+ records = [
643+ record for record in caplog .records if "FIDES is not supported with CodeAct providers." in record .message
644+ ]
645+ assert len (records ) == 1
646+ assert records [0 ].args == ("shared" ,)
647+ assert codeact .get_tools () == [replacement_tool ]
648+
649+
526650def test_execute_code_tool_replaces_tools_with_the_same_name () -> None :
527651 execute_code = HyperlightExecuteCodeTool (tools = [compute ], _registry = _FakeRuntime ())
528652
0 commit comments