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.
Files changed (546) hide show
  1. aip_agents/__init__.py +65 -0
  2. aip_agents/__init__.pyi +19 -0
  3. aip_agents/a2a/__init__.py +19 -0
  4. aip_agents/a2a/__init__.pyi +3 -0
  5. aip_agents/a2a/server/__init__.py +10 -0
  6. aip_agents/a2a/server/__init__.pyi +4 -0
  7. aip_agents/a2a/server/base_executor.py +1086 -0
  8. aip_agents/a2a/server/base_executor.pyi +73 -0
  9. aip_agents/a2a/server/google_adk_executor.py +198 -0
  10. aip_agents/a2a/server/google_adk_executor.pyi +51 -0
  11. aip_agents/a2a/server/langflow_executor.py +180 -0
  12. aip_agents/a2a/server/langflow_executor.pyi +43 -0
  13. aip_agents/a2a/server/langgraph_executor.py +270 -0
  14. aip_agents/a2a/server/langgraph_executor.pyi +47 -0
  15. aip_agents/a2a/types.py +232 -0
  16. aip_agents/a2a/types.pyi +132 -0
  17. aip_agents/agent/__init__.py +27 -0
  18. aip_agents/agent/__init__.pyi +9 -0
  19. aip_agents/agent/base_agent.py +970 -0
  20. aip_agents/agent/base_agent.pyi +221 -0
  21. aip_agents/agent/base_langgraph_agent.py +2942 -0
  22. aip_agents/agent/base_langgraph_agent.pyi +232 -0
  23. aip_agents/agent/google_adk_agent.py +926 -0
  24. aip_agents/agent/google_adk_agent.pyi +141 -0
  25. aip_agents/agent/google_adk_constants.py +6 -0
  26. aip_agents/agent/google_adk_constants.pyi +3 -0
  27. aip_agents/agent/hitl/__init__.py +24 -0
  28. aip_agents/agent/hitl/__init__.pyi +6 -0
  29. aip_agents/agent/hitl/config.py +28 -0
  30. aip_agents/agent/hitl/config.pyi +15 -0
  31. aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
  32. aip_agents/agent/hitl/langgraph_hitl_mixin.pyi +42 -0
  33. aip_agents/agent/hitl/manager.py +532 -0
  34. aip_agents/agent/hitl/manager.pyi +200 -0
  35. aip_agents/agent/hitl/models.py +18 -0
  36. aip_agents/agent/hitl/models.pyi +3 -0
  37. aip_agents/agent/hitl/prompt/__init__.py +9 -0
  38. aip_agents/agent/hitl/prompt/__init__.pyi +4 -0
  39. aip_agents/agent/hitl/prompt/base.py +42 -0
  40. aip_agents/agent/hitl/prompt/base.pyi +24 -0
  41. aip_agents/agent/hitl/prompt/deferred.py +73 -0
  42. aip_agents/agent/hitl/prompt/deferred.pyi +30 -0
  43. aip_agents/agent/hitl/registry.py +149 -0
  44. aip_agents/agent/hitl/registry.pyi +101 -0
  45. aip_agents/agent/interface.py +138 -0
  46. aip_agents/agent/interface.pyi +81 -0
  47. aip_agents/agent/interfaces.py +65 -0
  48. aip_agents/agent/interfaces.pyi +44 -0
  49. aip_agents/agent/langflow_agent.py +464 -0
  50. aip_agents/agent/langflow_agent.pyi +133 -0
  51. aip_agents/agent/langgraph_memory_enhancer_agent.py +433 -0
  52. aip_agents/agent/langgraph_memory_enhancer_agent.pyi +49 -0
  53. aip_agents/agent/langgraph_react_agent.py +2514 -0
  54. aip_agents/agent/langgraph_react_agent.pyi +126 -0
  55. aip_agents/agent/system_instruction_context.py +34 -0
  56. aip_agents/agent/system_instruction_context.pyi +13 -0
  57. aip_agents/clients/__init__.py +10 -0
  58. aip_agents/clients/__init__.pyi +4 -0
  59. aip_agents/clients/langflow/__init__.py +10 -0
  60. aip_agents/clients/langflow/__init__.pyi +4 -0
  61. aip_agents/clients/langflow/client.py +477 -0
  62. aip_agents/clients/langflow/client.pyi +140 -0
  63. aip_agents/clients/langflow/types.py +18 -0
  64. aip_agents/clients/langflow/types.pyi +7 -0
  65. aip_agents/constants.py +23 -0
  66. aip_agents/constants.pyi +7 -0
  67. aip_agents/credentials/manager.py +132 -0
  68. aip_agents/examples/__init__.py +5 -0
  69. aip_agents/examples/__init__.pyi +0 -0
  70. aip_agents/examples/compare_streaming_client.py +783 -0
  71. aip_agents/examples/compare_streaming_client.pyi +48 -0
  72. aip_agents/examples/compare_streaming_server.py +142 -0
  73. aip_agents/examples/compare_streaming_server.pyi +18 -0
  74. aip_agents/examples/demo_memory_recall.py +401 -0
  75. aip_agents/examples/demo_memory_recall.pyi +58 -0
  76. aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
  77. aip_agents/examples/hello_world_a2a_google_adk_client.pyi +9 -0
  78. aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
  79. aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +9 -0
  80. aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
  81. aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +9 -0
  82. aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
  83. aip_agents/examples/hello_world_a2a_google_adk_server.pyi +15 -0
  84. aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
  85. aip_agents/examples/hello_world_a2a_langchain_client.pyi +5 -0
  86. aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
  87. aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +5 -0
  88. aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
  89. aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +5 -0
  90. aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
  91. aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +5 -0
  92. aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
  93. aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +5 -0
  94. aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
  95. aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +15 -0
  96. aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
  97. aip_agents/examples/hello_world_a2a_langchain_server.pyi +15 -0
  98. aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
  99. aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +15 -0
  100. aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
  101. aip_agents/examples/hello_world_a2a_langflow_client.pyi +9 -0
  102. aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
  103. aip_agents/examples/hello_world_a2a_langflow_server.pyi +14 -0
  104. aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
  105. aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +5 -0
  106. aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
  107. aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +5 -0
  108. aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
  109. aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +16 -0
  110. aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
  111. aip_agents/examples/hello_world_a2a_langgraph_client.pyi +9 -0
  112. aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
  113. aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +9 -0
  114. aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
  115. aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +2 -0
  116. aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
  117. aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +9 -0
  118. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
  119. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +5 -0
  120. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
  121. aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +5 -0
  122. aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
  123. aip_agents/examples/hello_world_a2a_langgraph_server.pyi +14 -0
  124. aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
  125. aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +15 -0
  126. aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
  127. aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +15 -0
  128. aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
  129. aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +48 -0
  130. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
  131. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +48 -0
  132. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
  133. aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +45 -0
  134. aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
  135. aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +5 -0
  136. aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
  137. aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +15 -0
  138. aip_agents/examples/hello_world_google_adk.py +41 -0
  139. aip_agents/examples/hello_world_google_adk.pyi +5 -0
  140. aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
  141. aip_agents/examples/hello_world_google_adk_mcp_http.pyi +5 -0
  142. aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
  143. aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +5 -0
  144. aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
  145. aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +5 -0
  146. aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
  147. aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +5 -0
  148. aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
  149. aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +5 -0
  150. aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
  151. aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +5 -0
  152. aip_agents/examples/hello_world_google_adk_stream.py +44 -0
  153. aip_agents/examples/hello_world_google_adk_stream.pyi +5 -0
  154. aip_agents/examples/hello_world_langchain.py +28 -0
  155. aip_agents/examples/hello_world_langchain.pyi +5 -0
  156. aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
  157. aip_agents/examples/hello_world_langchain_lm_invoker.pyi +2 -0
  158. aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
  159. aip_agents/examples/hello_world_langchain_mcp_http.pyi +5 -0
  160. aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
  161. aip_agents/examples/hello_world_langchain_mcp_http_interactive.pyi +16 -0
  162. aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
  163. aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +5 -0
  164. aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
  165. aip_agents/examples/hello_world_langchain_mcp_multi_server.pyi +18 -0
  166. aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
  167. aip_agents/examples/hello_world_langchain_mcp_sse.pyi +5 -0
  168. aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
  169. aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +5 -0
  170. aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
  171. aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +5 -0
  172. aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
  173. aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +5 -0
  174. aip_agents/examples/hello_world_langchain_stream.py +36 -0
  175. aip_agents/examples/hello_world_langchain_stream.pyi +5 -0
  176. aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
  177. aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +5 -0
  178. aip_agents/examples/hello_world_langflow_agent.py +163 -0
  179. aip_agents/examples/hello_world_langflow_agent.pyi +35 -0
  180. aip_agents/examples/hello_world_langgraph.py +39 -0
  181. aip_agents/examples/hello_world_langgraph.pyi +5 -0
  182. aip_agents/examples/hello_world_langgraph_bosa_twitter.py +41 -0
  183. aip_agents/examples/hello_world_langgraph_bosa_twitter.pyi +5 -0
  184. aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
  185. aip_agents/examples/hello_world_langgraph_mcp_http.pyi +5 -0
  186. aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
  187. aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +5 -0
  188. aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
  189. aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +5 -0
  190. aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
  191. aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +5 -0
  192. aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
  193. aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +5 -0
  194. aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
  195. aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +5 -0
  196. aip_agents/examples/hello_world_langgraph_stream.py +43 -0
  197. aip_agents/examples/hello_world_langgraph_stream.pyi +5 -0
  198. aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
  199. aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +5 -0
  200. aip_agents/examples/hello_world_model_switch_cli.py +210 -0
  201. aip_agents/examples/hello_world_model_switch_cli.pyi +30 -0
  202. aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
  203. aip_agents/examples/hello_world_multi_agent_adk.pyi +6 -0
  204. aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
  205. aip_agents/examples/hello_world_multi_agent_langchain.pyi +5 -0
  206. aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
  207. aip_agents/examples/hello_world_multi_agent_langgraph.pyi +5 -0
  208. aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
  209. aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +5 -0
  210. aip_agents/examples/hello_world_pii_logger.py +21 -0
  211. aip_agents/examples/hello_world_pii_logger.pyi +5 -0
  212. aip_agents/examples/hello_world_sentry.py +133 -0
  213. aip_agents/examples/hello_world_sentry.pyi +21 -0
  214. aip_agents/examples/hello_world_step_limits.py +273 -0
  215. aip_agents/examples/hello_world_step_limits.pyi +17 -0
  216. aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
  217. aip_agents/examples/hello_world_stock_a2a_server.pyi +17 -0
  218. aip_agents/examples/hello_world_tool_output_client.py +46 -0
  219. aip_agents/examples/hello_world_tool_output_client.pyi +5 -0
  220. aip_agents/examples/hello_world_tool_output_server.py +114 -0
  221. aip_agents/examples/hello_world_tool_output_server.pyi +19 -0
  222. aip_agents/examples/hitl_demo.py +724 -0
  223. aip_agents/examples/hitl_demo.pyi +67 -0
  224. aip_agents/examples/mcp_configs/configs.py +63 -0
  225. aip_agents/examples/mcp_servers/common.py +76 -0
  226. aip_agents/examples/mcp_servers/mcp_name.py +29 -0
  227. aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
  228. aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
  229. aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
  230. aip_agents/examples/mcp_servers/mcp_time.py +10 -0
  231. aip_agents/examples/pii_demo_langgraph_client.py +69 -0
  232. aip_agents/examples/pii_demo_langgraph_client.pyi +5 -0
  233. aip_agents/examples/pii_demo_langgraph_server.py +126 -0
  234. aip_agents/examples/pii_demo_langgraph_server.pyi +20 -0
  235. aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
  236. aip_agents/examples/pii_demo_multi_agent_client.pyi +5 -0
  237. aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
  238. aip_agents/examples/pii_demo_multi_agent_server.pyi +40 -0
  239. aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
  240. aip_agents/examples/todolist_planning_a2a_langchain_client.pyi +5 -0
  241. aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
  242. aip_agents/examples/todolist_planning_a2a_langgraph_server.pyi +19 -0
  243. aip_agents/examples/tools/__init__.py +27 -0
  244. aip_agents/examples/tools/__init__.pyi +9 -0
  245. aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
  246. aip_agents/examples/tools/adk_arithmetic_tools.pyi +24 -0
  247. aip_agents/examples/tools/adk_weather_tool.py +60 -0
  248. aip_agents/examples/tools/adk_weather_tool.pyi +18 -0
  249. aip_agents/examples/tools/data_generator_tool.py +103 -0
  250. aip_agents/examples/tools/data_generator_tool.pyi +15 -0
  251. aip_agents/examples/tools/data_visualization_tool.py +312 -0
  252. aip_agents/examples/tools/data_visualization_tool.pyi +19 -0
  253. aip_agents/examples/tools/image_artifact_tool.py +136 -0
  254. aip_agents/examples/tools/image_artifact_tool.pyi +26 -0
  255. aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
  256. aip_agents/examples/tools/langchain_arithmetic_tools.pyi +17 -0
  257. aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
  258. aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +20 -0
  259. aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
  260. aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +25 -0
  261. aip_agents/examples/tools/langchain_weather_tool.py +48 -0
  262. aip_agents/examples/tools/langchain_weather_tool.pyi +19 -0
  263. aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
  264. aip_agents/examples/tools/langgraph_streaming_tool.pyi +43 -0
  265. aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
  266. aip_agents/examples/tools/mock_retrieval_tool.pyi +13 -0
  267. aip_agents/examples/tools/pii_demo_tools.py +189 -0
  268. aip_agents/examples/tools/pii_demo_tools.pyi +54 -0
  269. aip_agents/examples/tools/random_chart_tool.py +142 -0
  270. aip_agents/examples/tools/random_chart_tool.pyi +20 -0
  271. aip_agents/examples/tools/serper_tool.py +202 -0
  272. aip_agents/examples/tools/serper_tool.pyi +16 -0
  273. aip_agents/examples/tools/stock_tools.py +82 -0
  274. aip_agents/examples/tools/stock_tools.pyi +36 -0
  275. aip_agents/examples/tools/table_generator_tool.py +167 -0
  276. aip_agents/examples/tools/table_generator_tool.pyi +22 -0
  277. aip_agents/examples/tools/time_tool.py +82 -0
  278. aip_agents/examples/tools/time_tool.pyi +15 -0
  279. aip_agents/examples/tools/weather_forecast_tool.py +38 -0
  280. aip_agents/examples/tools/weather_forecast_tool.pyi +14 -0
  281. aip_agents/executor/agent_executor.py +473 -0
  282. aip_agents/executor/base.py +48 -0
  283. aip_agents/mcp/__init__.py +1 -0
  284. aip_agents/mcp/__init__.pyi +0 -0
  285. aip_agents/mcp/client/__init__.py +14 -0
  286. aip_agents/mcp/client/__init__.pyi +5 -0
  287. aip_agents/mcp/client/base_mcp_client.py +369 -0
  288. aip_agents/mcp/client/base_mcp_client.pyi +148 -0
  289. aip_agents/mcp/client/connection_manager.py +193 -0
  290. aip_agents/mcp/client/connection_manager.pyi +48 -0
  291. aip_agents/mcp/client/google_adk/__init__.py +11 -0
  292. aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
  293. aip_agents/mcp/client/google_adk/client.py +381 -0
  294. aip_agents/mcp/client/google_adk/client.pyi +75 -0
  295. aip_agents/mcp/client/langchain/__init__.py +11 -0
  296. aip_agents/mcp/client/langchain/__init__.pyi +3 -0
  297. aip_agents/mcp/client/langchain/client.py +265 -0
  298. aip_agents/mcp/client/langchain/client.pyi +48 -0
  299. aip_agents/mcp/client/persistent_session.py +359 -0
  300. aip_agents/mcp/client/persistent_session.pyi +113 -0
  301. aip_agents/mcp/client/session_pool.py +351 -0
  302. aip_agents/mcp/client/session_pool.pyi +101 -0
  303. aip_agents/mcp/client/transports.py +215 -0
  304. aip_agents/mcp/client/transports.pyi +123 -0
  305. aip_agents/mcp/utils/__init__.py +7 -0
  306. aip_agents/mcp/utils/__init__.pyi +0 -0
  307. aip_agents/mcp/utils/config_validator.py +139 -0
  308. aip_agents/mcp/utils/config_validator.pyi +82 -0
  309. aip_agents/memory/__init__.py +14 -0
  310. aip_agents/memory/__init__.pyi +5 -0
  311. aip_agents/memory/adapters/__init__.py +10 -0
  312. aip_agents/memory/adapters/__init__.pyi +4 -0
  313. aip_agents/memory/adapters/base_adapter.py +717 -0
  314. aip_agents/memory/adapters/base_adapter.pyi +150 -0
  315. aip_agents/memory/adapters/mem0.py +84 -0
  316. aip_agents/memory/adapters/mem0.pyi +22 -0
  317. aip_agents/memory/base.py +84 -0
  318. aip_agents/memory/base.pyi +60 -0
  319. aip_agents/memory/constants.py +49 -0
  320. aip_agents/memory/constants.pyi +25 -0
  321. aip_agents/memory/factory.py +86 -0
  322. aip_agents/memory/factory.pyi +24 -0
  323. aip_agents/memory/guidance.py +20 -0
  324. aip_agents/memory/guidance.pyi +3 -0
  325. aip_agents/memory/simple_memory.py +47 -0
  326. aip_agents/memory/simple_memory.pyi +23 -0
  327. aip_agents/middleware/__init__.py +17 -0
  328. aip_agents/middleware/__init__.pyi +5 -0
  329. aip_agents/middleware/base.py +88 -0
  330. aip_agents/middleware/base.pyi +71 -0
  331. aip_agents/middleware/manager.py +128 -0
  332. aip_agents/middleware/manager.pyi +80 -0
  333. aip_agents/middleware/todolist.py +274 -0
  334. aip_agents/middleware/todolist.pyi +125 -0
  335. aip_agents/schema/__init__.py +69 -0
  336. aip_agents/schema/__init__.pyi +9 -0
  337. aip_agents/schema/a2a.py +56 -0
  338. aip_agents/schema/a2a.pyi +40 -0
  339. aip_agents/schema/agent.py +111 -0
  340. aip_agents/schema/agent.pyi +65 -0
  341. aip_agents/schema/hitl.py +157 -0
  342. aip_agents/schema/hitl.pyi +89 -0
  343. aip_agents/schema/langgraph.py +37 -0
  344. aip_agents/schema/langgraph.pyi +28 -0
  345. aip_agents/schema/model_id.py +97 -0
  346. aip_agents/schema/model_id.pyi +54 -0
  347. aip_agents/schema/step_limit.py +108 -0
  348. aip_agents/schema/step_limit.pyi +63 -0
  349. aip_agents/schema/storage.py +40 -0
  350. aip_agents/schema/storage.pyi +21 -0
  351. aip_agents/sentry/__init__.py +11 -0
  352. aip_agents/sentry/__init__.pyi +3 -0
  353. aip_agents/sentry/sentry.py +151 -0
  354. aip_agents/sentry/sentry.pyi +48 -0
  355. aip_agents/storage/__init__.py +41 -0
  356. aip_agents/storage/__init__.pyi +8 -0
  357. aip_agents/storage/base.py +85 -0
  358. aip_agents/storage/base.pyi +58 -0
  359. aip_agents/storage/clients/__init__.py +12 -0
  360. aip_agents/storage/clients/__init__.pyi +3 -0
  361. aip_agents/storage/clients/minio_client.py +318 -0
  362. aip_agents/storage/clients/minio_client.pyi +137 -0
  363. aip_agents/storage/config.py +62 -0
  364. aip_agents/storage/config.pyi +29 -0
  365. aip_agents/storage/providers/__init__.py +15 -0
  366. aip_agents/storage/providers/__init__.pyi +5 -0
  367. aip_agents/storage/providers/base.py +106 -0
  368. aip_agents/storage/providers/base.pyi +88 -0
  369. aip_agents/storage/providers/memory.py +114 -0
  370. aip_agents/storage/providers/memory.pyi +79 -0
  371. aip_agents/storage/providers/object_storage.py +214 -0
  372. aip_agents/storage/providers/object_storage.pyi +98 -0
  373. aip_agents/tools/__init__.py +33 -0
  374. aip_agents/tools/__init__.pyi +13 -0
  375. aip_agents/tools/bosa_tools.py +105 -0
  376. aip_agents/tools/bosa_tools.pyi +37 -0
  377. aip_agents/tools/browser_use/__init__.py +82 -0
  378. aip_agents/tools/browser_use/__init__.pyi +14 -0
  379. aip_agents/tools/browser_use/action_parser.py +103 -0
  380. aip_agents/tools/browser_use/action_parser.pyi +18 -0
  381. aip_agents/tools/browser_use/browser_use_tool.py +1112 -0
  382. aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
  383. aip_agents/tools/browser_use/llm_config.py +120 -0
  384. aip_agents/tools/browser_use/llm_config.pyi +52 -0
  385. aip_agents/tools/browser_use/minio_storage.py +198 -0
  386. aip_agents/tools/browser_use/minio_storage.pyi +109 -0
  387. aip_agents/tools/browser_use/schemas.py +119 -0
  388. aip_agents/tools/browser_use/schemas.pyi +32 -0
  389. aip_agents/tools/browser_use/session.py +76 -0
  390. aip_agents/tools/browser_use/session.pyi +4 -0
  391. aip_agents/tools/browser_use/session_errors.py +132 -0
  392. aip_agents/tools/browser_use/session_errors.pyi +53 -0
  393. aip_agents/tools/browser_use/steel_session_recording.py +317 -0
  394. aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
  395. aip_agents/tools/browser_use/streaming.py +813 -0
  396. aip_agents/tools/browser_use/streaming.pyi +81 -0
  397. aip_agents/tools/browser_use/structured_data_parser.py +257 -0
  398. aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
  399. aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
  400. aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
  401. aip_agents/tools/browser_use/types.py +78 -0
  402. aip_agents/tools/browser_use/types.pyi +45 -0
  403. aip_agents/tools/code_sandbox/__init__.py +26 -0
  404. aip_agents/tools/code_sandbox/__init__.pyi +3 -0
  405. aip_agents/tools/code_sandbox/constant.py +13 -0
  406. aip_agents/tools/code_sandbox/constant.pyi +4 -0
  407. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +257 -0
  408. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +86 -0
  409. aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
  410. aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
  411. aip_agents/tools/constants.py +165 -0
  412. aip_agents/tools/constants.pyi +135 -0
  413. aip_agents/tools/document_loader/__init__.py +44 -0
  414. aip_agents/tools/document_loader/__init__.pyi +7 -0
  415. aip_agents/tools/document_loader/base_reader.py +302 -0
  416. aip_agents/tools/document_loader/base_reader.pyi +75 -0
  417. aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
  418. aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
  419. aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
  420. aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
  421. aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
  422. aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
  423. aip_agents/tools/document_loader/pdf_splitter.py +169 -0
  424. aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
  425. aip_agents/tools/gl_connector/__init__.py +5 -0
  426. aip_agents/tools/gl_connector/__init__.pyi +3 -0
  427. aip_agents/tools/gl_connector/tool.py +351 -0
  428. aip_agents/tools/gl_connector/tool.pyi +74 -0
  429. aip_agents/tools/memory_search/__init__.py +22 -0
  430. aip_agents/tools/memory_search/__init__.pyi +5 -0
  431. aip_agents/tools/memory_search/base.py +200 -0
  432. aip_agents/tools/memory_search/base.pyi +69 -0
  433. aip_agents/tools/memory_search/mem0.py +258 -0
  434. aip_agents/tools/memory_search/mem0.pyi +19 -0
  435. aip_agents/tools/memory_search/schema.py +48 -0
  436. aip_agents/tools/memory_search/schema.pyi +15 -0
  437. aip_agents/tools/memory_search_tool.py +26 -0
  438. aip_agents/tools/memory_search_tool.pyi +3 -0
  439. aip_agents/tools/time_tool.py +117 -0
  440. aip_agents/tools/time_tool.pyi +16 -0
  441. aip_agents/tools/tool_config_injector.py +300 -0
  442. aip_agents/tools/tool_config_injector.pyi +26 -0
  443. aip_agents/tools/web_search/__init__.py +15 -0
  444. aip_agents/tools/web_search/__init__.pyi +3 -0
  445. aip_agents/tools/web_search/serper_tool.py +187 -0
  446. aip_agents/tools/web_search/serper_tool.pyi +19 -0
  447. aip_agents/types/__init__.py +70 -0
  448. aip_agents/types/__init__.pyi +36 -0
  449. aip_agents/types/a2a_events.py +13 -0
  450. aip_agents/types/a2a_events.pyi +3 -0
  451. aip_agents/utils/__init__.py +79 -0
  452. aip_agents/utils/__init__.pyi +11 -0
  453. aip_agents/utils/a2a_connector.py +1757 -0
  454. aip_agents/utils/a2a_connector.pyi +146 -0
  455. aip_agents/utils/artifact_helpers.py +502 -0
  456. aip_agents/utils/artifact_helpers.pyi +203 -0
  457. aip_agents/utils/constants.py +22 -0
  458. aip_agents/utils/constants.pyi +10 -0
  459. aip_agents/utils/datetime/__init__.py +34 -0
  460. aip_agents/utils/datetime/__init__.pyi +4 -0
  461. aip_agents/utils/datetime/normalization.py +231 -0
  462. aip_agents/utils/datetime/normalization.pyi +95 -0
  463. aip_agents/utils/datetime/timezone.py +206 -0
  464. aip_agents/utils/datetime/timezone.pyi +48 -0
  465. aip_agents/utils/env_loader.py +27 -0
  466. aip_agents/utils/env_loader.pyi +10 -0
  467. aip_agents/utils/event_handler_registry.py +58 -0
  468. aip_agents/utils/event_handler_registry.pyi +23 -0
  469. aip_agents/utils/file_prompt_utils.py +176 -0
  470. aip_agents/utils/file_prompt_utils.pyi +21 -0
  471. aip_agents/utils/final_response_builder.py +211 -0
  472. aip_agents/utils/final_response_builder.pyi +34 -0
  473. aip_agents/utils/formatter_llm_client.py +231 -0
  474. aip_agents/utils/formatter_llm_client.pyi +71 -0
  475. aip_agents/utils/langgraph/__init__.py +19 -0
  476. aip_agents/utils/langgraph/__init__.pyi +3 -0
  477. aip_agents/utils/langgraph/converter.py +128 -0
  478. aip_agents/utils/langgraph/converter.pyi +49 -0
  479. aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
  480. aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
  481. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
  482. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
  483. aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
  484. aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
  485. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1071 -0
  486. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
  487. aip_agents/utils/langgraph/tool_output_management.py +967 -0
  488. aip_agents/utils/langgraph/tool_output_management.pyi +292 -0
  489. aip_agents/utils/logger.py +195 -0
  490. aip_agents/utils/logger.pyi +60 -0
  491. aip_agents/utils/metadata/__init__.py +27 -0
  492. aip_agents/utils/metadata/__init__.pyi +5 -0
  493. aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
  494. aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
  495. aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
  496. aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
  497. aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
  498. aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
  499. aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
  500. aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
  501. aip_agents/utils/metadata/activity_narrative/context.py +49 -0
  502. aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
  503. aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
  504. aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
  505. aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
  506. aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
  507. aip_agents/utils/metadata/schemas/__init__.py +16 -0
  508. aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
  509. aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
  510. aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
  511. aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
  512. aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
  513. aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
  514. aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
  515. aip_agents/utils/metadata_helper.py +358 -0
  516. aip_agents/utils/metadata_helper.pyi +117 -0
  517. aip_agents/utils/name_preprocessor/__init__.py +17 -0
  518. aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
  519. aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
  520. aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
  521. aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
  522. aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
  523. aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
  524. aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
  525. aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
  526. aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
  527. aip_agents/utils/pii/__init__.py +25 -0
  528. aip_agents/utils/pii/__init__.pyi +5 -0
  529. aip_agents/utils/pii/pii_handler.py +397 -0
  530. aip_agents/utils/pii/pii_handler.pyi +96 -0
  531. aip_agents/utils/pii/pii_helper.py +207 -0
  532. aip_agents/utils/pii/pii_helper.pyi +78 -0
  533. aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
  534. aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
  535. aip_agents/utils/reference_helper.py +273 -0
  536. aip_agents/utils/reference_helper.pyi +81 -0
  537. aip_agents/utils/sse_chunk_transformer.py +831 -0
  538. aip_agents/utils/sse_chunk_transformer.pyi +166 -0
  539. aip_agents/utils/step_limit_manager.py +265 -0
  540. aip_agents/utils/step_limit_manager.pyi +112 -0
  541. aip_agents/utils/token_usage_helper.py +156 -0
  542. aip_agents/utils/token_usage_helper.pyi +60 -0
  543. aip_agents_binary-0.5.20.dist-info/METADATA +681 -0
  544. aip_agents_binary-0.5.20.dist-info/RECORD +546 -0
  545. aip_agents_binary-0.5.20.dist-info/WHEEL +5 -0
  546. aip_agents_binary-0.5.20.dist-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+ from aip_agents.memory.base import BaseMemory as BaseMemory, ChatMessage as ChatMessage
