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,638 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import functools
|
|
5
|
+
import logging
|
|
6
|
+
import warnings
|
|
7
|
+
from typing import Any, Callable, Dict, Optional, Sequence, TypeVar, Union
|
|
8
|
+
|
|
9
|
+
from gatewaysdk.adapter import TraceAdapter, TracerTraceToTriplet
|
|
10
|
+
from gatewaysdk.algorithm import Algorithm, Baseline, FastAlgorithm
|
|
11
|
+
from gatewaysdk.client import GatewayClient
|
|
12
|
+
from gatewaysdk.execution.base import ExecutionStrategy
|
|
13
|
+
from gatewaysdk.execution.client_server import ClientServerExecutionStrategy
|
|
14
|
+
from gatewaysdk.execution.events import ExecutionEvent
|
|
15
|
+
from gatewaysdk.litagent import LitAgent
|
|
16
|
+
from gatewaysdk.llm_proxy import LLMProxy
|
|
17
|
+
from gatewaysdk.runner import LitAgentRunner, Runner
|
|
18
|
+
from gatewaysdk.store.base import LightningStore
|
|
19
|
+
from gatewaysdk.store.memory import InMemoryLightningStore
|
|
20
|
+
from gatewaysdk.tracer.base import Tracer
|
|
21
|
+
from gatewaysdk.tracer.otel import OtelTracer
|
|
22
|
+
from gatewaysdk.types import Dataset, Hook, NamedResources
|
|
23
|
+
|
|
24
|
+
from .init_utils import build_component, instantiate_component
|
|
25
|
+
from .legacy import TrainerLegacy
|
|
26
|
+
from .registry import ExecutionStrategyRegistry
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
T_co = TypeVar("T_co", covariant=True)
|
|
31
|
+
T = TypeVar("T")
|
|
32
|
+
|
|
33
|
+
ComponentSpec = Union[T, type[T], Callable[[], T], str, Dict[str, Any], None]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Trainer(TrainerLegacy):
|
|
37
|
+
"""High-level orchestration layer that wires Algorithm <-> Runner <-> Store.
|
|
38
|
+
|
|
39
|
+
A [`Trainer`][gatewaysdk.Trainer] packages the moving parts of Agent-Lightning's
|
|
40
|
+
training loop into a single entry point:
|
|
41
|
+
|
|
42
|
+
* **Algorithm lifecycle:** Instantiates or accepts an [`Algorithm`][gatewaysdk.Algorithm],
|
|
43
|
+
attaches the current [`LightningStore`][gatewaysdk.LightningStore], adapter, and
|
|
44
|
+
initial resources, then executes the algorithm role inside the configured execution strategy.
|
|
45
|
+
* **Runner fleet:** Spawns one or more [`Runner`][gatewaysdk.Runner] instances (defaulting
|
|
46
|
+
to [`LitAgentRunner`][gatewaysdk.LitAgentRunner]) that hydrate a [`LitAgent`][gatewaysdk.LitAgent],
|
|
47
|
+
claim rollouts, stream spans, and respect graceful termination signals from the execution strategy.
|
|
48
|
+
* **Execution strategy:** Delegates process management to an
|
|
49
|
+
[`ExecutionStrategy`][gatewaysdk.ExecutionStrategy] (shared memory, client/server, etc.),
|
|
50
|
+
so advanced users can swap orchestration backends without changing trainer code.
|
|
51
|
+
* **Telemetry plumbing:** Ensures tracers, adapters, and optional [`LLMProxy`][gatewaysdk.LLMProxy]
|
|
52
|
+
are wired into both algorithm and runners so telemetry flows back into the store.
|
|
53
|
+
|
|
54
|
+
The trainer exposes two convenience entry points:
|
|
55
|
+
[`fit()`][gatewaysdk.Trainer.fit] for full training and
|
|
56
|
+
[`dev()`][gatewaysdk.Trainer.dev] for fast, reproducible dry-runs. See the
|
|
57
|
+
[Train the First Agent](../how-to/train-first-agent.md) and
|
|
58
|
+
[Write the First Algorithm](../how-to/write-first-algorithm.md) tutorials for the broader context.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
algorithm: Optional[Algorithm]
|
|
62
|
+
"""An instance of [`Algorithm`][gatewaysdk.Algorithm] to use for training."""
|
|
63
|
+
|
|
64
|
+
store: LightningStore
|
|
65
|
+
"""An instance of [`LightningStore`][gatewaysdk.LightningStore] to use for storing tasks and traces."""
|
|
66
|
+
|
|
67
|
+
runner: Runner[Any]
|
|
68
|
+
"""An instance of [`Runner`][gatewaysdk.Runner] to use for running the agent."""
|
|
69
|
+
|
|
70
|
+
initial_resources: Optional[NamedResources]
|
|
71
|
+
"""An instance of [`NamedResources`][gatewaysdk.NamedResources] to use for bootstrapping the fit/dev process.
|
|
72
|
+
|
|
73
|
+
The resources will be handed over to the algorithm. Note that not all algorithms support seeding resources.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
n_runners: int
|
|
77
|
+
"""Number of agent runners to run in parallel."""
|
|
78
|
+
|
|
79
|
+
max_rollouts: Optional[int]
|
|
80
|
+
"""Maximum number of rollouts to process per runner. If None, workers run until no more rollouts are available."""
|
|
81
|
+
|
|
82
|
+
strategy: ExecutionStrategy
|
|
83
|
+
"""An instance of [`ExecutionStrategy`][gatewaysdk.ExecutionStrategy] to use for spawning the algorithm and runners."""
|
|
84
|
+
|
|
85
|
+
tracer: Tracer
|
|
86
|
+
"""A tracer instance, or a string pointing to the class full name or a dictionary with a 'type' key
|
|
87
|
+
that specifies the class full name and other initialization parameters.
|
|
88
|
+
If None, a default [`OtelTracer`][gatewaysdk.OtelTracer] will be created."""
|
|
89
|
+
|
|
90
|
+
hooks: Sequence[Hook]
|
|
91
|
+
"""A sequence of [`Hook`][gatewaysdk.Hook] instances to be called at various lifecycle stages (e.g., `on_trace_start`,
|
|
92
|
+
`on_trace_end`, `on_rollout_start`, `on_rollout_end`)."""
|
|
93
|
+
|
|
94
|
+
adapter: TraceAdapter[Any]
|
|
95
|
+
"""An instance of [`TraceAdapter`][gatewaysdk.TraceAdapter] to export data consumble by algorithms from traces."""
|
|
96
|
+
|
|
97
|
+
llm_proxy: Optional[LLMProxy]
|
|
98
|
+
"""An instance of [`LLMProxy`][gatewaysdk.LLMProxy] to use for intercepting the LLM calls.
|
|
99
|
+
If not provided, algorithm may create one on its own."""
|
|
100
|
+
|
|
101
|
+
n_workers: int
|
|
102
|
+
"""Number of agent workers to run in parallel. Deprecated in favor of `n_runners`."""
|
|
103
|
+
|
|
104
|
+
max_tasks: Optional[int]
|
|
105
|
+
"""Maximum number of tasks to process per runner. Deprecated in favor of `max_rollouts`."""
|
|
106
|
+
|
|
107
|
+
daemon: bool
|
|
108
|
+
"""Whether worker processes should be daemons. Daemon processes
|
|
109
|
+
are terminated automatically when the main process exits. Deprecated.
|
|
110
|
+
Only have effect with `fit_v0`."""
|
|
111
|
+
|
|
112
|
+
triplet_exporter: TraceAdapter[Any]
|
|
113
|
+
"""An instance of [`TracerTraceToTriplet`][gatewaysdk.TracerTraceToTriplet] to export triplets from traces,
|
|
114
|
+
or a dictionary with the initialization parameters for the exporter.
|
|
115
|
+
Deprecated. Use [`adapter`][gatewaysdk.Trainer.adapter] instead."""
|
|
116
|
+
|
|
117
|
+
port: Optional[int]
|
|
118
|
+
"""Port forwarded to [`ClientServerExecutionStrategy`][gatewaysdk.ClientServerExecutionStrategy]."""
|
|
119
|
+
|
|
120
|
+
def __init__(
|
|
121
|
+
self,
|
|
122
|
+
*,
|
|
123
|
+
dev: bool = False,
|
|
124
|
+
n_runners: Optional[int] = None,
|
|
125
|
+
max_rollouts: Optional[int] = None,
|
|
126
|
+
initial_resources: Optional[NamedResources] = None,
|
|
127
|
+
tracer: ComponentSpec[Tracer] = None,
|
|
128
|
+
adapter: ComponentSpec[TraceAdapter[Any]] = None,
|
|
129
|
+
store: ComponentSpec[LightningStore] = None,
|
|
130
|
+
runner: ComponentSpec[Runner[Any]] = None,
|
|
131
|
+
strategy: ComponentSpec[ExecutionStrategy] = None,
|
|
132
|
+
port: Optional[int] = None,
|
|
133
|
+
algorithm: ComponentSpec[Algorithm] = None,
|
|
134
|
+
llm_proxy: ComponentSpec[LLMProxy] = None,
|
|
135
|
+
n_workers: Optional[int] = None,
|
|
136
|
+
max_tasks: Optional[int] = None,
|
|
137
|
+
daemon: bool = True,
|
|
138
|
+
triplet_exporter: ComponentSpec[TracerTraceToTriplet] = None,
|
|
139
|
+
hooks: Optional[Union[Hook, Sequence[Hook]]] = None,
|
|
140
|
+
):
|
|
141
|
+
"""Configure the trainer and resolve user-provided component specifications.
|
|
142
|
+
|
|
143
|
+
Each keyword accepts either a concrete instance, a class, a callable factory, a
|
|
144
|
+
registry string, or a lightweight configuration dictionary (see
|
|
145
|
+
[`build_component()`][gatewaysdk.trainer.init_utils.build_component]).
|
|
146
|
+
|
|
147
|
+
When ``port`` is provided it is forwarded to
|
|
148
|
+
[`ClientServerExecutionStrategy`][gatewaysdk.ClientServerExecutionStrategy]
|
|
149
|
+
instances constructed (or supplied) for the trainer.
|
|
150
|
+
"""
|
|
151
|
+
# Do not call super().__init__() here.
|
|
152
|
+
# super().__init__() will call TrainerLegacy's initialization, which is not intended.
|
|
153
|
+
self.worker_id: Optional[int] = None
|
|
154
|
+
|
|
155
|
+
if dev:
|
|
156
|
+
warnings.warn(
|
|
157
|
+
"Trainer(dev=True) is deprecated and will be removed in future versions. "
|
|
158
|
+
"Please use Trainer.dev(...) instead.",
|
|
159
|
+
DeprecationWarning,
|
|
160
|
+
stacklevel=2,
|
|
161
|
+
)
|
|
162
|
+
self._dev = dev
|
|
163
|
+
self.daemon = daemon
|
|
164
|
+
self._client: GatewayClient | None = None # Will be initialized in fit or fit_v0
|
|
165
|
+
|
|
166
|
+
if n_workers is not None:
|
|
167
|
+
warnings.warn(
|
|
168
|
+
"`n_workers` is deprecated. Please use `n_runners`.",
|
|
169
|
+
DeprecationWarning,
|
|
170
|
+
stacklevel=2,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if n_runners is None:
|
|
174
|
+
n_runners = n_workers if n_workers is not None else 1
|
|
175
|
+
else:
|
|
176
|
+
if n_workers is not None and n_workers != n_runners:
|
|
177
|
+
warnings.warn(
|
|
178
|
+
"`n_workers` is ignored when `n_runners` is provided.",
|
|
179
|
+
DeprecationWarning,
|
|
180
|
+
stacklevel=2,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
self.n_runners = n_runners
|
|
184
|
+
self.n_workers = n_runners # Backwards compatibility for fit_v0
|
|
185
|
+
|
|
186
|
+
if max_tasks is not None:
|
|
187
|
+
warnings.warn(
|
|
188
|
+
"`max_tasks` is deprecated. Please use `max_rollouts`.",
|
|
189
|
+
DeprecationWarning,
|
|
190
|
+
stacklevel=2,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if max_rollouts is None:
|
|
194
|
+
max_rollouts = max_tasks
|
|
195
|
+
elif max_tasks is not None and max_tasks != max_rollouts:
|
|
196
|
+
warnings.warn(
|
|
197
|
+
"`max_tasks` is ignored when `max_rollouts` is provided.",
|
|
198
|
+
DeprecationWarning,
|
|
199
|
+
stacklevel=2,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
self.max_rollouts = max_rollouts
|
|
203
|
+
self.max_tasks = max_tasks if max_tasks is not None else max_rollouts
|
|
204
|
+
|
|
205
|
+
# Note: tracer is created after store to enable auto-detection of OTLP-capable stores
|
|
206
|
+
self._tracer_spec = tracer # Store spec for later resolution
|
|
207
|
+
|
|
208
|
+
if adapter is not None and triplet_exporter is not None:
|
|
209
|
+
warnings.warn(
|
|
210
|
+
"`triplet_exporter` is deprecated and ignored because `adapter` is provided.",
|
|
211
|
+
DeprecationWarning,
|
|
212
|
+
stacklevel=2,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
adapter_spec = adapter if adapter is not None else triplet_exporter
|
|
216
|
+
self.adapter = self._make_adapter(adapter_spec)
|
|
217
|
+
self.triplet_exporter = self.adapter # Backwards compatibility
|
|
218
|
+
|
|
219
|
+
self.algorithm = self._make_algorithm(algorithm)
|
|
220
|
+
|
|
221
|
+
# We might be able to support a list of resources in future.
|
|
222
|
+
self.initial_resources = initial_resources
|
|
223
|
+
|
|
224
|
+
self.port = port
|
|
225
|
+
|
|
226
|
+
self.strategy = self._make_strategy(
|
|
227
|
+
strategy,
|
|
228
|
+
n_runners=self.n_runners,
|
|
229
|
+
port=port,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# The active store for the current execution context
|
|
233
|
+
self.store = self._make_store(store, self.strategy)
|
|
234
|
+
|
|
235
|
+
# Create tracer after store so we can auto-detect OTLP-capable stores
|
|
236
|
+
self.tracer = self._make_tracer(self._tracer_spec, self.store)
|
|
237
|
+
|
|
238
|
+
self.runner = self._make_runner(runner)
|
|
239
|
+
|
|
240
|
+
if hasattr(self.strategy, "n_runners"):
|
|
241
|
+
strategy_runners = getattr(self.strategy, "n_runners")
|
|
242
|
+
if isinstance(strategy_runners, int) and strategy_runners > 0:
|
|
243
|
+
self.n_runners = strategy_runners
|
|
244
|
+
self.n_workers = strategy_runners
|
|
245
|
+
|
|
246
|
+
self.llm_proxy = self._make_llm_proxy(llm_proxy, store=self.store)
|
|
247
|
+
|
|
248
|
+
self.hooks = self._normalize_hooks(hooks)
|
|
249
|
+
|
|
250
|
+
if not self.daemon:
|
|
251
|
+
logger.warning(
|
|
252
|
+
"daemon=False. Worker processes are non-daemonic. "
|
|
253
|
+
"The worker processes will NOT be terminated when the main process exits. "
|
|
254
|
+
"The cleanup must be handled manually."
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
def _make_tracer(self, tracer: ComponentSpec[Tracer], store: Optional[LightningStore] = None) -> Tracer:
|
|
258
|
+
"""Resolve the tracer component from user input.
|
|
259
|
+
|
|
260
|
+
Uses OtelTracer as the default tracer for all stores.
|
|
261
|
+
"""
|
|
262
|
+
default_factory = lambda: OtelTracer()
|
|
263
|
+
|
|
264
|
+
return build_component(
|
|
265
|
+
tracer,
|
|
266
|
+
expected_type=Tracer,
|
|
267
|
+
spec_name="tracer",
|
|
268
|
+
default_factory=default_factory,
|
|
269
|
+
dict_requires_type=True,
|
|
270
|
+
invalid_spec_error_fmt="Invalid tracer type: {actual_type}. Expected Tracer, str, dict, or None.",
|
|
271
|
+
type_error_fmt="Tracer factory returned {type_name}, which is not a Tracer subclass.",
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def _make_algorithm(self, algorithm: ComponentSpec[Algorithm]) -> Optional[Algorithm]:
|
|
275
|
+
"""Resolve the algorithm component, allowing `None` for dev-mode dry runs."""
|
|
276
|
+
return build_component(
|
|
277
|
+
algorithm,
|
|
278
|
+
expected_type=Algorithm,
|
|
279
|
+
spec_name="algorithm",
|
|
280
|
+
allow_none=True,
|
|
281
|
+
invalid_spec_error_fmt="Invalid algorithm type: {actual_type}. Expected Algorithm, str, dict, or None.",
|
|
282
|
+
type_error_fmt="Algorithm factory returned {type_name}, which is not a Algorithm subclass.",
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
def _make_adapter(self, adapter: ComponentSpec[TraceAdapter[Any]]) -> TraceAdapter[Any]:
|
|
286
|
+
"""Resolve the adapter used to transform spans into algorithm-ready payloads."""
|
|
287
|
+
return build_component(
|
|
288
|
+
adapter,
|
|
289
|
+
expected_type=TraceAdapter,
|
|
290
|
+
spec_name="adapter",
|
|
291
|
+
default_factory=TracerTraceToTriplet,
|
|
292
|
+
dict_requires_type=False,
|
|
293
|
+
dict_default_cls=TracerTraceToTriplet,
|
|
294
|
+
invalid_spec_error_fmt="Invalid adapter type: {actual_type}. Expected TraceAdapter, dict, or None.",
|
|
295
|
+
type_error_fmt="Adapter factory returned {type_name}, which is not a TraceAdapter subclass.",
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
def _make_store(self, store: ComponentSpec[LightningStore], strategy: ExecutionStrategy) -> LightningStore:
|
|
299
|
+
"""Resolve the store implementation backing rollouts, attempts, spans, and resources.
|
|
300
|
+
|
|
301
|
+
By default, it's always a in-memory store. If using a client/server execution strategy,
|
|
302
|
+
the in-memory store will be initialized in a thread-safe manner.
|
|
303
|
+
"""
|
|
304
|
+
is_client_server = isinstance(strategy, ClientServerExecutionStrategy)
|
|
305
|
+
default_store_factory = lambda: InMemoryLightningStore(thread_safe=is_client_server)
|
|
306
|
+
return build_component(
|
|
307
|
+
store,
|
|
308
|
+
expected_type=LightningStore,
|
|
309
|
+
spec_name="store",
|
|
310
|
+
default_factory=default_store_factory,
|
|
311
|
+
invalid_spec_error_fmt="Invalid store type: {actual_type}. Expected LightningStore, str, dict, or None.",
|
|
312
|
+
type_error_fmt="Store factory returned {type_name}, which is not a LightningStore subclass.",
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
def _make_strategy(
|
|
316
|
+
self,
|
|
317
|
+
strategy: ComponentSpec[ExecutionStrategy],
|
|
318
|
+
*,
|
|
319
|
+
n_runners: int,
|
|
320
|
+
port: Optional[int] = None,
|
|
321
|
+
) -> ExecutionStrategy:
|
|
322
|
+
"""Resolve the execution strategy and seed defaults such as `n_runners`."""
|
|
323
|
+
if isinstance(strategy, ExecutionStrategy):
|
|
324
|
+
if port is not None and isinstance(strategy, ClientServerExecutionStrategy):
|
|
325
|
+
strategy.server_port = port
|
|
326
|
+
return strategy
|
|
327
|
+
optional_defaults: Dict[str, Callable[[], Any]] = {"n_runners": lambda: n_runners}
|
|
328
|
+
if port is not None:
|
|
329
|
+
optional_defaults["server_port"] = lambda: port
|
|
330
|
+
|
|
331
|
+
def default_factory() -> ExecutionStrategy:
|
|
332
|
+
if port is not None:
|
|
333
|
+
return ClientServerExecutionStrategy(n_runners=n_runners, server_port=port)
|
|
334
|
+
return ClientServerExecutionStrategy(n_runners=n_runners)
|
|
335
|
+
|
|
336
|
+
return build_component(
|
|
337
|
+
strategy,
|
|
338
|
+
expected_type=ExecutionStrategy,
|
|
339
|
+
spec_name="strategy",
|
|
340
|
+
default_factory=default_factory,
|
|
341
|
+
optional_defaults=optional_defaults,
|
|
342
|
+
invalid_spec_error_fmt="Invalid strategy type: {actual_type}. Expected ExecutionStrategy, str, dict, or None.",
|
|
343
|
+
type_error_fmt="Strategy factory returned {type_name}, which is not an ExecutionStrategy subclass.",
|
|
344
|
+
registry=ExecutionStrategyRegistry,
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
def _make_llm_proxy(
|
|
348
|
+
self,
|
|
349
|
+
llm_proxy: ComponentSpec[LLMProxy],
|
|
350
|
+
*,
|
|
351
|
+
store: LightningStore,
|
|
352
|
+
) -> Optional[LLMProxy]:
|
|
353
|
+
"""Resolve an optional LLM proxy and ensure it shares the trainer's store instance."""
|
|
354
|
+
if isinstance(llm_proxy, LLMProxy):
|
|
355
|
+
return llm_proxy
|
|
356
|
+
|
|
357
|
+
optional_defaults: Dict[str, Callable[[], Any]] = {"store": lambda: store}
|
|
358
|
+
|
|
359
|
+
# Extract OTLP endpoint and headers from store if it supports OTLP
|
|
360
|
+
if hasattr(store, "capabilities") and store.capabilities.get("otlp_traces", False):
|
|
361
|
+
try:
|
|
362
|
+
otlp_endpoint = store.otlp_traces_endpoint()
|
|
363
|
+
otlp_headers = store.get_otlp_headers() if hasattr(store, "get_otlp_headers") else {}
|
|
364
|
+
optional_defaults["otlp_endpoint"] = lambda: otlp_endpoint
|
|
365
|
+
optional_defaults["otlp_headers"] = lambda: otlp_headers
|
|
366
|
+
logger.info(f"Trainer: Store provides OTLP endpoint for proxy: {otlp_endpoint}")
|
|
367
|
+
except Exception as e:
|
|
368
|
+
logger.warning(f"Trainer: Failed to get OTLP endpoint from store: {e}")
|
|
369
|
+
|
|
370
|
+
if isinstance(llm_proxy, dict):
|
|
371
|
+
llm_proxy = {**llm_proxy}
|
|
372
|
+
llm_proxy.setdefault("store", store)
|
|
373
|
+
# Pass OTLP config to proxy if store provides it and it's not already set
|
|
374
|
+
if "otlp_endpoint" in optional_defaults and "otlp_endpoint" not in llm_proxy:
|
|
375
|
+
llm_proxy.setdefault("otlp_endpoint", optional_defaults["otlp_endpoint"]())
|
|
376
|
+
if "otlp_headers" in optional_defaults and "otlp_headers" not in llm_proxy:
|
|
377
|
+
llm_proxy.setdefault("otlp_headers", optional_defaults["otlp_headers"]())
|
|
378
|
+
|
|
379
|
+
return build_component(
|
|
380
|
+
llm_proxy,
|
|
381
|
+
expected_type=LLMProxy,
|
|
382
|
+
spec_name="llm_proxy",
|
|
383
|
+
allow_none=True,
|
|
384
|
+
optional_defaults=optional_defaults,
|
|
385
|
+
invalid_spec_error_fmt="Invalid llm_proxy type: {actual_type}. Expected LLMProxy, dict, str, or None.",
|
|
386
|
+
type_error_fmt="llm_proxy factory returned {type_name}, which is not an LLMProxy subclass.",
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
def _make_runner(self, runner: ComponentSpec[Runner[Any]]) -> Runner[Any]:
|
|
390
|
+
"""Resolve the runner responsible for executing the agent inside each worker."""
|
|
391
|
+
optional_defaults: Dict[str, Callable[[], Any]] = {"tracer": lambda: self.tracer}
|
|
392
|
+
if self.max_rollouts is not None:
|
|
393
|
+
optional_defaults["max_rollouts"] = lambda: self.max_rollouts
|
|
394
|
+
|
|
395
|
+
def default_runner_factory() -> Runner[Any]:
|
|
396
|
+
return instantiate_component(LitAgentRunner, optional_defaults=optional_defaults)
|
|
397
|
+
|
|
398
|
+
return build_component(
|
|
399
|
+
runner,
|
|
400
|
+
expected_type=Runner,
|
|
401
|
+
spec_name="runner",
|
|
402
|
+
default_factory=default_runner_factory,
|
|
403
|
+
optional_defaults=optional_defaults,
|
|
404
|
+
invalid_spec_error_fmt="Invalid runner type: {actual_type}. Expected Runner, callable, str, dict, or None.",
|
|
405
|
+
type_error_fmt="Runner factory returned {type_name}, which is not a Runner subclass.",
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
def _normalize_hooks(self, hooks: Optional[Union[Hook, Sequence[Hook]]]) -> Sequence[Hook]:
|
|
409
|
+
"""Coerce hook inputs into an immutable sequence for runner initialization."""
|
|
410
|
+
if hooks is None:
|
|
411
|
+
return ()
|
|
412
|
+
if isinstance(hooks, Hook):
|
|
413
|
+
return (hooks,)
|
|
414
|
+
return tuple(hooks)
|
|
415
|
+
|
|
416
|
+
def fit(
|
|
417
|
+
self,
|
|
418
|
+
agent: LitAgent[T_co],
|
|
419
|
+
train_dataset: Optional[Dataset[T_co]] = None,
|
|
420
|
+
*,
|
|
421
|
+
val_dataset: Optional[Dataset[T_co]] = None,
|
|
422
|
+
) -> None:
|
|
423
|
+
"""Execute the full algorithm/runner training loop.
|
|
424
|
+
|
|
425
|
+
[`Trainer.fit`][gatewaysdk.Trainer.fit] packages the algorithm and runner bundles,
|
|
426
|
+
then hands them to the active [`ExecutionStrategy`][gatewaysdk.ExecutionStrategy].
|
|
427
|
+
The strategy rarely returns until:
|
|
428
|
+
|
|
429
|
+
* The algorithm exhausts the dataset(s) and stops enqueuing rollouts.
|
|
430
|
+
* `max_rollouts` causes individual runners to exit.
|
|
431
|
+
* An exception or interrupt cancels the shared [`ExecutionEvent`][gatewaysdk.ExecutionEvent].
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
agent: [`LitAgent`][gatewaysdk.LitAgent] implementation executed by runners.
|
|
435
|
+
train_dataset: Optional iterable of rollout inputs consumed by the algorithm.
|
|
436
|
+
val_dataset: Optional iterable consumed by validation passes.
|
|
437
|
+
"""
|
|
438
|
+
if isinstance(train_dataset, str):
|
|
439
|
+
logger.warning(
|
|
440
|
+
"Trainer.fit will no longer accepts a string URL in future version. "
|
|
441
|
+
"To continue using a string URL, please use Trainer.fit_v0 instead. "
|
|
442
|
+
"See documentation for how to migrate to latest version: https://microsoft.github.io/gatewaysdk/stable/"
|
|
443
|
+
)
|
|
444
|
+
return self.fit_v0( # type: ignore
|
|
445
|
+
agent,
|
|
446
|
+
train_dataset,
|
|
447
|
+
val_dataset, # type: ignore
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
agent.set_trainer(self)
|
|
451
|
+
|
|
452
|
+
# Wire remote cancellation: if the UI cancels the run, the heartbeat
|
|
453
|
+
# detects it and calls algorithm.request_cancel() so GEPA/Evals stop.
|
|
454
|
+
if self.algorithm is not None and hasattr(self.store, "_run"):
|
|
455
|
+
run_obj = getattr(self.store, "_run", None)
|
|
456
|
+
if run_obj is not None and hasattr(run_obj, "set_on_cancel"):
|
|
457
|
+
run_obj.set_on_cancel(self.algorithm.request_cancel)
|
|
458
|
+
|
|
459
|
+
algorithm_bundle = functools.partial(
|
|
460
|
+
self._algorithm_bundle,
|
|
461
|
+
train_dataset=train_dataset,
|
|
462
|
+
val_dataset=val_dataset,
|
|
463
|
+
algorithm=self.algorithm,
|
|
464
|
+
)
|
|
465
|
+
runner_bundle = functools.partial(self._runner_bundle, agent=agent)
|
|
466
|
+
|
|
467
|
+
# Execute training with automatic run lifecycle management
|
|
468
|
+
try:
|
|
469
|
+
self.strategy.execute(algorithm_bundle, runner_bundle, self.store)
|
|
470
|
+
|
|
471
|
+
# Mark run as completed on success
|
|
472
|
+
if hasattr(self.store, "complete"):
|
|
473
|
+
try:
|
|
474
|
+
self.store.complete()
|
|
475
|
+
logger.info("Run marked as completed")
|
|
476
|
+
except Exception as e:
|
|
477
|
+
logger.warning(f"Failed to mark run as completed: {e}")
|
|
478
|
+
except Exception as e:
|
|
479
|
+
# Mark run as failed on exception
|
|
480
|
+
if hasattr(self.store, "fail"):
|
|
481
|
+
try:
|
|
482
|
+
self.store.fail(str(e))
|
|
483
|
+
logger.info(f"Run marked as failed: {e}")
|
|
484
|
+
except Exception as fail_err:
|
|
485
|
+
logger.warning(f"Failed to mark run as failed: {fail_err}")
|
|
486
|
+
raise
|
|
487
|
+
|
|
488
|
+
def dev(
|
|
489
|
+
self,
|
|
490
|
+
agent: LitAgent[T_co],
|
|
491
|
+
train_dataset: Optional[Dataset[T_co]] = None,
|
|
492
|
+
*,
|
|
493
|
+
val_dataset: Optional[Dataset[T_co]] = None,
|
|
494
|
+
) -> None:
|
|
495
|
+
"""Exercise the infrastructure using a fast, synchronous algorithm.
|
|
496
|
+
|
|
497
|
+
[`Trainer.dev`][gatewaysdk.Trainer.dev] mirrors [`fit()`][gatewaysdk.Trainer.fit] but
|
|
498
|
+
insists on an [`Algorithm`][gatewaysdk.Algorithm] subtype that also derives from
|
|
499
|
+
[`FastAlgorithm`][gatewaysdk.FastAlgorithm]. This keeps the loop responsive for
|
|
500
|
+
debugging while still touching the same store, runners, hooks, and tracer plumbing.
|
|
501
|
+
|
|
502
|
+
If no algorithm is provided, a default [`Baseline`][gatewaysdk.Baseline] algorithm will be used.
|
|
503
|
+
|
|
504
|
+
Args:
|
|
505
|
+
agent: [`LitAgent`][gatewaysdk.LitAgent] implementation to execute.
|
|
506
|
+
train_dataset: Optional iterable passed to the algorithm.
|
|
507
|
+
val_dataset: Optional iterable passed to the algorithm.
|
|
508
|
+
|
|
509
|
+
Raises:
|
|
510
|
+
TypeError: If the configured algorithm does not inherit from `FastAlgorithm`.
|
|
511
|
+
"""
|
|
512
|
+
agent.set_trainer(self)
|
|
513
|
+
|
|
514
|
+
# Sanity check
|
|
515
|
+
if self.algorithm is None:
|
|
516
|
+
algorithm = Baseline()
|
|
517
|
+
else:
|
|
518
|
+
algorithm = self.algorithm
|
|
519
|
+
|
|
520
|
+
if not isinstance(algorithm, FastAlgorithm):
|
|
521
|
+
raise TypeError(
|
|
522
|
+
"Trainer.dev() requires an algorithm that inherits from FastAlgorithm. "
|
|
523
|
+
f"Received {type(algorithm).__name__}."
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
algorithm_bundle = functools.partial(
|
|
527
|
+
self._algorithm_bundle,
|
|
528
|
+
train_dataset=train_dataset,
|
|
529
|
+
val_dataset=val_dataset,
|
|
530
|
+
algorithm=algorithm,
|
|
531
|
+
)
|
|
532
|
+
runner_bundle = functools.partial(self._runner_bundle, agent=agent)
|
|
533
|
+
|
|
534
|
+
# Execute with automatic run lifecycle management
|
|
535
|
+
try:
|
|
536
|
+
self.strategy.execute(algorithm_bundle, runner_bundle, self.store)
|
|
537
|
+
|
|
538
|
+
# Mark run as completed on success
|
|
539
|
+
if hasattr(self.store, "complete"):
|
|
540
|
+
try:
|
|
541
|
+
self.store.complete()
|
|
542
|
+
logger.info("Run marked as completed")
|
|
543
|
+
except Exception as e:
|
|
544
|
+
logger.warning(f"Failed to mark run as completed: {e}")
|
|
545
|
+
except Exception as e:
|
|
546
|
+
# Mark run as failed on exception
|
|
547
|
+
if hasattr(self.store, "fail"):
|
|
548
|
+
try:
|
|
549
|
+
self.store.fail(str(e))
|
|
550
|
+
logger.info(f"Run marked as failed: {e}")
|
|
551
|
+
except Exception as fail_err:
|
|
552
|
+
logger.warning(f"Failed to mark run as failed: {fail_err}")
|
|
553
|
+
raise
|
|
554
|
+
|
|
555
|
+
async def _algorithm_bundle(
|
|
556
|
+
self,
|
|
557
|
+
store: LightningStore,
|
|
558
|
+
event: ExecutionEvent,
|
|
559
|
+
train_dataset: Optional[Dataset[T_co]],
|
|
560
|
+
val_dataset: Optional[Dataset[T_co]],
|
|
561
|
+
algorithm: Optional[Algorithm],
|
|
562
|
+
) -> None:
|
|
563
|
+
"""Internal entry point executed by the strategy for the algorithm role.
|
|
564
|
+
|
|
565
|
+
This coroutine is scheduled inside the strategy's process/thread and is responsible
|
|
566
|
+
for binding algorithm dependencies (store, adapter, initial resources, proxy) before
|
|
567
|
+
invoking [`Algorithm.run`][gatewaysdk.Algorithm.run].
|
|
568
|
+
When `algorithm` is `None` the bundle simply waits for the
|
|
569
|
+
shared `event` to signal shutdown so runners can still execute (useful for manual queue
|
|
570
|
+
seeding or external algorithms).
|
|
571
|
+
"""
|
|
572
|
+
if algorithm is not None:
|
|
573
|
+
algorithm.set_trainer(self)
|
|
574
|
+
algorithm.set_store(store)
|
|
575
|
+
algorithm.set_adapter(self.adapter)
|
|
576
|
+
if self.initial_resources is not None:
|
|
577
|
+
algorithm.set_initial_resources(self.initial_resources)
|
|
578
|
+
if self.llm_proxy is not None:
|
|
579
|
+
self.llm_proxy.set_store(store)
|
|
580
|
+
algorithm.set_llm_proxy(self.llm_proxy)
|
|
581
|
+
|
|
582
|
+
if algorithm is None:
|
|
583
|
+
while not event.is_set():
|
|
584
|
+
await asyncio.sleep(0.1)
|
|
585
|
+
return
|
|
586
|
+
try:
|
|
587
|
+
if algorithm.is_async():
|
|
588
|
+
await algorithm.run( # type: ignore
|
|
589
|
+
train_dataset=train_dataset,
|
|
590
|
+
val_dataset=val_dataset,
|
|
591
|
+
)
|
|
592
|
+
else:
|
|
593
|
+
# This will block the event loop to maximize the debugging experience
|
|
594
|
+
# It's the responsibility of the execution strategy to enable async execution
|
|
595
|
+
algorithm.run(
|
|
596
|
+
train_dataset=train_dataset,
|
|
597
|
+
val_dataset=val_dataset,
|
|
598
|
+
)
|
|
599
|
+
except Exception:
|
|
600
|
+
logger.exception("Algorithm bundle encountered an error.")
|
|
601
|
+
raise
|
|
602
|
+
|
|
603
|
+
async def _runner_bundle(
|
|
604
|
+
self, store: LightningStore, worker_id: int, event: ExecutionEvent, agent: LitAgent[T_co]
|
|
605
|
+
) -> None:
|
|
606
|
+
"""Internal entry point executed by the strategy for each runner role.
|
|
607
|
+
|
|
608
|
+
The bundle materializes the configured runner, binds the agent and hooks, associates
|
|
609
|
+
the worker with the shared store, and then drives the runner's [`iter`][gatewaysdk.Runner.iter]
|
|
610
|
+
loop until the execution event is set or an exception occurs. Cleanup mirrors the initialization
|
|
611
|
+
sequence to keep tracer state, hooks, and agent resources consistent across restarts.
|
|
612
|
+
"""
|
|
613
|
+
runner_instance: Runner[Any] | None = None
|
|
614
|
+
runner_initialized = False
|
|
615
|
+
worker_initialized = False
|
|
616
|
+
try:
|
|
617
|
+
# If not using shm execution strategy, we are already in the forked process
|
|
618
|
+
runner_instance = self.runner
|
|
619
|
+
runner_instance.init(agent=agent, hooks=self.hooks)
|
|
620
|
+
runner_initialized = True
|
|
621
|
+
runner_instance.init_worker(worker_id, store)
|
|
622
|
+
worker_initialized = True
|
|
623
|
+
await runner_instance.iter(event=event)
|
|
624
|
+
except Exception:
|
|
625
|
+
logger.exception("Runner bundle encountered an error (worker_id=%s).", worker_id)
|
|
626
|
+
raise
|
|
627
|
+
finally:
|
|
628
|
+
if runner_instance is not None:
|
|
629
|
+
if worker_initialized:
|
|
630
|
+
try:
|
|
631
|
+
runner_instance.teardown_worker(worker_id)
|
|
632
|
+
except Exception:
|
|
633
|
+
logger.exception("Error during runner worker teardown (worker_id=%s).", worker_id)
|
|
634
|
+
if runner_initialized:
|
|
635
|
+
try:
|
|
636
|
+
runner_instance.teardown()
|
|
637
|
+
except Exception:
|
|
638
|
+
logger.exception("Error during runner teardown (worker_id=%s).", worker_id)
|