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,81 @@
1
+ from aip_agents.tools.browser_use.types import StreamingResponse, ToolCallInfo
2
+ from browser_use import Agent
3
+ from typing import Any, Literal
4
+
5
+ __all__ = ['PROCESSING_MESSAGE', 'TASK_COMPLETED_MESSAGE', 'create_error_response', 'create_step_response', 'generate_step_content', 'generate_thinking_message', 'yield_iframe_activity', 'yield_status_message', 'yield_thinking_marker']
6
+
7
+ TASK_COMPLETED_MESSAGE: str
8
+ PROCESSING_MESSAGE: str
9
+
10
+ def create_step_response(agent: Agent, tool_calls: list[ToolCallInfo], is_done: bool, content: str, thinking_message: str | None) -> StreamingResponse:
11
+ """Compose the per-step payload emitted during browser-use streaming.
12
+
13
+ Args:
14
+ agent: Browser-use agent producing the step output.
15
+ tool_calls: Tool call descriptors extracted from the step.
16
+ is_done: Flag indicating whether this is the final step in the run.
17
+ content: High-level status text describing the step progress.
18
+ thinking_message: Optional preformatted thinking summary to attach.
19
+
20
+ Returns:
21
+ StreamingResponse: Serialized payload for the current streaming step.
22
+ """
23
+ async def generate_thinking_message(content: str, tool_calls: list[dict[str, Any]], *, is_final: bool) -> str | None:
24
+ """Generate a user-facing thinking summary using the formatter LLM when available.
25
+
26
+ Args:
27
+ content: High-level status text describing the step progress.
28
+ tool_calls: Serialized tool call dictionaries with outputs.
29
+ is_final: Whether the task has completed.
30
+
31
+ Returns:
32
+ Markdown-formatted summary string, or ``None`` when not applicable.
33
+ """
34
+ def create_error_response(error_message: str, recording_url: str = '') -> dict:
35
+ """Create a standardized error response.
36
+
37
+ Args:
38
+ error_message: The error message to include.
39
+ recording_url: The recording URL if available.
40
+
41
+ Returns:
42
+ dict: Standardized error response.
43
+ """
44
+ def generate_step_content(tool_calls: list[ToolCallInfo], is_done: bool) -> str:
45
+ """Return user-friendly status text derived from tool call outputs.
46
+
47
+ Args:
48
+ tool_calls: Tool call descriptors extracted from the step.
49
+ is_done: Flag indicating whether this is the final step in the run.
50
+
51
+ Returns:
52
+ User-friendly status text string.
53
+ """
54
+ def yield_iframe_activity(url: str, content: str) -> dict:
55
+ """Create and return an iframe activity streaming response.
56
+
57
+ Args:
58
+ url: The URL to display in the iframe.
59
+ content: The content message for the response.
60
+
61
+ Returns:
62
+ dict: Streaming response dictionary.
63
+ """
64
+ def yield_status_message(content: str) -> dict:
65
+ """Create a status update event notifying clients about recovery attempts.
66
+
67
+ Args:
68
+ content: The status message content to include in the event.
69
+
70
+ Returns:
71
+ dict: Streaming response dictionary for the status update event.
72
+ """
73
+ def yield_thinking_marker(marker_type: Literal['start', 'end']) -> dict:
74
+ """Create and return a thinking marker streaming response.
75
+
76
+ Args:
77
+ marker_type: Either 'start' or 'end' to indicate thinking phase.
78
+
79
+ Returns:
80
+ dict: Streaming response dictionary.
81
+ """
@@ -0,0 +1,257 @@
1
+ """High-level helpers for parsing and validating structured data extractor output.
2
+
3
+ Authors:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from collections.abc import Callable, Sequence
11
+ from typing import Any
12
+
13
+ from aip_agents.tools.browser_use.structured_data_recovery import (
14
+ recover_concatenated_json_objects,
15
+ repair_json_blob,
16
+ )
17
+ from aip_agents.tools.browser_use.types import ToolCallInfo
18
+ from aip_agents.utils.logger import get_logger
19
+
20
+ logger = get_logger(__name__)
21
+
22
+
23
+ def detect_structured_data_failure(
24
+ tool_calls: Sequence[ToolCallInfo],
25
+ summarize_error: Callable[[str], str],
26
+ ) -> str | None:
27
+ """Return a descriptive error when structured data extraction yields no results.
28
+
29
+ Args:
30
+ tool_calls: Tool call descriptors extracted from the latest agent step.
31
+ summarize_error: Function to summarize error messages.
32
+
33
+ Returns:
34
+ str | None: Failure reason when extraction yielded nothing, otherwise None.
35
+ """
36
+ for call in tool_calls:
37
+ failure = structured_data_failure_for_call(call, summarize_error)
38
+ if failure:
39
+ return failure
40
+ return None
41
+
42
+
43
+ def structured_data_failure_for_call(
44
+ call: ToolCallInfo,
45
+ summarize_error: Callable[[str], str],
46
+ ) -> str | None:
47
+ """Evaluate a single tool call for extractor failures.
48
+
49
+ Args:
50
+ call: Tool call descriptor encapsulating name/args/output.
51
+ summarize_error: Function to summarize error messages.
52
+
53
+ Returns:
54
+ str | None: Failure message when the call represents a bad extraction.
55
+ """
56
+ if call.name != "extract_structured_data":
57
+ return None
58
+
59
+ payload, parse_error = parse_structured_data(call.output or "", summarize_error)
60
+ if parse_error:
61
+ summary = summarize_error(parse_error)
62
+ return f"Structured data extraction emitted invalid JSON. Decoder reported: {summary}"
63
+ if payload is None:
64
+ return None
65
+
66
+ raw_output = call.output or ""
67
+ if isinstance(payload, dict):
68
+ error_message = payload_reports_error(payload, raw_output, summarize_error)
69
+ if error_message:
70
+ return error_message
71
+
72
+ empty_message = payload_reports_empty(payload, raw_output, summarize_error)
73
+ if empty_message:
74
+ return empty_message
75
+
76
+ return None
77
+
78
+
79
+ def payload_reports_error(
80
+ payload: dict[str, Any],
81
+ raw_output: str,
82
+ summarize_error: Callable[[str], str],
83
+ ) -> str | None:
84
+ """Return a formatted error message when extractor status indicates failure.
85
+
86
+ Args:
87
+ payload: Parsed JSON payload emitted by the extractor.
88
+ raw_output: Original extractor output (used for fallback summaries).
89
+ summarize_error: Function to summarize error messages.
90
+
91
+ Returns:
92
+ str | None: Human-readable failure string when extraction failed.
93
+ """
94
+ status = payload.get("status")
95
+ if isinstance(status, str) and status.lower() == "error":
96
+ message = payload.get("message") or payload.get("error") or raw_output
97
+ summary = summarize_error(message)
98
+ return f"Structured data extraction failed: {summary}"
99
+ return None
100
+
101
+
102
+ def payload_reports_empty(
103
+ payload: dict[str, Any],
104
+ raw_output: str,
105
+ summarize_error: Callable[[str], str],
106
+ ) -> str | None:
107
+ """Return a formatted message when the extractor returned no usable data.
108
+
109
+ Args:
110
+ payload: Parsed JSON payload emitted by the extractor.
111
+ raw_output: Original extractor output string.
112
+ summarize_error: Function to summarize error messages.
113
+
114
+ Returns:
115
+ str | None: Human-readable failure message when no content was extracted.
116
+ """
117
+ products = payload.get("products")
118
+ count = payload.get("count")
119
+ available = payload.get("available")
120
+ products_found = payload.get("products_found")
121
+
122
+ no_products = isinstance(products, list) and len(products) == 0
123
+ explicit_zero = count == 0 or products_found == 0
124
+ explicitly_unavailable = available is False
125
+
126
+ if no_products or explicit_zero or explicitly_unavailable:
127
+ summary = summarize_error(raw_output)
128
+ return f"Structured data extraction returned no usable entries. Extractor response: {summary}"
129
+ return None
130
+
131
+
132
+ def parse_structured_data(
133
+ output: str,
134
+ summarize_error: Callable[[str], str],
135
+ ) -> tuple[dict[str, Any] | list[Any] | None, str | None]:
136
+ """Extract the JSON blob emitted by extract_structured_data if present.
137
+
138
+ Args:
139
+ output: Raw string payload returned by extract_structured_data.
140
+ summarize_error: Function to summarize error messages.
141
+
142
+ Returns:
143
+ tuple[dict[str, Any] | list[Any] | None, str | None]: Parsed JSON payload when extraction succeeds,
144
+ otherwise a tuple containing None and a diagnostic string on failure.
145
+ """
146
+ content = extract_content_after_marker(output)
147
+ if not content:
148
+ return None, None
149
+
150
+ json_blob = extract_json_blob(content)
151
+ if not json_blob:
152
+ return None, None
153
+
154
+ parsed_data = attempt_json_recovery(json_blob)
155
+ if parsed_data is not None:
156
+ return parsed_data, None
157
+
158
+ snippet = summarize_error(json_blob)
159
+ error_msg = "JSON parsing failed after all recovery attempts"
160
+ logger.warning(
161
+ "Structured data extractor emitted malformed JSON: %s. snippet=%s",
162
+ error_msg,
163
+ snippet,
164
+ )
165
+ return None, f"{error_msg}: {snippet}"
166
+
167
+
168
+ def extract_content_after_marker(output: str) -> str | None:
169
+ """Extract content after the 'Extracted Content:' marker and clean trailing metadata.
170
+
171
+ Args:
172
+ output: Raw string payload returned by extract_structured_data.
173
+
174
+ Returns:
175
+ str | None: Cleaned content after the marker, or None if marker not found.
176
+ """
177
+ if "Extracted Content:" not in output:
178
+ return None
179
+
180
+ _, remainder = output.split("Extracted Content:", 1)
181
+
182
+ for marker in ("</extracted_content>", "<file_system>", "</file_system>"):
183
+ marker_index = remainder.find(marker)
184
+ if marker_index != -1:
185
+ remainder = remainder[:marker_index]
186
+ break
187
+
188
+ remainder = remainder.strip()
189
+ return remainder if remainder else None
190
+
191
+
192
+ def extract_json_blob(content: str) -> str | None:
193
+ """Extract the JSON blob from content by finding delimiters and trimming trailing content.
194
+
195
+ Args:
196
+ content: Content string potentially containing JSON.
197
+
198
+ Returns:
199
+ str | None: Extracted JSON blob, or None if no valid JSON delimiters found.
200
+ """
201
+ first_bracket = content.find("[")
202
+ first_brace = content.find("{")
203
+ candidates = [index for index in (first_bracket, first_brace) if index != -1]
204
+ if not candidates:
205
+ return None
206
+
207
+ start = min(candidates)
208
+ json_blob = content[start:]
209
+
210
+ closing_char = "]" if json_blob.startswith("[") else "}"
211
+ end = json_blob.rfind(closing_char)
212
+ if end == -1:
213
+ return None
214
+ return json_blob[: end + 1].strip()
215
+
216
+
217
+ def attempt_json_recovery(json_blob: str) -> dict[str, Any] | list[Any] | None:
218
+ """Attempt to parse JSON blob, with recovery strategies for common issues.
219
+
220
+ Args:
221
+ json_blob: JSON string to attempt parsing.
222
+
223
+ Returns:
224
+ dict[str, Any] | list[Any] | None: Parsed JSON data if successful, None if all recovery attempts fail.
225
+ """
226
+ try:
227
+ return json.loads(json_blob)
228
+ except json.JSONDecodeError as error:
229
+ recovered_payload = recover_concatenated_json_objects(json_blob)
230
+ if recovered_payload is not None:
231
+ return recovered_payload
232
+
233
+ repaired = repair_json_blob(json_blob)
234
+ if repaired:
235
+ try:
236
+ payload = json.loads(repaired)
237
+ except json.JSONDecodeError:
238
+ logger.debug("json_repair returned unrecoverable payload for structured data output.")
239
+ else:
240
+ logger.info(
241
+ "Structured data extractor output repaired via json_repair and parsed successfully. original_error=%s",
242
+ error.msg,
243
+ )
244
+ return payload
245
+ return None
246
+
247
+
248
+ __all__ = [
249
+ "attempt_json_recovery",
250
+ "detect_structured_data_failure",
251
+ "extract_content_after_marker",
252
+ "extract_json_blob",
253
+ "parse_structured_data",
254
+ "payload_reports_empty",
255
+ "payload_reports_error",
256
+ "structured_data_failure_for_call",
257
+ ]
@@ -0,0 +1,86 @@
1
+ from aip_agents.tools.browser_use.types import ToolCallInfo
2
+ from collections.abc import Callable, Sequence
3
+ from typing import Any
4
+
5
+ __all__ = ['attempt_json_recovery', 'detect_structured_data_failure', 'extract_content_after_marker', 'extract_json_blob', 'parse_structured_data', 'payload_reports_empty', 'payload_reports_error', 'structured_data_failure_for_call']
6
+
7
+ def detect_structured_data_failure(tool_calls: Sequence[ToolCallInfo], summarize_error: Callable[[str], str]) -> str | None:
8
+ """Return a descriptive error when structured data extraction yields no results.
9
+
10
+ Args:
11
+ tool_calls: Tool call descriptors extracted from the latest agent step.
12
+ summarize_error: Function to summarize error messages.
13
+
14
+ Returns:
15
+ str | None: Failure reason when extraction yielded nothing, otherwise None.
16
+ """
17
+ def structured_data_failure_for_call(call: ToolCallInfo, summarize_error: Callable[[str], str]) -> str | None:
18
+ """Evaluate a single tool call for extractor failures.
19
+
20
+ Args:
21
+ call: Tool call descriptor encapsulating name/args/output.
22
+ summarize_error: Function to summarize error messages.
23
+
24
+ Returns:
25
+ str | None: Failure message when the call represents a bad extraction.
26
+ """
27
+ def payload_reports_error(payload: dict[str, Any], raw_output: str, summarize_error: Callable[[str], str]) -> str | None:
28
+ """Return a formatted error message when extractor status indicates failure.
29
+
30
+ Args:
31
+ payload: Parsed JSON payload emitted by the extractor.
32
+ raw_output: Original extractor output (used for fallback summaries).
33
+ summarize_error: Function to summarize error messages.
34
+
35
+ Returns:
36
+ str | None: Human-readable failure string when extraction failed.
37
+ """
38
+ def payload_reports_empty(payload: dict[str, Any], raw_output: str, summarize_error: Callable[[str], str]) -> str | None:
39
+ """Return a formatted message when the extractor returned no usable data.
40
+
41
+ Args:
42
+ payload: Parsed JSON payload emitted by the extractor.
43
+ raw_output: Original extractor output string.
44
+ summarize_error: Function to summarize error messages.
45
+
46
+ Returns:
47
+ str | None: Human-readable failure message when no content was extracted.
48
+ """
49
+ def parse_structured_data(output: str, summarize_error: Callable[[str], str]) -> tuple[dict[str, Any] | list[Any] | None, str | None]:
50
+ """Extract the JSON blob emitted by extract_structured_data if present.
51
+
52
+ Args:
53
+ output: Raw string payload returned by extract_structured_data.
54
+ summarize_error: Function to summarize error messages.
55
+
56
+ Returns:
57
+ tuple[dict[str, Any] | list[Any] | None, str | None]: Parsed JSON payload when extraction succeeds,
58
+ otherwise a tuple containing None and a diagnostic string on failure.
59
+ """
60
+ def extract_content_after_marker(output: str) -> str | None:
61
+ """Extract content after the 'Extracted Content:' marker and clean trailing metadata.
62
+
63
+ Args:
64
+ output: Raw string payload returned by extract_structured_data.
65
+
66
+ Returns:
67
+ str | None: Cleaned content after the marker, or None if marker not found.
68
+ """
69
+ def extract_json_blob(content: str) -> str | None:
70
+ """Extract the JSON blob from content by finding delimiters and trimming trailing content.
71
+
72
+ Args:
73
+ content: Content string potentially containing JSON.
74
+
75
+ Returns:
76
+ str | None: Extracted JSON blob, or None if no valid JSON delimiters found.
77
+ """
78
+ def attempt_json_recovery(json_blob: str) -> dict[str, Any] | list[Any] | None:
79
+ """Attempt to parse JSON blob, with recovery strategies for common issues.
80
+
81
+ Args:
82
+ json_blob: JSON string to attempt parsing.
83
+
84
+ Returns:
85
+ dict[str, Any] | list[Any] | None: Parsed JSON data if successful, None if all recovery attempts fail.
86
+ """
@@ -0,0 +1,204 @@
1
+ """Utilities for recovering malformed structured-data payloads emitted by browser-use.
2
+
3
+ Authors:
4
+ Raymond Christopher (raymond.christopher@gdplabs.id)
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from typing import Any
11
+
12
+ from json_repair import repair_json
13
+
14
+ from aip_agents.utils.logger import get_logger
15
+
16
+ logger = get_logger(__name__)
17
+
18
+
19
+ def recover_concatenated_json_objects(json_blob: str) -> dict[str, Any] | None:
20
+ """Normalize concatenated JSON object strings into a structured payload.
21
+
22
+ Args:
23
+ json_blob: Raw JSON-like string returned by the structured data extractor.
24
+
25
+ Returns:
26
+ dict[str, Any] | None: Standardized payload when multiple objects are recovered,
27
+ otherwise None.
28
+ """
29
+ segments = _split_top_level_json_objects(json_blob)
30
+ if len(segments) <= 1:
31
+ return None
32
+
33
+ try:
34
+ records = [json.loads(segment) for segment in segments]
35
+ except json.JSONDecodeError:
36
+ return None
37
+
38
+ count = len(records)
39
+ logger.info("Structured data extractor returned concatenated JSON objects. recovered=%s", count)
40
+ return {
41
+ "status": "ok",
42
+ "items": records,
43
+ "products": records,
44
+ "count": count,
45
+ "products_found": count,
46
+ "available": bool(records),
47
+ }
48
+
49
+
50
+ def repair_json_blob(json_blob: str) -> str | None:
51
+ """Apply json_repair to malformed JSON strings and return the mutated payload.
52
+
53
+ Args:
54
+ json_blob: Raw JSON string that may contain syntax mistakes.
55
+
56
+ Returns:
57
+ str | None: Repaired JSON string when modifications were applied, otherwise None.
58
+ """
59
+ try:
60
+ repaired = repair_json(json_blob)
61
+ except Exception:
62
+ logger.debug("json_repair failed to repair structured data output.", exc_info=True)
63
+ return None
64
+
65
+ if not repaired or repaired == json_blob:
66
+ return None
67
+
68
+ return repaired
69
+
70
+
71
+ def _split_top_level_json_objects(json_blob: str) -> list[str]:
72
+ """Split concatenated JSON objects while respecting string literals.
73
+
74
+ Args:
75
+ json_blob: The JSON string containing concatenated objects to split.
76
+ """
77
+ splitter = _JsonObjectSplitter(json_blob)
78
+ return splitter.split_objects()
79
+
80
+
81
+ def _has_only_separators(value: str) -> bool:
82
+ """Return True when the substring only contains whitespace or commas.
83
+
84
+ Args:
85
+ value: The string to check for separators only.
86
+ """
87
+ return value.strip(" \t\r\n,") == ""
88
+
89
+
90
+ class _JsonObjectSplitter:
91
+ """Helper class to split JSON objects with reduced cognitive complexity."""
92
+
93
+ def __init__(self, json_blob: str) -> None:
94
+ """Initialize the splitter with the raw JSON string.
95
+
96
+ Args:
97
+ json_blob: Raw string potentially containing concatenated JSON objects.
98
+ """
99
+ self.json_blob = json_blob
100
+ self.segments: list[str] = []
101
+ self.depth = 0
102
+ self.start: int | None = None
103
+ self.last_end = 0
104
+ self.in_string = False
105
+ self.escaping = False
106
+
107
+ def split_objects(self) -> list[str]:
108
+ """Main method to split JSON objects."""
109
+ if not self._parse_characters():
110
+ return []
111
+
112
+ if not self._validate_final_state():
113
+ return []
114
+
115
+ return self.segments
116
+
117
+ def _parse_characters(self) -> bool:
118
+ """Parse each character and build segments. Returns False if invalid."""
119
+ for index, char in enumerate(self.json_blob):
120
+ if not self._process_character(char, index):
121
+ return False
122
+ return True
123
+
124
+ def _process_character(self, char: str, index: int) -> bool:
125
+ """Process a single character. Returns False if parsing should stop.
126
+
127
+ Args:
128
+ char: The character to process.
129
+ index: The position of the character in the JSON blob.
130
+
131
+ Returns:
132
+ True if processing should continue, False if parsing should stop.
133
+ """
134
+ if self.escaping:
135
+ self.escaping = False
136
+ return True
137
+
138
+ if char == "\\":
139
+ self.escaping = True
140
+ return True
141
+
142
+ if char == '"':
143
+ self.in_string = not self.in_string
144
+ return True
145
+
146
+ if self.in_string:
147
+ return True
148
+
149
+ return self._process_non_string_char(char, index)
150
+
151
+ def _process_non_string_char(self, char: str, index: int) -> bool:
152
+ """Process characters outside of strings.
153
+
154
+ Args:
155
+ char: The character to process (not in a string).
156
+ index: The position of the character in the JSON blob.
157
+
158
+ Returns:
159
+ True if processing should continue, False if invalid structure found.
160
+ """
161
+ if char == "{":
162
+ return self._handle_open_brace(index)
163
+ if char == "}":
164
+ return self._handle_close_brace(index)
165
+ return True
166
+
167
+ def _handle_open_brace(self, index: int) -> bool:
168
+ """Handle opening brace character.
169
+
170
+ Args:
171
+ index: The position of the opening brace in the JSON blob.
172
+
173
+ Returns:
174
+ True if brace should be processed, False if invalid separators found.
175
+ """
176
+ if self.depth == 0:
177
+ if not _has_only_separators(self.json_blob[self.last_end : index]):
178
+ return False
179
+ self.start = index
180
+ self.depth += 1
181
+ return True
182
+
183
+ def _handle_close_brace(self, index: int) -> bool:
184
+ """Handle closing brace character.
185
+
186
+ Args:
187
+ index: The position of the closing brace in the JSON blob.
188
+
189
+ Returns:
190
+ Always True as closing braces don't cause parsing failures.
191
+ """
192
+ self.depth -= 1
193
+ if self.depth == 0 and self.start is not None:
194
+ end = index + 1
195
+ self.segments.append(self.json_blob[self.start : end])
196
+ self.last_end = end
197
+ return True
198
+
199
+ def _validate_final_state(self) -> bool:
200
+ """Validate that parsing completed successfully."""
201
+ if self.depth != 0 or self.in_string:
202
+ return False
203
+
204
+ return _has_only_separators(self.json_blob[self.last_end :])
@@ -0,0 +1,43 @@
1
+ from _typeshed import Incomplete
2
+ from aip_agents.utils.logger import get_logger as get_logger
3
+ from typing import Any
4
+
5
+ logger: Incomplete
6
+
7
+ def recover_concatenated_json_objects(json_blob: str) -> dict[str, Any] | None:
8
+ """Normalize concatenated JSON object strings into a structured payload.
9
+
10
+ Args:
11
+ json_blob: Raw JSON-like string returned by the structured data extractor.
12
+
13
+ Returns:
14
+ dict[str, Any] | None: Standardized payload when multiple objects are recovered,
15
+ otherwise None.
16
+ """
17
+ def repair_json_blob(json_blob: str) -> str | None:
18
+ """Apply json_repair to malformed JSON strings and return the mutated payload.
19
+
20
+ Args:
21
+ json_blob: Raw JSON string that may contain syntax mistakes.
22
+
23
+ Returns:
24
+ str | None: Repaired JSON string when modifications were applied, otherwise None.
25
+ """
26
+
27
+ class _JsonObjectSplitter:
28
+ """Helper class to split JSON objects with reduced cognitive complexity."""
29
+ json_blob: Incomplete
30
+ segments: list[str]
31
+ depth: int
32
+ start: int | None
33
+ last_end: int
34
+ in_string: bool
35
+ escaping: bool
36
+ def __init__(self, json_blob: str) -> None:
37
+ """Initialize the splitter with the raw JSON string.
38
+
39
+ Args:
40
+ json_blob: Raw string potentially containing concatenated JSON objects.
41
+ """
42
+ def split_objects(self) -> list[str]:
43
+ """Main method to split JSON objects."""