aip-agents-binary 0.5.25b1__py3-none-macosx_13_0_arm64.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.
- 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 +2948 -0
- aip_agents/agent/base_langgraph_agent.pyi +232 -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 +433 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +49 -0
- aip_agents/agent/langgraph_react_agent.py +2596 -0
- aip_agents/agent/langgraph_react_agent.pyi +131 -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/demo_memory_recall.py +401 -0
- aip_agents/examples/demo_memory_recall.pyi +58 -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_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 +46 -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 +193 -0
- aip_agents/mcp/client/connection_manager.pyi +48 -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 +362 -0
- aip_agents/mcp/client/persistent_session.pyi +113 -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 +228 -0
- aip_agents/mcp/client/transports.pyi +123 -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 +717 -0
- aip_agents/memory/adapters/base_adapter.pyi +150 -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/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 +53 -0
- aip_agents/tools/__init__.pyi +9 -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 +1112 -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 +813 -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/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/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 +22 -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 +258 -0
- aip_agents/tools/memory_search/mem0.pyi +19 -0
- aip_agents/tools/memory_search/schema.py +48 -0
- aip_agents/tools/memory_search/schema.pyi +15 -0
- aip_agents/tools/memory_search_tool.py +26 -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 +1071 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
- aip_agents/utils/langgraph/tool_output_management.py +967 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +292 -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.5.25b1.dist-info/METADATA +681 -0
- aip_agents_binary-0.5.25b1.dist-info/RECORD +566 -0
- aip_agents_binary-0.5.25b1.dist-info/WHEEL +5 -0
- aip_agents_binary-0.5.25b1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Tool to get the current time.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from datetime import datetime, timedelta, timezone, tzinfo
|
|
9
|
+
|
|
10
|
+
from dateutil import tz
|
|
11
|
+
from langchain_core.tools import BaseTool
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
FORMAT_STRING = "%m/%d/%y %H:%M:%S"
|
|
15
|
+
DEFAULT_TIMEZONE = "UTC+7"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TimeToolInput(BaseModel):
|
|
19
|
+
"""Input schema for the TimeTool."""
|
|
20
|
+
|
|
21
|
+
datetime_format: str = Field(
|
|
22
|
+
default=FORMAT_STRING,
|
|
23
|
+
description="""
|
|
24
|
+
Optional datetime format string. Default: '%m/%d/%y %H:%M:%S'
|
|
25
|
+
|
|
26
|
+
Common format codes:
|
|
27
|
+
%Y: Year with century (2024)
|
|
28
|
+
%m: Month as number (01-12)
|
|
29
|
+
%d: Day of month (01-31)
|
|
30
|
+
%A: Full weekday name (Wednesday)
|
|
31
|
+
%a: Short weekday name (Wed)
|
|
32
|
+
%H: Hour (00-23)
|
|
33
|
+
%M: Minute (00-59)
|
|
34
|
+
%S: Second (00-59)
|
|
35
|
+
%Z: Timezone name
|
|
36
|
+
%j: Day of year (001-366)
|
|
37
|
+
%W: Week number (00-53, Monday first)
|
|
38
|
+
%U: Week number (00-53, Sunday first)
|
|
39
|
+
%c: Locale's date and time
|
|
40
|
+
%x: Locale's date
|
|
41
|
+
%X: Locale's time
|
|
42
|
+
""",
|
|
43
|
+
)
|
|
44
|
+
timezone: str | None = Field(
|
|
45
|
+
default=DEFAULT_TIMEZONE,
|
|
46
|
+
description="""
|
|
47
|
+
Optional timezone identifier. Supports IANA names (e.g., 'Asia/Jakarta')
|
|
48
|
+
or offsets (e.g., 'UTC+7', 'UTC-04:30'). Default: 'UTC+7' (Asia/Jakarta).
|
|
49
|
+
Highly recommended to be filled when getting the current time to ensure
|
|
50
|
+
the time is in the correct timezone.
|
|
51
|
+
""",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _parse_timezone(timezone_value: str | None) -> tzinfo | None:
|
|
56
|
+
"""Return a tzinfo instance for a given timezone string.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
timezone_value: Timezone string (e.g., "UTC+7", "UTC-5:30") or None.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
tzinfo instance or None if invalid/None input.
|
|
63
|
+
"""
|
|
64
|
+
if timezone_value is None:
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
tz_string = timezone_value.strip()
|
|
68
|
+
if not tz_string:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
offset_match = re.fullmatch(r"UTC([+-])(\d{1,2})(?::?(\d{2}))?$", tz_string.upper())
|
|
72
|
+
if offset_match:
|
|
73
|
+
sign, hours_str, minutes_str = offset_match.groups()
|
|
74
|
+
hours = int(hours_str)
|
|
75
|
+
minutes = int(minutes_str) if minutes_str else 0
|
|
76
|
+
MAX_HOURS_OFFSET = 12
|
|
77
|
+
MINUTES_OFFSETS = [0, 30, 45]
|
|
78
|
+
if hours > MAX_HOURS_OFFSET or minutes not in MINUTES_OFFSETS:
|
|
79
|
+
raise ValueError(f"Invalid timezone offset: {timezone_value}")
|
|
80
|
+
delta = timedelta(hours=hours, minutes=minutes)
|
|
81
|
+
if sign == "-":
|
|
82
|
+
delta = -delta
|
|
83
|
+
return timezone(delta)
|
|
84
|
+
|
|
85
|
+
tzinfo = tz.gettz(tz_string)
|
|
86
|
+
if tzinfo is not None:
|
|
87
|
+
return tzinfo
|
|
88
|
+
|
|
89
|
+
raise ValueError(f"Unknown timezone: {timezone_value}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class TimeTool(BaseTool):
|
|
93
|
+
"""Tool to get the current time."""
|
|
94
|
+
|
|
95
|
+
name: str = "time_tool"
|
|
96
|
+
description: str = """
|
|
97
|
+
Useful for getting the current time in a specified format and timezone.
|
|
98
|
+
Default format: '%m/%d/%y %H:%M:%S' (e.g., '05/15/24 17:30:00')
|
|
99
|
+
|
|
100
|
+
Supports timezone specification to get the current time in any timezone.
|
|
101
|
+
It is highly recommended to specify a timezone to ensure accurate results.
|
|
102
|
+
"""
|
|
103
|
+
args_schema: type[BaseModel] = TimeToolInput
|
|
104
|
+
|
|
105
|
+
def _run(self, datetime_format: str = FORMAT_STRING, timezone: str | None = DEFAULT_TIMEZONE) -> str:
|
|
106
|
+
"""Get current time formatted according to the specified format and timezone.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
datetime_format: Format string for datetime (default: ISO format).
|
|
110
|
+
timezone: Timezone string (default: UTC).
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Formatted datetime string.
|
|
114
|
+
"""
|
|
115
|
+
tzinfo = _parse_timezone(timezone)
|
|
116
|
+
current_time = datetime.now(tz=tzinfo)
|
|
117
|
+
return current_time.strftime(datetime_format)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from langchain_core.tools import BaseTool
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
FORMAT_STRING: str
|
|
5
|
+
DEFAULT_TIMEZONE: str
|
|
6
|
+
|
|
7
|
+
class TimeToolInput(BaseModel):
|
|
8
|
+
"""Input schema for the TimeTool."""
|
|
9
|
+
datetime_format: str
|
|
10
|
+
timezone: str | None
|
|
11
|
+
|
|
12
|
+
class TimeTool(BaseTool):
|
|
13
|
+
"""Tool to get the current time."""
|
|
14
|
+
name: str
|
|
15
|
+
description: str
|
|
16
|
+
args_schema: type[BaseModel]
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"""Tool Configuration Injector for existing LangChain tools.
|
|
2
|
+
|
|
3
|
+
This module provides utilities to inject Pydantic-based configuration into existing
|
|
4
|
+
LangChain tools without requiring inheritance or modification of the tool classes.
|
|
5
|
+
|
|
6
|
+
The SDK automatically injects configuration capabilities into tools that have a
|
|
7
|
+
tool_config_schema attribute, providing:
|
|
8
|
+
- Agent-level default configurations
|
|
9
|
+
- Runtime configuration overrides via RunnableConfig metadata
|
|
10
|
+
- Type-safe validation using Pydantic models
|
|
11
|
+
- Support for optional fields with proper default handling
|
|
12
|
+
|
|
13
|
+
Configuration Extraction Examples:
|
|
14
|
+
|
|
15
|
+
Nested format:
|
|
16
|
+
metadata = {"tool_configs": {"tool_name": {"api_key": "secret", "timeout": 30}}}
|
|
17
|
+
|
|
18
|
+
Flattened format (only works if ALL required fields are present):
|
|
19
|
+
metadata = {"api_key": "secret", "timeout": 30} # Optional fields can be omitted
|
|
20
|
+
|
|
21
|
+
Required vs Optional fields:
|
|
22
|
+
class ToolConfig(BaseModel):
|
|
23
|
+
api_key: str # Required - must be provided
|
|
24
|
+
timeout: int = 30 # Optional - will use default if not provided
|
|
25
|
+
retries: Optional[int] = None # Optional - can be None
|
|
26
|
+
|
|
27
|
+
Authors:
|
|
28
|
+
Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from typing import Any, TypeVar
|
|
32
|
+
|
|
33
|
+
from langchain_core.runnables import RunnableConfig
|
|
34
|
+
from langchain_core.tools import BaseTool
|
|
35
|
+
from pydantic import BaseModel
|
|
36
|
+
|
|
37
|
+
from aip_agents.utils.logger import get_logger
|
|
38
|
+
|
|
39
|
+
logger = get_logger(__name__)
|
|
40
|
+
|
|
41
|
+
ConfigSchema = TypeVar("ConfigSchema", bound=BaseModel)
|
|
42
|
+
|
|
43
|
+
# Public API exports
|
|
44
|
+
__all__ = [
|
|
45
|
+
"inject_config_methods_into_tool",
|
|
46
|
+
"CONFIG_SCHEMA_ATTR",
|
|
47
|
+
"CONFIG_ATTR",
|
|
48
|
+
"TOOL_CONFIG_SCHEMA_ATTR",
|
|
49
|
+
"TOOL_CONFIGS_KEY",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Constants for configuration attribute names and keys
|
|
53
|
+
CONFIG_SCHEMA_ATTR: str = "_config_schema"
|
|
54
|
+
CONFIG_ATTR: str = "_config"
|
|
55
|
+
TOOL_CONFIG_SCHEMA_ATTR: str = "tool_config_schema"
|
|
56
|
+
TOOL_CONFIGS_KEY: str = "tool_configs"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _get_config_field_names(schema: type[BaseModel]) -> list[str]:
|
|
60
|
+
"""Get field names from a Pydantic model schema.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
schema: The Pydantic model schema to get field names from.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
A list of field names.
|
|
67
|
+
"""
|
|
68
|
+
if hasattr(schema, "model_fields"):
|
|
69
|
+
return list(schema.model_fields.keys())
|
|
70
|
+
elif hasattr(schema, "__fields__"):
|
|
71
|
+
return list(schema.__fields__.keys())
|
|
72
|
+
else:
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _get_required_field_names(schema: type[BaseModel]) -> set[str]:
|
|
77
|
+
"""Get required field names from a Pydantic model schema.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
schema: The Pydantic model schema to get required field names from.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
A set of required field names.
|
|
84
|
+
"""
|
|
85
|
+
# Pydantic V2
|
|
86
|
+
if hasattr(schema, "model_fields"):
|
|
87
|
+
return {name for name, field_info in schema.model_fields.items() if field_info.is_required()}
|
|
88
|
+
|
|
89
|
+
# Pydantic V1 (fallback)
|
|
90
|
+
elif hasattr(schema, "__fields__"):
|
|
91
|
+
return {name for name, field in schema.__fields__.items() if field.required}
|
|
92
|
+
|
|
93
|
+
return set()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _extract_nested_config(tool: BaseTool, metadata: dict[str, Any]) -> ConfigSchema | None:
|
|
97
|
+
"""Extract tool config from nested tool_configs structure.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
tool: The tool instance to extract configuration from.
|
|
101
|
+
metadata: The metadata to use.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
The nested configuration.
|
|
105
|
+
"""
|
|
106
|
+
tool_configs = metadata.get(TOOL_CONFIGS_KEY, {})
|
|
107
|
+
if not isinstance(tool_configs, dict) or tool.name not in tool_configs:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
tool_config_data = tool_configs[tool.name]
|
|
111
|
+
try:
|
|
112
|
+
config_schema = getattr(tool, CONFIG_SCHEMA_ATTR)
|
|
113
|
+
if isinstance(tool_config_data, dict):
|
|
114
|
+
return config_schema(**tool_config_data)
|
|
115
|
+
elif isinstance(tool_config_data, config_schema):
|
|
116
|
+
return tool_config_data
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.debug(f"Failed to validate nested config for tool '{tool.name}': {e}")
|
|
119
|
+
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _extract_flattened_config(tool: BaseTool, metadata: dict[str, Any]) -> ConfigSchema | None:
|
|
124
|
+
"""Extract tool config from flattened metadata keys.
|
|
125
|
+
|
|
126
|
+
This function builds a configuration from metadata keys that match the tool's
|
|
127
|
+
config schema field names. Only required fields must be present; optional fields
|
|
128
|
+
with defaults will be handled by Pydantic during instantiation.
|
|
129
|
+
|
|
130
|
+
Behavior:
|
|
131
|
+
- Returns None silently if metadata is empty (likely using agent defaults)
|
|
132
|
+
- Logs debug message if metadata exists but contains no matching config fields
|
|
133
|
+
- Logs warning if some required fields are missing from provided config fields
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
tool: The tool instance to extract configuration from.
|
|
137
|
+
metadata: The metadata to use.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
The flattened configuration if all required fields are present, None otherwise.
|
|
141
|
+
"""
|
|
142
|
+
config_schema = getattr(tool, CONFIG_SCHEMA_ATTR)
|
|
143
|
+
config_fields = _get_config_field_names(config_schema)
|
|
144
|
+
required_fields = _get_required_field_names(config_schema)
|
|
145
|
+
|
|
146
|
+
if not config_fields:
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
# Extract all available config fields from metadata
|
|
150
|
+
flattened_config = {}
|
|
151
|
+
for field_name in config_fields:
|
|
152
|
+
if field_name in metadata:
|
|
153
|
+
flattened_config[field_name] = metadata[field_name]
|
|
154
|
+
|
|
155
|
+
# Only proceed if we have at least some configuration fields
|
|
156
|
+
if not flattened_config:
|
|
157
|
+
if metadata:
|
|
158
|
+
logger.debug(
|
|
159
|
+
f"No valid config fields found in flattened metadata for tool '{tool.name}'. "
|
|
160
|
+
f"Available metadata keys: {list(metadata.keys())}, "
|
|
161
|
+
f"Expected config fields: {config_fields}"
|
|
162
|
+
)
|
|
163
|
+
return None
|
|
164
|
+
|
|
165
|
+
# Check if all required fields are present
|
|
166
|
+
provided_fields = set(flattened_config.keys())
|
|
167
|
+
missing_required_fields = required_fields - provided_fields
|
|
168
|
+
|
|
169
|
+
if missing_required_fields:
|
|
170
|
+
logger.warning(f"Missing required fields for flattened config in tool '{tool.name}': {missing_required_fields}")
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
return config_schema(**flattened_config)
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.debug(f"Failed to validate flattened config for tool '{tool.name}': {e}")
|
|
177
|
+
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _extract_runtime_config(tool: BaseTool, config: RunnableConfig | None) -> ConfigSchema | None:
|
|
182
|
+
"""Extract runtime configuration from RunnableConfig metadata.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
tool: The tool instance to extract configuration from.
|
|
186
|
+
config: The configuration to use.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
The runtime configuration.
|
|
190
|
+
"""
|
|
191
|
+
if not config or not hasattr(tool, CONFIG_SCHEMA_ATTR):
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
metadata = config.get("metadata", {})
|
|
195
|
+
if not isinstance(metadata, dict):
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
# Try nested structure first
|
|
199
|
+
nested_config = _extract_nested_config(tool, metadata)
|
|
200
|
+
if nested_config is not None:
|
|
201
|
+
return nested_config
|
|
202
|
+
|
|
203
|
+
# Try flattened structure
|
|
204
|
+
return _extract_flattened_config(tool, metadata)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _create_tool_config_methods(tool: BaseTool) -> dict[str, Any]:
|
|
208
|
+
"""Create the configuration management methods for a tool.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
tool: The tool instance to create methods for.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Dictionary of method names to method functions.
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
def set_tool_config(config: ConfigSchema | dict[str, Any] | None) -> None:
|
|
218
|
+
"""Set the tool's agent-level default configuration with validation.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
config: The configuration to set.
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
ValueError: If the config is not an instance of the tool's config schema or a dictionary.
|
|
225
|
+
"""
|
|
226
|
+
if config is None:
|
|
227
|
+
object.__setattr__(tool, CONFIG_ATTR, None)
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
config_schema = getattr(tool, CONFIG_SCHEMA_ATTR)
|
|
231
|
+
if isinstance(config, dict):
|
|
232
|
+
object.__setattr__(tool, CONFIG_ATTR, config_schema(**config))
|
|
233
|
+
elif isinstance(config, config_schema):
|
|
234
|
+
object.__setattr__(tool, CONFIG_ATTR, config)
|
|
235
|
+
else:
|
|
236
|
+
config_schema_name = getattr(config_schema, "__name__", repr(config_schema))
|
|
237
|
+
raise ValueError(f"Config must be an instance of {config_schema_name} or dict, got {type(config).__name__}")
|
|
238
|
+
|
|
239
|
+
def get_default_config() -> ConfigSchema | None:
|
|
240
|
+
"""Get the agent-level default configuration.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
The agent-level default configuration.
|
|
244
|
+
"""
|
|
245
|
+
return getattr(tool, CONFIG_ATTR)
|
|
246
|
+
|
|
247
|
+
def has_tool_config() -> bool:
|
|
248
|
+
"""Check if the tool has an agent-level default configuration set.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
True if the tool has an agent-level default configuration set, False otherwise.
|
|
252
|
+
"""
|
|
253
|
+
return getattr(tool, CONFIG_ATTR) is not None
|
|
254
|
+
|
|
255
|
+
def get_tool_config(config: RunnableConfig | None = None) -> ConfigSchema | None:
|
|
256
|
+
"""Get the effective tool configuration.
|
|
257
|
+
|
|
258
|
+
This function extracts the tool configuration from the runnable configuration.
|
|
259
|
+
If the tool configuration is not found in the runnable configuration, it will
|
|
260
|
+
return the agent-level default configuration.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
config: The runnable configuration to use from LangGraph.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
The effective tool configuration.
|
|
267
|
+
"""
|
|
268
|
+
runtime_config = _extract_runtime_config(tool, config)
|
|
269
|
+
return runtime_config if runtime_config is not None else getattr(tool, CONFIG_ATTR)
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
"set_tool_config": set_tool_config,
|
|
273
|
+
"get_default_config": get_default_config,
|
|
274
|
+
"has_tool_config": has_tool_config,
|
|
275
|
+
"get_tool_config": get_tool_config,
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def inject_config_methods_into_tool(tool: BaseTool, config_schema: type[ConfigSchema]) -> None:
|
|
280
|
+
"""Inject configuration methods into a tool.
|
|
281
|
+
|
|
282
|
+
This function is used by the SDK to automatically inject configuration capabilities
|
|
283
|
+
into tools that have a tool_config_schema attribute. It can also be used directly
|
|
284
|
+
by developers who want to add configuration support to their tools.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
tool: The tool to inject configuration capabilities into.
|
|
288
|
+
config_schema: Pydantic model class for configuration validation.
|
|
289
|
+
|
|
290
|
+
Raises:
|
|
291
|
+
ValueError: If tool is not a BaseTool instance or config_schema is not a Pydantic BaseModel subclass.
|
|
292
|
+
"""
|
|
293
|
+
# Add configuration attributes
|
|
294
|
+
object.__setattr__(tool, CONFIG_SCHEMA_ATTR, config_schema)
|
|
295
|
+
object.__setattr__(tool, CONFIG_ATTR, None)
|
|
296
|
+
|
|
297
|
+
# Create and inject methods
|
|
298
|
+
methods = _create_tool_config_methods(tool)
|
|
299
|
+
for method_name, method_func in methods.items():
|
|
300
|
+
object.__setattr__(tool, method_name, method_func)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from langchain_core.tools import BaseTool
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
from typing import TypeVar
|
|
4
|
+
|
|
5
|
+
__all__ = ['inject_config_methods_into_tool', 'CONFIG_SCHEMA_ATTR', 'CONFIG_ATTR', 'TOOL_CONFIG_SCHEMA_ATTR', 'TOOL_CONFIGS_KEY']
|
|
6
|
+
|
|
7
|
+
ConfigSchema = TypeVar('ConfigSchema', bound=BaseModel)
|
|
8
|
+
CONFIG_SCHEMA_ATTR: str
|
|
9
|
+
CONFIG_ATTR: str
|
|
10
|
+
TOOL_CONFIG_SCHEMA_ATTR: str
|
|
11
|
+
TOOL_CONFIGS_KEY: str
|
|
12
|
+
|
|
13
|
+
def inject_config_methods_into_tool(tool: BaseTool, config_schema: type[ConfigSchema]) -> None:
|
|
14
|
+
"""Inject configuration methods into a tool.
|
|
15
|
+
|
|
16
|
+
This function is used by the SDK to automatically inject configuration capabilities
|
|
17
|
+
into tools that have a tool_config_schema attribute. It can also be used directly
|
|
18
|
+
by developers who want to add configuration support to their tools.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
tool: The tool to inject configuration capabilities into.
|
|
22
|
+
config_schema: Pydantic model class for configuration validation.
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
ValueError: If tool is not a BaseTool instance or config_schema is not a Pydantic BaseModel subclass.
|
|
26
|
+
"""
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Web Search Tools for AI Agents.
|
|
2
|
+
|
|
3
|
+
This package provides web search capabilities for AI agents through integration
|
|
4
|
+
with Google Serper API and Tavily Search API.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
|
|
8
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
9
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
10
|
+
Fachriza Adhiatma (fachriza.d.adhiatma@gdplabs.id)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from aip_agents.tools.web_search.serper_tool import GoogleSerperTool
|
|
14
|
+
|
|
15
|
+
__all__ = ["GoogleSerperTool"]
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""Tool to search Google Serper API.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
|
|
5
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
6
|
+
Fachriza Adhiatma (fachriza.d.adhiatma@gdplabs.id)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from json import dumps
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from gllm_core.schema import Chunk
|
|
14
|
+
from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
|
|
15
|
+
from langchain_core.tools import BaseTool
|
|
16
|
+
from pydantic import BaseModel, Field
|
|
17
|
+
|
|
18
|
+
from aip_agents.utils.logger import get_logger
|
|
19
|
+
|
|
20
|
+
logger = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GoogleSerperInput(BaseModel):
|
|
24
|
+
"""Input schema for the GoogleSerperTool."""
|
|
25
|
+
|
|
26
|
+
query: str = Field(..., description="Search query", min_length=1)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class GoogleSerperTool(BaseTool):
|
|
30
|
+
"""Tool to search Google Serper API."""
|
|
31
|
+
|
|
32
|
+
name: str = "google_serper"
|
|
33
|
+
description: str = """
|
|
34
|
+
Useful for searching the web using the Google Serper API.
|
|
35
|
+
Input should be a search query.
|
|
36
|
+
"""
|
|
37
|
+
save_output_history: bool = Field(default=True)
|
|
38
|
+
args_schema: type[BaseModel] = GoogleSerperInput
|
|
39
|
+
api_wrapper: GoogleSerperAPIWrapper = Field(default_factory=GoogleSerperAPIWrapper, exclude=True)
|
|
40
|
+
|
|
41
|
+
def _run(
|
|
42
|
+
self,
|
|
43
|
+
query: str,
|
|
44
|
+
) -> str:
|
|
45
|
+
"""Executes a query using the API wrapper and returns the result as a JSON string.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
query (str): The query string to be executed.
|
|
49
|
+
run_manager (Optional[CallbackManagerForToolRun], optional): An optional callback manager for the tool run.
|
|
50
|
+
Defaults to None.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
str: The result of the query execution, serialized as a JSON string.
|
|
54
|
+
"""
|
|
55
|
+
result = self.api_wrapper.results(query)
|
|
56
|
+
return dumps(result)
|
|
57
|
+
|
|
58
|
+
def _format_agent_reference(self, tool_output: str) -> list[Chunk]:
|
|
59
|
+
"""Format tool output into agent references.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
tool_output (str): The output from the tool, which is expected to be a JSON string.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
list[Chunk]: Formatted tool output as agent references
|
|
66
|
+
"""
|
|
67
|
+
# Parse the tool output if it's a string
|
|
68
|
+
parsed_output = self._parse_tool_output(tool_output)
|
|
69
|
+
if not parsed_output:
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
formatted_chunks = []
|
|
73
|
+
file_id_counter = 0
|
|
74
|
+
|
|
75
|
+
for section_name, section_data in parsed_output.items():
|
|
76
|
+
# Process only list-type sections
|
|
77
|
+
if not isinstance(section_data, list):
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
# Process each item in the section
|
|
81
|
+
results = self._process_section_items(section_name, section_data, file_id_counter)
|
|
82
|
+
formatted_chunks.extend(results["chunks"])
|
|
83
|
+
file_id_counter = results["counter"]
|
|
84
|
+
|
|
85
|
+
return formatted_chunks
|
|
86
|
+
|
|
87
|
+
def _parse_tool_output(self, tool_output: str) -> dict[str, Any]:
|
|
88
|
+
"""Parses the tool output to ensure it is in dictionary format.
|
|
89
|
+
|
|
90
|
+
This method attempts to convert string outputs to JSON dictionaries and handles
|
|
91
|
+
potential JSON parsing errors gracefully.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
tool_output (str): The output from a tool, which is expected to be a JSON string.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
dict[str, Any]: The parsed output as a dictionary. Returns an empty
|
|
98
|
+
dictionary if parsing fails.
|
|
99
|
+
"""
|
|
100
|
+
if isinstance(tool_output, str):
|
|
101
|
+
try:
|
|
102
|
+
return json.loads(tool_output)
|
|
103
|
+
except json.JSONDecodeError:
|
|
104
|
+
logger.warning("Error: Unable to parse tool_output as JSON when formatting agent references.")
|
|
105
|
+
return {}
|
|
106
|
+
return tool_output
|
|
107
|
+
|
|
108
|
+
def _process_section_items(self, section_name: str, section_data: list[dict], start_counter: int) -> dict[str, Any]:
|
|
109
|
+
"""Process items from a specific section of search results and create chunks.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
section_name (str): Name of the section being processed (e.g., 'organic', 'news').
|
|
113
|
+
section_data (list): List of items to process from the section.
|
|
114
|
+
start_counter (int): Initial counter value for chunk numbering.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
dict[str, Any]: Dictionary containing:
|
|
118
|
+
- chunks (list): List of processed chunks extracted from the section items.
|
|
119
|
+
- counter (int): Updated counter after processing all items.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
Exception: Logs errors that occur during processing of individual items.
|
|
123
|
+
"""
|
|
124
|
+
chunks = []
|
|
125
|
+
counter = start_counter
|
|
126
|
+
|
|
127
|
+
for item in section_data:
|
|
128
|
+
if not isinstance(item, dict):
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
chunk = self._create_chunk_from_item(section_name, item, counter)
|
|
133
|
+
if chunk:
|
|
134
|
+
chunks.append(chunk)
|
|
135
|
+
counter += 1
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.warning(f"Error processing {section_name} result: {e}")
|
|
138
|
+
|
|
139
|
+
return {"chunks": chunks, "counter": counter}
|
|
140
|
+
|
|
141
|
+
def _create_chunk_from_item(self, section_name: str, item: dict[str, Any], file_id: int) -> Chunk | None:
|
|
142
|
+
"""Creates a Chunk object from a search result item.
|
|
143
|
+
|
|
144
|
+
This method extracts content and metadata from a search result item and creates
|
|
145
|
+
a Chunk object. It prioritizes snippet over title for content and includes various
|
|
146
|
+
metadata fields.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
section_name (str): The name of the section this item belongs to.
|
|
150
|
+
item (dict[str, Any]): The search result item containing information like
|
|
151
|
+
snippet, title, and link.
|
|
152
|
+
file_id (int): The ID of the file associated with this chunk.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Optional[Chunk]: A Chunk object containing the extracted content and metadata,
|
|
156
|
+
or None if the item lacks essential information (link or content).
|
|
157
|
+
"""
|
|
158
|
+
# First check if link exists
|
|
159
|
+
link = item.get("link")
|
|
160
|
+
if not link:
|
|
161
|
+
logger.warning(f"Skipping item {file_id} from {section_name} result: Missing link")
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
# Then extract and check content
|
|
165
|
+
content = ""
|
|
166
|
+
if "snippet" in item:
|
|
167
|
+
content = item["snippet"]
|
|
168
|
+
elif "title" in item:
|
|
169
|
+
content = item["title"]
|
|
170
|
+
|
|
171
|
+
if not content:
|
|
172
|
+
logger.warning(f"Skipping item {file_id} from {section_name} result: Missing content")
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
metadata = {
|
|
176
|
+
"source": item.get("title", "Untitled Source"),
|
|
177
|
+
"section_type": section_name,
|
|
178
|
+
"source_type": "website",
|
|
179
|
+
"title": item.get("title", "Untitled"),
|
|
180
|
+
"link": link,
|
|
181
|
+
"file_id": str(file_id),
|
|
182
|
+
"url": link,
|
|
183
|
+
"start_index": 0,
|
|
184
|
+
"end_index": 0,
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return Chunk(content=content, metadata=metadata)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.utils.logger import get_logger as get_logger
|
|
3
|
+
from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
|
|
4
|
+
from langchain_core.tools import BaseTool
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
logger: Incomplete
|
|
8
|
+
|
|
9
|
+
class GoogleSerperInput(BaseModel):
|
|
10
|
+
"""Input schema for the GoogleSerperTool."""
|
|
11
|
+
query: str
|
|
12
|
+
|
|
13
|
+
class GoogleSerperTool(BaseTool):
|
|
14
|
+
"""Tool to search Google Serper API."""
|
|
15
|
+
name: str
|
|
16
|
+
description: str
|
|
17
|
+
save_output_history: bool
|
|
18
|
+
args_schema: type[BaseModel]
|
|
19
|
+
api_wrapper: GoogleSerperAPIWrapper
|