aip-agents-binary 0.5.25b1__py3-none-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) 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 +2948 -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 +2596 -0
  54. aip_agents/agent/langgraph_react_agent.pyi +131 -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_gl_connector_twitter.py +44 -0
  183. aip_agents/examples/hello_world_langgraph_gl_connector_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/guardrails/__init__.py +83 -0
  284. aip_agents/guardrails/__init__.pyi +6 -0
  285. aip_agents/guardrails/engines/__init__.py +69 -0
  286. aip_agents/guardrails/engines/__init__.pyi +4 -0
  287. aip_agents/guardrails/engines/base.py +90 -0
  288. aip_agents/guardrails/engines/base.pyi +61 -0
  289. aip_agents/guardrails/engines/nemo.py +101 -0
  290. aip_agents/guardrails/engines/nemo.pyi +46 -0
  291. aip_agents/guardrails/engines/phrase_matcher.py +113 -0
  292. aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
  293. aip_agents/guardrails/exceptions.py +39 -0
  294. aip_agents/guardrails/exceptions.pyi +23 -0
  295. aip_agents/guardrails/manager.py +163 -0
  296. aip_agents/guardrails/manager.pyi +42 -0
  297. aip_agents/guardrails/middleware.py +199 -0
  298. aip_agents/guardrails/middleware.pyi +87 -0
  299. aip_agents/guardrails/schemas.py +63 -0
  300. aip_agents/guardrails/schemas.pyi +43 -0
  301. aip_agents/guardrails/utils.py +45 -0
  302. aip_agents/guardrails/utils.pyi +19 -0
  303. aip_agents/mcp/__init__.py +1 -0
  304. aip_agents/mcp/__init__.pyi +0 -0
  305. aip_agents/mcp/client/__init__.py +14 -0
  306. aip_agents/mcp/client/__init__.pyi +5 -0
  307. aip_agents/mcp/client/base_mcp_client.py +369 -0
  308. aip_agents/mcp/client/base_mcp_client.pyi +148 -0
  309. aip_agents/mcp/client/connection_manager.py +193 -0
  310. aip_agents/mcp/client/connection_manager.pyi +48 -0
  311. aip_agents/mcp/client/google_adk/__init__.py +11 -0
  312. aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
  313. aip_agents/mcp/client/google_adk/client.py +381 -0
  314. aip_agents/mcp/client/google_adk/client.pyi +75 -0
  315. aip_agents/mcp/client/langchain/__init__.py +11 -0
  316. aip_agents/mcp/client/langchain/__init__.pyi +3 -0
  317. aip_agents/mcp/client/langchain/client.py +265 -0
  318. aip_agents/mcp/client/langchain/client.pyi +48 -0
  319. aip_agents/mcp/client/persistent_session.py +362 -0
  320. aip_agents/mcp/client/persistent_session.pyi +113 -0
  321. aip_agents/mcp/client/session_pool.py +351 -0
  322. aip_agents/mcp/client/session_pool.pyi +101 -0
  323. aip_agents/mcp/client/transports.py +228 -0
  324. aip_agents/mcp/client/transports.pyi +123 -0
  325. aip_agents/mcp/utils/__init__.py +7 -0
  326. aip_agents/mcp/utils/__init__.pyi +0 -0
  327. aip_agents/mcp/utils/config_validator.py +139 -0
  328. aip_agents/mcp/utils/config_validator.pyi +82 -0
  329. aip_agents/memory/__init__.py +14 -0
  330. aip_agents/memory/__init__.pyi +5 -0
  331. aip_agents/memory/adapters/__init__.py +10 -0
  332. aip_agents/memory/adapters/__init__.pyi +4 -0
  333. aip_agents/memory/adapters/base_adapter.py +717 -0
  334. aip_agents/memory/adapters/base_adapter.pyi +150 -0
  335. aip_agents/memory/adapters/mem0.py +84 -0
  336. aip_agents/memory/adapters/mem0.pyi +22 -0
  337. aip_agents/memory/base.py +84 -0
  338. aip_agents/memory/base.pyi +60 -0
  339. aip_agents/memory/constants.py +49 -0
  340. aip_agents/memory/constants.pyi +25 -0
  341. aip_agents/memory/factory.py +86 -0
  342. aip_agents/memory/factory.pyi +24 -0
  343. aip_agents/memory/guidance.py +20 -0
  344. aip_agents/memory/guidance.pyi +3 -0
  345. aip_agents/memory/simple_memory.py +47 -0
  346. aip_agents/memory/simple_memory.pyi +23 -0
  347. aip_agents/middleware/__init__.py +17 -0
  348. aip_agents/middleware/__init__.pyi +5 -0
  349. aip_agents/middleware/base.py +96 -0
  350. aip_agents/middleware/base.pyi +75 -0
  351. aip_agents/middleware/manager.py +150 -0
  352. aip_agents/middleware/manager.pyi +84 -0
  353. aip_agents/middleware/todolist.py +274 -0
  354. aip_agents/middleware/todolist.pyi +125 -0
  355. aip_agents/schema/__init__.py +69 -0
  356. aip_agents/schema/__init__.pyi +9 -0
  357. aip_agents/schema/a2a.py +56 -0
  358. aip_agents/schema/a2a.pyi +40 -0
  359. aip_agents/schema/agent.py +111 -0
  360. aip_agents/schema/agent.pyi +65 -0
  361. aip_agents/schema/hitl.py +157 -0
  362. aip_agents/schema/hitl.pyi +89 -0
  363. aip_agents/schema/langgraph.py +37 -0
  364. aip_agents/schema/langgraph.pyi +28 -0
  365. aip_agents/schema/model_id.py +97 -0
  366. aip_agents/schema/model_id.pyi +54 -0
  367. aip_agents/schema/step_limit.py +108 -0
  368. aip_agents/schema/step_limit.pyi +63 -0
  369. aip_agents/schema/storage.py +40 -0
  370. aip_agents/schema/storage.pyi +21 -0
  371. aip_agents/sentry/__init__.py +11 -0
  372. aip_agents/sentry/__init__.pyi +3 -0
  373. aip_agents/sentry/sentry.py +151 -0
  374. aip_agents/sentry/sentry.pyi +48 -0
  375. aip_agents/storage/__init__.py +41 -0
  376. aip_agents/storage/__init__.pyi +8 -0
  377. aip_agents/storage/base.py +85 -0
  378. aip_agents/storage/base.pyi +58 -0
  379. aip_agents/storage/clients/__init__.py +12 -0
  380. aip_agents/storage/clients/__init__.pyi +3 -0
  381. aip_agents/storage/clients/minio_client.py +318 -0
  382. aip_agents/storage/clients/minio_client.pyi +137 -0
  383. aip_agents/storage/config.py +62 -0
  384. aip_agents/storage/config.pyi +29 -0
  385. aip_agents/storage/providers/__init__.py +15 -0
  386. aip_agents/storage/providers/__init__.pyi +5 -0
  387. aip_agents/storage/providers/base.py +106 -0
  388. aip_agents/storage/providers/base.pyi +88 -0
  389. aip_agents/storage/providers/memory.py +114 -0
  390. aip_agents/storage/providers/memory.pyi +79 -0
  391. aip_agents/storage/providers/object_storage.py +214 -0
  392. aip_agents/storage/providers/object_storage.pyi +98 -0
  393. aip_agents/tools/__init__.py +53 -0
  394. aip_agents/tools/__init__.pyi +9 -0
  395. aip_agents/tools/browser_use/__init__.py +82 -0
  396. aip_agents/tools/browser_use/__init__.pyi +14 -0
  397. aip_agents/tools/browser_use/action_parser.py +103 -0
  398. aip_agents/tools/browser_use/action_parser.pyi +18 -0
  399. aip_agents/tools/browser_use/browser_use_tool.py +1112 -0
  400. aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
  401. aip_agents/tools/browser_use/llm_config.py +120 -0
  402. aip_agents/tools/browser_use/llm_config.pyi +52 -0
  403. aip_agents/tools/browser_use/minio_storage.py +198 -0
  404. aip_agents/tools/browser_use/minio_storage.pyi +109 -0
  405. aip_agents/tools/browser_use/schemas.py +119 -0
  406. aip_agents/tools/browser_use/schemas.pyi +32 -0
  407. aip_agents/tools/browser_use/session.py +76 -0
  408. aip_agents/tools/browser_use/session.pyi +4 -0
  409. aip_agents/tools/browser_use/session_errors.py +132 -0
  410. aip_agents/tools/browser_use/session_errors.pyi +53 -0
  411. aip_agents/tools/browser_use/steel_session_recording.py +317 -0
  412. aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
  413. aip_agents/tools/browser_use/streaming.py +813 -0
  414. aip_agents/tools/browser_use/streaming.pyi +81 -0
  415. aip_agents/tools/browser_use/structured_data_parser.py +257 -0
  416. aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
  417. aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
  418. aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
  419. aip_agents/tools/browser_use/types.py +78 -0
  420. aip_agents/tools/browser_use/types.pyi +45 -0
  421. aip_agents/tools/code_sandbox/__init__.py +26 -0
  422. aip_agents/tools/code_sandbox/__init__.pyi +3 -0
  423. aip_agents/tools/code_sandbox/constant.py +13 -0
  424. aip_agents/tools/code_sandbox/constant.pyi +4 -0
  425. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +306 -0
  426. aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +102 -0
  427. aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
  428. aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
  429. aip_agents/tools/constants.py +177 -0
  430. aip_agents/tools/constants.pyi +138 -0
  431. aip_agents/tools/document_loader/__init__.py +44 -0
  432. aip_agents/tools/document_loader/__init__.pyi +7 -0
  433. aip_agents/tools/document_loader/base_reader.py +302 -0
  434. aip_agents/tools/document_loader/base_reader.pyi +75 -0
  435. aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
  436. aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
  437. aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
  438. aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
  439. aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
  440. aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
  441. aip_agents/tools/document_loader/pdf_splitter.py +169 -0
  442. aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
  443. aip_agents/tools/gl_connector/__init__.py +5 -0
  444. aip_agents/tools/gl_connector/__init__.pyi +3 -0
  445. aip_agents/tools/gl_connector/tool.py +383 -0
  446. aip_agents/tools/gl_connector/tool.pyi +74 -0
  447. aip_agents/tools/gl_connector_tools.py +119 -0
  448. aip_agents/tools/gl_connector_tools.pyi +39 -0
  449. aip_agents/tools/memory_search/__init__.py +22 -0
  450. aip_agents/tools/memory_search/__init__.pyi +5 -0
  451. aip_agents/tools/memory_search/base.py +200 -0
  452. aip_agents/tools/memory_search/base.pyi +69 -0
  453. aip_agents/tools/memory_search/mem0.py +258 -0
  454. aip_agents/tools/memory_search/mem0.pyi +19 -0
  455. aip_agents/tools/memory_search/schema.py +48 -0
  456. aip_agents/tools/memory_search/schema.pyi +15 -0
  457. aip_agents/tools/memory_search_tool.py +26 -0
  458. aip_agents/tools/memory_search_tool.pyi +3 -0
  459. aip_agents/tools/time_tool.py +117 -0
  460. aip_agents/tools/time_tool.pyi +16 -0
  461. aip_agents/tools/tool_config_injector.py +300 -0
  462. aip_agents/tools/tool_config_injector.pyi +26 -0
  463. aip_agents/tools/web_search/__init__.py +15 -0
  464. aip_agents/tools/web_search/__init__.pyi +3 -0
  465. aip_agents/tools/web_search/serper_tool.py +187 -0
  466. aip_agents/tools/web_search/serper_tool.pyi +19 -0
  467. aip_agents/types/__init__.py +70 -0
  468. aip_agents/types/__init__.pyi +36 -0
  469. aip_agents/types/a2a_events.py +13 -0
  470. aip_agents/types/a2a_events.pyi +3 -0
  471. aip_agents/utils/__init__.py +79 -0
  472. aip_agents/utils/__init__.pyi +11 -0
  473. aip_agents/utils/a2a_connector.py +1757 -0
  474. aip_agents/utils/a2a_connector.pyi +146 -0
  475. aip_agents/utils/artifact_helpers.py +502 -0
  476. aip_agents/utils/artifact_helpers.pyi +203 -0
  477. aip_agents/utils/constants.py +22 -0
  478. aip_agents/utils/constants.pyi +10 -0
  479. aip_agents/utils/datetime/__init__.py +34 -0
  480. aip_agents/utils/datetime/__init__.pyi +4 -0
  481. aip_agents/utils/datetime/normalization.py +231 -0
  482. aip_agents/utils/datetime/normalization.pyi +95 -0
  483. aip_agents/utils/datetime/timezone.py +206 -0
  484. aip_agents/utils/datetime/timezone.pyi +48 -0
  485. aip_agents/utils/env_loader.py +27 -0
  486. aip_agents/utils/env_loader.pyi +10 -0
  487. aip_agents/utils/event_handler_registry.py +58 -0
  488. aip_agents/utils/event_handler_registry.pyi +23 -0
  489. aip_agents/utils/file_prompt_utils.py +176 -0
  490. aip_agents/utils/file_prompt_utils.pyi +21 -0
  491. aip_agents/utils/final_response_builder.py +211 -0
  492. aip_agents/utils/final_response_builder.pyi +34 -0
  493. aip_agents/utils/formatter_llm_client.py +231 -0
  494. aip_agents/utils/formatter_llm_client.pyi +71 -0
  495. aip_agents/utils/langgraph/__init__.py +19 -0
  496. aip_agents/utils/langgraph/__init__.pyi +3 -0
  497. aip_agents/utils/langgraph/converter.py +128 -0
  498. aip_agents/utils/langgraph/converter.pyi +49 -0
  499. aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
  500. aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
  501. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
  502. aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
  503. aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
  504. aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
  505. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1071 -0
  506. aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
  507. aip_agents/utils/langgraph/tool_output_management.py +967 -0
  508. aip_agents/utils/langgraph/tool_output_management.pyi +292 -0
  509. aip_agents/utils/logger.py +195 -0
  510. aip_agents/utils/logger.pyi +60 -0
  511. aip_agents/utils/metadata/__init__.py +27 -0
  512. aip_agents/utils/metadata/__init__.pyi +5 -0
  513. aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
  514. aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
  515. aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
  516. aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
  517. aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
  518. aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
  519. aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
  520. aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
  521. aip_agents/utils/metadata/activity_narrative/context.py +49 -0
  522. aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
  523. aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
  524. aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
  525. aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
  526. aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
  527. aip_agents/utils/metadata/schemas/__init__.py +16 -0
  528. aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
  529. aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
  530. aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
  531. aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
  532. aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
  533. aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
  534. aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
  535. aip_agents/utils/metadata_helper.py +358 -0
  536. aip_agents/utils/metadata_helper.pyi +117 -0
  537. aip_agents/utils/name_preprocessor/__init__.py +17 -0
  538. aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
  539. aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
  540. aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
  541. aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
  542. aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
  543. aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
  544. aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
  545. aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
  546. aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
  547. aip_agents/utils/pii/__init__.py +25 -0
  548. aip_agents/utils/pii/__init__.pyi +5 -0
  549. aip_agents/utils/pii/pii_handler.py +397 -0
  550. aip_agents/utils/pii/pii_handler.pyi +96 -0
  551. aip_agents/utils/pii/pii_helper.py +207 -0
  552. aip_agents/utils/pii/pii_helper.pyi +78 -0
  553. aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
  554. aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
  555. aip_agents/utils/reference_helper.py +273 -0
  556. aip_agents/utils/reference_helper.pyi +81 -0
  557. aip_agents/utils/sse_chunk_transformer.py +831 -0
  558. aip_agents/utils/sse_chunk_transformer.pyi +166 -0
  559. aip_agents/utils/step_limit_manager.py +265 -0
  560. aip_agents/utils/step_limit_manager.pyi +112 -0
  561. aip_agents/utils/token_usage_helper.py +156 -0
  562. aip_agents/utils/token_usage_helper.pyi +60 -0
  563. aip_agents_binary-0.5.25b1.dist-info/METADATA +681 -0
  564. aip_agents_binary-0.5.25b1.dist-info/RECORD +566 -0
  565. aip_agents_binary-0.5.25b1.dist-info/WHEEL +5 -0
  566. aip_agents_binary-0.5.25b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,717 @@
