gatewaysdk 0.3.2__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.
- gatewaysdk/__init__.py +540 -0
- gatewaysdk/adapter/__init__.py +15 -0
- gatewaysdk/adapter/base.py +94 -0
- gatewaysdk/adapter/messages.py +270 -0
- gatewaysdk/adapter/triplet.py +1026 -0
- gatewaysdk/algorithm/__init__.py +39 -0
- gatewaysdk/algorithm/apo/__init__.py +5 -0
- gatewaysdk/algorithm/apo/apo.py +898 -0
- gatewaysdk/algorithm/apo/prompts/apply_edit_variant01.poml +22 -0
- gatewaysdk/algorithm/apo/prompts/apply_edit_variant02.poml +18 -0
- gatewaysdk/algorithm/apo/prompts/text_gradient_variant01.poml +18 -0
- gatewaysdk/algorithm/apo/prompts/text_gradient_variant02.poml +16 -0
- gatewaysdk/algorithm/apo/prompts/text_gradient_variant03.poml +107 -0
- gatewaysdk/algorithm/base.py +262 -0
- gatewaysdk/algorithm/decorator.py +264 -0
- gatewaysdk/algorithm/evals/__init__.py +7 -0
- gatewaysdk/algorithm/evals/evals.py +217 -0
- gatewaysdk/algorithm/fast.py +250 -0
- gatewaysdk/algorithm/gepa/__init__.py +61 -0
- gatewaysdk/algorithm/gepa/adapter.py +495 -0
- gatewaysdk/algorithm/gepa/gepa.py +570 -0
- gatewaysdk/algorithm/gepa/lib/__init__.py +18 -0
- gatewaysdk/algorithm/gepa/lib/adapters/README.md +12 -0
- gatewaysdk/algorithm/gepa/lib/adapters/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/README.md +341 -0
- gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/__init__.py +1 -0
- gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
- gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/requirements.txt +1 -0
- gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/README.md +0 -0
- gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/default_adapter.py +209 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/README.md +7 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/dspy_adapter.py +307 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/README.md +99 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
- gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/full_program_adapter.py +268 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/GEPA_RAG.md +621 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/__init__.py +56 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
- gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
- gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/README.md +552 -0
- gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/__init__.py +37 -0
- gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_adapter.py +699 -0
- gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_client.py +364 -0
- gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/README.md +9 -0
- gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
- gatewaysdk/algorithm/gepa/lib/api.py +382 -0
- gatewaysdk/algorithm/gepa/lib/core/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/core/adapter.py +180 -0
- gatewaysdk/algorithm/gepa/lib/core/data_loader.py +74 -0
- gatewaysdk/algorithm/gepa/lib/core/engine.py +379 -0
- gatewaysdk/algorithm/gepa/lib/core/result.py +233 -0
- gatewaysdk/algorithm/gepa/lib/core/state.py +636 -0
- gatewaysdk/algorithm/gepa/lib/examples/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/examples/aime.py +24 -0
- gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/eval_default.py +111 -0
- gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/instruction_prompt.txt +9 -0
- gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/optimal_prompt.txt +24 -0
- gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/train_anymaths.py +177 -0
- gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/arc_agi.ipynb +25705 -0
- gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/example.ipynb +348 -0
- gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/__init__.py +4 -0
- gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/mcp_optimization_example.py +456 -0
- gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/RAG_GUIDE.md +613 -0
- gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/__init__.py +9 -0
- gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/rag_optimization.py +820 -0
- gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/requirements-rag.txt +29 -0
- gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/instruction_prompt.txt +16 -0
- gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/terminus.txt +9 -0
- gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/train_terminus.py +161 -0
- gatewaysdk/algorithm/gepa/lib/gepa_utils.py +117 -0
- gatewaysdk/algorithm/gepa/lib/logging/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/logging/experiment_tracker.py +187 -0
- gatewaysdk/algorithm/gepa/lib/logging/logger.py +75 -0
- gatewaysdk/algorithm/gepa/lib/logging/utils.py +103 -0
- gatewaysdk/algorithm/gepa/lib/proposer/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/proposer/base.py +31 -0
- gatewaysdk/algorithm/gepa/lib/proposer/merge.py +357 -0
- gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/base.py +49 -0
- gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/reflective_mutation.py +176 -0
- gatewaysdk/algorithm/gepa/lib/py.typed +0 -0
- gatewaysdk/algorithm/gepa/lib/strategies/__init__.py +0 -0
- gatewaysdk/algorithm/gepa/lib/strategies/batch_sampler.py +77 -0
- gatewaysdk/algorithm/gepa/lib/strategies/candidate_selector.py +50 -0
- gatewaysdk/algorithm/gepa/lib/strategies/component_selector.py +36 -0
- gatewaysdk/algorithm/gepa/lib/strategies/eval_policy.py +64 -0
- gatewaysdk/algorithm/gepa/lib/strategies/instruction_proposal.py +126 -0
- gatewaysdk/algorithm/gepa/lib/utils/__init__.py +10 -0
- gatewaysdk/algorithm/gepa/lib/utils/stop_condition.py +196 -0
- gatewaysdk/algorithm/gepa/tracing.py +105 -0
- gatewaysdk/algorithm/utils.py +177 -0
- gatewaysdk/algorithm/verl/__init__.py +5 -0
- gatewaysdk/algorithm/verl/interface.py +202 -0
- gatewaysdk/automations.py +111 -0
- gatewaysdk/benchmark_hub/README.md +88 -0
- gatewaysdk/benchmark_hub/__init__.py +119 -0
- gatewaysdk/benchmark_hub/_archive.py +189 -0
- gatewaysdk/benchmark_hub/_tar.py +6 -0
- gatewaysdk/benchmark_hub/client.py +992 -0
- gatewaysdk/benchmark_hub/dispatch_shard.py +34 -0
- gatewaysdk/benchmark_hub/eval_config.py +20 -0
- gatewaysdk/benchmark_hub/evals.py +351 -0
- gatewaysdk/benchmark_hub/harbor_adapter.py +673 -0
- gatewaysdk/benchmark_hub/path_utils.py +81 -0
- gatewaysdk/benchmark_hub/save_utils.py +101 -0
- gatewaysdk/benchmark_hub/verifiers_adapter.py +327 -0
- gatewaysdk/benchmark_hub/versioning.py +72 -0
- gatewaysdk/build.py +515 -0
- gatewaysdk/cli/__init__.py +58 -0
- gatewaysdk/cli/agent_runner.py +132 -0
- gatewaysdk/cli/http_client.py +115 -0
- gatewaysdk/cli/platform.py +4086 -0
- gatewaysdk/cli/prometheus.py +115 -0
- gatewaysdk/cli/release_gate.py +215 -0
- gatewaysdk/cli/store.py +131 -0
- gatewaysdk/cli/vllm.py +29 -0
- gatewaysdk/client.py +406 -0
- gatewaysdk/config.py +348 -0
- gatewaysdk/connectors/__init__.py +25 -0
- gatewaysdk/connectors/client.py +203 -0
- gatewaysdk/connectors/skill.py +25 -0
- gatewaysdk/connectors/template.py +106 -0
- gatewaysdk/context.py +606 -0
- gatewaysdk/emitter/__init__.py +43 -0
- gatewaysdk/emitter/annotation.py +370 -0
- gatewaysdk/emitter/exception.py +54 -0
- gatewaysdk/emitter/message.py +61 -0
- gatewaysdk/emitter/object.py +117 -0
- gatewaysdk/emitter/reward.py +320 -0
- gatewaysdk/env_var.py +156 -0
- gatewaysdk/environment/__init__.py +108 -0
- gatewaysdk/environment/_bundle.py +281 -0
- gatewaysdk/environment/_harbor.py +276 -0
- gatewaysdk/environment/_materialize.py +97 -0
- gatewaysdk/environment/_tar.py +33 -0
- gatewaysdk/environment/_world.py +346 -0
- gatewaysdk/environment/core.py +527 -0
- gatewaysdk/environment/errors.py +58 -0
- gatewaysdk/environment/runtime.py +150 -0
- gatewaysdk/environment/schema/__init__.py +35 -0
- gatewaysdk/environment/schema/__main__.py +225 -0
- gatewaysdk/environment/schema/_slack_fidelity.py +116 -0
- gatewaysdk/environment/schema/_slack_scenario.py +183 -0
- gatewaysdk/environment/schema/api.py +1628 -0
- gatewaysdk/environment/schema/batch.py +755 -0
- gatewaysdk/environment/schema/compiler.py +615 -0
- gatewaysdk/environment/schema/conform.py +428 -0
- gatewaysdk/environment/schema/connector.py +777 -0
- gatewaysdk/environment/schema/connectors/apple-business-manager/handlers.py +17 -0
- gatewaysdk/environment/schema/connectors/apple-business-manager/parity.json +28 -0
- gatewaysdk/environment/schema/connectors/apple-business-manager/provenance.json +233 -0
- gatewaysdk/environment/schema/connectors/apple-business-manager/scope.toml +112 -0
- gatewaysdk/environment/schema/connectors/apple-business-manager/world.json +1380 -0
- gatewaysdk/environment/schema/connectors/base.json +28 -0
- gatewaysdk/environment/schema/connectors/custom/handlers.py +18 -0
- gatewaysdk/environment/schema/connectors/custom/world.json +123 -0
- gatewaysdk/environment/schema/connectors/github/handlers.py +81 -0
- gatewaysdk/environment/schema/connectors/github/parity.json +37 -0
- gatewaysdk/environment/schema/connectors/github/provenance.json +134 -0
- gatewaysdk/environment/schema/connectors/github/scope.toml +158 -0
- gatewaysdk/environment/schema/connectors/github/world.json +5869 -0
- gatewaysdk/environment/schema/connectors/google-calendar/handlers.py +23 -0
- gatewaysdk/environment/schema/connectors/google-calendar/world.json +209 -0
- gatewaysdk/environment/schema/connectors/google-drive/handlers.py +18 -0
- gatewaysdk/environment/schema/connectors/google-drive/world.json +286 -0
- gatewaysdk/environment/schema/connectors/jamf/handlers.py +34 -0
- gatewaysdk/environment/schema/connectors/jamf/parity.json +49 -0
- gatewaysdk/environment/schema/connectors/jamf/provenance.json +181 -0
- gatewaysdk/environment/schema/connectors/jamf/scope.toml +128 -0
- gatewaysdk/environment/schema/connectors/jamf/world.json +2218 -0
- gatewaysdk/environment/schema/connectors/jira/handlers.py +28 -0
- gatewaysdk/environment/schema/connectors/jira/world.json +389 -0
- gatewaysdk/environment/schema/connectors/kandji/handlers.py +38 -0
- gatewaysdk/environment/schema/connectors/kandji/parity.json +29 -0
- gatewaysdk/environment/schema/connectors/kandji/provenance.json +152 -0
- gatewaysdk/environment/schema/connectors/kandji/scope.toml +120 -0
- gatewaysdk/environment/schema/connectors/kandji/world.json +765 -0
- gatewaysdk/environment/schema/connectors/linear/handlers.py +20 -0
- gatewaysdk/environment/schema/connectors/linear/world.json +363 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/fidelity.json +45 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/handlers.py +1 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/provenance.json +851 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/scope.md +231 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/teams-types.json +1710 -0
- gatewaysdk/environment/schema/connectors/microsoft-teams/world.json +858 -0
- gatewaysdk/environment/schema/connectors/netsuite/handlers.py +32 -0
- gatewaysdk/environment/schema/connectors/netsuite/parity.json +50 -0
- gatewaysdk/environment/schema/connectors/netsuite/provenance.json +137 -0
- gatewaysdk/environment/schema/connectors/netsuite/scope.toml +78 -0
- gatewaysdk/environment/schema/connectors/netsuite/world.json +16243 -0
- gatewaysdk/environment/schema/connectors/salesforce/handlers.py +806 -0
- gatewaysdk/environment/schema/connectors/salesforce/parity.json +46 -0
- gatewaysdk/environment/schema/connectors/salesforce/provenance.json +143 -0
- gatewaysdk/environment/schema/connectors/salesforce/scope.toml +174 -0
- gatewaysdk/environment/schema/connectors/salesforce/world.json +4695 -0
- gatewaysdk/environment/schema/connectors/slack/MODEL.md +236 -0
- gatewaysdk/environment/schema/connectors/slack/capabilities.json +1039 -0
- gatewaysdk/environment/schema/connectors/slack/handlers.py +762 -0
- gatewaysdk/environment/schema/connectors/slack/parity.json +65 -0
- gatewaysdk/environment/schema/connectors/slack/provenance.json +294 -0
- gatewaysdk/environment/schema/connectors/slack/scope.toml +44 -0
- gatewaysdk/environment/schema/connectors/slack/world.json +4993 -0
- gatewaysdk/environment/schema/connectors/workday/handlers.py +75 -0
- gatewaysdk/environment/schema/connectors/workday/parity.json +36 -0
- gatewaysdk/environment/schema/connectors/workday/provenance.json +179 -0
- gatewaysdk/environment/schema/connectors/workday/scope.toml +180 -0
- gatewaysdk/environment/schema/connectors/workday/world.json +806 -0
- gatewaysdk/environment/schema/data.py +593 -0
- gatewaysdk/environment/schema/extract.py +263 -0
- gatewaysdk/environment/schema/host.py +2437 -0
- gatewaysdk/environment/schema/host_surfaces.py +275 -0
- gatewaysdk/environment/schema/platform.py +1272 -0
- gatewaysdk/environment/schema/scaffold.py +250 -0
- gatewaysdk/environment/schema/skill.py +118 -0
- gatewaysdk/environment/schema/skills/agents/connector-template-author.md +202 -0
- gatewaysdk/environment/schema/skills/connector-schema-authoring/CONNECTORS.md +331 -0
- gatewaysdk/environment/schema/skills/connector-schema-authoring/CONVENTIONS.md +100 -0
- gatewaysdk/environment/schema/skills/connector-schema-authoring/SKILL.md +313 -0
- gatewaysdk/environment/schema/skills/world-data-ingestion/ROWS.md +223 -0
- gatewaysdk/environment/schema/skills/world-data-ingestion/SKILL.md +293 -0
- gatewaysdk/environment/schema/skills/worlds-getting-started/SKILL.md +390 -0
- gatewaysdk/environment/schema/slack.py +757 -0
- gatewaysdk/environment/schema/snapshot.py +479 -0
- gatewaysdk/environment/schema/store.py +904 -0
- gatewaysdk/environment/schema/tasks.py +525 -0
- gatewaysdk/environment/schema/tools_world.py +322 -0
- gatewaysdk/environment/schema/validation.py +577 -0
- gatewaysdk/environment/schema/worker.py +78 -0
- gatewaysdk/environment/schema/workers.py +500 -0
- gatewaysdk/environment/schema/world_tests.py +336 -0
- gatewaysdk/environments/__init__.py +24 -0
- gatewaysdk/environments/client.py +486 -0
- gatewaysdk/environments/types.py +318 -0
- gatewaysdk/execution/__init__.py +15 -0
- gatewaysdk/execution/base.py +64 -0
- gatewaysdk/execution/client_server.py +443 -0
- gatewaysdk/execution/events.py +69 -0
- gatewaysdk/execution/inter_process.py +16 -0
- gatewaysdk/execution/shared_memory.py +282 -0
- gatewaysdk/experiments/__init__.py +90 -0
- gatewaysdk/experiments/assignment.py +177 -0
- gatewaysdk/experiments/client.py +877 -0
- gatewaysdk/experiments/exposure.py +222 -0
- gatewaysdk/experiments/types.py +81 -0
- gatewaysdk/importers/__init__.py +49 -0
- gatewaysdk/importers/_normalize.py +91 -0
- gatewaysdk/importers/builder.py +173 -0
- gatewaysdk/importers/client.py +95 -0
- gatewaysdk/importers/langsmith.py +196 -0
- gatewaysdk/importers/recipes.py +249 -0
- gatewaysdk/instrumentation/__init__.py +300 -0
- gatewaysdk/instrumentation/agentops.py +314 -0
- gatewaysdk/instrumentation/agentops_langchain.py +45 -0
- gatewaysdk/instrumentation/base.py +119 -0
- gatewaysdk/instrumentation/litellm.py +83 -0
- gatewaysdk/instrumentation/registry.py +273 -0
- gatewaysdk/instrumentation/vllm.py +81 -0
- gatewaysdk/instrumentation/weave.py +500 -0
- gatewaysdk/integrations/__init__.py +15 -0
- gatewaysdk/integrations/gateway/__init__.py +11 -0
- gatewaysdk/integrations/gateway/client.py +171 -0
- gatewaysdk/integrations/tool_access.py +549 -0
- gatewaysdk/litagent/__init__.py +11 -0
- gatewaysdk/litagent/decorator.py +536 -0
- gatewaysdk/litagent/litagent.py +252 -0
- gatewaysdk/llm_proxy.py +1742 -0
- gatewaysdk/logging.py +370 -0
- gatewaysdk/memory.py +278 -0
- gatewaysdk/personas.py +186 -0
- gatewaysdk/platform/__init__.py +17 -0
- gatewaysdk/platform/builder.py +221 -0
- gatewaysdk/platform/compatibility.py +67 -0
- gatewaysdk/platform/manifest.py +185 -0
- gatewaysdk/platform/orchestrator.py +901 -0
- gatewaysdk/platform/registry.py +122 -0
- gatewaysdk/platform/worker.py +864 -0
- gatewaysdk/replay/__init__.py +1032 -0
- gatewaysdk/replay/pytest.py +56 -0
- gatewaysdk/reward.py +7 -0
- gatewaysdk/run.py +1781 -0
- gatewaysdk/runner/__init__.py +11 -0
- gatewaysdk/runner/agent.py +878 -0
- gatewaysdk/runner/base.py +182 -0
- gatewaysdk/runner/legacy.py +309 -0
- gatewaysdk/security.py +700 -0
- gatewaysdk/semconv.py +170 -0
- gatewaysdk/server.py +399 -0
- gatewaysdk/sessions.py +282 -0
- gatewaysdk/store/__init__.py +45 -0
- gatewaysdk/store/base.py +908 -0
- gatewaysdk/store/client_server.py +2093 -0
- gatewaysdk/store/collection/__init__.py +30 -0
- gatewaysdk/store/collection/base.py +587 -0
- gatewaysdk/store/collection/memory.py +970 -0
- gatewaysdk/store/collection/mongo.py +1412 -0
- gatewaysdk/store/collection_based.py +1823 -0
- gatewaysdk/store/gateway.py +983 -0
- gatewaysdk/store/gateway_listener.py +465 -0
- gatewaysdk/store/listener.py +58 -0
- gatewaysdk/store/memory.py +396 -0
- gatewaysdk/store/mongo.py +165 -0
- gatewaysdk/store/redis_stream.py +517 -0
- gatewaysdk/store/sqlite.py +3 -0
- gatewaysdk/store/threading.py +370 -0
- gatewaysdk/store/utils.py +142 -0
- gatewaysdk/tracer/__init__.py +14 -0
- gatewaysdk/tracer/base.py +286 -0
- gatewaysdk/tracer/dummy.py +106 -0
- gatewaysdk/tracer/otel.py +559 -0
- gatewaysdk/tracing/__init__.py +110 -0
- gatewaysdk/tracing/api.py +808 -0
- gatewaysdk/tracing/attributes.py +9 -0
- gatewaysdk/tracing/context.py +272 -0
- gatewaysdk/tracing/exporters/__init__.py +10 -0
- gatewaysdk/tracing/exporters/gateway.py +228 -0
- gatewaysdk/tracing/identity.py +288 -0
- gatewaysdk/tracing/init.py +620 -0
- gatewaysdk/tracing/instrumentors/__init__.py +15 -0
- gatewaysdk/tracing/instrumentors/claude_agent_sdk.py +766 -0
- gatewaysdk/tracing/instrumentors/instrumentation_principles.md +294 -0
- gatewaysdk/tracing/instrumentors/registry.py +352 -0
- gatewaysdk/tracing/mapping.py +729 -0
- gatewaysdk/tracing/processors.py +393 -0
- gatewaysdk/tracing/push.py +617 -0
- gatewaysdk/tracing/push_models.py +247 -0
- gatewaysdk/tracing/semconv.py +294 -0
- gatewaysdk/tracing/span_builder.py +356 -0
- gatewaysdk/trainer/__init__.py +6 -0
- gatewaysdk/trainer/init_utils.py +263 -0
- gatewaysdk/trainer/legacy.py +359 -0
- gatewaysdk/trainer/registry.py +12 -0
- gatewaysdk/trainer/trainer.py +638 -0
- gatewaysdk/types/__init__.py +63 -0
- gatewaysdk/types/core.py +556 -0
- gatewaysdk/types/resources.py +204 -0
- gatewaysdk/types/tracer.py +515 -0
- gatewaysdk/types/tracing.py +162 -0
- gatewaysdk/users.py +251 -0
- gatewaysdk/utils/__init__.py +1 -0
- gatewaysdk/utils/id.py +18 -0
- gatewaysdk/utils/metrics.py +1025 -0
- gatewaysdk/utils/otel.py +550 -0
- gatewaysdk/utils/otlp.py +556 -0
- gatewaysdk/utils/redact.py +22 -0
- gatewaysdk/utils/server_launcher.py +1045 -0
- gatewaysdk/utils/system_snapshot.py +90 -0
- gatewaysdk/verl/__init__.py +8 -0
- gatewaysdk/verl/__main__.py +6 -0
- gatewaysdk/verl/async_server.py +46 -0
- gatewaysdk/verl/config.yaml +27 -0
- gatewaysdk/verl/daemon.py +1154 -0
- gatewaysdk/verl/dataset.py +44 -0
- gatewaysdk/verl/entrypoint.py +248 -0
- gatewaysdk/verl/trainer.py +549 -0
- gatewaysdk/world_browser.py +748 -0
- gatewaysdk/world_data.py +453 -0
- gatewaysdk/world_sessions.py +978 -0
- gatewaysdk/world_tasks.py +285 -0
- gatewaysdk/world_tools.py +115 -0
- gatewaysdk/worlds.py +639 -0
- gatewaysdk-0.3.2.dist-info/METADATA +236 -0
- gatewaysdk-0.3.2.dist-info/RECORD +376 -0
- gatewaysdk-0.3.2.dist-info/WHEEL +4 -0
- gatewaysdk-0.3.2.dist-info/entry_points.txt +5 -0
- gatewaysdk-0.3.2.dist-info/licenses/LICENSE +19 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
# Copyright (c) Gateway. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Initialization and lifecycle management for GatewayDK tracing.
|
|
4
|
+
|
|
5
|
+
This module provides the core init(), shutdown(), and flush() functions
|
|
6
|
+
for managing the OpenTelemetry TracerProvider lifecycle.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import threading
|
|
15
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
16
|
+
|
|
17
|
+
from opentelemetry import trace
|
|
18
|
+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
19
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
20
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter
|
|
21
|
+
|
|
22
|
+
from .attributes import GATEWAY_ENVIRONMENT, GATEWAY_VERSION
|
|
23
|
+
from .exporters.gateway import gateway, is_gateway_configured
|
|
24
|
+
from .processors import LoggingSpanProcessor, TracingContextSpanProcessor
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from .identity import AgentIdentity
|
|
28
|
+
from openinference.instrumentation import TraceConfig
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
# Module-level state
|
|
33
|
+
_initialized = False
|
|
34
|
+
_init_lock = threading.Lock()
|
|
35
|
+
_provider: Optional[TracerProvider] = None
|
|
36
|
+
_processors: List[BatchSpanProcessor] = []
|
|
37
|
+
_export_count = 0
|
|
38
|
+
_batch_config: Dict[str, Any] = {} # Batch processor kwargs, set by init()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def init(
|
|
42
|
+
*,
|
|
43
|
+
agent: Optional[Union[str, dict, "AgentIdentity"]] = None,
|
|
44
|
+
trace_name: Optional[str] = None,
|
|
45
|
+
service_name: Optional[str] = None,
|
|
46
|
+
environment: Optional[str] = None,
|
|
47
|
+
version: Optional[str] = None,
|
|
48
|
+
# Gateway configuration (alternative to env vars)
|
|
49
|
+
gateway_host: Optional[str] = None,
|
|
50
|
+
gateway_public_key: Optional[str] = None,
|
|
51
|
+
gateway_secret_key: Optional[str] = None,
|
|
52
|
+
gateway_endpoint: Optional[str] = None,
|
|
53
|
+
instrument_default: bool = True,
|
|
54
|
+
exporters: Optional[List[SpanExporter]] = None,
|
|
55
|
+
trace_config: Optional["TraceConfig"] = None,
|
|
56
|
+
force: bool = False,
|
|
57
|
+
integrations: Optional[Dict[str, Any]] = None,
|
|
58
|
+
debug: Union[bool, str] = False,
|
|
59
|
+
# Batch processor tuning (passed through to BatchSpanProcessor)
|
|
60
|
+
batch_queue_size: Optional[int] = None,
|
|
61
|
+
batch_flush_interval: Optional[int] = None,
|
|
62
|
+
batch_max_export_size: Optional[int] = None,
|
|
63
|
+
) -> None:
|
|
64
|
+
"""Initialize GatewaySDK standalone tracing.
|
|
65
|
+
|
|
66
|
+
This function configures OpenTelemetry with a connection to Gateway
|
|
67
|
+
(if configured via environment variables), and automatically instruments
|
|
68
|
+
installed AI libraries (OpenAI, Anthropic, LiteLLM, OpenAI Agents SDK, etc.).
|
|
69
|
+
|
|
70
|
+
Provider Reuse Behavior:
|
|
71
|
+
- If no TracerProvider exists, creates one.
|
|
72
|
+
- If a TracerProvider exists and force=False, reuses it and adds
|
|
73
|
+
processors/exporters (avoiding duplicates).
|
|
74
|
+
- If force=True, replaces the existing TracerProvider.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
agent: The agent this process runs as — the one identity you declare.
|
|
78
|
+
A string id, an AgentIdentity, or a dict with id/name/version.
|
|
79
|
+
Falls back to GATEWAY_AGENT_ID / GATEWAY_AGENT_NAME /
|
|
80
|
+
GATEWAY_AGENT_VERSION. Every trace is stamped with the agent
|
|
81
|
+
automatically, and the agent is registered with the platform
|
|
82
|
+
control plane (best-effort, non-blocking) so it appears on the
|
|
83
|
+
Agents page before its first trace.
|
|
84
|
+
trace_name: Optional name for the trace.
|
|
85
|
+
service_name: Name of the service (mapped to resource attributes).
|
|
86
|
+
Defaults to "gatewaysdk-tracing".
|
|
87
|
+
environment: Environment name (e.g., "production", "staging", "development").
|
|
88
|
+
Sets `gateway.environment` resource attribute for filtering traces in Gateway.
|
|
89
|
+
version: Application version (e.g., "1.2.3", git SHA). Sets `gateway.version`
|
|
90
|
+
resource attribute for tracking regressions across versions.
|
|
91
|
+
gateway_host: Gateway server URL (e.g., "https://app.gateway.dev").
|
|
92
|
+
Overrides GATEWAY_HOST environment variable.
|
|
93
|
+
gateway_public_key: Gateway public key (pk-lf-...).
|
|
94
|
+
Overrides GATEWAY_PUBLIC_KEY environment variable.
|
|
95
|
+
gateway_secret_key: Gateway secret key (sk-lf-...).
|
|
96
|
+
Overrides GATEWAY_SECRET_KEY environment variable.
|
|
97
|
+
gateway_endpoint: Optional OTLP endpoint URL. Overrides GATEWAY_OTLP_ENDPOINT.
|
|
98
|
+
If not provided, derived from gateway_host.
|
|
99
|
+
instrument_default: Whether to automatically instrument the "core set"
|
|
100
|
+
of libraries (OpenAI Agents SDK, OpenAI, Anthropic, LiteLLM, etc.)
|
|
101
|
+
if installed. Defaults to True.
|
|
102
|
+
exporters: List of custom OpenTelemetry SpanExporters. If None and
|
|
103
|
+
Gateway credentials are configured (via params or env vars), auto-creates
|
|
104
|
+
an Gateway exporter.
|
|
105
|
+
trace_config: OpenInference TraceConfig for controlling capture behavior
|
|
106
|
+
(hiding inputs/outputs, etc.). Default captures all.
|
|
107
|
+
force: If True, replaces any existing global TracerProvider. If False
|
|
108
|
+
(default), reuses the existing provider and appends processors.
|
|
109
|
+
integrations: Dictionary for fine-grained control over integrations.
|
|
110
|
+
debug: Controls console logging of tracing activity. Accepts:
|
|
111
|
+
- False (default): Silent operation, no console output.
|
|
112
|
+
- True: Shortcut for "DEBUG" -- full firehose including every
|
|
113
|
+
span start/end, export results, and internal plumbing.
|
|
114
|
+
- "DEBUG": Same as True.
|
|
115
|
+
- "INFO": Recommended. Shows init summary, export success/failure,
|
|
116
|
+
instrumentor activation, and shutdown summary.
|
|
117
|
+
- "WARNING": Minimal. Only shows export failures and missing
|
|
118
|
+
exporter warnings.
|
|
119
|
+
- "ERROR": Only export failures and exceptions.
|
|
120
|
+
batch_queue_size: Max spans buffered in memory by BatchSpanProcessor.
|
|
121
|
+
Default: 2048. Increase for bulk import workloads to prevent
|
|
122
|
+
silent span drops. Wraps OTEL_BSP_MAX_QUEUE_SIZE.
|
|
123
|
+
batch_flush_interval: How often (in ms) the processor flushes spans.
|
|
124
|
+
Default: 5000. Decrease for lower-latency export.
|
|
125
|
+
Wraps OTEL_BSP_SCHEDULE_DELAY.
|
|
126
|
+
batch_max_export_size: Max spans per export call. Default: 512.
|
|
127
|
+
Wraps OTEL_BSP_MAX_EXPORT_BATCH_SIZE.
|
|
128
|
+
|
|
129
|
+
Example::
|
|
130
|
+
|
|
131
|
+
import gatewaysdk.tracing as tracing
|
|
132
|
+
|
|
133
|
+
# Minimal: auto-detect Gateway from env vars, auto-instrument
|
|
134
|
+
tracing.init()
|
|
135
|
+
|
|
136
|
+
# With environment and version for filtering in Gateway
|
|
137
|
+
tracing.init(
|
|
138
|
+
service_name="my-agent",
|
|
139
|
+
environment="production",
|
|
140
|
+
version="1.2.3",
|
|
141
|
+
instrument_default=True,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Explicit Gateway credentials (instead of env vars)
|
|
145
|
+
tracing.init(
|
|
146
|
+
service_name="my-agent",
|
|
147
|
+
environment="production",
|
|
148
|
+
version="1.2.3",
|
|
149
|
+
gateway_host="https://app.gateway.dev",
|
|
150
|
+
gateway_public_key="pk-lf-...",
|
|
151
|
+
gateway_secret_key="sk-lf-...",
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Ensure cleanup on shutdown
|
|
155
|
+
import atexit
|
|
156
|
+
atexit.register(tracing.shutdown)
|
|
157
|
+
"""
|
|
158
|
+
global _initialized, _provider
|
|
159
|
+
|
|
160
|
+
resolved_level = _resolve_debug_level(debug)
|
|
161
|
+
if resolved_level is not None:
|
|
162
|
+
_configure_debug_logging(resolved_level)
|
|
163
|
+
|
|
164
|
+
with _init_lock:
|
|
165
|
+
# Check existing provider
|
|
166
|
+
current_provider = trace.get_tracer_provider()
|
|
167
|
+
has_sdk_provider = isinstance(current_provider, TracerProvider)
|
|
168
|
+
|
|
169
|
+
if _initialized and not force:
|
|
170
|
+
logger.debug("GatewaySDK tracing already initialized. Use force=True to reinitialize.")
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
if has_sdk_provider and not force:
|
|
174
|
+
# Reuse existing provider
|
|
175
|
+
logger.info("Reusing existing TracerProvider")
|
|
176
|
+
_provider = current_provider
|
|
177
|
+
else:
|
|
178
|
+
# Create new provider
|
|
179
|
+
resource_attrs = {
|
|
180
|
+
SERVICE_NAME: service_name or "gatewaysdk-tracing",
|
|
181
|
+
}
|
|
182
|
+
if trace_name:
|
|
183
|
+
resource_attrs["trace.name"] = trace_name
|
|
184
|
+
if environment:
|
|
185
|
+
resource_attrs[GATEWAY_ENVIRONMENT] = environment
|
|
186
|
+
if version:
|
|
187
|
+
resource_attrs[GATEWAY_VERSION] = version
|
|
188
|
+
|
|
189
|
+
resource = Resource.create(resource_attrs)
|
|
190
|
+
_provider = TracerProvider(resource=resource)
|
|
191
|
+
|
|
192
|
+
# Set as global provider
|
|
193
|
+
trace.set_tracer_provider(_provider)
|
|
194
|
+
logger.info("Created new TracerProvider with service_name=%s", service_name or "gatewaysdk-tracing")
|
|
195
|
+
|
|
196
|
+
# Add TracingContextSpanProcessor for automatic context injection
|
|
197
|
+
# This must be added BEFORE exporter processors so context is set first
|
|
198
|
+
_add_context_processor_idempotent(_provider)
|
|
199
|
+
|
|
200
|
+
if resolved_level is not None:
|
|
201
|
+
_add_logging_processor_idempotent(_provider)
|
|
202
|
+
|
|
203
|
+
configured_exporters = exporters or []
|
|
204
|
+
|
|
205
|
+
# Auto-configure Gateway exporter if no custom exporters provided
|
|
206
|
+
if not configured_exporters:
|
|
207
|
+
# Check if Gateway credentials are provided via parameters
|
|
208
|
+
if gateway_host and gateway_public_key and gateway_secret_key:
|
|
209
|
+
try:
|
|
210
|
+
gateway_exporter = gateway(
|
|
211
|
+
host=gateway_host,
|
|
212
|
+
public_key=gateway_public_key,
|
|
213
|
+
secret_key=gateway_secret_key,
|
|
214
|
+
endpoint=gateway_endpoint,
|
|
215
|
+
)
|
|
216
|
+
configured_exporters.append(gateway_exporter)
|
|
217
|
+
logger.info("Configured Gateway exporter from init() parameters")
|
|
218
|
+
except ValueError as e:
|
|
219
|
+
logger.warning("Could not configure Gateway exporter: %s", e)
|
|
220
|
+
# Fall back to environment variables
|
|
221
|
+
elif is_gateway_configured():
|
|
222
|
+
try:
|
|
223
|
+
gateway_exporter = gateway()
|
|
224
|
+
configured_exporters.append(gateway_exporter)
|
|
225
|
+
logger.info("Auto-configured Gateway exporter from environment variables")
|
|
226
|
+
except ValueError as e:
|
|
227
|
+
logger.warning("Could not auto-configure Gateway exporter: %s", e)
|
|
228
|
+
|
|
229
|
+
if not configured_exporters:
|
|
230
|
+
logger.warning("No exporter configured -- spans will not be persisted")
|
|
231
|
+
|
|
232
|
+
# Store batch processor config for _add_processor_idempotent
|
|
233
|
+
_batch_config.clear()
|
|
234
|
+
if batch_queue_size is not None:
|
|
235
|
+
_batch_config["max_queue_size"] = batch_queue_size
|
|
236
|
+
if batch_flush_interval is not None:
|
|
237
|
+
_batch_config["schedule_delay_millis"] = batch_flush_interval
|
|
238
|
+
if batch_max_export_size is not None:
|
|
239
|
+
_batch_config["max_export_batch_size"] = batch_max_export_size
|
|
240
|
+
|
|
241
|
+
# Add processors for each exporter (idempotent)
|
|
242
|
+
for exporter in configured_exporters:
|
|
243
|
+
_add_processor_idempotent(_provider, exporter)
|
|
244
|
+
|
|
245
|
+
# Run instrumentation
|
|
246
|
+
if instrument_default:
|
|
247
|
+
instrument()
|
|
248
|
+
|
|
249
|
+
# Agent identity: the one declared identity. Everything else
|
|
250
|
+
# (user, session, context items) flows inherently.
|
|
251
|
+
from .identity import (
|
|
252
|
+
register_agent_with_platform,
|
|
253
|
+
resolve_agent_identity,
|
|
254
|
+
set_agent_identity,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
identity = resolve_agent_identity(agent)
|
|
258
|
+
set_agent_identity(identity)
|
|
259
|
+
from .identity import initialize_ambient_session
|
|
260
|
+
|
|
261
|
+
initialize_ambient_session()
|
|
262
|
+
if identity is not None:
|
|
263
|
+
register_agent_with_platform(
|
|
264
|
+
identity,
|
|
265
|
+
host=gateway_host,
|
|
266
|
+
public_key=gateway_public_key,
|
|
267
|
+
secret_key=gateway_secret_key,
|
|
268
|
+
)
|
|
269
|
+
# Agent build identity — "the agent IS the manifest": everything
|
|
270
|
+
# registered before init (define_tool / register_prompt) plus the
|
|
271
|
+
# code ref becomes a content-addressed build, stamped on every
|
|
272
|
+
# span and auto-registered (idempotent on hash, fail-soft).
|
|
273
|
+
from gatewaysdk.build import activate_build
|
|
274
|
+
|
|
275
|
+
activate_build(
|
|
276
|
+
identity.id,
|
|
277
|
+
version=identity.version,
|
|
278
|
+
host=gateway_host,
|
|
279
|
+
public_key=gateway_public_key,
|
|
280
|
+
secret_key=gateway_secret_key,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
_initialized = True
|
|
284
|
+
logger.info("GatewaySDK tracing initialized successfully")
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def instrument(
|
|
288
|
+
names: Optional[List[str]] = None,
|
|
289
|
+
skip: Optional[List[str]] = None,
|
|
290
|
+
) -> None:
|
|
291
|
+
"""Manually enable specific instrumentations.
|
|
292
|
+
|
|
293
|
+
This function looks up instrumentors by name from the registry and
|
|
294
|
+
activates them. If no names are provided and init() was called with
|
|
295
|
+
instrument_default=True, this enables the "core set".
|
|
296
|
+
|
|
297
|
+
Core Set (enabled by default):
|
|
298
|
+
- openai
|
|
299
|
+
- anthropic
|
|
300
|
+
- langchain
|
|
301
|
+
- llama_index
|
|
302
|
+
- litellm
|
|
303
|
+
|
|
304
|
+
Additional Available:
|
|
305
|
+
- google_adk
|
|
306
|
+
- mistral
|
|
307
|
+
- groq
|
|
308
|
+
- bedrock
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
names: List of instrumentor names to enable. If None and called from
|
|
312
|
+
init() with instrument_default=True, enables the core set.
|
|
313
|
+
skip: List of instrumentor names to explicitly skip.
|
|
314
|
+
|
|
315
|
+
Example::
|
|
316
|
+
|
|
317
|
+
import gatewaysdk.tracing_claude as tracing
|
|
318
|
+
|
|
319
|
+
# Enable only specific instrumentors
|
|
320
|
+
tracing.init(instrument_default=False)
|
|
321
|
+
tracing.instrument(names=["openai", "anthropic"])
|
|
322
|
+
|
|
323
|
+
# Enable all except langchain
|
|
324
|
+
tracing.instrument(skip=["langchain"])
|
|
325
|
+
"""
|
|
326
|
+
from .instrumentors.registry import get_registry
|
|
327
|
+
|
|
328
|
+
registry = get_registry()
|
|
329
|
+
skip_set = set(skip or [])
|
|
330
|
+
|
|
331
|
+
# Determine which instrumentors to enable
|
|
332
|
+
if names is None:
|
|
333
|
+
# Default core set -- instruments all installed AI libraries automatically
|
|
334
|
+
target_names = [
|
|
335
|
+
"openai_agents",
|
|
336
|
+
"claude_agent_sdk",
|
|
337
|
+
"openai",
|
|
338
|
+
"anthropic",
|
|
339
|
+
"langchain",
|
|
340
|
+
"llama_index",
|
|
341
|
+
"litellm",
|
|
342
|
+
]
|
|
343
|
+
else:
|
|
344
|
+
target_names = names
|
|
345
|
+
|
|
346
|
+
# Filter out skipped instrumentors
|
|
347
|
+
target_names = [name for name in target_names if name not in skip_set]
|
|
348
|
+
|
|
349
|
+
# Activate each instrumentor
|
|
350
|
+
for name in target_names:
|
|
351
|
+
instrumentor = registry.get(name)
|
|
352
|
+
if instrumentor is not None:
|
|
353
|
+
try:
|
|
354
|
+
instrumentor.instrument()
|
|
355
|
+
logger.info("Instrumented: %s", name)
|
|
356
|
+
except Exception as e:
|
|
357
|
+
logger.debug("Could not instrument %s: %s", name, e)
|
|
358
|
+
else:
|
|
359
|
+
logger.debug("Instrumentor not available (not installed?): %s", name)
|
|
360
|
+
# Warn loudly when the AI library IS installed but its instrumentor
|
|
361
|
+
# is missing — otherwise the user gets zero telemetry, silently.
|
|
362
|
+
registry.warn_if_lib_present_but_uninstrumented(name)
|
|
363
|
+
|
|
364
|
+
# The openai-agents instrumentor rides on the Agents SDK's own tracing
|
|
365
|
+
# pipeline. OPENAI_AGENTS_DISABLE_TRACING=1 (commonly set to silence the
|
|
366
|
+
# OpenAI trace-upload 401s when pointing at a non-OpenAI base URL) turns
|
|
367
|
+
# that pipeline off entirely — and with it, ALL Gateway telemetry for the
|
|
368
|
+
# agent. Warn loudly; the 401 noise alone is harmless.
|
|
369
|
+
if "openai_agents" in target_names and os.environ.get(
|
|
370
|
+
"OPENAI_AGENTS_DISABLE_TRACING", ""
|
|
371
|
+
).lower() in ("1", "true", "yes"):
|
|
372
|
+
print(
|
|
373
|
+
"gatewaysdk.tracing: OPENAI_AGENTS_DISABLE_TRACING is set, which "
|
|
374
|
+
"disables the OpenAI Agents SDK tracing pipeline the Gateway "
|
|
375
|
+
"instrumentor rides on — NOTHING from openai-agents will reach "
|
|
376
|
+
"Gateway. Unset it (the OpenAI trace-upload 401s it silences are "
|
|
377
|
+
"harmless) or set OPENAI_AGENTS_TRACING_EXPORT_API_KEY to a real "
|
|
378
|
+
"OpenAI key.",
|
|
379
|
+
file=sys.stderr,
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def shutdown(timeout_millis: int = 30000) -> None:
|
|
384
|
+
"""Force flush all pending spans and shutdown the tracer provider.
|
|
385
|
+
|
|
386
|
+
This function should be called before process exit to ensure all spans
|
|
387
|
+
are exported. It is safe to call multiple times.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
timeout_millis: Maximum time to wait for flush completion in milliseconds.
|
|
391
|
+
|
|
392
|
+
Example::
|
|
393
|
+
|
|
394
|
+
import gatewaysdk.tracing_claude as tracing
|
|
395
|
+
import atexit
|
|
396
|
+
|
|
397
|
+
tracing.init()
|
|
398
|
+
atexit.register(tracing.shutdown)
|
|
399
|
+
|
|
400
|
+
# ... run application ...
|
|
401
|
+
"""
|
|
402
|
+
global _initialized, _provider, _context_processor_added, _logging_processor_added, _export_count
|
|
403
|
+
|
|
404
|
+
with _init_lock:
|
|
405
|
+
if not _initialized or _provider is None:
|
|
406
|
+
logger.debug("Tracing not initialized, nothing to shutdown")
|
|
407
|
+
return
|
|
408
|
+
|
|
409
|
+
try:
|
|
410
|
+
# Shutdown the provider (which flushes and shuts down processors)
|
|
411
|
+
_provider.shutdown()
|
|
412
|
+
logger.info("Shutdown complete: exported %d span(s) total", _export_count)
|
|
413
|
+
except Exception as e:
|
|
414
|
+
logger.warning("Error during TracerProvider shutdown: %s", e)
|
|
415
|
+
|
|
416
|
+
_processors.clear()
|
|
417
|
+
_batch_config.clear()
|
|
418
|
+
_initialized = False
|
|
419
|
+
_provider = None
|
|
420
|
+
_context_processor_added = False
|
|
421
|
+
_logging_processor_added = False
|
|
422
|
+
_export_count = 0
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def flush(timeout_millis: int = 30000) -> bool:
|
|
426
|
+
"""Force flush all pending spans without shutting down.
|
|
427
|
+
|
|
428
|
+
This is useful for ensuring spans are exported at specific points
|
|
429
|
+
(e.g., after completing a batch of work) without ending the tracing session.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
timeout_millis: Maximum time to wait for flush completion in milliseconds.
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
True if flush completed successfully, False otherwise.
|
|
436
|
+
|
|
437
|
+
Example::
|
|
438
|
+
|
|
439
|
+
import gatewaysdk.tracing_claude as tracing
|
|
440
|
+
|
|
441
|
+
tracing.init()
|
|
442
|
+
|
|
443
|
+
# Process batch
|
|
444
|
+
for item in batch:
|
|
445
|
+
process(item)
|
|
446
|
+
|
|
447
|
+
# Ensure all spans from this batch are exported
|
|
448
|
+
tracing.flush()
|
|
449
|
+
"""
|
|
450
|
+
with _init_lock:
|
|
451
|
+
if _provider is None:
|
|
452
|
+
logger.debug("No provider to flush")
|
|
453
|
+
return True
|
|
454
|
+
|
|
455
|
+
try:
|
|
456
|
+
success = _provider.force_flush(timeout_millis=timeout_millis)
|
|
457
|
+
if success:
|
|
458
|
+
logger.debug("Flush completed successfully")
|
|
459
|
+
else:
|
|
460
|
+
logger.warning("Flush timed out after %d ms", timeout_millis)
|
|
461
|
+
return success
|
|
462
|
+
except Exception as e:
|
|
463
|
+
logger.warning("Error during flush: %s", e)
|
|
464
|
+
return False
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
# Track if context processor has been added
|
|
468
|
+
_context_processor_added = False
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def _add_context_processor_idempotent(provider: TracerProvider) -> None:
|
|
472
|
+
"""Add the TracingContextSpanProcessor if not already added.
|
|
473
|
+
|
|
474
|
+
This processor injects run context (run_id, session_id) and tracing
|
|
475
|
+
context (call_type, tags, environment) into all spans automatically.
|
|
476
|
+
"""
|
|
477
|
+
global _context_processor_added
|
|
478
|
+
|
|
479
|
+
if _context_processor_added:
|
|
480
|
+
logger.debug("TracingContextSpanProcessor already added")
|
|
481
|
+
return
|
|
482
|
+
|
|
483
|
+
processor = TracingContextSpanProcessor()
|
|
484
|
+
provider.add_span_processor(processor)
|
|
485
|
+
_context_processor_added = True
|
|
486
|
+
logger.debug("Added TracingContextSpanProcessor for automatic context injection")
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def _add_processor_idempotent(provider: TracerProvider, exporter: SpanExporter) -> None:
|
|
490
|
+
"""Add a BatchSpanProcessor for the exporter, avoiding duplicates.
|
|
491
|
+
|
|
492
|
+
Checks if a processor for the same exporter type/endpoint already exists
|
|
493
|
+
to prevent duplicate exports.
|
|
494
|
+
"""
|
|
495
|
+
# Check for existing processor with same exporter type
|
|
496
|
+
exporter_id = _get_exporter_id(exporter)
|
|
497
|
+
for existing in _processors:
|
|
498
|
+
if _get_exporter_id(existing.span_exporter) == exporter_id:
|
|
499
|
+
logger.debug("Processor already exists for exporter: %s", exporter_id)
|
|
500
|
+
return
|
|
501
|
+
|
|
502
|
+
# Create and add new processor.
|
|
503
|
+
# Wrap Gateway exporters with AnnotationFilterSpanProcessor to suppress
|
|
504
|
+
# gatewaysdk.annotation reward spans from OTLP (rewards are sent as
|
|
505
|
+
# Langfuse Scores via the API instead).
|
|
506
|
+
from .exporters.gateway import GatewayOTLPExporter
|
|
507
|
+
from .processors import AnnotationFilterSpanProcessor
|
|
508
|
+
|
|
509
|
+
batch_processor = BatchSpanProcessor(exporter, **_batch_config)
|
|
510
|
+
if isinstance(exporter, GatewayOTLPExporter):
|
|
511
|
+
filtered = AnnotationFilterSpanProcessor(batch_processor)
|
|
512
|
+
provider.add_span_processor(filtered)
|
|
513
|
+
logger.debug("Added filtered BatchSpanProcessor for: %s", exporter_id)
|
|
514
|
+
else:
|
|
515
|
+
provider.add_span_processor(batch_processor)
|
|
516
|
+
logger.debug("Added BatchSpanProcessor for: %s", exporter_id)
|
|
517
|
+
_processors.append(batch_processor)
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def _get_exporter_id(exporter: SpanExporter) -> str:
|
|
521
|
+
"""Generate a unique identifier for an exporter instance.
|
|
522
|
+
|
|
523
|
+
Uses class name + endpoint (if available) to identify exporters.
|
|
524
|
+
"""
|
|
525
|
+
class_name = exporter.__class__.__name__
|
|
526
|
+
|
|
527
|
+
# Try to get endpoint for OTLP exporters
|
|
528
|
+
endpoint = getattr(exporter, "_endpoint", None)
|
|
529
|
+
if endpoint:
|
|
530
|
+
return f"{class_name}:{endpoint}"
|
|
531
|
+
|
|
532
|
+
return class_name
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
def _resolve_debug_level(debug: Union[bool, str]) -> Optional[str]:
|
|
536
|
+
"""Resolve the debug parameter to a Python logging level name, or None if disabled."""
|
|
537
|
+
if debug is False or debug is None:
|
|
538
|
+
return None
|
|
539
|
+
if debug is True:
|
|
540
|
+
return "DEBUG"
|
|
541
|
+
level_name = str(debug).upper()
|
|
542
|
+
if level_name not in ("DEBUG", "INFO", "WARNING", "ERROR"):
|
|
543
|
+
raise ValueError(f"Invalid debug level: {debug!r}. " "Use True, False, 'DEBUG', 'INFO', 'WARNING', or 'ERROR'.")
|
|
544
|
+
return level_name
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def _record_exported(count: int) -> None:
|
|
548
|
+
"""Increment the global export counter (called by GatewayOTLPExporter)."""
|
|
549
|
+
global _export_count
|
|
550
|
+
_export_count += count
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
_logging_processor_added = False
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
def _add_logging_processor_idempotent(provider: TracerProvider) -> None:
|
|
557
|
+
"""Add the LoggingSpanProcessor if not already added."""
|
|
558
|
+
global _logging_processor_added
|
|
559
|
+
|
|
560
|
+
if _logging_processor_added:
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
provider.add_span_processor(LoggingSpanProcessor())
|
|
564
|
+
_logging_processor_added = True
|
|
565
|
+
logger.debug("Added LoggingSpanProcessor for debug visibility")
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
def _configure_debug_logging(level: str = "DEBUG") -> None:
|
|
569
|
+
"""Configure Python logging so gatewaysdk.tracing messages reach the console.
|
|
570
|
+
|
|
571
|
+
Sets up a StreamHandler on the ``gatewaysdk.tracing`` logger hierarchy
|
|
572
|
+
(and the OTLP exporter logger) at the requested level.
|
|
573
|
+
Writes to stdout (not stderr) so output interleaves naturally with
|
|
574
|
+
application print() statements.
|
|
575
|
+
|
|
576
|
+
Args:
|
|
577
|
+
level: Python logging level name (DEBUG, INFO, WARNING, ERROR).
|
|
578
|
+
"""
|
|
579
|
+
import sys
|
|
580
|
+
|
|
581
|
+
numeric_level = getattr(logging, level, logging.DEBUG)
|
|
582
|
+
|
|
583
|
+
tracing_logger = logging.getLogger("gatewaysdk.tracing")
|
|
584
|
+
if tracing_logger.handlers:
|
|
585
|
+
return
|
|
586
|
+
|
|
587
|
+
handler = logging.StreamHandler(stream=sys.stdout)
|
|
588
|
+
handler.setLevel(numeric_level)
|
|
589
|
+
fmt = logging.Formatter("[%(name)s] %(message)s")
|
|
590
|
+
handler.setFormatter(fmt)
|
|
591
|
+
|
|
592
|
+
tracing_logger.addHandler(handler)
|
|
593
|
+
tracing_logger.setLevel(numeric_level)
|
|
594
|
+
tracing_logger.propagate = False
|
|
595
|
+
|
|
596
|
+
# Also capture OTLP exporter warnings (connection failures, retries)
|
|
597
|
+
otel_logger = logging.getLogger("opentelemetry.exporter.otlp")
|
|
598
|
+
otel_logger.addHandler(handler)
|
|
599
|
+
otel_logger.setLevel(logging.WARNING)
|
|
600
|
+
otel_logger.propagate = False
|
|
601
|
+
|
|
602
|
+
# Suppress noisy OTel warnings about provider overriding (force=True triggers these)
|
|
603
|
+
for name in ("opentelemetry.trace", "opentelemetry.sdk.trace"):
|
|
604
|
+
lg = logging.getLogger(name)
|
|
605
|
+
lg.setLevel(logging.ERROR)
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
def get_tracer(name: str = "gatewaysdk.tracing") -> trace.Tracer:
|
|
609
|
+
"""Get a tracer instance for creating spans.
|
|
610
|
+
|
|
611
|
+
This is primarily for internal use. Users should prefer the
|
|
612
|
+
trace() and span() context managers.
|
|
613
|
+
|
|
614
|
+
Args:
|
|
615
|
+
name: The tracer name (instrumentation scope).
|
|
616
|
+
|
|
617
|
+
Returns:
|
|
618
|
+
OpenTelemetry Tracer instance.
|
|
619
|
+
"""
|
|
620
|
+
return trace.get_tracer(name)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright (c) Gateway. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Instrumentors for GatewayDK tracing.
|
|
4
|
+
|
|
5
|
+
This module provides a registry-based system for managing OpenTelemetry
|
|
6
|
+
instrumentors from various sources (OpenInference, AgentOps, etc.).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .registry import BaseInstrumentor, InstrumentorRegistry, get_registry
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"get_registry",
|
|
13
|
+
"InstrumentorRegistry",
|
|
14
|
+
"BaseInstrumentor",
|
|
15
|
+
]
|