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,28 @@
|
|
|
1
|
+
"""Bedrock AgentCore sandbox provider factory."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from gllm_tools.code_interpreter.code_sandbox.bedrock_agentcore_sandbox import BedrockAgentCoreSandbox
|
|
6
|
+
|
|
7
|
+
from aip_agents.sandbox.providers.base import BaseSandboxProvider, SandboxConfig, SandboxCreateResult
|
|
8
|
+
from aip_agents.utils.logger import get_logger
|
|
9
|
+
|
|
10
|
+
logger = get_logger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BedrockProvider(BaseSandboxProvider):
|
|
14
|
+
"""Bedrock AgentCore sandbox provider."""
|
|
15
|
+
|
|
16
|
+
async def create(self, config: SandboxConfig) -> SandboxCreateResult:
|
|
17
|
+
"""Create a Bedrock AgentCore sandbox."""
|
|
18
|
+
if config.template:
|
|
19
|
+
logger.warning("Bedrock has no template build; ignoring requested template %r", config.template)
|
|
20
|
+
region = os.environ.get("AWS_REGION", "us-east-1")
|
|
21
|
+
sandbox = BedrockAgentCoreSandbox(region=region)
|
|
22
|
+
logger.info("Bedrock sandbox created (region=%s)", region)
|
|
23
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=False)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def create(config: SandboxConfig) -> SandboxCreateResult:
|
|
27
|
+
"""Compatibility wrapper for the old module-level provider factory."""
|
|
28
|
+
return await BedrockProvider().create(config)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""E2B sandbox provider factory.
|
|
2
|
+
|
|
3
|
+
Owns the E2B-specific create flow: create-with-template, transient placement
|
|
4
|
+
retry, the 404 → auto-build → retry sequence, and fail-fast surfacing of real
|
|
5
|
+
template/configuration errors.
|
|
6
|
+
|
|
7
|
+
Env config:
|
|
8
|
+
E2B_API_KEY E2B API key (used unless passed via ``SandboxConfig.api_key``).
|
|
9
|
+
E2B_DOMAIN Optional E2B domain override (used unless passed via ``SandboxConfig.domain``).
|
|
10
|
+
|
|
11
|
+
When auto-build is enabled (``SandboxConfig.auto_build_template``), template
|
|
12
|
+
building additionally uses the image-registry env (``AIP_SANDBOX_IMAGE_REGISTRY`` /
|
|
13
|
+
``AIP_SANDBOX_REGISTRY_AUTH``) — see ``aip_agents.sandbox.image_registry``.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import math
|
|
18
|
+
import os
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from gllm_tools.code_interpreter.code_sandbox.e2b_sandbox import E2BSandbox
|
|
22
|
+
from gllm_tools.code_interpreter.code_sandbox.sandbox import CodeInterpreterSandbox
|
|
23
|
+
|
|
24
|
+
from aip_agents.sandbox import image_registry
|
|
25
|
+
from aip_agents.sandbox.providers.base import (
|
|
26
|
+
BaseSandboxProvider,
|
|
27
|
+
SandboxConfig,
|
|
28
|
+
SandboxCreateResult,
|
|
29
|
+
SandboxPlacementError,
|
|
30
|
+
create_with_placement_retry,
|
|
31
|
+
)
|
|
32
|
+
from aip_agents.sandbox.template_builder import (
|
|
33
|
+
DockerfileNotFoundError,
|
|
34
|
+
ensure_sandbox_template,
|
|
35
|
+
get_sandbox_dockerfile_path,
|
|
36
|
+
)
|
|
37
|
+
from aip_agents.utils.logger import get_logger
|
|
38
|
+
|
|
39
|
+
logger = get_logger(__name__)
|
|
40
|
+
|
|
41
|
+
AUTO_BUILD_TEMPLATE_CREATE_RETRY_ATTEMPTS = 5
|
|
42
|
+
AUTO_BUILD_TEMPLATE_CREATE_RETRY_DELAY_SECONDS = 5.0
|
|
43
|
+
|
|
44
|
+
# E2B provider markers for transient sandbox placement-capacity failures.
|
|
45
|
+
_PLACEMENT_FAILURE_MARKERS = (
|
|
46
|
+
"failed to place sandbox",
|
|
47
|
+
"sandbox placement",
|
|
48
|
+
"placement failed",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def is_placement_failure(error: Exception) -> bool:
|
|
53
|
+
"""Classify transient E2B placement-capacity failures as retryable."""
|
|
54
|
+
message = str(error).lower()
|
|
55
|
+
return any(marker in message for marker in _PLACEMENT_FAILURE_MARKERS)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _normalize_e2b_timeout(execution_timeout: float) -> int:
|
|
59
|
+
"""Normalize E2B timeout values to integer seconds."""
|
|
60
|
+
timeout_seconds = float(execution_timeout)
|
|
61
|
+
if timeout_seconds <= 0:
|
|
62
|
+
return 0
|
|
63
|
+
return math.ceil(timeout_seconds)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _credentials(config: SandboxConfig) -> tuple[str | None, str | None]:
|
|
67
|
+
"""Resolve E2B credentials with explicit values taking precedence over env."""
|
|
68
|
+
api_key = config.api_key if config.api_key is not None else os.environ.get("E2B_API_KEY")
|
|
69
|
+
domain = config.domain if config.domain is not None else os.environ.get("E2B_DOMAIN")
|
|
70
|
+
return api_key, domain
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _create_kwargs(config: SandboxConfig, *, template: str | None = None) -> dict[str, Any]:
|
|
74
|
+
"""Build E2B create kwargs, preserving timeout/domain behavior."""
|
|
75
|
+
api_key, domain = _credentials(config)
|
|
76
|
+
kwargs: dict[str, Any] = {
|
|
77
|
+
"api_key": api_key,
|
|
78
|
+
"domain": domain,
|
|
79
|
+
"timeout": _normalize_e2b_timeout(config.sandbox_timeout),
|
|
80
|
+
}
|
|
81
|
+
if template is not None:
|
|
82
|
+
kwargs["template"] = template
|
|
83
|
+
return kwargs
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class E2BProvider(BaseSandboxProvider):
|
|
87
|
+
"""E2B sandbox provider."""
|
|
88
|
+
|
|
89
|
+
async def create(self, config: SandboxConfig) -> SandboxCreateResult:
|
|
90
|
+
"""Create an E2B sandbox, honoring template/auto-build/fail-fast rules."""
|
|
91
|
+
if config.template:
|
|
92
|
+
return await _create_with_template(config, config.template)
|
|
93
|
+
sandbox = await _create_default(config)
|
|
94
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=False)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
async def create(config: SandboxConfig) -> SandboxCreateResult:
|
|
98
|
+
"""Compatibility wrapper for the old module-level provider factory."""
|
|
99
|
+
return await E2BProvider().create(config)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def _create_default(config: SandboxConfig) -> CodeInterpreterSandbox:
|
|
103
|
+
"""Create a sandbox using the default no-template path with placement retry."""
|
|
104
|
+
domain = _credentials(config)[1]
|
|
105
|
+
sandbox = await create_with_placement_retry(
|
|
106
|
+
lambda: E2BSandbox.create(**_create_kwargs(config)),
|
|
107
|
+
is_placement_failure=is_placement_failure,
|
|
108
|
+
template=None,
|
|
109
|
+
domain=domain,
|
|
110
|
+
timeout_budget_seconds=config.timeout_budget_seconds,
|
|
111
|
+
)
|
|
112
|
+
logger.info("E2B sandbox created (default): %s", _sandbox_identifier(sandbox))
|
|
113
|
+
return sandbox
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
async def _create_with_template(config: SandboxConfig, template: str) -> SandboxCreateResult:
|
|
117
|
+
"""Attempt to create a sandbox using *template*, surfacing failures explicitly."""
|
|
118
|
+
domain = _credentials(config)[1]
|
|
119
|
+
try:
|
|
120
|
+
sandbox = await create_with_placement_retry(
|
|
121
|
+
lambda: E2BSandbox.create(**_create_kwargs(config, template=template)),
|
|
122
|
+
is_placement_failure=is_placement_failure,
|
|
123
|
+
template=template,
|
|
124
|
+
domain=domain,
|
|
125
|
+
timeout_budget_seconds=config.timeout_budget_seconds,
|
|
126
|
+
)
|
|
127
|
+
logger.info("E2B sandbox created: %s", _sandbox_identifier(sandbox))
|
|
128
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=True)
|
|
129
|
+
except Exception as e:
|
|
130
|
+
return await _handle_template_failure(config, template, e)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
async def _handle_template_failure(config: SandboxConfig, template: str, error: Exception) -> SandboxCreateResult:
|
|
134
|
+
"""Decide whether to auto-build or fail fast for template creation errors.
|
|
135
|
+
|
|
136
|
+
Placement failures are propagated as ``SandboxPlacementError``. 404 errors
|
|
137
|
+
trigger auto-build (when enabled). All other template/config errors fail
|
|
138
|
+
fast instead of silently falling back to a default sandbox.
|
|
139
|
+
"""
|
|
140
|
+
if isinstance(error, SandboxPlacementError):
|
|
141
|
+
raise error
|
|
142
|
+
is_not_found = "404" in str(error) or "not found" in str(error).lower()
|
|
143
|
+
if is_not_found and config.auto_build_template:
|
|
144
|
+
logger.info("Template %r not found; attempting to build it automatically", template)
|
|
145
|
+
return await _try_auto_build_and_retry(config, template)
|
|
146
|
+
logger.warning("Template creation failed (%s): %s", template, error)
|
|
147
|
+
raise RuntimeError(f"Template creation failed ({template}): {error}") from error
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
async def _try_auto_build_and_retry(config: SandboxConfig, template: str) -> SandboxCreateResult:
|
|
151
|
+
"""Auto-build *template* and retry sandbox creation, surfacing failures explicitly.
|
|
152
|
+
|
|
153
|
+
Newly built E2B aliases can take a short time to become ready for sandbox
|
|
154
|
+
creation, so retry a few times before surfacing the failure.
|
|
155
|
+
"""
|
|
156
|
+
built = await _auto_build(config, template)
|
|
157
|
+
if not built:
|
|
158
|
+
logger.warning("Auto-build failed for template %r", template)
|
|
159
|
+
raise RuntimeError(f"Template creation failed after auto-build ({template})")
|
|
160
|
+
|
|
161
|
+
domain = _credentials(config)[1]
|
|
162
|
+
last_error: Exception | None = None
|
|
163
|
+
for attempt in range(1, AUTO_BUILD_TEMPLATE_CREATE_RETRY_ATTEMPTS + 1):
|
|
164
|
+
try:
|
|
165
|
+
sandbox = await create_with_placement_retry(
|
|
166
|
+
lambda: E2BSandbox.create(**_create_kwargs(config, template=template)),
|
|
167
|
+
is_placement_failure=is_placement_failure,
|
|
168
|
+
template=template,
|
|
169
|
+
domain=domain,
|
|
170
|
+
timeout_budget_seconds=config.timeout_budget_seconds,
|
|
171
|
+
)
|
|
172
|
+
logger.info("E2B sandbox created after auto-build: %s", _sandbox_identifier(sandbox))
|
|
173
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=True)
|
|
174
|
+
except Exception as e2:
|
|
175
|
+
last_error = e2
|
|
176
|
+
if attempt == AUTO_BUILD_TEMPLATE_CREATE_RETRY_ATTEMPTS:
|
|
177
|
+
break
|
|
178
|
+
logger.info(
|
|
179
|
+
"Template creation not ready after auto-build (%s, attempt %s/%s): %s. Retrying in %.1fs",
|
|
180
|
+
template,
|
|
181
|
+
attempt,
|
|
182
|
+
AUTO_BUILD_TEMPLATE_CREATE_RETRY_ATTEMPTS,
|
|
183
|
+
e2,
|
|
184
|
+
AUTO_BUILD_TEMPLATE_CREATE_RETRY_DELAY_SECONDS,
|
|
185
|
+
)
|
|
186
|
+
await asyncio.sleep(AUTO_BUILD_TEMPLATE_CREATE_RETRY_DELAY_SECONDS)
|
|
187
|
+
|
|
188
|
+
logger.warning("Template creation failed after auto-build (%s): %s", template, last_error)
|
|
189
|
+
raise RuntimeError(f"Template creation failed after auto-build ({template}): {last_error}") from last_error
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
async def _auto_build(config: SandboxConfig, template_id: str) -> bool:
|
|
193
|
+
"""Attempt to build an E2B template that does not exist yet."""
|
|
194
|
+
config_packages = list(config.packages) if config.packages else None
|
|
195
|
+
if image_registry.resolve_image_ref() is not None:
|
|
196
|
+
dockerfile = None
|
|
197
|
+
packages = config_packages
|
|
198
|
+
else:
|
|
199
|
+
dockerfile = _resolve_auto_build_dockerfile(template_id)
|
|
200
|
+
packages = None if dockerfile else config_packages
|
|
201
|
+
loop = asyncio.get_event_loop()
|
|
202
|
+
result = await loop.run_in_executor(
|
|
203
|
+
None,
|
|
204
|
+
lambda: ensure_sandbox_template(
|
|
205
|
+
template_id,
|
|
206
|
+
config.build_base_template,
|
|
207
|
+
packages,
|
|
208
|
+
dockerfile=dockerfile,
|
|
209
|
+
),
|
|
210
|
+
)
|
|
211
|
+
return result is not None
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _resolve_auto_build_dockerfile(template_id: str) -> str | None:
|
|
215
|
+
"""Resolve the packaged Dockerfile path for auto-build."""
|
|
216
|
+
try:
|
|
217
|
+
return str(get_sandbox_dockerfile_path(template_id))
|
|
218
|
+
except DockerfileNotFoundError:
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _sandbox_identifier(sandbox: Any) -> str:
|
|
223
|
+
"""Return a best-effort sandbox identifier across wrapper versions."""
|
|
224
|
+
sandbox_id = getattr(sandbox, "sandbox_id", None)
|
|
225
|
+
if sandbox_id is None:
|
|
226
|
+
nested_sandbox = getattr(sandbox, "sandbox", None)
|
|
227
|
+
sandbox_id = getattr(nested_sandbox, "sandbox_id", None) or getattr(nested_sandbox, "id", None)
|
|
228
|
+
if sandbox_id is None:
|
|
229
|
+
sandbox_id = getattr(sandbox, "id", None)
|
|
230
|
+
return str(sandbox_id or "unknown")
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""OpenSandbox provider factory.
|
|
2
|
+
|
|
3
|
+
Creates an OpenSandbox session from env config, mapping the requested template
|
|
4
|
+
alias to a snapshot name and supplying the boot entrypoint. Transient
|
|
5
|
+
placement-capacity failures (pool acquire/empty) are retried with bounded
|
|
6
|
+
backoff via the shared placement-retry helper, giving OpenSandbox parity with
|
|
7
|
+
the E2B provider. The OpenSandbox SDK is imported lazily so it stays an optional
|
|
8
|
+
dependency.
|
|
9
|
+
|
|
10
|
+
Env config:
|
|
11
|
+
OPENSANDBOX_API_KEY API key for the OpenSandbox server (optional).
|
|
12
|
+
OPENSANDBOX_DOMAIN host:port of the server (required).
|
|
13
|
+
OPENSANDBOX_PROTOCOL "http" | "https" (default "http").
|
|
14
|
+
OPENSANDBOX_ENTRYPOINT Shell-split boot command; defaults to the code-interpreter entrypoint.
|
|
15
|
+
OPENSANDBOX_SERVER_PROXY "1"/"true"/"yes"/"on" enables server-proxy mode (default "true").
|
|
16
|
+
GLCU_OPENSANDBOX_SERVER_PROXY GLCU-specific override for the same flag.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import shlex
|
|
21
|
+
|
|
22
|
+
from gllm_tools.code_interpreter.code_sandbox.opensandbox_sandbox import OpenSandbox
|
|
23
|
+
from gllm_tools.code_interpreter.code_sandbox.sandbox import CodeInterpreterSandbox
|
|
24
|
+
|
|
25
|
+
from aip_agents.sandbox.providers.base import (
|
|
26
|
+
BaseSandboxProvider,
|
|
27
|
+
SandboxConfig,
|
|
28
|
+
SandboxCreateResult,
|
|
29
|
+
SandboxPlacementError,
|
|
30
|
+
create_with_placement_retry,
|
|
31
|
+
)
|
|
32
|
+
from aip_agents.utils.logger import get_logger
|
|
33
|
+
|
|
34
|
+
logger = get_logger(__name__)
|
|
35
|
+
|
|
36
|
+
_DOMAIN_REQUIRED_ERROR = "OPENSANDBOX_DOMAIN is required for the OpenSandbox provider"
|
|
37
|
+
|
|
38
|
+
# OpenSandbox SDK exception types that signal transient placement-capacity
|
|
39
|
+
# failures (the pool could not allocate a sandbox right now). Classified by class
|
|
40
|
+
# name so the optional SDK is not imported at module load. gllm_tools wraps
|
|
41
|
+
# create errors as RuntimeError(...) from <cause>, so the cause chain is walked.
|
|
42
|
+
_RETRYABLE_PLACEMENT_TYPES = frozenset(
|
|
43
|
+
{
|
|
44
|
+
"PoolAcquireFailedException",
|
|
45
|
+
"PoolEmptyException",
|
|
46
|
+
"PoolStateStoreUnavailableException",
|
|
47
|
+
"PoolStateStoreContentionException",
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def is_placement_failure(error: Exception) -> bool:
|
|
53
|
+
"""Classify transient OpenSandbox pool-capacity failures as retryable."""
|
|
54
|
+
candidates = [error]
|
|
55
|
+
cause = error.__cause__
|
|
56
|
+
if cause is not None:
|
|
57
|
+
candidates.append(cause)
|
|
58
|
+
return any(type(candidate).__name__ in _RETRYABLE_PLACEMENT_TYPES for candidate in candidates)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _env_value(*names: str) -> str | None:
|
|
62
|
+
"""Return the first non-empty env value among ``names``."""
|
|
63
|
+
for name in names:
|
|
64
|
+
value = os.environ.get(name)
|
|
65
|
+
if value is not None and value.strip() != "":
|
|
66
|
+
return value
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _resolve_server_proxy() -> bool:
|
|
71
|
+
"""Resolve the server-proxy flag, defaulting to True when unset.
|
|
72
|
+
|
|
73
|
+
Mirrors ``computer_use_tool._resolve_opensandbox_server_proxy`` but defaults
|
|
74
|
+
to True to preserve the OpenSandbox runtime's established behavior.
|
|
75
|
+
"""
|
|
76
|
+
raw = _env_value("GLCU_OPENSANDBOX_SERVER_PROXY", "OPENSANDBOX_SERVER_PROXY")
|
|
77
|
+
if raw is None:
|
|
78
|
+
return True
|
|
79
|
+
return raw.strip().lower() in {"1", "true", "yes", "on"}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _build_create_kwargs(config: SandboxConfig) -> dict:
|
|
83
|
+
"""Resolve OpenSandbox.create() kwargs from config and environment.
|
|
84
|
+
|
|
85
|
+
Unset optional values are omitted so the SDK applies its own defaults
|
|
86
|
+
(api_key, protocol, entrypoint).
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
ValueError: If no domain is configured.
|
|
90
|
+
"""
|
|
91
|
+
domain = config.domain if config.domain is not None else os.environ.get("OPENSANDBOX_DOMAIN")
|
|
92
|
+
if not domain:
|
|
93
|
+
raise ValueError(_DOMAIN_REQUIRED_ERROR)
|
|
94
|
+
|
|
95
|
+
entrypoint_cmd = os.environ.get("OPENSANDBOX_ENTRYPOINT")
|
|
96
|
+
kwargs = {
|
|
97
|
+
"domain": domain,
|
|
98
|
+
"use_server_proxy": _resolve_server_proxy(),
|
|
99
|
+
"api_key": config.api_key if config.api_key is not None else os.environ.get("OPENSANDBOX_API_KEY"),
|
|
100
|
+
"protocol": os.environ.get("OPENSANDBOX_PROTOCOL"),
|
|
101
|
+
"entrypoint": shlex.split(entrypoint_cmd) if entrypoint_cmd else None,
|
|
102
|
+
}
|
|
103
|
+
return {k: v for k, v in kwargs.items() if v is not None}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def _create_with_retry(
|
|
107
|
+
config: SandboxConfig, create_kwargs: dict, *, snapshot_name: str | None
|
|
108
|
+
) -> CodeInterpreterSandbox:
|
|
109
|
+
"""Create an OpenSandbox session with transient placement retry."""
|
|
110
|
+
kwargs = dict(create_kwargs)
|
|
111
|
+
if snapshot_name is not None:
|
|
112
|
+
kwargs["snapshot_name"] = snapshot_name
|
|
113
|
+
return await create_with_placement_retry(
|
|
114
|
+
lambda: OpenSandbox.create(**kwargs),
|
|
115
|
+
is_placement_failure=is_placement_failure,
|
|
116
|
+
template=snapshot_name,
|
|
117
|
+
domain=create_kwargs.get("domain"),
|
|
118
|
+
timeout_budget_seconds=config.timeout_budget_seconds,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class OpenSandboxProvider(BaseSandboxProvider):
|
|
123
|
+
"""OpenSandbox provider."""
|
|
124
|
+
|
|
125
|
+
async def create(self, config: SandboxConfig) -> SandboxCreateResult:
|
|
126
|
+
"""Create an OpenSandbox session, falling back to the default image on snapshot failure.
|
|
127
|
+
|
|
128
|
+
Transient placement-capacity failures are retried (and surface as
|
|
129
|
+
``SandboxPlacementError`` when exhausted). Other snapshot errors fall back
|
|
130
|
+
to the default image, preserving existing behavior.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
config: Provider-neutral create inputs. ``template`` maps to a snapshot name.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The created sandbox plus whether the requested snapshot was used.
|
|
137
|
+
"""
|
|
138
|
+
create_kwargs = _build_create_kwargs(config)
|
|
139
|
+
snapshot_name = config.template
|
|
140
|
+
|
|
141
|
+
if snapshot_name is None:
|
|
142
|
+
sandbox = await _create_with_retry(config, create_kwargs, snapshot_name=None)
|
|
143
|
+
logger.info("OpenSandbox created (default image): %s", sandbox.sandbox_id)
|
|
144
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=False)
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
sandbox = await _create_with_retry(config, create_kwargs, snapshot_name=snapshot_name)
|
|
148
|
+
logger.info("OpenSandbox created (snapshot=%s): %s", snapshot_name, sandbox.sandbox_id)
|
|
149
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=True)
|
|
150
|
+
except SandboxPlacementError:
|
|
151
|
+
raise
|
|
152
|
+
except Exception as e:
|
|
153
|
+
logger.warning(
|
|
154
|
+
"OpenSandbox snapshot %r creation failed (%s); falling back to default image", snapshot_name, e
|
|
155
|
+
)
|
|
156
|
+
sandbox = await _create_with_retry(config, create_kwargs, snapshot_name=None)
|
|
157
|
+
logger.info("OpenSandbox created (default image): %s", sandbox.sandbox_id)
|
|
158
|
+
return SandboxCreateResult(sandbox=sandbox, created_with_template=False)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
async def create(config: SandboxConfig) -> SandboxCreateResult:
|
|
162
|
+
"""Compatibility wrapper for the old module-level provider factory."""
|
|
163
|
+
return await OpenSandboxProvider().create(config)
|