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,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class for instrumentors.
|
|
3
|
+
|
|
4
|
+
Instrumentors provide automatic metric collection and tracing for specific libraries.
|
|
5
|
+
They follow a plugin architecture where each instrumentor self-registers with the
|
|
6
|
+
InstrumentorRegistry.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Dict, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class MetricSchema:
|
|
16
|
+
"""
|
|
17
|
+
Describes a metric that an instrumentor may log.
|
|
18
|
+
|
|
19
|
+
This is used for documentation/discovery, NOT validation.
|
|
20
|
+
The schema-less design means any metric can be logged,
|
|
21
|
+
but MetricSchema helps developers understand what metrics
|
|
22
|
+
are available from each instrumentor.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name: str
|
|
26
|
+
description: str
|
|
27
|
+
unit: str = ""
|
|
28
|
+
metric_type: str = "gauge" # gauge, counter, histogram
|
|
29
|
+
labels: Dict[str, str] = field(default_factory=dict) # Label name -> description
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Instrumentor(ABC):
|
|
33
|
+
"""
|
|
34
|
+
Base class for auto-instrumentation plugins.
|
|
35
|
+
|
|
36
|
+
Instrumentors provide automatic metric collection and tracing
|
|
37
|
+
for specific libraries (e.g., OpenAI, Anthropic, custom algorithms).
|
|
38
|
+
|
|
39
|
+
Usage:
|
|
40
|
+
class OpenAIInstrumentor(Instrumentor):
|
|
41
|
+
@property
|
|
42
|
+
def name(self) -> str:
|
|
43
|
+
return "openai"
|
|
44
|
+
|
|
45
|
+
def instrument(self) -> None:
|
|
46
|
+
# Apply monkey patches or hooks
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
def uninstrument(self) -> None:
|
|
50
|
+
# Remove patches
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
Instrumentors are registered via the InstrumentorRegistry:
|
|
54
|
+
InstrumentorRegistry.register("openai", OpenAIInstrumentor)
|
|
55
|
+
|
|
56
|
+
Or via Python entry points in pyproject.toml:
|
|
57
|
+
[project.entry-points."gatewaysdk.instrumentors"]
|
|
58
|
+
openai = "gatewaysdk.instrumentation.openai:OpenAIInstrumentor"
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def name(self) -> str:
|
|
64
|
+
"""
|
|
65
|
+
Unique identifier for this instrumentor.
|
|
66
|
+
|
|
67
|
+
Examples: 'openai', 'anthropic', 'gepa', 'langchain'
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def default_labels(self) -> Dict[str, str]:
|
|
73
|
+
"""
|
|
74
|
+
Labels added to all metrics from this instrumentor.
|
|
75
|
+
|
|
76
|
+
Override to add custom default labels. By default,
|
|
77
|
+
includes the instrumentor name.
|
|
78
|
+
"""
|
|
79
|
+
return {"instrumentor": self.name}
|
|
80
|
+
|
|
81
|
+
def get_metric_schema(self) -> Dict[str, MetricSchema]:
|
|
82
|
+
"""
|
|
83
|
+
Describe metrics this instrumentor may log.
|
|
84
|
+
|
|
85
|
+
Used for documentation/discovery, NOT validation.
|
|
86
|
+
Returns a dict mapping metric names to their schemas.
|
|
87
|
+
|
|
88
|
+
Override this to document the metrics your instrumentor logs.
|
|
89
|
+
"""
|
|
90
|
+
return {}
|
|
91
|
+
|
|
92
|
+
@abstractmethod
|
|
93
|
+
def instrument(self) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Apply patches/hooks to the target library.
|
|
96
|
+
|
|
97
|
+
This method is called when the instrumentor is activated.
|
|
98
|
+
It should apply any necessary monkey patches, register
|
|
99
|
+
callbacks, or otherwise hook into the target library.
|
|
100
|
+
"""
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
def uninstrument(self) -> None:
|
|
104
|
+
"""
|
|
105
|
+
Remove patches/hooks from the target library.
|
|
106
|
+
|
|
107
|
+
Override this method to provide cleanup functionality.
|
|
108
|
+
Used primarily for testing to restore original behavior.
|
|
109
|
+
"""
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
def is_available(self) -> bool:
|
|
113
|
+
"""
|
|
114
|
+
Check if the target library is available.
|
|
115
|
+
|
|
116
|
+
Override this to check if the library this instrumentor
|
|
117
|
+
targets is installed. By default returns True.
|
|
118
|
+
"""
|
|
119
|
+
return True
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""LiteLLM instrumentations.
|
|
4
|
+
|
|
5
|
+
Patches LiteLLM's OpenTelemetry integration to add GatewaySDK-specific attributes
|
|
6
|
+
to spans, including session_id, tags, environment, and call_type from context.
|
|
7
|
+
|
|
8
|
+
The call_type is read from a ContextVar that is set by algorithm-specific
|
|
9
|
+
decorators (e.g., @gepa.judge, @gepa.agent).
|
|
10
|
+
|
|
11
|
+
[Related documentation](https://docs.litellm.ai/docs/observability/agentops_integration).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
from typing import Any, Optional
|
|
16
|
+
|
|
17
|
+
from litellm.integrations.opentelemetry import OpenTelemetry
|
|
18
|
+
|
|
19
|
+
from gatewaysdk.tracing.context import get_current_call_type
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"instrument_litellm",
|
|
23
|
+
"uninstrument_litellm",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
original_set_attributes = OpenTelemetry.set_attributes # type: ignore
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def patched_set_attributes(self: Any, span: Any, kwargs: Any, response_obj: Optional[Any]):
|
|
30
|
+
"""Enhanced set_attributes that adds GatewaySDK tracing metadata to spans.
|
|
31
|
+
|
|
32
|
+
Extracts session_id, tags, and environment from kwargs["metadata"] and sets
|
|
33
|
+
them as OTEL span attributes for visibility in Gateway/Langfuse.
|
|
34
|
+
|
|
35
|
+
Also reads the current call_type from context (set by decorators like
|
|
36
|
+
@gepa.judge) and adds it as a span attribute.
|
|
37
|
+
"""
|
|
38
|
+
original_set_attributes(self, span, kwargs, response_obj)
|
|
39
|
+
|
|
40
|
+
# Add token IDs if available
|
|
41
|
+
if response_obj is not None and response_obj.get("prompt_token_ids"):
|
|
42
|
+
span.set_attribute("prompt_token_ids", list(response_obj.get("prompt_token_ids")))
|
|
43
|
+
if response_obj is not None and response_obj.get("response_token_ids"):
|
|
44
|
+
span.set_attribute("response_token_ids", list(response_obj.get("response_token_ids")[0]))
|
|
45
|
+
|
|
46
|
+
# Read call_type from context (set by @gepa.judge, @gepa.agent, etc.)
|
|
47
|
+
call_type = get_current_call_type()
|
|
48
|
+
if call_type:
|
|
49
|
+
span.set_attribute("gateway.call_type", call_type)
|
|
50
|
+
|
|
51
|
+
# Extract GatewaySDK tracing metadata from kwargs
|
|
52
|
+
metadata = kwargs.get("metadata", {}) if kwargs else {}
|
|
53
|
+
if not metadata:
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
# Set session_id as span attribute (standard Langfuse/Gateway attribute)
|
|
57
|
+
session_id = metadata.get("session_id")
|
|
58
|
+
if session_id:
|
|
59
|
+
span.set_attribute("session.id", session_id)
|
|
60
|
+
|
|
61
|
+
# Set tags as span attribute (JSON array for Langfuse compatibility)
|
|
62
|
+
tags = metadata.get("tags")
|
|
63
|
+
if tags and isinstance(tags, list):
|
|
64
|
+
# Langfuse expects tags as a JSON array string or individual attributes
|
|
65
|
+
span.set_attribute("tags", json.dumps(tags))
|
|
66
|
+
# Also set individual tag attributes for filtering
|
|
67
|
+
for i, tag in enumerate(tags):
|
|
68
|
+
span.set_attribute(f"tag.{i}", str(tag))
|
|
69
|
+
|
|
70
|
+
# Set environment as span attribute
|
|
71
|
+
environment = metadata.get("environment")
|
|
72
|
+
if environment:
|
|
73
|
+
span.set_attribute("environment", environment)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def instrument_litellm():
|
|
77
|
+
"""Instrument litellm to capture token IDs."""
|
|
78
|
+
OpenTelemetry.set_attributes = patched_set_attributes
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def uninstrument_litellm():
|
|
82
|
+
"""Uninstrument litellm to stop capturing token IDs."""
|
|
83
|
+
OpenTelemetry.set_attributes = original_set_attributes
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Instrumentor Registry for auto-instrumentation.
|
|
3
|
+
|
|
4
|
+
The registry provides a central location to register and activate
|
|
5
|
+
instrumentors. It supports both explicit registration and automatic
|
|
6
|
+
discovery via Python entry points.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import sys
|
|
11
|
+
from typing import Dict, List, Optional, Type
|
|
12
|
+
|
|
13
|
+
from .base import Instrumentor, MetricSchema
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InstrumentorRegistry:
|
|
19
|
+
"""
|
|
20
|
+
Global registry for metric instrumentors.
|
|
21
|
+
|
|
22
|
+
Instrumentors can be registered in two ways:
|
|
23
|
+
1. Explicit registration:
|
|
24
|
+
InstrumentorRegistry.register("openai", OpenAIInstrumentor)
|
|
25
|
+
|
|
26
|
+
2. Entry point discovery (in pyproject.toml):
|
|
27
|
+
[project.entry-points."gatewaysdk.instrumentors"]
|
|
28
|
+
openai = "gatewaysdk.instrumentation.openai:OpenAIInstrumentor"
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
# Enable a specific instrumentor
|
|
32
|
+
gatewaysdk.instrument("openai")
|
|
33
|
+
|
|
34
|
+
# Enable multiple instrumentors
|
|
35
|
+
gatewaysdk.instrument("openai", "anthropic", "langchain")
|
|
36
|
+
|
|
37
|
+
# Get list of available instrumentors
|
|
38
|
+
InstrumentorRegistry.list_available()
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
_instrumentors: Dict[str, Type[Instrumentor]] = {}
|
|
42
|
+
_active: Dict[str, Instrumentor] = {}
|
|
43
|
+
_discovered: bool = False
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def register(cls, name: str, instrumentor_cls: Type[Instrumentor]) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Register an instrumentor class.
|
|
49
|
+
|
|
50
|
+
This is typically called at import time by instrumentor modules,
|
|
51
|
+
or by entry point discovery.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
name: Unique identifier for the instrumentor (e.g., "openai")
|
|
55
|
+
instrumentor_cls: The instrumentor class to register
|
|
56
|
+
"""
|
|
57
|
+
cls._instrumentors[name] = instrumentor_cls
|
|
58
|
+
logger.debug(f"Registered instrumentor: {name}")
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def instrument(cls, name: str, **kwargs) -> Optional[Instrumentor]:
|
|
62
|
+
"""
|
|
63
|
+
Activate an instrumentor by name.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
name: The instrumentor name to activate
|
|
67
|
+
**kwargs: Additional arguments passed to the instrumentor constructor
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The activated instrumentor instance, or None if not available
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
ValueError: If the instrumentor name is not registered
|
|
74
|
+
"""
|
|
75
|
+
# Auto-discover instrumentors if not already done
|
|
76
|
+
if not cls._discovered:
|
|
77
|
+
cls.discover()
|
|
78
|
+
|
|
79
|
+
if name not in cls._instrumentors:
|
|
80
|
+
available = list(cls._instrumentors.keys())
|
|
81
|
+
raise ValueError(f"Unknown instrumentor: {name}. Available: {available}")
|
|
82
|
+
|
|
83
|
+
# Return existing instance if already active
|
|
84
|
+
if name in cls._active:
|
|
85
|
+
return cls._active[name]
|
|
86
|
+
|
|
87
|
+
# Create and activate new instance
|
|
88
|
+
instrumentor_cls = cls._instrumentors[name]
|
|
89
|
+
instance = instrumentor_cls(**kwargs)
|
|
90
|
+
|
|
91
|
+
# Check if target library is available
|
|
92
|
+
if not instance.is_available():
|
|
93
|
+
logger.warning(f"Instrumentor '{name}' target library is not available")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
instance.instrument()
|
|
98
|
+
cls._active[name] = instance
|
|
99
|
+
logger.info(f"Activated instrumentor: {name}")
|
|
100
|
+
return instance
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(f"Failed to activate instrumentor '{name}': {e}")
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def uninstrument(cls, name: str) -> bool:
|
|
107
|
+
"""
|
|
108
|
+
Deactivate an instrumentor by name.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
name: The instrumentor name to deactivate
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
True if successfully deactivated, False otherwise
|
|
115
|
+
"""
|
|
116
|
+
if name not in cls._active:
|
|
117
|
+
logger.debug(f"Instrumentor '{name}' is not active")
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
instance = cls._active[name]
|
|
121
|
+
try:
|
|
122
|
+
instance.uninstrument()
|
|
123
|
+
del cls._active[name]
|
|
124
|
+
logger.info(f"Deactivated instrumentor: {name}")
|
|
125
|
+
return True
|
|
126
|
+
except Exception as e:
|
|
127
|
+
logger.error(f"Failed to deactivate instrumentor '{name}': {e}")
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def uninstrument_all(cls) -> None:
|
|
132
|
+
"""Deactivate all active instrumentors."""
|
|
133
|
+
for name in list(cls._active.keys()):
|
|
134
|
+
cls.uninstrument(name)
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def discover(cls) -> None:
|
|
138
|
+
"""
|
|
139
|
+
Auto-discover instrumentors via Python entry points.
|
|
140
|
+
|
|
141
|
+
Entry points should be defined in pyproject.toml:
|
|
142
|
+
[project.entry-points."gatewaysdk.instrumentors"]
|
|
143
|
+
openai = "gatewaysdk.instrumentation.openai:OpenAIInstrumentor"
|
|
144
|
+
"""
|
|
145
|
+
if cls._discovered:
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
# Python 3.10+ has importlib.metadata.entry_points with group param
|
|
150
|
+
if sys.version_info >= (3, 10):
|
|
151
|
+
from importlib.metadata import entry_points
|
|
152
|
+
|
|
153
|
+
eps = entry_points(group="gatewaysdk.instrumentors")
|
|
154
|
+
else:
|
|
155
|
+
# Python 3.9 compatibility
|
|
156
|
+
from importlib.metadata import entry_points
|
|
157
|
+
|
|
158
|
+
eps = entry_points().get("gatewaysdk.instrumentors", [])
|
|
159
|
+
|
|
160
|
+
for ep in eps:
|
|
161
|
+
try:
|
|
162
|
+
instrumentor_cls = ep.load()
|
|
163
|
+
cls.register(ep.name, instrumentor_cls)
|
|
164
|
+
except Exception as e:
|
|
165
|
+
logger.warning(f"Failed to load instrumentor '{ep.name}': {e}")
|
|
166
|
+
|
|
167
|
+
except ImportError:
|
|
168
|
+
logger.debug("importlib.metadata not available, skipping entry point discovery")
|
|
169
|
+
|
|
170
|
+
cls._discovered = True
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def list_available(cls) -> List[str]:
|
|
174
|
+
"""
|
|
175
|
+
List all registered instrumentor names.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
List of instrumentor names
|
|
179
|
+
"""
|
|
180
|
+
if not cls._discovered:
|
|
181
|
+
cls.discover()
|
|
182
|
+
return list(cls._instrumentors.keys())
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def list_active(cls) -> List[str]:
|
|
186
|
+
"""
|
|
187
|
+
List all currently active instrumentor names.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
List of active instrumentor names
|
|
191
|
+
"""
|
|
192
|
+
return list(cls._active.keys())
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def get_metric_schemas(cls) -> Dict[str, Dict[str, MetricSchema]]:
|
|
196
|
+
"""
|
|
197
|
+
Get metric schemas from all registered instrumentors.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Dict mapping instrumentor names to their metric schemas
|
|
201
|
+
"""
|
|
202
|
+
if not cls._discovered:
|
|
203
|
+
cls.discover()
|
|
204
|
+
|
|
205
|
+
schemas = {}
|
|
206
|
+
for name, instrumentor_cls in cls._instrumentors.items():
|
|
207
|
+
instance = instrumentor_cls()
|
|
208
|
+
schema = instance.get_metric_schema()
|
|
209
|
+
if schema:
|
|
210
|
+
schemas[name] = schema
|
|
211
|
+
return schemas
|
|
212
|
+
|
|
213
|
+
@classmethod
|
|
214
|
+
def is_active(cls, name: str) -> bool:
|
|
215
|
+
"""
|
|
216
|
+
Check if an instrumentor is currently active.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
name: The instrumentor name to check
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
True if the instrumentor is active
|
|
223
|
+
"""
|
|
224
|
+
return name in cls._active
|
|
225
|
+
|
|
226
|
+
@classmethod
|
|
227
|
+
def get(cls, name: str) -> Optional[Instrumentor]:
|
|
228
|
+
"""
|
|
229
|
+
Get an active instrumentor instance by name.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
name: The instrumentor name
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
The instrumentor instance if active, None otherwise
|
|
236
|
+
"""
|
|
237
|
+
return cls._active.get(name)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
# Convenience function for module-level access
|
|
241
|
+
def instrument(*names: str, **kwargs) -> List[Optional[Instrumentor]]:
|
|
242
|
+
"""
|
|
243
|
+
Activate one or more instrumentors by name.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
*names: Instrumentor names to activate
|
|
247
|
+
**kwargs: Additional arguments passed to instrumentor constructors
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
List of activated instrumentor instances (None for failed activations)
|
|
251
|
+
|
|
252
|
+
Examples:
|
|
253
|
+
# Enable OpenAI instrumentation
|
|
254
|
+
gatewaysdk.instrument("openai")
|
|
255
|
+
|
|
256
|
+
# Enable multiple instrumentors
|
|
257
|
+
gatewaysdk.instrument("openai", "anthropic", "langchain")
|
|
258
|
+
"""
|
|
259
|
+
return [InstrumentorRegistry.instrument(name, **kwargs) for name in names]
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def uninstrument(*names: str) -> None:
|
|
263
|
+
"""
|
|
264
|
+
Deactivate one or more instrumentors by name.
|
|
265
|
+
|
|
266
|
+
Args:
|
|
267
|
+
*names: Instrumentor names to deactivate
|
|
268
|
+
|
|
269
|
+
Examples:
|
|
270
|
+
gatewaysdk.uninstrument("openai")
|
|
271
|
+
"""
|
|
272
|
+
for name in names:
|
|
273
|
+
InstrumentorRegistry.uninstrument(name)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import Any, List
|
|
7
|
+
|
|
8
|
+
import vllm.entrypoints.openai.protocol
|
|
9
|
+
from vllm.entrypoints.openai.protocol import ChatCompletionResponse
|
|
10
|
+
from vllm.entrypoints.openai.serving_chat import OpenAIServingChat
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"instrument_vllm",
|
|
14
|
+
"uninstrument_vllm",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ChatCompletionResponsePatched(ChatCompletionResponse):
|
|
19
|
+
prompt_token_ids: List[int] | None = None
|
|
20
|
+
response_token_ids: List[int] | None = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
original_chat_completion_full_generator = OpenAIServingChat.chat_completion_full_generator
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def chat_completion_full_generator(
|
|
27
|
+
self: Any,
|
|
28
|
+
request: Any,
|
|
29
|
+
result_generator: Any,
|
|
30
|
+
request_id: str,
|
|
31
|
+
model_name: str,
|
|
32
|
+
conversation: Any,
|
|
33
|
+
tokenizer: Any,
|
|
34
|
+
request_metadata: Any,
|
|
35
|
+
) -> Any:
|
|
36
|
+
prompt_token_ids: List[int] | None = None
|
|
37
|
+
response_token_ids: List[List[int]] | None = None
|
|
38
|
+
|
|
39
|
+
async def _generate_inceptor():
|
|
40
|
+
nonlocal prompt_token_ids, response_token_ids
|
|
41
|
+
async for res in result_generator:
|
|
42
|
+
yield res
|
|
43
|
+
prompt_token_ids = res.prompt_token_ids
|
|
44
|
+
response_token_ids = [output.token_ids for output in res.outputs]
|
|
45
|
+
|
|
46
|
+
response = await original_chat_completion_full_generator(
|
|
47
|
+
self,
|
|
48
|
+
request,
|
|
49
|
+
_generate_inceptor(),
|
|
50
|
+
request_id,
|
|
51
|
+
model_name,
|
|
52
|
+
conversation,
|
|
53
|
+
tokenizer,
|
|
54
|
+
request_metadata,
|
|
55
|
+
)
|
|
56
|
+
response = response.model_copy(
|
|
57
|
+
update={
|
|
58
|
+
"prompt_token_ids": prompt_token_ids,
|
|
59
|
+
"response_token_ids": response_token_ids,
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return response
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def instrument_vllm():
|
|
67
|
+
"""Instrument vLLM to capture token IDs generated by engine.
|
|
68
|
+
|
|
69
|
+
This instrumentation has been merged to upstream vLLM since v0.10.2.
|
|
70
|
+
"""
|
|
71
|
+
if vllm.entrypoints.openai.protocol.ChatCompletionResponse is ChatCompletionResponsePatched:
|
|
72
|
+
warnings.warn("vllm is already instrumented. Skip the instrumentation.")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
vllm.entrypoints.openai.protocol.ChatCompletionResponse = ChatCompletionResponsePatched
|
|
76
|
+
OpenAIServingChat.chat_completion_full_generator = chat_completion_full_generator
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def uninstrument_vllm():
|
|
80
|
+
"""Uninstrument vLLM to stop capturing token IDs generated by engine."""
|
|
81
|
+
OpenAIServingChat.chat_completion_full_generator = original_chat_completion_full_generator
|