aip-agents-binary 0.5.20__py3-none-manylinux_2_31_x86_64.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 +2942 -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 +2514 -0
- aip_agents/agent/langgraph_react_agent.pyi +126 -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_bosa_twitter.py +41 -0
- aip_agents/examples/hello_world_langgraph_bosa_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/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 +359 -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 +215 -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 +88 -0
- aip_agents/middleware/base.pyi +71 -0
- aip_agents/middleware/manager.py +128 -0
- aip_agents/middleware/manager.pyi +80 -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 +33 -0
- aip_agents/tools/__init__.pyi +13 -0
- aip_agents/tools/bosa_tools.py +105 -0
- aip_agents/tools/bosa_tools.pyi +37 -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 +257 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +86 -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 +165 -0
- aip_agents/tools/constants.pyi +135 -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 +351 -0
- aip_agents/tools/gl_connector/tool.pyi +74 -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.20.dist-info/METADATA +681 -0
- aip_agents_binary-0.5.20.dist-info/RECORD +546 -0
- aip_agents_binary-0.5.20.dist-info/WHEEL +5 -0
- aip_agents_binary-0.5.20.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"""GL Connector tool wrapper for BOSA connector tools.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
5
|
+
|
|
6
|
+
Reference:
|
|
7
|
+
https://gl-docs.gitbook.io/bosa/gl-connector/gl-connector
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
from collections.abc import Iterable
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from bosa_connectors import BosaConnector, BOSAConnectorToolGenerator
|
|
17
|
+
from langchain_core.runnables import RunnableConfig
|
|
18
|
+
from langchain_core.tools import BaseTool
|
|
19
|
+
from pydantic import ConfigDict, PrivateAttr
|
|
20
|
+
|
|
21
|
+
from aip_agents.tools.constants import ToolType
|
|
22
|
+
|
|
23
|
+
_REQUIRED_ENV_VARS: tuple[str, ...] = (
|
|
24
|
+
"BOSA_BASE_URL",
|
|
25
|
+
"BOSA_API_KEY",
|
|
26
|
+
"BOSA_USERNAME",
|
|
27
|
+
"BOSA_PASSWORD",
|
|
28
|
+
)
|
|
29
|
+
_TOP_LEVEL_KEYS: tuple[str, ...] = (
|
|
30
|
+
"token",
|
|
31
|
+
"identifier",
|
|
32
|
+
"timeout",
|
|
33
|
+
"request",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class _InjectedTool(BaseTool):
|
|
38
|
+
"""Wrap a BaseTool to inject token and optional identifier into inputs."""
|
|
39
|
+
|
|
40
|
+
_base_tool: BaseTool = PrivateAttr()
|
|
41
|
+
_token: str = PrivateAttr()
|
|
42
|
+
_identifier: str | None = PrivateAttr(default=None)
|
|
43
|
+
|
|
44
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
45
|
+
|
|
46
|
+
def __init__(self, base_tool: BaseTool, token: str, identifier: str | None) -> None:
|
|
47
|
+
"""Initialize the injected tool wrapper.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
base_tool: The base tool to wrap.
|
|
51
|
+
token: Authentication token to inject into tool inputs.
|
|
52
|
+
identifier: Optional identifier to inject into tool inputs.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
None
|
|
56
|
+
"""
|
|
57
|
+
base_fields = {field: getattr(base_tool, field) for field in BaseTool.model_fields}
|
|
58
|
+
super().__init__(**base_fields)
|
|
59
|
+
self._base_tool = base_tool
|
|
60
|
+
self._token = token
|
|
61
|
+
self._identifier = identifier
|
|
62
|
+
|
|
63
|
+
def _run(self, *args: Any, **kwargs: Any) -> Any:
|
|
64
|
+
"""Execute the wrapped tool synchronously.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
*args: Positional arguments to pass to the base tool.
|
|
68
|
+
**kwargs: Keyword arguments to pass to the base tool.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The result of executing the base tool.
|
|
72
|
+
"""
|
|
73
|
+
return self._base_tool._run(*args, **kwargs)
|
|
74
|
+
|
|
75
|
+
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
|
|
76
|
+
"""Execute the wrapped tool asynchronously.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
*args: Positional arguments to pass to the base tool.
|
|
80
|
+
**kwargs: Keyword arguments to pass to the base tool.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The result of executing the base tool.
|
|
84
|
+
"""
|
|
85
|
+
return await self._base_tool._arun(*args, **kwargs)
|
|
86
|
+
|
|
87
|
+
def invoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
|
|
88
|
+
"""Invoke the tool with token and optional identifier injected.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
input: Tool input to process.
|
|
92
|
+
config: Optional runnable configuration.
|
|
93
|
+
**kwargs: Additional keyword arguments.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
The result of invoking the tool with injected parameters.
|
|
97
|
+
"""
|
|
98
|
+
injected = _inject_params(input, self._token, self._identifier, self._base_tool)
|
|
99
|
+
return super().invoke(injected, config=config, **kwargs)
|
|
100
|
+
|
|
101
|
+
async def ainvoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
|
|
102
|
+
"""Invoke the tool asynchronously with token and optional identifier injected.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
input: Tool input to process.
|
|
106
|
+
config: Optional runnable configuration.
|
|
107
|
+
**kwargs: Additional keyword arguments.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
The result of invoking the tool with injected parameters.
|
|
111
|
+
"""
|
|
112
|
+
injected = _inject_params(input, self._token, self._identifier, self._base_tool)
|
|
113
|
+
return await super().ainvoke(injected, config=config, **kwargs)
|
|
114
|
+
|
|
115
|
+
def run(self, tool_input: Any, **kwargs: Any) -> Any:
|
|
116
|
+
"""Run the tool with token and optional identifier injected.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
tool_input: Tool input to process.
|
|
120
|
+
**kwargs: Additional keyword arguments.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
The result of running the tool with injected parameters.
|
|
124
|
+
"""
|
|
125
|
+
injected = _inject_params(tool_input, self._token, self._identifier, self._base_tool)
|
|
126
|
+
return super().run(injected, **kwargs)
|
|
127
|
+
|
|
128
|
+
async def arun(self, tool_input: Any, **kwargs: Any) -> Any:
|
|
129
|
+
"""Run the tool asynchronously with token and optional identifier injected.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
tool_input: Tool input to process.
|
|
133
|
+
**kwargs: Additional keyword arguments.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The result of running the tool with injected parameters.
|
|
137
|
+
"""
|
|
138
|
+
injected = _inject_params(tool_input, self._token, self._identifier, self._base_tool)
|
|
139
|
+
return await super().arun(injected, **kwargs)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def GLConnectorTool(
|
|
143
|
+
tool_name: str,
|
|
144
|
+
*,
|
|
145
|
+
api_key: str | None = None,
|
|
146
|
+
identifier: str | None = None,
|
|
147
|
+
) -> BaseTool:
|
|
148
|
+
"""Create a single GL Connector tool by exact tool name.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
tool_name: Exact tool name (not module name).
|
|
152
|
+
api_key: Optional override for BOSA API key.
|
|
153
|
+
identifier: Optional override for BOSA identifier.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
A single LangChain BaseTool with token injection.
|
|
157
|
+
"""
|
|
158
|
+
if not tool_name or not tool_name.strip():
|
|
159
|
+
raise ValueError("tool_name must be a non-empty string")
|
|
160
|
+
|
|
161
|
+
env_values = _load_env(api_key=api_key, identifier=identifier)
|
|
162
|
+
connector = BosaConnector(api_base_url=env_values["BOSA_BASE_URL"], api_key=env_values["BOSA_API_KEY"])
|
|
163
|
+
|
|
164
|
+
modules = _get_available_modules(connector)
|
|
165
|
+
module_name = _resolve_module(tool_name, modules)
|
|
166
|
+
|
|
167
|
+
generator = BOSAConnectorToolGenerator(
|
|
168
|
+
api_base_url=env_values["BOSA_BASE_URL"],
|
|
169
|
+
api_key=env_values["BOSA_API_KEY"],
|
|
170
|
+
app_name=module_name,
|
|
171
|
+
)
|
|
172
|
+
tools = generator.generate_tools(tool_type=ToolType.LANGCHAIN)
|
|
173
|
+
|
|
174
|
+
matching = [tool for tool in tools if getattr(tool, "name", None) == tool_name]
|
|
175
|
+
if not matching:
|
|
176
|
+
raise ValueError(f"Tool '{tool_name}' not found in module '{module_name}'")
|
|
177
|
+
if len(matching) > 1:
|
|
178
|
+
raise ValueError(f"Multiple tools named '{tool_name}' found in module '{module_name}'")
|
|
179
|
+
|
|
180
|
+
token = _create_token(connector, env_values["BOSA_USERNAME"], env_values["BOSA_PASSWORD"])
|
|
181
|
+
return _InjectedTool(matching[0], token, env_values.get("BOSA_IDENTIFIER"))
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _load_env(*, api_key: str | None, identifier: str | None) -> dict[str, str]:
|
|
185
|
+
"""Load and validate environment configuration for connector access.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
api_key: Optional override for BOSA API key.
|
|
189
|
+
identifier: Optional override for BOSA identifier.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Dictionary containing environment configuration values.
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
ValueError: If required environment variables are missing.
|
|
196
|
+
"""
|
|
197
|
+
env = {key: os.getenv(key) for key in _REQUIRED_ENV_VARS}
|
|
198
|
+
|
|
199
|
+
resolved_api_key = api_key or env["BOSA_API_KEY"]
|
|
200
|
+
env["BOSA_API_KEY"] = resolved_api_key
|
|
201
|
+
|
|
202
|
+
optional_identifier = identifier or os.getenv("BOSA_IDENTIFIER")
|
|
203
|
+
|
|
204
|
+
if optional_identifier:
|
|
205
|
+
env["BOSA_IDENTIFIER"] = optional_identifier
|
|
206
|
+
|
|
207
|
+
missing = [key for key, value in env.items() if key in _REQUIRED_ENV_VARS and not value]
|
|
208
|
+
if missing:
|
|
209
|
+
raise ValueError(f"Missing required environment variables: {', '.join(missing)}")
|
|
210
|
+
|
|
211
|
+
return {key: value for key, value in env.items() if value is not None}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _get_available_modules(connector: BosaConnector) -> list[str]:
|
|
215
|
+
"""Return available connector modules or raise an actionable error.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
connector: BOSA connector instance to query for modules.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
List of available module names.
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
ValueError: If module fetching fails or no modules are available.
|
|
225
|
+
"""
|
|
226
|
+
try:
|
|
227
|
+
modules = list(connector.get_available_modules())
|
|
228
|
+
except Exception as exc:
|
|
229
|
+
raise ValueError("Failed to fetch available connector modules") from exc
|
|
230
|
+
|
|
231
|
+
if not modules:
|
|
232
|
+
raise ValueError("No connector modules available")
|
|
233
|
+
return modules
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def _resolve_module(tool_name: str, modules: Iterable[str]) -> str:
|
|
237
|
+
"""Resolve the module name by longest prefix match.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
tool_name: Name of the tool to resolve module for.
|
|
241
|
+
modules: Iterable of available module names.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
The resolved module name.
|
|
245
|
+
|
|
246
|
+
Raises:
|
|
247
|
+
ValueError: If no matching module is found or multiple ambiguous matches exist.
|
|
248
|
+
"""
|
|
249
|
+
candidates = [module for module in modules if tool_name == module or tool_name.startswith(f"{module}_")]
|
|
250
|
+
if not candidates:
|
|
251
|
+
raise ValueError(f"Unable to resolve module for tool '{tool_name}'. Available modules: {', '.join(modules)}")
|
|
252
|
+
|
|
253
|
+
candidates.sort(key=len, reverse=True)
|
|
254
|
+
if len(candidates) > 1 and len(candidates[0]) == len(candidates[1]):
|
|
255
|
+
raise ValueError(f"Ambiguous module match for tool '{tool_name}'. Matches: {', '.join(candidates)}")
|
|
256
|
+
return candidates[0]
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _create_token(connector: BosaConnector, username: str, password: str) -> str:
|
|
260
|
+
"""Authenticate the connector user and return a user token.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
connector: BOSA connector instance for authentication.
|
|
264
|
+
username: BOSA username for authentication.
|
|
265
|
+
password: BOSA password for authentication.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Authentication token string.
|
|
269
|
+
|
|
270
|
+
Raises:
|
|
271
|
+
ValueError: If authentication fails or token is missing.
|
|
272
|
+
"""
|
|
273
|
+
try:
|
|
274
|
+
user = connector.authenticate_bosa_user(username, password)
|
|
275
|
+
except Exception as exc:
|
|
276
|
+
raise ValueError("Failed to authenticate BOSA user") from exc
|
|
277
|
+
|
|
278
|
+
token = getattr(user, "token", None)
|
|
279
|
+
if not token:
|
|
280
|
+
raise ValueError("BOSA user token missing after authentication")
|
|
281
|
+
return token
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _inject_params(tool_input: Any, token: str, identifier: str | None, base_tool: BaseTool) -> dict[str, Any]:
|
|
285
|
+
"""Inject token and optional identifier into tool input.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
tool_input: Original tool input dictionary.
|
|
289
|
+
token: Authentication token to inject.
|
|
290
|
+
identifier: Optional identifier to inject.
|
|
291
|
+
base_tool: Base tool instance for schema inspection.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Dictionary with token and optional identifier injected.
|
|
295
|
+
|
|
296
|
+
Raises:
|
|
297
|
+
TypeError: If tool_input is not a dictionary.
|
|
298
|
+
"""
|
|
299
|
+
if tool_input is None:
|
|
300
|
+
tool_input = {}
|
|
301
|
+
|
|
302
|
+
if not isinstance(tool_input, dict):
|
|
303
|
+
raise TypeError("Connector tool input must be a dict to inject token")
|
|
304
|
+
|
|
305
|
+
if "args" in tool_input and isinstance(tool_input.get("args"), dict):
|
|
306
|
+
injected_args = dict(tool_input["args"])
|
|
307
|
+
injected_args["token"] = token
|
|
308
|
+
if identifier:
|
|
309
|
+
injected_args["identifier"] = identifier
|
|
310
|
+
injected = dict(tool_input)
|
|
311
|
+
injected["args"] = injected_args
|
|
312
|
+
return injected
|
|
313
|
+
|
|
314
|
+
injected = dict(tool_input)
|
|
315
|
+
injected = _wrap_request_if_needed(injected, base_tool)
|
|
316
|
+
injected["token"] = token
|
|
317
|
+
if identifier:
|
|
318
|
+
injected["identifier"] = identifier
|
|
319
|
+
return injected
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _wrap_request_if_needed(tool_input: dict[str, Any], base_tool: BaseTool) -> dict[str, Any]:
|
|
323
|
+
"""Wrap flat inputs into a 'request' payload when required by schema.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
tool_input: Tool input dictionary to potentially wrap.
|
|
327
|
+
base_tool: Base tool instance for schema inspection.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
Dictionary with inputs wrapped in 'request' key if needed, otherwise unchanged.
|
|
331
|
+
"""
|
|
332
|
+
args_schema = getattr(base_tool, "args_schema", None)
|
|
333
|
+
if not (isinstance(args_schema, dict) and "request" in args_schema.get("properties", {})):
|
|
334
|
+
return tool_input
|
|
335
|
+
|
|
336
|
+
request_payload = {}
|
|
337
|
+
existing_request = tool_input.get("request")
|
|
338
|
+
if isinstance(existing_request, dict):
|
|
339
|
+
request_payload.update(existing_request)
|
|
340
|
+
|
|
341
|
+
for key, value in tool_input.items():
|
|
342
|
+
if key in _TOP_LEVEL_KEYS:
|
|
343
|
+
continue
|
|
344
|
+
request_payload.setdefault(key, value)
|
|
345
|
+
|
|
346
|
+
wrapped = dict(tool_input)
|
|
347
|
+
wrapped["request"] = request_payload
|
|
348
|
+
for key in list(wrapped.keys()):
|
|
349
|
+
if key not in _TOP_LEVEL_KEYS:
|
|
350
|
+
wrapped.pop(key, None)
|
|
351
|
+
return wrapped
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.tools.constants import ToolType as ToolType
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from langchain_core.tools import BaseTool
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
class _InjectedTool(BaseTool):
|
|
8
|
+
"""Wrap a BaseTool to inject token and optional identifier into inputs."""
|
|
9
|
+
model_config: Incomplete
|
|
10
|
+
def __init__(self, base_tool: BaseTool, token: str, identifier: str | None) -> None:
|
|
11
|
+
"""Initialize the injected tool wrapper.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
base_tool: The base tool to wrap.
|
|
15
|
+
token: Authentication token to inject into tool inputs.
|
|
16
|
+
identifier: Optional identifier to inject into tool inputs.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
None
|
|
20
|
+
"""
|
|
21
|
+
def invoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
|
|
22
|
+
"""Invoke the tool with token and optional identifier injected.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
input: Tool input to process.
|
|
26
|
+
config: Optional runnable configuration.
|
|
27
|
+
**kwargs: Additional keyword arguments.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The result of invoking the tool with injected parameters.
|
|
31
|
+
"""
|
|
32
|
+
async def ainvoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
|
|
33
|
+
"""Invoke the tool asynchronously with token and optional identifier injected.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
input: Tool input to process.
|
|
37
|
+
config: Optional runnable configuration.
|
|
38
|
+
**kwargs: Additional keyword arguments.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
The result of invoking the tool with injected parameters.
|
|
42
|
+
"""
|
|
43
|
+
def run(self, tool_input: Any, **kwargs: Any) -> Any:
|
|
44
|
+
"""Run the tool with token and optional identifier injected.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
tool_input: Tool input to process.
|
|
48
|
+
**kwargs: Additional keyword arguments.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
The result of running the tool with injected parameters.
|
|
52
|
+
"""
|
|
53
|
+
async def arun(self, tool_input: Any, **kwargs: Any) -> Any:
|
|
54
|
+
"""Run the tool asynchronously with token and optional identifier injected.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
tool_input: Tool input to process.
|
|
58
|
+
**kwargs: Additional keyword arguments.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
The result of running the tool with injected parameters.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def GLConnectorTool(tool_name: str, *, api_key: str | None = None, identifier: str | None = None) -> BaseTool:
|
|
65
|
+
"""Create a single GL Connector tool by exact tool name.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
tool_name: Exact tool name (not module name).
|
|
69
|
+
api_key: Optional override for BOSA API key.
|
|
70
|
+
identifier: Optional override for BOSA identifier.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
A single LangChain BaseTool with token injection.
|
|
74
|
+
"""
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Memory search tool package exposing shared schemas and implementations.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool
|
|
8
|
+
from aip_agents.tools.memory_search.mem0 import (
|
|
9
|
+
MEMORY_SEARCH_TOOL_NAME,
|
|
10
|
+
Mem0SearchInput,
|
|
11
|
+
Mem0SearchTool,
|
|
12
|
+
)
|
|
13
|
+
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput, MemoryConfig
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"MemoryConfig",
|
|
17
|
+
"LongTermMemorySearchInput",
|
|
18
|
+
"LongTermMemorySearchTool",
|
|
19
|
+
"Mem0SearchInput",
|
|
20
|
+
"Mem0SearchTool",
|
|
21
|
+
"MEMORY_SEARCH_TOOL_NAME",
|
|
22
|
+
]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool as LongTermMemorySearchTool
|
|
2
|
+
from aip_agents.tools.memory_search.mem0 import MEMORY_SEARCH_TOOL_NAME as MEMORY_SEARCH_TOOL_NAME, Mem0SearchInput as Mem0SearchInput, Mem0SearchTool as Mem0SearchTool
|
|
3
|
+
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput as LongTermMemorySearchInput, MemoryConfig as MemoryConfig
|
|
4
|
+
|
|
5
|
+
__all__ = ['MemoryConfig', 'LongTermMemorySearchInput', 'LongTermMemorySearchTool', 'Mem0SearchInput', 'Mem0SearchTool', 'MEMORY_SEARCH_TOOL_NAME']
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""Abstract base class for long-term memory search tools.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from typing import Any, ClassVar, Protocol, runtime_checkable
|
|
13
|
+
|
|
14
|
+
from langchain_core.runnables import RunnableConfig
|
|
15
|
+
from langchain_core.tools import BaseTool
|
|
16
|
+
from pydantic import BaseModel
|
|
17
|
+
|
|
18
|
+
from aip_agents.memory.constants import MemoryDefaults
|
|
19
|
+
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput, MemoryConfig
|
|
20
|
+
from aip_agents.utils.logger import get_logger
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@runtime_checkable
|
|
26
|
+
class LongTermMemoryBackend(Protocol):
|
|
27
|
+
"""Protocol for memory adapters that support retrieval and formatting."""
|
|
28
|
+
|
|
29
|
+
def retrieve(
|
|
30
|
+
self,
|
|
31
|
+
*,
|
|
32
|
+
query: str | None,
|
|
33
|
+
user_id: str,
|
|
34
|
+
limit: int | None = None,
|
|
35
|
+
filters: dict[str, Any] | None = None,
|
|
36
|
+
page: int | None = None,
|
|
37
|
+
) -> list[dict[str, Any]]:
|
|
38
|
+
"""Retrieve memories matching the given query and filters.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
query: Optional search query string.
|
|
42
|
+
user_id: User identifier for scoped retrieval.
|
|
43
|
+
limit: Maximum number of results to return.
|
|
44
|
+
filters: Optional filters to apply to the retrieval.
|
|
45
|
+
page: Page number for pagination.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
List of memory hit dictionaries.
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
def format_hits(
|
|
53
|
+
self,
|
|
54
|
+
hits: list[dict[str, Any]],
|
|
55
|
+
max_items: int = MemoryDefaults.MAX_ITEMS,
|
|
56
|
+
with_tag: bool = True,
|
|
57
|
+
) -> str:
|
|
58
|
+
"""Format memory hits into a readable string.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
hits: List of memory hit dictionaries to format.
|
|
62
|
+
max_items: Maximum number of hits to include in output.
|
|
63
|
+
with_tag: Whether to wrap output with memory tags.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Formatted string representation of memory hits.
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class LongTermMemorySearchTool(BaseTool, ABC):
|
|
72
|
+
"""Abstract base class for provider-specific long-term memory search tools."""
|
|
73
|
+
|
|
74
|
+
name: str = "long_term_memory_search"
|
|
75
|
+
description: str = "Abstract interface for tools that retrieve long-term memories."
|
|
76
|
+
args_schema: type[LongTermMemorySearchInput] = LongTermMemorySearchInput
|
|
77
|
+
tool_config_schema: type[BaseModel] = MemoryConfig
|
|
78
|
+
memory: LongTermMemoryBackend
|
|
79
|
+
default_user_id: str | None = None
|
|
80
|
+
user_id_provider: Callable[[], str | None] | None = None
|
|
81
|
+
MINIMUM_MEMORY_RETRIEVAL: ClassVar[int] = 5
|
|
82
|
+
LOG_PREFIX: ClassVar[str] = "LongTermMemorySearchTool"
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
memory: LongTermMemoryBackend,
|
|
87
|
+
*,
|
|
88
|
+
default_user_id: str | None = None,
|
|
89
|
+
user_id_provider: Callable[[], str | None] | None = None,
|
|
90
|
+
**kwargs: Any,
|
|
91
|
+
) -> None:
|
|
92
|
+
"""Initialize the long-term memory search tool.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
memory: Memory adapter instance with retrieve() and format_hits() methods.
|
|
96
|
+
default_user_id: Default user ID to use if not provided in metadata.
|
|
97
|
+
user_id_provider: Callable that returns a user ID.
|
|
98
|
+
**kwargs: Additional keyword arguments passed to the parent class.
|
|
99
|
+
"""
|
|
100
|
+
required_attributes = {"retrieve", "format_hits"}
|
|
101
|
+
if not all(hasattr(memory, attr) for attr in required_attributes):
|
|
102
|
+
raise ValueError(
|
|
103
|
+
"LongTermMemorySearchTool requires a memory instance that implements retrieve() and format_hits()."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
super().__init__(
|
|
107
|
+
memory=memory,
|
|
108
|
+
default_user_id=default_user_id,
|
|
109
|
+
user_id_provider=user_id_provider,
|
|
110
|
+
**kwargs,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
@abstractmethod
|
|
114
|
+
async def _arun(
|
|
115
|
+
self,
|
|
116
|
+
query: str | None = None,
|
|
117
|
+
config: RunnableConfig | None = None,
|
|
118
|
+
run_manager: Any | None = None,
|
|
119
|
+
**kwargs: Any,
|
|
120
|
+
) -> str:
|
|
121
|
+
"""Execute provider-specific retrieval logic.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
query: Optional search query string.
|
|
125
|
+
config: Runnable configuration for the execution.
|
|
126
|
+
run_manager: Optional run manager for execution tracking.
|
|
127
|
+
**kwargs: Additional keyword arguments.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Formatted string of retrieved memories.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
def _run(
|
|
134
|
+
self,
|
|
135
|
+
query: str | None = None,
|
|
136
|
+
config: RunnableConfig | None = None,
|
|
137
|
+
run_manager: Any | None = None,
|
|
138
|
+
**kwargs: Any,
|
|
139
|
+
) -> str:
|
|
140
|
+
"""Synchronous wrapper that delegates to `_arun` using `asyncio.run`.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
query: Optional search query string.
|
|
144
|
+
config: Runnable configuration for the execution.
|
|
145
|
+
run_manager: Optional run manager for execution tracking.
|
|
146
|
+
**kwargs: Additional keyword arguments.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Formatted string of retrieved memories.
|
|
150
|
+
"""
|
|
151
|
+
return asyncio.run(self._arun(query=query, config=config, run_manager=run_manager, **kwargs))
|
|
152
|
+
|
|
153
|
+
def _resolve_user_id(self, metadata: dict[str, Any] | None, config: RunnableConfig | None = None) -> str:
|
|
154
|
+
"""Resolve the user ID for memory operations in a provider-agnostic way.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
metadata: Optional metadata dictionary that may contain user_id.
|
|
158
|
+
config: Optional runnable configuration for tool context.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
The resolved user ID string.
|
|
162
|
+
"""
|
|
163
|
+
user_id: str | None = None
|
|
164
|
+
|
|
165
|
+
if isinstance(metadata, dict):
|
|
166
|
+
user_id = metadata.get("user_id")
|
|
167
|
+
|
|
168
|
+
if not user_id and config and hasattr(self, "get_tool_config"):
|
|
169
|
+
logger.info("%s: Resolving user_id from RunnableConfig", self.LOG_PREFIX)
|
|
170
|
+
try:
|
|
171
|
+
tool_config = self.get_tool_config(config) # injected by tool_config_injector
|
|
172
|
+
logger.info("%s: Injected tool_config: %s", self.LOG_PREFIX, tool_config)
|
|
173
|
+
if tool_config and hasattr(tool_config, "user_id"):
|
|
174
|
+
user_id = tool_config.user_id
|
|
175
|
+
logger.info("%s: Using user_id from tool config: %s", self.LOG_PREFIX, user_id)
|
|
176
|
+
except Exception as exc: # noqa: BLE001
|
|
177
|
+
logger.warning("%s: get_tool_config failed: %s", self.LOG_PREFIX, exc)
|
|
178
|
+
|
|
179
|
+
if not user_id and self.user_id_provider:
|
|
180
|
+
try:
|
|
181
|
+
user_id = self.user_id_provider()
|
|
182
|
+
logger.info("%s: Using user_id from provider: %s", self.LOG_PREFIX, user_id)
|
|
183
|
+
except Exception as exc: # noqa: BLE001
|
|
184
|
+
logger.warning("%s: user_id_provider failed: %s", self.LOG_PREFIX, exc)
|
|
185
|
+
|
|
186
|
+
resolved_user_id = user_id or self.default_user_id or MemoryDefaults.DEFAULT_USER_ID
|
|
187
|
+
logger.info("%s: Resolved user_id: %s", self.LOG_PREFIX, resolved_user_id)
|
|
188
|
+
return resolved_user_id
|
|
189
|
+
|
|
190
|
+
def format_hits(self, hits: list[dict[str, Any]], with_tag: bool = False) -> str:
|
|
191
|
+
"""Format hits into a string with optional tags.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
hits: List of memory hit dictionaries to format.
|
|
195
|
+
with_tag: Whether to wrap the output with memory tags.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Formatted string representation of the memory hits.
|
|
199
|
+
"""
|
|
200
|
+
return self.memory.format_hits(hits, max_items=len(hits), with_tag=with_tag)
|