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
gatewaysdk/config.py ADDED
@@ -0,0 +1,348 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ """
4
+ This file is not carefully reviewed.
5
+ It might contain unintentional bugs and issues.
6
+ Please always review the parsed construction arguments before using them.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import inspect
13
+ import logging
14
+ from typing import _GenericAlias # type: ignore
15
+ from typing import (
16
+ Any,
17
+ Callable,
18
+ Dict,
19
+ List,
20
+ Tuple,
21
+ Type,
22
+ TypeVar,
23
+ Union,
24
+ get_args,
25
+ get_origin,
26
+ get_type_hints,
27
+ overload,
28
+ )
29
+
30
+ CliConfigurable = Any
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+ __all__ = ["lightning_cli"]
35
+
36
+ # TypeVars for precise return type hinting with overloads
37
+ _C = TypeVar("_C", bound=CliConfigurable)
38
+ _C1 = TypeVar("_C1", bound=CliConfigurable)
39
+ _C2 = TypeVar("_C2", bound=CliConfigurable)
40
+ _C3 = TypeVar("_C3", bound=CliConfigurable)
41
+ _C4 = TypeVar("_C4", bound=CliConfigurable)
42
+
43
+
44
+ # Custom type for CLI arguments that can be string or None
45
+ def nullable_str(value: str) -> str | None:
46
+ """Converts specific string values (case-insensitive) to None, otherwise returns the string."""
47
+ if value.lower() in ["none", "null", "~", "nil"]: # Define keywords for None
48
+ return None
49
+ return value
50
+
51
+
52
+ def nullable_int(value: str) -> int | None:
53
+ """Converts specific string values (case-insensitive) to None, otherwise returns the integer."""
54
+ if value.lower() in ["none", "null", "~", "nil"]: # Define keywords for None
55
+ return None
56
+ try:
57
+ return int(value)
58
+ except ValueError:
59
+ raise argparse.ArgumentTypeError(f"Invalid integer value: '{value}'")
60
+
61
+
62
+ def nullable_float(value: str) -> float | None:
63
+ """Converts specific string values (case-insensitive) to None, otherwise returns the float."""
64
+ if value.lower() in ["none", "null", "~", "nil"]: # Define keywords for None
65
+ return None
66
+ try:
67
+ return float(value)
68
+ except ValueError:
69
+ raise argparse.ArgumentTypeError(f"Invalid float value: '{value}'")
70
+
71
+
72
+ def _str_to_bool(v: str) -> bool:
73
+ """Converts common string representations of bool to Python bool (case-insensitive)."""
74
+ if isinstance(v, bool): # type: ignore
75
+ return v # Allow passing bools directly if used programmatically
76
+ lowered_v = v.lower()
77
+ if lowered_v in ("yes", "true", "t", "y", "1"):
78
+ return True
79
+ elif lowered_v in ("no", "false", "f", "n", "0"):
80
+ return False
81
+ else:
82
+ raise argparse.ArgumentTypeError(f"Boolean value expected (e.g., 'true', 'false', 'yes', 'no'), got '{v}'")
83
+
84
+
85
+ def _get_param_type_details(param_annotation: Any) -> Tuple[Any, bool, bool]:
86
+ """Normalize an annotation into its core type, optionality, and list status.
87
+
88
+ Args:
89
+ param_annotation: The annotation to inspect.
90
+
91
+ Returns:
92
+ A tuple ``(core_type, is_optional, is_list)`` describing the normalized type.
93
+
94
+ - For ``Optional[T]`` → ``(T, True, is_list_status_of_T)``
95
+ - For ``List[T]`` → ``(List[T], is_optional_status_of_List, True)``
96
+ - For ``Optional[List[T]]`` → ``(List[T], True, True)``
97
+ """
98
+ is_optional = False
99
+ is_list = False
100
+ current_type = param_annotation
101
+
102
+ # Check for outer Optional
103
+ origin = get_origin(current_type)
104
+ if origin is Union:
105
+ union_args = get_args(current_type)
106
+ if len(union_args) == 2 and type(None) in union_args:
107
+ is_optional = True
108
+ current_type = next(arg for arg in union_args if arg is not type(None)) # Unwrap Optional
109
+
110
+ # Check if the (potentially unwrapped) type is a List
111
+ origin = get_origin(current_type) # Re-check origin after potential unwrap
112
+ if origin is list or (isinstance(current_type, _GenericAlias) and current_type.__origin__ is list):
113
+ is_list = True
114
+
115
+ return current_type, is_optional, is_list
116
+
117
+
118
+ def _determine_argparse_type(param_type: Any) -> Callable[[str], Any]:
119
+ """Determines the type for argparse based on parameter type details."""
120
+ core_type, is_optional, _ = _get_param_type_details(param_type)
121
+ if core_type is str and is_optional:
122
+ return nullable_str # Special handling for Optional[str]
123
+ elif core_type is int and is_optional:
124
+ return nullable_int
125
+ elif core_type is float and is_optional:
126
+ return nullable_float
127
+ elif core_type is bool:
128
+ return _str_to_bool # Special handling for bool
129
+ elif core_type in (int, float, str):
130
+ return core_type
131
+ return str # Default to str if no specific type is provided (including empty)
132
+
133
+
134
+ def _determine_argparse_type_and_nargs(
135
+ core_param_type: Any, is_param_list: bool # The type after unwrapping an outer Optional
136
+ ) -> Dict[str, Any]:
137
+ """Determines the 'type' and 'nargs' for argparse based on parameter type details."""
138
+ kwargs: Dict[str, Any] = {}
139
+
140
+ if is_param_list:
141
+ kwargs["nargs"] = "*" # Allows zero or more arguments for lists
142
+ list_item_annotations = get_args(core_param_type) # For List[T], core_param_type is List[T]
143
+
144
+ if list_item_annotations and list_item_annotations[0] is not Any:
145
+ item_ann = list_item_annotations[0]
146
+ # Check if the list item itself is, e.g., Optional[str] or bool
147
+ kwargs["type"] = _determine_argparse_type(item_ann)
148
+ else:
149
+ kwargs["type"] = str
150
+ else: # Not a list
151
+ kwargs["type"] = _determine_argparse_type(core_param_type)
152
+ return kwargs
153
+
154
+
155
+ def _build_help_string(cls_name: str, param_name: str, core_type: Any, is_optional: bool, is_list: bool) -> str:
156
+ """Constructs a descriptive help string for a CLI argument."""
157
+ type_display_name = "Any"
158
+ if core_type is not inspect.Parameter.empty:
159
+ type_display_name = getattr(core_type, "__name__", str(core_type))
160
+
161
+ if is_list:
162
+ list_item_args = get_args(core_type) # core_type is List[T] here
163
+ item_name = "Any"
164
+ if list_item_args and list_item_args[0] is not Any:
165
+ inner_item_core_type, inner_item_optional, _ = _get_param_type_details(list_item_args[0])
166
+ item_name = getattr(inner_item_core_type, "__name__", str(inner_item_core_type))
167
+ if inner_item_optional: # e.g. List[Optional[str]]
168
+ item_name = f"Optional[{item_name}]"
169
+ type_display_name = f"List[{item_name}]"
170
+
171
+ full_type_display = f"Optional[{type_display_name}]" if is_optional and not is_list else type_display_name
172
+ if is_optional and is_list: # e.g. Optional[List[str]]
173
+ full_type_display = f"Optional[{type_display_name}]"
174
+
175
+ help_str = f"For {cls_name}: '{param_name}'. Inferred type: {full_type_display}."
176
+ return help_str
177
+
178
+
179
+ def _add_argument_for_parameter(
180
+ parser: argparse.ArgumentParser,
181
+ cls: Type[CliConfigurable],
182
+ param_name: str,
183
+ param_obj: inspect.Parameter,
184
+ dest_name: str,
185
+ resolved_param_annotation: Any = None,
186
+ ) -> None:
187
+ """Configures and adds a single CLI argument for an __init__ parameter."""
188
+ if resolved_param_annotation is None:
189
+ param_type_annotation = param_obj.annotation
190
+ else:
191
+ param_type_annotation = resolved_param_annotation
192
+
193
+ # core_type is the main type (e.g., int, str, List[str]), after unwrapping the outermost Optional.
194
+ # is_overall_optional indicates if the parameter itself can be None (e.g. param: Optional[T] = None)
195
+ # is_list indicates if core_type is a List.
196
+ core_type, is_overall_optional, is_list = _get_param_type_details(param_type_annotation)
197
+
198
+ has_init_default = param_obj.default is not inspect.Parameter.empty
199
+ init_default_value = param_obj.default if has_init_default else None
200
+
201
+ argparse_kwargs = _determine_argparse_type_and_nargs(core_type if is_list else param_type_annotation, is_list)
202
+
203
+ if has_init_default:
204
+ argparse_kwargs["default"] = init_default_value
205
+ elif is_overall_optional: # Parameter is Optional (e.g. Optional[int]) and no explicit default in __init__
206
+ argparse_kwargs["default"] = None # So, if not provided on CLI, it becomes None.
207
+
208
+ argparse_kwargs["help"] = _build_help_string(cls.__name__, param_name, core_type, is_overall_optional, is_list)
209
+
210
+ if not has_init_default and not is_overall_optional: # Required if no __init__ default AND not Optional
211
+ argparse_kwargs["required"] = True
212
+ if "default" in argparse_kwargs: # Should not happen if logic is correct
213
+ del argparse_kwargs["default"]
214
+
215
+ cli_arg_name = f"--{cls.__name__.lower()}.{param_name.replace('_', '-')}"
216
+ parser.add_argument(cli_arg_name, dest=dest_name, **argparse_kwargs)
217
+
218
+
219
+ def _add_arguments_for_class(
220
+ parser: argparse.ArgumentParser,
221
+ cls: Type[CliConfigurable],
222
+ class_arg_configs_maps: Dict[Type[CliConfigurable], Dict[str, str]], # Maps cls to {param_name: dest_name}
223
+ ) -> None:
224
+ """Adds all relevant CLI arguments for a given class by processing its __init__ parameters."""
225
+ cls_name_lower = cls.__name__.lower()
226
+ sig = inspect.signature(cls.__init__)
227
+
228
+ try:
229
+ # Resolve string annotations to actual types using get_type_hints.
230
+ # For methods, get_type_hints automatically uses obj.__globals__ for globalns.
231
+ resolved_hints = get_type_hints(cls.__init__)
232
+ except Exception as e:
233
+ logger.warning(
234
+ f"Could not resolve type hints for {cls.__name__}.__init__ using get_type_hints: {e}. "
235
+ f"CLI argument parsing for this class might be based on string annotations, "
236
+ "which could be unreliable for complex types."
237
+ )
238
+ resolved_hints = {} # Fallback to an empty dict if resolution fails
239
+
240
+ if cls not in class_arg_configs_maps: # Ensure the class entry exists
241
+ class_arg_configs_maps[cls] = {}
242
+
243
+ for param_name, param_obj in sig.parameters.items():
244
+ if param_name == "self": # Skip 'self'
245
+ continue
246
+
247
+ dest_name = f"{cls_name_lower}_{param_name}" # Unique destination for argparse
248
+ class_arg_configs_maps[cls][param_name] = dest_name # Store mapping for later instantiation
249
+
250
+ # Use the resolved hint if available, otherwise fallback to param_obj.annotation (which might be a string)
251
+ actual_param_annotation = resolved_hints.get(param_name, param_obj.annotation)
252
+ _add_argument_for_parameter(parser, cls, param_name, param_obj, dest_name, actual_param_annotation)
253
+
254
+
255
+ def _create_argument_parser() -> argparse.ArgumentParser:
256
+ """Creates and returns the main ArgumentParser with default settings."""
257
+ return argparse.ArgumentParser(
258
+ description="CLI configurator for application components.",
259
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter, # Automatically shows default values in help
260
+ )
261
+
262
+
263
+ def _instantiate_classes(
264
+ parsed_args: argparse.Namespace,
265
+ classes: Tuple[Type[CliConfigurable], ...],
266
+ class_arg_configs_maps: Dict[Type[CliConfigurable], Dict[str, str]],
267
+ ) -> Tuple[CliConfigurable, ...]:
268
+ """Instantiates classes using the parsed CLI arguments and the stored mappings."""
269
+ instances_list: List[CliConfigurable] = []
270
+ for cls in classes:
271
+ constructor_args: Dict[str, Any] = {}
272
+ # Get the {__init__ param_name: argparse_dest_name} map for the current class
273
+ param_to_dest_map = class_arg_configs_maps.get(cls, {})
274
+
275
+ sig = inspect.signature(cls.__init__)
276
+ for param_name_in_sig, _ in sig.parameters.items():
277
+ if param_name_in_sig == "self":
278
+ continue
279
+
280
+ dest_name_for_arg = param_to_dest_map.get(param_name_in_sig)
281
+ if dest_name_for_arg and hasattr(parsed_args, dest_name_for_arg):
282
+ value = getattr(parsed_args, dest_name_for_arg)
283
+ constructor_args[param_name_in_sig] = value
284
+ # If an argument was required by argparse, parse_args() would have exited if missing.
285
+ # If not required and not provided, its default value (set by argparse) is used.
286
+
287
+ try:
288
+ logger.info("Instantiating %s with args: %s", cls.__name__, constructor_args)
289
+ instances_list.append(cls(**constructor_args))
290
+ except Exception as e:
291
+ parsed_args_for_cls = {
292
+ k: getattr(parsed_args, v) for k, v in param_to_dest_map.items() if hasattr(parsed_args, v)
293
+ }
294
+ logger.error(
295
+ f"Error instantiating {cls.__name__} with resolved args {constructor_args}. "
296
+ f"Parsed args for class: "
297
+ f"{parsed_args_for_cls}. "
298
+ f"Error: {e}"
299
+ )
300
+ raise
301
+
302
+ return tuple(instances_list)
303
+
304
+
305
+ @overload
306
+ def lightning_cli(cls1: Type[_C1]) -> _C1: ...
307
+ @overload
308
+ def lightning_cli(cls1: Type[_C1], cls2: Type[_C2]) -> Tuple[_C1, _C2]: ...
309
+ @overload
310
+ def lightning_cli(cls1: Type[_C1], cls2: Type[_C2], cls3: Type[_C3]) -> Tuple[_C1, _C2, _C3]: ...
311
+ @overload
312
+ def lightning_cli(cls1: Type[_C1], cls2: Type[_C2], cls3: Type[_C3], cls4: Type[_C4]) -> Tuple[_C1, _C2, _C3, _C4]: ...
313
+ @overload # Fallback for more than 4 or a dynamic number of classes
314
+ def lightning_cli(*classes: Type[CliConfigurable]) -> Tuple[CliConfigurable, ...]: ...
315
+
316
+
317
+ # FIXME: lightning_cli needs to be fixed to comply with the latest trainer implementation.
318
+
319
+
320
+ def lightning_cli(*classes: Type[CliConfigurable]) -> CliConfigurable | Tuple[CliConfigurable, ...]: # type: ignore
321
+ """
322
+ Parses command-line arguments to configure and instantiate provided CliConfigurable classes.
323
+
324
+ Args:
325
+ *classes: One or more classes that inherit from CliConfigurable. Each class's
326
+ __init__ parameters will be exposed as command-line arguments.
327
+
328
+ Returns:
329
+ A tuple of instantiated objects, corresponding to the input classes in order.
330
+ """
331
+ if not classes:
332
+ return tuple() # Return an empty tuple if no classes are provided
333
+
334
+ parser = _create_argument_parser()
335
+
336
+ # This map will store {cls: {init_param_name: argparse_dest_name}}
337
+ class_arg_configs_maps: Dict[Type[CliConfigurable], Dict[str, str]] = {}
338
+
339
+ for cls in classes:
340
+ _add_arguments_for_class(parser, cls, class_arg_configs_maps)
341
+
342
+ parsed_args = parser.parse_args() # Uses sys.argv[1:] by default
343
+
344
+ # Correctly handle single class case for return type matching overloads
345
+ instances = _instantiate_classes(parsed_args, classes, class_arg_configs_maps)
346
+ if len(classes) == 1:
347
+ return instances[0]
348
+ return instances
@@ -0,0 +1,25 @@
1
+ """Gateway workspace connectors SDK.
2
+
3
+ Publish an authored connector template to the organization's workspace, list
4
+ the organization's connectors and the deployment-wide hub, pull a template
5
+ back, and clone a published one — the client behind ``gateway worlds connector
6
+ publish | list | pull | clone`` and ``gateway worlds schema init … --connector
7
+ workspace:<slug>``. Auth + host resolution match ``GatewayEnvironmentClient``
8
+ (``GATEWAY_PUBLIC_KEY`` / ``GATEWAY_SECRET_KEY`` / ``GATEWAY_HOST``); writes
9
+ require the secret key.
10
+
11
+ from gatewaysdk.connectors import GatewayConnectorsClient
12
+
13
+ client = GatewayConnectorsClient.from_env()
14
+ for row in client.hub():
15
+ print(row["slug"], row["orgName"], row["metadata"]["vendor"])
16
+ """
17
+
18
+ from .client import GatewayConnectorsClient, GatewayConnectorsError
19
+ from .template import collect_template
20
+
21
+ __all__ = [
22
+ "GatewayConnectorsClient",
23
+ "GatewayConnectorsError",
24
+ "collect_template",
25
+ ]
@@ -0,0 +1,203 @@
1
+ """Gateway workspace-connector public-API client.
2
+
3
+ A workspace connector is an authored connector template (``world.json``,
4
+ ``connector.toml``, ``handlers.py``, ``api/handlers.py``, ``provenance.json``,
5
+ ``scope.toml``, ``scenarios/**`` …) saved in the organization's Context Hub as a
6
+ ``connector`` repo: versioned, org-owned, publishable to every organization on
7
+ the deployment and cloned from there with provenance.
8
+
9
+ Talks to ``/api/public/context/connectors`` (list / pull / exists / push /
10
+ delete) and ``/api/public/connectors/{hub,clone}`` (the cross-org catalog and
11
+ clone). Auth and host resolution match ``GatewayEnvironmentClient``: a project
12
+ public + secret key sent as HTTP Basic (``GATEWAY_PUBLIC_KEY`` /
13
+ ``GATEWAY_SECRET_KEY`` / ``GATEWAY_HOST``). Stdlib only.
14
+
15
+ Answers are plain dicts in the shape the API returns, except that ``pull``
16
+ flattens each file entry to its text so ``files`` is ``{path: content}`` — the
17
+ same mapping ``push`` takes (``None`` deletes a path).
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import base64
23
+ import json
24
+ import os
25
+ import urllib.error
26
+ import urllib.parse
27
+ import urllib.request
28
+ from typing import Any, Dict, List, Optional
29
+
30
+ CONNECTORS = "/api/public/context/connectors"
31
+ HUB = "/api/public/connectors/hub"
32
+ CLONE = "/api/public/connectors/clone"
33
+
34
+
35
+ class GatewayConnectorsError(RuntimeError):
36
+ """Raised when any workspace-connector API call fails."""
37
+
38
+
39
+ class GatewayConnectorsClient:
40
+ """Client for the Gateway workspace-connector public API.
41
+
42
+ Authenticate with the project's public + secret key (HTTP Basic), the same
43
+ as the environment client — writes require the secret key.
44
+ """
45
+
46
+ def __init__(self, host: str, public_key: str, secret_key: str) -> None:
47
+ if not host:
48
+ raise ValueError("host is required (e.g. https://withgateway.ai)")
49
+ if not public_key or not secret_key:
50
+ raise ValueError("both public_key and secret_key are required")
51
+ self.host = host.rstrip("/")
52
+ self._auth = base64.b64encode(f"{public_key}:{secret_key}".encode("utf-8")).decode("ascii")
53
+
54
+ @classmethod
55
+ def from_env(cls, host: Optional[str] = None) -> "GatewayConnectorsClient":
56
+ return cls(
57
+ host=host or os.environ.get("GATEWAY_HOST", ""),
58
+ public_key=os.environ.get("GATEWAY_PUBLIC_KEY", ""),
59
+ secret_key=os.environ.get("GATEWAY_SECRET_KEY", ""),
60
+ )
61
+
62
+ # ── HTTP ────────────────────────────────────────────────────────────────
63
+
64
+ def _request(self, method: str, path: str, body: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
65
+ headers = {"Authorization": f"Basic {self._auth}"}
66
+ data = None
67
+ if body is not None:
68
+ headers["Content-Type"] = "application/json"
69
+ data = json.dumps(body).encode("utf-8")
70
+ req = urllib.request.Request(f"{self.host}{path}", data=data, method=method, headers=headers)
71
+ try:
72
+ with urllib.request.urlopen(req, timeout=120) as resp:
73
+ text = resp.read().decode("utf-8")
74
+ return json.loads(text) if text else {}
75
+ except urllib.error.HTTPError as e:
76
+ detail = e.read().decode("utf-8", "replace")[:500]
77
+ raise GatewayConnectorsError(f"{method} {path} -> {e.code}: {detail}") from None
78
+
79
+ def _get(self, path: str) -> Dict[str, Any]:
80
+ return self._request("GET", path)
81
+
82
+ def _post(self, path: str, body: Dict[str, Any]) -> Dict[str, Any]:
83
+ return self._request("POST", path, body)
84
+
85
+ def _delete(self, path: str) -> Dict[str, Any]:
86
+ return self._request("DELETE", path)
87
+
88
+ @staticmethod
89
+ def _one(slug: str, **query: Any) -> str:
90
+ if not slug or "/" in slug:
91
+ raise ValueError("a connector slug is a single path segment")
92
+ path = f"{CONNECTORS}/{urllib.parse.quote(slug, safe='')}"
93
+ present = {k: v for k, v in query.items() if v is not None}
94
+ return f"{path}?{urllib.parse.urlencode(present)}" if present else path
95
+
96
+ # ── this organization's connectors ──────────────────────────────────────
97
+
98
+ def list(
99
+ self,
100
+ query: Optional[str] = None,
101
+ *,
102
+ limit: int = 100,
103
+ offset: int = 0,
104
+ workspace_visible: Optional[bool] = None,
105
+ ) -> Dict[str, Any]:
106
+ """The organization's connector repos (``repos``, ``total``, ``limit``, ``offset``).
107
+
108
+ ``workspace_visible`` filters on the repo's ``isPublic`` flag, which for a
109
+ connector means visible to the whole workspace, not published across
110
+ organizations — see :meth:`hub` for those."""
111
+ params: Dict[str, Any] = {"limit": limit, "offset": offset}
112
+ if query:
113
+ params["query"] = query
114
+ if workspace_visible is not None:
115
+ params["is_public"] = "true" if workspace_visible else "false"
116
+ return self._get(f"{CONNECTORS}?{urllib.parse.urlencode(params)}")
117
+
118
+ def exists(self, slug: str) -> bool:
119
+ return bool(self._get(self._one(slug, exists="true")).get("exists"))
120
+
121
+ def pull(self, slug: str, version: Optional[str] = None) -> Dict[str, Any]:
122
+ """The connector's ``repo``, the resolved ``commit`` and its ``files`` as
123
+ ``{path: content}``. ``version`` is a label or a commit hash; the head by default."""
124
+ answer = self._get(self._one(slug, version=version))
125
+ files: Dict[str, str] = {}
126
+ for path, entry in (answer.get("files") or {}).items():
127
+ if not isinstance(entry, dict) or entry.get("type") != "file" or not isinstance(entry.get("content"), str):
128
+ raise GatewayConnectorsError(
129
+ f"{slug}: {path} is not a file entry; a connector template holds files only"
130
+ )
131
+ files[path] = entry["content"]
132
+ return {"repo": answer.get("repo", {}), "commit": answer.get("commit", {}), "files": files}
133
+
134
+ def push(
135
+ self,
136
+ slug: str,
137
+ files: Dict[str, Optional[str]],
138
+ *,
139
+ message: str,
140
+ parent_commit: Optional[str] = None,
141
+ description: Optional[str] = None,
142
+ tags: Optional[List[str]] = None,
143
+ readme: Optional[str] = None,
144
+ workspace_visible: bool = False,
145
+ scope: str = "org",
146
+ ) -> Dict[str, Any]:
147
+ """Create the connector or commit to it. ``files`` maps a template path to its
148
+ text, or to ``None`` to delete the path from the head. The platform compiles the
149
+ resulting template before accepting it and answers 400 with the reason otherwise.
150
+ Returns ``url``, ``status`` (``committed`` or ``proposed``), ``repoId``,
151
+ ``commitId`` and ``commitHash``."""
152
+ if scope not in ("org", "project"):
153
+ raise ValueError("scope must be 'org' or 'project'")
154
+ body: Dict[str, Any] = {
155
+ "files": {path: (None if content is None else {"content": content}) for path, content in files.items()},
156
+ "message": message,
157
+ "is_public": workspace_visible,
158
+ "scope": scope,
159
+ "source": "sdk",
160
+ }
161
+ if parent_commit is not None:
162
+ body["parent_commit"] = parent_commit
163
+ if description is not None:
164
+ body["description"] = description
165
+ if tags is not None:
166
+ body["tags"] = list(tags)
167
+ if readme is not None:
168
+ body["readme"] = readme
169
+ return self._post(self._one(slug), body)
170
+
171
+ def delete(self, slug: str) -> Dict[str, Any]:
172
+ return self._delete(self._one(slug))
173
+
174
+ # ── the cross-organization catalog ──────────────────────────────────────
175
+
176
+ def hub(self, query: Optional[str] = None) -> List[Dict[str, Any]]:
177
+ """Every connector this organization can use: its own (``isOwn``) plus the
178
+ ones other organizations published. Each row carries ``metadata`` (vendor,
179
+ auth, entity/operation counts, digest) derived from its head commit."""
180
+ path = f"{HUB}?{urllib.parse.urlencode({'query': query})}" if query else HUB
181
+ return list(self._get(path).get("connectors") or [])
182
+
183
+ def clone(
184
+ self,
185
+ source_repo_id: str,
186
+ name: Optional[str] = None,
187
+ slug: Optional[str] = None,
188
+ scope: str = "org",
189
+ ) -> Dict[str, Any]:
190
+ """Copy a hub connector into this organization with provenance (``id``,
191
+ ``slug``, ``commitId``). The clone is this organization's; later edits by the
192
+ publisher never reach it unless it is cloned again."""
193
+ if scope not in ("org", "project"):
194
+ raise ValueError("scope must be 'org' or 'project'")
195
+ body: Dict[str, Any] = {"sourceRepoId": source_repo_id, "scope": scope}
196
+ if name is not None:
197
+ body["name"] = name
198
+ if slug is not None:
199
+ body["slug"] = slug
200
+ return self._post(CLONE, body)
201
+
202
+
203
+ __all__ = ["GatewayConnectorsClient", "GatewayConnectorsError"]
@@ -0,0 +1,25 @@
1
+ """Re-export of :mod:`gatewaysdk.environment.schema.skill`, the skills the SDK ships."""
2
+
3
+ from gatewaysdk.environment.schema.skill import (
4
+ NEXT_STEP,
5
+ SKILL_NAME,
6
+ SKILLS,
7
+ InstallReport,
8
+ install_skill,
9
+ next_step,
10
+ packaged_files,
11
+ packaged_skills,
12
+ skill_text,
13
+ )
14
+
15
+ __all__ = [
16
+ "InstallReport",
17
+ "NEXT_STEP",
18
+ "SKILLS",
19
+ "SKILL_NAME",
20
+ "install_skill",
21
+ "next_step",
22
+ "packaged_files",
23
+ "packaged_skills",
24
+ "skill_text",
25
+ ]