aip-agents-binary 0.0.0b2__py3-none-any.whl → 0.5.12__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 (426) 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.pyi → interface.py} +70 -13
  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.pyi → adk_arithmetic_tools.py} +12 -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.pyi → base.py} +40 -5
  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.pyi → base.py} +30 -4
  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.pyi → base.py} +23 -6
  190. aip_agents/storage/providers/{memory.pyi → memory.py} +38 -3
  191. aip_agents/storage/providers/object_storage.py +214 -0
  192. aip_agents/tools/__init__.py +6 -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 +37 -0
  213. aip_agents/tools/document_loader/base_reader.py +262 -0
  214. aip_agents/tools/document_loader/docx_reader_tool.py +53 -0
  215. aip_agents/tools/document_loader/excel_reader_tool.py +160 -0
  216. aip_agents/tools/document_loader/pdf_reader_tool.py +67 -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/tool_config_injector.py +300 -0
  226. aip_agents/tools/web_search/__init__.py +15 -0
  227. aip_agents/tools/web_search/serper_tool.py +187 -0
  228. aip_agents/types/__init__.py +70 -0
  229. aip_agents/types/a2a_events.py +13 -0
  230. aip_agents/utils/__init__.py +79 -0
  231. aip_agents/utils/a2a_connector.py +1757 -0
  232. aip_agents/utils/artifact_helpers.py +502 -0
  233. aip_agents/utils/constants.py +22 -0
  234. aip_agents/utils/datetime/__init__.py +34 -0
  235. aip_agents/utils/datetime/normalization.py +231 -0
  236. aip_agents/utils/datetime/timezone.py +206 -0
  237. aip_agents/utils/env_loader.py +27 -0
  238. aip_agents/utils/event_handler_registry.py +58 -0
  239. aip_agents/utils/file_prompt_utils.py +176 -0
  240. aip_agents/utils/final_response_builder.py +211 -0
  241. aip_agents/utils/formatter_llm_client.py +231 -0
  242. aip_agents/utils/langgraph/__init__.py +19 -0
  243. aip_agents/utils/langgraph/converter.py +128 -0
  244. aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
  245. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
  246. aip_agents/utils/langgraph/tool_managers/{base_tool_manager.pyi → base_tool_manager.py} +25 -8
  247. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1071 -0
  248. aip_agents/utils/langgraph/tool_output_management.py +967 -0
  249. aip_agents/utils/logger.py +195 -0
  250. aip_agents/utils/metadata/__init__.py +27 -0
  251. aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
  252. aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
  253. aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
  254. aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
  255. aip_agents/utils/metadata/activity_narrative/context.py +49 -0
  256. aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
  257. aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
  258. aip_agents/utils/metadata/schemas/__init__.py +16 -0
  259. aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
  260. aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
  261. aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
  262. aip_agents/utils/metadata_helper.py +358 -0
  263. aip_agents/utils/name_preprocessor/__init__.py +17 -0
  264. aip_agents/utils/name_preprocessor/{base_name_preprocessor.pyi → base_name_preprocessor.py} +22 -2
  265. aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
  266. aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
  267. aip_agents/utils/name_preprocessor/{openai_name_preprocessor.pyi → openai_name_preprocessor.py} +19 -5
  268. aip_agents/utils/pii/__init__.py +25 -0
  269. aip_agents/utils/pii/pii_handler.py +397 -0
  270. aip_agents/utils/pii/pii_helper.py +207 -0
  271. aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
  272. aip_agents/utils/reference_helper.py +273 -0
  273. aip_agents/utils/sse_chunk_transformer.py +831 -0
  274. aip_agents/utils/step_limit_manager.py +265 -0
  275. aip_agents/utils/token_usage_helper.py +156 -0
  276. aip_agents_binary-0.5.12.dist-info/METADATA +689 -0
  277. aip_agents_binary-0.5.12.dist-info/RECORD +279 -0
  278. {aip_agents_binary-0.0.0b2.dist-info → aip_agents_binary-0.5.12.dist-info}/WHEEL +2 -1
  279. aip_agents_binary-0.5.12.dist-info/top_level.txt +1 -0
  280. aip_agents/__init__.pyi +0 -0
  281. aip_agents/a2a/__init__.pyi +0 -3
  282. aip_agents/a2a/server/__init__.pyi +0 -4
  283. aip_agents/a2a/server/base_executor.pyi +0 -63
  284. aip_agents/a2a/server/google_adk_executor.pyi +0 -51
  285. aip_agents/a2a/server/langgraph_executor.pyi +0 -48
  286. aip_agents/a2a/types.pyi +0 -125
  287. aip_agents/agent/__init__.pyi +0 -7
  288. aip_agents/agent/base_agent.pyi +0 -205
  289. aip_agents/agent/base_langgraph_agent.pyi +0 -164
  290. aip_agents/agent/google_adk_agent.pyi +0 -128
  291. aip_agents/agent/langgraph_react_agent.pyi +0 -131
  292. aip_agents/agent/types.pyi +0 -106
  293. aip_agents/constants.pyi +0 -6
  294. aip_agents/examples/__init__.pyi +0 -0
  295. aip_agents/examples/hello_world_a2a_google_adk_client.pyi +0 -9
  296. aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +0 -9
  297. aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +0 -9
  298. aip_agents/examples/hello_world_a2a_google_adk_server.pyi +0 -10
  299. aip_agents/examples/hello_world_a2a_langchain_client.pyi +0 -5
  300. aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +0 -5
  301. aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +0 -5
  302. aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +0 -5
  303. aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +0 -5
  304. aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +0 -10
  305. aip_agents/examples/hello_world_a2a_langchain_server.pyi +0 -10
  306. aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +0 -10
  307. aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +0 -5
  308. aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +0 -5
  309. aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +0 -11
  310. aip_agents/examples/hello_world_a2a_langgraph_client.pyi +0 -9
  311. aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +0 -9
  312. aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +0 -2
  313. aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +0 -9
  314. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +0 -5
  315. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +0 -5
  316. aip_agents/examples/hello_world_a2a_langgraph_server.pyi +0 -9
  317. aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +0 -10
  318. aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +0 -10
  319. aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +0 -48
  320. aip_agents/examples/hello_world_a2a_multi_agent_coordinator_client.pyi +0 -15
  321. aip_agents/examples/hello_world_a2a_multi_agent_coordinator_client_streaming.pyi +0 -5
  322. aip_agents/examples/hello_world_a2a_multi_agent_coordinator_server.pyi +0 -11
  323. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +0 -23
  324. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +0 -17
  325. aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +0 -5
  326. aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +0 -10
  327. aip_agents/examples/hello_world_google_adk.pyi +0 -5
  328. aip_agents/examples/hello_world_google_adk_mcp_http.pyi +0 -5
  329. aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +0 -5
  330. aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +0 -5
  331. aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +0 -5
  332. aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +0 -5
  333. aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +0 -5
  334. aip_agents/examples/hello_world_google_adk_stream.pyi +0 -5
  335. aip_agents/examples/hello_world_langchain.pyi +0 -5
  336. aip_agents/examples/hello_world_langchain_lm_invoker.pyi +0 -2
  337. aip_agents/examples/hello_world_langchain_mcp_http.pyi +0 -5
  338. aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +0 -5
  339. aip_agents/examples/hello_world_langchain_mcp_sse.pyi +0 -5
  340. aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +0 -5
  341. aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +0 -5
  342. aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +0 -5
  343. aip_agents/examples/hello_world_langchain_stream.pyi +0 -5
  344. aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +0 -5
  345. aip_agents/examples/hello_world_langgraph.pyi +0 -5
  346. aip_agents/examples/hello_world_langgraph_bosa.pyi +0 -5
  347. aip_agents/examples/hello_world_langgraph_bosa_twitter.pyi +0 -5
  348. aip_agents/examples/hello_world_langgraph_mcp_http.pyi +0 -5
  349. aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +0 -5
  350. aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +0 -5
  351. aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +0 -5
  352. aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +0 -5
  353. aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +0 -5
  354. aip_agents/examples/hello_world_langgraph_stream.pyi +0 -5
  355. aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +0 -5
  356. aip_agents/examples/hello_world_model_switch_cli.pyi +0 -15
  357. aip_agents/examples/hello_world_multi_agent_adk.pyi +0 -6
  358. aip_agents/examples/hello_world_multi_agent_langchain.pyi +0 -5
  359. aip_agents/examples/hello_world_multi_agent_langgraph.pyi +0 -5
  360. aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +0 -5
  361. aip_agents/examples/hello_world_pii_logger.pyi +0 -5
  362. aip_agents/examples/hello_world_sentry.pyi +0 -21
  363. aip_agents/examples/hello_world_stock_a2a_server.pyi +0 -12
  364. aip_agents/examples/hello_world_tool_output_client.pyi +0 -5
  365. aip_agents/examples/hello_world_tool_output_server.pyi +0 -14
  366. aip_agents/examples/tools/__init__.pyi +0 -7
  367. aip_agents/examples/tools/adk_weather_tool.pyi +0 -18
  368. aip_agents/examples/tools/data_generator_tool.pyi +0 -15
  369. aip_agents/examples/tools/data_visualization_tool.pyi +0 -17
  370. aip_agents/examples/tools/image_artifact_tool.pyi +0 -24
  371. aip_agents/examples/tools/langchain_arithmetic_tools.pyi +0 -10
  372. aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +0 -21
  373. aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +0 -23
  374. aip_agents/examples/tools/langchain_weather_tool.pyi +0 -19
  375. aip_agents/examples/tools/langgraph_streaming_tool.pyi +0 -43
  376. aip_agents/examples/tools/pr_details_bosa_tool.pyi +0 -26
  377. aip_agents/examples/tools/serper_tool.pyi +0 -16
  378. aip_agents/examples/tools/stock_tools.pyi +0 -21
  379. aip_agents/examples/tools/table_generator_tool.pyi +0 -22
  380. aip_agents/examples/tools/time_tool.pyi +0 -15
  381. aip_agents/examples/tools/weather_forecast_tool.pyi +0 -14
  382. aip_agents/mcp/__init__.pyi +0 -0
  383. aip_agents/mcp/client/__init__.pyi +0 -4
  384. aip_agents/mcp/client/google_adk/__init__.pyi +0 -3
  385. aip_agents/mcp/client/google_adk/client.pyi +0 -38
  386. aip_agents/mcp/client/langchain/__init__.pyi +0 -3
  387. aip_agents/mcp/client/langchain/client.pyi +0 -3
  388. aip_agents/memory/__init__.pyi +0 -0
  389. aip_agents/memory/simple_memory.pyi +0 -22
  390. aip_agents/sentry/__init__.pyi +0 -3
  391. aip_agents/sentry/sentry.pyi +0 -48
  392. aip_agents/storage/__init__.pyi +0 -8
  393. aip_agents/storage/clients/__init__.pyi +0 -3
  394. aip_agents/storage/clients/minio_client.pyi +0 -137
  395. aip_agents/storage/config.pyi +0 -66
  396. aip_agents/storage/providers/__init__.pyi +0 -5
  397. aip_agents/storage/providers/object_storage.pyi +0 -98
  398. aip_agents/tools/__init__.pyi +0 -3
  399. aip_agents/tools/base.pyi +0 -44
  400. aip_agents/tools/base_bosa_tools.pyi +0 -12
  401. aip_agents/tools/bosa_connector.pyi +0 -30
  402. aip_agents/tools/bosa_tools.pyi +0 -37
  403. aip_agents/tools/bosa_tools_interface.pyi +0 -26
  404. aip_agents/tools/constants.pyi +0 -130
  405. aip_agents/tools/nested_agent_tool.pyi +0 -45
  406. aip_agents/tools/tool_config_injector.pyi +0 -26
  407. aip_agents/types/__init__.pyi +0 -3
  408. aip_agents/types/a2a_events.pyi +0 -74
  409. aip_agents/utils/__init__.pyi +0 -5
  410. aip_agents/utils/a2a_connector.pyi +0 -135
  411. aip_agents/utils/artifact_helpers.pyi +0 -179
  412. aip_agents/utils/langgraph/__init__.pyi +0 -3
  413. aip_agents/utils/langgraph/converter.pyi +0 -49
  414. aip_agents/utils/langgraph/tool_managers/__init__.pyi +0 -5
  415. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +0 -35
  416. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +0 -50
  417. aip_agents/utils/langgraph/tool_output_management.pyi +0 -310
  418. aip_agents/utils/logger_manager.pyi +0 -151
  419. aip_agents/utils/metadata_helper.pyi +0 -110
  420. aip_agents/utils/name_preprocessor/__init__.pyi +0 -6
  421. aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +0 -38
  422. aip_agents/utils/name_preprocessor/name_preprocessor.pyi +0 -41
  423. aip_agents/utils/reference_helper.pyi +0 -49
  424. aip_agents/utils/token_usage_helper.pyi +0 -60
  425. aip_agents_binary-0.0.0b2.dist-info/METADATA +0 -277
  426. aip_agents_binary-0.0.0b2.dist-info/RECORD +0 -157
