aip-agents-binary 0.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of aip-agents-binary might be problematic. Click here for more details.
- aip_agents/__init__.py +65 -0
- aip_agents/__init__.pyi +19 -0
- aip_agents/a2a/__init__.py +19 -0
- aip_agents/a2a/__init__.pyi +3 -0
- aip_agents/a2a/server/__init__.py +10 -0
- aip_agents/a2a/server/__init__.pyi +4 -0
- aip_agents/a2a/server/base_executor.py +1086 -0
- aip_agents/a2a/server/base_executor.pyi +73 -0
- aip_agents/a2a/server/google_adk_executor.py +198 -0
- aip_agents/a2a/server/google_adk_executor.pyi +51 -0
- aip_agents/a2a/server/langflow_executor.py +180 -0
- aip_agents/a2a/server/langflow_executor.pyi +43 -0
- aip_agents/a2a/server/langgraph_executor.py +270 -0
- aip_agents/a2a/server/langgraph_executor.pyi +47 -0
- aip_agents/a2a/types.py +232 -0
- aip_agents/a2a/types.pyi +132 -0
- aip_agents/agent/__init__.py +27 -0
- aip_agents/agent/__init__.pyi +9 -0
- aip_agents/agent/base_agent.py +970 -0
- aip_agents/agent/base_agent.pyi +221 -0
- aip_agents/agent/base_langgraph_agent.py +3037 -0
- aip_agents/agent/base_langgraph_agent.pyi +233 -0
- aip_agents/agent/google_adk_agent.py +926 -0
- aip_agents/agent/google_adk_agent.pyi +141 -0
- aip_agents/agent/google_adk_constants.py +6 -0
- aip_agents/agent/google_adk_constants.pyi +3 -0
- aip_agents/agent/hitl/__init__.py +24 -0
- aip_agents/agent/hitl/__init__.pyi +6 -0
- aip_agents/agent/hitl/config.py +28 -0
- aip_agents/agent/hitl/config.pyi +15 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.pyi +42 -0
- aip_agents/agent/hitl/manager.py +532 -0
- aip_agents/agent/hitl/manager.pyi +200 -0
- aip_agents/agent/hitl/models.py +18 -0
- aip_agents/agent/hitl/models.pyi +3 -0
- aip_agents/agent/hitl/prompt/__init__.py +9 -0
- aip_agents/agent/hitl/prompt/__init__.pyi +4 -0
- aip_agents/agent/hitl/prompt/base.py +42 -0
- aip_agents/agent/hitl/prompt/base.pyi +24 -0
- aip_agents/agent/hitl/prompt/deferred.py +73 -0
- aip_agents/agent/hitl/prompt/deferred.pyi +30 -0
- aip_agents/agent/hitl/registry.py +149 -0
- aip_agents/agent/hitl/registry.pyi +101 -0
- aip_agents/agent/interface.py +138 -0
- aip_agents/agent/interface.pyi +81 -0
- aip_agents/agent/interfaces.py +65 -0
- aip_agents/agent/interfaces.pyi +44 -0
- aip_agents/agent/langflow_agent.py +464 -0
- aip_agents/agent/langflow_agent.pyi +133 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.py +767 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +50 -0
- aip_agents/agent/langgraph_react_agent.py +2856 -0
- aip_agents/agent/langgraph_react_agent.pyi +170 -0
- aip_agents/agent/system_instruction_context.py +34 -0
- aip_agents/agent/system_instruction_context.pyi +13 -0
- aip_agents/clients/__init__.py +10 -0
- aip_agents/clients/__init__.pyi +4 -0
- aip_agents/clients/langflow/__init__.py +10 -0
- aip_agents/clients/langflow/__init__.pyi +4 -0
- aip_agents/clients/langflow/client.py +477 -0
- aip_agents/clients/langflow/client.pyi +140 -0
- aip_agents/clients/langflow/types.py +18 -0
- aip_agents/clients/langflow/types.pyi +7 -0
- aip_agents/constants.py +23 -0
- aip_agents/constants.pyi +7 -0
- aip_agents/credentials/manager.py +132 -0
- aip_agents/examples/__init__.py +5 -0
- aip_agents/examples/__init__.pyi +0 -0
- aip_agents/examples/compare_streaming_client.py +783 -0
- aip_agents/examples/compare_streaming_client.pyi +48 -0
- aip_agents/examples/compare_streaming_server.py +142 -0
- aip_agents/examples/compare_streaming_server.pyi +18 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
- aip_agents/examples/hello_world_a2a_langchain_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
- aip_agents/examples/hello_world_a2a_langflow_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
- aip_agents/examples/hello_world_a2a_langflow_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +16 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +15 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +45 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_google_adk.py +41 -0
- aip_agents/examples/hello_world_google_adk.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_stream.py +44 -0
- aip_agents/examples/hello_world_google_adk_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain.py +28 -0
- aip_agents/examples/hello_world_langchain.pyi +5 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.pyi +16 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.pyi +18 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream.py +36 -0
- aip_agents/examples/hello_world_langchain_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_langflow_agent.py +163 -0
- aip_agents/examples/hello_world_langflow_agent.pyi +35 -0
- aip_agents/examples/hello_world_langgraph.py +39 -0
- aip_agents/examples/hello_world_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream.py +43 -0
- aip_agents/examples/hello_world_langgraph_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_model_switch_cli.py +210 -0
- aip_agents/examples/hello_world_model_switch_cli.pyi +30 -0
- aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
- aip_agents/examples/hello_world_multi_agent_adk.pyi +6 -0
- aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
- aip_agents/examples/hello_world_multi_agent_langchain.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_pii_logger.py +21 -0
- aip_agents/examples/hello_world_pii_logger.pyi +5 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_sentry.py +133 -0
- aip_agents/examples/hello_world_sentry.pyi +21 -0
- aip_agents/examples/hello_world_step_limits.py +273 -0
- aip_agents/examples/hello_world_step_limits.pyi +17 -0
- aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
- aip_agents/examples/hello_world_stock_a2a_server.pyi +17 -0
- aip_agents/examples/hello_world_tool_output_client.py +55 -0
- aip_agents/examples/hello_world_tool_output_client.pyi +5 -0
- aip_agents/examples/hello_world_tool_output_server.py +114 -0
- aip_agents/examples/hello_world_tool_output_server.pyi +19 -0
- aip_agents/examples/hitl_demo.py +724 -0
- aip_agents/examples/hitl_demo.pyi +67 -0
- aip_agents/examples/mcp_configs/configs.py +63 -0
- aip_agents/examples/mcp_servers/common.py +76 -0
- aip_agents/examples/mcp_servers/mcp_name.py +29 -0
- aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
- aip_agents/examples/mcp_servers/mcp_time.py +10 -0
- aip_agents/examples/pii_demo_langgraph_client.py +69 -0
- aip_agents/examples/pii_demo_langgraph_client.pyi +5 -0
- aip_agents/examples/pii_demo_langgraph_server.py +126 -0
- aip_agents/examples/pii_demo_langgraph_server.pyi +20 -0
- aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
- aip_agents/examples/pii_demo_multi_agent_client.pyi +5 -0
- aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
- aip_agents/examples/pii_demo_multi_agent_server.pyi +40 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.pyi +19 -0
- aip_agents/examples/tools/__init__.py +27 -0
- aip_agents/examples/tools/__init__.pyi +9 -0
- aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
- aip_agents/examples/tools/adk_arithmetic_tools.pyi +24 -0
- aip_agents/examples/tools/adk_weather_tool.py +60 -0
- aip_agents/examples/tools/adk_weather_tool.pyi +18 -0
- aip_agents/examples/tools/data_generator_tool.py +103 -0
- aip_agents/examples/tools/data_generator_tool.pyi +15 -0
- aip_agents/examples/tools/data_visualization_tool.py +312 -0
- aip_agents/examples/tools/data_visualization_tool.pyi +19 -0
- aip_agents/examples/tools/image_artifact_tool.py +136 -0
- aip_agents/examples/tools/image_artifact_tool.pyi +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.pyi +17 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +20 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +25 -0
- aip_agents/examples/tools/langchain_weather_tool.py +48 -0
- aip_agents/examples/tools/langchain_weather_tool.pyi +19 -0
- aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
- aip_agents/examples/tools/langgraph_streaming_tool.pyi +43 -0
- aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
- aip_agents/examples/tools/mock_retrieval_tool.pyi +13 -0
- aip_agents/examples/tools/pii_demo_tools.py +189 -0
- aip_agents/examples/tools/pii_demo_tools.pyi +54 -0
- aip_agents/examples/tools/random_chart_tool.py +142 -0
- aip_agents/examples/tools/random_chart_tool.pyi +20 -0
- aip_agents/examples/tools/serper_tool.py +202 -0
- aip_agents/examples/tools/serper_tool.pyi +16 -0
- aip_agents/examples/tools/stock_tools.py +82 -0
- aip_agents/examples/tools/stock_tools.pyi +36 -0
- aip_agents/examples/tools/table_generator_tool.py +167 -0
- aip_agents/examples/tools/table_generator_tool.pyi +22 -0
- aip_agents/examples/tools/time_tool.py +82 -0
- aip_agents/examples/tools/time_tool.pyi +15 -0
- aip_agents/examples/tools/weather_forecast_tool.py +38 -0
- aip_agents/examples/tools/weather_forecast_tool.pyi +14 -0
- aip_agents/executor/agent_executor.py +473 -0
- aip_agents/executor/base.py +48 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/__init__.pyi +6 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/__init__.pyi +4 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/base.pyi +61 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/nemo.pyi +46 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/exceptions.pyi +23 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/manager.pyi +42 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/middleware.pyi +87 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/schemas.pyi +43 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/guardrails/utils.pyi +19 -0
- aip_agents/mcp/__init__.py +1 -0
- aip_agents/mcp/__init__.pyi +0 -0
- aip_agents/mcp/client/__init__.py +14 -0
- aip_agents/mcp/client/__init__.pyi +5 -0
- aip_agents/mcp/client/base_mcp_client.py +369 -0
- aip_agents/mcp/client/base_mcp_client.pyi +148 -0
- aip_agents/mcp/client/connection_manager.py +228 -0
- aip_agents/mcp/client/connection_manager.pyi +51 -0
- aip_agents/mcp/client/google_adk/__init__.py +11 -0
- aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
- aip_agents/mcp/client/google_adk/client.py +381 -0
- aip_agents/mcp/client/google_adk/client.pyi +75 -0
- aip_agents/mcp/client/langchain/__init__.py +11 -0
- aip_agents/mcp/client/langchain/__init__.pyi +3 -0
- aip_agents/mcp/client/langchain/client.py +265 -0
- aip_agents/mcp/client/langchain/client.pyi +48 -0
- aip_agents/mcp/client/persistent_session.py +612 -0
- aip_agents/mcp/client/persistent_session.pyi +122 -0
- aip_agents/mcp/client/session_pool.py +351 -0
- aip_agents/mcp/client/session_pool.pyi +101 -0
- aip_agents/mcp/client/transports.py +263 -0
- aip_agents/mcp/client/transports.pyi +132 -0
- aip_agents/mcp/utils/__init__.py +7 -0
- aip_agents/mcp/utils/__init__.pyi +0 -0
- aip_agents/mcp/utils/config_validator.py +139 -0
- aip_agents/mcp/utils/config_validator.pyi +82 -0
- aip_agents/memory/__init__.py +14 -0
- aip_agents/memory/__init__.pyi +5 -0
- aip_agents/memory/adapters/__init__.py +10 -0
- aip_agents/memory/adapters/__init__.pyi +4 -0
- aip_agents/memory/adapters/base_adapter.py +811 -0
- aip_agents/memory/adapters/base_adapter.pyi +176 -0
- aip_agents/memory/adapters/mem0.py +84 -0
- aip_agents/memory/adapters/mem0.pyi +22 -0
- aip_agents/memory/base.py +84 -0
- aip_agents/memory/base.pyi +60 -0
- aip_agents/memory/constants.py +49 -0
- aip_agents/memory/constants.pyi +25 -0
- aip_agents/memory/factory.py +86 -0
- aip_agents/memory/factory.pyi +24 -0
- aip_agents/memory/guidance.py +20 -0
- aip_agents/memory/guidance.pyi +3 -0
- aip_agents/memory/simple_memory.py +47 -0
- aip_agents/memory/simple_memory.pyi +23 -0
- aip_agents/middleware/__init__.py +17 -0
- aip_agents/middleware/__init__.pyi +5 -0
- aip_agents/middleware/base.py +96 -0
- aip_agents/middleware/base.pyi +75 -0
- aip_agents/middleware/manager.py +150 -0
- aip_agents/middleware/manager.pyi +84 -0
- aip_agents/middleware/todolist.py +274 -0
- aip_agents/middleware/todolist.pyi +125 -0
- aip_agents/ptc/__init__.py +48 -0
- aip_agents/ptc/__init__.pyi +10 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +39 -0
- aip_agents/ptc/exceptions.pyi +22 -0
- aip_agents/ptc/executor.py +143 -0
- aip_agents/ptc/executor.pyi +73 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/__init__.pyi +7 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +668 -0
- aip_agents/ptc/mcp/sandbox_bridge.pyi +47 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/__init__.pyi +0 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +239 -0
- aip_agents/ptc/naming.py +184 -0
- aip_agents/ptc/naming.pyi +76 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +571 -0
- aip_agents/ptc/prompt_builder.pyi +55 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +58 -0
- aip_agents/ptc/sandbox_bridge.pyi +25 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/template_utils.pyi +13 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/__init__.pyi +0 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +9 -0
- aip_agents/sandbox/defaults.pyi +2 -0
- aip_agents/sandbox/e2b_runtime.py +267 -0
- aip_agents/sandbox/e2b_runtime.pyi +51 -0
- aip_agents/sandbox/template_builder.py +131 -0
- aip_agents/sandbox/template_builder.pyi +36 -0
- aip_agents/sandbox/types.py +24 -0
- aip_agents/sandbox/types.pyi +14 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/sandbox/validation.pyi +20 -0
- aip_agents/schema/__init__.py +69 -0
- aip_agents/schema/__init__.pyi +9 -0
- aip_agents/schema/a2a.py +56 -0
- aip_agents/schema/a2a.pyi +40 -0
- aip_agents/schema/agent.py +111 -0
- aip_agents/schema/agent.pyi +65 -0
- aip_agents/schema/hitl.py +157 -0
- aip_agents/schema/hitl.pyi +89 -0
- aip_agents/schema/langgraph.py +37 -0
- aip_agents/schema/langgraph.pyi +28 -0
- aip_agents/schema/model_id.py +97 -0
- aip_agents/schema/model_id.pyi +54 -0
- aip_agents/schema/step_limit.py +108 -0
- aip_agents/schema/step_limit.pyi +63 -0
- aip_agents/schema/storage.py +40 -0
- aip_agents/schema/storage.pyi +21 -0
- aip_agents/sentry/__init__.py +11 -0
- aip_agents/sentry/__init__.pyi +3 -0
- aip_agents/sentry/sentry.py +151 -0
- aip_agents/sentry/sentry.pyi +48 -0
- aip_agents/storage/__init__.py +41 -0
- aip_agents/storage/__init__.pyi +8 -0
- aip_agents/storage/base.py +85 -0
- aip_agents/storage/base.pyi +58 -0
- aip_agents/storage/clients/__init__.py +12 -0
- aip_agents/storage/clients/__init__.pyi +3 -0
- aip_agents/storage/clients/minio_client.py +318 -0
- aip_agents/storage/clients/minio_client.pyi +137 -0
- aip_agents/storage/config.py +62 -0
- aip_agents/storage/config.pyi +29 -0
- aip_agents/storage/providers/__init__.py +15 -0
- aip_agents/storage/providers/__init__.pyi +5 -0
- aip_agents/storage/providers/base.py +106 -0
- aip_agents/storage/providers/base.pyi +88 -0
- aip_agents/storage/providers/memory.py +114 -0
- aip_agents/storage/providers/memory.pyi +79 -0
- aip_agents/storage/providers/object_storage.py +214 -0
- aip_agents/storage/providers/object_storage.pyi +98 -0
- aip_agents/tools/__init__.py +64 -0
- aip_agents/tools/__init__.pyi +11 -0
- aip_agents/tools/browser_use/__init__.py +82 -0
- aip_agents/tools/browser_use/__init__.pyi +14 -0
- aip_agents/tools/browser_use/action_parser.py +103 -0
- aip_agents/tools/browser_use/action_parser.pyi +18 -0
- aip_agents/tools/browser_use/browser_use_tool.py +1120 -0
- aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
- aip_agents/tools/browser_use/llm_config.py +120 -0
- aip_agents/tools/browser_use/llm_config.pyi +52 -0
- aip_agents/tools/browser_use/minio_storage.py +198 -0
- aip_agents/tools/browser_use/minio_storage.pyi +109 -0
- aip_agents/tools/browser_use/schemas.py +119 -0
- aip_agents/tools/browser_use/schemas.pyi +32 -0
- aip_agents/tools/browser_use/session.py +76 -0
- aip_agents/tools/browser_use/session.pyi +4 -0
- aip_agents/tools/browser_use/session_errors.py +132 -0
- aip_agents/tools/browser_use/session_errors.pyi +53 -0
- aip_agents/tools/browser_use/steel_session_recording.py +317 -0
- aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
- aip_agents/tools/browser_use/streaming.py +815 -0
- aip_agents/tools/browser_use/streaming.pyi +81 -0
- aip_agents/tools/browser_use/structured_data_parser.py +257 -0
- aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
- aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
- aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
- aip_agents/tools/browser_use/types.py +78 -0
- aip_agents/tools/browser_use/types.pyi +45 -0
- aip_agents/tools/code_sandbox/__init__.py +26 -0
- aip_agents/tools/code_sandbox/__init__.pyi +3 -0
- aip_agents/tools/code_sandbox/constant.py +13 -0
- aip_agents/tools/code_sandbox/constant.pyi +4 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +306 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +102 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
- aip_agents/tools/constants.py +177 -0
- aip_agents/tools/constants.pyi +138 -0
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/date_range_tool.pyi +21 -0
- aip_agents/tools/document_loader/__init__.py +44 -0
- aip_agents/tools/document_loader/__init__.pyi +7 -0
- aip_agents/tools/document_loader/base_reader.py +302 -0
- aip_agents/tools/document_loader/base_reader.pyi +75 -0
- aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
- aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
- aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
- aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
- aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
- aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
- aip_agents/tools/document_loader/pdf_splitter.py +169 -0
- aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
- aip_agents/tools/execute_ptc_code.py +308 -0
- aip_agents/tools/execute_ptc_code.pyi +90 -0
- aip_agents/tools/gl_connector/__init__.py +5 -0
- aip_agents/tools/gl_connector/__init__.pyi +3 -0
- aip_agents/tools/gl_connector/tool.py +383 -0
- aip_agents/tools/gl_connector/tool.pyi +74 -0
- aip_agents/tools/gl_connector_tools.py +119 -0
- aip_agents/tools/gl_connector_tools.pyi +39 -0
- aip_agents/tools/memory_search/__init__.py +29 -0
- aip_agents/tools/memory_search/__init__.pyi +5 -0
- aip_agents/tools/memory_search/base.py +200 -0
- aip_agents/tools/memory_search/base.pyi +69 -0
- aip_agents/tools/memory_search/mem0.py +365 -0
- aip_agents/tools/memory_search/mem0.pyi +29 -0
- aip_agents/tools/memory_search/schema.py +81 -0
- aip_agents/tools/memory_search/schema.pyi +25 -0
- aip_agents/tools/memory_search_tool.py +34 -0
- aip_agents/tools/memory_search_tool.pyi +3 -0
- aip_agents/tools/time_tool.py +117 -0
- aip_agents/tools/time_tool.pyi +16 -0
- aip_agents/tools/tool_config_injector.py +300 -0
- aip_agents/tools/tool_config_injector.pyi +26 -0
- aip_agents/tools/web_search/__init__.py +15 -0
- aip_agents/tools/web_search/__init__.pyi +3 -0
- aip_agents/tools/web_search/serper_tool.py +187 -0
- aip_agents/tools/web_search/serper_tool.pyi +19 -0
- aip_agents/types/__init__.py +70 -0
- aip_agents/types/__init__.pyi +36 -0
- aip_agents/types/a2a_events.py +13 -0
- aip_agents/types/a2a_events.pyi +3 -0
- aip_agents/utils/__init__.py +79 -0
- aip_agents/utils/__init__.pyi +11 -0
- aip_agents/utils/a2a_connector.py +1757 -0
- aip_agents/utils/a2a_connector.pyi +146 -0
- aip_agents/utils/artifact_helpers.py +502 -0
- aip_agents/utils/artifact_helpers.pyi +203 -0
- aip_agents/utils/constants.py +22 -0
- aip_agents/utils/constants.pyi +10 -0
- aip_agents/utils/datetime/__init__.py +34 -0
- aip_agents/utils/datetime/__init__.pyi +4 -0
- aip_agents/utils/datetime/normalization.py +231 -0
- aip_agents/utils/datetime/normalization.pyi +95 -0
- aip_agents/utils/datetime/timezone.py +206 -0
- aip_agents/utils/datetime/timezone.pyi +48 -0
- aip_agents/utils/env_loader.py +27 -0
- aip_agents/utils/env_loader.pyi +10 -0
- aip_agents/utils/event_handler_registry.py +58 -0
- aip_agents/utils/event_handler_registry.pyi +23 -0
- aip_agents/utils/file_prompt_utils.py +176 -0
- aip_agents/utils/file_prompt_utils.pyi +21 -0
- aip_agents/utils/final_response_builder.py +211 -0
- aip_agents/utils/final_response_builder.pyi +34 -0
- aip_agents/utils/formatter_llm_client.py +231 -0
- aip_agents/utils/formatter_llm_client.pyi +71 -0
- aip_agents/utils/langgraph/__init__.py +19 -0
- aip_agents/utils/langgraph/__init__.pyi +3 -0
- aip_agents/utils/langgraph/converter.py +128 -0
- aip_agents/utils/langgraph/converter.pyi +49 -0
- aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
- aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1096 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
- aip_agents/utils/langgraph/tool_output_management.py +1047 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +329 -0
- aip_agents/utils/logger.py +195 -0
- aip_agents/utils/logger.pyi +60 -0
- aip_agents/utils/metadata/__init__.py +27 -0
- aip_agents/utils/metadata/__init__.pyi +5 -0
- aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
- aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
- aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
- aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
- aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
- aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
- aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
- aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
- aip_agents/utils/metadata/activity_narrative/context.py +49 -0
- aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
- aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
- aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
- aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
- aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
- aip_agents/utils/metadata/schemas/__init__.py +16 -0
- aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
- aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
- aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
- aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
- aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
- aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
- aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
- aip_agents/utils/metadata_helper.py +358 -0
- aip_agents/utils/metadata_helper.pyi +117 -0
- aip_agents/utils/name_preprocessor/__init__.py +17 -0
- aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
- aip_agents/utils/pii/__init__.py +25 -0
- aip_agents/utils/pii/__init__.pyi +5 -0
- aip_agents/utils/pii/pii_handler.py +397 -0
- aip_agents/utils/pii/pii_handler.pyi +96 -0
- aip_agents/utils/pii/pii_helper.py +207 -0
- aip_agents/utils/pii/pii_helper.pyi +78 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
- aip_agents/utils/reference_helper.py +273 -0
- aip_agents/utils/reference_helper.pyi +81 -0
- aip_agents/utils/sse_chunk_transformer.py +831 -0
- aip_agents/utils/sse_chunk_transformer.pyi +166 -0
- aip_agents/utils/step_limit_manager.py +265 -0
- aip_agents/utils/step_limit_manager.pyi +112 -0
- aip_agents/utils/token_usage_helper.py +156 -0
- aip_agents/utils/token_usage_helper.pyi +60 -0
- aip_agents_binary-0.6.4.dist-info/METADATA +673 -0
- aip_agents_binary-0.6.4.dist-info/RECORD +612 -0
- aip_agents_binary-0.6.4.dist-info/WHEEL +5 -0
- aip_agents_binary-0.6.4.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."""
|