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,350 @@
|
|
|
1
|
+
"""Provider-agnostic code-sandbox tool.
|
|
2
|
+
|
|
3
|
+
Executes Python code in a sandbox selected by ``SANDBOX_PROVIDER`` (or the tool's
|
|
4
|
+
``provider`` field), built entirely on the generic Seam B pieces — ``SandboxRuntime``
|
|
5
|
+
(create/execute/package-install/cleanup) and ``SandboxArtifactWatcher`` (artifact
|
|
6
|
+
detection via ``find -newer``). No backend SDK is referenced directly.
|
|
7
|
+
|
|
8
|
+
Authors:
|
|
9
|
+
Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
|
|
10
|
+
Komang Elang Surya Prawira (komang.e.s.prawira@gdplabs.id)
|
|
11
|
+
benedikus (benedikus.h.tjuatja@gdplabs.id)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
import json
|
|
16
|
+
import os
|
|
17
|
+
import time
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
import pandas as pd
|
|
21
|
+
from gllm_tools.code_interpreter.code_template.models import SandboxProvider
|
|
22
|
+
from langchain_core.tools import BaseTool
|
|
23
|
+
from langgraph.types import Command
|
|
24
|
+
from pydantic import BaseModel, Field
|
|
25
|
+
|
|
26
|
+
from aip_agents.a2a.types import get_mime_type_from_filename
|
|
27
|
+
from aip_agents.sandbox.sandbox_runtime import SandboxRuntime
|
|
28
|
+
from aip_agents.utils.artifact_helpers import ArtifactHandler, create_multiple_artifacts_response
|
|
29
|
+
from aip_agents.utils.file_watchers import SandboxArtifactWatcher
|
|
30
|
+
from aip_agents.utils.logger import get_logger
|
|
31
|
+
|
|
32
|
+
logger = get_logger(__name__)
|
|
33
|
+
|
|
34
|
+
# The data source is uploaded cwd-relative (the runtime uploads with upload_dir="") so it works
|
|
35
|
+
# on any provider, and the df preamble reads the same relative path.
|
|
36
|
+
DATA_FILE = "data.csv"
|
|
37
|
+
# Directory the tool watches for created artifacts (the model writes its outputs here).
|
|
38
|
+
ARTIFACT_OUTPUT_DIR = "/tmp/output" # NOSONAR - sandbox-isolated directory
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CodeSandboxInput(BaseModel):
|
|
42
|
+
"""Input schema for the code-sandbox tool."""
|
|
43
|
+
|
|
44
|
+
code: str = Field(
|
|
45
|
+
...,
|
|
46
|
+
description=(
|
|
47
|
+
"Python code to execute in the sandbox. "
|
|
48
|
+
"If `data_source` is provided, the data will be automatically pre-loaded into "
|
|
49
|
+
"the sandbox as a Pandas DataFrame. "
|
|
50
|
+
"You can access the data directly via a variable named `df`. "
|
|
51
|
+
"The final result must be printed to stdout."
|
|
52
|
+
),
|
|
53
|
+
min_length=1,
|
|
54
|
+
)
|
|
55
|
+
data_source: str | list[dict[str, Any]] | None = Field(
|
|
56
|
+
default=None,
|
|
57
|
+
description=(
|
|
58
|
+
"The data source used during code execution. "
|
|
59
|
+
"It can be a tool output reference (using $tool_output) or raw data. "
|
|
60
|
+
"If the code requires a data source, this field should not be left empty. "
|
|
61
|
+
"When an output reference is available, prioritize the output reference over raw data."
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
timeout: int = Field(default=30, description="Maximum execution time in seconds", ge=1, le=300)
|
|
65
|
+
language: str = Field(default="python", description="Programming language for the sandbox (Python only)")
|
|
66
|
+
additional_packages: list[str] | None = Field(
|
|
67
|
+
default=None,
|
|
68
|
+
description="Additional Python packages to install before execution",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class CodeSandboxTool(BaseTool):
|
|
73
|
+
"""Execute Python code in a provider-agnostic cloud sandbox.
|
|
74
|
+
|
|
75
|
+
Backend is chosen by ``provider`` (falls back to the ``SANDBOX_PROVIDER`` env, then
|
|
76
|
+
``e2b``). Files created during execution under ``/tmp/output`` are returned as artifacts.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
name: str = "code_sandbox_tool"
|
|
80
|
+
description: str = (
|
|
81
|
+
"Useful for executing Python code in a secure cloud sandbox environment. "
|
|
82
|
+
"Input should include the Python code to execute and optional data source, timeout, and packages. "
|
|
83
|
+
"Returns execution results including stdout, stderr, and any errors. "
|
|
84
|
+
"Automatically downloads all files created during execution as artifacts."
|
|
85
|
+
)
|
|
86
|
+
save_output_history: bool = Field(default=True)
|
|
87
|
+
args_schema: type[BaseModel] = CodeSandboxInput
|
|
88
|
+
provider: SandboxProvider | None = Field(
|
|
89
|
+
default=None,
|
|
90
|
+
description="Sandbox backend; defaults to the SANDBOX_PROVIDER env, then 'e2b'.",
|
|
91
|
+
)
|
|
92
|
+
api_key: str | None = Field(
|
|
93
|
+
default=None,
|
|
94
|
+
description="Backend API key override; the selected provider resolves its own env when None.",
|
|
95
|
+
)
|
|
96
|
+
domain: str | None = Field(
|
|
97
|
+
default=None,
|
|
98
|
+
description="Backend domain override (e.g. self-hosted endpoint); provider resolves its own env when None.",
|
|
99
|
+
)
|
|
100
|
+
template: str | None = Field(
|
|
101
|
+
default=None,
|
|
102
|
+
description="Provider-interpreted template alias (E2B) / snapshot name (OpenSandbox); provider default when None.",
|
|
103
|
+
)
|
|
104
|
+
default_additional_packages: list[str] = Field(
|
|
105
|
+
default_factory=lambda: [
|
|
106
|
+
pkg.strip() for pkg in os.getenv("SANDBOX_TOOL_ADDITIONAL_PACKAGES", "").split(",") if pkg.strip()
|
|
107
|
+
],
|
|
108
|
+
description="Default additional packages from environment variable",
|
|
109
|
+
)
|
|
110
|
+
store_final_output: bool = False
|
|
111
|
+
|
|
112
|
+
def _run(
|
|
113
|
+
self,
|
|
114
|
+
code: str,
|
|
115
|
+
data_source: str | list[dict[str, Any]] | None = None,
|
|
116
|
+
timeout: int = 30,
|
|
117
|
+
language: str = "python",
|
|
118
|
+
additional_packages: list[str] | None = None,
|
|
119
|
+
) -> str | dict[str, Any]:
|
|
120
|
+
"""Synchronous wrapper around :meth:`_arun` (runs in a fresh event loop)."""
|
|
121
|
+
loop: asyncio.AbstractEventLoop | None = None
|
|
122
|
+
try:
|
|
123
|
+
loop = asyncio.new_event_loop()
|
|
124
|
+
asyncio.set_event_loop(loop)
|
|
125
|
+
try:
|
|
126
|
+
return loop.run_until_complete(self._arun(code, data_source, timeout, language, additional_packages))
|
|
127
|
+
finally:
|
|
128
|
+
try:
|
|
129
|
+
pending = [t for t in asyncio.all_tasks(loop) if not t.done()]
|
|
130
|
+
for t in pending:
|
|
131
|
+
t.cancel()
|
|
132
|
+
if pending:
|
|
133
|
+
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
|
|
134
|
+
except Exception:
|
|
135
|
+
pass
|
|
136
|
+
try:
|
|
137
|
+
loop.close()
|
|
138
|
+
except Exception:
|
|
139
|
+
pass
|
|
140
|
+
except Exception as e:
|
|
141
|
+
logger.warning(f"Error in synchronous execution wrapper: {str(e)}")
|
|
142
|
+
return self._create_error_result(code, str(e))
|
|
143
|
+
|
|
144
|
+
async def _arun(
|
|
145
|
+
self,
|
|
146
|
+
code: str,
|
|
147
|
+
data_source: str | list[dict[str, Any]] | None = None,
|
|
148
|
+
timeout: int = 30,
|
|
149
|
+
language: str = "python", # noqa: ARG002 - accepted for schema compat; backends are Python-only
|
|
150
|
+
additional_packages: list[str] | None = None,
|
|
151
|
+
) -> str | dict[str, Any]:
|
|
152
|
+
"""Execute code in a provider-selected sandbox and return results + artifacts."""
|
|
153
|
+
runtime: SandboxRuntime | None = None
|
|
154
|
+
watcher: SandboxArtifactWatcher | None = None
|
|
155
|
+
try:
|
|
156
|
+
if isinstance(data_source, str) and data_source.startswith("$tool_output"):
|
|
157
|
+
logger.warning(f"Reference {data_source!r} not resolved! Skipping the code execution.")
|
|
158
|
+
return self._create_error_result(code, f"Reference {data_source!r} not resolved!")
|
|
159
|
+
|
|
160
|
+
files = self._create_files(data_source)
|
|
161
|
+
runtime = self._create_runtime(additional_packages)
|
|
162
|
+
watcher = SandboxArtifactWatcher(runtime)
|
|
163
|
+
|
|
164
|
+
await runtime.execute_command(f"mkdir -p {ARTIFACT_OUTPUT_DIR}")
|
|
165
|
+
await watcher.start(ARTIFACT_OUTPUT_DIR)
|
|
166
|
+
|
|
167
|
+
wrapped_code = self._wrap_code_with_dataframe(code, files is not None)
|
|
168
|
+
start_time = time.time()
|
|
169
|
+
result = await runtime.execute(wrapped_code, timeout=timeout, files=files)
|
|
170
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
171
|
+
|
|
172
|
+
created_files = sorted(await watcher.get_created_files())
|
|
173
|
+
return await self._process_execution_result(runtime, result, code, created_files, duration_ms)
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.error(f"Error executing code in sandbox: {str(e)}")
|
|
177
|
+
return self._create_error_result(code, str(e))
|
|
178
|
+
|
|
179
|
+
finally:
|
|
180
|
+
if watcher is not None:
|
|
181
|
+
try:
|
|
182
|
+
await watcher.stop()
|
|
183
|
+
except Exception as e:
|
|
184
|
+
logger.debug(f"Error stopping artifact watcher: {e}")
|
|
185
|
+
if runtime is not None:
|
|
186
|
+
await runtime.cleanup()
|
|
187
|
+
|
|
188
|
+
def _create_runtime(self, additional_packages: list[str] | None) -> SandboxRuntime:
|
|
189
|
+
"""Build a SandboxRuntime for the configured provider with the requested packages.
|
|
190
|
+
|
|
191
|
+
``api_key``/``domain``/``template`` are forwarded as-is; when None the
|
|
192
|
+
provider applies its own env fallback (e.g. ``E2B_API_KEY``/``E2B_DOMAIN``).
|
|
193
|
+
"""
|
|
194
|
+
packages = self._prepare_packages(additional_packages)
|
|
195
|
+
return SandboxRuntime(
|
|
196
|
+
provider=self.provider,
|
|
197
|
+
api_key=self.api_key or None,
|
|
198
|
+
domain=self.domain,
|
|
199
|
+
template=self.template,
|
|
200
|
+
packages=packages or None,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def _create_files(self, data_source: Command | list[dict[str, Any]] | None) -> dict[str, str] | None:
|
|
204
|
+
"""Convert a tabular data source into a single cwd-relative CSV upload.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
``{DATA_FILE: csv}`` for a non-empty list of dicts, else None.
|
|
208
|
+
"""
|
|
209
|
+
if isinstance(data_source, Command):
|
|
210
|
+
data_source = data_source.update["result"]
|
|
211
|
+
|
|
212
|
+
if not (isinstance(data_source, list) and data_source and all(isinstance(row, dict) for row in data_source)):
|
|
213
|
+
if not data_source:
|
|
214
|
+
logger.info("No data source provided. Ignoring the data source.")
|
|
215
|
+
else:
|
|
216
|
+
logger.warning("Unsupported `data_source` type. Expected a non-empty list of dictionaries. Ignoring.")
|
|
217
|
+
return None
|
|
218
|
+
|
|
219
|
+
try:
|
|
220
|
+
logger.info("Creating a CSV file from the data source to upload to the sandbox...")
|
|
221
|
+
csv_string = pd.DataFrame(data_source).to_csv(index=False)
|
|
222
|
+
return {DATA_FILE: csv_string}
|
|
223
|
+
except Exception as e:
|
|
224
|
+
logger.warning(f"Error creating files from data source: {str(e)}. Ignoring the data source.")
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
@staticmethod
|
|
228
|
+
def _wrap_code_with_dataframe(code: str, has_data: bool) -> str:
|
|
229
|
+
"""Prepend the ``df`` preload when a data file was uploaded (cwd-relative path)."""
|
|
230
|
+
if not has_data:
|
|
231
|
+
return code
|
|
232
|
+
return f"import pandas as pd\ndf = pd.read_csv({DATA_FILE!r})\n{code}"
|
|
233
|
+
|
|
234
|
+
def _prepare_packages(self, additional_packages: list[str] | None) -> list[str]:
|
|
235
|
+
"""Combine the default packages with the per-call ones, de-duplicated."""
|
|
236
|
+
all_packages = list(self.default_additional_packages) + (additional_packages or [])
|
|
237
|
+
return list(dict.fromkeys(all_packages))
|
|
238
|
+
|
|
239
|
+
@staticmethod
|
|
240
|
+
def _result_to_dict(result: Any, code: str, duration_ms: int) -> dict[str, Any]:
|
|
241
|
+
"""Map a ``SandboxExecutionResult`` to the tool's result dict.
|
|
242
|
+
|
|
243
|
+
``SandboxExecutionResult`` folds the error into ``stderr``; ``status`` is derived
|
|
244
|
+
from ``exit_code`` and ``duration_ms`` is measured by the tool.
|
|
245
|
+
"""
|
|
246
|
+
failed = result.exit_code != 0
|
|
247
|
+
return {
|
|
248
|
+
"status": "error" if failed else "success",
|
|
249
|
+
"code": code,
|
|
250
|
+
"stdout": result.stdout,
|
|
251
|
+
"stderr": result.stderr,
|
|
252
|
+
"error": result.stderr if failed else "",
|
|
253
|
+
"duration_ms": duration_ms,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
def _create_error_result(self, code: str, error_message: str, duration_ms: int = 0) -> str:
|
|
257
|
+
"""Create a standardized JSON error result."""
|
|
258
|
+
return json.dumps(
|
|
259
|
+
{
|
|
260
|
+
"status": "error",
|
|
261
|
+
"code": code,
|
|
262
|
+
"stdout": "",
|
|
263
|
+
"stderr": "",
|
|
264
|
+
"error": error_message,
|
|
265
|
+
"duration_ms": duration_ms,
|
|
266
|
+
},
|
|
267
|
+
indent=2,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
async def _process_execution_result(
|
|
271
|
+
self,
|
|
272
|
+
runtime: SandboxRuntime,
|
|
273
|
+
result: Any,
|
|
274
|
+
code: str,
|
|
275
|
+
created_files: list[str],
|
|
276
|
+
duration_ms: int,
|
|
277
|
+
) -> str | dict[str, Any]:
|
|
278
|
+
"""Build the JSON result, and an artifacts response when files were created."""
|
|
279
|
+
result_dict = self._result_to_dict(result, code, duration_ms)
|
|
280
|
+
|
|
281
|
+
if not created_files:
|
|
282
|
+
result_dict["message"] = "No new files were created during execution"
|
|
283
|
+
return json.dumps(result_dict, indent=2)
|
|
284
|
+
|
|
285
|
+
downloaded_artifacts = await self._create_artifacts_from_files(runtime, created_files)
|
|
286
|
+
if downloaded_artifacts:
|
|
287
|
+
execution_summary = self._create_execution_summary(result_dict, created_files)
|
|
288
|
+
return create_multiple_artifacts_response(result=execution_summary, artifacts=downloaded_artifacts)
|
|
289
|
+
|
|
290
|
+
logger.warning("Files were detected but could not be downloaded")
|
|
291
|
+
return json.dumps(result_dict, indent=2)
|
|
292
|
+
|
|
293
|
+
async def _create_artifacts_from_files(self, runtime: SandboxRuntime, file_paths: list[str]) -> list[dict[str, Any]]:
|
|
294
|
+
"""Download each created file and turn it into an artifact dict."""
|
|
295
|
+
artifacts: list[dict[str, Any]] = []
|
|
296
|
+
try:
|
|
297
|
+
for file_path in file_paths:
|
|
298
|
+
logger.debug(f"Processing newly created file: {file_path}")
|
|
299
|
+
artifact_dict = await self._download_and_create_artifact(runtime, file_path)
|
|
300
|
+
if artifact_dict:
|
|
301
|
+
artifacts.append(artifact_dict)
|
|
302
|
+
except Exception as e:
|
|
303
|
+
logger.error(f"Error creating artifacts from files: {str(e)}")
|
|
304
|
+
return artifacts
|
|
305
|
+
|
|
306
|
+
async def _download_and_create_artifact(self, runtime: SandboxRuntime, file_path: str) -> dict[str, Any] | None:
|
|
307
|
+
"""Download a single file via the runtime and create an artifact."""
|
|
308
|
+
try:
|
|
309
|
+
file_content = await runtime.download_file(file_path)
|
|
310
|
+
if file_content is None:
|
|
311
|
+
logger.warning(f"Failed to download file: {file_path}")
|
|
312
|
+
return None
|
|
313
|
+
|
|
314
|
+
filename = self._extract_filename(file_path)
|
|
315
|
+
artifact_response = ArtifactHandler().create_file_artifact(
|
|
316
|
+
result=f"File created during execution: {file_path}",
|
|
317
|
+
artifact_data=file_content,
|
|
318
|
+
artifact_name=filename,
|
|
319
|
+
artifact_description=f"File created during execution: {file_path}",
|
|
320
|
+
enable_deduplication=False,
|
|
321
|
+
)
|
|
322
|
+
logger.info(f"Successfully downloaded newly created file: {file_path} ({len(file_content)} bytes)")
|
|
323
|
+
return artifact_response["artifact"]
|
|
324
|
+
except Exception as e:
|
|
325
|
+
logger.warning(f"Failed to download file {file_path}: {str(e)}")
|
|
326
|
+
return None
|
|
327
|
+
|
|
328
|
+
def _create_execution_summary(self, result_dict: dict[str, Any], created_files: list[str]) -> str:
|
|
329
|
+
"""Create a markdown execution summary listing the downloaded files."""
|
|
330
|
+
execution_summary = f"Code executed successfully (status: {result_dict['status']}).\n"
|
|
331
|
+
if result_dict["stdout"]:
|
|
332
|
+
execution_summary += f"Output: {result_dict['stdout']}\n"
|
|
333
|
+
execution_summary += f"Downloaded {len(created_files)} file(s) created during execution:\n\n"
|
|
334
|
+
|
|
335
|
+
for file_path in created_files:
|
|
336
|
+
filename = self._extract_filename(file_path)
|
|
337
|
+
mime_type = get_mime_type_from_filename(filename)
|
|
338
|
+
if mime_type.startswith("image/"):
|
|
339
|
+
execution_summary += f"- **{filename}** (Image): \n"
|
|
340
|
+
else:
|
|
341
|
+
execution_summary += f"- **{filename}** ({mime_type}): `{file_path}`\n"
|
|
342
|
+
return execution_summary
|
|
343
|
+
|
|
344
|
+
@staticmethod
|
|
345
|
+
def _extract_filename(file_path: str) -> str:
|
|
346
|
+
"""Extract a filename from a path, with a stable fallback."""
|
|
347
|
+
filename = os.path.basename(file_path)
|
|
348
|
+
if not filename:
|
|
349
|
+
filename = f"sandbox_file_{hash(file_path) % 10000}"
|
|
350
|
+
return filename
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Constants for Code Sandbox tool.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Komang Elang Surya Prawira (komang.e.s.prawira@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# The filename `data.csv` is used as a hard-coded value because we currently lack a mechanism
|
|
8
|
+
# to dynamically determine the actual filename. This static filename is used for saving files
|
|
9
|
+
# inside the sandbox, and any pre-population steps will need to read from this filename.
|
|
10
|
+
# Code interacting with the sandbox can directly access the content of the file using the pre-defined variable,
|
|
11
|
+
# eliminating the need to load the file again. Agents or LLMs do not need to be aware of this filename.
|
|
12
|
+
DATA_FILE_NAME = "data.csv"
|
|
13
|
+
DATA_FILE_PATH = f"/files/{DATA_FILE_NAME}"
|