@@ -0,0 +1,142 @@
1
+ """Tool that generates random bar chart artifacts for streaming demos."""
2
+
3
+ import io
4
+ import random
5
+ from typing import Any
6
+
7
+ from langchain_core.tools import BaseTool
8
+ from langgraph.types import Command
9
+ from pydantic import BaseModel, Field
10
+
11
+ from aip_agents.a2a.types import MimeType
12
+ from aip_agents.utils.artifact_helpers import create_artifact_command
13
+
14
+ DEFAULT_RANDOM_CHART_TITLE = "Random Insights"
15
+
16
+ try:
17
+ from PIL import Image, ImageDraw # type: ignore
18
+
19
+ PIL_AVAILABLE = True
20
+ except ImportError: # pragma: no cover - PIL optional
21
+ PIL_AVAILABLE = False
22
+ Image = None
23
+ ImageDraw = None
24
+
25
+
26
+ class RandomChartInput(BaseModel):
27
+ """Input schema for random chart generation."""
28
+
29
+ title: str = Field(
30
+ default=DEFAULT_RANDOM_CHART_TITLE,
31
+ description="Title rendered at the top of the chart.",
32
+ )
33
+ num_bars: int = Field(
34
+ default=5,
35
+ ge=3,
36
+ le=10,
37
+ description="How many bars to render.",
38
+ )
39
+ min_value: int = Field(
40
+ default=10,
41
+ ge=0,
42
+ description="Minimum possible value for a bar.",
43
+ )
44
+ max_value: int = Field(
45
+ default=100,
46
+ gt=10,
47
+ description="Maximum possible value for a bar.",
48
+ )
49
+
50
+
51
+ class RandomChartTool(BaseTool):
52
+ """Generate random bar chart images without relying on upstream data."""
53
+
54
+ name: str = "random_chart_tool"
55
+ description: str = "Create a random bar chart image artifact to showcase image streaming."
56
+ args_schema: type[BaseModel] = RandomChartInput
57
+
58
+ def _run( # noqa: D401
59
+ self,
60
+ title: str = DEFAULT_RANDOM_CHART_TITLE,
61
+ num_bars: int = 5,
62
+ min_value: int = 10,
63
+ max_value: int = 100,
64
+ **kwargs: Any,
65
+ ) -> Command:
66
+ """Generate the chart synchronously."""
67
+ if min_value >= max_value:
68
+ return Command(
69
+ update={"result": "❌ min_value must be less than max_value", "metadata": {"error": "invalid_range"}}
70
+ )
71
+
72
+ rng = random.Random()
73
+ values = [rng.randint(min_value, max_value) for _ in range(num_bars)]
74
+ labels = [f"Bar {i + 1}" for i in range(num_bars)]
75
+
76
+ if PIL_AVAILABLE:
77
+ image_bytes = self._create_image_with_pil(title, labels, values)
78
+ else:
79
+ image_bytes = self._create_text_artifact(title, labels, values)
80
+
81
+ artifact_mime_type = MimeType.IMAGE_PNG if PIL_AVAILABLE else MimeType.TEXT_PLAIN
82
+ return create_artifact_command(
83
+ result=f"📊 Generated random bar chart '{title}' with {num_bars} bars",
84
+ artifact_data=image_bytes,
85
+ artifact_name=f"{title.lower().replace(' ', '_')}_random_chart.png",
86
+ artifact_description=f"Random bar chart ({num_bars} bars)",
87
+ mime_type=artifact_mime_type,
88
+ metadata_update={
89
+ "visualization": {
90
+ "chart_type": "bar",
91
+ "title": title,
92
+ "data_points": num_bars,
93
+ "randomized": True,
94
+ }
95
+ },
96
+ )
97
+
98
+ async def _arun(
99
+ self,
100
+ title: str = DEFAULT_RANDOM_CHART_TITLE,
101
+ num_bars: int = 5,
102
+ min_value: int = 10,
103
+ max_value: int = 100,
104
+ **kwargs: Any,
105
+ ) -> Command:
106
+ """Async wrapper for random chart generation."""
107
+ return self._run(title=title, num_bars=num_bars, min_value=min_value, max_value=max_value, **kwargs)
108
+
109
+ def _create_image_with_pil(self, title: str, labels: list[str], values: list[int]) -> bytes:
110
+ width, height = 400, 300
111
+ image = Image.new("RGB", (width, height), "white")
112
+ draw = ImageDraw.Draw(image)
113
+ draw.text((10, 10), title[:40], fill="black")
114
+
115
+ chart_x, chart_y = 40, 50
116
+ chart_width = width - 80
117
+ chart_height = height - 100
118
+
119
+ max_val = max(values)
120
+ min_val = min(values)
121
+ val_range = max_val - min_val if max_val != min_val else 1
122
+ bar_width = chart_width // len(values)
123
+
124
+ for idx, (label, value) in enumerate(zip(labels, values, strict=False)):
125
+ x = chart_x + idx * bar_width
126
+ normalized = (value - min_val) / val_range
127
+ y = chart_y + chart_height - (normalized * chart_height)
128
+
129
+ draw.rectangle([x + 2, y, x + bar_width - 4, chart_y + chart_height], fill="#4C78A8", outline="black")
130
+ draw.text((x + 2, chart_y + chart_height + 5), label[:8], fill="black")
131
+
132
+ buf = io.BytesIO()
133
+ image.save(buf, format="PNG")
134
+ return buf.getvalue()
135
+
136
+ def _create_text_artifact(self, title: str, labels: list[str], values: list[int]) -> bytes:
137
+ max_val = max(values)
138
+ lines = [f"=== {title} ===", "", "Random bar chart artifact", ""]
139
+ for label, value in zip(labels, values, strict=False):
140
+ length = int((value / max_val) * 30) if max_val else 0
141
+ lines.append(f"{label:>8}: {'█' * length} ({value})")
142
+ return "\n".join(lines).encode("utf-8")
@@ -0,0 +1,202 @@
1
+ """Tool to search Google Serper API.
2
+
3
+ Authors:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ Fachriza Adhiatma (fachriza.d.adhiatma@gdplabs.id)
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ from typing import Any
11
+
12
+ from gllm_core.schema import Chunk
13
+ from langchain_core.tools import BaseTool
14
+ from pydantic import BaseModel, Field
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class GoogleSerperInput(BaseModel):
20
+ """Input schema for the GoogleSerperTool."""
21
+
22
+ query: str = Field(..., description="Search query")
23
+
24
+
25
+ class MockGoogleSerperTool(BaseTool):
26
+ """Mock Tool to simulate Google Serper API results for testing."""
27
+
28
+ name: str = "google_serper"
29
+ description: str = """
30
+ Useful for searching the web using the Google Serper API (mocked).
31
+ Input should be a search query.
32
+ """
33
+ save_output_history: bool = True
34
+ args_schema: type[BaseModel] = GoogleSerperInput
35
+
36
+ def _run(self, query: str) -> str:
37
+ """Return a hardcoded mock response as a JSON string.
38
+
39
+ Args:
40
+ query (str): The search query to process.
41
+
42
+ Returns:
43
+ str: JSON string containing mock search results.
44
+ """
45
+ normalized_query = query.lower()
46
+
47
+ # Special-case oncology AI drug discovery queries so the agent
48
+ # naturally sees stock-oriented company context and can call
49
+ # stock tools (get_stock_price, get_stock_news) afterwards.
50
+ if "oncology" in normalized_query or "drug discovery" in normalized_query:
51
+ mock_result = {
52
+ "organic": [
53
+ {
54
+ "title": "NVIDIA (NVDA) - AI infrastructure for healthcare and drug discovery",
55
+ "link": "https://nvidia.example.com/healthcare-ai",
56
+ "snippet": (
57
+ "NVIDIA (ticker: NVDA) provides GPU-accelerated platforms widely used in AI-driven "
58
+ "drug discovery and oncology research. Investors closely watch NVDA stock as demand "
59
+ "for healthcare and life-sciences AI workloads grows."
60
+ ),
61
+ },
62
+ {
63
+ "title": "Microsoft (MSFT) - Azure AI partnerships with pharma and oncology",
64
+ "link": "https://microsoft.example.com/azure-health",
65
+ "snippet": (
66
+ "Microsoft (MSFT) collaborates with leading pharma companies to apply Azure AI to "
67
+ "oncology and drug discovery workflows. Analysts frequently reference MSFT stock when "
68
+ "discussing enterprise AI in healthcare."
69
+ ),
70
+ },
71
+ {
72
+ "title": "Apple (AAPL) - Devices and AI ecosystems in digital health",
73
+ "link": "https://apple.example.com/health-ai",
74
+ "snippet": (
75
+ "Apple (AAPL) integrates AI into health and wellness features that support oncology "
76
+ "patients and clinical research. Market commentary often links AAPL stock to long-term "
77
+ "growth in digital health and AI."
78
+ ),
79
+ },
80
+ ],
81
+ "news": [
82
+ {
83
+ "title": "NVDA rallies on new healthcare AI partnerships",
84
+ "link": "https://news.example.com/nvda-oncology-ai",
85
+ "snippet": (
86
+ "NVIDIA (NVDA) announced expanded collaborations focused on oncology and AI-driven "
87
+ "drug discovery, prompting renewed interest in NVDA stock among growth investors."
88
+ ),
89
+ },
90
+ {
91
+ "title": "MSFT deepens AI oncology collaborations on Azure",
92
+ "link": "https://news.example.com/msft-azure-oncology",
93
+ "snippet": (
94
+ "Microsoft (MSFT) reported new Azure AI partnerships with oncology research centers, "
95
+ "and analysts highlighted MSFT stock as a key AI infrastructure play in healthcare."
96
+ ),
97
+ },
98
+ {
99
+ "title": "AAPL explores AI-enabled health insights for cancer care",
100
+ "link": "https://news.example.com/aapl-health-oncology",
101
+ "snippet": (
102
+ "Apple (AAPL) is reportedly piloting AI-enabled health features that could support "
103
+ "oncology patient monitoring, adding another angle to the long-term AAPL stock story."
104
+ ),
105
+ },
106
+ ],
107
+ }
108
+ else:
109
+ # Default mock result used for generic queries.
110
+ mock_result = {
111
+ "organic": [
112
+ {
113
+ "title": "NeoAI - Artificial Intelligence Research",
114
+ "link": "https://neoai.example.com/",
115
+ "snippet": (
116
+ "NeoAI is an AI research and deployment company. Our mission is to ensure that "
117
+ "artificial general intelligence benefits all of humanity."
118
+ ),
119
+ },
120
+ {
121
+ "title": "Wikipedia - NeoAI",
122
+ "link": "https://en.wikipedia.org/wiki/NeoAI",
123
+ "snippet": (
124
+ "NeoAI is a fictional artificial intelligence research organization consisting of the "
125
+ "for-profit NeoAI LP and its parent company, the non-profit NeoAI Foundation."
126
+ ),
127
+ },
128
+ ],
129
+ "news": [
130
+ {
131
+ "title": "NeoAI unveils new LLM model",
132
+ "link": "https://news.example.com/neoai-llm",
133
+ "snippet": (
134
+ "NeoAI has announced the release of NeoAI-LLM, a new large multimodal model that accepts "
135
+ "image and text inputs."
136
+ ),
137
+ }
138
+ ],
139
+ }
140
+
141
+ return json.dumps(mock_result)
142
+
143
+ def _format_agent_reference(self, tool_output: str) -> list[Chunk]:
144
+ parsed_output = self._parse_tool_output(tool_output)
145
+ if not parsed_output:
146
+ return []
147
+ formatted_chunks = []
148
+ file_id_counter = 0
149
+ for section_name, section_data in parsed_output.items():
150
+ if not isinstance(section_data, list):
151
+ continue
152
+ results = self._process_section_items(section_name, section_data, file_id_counter)
153
+ formatted_chunks.extend(results["chunks"])
154
+ file_id_counter = results["counter"]
155
+ return formatted_chunks
156
+
157
+ def _parse_tool_output(self, tool_output: str) -> dict[str, Any]:
158
+ if isinstance(tool_output, str):
159
+ try:
160
+ return json.loads(tool_output)
161
+ except json.JSONDecodeError:
162
+ logger.error("Error: Unable to parse tool_output as JSON when formatting agent references.")
163
+ return {}
164
+ return tool_output
165
+
166
+ def _process_section_items(self, section_name: str, section_data: list[dict], start_counter: int) -> dict[str, Any]:
167
+ chunks = []
168
+ counter = start_counter
169
+ for item in section_data:
170
+ if not isinstance(item, dict):
171
+ continue
172
+ try:
173
+ chunk = self._create_chunk_from_item(section_name, item, counter)
174
+ if chunk:
175
+ chunks.append(chunk)
176
+ counter += 1
177
+ except Exception as e:
178
+ logger.error(f"Error processing {section_name} result: {e}")
179
+ return {"chunks": chunks, "counter": counter}
180
+
181
+ def _create_chunk_from_item(self, section_name: str, item: dict[str, Any], file_id: int) -> Chunk | None:
182
+ link = item.get("link")
183
+ if not link:
184
+ logger.warning(f"Skipping item {file_id} from {section_name} result: Missing link")
185
+ return None
186
+ content = ""
187
+ if "snippet" in item:
188
+ content = item["snippet"]
189
+ elif "title" in item:
190
+ content = item["title"]
191
+ if not content:
192
+ logger.warning(f"Skipping item {file_id} from {section_name} result: Missing content")
193
+ return None
194
+ metadata = {
195
+ "source": item.get("title", "Untitled Source"),
196
+ "section_type": section_name,
197
+ "source_type": "website",
198
+ "title": item.get("title", "Untitled"),
199
+ "link": link,
200
+ "file_id": str(file_id),
201
+ }
202
+ return Chunk(content=content, metadata=metadata)
@@ -0,0 +1,82 @@
1
+ """Defines tools for stock market data.
2
+
3
+ Authors:
4
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
5
+ Raymond Christopher (raymond.christopher@gdplabs.id)
6
+ """
7
+
8
+ import random
9
+ from typing import Any
10
+
11
+ from langchain_core.tools import tool
12
+ from pydantic import BaseModel, Field
13
+
14
+ from aip_agents.utils.logger import get_logger
15
+
16
+ logger = get_logger(__name__)
17
+
18
+
19
+ class StockPriceInput(BaseModel):
20
+ """Input for the stock price tool."""
21
+
22
+ symbol: str = Field(description="The stock symbol (e.g., AAPL, MSFT) to get the price for.")
23
+
24
+
25
+ @tool(args_schema=StockPriceInput)
26
+ def get_stock_price(symbol: str) -> dict[str, Any]:
27
+ """Get current stock price and performance data for a given symbol.
28
+
29
+ Args:
30
+ symbol (str): The stock symbol (e.g., AAPL, MSFT) to get the price for.
31
+
32
+ Returns:
33
+ dict[str, Any]: Dictionary containing stock price and performance data.
34
+ """
35
+ logger.info(f"Getting stock price for {symbol}")
36
+ # Simulate stock price data
37
+ price = round(random.uniform(100, 1000), 2)
38
+ change = round(random.uniform(-10, 10), 2)
39
+ change_percent = round((change / price) * 100, 2)
40
+ return {
41
+ "symbol": symbol.upper(),
42
+ "price": price,
43
+ "change": change,
44
+ "change_percent": change_percent,
45
+ "currency": "USD",
46
+ }
47
+
48
+
49
+ class StockNewsInput(BaseModel):
50
+ """Input for the stock news tool."""
51
+
52
+ symbol: str = Field(description="The stock symbol (e.g., AAPL, MSFT) to get news for.")
53
+ days: int = Field(default=7, description="Number of days of news to retrieve.")
54
+
55
+
56
+ @tool(args_schema=StockNewsInput)
57
+ def get_stock_news(symbol: str, days: int = 7) -> dict[str, Any]:
58
+ """Get recent news for a stock for a specified number of days.
59
+
60
+ Args:
61
+ symbol (str): The stock symbol (e.g., AAPL, MSFT) to get news for.
62
+ days (int, optional): Number of days of news to retrieve. Defaults to 7.
63
+
64
+ Returns:
65
+ dict[str, Any]: Dictionary containing stock news data.
66
+ """
67
+ logger.info(f"Getting stock news for {symbol} for the last {days} days")
68
+ # Simulate news data
69
+ news_items = [
70
+ f"{symbol.upper()} announces breakthrough in AI technology",
71
+ f"Analysts raise price target for {symbol.upper()}",
72
+ f"{symbol.upper()} reports better than expected earnings",
73
+ f"New product launch boosts {symbol.upper()} shares",
74
+ f"{symbol.upper()} partners with a major tech firm",
75
+ f"Regulatory changes impact {symbol.upper()}'s sector",
76
+ f"{symbol.upper()} to release new sustainability report",
77
+ ]
78
+ return {
79
+ "symbol": symbol.upper(),
80
+ "news": random.sample(news_items, min(days, len(news_items))),
81
+ "days": days,
82
+ }
@@ -0,0 +1,167 @@
1
+ """Table generator tool for demonstrating artifact generation.
2
+
3
+ This tool generates sample data tables and returns both a markdown representation
4
+ for the agent and a CSV file artifact for the user.
5
+
6
+ Authors:
7
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
+ """
9
+
10
+ import csv
11
+ import io
12
+ import random
13
+ from typing import Any
14
+
15
+ from langchain_core.tools import BaseTool
16
+ from pydantic import BaseModel, Field
17
+
18
+ from aip_agents.a2a.types import MimeType
19
+ from aip_agents.utils.artifact_helpers import create_artifact_response
20
+
21
+
22
+ class TableGeneratorInput(BaseModel):
23
+ """Input schema for table generator tool."""
24
+
25
+ rows: int = Field(default=5, description="Number of rows to generate", ge=1, le=100)
26
+ columns: list[str] = Field(default=["Name", "Age", "City"], description="Column names for the table")
27
+ table_name: str = Field(default="sample_data", description="Name for the generated table")
28
+
29
+
30
+ class TableGeneratorTool(BaseTool):
31
+ """Tool that generates sample data tables with artifact support.
32
+
33
+ This tool demonstrates the standardized artifact format by:
34
+ 1. Generating sample data
35
+ 2. Creating a markdown table for the agent's context
36
+ 3. Creating a CSV file artifact for the user
37
+ """
38
+
39
+ name: str = "table_generator"
40
+ description: str = "Generate sample data tables with specified columns and rows"
41
+ args_schema: type[BaseModel] = TableGeneratorInput
42
+
43
+ def _run(self, rows: int = 5, columns: list[str] = None, table_name: str = "sample_data") -> dict[str, Any]:
44
+ """Generate a table synchronously.
45
+
46
+ Args:
47
+ rows (int, optional): Number of rows to generate. Defaults to 5.
48
+ columns (list[str], optional): Column names for the table. Defaults to None.
49
+ table_name (str, optional): Name for the generated table. Defaults to "sample_data".
50
+
51
+ Returns:
52
+ dict[str, Any]: Response containing artifact data and metadata.
53
+ """
54
+ if columns is None:
55
+ columns = ["Name", "Age", "City"]
56
+
57
+ # Generate sample data
58
+ sample_data = self._generate_sample_data(rows, columns)
59
+
60
+ # Create markdown table for agent
61
+ markdown_table = self._create_markdown_table(sample_data, columns)
62
+
63
+ # Create CSV data for artifact
64
+ csv_data = self._create_csv_data(sample_data, columns)
65
+ csv_bytes = csv_data.encode("utf-8")
66
+
67
+ # Return standardized format using utility function
68
+ return create_artifact_response(
69
+ result=f"I have generated a {rows}-row table with columns: {', '.join(columns)}.\n\n{markdown_table}",
70
+ artifact_data=csv_bytes,
71
+ artifact_name=f"{table_name}.csv",
72
+ artifact_description=f"Generated table with {rows} rows and {len(columns)} columns",
73
+ mime_type=MimeType.TEXT_CSV,
74
+ )
75
+
76
+ async def _arun(self, rows: int = 5, columns: list[str] = None, table_name: str = "sample_data") -> dict[str, Any]:
77
+ """Generate a table asynchronously.
78
+
79
+ Args:
80
+ rows (int, optional): Number of rows to generate. Defaults to 5.
81
+ columns (list[str], optional): Column names for the table. Defaults to None.
82
+ table_name (str, optional): Name for the generated table. Defaults to "sample_data".
83
+
84
+ Returns:
85
+ dict[str, Any]: Response containing artifact data and metadata.
86
+ """
87
+ return self._run(rows, columns, table_name)
88
+
89
+ def _generate_sample_data(self, rows: int, columns: list[str]) -> list[list[str]]:
90
+ """Generate sample data based on column names.
91
+
92
+ Args:
93
+ rows (int): Number of rows to generate.
94
+ columns (list[str]): Column names for the table.
95
+
96
+ Returns:
97
+ list[list[str]]: Generated sample data as list of rows.
98
+ """
99
+ data = []
100
+ for i in range(rows):
101
+ row = []
102
+ for col in columns:
103
+ col_lower = col.lower()
104
+ if "name" in col_lower:
105
+ names = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry"]
106
+ row.append(random.choice(names))
107
+ elif "age" in col_lower:
108
+ row.append(str(random.randint(20, 65)))
109
+ elif "city" in col_lower:
110
+ cities = ["New York", "London", "Tokyo", "Paris", "Sydney", "Berlin", "Toronto", "Mumbai"]
111
+ row.append(random.choice(cities))
112
+ elif "email" in col_lower:
113
+ domains = ["gmail.com", "yahoo.com", "outlook.com", "company.com"]
114
+ username = f"user{i + 1}"
115
+ row.append(f"{username}@{random.choice(domains)}")
116
+ elif "score" in col_lower or "rating" in col_lower:
117
+ row.append(str(random.randint(1, 100)))
118
+ else:
119
+ row.append(f"Value{i + 1}")
120
+ data.append(row)
121
+ return data
122
+
123
+ def _create_markdown_table(self, data: list[list[str]], columns: list[str]) -> str:
124
+ """Create a markdown table representation.
125
+
126
+ Args:
127
+ data (list[list[str]]): Table data as list of rows.
128
+ columns (list[str]): Column names for the table.
129
+
130
+ Returns:
131
+ str: Markdown formatted table string.
132
+ """
133
+ if not data:
134
+ return "| No data |\n|---------|"
135
+
136
+ # Header
137
+ header = "| " + " | ".join(columns) + " |"
138
+ separator = "| " + " | ".join(["---"] * len(columns)) + " |"
139
+
140
+ # Rows
141
+ rows = []
142
+ for row in data:
143
+ rows.append("| " + " | ".join(row) + " |")
144
+
145
+ return "\n".join([header, separator] + rows)
146
+
147
+ def _create_csv_data(self, data: list[list[str]], columns: list[str]) -> str:
148
+ """Create CSV data string.
149
+
150
+ Args:
151
+ data (list[list[str]]): Table data as list of rows.
152
+ columns (list[str]): Column names for the table.
153
+
154
+ Returns:
155
+ str: CSV formatted data string.
156
+ """
157
+ output = io.StringIO()
158
+ writer = csv.writer(output)
159
+
160
+ # Write header
161
+ writer.writerow(columns)
162
+
163
+ # Write data
164
+ for row in data:
165
+ writer.writerow(row)
166
+
167
+ return output.getvalue()
@@ -0,0 +1,82 @@
1
+ """Tool to get the current time.
2
+
3
+ Authors:
4
+ Saul Sayers (saul.sayers@gdplabs.id)
5
+ """
6
+
7
+ from datetime import datetime
8
+
9
+ from gllm_core.schema import Chunk
10
+ from langchain_core.tools import BaseTool
11
+ from pydantic import BaseModel, Field
12
+
13
+ FORMAT_STRING = "%m/%d/%y %H:%M:%S"
14
+
15
+
16
+ class TimeToolInput(BaseModel):
17
+ """Input schema for the TimeTool."""
18
+
19
+ datetime_format: str = Field(
20
+ default=FORMAT_STRING,
21
+ description="""
22
+ Optional datetime format string. Default: '%m/%d/%y %H:%M:%S'
23
+
24
+ Common format codes:
25
+ %Y: Year with century (2024)
26
+ %m: Month as number (01-12)
27
+ %d: Day of month (01-31)
28
+ %A: Full weekday name (Wednesday)
29
+ %a: Short weekday name (Wed)
30
+ %H: Hour (00-23)
31
+ %M: Minute (00-59)
32
+ %S: Second (00-59)
33
+ %Z: Timezone name
34
+ %j: Day of year (001-366)
35
+ %W: Week number (00-53, Monday first)
36
+ %U: Week number (00-53, Sunday first)
37
+ %c: Locale's date and time
38
+ %x: Locale's date
39
+ %X: Locale's time
40
+ """,
41
+ )
42
+
43
+
44
+ class TimeTool(BaseTool):
45
+ """Tool to get the current time."""
46
+
47
+ name: str = "time_tool"
48
+ description: str = """
49
+ Useful for getting the current time in a specified format or the default format.
50
+ Default format: '%m/%d/%y %H:%M:%S' (e.g., '05/15/24 17:30:00')
51
+ """
52
+ save_output_history: bool = True
53
+ args_schema: type[BaseModel] = TimeToolInput
54
+
55
+ def _run(self, datetime_format: str = FORMAT_STRING) -> str:
56
+ """Get the current time formatted as a string.
57
+
58
+ Args:
59
+ datetime_format (str): The format string to use for the datetime output. Defaults to FORMAT_STRING.
60
+
61
+ Returns:
62
+ str: The current time formatted according to the provided format string.
63
+ """
64
+ return datetime.now().strftime(datetime_format)
65
+
66
+ def _format_agent_reference(self, tool_output: str) -> list[Chunk]:
67
+ """Format the tool output as a reference chunk for agent use.
68
+
69
+ Args:
70
+ tool_output (str): The output string from the tool execution.
71
+
72
+ Returns:
73
+ list[Chunk]: A list containing a single reference chunk with the tool output and metadata.
74
+ """
75
+ return [
76
+ Chunk(
77
+ content=tool_output,
78
+ metadata={
79
+ "tool_name": self.name,
80
+ },
81
+ )
82
+ ]