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.
Files changed (376) hide show
  1. gatewaysdk/__init__.py +540 -0
  2. gatewaysdk/adapter/__init__.py +15 -0
  3. gatewaysdk/adapter/base.py +94 -0
  4. gatewaysdk/adapter/messages.py +270 -0
  5. gatewaysdk/adapter/triplet.py +1026 -0
  6. gatewaysdk/algorithm/__init__.py +39 -0
  7. gatewaysdk/algorithm/apo/__init__.py +5 -0
  8. gatewaysdk/algorithm/apo/apo.py +898 -0
  9. gatewaysdk/algorithm/apo/prompts/apply_edit_variant01.poml +22 -0
  10. gatewaysdk/algorithm/apo/prompts/apply_edit_variant02.poml +18 -0
  11. gatewaysdk/algorithm/apo/prompts/text_gradient_variant01.poml +18 -0
  12. gatewaysdk/algorithm/apo/prompts/text_gradient_variant02.poml +16 -0
  13. gatewaysdk/algorithm/apo/prompts/text_gradient_variant03.poml +107 -0
  14. gatewaysdk/algorithm/base.py +262 -0
  15. gatewaysdk/algorithm/decorator.py +264 -0
  16. gatewaysdk/algorithm/evals/__init__.py +7 -0
  17. gatewaysdk/algorithm/evals/evals.py +217 -0
  18. gatewaysdk/algorithm/fast.py +250 -0
  19. gatewaysdk/algorithm/gepa/__init__.py +61 -0
  20. gatewaysdk/algorithm/gepa/adapter.py +495 -0
  21. gatewaysdk/algorithm/gepa/gepa.py +570 -0
  22. gatewaysdk/algorithm/gepa/lib/__init__.py +18 -0
  23. gatewaysdk/algorithm/gepa/lib/adapters/README.md +12 -0
  24. gatewaysdk/algorithm/gepa/lib/adapters/__init__.py +0 -0
  25. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/README.md +341 -0
  26. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/__init__.py +1 -0
  27. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
  28. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/requirements.txt +1 -0
  29. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/README.md +0 -0
  30. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/__init__.py +0 -0
  31. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/default_adapter.py +209 -0
  32. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/README.md +7 -0
  33. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/__init__.py +0 -0
  34. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/dspy_adapter.py +307 -0
  35. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/README.md +99 -0
  36. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
  37. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/full_program_adapter.py +268 -0
  38. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/GEPA_RAG.md +621 -0
  39. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/__init__.py +56 -0
  40. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
  41. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
  42. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
  43. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
  44. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
  45. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
  46. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
  47. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
  48. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
  49. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
  50. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/README.md +552 -0
  51. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/__init__.py +37 -0
  52. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_adapter.py +699 -0
  53. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_client.py +364 -0
  54. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/README.md +9 -0
  55. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/__init__.py +0 -0
  56. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
  57. gatewaysdk/algorithm/gepa/lib/api.py +382 -0
  58. gatewaysdk/algorithm/gepa/lib/core/__init__.py +0 -0
  59. gatewaysdk/algorithm/gepa/lib/core/adapter.py +180 -0
  60. gatewaysdk/algorithm/gepa/lib/core/data_loader.py +74 -0
  61. gatewaysdk/algorithm/gepa/lib/core/engine.py +379 -0
  62. gatewaysdk/algorithm/gepa/lib/core/result.py +233 -0
  63. gatewaysdk/algorithm/gepa/lib/core/state.py +636 -0
  64. gatewaysdk/algorithm/gepa/lib/examples/__init__.py +0 -0
  65. gatewaysdk/algorithm/gepa/lib/examples/aime.py +24 -0
  66. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/eval_default.py +111 -0
  67. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/instruction_prompt.txt +9 -0
  68. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/optimal_prompt.txt +24 -0
  69. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/train_anymaths.py +177 -0
  70. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/arc_agi.ipynb +25705 -0
  71. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/example.ipynb +348 -0
  72. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/__init__.py +4 -0
  73. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/mcp_optimization_example.py +456 -0
  74. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/RAG_GUIDE.md +613 -0
  75. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/__init__.py +9 -0
  76. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/rag_optimization.py +820 -0
  77. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/requirements-rag.txt +29 -0
  78. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/instruction_prompt.txt +16 -0
  79. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/terminus.txt +9 -0
  80. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/train_terminus.py +161 -0
  81. gatewaysdk/algorithm/gepa/lib/gepa_utils.py +117 -0
  82. gatewaysdk/algorithm/gepa/lib/logging/__init__.py +0 -0
  83. gatewaysdk/algorithm/gepa/lib/logging/experiment_tracker.py +187 -0
  84. gatewaysdk/algorithm/gepa/lib/logging/logger.py +75 -0
  85. gatewaysdk/algorithm/gepa/lib/logging/utils.py +103 -0
  86. gatewaysdk/algorithm/gepa/lib/proposer/__init__.py +0 -0
  87. gatewaysdk/algorithm/gepa/lib/proposer/base.py +31 -0
  88. gatewaysdk/algorithm/gepa/lib/proposer/merge.py +357 -0
  89. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/__init__.py +0 -0
  90. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/base.py +49 -0
  91. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/reflective_mutation.py +176 -0
  92. gatewaysdk/algorithm/gepa/lib/py.typed +0 -0
  93. gatewaysdk/algorithm/gepa/lib/strategies/__init__.py +0 -0
  94. gatewaysdk/algorithm/gepa/lib/strategies/batch_sampler.py +77 -0
  95. gatewaysdk/algorithm/gepa/lib/strategies/candidate_selector.py +50 -0
  96. gatewaysdk/algorithm/gepa/lib/strategies/component_selector.py +36 -0
  97. gatewaysdk/algorithm/gepa/lib/strategies/eval_policy.py +64 -0
  98. gatewaysdk/algorithm/gepa/lib/strategies/instruction_proposal.py +126 -0
  99. gatewaysdk/algorithm/gepa/lib/utils/__init__.py +10 -0
  100. gatewaysdk/algorithm/gepa/lib/utils/stop_condition.py +196 -0
  101. gatewaysdk/algorithm/gepa/tracing.py +105 -0
  102. gatewaysdk/algorithm/utils.py +177 -0
  103. gatewaysdk/algorithm/verl/__init__.py +5 -0
  104. gatewaysdk/algorithm/verl/interface.py +202 -0
  105. gatewaysdk/automations.py +111 -0
  106. gatewaysdk/benchmark_hub/README.md +88 -0
  107. gatewaysdk/benchmark_hub/__init__.py +119 -0
  108. gatewaysdk/benchmark_hub/_archive.py +189 -0
  109. gatewaysdk/benchmark_hub/_tar.py +6 -0
  110. gatewaysdk/benchmark_hub/client.py +992 -0
  111. gatewaysdk/benchmark_hub/dispatch_shard.py +34 -0
  112. gatewaysdk/benchmark_hub/eval_config.py +20 -0
  113. gatewaysdk/benchmark_hub/evals.py +351 -0
  114. gatewaysdk/benchmark_hub/harbor_adapter.py +673 -0
  115. gatewaysdk/benchmark_hub/path_utils.py +81 -0
  116. gatewaysdk/benchmark_hub/save_utils.py +101 -0
  117. gatewaysdk/benchmark_hub/verifiers_adapter.py +327 -0
  118. gatewaysdk/benchmark_hub/versioning.py +72 -0
  119. gatewaysdk/build.py +515 -0
  120. gatewaysdk/cli/__init__.py +58 -0
  121. gatewaysdk/cli/agent_runner.py +132 -0
  122. gatewaysdk/cli/http_client.py +115 -0
  123. gatewaysdk/cli/platform.py +4086 -0
  124. gatewaysdk/cli/prometheus.py +115 -0
  125. gatewaysdk/cli/release_gate.py +215 -0
  126. gatewaysdk/cli/store.py +131 -0
  127. gatewaysdk/cli/vllm.py +29 -0
  128. gatewaysdk/client.py +406 -0
  129. gatewaysdk/config.py +348 -0
  130. gatewaysdk/connectors/__init__.py +25 -0
  131. gatewaysdk/connectors/client.py +203 -0
  132. gatewaysdk/connectors/skill.py +25 -0
  133. gatewaysdk/connectors/template.py +106 -0
  134. gatewaysdk/context.py +606 -0
  135. gatewaysdk/emitter/__init__.py +43 -0
  136. gatewaysdk/emitter/annotation.py +370 -0
  137. gatewaysdk/emitter/exception.py +54 -0
  138. gatewaysdk/emitter/message.py +61 -0
  139. gatewaysdk/emitter/object.py +117 -0
  140. gatewaysdk/emitter/reward.py +320 -0
  141. gatewaysdk/env_var.py +156 -0
  142. gatewaysdk/environment/__init__.py +108 -0
  143. gatewaysdk/environment/_bundle.py +281 -0
  144. gatewaysdk/environment/_harbor.py +276 -0
  145. gatewaysdk/environment/_materialize.py +97 -0
  146. gatewaysdk/environment/_tar.py +33 -0
  147. gatewaysdk/environment/_world.py +346 -0
  148. gatewaysdk/environment/core.py +527 -0
  149. gatewaysdk/environment/errors.py +58 -0
  150. gatewaysdk/environment/runtime.py +150 -0
  151. gatewaysdk/environment/schema/__init__.py +35 -0
  152. gatewaysdk/environment/schema/__main__.py +225 -0
  153. gatewaysdk/environment/schema/_slack_fidelity.py +116 -0
  154. gatewaysdk/environment/schema/_slack_scenario.py +183 -0
  155. gatewaysdk/environment/schema/api.py +1628 -0
  156. gatewaysdk/environment/schema/batch.py +755 -0
  157. gatewaysdk/environment/schema/compiler.py +615 -0
  158. gatewaysdk/environment/schema/conform.py +428 -0
  159. gatewaysdk/environment/schema/connector.py +777 -0
  160. gatewaysdk/environment/schema/connectors/apple-business-manager/handlers.py +17 -0
  161. gatewaysdk/environment/schema/connectors/apple-business-manager/parity.json +28 -0
  162. gatewaysdk/environment/schema/connectors/apple-business-manager/provenance.json +233 -0
  163. gatewaysdk/environment/schema/connectors/apple-business-manager/scope.toml +112 -0
  164. gatewaysdk/environment/schema/connectors/apple-business-manager/world.json +1380 -0
  165. gatewaysdk/environment/schema/connectors/base.json +28 -0
  166. gatewaysdk/environment/schema/connectors/custom/handlers.py +18 -0
  167. gatewaysdk/environment/schema/connectors/custom/world.json +123 -0
  168. gatewaysdk/environment/schema/connectors/github/handlers.py +81 -0
  169. gatewaysdk/environment/schema/connectors/github/parity.json +37 -0
  170. gatewaysdk/environment/schema/connectors/github/provenance.json +134 -0
  171. gatewaysdk/environment/schema/connectors/github/scope.toml +158 -0
  172. gatewaysdk/environment/schema/connectors/github/world.json +5869 -0
  173. gatewaysdk/environment/schema/connectors/google-calendar/handlers.py +23 -0
  174. gatewaysdk/environment/schema/connectors/google-calendar/world.json +209 -0
  175. gatewaysdk/environment/schema/connectors/google-drive/handlers.py +18 -0
  176. gatewaysdk/environment/schema/connectors/google-drive/world.json +286 -0
  177. gatewaysdk/environment/schema/connectors/jamf/handlers.py +34 -0
  178. gatewaysdk/environment/schema/connectors/jamf/parity.json +49 -0
  179. gatewaysdk/environment/schema/connectors/jamf/provenance.json +181 -0
  180. gatewaysdk/environment/schema/connectors/jamf/scope.toml +128 -0
  181. gatewaysdk/environment/schema/connectors/jamf/world.json +2218 -0
  182. gatewaysdk/environment/schema/connectors/jira/handlers.py +28 -0
  183. gatewaysdk/environment/schema/connectors/jira/world.json +389 -0
  184. gatewaysdk/environment/schema/connectors/kandji/handlers.py +38 -0
  185. gatewaysdk/environment/schema/connectors/kandji/parity.json +29 -0
  186. gatewaysdk/environment/schema/connectors/kandji/provenance.json +152 -0
  187. gatewaysdk/environment/schema/connectors/kandji/scope.toml +120 -0
  188. gatewaysdk/environment/schema/connectors/kandji/world.json +765 -0
  189. gatewaysdk/environment/schema/connectors/linear/handlers.py +20 -0
  190. gatewaysdk/environment/schema/connectors/linear/world.json +363 -0
  191. gatewaysdk/environment/schema/connectors/microsoft-teams/fidelity.json +45 -0
  192. gatewaysdk/environment/schema/connectors/microsoft-teams/handlers.py +1 -0
  193. gatewaysdk/environment/schema/connectors/microsoft-teams/provenance.json +851 -0
  194. gatewaysdk/environment/schema/connectors/microsoft-teams/scope.md +231 -0
  195. gatewaysdk/environment/schema/connectors/microsoft-teams/teams-types.json +1710 -0
  196. gatewaysdk/environment/schema/connectors/microsoft-teams/world.json +858 -0
  197. gatewaysdk/environment/schema/connectors/netsuite/handlers.py +32 -0
  198. gatewaysdk/environment/schema/connectors/netsuite/parity.json +50 -0
  199. gatewaysdk/environment/schema/connectors/netsuite/provenance.json +137 -0
  200. gatewaysdk/environment/schema/connectors/netsuite/scope.toml +78 -0
  201. gatewaysdk/environment/schema/connectors/netsuite/world.json +16243 -0
  202. gatewaysdk/environment/schema/connectors/salesforce/handlers.py +806 -0
  203. gatewaysdk/environment/schema/connectors/salesforce/parity.json +46 -0
  204. gatewaysdk/environment/schema/connectors/salesforce/provenance.json +143 -0
  205. gatewaysdk/environment/schema/connectors/salesforce/scope.toml +174 -0
  206. gatewaysdk/environment/schema/connectors/salesforce/world.json +4695 -0
  207. gatewaysdk/environment/schema/connectors/slack/MODEL.md +236 -0
  208. gatewaysdk/environment/schema/connectors/slack/capabilities.json +1039 -0
  209. gatewaysdk/environment/schema/connectors/slack/handlers.py +762 -0
  210. gatewaysdk/environment/schema/connectors/slack/parity.json +65 -0
  211. gatewaysdk/environment/schema/connectors/slack/provenance.json +294 -0
  212. gatewaysdk/environment/schema/connectors/slack/scope.toml +44 -0
  213. gatewaysdk/environment/schema/connectors/slack/world.json +4993 -0
  214. gatewaysdk/environment/schema/connectors/workday/handlers.py +75 -0
  215. gatewaysdk/environment/schema/connectors/workday/parity.json +36 -0
  216. gatewaysdk/environment/schema/connectors/workday/provenance.json +179 -0
  217. gatewaysdk/environment/schema/connectors/workday/scope.toml +180 -0
  218. gatewaysdk/environment/schema/connectors/workday/world.json +806 -0
  219. gatewaysdk/environment/schema/data.py +593 -0
  220. gatewaysdk/environment/schema/extract.py +263 -0
  221. gatewaysdk/environment/schema/host.py +2437 -0
  222. gatewaysdk/environment/schema/host_surfaces.py +275 -0
  223. gatewaysdk/environment/schema/platform.py +1272 -0
  224. gatewaysdk/environment/schema/scaffold.py +250 -0
  225. gatewaysdk/environment/schema/skill.py +118 -0
  226. gatewaysdk/environment/schema/skills/agents/connector-template-author.md +202 -0
  227. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONNECTORS.md +331 -0
  228. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONVENTIONS.md +100 -0
  229. gatewaysdk/environment/schema/skills/connector-schema-authoring/SKILL.md +313 -0
  230. gatewaysdk/environment/schema/skills/world-data-ingestion/ROWS.md +223 -0
  231. gatewaysdk/environment/schema/skills/world-data-ingestion/SKILL.md +293 -0
  232. gatewaysdk/environment/schema/skills/worlds-getting-started/SKILL.md +390 -0
  233. gatewaysdk/environment/schema/slack.py +757 -0
  234. gatewaysdk/environment/schema/snapshot.py +479 -0
  235. gatewaysdk/environment/schema/store.py +904 -0
  236. gatewaysdk/environment/schema/tasks.py +525 -0
  237. gatewaysdk/environment/schema/tools_world.py +322 -0
  238. gatewaysdk/environment/schema/validation.py +577 -0
  239. gatewaysdk/environment/schema/worker.py +78 -0
  240. gatewaysdk/environment/schema/workers.py +500 -0
  241. gatewaysdk/environment/schema/world_tests.py +336 -0
  242. gatewaysdk/environments/__init__.py +24 -0
  243. gatewaysdk/environments/client.py +486 -0
  244. gatewaysdk/environments/types.py +318 -0
  245. gatewaysdk/execution/__init__.py +15 -0
  246. gatewaysdk/execution/base.py +64 -0
  247. gatewaysdk/execution/client_server.py +443 -0
  248. gatewaysdk/execution/events.py +69 -0
  249. gatewaysdk/execution/inter_process.py +16 -0
  250. gatewaysdk/execution/shared_memory.py +282 -0
  251. gatewaysdk/experiments/__init__.py +90 -0
  252. gatewaysdk/experiments/assignment.py +177 -0
  253. gatewaysdk/experiments/client.py +877 -0
  254. gatewaysdk/experiments/exposure.py +222 -0
  255. gatewaysdk/experiments/types.py +81 -0
  256. gatewaysdk/importers/__init__.py +49 -0
  257. gatewaysdk/importers/_normalize.py +91 -0
  258. gatewaysdk/importers/builder.py +173 -0
  259. gatewaysdk/importers/client.py +95 -0
  260. gatewaysdk/importers/langsmith.py +196 -0
  261. gatewaysdk/importers/recipes.py +249 -0
  262. gatewaysdk/instrumentation/__init__.py +300 -0
  263. gatewaysdk/instrumentation/agentops.py +314 -0
  264. gatewaysdk/instrumentation/agentops_langchain.py +45 -0
  265. gatewaysdk/instrumentation/base.py +119 -0
  266. gatewaysdk/instrumentation/litellm.py +83 -0
  267. gatewaysdk/instrumentation/registry.py +273 -0
  268. gatewaysdk/instrumentation/vllm.py +81 -0
  269. gatewaysdk/instrumentation/weave.py +500 -0
  270. gatewaysdk/integrations/__init__.py +15 -0
  271. gatewaysdk/integrations/gateway/__init__.py +11 -0
  272. gatewaysdk/integrations/gateway/client.py +171 -0
  273. gatewaysdk/integrations/tool_access.py +549 -0
  274. gatewaysdk/litagent/__init__.py +11 -0
  275. gatewaysdk/litagent/decorator.py +536 -0
  276. gatewaysdk/litagent/litagent.py +252 -0
  277. gatewaysdk/llm_proxy.py +1742 -0
  278. gatewaysdk/logging.py +370 -0
  279. gatewaysdk/memory.py +278 -0
  280. gatewaysdk/personas.py +186 -0
  281. gatewaysdk/platform/__init__.py +17 -0
  282. gatewaysdk/platform/builder.py +221 -0
  283. gatewaysdk/platform/compatibility.py +67 -0
  284. gatewaysdk/platform/manifest.py +185 -0
  285. gatewaysdk/platform/orchestrator.py +901 -0
  286. gatewaysdk/platform/registry.py +122 -0
  287. gatewaysdk/platform/worker.py +864 -0
  288. gatewaysdk/replay/__init__.py +1032 -0
  289. gatewaysdk/replay/pytest.py +56 -0
  290. gatewaysdk/reward.py +7 -0
  291. gatewaysdk/run.py +1781 -0
  292. gatewaysdk/runner/__init__.py +11 -0
  293. gatewaysdk/runner/agent.py +878 -0
  294. gatewaysdk/runner/base.py +182 -0
  295. gatewaysdk/runner/legacy.py +309 -0
  296. gatewaysdk/security.py +700 -0
  297. gatewaysdk/semconv.py +170 -0
  298. gatewaysdk/server.py +399 -0
  299. gatewaysdk/sessions.py +282 -0
  300. gatewaysdk/store/__init__.py +45 -0
  301. gatewaysdk/store/base.py +908 -0
  302. gatewaysdk/store/client_server.py +2093 -0
  303. gatewaysdk/store/collection/__init__.py +30 -0
  304. gatewaysdk/store/collection/base.py +587 -0
  305. gatewaysdk/store/collection/memory.py +970 -0
  306. gatewaysdk/store/collection/mongo.py +1412 -0
  307. gatewaysdk/store/collection_based.py +1823 -0
  308. gatewaysdk/store/gateway.py +983 -0
  309. gatewaysdk/store/gateway_listener.py +465 -0
  310. gatewaysdk/store/listener.py +58 -0
  311. gatewaysdk/store/memory.py +396 -0
  312. gatewaysdk/store/mongo.py +165 -0
  313. gatewaysdk/store/redis_stream.py +517 -0
  314. gatewaysdk/store/sqlite.py +3 -0
  315. gatewaysdk/store/threading.py +370 -0
  316. gatewaysdk/store/utils.py +142 -0
  317. gatewaysdk/tracer/__init__.py +14 -0
  318. gatewaysdk/tracer/base.py +286 -0
  319. gatewaysdk/tracer/dummy.py +106 -0
  320. gatewaysdk/tracer/otel.py +559 -0
  321. gatewaysdk/tracing/__init__.py +110 -0
  322. gatewaysdk/tracing/api.py +808 -0
  323. gatewaysdk/tracing/attributes.py +9 -0
  324. gatewaysdk/tracing/context.py +272 -0
  325. gatewaysdk/tracing/exporters/__init__.py +10 -0
  326. gatewaysdk/tracing/exporters/gateway.py +228 -0
  327. gatewaysdk/tracing/identity.py +288 -0
  328. gatewaysdk/tracing/init.py +620 -0
  329. gatewaysdk/tracing/instrumentors/__init__.py +15 -0
  330. gatewaysdk/tracing/instrumentors/claude_agent_sdk.py +766 -0
  331. gatewaysdk/tracing/instrumentors/instrumentation_principles.md +294 -0
  332. gatewaysdk/tracing/instrumentors/registry.py +352 -0
  333. gatewaysdk/tracing/mapping.py +729 -0
  334. gatewaysdk/tracing/processors.py +393 -0
  335. gatewaysdk/tracing/push.py +617 -0
  336. gatewaysdk/tracing/push_models.py +247 -0
  337. gatewaysdk/tracing/semconv.py +294 -0
  338. gatewaysdk/tracing/span_builder.py +356 -0
  339. gatewaysdk/trainer/__init__.py +6 -0
  340. gatewaysdk/trainer/init_utils.py +263 -0
  341. gatewaysdk/trainer/legacy.py +359 -0
  342. gatewaysdk/trainer/registry.py +12 -0
  343. gatewaysdk/trainer/trainer.py +638 -0
  344. gatewaysdk/types/__init__.py +63 -0
  345. gatewaysdk/types/core.py +556 -0
  346. gatewaysdk/types/resources.py +204 -0
  347. gatewaysdk/types/tracer.py +515 -0
  348. gatewaysdk/types/tracing.py +162 -0
  349. gatewaysdk/users.py +251 -0
  350. gatewaysdk/utils/__init__.py +1 -0
  351. gatewaysdk/utils/id.py +18 -0
  352. gatewaysdk/utils/metrics.py +1025 -0
  353. gatewaysdk/utils/otel.py +550 -0
  354. gatewaysdk/utils/otlp.py +556 -0
  355. gatewaysdk/utils/redact.py +22 -0
  356. gatewaysdk/utils/server_launcher.py +1045 -0
  357. gatewaysdk/utils/system_snapshot.py +90 -0
  358. gatewaysdk/verl/__init__.py +8 -0
  359. gatewaysdk/verl/__main__.py +6 -0
  360. gatewaysdk/verl/async_server.py +46 -0
  361. gatewaysdk/verl/config.yaml +27 -0
  362. gatewaysdk/verl/daemon.py +1154 -0
  363. gatewaysdk/verl/dataset.py +44 -0
  364. gatewaysdk/verl/entrypoint.py +248 -0
  365. gatewaysdk/verl/trainer.py +549 -0
  366. gatewaysdk/world_browser.py +748 -0
  367. gatewaysdk/world_data.py +453 -0
  368. gatewaysdk/world_sessions.py +978 -0
  369. gatewaysdk/world_tasks.py +285 -0
  370. gatewaysdk/world_tools.py +115 -0
  371. gatewaysdk/worlds.py +639 -0
  372. gatewaysdk-0.3.2.dist-info/METADATA +236 -0
  373. gatewaysdk-0.3.2.dist-info/RECORD +376 -0
  374. gatewaysdk-0.3.2.dist-info/WHEEL +4 -0
  375. gatewaysdk-0.3.2.dist-info/entry_points.txt +5 -0
  376. 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
+ ]