aip-agents-binary 0.5.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. aip_agents/__init__.py +65 -0
  2. aip_agents/a2a/__init__.py +19 -0
  3. aip_agents/a2a/server/__init__.py +10 -0
  4. aip_agents/a2a/server/base_executor.py +1086 -0
  5. aip_agents/a2a/server/google_adk_executor.py +198 -0
  6. aip_agents/a2a/server/langflow_executor.py +180 -0
  7. aip_agents/a2a/server/langgraph_executor.py +270 -0
  8. aip_agents/a2a/types.py +232 -0
  9. aip_agents/agent/__init__.py +27 -0
  10. aip_agents/agent/base_agent.py +970 -0
  11. aip_agents/agent/base_langgraph_agent.py +2942 -0
  12. aip_agents/agent/google_adk_agent.py +926 -0
  13. aip_agents/agent/google_adk_constants.py +6 -0
  14. aip_agents/agent/hitl/__init__.py +24 -0
  15. aip_agents/agent/hitl/config.py +28 -0
  16. aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
  17. aip_agents/agent/hitl/manager.py +532 -0
  18. aip_agents/agent/hitl/models.py +18 -0
  19. aip_agents/agent/hitl/prompt/__init__.py +9 -0
  20. aip_agents/agent/hitl/prompt/base.py +42 -0
  21. aip_agents/agent/hitl/prompt/deferred.py +73 -0
  22. aip_agents/agent/hitl/registry.py +149 -0
  23. aip_agents/agent/interface.py +138 -0
  24. aip_agents/agent/interfaces.py +65 -0
  25. aip_agents/agent/langflow_agent.py +464 -0
  26. aip_agents/agent/langgraph_memory_enhancer_agent.py +433 -0
  27. aip_agents/agent/langgraph_react_agent.py +2514 -0
  28. aip_agents/agent/system_instruction_context.py +34 -0
  29. aip_agents/clients/__init__.py +10 -0
  30. aip_agents/clients/langflow/__init__.py +10 -0
  31. aip_agents/clients/langflow/client.py +477 -0
  32. aip_agents/clients/langflow/types.py +18 -0
  33. aip_agents/constants.py +23 -0
  34. aip_agents/credentials/manager.py +132 -0
  35. aip_agents/examples/__init__.py +5 -0
  36. aip_agents/examples/compare_streaming_client.py +783 -0
  37. aip_agents/examples/compare_streaming_server.py +142 -0
  38. aip_agents/examples/demo_memory_recall.py +401 -0
  39. aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
  40. aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
  41. aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
  42. aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
  43. aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
  44. aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
  45. aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
  46. aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
  47. aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
  48. aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
  49. aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
  50. aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
  51. aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
  52. aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
  53. aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
  54. aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
  55. aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
  56. aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
  57. aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
  58. aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
  59. aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
  60. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
  61. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
  62. aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
  63. aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
  64. aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
  65. aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
  66. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
  67. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
  68. aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
  69. aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
  70. aip_agents/examples/hello_world_google_adk.py +41 -0
  71. aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
  72. aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
  73. aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
  74. aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
  75. aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
  76. aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
  77. aip_agents/examples/hello_world_google_adk_stream.py +44 -0
  78. aip_agents/examples/hello_world_langchain.py +28 -0
  79. aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
  80. aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
  81. aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
  82. aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
  83. aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
  84. aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
  85. aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
  86. aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
  87. aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
  88. aip_agents/examples/hello_world_langchain_stream.py +36 -0
  89. aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
  90. aip_agents/examples/hello_world_langflow_agent.py +163 -0
  91. aip_agents/examples/hello_world_langgraph.py +39 -0
  92. aip_agents/examples/hello_world_langgraph_bosa_twitter.py +41 -0
  93. aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
  94. aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
  95. aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
  96. aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
  97. aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
  98. aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
  99. aip_agents/examples/hello_world_langgraph_stream.py +43 -0
  100. aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
  101. aip_agents/examples/hello_world_model_switch_cli.py +210 -0
  102. aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
  103. aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
  104. aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
  105. aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
  106. aip_agents/examples/hello_world_pii_logger.py +21 -0
  107. aip_agents/examples/hello_world_sentry.py +133 -0
  108. aip_agents/examples/hello_world_step_limits.py +273 -0
  109. aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
  110. aip_agents/examples/hello_world_tool_output_client.py +46 -0
  111. aip_agents/examples/hello_world_tool_output_server.py +114 -0
  112. aip_agents/examples/hitl_demo.py +724 -0
  113. aip_agents/examples/mcp_configs/configs.py +63 -0
  114. aip_agents/examples/mcp_servers/common.py +76 -0
  115. aip_agents/examples/mcp_servers/mcp_name.py +29 -0
  116. aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
  117. aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
  118. aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
  119. aip_agents/examples/mcp_servers/mcp_time.py +10 -0
  120. aip_agents/examples/pii_demo_langgraph_client.py +69 -0
  121. aip_agents/examples/pii_demo_langgraph_server.py +126 -0
  122. aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
  123. aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
  124. aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
  125. aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
  126. aip_agents/examples/tools/__init__.py +27 -0
  127. aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
  128. aip_agents/examples/tools/adk_weather_tool.py +60 -0
  129. aip_agents/examples/tools/data_generator_tool.py +103 -0
  130. aip_agents/examples/tools/data_visualization_tool.py +312 -0
  131. aip_agents/examples/tools/image_artifact_tool.py +136 -0
  132. aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
  133. aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
  134. aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
  135. aip_agents/examples/tools/langchain_weather_tool.py +48 -0
  136. aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
  137. aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
  138. aip_agents/examples/tools/pii_demo_tools.py +189 -0
  139. aip_agents/examples/tools/random_chart_tool.py +142 -0
  140. aip_agents/examples/tools/serper_tool.py +202 -0
  141. aip_agents/examples/tools/stock_tools.py +82 -0
  142. aip_agents/examples/tools/table_generator_tool.py +167 -0
  143. aip_agents/examples/tools/time_tool.py +82 -0
  144. aip_agents/examples/tools/weather_forecast_tool.py +38 -0
  145. aip_agents/executor/agent_executor.py +473 -0
  146. aip_agents/executor/base.py +48 -0
  147. aip_agents/mcp/__init__.py +1 -0
  148. aip_agents/mcp/client/__init__.py +14 -0
  149. aip_agents/mcp/client/base_mcp_client.py +369 -0
  150. aip_agents/mcp/client/connection_manager.py +193 -0
  151. aip_agents/mcp/client/google_adk/__init__.py +11 -0
  152. aip_agents/mcp/client/google_adk/client.py +381 -0
  153. aip_agents/mcp/client/langchain/__init__.py +11 -0
  154. aip_agents/mcp/client/langchain/client.py +265 -0
  155. aip_agents/mcp/client/persistent_session.py +359 -0
  156. aip_agents/mcp/client/session_pool.py +351 -0
  157. aip_agents/mcp/client/transports.py +215 -0
  158. aip_agents/mcp/utils/__init__.py +7 -0
  159. aip_agents/mcp/utils/config_validator.py +139 -0
  160. aip_agents/memory/__init__.py +14 -0
  161. aip_agents/memory/adapters/__init__.py +10 -0
  162. aip_agents/memory/adapters/base_adapter.py +717 -0
  163. aip_agents/memory/adapters/mem0.py +84 -0
  164. aip_agents/memory/base.py +84 -0
  165. aip_agents/memory/constants.py +49 -0
  166. aip_agents/memory/factory.py +86 -0
  167. aip_agents/memory/guidance.py +20 -0
  168. aip_agents/memory/simple_memory.py +47 -0
  169. aip_agents/middleware/__init__.py +17 -0
  170. aip_agents/middleware/base.py +88 -0
  171. aip_agents/middleware/manager.py +128 -0
  172. aip_agents/middleware/todolist.py +274 -0
  173. aip_agents/schema/__init__.py +69 -0
  174. aip_agents/schema/a2a.py +56 -0
  175. aip_agents/schema/agent.py +111 -0
  176. aip_agents/schema/hitl.py +157 -0
  177. aip_agents/schema/langgraph.py +37 -0
  178. aip_agents/schema/model_id.py +97 -0
  179. aip_agents/schema/step_limit.py +108 -0
  180. aip_agents/schema/storage.py +40 -0
  181. aip_agents/sentry/__init__.py +11 -0
  182. aip_agents/sentry/sentry.py +151 -0
  183. aip_agents/storage/__init__.py +41 -0
  184. aip_agents/storage/base.py +85 -0
  185. aip_agents/storage/clients/__init__.py +12 -0
  186. aip_agents/storage/clients/minio_client.py +318 -0
  187. aip_agents/storage/config.py +62 -0
  188. aip_agents/storage/providers/__init__.py +15 -0
  189. aip_agents/storage/providers/base.py +106 -0
  190. aip_agents/storage/providers/memory.py +114 -0
  191. aip_agents/storage/providers/object_storage.py +214 -0
  192. aip_agents/tools/__init__.py +33 -0
  193. aip_agents/tools/bosa_tools.py +105 -0
  194. aip_agents/tools/browser_use/__init__.py +82 -0
  195. aip_agents/tools/browser_use/action_parser.py +103 -0
  196. aip_agents/tools/browser_use/browser_use_tool.py +1112 -0
  197. aip_agents/tools/browser_use/llm_config.py +120 -0
  198. aip_agents/tools/browser_use/minio_storage.py +198 -0
  199. aip_agents/tools/browser_use/schemas.py +119 -0
  200. aip_agents/tools/browser_use/session.py +76 -0
  201. aip_agents/tools/browser_use/session_errors.py +132 -0
  202. aip_agents/tools/browser_use/steel_session_recording.py +317 -0
  203. aip_agents/tools/browser_use/streaming.py +813 -0
  204. aip_agents/tools/browser_use/structured_data_parser.py +257 -0
  205. aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
  206. aip_agents/tools/browser_use/types.py +78 -0
  207. aip_agents/tools/code_sandbox/__init__.py +26 -0
  208. aip_agents/tools/code_sandbox/constant.py +13 -0
  209. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +257 -0
  210. aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
  211. aip_agents/tools/constants.py +165 -0
  212. aip_agents/tools/document_loader/__init__.py +44 -0
  213. aip_agents/tools/document_loader/base_reader.py +302 -0
  214. aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
  215. aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
  216. aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
  217. aip_agents/tools/document_loader/pdf_splitter.py +169 -0
  218. aip_agents/tools/gl_connector/__init__.py +5 -0
  219. aip_agents/tools/gl_connector/tool.py +351 -0
  220. aip_agents/tools/memory_search/__init__.py +22 -0
  221. aip_agents/tools/memory_search/base.py +200 -0
  222. aip_agents/tools/memory_search/mem0.py +258 -0
  223. aip_agents/tools/memory_search/schema.py +48 -0
  224. aip_agents/tools/memory_search_tool.py +26 -0
  225. aip_agents/tools/time_tool.py +117 -0
  226. aip_agents/tools/tool_config_injector.py +300 -0
  227. aip_agents/tools/web_search/__init__.py +15 -0
  228. aip_agents/tools/web_search/serper_tool.py +187 -0
  229. aip_agents/types/__init__.py +70 -0
  230. aip_agents/types/a2a_events.py +13 -0
  231. aip_agents/utils/__init__.py +79 -0
  232. aip_agents/utils/a2a_connector.py +1757 -0
  233. aip_agents/utils/artifact_helpers.py +502 -0
  234. aip_agents/utils/constants.py +22 -0
  235. aip_agents/utils/datetime/__init__.py +34 -0
  236. aip_agents/utils/datetime/normalization.py +231 -0
  237. aip_agents/utils/datetime/timezone.py +206 -0
  238. aip_agents/utils/env_loader.py +27 -0
  239. aip_agents/utils/event_handler_registry.py +58 -0
  240. aip_agents/utils/file_prompt_utils.py +176 -0
  241. aip_agents/utils/final_response_builder.py +211 -0
  242. aip_agents/utils/formatter_llm_client.py +231 -0
  243. aip_agents/utils/langgraph/__init__.py +19 -0
  244. aip_agents/utils/langgraph/converter.py +128 -0
  245. aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
  246. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
  247. aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
  248. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1071 -0
  249. aip_agents/utils/langgraph/tool_output_management.py +967 -0
  250. aip_agents/utils/logger.py +195 -0
  251. aip_agents/utils/metadata/__init__.py +27 -0
  252. aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
  253. aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
  254. aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
  255. aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
  256. aip_agents/utils/metadata/activity_narrative/context.py +49 -0
  257. aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
  258. aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
  259. aip_agents/utils/metadata/schemas/__init__.py +16 -0
  260. aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
  261. aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
  262. aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
  263. aip_agents/utils/metadata_helper.py +358 -0
  264. aip_agents/utils/name_preprocessor/__init__.py +17 -0
  265. aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
  266. aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
  267. aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
  268. aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
  269. aip_agents/utils/pii/__init__.py +25 -0
  270. aip_agents/utils/pii/pii_handler.py +397 -0
  271. aip_agents/utils/pii/pii_helper.py +207 -0
  272. aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
  273. aip_agents/utils/reference_helper.py +273 -0
  274. aip_agents/utils/sse_chunk_transformer.py +831 -0
  275. aip_agents/utils/step_limit_manager.py +265 -0
  276. aip_agents/utils/token_usage_helper.py +156 -0
  277. aip_agents_binary-0.5.20.dist-info/METADATA +681 -0
  278. aip_agents_binary-0.5.20.dist-info/RECORD +280 -0
  279. aip_agents_binary-0.5.20.dist-info/WHEEL +5 -0
  280. aip_agents_binary-0.5.20.dist-info/top_level.txt +1 -0
