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,267 @@
|
|
|
1
|
+
"""This file contains the Sentry and OpenTelemetry configuration for GL Connectors SDK.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import inspect
|
|
8
|
+
import os
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import Any, Optional, Sequence
|
|
11
|
+
|
|
12
|
+
from dotenv import load_dotenv
|
|
13
|
+
from fastapi import FastAPI
|
|
14
|
+
from gl_observability.initializer import FastAPIConfig, SentryBackendConfig, TelemetryConfig, init_telemetry
|
|
15
|
+
from gl_observability.traces.instrument.functions import FunctionsInstrumentor
|
|
16
|
+
from opentelemetry.context import Context
|
|
17
|
+
from opentelemetry.sdk.trace.sampling import Decision, ParentBased, Sampler, SamplingResult, TraceIdRatioBased
|
|
18
|
+
from opentelemetry.trace import Link, SpanKind
|
|
19
|
+
from opentelemetry.trace.span import TraceState
|
|
20
|
+
from opentelemetry.util.types import Attributes
|
|
21
|
+
|
|
22
|
+
from aip_agents.agent import BaseAgent, LangChainAgent, LangGraphAgent
|
|
23
|
+
from aip_agents.utils.logger import get_logger
|
|
24
|
+
|
|
25
|
+
load_dotenv()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
logger = get_logger(__name__)
|
|
29
|
+
|
|
30
|
+
SENTRY_DSN = os.getenv("SENTRY_DSN")
|
|
31
|
+
SENTRY_ENVIRONMENT = os.getenv("SENTRY_ENVIRONMENT", "development")
|
|
32
|
+
SENTRY_PROJECT = os.getenv("SENTRY_PROJECT")
|
|
33
|
+
VERSION_NUMBER = os.getenv("VERSION_NUMBER", "0.0.0")
|
|
34
|
+
BUILD_NUMBER = os.getenv("BUILD_NUMBER", "0")
|
|
35
|
+
USE_OPENTELEMETRY = os.getenv("USE_OPENTELEMETRY", "true").lower() == "true"
|
|
36
|
+
|
|
37
|
+
# Lazy import of GoogleADKAgent to avoid heavy dependencies when not needed.
|
|
38
|
+
# This is initialized lazily by _get_classes_to_instrument() and can be
|
|
39
|
+
# patched by tests for mocking purposes.
|
|
40
|
+
CLASSES_TO_INSTRUMENT: list[type[Any]] | None = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _is_optional_google_adk_import_error(error: ImportError) -> bool:
|
|
44
|
+
"""Return True when the import failure is due to missing Google ADK extras."""
|
|
45
|
+
cause = error.__cause__
|
|
46
|
+
if isinstance(cause, ModuleNotFoundError) and cause.name and cause.name.startswith("google"):
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
return "aip-agents[google]" in str(error) or "aip-agents[google-adk]" in str(error)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _get_classes_to_instrument() -> list[type[Any]]:
|
|
53
|
+
"""Get the list of classes to instrument.
|
|
54
|
+
|
|
55
|
+
This lazily imports GoogleADKAgent only when telemetry is being set up,
|
|
56
|
+
avoiding the heavy Google ADK dependencies during module import.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
List of agent classes to instrument.
|
|
60
|
+
"""
|
|
61
|
+
global CLASSES_TO_INSTRUMENT
|
|
62
|
+
if CLASSES_TO_INSTRUMENT is None:
|
|
63
|
+
classes_to_instrument = [
|
|
64
|
+
BaseAgent,
|
|
65
|
+
LangGraphAgent,
|
|
66
|
+
LangChainAgent,
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
from aip_agents.agent import GoogleADKAgent
|
|
71
|
+
|
|
72
|
+
classes_to_instrument.append(GoogleADKAgent)
|
|
73
|
+
except ImportError as e:
|
|
74
|
+
if _is_optional_google_adk_import_error(e):
|
|
75
|
+
logger.debug("Google ADK extra is not installed; skipping GoogleADKAgent instrumentation")
|
|
76
|
+
else:
|
|
77
|
+
raise
|
|
78
|
+
|
|
79
|
+
CLASSES_TO_INSTRUMENT = classes_to_instrument
|
|
80
|
+
return CLASSES_TO_INSTRUMENT
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def get_all_methods(cls: type) -> list:
|
|
84
|
+
"""Get all methods from a class.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
cls: The class to get methods from.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
list: A list of methods.
|
|
91
|
+
"""
|
|
92
|
+
methods = []
|
|
93
|
+
for name, member in inspect.getmembers(cls):
|
|
94
|
+
if name.startswith("_"):
|
|
95
|
+
continue # skip dunder and private
|
|
96
|
+
if inspect.isfunction(member) or inspect.ismethod(member) or inspect.iscoroutinefunction(member):
|
|
97
|
+
methods.append(member)
|
|
98
|
+
return methods
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def instrument_gl_functions() -> None:
|
|
102
|
+
"""Instrument GL functions."""
|
|
103
|
+
agent_methods = []
|
|
104
|
+
for cls in _get_classes_to_instrument():
|
|
105
|
+
agent_methods.extend(get_all_methods(cls))
|
|
106
|
+
FunctionsInstrumentor().instrument(methods=agent_methods)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@dataclass(frozen=True)
|
|
110
|
+
class EndpointSamplingConfig:
|
|
111
|
+
"""Immutable configuration for endpoint-based trace sampling.
|
|
112
|
+
|
|
113
|
+
Maps FastAPI route patterns to sampling rates. Routes not listed
|
|
114
|
+
use the default rate.
|
|
115
|
+
|
|
116
|
+
Attributes:
|
|
117
|
+
default_rate: Sampling rate for routes not in any set (0.0–1.0).
|
|
118
|
+
no_sample_routes: Routes that should never be sampled (rate 0.0).
|
|
119
|
+
no_sample_prefixes: Route prefixes dropped at rate 0.0. A prefix
|
|
120
|
+
``/health-check`` matches ``/health-check`` and ``/health-check/*``
|
|
121
|
+
but not ``/health-checker``.
|
|
122
|
+
high_priority_routes: Routes sampled at 100% regardless of default.
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
default_rate: float = 1.0
|
|
126
|
+
no_sample_routes: frozenset[str] = frozenset()
|
|
127
|
+
no_sample_prefixes: frozenset[str] = frozenset()
|
|
128
|
+
high_priority_routes: frozenset[str] = frozenset()
|
|
129
|
+
|
|
130
|
+
def rate_for(self, route: str | None) -> float:
|
|
131
|
+
"""Return the sampling rate for a given route.
|
|
132
|
+
|
|
133
|
+
Normalizes by stripping a trailing slash so variants such as
|
|
134
|
+
``/health-check/`` still match the configured route sets/prefixes.
|
|
135
|
+
"""
|
|
136
|
+
if route is None:
|
|
137
|
+
return self.default_rate
|
|
138
|
+
normalized = route.rstrip("/") or "/"
|
|
139
|
+
if normalized in self.no_sample_routes:
|
|
140
|
+
return 0.0
|
|
141
|
+
if any(normalized == prefix or normalized.startswith(prefix + "/") for prefix in self.no_sample_prefixes):
|
|
142
|
+
return 0.0
|
|
143
|
+
if normalized in self.high_priority_routes:
|
|
144
|
+
return 1.0
|
|
145
|
+
return self.default_rate
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class EndpointRouteSampler(Sampler):
|
|
149
|
+
"""OpenTelemetry Sampler that varies sampling rate by FastAPI route.
|
|
150
|
+
|
|
151
|
+
Inspects the ``http.route`` span attribute and delegates to a
|
|
152
|
+
fresh ``ParentBased(TraceIdRatioBased(rate))`` per span, following
|
|
153
|
+
the GL Observability cookbook pattern.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
config: Route-to-rate mapping configuration.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
def __init__(self, config: EndpointSamplingConfig) -> None:
|
|
160
|
+
self._config = config
|
|
161
|
+
|
|
162
|
+
def should_sample(
|
|
163
|
+
self,
|
|
164
|
+
parent_context: Optional[Context],
|
|
165
|
+
trace_id: int,
|
|
166
|
+
name: str,
|
|
167
|
+
kind: SpanKind = None,
|
|
168
|
+
attributes: Attributes = None,
|
|
169
|
+
links: Sequence[Link] = None,
|
|
170
|
+
trace_state: TraceState = None,
|
|
171
|
+
) -> SamplingResult:
|
|
172
|
+
"""Compute a sampling decision, dropping configured no-sample routes.
|
|
173
|
+
|
|
174
|
+
``http.route`` (set by FastAPI instrumentation) is preferred; when it
|
|
175
|
+
is absent on an incoming span, fall back to ``url.path`` and
|
|
176
|
+
``http.target`` (stripping any query string) so health-check traces
|
|
177
|
+
are still filtered.
|
|
178
|
+
"""
|
|
179
|
+
route = None
|
|
180
|
+
if attributes:
|
|
181
|
+
route = (
|
|
182
|
+
attributes.get("http.route")
|
|
183
|
+
or attributes.get("url.path")
|
|
184
|
+
or attributes.get("http.target")
|
|
185
|
+
)
|
|
186
|
+
if isinstance(route, str) and "?" in route:
|
|
187
|
+
route = route.split("?", 1)[0]
|
|
188
|
+
rate = self._config.rate_for(route)
|
|
189
|
+
sampler = ParentBased(TraceIdRatioBased(rate))
|
|
190
|
+
return sampler.should_sample(
|
|
191
|
+
parent_context, trace_id, name, kind, attributes, links, trace_state
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def get_description(self) -> str:
|
|
195
|
+
"""Return a human-readable description of this sampler."""
|
|
196
|
+
return f"EndpointRouteSampler(default={self._config.default_rate})"
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _create_telemetry_config(app: FastAPI | None) -> TelemetryConfig:
|
|
200
|
+
"""Build a telemetry configuration for Sentry-backed tracing.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
app: Optional FastAPI application instance for instrumentation.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
TelemetryConfig instance for initializing telemetry.
|
|
207
|
+
"""
|
|
208
|
+
backend_config = SentryBackendConfig(
|
|
209
|
+
dsn=SENTRY_DSN,
|
|
210
|
+
environment=SENTRY_ENVIRONMENT,
|
|
211
|
+
release=f"{SENTRY_PROJECT}@{VERSION_NUMBER}+{BUILD_NUMBER}",
|
|
212
|
+
send_default_pii=True,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
fastapi_config = FastAPIConfig(app) if app is not None else None
|
|
216
|
+
|
|
217
|
+
sampling_config = EndpointSamplingConfig(
|
|
218
|
+
default_rate=1.0,
|
|
219
|
+
no_sample_prefixes=frozenset({"/health-check"}),
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
return TelemetryConfig(
|
|
223
|
+
trace_sampler=EndpointRouteSampler(sampling_config),
|
|
224
|
+
fastapi_config=fastapi_config,
|
|
225
|
+
use_langchain=True,
|
|
226
|
+
backend_config=backend_config,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def setup_sentry_with_open_telemetry(app: FastAPI) -> None:
|
|
231
|
+
"""Configure telemetry with both Sentry and OpenTelemetry.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
app: FastAPI application instance
|
|
235
|
+
"""
|
|
236
|
+
try:
|
|
237
|
+
telemetry_config = _create_telemetry_config(app)
|
|
238
|
+
init_telemetry(telemetry_config)
|
|
239
|
+
logger.info(f"Telemetry initialized with OpenTelemetry for environment: {SENTRY_ENVIRONMENT}")
|
|
240
|
+
except Exception as e:
|
|
241
|
+
logger.error(f"Failed to initialize telemetry with OpenTelemetry: {e}")
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def setup_sentry_only() -> None:
|
|
245
|
+
"""Configure telemetry with Sentry only (no OpenTelemetry)."""
|
|
246
|
+
try:
|
|
247
|
+
telemetry_config = _create_telemetry_config(app=None)
|
|
248
|
+
init_telemetry(telemetry_config)
|
|
249
|
+
logger.info(f"Telemetry initialized with Sentry only for environment: {SENTRY_ENVIRONMENT}")
|
|
250
|
+
except Exception as e:
|
|
251
|
+
logger.error(f"Failed to initialize telemetry with Sentry only: {e}")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def setup_telemetry(app: FastAPI) -> None:
|
|
255
|
+
"""Configure and initialize telemetry based on configuration.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
app: FastAPI application instance
|
|
259
|
+
"""
|
|
260
|
+
if not SENTRY_DSN:
|
|
261
|
+
logger.warning("Warning: SENTRY_DSN not set. Sentry will not be enabled.")
|
|
262
|
+
return
|
|
263
|
+
if USE_OPENTELEMETRY:
|
|
264
|
+
setup_sentry_with_open_telemetry(app)
|
|
265
|
+
else:
|
|
266
|
+
setup_sentry_only()
|
|
267
|
+
instrument_gl_functions()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Skills support for AIP Agents (PR-001 foundation).
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from aip_agents.skills.errors import (
|
|
10
|
+
SkillError,
|
|
11
|
+
SkillExecutionError,
|
|
12
|
+
SkillInstallError,
|
|
13
|
+
SkillMetadataError,
|
|
14
|
+
SkillValidationError,
|
|
15
|
+
)
|
|
16
|
+
from aip_agents.skills.installer import SkillInstaller
|
|
17
|
+
from aip_agents.skills.models import ResourceEntry, ResourceManifest, ResourceType, Skill
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"SkillError",
|
|
21
|
+
"SkillInstallError",
|
|
22
|
+
"SkillMetadataError",
|
|
23
|
+
"SkillValidationError",
|
|
24
|
+
"SkillExecutionError",
|
|
25
|
+
"Skill",
|
|
26
|
+
"SkillInstaller",
|
|
27
|
+
"ResourceType",
|
|
28
|
+
"ResourceEntry",
|
|
29
|
+
"ResourceManifest",
|
|
30
|
+
]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Skill-related error types.
|
|
2
|
+
|
|
3
|
+
These errors are intentionally small and human-readable since they are expected to
|
|
4
|
+
surface to SDK users (e.g., during skill installation).
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Saul Sayers (saul.sayers@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any, Literal, TypedDict
|
|
13
|
+
|
|
14
|
+
SkillSourceStatus = Literal[
|
|
15
|
+
"missing_dependency",
|
|
16
|
+
"auth_failure",
|
|
17
|
+
"invalid_url",
|
|
18
|
+
"unsupported_local_path",
|
|
19
|
+
"cache_unavailable",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SkillSourceError(TypedDict):
|
|
24
|
+
"""Structured skill source readiness failure."""
|
|
25
|
+
|
|
26
|
+
source: str
|
|
27
|
+
status: SkillSourceStatus
|
|
28
|
+
message: str
|
|
29
|
+
detail: str
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SkillError(Exception):
|
|
33
|
+
"""Base error for skill operations."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SkillInstallError(SkillError):
|
|
37
|
+
"""Raised when a skill cannot be installed (network/auth/archive errors)."""
|
|
38
|
+
|
|
39
|
+
def __init__(self, message: str, *, source_errors: list[SkillSourceError] | None = None) -> None:
|
|
40
|
+
"""Create an install error with optional structured source failures."""
|
|
41
|
+
super().__init__(message)
|
|
42
|
+
self.source_errors = source_errors or []
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SkillValidationError(SkillError):
|
|
46
|
+
"""Raised when a local skill path is invalid (naming, missing files, etc.)."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class SkillMetadataError(SkillError):
|
|
50
|
+
"""Raised when SKILL.md metadata is invalid.
|
|
51
|
+
|
|
52
|
+
PR-001 does not parse SKILL.md frontmatter, but later milestones will.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class SkillExecutionError(ValueError):
|
|
57
|
+
"""Raised when a skill execution request is invalid."""
|
|
58
|
+
|
|
59
|
+
def __init__(self, message: str, *, denial: dict[str, Any] | None = None) -> None:
|
|
60
|
+
"""Create an execution error with optional structured denial details."""
|
|
61
|
+
super().__init__(message)
|
|
62
|
+
self.denial = denial or {}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _iter_causes(error: Exception) -> list[Exception]:
|
|
66
|
+
causes: list[Exception] = []
|
|
67
|
+
current: Exception | None = error
|
|
68
|
+
while current is not None:
|
|
69
|
+
causes.append(current)
|
|
70
|
+
current = current.__cause__ or current.__context__
|
|
71
|
+
return causes
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _has_status_code(error: Exception, status_codes: set[int]) -> bool:
|
|
75
|
+
for cause in _iter_causes(error):
|
|
76
|
+
response = getattr(cause, "response", None) # NOSONAR
|
|
77
|
+
status_code = getattr(response, "status_code", None)
|
|
78
|
+
if status_code in status_codes:
|
|
79
|
+
return True
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def classify_skill_source_error(source: str, error: Exception) -> SkillSourceError:
|
|
84
|
+
"""Classify a skill source failure into a structured readiness object."""
|
|
85
|
+
detail = str(error)
|
|
86
|
+
causes = _iter_causes(error)
|
|
87
|
+
messages = " ".join(str(cause) for cause in causes)
|
|
88
|
+
|
|
89
|
+
if any(isinstance(cause, ImportError) for cause in causes) or "gl-connectors-tools" in messages:
|
|
90
|
+
status: SkillSourceStatus = "missing_dependency"
|
|
91
|
+
message = "Skill installer dependency is missing."
|
|
92
|
+
elif _has_status_code(error, {401, 403}):
|
|
93
|
+
status = "auth_failure"
|
|
94
|
+
message = "Skill source could not be accessed with the current GitHub credentials."
|
|
95
|
+
elif _has_status_code(error, {404}) or isinstance(error, SkillValidationError) or "Unsupported GitHub" in messages:
|
|
96
|
+
status = "invalid_url"
|
|
97
|
+
message = "Skill source URL is invalid or does not point to a supported GitHub skill tree."
|
|
98
|
+
elif any(isinstance(cause, OSError) for cause in causes):
|
|
99
|
+
status = "cache_unavailable"
|
|
100
|
+
message = "Skill source cache or install destination is unavailable."
|
|
101
|
+
else:
|
|
102
|
+
status = "cache_unavailable"
|
|
103
|
+
message = "Skill source could not be installed or refreshed."
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
"source": source,
|
|
107
|
+
"status": status,
|
|
108
|
+
"message": message,
|
|
109
|
+
"detail": detail,
|
|
110
|
+
}
|