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,320 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Helpers for emitting reward spans and integrating with AgentOps telemetry."""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import inspect
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
import warnings
|
|
10
|
+
from typing import (
|
|
11
|
+
Any,
|
|
12
|
+
Callable,
|
|
13
|
+
Dict,
|
|
14
|
+
List,
|
|
15
|
+
Literal,
|
|
16
|
+
Optional,
|
|
17
|
+
Sequence,
|
|
18
|
+
TypedDict,
|
|
19
|
+
TypeVar,
|
|
20
|
+
cast,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from pydantic import TypeAdapter
|
|
24
|
+
|
|
25
|
+
from gatewaysdk.semconv import AGL_ANNOTATION, LightningSpanAttributes, RewardPydanticModel
|
|
26
|
+
from gatewaysdk.types import SpanCoreFields, SpanLike
|
|
27
|
+
from gatewaysdk.utils.otel import filter_and_unflatten_attributes
|
|
28
|
+
|
|
29
|
+
# NOTE: emit_annotation is imported lazily in emit_reward() to avoid circular import
|
|
30
|
+
# The cycle is: emitter/__init__ → annotation → tracer → store → gateway → reward → annotation
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"reward",
|
|
36
|
+
"emit_reward",
|
|
37
|
+
"get_reward_value",
|
|
38
|
+
"get_rewards_from_span",
|
|
39
|
+
"is_reward_span",
|
|
40
|
+
"find_reward_spans",
|
|
41
|
+
"find_final_reward",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class RewardDimension(TypedDict):
|
|
46
|
+
"""Type representing a single dimension in a multi-dimensional reward."""
|
|
47
|
+
|
|
48
|
+
name: str
|
|
49
|
+
value: float
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class _RewardSpanData(TypedDict):
|
|
53
|
+
type: Literal["reward"]
|
|
54
|
+
value: Optional[float]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
_FnType = TypeVar("_FnType", bound=Callable[..., Any])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _agentops_initialized() -> bool:
|
|
61
|
+
"""Return `True` when the AgentOps client has been configured."""
|
|
62
|
+
import agentops
|
|
63
|
+
|
|
64
|
+
return agentops.get_client().initialized
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def reward(fn: _FnType) -> _FnType:
|
|
68
|
+
"""Decorate a reward function so its outputs are tracked as spans.
|
|
69
|
+
|
|
70
|
+
The decorator integrates with AgentOps when it is available and falls back to
|
|
71
|
+
the built-in telemetry otherwise. Both synchronous and asynchronous functions
|
|
72
|
+
are supported transparently.
|
|
73
|
+
|
|
74
|
+
Deprecated:
|
|
75
|
+
This decorator is deprecated. Use [`emit_reward`][gatewaysdk.emit_reward] instead.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
fn: Callable that produces a numeric reward.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Wrapped callable that preserves the original signature.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
from agentops.sdk.decorators import operation
|
|
85
|
+
|
|
86
|
+
def wrap_result(result: Optional[float]) -> _RewardSpanData:
|
|
87
|
+
"""Normalize the reward value into the span payload format."""
|
|
88
|
+
if result is None:
|
|
89
|
+
return {"type": "reward", "value": None}
|
|
90
|
+
if not isinstance(result, (float, int)): # type: ignore
|
|
91
|
+
warnings.warn(f"Reward is ignored because it is not a number: {result}")
|
|
92
|
+
return {"type": "reward", "value": None}
|
|
93
|
+
return {"type": "reward", "value": float(result)}
|
|
94
|
+
|
|
95
|
+
# Check if the function is async
|
|
96
|
+
is_async = asyncio.iscoroutinefunction(fn) or inspect.iscoroutinefunction(fn)
|
|
97
|
+
|
|
98
|
+
if is_async:
|
|
99
|
+
|
|
100
|
+
async def wrapper_async(*args: Any, **kwargs: Any) -> Any:
|
|
101
|
+
if not _agentops_initialized():
|
|
102
|
+
# Track the reward without AgentOps
|
|
103
|
+
result = await fn(*args, **kwargs)
|
|
104
|
+
emit_reward(cast(float, result))
|
|
105
|
+
return result
|
|
106
|
+
|
|
107
|
+
result: Optional[float] = None
|
|
108
|
+
|
|
109
|
+
@operation
|
|
110
|
+
async def agentops_reward_operation() -> _RewardSpanData:
|
|
111
|
+
# The reward function we are interested in tracing
|
|
112
|
+
# It takes zero inputs and return a formatted dict
|
|
113
|
+
nonlocal result
|
|
114
|
+
result = await fn(*args, **kwargs)
|
|
115
|
+
return wrap_result(result)
|
|
116
|
+
|
|
117
|
+
await agentops_reward_operation()
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
return wrapper_async # type: ignore
|
|
121
|
+
|
|
122
|
+
else:
|
|
123
|
+
|
|
124
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
125
|
+
if not _agentops_initialized():
|
|
126
|
+
# Track the reward without AgentOps
|
|
127
|
+
result = fn(*args, **kwargs)
|
|
128
|
+
emit_reward(cast(float, result))
|
|
129
|
+
return result
|
|
130
|
+
|
|
131
|
+
result: Optional[float] = None
|
|
132
|
+
|
|
133
|
+
@operation
|
|
134
|
+
def agentops_reward_operation() -> _RewardSpanData:
|
|
135
|
+
nonlocal result
|
|
136
|
+
result = fn(*args, **kwargs)
|
|
137
|
+
return wrap_result(result)
|
|
138
|
+
|
|
139
|
+
agentops_reward_operation()
|
|
140
|
+
return result
|
|
141
|
+
|
|
142
|
+
return wrapper # type: ignore
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def emit_reward(
|
|
146
|
+
reward: float | Dict[str, Any],
|
|
147
|
+
*,
|
|
148
|
+
primary_key: str | None = None,
|
|
149
|
+
attributes: Dict[str, Any] | None = None,
|
|
150
|
+
propagate: bool = True,
|
|
151
|
+
) -> SpanCoreFields:
|
|
152
|
+
"""Emit a reward value as an OpenTelemetry span.
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
155
|
+
Emit a single-dimensional reward:
|
|
156
|
+
>>> emit_reward(1.0)
|
|
157
|
+
|
|
158
|
+
Emit multi-dimensional rewards:
|
|
159
|
+
>>> emit_reward({"task_completion": 1.0, "efficiency": 0.8}, primary_key="task_completion")
|
|
160
|
+
|
|
161
|
+
Emit a reward with additional attributes (for example linking to another response span):
|
|
162
|
+
>>> from gatewaysdk.utils.otel import make_link_attributes
|
|
163
|
+
>>> emit_reward(0.5, attributes=make_link_attributes({"gen_ai.response.id": "response-123"}))
|
|
164
|
+
|
|
165
|
+
Or adding tags onto the reward span:
|
|
166
|
+
>>> from gatewaysdk.utils.otel import make_tag_attributes
|
|
167
|
+
>>> emit_reward(0.7, attributes=make_tag_attributes(["fast", "reliable"]))
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
reward: Numeric reward to record. Integers and booleans are converted to
|
|
171
|
+
floating point numbers for consistency.
|
|
172
|
+
Use a dictionary to represent a multi-dimensional reward.
|
|
173
|
+
attributes: Other optional span attributes.
|
|
174
|
+
propagate: Whether to propagate the span to exporters automatically.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Span core fields capturing the recorded reward.
|
|
178
|
+
"""
|
|
179
|
+
# Lazy import to avoid circular dependency
|
|
180
|
+
from .annotation import emit_annotation
|
|
181
|
+
|
|
182
|
+
logger.debug(f"Emitting reward: {reward}")
|
|
183
|
+
reward_dimensions: List[RewardDimension] = []
|
|
184
|
+
if isinstance(reward, dict):
|
|
185
|
+
reward_dict: Dict[str, float] = {}
|
|
186
|
+
for k, v in reward.items():
|
|
187
|
+
if isinstance(v, (int, bool)):
|
|
188
|
+
reward_dict[k] = float(v)
|
|
189
|
+
elif isinstance(v, float):
|
|
190
|
+
reward_dict[k] = v
|
|
191
|
+
else:
|
|
192
|
+
raise ValueError(f"Reward value must be a number, got: {type(v)} for key {k}")
|
|
193
|
+
if primary_key is None:
|
|
194
|
+
raise ValueError("When emitting a multi-dimensional reward as a dict, primary_key must be provided.")
|
|
195
|
+
if primary_key not in reward_dict:
|
|
196
|
+
raise ValueError(f"Primary key '{primary_key}' not found in reward dict keys: {list(reward_dict.keys())}")
|
|
197
|
+
reward_dimensions.append(RewardDimension(name=primary_key, value=reward_dict[primary_key]))
|
|
198
|
+
for k, v in reward_dict.items():
|
|
199
|
+
if k != primary_key:
|
|
200
|
+
reward_dimensions.append(RewardDimension(name=k, value=v))
|
|
201
|
+
else:
|
|
202
|
+
if isinstance(reward, (int, bool)):
|
|
203
|
+
reward = float(reward)
|
|
204
|
+
elif not isinstance(reward, float): # pyright: ignore[reportUnnecessaryIsInstance]
|
|
205
|
+
raise TypeError(f"Reward must be a number, got: {type(reward)}")
|
|
206
|
+
reward_dimensions.append(RewardDimension(name="primary", value=reward))
|
|
207
|
+
|
|
208
|
+
return emit_annotation(
|
|
209
|
+
{LightningSpanAttributes.REWARD.value: reward_dimensions, **(attributes or {})}, propagate=propagate
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def get_reward_value(span: SpanLike) -> Optional[float]:
|
|
214
|
+
"""Extract the reward value from a span, if available.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
span: Span object produced by AgentOps or GatewaySDK emitters.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
The primary reward encoded in the span or `None` when the span does not represent a reward.
|
|
221
|
+
"""
|
|
222
|
+
# v0.3+ emit reward format
|
|
223
|
+
reward_list = get_rewards_from_span(span)
|
|
224
|
+
if reward_list:
|
|
225
|
+
# Reward list is ordered and the first element is the primary reward
|
|
226
|
+
return reward_list[0].value
|
|
227
|
+
|
|
228
|
+
for key in [
|
|
229
|
+
"agentops.task.output", # newer versions of agentops
|
|
230
|
+
"agentops.entity.output",
|
|
231
|
+
]:
|
|
232
|
+
reward_dict: Dict[str, Any] | None = None
|
|
233
|
+
if span.attributes:
|
|
234
|
+
output = span.attributes.get(key)
|
|
235
|
+
if output:
|
|
236
|
+
if isinstance(output, dict):
|
|
237
|
+
reward_dict = cast(Dict[str, Any], output)
|
|
238
|
+
elif isinstance(output, str):
|
|
239
|
+
try:
|
|
240
|
+
reward_dict = cast(Dict[str, Any], json.loads(output))
|
|
241
|
+
except json.JSONDecodeError:
|
|
242
|
+
reward_dict = None
|
|
243
|
+
|
|
244
|
+
if reward_dict and reward_dict.get("type") == "reward":
|
|
245
|
+
reward_value = reward_dict.get("value", None)
|
|
246
|
+
if reward_value is None:
|
|
247
|
+
return None
|
|
248
|
+
if not isinstance(reward_value, float):
|
|
249
|
+
logger.error(f"Reward is not a number, got: {type(reward_value)}. This may cause undefined behaviors.")
|
|
250
|
+
logger.warning(
|
|
251
|
+
f"Extracted reward {reward_value} from AgentOps. This format is deprecated, please migrate to using `emit_reward`."
|
|
252
|
+
)
|
|
253
|
+
return cast(float, reward_value)
|
|
254
|
+
|
|
255
|
+
# v0.2 emit reward format
|
|
256
|
+
if span.name == AGL_ANNOTATION and span.attributes:
|
|
257
|
+
reward_value = span.attributes.get("reward", None)
|
|
258
|
+
if reward_value is None:
|
|
259
|
+
return None
|
|
260
|
+
if not isinstance(reward_value, float):
|
|
261
|
+
logger.error(f"Reward is not a number, got: {type(reward_value)}. This may cause undefined behaviors.")
|
|
262
|
+
logger.warning(
|
|
263
|
+
f"Extracted reward {reward_value} from a legacy version of reward span. You might have inconsistent gatewaysdk versions."
|
|
264
|
+
)
|
|
265
|
+
return cast(float, reward_value)
|
|
266
|
+
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def get_rewards_from_span(span: SpanLike) -> List[RewardPydanticModel]:
|
|
271
|
+
"""Extract the reward as a list from a span, if available.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
span: Span object produced by AgentOps or GatewaySDK emitters.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
A list of reward dimensions encoded in the span or an empty list when the span does not represent a reward.
|
|
278
|
+
"""
|
|
279
|
+
if span.attributes and any(key.startswith(LightningSpanAttributes.REWARD.value) for key in span.attributes):
|
|
280
|
+
reward_attr = filter_and_unflatten_attributes(
|
|
281
|
+
cast(Any, span.attributes or {}), LightningSpanAttributes.REWARD.value
|
|
282
|
+
)
|
|
283
|
+
recovered_rewards = TypeAdapter(List[RewardPydanticModel]).validate_python(reward_attr)
|
|
284
|
+
return recovered_rewards
|
|
285
|
+
else:
|
|
286
|
+
return []
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def is_reward_span(span: SpanLike) -> bool:
|
|
290
|
+
"""Return ``True`` when the provided span encodes a reward value."""
|
|
291
|
+
maybe_reward = get_reward_value(span)
|
|
292
|
+
return maybe_reward is not None
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def find_reward_spans(spans: Sequence[SpanLike]) -> List[SpanLike]:
|
|
296
|
+
"""Return all reward spans in the provided sequence.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
spans: Sequence containing [`ReadableSpan`](https://opentelemetry.io/docs/concepts/signals/traces/) objects or mocked span-like values.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
List of spans that could be parsed as rewards.
|
|
303
|
+
"""
|
|
304
|
+
return [span for span in spans if is_reward_span(span)]
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def find_final_reward(spans: Sequence[SpanLike]) -> Optional[float]:
|
|
308
|
+
"""Return the last reward value present in the provided spans.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
spans: Sequence containing [`ReadableSpan`](https://opentelemetry.io/docs/concepts/signals/traces/) objects or mocked span-like values.
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
Reward value from the latest reward span, or `None` when none are found.
|
|
315
|
+
"""
|
|
316
|
+
for span in reversed(spans):
|
|
317
|
+
reward = get_reward_value(span)
|
|
318
|
+
if reward is not None:
|
|
319
|
+
return reward
|
|
320
|
+
return None
|
gatewaysdk/env_var.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Environment variable managements."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import overload
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"LightningEnvVar",
|
|
13
|
+
"resolve_bool_env_var",
|
|
14
|
+
"resolve_int_env_var",
|
|
15
|
+
"resolve_str_env_var",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class LightningEnvVar(Enum):
|
|
20
|
+
"""Environment variables for GatewaySDK."""
|
|
21
|
+
|
|
22
|
+
AGL_EMITTER_DEBUG = "AGL_EMITTER_DEBUG"
|
|
23
|
+
"""Enable debug logging for the emitter."""
|
|
24
|
+
|
|
25
|
+
AGL_MANAGED_STORE = "AGL_MANAGED_STORE"
|
|
26
|
+
"""If yes, the [`ExecutionStrategy`][gatewaysdk.ExecutionStrategy]
|
|
27
|
+
constructs LightningStore wrappers automatically. When `False` the provided
|
|
28
|
+
`store` is passed directly to the bundles, allowing callers to manage
|
|
29
|
+
store wrappers manually."""
|
|
30
|
+
|
|
31
|
+
AGL_CURRENT_ROLE = "AGL_CURRENT_ROLE"
|
|
32
|
+
"""Which side(s) to run in this process. Used in
|
|
33
|
+
[`ClientServerExecutionStrategy`][gatewaysdk.ClientServerExecutionStrategy]."""
|
|
34
|
+
|
|
35
|
+
AGL_SERVER_HOST = "AGL_SERVER_HOST"
|
|
36
|
+
"""Interface the [`LightningStoreServer`][gatewaysdk.LightningStoreServer]
|
|
37
|
+
binds to when running the algorithm bundle locally."""
|
|
38
|
+
|
|
39
|
+
AGL_SERVER_PORT = "AGL_SERVER_PORT"
|
|
40
|
+
"""Port the [`LightningStoreServer`][gatewaysdk.LightningStoreServer] listens to."""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
_TRUTHY_VALUES = {"1", "true", "yes", "on"}
|
|
44
|
+
_FALSY_VALUES = {"0", "false", "no", "off"}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@overload
|
|
48
|
+
def resolve_bool_env_var(env_var: LightningEnvVar, override: bool, fallback: bool) -> bool: ...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@overload
|
|
52
|
+
def resolve_bool_env_var(env_var: LightningEnvVar, *, fallback: bool) -> bool: ...
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@overload
|
|
56
|
+
def resolve_bool_env_var(
|
|
57
|
+
env_var: LightningEnvVar, override: bool | None = None, fallback: bool | None = None
|
|
58
|
+
) -> bool | None: ...
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def resolve_bool_env_var(
|
|
62
|
+
env_var: LightningEnvVar, override: bool | None = None, fallback: bool | None = None
|
|
63
|
+
) -> bool | None:
|
|
64
|
+
"""Resolve a boolean environment variable.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
env_var: The environment variable to resolve.
|
|
68
|
+
override: Optional override supplied by the caller.
|
|
69
|
+
fallback: Default value if the environment variable is not set.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if override is not None:
|
|
73
|
+
return override
|
|
74
|
+
|
|
75
|
+
env_value = os.getenv(env_var.value)
|
|
76
|
+
if env_value is None:
|
|
77
|
+
return fallback
|
|
78
|
+
|
|
79
|
+
normalized = env_value.strip().lower()
|
|
80
|
+
if normalized in _TRUTHY_VALUES:
|
|
81
|
+
return True
|
|
82
|
+
if normalized in _FALSY_VALUES:
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
raise ValueError(f"{env_var.value} must be one of {_TRUTHY_VALUES} or {_FALSY_VALUES}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@overload
|
|
89
|
+
def resolve_int_env_var(env_var: LightningEnvVar, override: int, fallback: int) -> int: ...
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@overload
|
|
93
|
+
def resolve_int_env_var(env_var: LightningEnvVar, *, fallback: int) -> int: ...
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@overload
|
|
97
|
+
def resolve_int_env_var(
|
|
98
|
+
env_var: LightningEnvVar, override: int | None = None, fallback: int | None = None
|
|
99
|
+
) -> int | None: ...
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def resolve_int_env_var(
|
|
103
|
+
env_var: LightningEnvVar, override: int | None = None, fallback: int | None = None
|
|
104
|
+
) -> int | None:
|
|
105
|
+
"""Resolve an integer environment variable.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
env_var: The environment variable to resolve.
|
|
109
|
+
override: Optional override supplied by the caller.
|
|
110
|
+
fallback: Default value if the environment variable is not set.
|
|
111
|
+
"""
|
|
112
|
+
if override is not None:
|
|
113
|
+
return override
|
|
114
|
+
|
|
115
|
+
env_value = os.getenv(env_var.value)
|
|
116
|
+
if env_value is None:
|
|
117
|
+
return fallback
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
return int(env_value)
|
|
121
|
+
except ValueError:
|
|
122
|
+
raise ValueError(f"{env_var.value} must be an integer")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@overload
|
|
126
|
+
def resolve_str_env_var(env_var: LightningEnvVar, override: str, fallback: str) -> str: ...
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@overload
|
|
130
|
+
def resolve_str_env_var(env_var: LightningEnvVar, *, fallback: str) -> str: ...
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@overload
|
|
134
|
+
def resolve_str_env_var(
|
|
135
|
+
env_var: LightningEnvVar, override: str | None = None, fallback: str | None = None
|
|
136
|
+
) -> str | None: ...
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def resolve_str_env_var(
|
|
140
|
+
env_var: LightningEnvVar, override: str | None = None, fallback: str | None = None
|
|
141
|
+
) -> str | None:
|
|
142
|
+
"""Resolve a string environment variable.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
env_var: The environment variable to resolve.
|
|
146
|
+
override: Optional override supplied by the caller.
|
|
147
|
+
fallback: Default value if the environment variable is not set.
|
|
148
|
+
"""
|
|
149
|
+
if override is not None:
|
|
150
|
+
return override
|
|
151
|
+
|
|
152
|
+
env_value = os.getenv(env_var.value)
|
|
153
|
+
if env_value is None:
|
|
154
|
+
return fallback
|
|
155
|
+
|
|
156
|
+
return env_value
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Mock environments as an execution substrate — ``gatewaysdk.environment``.
|
|
2
|
+
|
|
3
|
+
import gatewaysdk.environment as gwenv
|
|
4
|
+
|
|
5
|
+
env = gwenv.init("refund-flows-env") # slug/id, READY head
|
|
6
|
+
with env: # fresh world + ambient interception
|
|
7
|
+
my_agent("handle ticket #4415") # define_tool calls hit the mock world
|
|
8
|
+
assert env.verify("refund_row_created").passed
|
|
9
|
+
|
|
10
|
+
Seams (spec §4.4): ``world.as_registry()`` (replay's registry contract),
|
|
11
|
+
``world.wrap_tools()``, ``world.execute()``, and the ambient ``define_tool``
|
|
12
|
+
wrapper inside ``with env:`` / ``env.branch()``. Harbor-kind environments
|
|
13
|
+
(task.toml trees) expose ``env.tasks`` / ``env.task(name)`` docker sandboxes
|
|
14
|
+
instead. ``gwenv.init_from_path(dir)`` boots a local bundle offline.
|
|
15
|
+
|
|
16
|
+
Note: :mod:`gatewaysdk.environments` (plural) is the platform HUB client
|
|
17
|
+
(read/inspect/trigger); this module is the local execution runtime built on
|
|
18
|
+
top of it.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import importlib
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
from . import runtime
|
|
25
|
+
from ._bundle import EnvManifest, HarborTask
|
|
26
|
+
from .errors import (
|
|
27
|
+
EnvironmentKindError,
|
|
28
|
+
EnvironmentNotConfigured,
|
|
29
|
+
EnvironmentNotReady,
|
|
30
|
+
GatewayEnvError,
|
|
31
|
+
HermeticViolation,
|
|
32
|
+
ToolRouteError,
|
|
33
|
+
VerifierError,
|
|
34
|
+
WorldStartError,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# The heavy seams live in ``core`` (platform hub + tracing clients), ``_harbor``
|
|
38
|
+
# (docker CLI) and ``_world`` (the replay registry contract). Bind them LAZILY
|
|
39
|
+
# via PEP 562 so a lean consumer — e.g. the benchmark runner's mock_tools engine,
|
|
40
|
+
# which vendors only this ``environment`` subpackage and imports ``_bundle`` /
|
|
41
|
+
# ``_world`` (worlds + verifiers) directly — can ``import gatewaysdk.environment``
|
|
42
|
+
# without dragging ``gatewaysdk.environments`` / ``gatewaysdk.build`` / docker /
|
|
43
|
+
# replay into the image. First access to any of these names imports its module
|
|
44
|
+
# on demand, so full-SDK behaviour is unchanged (just deferred).
|
|
45
|
+
_LAZY_ATTRS = {
|
|
46
|
+
"ENV_ENVIRONMENT_PREFIX": "core",
|
|
47
|
+
"Environment": "core",
|
|
48
|
+
"Report": "core",
|
|
49
|
+
"RouteRecord": "core",
|
|
50
|
+
"get_active_world": "core",
|
|
51
|
+
"init": "core",
|
|
52
|
+
"init_from_path": "core",
|
|
53
|
+
"CliDockerRuntime": "_harbor",
|
|
54
|
+
"DockerRuntime": "_harbor",
|
|
55
|
+
"ExecResult": "_harbor",
|
|
56
|
+
"HarborWorld": "_harbor",
|
|
57
|
+
"VerifierResult": "_world",
|
|
58
|
+
"World": "_world",
|
|
59
|
+
"WorldRegistry": "_world",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if TYPE_CHECKING: # pragma: no cover — static analysers still see the symbols
|
|
63
|
+
from ._harbor import CliDockerRuntime, DockerRuntime, ExecResult, HarborWorld
|
|
64
|
+
from ._world import VerifierResult, World, WorldRegistry
|
|
65
|
+
from .core import (
|
|
66
|
+
ENV_ENVIRONMENT_PREFIX,
|
|
67
|
+
Environment,
|
|
68
|
+
Report,
|
|
69
|
+
RouteRecord,
|
|
70
|
+
get_active_world,
|
|
71
|
+
init,
|
|
72
|
+
init_from_path,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def __getattr__(name: str):
|
|
77
|
+
module = _LAZY_ATTRS.get(name)
|
|
78
|
+
if module is None:
|
|
79
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
80
|
+
return getattr(importlib.import_module(f".{module}", __name__), name)
|
|
81
|
+
|
|
82
|
+
__all__ = [
|
|
83
|
+
"ENV_ENVIRONMENT_PREFIX",
|
|
84
|
+
"CliDockerRuntime",
|
|
85
|
+
"DockerRuntime",
|
|
86
|
+
"EnvManifest",
|
|
87
|
+
"Environment",
|
|
88
|
+
"EnvironmentKindError",
|
|
89
|
+
"EnvironmentNotConfigured",
|
|
90
|
+
"EnvironmentNotReady",
|
|
91
|
+
"ExecResult",
|
|
92
|
+
"GatewayEnvError",
|
|
93
|
+
"HarborTask",
|
|
94
|
+
"HarborWorld",
|
|
95
|
+
"HermeticViolation",
|
|
96
|
+
"Report",
|
|
97
|
+
"RouteRecord",
|
|
98
|
+
"ToolRouteError",
|
|
99
|
+
"VerifierError",
|
|
100
|
+
"VerifierResult",
|
|
101
|
+
"World",
|
|
102
|
+
"WorldRegistry",
|
|
103
|
+
"WorldStartError",
|
|
104
|
+
"get_active_world",
|
|
105
|
+
"init",
|
|
106
|
+
"init_from_path",
|
|
107
|
+
"runtime",
|
|
108
|
+
]
|