@@ -0,0 +1,38 @@
1
+ """Weather Forecast Tool."""
2
+
3
+ from typing import Literal
4
+
5
+ # Predefined weather data for each day
6
+ DAILY_WEATHER = {
7
+ "monday": {"condition": "sunny", "temp_low": 28, "temp_high": 32},
8
+ "tuesday": {"condition": "partly cloudy", "temp_low": 25, "temp_high": 28},
9
+ "wednesday": {"condition": "cloudy", "temp_low": 22, "temp_high": 25},
10
+ "thursday": {"condition": "light rain", "temp_low": 20, "temp_high": 23},
11
+ "friday": {"condition": "windy", "temp_low": 19, "temp_high": 24},
12
+ "saturday": {"condition": "sunny", "temp_low": 27, "temp_high": 31},
13
+ "sunday": {"condition": "partly cloudy", "temp_low": 24, "temp_high": 27},
14
+ }
15
+
16
+ DayOfWeek = Literal["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
17
+
18
+
19
+ def get_weather_forecast(day: DayOfWeek) -> str:
20
+ """Get the weather forecast for a specific day of the week.
21
+
22
+ Args:
23
+ day: The day of the week (monday, tuesday, wednesday, etc.)
24
+
25
+ Returns:
26
+ str: A weather forecast message including conditions and temperature.
27
+ """
28
+ # Get the predefined weather data for the day
29
+ weather_data = DAILY_WEATHER[day]
30
+
31
+ # Format the forecast message
32
+ forecast = (
33
+ f"Weather forecast for {day.capitalize()}: "
34
+ f"{weather_data['condition'].capitalize()} with temperatures between "
35
+ f"{weather_data['temp_low']}°C and {weather_data['temp_high']}°C"
36
+ )
37
+
38
+ return forecast
@@ -0,0 +1,473 @@
1
+ """AgentExecutor and GLLMMultiActionAgent for AIP Agents.
2
+
3
+ This module provides a custom implementation of LangChain's AgentExecutor
4
+ and a GLLMMultiActionAgent that bridges between the GLLM Agent implementation
5
+ and LangChain's BaseMultiActionAgent interface.
6
+
7
+ Authors:
8
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
9
+ Raymond Christopher (raymond.christopher@gdplabs.id)
10
+ """
11
+
12
+ from collections.abc import Sequence
13
+ from dataclasses import dataclass
14
+ from typing import Any
15
+
16
+ from gllm_core.constants import EventLevel, EventType
17
+ from gllm_core.event import EventEmitter
18
+ from gllm_inference.lm_invoker.lm_invoker import BaseLMInvoker
19
+ from gllm_inference.schema import (
20
+ LMOutput,
21
+ MessageRole,
22
+ ToolCall,
23
+ ToolResult,
24
+ )
25
+ from langchain.agents import (
26
+ AgentExecutor as LangchainAgentExecutor,
27
+ ) # Alias for clarity
28
+ from langchain.agents import BaseMultiActionAgent
29
+ from langchain.agents.tools import InvalidTool
30
+ from langchain_core.agents import AgentAction, AgentFinish, AgentStep
31
+ from langchain_core.callbacks import (
32
+ AsyncCallbackManagerForChainRun,
33
+ CallbackManagerForChainRun,
34
+ Callbacks,
35
+ )
36
+ from langchain_core.tools import BaseTool
37
+ from pydantic import ConfigDict
38
+
39
+ from aip_agents.utils.logger import get_logger
40
+
41
+ logger = get_logger(__name__)
42
+
43
+
44
+ @dataclass
45
+ class ExecutorConfig:
46
+ """Configuration for AgentExecutor."""
47
+
48
+ instruction: str
49
+ invoker: BaseLMInvoker
50
+ tools: Sequence[BaseTool]
51
+ max_iterations: int | None = 15
52
+ max_execution_time: float | None = None
53
+ verbose: bool = False
54
+ event_emitter: EventEmitter | None = None
55
+ handle_parsing_errors: bool = True
56
+ prompt_memory: list | None = None
57
+
58
+
59
+ class GLLMMultiActionAgent(BaseMultiActionAgent):
60
+ """Bridges a GLLM Agent with LangChain's BaseMultiActionAgent interface.
61
+
62
+ This class allows a GLLM Agent (which uses an LMInvoker internally) to be
63
+ used within LangChain's execution framework (e.g., with an AgentExecutor).
64
+ It handles the conversion of prompts and responses between the GLLM Agent's
65
+ LMInvoker system and the format expected by LangChain.
66
+
67
+ Primarily designed for asynchronous operation via the `aplan` method.
68
+
69
+ Attributes:
70
+ instruction (str): The system instruction for the language model.
71
+ invoker (BaseLMInvoker): The LMInvoker instance associated with the GLLM Agent,
72
+ used for making calls to the language model.
73
+ tools (list[BaseTool]): A list of tools available to the GLLM Agent.
74
+ event_emitter (Optional[EventEmitter]): An optional event emitter for streaming
75
+ intermediate steps and other events. Defaults to None.
76
+ input_keys_arg (list[str]): The list of input keys that the agent expects.
77
+ Defaults to ["input"].
78
+ return_keys_arg (list[str]): The list of keys for the agent's return values.
79
+ Defaults to ["output"].
80
+ prompt_memory (list[tuple[MessageRole, list[Any]]]): Pre-formatted prompt memory.
81
+ """
82
+
83
+ instruction: str
84
+ invoker: BaseLMInvoker
85
+ tools: list[BaseTool]
86
+ event_emitter: EventEmitter | None = None
87
+ input_keys_arg: list[str] = ["input"]
88
+ return_keys_arg: list[str] = ["output"]
89
+ prompt_memory: list | None = None
90
+
91
+ model_config = ConfigDict(arbitrary_types_allowed=True)
92
+
93
+ def __init__(
94
+ self,
95
+ instruction: str,
96
+ invoker: BaseLMInvoker,
97
+ tools: list[BaseTool],
98
+ event_emitter: EventEmitter | None = None,
99
+ prompt_memory: list | None = None,
100
+ ):
101
+ """Initializes the GLLMMultiActionAgent.
102
+
103
+ Args:
104
+ instruction (str): The system instruction for the language model.
105
+ invoker (BaseLMInvoker): The LMInvoker from the GLLM Agent.
106
+ tools (list[BaseTool]): Tools available to the GLLM Agent.
107
+ event_emitter (Optional[EventEmitter], optional): Event emitter for streaming.
108
+ Defaults to None.
109
+ prompt_memory (Optional[list], optional):
110
+ Pre-formatted prompt memory. Defaults to None.
111
+ """
112
+ super().__init__(
113
+ instruction=instruction,
114
+ invoker=invoker,
115
+ tools=tools,
116
+ event_emitter=event_emitter,
117
+ prompt_memory=prompt_memory,
118
+ )
119
+
120
+ @property
121
+ def input_keys(self) -> list[str]:
122
+ """Input keys for the agent."""
123
+ return self.input_keys_arg
124
+
125
+ @property
126
+ def return_values(self) -> list[str]:
127
+ """Return values of the agent."""
128
+ return self.return_keys_arg
129
+
130
+ def plan(
131
+ self,
132
+ intermediate_steps: list[tuple[AgentAction, str]],
133
+ _callbacks: Callbacks = None,
134
+ **kwargs: Any,
135
+ ) -> list[AgentAction] | AgentFinish:
136
+ """Synchronous planning. (Not Implemented).
137
+
138
+ This method is intentionally not implemented to encourage asynchronous
139
+ operations. Please use the `aplan` method.
140
+
141
+ Args:
142
+ intermediate_steps: Steps the LLM has taken to date, along with observations.
143
+ _callbacks: Callbacks to run.
144
+ **kwargs: User inputs.
145
+
146
+ Raises:
147
+ NotImplementedError: This method is not implemented.
148
+ """
149
+ logger.warning(
150
+ "GLLMMultiActionAgent synchronous 'plan' method was called but is not implemented. Use 'aplan' instead."
151
+ )
152
+ raise NotImplementedError("Synchronous planning is not implemented. Please use the 'aplan' method.")
153
+
154
+ async def aplan(
155
+ self,
156
+ intermediate_steps: list[tuple[AgentAction, str]],
157
+ _callbacks: Callbacks = None,
158
+ **kwargs: Any,
159
+ ) -> list[AgentAction] | AgentFinish:
160
+ """Asynchronously decides the next action(s) or finishes execution.
161
+
162
+ Args:
163
+ intermediate_steps (list[tuple[AgentAction, str]]): A list of previous
164
+ agent actions and their corresponding string observations.
165
+ _callbacks (Callbacks, optional): LangChain callbacks. Not directly used by
166
+ this method but maintained for interface compatibility. Defaults to None.
167
+ **kwargs (Any): Additional keyword arguments representing the initial inputs
168
+ to the agent (e.g., `input="user's query"`).
169
+
170
+ Returns:
171
+ list[AgentAction] | AgentFinish: A list of `AgentAction` objects if the
172
+ agent decides to take one or more actions, or an `AgentFinish` object
173
+ if the agent has completed its work.
174
+ """
175
+ prompt_messages: list = self._create_prompt(intermediate_steps, **kwargs)
176
+
177
+ logger.debug(f"Prompt messages for GLLMMultiActionAgent aplan: {prompt_messages}")
178
+ response = await self.invoker.invoke(prompt=prompt_messages, event_emitter=self.event_emitter)
179
+
180
+ parsed_response = await self._parse_response(response)
181
+ return parsed_response
182
+
183
+ def get_allowed_tools(self) -> list[str] | None:
184
+ """Returns a list of tool names that this agent is allowed to use."""
185
+ return [tool.name for tool in self.tools]
186
+
187
+ def return_stopped_response(
188
+ self,
189
+ early_stopping_method: str,
190
+ _intermediate_steps: list[tuple[AgentAction, str]],
191
+ **kwargs: Any,
192
+ ) -> AgentFinish:
193
+ """Returns an AgentFinish object when the agent is stopped early.
194
+
195
+ Args:
196
+ early_stopping_method (str): The method used for early stopping.
197
+ Currently, only "force" is supported.
198
+ _intermediate_steps (list[tuple[AgentAction, str]]): The history of
199
+ actions and observations.
200
+ **kwargs (Any): Additional inputs.
201
+
202
+ Returns:
203
+ AgentFinish: An AgentFinish object indicating the agent stopped.
204
+
205
+ Raises:
206
+ ValueError: If `early_stopping_method` is not "force".
207
+ """
208
+ if early_stopping_method == "force":
209
+ return AgentFinish(
210
+ return_values={"output": "Agent stopped due to iteration limit or time limit."},
211
+ log="Agent stopped due to iteration limit or time limit.\n",
212
+ )
213
+ raise ValueError(f"Got unsupported early_stopping_method `{early_stopping_method}`")
214
+
215
+ def tool_run_logging_kwargs(self) -> dict[str, Any]:
216
+ """Returns keyword arguments for logging tool runs. Currently empty."""
217
+ return {}
218
+
219
+ def _create_prompt(self, intermediate_steps: list[tuple[AgentAction, str]], **kwargs: Any) -> list:
220
+ """Create a multimodal prompt from intermediate steps and inputs.
221
+
222
+ Args:
223
+ intermediate_steps: Steps the LLM has taken to date, along with observations.
224
+ **kwargs: User inputs.
225
+
226
+ Returns:
227
+ A list (list of prompt message tuples).
228
+ """
229
+ prompt_msgs: list = []
230
+
231
+ # 1. System instruction
232
+ prompt_msgs.append((MessageRole.SYSTEM, [self.instruction]))
233
+
234
+ # 2. Prepend chat history
235
+ if self.prompt_memory:
236
+ prompt_msgs.extend(self.prompt_memory)
237
+
238
+ # 3. Current user input
239
+ if "input" in kwargs:
240
+ prompt_msgs.append((MessageRole.USER, [kwargs["input"]]))
241
+
242
+ # 4. Intermediate steps (tool calls and observations for the current turn)
243
+ for i, (action, observation) in enumerate(intermediate_steps):
244
+ tool_call_id = f"call_{action.tool}_{i}"
245
+ if isinstance(action.tool_input, dict):
246
+ args = action.tool_input
247
+ else:
248
+ args = {"query": action.tool_input}
249
+ tool_call = ToolCall(id=tool_call_id, name=action.tool, args=args)
250
+ prompt_msgs.append((MessageRole.ASSISTANT, [tool_call]))
251
+ tool_result = ToolResult(id=tool_call_id, output=observation)
252
+ prompt_msgs.append((MessageRole.USER, [tool_result]))
253
+
254
+ return prompt_msgs
255
+
256
+ async def _handle_tool_calls(self, tool_calls: list[ToolCall]) -> list[AgentAction] | None:
257
+ """Handles tool calls by converting them to AgentActions.
258
+
259
+ Args:
260
+ tool_calls: list of tool calls to process.
261
+
262
+ Returns:
263
+ Optional[list[AgentAction]]: List of agent actions if any tool calls exist.
264
+ """
265
+ if not tool_calls:
266
+ return None
267
+
268
+ actions = []
269
+ for tool_call in tool_calls:
270
+ tool_input = tool_call.args if tool_call.args else {}
271
+ action_log = f"Invoking: `{tool_call.name}` with `{tool_input}`\n"
272
+ actions.append(
273
+ AgentAction(
274
+ tool=tool_call.name,
275
+ tool_input=tool_input,
276
+ log=f"\n{action_log}\n",
277
+ )
278
+ )
279
+ if self.event_emitter:
280
+ await self.event_emitter.emit(
281
+ event_type=EventType.DATA,
282
+ event_level=EventLevel.INFO,
283
+ value=action_log,
284
+ )
285
+ return actions
286
+
287
+ async def _parse_response(self, response: LMOutput) -> list[AgentAction] | AgentFinish:
288
+ """Parses the LMInvoker's response into LangChain actions or finish signal.
289
+
290
+ If the response contains tool calls, they are converted to `AgentAction` objects.
291
+ Otherwise, the response is treated as a final answer and converted to an
292
+ `AgentFinish` object.
293
+
294
+ Args:
295
+ response (LMOutput): The output from the LMInvoker.
296
+
297
+ Returns:
298
+ list[AgentAction] | AgentFinish: LangChain actions or finish signal.
299
+ """
300
+ logger.debug(f"Response from LM Invoker in GLLMMultiActionAgent: {response}")
301
+
302
+ if not isinstance(response, LMOutput):
303
+ return AgentFinish(return_values={"output": response}, log=response)
304
+
305
+ actions = await self._handle_tool_calls(response.tool_calls)
306
+ if actions:
307
+ return actions
308
+
309
+ return AgentFinish(
310
+ return_values={"output": str(response.response)},
311
+ log=str(response.response),
312
+ )
313
+
314
+
315
+ class AgentExecutor(LangchainAgentExecutor):
316
+ """Custom GLLM AgentExecutor extending LangChain's AgentExecutor.
317
+
318
+ This executor orchestrates the execution loop for a GLLM Agent. It receives
319
+ the GLLM Agent instance and necessary components (invoker, tools) and internally
320
+ creates the `GLLMMultiActionAgent` adapter needed for the LangChain execution flow.
321
+
322
+ It prioritizes asynchronous operations (`_aperform_agent_action`) and integrates
323
+ with the GLLM event emitter system.
324
+ """
325
+
326
+ def __init__(
327
+ self,
328
+ config: ExecutorConfig,
329
+ **kwargs: Any,
330
+ ):
331
+ """Initializes the custom AgentExecutor.
332
+
333
+ Args:
334
+ config: Configuration object containing all executor parameters.
335
+ **kwargs: Additional keyword arguments passed to the parent
336
+ `LangchainAgentExecutor` constructor.
337
+ """
338
+ action_agent = GLLMMultiActionAgent(
339
+ instruction=config.instruction,
340
+ invoker=config.invoker,
341
+ tools=list(config.tools),
342
+ event_emitter=config.event_emitter,
343
+ prompt_memory=config.prompt_memory,
344
+ )
345
+
346
+ super().__init__(
347
+ agent=action_agent,
348
+ tools=config.tools,
349
+ max_iterations=config.max_iterations,
350
+ max_execution_time=config.max_execution_time,
351
+ verbose=config.verbose,
352
+ handle_parsing_errors=config.handle_parsing_errors,
353
+ **kwargs,
354
+ )
355
+ self._event_emitter = config.event_emitter
356
+
357
+ @property
358
+ def event_emitter(self) -> EventEmitter | None:
359
+ """Get the event emitter."""
360
+ return self._event_emitter
361
+
362
+ async def _aperform_agent_action(
363
+ self,
364
+ name_to_tool_map: dict[str, BaseTool],
365
+ color_mapping: dict[str, str],
366
+ agent_action: AgentAction,
367
+ run_manager: AsyncCallbackManagerForChainRun | None = None,
368
+ ) -> AgentStep:
369
+ """Asynchronously performs a single agent action (tool execution).
370
+
371
+ This method executes the specified tool with the given input and logs
372
+ the action and observation. If an `event_emitter` is configured, it emits
373
+ events for tool responses and invalid tool requests.
374
+
375
+ Args:
376
+ name_to_tool_map (dict[str, BaseTool]): Mapping of tool names to tool instances.
377
+ color_mapping (dict[str, str]): Mapping of tool names to colors for logging.
378
+ agent_action (AgentAction): The agent action to perform, specifying the tool
379
+ and tool input.
380
+ run_manager (Optional[AsyncCallbackManagerForChainRun], optional): LangChain
381
+ callback manager for the current run. Defaults to None.
382
+
383
+ Returns:
384
+ AgentStep: An `AgentStep` object containing the performed action and the
385
+ resulting observation from the tool.
386
+ """
387
+ if run_manager:
388
+ await run_manager.on_agent_action(agent_action, verbose=self.verbose, color="green")
389
+
390
+ observation = ""
391
+ tool_to_run: BaseTool | None = name_to_tool_map.get(agent_action.tool)
392
+
393
+ if tool_to_run:
394
+ tool_run_kwargs = self._action_agent.tool_run_logging_kwargs()
395
+ if tool_to_run.return_direct:
396
+ tool_run_kwargs["llm_prefix"] = ""
397
+
398
+ tool_input = await self._preprocess_tool_input(agent_action.tool_input)
399
+ observation = await tool_to_run.arun(
400
+ tool_input,
401
+ verbose=self.verbose,
402
+ color=color_mapping.get(agent_action.tool),
403
+ callbacks=run_manager.get_child() if run_manager else None,
404
+ **tool_run_kwargs,
405
+ )
406
+ observation = await self._postprocess_tool_output(observation)
407
+ logger.info(f"Tool {agent_action.tool} responded: {observation}")
408
+ else:
409
+ tool_run_kwargs = self._action_agent.tool_run_logging_kwargs()
410
+ observation = await InvalidTool().arun(
411
+ tool_input={
412
+ "requested_tool_name": agent_action.tool,
413
+ "available_tool_names": list(name_to_tool_map.keys()),
414
+ },
415
+ verbose=self.verbose,
416
+ color=None,
417
+ callbacks=run_manager.get_child() if run_manager else None,
418
+ **tool_run_kwargs,
419
+ )
420
+ logger.warning(f"Invalid tool requested: {agent_action.tool}. Observation: {observation}")
421
+ return AgentStep(action=agent_action, observation=observation)
422
+
423
+ async def _preprocess_tool_input(self, tool_input: Any) -> Any:
424
+ """Preprocess the tool input.
425
+
426
+ Args:
427
+ tool_input (Any): The tool input to preprocess.
428
+
429
+ Returns:
430
+ Any: The preprocessed tool input.
431
+ """
432
+ return tool_input
433
+
434
+ async def _postprocess_tool_output(self, tool_output: Any) -> Any:
435
+ """Postprocess the tool output.
436
+
437
+ Args:
438
+ tool_output (Any): The tool output to postprocess.
439
+
440
+ Returns:
441
+ Any: The postprocessed tool output.
442
+ """
443
+ return tool_output
444
+
445
+ def _perform_agent_action(
446
+ self,
447
+ name_to_tool_map: dict[str, BaseTool],
448
+ color_mapping: dict[str, str],
449
+ agent_action: AgentAction,
450
+ run_manager: CallbackManagerForChainRun | None = None,
451
+ ) -> AgentStep:
452
+ """Synchronous agent action. (Not Implemented).
453
+
454
+ This method is intentionally not implemented to encourage asynchronous
455
+ operations. Please use the `_aperform_agent_action` method.
456
+
457
+ Args:
458
+ name_to_tool_map (dict[str, BaseTool]): Mapping of tool names to tools.
459
+ color_mapping (dict[str, str]): Mapping of tool names to colors.
460
+ agent_action (AgentAction): The action to execute.
461
+ run_manager (Optional[CallbackManagerForChainRun], optional): Callback manager.
462
+ Defaults to None.
463
+
464
+ Raises:
465
+ NotImplementedError: This method is not implemented.
466
+ """
467
+ logger.warning(
468
+ "AgentExecutor synchronous '_perform_agent_action' was called but is not implemented. "
469
+ "Use '_aperform_agent_action' instead."
470
+ )
471
+ raise NotImplementedError(
472
+ "Synchronous agent action execution is not implemented. Please use the '_aperform_agent_action' method."
473
+ )
@@ -0,0 +1,48 @@
1
+ """Defines the base class for agent executors.
2
+
3
+ Author:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import Any
9
+
10
+
11
+ class BaseExecutor(ABC):
12
+ """Base class for agent executors.
13
+
14
+ This concrete base class provides a default structure for executing agents.
15
+
16
+ Attributes:
17
+ None. This is an abstract base class that defines an interface.
18
+ """
19
+
20
+ @abstractmethod
21
+ def invoke(self, _inputs: dict[str, Any], **kwargs: Any) -> dict[str, Any]:
22
+ """Invoke the agent executor.
23
+
24
+ Subclasses must implement this method with their specific implementation.
25
+
26
+ Args:
27
+ _inputs: A dictionary of inputs for the executor.
28
+ **kwargs: Additional keyword arguments for customizing execution behavior.
29
+
30
+ Returns:
31
+ A dictionary containing the execution result.
32
+ """
33
+ raise NotImplementedError("Subclasses must implement invoke()")
34
+
35
+ @abstractmethod
36
+ async def ainvoke(self, _inputs: dict[str, Any], **kwargs: Any) -> dict[str, Any]:
37
+ """Asynchronously invoke the agent executor.
38
+
39
+ Subclasses must implement this method with their specific implementation.
40
+
41
+ Args:
42
+ _inputs: A dictionary of inputs for the executor.
43
+ **kwargs: Additional keyword arguments for customizing execution behavior.
44
+
45
+ Returns:
46
+ A dictionary containing the execution result.
47
+ """
48
+ raise NotImplementedError("Subclasses must implement ainvoke()")
@@ -0,0 +1 @@
1
+ """Model Context Protocol related classes and functions."""
@@ -0,0 +1,14 @@
1
+ """MCP Client.
2
+
3
+ This module provides a adapter client for interacting with MCP servers.
4
+
5
+ Authors:
6
+ Fachriza Dian Adhiatma (fachriza.d.adhiatma@gdplabs.id)
7
+ Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
8
+ """
9
+
10
+ from aip_agents.mcp.client.base_mcp_client import BaseMCPClient
11
+ from aip_agents.mcp.client.google_adk.client import GoogleADKMCPClient
12
+ from aip_agents.mcp.client.langchain.client import LangchainMCPClient
13
+
14
+ __all__ = ["GoogleADKMCPClient", "LangchainMCPClient", "BaseMCPClient"]