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,275 @@
|
|
|
1
|
+
"""The UI and browser surfaces of a World Host session.
|
|
2
|
+
|
|
3
|
+
The api surface is the world's own routes, answered by :class:`WorldApp`. The
|
|
4
|
+
two surfaces here are what a *person* (or an agent driving a browser) reaches:
|
|
5
|
+
|
|
6
|
+
* **ui** — ``w-<sid>.<domain>``: the version's prebuilt static UI (``[ui]
|
|
7
|
+
static = "ui/static"`` in ``gateway-api-world.toml``), a single-page app served
|
|
8
|
+
straight from the version cache with an SPA fallback, plus its same-origin
|
|
9
|
+
``api_path`` prefix rewritten onto the session's own api. The pod engine
|
|
10
|
+
builds this into an nginx image per version; the host serves the files.
|
|
11
|
+
* **browser** — ``w-<sid>-cdp.<domain>``: a websocket tunnel to the Chromium
|
|
12
|
+
the platform leased for the session from the browser pool (one
|
|
13
|
+
``deploy/world-browser`` relay per session, single use). The host checks the
|
|
14
|
+
per-session token or live grant, then pipes bytes.
|
|
15
|
+
|
|
16
|
+
A browser cannot set an ``Authorization`` header on a page load, so the ui
|
|
17
|
+
surface admits a session token from a cookie as well: the first request
|
|
18
|
+
carries ``?token=`` (the URL the platform hands out), the host answers with the
|
|
19
|
+
cookie and a redirect to the same URL without it, and every request after
|
|
20
|
+
that — pages, assets, ``api_path`` calls — is admitted by the cookie.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import hmac
|
|
26
|
+
import mimetypes
|
|
27
|
+
import selectors
|
|
28
|
+
import socket
|
|
29
|
+
import time
|
|
30
|
+
import urllib.parse
|
|
31
|
+
from dataclasses import dataclass
|
|
32
|
+
from http.cookies import SimpleCookie
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
import tomllib
|
|
37
|
+
except ModuleNotFoundError: # pragma: no cover - python < 3.11
|
|
38
|
+
import tomli as tomllib # type: ignore[no-redef]
|
|
39
|
+
|
|
40
|
+
from .validation import fail
|
|
41
|
+
|
|
42
|
+
API_BUNDLE = "gateway-api-world.toml"
|
|
43
|
+
#: The cookie the ui surface admits a session by.
|
|
44
|
+
SESSION_COOKIE = "__world_session"
|
|
45
|
+
#: Query parameter that carries the session token exactly once, on the way in.
|
|
46
|
+
TOKEN_QUERY = "token"
|
|
47
|
+
#: Marks a request another host already forwarded once; never sent on again.
|
|
48
|
+
HOP_HEADER = "x-worlds-hop"
|
|
49
|
+
#: Headers copied from a websocket client's upgrade request upstream.
|
|
50
|
+
UPGRADE_HEADERS = (
|
|
51
|
+
HOP_HEADER,
|
|
52
|
+
"upgrade",
|
|
53
|
+
"connection",
|
|
54
|
+
"sec-websocket-key",
|
|
55
|
+
"sec-websocket-version",
|
|
56
|
+
"sec-websocket-protocol",
|
|
57
|
+
"sec-websocket-extensions",
|
|
58
|
+
"origin",
|
|
59
|
+
"user-agent",
|
|
60
|
+
)
|
|
61
|
+
#: Live-view grant scopes, as ``deploy/world-browser/relay.mjs`` knows them.
|
|
62
|
+
LIVE_SCOPES = ("view", "control")
|
|
63
|
+
TUNNEL_CONNECT_TIMEOUT_S = 10.0
|
|
64
|
+
TUNNEL_BUFFER = 64 * 1024
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# --------------------------------------------------------------------------- #
|
|
68
|
+
# The static ui.
|
|
69
|
+
# --------------------------------------------------------------------------- #
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@dataclass(frozen=True)
|
|
73
|
+
class UiSurface:
|
|
74
|
+
#: The directory holding ``index.html`` and the built assets.
|
|
75
|
+
root: Path
|
|
76
|
+
#: The page an agent lands on first.
|
|
77
|
+
entry: str
|
|
78
|
+
#: Same-origin prefix the SPA calls the api at, or None when it has none.
|
|
79
|
+
api_path: str | None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def load_ui_surface(bundle: Path) -> UiSurface | None:
|
|
83
|
+
"""The bundle's static ui, or None when its manifest declares none.
|
|
84
|
+
``[ui] static`` names a directory inside the bundle; one that is missing,
|
|
85
|
+
outside the bundle or without an ``index.html`` is refused at open, so a
|
|
86
|
+
session never advertises a ui that would 404."""
|
|
87
|
+
manifest = bundle / API_BUNDLE
|
|
88
|
+
if not manifest.is_file():
|
|
89
|
+
return None
|
|
90
|
+
data = tomllib.loads(manifest.read_text(encoding="utf-8"))
|
|
91
|
+
ui = data.get("ui")
|
|
92
|
+
if not isinstance(ui, dict):
|
|
93
|
+
return None
|
|
94
|
+
static = ui.get("static")
|
|
95
|
+
if not isinstance(static, str) or not static:
|
|
96
|
+
return None
|
|
97
|
+
bundle_root = bundle.resolve()
|
|
98
|
+
root = (bundle_root / static).resolve()
|
|
99
|
+
if root != bundle_root and bundle_root not in root.parents:
|
|
100
|
+
fail("host", f"[ui].static = {static!r} points outside the bundle")
|
|
101
|
+
if not (root / "index.html").is_file():
|
|
102
|
+
fail("host", f"[ui].static = {static!r} has no index.html; build the ui before pushing")
|
|
103
|
+
entry = ui.get("entry")
|
|
104
|
+
api_path = ui.get("api_path")
|
|
105
|
+
return UiSurface(
|
|
106
|
+
root=root,
|
|
107
|
+
entry=entry if isinstance(entry, str) and entry.startswith("/") else "/",
|
|
108
|
+
api_path=(
|
|
109
|
+
api_path.rstrip("/") if isinstance(api_path, str) and api_path.startswith("/") and api_path != "/" else None
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def api_target(ui: UiSurface, path: str) -> str | None:
|
|
115
|
+
"""The api route a ui-origin ``path`` proxies to, or None when the path is
|
|
116
|
+
a page or an asset. ``/__world-api/v1/charges`` → ``/v1/charges``."""
|
|
117
|
+
prefix = ui.api_path
|
|
118
|
+
if prefix is None:
|
|
119
|
+
return None
|
|
120
|
+
if path == prefix:
|
|
121
|
+
return "/"
|
|
122
|
+
if path.startswith(prefix + "/"):
|
|
123
|
+
return path[len(prefix) :]
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def static_file(ui: UiSurface, path: str) -> tuple[int, dict[str, str], bytes]:
|
|
128
|
+
"""One static response: the file at ``path`` under the ui root, or
|
|
129
|
+
``index.html`` for a client-side route (a path with no extension). A path
|
|
130
|
+
that escapes the root, or names a missing asset, is a 404."""
|
|
131
|
+
rel = urllib.parse.unquote(path).lstrip("/")
|
|
132
|
+
candidate = (ui.root / rel).resolve() if rel else ui.root / "index.html"
|
|
133
|
+
if candidate != ui.root and ui.root not in candidate.parents:
|
|
134
|
+
return 404, {"content-type": "application/json"}, b'{"error":"not found"}'
|
|
135
|
+
if candidate.is_dir():
|
|
136
|
+
candidate = candidate / "index.html"
|
|
137
|
+
if not candidate.is_file():
|
|
138
|
+
if Path(rel).suffix:
|
|
139
|
+
return 404, {"content-type": "application/json"}, b'{"error":"not found"}'
|
|
140
|
+
candidate = ui.root / "index.html"
|
|
141
|
+
kind, _ = mimetypes.guess_type(candidate.name)
|
|
142
|
+
content_type = kind or "application/octet-stream"
|
|
143
|
+
if content_type.startswith("text/") or content_type in ("application/javascript", "application/json"):
|
|
144
|
+
content_type += "; charset=utf-8"
|
|
145
|
+
# Hashed assets live forever; index.html and anything unhashed must be
|
|
146
|
+
# re-checked so a new version's UI is what the agent sees.
|
|
147
|
+
cache = "public, max-age=31536000, immutable" if "assets/" in rel else "no-cache"
|
|
148
|
+
return 200, {"content-type": content_type, "cache-control": cache}, candidate.read_bytes()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# --------------------------------------------------------------------------- #
|
|
152
|
+
# Admitting a person: the token cookie.
|
|
153
|
+
# --------------------------------------------------------------------------- #
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def cookie_token(headers: dict[str, str]) -> str | None:
|
|
157
|
+
"""The session token a request's cookie carries, if any."""
|
|
158
|
+
raw = headers.get("cookie")
|
|
159
|
+
if not raw:
|
|
160
|
+
return None
|
|
161
|
+
jar: SimpleCookie = SimpleCookie()
|
|
162
|
+
try:
|
|
163
|
+
jar.load(raw)
|
|
164
|
+
except Exception: # noqa: BLE001 - a malformed cookie header admits nothing
|
|
165
|
+
return None
|
|
166
|
+
morsel = jar.get(SESSION_COOKIE)
|
|
167
|
+
return morsel.value if morsel is not None else None
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def query_token(query: str) -> str | None:
|
|
171
|
+
values = urllib.parse.parse_qs(query, keep_blank_values=False).get(TOKEN_QUERY)
|
|
172
|
+
return values[0] if values else None
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def without_query_token(url: urllib.parse.SplitResult) -> str:
|
|
176
|
+
"""The same request URL with ``?token=`` removed, for the redirect that
|
|
177
|
+
follows the cookie exchange."""
|
|
178
|
+
pairs = [(k, v) for k, v in urllib.parse.parse_qsl(url.query, keep_blank_values=True) if k != TOKEN_QUERY]
|
|
179
|
+
return urllib.parse.urlunsplit(("", "", url.path or "/", urllib.parse.urlencode(pairs), ""))
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def session_cookie(token: str, *, secure: bool, max_age_s: float) -> str:
|
|
183
|
+
"""The ``Set-Cookie`` value that admits this session. ``HttpOnly`` keeps it
|
|
184
|
+
from the SPA's own scripts; ``SameSite=Lax`` keeps other origins from
|
|
185
|
+
riding it; ``Secure`` is set unless the deployment says its public surface
|
|
186
|
+
is plain http (a dev host, ``WORLDS_HOST_PLAIN_HTTP=1``); ``Max-Age``
|
|
187
|
+
is the session's lease, so the browser forgets the credential when the
|
|
188
|
+
host would have, instead of keeping it for the profile's lifetime."""
|
|
189
|
+
attrs = [f"{SESSION_COOKIE}={token}", "Path=/", f"Max-Age={int(max_age_s)}", "HttpOnly", "SameSite=Lax"]
|
|
190
|
+
if secure:
|
|
191
|
+
attrs.append("Secure")
|
|
192
|
+
return "; ".join(attrs)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def matches(candidate: str | None, token: str) -> bool:
|
|
196
|
+
return candidate is not None and hmac.compare_digest(candidate, token)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# --------------------------------------------------------------------------- #
|
|
200
|
+
# Live-view grants: the relay's scheme, so a console viewer needs no token.
|
|
201
|
+
# --------------------------------------------------------------------------- #
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def mint_live_grant(token: str, ttl_ms: int, scope: str = "view", now_ms: int | None = None) -> str:
|
|
205
|
+
"""``<expiresAtMs>.<scope>.<hmac>`` signed with ``token`` — the format
|
|
206
|
+
``deploy/world-browser/relay.mjs`` verifies."""
|
|
207
|
+
if scope not in LIVE_SCOPES:
|
|
208
|
+
raise ValueError(f"unknown live scope {scope}")
|
|
209
|
+
exp = str((int(time.time() * 1000) if now_ms is None else now_ms) + ttl_ms)
|
|
210
|
+
sig = hmac.new(token.encode(), f"live:{scope}:{exp}".encode(), "sha256").hexdigest()
|
|
211
|
+
return f"{exp}.{scope}.{sig}"
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def verify_live_grant(grant: str, token: str, now_ms: int | None = None) -> str | None:
|
|
215
|
+
"""The grant's scope when it verifies against ``token`` and has not
|
|
216
|
+
expired, else None."""
|
|
217
|
+
parts = grant.split(".")
|
|
218
|
+
if len(parts) != 3 or not token:
|
|
219
|
+
return None
|
|
220
|
+
exp, scope, sig = parts
|
|
221
|
+
if not exp.isdigit() or len(exp) > 16 or scope not in LIVE_SCOPES or len(sig) != 64:
|
|
222
|
+
return None
|
|
223
|
+
if int(exp) <= (int(time.time() * 1000) if now_ms is None else now_ms):
|
|
224
|
+
return None
|
|
225
|
+
expected = hmac.new(token.encode(), f"live:{scope}:{exp}".encode(), "sha256").hexdigest()
|
|
226
|
+
return scope if hmac.compare_digest(sig, expected) else None
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
# --------------------------------------------------------------------------- #
|
|
230
|
+
# The websocket tunnel.
|
|
231
|
+
# --------------------------------------------------------------------------- #
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def tunnel(client: socket.socket, target: str, path: str, headers: dict[str, str], host: str | None = None) -> None:
|
|
235
|
+
"""Pipe a websocket client through to ``target`` (``ws://host:port``): send
|
|
236
|
+
the upgrade request for ``path`` with the client's handshake headers, then
|
|
237
|
+
copy bytes both ways until either side closes. The client's request line
|
|
238
|
+
and headers have already been read by the caller; a websocket client sends
|
|
239
|
+
nothing more until it has the ``101``, so nothing of its is lost. ``host``
|
|
240
|
+
is the ``Host`` presented upstream: the session's origin when the hop is
|
|
241
|
+
to another world host (which routes by it), the target's own by default."""
|
|
242
|
+
url = urllib.parse.urlsplit(target)
|
|
243
|
+
if url.scheme != "ws" or not url.hostname:
|
|
244
|
+
raise ValueError(f"browser url must be ws://host:port, not {target!r}")
|
|
245
|
+
upstream = socket.create_connection((url.hostname, url.port or 80), timeout=TUNNEL_CONNECT_TIMEOUT_S)
|
|
246
|
+
try:
|
|
247
|
+
lines = [f"GET {path} HTTP/1.1", f"Host: {host or url.netloc}"]
|
|
248
|
+
lines += [f"{name}: {headers[name]}" for name in UPGRADE_HEADERS if name in headers]
|
|
249
|
+
upstream.sendall(("\r\n".join(lines) + "\r\n\r\n").encode("latin-1"))
|
|
250
|
+
upstream.settimeout(None)
|
|
251
|
+
client.settimeout(None)
|
|
252
|
+
pump(client, upstream)
|
|
253
|
+
finally:
|
|
254
|
+
upstream.close()
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def pump(a: socket.socket, b: socket.socket) -> None:
|
|
258
|
+
"""Copy bytes between two sockets until one of them closes."""
|
|
259
|
+
peers = {a.fileno(): (a, b), b.fileno(): (b, a)}
|
|
260
|
+
with selectors.DefaultSelector() as sel:
|
|
261
|
+
sel.register(a, selectors.EVENT_READ)
|
|
262
|
+
sel.register(b, selectors.EVENT_READ)
|
|
263
|
+
while True:
|
|
264
|
+
for key, _ in sel.select():
|
|
265
|
+
source, sink = peers[key.fd]
|
|
266
|
+
try:
|
|
267
|
+
data = source.recv(TUNNEL_BUFFER)
|
|
268
|
+
except OSError:
|
|
269
|
+
return
|
|
270
|
+
if not data:
|
|
271
|
+
return
|
|
272
|
+
try:
|
|
273
|
+
sink.sendall(data)
|
|
274
|
+
except OSError:
|
|
275
|
+
return
|