1
+ """Base adapter that bridges aip-agents BaseMemory to async memory managers.
2
+
3
+ This adapter hides the async nature of gllm_memory.MemoryManager (or any future
4
+ async provider) behind the existing synchronous BaseMemory contract so downstream
5
+ LangGraph/LangChain components can continue using blocking calls.
6
+
7
+ Authors:
8
+ Raymond Christopher (raymond.christopher@gdplabs.id)
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import asyncio
14
+ import threading
15
+ from concurrent.futures import Future, ThreadPoolExecutor
16
+ from contextlib import suppress
17
+ from dataclasses import dataclass
18
+ from datetime import datetime, timedelta
19
+ from time import perf_counter
20
+ from typing import Any, ClassVar
21
+
22
+ from gllm_core.schema import Chunk
23
+ from gllm_inference.schema.message import Message
24
+
25
+ try:
26
+ from gllm_memory import MemoryManager
27
+ from gllm_memory.enums import MemoryScope
28
+
29
+ _HAS_GLLM_MEMORY = True
30
+ except ImportError: # pragma: no cover
31
+ MemoryManager = Any # type: ignore[assignment]
32
+ MemoryScope = Any # type: ignore[assignment]
33
+ _HAS_GLLM_MEMORY = False
34
+
35
+ from aip_agents.memory.base import BaseMemory
36
+ from aip_agents.memory.constants import MemoryDefaults
37
+ from aip_agents.types import ChatMessage
38
+ from aip_agents.utils.datetime import format_created_updated_label
39
+ from aip_agents.utils.logger import get_logger
40
+
41
+ logger = get_logger(__name__)
42
+
43
+
44
+ def _require_gllm_memory() -> None:
45
+ if not _HAS_GLLM_MEMORY:
46
+ raise ImportError("optional dependency 'gllm-memory' is required for memory adapters")
47
+
48
+
49
+ if _HAS_GLLM_MEMORY:
50
+ DEFAULT_SCOPE: ClassVar[set[MemoryScope]] = {MemoryScope.USER}
51
+ else:
52
+ DEFAULT_SCOPE: ClassVar[set[Any]] = set()
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class _RetrieveOptions:
57
+ user_id: str
58
+ top_k: int
59
+ metadata: dict[str, str] | None
60
+ keywords: Any
61
+ page: int
62
+ categories: list[str] | None
63
+
64
+
65
+ class _AsyncRunner:
66
+ """Runs async coroutines on a dedicated background event loop."""
67
+
68
+ def __init__(self) -> None:
69
+ self._loop = asyncio.new_event_loop()
70
+ self._thread = threading.Thread(target=self._loop.run_forever, daemon=True)
71
+ self._thread.start()
72
+ self._shutdown = False
73
+
74
+ def run(self, awaitable: Any) -> Any:
75
+ """Execute an awaitable on the background loop and block for the result.
76
+
77
+ Args:
78
+ awaitable: The coroutine to execute.
79
+
80
+ Returns:
81
+ The result of the coroutine execution.
82
+ """
83
+ if self._shutdown:
84
+ raise RuntimeError("AsyncRunner has been shut down")
85
+ future = asyncio.run_coroutine_threadsafe(awaitable, self._loop)
86
+ return future.result()
87
+
88
+ def shutdown(self, timeout: float | None = 5.0) -> None:
89
+ """Gracefully stop the event loop thread.
90
+
91
+ Args:
92
+ timeout: Maximum time to wait for the thread to stop.
93
+ """
94
+ if self._shutdown:
95
+ return
96
+ self._shutdown = True
97
+ self._loop.call_soon_threadsafe(self._loop.stop)
98
+ self._thread.join(timeout)
99
+ with suppress(Exception):
100
+ self._loop.close()
101
+
102
+ def __del__(self) -> None: # pragma: no cover - best effort cleanup
103
+ with suppress(Exception):
104
+ self.shutdown(timeout=0)
105
+
106
+
107
+ class BaseMemoryAdapter(BaseMemory):
108
+ """Provider-agnostic long-term memory adapter backed by gllm_memory."""
109
+
110
+ def __init__(
111
+ self,
112
+ *,
113
+ agent_id: str,
114
+ manager: MemoryManager,
115
+ namespace: str | None = None,
116
+ limit: int = MemoryDefaults.RETRIEVAL_LIMIT,
117
+ max_chars: int = MemoryDefaults.MAX_CHARS,
118
+ ) -> None:
119
+ """Initialize the GLLM memory adapter.
120
+
121
+ Args:
122
+ agent_id: Unique identifier for the agent using this memory.
123
+ manager: Configured gllm_memory MemoryManager instance.
124
+ namespace: Optional namespace for organizing memories.
125
+ limit: Maximum number of memories to retrieve in search operations.
126
+ max_chars: Maximum character length for text content.
127
+ """
128
+ _require_gllm_memory()
129
+
130
+ self.agent_id = agent_id or MemoryDefaults.DEFAULT_USER_ID
131
+ self.namespace = namespace
132
+ self.limit = int(limit)
133
+ self.max_chars = int(max_chars)
134
+
135
+ self._manager = manager
136
+ self._runner = _AsyncRunner()
137
+ self._executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="memory-save")
138
+ self._pending_futures: set[Future[Any]] = set()
139
+ self._futures_lock = threading.Lock()
140
+ self._closed = False
141
+
142
+ @classmethod
143
+ def validate_env(
144
+ cls,
145
+ ) -> None: # pragma: no cover - base adapter has no env requirements
146
+ """Base adapter does not enforce environment validation."""
147
+ return None
148
+
149
+ # ------------------------------------------------------------------ #
150
+ # BaseMemory interface
151
+ # ------------------------------------------------------------------ #
152
+
153
+ def get_messages(self) -> list[ChatMessage]:
154
+ """Retrieve all stored chat messages.
155
+
156
+ Returns:
157
+ An empty list as GLLM adapter doesn't support message retrieval.
158
+ """
159
+ return []
160
+
161
+ def add_message(self, message: ChatMessage) -> None:
162
+ """Best-effort single-message persistence for API parity.
163
+
164
+ Args:
165
+ message: The chat message to add to memory.
166
+ """
167
+ try:
168
+ self._runner.run(
169
+ self._manager.add(
170
+ user_id=self.agent_id,
171
+ agent_id=self.agent_id,
172
+ messages=[self._to_message(message)],
173
+ scopes=DEFAULT_SCOPE,
174
+ infer=False,
175
+ )
176
+ )
177
+ except Exception as exc: # noqa: BLE001
178
+ logger.debug("BaseMemoryAdapter.add_message ignored error: %s", exc)
179
+
180
+ def clear(self) -> None:
181
+ """Clear all stored memories.
182
+
183
+ Raises:
184
+ NotImplementedError: This method is not implemented for GLLM adapter.
185
+ """
186
+ raise NotImplementedError("clear() is not implemented for BaseMemoryAdapter.")
187
+
188
+ # ------------------------------------------------------------------ #
189
+ # Legacy Mem0Memory-compatible surface area
190
+ # ------------------------------------------------------------------ #
191
+
192
+ def search(
193
+ self,
194
+ query: str,
195
+ *,
196
+ user_id: str,
197
+ limit: int | None = None,
198
+ filters: dict[str, Any] | None = None,
199
+ ) -> list[dict[str, Any]]:
200
+ """Search for memories using a text query.
201
+
202
+ Args:
203
+ query: The search query string.
204
+ user_id: User identifier for the search scope.
205
+ limit: Maximum number of results to return.
206
+ filters: Optional filters to apply to the search.
207
+
208
+ Returns:
209
+ List of memory hits matching the search criteria.
210
+ """
211
+ return self.retrieve(query=query, user_id=user_id, limit=limit, filters=filters)
212
+
213
+ def retrieve(
214
+ self,
215
+ *,
216
+ query: str | None,
217
+ user_id: str,
218
+ limit: int | None = None,
219
+ filters: dict[str, Any] | None = None,
220
+ page: int | None = None,
221
+ ) -> list[dict[str, Any]]:
222
+ """Retrieve memories with optional search query and filters.
223
+
224
+ Args:
225
+ query: Optional search query string. If None, retrieves all memories.
226
+ user_id: User identifier for the retrieval scope.
227
+ limit: Maximum number of results to return.
228
+ filters: Optional filters to apply to the retrieval.
229
+ page: Page number for pagination.
230
+
231
+ Returns:
232
+ List of memory hits matching the criteria.
233
+ """
234
+ options = self._build_retrieve_options(
235
+ user_id=user_id,
236
+ limit=limit,
237
+ filters=filters,
238
+ page=page,
239
+ )
240
+ try:
241
+ start = perf_counter()
242
+ chunks = self._runner.run(self._create_retrieve_task(query, options))
243
+ duration = perf_counter() - start
244
+ logger.info(
245
+ "BaseMemoryAdapter: retrieve user_id='%s' query='%s' limit=%s returned %d hits in %.2fs (filters=%s)",
246
+ user_id,
247
+ query,
248
+ options.top_k,
249
+ len(chunks),
250
+ duration,
251
+ options.metadata,
252
+ )
253
+ except Exception as exc: # noqa: BLE001
254
+ logger.debug("BaseMemoryAdapter.retrieve ignored error: %s", exc)
255
+ return []
256
+
257
+ return [self._chunk_to_hit(chunk) for chunk in chunks]
258
+
259
+ def save_interaction(self, *, user_text: str, ai_text: str, user_id: str) -> None:
260
+ """Save a user-AI interaction as memories.
261
+
262
+ Args:
263
+ user_text: The user's input text.
264
+ ai_text: The AI's response text.
265
+ user_id: User identifier for the memory storage.
266
+ """
267
+ truncated_user = str(user_text)[: self.max_chars]
268
+ truncated_ai = str(ai_text)[: self.max_chars]
269
+ messages = [
270
+ Message.user(contents=truncated_user),
271
+ Message.assistant(contents=truncated_ai),
272
+ ]
273
+ preview_user = truncated_user[: MemoryDefaults.LOG_PREVIEW_LENGTH]
274
+ preview_ai = truncated_ai[: MemoryDefaults.LOG_PREVIEW_LENGTH]
275
+ logger.info(
276
+ "BaseMemoryAdapter: saving interaction user_id='%s' user_preview='%s%s' ai_preview='%s%s'",
277
+ user_id,
278
+ preview_user,
279
+ "..." if len(truncated_user) > len(preview_user) else "",
280
+ preview_ai,
281
+ "..." if len(truncated_ai) > len(preview_ai) else "",
282
+ )
283
+ try:
284
+ start = perf_counter()
285
+ self._runner.run(
286
+ self._manager.add(
287
+ user_id=user_id or self.agent_id,
288
+ agent_id=self.agent_id,
289
+ messages=messages,
290
+ scopes=DEFAULT_SCOPE,
291
+ )
292
+ )
293
+ duration = perf_counter() - start
294
+ logger.info(
295
+ "BaseMemoryAdapter: save_interaction completed for user_id='%s' in %.2fs",
296
+ user_id,
297
+ duration,
298
+ )
299
+ except Exception as exc: # noqa: BLE001
300
+ logger.debug("BaseMemoryAdapter.save_interaction ignored error: %s", exc)
301
+
302
+ def save_interaction_async(self, *, user_text: str, ai_text: str, user_id: str) -> Future[Any]:
303
+ """Schedule save_interaction without blocking the caller.
304
+
305
+ Args:
306
+ user_text: The user's input text to save.
307
+ ai_text: The AI's response text to save.
308
+ user_id: User identifier for the memory storage.
309
+ """
310
+ future = self._executor.submit(
311
+ self.save_interaction,
312
+ user_text=user_text,
313
+ ai_text=ai_text,
314
+ user_id=user_id,
315
+ )
316
+ with self._futures_lock:
317
+ self._pending_futures.add(future)
318
+
319
+ def _on_complete(done: Future[Any]) -> None:
320
+ """Discard a completed future from the pending set and log failures.
321
+
322
+ Args:
323
+ done: Future returned by the executor for save_interaction.
324
+ """
325
+ with self._futures_lock:
326
+ self._pending_futures.discard(done)
327
+ exc = done.exception()
328
+ if exc:
329
+ logger.warning(
330
+ "BaseMemoryAdapter: async save failed for user_id='%s': %s",
331
+ user_id,
332
+ exc,
333
+ )
334
+
335
+ future.add_done_callback(_on_complete)
336
+ return future
337
+
338
+ def format_hits(
339
+ self,
340
+ hits: list[dict[str, Any]],
341
+ max_items: int = MemoryDefaults.MAX_ITEMS,
342
+ with_tag: bool = True,
343
+ ) -> str:
344
+ """Format memory hits into a readable string.
345
+
346
+ Args:
347
+ hits: List of memory hit dictionaries to format.
348
+ max_items: Maximum number of hits to include in the output.
349
+ with_tag: Whether to wrap the output with memory tags.
350
+
351
+ Returns:
352
+ Formatted string representation of the memory hits.
353
+ """
354
+ lines: list[str] = []
355
+ for hit in hits[:max_items]:
356
+ if not isinstance(hit, dict):
357
+ lines.append(f"- {hit}")
358
+ continue
359
+ text = hit.get("memory") or hit.get("text") or hit.get("content")
360
+ if not text:
361
+ text = str(hit)
362
+ label = format_created_updated_label(hit.get("created_at"), hit.get("updated_at"))
363
+ prefix = f"- [{label}] " if label else "- "
364
+ lines.append(f"{prefix}{text}")
365
+
366
+ if not lines:
367
+ logger.info("BaseMemoryAdapter: No memories to format for prompt")
368
+ return ""
369
+
370
+ formatted_memory = (
371
+ f"{MemoryDefaults.MEMORY_TAG_OPEN}\n" + "\n".join(lines) + f"\n{MemoryDefaults.MEMORY_TAG_CLOSE}\n\n"
372
+ if with_tag
373
+ else "\n".join(lines)
374
+ )
375
+ logger.info("BaseMemoryAdapter: Formatted %s memories for prompt", len(lines))
376
+ logger.info(
377
+ "BaseMemoryAdapter: Prompt memory block:%s%s",
378
+ "\n" if lines else " ",
379
+ formatted_memory.strip(),
380
+ )
381
+ return formatted_memory
382
+
383
+ def flush_pending_writes(self, timeout: float | None = None) -> None:
384
+ """Block until current async writes complete.
385
+
386
+ Args:
387
+ timeout: Maximum time to wait for pending writes to complete.
388
+ """
389
+ futures = self._snapshot_pending_futures()
390
+ for future in futures:
391
+ try:
392
+ future.result(timeout=timeout)
393
+ except Exception as exc: # noqa: BLE001
394
+ logger.warning("BaseMemoryAdapter: Pending async save raised: %s", exc)
395
+
396
+ def close(self, *, wait: bool = True, timeout: float | None = None) -> None:
397
+ """Release background resources and optionally wait for pending saves.
398
+
399
+ Args:
400
+ wait: Whether to wait for pending async operations to complete.
401
+ timeout: Maximum time to wait when wait=True.
402
+ """
403
+ if self._closed:
404
+ return
405
+ self._closed = True
406
+ if wait:
407
+ self.flush_pending_writes(timeout=timeout)
408
+ self._executor.shutdown(wait=wait, cancel_futures=not wait)
409
+ self._runner.shutdown()
410
+
411
+ def __del__(self) -> None: # pragma: no cover - best effort cleanup
412
+ """Clean up resources when the adapter is garbage collected."""
413
+ with suppress(Exception):
414
+ self.close(wait=False)
415
+
416
+ def _snapshot_pending_futures(self) -> list[Future[Any]]:
417
+ with self._futures_lock:
418
+ return list(self._pending_futures)
419
+
420
+ def _call_manager_with_optional_categories(
421
+ self,
422
+ func: Any,
423
+ *,
424
+ categories: list[str] | None,
425
+ **kwargs: Any,
426
+ ) -> Any:
427
+ """Invoke a MemoryManager coroutine, retrying without categories if unsupported.
428
+
429
+ Args:
430
+ func: The MemoryManager method to call.
431
+ categories: Optional categories to pass to the method.
432
+ **kwargs: Additional keyword arguments to pass to the method.
433
+
434
+ Returns:
435
+ The result of calling the MemoryManager method.
436
+ """
437
+ if categories:
438
+ try:
439
+ return func(categories=categories, **kwargs)
440
+ except TypeError:
441
+ logger.debug(
442
+ "BaseMemoryAdapter: '%s' does not accept categories, retrying without it",
443
+ getattr(func, "__name__", func),
444
+ )
445
+ return func(**kwargs)
446
+
447
+ # ------------------------------------------------------------------ #
448
+ # Helper utilities
449
+ # ------------------------------------------------------------------ #
450
+
451
+ def _build_retrieve_options(
452
+ self,
453
+ *,
454
+ user_id: str,
455
+ limit: int | None,
456
+ filters: dict[str, Any] | None,
457
+ page: int | None,
458
+ ) -> _RetrieveOptions:
459
+ """Assemble normalized retrieval options for the MemoryManager.
460
+
461
+ Args:
462
+ user_id: Optional user identifier requesting the memory retrieval.
463
+ limit: Maximum number of items to return.
464
+ filters: Raw filter payload supplied by the caller.
465
+ page: Page number for paginated listing operations.
466
+
467
+ Returns:
468
+ _RetrieveOptions instance consumed by downstream search/list calls.
469
+ """
470
+ effective_user = user_id or self.agent_id or MemoryDefaults.DEFAULT_USER_ID
471
+ top_k = int(limit) if limit is not None else self.limit
472
+ normalized_filters = self._normalize_filters(filters or {})
473
+ metadata_payload = self._build_metadata_payload(normalized_filters)
474
+ keywords = normalized_filters.get("keywords")
475
+ categories = normalized_filters.get("categories")
476
+ return _RetrieveOptions(
477
+ user_id=effective_user,
478
+ top_k=top_k,
479
+ metadata=metadata_payload,
480
+ keywords=keywords,
481
+ page=page or 1,
482
+ categories=list(categories) if isinstance(categories, list) else categories,
483
+ )
484
+
485
+ def _create_retrieve_task(self, query: str | None, options: _RetrieveOptions) -> Any:
486
+ """Build the manager coroutine to execute for search/list requests.
487
+
488
+ Args:
489
+ query: Optional search query to execute against the memories.
490
+ options: Prepared retrieval options containing metadata and pagination.
491
+
492
+ Returns:
493
+ Awaitable returned by the MemoryManager search or list method.
494
+ """
495
+ if query:
496
+ return self._call_manager_with_optional_categories(
497
+ self._manager.search,
498
+ categories=options.categories,
499
+ query=query,
500
+ user_id=options.user_id,
501
+ agent_id=self.agent_id,
502
+ scopes=DEFAULT_SCOPE,
503
+ metadata=options.metadata,
504
+ top_k=options.top_k,
505
+ )
506
+ return self._call_manager_with_optional_categories(
507
+ self._manager.list_memories,
508
+ categories=options.categories,
509
+ user_id=options.user_id,
510
+ agent_id=self.agent_id,
511
+ scopes=DEFAULT_SCOPE,
512
+ metadata=options.metadata,
513
+ keywords=options.keywords,
514
+ page=options.page,
515
+ page_size=options.top_k,
516
+ )
517
+
518
+ def _normalize_filters(self, filters: dict[str, Any]) -> dict[str, Any]:
519
+ """Normalize filters from legacy AND/OR format to the expected structure.
520
+
521
+ Args:
522
+ filters: Raw filter dictionary that may use legacy format.
523
+
524
+ Returns:
525
+ Normalized filter dictionary.
526
+ """
527
+ if self._is_legacy_filter_format(filters):
528
+ return self._convert_legacy_filters(filters)
529
+ return filters
530
+
531
+ @staticmethod
532
+ def _is_legacy_filter_format(filters: dict[str, Any]) -> bool:
533
+ """Return True when the filters dict uses legacy AND/OR syntax.
534
+
535
+ Args:
536
+ filters: Filter dictionary to check.
537
+
538
+ Returns:
539
+ True if the filters use legacy AND/OR syntax.
540
+ """
541
+ if not isinstance(filters, dict):
542
+ return False
543
+ return "AND" in filters or "OR" in filters
544
+
545
+ @staticmethod
546
+ def _convert_legacy_filters(filters: dict[str, Any]) -> dict[str, Any]:
547
+ """Convert AND/OR style legacy filters into the normalized structure.
548
+
549
+ Args:
550
+ filters: Legacy filter payload coming from older clients.
551
+
552
+ Returns:
553
+ Dictionary with metadata, categories, and date range keys.
554
+ """
555
+ normalized: dict[str, Any] = {
556
+ "metadata": {},
557
+ "categories": None,
558
+ "start_time": None,
559
+ "end_time": None,
560
+ }
561
+
562
+ clauses = filters.get("AND", [])
563
+ for clause in clauses:
564
+ if not isinstance(clause, dict):
565
+ continue
566
+ BaseMemoryAdapter._process_clause(clause, normalized)
567
+
568
+ return normalized
569
+
570
+ @staticmethod
571
+ def _process_clause(clause: dict[str, Any], normalized: dict[str, Any]) -> None:
572
+ """Process a single clause and update the normalized filters.
573
+
574
+ Args:
575
+ clause: Single filter clause to process.
576
+ normalized: Dictionary to update with normalized filter values.
577
+ """
578
+ if "created_at" in clause and isinstance(clause["created_at"], dict):
579
+ BaseMemoryAdapter._process_created_at_clause(clause["created_at"], normalized)
580
+ elif "categories" in clause and isinstance(clause["categories"], dict):
581
+ BaseMemoryAdapter._process_categories_clause(clause["categories"], normalized)
582
+ elif "metadata" in clause and isinstance(clause["metadata"], dict):
583
+ normalized["metadata"].update(clause["metadata"])
584
+
585
+ @staticmethod
586
+ def _process_created_at_clause(created_filter: dict[str, Any], normalized: dict[str, Any]) -> None:
587
+ """Process created_at clause for date filtering.
588
+
589
+ Args:
590
+ created_filter: Created date filter criteria.
591
+ normalized: Dictionary to update with normalized date values.
592
+ """
593
+ start_candidate = created_filter.get("gte") or created_filter.get("gt")
594
+ end_candidate = created_filter.get("lte") or created_filter.get("lt")
595
+ if start_candidate:
596
+ normalized["start_time"] = start_candidate
597
+ if end_candidate:
598
+ normalized["end_time"] = BaseMemoryAdapter._restore_end_date(created_filter)
599
+
600
+ @staticmethod
601
+ def _process_categories_clause(categories_filter: dict[str, Any], normalized: dict[str, Any]) -> None:
602
+ """Process categories clause for category filtering.
603
+
604
+ Args:
605
+ categories_filter: Categories filter criteria.
606
+ normalized: Dictionary to update with normalized category values.
607
+ """
608
+ cats = categories_filter.get("in")
609
+ if cats:
610
+ normalized["categories"] = list(cats)
611
+
612
+ @staticmethod
613
+ def _restore_end_date(created_filter: dict[str, Any]) -> str | None:
614
+ """Convert exclusive lt filters back to the user's original end date.
615
+
616
+ Args:
617
+ created_filter: Dictionary containing date filter criteria.
618
+
619
+ Returns:
620
+ The restored end date string, or None if not applicable.
621
+ """
622
+ end_candidate = created_filter.get("lte") or created_filter.get("lt")
623
+ if end_candidate is None:
624
+ return None
625
+ if "lt" in created_filter and "lte" not in created_filter:
626
+ try:
627
+ dt = datetime.strptime(end_candidate, "%Y-%m-%d") - timedelta(days=1)
628
+ return dt.date().isoformat()
629
+ except ValueError:
630
+ return end_candidate
631
+ return end_candidate
632
+
633
+ @staticmethod
634
+ def _build_metadata_payload(
635
+ filters: dict[str, Any] | None,
636
+ ) -> dict[str, str] | None:
637
+ """Create the metadata payload expected by the MemoryManager APIs.
638
+
639
+ Args:
640
+ filters: Normalized filter dictionary built from user input.
641
+
642
+ Returns:
643
+ Dictionary of metadata strings or None when no metadata was provided.
644
+ """
645
+ if not filters:
646
+ return None
647
+
648
+ metadata: dict[str, str] = {}
649
+
650
+ raw_metadata = filters.get("metadata") or {}
651
+ for key, value in raw_metadata.items():
652
+ if value is None:
653
+ continue
654
+ metadata[key] = str(value)
655
+
656
+ start_time = filters.get("start_time")
657
+ end_time = filters.get("end_time")
658
+ if start_time:
659
+ metadata["start_time"] = str(start_time)
660
+ if end_time:
661
+ metadata["end_time"] = str(end_time)
662
+
663
+ categories = filters.get("categories")
664
+ if categories:
665
+ metadata["category"] = ",".join(str(cat) for cat in categories)
666
+
667
+ return metadata or None
668
+
669
+ @staticmethod
670
+ def _to_message(message: ChatMessage) -> Message:
671
+ """Convert a MemoryManager ChatMessage into the shared Message schema.
672
+
673
+ Args:
674
+ message: ChatMessage returned from the memory service.
675
+
676
+ Returns:
677
+ Message: Structured message with normalized role and content.
678
+ """
679
+ role = (message.role or "user").lower()
680
+ content = str(message.content) if message.content is not None else ""
681
+ if role == "assistant":
682
+ return Message.assistant(contents=content)
683
+ if role == "system":
684
+ return Message.system(contents=content)
685
+ return Message.user(contents=content)
686
+
687
+ @staticmethod
688
+ def _chunk_to_hit(chunk: Chunk) -> dict[str, Any]:
689
+ """Transform a Chunk record into the hit dict consumed by callers.
690
+
691
+ Args:
692
+ chunk: Chunk object returned by the retriever.
693
+
694
+ Returns:
695
+ dict[str, Any]: Serializable hit payload.
696
+ """
697
+ metadata = dict(chunk.metadata or {})
698
+ content = chunk.content
699
+ if isinstance(content, bytes):
700
+ try:
701
+ content = content.decode("utf-8")
702
+ except Exception: # noqa: BLE001
703
+ content = content.decode("utf-8", "ignore")
704
+ if content is None:
705
+ content = ""
706
+
707
+ hit = {
708
+ "id": chunk.id,
709
+ "memory": content,
710
+ "score": chunk.score,
711
+ "metadata": metadata,
712
+ "created_at": metadata.get("created_at"),
713
+ "updated_at": metadata.get("updated_at"),
714
+ "user_id": metadata.get("user_id"),
715
+ "agent_id": metadata.get("agent_id"),
716
+ }
717
+ return hit