2
+
3
+ class SimpleMemory(BaseMemory):
4
+ """A simple memory implementation that stores messages in a list."""
5
+ messages: list[ChatMessage]
6
+ def __init__(self) -> None:
7
+ """Initialize the SimpleMemory instance with an empty message list."""
8
+ def add_message(self, message_or_role, content=None) -> None:
9
+ '''Add a message to memory.
10
+
11
+ Supports two calling patterns for backward compatibility:
12
+ 1. add_message(ChatMessage) - Adds a ChatMessage object directly
13
+ 2. add_message(role, content) - Creates and adds a ChatMessage with the given role and content
14
+
15
+ Args:
16
+ message_or_role: Either a ChatMessage object or a string role (e.g., "user", "assistant").
17
+ content: Optional content string when using the role+content pattern.
18
+ Required when message_or_role is a string role.
19
+ '''
20
+ def get_messages(self) -> list[ChatMessage]:
21
+ """Get all messages from memory."""
22
+ def clear(self) -> None:
23
+ """Clear all messages from memory."""
@@ -0,0 +1,17 @@
1
+ """Planning Middleware package.
2
+
3
+ Provides composable middleware components for enhancing agent capabilities with
4
+ planning and custom lifecycle hooks.
5
+ """
6
+
7
+ from aip_agents.middleware.base import AgentMiddleware, ModelRequest
8
+ from aip_agents.middleware.manager import MiddlewareManager
9
+ from aip_agents.middleware.todolist import TodoListMiddleware, TodoStatus
10
+
11
+ __all__ = [
12
+ "AgentMiddleware",
13
+ "ModelRequest",
14
+ "MiddlewareManager",
15
+ "TodoListMiddleware",
16
+ "TodoStatus",
17
+ ]
@@ -0,0 +1,5 @@
1
+ from aip_agents.middleware.base import AgentMiddleware as AgentMiddleware, ModelRequest as ModelRequest
2
+ from aip_agents.middleware.manager import MiddlewareManager as MiddlewareManager
3
+ from aip_agents.middleware.todolist import TodoListMiddleware as TodoListMiddleware, TodoStatus as TodoStatus
4
+
5
+ __all__ = ['AgentMiddleware', 'ModelRequest', 'MiddlewareManager', 'TodoListMiddleware', 'TodoStatus']
@@ -0,0 +1,88 @@
1
+ """Base protocol and types for agent middleware.
2
+
3
+ This module defines the core AgentMiddleware protocol that all middleware components
4
+ must implement, along with the ModelRequest type for model invocations.
5
+ """
6
+
7
+ from typing import Any, Protocol, TypedDict
8
+
9
+ from langchain_core.tools import BaseTool
10
+
11
+
12
+ class ModelRequest(TypedDict, total=False):
13
+ """Represents parameters for a model invocation that middleware can modify.
14
+
15
+ This TypedDict defines the structure of requests passed to the LLM, allowing
16
+ middleware to add tools or modify prompts before each invocation.
17
+
18
+ Attributes:
19
+ messages: List of messages in the conversation.
20
+ tools: List of tools available to the model.
21
+ system_prompt: System-level instruction for the model.
22
+ """
23
+
24
+ messages: list[Any]
25
+ tools: list[BaseTool]
26
+ system_prompt: str
27
+
28
+
29
+ class AgentMiddleware(Protocol):
30
+ """Protocol defining the interface for composable agent middleware.
31
+
32
+ Middleware components can contribute tools, enhance system prompts, and provide
33
+ lifecycle hooks that execute before, during, and after model invocations.
34
+
35
+ All middleware must implement this protocol to be compatible with MiddlewareManager.
36
+
37
+ Attributes:
38
+ tools: List of tools contributed by this middleware.
39
+ system_prompt_additions: Optional text to append to the agent's system prompt.
40
+ """
41
+
42
+ tools: list[BaseTool]
43
+ system_prompt_additions: str | None
44
+
45
+ def before_model(self, state: dict[str, Any]) -> dict[str, Any]:
46
+ """Hook executed before each model invocation.
47
+
48
+ Use this hook to prepare state, log context, or perform setup tasks
49
+ before the model is called.
50
+
51
+ Args:
52
+ state: Current agent state containing messages and other context.
53
+
54
+ Returns:
55
+ Dict of state updates to merge into the agent state. Return empty dict
56
+ if no updates are needed.
57
+ """
58
+ return {} # pragma: no cover # Protocol default - cannot be executed directly
59
+
60
+ def modify_model_request(self, request: ModelRequest, state: dict[str, Any]) -> ModelRequest:
61
+ """Hook to modify the model request before invocation.
62
+
63
+ Use this hook to add tools, modify the system prompt, adjust model parameters,
64
+ or change tool selection strategy.
65
+
66
+ Args:
67
+ request: The model request that will be sent to the LLM.
68
+ state: Current agent state for context.
69
+
70
+ Returns:
71
+ Modified ModelRequest. Can return the same request if no changes needed.
72
+ """
73
+ return request # pragma: no cover # Protocol default - cannot be executed directly # pragma: no cover # Protocol default - cannot be executed directly
74
+
75
+ def after_model(self, state: dict[str, Any]) -> dict[str, Any]:
76
+ """Hook executed after each model invocation.
77
+
78
+ Use this hook for cleanup, logging, state updates, or post-processing
79
+ of model outputs.
80
+
81
+ Args:
82
+ state: Current agent state after model invocation.
83
+
84
+ Returns:
85
+ Dict of state updates to merge into the agent state. Return empty dict
86
+ if no updates are needed.
87
+ """
88
+ return {} # pragma: no cover # Protocol default - cannot be executed directly
@@ -0,0 +1,71 @@
1
+ from langchain_core.tools import BaseTool as BaseTool
2
+ from typing import Any, Protocol, TypedDict
3
+
4
+ class ModelRequest(TypedDict, total=False):
5
+ """Represents parameters for a model invocation that middleware can modify.
6
+
7
+ This TypedDict defines the structure of requests passed to the LLM, allowing
8
+ middleware to add tools or modify prompts before each invocation.
9
+
10
+ Attributes:
11
+ messages: List of messages in the conversation.
12
+ tools: List of tools available to the model.
13
+ system_prompt: System-level instruction for the model.
14
+ """
15
+ messages: list[Any]
16
+ tools: list[BaseTool]
17
+ system_prompt: str
18
+
19
+ class AgentMiddleware(Protocol):
20
+ """Protocol defining the interface for composable agent middleware.
21
+
22
+ Middleware components can contribute tools, enhance system prompts, and provide
23
+ lifecycle hooks that execute before, during, and after model invocations.
24
+
25
+ All middleware must implement this protocol to be compatible with MiddlewareManager.
26
+
27
+ Attributes:
28
+ tools: List of tools contributed by this middleware.
29
+ system_prompt_additions: Optional text to append to the agent's system prompt.
30
+ """
31
+ tools: list[BaseTool]
32
+ system_prompt_additions: str | None
33
+ def before_model(self, state: dict[str, Any]) -> dict[str, Any]:
34
+ """Hook executed before each model invocation.
35
+
36
+ Use this hook to prepare state, log context, or perform setup tasks
37
+ before the model is called.
38
+
39
+ Args:
40
+ state: Current agent state containing messages and other context.
41
+
42
+ Returns:
43
+ Dict of state updates to merge into the agent state. Return empty dict
44
+ if no updates are needed.
45
+ """
46
+ def modify_model_request(self, request: ModelRequest, state: dict[str, Any]) -> ModelRequest:
47
+ """Hook to modify the model request before invocation.
48
+
49
+ Use this hook to add tools, modify the system prompt, adjust model parameters,
50
+ or change tool selection strategy.
51
+
52
+ Args:
53
+ request: The model request that will be sent to the LLM.
54
+ state: Current agent state for context.
55
+
56
+ Returns:
57
+ Modified ModelRequest. Can return the same request if no changes needed.
58
+ """
59
+ def after_model(self, state: dict[str, Any]) -> dict[str, Any]:
60
+ """Hook executed after each model invocation.
61
+
62
+ Use this hook for cleanup, logging, state updates, or post-processing
63
+ of model outputs.
64
+
65
+ Args:
66
+ state: Current agent state after model invocation.
67
+
68
+ Returns:
69
+ Dict of state updates to merge into the agent state. Return empty dict
70
+ if no updates are needed.
71
+ """
@@ -0,0 +1,128 @@
1
+ """Middleware orchestration and lifecycle management.
2
+
3
+ This module provides MiddlewareManager, which coordinates multiple middleware
4
+ components and manages their lifecycle hooks.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from langchain_core.tools import BaseTool
10
+
11
+ from aip_agents.middleware.base import AgentMiddleware, ModelRequest
12
+
13
+
14
+ class MiddlewareManager:
15
+ """Orchestrates multiple middleware components and manages hook execution.
16
+
17
+ The manager collects tools from all middleware, builds enhanced system prompts,
18
+ and executes lifecycle hooks in the correct order (forward for setup, reverse
19
+ for cleanup).
20
+
21
+ Attributes:
22
+ middleware: List of middleware components in registration order.
23
+ """
24
+
25
+ def __init__(self, middleware: list[AgentMiddleware]) -> None:
26
+ """Initialize the middleware manager.
27
+
28
+ Args:
29
+ middleware: List of middleware components to manage. Order matters:
30
+ hooks execute forward (first to last) for before/modify,
31
+ and reverse (last to first) for after.
32
+ """
33
+ self.middleware = middleware
34
+
35
+ def get_all_tools(self) -> list[BaseTool]:
36
+ """Collect tools from all registered middleware.
37
+
38
+ Returns:
39
+ Combined list of all tools contributed by all middleware components.
40
+ Empty list if no middleware or if middleware provide no tools.
41
+ """
42
+ tools: list[BaseTool] = []
43
+ for mw in self.middleware:
44
+ tools.extend(mw.tools)
45
+ return tools
46
+
47
+ def build_system_prompt(self, base_instruction: str) -> str:
48
+ """Build enhanced system prompt by concatenating base instruction with middleware additions.
49
+
50
+ Args:
51
+ base_instruction: The base system prompt for the agent.
52
+
53
+ Returns:
54
+ Enhanced system prompt with all middleware additions appended.
55
+ If no middleware provide additions, returns base_instruction unchanged.
56
+ """
57
+ parts = [base_instruction]
58
+
59
+ for mw in self.middleware:
60
+ if mw.system_prompt_additions:
61
+ parts.append(mw.system_prompt_additions)
62
+
63
+ return "\n\n".join(parts)
64
+
65
+ def before_model(self, state: dict[str, Any]) -> dict[str, Any]:
66
+ """Execute before_model hooks for all middleware in forward order.
67
+
68
+ Hooks run first to last, allowing earlier middleware to prepare state
69
+ for later middleware.
70
+
71
+ Args:
72
+ state: Current agent state.
73
+
74
+ Returns:
75
+ Merged dictionary of all state updates from all middleware.
76
+ Updates are accumulated in order of execution.
77
+ """
78
+ state_updates: dict[str, Any] = {}
79
+
80
+ for mw in self.middleware:
81
+ mw_updates = mw.before_model(state)
82
+ if mw_updates:
83
+ state_updates.update(mw_updates)
84
+
85
+ return state_updates
86
+
87
+ def modify_model_request(self, request: ModelRequest, state: dict[str, Any]) -> ModelRequest:
88
+ """Execute modify_model_request hooks for all middleware in forward order.
89
+
90
+ Each middleware receives the request modified by previous middleware,
91
+ allowing them to build on each other's changes.
92
+
93
+ Args:
94
+ request: The model request to be modified.
95
+ state: Current agent state for context.
96
+
97
+ Returns:
98
+ Final modified request after all middleware have processed it.
99
+ """
100
+ current_request = request
101
+
102
+ for mw in self.middleware:
103
+ current_request = mw.modify_model_request(current_request, state)
104
+
105
+ return current_request
106
+
107
+ def after_model(self, state: dict[str, Any]) -> dict[str, Any]:
108
+ """Execute after_model hooks for all middleware in reverse order.
109
+
110
+ Hooks run last to first (reverse of registration order), allowing
111
+ proper cleanup and unwinding of middleware operations.
112
+
113
+ Args:
114
+ state: Current agent state after model invocation.
115
+
116
+ Returns:
117
+ Merged dictionary of all state updates from all middleware.
118
+ Updates are accumulated in reverse order of execution.
119
+ """
120
+ updates: dict[str, Any] = {}
121
+
122
+ # Execute in reverse order
123
+ for mw in reversed(self.middleware):
124
+ mw_updates = mw.after_model(state)
125
+ if mw_updates:
126
+ updates.update(mw_updates)
127
+
128
+ return updates
@@ -0,0 +1,80 @@
1
+ from _typeshed import Incomplete
2
+ from aip_agents.middleware.base import AgentMiddleware as AgentMiddleware, ModelRequest as ModelRequest
3
+ from langchain_core.tools import BaseTool as BaseTool
4
+ from typing import Any
5
+
6
+ class MiddlewareManager:
7
+ """Orchestrates multiple middleware components and manages hook execution.
8
+
9
+ The manager collects tools from all middleware, builds enhanced system prompts,
10
+ and executes lifecycle hooks in the correct order (forward for setup, reverse
11
+ for cleanup).
12
+
13
+ Attributes:
14
+ middleware: List of middleware components in registration order.
15
+ """
16
+ middleware: Incomplete
17
+ def __init__(self, middleware: list[AgentMiddleware]) -> None:
18
+ """Initialize the middleware manager.
19
+
20
+ Args:
21
+ middleware: List of middleware components to manage. Order matters:
22
+ hooks execute forward (first to last) for before/modify,
23
+ and reverse (last to first) for after.
24
+ """
25
+ def get_all_tools(self) -> list[BaseTool]:
26
+ """Collect tools from all registered middleware.
27
+
28
+ Returns:
29
+ Combined list of all tools contributed by all middleware components.
30
+ Empty list if no middleware or if middleware provide no tools.
31
+ """
32
+ def build_system_prompt(self, base_instruction: str) -> str:
33
+ """Build enhanced system prompt by concatenating base instruction with middleware additions.
34
+
35
+ Args:
36
+ base_instruction: The base system prompt for the agent.
37
+
38
+ Returns:
39
+ Enhanced system prompt with all middleware additions appended.
40
+ If no middleware provide additions, returns base_instruction unchanged.
41
+ """
42
+ def before_model(self, state: dict[str, Any]) -> dict[str, Any]:
43
+ """Execute before_model hooks for all middleware in forward order.
44
+
45
+ Hooks run first to last, allowing earlier middleware to prepare state
46
+ for later middleware.
47
+
48
+ Args:
49
+ state: Current agent state.
50
+
51
+ Returns:
52
+ Merged dictionary of all state updates from all middleware.
53
+ Updates are accumulated in order of execution.
54
+ """
55
+ def modify_model_request(self, request: ModelRequest, state: dict[str, Any]) -> ModelRequest:
56
+ """Execute modify_model_request hooks for all middleware in forward order.
57
+
58
+ Each middleware receives the request modified by previous middleware,
59
+ allowing them to build on each other's changes.
60
+
61
+ Args:
62
+ request: The model request to be modified.
63
+ state: Current agent state for context.
64
+
65
+ Returns:
66
+ Final modified request after all middleware have processed it.
67
+ """
68
+ def after_model(self, state: dict[str, Any]) -> dict[str, Any]:
69
+ """Execute after_model hooks for all middleware in reverse order.
70
+
71
+ Hooks run last to first (reverse of registration order), allowing
72
+ proper cleanup and unwinding of middleware operations.
73
+
74
+ Args:
75
+ state: Current agent state after model invocation.
76
+
77
+ Returns:
78
+ Merged dictionary of all state updates from all middleware.
79
+ Updates are accumulated in reverse order of execution.
80
+ """
@@ -0,0 +1,274 @@
1
+ """TodoList middleware for agent planning and task decomposition.
2
+
3
+ Provides a write_todos tool that allows agents to break down complex tasks
4
+ into discrete, trackable steps with status management.
5
+ """
6
+
7
+ import threading
8
+ from enum import StrEnum
9
+ from typing import Any
10
+
11
+ from langchain_core.runnables import RunnableConfig
12
+ from langchain_core.tools import BaseTool
13
+ from pydantic import BaseModel, Field, SkipValidation
14
+
15
+ from aip_agents.middleware.base import ModelRequest
16
+ from aip_agents.utils.logger import get_logger
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ class TodoStatus(StrEnum):
22
+ """Enumeration of possible todo item statuses."""
23
+
24
+ PENDING = "pending"
25
+ IN_PROGRESS = "in_progress"
26
+ COMPLETED = "completed"
27
+
28
+
29
+ WRITE_TODOS_SYSTEM_PROMPT = """## Task Planning with `write_todos`
30
+
31
+ Use `write_todos` to plan and track complex multi-step objectives (3+ steps, multiple deliverables, or tasks described as "comprehensive"). Skip for trivial single-action requests.
32
+
33
+ **Execution rules:**
34
+ 1. Create the plan with `write_todos` BEFORE executing work
35
+ 2. Execute ALL tasks autonomously—do NOT pause to ask "should I continue?" or "would you like a preview?"
36
+ 3. Revise the plan as needed when new information emerges
37
+ 4. Mark tasks completed as you finish them
38
+ 5. **CRITICAL: Before your final response, call `write_todos` one last time to mark ALL tasks as `completed`. Never respond to the user while any task is `pending` or `in_progress`.**
39
+ """
40
+
41
+ EMPTY_TODO_REMINDER = (
42
+ "\n\n**Todo List Reminder:** Your todo list is currently empty. "
43
+ "If you are working on tasks that would benefit from a todo list, "
44
+ "use the write_todos tool to create one. This helps track progress "
45
+ "and ensures you don't forget important steps.\n"
46
+ )
47
+
48
+
49
+ class TodoItem(BaseModel):
50
+ """Represents a single todo item in the agent's plan.
51
+
52
+ Attributes:
53
+ content: Human-readable description of the task.
54
+ active_form: Short imperative phrase for UI display.
55
+ status: Current status of the todo item.
56
+ """
57
+
58
+ content: str = Field(description="Description of what needs to be done")
59
+ active_form: str = Field(description="Short active form for display (e.g., 'researching topic')")
60
+ status: TodoStatus = Field(default=TodoStatus.PENDING, description="Current status of this todo")
61
+
62
+
63
+ class TodoList(BaseModel):
64
+ """Represents a complete todo list for a thread.
65
+
66
+ Attributes:
67
+ items: List of todo items in order.
68
+ """
69
+
70
+ items: list[TodoItem] = Field(default_factory=list)
71
+
72
+
73
+ WRITE_TODOS_TOOL_DESCRIPTION = """Create and manage a structured task list for complex work sessions (3+ steps).
74
+
75
+ ## When to Use
76
+ - Multi-step tasks with 3+ distinct steps
77
+ - Requests with multiple deliverables
78
+ - User provides a list of tasks
79
+ - User explicitly requests a todo list
80
+
81
+ ## When to Skip
82
+ - Single straightforward action
83
+ - Trivial tasks with no tracking benefit
84
+
85
+ ## Task States
86
+ - `pending`: Not started
87
+ - `in_progress`: Currently working
88
+ - `completed`: Fully finished
89
+
90
+ ## Workflow
91
+ 1. **Plan first**: Call `write_todos` before executing work. Mark first task(s) as `in_progress`.
92
+ 2. **Stay autonomous**: Execute all tasks without pausing for user confirmation.
93
+ 3. **Adapt the plan**: Add new tasks as discovered, remove irrelevant ones.
94
+ 4. **Mark progress**: Update task status as you complete work.
95
+ 5. **Final update**: Before responding to user, call `write_todos` to mark ALL remaining tasks `completed`.
96
+
97
+ ## CRITICAL: Final Response Rule
98
+ You must NOT respond to the user until EVERY task is marked `completed`. Your final action before responding should be a `write_todos` call that marks the last task(s) complete. If any task remains `pending` or `in_progress`, you are not done—keep working or update the plan."""
99
+
100
+
101
+ class WriteTodosInput(BaseModel):
102
+ """Input schema for the write_todos tool."""
103
+
104
+ todos: TodoList = Field(
105
+ ...,
106
+ description="List of todo items, each with 'content' and 'activeForm' keys.",
107
+ )
108
+
109
+
110
+ class WriteTodosTool(BaseTool):
111
+ """LangChain-compatible tool for managing todo lists via TodoListMiddleware."""
112
+
113
+ name: str = "write_todos_tool"
114
+ description: str = WRITE_TODOS_TOOL_DESCRIPTION
115
+ args_schema: type[BaseModel] = WriteTodosInput
116
+
117
+ # Instance reference to middleware storage (excluded from serialization, skip validation)
118
+ storage: SkipValidation[dict[str, TodoList]] = Field(default_factory=dict, exclude=True)
119
+ storage_lock: SkipValidation[threading.RLock] = Field(default_factory=threading.RLock, exclude=True)
120
+
121
+ def _run(self, todos: TodoList, config: RunnableConfig | None = None) -> str: # type: ignore[override]
122
+ """Synchronous entrypoint used by generic tool runners.
123
+
124
+ Args:
125
+ todos: The todo list to write.
126
+ config: Optional configuration for the tool run.
127
+
128
+ Returns:
129
+ str: A success message indicating the number of todo items written.
130
+ """
131
+ tid = "default"
132
+ if config and "configurable" in config:
133
+ tid = config["configurable"].get("thread_id", "default")
134
+
135
+ try:
136
+ # Store in thread-safe manner
137
+ with self.storage_lock:
138
+ self.storage[tid] = todos
139
+
140
+ return f"Successfully wrote {len(todos.items)} todo items to your plan."
141
+ except Exception as e: # pragma: no cover - defensive
142
+ return f"Error writing todos: {str(e)}"
143
+
144
+
145
+ class TodoListMiddleware:
146
+ """Middleware that provides planning capabilities via todo list management.
147
+
148
+ Adds the write_todos tool and enhances the system prompt with planning
149
+ instructions, encouraging agents to break down complex tasks.
150
+
151
+ This middleware maintains thread-isolated todo lists, ensuring that
152
+ different conversation threads don't interfere with each other.
153
+
154
+ Each middleware instance has its own storage, preventing race conditions
155
+ when multiple agent instances are used concurrently.
156
+ """
157
+
158
+ def __init__(self) -> None:
159
+ """Initialize the TodoList middleware with planning tools and instructions."""
160
+ # Instance-level storage to prevent race conditions across agent instances
161
+ self._storage: dict[str, TodoList] = {}
162
+ self._storage_lock = threading.RLock()
163
+
164
+ # Create tool with reference to this instance's storage
165
+ self.tools = [WriteTodosTool(storage=self._storage, storage_lock=self._storage_lock)]
166
+ self.system_prompt_additions = WRITE_TODOS_SYSTEM_PROMPT
167
+
168
+ def before_model(self, state: dict[str, Any]) -> dict[str, Any]:
169
+ """Hook executed before model invocation.
170
+
171
+ Syncs todos FROM state TO internal storage for LangGraph agents.
172
+ This allows todos to be persisted via LangGraph checkpointer.
173
+
174
+ Args:
175
+ state: Current agent state (may contain 'todos' key).
176
+
177
+ Returns:
178
+ Empty dict (no state updates needed).
179
+ """
180
+ # Sync from LangGraph state to internal storage (if state has todos)
181
+ if "todos" in state and state["todos"] is not None:
182
+ thread_id = state.get("thread_id", "default")
183
+
184
+ # Deep copy to prevent mutation issues between state and storage
185
+ with self._storage_lock:
186
+ self._storage[thread_id] = state["todos"].model_copy(deep=True)
187
+
188
+ return {}
189
+
190
+ def modify_model_request(self, request: ModelRequest, state: dict[str, Any]) -> ModelRequest:
191
+ """Hook to modify model request before invocation.
192
+
193
+ Injects current todo list status into the system prompt, ensuring
194
+ the agent has visibility into its current plan on every turn.
195
+ This follows Claude Code's pattern of injecting system reminders.
196
+
197
+ Args:
198
+ request: The model request.
199
+ state: Current agent state.
200
+
201
+ Returns:
202
+ Modified request with todo status injected into system prompt.
203
+ """
204
+ thread_id = state.get("thread_id", "default")
205
+
206
+ # Get current todos from storage
207
+ with self._storage_lock:
208
+ current_todos = self._storage.get(thread_id)
209
+
210
+ # Inject todo status into system prompt
211
+ if current_todos and current_todos.items:
212
+ # Build todo status reminder
213
+ todo_reminder = "\n\n## Current Todo List Status\n\n"
214
+ todo_reminder += "Your current todo list:\n"
215
+
216
+ for item in current_todos.items:
217
+ todo_reminder += f"[{item.status.value.upper()}] {item.content}\n"
218
+
219
+ todo_reminder += "\n**Remember to update the todo list as you complete tasks using write_todos.**\n"
220
+
221
+ # Append to system prompt
222
+ current_system_prompt = request.get("system_prompt", "")
223
+ request["system_prompt"] = current_system_prompt + todo_reminder
224
+ else:
225
+ # Static reminder when no todos exist
226
+ current_system_prompt = request.get("system_prompt", "")
227
+ request["system_prompt"] = current_system_prompt + EMPTY_TODO_REMINDER
228
+
229
+ return request
230
+
231
+ def after_model(self, state: dict[str, Any]) -> dict[str, Any]:
232
+ """Hook executed after model invocation.
233
+
234
+ Syncs todos FROM internal storage TO state for LangGraph agents.
235
+ This ensures any tool updates are reflected in the checkpointed state.
236
+
237
+ Args:
238
+ state: Current agent state.
239
+
240
+ Returns:
241
+ Dict with 'todos' key containing updated TodoList, or empty dict.
242
+ """
243
+ thread_id = state.get("thread_id", "default")
244
+
245
+ with self._storage_lock:
246
+ if thread_id in self._storage:
247
+ # Deep copy to prevent mutation issues between storage and state
248
+ return {"todos": self._storage[thread_id].model_copy(deep=True)}
249
+
250
+ return {}
251
+
252
+ def get_todos(self, thread_id: str = "default") -> TodoList:
253
+ """Retrieve the todo list for a specific thread.
254
+
255
+ Args:
256
+ thread_id: Thread identifier. Defaults to "default".
257
+
258
+ Returns:
259
+ TodoList for the thread, or empty list if none exists.
260
+ """
261
+ with self._storage_lock:
262
+ return self._storage.get(thread_id, TodoList())
263
+
264
+ def clear_todos(self, thread_id: str = "default") -> None:
265
+ """Clear the todo list for a specific thread.
266
+
267
+ Useful for cleanup between test runs or conversation resets.
268
+
269
+ Args:
270
+ thread_id: Thread identifier. Defaults to "default".
271
+ """
272
+ with self._storage_lock:
273
+ if thread_id in self._storage:
274
+ del self._storage[thread_id]