aip-agents-binary 0.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of aip-agents-binary might be problematic. Click here for more details.
- aip_agents/__init__.py +65 -0
- aip_agents/__init__.pyi +19 -0
- aip_agents/a2a/__init__.py +19 -0
- aip_agents/a2a/__init__.pyi +3 -0
- aip_agents/a2a/server/__init__.py +10 -0
- aip_agents/a2a/server/__init__.pyi +4 -0
- aip_agents/a2a/server/base_executor.py +1086 -0
- aip_agents/a2a/server/base_executor.pyi +73 -0
- aip_agents/a2a/server/google_adk_executor.py +198 -0
- aip_agents/a2a/server/google_adk_executor.pyi +51 -0
- aip_agents/a2a/server/langflow_executor.py +180 -0
- aip_agents/a2a/server/langflow_executor.pyi +43 -0
- aip_agents/a2a/server/langgraph_executor.py +270 -0
- aip_agents/a2a/server/langgraph_executor.pyi +47 -0
- aip_agents/a2a/types.py +232 -0
- aip_agents/a2a/types.pyi +132 -0
- aip_agents/agent/__init__.py +27 -0
- aip_agents/agent/__init__.pyi +9 -0
- aip_agents/agent/base_agent.py +970 -0
- aip_agents/agent/base_agent.pyi +221 -0
- aip_agents/agent/base_langgraph_agent.py +3037 -0
- aip_agents/agent/base_langgraph_agent.pyi +233 -0
- aip_agents/agent/google_adk_agent.py +926 -0
- aip_agents/agent/google_adk_agent.pyi +141 -0
- aip_agents/agent/google_adk_constants.py +6 -0
- aip_agents/agent/google_adk_constants.pyi +3 -0
- aip_agents/agent/hitl/__init__.py +24 -0
- aip_agents/agent/hitl/__init__.pyi +6 -0
- aip_agents/agent/hitl/config.py +28 -0
- aip_agents/agent/hitl/config.pyi +15 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.pyi +42 -0
- aip_agents/agent/hitl/manager.py +532 -0
- aip_agents/agent/hitl/manager.pyi +200 -0
- aip_agents/agent/hitl/models.py +18 -0
- aip_agents/agent/hitl/models.pyi +3 -0
- aip_agents/agent/hitl/prompt/__init__.py +9 -0
- aip_agents/agent/hitl/prompt/__init__.pyi +4 -0
- aip_agents/agent/hitl/prompt/base.py +42 -0
- aip_agents/agent/hitl/prompt/base.pyi +24 -0
- aip_agents/agent/hitl/prompt/deferred.py +73 -0
- aip_agents/agent/hitl/prompt/deferred.pyi +30 -0
- aip_agents/agent/hitl/registry.py +149 -0
- aip_agents/agent/hitl/registry.pyi +101 -0
- aip_agents/agent/interface.py +138 -0
- aip_agents/agent/interface.pyi +81 -0
- aip_agents/agent/interfaces.py +65 -0
- aip_agents/agent/interfaces.pyi +44 -0
- aip_agents/agent/langflow_agent.py +464 -0
- aip_agents/agent/langflow_agent.pyi +133 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.py +767 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +50 -0
- aip_agents/agent/langgraph_react_agent.py +2856 -0
- aip_agents/agent/langgraph_react_agent.pyi +170 -0
- aip_agents/agent/system_instruction_context.py +34 -0
- aip_agents/agent/system_instruction_context.pyi +13 -0
- aip_agents/clients/__init__.py +10 -0
- aip_agents/clients/__init__.pyi +4 -0
- aip_agents/clients/langflow/__init__.py +10 -0
- aip_agents/clients/langflow/__init__.pyi +4 -0
- aip_agents/clients/langflow/client.py +477 -0
- aip_agents/clients/langflow/client.pyi +140 -0
- aip_agents/clients/langflow/types.py +18 -0
- aip_agents/clients/langflow/types.pyi +7 -0
- aip_agents/constants.py +23 -0
- aip_agents/constants.pyi +7 -0
- aip_agents/credentials/manager.py +132 -0
- aip_agents/examples/__init__.py +5 -0
- aip_agents/examples/__init__.pyi +0 -0
- aip_agents/examples/compare_streaming_client.py +783 -0
- aip_agents/examples/compare_streaming_client.pyi +48 -0
- aip_agents/examples/compare_streaming_server.py +142 -0
- aip_agents/examples/compare_streaming_server.pyi +18 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
- aip_agents/examples/hello_world_a2a_langchain_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
- aip_agents/examples/hello_world_a2a_langflow_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
- aip_agents/examples/hello_world_a2a_langflow_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +16 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +15 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +45 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_google_adk.py +41 -0
- aip_agents/examples/hello_world_google_adk.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_stream.py +44 -0
- aip_agents/examples/hello_world_google_adk_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain.py +28 -0
- aip_agents/examples/hello_world_langchain.pyi +5 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.pyi +16 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.pyi +18 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream.py +36 -0
- aip_agents/examples/hello_world_langchain_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_langflow_agent.py +163 -0
- aip_agents/examples/hello_world_langflow_agent.pyi +35 -0
- aip_agents/examples/hello_world_langgraph.py +39 -0
- aip_agents/examples/hello_world_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream.py +43 -0
- aip_agents/examples/hello_world_langgraph_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_model_switch_cli.py +210 -0
- aip_agents/examples/hello_world_model_switch_cli.pyi +30 -0
- aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
- aip_agents/examples/hello_world_multi_agent_adk.pyi +6 -0
- aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
- aip_agents/examples/hello_world_multi_agent_langchain.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_pii_logger.py +21 -0
- aip_agents/examples/hello_world_pii_logger.pyi +5 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_sentry.py +133 -0
- aip_agents/examples/hello_world_sentry.pyi +21 -0
- aip_agents/examples/hello_world_step_limits.py +273 -0
- aip_agents/examples/hello_world_step_limits.pyi +17 -0
- aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
- aip_agents/examples/hello_world_stock_a2a_server.pyi +17 -0
- aip_agents/examples/hello_world_tool_output_client.py +55 -0
- aip_agents/examples/hello_world_tool_output_client.pyi +5 -0
- aip_agents/examples/hello_world_tool_output_server.py +114 -0
- aip_agents/examples/hello_world_tool_output_server.pyi +19 -0
- aip_agents/examples/hitl_demo.py +724 -0
- aip_agents/examples/hitl_demo.pyi +67 -0
- aip_agents/examples/mcp_configs/configs.py +63 -0
- aip_agents/examples/mcp_servers/common.py +76 -0
- aip_agents/examples/mcp_servers/mcp_name.py +29 -0
- aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
- aip_agents/examples/mcp_servers/mcp_time.py +10 -0
- aip_agents/examples/pii_demo_langgraph_client.py +69 -0
- aip_agents/examples/pii_demo_langgraph_client.pyi +5 -0
- aip_agents/examples/pii_demo_langgraph_server.py +126 -0
- aip_agents/examples/pii_demo_langgraph_server.pyi +20 -0
- aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
- aip_agents/examples/pii_demo_multi_agent_client.pyi +5 -0
- aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
- aip_agents/examples/pii_demo_multi_agent_server.pyi +40 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.pyi +19 -0
- aip_agents/examples/tools/__init__.py +27 -0
- aip_agents/examples/tools/__init__.pyi +9 -0
- aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
- aip_agents/examples/tools/adk_arithmetic_tools.pyi +24 -0
- aip_agents/examples/tools/adk_weather_tool.py +60 -0
- aip_agents/examples/tools/adk_weather_tool.pyi +18 -0
- aip_agents/examples/tools/data_generator_tool.py +103 -0
- aip_agents/examples/tools/data_generator_tool.pyi +15 -0
- aip_agents/examples/tools/data_visualization_tool.py +312 -0
- aip_agents/examples/tools/data_visualization_tool.pyi +19 -0
- aip_agents/examples/tools/image_artifact_tool.py +136 -0
- aip_agents/examples/tools/image_artifact_tool.pyi +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.pyi +17 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +20 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +25 -0
- aip_agents/examples/tools/langchain_weather_tool.py +48 -0
- aip_agents/examples/tools/langchain_weather_tool.pyi +19 -0
- aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
- aip_agents/examples/tools/langgraph_streaming_tool.pyi +43 -0
- aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
- aip_agents/examples/tools/mock_retrieval_tool.pyi +13 -0
- aip_agents/examples/tools/pii_demo_tools.py +189 -0
- aip_agents/examples/tools/pii_demo_tools.pyi +54 -0
- aip_agents/examples/tools/random_chart_tool.py +142 -0
- aip_agents/examples/tools/random_chart_tool.pyi +20 -0
- aip_agents/examples/tools/serper_tool.py +202 -0
- aip_agents/examples/tools/serper_tool.pyi +16 -0
- aip_agents/examples/tools/stock_tools.py +82 -0
- aip_agents/examples/tools/stock_tools.pyi +36 -0
- aip_agents/examples/tools/table_generator_tool.py +167 -0
- aip_agents/examples/tools/table_generator_tool.pyi +22 -0
- aip_agents/examples/tools/time_tool.py +82 -0
- aip_agents/examples/tools/time_tool.pyi +15 -0
- aip_agents/examples/tools/weather_forecast_tool.py +38 -0
- aip_agents/examples/tools/weather_forecast_tool.pyi +14 -0
- aip_agents/executor/agent_executor.py +473 -0
- aip_agents/executor/base.py +48 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/__init__.pyi +6 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/__init__.pyi +4 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/base.pyi +61 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/nemo.pyi +46 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/exceptions.pyi +23 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/manager.pyi +42 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/middleware.pyi +87 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/schemas.pyi +43 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/guardrails/utils.pyi +19 -0
- aip_agents/mcp/__init__.py +1 -0
- aip_agents/mcp/__init__.pyi +0 -0
- aip_agents/mcp/client/__init__.py +14 -0
- aip_agents/mcp/client/__init__.pyi +5 -0
- aip_agents/mcp/client/base_mcp_client.py +369 -0
- aip_agents/mcp/client/base_mcp_client.pyi +148 -0
- aip_agents/mcp/client/connection_manager.py +228 -0
- aip_agents/mcp/client/connection_manager.pyi +51 -0
- aip_agents/mcp/client/google_adk/__init__.py +11 -0
- aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
- aip_agents/mcp/client/google_adk/client.py +381 -0
- aip_agents/mcp/client/google_adk/client.pyi +75 -0
- aip_agents/mcp/client/langchain/__init__.py +11 -0
- aip_agents/mcp/client/langchain/__init__.pyi +3 -0
- aip_agents/mcp/client/langchain/client.py +265 -0
- aip_agents/mcp/client/langchain/client.pyi +48 -0
- aip_agents/mcp/client/persistent_session.py +612 -0
- aip_agents/mcp/client/persistent_session.pyi +122 -0
- aip_agents/mcp/client/session_pool.py +351 -0
- aip_agents/mcp/client/session_pool.pyi +101 -0
- aip_agents/mcp/client/transports.py +263 -0
- aip_agents/mcp/client/transports.pyi +132 -0
- aip_agents/mcp/utils/__init__.py +7 -0
- aip_agents/mcp/utils/__init__.pyi +0 -0
- aip_agents/mcp/utils/config_validator.py +139 -0
- aip_agents/mcp/utils/config_validator.pyi +82 -0
- aip_agents/memory/__init__.py +14 -0
- aip_agents/memory/__init__.pyi +5 -0
- aip_agents/memory/adapters/__init__.py +10 -0
- aip_agents/memory/adapters/__init__.pyi +4 -0
- aip_agents/memory/adapters/base_adapter.py +811 -0
- aip_agents/memory/adapters/base_adapter.pyi +176 -0
- aip_agents/memory/adapters/mem0.py +84 -0
- aip_agents/memory/adapters/mem0.pyi +22 -0
- aip_agents/memory/base.py +84 -0
- aip_agents/memory/base.pyi +60 -0
- aip_agents/memory/constants.py +49 -0
- aip_agents/memory/constants.pyi +25 -0
- aip_agents/memory/factory.py +86 -0
- aip_agents/memory/factory.pyi +24 -0
- aip_agents/memory/guidance.py +20 -0
- aip_agents/memory/guidance.pyi +3 -0
- aip_agents/memory/simple_memory.py +47 -0
- aip_agents/memory/simple_memory.pyi +23 -0
- aip_agents/middleware/__init__.py +17 -0
- aip_agents/middleware/__init__.pyi +5 -0
- aip_agents/middleware/base.py +96 -0
- aip_agents/middleware/base.pyi +75 -0
- aip_agents/middleware/manager.py +150 -0
- aip_agents/middleware/manager.pyi +84 -0
- aip_agents/middleware/todolist.py +274 -0
- aip_agents/middleware/todolist.pyi +125 -0
- aip_agents/ptc/__init__.py +48 -0
- aip_agents/ptc/__init__.pyi +10 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +39 -0
- aip_agents/ptc/exceptions.pyi +22 -0
- aip_agents/ptc/executor.py +143 -0
- aip_agents/ptc/executor.pyi +73 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/__init__.pyi +7 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +668 -0
- aip_agents/ptc/mcp/sandbox_bridge.pyi +47 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/__init__.pyi +0 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +239 -0
- aip_agents/ptc/naming.py +184 -0
- aip_agents/ptc/naming.pyi +76 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +571 -0
- aip_agents/ptc/prompt_builder.pyi +55 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +58 -0
- aip_agents/ptc/sandbox_bridge.pyi +25 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/template_utils.pyi +13 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/__init__.pyi +0 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +9 -0
- aip_agents/sandbox/defaults.pyi +2 -0
- aip_agents/sandbox/e2b_runtime.py +267 -0
- aip_agents/sandbox/e2b_runtime.pyi +51 -0
- aip_agents/sandbox/template_builder.py +131 -0
- aip_agents/sandbox/template_builder.pyi +36 -0
- aip_agents/sandbox/types.py +24 -0
- aip_agents/sandbox/types.pyi +14 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/sandbox/validation.pyi +20 -0
- aip_agents/schema/__init__.py +69 -0
- aip_agents/schema/__init__.pyi +9 -0
- aip_agents/schema/a2a.py +56 -0
- aip_agents/schema/a2a.pyi +40 -0
- aip_agents/schema/agent.py +111 -0
- aip_agents/schema/agent.pyi +65 -0
- aip_agents/schema/hitl.py +157 -0
- aip_agents/schema/hitl.pyi +89 -0
- aip_agents/schema/langgraph.py +37 -0
- aip_agents/schema/langgraph.pyi +28 -0
- aip_agents/schema/model_id.py +97 -0
- aip_agents/schema/model_id.pyi +54 -0
- aip_agents/schema/step_limit.py +108 -0
- aip_agents/schema/step_limit.pyi +63 -0
- aip_agents/schema/storage.py +40 -0
- aip_agents/schema/storage.pyi +21 -0
- aip_agents/sentry/__init__.py +11 -0
- aip_agents/sentry/__init__.pyi +3 -0
- aip_agents/sentry/sentry.py +151 -0
- aip_agents/sentry/sentry.pyi +48 -0
- aip_agents/storage/__init__.py +41 -0
- aip_agents/storage/__init__.pyi +8 -0
- aip_agents/storage/base.py +85 -0
- aip_agents/storage/base.pyi +58 -0
- aip_agents/storage/clients/__init__.py +12 -0
- aip_agents/storage/clients/__init__.pyi +3 -0
- aip_agents/storage/clients/minio_client.py +318 -0
- aip_agents/storage/clients/minio_client.pyi +137 -0
- aip_agents/storage/config.py +62 -0
- aip_agents/storage/config.pyi +29 -0
- aip_agents/storage/providers/__init__.py +15 -0
- aip_agents/storage/providers/__init__.pyi +5 -0
- aip_agents/storage/providers/base.py +106 -0
- aip_agents/storage/providers/base.pyi +88 -0
- aip_agents/storage/providers/memory.py +114 -0
- aip_agents/storage/providers/memory.pyi +79 -0
- aip_agents/storage/providers/object_storage.py +214 -0
- aip_agents/storage/providers/object_storage.pyi +98 -0
- aip_agents/tools/__init__.py +64 -0
- aip_agents/tools/__init__.pyi +11 -0
- aip_agents/tools/browser_use/__init__.py +82 -0
- aip_agents/tools/browser_use/__init__.pyi +14 -0
- aip_agents/tools/browser_use/action_parser.py +103 -0
- aip_agents/tools/browser_use/action_parser.pyi +18 -0
- aip_agents/tools/browser_use/browser_use_tool.py +1120 -0
- aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
- aip_agents/tools/browser_use/llm_config.py +120 -0
- aip_agents/tools/browser_use/llm_config.pyi +52 -0
- aip_agents/tools/browser_use/minio_storage.py +198 -0
- aip_agents/tools/browser_use/minio_storage.pyi +109 -0
- aip_agents/tools/browser_use/schemas.py +119 -0
- aip_agents/tools/browser_use/schemas.pyi +32 -0
- aip_agents/tools/browser_use/session.py +76 -0
- aip_agents/tools/browser_use/session.pyi +4 -0
- aip_agents/tools/browser_use/session_errors.py +132 -0
- aip_agents/tools/browser_use/session_errors.pyi +53 -0
- aip_agents/tools/browser_use/steel_session_recording.py +317 -0
- aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
- aip_agents/tools/browser_use/streaming.py +815 -0
- aip_agents/tools/browser_use/streaming.pyi +81 -0
- aip_agents/tools/browser_use/structured_data_parser.py +257 -0
- aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
- aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
- aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
- aip_agents/tools/browser_use/types.py +78 -0
- aip_agents/tools/browser_use/types.pyi +45 -0
- aip_agents/tools/code_sandbox/__init__.py +26 -0
- aip_agents/tools/code_sandbox/__init__.pyi +3 -0
- aip_agents/tools/code_sandbox/constant.py +13 -0
- aip_agents/tools/code_sandbox/constant.pyi +4 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +306 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +102 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
- aip_agents/tools/constants.py +177 -0
- aip_agents/tools/constants.pyi +138 -0
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/date_range_tool.pyi +21 -0
- aip_agents/tools/document_loader/__init__.py +44 -0
- aip_agents/tools/document_loader/__init__.pyi +7 -0
- aip_agents/tools/document_loader/base_reader.py +302 -0
- aip_agents/tools/document_loader/base_reader.pyi +75 -0
- aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
- aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
- aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
- aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
- aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
- aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
- aip_agents/tools/document_loader/pdf_splitter.py +169 -0
- aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
- aip_agents/tools/execute_ptc_code.py +308 -0
- aip_agents/tools/execute_ptc_code.pyi +90 -0
- aip_agents/tools/gl_connector/__init__.py +5 -0
- aip_agents/tools/gl_connector/__init__.pyi +3 -0
- aip_agents/tools/gl_connector/tool.py +383 -0
- aip_agents/tools/gl_connector/tool.pyi +74 -0
- aip_agents/tools/gl_connector_tools.py +119 -0
- aip_agents/tools/gl_connector_tools.pyi +39 -0
- aip_agents/tools/memory_search/__init__.py +29 -0
- aip_agents/tools/memory_search/__init__.pyi +5 -0
- aip_agents/tools/memory_search/base.py +200 -0
- aip_agents/tools/memory_search/base.pyi +69 -0
- aip_agents/tools/memory_search/mem0.py +365 -0
- aip_agents/tools/memory_search/mem0.pyi +29 -0
- aip_agents/tools/memory_search/schema.py +81 -0
- aip_agents/tools/memory_search/schema.pyi +25 -0
- aip_agents/tools/memory_search_tool.py +34 -0
- aip_agents/tools/memory_search_tool.pyi +3 -0
- aip_agents/tools/time_tool.py +117 -0
- aip_agents/tools/time_tool.pyi +16 -0
- aip_agents/tools/tool_config_injector.py +300 -0
- aip_agents/tools/tool_config_injector.pyi +26 -0
- aip_agents/tools/web_search/__init__.py +15 -0
- aip_agents/tools/web_search/__init__.pyi +3 -0
- aip_agents/tools/web_search/serper_tool.py +187 -0
- aip_agents/tools/web_search/serper_tool.pyi +19 -0
- aip_agents/types/__init__.py +70 -0
- aip_agents/types/__init__.pyi +36 -0
- aip_agents/types/a2a_events.py +13 -0
- aip_agents/types/a2a_events.pyi +3 -0
- aip_agents/utils/__init__.py +79 -0
- aip_agents/utils/__init__.pyi +11 -0
- aip_agents/utils/a2a_connector.py +1757 -0
- aip_agents/utils/a2a_connector.pyi +146 -0
- aip_agents/utils/artifact_helpers.py +502 -0
- aip_agents/utils/artifact_helpers.pyi +203 -0
- aip_agents/utils/constants.py +22 -0
- aip_agents/utils/constants.pyi +10 -0
- aip_agents/utils/datetime/__init__.py +34 -0
- aip_agents/utils/datetime/__init__.pyi +4 -0
- aip_agents/utils/datetime/normalization.py +231 -0
- aip_agents/utils/datetime/normalization.pyi +95 -0
- aip_agents/utils/datetime/timezone.py +206 -0
- aip_agents/utils/datetime/timezone.pyi +48 -0
- aip_agents/utils/env_loader.py +27 -0
- aip_agents/utils/env_loader.pyi +10 -0
- aip_agents/utils/event_handler_registry.py +58 -0
- aip_agents/utils/event_handler_registry.pyi +23 -0
- aip_agents/utils/file_prompt_utils.py +176 -0
- aip_agents/utils/file_prompt_utils.pyi +21 -0
- aip_agents/utils/final_response_builder.py +211 -0
- aip_agents/utils/final_response_builder.pyi +34 -0
- aip_agents/utils/formatter_llm_client.py +231 -0
- aip_agents/utils/formatter_llm_client.pyi +71 -0
- aip_agents/utils/langgraph/__init__.py +19 -0
- aip_agents/utils/langgraph/__init__.pyi +3 -0
- aip_agents/utils/langgraph/converter.py +128 -0
- aip_agents/utils/langgraph/converter.pyi +49 -0
- aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
- aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1096 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
- aip_agents/utils/langgraph/tool_output_management.py +1047 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +329 -0
- aip_agents/utils/logger.py +195 -0
- aip_agents/utils/logger.pyi +60 -0
- aip_agents/utils/metadata/__init__.py +27 -0
- aip_agents/utils/metadata/__init__.pyi +5 -0
- aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
- aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
- aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
- aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
- aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
- aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
- aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
- aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
- aip_agents/utils/metadata/activity_narrative/context.py +49 -0
- aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
- aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
- aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
- aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
- aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
- aip_agents/utils/metadata/schemas/__init__.py +16 -0
- aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
- aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
- aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
- aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
- aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
- aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
- aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
- aip_agents/utils/metadata_helper.py +358 -0
- aip_agents/utils/metadata_helper.pyi +117 -0
- aip_agents/utils/name_preprocessor/__init__.py +17 -0
- aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
- aip_agents/utils/pii/__init__.py +25 -0
- aip_agents/utils/pii/__init__.pyi +5 -0
- aip_agents/utils/pii/pii_handler.py +397 -0
- aip_agents/utils/pii/pii_handler.pyi +96 -0
- aip_agents/utils/pii/pii_helper.py +207 -0
- aip_agents/utils/pii/pii_helper.pyi +78 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
- aip_agents/utils/reference_helper.py +273 -0
- aip_agents/utils/reference_helper.pyi +81 -0
- aip_agents/utils/sse_chunk_transformer.py +831 -0
- aip_agents/utils/sse_chunk_transformer.pyi +166 -0
- aip_agents/utils/step_limit_manager.py +265 -0
- aip_agents/utils/step_limit_manager.pyi +112 -0
- aip_agents/utils/token_usage_helper.py +156 -0
- aip_agents/utils/token_usage_helper.pyi +60 -0
- aip_agents_binary-0.6.4.dist-info/METADATA +673 -0
- aip_agents_binary-0.6.4.dist-info/RECORD +612 -0
- aip_agents_binary-0.6.4.dist-info/WHEEL +5 -0
- aip_agents_binary-0.6.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.utils.logger import LoggerManager as LoggerManager
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
logger: Incomplete
|
|
6
|
+
|
|
7
|
+
def normalize_enable_pii(enable_pii: Any) -> bool | None:
|
|
8
|
+
"""Normalize enable_pii value from agent configuration.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
enable_pii: Raw enable_pii value from agent configuration.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
The normalized enable_pii flag when explicitly set (True/False), otherwise None.
|
|
15
|
+
"""
|
|
16
|
+
def add_pii_mappings(left: dict[str, str] | None, right: dict[str, str] | None) -> dict[str, str]:
|
|
17
|
+
"""Reducer function to merge PII mappings from multiple sources.
|
|
18
|
+
|
|
19
|
+
This is a LangGraph reducer function that merges PII mappings from:
|
|
20
|
+
- Parent agent's initial mapping
|
|
21
|
+
- Tool outputs with newly discovered PII
|
|
22
|
+
- Subagent responses with their discovered PII
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
left: Existing PII mapping (or None)
|
|
26
|
+
right: New PII mapping to merge (or None)
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Merged PII mapping dictionary
|
|
30
|
+
|
|
31
|
+
Note:
|
|
32
|
+
- Right (new) mappings take precedence over left (existing)
|
|
33
|
+
- Handles None/non-dict cases gracefully
|
|
34
|
+
- Preserves all unique PII tags
|
|
35
|
+
- Returns empty dict if both inputs are None/empty
|
|
36
|
+
"""
|
|
37
|
+
def extract_pii_mapping_from_agent_response(result: Any) -> dict[str, str] | None:
|
|
38
|
+
"""Extract PII mapping from subagent response.
|
|
39
|
+
|
|
40
|
+
Used by DelegationToolManager to propagate PII mappings from subagents
|
|
41
|
+
back to parent agents.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
result: The result returned by the delegated agent
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
PII mapping dictionary if found, None otherwise
|
|
48
|
+
|
|
49
|
+
Note:
|
|
50
|
+
- Checks if result is a dict
|
|
51
|
+
- Extracts 'full_final_state' from result
|
|
52
|
+
- Extracts 'pii_mapping' from full_final_state
|
|
53
|
+
- Validates mapping is a non-empty dict
|
|
54
|
+
- Returns None if any step fails
|
|
55
|
+
"""
|
|
56
|
+
def deanonymize_final_response_content(content: str, is_final_response: bool, metadata: dict[str, Any] | None) -> str:
|
|
57
|
+
"""Deanonymize final response content using PII mapping from metadata.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
content: Final response content that may contain PII tags.
|
|
61
|
+
is_final_response: Flag indicating whether this message is a final response.
|
|
62
|
+
metadata: Optional metadata dict (or event payload containing ``metadata``) with
|
|
63
|
+
``pii_mapping`` tag-to-value mapping.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Content string with PII tags replaced by real values when applicable.
|
|
67
|
+
"""
|
|
68
|
+
def anonymize_final_response_content(content: str, metadata: dict[str, Any] | None) -> str:
|
|
69
|
+
"""Anonymize final response content using PII mapping from metadata.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
content: Final response content that may contain real PII values.
|
|
73
|
+
metadata: Metadata dict (or event payload containing ``metadata``) with
|
|
74
|
+
``pii_mapping`` tag-to-value mapping.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Content string with real PII values replaced by their PII tags when mapping is present.
|
|
78
|
+
"""
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""UUID-based deanonymizer mapping utilities.
|
|
2
|
+
|
|
3
|
+
This module provides a UUID-based implementation of the deanonymizer mapping,
|
|
4
|
+
where anonymized entities are suffixed with UUIDs instead of sequential numbers.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Fachriza Adhiatma (fachriza.d.adhiatma@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
import re
|
|
12
|
+
import uuid
|
|
13
|
+
from collections import defaultdict
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from gllm_privacy.pii_detector.utils.deanonymizer_mapping import (
|
|
18
|
+
DeanonymizerMapping,
|
|
19
|
+
MappingDataType,
|
|
20
|
+
)
|
|
21
|
+
except ImportError: # pragma: no cover
|
|
22
|
+
MappingDataType = dict[str, dict[str, str]]
|
|
23
|
+
|
|
24
|
+
class DeanonymizerMapping: # type: ignore[no-redef]
|
|
25
|
+
"""Fallback deanonymizer mapping when optional dependency is missing.
|
|
26
|
+
|
|
27
|
+
This class exists only to keep the module importable when `gllm-privacy`
|
|
28
|
+
is not installed.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
32
|
+
"""Initialize the mapping.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ImportError: Always raised because `gllm-privacy` is required.
|
|
36
|
+
"""
|
|
37
|
+
raise ImportError("optional dependency 'gllm-privacy' is required for UUIDDeanonymizerMapping")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
from aip_agents.utils.constants import DEFAULT_PII_TAG_NAMESPACE
|
|
41
|
+
|
|
42
|
+
logger = logging.getLogger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def format_operator_with_uuid(operator_name: str, uuid_suffix: str) -> str:
|
|
46
|
+
"""Format the operator name with a UUID suffix.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
operator_name: The operator name.
|
|
50
|
+
uuid_suffix: The UUID suffix to append.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
The formatted operator name with UUID suffix.
|
|
54
|
+
"""
|
|
55
|
+
clean_operator_name = re.sub(r"[<>]", "", operator_name)
|
|
56
|
+
clean_operator_name = re.sub(r"_[a-f0-9-]+$", "", clean_operator_name)
|
|
57
|
+
|
|
58
|
+
if operator_name.startswith("<") and operator_name.endswith(">"):
|
|
59
|
+
return f"<{clean_operator_name}_{uuid_suffix}>"
|
|
60
|
+
else:
|
|
61
|
+
return f"{clean_operator_name}_{uuid_suffix}"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class UUIDDeanonymizerMapping(DeanonymizerMapping):
|
|
65
|
+
"""Class to store the deanonymizer mapping with UUID suffixes.
|
|
66
|
+
|
|
67
|
+
This class extends DeanonymizerMapping to use UUID suffixes instead of
|
|
68
|
+
sequential numbers for differentiating multiple entities of the same type.
|
|
69
|
+
|
|
70
|
+
Attributes:
|
|
71
|
+
mapping: The deanonymizer mapping.
|
|
72
|
+
skip_format_duplicates: Whether to skip formatting duplicated operators.
|
|
73
|
+
uuid_length: The length of the UUID suffix to use (default: 8).
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
mapping: MappingDataType | None = None,
|
|
79
|
+
skip_format_duplicates: bool = False,
|
|
80
|
+
uuid_length: int = 8,
|
|
81
|
+
) -> None:
|
|
82
|
+
"""Initialize UUIDDeanonymizerMapping.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
mapping: The deanonymizer mapping. If None, creates an empty defaultdict(dict).
|
|
86
|
+
skip_format_duplicates: Whether to skip formatting duplicated operators.
|
|
87
|
+
uuid_length: The length of the UUID suffix to use (default: 8).
|
|
88
|
+
"""
|
|
89
|
+
if mapping is None:
|
|
90
|
+
mapping = defaultdict(dict)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
super().__init__(mapping=mapping, skip_format_duplicates=skip_format_duplicates)
|
|
94
|
+
except TypeError as exc:
|
|
95
|
+
logger.warning(
|
|
96
|
+
"DeanonymizerMapping init skipped due to incompatible signature; " "using local attributes only: %s",
|
|
97
|
+
exc,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
self.mapping = mapping
|
|
101
|
+
self.skip_format_duplicates = skip_format_duplicates
|
|
102
|
+
self.uuid_length = uuid_length
|
|
103
|
+
|
|
104
|
+
def update(self, new_mapping: MappingDataType, use_uuid_suffix: bool | None = None) -> None:
|
|
105
|
+
"""Update the deanonymizer mapping with new values using UUID suffixes.
|
|
106
|
+
|
|
107
|
+
Duplicated values will not be added. If there are multiple entities of the same type,
|
|
108
|
+
the mapping will include a UUID suffix to differentiate them. For example, if there are
|
|
109
|
+
two names in the input text, the mapping will include NAME_<uuid1> and NAME_<uuid2>.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
new_mapping: The new mapping to be added to the existing deanonymizer mapping.
|
|
113
|
+
use_uuid_suffix: Whether to apply UUID suffixes to keys.
|
|
114
|
+
If True, keys will always be formatted with UUID suffixes.
|
|
115
|
+
If False, keys will be used as-is without UUID formatting.
|
|
116
|
+
If None, behavior falls back to the instance configuration via
|
|
117
|
+
skip_format_duplicates (preserving existing behavior).
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
None
|
|
121
|
+
"""
|
|
122
|
+
seen_values: set[str] = set()
|
|
123
|
+
format_with_uuid = self._should_format_with_uuid(use_uuid_suffix)
|
|
124
|
+
|
|
125
|
+
for entity_type, values in new_mapping.items():
|
|
126
|
+
self._update_entity_type(entity_type, values, seen_values, format_with_uuid)
|
|
127
|
+
|
|
128
|
+
def _update_entity_type(
|
|
129
|
+
self,
|
|
130
|
+
entity_type: str,
|
|
131
|
+
values: dict[str, str],
|
|
132
|
+
seen_values: set[str],
|
|
133
|
+
format_with_uuid: bool,
|
|
134
|
+
) -> None:
|
|
135
|
+
"""Update mapping entries for a single entity type.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
entity_type: The entity category being updated.
|
|
139
|
+
values: Mapping of anonymized keys to original values for the entity.
|
|
140
|
+
seen_values: Set tracking values already processed in this update call.
|
|
141
|
+
format_with_uuid: Whether UUID formatting should be applied to keys.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
None
|
|
145
|
+
"""
|
|
146
|
+
for key, value in values.items():
|
|
147
|
+
if not self._should_store_value(entity_type, value, seen_values):
|
|
148
|
+
continue
|
|
149
|
+
|
|
150
|
+
new_key = self._format_key(key, value, format_with_uuid)
|
|
151
|
+
self.mapping[entity_type][new_key] = value
|
|
152
|
+
seen_values.add(value)
|
|
153
|
+
|
|
154
|
+
def _should_format_with_uuid(self, use_uuid_suffix: bool | None) -> bool:
|
|
155
|
+
"""Determine whether UUID suffix formatting is required.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
use_uuid_suffix: Override controlling UUID formatting behavior.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
True if UUID suffixes should be applied, otherwise False.
|
|
162
|
+
"""
|
|
163
|
+
if use_uuid_suffix is None:
|
|
164
|
+
return not self.skip_format_duplicates
|
|
165
|
+
return use_uuid_suffix
|
|
166
|
+
|
|
167
|
+
def _should_store_value(self, entity_type: str, value: str, seen_values: set[str]) -> bool:
|
|
168
|
+
"""Check if the provided value should be stored in the mapping.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
entity_type: Entity category being updated.
|
|
172
|
+
value: Original value corresponding to the anonymized key.
|
|
173
|
+
seen_values: Values already processed during this update call.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
True if the value is new for the entity type and current update scope.
|
|
177
|
+
"""
|
|
178
|
+
return value not in seen_values and value not in self.mapping[entity_type].values()
|
|
179
|
+
|
|
180
|
+
def _format_key(self, key: str, value: str, format_with_uuid: bool) -> str:
|
|
181
|
+
"""Return the appropriate key representation based on format flag.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
key: Original anonymized key produced by the detector.
|
|
185
|
+
value: Original value used to derive deterministic UUID suffixes.
|
|
186
|
+
format_with_uuid: Whether UUID suffix formatting should be applied.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
The formatted key respecting the desired UUID formatting behavior.
|
|
190
|
+
"""
|
|
191
|
+
if not format_with_uuid:
|
|
192
|
+
return key
|
|
193
|
+
|
|
194
|
+
uuid_suffix = uuid.uuid5(DEFAULT_PII_TAG_NAMESPACE, value).hex[: self.uuid_length]
|
|
195
|
+
return format_operator_with_uuid(key, uuid_suffix)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.utils.constants import DEFAULT_PII_TAG_NAMESPACE as DEFAULT_PII_TAG_NAMESPACE
|
|
3
|
+
from gllm_privacy.pii_detector.utils.deanonymizer_mapping import DeanonymizerMapping, MappingDataType
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
MappingDataType = dict[str, dict[str, str]]
|
|
7
|
+
|
|
8
|
+
class DeanonymizerMapping:
|
|
9
|
+
"""Fallback deanonymizer mapping when optional dependency is missing.
|
|
10
|
+
|
|
11
|
+
This class exists only to keep the module importable when `gllm-privacy`
|
|
12
|
+
is not installed.
|
|
13
|
+
"""
|
|
14
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
15
|
+
"""Initialize the mapping.
|
|
16
|
+
|
|
17
|
+
Raises:
|
|
18
|
+
ImportError: Always raised because `gllm-privacy` is required.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
logger: Incomplete
|
|
22
|
+
|
|
23
|
+
def format_operator_with_uuid(operator_name: str, uuid_suffix: str) -> str:
|
|
24
|
+
"""Format the operator name with a UUID suffix.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
operator_name: The operator name.
|
|
28
|
+
uuid_suffix: The UUID suffix to append.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
The formatted operator name with UUID suffix.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
class UUIDDeanonymizerMapping(DeanonymizerMapping):
|
|
35
|
+
"""Class to store the deanonymizer mapping with UUID suffixes.
|
|
36
|
+
|
|
37
|
+
This class extends DeanonymizerMapping to use UUID suffixes instead of
|
|
38
|
+
sequential numbers for differentiating multiple entities of the same type.
|
|
39
|
+
|
|
40
|
+
Attributes:
|
|
41
|
+
mapping: The deanonymizer mapping.
|
|
42
|
+
skip_format_duplicates: Whether to skip formatting duplicated operators.
|
|
43
|
+
uuid_length: The length of the UUID suffix to use (default: 8).
|
|
44
|
+
"""
|
|
45
|
+
mapping: Incomplete
|
|
46
|
+
skip_format_duplicates: Incomplete
|
|
47
|
+
uuid_length: Incomplete
|
|
48
|
+
def __init__(self, mapping: MappingDataType | None = None, skip_format_duplicates: bool = False, uuid_length: int = 8) -> None:
|
|
49
|
+
"""Initialize UUIDDeanonymizerMapping.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
mapping: The deanonymizer mapping. If None, creates an empty defaultdict(dict).
|
|
53
|
+
skip_format_duplicates: Whether to skip formatting duplicated operators.
|
|
54
|
+
uuid_length: The length of the UUID suffix to use (default: 8).
|
|
55
|
+
"""
|
|
56
|
+
def update(self, new_mapping: MappingDataType, use_uuid_suffix: bool | None = None) -> None:
|
|
57
|
+
"""Update the deanonymizer mapping with new values using UUID suffixes.
|
|
58
|
+
|
|
59
|
+
Duplicated values will not be added. If there are multiple entities of the same type,
|
|
60
|
+
the mapping will include a UUID suffix to differentiate them. For example, if there are
|
|
61
|
+
two names in the input text, the mapping will include NAME_<uuid1> and NAME_<uuid2>.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
new_mapping: The new mapping to be added to the existing deanonymizer mapping.
|
|
65
|
+
use_uuid_suffix: Whether to apply UUID suffixes to keys.
|
|
66
|
+
If True, keys will always be formatted with UUID suffixes.
|
|
67
|
+
If False, keys will be used as-is without UUID formatting.
|
|
68
|
+
If None, behavior falls back to the instance configuration via
|
|
69
|
+
skip_format_duplicates (preserving existing behavior).
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
None
|
|
73
|
+
"""
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""Reference helper utilities for handling and validating reference data.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from gllm_core.schema import Chunk
|
|
10
|
+
from langgraph.types import Command
|
|
11
|
+
|
|
12
|
+
from aip_agents.utils.logger import get_logger
|
|
13
|
+
from aip_agents.utils.metadata_helper import MetadataFieldKeys
|
|
14
|
+
|
|
15
|
+
logger = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Tool attribute constants for reference extraction
|
|
19
|
+
SAVE_OUTPUT_HISTORY_ATTR = "save_output_history"
|
|
20
|
+
FORMAT_AGENT_REFERENCE = "_format_agent_reference"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def extract_references_from_tool(tool: Any, tool_output: Any) -> list[Chunk]:
|
|
24
|
+
"""Extract reference data from tools that support it.
|
|
25
|
+
|
|
26
|
+
Extraction priority:
|
|
27
|
+
1. Direct tool references via _format_agent_reference (preferred)
|
|
28
|
+
2. Command.update references (fallback for delegation tools)
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
tool: The tool instance to extract references from
|
|
32
|
+
tool_output: The output from the tool execution
|
|
33
|
+
Returns:
|
|
34
|
+
List of deduplicated Chunk objects containing reference data
|
|
35
|
+
|
|
36
|
+
Note:
|
|
37
|
+
- Never raises exceptions; logs warnings for issues
|
|
38
|
+
- Direct tool references take precedence over Command references
|
|
39
|
+
"""
|
|
40
|
+
if getattr(tool, SAVE_OUTPUT_HISTORY_ATTR, False):
|
|
41
|
+
logger.debug(
|
|
42
|
+
"Ignoring save_output_history for %s during reference extraction.",
|
|
43
|
+
tool.__class__.__name__,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Prefer direct tool references
|
|
47
|
+
direct_references = _extract_direct_tool_references(tool, tool_output)
|
|
48
|
+
if direct_references:
|
|
49
|
+
return validate_references(direct_references)
|
|
50
|
+
|
|
51
|
+
if isinstance(tool_output, Command):
|
|
52
|
+
command_references = extract_references_from_command_update(tool_output)
|
|
53
|
+
if command_references:
|
|
54
|
+
return validate_references(command_references)
|
|
55
|
+
|
|
56
|
+
return []
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _extract_direct_tool_references(tool: Any, tool_output: Any) -> list[Any]:
|
|
60
|
+
"""Extract references directly from tool hooks when available.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
tool: The tool instance to extract references from
|
|
64
|
+
tool_output: The output from the tool execution
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
List of reference data (not yet validated/deduplicated)
|
|
68
|
+
"""
|
|
69
|
+
if not hasattr(tool, FORMAT_AGENT_REFERENCE):
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
reference_data = tool._format_agent_reference(tool_output)
|
|
74
|
+
except (AttributeError, ValueError, TypeError) as e:
|
|
75
|
+
logger.warning(f"Failed to extract references from {tool.__class__.__name__}: {e}")
|
|
76
|
+
return []
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.error(
|
|
79
|
+
f"Unexpected error extracting references from {tool.__class__.__name__}: {e}",
|
|
80
|
+
exc_info=True,
|
|
81
|
+
)
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
return _normalize_reference_data(reference_data, tool)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _normalize_reference_data(reference_data: Any, tool: Any | None = None) -> list[Any]:
|
|
88
|
+
"""Normalize reference payloads into a list for downstream processing.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
reference_data: Arbitrary payload returned by a tool or command.
|
|
92
|
+
tool: Optional tool instance used for contextual logging when payload type is invalid.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
A list of reference objects ready for validation. Returns an empty list when
|
|
96
|
+
the payload is ``None`` or cannot be interpreted as a reference collection.
|
|
97
|
+
|
|
98
|
+
Notes:
|
|
99
|
+
- Accepts `Chunk` instances and wraps them in a list.
|
|
100
|
+
- Pass-through for list inputs to preserve existing semantics.
|
|
101
|
+
- Emits a warning when encountering unsupported payload types, including
|
|
102
|
+
the originating tool class when available.
|
|
103
|
+
"""
|
|
104
|
+
if reference_data is None:
|
|
105
|
+
return []
|
|
106
|
+
if isinstance(reference_data, Chunk):
|
|
107
|
+
return [reference_data]
|
|
108
|
+
if isinstance(reference_data, list):
|
|
109
|
+
return reference_data
|
|
110
|
+
|
|
111
|
+
if tool is not None:
|
|
112
|
+
logger.warning(
|
|
113
|
+
"Invalid reference data format from %s: %s",
|
|
114
|
+
tool.__class__.__name__,
|
|
115
|
+
reference_data,
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
logger.warning("Invalid reference data format: %s", reference_data)
|
|
119
|
+
|
|
120
|
+
return []
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def extract_references_from_command_update(command: Command) -> list[Any]:
|
|
124
|
+
"""Extract references from a Command object's update dictionary.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
command: A Command object potentially containing references in its update dict.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
List of reference data (not yet validated/deduplicated)
|
|
131
|
+
|
|
132
|
+
Note:
|
|
133
|
+
- Never raises exceptions; logs warnings for malformed data
|
|
134
|
+
- Skips non-Chunk items with warning log
|
|
135
|
+
"""
|
|
136
|
+
update = getattr(command, "update", None)
|
|
137
|
+
if not isinstance(update, dict):
|
|
138
|
+
return []
|
|
139
|
+
|
|
140
|
+
raw_refs = update.get(MetadataFieldKeys.REFERENCES)
|
|
141
|
+
if not isinstance(raw_refs, list):
|
|
142
|
+
return []
|
|
143
|
+
|
|
144
|
+
valid_refs = []
|
|
145
|
+
for ref in raw_refs:
|
|
146
|
+
if isinstance(ref, Chunk):
|
|
147
|
+
valid_refs.append(ref)
|
|
148
|
+
else:
|
|
149
|
+
logger.warning(
|
|
150
|
+
"Ignoring non-Chunk reference payload from delegation command: %s (type: %s)",
|
|
151
|
+
ref,
|
|
152
|
+
type(ref).__name__,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
return valid_refs
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def validate_references(references: list[Any]) -> list[Chunk]:
|
|
159
|
+
"""Validate and deduplicate reference data.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
references: List of reference data (expected to be Chunk objects).
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
List of validated, deduplicated Chunk objects by content.
|
|
166
|
+
"""
|
|
167
|
+
if not references:
|
|
168
|
+
return []
|
|
169
|
+
|
|
170
|
+
validated = []
|
|
171
|
+
seen_content = set()
|
|
172
|
+
|
|
173
|
+
for ref in references:
|
|
174
|
+
# Skip non-Chunk objects
|
|
175
|
+
if not isinstance(ref, Chunk):
|
|
176
|
+
logger.debug(f"Skipping non-Chunk reference: {type(ref)}")
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
# Skip invalid content/metadata
|
|
180
|
+
if not isinstance(ref.content, str | bytes) or not isinstance(ref.metadata, dict):
|
|
181
|
+
logger.debug(f"Skipping reference with invalid content/metadata: {type(ref.content)}, {type(ref.metadata)}")
|
|
182
|
+
continue
|
|
183
|
+
|
|
184
|
+
# Deduplicate by content
|
|
185
|
+
if ref.content not in seen_content:
|
|
186
|
+
seen_content.add(ref.content)
|
|
187
|
+
validated.append(ref)
|
|
188
|
+
|
|
189
|
+
return validated
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def serialize_references_for_metadata(references: list[Any]) -> list[dict[str, Any]]:
|
|
193
|
+
"""Serialize references for inclusion in A2A metadata.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
references: List of reference objects (typically Chunk objects).
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
List of serialized reference dictionaries.
|
|
200
|
+
"""
|
|
201
|
+
serialized_refs = []
|
|
202
|
+
for ref in references:
|
|
203
|
+
if hasattr(ref, "model_dump"):
|
|
204
|
+
# For Pydantic models like Chunk
|
|
205
|
+
serialized_refs.append(ref.model_dump(mode="python"))
|
|
206
|
+
elif isinstance(ref, dict):
|
|
207
|
+
# Plain dicts pass through unchanged
|
|
208
|
+
serialized_refs.append(ref)
|
|
209
|
+
elif hasattr(ref, "__dict__"):
|
|
210
|
+
# For regular objects with attributes
|
|
211
|
+
serialized_refs.append(ref.__dict__)
|
|
212
|
+
else:
|
|
213
|
+
# Fallback for other types
|
|
214
|
+
serialized_refs.append(str(ref))
|
|
215
|
+
return serialized_refs
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def add_references_chunks(left: list[Chunk], right: list[Chunk]) -> list[Chunk]:
|
|
219
|
+
"""Reducer function to accumulate reference data from multiple tool calls.
|
|
220
|
+
|
|
221
|
+
This is a LangGraph reducer function that should be forgiving and handle
|
|
222
|
+
edge cases gracefully. Non-Chunk items are filtered out.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
left: Existing list of reference chunks (or None/non-list)
|
|
226
|
+
right: New list of reference chunks to add (or None/non-list)
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Combined list of valid Chunk objects
|
|
230
|
+
"""
|
|
231
|
+
# Handle None/non-list cases by converting to empty lists
|
|
232
|
+
left_list = left if isinstance(left, list) else []
|
|
233
|
+
right_list = right if isinstance(right, list) else []
|
|
234
|
+
|
|
235
|
+
# Filter to only include valid Chunk objects
|
|
236
|
+
valid_left = [item for item in left_list if isinstance(item, Chunk)]
|
|
237
|
+
valid_right = [item for item in right_list if isinstance(item, Chunk)]
|
|
238
|
+
|
|
239
|
+
# Handle empty cases efficiently
|
|
240
|
+
if not valid_left:
|
|
241
|
+
return valid_right
|
|
242
|
+
if not valid_right:
|
|
243
|
+
return valid_left
|
|
244
|
+
|
|
245
|
+
return valid_left + valid_right
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def extract_references_from_agent_response(result: Any) -> list[dict[str, Any]] | None:
|
|
249
|
+
"""Extract references from agent response for delegation tools.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
result: The result returned by the delegated agent.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
List of reference chunks if found, None otherwise.
|
|
256
|
+
"""
|
|
257
|
+
if not isinstance(result, dict):
|
|
258
|
+
return None
|
|
259
|
+
|
|
260
|
+
full_state = result.get("full_final_state", {})
|
|
261
|
+
if not isinstance(full_state, dict):
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
references = full_state.get("references")
|
|
265
|
+
if not isinstance(references, list) or not references:
|
|
266
|
+
return None
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
validated_refs = validate_references(references)
|
|
270
|
+
return validated_refs if validated_refs else None
|
|
271
|
+
except Exception as e:
|
|
272
|
+
logger.warning(f"ExtractRefFromAgentResponse: Error validating references: {e}")
|
|
273
|
+
return None
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.utils.logger import get_logger as get_logger
|
|
3
|
+
from aip_agents.utils.metadata_helper import MetadataFieldKeys as MetadataFieldKeys
|
|
4
|
+
from gllm_core.schema import Chunk
|
|
5
|
+
from langgraph.types import Command
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
logger: Incomplete
|
|
9
|
+
SAVE_OUTPUT_HISTORY_ATTR: str
|
|
10
|
+
FORMAT_AGENT_REFERENCE: str
|
|
11
|
+
|
|
12
|
+
def extract_references_from_tool(tool: Any, tool_output: Any) -> list[Chunk]:
|
|
13
|
+
"""Extract reference data from tools that support it.
|
|
14
|
+
|
|
15
|
+
Extraction priority:
|
|
16
|
+
1. Direct tool references via _format_agent_reference (preferred)
|
|
17
|
+
2. Command.update references (fallback for delegation tools)
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
tool: The tool instance to extract references from
|
|
21
|
+
tool_output: The output from the tool execution
|
|
22
|
+
Returns:
|
|
23
|
+
List of deduplicated Chunk objects containing reference data
|
|
24
|
+
|
|
25
|
+
Note:
|
|
26
|
+
- Never raises exceptions; logs warnings for issues
|
|
27
|
+
- Direct tool references take precedence over Command references
|
|
28
|
+
"""
|
|
29
|
+
def extract_references_from_command_update(command: Command) -> list[Any]:
|
|
30
|
+
"""Extract references from a Command object's update dictionary.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
command: A Command object potentially containing references in its update dict.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
List of reference data (not yet validated/deduplicated)
|
|
37
|
+
|
|
38
|
+
Note:
|
|
39
|
+
- Never raises exceptions; logs warnings for malformed data
|
|
40
|
+
- Skips non-Chunk items with warning log
|
|
41
|
+
"""
|
|
42
|
+
def validate_references(references: list[Any]) -> list[Chunk]:
|
|
43
|
+
"""Validate and deduplicate reference data.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
references: List of reference data (expected to be Chunk objects).
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
List of validated, deduplicated Chunk objects by content.
|
|
50
|
+
"""
|
|
51
|
+
def serialize_references_for_metadata(references: list[Any]) -> list[dict[str, Any]]:
|
|
52
|
+
"""Serialize references for inclusion in A2A metadata.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
references: List of reference objects (typically Chunk objects).
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
List of serialized reference dictionaries.
|
|
59
|
+
"""
|
|
60
|
+
def add_references_chunks(left: list[Chunk], right: list[Chunk]) -> list[Chunk]:
|
|
61
|
+
"""Reducer function to accumulate reference data from multiple tool calls.
|
|
62
|
+
|
|
63
|
+
This is a LangGraph reducer function that should be forgiving and handle
|
|
64
|
+
edge cases gracefully. Non-Chunk items are filtered out.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
left: Existing list of reference chunks (or None/non-list)
|
|
68
|
+
right: New list of reference chunks to add (or None/non-list)
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Combined list of valid Chunk objects
|
|
72
|
+
"""
|
|
73
|
+
def extract_references_from_agent_response(result: Any) -> list[dict[str, Any]] | None:
|
|
74
|
+
"""Extract references from agent response for delegation tools.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
result: The result returned by the delegated agent.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
List of reference chunks if found, None otherwise.
|
|
81
|
+
"""
|