aip-agents-binary 0.0.0__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.
- aip_agents/__init__.py +66 -0
- aip_agents/a2a/__init__.py +19 -0
- aip_agents/a2a/server/__init__.py +10 -0
- aip_agents/a2a/server/base_executor.py +1125 -0
- aip_agents/a2a/server/google_adk_executor.py +198 -0
- aip_agents/a2a/server/langflow_executor.py +180 -0
- aip_agents/a2a/server/langgraph_executor.py +270 -0
- aip_agents/a2a/types.py +232 -0
- aip_agents/a2ui/__init__.py +26 -0
- aip_agents/a2ui/catalog_provider.py +109 -0
- aip_agents/a2ui/examples/0.8/booking_form.json +1 -0
- aip_agents/a2ui/examples/0.8/confirmation.json +1 -0
- aip_agents/a2ui/examples/0.8/single_column_list.json +1 -0
- aip_agents/a2ui/examples/0.9/booking_form.json +1 -0
- aip_agents/a2ui/examples/0.9/confirmation.json +1 -0
- aip_agents/a2ui/examples/0.9/single_column_list.json +1 -0
- aip_agents/a2ui/middleware.py +754 -0
- aip_agents/a2ui/models.py +153 -0
- aip_agents/a2ui/public_url.py +138 -0
- aip_agents/a2ui/stream_filter.py +67 -0
- aip_agents/agent/__init__.py +72 -0
- aip_agents/agent/base_agent.py +1437 -0
- aip_agents/agent/base_langgraph_agent.py +4048 -0
- aip_agents/agent/google_adk_agent.py +932 -0
- aip_agents/agent/google_adk_constants.py +11 -0
- aip_agents/agent/graph_runtime.py +185 -0
- aip_agents/agent/hitl/__init__.py +24 -0
- aip_agents/agent/hitl/config.py +28 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
- aip_agents/agent/hitl/manager.py +532 -0
- aip_agents/agent/hitl/models.py +18 -0
- aip_agents/agent/hitl/prompt/__init__.py +9 -0
- aip_agents/agent/hitl/prompt/base.py +42 -0
- aip_agents/agent/hitl/prompt/deferred.py +73 -0
- aip_agents/agent/hitl/registry.py +149 -0
- aip_agents/agent/interface.py +138 -0
- aip_agents/agent/interfaces.py +65 -0
- aip_agents/agent/langflow_agent.py +464 -0
- aip_agents/agent/langgraph_react_agent.py +3741 -0
- aip_agents/agent/model_invocation_adapter.py +346 -0
- aip_agents/agent/system_instruction_context.py +34 -0
- aip_agents/agent/tool_execution_engine.py +587 -0
- aip_agents/audio_interface/__init__.py +30 -0
- aip_agents/audio_interface/audio_agent_adapter.py +254 -0
- aip_agents/audio_interface/config.py +146 -0
- aip_agents/audio_interface/errors.py +15 -0
- aip_agents/audio_interface/livekit_audio_session.py +504 -0
- aip_agents/audio_interface/livekit_realtime_audio_session.py +142 -0
- aip_agents/audio_interface/session_factory.py +40 -0
- aip_agents/clients/__init__.py +10 -0
- aip_agents/clients/langflow/__init__.py +10 -0
- aip_agents/clients/langflow/client.py +477 -0
- aip_agents/clients/langflow/types.py +18 -0
- aip_agents/common/__init__.py +5 -0
- aip_agents/common/callable_introspection.py +17 -0
- aip_agents/constants.py +23 -0
- aip_agents/context/__init__.py +5 -0
- aip_agents/context/budget.py +237 -0
- aip_agents/context/compaction.py +339 -0
- aip_agents/context/metadata.py +169 -0
- aip_agents/context/offload.py +449 -0
- aip_agents/context/preparation.py +196 -0
- aip_agents/context/prompt.py +61 -0
- aip_agents/context/runtime.py +149 -0
- aip_agents/context/session_recall.py +69 -0
- aip_agents/context/state.py +48 -0
- aip_agents/context/utils.py +44 -0
- aip_agents/credentials/manager.py +132 -0
- aip_agents/examples/__init__.py +5 -0
- aip_agents/examples/audio_livekit_session.py +116 -0
- aip_agents/examples/compare_streaming_client.py +783 -0
- aip_agents/examples/compare_streaming_server.py +141 -0
- aip_agents/examples/gl_connectors_smoke.py +148 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.py +104 -0
- aip_agents/examples/hello_world_a2a_langchain_server.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +77 -0
- aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
- aip_agents/examples/hello_world_a2a_langflow_server.py +80 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +91 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.py +83 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +78 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +131 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -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_server.py +250 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +79 -0
- aip_agents/examples/hello_world_filesystem.py +162 -0
- aip_agents/examples/hello_world_google_adk.py +41 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_stream.py +44 -0
- aip_agents/examples/hello_world_langchain.py +28 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
- aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
- aip_agents/examples/hello_world_langchain_stream.py +36 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
- aip_agents/examples/hello_world_langflow_agent.py +163 -0
- aip_agents/examples/hello_world_langgraph.py +39 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_skills.py +62 -0
- aip_agents/examples/hello_world_langgraph_stream.py +43 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_model_switch_cli.py +210 -0
- aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
- aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
- aip_agents/examples/hello_world_multi_agent_tool_output_client.py +57 -0
- aip_agents/examples/hello_world_multi_agent_tool_output_server.py +131 -0
- aip_agents/examples/hello_world_pii_logger.py +21 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc_custom_tools.py +83 -0
- aip_agents/examples/hello_world_sentry.py +133 -0
- aip_agents/examples/hello_world_step_limits.py +273 -0
- aip_agents/examples/hello_world_stock_a2a_server.py +100 -0
- aip_agents/examples/hello_world_tool_output_client.py +55 -0
- aip_agents/examples/hello_world_tool_output_server.py +113 -0
- aip_agents/examples/hitl_demo.py +724 -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_server.py +125 -0
- aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
- aip_agents/examples/pii_demo_multi_agent_server.py +246 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +87 -0
- aip_agents/examples/tools/__init__.py +27 -0
- aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
- aip_agents/examples/tools/adk_weather_tool.py +60 -0
- aip_agents/examples/tools/data_generator_tool.py +103 -0
- aip_agents/examples/tools/data_visualization_tool.py +312 -0
- aip_agents/examples/tools/image_artifact_tool.py +136 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
- aip_agents/examples/tools/langchain_weather_tool.py +48 -0
- aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
- aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
- aip_agents/examples/tools/multiply_tool.py +43 -0
- aip_agents/examples/tools/pii_demo_tools.py +189 -0
- aip_agents/examples/tools/random_chart_tool.py +142 -0
- aip_agents/examples/tools/serper_tool.py +202 -0
- aip_agents/examples/tools/stock_tools.py +82 -0
- aip_agents/examples/tools/table_generator_tool.py +167 -0
- aip_agents/examples/tools/time_tool.py +82 -0
- aip_agents/examples/tools/weather_forecast_tool.py +38 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/integration/__init__.py +43 -0
- aip_agents/integration/agent.py +58 -0
- aip_agents/integration/guardrails.py +52 -0
- aip_agents/integration/hitl.py +71 -0
- aip_agents/integration/ptc.py +95 -0
- aip_agents/integration/skills.py +37 -0
- aip_agents/integration/storage.py +81 -0
- aip_agents/integration/version.py +103 -0
- aip_agents/mcp/__init__.py +1 -0
- aip_agents/mcp/client/__init__.py +60 -0
- aip_agents/mcp/client/base_mcp_client.py +377 -0
- aip_agents/mcp/client/connection_manager.py +231 -0
- aip_agents/mcp/client/errors.py +119 -0
- aip_agents/mcp/client/google_adk/__init__.py +45 -0
- aip_agents/mcp/client/google_adk/client.py +383 -0
- aip_agents/mcp/client/langchain/__init__.py +11 -0
- aip_agents/mcp/client/langchain/client.py +265 -0
- aip_agents/mcp/client/persistent_session.py +704 -0
- aip_agents/mcp/client/session_pool.py +358 -0
- aip_agents/mcp/client/transports.py +288 -0
- aip_agents/mcp/utils/__init__.py +7 -0
- aip_agents/mcp/utils/config_validator.py +139 -0
- aip_agents/memory/__init__.py +14 -0
- aip_agents/memory/adapters/__init__.py +10 -0
- aip_agents/memory/adapters/base_adapter.py +815 -0
- aip_agents/memory/adapters/mem0.py +286 -0
- aip_agents/memory/base.py +84 -0
- aip_agents/memory/constants.py +49 -0
- aip_agents/memory/factory.py +86 -0
- aip_agents/memory/guidance.py +20 -0
- aip_agents/memory/simple_memory.py +47 -0
- aip_agents/middleware/__init__.py +65 -0
- aip_agents/middleware/backends/__init__.py +72 -0
- aip_agents/middleware/backends/in_memory.py +578 -0
- aip_agents/middleware/backends/local_disk.py +1203 -0
- aip_agents/middleware/backends/protocol.py +353 -0
- aip_agents/middleware/backends/sandbox.py +1431 -0
- aip_agents/middleware/backends/sandbox_files.py +113 -0
- aip_agents/middleware/backends/utils.py +293 -0
- aip_agents/middleware/base.py +239 -0
- aip_agents/middleware/filesystem.py +690 -0
- aip_agents/middleware/manager.py +291 -0
- aip_agents/middleware/memory.py +532 -0
- aip_agents/middleware/pii_middleware.py +192 -0
- aip_agents/middleware/schema.py +19 -0
- aip_agents/middleware/skills.py +872 -0
- aip_agents/middleware/task_delegation.py +1656 -0
- aip_agents/middleware/todolist.py +276 -0
- aip_agents/middleware/tools/__init__.py +23 -0
- aip_agents/middleware/tools/edit_file.py +70 -0
- aip_agents/middleware/tools/execute.py +428 -0
- aip_agents/middleware/tools/grep_file.py +79 -0
- aip_agents/middleware/tools/ls.py +71 -0
- aip_agents/middleware/tools/read_file.py +239 -0
- aip_agents/middleware/tools/skill_load.py +193 -0
- aip_agents/middleware/tools/skill_resource.py +338 -0
- aip_agents/middleware/tools/write_file.py +114 -0
- aip_agents/middleware/vision.py +322 -0
- aip_agents/ptc/__init__.py +87 -0
- aip_agents/ptc/custom_tools.py +511 -0
- aip_agents/ptc/custom_tools_payload.py +499 -0
- aip_agents/ptc/custom_tools_templates/__init__.py +1 -0
- aip_agents/ptc/custom_tools_templates/custom_build_function.py.template +24 -0
- aip_agents/ptc/custom_tools_templates/custom_init.py.template +26 -0
- aip_agents/ptc/custom_tools_templates/custom_invoke.py.template +149 -0
- aip_agents/ptc/custom_tools_templates/custom_registry.py.template +112 -0
- aip_agents/ptc/custom_tools_templates/custom_sources_init.py.template +7 -0
- aip_agents/ptc/custom_tools_templates/custom_wrapper.py.template +87 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/exceptions.py +57 -0
- aip_agents/ptc/executor.py +627 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +679 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +240 -0
- aip_agents/ptc/naming.py +430 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/prompt_builder.py +674 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/sandbox_bridge.py +297 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/ptc/tool_def_helpers.py +101 -0
- aip_agents/ptc/tool_enrichment.py +163 -0
- aip_agents/resilience/__init__.py +10 -0
- aip_agents/resilience/base.py +46 -0
- aip_agents/resilience/tool.py +1661 -0
- aip_agents/sandbox/__init__.py +62 -0
- aip_agents/sandbox/defaults.py +220 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-1-datasaur.Dockerfile +120 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-1.Dockerfile +100 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-2-datasaur.Dockerfile +143 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-2.Dockerfile +119 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-3-datasaur.Dockerfile +173 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-3.Dockerfile +130 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.Dockerfile +164 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.patch_js_context.py +41 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2-4-runner-managed.requirements.txt +29 -0
- aip_agents/sandbox/dockerfiles/aip-agents-sandbox-v2.Dockerfile +87 -0
- aip_agents/sandbox/e2b_runtime.py +27 -0
- aip_agents/sandbox/image_registry.py +98 -0
- aip_agents/sandbox/providers/__init__.py +76 -0
- aip_agents/sandbox/providers/base.py +392 -0
- aip_agents/sandbox/providers/bedrock.py +28 -0
- aip_agents/sandbox/providers/e2b.py +230 -0
- aip_agents/sandbox/providers/opensandbox.py +163 -0
- aip_agents/sandbox/sandbox_runtime.py +967 -0
- aip_agents/sandbox/template_builder.py +240 -0
- aip_agents/sandbox/types.py +141 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/schema/__init__.py +106 -0
- aip_agents/schema/a2a.py +58 -0
- aip_agents/schema/agent.py +117 -0
- aip_agents/schema/artifacts.py +75 -0
- aip_agents/schema/attachments.py +425 -0
- aip_agents/schema/hitl.py +157 -0
- aip_agents/schema/langgraph.py +47 -0
- aip_agents/schema/model_id.py +103 -0
- aip_agents/schema/model_usage.py +50 -0
- aip_agents/schema/runtime_metadata.py +78 -0
- aip_agents/schema/step_limit.py +108 -0
- aip_agents/schema/storage.py +40 -0
- aip_agents/schema/tool_payloads.py +68 -0
- aip_agents/sentry/__init__.py +11 -0
- aip_agents/sentry/sentry.py +267 -0
- aip_agents/skills/__init__.py +30 -0
- aip_agents/skills/errors.py +110 -0
- aip_agents/skills/installer.py +479 -0
- aip_agents/skills/models.py +769 -0
- aip_agents/skills/stager.py +224 -0
- aip_agents/skills/validation.py +53 -0
- aip_agents/storage/__init__.py +41 -0
- aip_agents/storage/base.py +85 -0
- aip_agents/storage/clients/__init__.py +12 -0
- aip_agents/storage/clients/minio_client.py +318 -0
- aip_agents/storage/config.py +62 -0
- aip_agents/storage/providers/__init__.py +15 -0
- aip_agents/storage/providers/base.py +106 -0
- aip_agents/storage/providers/memory.py +114 -0
- aip_agents/storage/providers/object_storage.py +214 -0
- aip_agents/tools/__init__.py +65 -0
- aip_agents/tools/agent_schedule_tool.py +392 -0
- aip_agents/tools/browser_use/__init__.py +83 -0
- aip_agents/tools/browser_use/action_parser.py +104 -0
- aip_agents/tools/browser_use/browser_use_tool.py +1118 -0
- aip_agents/tools/browser_use/llm_config.py +120 -0
- aip_agents/tools/browser_use/minio_storage.py +203 -0
- aip_agents/tools/browser_use/schemas.py +121 -0
- aip_agents/tools/browser_use/session.py +13 -0
- aip_agents/tools/browser_use/session_errors.py +132 -0
- aip_agents/tools/browser_use/steel_session_recording.py +321 -0
- aip_agents/tools/browser_use/streaming.py +263 -0
- aip_agents/tools/browser_use/structured_data_parser.py +257 -0
- aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
- aip_agents/tools/browser_use/types.py +37 -0
- aip_agents/tools/code_sandbox/__init__.py +48 -0
- aip_agents/tools/code_sandbox/code_sandbox_tool.py +350 -0
- aip_agents/tools/code_sandbox/constant.py +13 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +346 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +65 -0
- aip_agents/tools/computer_use/__init__.py +75 -0
- aip_agents/tools/computer_use/computer_use_tool.py +910 -0
- aip_agents/tools/computer_use/schemas.py +78 -0
- aip_agents/tools/computer_use/streaming.py +198 -0
- aip_agents/tools/computer_use/types.py +32 -0
- aip_agents/tools/constants.py +177 -0
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/document_loader/__init__.py +44 -0
- aip_agents/tools/document_loader/base_reader.py +302 -0
- aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
- aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
- aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
- aip_agents/tools/document_loader/pdf_splitter.py +169 -0
- aip_agents/tools/execute_ptc_code.py +582 -0
- aip_agents/tools/gl_connector/__init__.py +5 -0
- aip_agents/tools/gl_connector/tool.py +518 -0
- aip_agents/tools/gl_connector_tools.py +170 -0
- aip_agents/tools/memory_search/__init__.py +29 -0
- aip_agents/tools/memory_search/base.py +213 -0
- aip_agents/tools/memory_search/mem0.py +424 -0
- aip_agents/tools/memory_search/schema.py +81 -0
- aip_agents/tools/memory_search_tool.py +34 -0
- aip_agents/tools/streaming_common.py +577 -0
- aip_agents/tools/time_tool.py +117 -0
- aip_agents/tools/tool_config_injector.py +300 -0
- aip_agents/tools/web_search/__init__.py +15 -0
- aip_agents/tools/web_search/serper_tool.py +187 -0
- aip_agents/types/__init__.py +73 -0
- aip_agents/types/a2a_events.py +13 -0
- aip_agents/utils/__init__.py +91 -0
- aip_agents/utils/a2a_connector.py +1758 -0
- aip_agents/utils/artifact_helpers.py +542 -0
- aip_agents/utils/artifacts/__init__.py +20 -0
- aip_agents/utils/artifacts/tracker.py +367 -0
- aip_agents/utils/attachment_helpers.py +178 -0
- aip_agents/utils/constants.py +22 -0
- aip_agents/utils/datetime/__init__.py +34 -0
- aip_agents/utils/datetime/normalization.py +231 -0
- aip_agents/utils/datetime/timezone.py +206 -0
- aip_agents/utils/env_loader.py +27 -0
- aip_agents/utils/event_handler_registry.py +58 -0
- aip_agents/utils/file_prompt_utils.py +276 -0
- aip_agents/utils/file_watchers/__init__.py +33 -0
- aip_agents/utils/file_watchers/base.py +46 -0
- aip_agents/utils/file_watchers/e2b.py +128 -0
- aip_agents/utils/file_watchers/factory.py +39 -0
- aip_agents/utils/file_watchers/ls_diff.py +88 -0
- aip_agents/utils/file_watchers/sandbox.py +66 -0
- aip_agents/utils/file_watchers/watchdog.py +97 -0
- aip_agents/utils/final_response_builder.py +211 -0
- aip_agents/utils/formatter_llm_client.py +258 -0
- aip_agents/utils/langgraph/__init__.py +19 -0
- aip_agents/utils/langgraph/converter.py +399 -0
- aip_agents/utils/langgraph/delegation_context.py +22 -0
- aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1329 -0
- aip_agents/utils/langgraph/tool_output_management.py +1047 -0
- aip_agents/utils/logger.py +195 -0
- aip_agents/utils/metadata/__init__.py +27 -0
- aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
- aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
- aip_agents/utils/metadata/activity_narrative/builder.py +822 -0
- aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
- aip_agents/utils/metadata/activity_narrative/context.py +49 -0
- aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
- aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
- aip_agents/utils/metadata/schemas/__init__.py +16 -0
- aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
- aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
- aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
- aip_agents/utils/metadata_helper.py +363 -0
- aip_agents/utils/name_preprocessor/__init__.py +17 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
- aip_agents/utils/pii/__init__.py +29 -0
- aip_agents/utils/pii/pii_handler.py +555 -0
- aip_agents/utils/pii/pii_helper.py +225 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
- aip_agents/utils/reference_helper.py +273 -0
- aip_agents/utils/sse_chunk_transformer.py +836 -0
- aip_agents/utils/step_limit_manager.py +265 -0
- aip_agents/utils/token_usage_helper.py +531 -0
- aip_agents_binary-0.0.0.dist-info/METADATA +825 -0
- aip_agents_binary-0.0.0.dist-info/RECORD +447 -0
- aip_agents_binary-0.0.0.dist-info/WHEEL +5 -0
- aip_agents_binary-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Helpers for configuring browser-use LLM instances and environment flags.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from browser_use.llm import ChatOpenAI
|
|
13
|
+
from browser_use.logging_config import setup_logging
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def model_disallows_tunable_params(model: Any) -> bool:
|
|
17
|
+
"""Return True if the provider forbids temperature/frequency overrides for the model.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
model: The model name or identifier to check.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
bool: True if the model disallows tunable parameters, False otherwise.
|
|
24
|
+
"""
|
|
25
|
+
model_name = str(model).lower()
|
|
26
|
+
|
|
27
|
+
if model_name.startswith("gpt-5"):
|
|
28
|
+
return True
|
|
29
|
+
|
|
30
|
+
short_name = model_name.split("-", 1)[0]
|
|
31
|
+
return short_name.startswith("o") and short_name[1:].isdigit()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def supports_temperature_override(model: Any) -> bool:
|
|
35
|
+
"""Return True when the given model supports setting a custom temperature.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
model: The model name or identifier to check.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
bool: True if the model supports temperature override, False otherwise.
|
|
42
|
+
"""
|
|
43
|
+
return not model_disallows_tunable_params(model)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def supports_frequency_penalty(model: Any) -> bool:
|
|
47
|
+
"""Return True when the given model supports custom frequency penalties.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
model: The model name or identifier to check.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
bool: True if the model supports frequency penalty override, False otherwise.
|
|
54
|
+
"""
|
|
55
|
+
return not model_disallows_tunable_params(model)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def build_browser_use_llm(
|
|
59
|
+
*,
|
|
60
|
+
model: Any,
|
|
61
|
+
reasoning_effort: Any,
|
|
62
|
+
temperature: float | None,
|
|
63
|
+
api_key: str,
|
|
64
|
+
base_url: str | None = None,
|
|
65
|
+
) -> ChatOpenAI:
|
|
66
|
+
"""Construct a ChatOpenAI instance with browser-use specific safeguards.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
model: The model name or identifier to use.
|
|
70
|
+
reasoning_effort: The reasoning effort level for the model.
|
|
71
|
+
temperature: Optional temperature setting for the model. Can be None.
|
|
72
|
+
api_key: The API key for authentication.
|
|
73
|
+
base_url: The base URL for the model.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
ChatOpenAI: The configured ChatOpenAI instance.
|
|
77
|
+
"""
|
|
78
|
+
llm_kwargs: dict[str, Any] = {
|
|
79
|
+
"model": model,
|
|
80
|
+
"reasoning_effort": reasoning_effort,
|
|
81
|
+
"api_key": api_key,
|
|
82
|
+
"base_url": base_url,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if temperature is not None and supports_temperature_override(model):
|
|
86
|
+
llm_kwargs["temperature"] = temperature
|
|
87
|
+
else:
|
|
88
|
+
llm_kwargs["temperature"] = None
|
|
89
|
+
|
|
90
|
+
if not supports_frequency_penalty(model):
|
|
91
|
+
llm_kwargs["frequency_penalty"] = None
|
|
92
|
+
|
|
93
|
+
return ChatOpenAI(**llm_kwargs)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def configure_browser_use_environment(enable_cloud_sync: bool, logging_level: str) -> None:
|
|
97
|
+
"""Ensure Browser Use environment flags are aligned with tool configuration.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
enable_cloud_sync: Whether to enable cloud synchronization for browser sessions.
|
|
101
|
+
logging_level: The desired logging level for browser use operations.
|
|
102
|
+
"""
|
|
103
|
+
desired_sync = "true" if enable_cloud_sync else "false"
|
|
104
|
+
if os.environ.get("BROWSER_USE_CLOUD_SYNC") != desired_sync:
|
|
105
|
+
os.environ["BROWSER_USE_CLOUD_SYNC"] = desired_sync
|
|
106
|
+
|
|
107
|
+
desired_level = logging_level.lower()
|
|
108
|
+
current_level = os.environ.get("BROWSER_USE_LOGGING_LEVEL")
|
|
109
|
+
if not current_level or current_level.lower() != desired_level:
|
|
110
|
+
os.environ["BROWSER_USE_LOGGING_LEVEL"] = desired_level
|
|
111
|
+
setup_logging(log_level=desired_level, force_setup=True)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
__all__ = [
|
|
115
|
+
"build_browser_use_llm",
|
|
116
|
+
"configure_browser_use_environment",
|
|
117
|
+
"model_disallows_tunable_params",
|
|
118
|
+
"supports_frequency_penalty",
|
|
119
|
+
"supports_temperature_override",
|
|
120
|
+
]
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"""MinIO Storage Handler for Steel Session Recording.
|
|
2
|
+
|
|
3
|
+
This module provides MinIO cloud storage functionality for uploading and managing
|
|
4
|
+
video files from Steel session recordings. It handles file uploads, bucket management,
|
|
5
|
+
and presigned URL generation for secure file access.
|
|
6
|
+
|
|
7
|
+
The module supports:
|
|
8
|
+
- Automatic bucket creation and validation
|
|
9
|
+
- Secure file uploads with proper content types
|
|
10
|
+
- Presigned URL generation for temporary file access
|
|
11
|
+
- Directory prefix support for organized storage
|
|
12
|
+
- Comprehensive error handling and logging
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
Reinhart Linanda (reinhart.linanda@gdplabs.id)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import mimetypes
|
|
19
|
+
import os
|
|
20
|
+
|
|
21
|
+
from dotenv import load_dotenv
|
|
22
|
+
from minio import Minio
|
|
23
|
+
from minio.error import S3Error
|
|
24
|
+
|
|
25
|
+
load_dotenv()
|
|
26
|
+
|
|
27
|
+
OBJECT_NAME_PREFIX = "steel-recordings/"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MinIOStorage:
|
|
31
|
+
"""Handles MinIO cloud storage operations for video files.
|
|
32
|
+
|
|
33
|
+
This class provides a complete interface for MinIO operations including:
|
|
34
|
+
- Connection management with authentication
|
|
35
|
+
- Bucket existence validation and creation
|
|
36
|
+
- File upload with proper metadata
|
|
37
|
+
- Presigned URL generation for secure access
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
endpoint: MinIO server endpoint URL.
|
|
41
|
+
access_key: MinIO access key for authentication.
|
|
42
|
+
secret_key: MinIO secret key for authentication.
|
|
43
|
+
secure: Whether to use HTTPS/TLS for connections.
|
|
44
|
+
bucket_name: Target bucket for file storage.
|
|
45
|
+
directory_prefix: Optional directory prefix for organized storage.
|
|
46
|
+
client: MinIO client instance for API operations.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self):
|
|
50
|
+
"""Initialize MinIO storage with configuration from environment variables.
|
|
51
|
+
|
|
52
|
+
Reads configuration from the following environment variables:
|
|
53
|
+
- OBJECT_STORAGE_URL: MinIO server endpoint
|
|
54
|
+
- OBJECT_STORAGE_USER: MinIO access key
|
|
55
|
+
- OBJECT_STORAGE_PASSWORD: MinIO secret key
|
|
56
|
+
- OBJECT_STORAGE_SECURE: Whether to use HTTPS (default: False)
|
|
57
|
+
- OBJECT_STORAGE_BUCKET: Target bucket name
|
|
58
|
+
- OBJECT_STORAGE_DIRECTORY_PREFIX: Optional directory prefix
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
ValueError: If required environment variables are missing.
|
|
62
|
+
Exception: If bucket creation or validation fails.
|
|
63
|
+
|
|
64
|
+
Note:
|
|
65
|
+
The method automatically ensures the target bucket exists,
|
|
66
|
+
creating it if necessary.
|
|
67
|
+
"""
|
|
68
|
+
self.endpoint = os.getenv("OBJECT_STORAGE_URL")
|
|
69
|
+
self.access_key = os.getenv("OBJECT_STORAGE_USER")
|
|
70
|
+
self.secret_key = os.getenv("OBJECT_STORAGE_PASSWORD")
|
|
71
|
+
self.secure = os.getenv("OBJECT_STORAGE_SECURE", "False").lower() == "true"
|
|
72
|
+
self.bucket_name = os.getenv("OBJECT_STORAGE_BUCKET")
|
|
73
|
+
self.directory_prefix = os.getenv("OBJECT_STORAGE_DIRECTORY_PREFIX")
|
|
74
|
+
|
|
75
|
+
if not all([self.endpoint, self.access_key, self.secret_key, self.bucket_name]):
|
|
76
|
+
raise ValueError(
|
|
77
|
+
"MinIO configuration incomplete. Set OBJECT_STORAGE_URL, OBJECT_STORAGE_USER, OBJECT_STORAGE_PASSWORD,"
|
|
78
|
+
"and OBJECT_STORAGE_BUCKET."
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
self.client = Minio(
|
|
82
|
+
self.endpoint,
|
|
83
|
+
access_key=self.access_key,
|
|
84
|
+
secret_key=self.secret_key,
|
|
85
|
+
secure=self.secure,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Ensure bucket exists
|
|
89
|
+
self._ensure_bucket_exists()
|
|
90
|
+
|
|
91
|
+
def _ensure_bucket_exists(self) -> None:
|
|
92
|
+
"""Ensure the configured bucket exists, create if it doesn't.
|
|
93
|
+
|
|
94
|
+
This method checks if the target bucket exists and creates it if necessary.
|
|
95
|
+
It's called during initialization to ensure the storage is ready for use.
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
Exception: If bucket creation or validation fails.
|
|
99
|
+
|
|
100
|
+
Note:
|
|
101
|
+
Bucket creation failures are logged as warnings but don't prevent
|
|
102
|
+
the class from being usable (existing buckets can still be accessed).
|
|
103
|
+
"""
|
|
104
|
+
try:
|
|
105
|
+
if not self.client.bucket_exists(self.bucket_name):
|
|
106
|
+
self.client.make_bucket(self.bucket_name)
|
|
107
|
+
except S3Error as e:
|
|
108
|
+
raise Exception(f"Warning: Could not ensure bucket exists: {e}") from e
|
|
109
|
+
|
|
110
|
+
def get_object_name(self, object_name: str) -> str:
|
|
111
|
+
"""Get the object name with the directory prefix.
|
|
112
|
+
|
|
113
|
+
This method constructs the full object path by combining the directory
|
|
114
|
+
prefix with the base object name. It ensures consistent path structure
|
|
115
|
+
for all stored files.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
object_name: Name of the object in MinIO.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
str: Object name with the directory prefix and steel-recordings subdirectory.
|
|
122
|
+
Format: {prefix}/steel-recordings/{object_name} or steel-recordings/{object_name}
|
|
123
|
+
|
|
124
|
+
Note:
|
|
125
|
+
The method automatically adds a "steel-recordings" subdirectory to
|
|
126
|
+
organize video files separately from other content.
|
|
127
|
+
"""
|
|
128
|
+
object_name = f"{OBJECT_NAME_PREFIX}{object_name}"
|
|
129
|
+
if self.directory_prefix:
|
|
130
|
+
return f"{self.directory_prefix}/{object_name}"
|
|
131
|
+
return object_name
|
|
132
|
+
|
|
133
|
+
def upload_file(self, file_path: str, object_name: str) -> None:
|
|
134
|
+
"""Upload a file to MinIO bucket.
|
|
135
|
+
|
|
136
|
+
This method handles the complete file upload process including:
|
|
137
|
+
- File existence validation
|
|
138
|
+
- Proper content type setting for video files
|
|
139
|
+
- Error handling and logging
|
|
140
|
+
- Structured object naming with prefixes
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
file_path: Local path to the file to upload.
|
|
144
|
+
object_name: Name to use for the object in MinIO.
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
Exception: If the file doesn't exist or upload fails.
|
|
148
|
+
Specific S3Error details are included in the exception message.
|
|
149
|
+
|
|
150
|
+
Note:
|
|
151
|
+
Content type is derived from the file extension (e.g. .mp4 -> video/mp4,
|
|
152
|
+
.webm -> video/webm). Falls back to video/webm if detection fails.
|
|
153
|
+
"""
|
|
154
|
+
try:
|
|
155
|
+
if not os.path.exists(file_path):
|
|
156
|
+
raise Exception(f"File not found: {file_path}")
|
|
157
|
+
|
|
158
|
+
content_type, _ = mimetypes.guess_type(file_path)
|
|
159
|
+
if content_type is None or not content_type.startswith("video/"):
|
|
160
|
+
content_type = "video/webm"
|
|
161
|
+
|
|
162
|
+
# Upload the file
|
|
163
|
+
self.client.fput_object(
|
|
164
|
+
self.bucket_name,
|
|
165
|
+
self.get_object_name(object_name),
|
|
166
|
+
file_path,
|
|
167
|
+
content_type=content_type,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
except S3Error as e:
|
|
171
|
+
raise Exception(f"Error uploading to MinIO: {e}") from e
|
|
172
|
+
except Exception as e:
|
|
173
|
+
raise Exception(f"Unexpected error during upload: {e}") from e
|
|
174
|
+
|
|
175
|
+
def get_file_url(self, object_name: str) -> str:
|
|
176
|
+
"""Generate a presigned URL for accessing the uploaded file.
|
|
177
|
+
|
|
178
|
+
This method creates a temporary, secure URL that allows access to the
|
|
179
|
+
uploaded file without requiring MinIO credentials. The URL is valid
|
|
180
|
+
for a limited time and provides secure, direct access to the file.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
object_name: Name of the object in MinIO.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
str: Presigned URL for secure file access.
|
|
187
|
+
The URL includes authentication tokens and is valid for a limited time.
|
|
188
|
+
|
|
189
|
+
Raises:
|
|
190
|
+
Exception: If presigned URL generation fails.
|
|
191
|
+
S3Error details are included in the exception message.
|
|
192
|
+
|
|
193
|
+
Note:
|
|
194
|
+
Presigned URLs are useful for sharing files temporarily without
|
|
195
|
+
exposing MinIO credentials or requiring users to have storage access.
|
|
196
|
+
"""
|
|
197
|
+
try:
|
|
198
|
+
return self.client.presigned_get_object(
|
|
199
|
+
self.bucket_name,
|
|
200
|
+
self.get_object_name(object_name),
|
|
201
|
+
)
|
|
202
|
+
except S3Error as e:
|
|
203
|
+
raise Exception(f"Error generating presigned URL: {e}") from e
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Configuration schemas for Browser Use tool.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Reinhart Linanda (reinhart.linanda@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from openai.types.shared.chat_model import ChatModel
|
|
11
|
+
from openai.types.shared.reasoning_effort import ReasoningEffort
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BrowserUseToolInput(BaseModel):
|
|
16
|
+
"""Input schema for Browser Use tool."""
|
|
17
|
+
|
|
18
|
+
task: str = Field(..., description="Task prompt for the AI agent to execute in the browser")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class BrowserUseToolConfig(BaseModel):
|
|
22
|
+
"""Tool configuration schema for Browser Use tool."""
|
|
23
|
+
|
|
24
|
+
steel_api_key: str = Field(
|
|
25
|
+
default_factory=lambda: os.getenv("STEEL_API_KEY"),
|
|
26
|
+
description="Steel API key for Steel access",
|
|
27
|
+
)
|
|
28
|
+
steel_base_url: str = Field(
|
|
29
|
+
default="https://api.steel.dev",
|
|
30
|
+
description="Steel API base URL",
|
|
31
|
+
)
|
|
32
|
+
steel_ws_url: str = Field(
|
|
33
|
+
default="wss://connect.steel.dev",
|
|
34
|
+
description="Steel WebSocket URL for browser connection",
|
|
35
|
+
)
|
|
36
|
+
steel_timeout_in_ms: int = Field(
|
|
37
|
+
default=600_000,
|
|
38
|
+
description="Timeout for Steel operations in milliseconds",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
browser_use_llm_openai_api_key: str = Field(
|
|
42
|
+
default_factory=lambda: os.getenv("OPENAI_API_KEY"),
|
|
43
|
+
description="OpenAI API key for browser-use access",
|
|
44
|
+
)
|
|
45
|
+
browser_use_llm_openai_model: ChatModel | str = Field(
|
|
46
|
+
default="o3",
|
|
47
|
+
description="OpenAI model to use for browser-use agent",
|
|
48
|
+
)
|
|
49
|
+
browser_use_llm_openai_temperature: float | None = Field(
|
|
50
|
+
default=None,
|
|
51
|
+
description="Temperature setting for OpenAI model (None uses provider default)",
|
|
52
|
+
)
|
|
53
|
+
browser_use_llm_openai_reasoning_effort: ReasoningEffort = Field(
|
|
54
|
+
default="low",
|
|
55
|
+
description="Reasoning effort for OpenAI model",
|
|
56
|
+
)
|
|
57
|
+
browser_use_llm_openai_base_url: str | None = Field(
|
|
58
|
+
default=None,
|
|
59
|
+
description="Base URL for OpenAI model (None uses provider default)",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
browser_use_page_extraction_llm_openai_api_key: str = Field(
|
|
63
|
+
default_factory=lambda: os.getenv("OPENAI_API_KEY"),
|
|
64
|
+
description="OpenAI API key for page extraction access",
|
|
65
|
+
)
|
|
66
|
+
browser_use_page_extraction_llm_openai_model: ChatModel | str = Field(
|
|
67
|
+
default="gpt-5-mini",
|
|
68
|
+
description="OpenAI model to use for page extraction",
|
|
69
|
+
)
|
|
70
|
+
browser_use_page_extraction_llm_openai_temperature: float | None = Field(
|
|
71
|
+
default=None,
|
|
72
|
+
description="Temperature setting for OpenAI model (None uses provider default)",
|
|
73
|
+
)
|
|
74
|
+
browser_use_page_extraction_llm_openai_reasoning_effort: ReasoningEffort = Field(
|
|
75
|
+
default="minimal",
|
|
76
|
+
description="Reasoning effort for OpenAI model",
|
|
77
|
+
)
|
|
78
|
+
browser_use_page_extraction_llm_openai_base_url: str | None = Field(
|
|
79
|
+
default=None,
|
|
80
|
+
description="Base URL for OpenAI model (None uses provider default)",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
browser_use_extend_system_message: str | None = Field(
|
|
84
|
+
default=None,
|
|
85
|
+
description="Extend system message for browser-use agent",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
browser_use_vision_detail_level: Literal["auto", "low", "high"] = Field(
|
|
89
|
+
default="auto",
|
|
90
|
+
description="Detail level for vision",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
browser_use_llm_timeout_in_s: int | None = Field(
|
|
94
|
+
default=None,
|
|
95
|
+
description="Timeout for LLM in seconds",
|
|
96
|
+
)
|
|
97
|
+
browser_use_step_timeout_in_s: int = Field(
|
|
98
|
+
default=180,
|
|
99
|
+
description="Timeout for step in seconds",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
browser_use_enable_cloud_sync: bool = Field(
|
|
103
|
+
default=False,
|
|
104
|
+
description="Enable Browser Use cloud sync and telemetry events",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
browser_use_logging_level: Literal["debug", "info", "warning", "error", "result"] = Field(
|
|
108
|
+
default="info",
|
|
109
|
+
description="Logging verbosity for browser-use internals",
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
browser_use_max_session_retries: int = Field(
|
|
113
|
+
default=2,
|
|
114
|
+
ge=0,
|
|
115
|
+
description="How many times to recreate the Steel session after recoverable disconnects.",
|
|
116
|
+
)
|
|
117
|
+
browser_use_session_retry_delay_in_s: float = Field(
|
|
118
|
+
default=3.0,
|
|
119
|
+
ge=0.0,
|
|
120
|
+
description="Delay (in seconds) before attempting to recover from a lost Steel session.",
|
|
121
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Session management for browser-use framework.
|
|
2
|
+
|
|
3
|
+
Uses browser-use's BrowserSession directly. Custom session overrides from
|
|
4
|
+
v0.5.9 (input text handling) were removed as browser-use 0.11+ implements
|
|
5
|
+
that logic in DefaultActionWatchdog.
|
|
6
|
+
|
|
7
|
+
Authors:
|
|
8
|
+
Reinhart Linanda (reinhart.linanda@gdplabs.id)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from browser_use.browser import BrowserSession
|
|
12
|
+
|
|
13
|
+
__all__ = ["BrowserSession"]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""Centralized Steel/browser session error policies used by BrowserUseTool.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from collections.abc import Iterable
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class SessionErrorCategory:
|
|
13
|
+
"""Represents a fatal Steel/browser disconnect classification."""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
markers: tuple[str, ...]
|
|
17
|
+
fatal: bool
|
|
18
|
+
retryable: bool
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_FATAL_SESSION_ERROR_CATEGORIES: tuple[SessionErrorCategory, ...] = (
|
|
22
|
+
SessionErrorCategory(
|
|
23
|
+
name="browser_closed",
|
|
24
|
+
markers=(
|
|
25
|
+
"browser has been closed",
|
|
26
|
+
"target page, context or browser has been closed",
|
|
27
|
+
),
|
|
28
|
+
fatal=True,
|
|
29
|
+
retryable=True,
|
|
30
|
+
),
|
|
31
|
+
SessionErrorCategory(
|
|
32
|
+
name="websocket_disconnect",
|
|
33
|
+
markers=(
|
|
34
|
+
"code=1006",
|
|
35
|
+
"websocket was closed before the connection was established",
|
|
36
|
+
"websocket error",
|
|
37
|
+
),
|
|
38
|
+
fatal=True,
|
|
39
|
+
retryable=True,
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
_WARNING_MARKERS: dict[str, str] = {
|
|
44
|
+
"502 bad gateway": "page_load_warning",
|
|
45
|
+
"page link: about:blank": "blank_page_warning",
|
|
46
|
+
"no webpage content": "blank_page_warning",
|
|
47
|
+
"scroll_into_view_if_needed": "element_interaction_warning",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_FATAL_LOOKUP: dict[str, SessionErrorCategory] = {
|
|
51
|
+
marker.lower(): category for category in _FATAL_SESSION_ERROR_CATEGORIES for marker in category.markers
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def categorize_fatal_message(message: str) -> SessionErrorCategory | None:
|
|
56
|
+
"""Return the fatal session category associated with the given message, if any.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
message: The error message to categorize.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
The SessionErrorCategory if the message matches a fatal error pattern,
|
|
63
|
+
None otherwise.
|
|
64
|
+
"""
|
|
65
|
+
if not message:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
lowered = message.lower()
|
|
69
|
+
for marker, category in _FATAL_LOOKUP.items():
|
|
70
|
+
if marker in lowered:
|
|
71
|
+
return category
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def categorize_warning_message(message: str) -> str | None:
|
|
76
|
+
"""Return the name of a known non-fatal warning when present in the message.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
message: The error message to check for warning patterns.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
The warning name if the message matches a known warning pattern,
|
|
83
|
+
None otherwise.
|
|
84
|
+
"""
|
|
85
|
+
if not message:
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
lowered = message.lower()
|
|
89
|
+
for marker, warning_name in _WARNING_MARKERS.items():
|
|
90
|
+
if marker in lowered:
|
|
91
|
+
return warning_name
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def find_fatal_message(messages: Iterable[str]) -> tuple[str, SessionErrorCategory] | None:
|
|
96
|
+
"""Return the first fatal message detected in the iterable.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
messages: An iterable of error messages to search through.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
A tuple of (message, category) for the first fatal message found,
|
|
103
|
+
None if no fatal messages are detected.
|
|
104
|
+
"""
|
|
105
|
+
for message in messages:
|
|
106
|
+
category = categorize_fatal_message(message)
|
|
107
|
+
if category:
|
|
108
|
+
return message, category
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def is_recoverable_message(message: str) -> bool:
|
|
113
|
+
"""Return True when the message maps to a retryable session disconnect.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
message: The error message to check for recoverability.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
True if the message corresponds to a retryable fatal error,
|
|
120
|
+
False otherwise.
|
|
121
|
+
"""
|
|
122
|
+
category = categorize_fatal_message(message)
|
|
123
|
+
return bool(category and category.retryable)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
__all__ = [
|
|
127
|
+
"SessionErrorCategory",
|
|
128
|
+
"categorize_fatal_message",
|
|
129
|
+
"categorize_warning_message",
|
|
130
|
+
"find_fatal_message",
|
|
131
|
+
"is_recoverable_message",
|
|
132
|
+
]
|