agent-engine-runner-shared 0.11.9__tar.gz → 0.11.10__tar.gz
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.
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/CHANGELOG.md +6 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/Dockerfile +1 -1
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/PKG-INFO +4 -4
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/docs/api.md +91 -29
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/pyproject.toml +6 -4
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/__init__.py +2 -0
- agent_engine_runner_shared-0.11.10/src/agent_engine_runner_shared/caller_trace.py +138 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/README.md +8 -5
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/executor.py +13 -2
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/custom_events.py +5 -2
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/error_reporting.py +1 -1
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/launcher.py +103 -3
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_oauth_secret.py +27 -1
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/node_logger.py +5 -3
- agent_engine_runner_shared-0.11.10/src/agent_engine_runner_shared/owner_callback.py +139 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/progress.py +9 -85
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/secure_wrapper.py +516 -125
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/aer.py +13 -22
- agent_engine_runner_shared-0.11.10/src/agent_engine_runner_shared/server/atlas_dns.py +88 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/base.py +54 -3
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/http_retry.py +29 -2
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/tool.py +110 -15
- agent_engine_runner_shared-0.11.10/src/agent_engine_runner_shared/startup_state.py +19 -0
- agent_engine_runner_shared-0.11.10/src/agent_engine_runner_shared/tls_client.py +579 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/tool_api_error.py +44 -5
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/utils.py +7 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/__init__.py +8 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/activity.py +76 -6
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/context.py +198 -11
- agent_engine_runner_shared-0.11.10/tests/conftest.py +33 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/test_core.py +155 -0
- agent_engine_runner_shared-0.11.10/tests/unit/test_atlas_dns.py +129 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_durable_guardrail_review.py +1 -2
- agent_engine_runner_shared-0.11.10/tests/unit/test_durable_oauth.py +300 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_durable_proxies.py +5 -1
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_emit_custom_event.py +33 -13
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_emit_progress.py +37 -40
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_function_mode.py +12 -6
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_hitl_interrupt.py +56 -4
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_http_retry.py +100 -5
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_launcher.py +30 -3
- agent_engine_runner_shared-0.11.10/tests/unit/test_launcher_reports.py +390 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_node_logger.py +28 -53
- agent_engine_runner_shared-0.11.10/tests/unit/test_owner_callback.py +234 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_query_routes.py +1 -1
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_secure_wrapper.py +384 -94
- agent_engine_runner_shared-0.11.10/tests/unit/test_server_startup_failures.py +194 -0
- agent_engine_runner_shared-0.11.10/tests/unit/test_shared_client.py +510 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tls_client.py +15 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tls_client_integration.py +2 -2
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool.py +14 -10
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_api_error.py +56 -5
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_trace_context.py +250 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_activity.py +108 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_context.py +147 -0
- agent_engine_runner_shared-0.11.9/src/agent_engine_runner_shared/owner_callback.py +0 -60
- agent_engine_runner_shared-0.11.9/src/agent_engine_runner_shared/tls_client.py +0 -314
- agent_engine_runner_shared-0.11.9/tests/conftest.py +0 -18
- agent_engine_runner_shared-0.11.9/tests/unit/test_owner_callback.py +0 -109
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/LICENSE +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/Makefile +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/README.md +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/pydoc-markdown.yml +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/pyrightconfig.json +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/scripts/agentic-vendored-wheel-check.sh +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/__main__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/a2a.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/a2a_auth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/agent_config.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/async_utils.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/checkpoint_workspace.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/bundle.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/create_tool.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/definitions.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/README.md +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/authoring.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/catalog.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/modes.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/naming.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/parameters.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/security.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/generate/spec.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/materialize.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/connectors/runtime.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/db_config.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/db_naming.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/execution.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/activity_pb2.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/activity_pb2.pyi +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/common_pb2.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/common_pb2.pyi +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/runtime_pb2.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/runtime_pb2.pyi +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/state_pb2.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/generated/workflow/v1/state_pb2.pyi +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/guardrails_evaluator/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/guardrails_evaluator/core.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/guardrails_evaluator/regex.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/hooks.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/http_path.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_oauth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_oauth_cache_lock.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_oauth_cache_name.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_oauth_cli.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/mcp_tools.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/memory.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/memory_appbound.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/metrics.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/models.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/py.typed +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/runtime.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/secure_llm_proxy.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/auth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/call_interrupt.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/callback_delivery.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/chunk_types.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/cors.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/drain.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/function.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/graph_warm.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/metadata.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/oe_url.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/owner_url.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/server/query.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/span_kinds.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/span_names.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/structured_logging.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/tool_memory_ownership.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/toolpod_handlers.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/tracing/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/tracing/exporters.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/tracing/setup.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/types.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/attempt.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/cancelled_history.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/client.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/heartbeat.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/memory.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/protojson.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/src/agent_engine_runner_shared/workflow/settlement.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/.gitignore +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/README.md +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/fetch_corpus.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/manifest.json +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/corpus/test_api_corpus.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/mock_embedder.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/test_a2a_trace_propagation.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/test_runtime.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/test_secure_async.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/test_secure_sync.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/integration/test_tracing_otlp_wire_format.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/pact/conftest.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/pact/test_oe_provider_verification.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/__init__.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/fixtures/jira.tool_defs.yaml +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/test_bundle.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/test_create_tool.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/test_generate.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/connectors/test_materialize.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_a2a.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_a2a_auth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_a2a_registration.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_build_agent_span.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_cancelled_turn.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_capability_advertise.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_chunk_delivery_reliability.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_chunk_emission.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_durable_attempt.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_llm_invocation_signal.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_metadata_payload.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_policy_denied.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_session_finish.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_timeout_signal.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_trace_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_aer_workspace_scope.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_agent_config.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_async_utils.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_call_interrupt.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_call_interrupt_contract.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_checkpoint_workspace.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_cors.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_create_memory_client_headers.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_custom_headers_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_custom_headers_models.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_db_naming.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_debug_hook.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_drain.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_drain_contract.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_error_reporting.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_execution.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_extract_turn_messages.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_format_llm_error.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_graph_warm.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_guardrails_protocol.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_hooks.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_http_path.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_listen_host.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_llm_credential_classification.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_llm_routing.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_mcp_oauth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_mcp_oauth_cli.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_mcp_oauth_secret.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_mcp_tools.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_memory_appbound.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_memory_search_metadata.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_memory_writer_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_metadata.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_metrics.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_models.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_no_lc_imports.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_oe_url.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_owner_url.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_payload_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_request_id_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_resume_payload.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_build_context_from_sources.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_checkpoint_workspace.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_custom_memory.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_memory_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_models.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_runtime_register_tool.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_secure_llm_proxy.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_server_auth.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_server_health.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_server_shutdown.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_session_filesystem_isolation.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_session_finish_context.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_structured_logging.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_thinking_tokens.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_token_capture.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_authorization.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_cancellation_boundary.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_deserialization.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_log_redaction.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_memory_ownership.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tool_server_startup.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_toolpod_handlers.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tracing_exporter.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/test_tracing_retry.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_attempt.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_cancelled_history.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_client.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_heartbeat.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_memory.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_protojson.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_protojson_helpers.py +0 -0
- {agent_engine_runner_shared-0.11.9 → agent_engine_runner_shared-0.11.10}/tests/unit/workflow/test_settlement.py +0 -0
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
- Reuse a process-wide keep-alive mTLS client for OE callbacks (tool
|
|
12
|
+
execute/result, node events, progress and custom events) and drain callback
|
|
13
|
+
response bodies so connections return to the pool; removes a full TLS
|
|
14
|
+
handshake per callback.
|
|
15
|
+
|
|
10
16
|
### Fixed
|
|
11
17
|
- Uncaught exceptions in agent code now emit one filterable `level=ERROR`
|
|
12
18
|
record instead of only `WARNING`. Ordinary stderr writes with no
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Usage: docker buildx build -t runner:latest -f packages/python/packages/agent-engine-runner-shared/Dockerfile .
|
|
6
6
|
|
|
7
7
|
ARG BASE_TARGETPLATFORM=linux/amd64
|
|
8
|
-
ARG RUNNER_BASE_IMAGE=664315256653.dkr.ecr.us-east-1.amazonaws.com/base/amazonlinux2023-python:v3.11-
|
|
8
|
+
ARG RUNNER_BASE_IMAGE=664315256653.dkr.ecr.us-east-1.amazonaws.com/base/amazonlinux2023-python:v3.11-202610191636-2ff39c3@sha256:30ecac067fceafe43a5f0f5e80d1725b60708204dcd2fe3f176363417e2a2402
|
|
9
9
|
|
|
10
10
|
FROM --platform=${BASE_TARGETPLATFORM} ghcr.io/astral-sh/uv@sha256:ff07b86af50d4d9391d9daf4ff89ce427bc544f9aae87057e69a1cc0aa369946 AS uv
|
|
11
11
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-engine-runner-shared
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.10
|
|
4
4
|
Summary: Runner SDK - Framework-agnostic agent runtime
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Python: >=3.11
|
|
8
|
-
Requires-Dist: agent-engine-sdk-memory==0.11.
|
|
9
|
-
Requires-Dist: agent-engine-sdk==0.11.
|
|
8
|
+
Requires-Dist: agent-engine-sdk-memory==0.11.10
|
|
9
|
+
Requires-Dist: agent-engine-sdk==0.11.10
|
|
10
10
|
Requires-Dist: fastapi>=0.141.1
|
|
11
11
|
Requires-Dist: filelock>=3.0.0
|
|
12
12
|
Requires-Dist: httpx-sse>=0.4.0
|
|
@@ -21,7 +21,7 @@ Requires-Dist: pyyaml>=6.0
|
|
|
21
21
|
Requires-Dist: regex>=2026.4.4
|
|
22
22
|
Requires-Dist: sentry-sdk>=2.27.0
|
|
23
23
|
Requires-Dist: starlette>=1.7.0
|
|
24
|
-
Requires-Dist: uvicorn>=0.
|
|
24
|
+
Requires-Dist: uvicorn>=0.50.0
|
|
25
25
|
Provides-Extra: debug
|
|
26
26
|
Requires-Dist: debugpy>=1.8.0; extra == 'debug'
|
|
27
27
|
Provides-Extra: dev
|
|
@@ -174,10 +174,14 @@
|
|
|
174
174
|
* [response\_from\_stream\_chunks](#agent_engine_runner_shared.secure_llm_proxy.SecureLLMProxy.response_from_stream_chunks)
|
|
175
175
|
* [stream](#agent_engine_runner_shared.secure_llm_proxy.SecureLLMProxy.stream)
|
|
176
176
|
* [agent\_engine\_runner\_shared.secure\_wrapper](#agent_engine_runner_shared.secure_wrapper)
|
|
177
|
+
* [\_OAuthAuthorizationRequired](#agent_engine_runner_shared.secure_wrapper._OAuthAuthorizationRequired)
|
|
178
|
+
* [\_\_init\_\_](#agent_engine_runner_shared.secure_wrapper._OAuthAuthorizationRequired.__init__)
|
|
179
|
+
* [oauth\_authorization\_wait\_id](#agent_engine_runner_shared.secure_wrapper.oauth_authorization_wait_id)
|
|
177
180
|
* [extract\_usage](#agent_engine_runner_shared.secure_wrapper.extract_usage)
|
|
178
181
|
* [PolicyDeniedException](#agent_engine_runner_shared.secure_wrapper.PolicyDeniedException)
|
|
179
182
|
* [OERetryAfterError](#agent_engine_runner_shared.secure_wrapper.OERetryAfterError)
|
|
180
183
|
* [ToolExecutionError](#agent_engine_runner_shared.secure_wrapper.ToolExecutionError)
|
|
184
|
+
* [ToolPlatformError](#agent_engine_runner_shared.secure_wrapper.ToolPlatformError)
|
|
181
185
|
* [TerminalExecutionError](#agent_engine_runner_shared.secure_wrapper.TerminalExecutionError)
|
|
182
186
|
* [raise\_for\_oe\_rejection](#agent_engine_runner_shared.secure_wrapper.raise_for_oe_rejection)
|
|
183
187
|
* [ToolCallTimeoutError](#agent_engine_runner_shared.secure_wrapper.ToolCallTimeoutError)
|
|
@@ -2733,6 +2737,36 @@ This module provides:
|
|
|
2733
2737
|
|
|
2734
2738
|
HITL is handled via LangGraph's native interrupt() / Command(resume=...) API.
|
|
2735
2739
|
|
|
2740
|
+
<a id="agent_engine_runner_shared.secure_wrapper._OAuthAuthorizationRequired"></a>
|
|
2741
|
+
|
|
2742
|
+
## \_OAuthAuthorizationRequired
|
|
2743
|
+
|
|
2744
|
+
```python
|
|
2745
|
+
class _OAuthAuthorizationRequired(Exception)
|
|
2746
|
+
```
|
|
2747
|
+
|
|
2748
|
+
Leave durable dispatch with typed consent control instead of interrupting its activity.
|
|
2749
|
+
|
|
2750
|
+
<a id="agent_engine_runner_shared.secure_wrapper._OAuthAuthorizationRequired.__init__"></a>
|
|
2751
|
+
|
|
2752
|
+
#### \_\_init\_\_
|
|
2753
|
+
|
|
2754
|
+
```python
|
|
2755
|
+
def __init__(elicitation: ElicitationInfo, step: int) -> None
|
|
2756
|
+
```
|
|
2757
|
+
|
|
2758
|
+
Carry the OE response to its activity boundary without exposing it in errors.
|
|
2759
|
+
|
|
2760
|
+
<a id="agent_engine_runner_shared.secure_wrapper.oauth_authorization_wait_id"></a>
|
|
2761
|
+
|
|
2762
|
+
#### oauth\_authorization\_wait\_id
|
|
2763
|
+
|
|
2764
|
+
```python
|
|
2765
|
+
def oauth_authorization_wait_id(value: Any) -> str | None
|
|
2766
|
+
```
|
|
2767
|
+
|
|
2768
|
+
Identify a consent wait only when this attempt recorded the platform's challenge.
|
|
2769
|
+
|
|
2736
2770
|
<a id="agent_engine_runner_shared.secure_wrapper.extract_usage"></a>
|
|
2737
2771
|
|
|
2738
2772
|
#### extract\_usage
|
|
@@ -2783,12 +2817,26 @@ class ToolExecutionError(Exception)
|
|
|
2783
2817
|
|
|
2784
2818
|
Raised when tool execution fails.
|
|
2785
2819
|
|
|
2820
|
+
<a id="agent_engine_runner_shared.secure_wrapper.ToolPlatformError"></a>
|
|
2821
|
+
|
|
2822
|
+
## ToolPlatformError
|
|
2823
|
+
|
|
2824
|
+
```python
|
|
2825
|
+
class ToolPlatformError(ToolExecutionError)
|
|
2826
|
+
```
|
|
2827
|
+
|
|
2828
|
+
Raised when the platform, not the tool, failed a tool call.
|
|
2829
|
+
|
|
2830
|
+
The tool may already have run, for example when OE rejects or never
|
|
2831
|
+
acknowledges its result, so an adapter must not report this to the model as
|
|
2832
|
+
a failed tool it could call again.
|
|
2833
|
+
|
|
2786
2834
|
<a id="agent_engine_runner_shared.secure_wrapper.TerminalExecutionError"></a>
|
|
2787
2835
|
|
|
2788
2836
|
## TerminalExecutionError
|
|
2789
2837
|
|
|
2790
2838
|
```python
|
|
2791
|
-
class TerminalExecutionError(
|
|
2839
|
+
class TerminalExecutionError(ToolPlatformError)
|
|
2792
2840
|
```
|
|
2793
2841
|
|
|
2794
2842
|
Raised when OE rejects a tool call because the execution already ended.
|
|
@@ -3077,24 +3125,30 @@ Clean up resources owned by this execution's wrapper.
|
|
|
3077
3125
|
#### execute\_tool
|
|
3078
3126
|
|
|
3079
3127
|
```python
|
|
3080
|
-
def execute_tool(
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3128
|
+
def execute_tool(
|
|
3129
|
+
tool_name: str,
|
|
3130
|
+
arguments: Dict[str, Any],
|
|
3131
|
+
*,
|
|
3132
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
3133
|
+
provider_type: Optional[str] = None,
|
|
3134
|
+
scopes: Optional[list[str]] = None,
|
|
3135
|
+
tool_call_id: Optional[str] = None,
|
|
3136
|
+
raw_on_interrupt: bool = False,
|
|
3137
|
+
redact_fields: Optional[list[str]] = None,
|
|
3138
|
+
is_local: bool = True,
|
|
3139
|
+
local_executor: Optional[Callable[[], Any]] = None,
|
|
3140
|
+
is_framework_control_flow: Optional[Callable[[BaseException],
|
|
3141
|
+
bool]] = None,
|
|
3142
|
+
call_channel_expected: bool = False,
|
|
3143
|
+
on_unknown_outcome: Optional[UnknownOutcomePolicy] = None) -> Any
|
|
3094
3144
|
```
|
|
3095
3145
|
|
|
3096
3146
|
Execute a tool call through OE.
|
|
3097
3147
|
|
|
3148
|
+
Durable OAuth records a typed challenge before a separate framework
|
|
3149
|
+
wait, then records the actual resource call after reauthorization.
|
|
3150
|
+
Its consent answer never becomes a tool result or Memory content.
|
|
3151
|
+
|
|
3098
3152
|
**Arguments**:
|
|
3099
3153
|
|
|
3100
3154
|
- `tool_name` - Name of the tool
|
|
@@ -3111,6 +3165,9 @@ Execute a tool call through OE.
|
|
|
3111
3165
|
- `is_local` - Whether OE should return the approved call to this AER.
|
|
3112
3166
|
- `local_executor` - Callback that invokes the registered tool on the
|
|
3113
3167
|
current framework stack. Required for local tools.
|
|
3168
|
+
- `on_unknown_outcome` - What a retry does when the runner was lost while
|
|
3169
|
+
this tool was in flight in a durable workflow: ``"rerun"`` runs it
|
|
3170
|
+
again, ``"fail"`` refuses the retry.
|
|
3114
3171
|
|
|
3115
3172
|
|
|
3116
3173
|
**Returns**:
|
|
@@ -3132,20 +3189,22 @@ Execute a tool call through OE.
|
|
|
3132
3189
|
|
|
3133
3190
|
```python
|
|
3134
3191
|
def create_secure_tool_function(
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3192
|
+
original_tool: Any,
|
|
3193
|
+
tool_name: str,
|
|
3194
|
+
*,
|
|
3195
|
+
allow_direct: bool = False,
|
|
3196
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
3197
|
+
is_local: bool = True,
|
|
3198
|
+
provider_type: Optional[str] = None,
|
|
3199
|
+
scopes: Optional[list[str]] = None,
|
|
3200
|
+
response_format: Literal["content",
|
|
3201
|
+
"content_and_artifact"] = "content",
|
|
3202
|
+
tool_declared_format: Optional[Literal["content",
|
|
3203
|
+
"content_and_artifact"]] = None,
|
|
3204
|
+
redact_fields: Optional[list[str]] = None,
|
|
3205
|
+
is_framework_control_flow: Optional[Callable[[BaseException],
|
|
3206
|
+
bool]] = None,
|
|
3207
|
+
on_unknown_outcome: Optional[UnknownOutcomePolicy] = None) -> Callable
|
|
3149
3208
|
```
|
|
3150
3209
|
|
|
3151
3210
|
Create a wrapped tool function that routes through SecureToolWrapper.
|
|
@@ -3165,6 +3224,9 @@ to be built before execution context exists.
|
|
|
3165
3224
|
- `tool_declared_format` - The tool author's own original format, used only
|
|
3166
3225
|
to decide whether a normal result gets shape-matched into a tuple.
|
|
3167
3226
|
Defaults to ``response_format``.
|
|
3227
|
+
- `on_unknown_outcome` - What a retry does when the runner was lost while
|
|
3228
|
+
this tool was in flight in a durable workflow: ``"rerun"`` runs it
|
|
3229
|
+
again, ``"fail"`` refuses the retry.
|
|
3168
3230
|
|
|
3169
3231
|
|
|
3170
3232
|
**Returns**:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agent-engine-runner-shared"
|
|
3
|
-
version = "0.11.
|
|
3
|
+
version = "0.11.10"
|
|
4
4
|
description = "Runner SDK - Framework-agnostic agent runtime"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "Apache-2.0"}
|
|
@@ -12,7 +12,9 @@ dependencies = [
|
|
|
12
12
|
# validation, which can disagree with scope["path"]. The
|
|
13
13
|
# Host-validating _HOST_RE landed in starlette 1.4.1.
|
|
14
14
|
"starlette>=1.7.0",
|
|
15
|
-
|
|
15
|
+
# The launcher relies on uvicorn's STARTUP_FAILURE (exit 3) contract for
|
|
16
|
+
# lifespan startup and bind failures, added in 0.50.0.
|
|
17
|
+
"uvicorn>=0.50.0",
|
|
16
18
|
"pydantic>=2.0.0",
|
|
17
19
|
"protobuf>=6.33.6,<7",
|
|
18
20
|
"httpx>=0.27.0",
|
|
@@ -23,9 +25,9 @@ dependencies = [
|
|
|
23
25
|
"jsonschema>=4.26.0",
|
|
24
26
|
"sentry-sdk>=2.27.0",
|
|
25
27
|
# BaseAgent protocol and AgentInput/AgentEvent models
|
|
26
|
-
"agent-engine-sdk==0.11.
|
|
28
|
+
"agent-engine-sdk==0.11.10",
|
|
27
29
|
# Memory models and the MemoryClient HTTP client
|
|
28
|
-
"agent-engine-sdk-memory==0.11.
|
|
30
|
+
"agent-engine-sdk-memory==0.11.10",
|
|
29
31
|
# Required for checkpoint message decoding (query/sessions endpoints)
|
|
30
32
|
"msgpack>=1.0.0",
|
|
31
33
|
# Required by guardrails_evaluator/regex.py for advanced regex matching
|
|
@@ -96,6 +96,7 @@ from agent_engine_runner_shared.secure_wrapper import (
|
|
|
96
96
|
TerminalExecutionError,
|
|
97
97
|
ToolCallTimeoutError,
|
|
98
98
|
ToolExecutionError,
|
|
99
|
+
ToolPlatformError,
|
|
99
100
|
extract_usage,
|
|
100
101
|
)
|
|
101
102
|
from agent_engine_runner_shared.structured_logging import (
|
|
@@ -190,6 +191,7 @@ __all__ = [
|
|
|
190
191
|
"TerminalExecutionError",
|
|
191
192
|
"ToolCallTimeoutError",
|
|
192
193
|
"ToolExecutionError",
|
|
194
|
+
"ToolPlatformError",
|
|
193
195
|
"ExternalAPICallError",
|
|
194
196
|
# Utilities
|
|
195
197
|
"extract_usage",
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Distinguish an inbound caller trace from a root this runner created.
|
|
2
|
+
|
|
3
|
+
AER always starts ``aer.execute``. With no inbound traceparent that span is a
|
|
4
|
+
root, and ``tls_client`` injects it on the call to the OE. The OE forwards
|
|
5
|
+
that header, so the tool process sees a remote parent even though no caller
|
|
6
|
+
trace was bound. W3C traceparent cannot say who created the root, so the
|
|
7
|
+
outgoing tracestate carries ``agentengine=root`` for a runner-created trace.
|
|
8
|
+
Guardrail content is recorded only when that marker is absent.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from contextlib import contextmanager
|
|
14
|
+
from typing import Any, Iterator
|
|
15
|
+
|
|
16
|
+
# Simple W3C tracestate member. A value of "root" means a runner process
|
|
17
|
+
# created this trace; an inbound caller does not set it.
|
|
18
|
+
RUNNER_ROOT_TRACESTATE_KEY = "agentengine"
|
|
19
|
+
RUNNER_ROOT_TRACESTATE_VALUE = "root"
|
|
20
|
+
|
|
21
|
+
_RUNNER_ROOTED_KEY: Any = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _runner_rooted_key() -> Any:
|
|
25
|
+
global _RUNNER_ROOTED_KEY
|
|
26
|
+
if _RUNNER_ROOTED_KEY is None:
|
|
27
|
+
from opentelemetry import context
|
|
28
|
+
|
|
29
|
+
_RUNNER_ROOTED_KEY = context.create_key("agentengine.runner_rooted_trace")
|
|
30
|
+
return _RUNNER_ROOTED_KEY
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def trace_state_marks_runner_root(trace_state: Any) -> bool:
|
|
34
|
+
"""True when tracestate says a runner created this trace's root."""
|
|
35
|
+
if trace_state is None:
|
|
36
|
+
return False
|
|
37
|
+
try:
|
|
38
|
+
marked = RUNNER_ROOT_TRACESTATE_KEY in trace_state
|
|
39
|
+
except TypeError:
|
|
40
|
+
return False
|
|
41
|
+
if not marked:
|
|
42
|
+
return False
|
|
43
|
+
return trace_state[RUNNER_ROOT_TRACESTATE_KEY] == RUNNER_ROOT_TRACESTATE_VALUE
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def merge_runner_root_trace_state(existing: str | None) -> str:
|
|
47
|
+
"""Return tracestate with the runner-root member first, without duplicates."""
|
|
48
|
+
kept: list[str] = []
|
|
49
|
+
prefix = f"{RUNNER_ROOT_TRACESTATE_KEY}="
|
|
50
|
+
for part in (existing or "").split(","):
|
|
51
|
+
item = part.strip()
|
|
52
|
+
if not item or item.startswith(prefix):
|
|
53
|
+
continue
|
|
54
|
+
kept.append(item)
|
|
55
|
+
member = f"{RUNNER_ROOT_TRACESTATE_KEY}={RUNNER_ROOT_TRACESTATE_VALUE}"
|
|
56
|
+
return ",".join([member, *kept])
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def parent_context_is_runner_rooted(parent_context: Any) -> bool:
|
|
60
|
+
"""True when ``parent_context`` is not an inbound caller trace.
|
|
61
|
+
|
|
62
|
+
An invalid extract means this process is about to create the root. A
|
|
63
|
+
remote parent without the runner-root marker was already bound by a caller.
|
|
64
|
+
"""
|
|
65
|
+
from opentelemetry import trace
|
|
66
|
+
|
|
67
|
+
span_context = trace.get_current_span(parent_context).get_span_context()
|
|
68
|
+
if span_context is None or not span_context.is_valid:
|
|
69
|
+
return True
|
|
70
|
+
if trace_state_marks_runner_root(getattr(span_context, "trace_state", None)):
|
|
71
|
+
return True
|
|
72
|
+
if getattr(span_context, "is_remote", False):
|
|
73
|
+
return False
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def bind_runner_rooted_trace(ctx: Any, rooted: bool) -> Any:
|
|
78
|
+
"""Return ``ctx`` with the runner-rooted flag set for descendant spans."""
|
|
79
|
+
from opentelemetry import context
|
|
80
|
+
|
|
81
|
+
return context.set_value(_runner_rooted_key(), rooted, ctx)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def runner_rooted_trace_active() -> bool:
|
|
85
|
+
"""True when the active span's trace was created by a runner, not a caller.
|
|
86
|
+
|
|
87
|
+
The flag set at span entry wins. Without it, a remote parent that carries
|
|
88
|
+
the marker — or any local root — is treated as runner-created so guardrail
|
|
89
|
+
content stays off unless a caller trace was already bound.
|
|
90
|
+
"""
|
|
91
|
+
try:
|
|
92
|
+
from opentelemetry import context, trace
|
|
93
|
+
except ImportError:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
explicit = context.get_value(_runner_rooted_key())
|
|
97
|
+
if explicit is True:
|
|
98
|
+
return True
|
|
99
|
+
if explicit is False:
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
span = trace.get_current_span()
|
|
103
|
+
span_context = span.get_span_context()
|
|
104
|
+
if trace_state_marks_runner_root(getattr(span_context, "trace_state", None)):
|
|
105
|
+
return True
|
|
106
|
+
parent = getattr(span, "parent", None)
|
|
107
|
+
if parent is not None and getattr(parent, "is_valid", False):
|
|
108
|
+
if trace_state_marks_runner_root(getattr(parent, "trace_state", None)):
|
|
109
|
+
return True
|
|
110
|
+
if getattr(parent, "is_remote", False):
|
|
111
|
+
return False
|
|
112
|
+
# Parent was created in this process and nobody bound a caller trace.
|
|
113
|
+
return True
|
|
114
|
+
if span_context is not None and span_context.is_valid:
|
|
115
|
+
if getattr(span_context, "is_remote", False):
|
|
116
|
+
return trace_state_marks_runner_root(getattr(span_context, "trace_state", None))
|
|
117
|
+
return True
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@contextmanager
|
|
122
|
+
def runner_trace_scope(parent_context: Any) -> Iterator[None]:
|
|
123
|
+
"""Attach the runner-rooted flag for the span about to be started.
|
|
124
|
+
|
|
125
|
+
``start_as_current_span`` copies the ambient context, so the flag has to
|
|
126
|
+
be attached before the span or nested ``tls_client`` calls will not see it.
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
from opentelemetry import context as otel_context
|
|
130
|
+
except ImportError:
|
|
131
|
+
yield
|
|
132
|
+
return
|
|
133
|
+
rooted = parent_context_is_runner_rooted(parent_context)
|
|
134
|
+
token = otel_context.attach(bind_runner_rooted_trace(otel_context.get_current(), rooted))
|
|
135
|
+
try:
|
|
136
|
+
yield
|
|
137
|
+
finally:
|
|
138
|
+
otel_context.detach(token)
|
|
@@ -107,14 +107,17 @@ Only GET, HEAD and OPTIONS retry 429/503, at most three times; `Retry-After` is
|
|
|
107
107
|
at 30 seconds. Each invocation carries a 30-second budget between requests, redirects,
|
|
108
108
|
response chunks and retry waits. Every request
|
|
109
109
|
uses its remaining budget for HTTPX's standard connect, read, write and pool timeouts;
|
|
110
|
-
the read timeout bounds each blocking read, as defined by HTTPX.
|
|
110
|
+
the read timeout bounds each blocking read, as defined by HTTPX. Requests carry
|
|
111
|
+
`User-Agent: agent-engine-connector` unless the connector sets its own in
|
|
112
|
+
`auth.headers`, matched case-insensitively.
|
|
111
113
|
|
|
112
114
|
HTTP failures, including rejected provider redirects, use `httpx.HTTPStatusError`,
|
|
113
115
|
and transport failures use the existing
|
|
114
116
|
timeout/connection exception types recognized by `classify_tool_api_error`. An HTTP
|
|
115
117
|
error may retain a bounded provider error body (at most 4 KB) so the shared classifier
|
|
116
|
-
can surface the provider's own explanation
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
can surface the provider's own explanation: a recognized JSON error field, or a
|
|
119
|
+
plain-text body that is not HTML markup, up to its first link. The retained body is
|
|
120
|
+
never logged; the classifier applies rudimentary hygiene to the extracted explanation
|
|
121
|
+
— control characters dropped, URL-shaped text rejected, exact credential values
|
|
122
|
+
redacted, result bounded. This is best-effort, not a guarantee. Oversized bodies, redirect locations,
|
|
120
123
|
and credential-bearing request objects are never retained.
|
|
@@ -39,6 +39,9 @@ MAX_RETRIES = 3
|
|
|
39
39
|
# Mirrors the classifier's envelope cap: only a body small enough to be parsed
|
|
40
40
|
# as a provider error envelope is retained on a raised HTTP error.
|
|
41
41
|
MAX_ERROR_ENVELOPE_BYTES = 4096
|
|
42
|
+
# Sent when the connector supplies none: the bare transport skips httpx.Client,
|
|
43
|
+
# which normally adds one, and some providers refuse requests without it.
|
|
44
|
+
USER_AGENT = "agent-engine-connector"
|
|
42
45
|
|
|
43
46
|
|
|
44
47
|
def _origin(url: httpx.URL) -> tuple[str, str, int | None]:
|
|
@@ -83,9 +86,15 @@ class ConnectorExecutor:
|
|
|
83
86
|
):
|
|
84
87
|
raise ValueError("connector path credential must be materialized before execution")
|
|
85
88
|
self._operations = {tool.name: tool for tool in self._definitions.tools}
|
|
86
|
-
# The transport provides pooling without Client's cookie or redirect state
|
|
89
|
+
# The transport provides pooling without Client's cookie or redirect state,
|
|
90
|
+
# and ignores proxy and netrc settings. Trust still follows SSL_CERT_FILE /
|
|
91
|
+
# SSL_CERT_DIR so a TLS-inspecting gateway's CA (`agentengine dev up
|
|
92
|
+
# --ca-bundle`) is honoured; the process environment is tenant-owned, so
|
|
93
|
+
# this trusts nothing the tenant could not already change in-process.
|
|
87
94
|
self._transport = (
|
|
88
|
-
transport
|
|
95
|
+
transport
|
|
96
|
+
if transport is not None
|
|
97
|
+
else httpx.HTTPTransport(trust_env=False, verify=httpx.create_ssl_context())
|
|
89
98
|
)
|
|
90
99
|
self._timeout_seconds = timeout_seconds
|
|
91
100
|
|
|
@@ -187,6 +196,8 @@ class ConnectorExecutor:
|
|
|
187
196
|
content, content_type = self._request_body(tool, arguments)
|
|
188
197
|
if content_type:
|
|
189
198
|
headers["Content-Type"] = content_type
|
|
199
|
+
if not any(name.lower() == "user-agent" for name in headers):
|
|
200
|
+
headers["User-Agent"] = USER_AGENT
|
|
190
201
|
url = httpx.URL(base_url + path)
|
|
191
202
|
if query:
|
|
192
203
|
url = url.copy_merge_params(query)
|
|
@@ -31,8 +31,10 @@ from agent_engine_runner_shared.context import (
|
|
|
31
31
|
get_current_oe_owner_url,
|
|
32
32
|
report_oe_owner_url_failure,
|
|
33
33
|
)
|
|
34
|
-
from agent_engine_runner_shared.progress import
|
|
34
|
+
from agent_engine_runner_shared.progress import _post_chunk_owner_first
|
|
35
35
|
from agent_engine_runner_shared.server.chunk_types import CUSTOM_EVENT
|
|
36
|
+
from agent_engine_runner_shared.tls_client import get_shared_client
|
|
37
|
+
from agent_engine_runner_shared.utils import PROGRESS_TIMEOUT_SECS
|
|
36
38
|
|
|
37
39
|
logger = logging.getLogger(__name__)
|
|
38
40
|
_JSON_OBJECT_ADAPTER = TypeAdapter(dict[str, JsonValue], config=ConfigDict(allow_inf_nan=False))
|
|
@@ -154,7 +156,7 @@ class OEHTTPCustomEventTransport:
|
|
|
154
156
|
if not execution_id or not oe_url:
|
|
155
157
|
return
|
|
156
158
|
try:
|
|
157
|
-
client =
|
|
159
|
+
client = get_shared_client(oe_url)
|
|
158
160
|
_post_chunk_owner_first(
|
|
159
161
|
client,
|
|
160
162
|
service_url=f"{oe_url.rstrip('/')}/stream/chunk",
|
|
@@ -165,6 +167,7 @@ class OEHTTPCustomEventTransport:
|
|
|
165
167
|
"custom_event": dict(payload),
|
|
166
168
|
},
|
|
167
169
|
on_owner_failure=report_oe_owner_url_failure,
|
|
170
|
+
timeout=PROGRESS_TIMEOUT_SECS,
|
|
168
171
|
)
|
|
169
172
|
except Exception as exc: # noqa: BLE001 - best-effort; never fail the tool
|
|
170
173
|
logger.debug("emit_custom_event: failed to send chunk: %s", exc)
|
|
@@ -41,7 +41,7 @@ _SECRET_INLINE_PATTERN = re.compile(
|
|
|
41
41
|
r"([\"']?\s*[=:]\s*)"
|
|
42
42
|
r"(\"(?:\\.|[^\"\\])*\"|'(?:\\.|[^'\\])*'|\"(?:\\.|[^\"\\])*$|'(?:\\.|[^'\\])*$|[^\s,]+(?:,(?!\s*[\"']?[A-Za-z0-9_.\-]+[\"']?\s*[=:])[^\s,]+)*)"
|
|
43
43
|
)
|
|
44
|
-
_BEARER_PATTERN = re.compile(r"(?i)\b(bearer)\s+[A-Za-z0-9._
|
|
44
|
+
_BEARER_PATTERN = re.compile(r"(?i)\b(bearer)\s+[A-Za-z0-9._\-+/=~]+")
|
|
45
45
|
# Key-name blocklist for structured payloads: a bare secret under a
|
|
46
46
|
# secret-named field matches no inline content pattern, so the field name
|
|
47
47
|
# itself must trigger masking.
|
|
@@ -38,12 +38,21 @@ from __future__ import annotations
|
|
|
38
38
|
import importlib
|
|
39
39
|
import logging
|
|
40
40
|
import os
|
|
41
|
+
import re
|
|
41
42
|
import sys
|
|
43
|
+
import threading
|
|
42
44
|
import traceback
|
|
43
45
|
from typing import NoReturn
|
|
46
|
+
from urllib.parse import urlsplit
|
|
47
|
+
from uuid import UUID
|
|
44
48
|
|
|
45
49
|
from agent_engine_runner_shared.error_reporting import _redact_text
|
|
46
|
-
from agent_engine_runner_shared.mcp_oauth_secret import
|
|
50
|
+
from agent_engine_runner_shared.mcp_oauth_secret import (
|
|
51
|
+
materialize_mcp_oauth_secret_cache,
|
|
52
|
+
mcp_oauth_secret_values,
|
|
53
|
+
)
|
|
54
|
+
from agent_engine_runner_shared.startup_state import has_startup_completed, reset_startup_state
|
|
55
|
+
from agent_engine_runner_shared.tool_api_error import is_credential_name
|
|
47
56
|
from agent_engine_runner_shared.utils import get_runtime_mode, setup_logging
|
|
48
57
|
|
|
49
58
|
logger = logging.getLogger(__name__)
|
|
@@ -61,6 +70,93 @@ _TERMINATION_LOG_PATH = "/dev/termination-log"
|
|
|
61
70
|
# since there's no cross-language shared package for this).
|
|
62
71
|
_TERMINATION_MESSAGE_MAX_BYTES = 4 * 1024
|
|
63
72
|
_TERMINATION_MESSAGE_MAX_LINES = 40
|
|
73
|
+
_STARTUP_REPORT_DEADLINE_SECONDS = 2.0
|
|
74
|
+
_STARTUP_REPORT_MAX_BYTES = 512
|
|
75
|
+
_STARTUP_REPORT_INPUT_BYTES = 4096
|
|
76
|
+
_CONTROL_CHARS = re.compile(r"[\x00-\x1f\x7f-\x9f\u2028\u2029]")
|
|
77
|
+
_startup_secrets: tuple[str, ...] = ()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _snapshot_startup_secrets() -> tuple[str, ...]:
|
|
81
|
+
"""Capture credential values before OAuth materialization removes them from the env."""
|
|
82
|
+
values = {value for name, value in os.environ.items() if value and is_credential_name(name)}
|
|
83
|
+
values.update(mcp_oauth_secret_values())
|
|
84
|
+
values.discard("")
|
|
85
|
+
# Longest first so a secret containing another is replaced whole.
|
|
86
|
+
return tuple(sorted(values, key=len, reverse=True))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _startup_report_text(text: str) -> str:
|
|
90
|
+
# Truncating before scrubbing could cut a credential in half and defeat redaction.
|
|
91
|
+
if len(text.encode("utf-8", errors="replace")) > _STARTUP_REPORT_INPUT_BYTES:
|
|
92
|
+
return "Startup error message exceeded the reporting limit"
|
|
93
|
+
# Known values go first: a pattern that redacts only part of a secret would
|
|
94
|
+
# leave the rest unmatchable by its exact value.
|
|
95
|
+
for value in _startup_secrets:
|
|
96
|
+
text = text.replace(value, "<redacted>")
|
|
97
|
+
text = _redact_text(text)
|
|
98
|
+
text = _CONTROL_CHARS.sub(" ", text)
|
|
99
|
+
return text.encode("utf-8")[:_STARTUP_REPORT_MAX_BYTES].decode("utf-8", errors="ignore")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _boot_error_url() -> str | None:
|
|
103
|
+
raw_boot_id = os.environ.get("AGENTIC_BOOT_ID", "")
|
|
104
|
+
oe_url = os.environ.get("OE_URL", "")
|
|
105
|
+
try:
|
|
106
|
+
boot_id = UUID(raw_boot_id)
|
|
107
|
+
origin = urlsplit(oe_url)
|
|
108
|
+
hostname = origin.hostname
|
|
109
|
+
except ValueError:
|
|
110
|
+
return None
|
|
111
|
+
# Match the TypeScript launcher: only the canonical dashed form is a boot ID.
|
|
112
|
+
if str(boot_id) != raw_boot_id.lower():
|
|
113
|
+
return None
|
|
114
|
+
if origin.scheme not in {"http", "https"} or not hostname:
|
|
115
|
+
return None
|
|
116
|
+
if origin.username or origin.password:
|
|
117
|
+
return None
|
|
118
|
+
return f"{oe_url.rstrip('/')}/boots/{boot_id}/errors"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _report_startup_error(summary: str, exc: BaseException | None, code: int) -> None:
|
|
122
|
+
"""Best-effort POST of a scrubbed startup error to OE; never raises."""
|
|
123
|
+
try:
|
|
124
|
+
_send_startup_report(summary, exc, code)
|
|
125
|
+
except Exception:
|
|
126
|
+
logger.debug("Startup report could not be prepared")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _send_startup_report(summary: str, exc: BaseException | None, code: int) -> None:
|
|
130
|
+
"""POST a scrubbed startup error to OE, bounded by one deadline."""
|
|
131
|
+
if has_startup_completed():
|
|
132
|
+
return
|
|
133
|
+
url = _boot_error_url()
|
|
134
|
+
if url is None:
|
|
135
|
+
logger.debug("Skipping startup report without a valid boot ID and OE URL")
|
|
136
|
+
return
|
|
137
|
+
body = {
|
|
138
|
+
"sandbox": "tool" if _resolve_runner_mode() == "tool" else "agent",
|
|
139
|
+
"exitCode": code,
|
|
140
|
+
"errorType": _startup_report_text(type(exc).__name__ if exc else "StartupError"),
|
|
141
|
+
"message": _startup_report_text(f"{summary}: {exc}" if exc else summary),
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
def send() -> None:
|
|
145
|
+
from agent_engine_runner_shared.tls_client import create_httpx_client_with_tls
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
with create_httpx_client_with_tls(url, _STARTUP_REPORT_DEADLINE_SECONDS) as client:
|
|
149
|
+
# stream() so the response body is never read.
|
|
150
|
+
with client.stream("POST", url, json=body, follow_redirects=False) as response:
|
|
151
|
+
logger.debug("Startup report returned status %d", response.status_code)
|
|
152
|
+
except Exception:
|
|
153
|
+
logger.debug("Startup report could not be delivered")
|
|
154
|
+
|
|
155
|
+
# httpx timeouts are per phase; a joined daemon thread bounds the whole
|
|
156
|
+
# exchange (DNS, TLS, headers) and works even when called from an event loop.
|
|
157
|
+
worker = threading.Thread(target=send, daemon=True)
|
|
158
|
+
worker.start()
|
|
159
|
+
worker.join(timeout=_STARTUP_REPORT_DEADLINE_SECONDS)
|
|
64
160
|
|
|
65
161
|
|
|
66
162
|
def _bound_text(
|
|
@@ -161,6 +257,7 @@ def _fatal(summary: str, exc: BaseException | None = None, code: int = 1) -> NoR
|
|
|
161
257
|
else:
|
|
162
258
|
logger.error(summary)
|
|
163
259
|
_write_termination_message(summary, exc)
|
|
260
|
+
_report_startup_error(summary, exc, code)
|
|
164
261
|
sys.exit(code)
|
|
165
262
|
|
|
166
263
|
|
|
@@ -207,14 +304,17 @@ def _resolve_entrypoint() -> tuple[str, str]:
|
|
|
207
304
|
|
|
208
305
|
def main() -> None:
|
|
209
306
|
"""Entry point invoked by ``python -m agent_engine_runner_shared.launcher``."""
|
|
307
|
+
global _startup_secrets
|
|
308
|
+
reset_startup_state()
|
|
309
|
+
_startup_secrets = _snapshot_startup_secrets()
|
|
210
310
|
# Install before any import/entrypoint work. After this, print-to-stderr
|
|
211
311
|
# is captured as WARNING (not ERROR), so failure paths must use the logger.
|
|
212
312
|
setup_logging(app_name="launcher", mode=_resolve_runner_mode())
|
|
213
313
|
|
|
214
314
|
try:
|
|
215
315
|
materialize_mcp_oauth_secret_cache()
|
|
216
|
-
except
|
|
217
|
-
_fatal("Cannot materialize MCP OAuth credentials", exc)
|
|
316
|
+
except Exception as exc:
|
|
317
|
+
_fatal("Cannot materialize MCP OAuth credentials", exc, code=EXIT_STARTUP_CRASH)
|
|
218
318
|
|
|
219
319
|
module_path, target_name = _resolve_entrypoint()
|
|
220
320
|
|