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,620 @@
1
+ # Copyright (c) Gateway. All rights reserved.
2
+
3
+ """Initialization and lifecycle management for GatewayDK tracing.
4
+
5
+ This module provides the core init(), shutdown(), and flush() functions
6
+ for managing the OpenTelemetry TracerProvider lifecycle.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ import os
13
+ import sys
14
+ import threading
15
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
16
+
17
+ from opentelemetry import trace
18
+ from opentelemetry.sdk.resources import SERVICE_NAME, Resource
19
+ from opentelemetry.sdk.trace import TracerProvider
20
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter
21
+
22
+ from .attributes import GATEWAY_ENVIRONMENT, GATEWAY_VERSION
23
+ from .exporters.gateway import gateway, is_gateway_configured
24
+ from .processors import LoggingSpanProcessor, TracingContextSpanProcessor
25
+
26
+ if TYPE_CHECKING:
27
+ from .identity import AgentIdentity
28
+ from openinference.instrumentation import TraceConfig
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+ # Module-level state
33
+ _initialized = False
34
+ _init_lock = threading.Lock()
35
+ _provider: Optional[TracerProvider] = None
36
+ _processors: List[BatchSpanProcessor] = []
37
+ _export_count = 0
38
+ _batch_config: Dict[str, Any] = {} # Batch processor kwargs, set by init()
39
+
40
+
41
+ def init(
42
+ *,
43
+ agent: Optional[Union[str, dict, "AgentIdentity"]] = None,
44
+ trace_name: Optional[str] = None,
45
+ service_name: Optional[str] = None,
46
+ environment: Optional[str] = None,
47
+ version: Optional[str] = None,
48
+ # Gateway configuration (alternative to env vars)
49
+ gateway_host: Optional[str] = None,
50
+ gateway_public_key: Optional[str] = None,
51
+ gateway_secret_key: Optional[str] = None,
52
+ gateway_endpoint: Optional[str] = None,
53
+ instrument_default: bool = True,
54
+ exporters: Optional[List[SpanExporter]] = None,
55
+ trace_config: Optional["TraceConfig"] = None,
56
+ force: bool = False,
57
+ integrations: Optional[Dict[str, Any]] = None,
58
+ debug: Union[bool, str] = False,
59
+ # Batch processor tuning (passed through to BatchSpanProcessor)
60
+ batch_queue_size: Optional[int] = None,
61
+ batch_flush_interval: Optional[int] = None,
62
+ batch_max_export_size: Optional[int] = None,
63
+ ) -> None:
64
+ """Initialize GatewaySDK standalone tracing.
65
+
66
+ This function configures OpenTelemetry with a connection to Gateway
67
+ (if configured via environment variables), and automatically instruments
68
+ installed AI libraries (OpenAI, Anthropic, LiteLLM, OpenAI Agents SDK, etc.).
69
+
70
+ Provider Reuse Behavior:
71
+ - If no TracerProvider exists, creates one.
72
+ - If a TracerProvider exists and force=False, reuses it and adds
73
+ processors/exporters (avoiding duplicates).
74
+ - If force=True, replaces the existing TracerProvider.
75
+
76
+ Args:
77
+ agent: The agent this process runs as — the one identity you declare.
78
+ A string id, an AgentIdentity, or a dict with id/name/version.
79
+ Falls back to GATEWAY_AGENT_ID / GATEWAY_AGENT_NAME /
80
+ GATEWAY_AGENT_VERSION. Every trace is stamped with the agent
81
+ automatically, and the agent is registered with the platform
82
+ control plane (best-effort, non-blocking) so it appears on the
83
+ Agents page before its first trace.
84
+ trace_name: Optional name for the trace.
85
+ service_name: Name of the service (mapped to resource attributes).
86
+ Defaults to "gatewaysdk-tracing".
87
+ environment: Environment name (e.g., "production", "staging", "development").
88
+ Sets `gateway.environment` resource attribute for filtering traces in Gateway.
89
+ version: Application version (e.g., "1.2.3", git SHA). Sets `gateway.version`
90
+ resource attribute for tracking regressions across versions.
91
+ gateway_host: Gateway server URL (e.g., "https://app.gateway.dev").
92
+ Overrides GATEWAY_HOST environment variable.
93
+ gateway_public_key: Gateway public key (pk-lf-...).
94
+ Overrides GATEWAY_PUBLIC_KEY environment variable.
95
+ gateway_secret_key: Gateway secret key (sk-lf-...).
96
+ Overrides GATEWAY_SECRET_KEY environment variable.
97
+ gateway_endpoint: Optional OTLP endpoint URL. Overrides GATEWAY_OTLP_ENDPOINT.
98
+ If not provided, derived from gateway_host.
99
+ instrument_default: Whether to automatically instrument the "core set"
100
+ of libraries (OpenAI Agents SDK, OpenAI, Anthropic, LiteLLM, etc.)
101
+ if installed. Defaults to True.
102
+ exporters: List of custom OpenTelemetry SpanExporters. If None and
103
+ Gateway credentials are configured (via params or env vars), auto-creates
104
+ an Gateway exporter.
105
+ trace_config: OpenInference TraceConfig for controlling capture behavior
106
+ (hiding inputs/outputs, etc.). Default captures all.
107
+ force: If True, replaces any existing global TracerProvider. If False
108
+ (default), reuses the existing provider and appends processors.
109
+ integrations: Dictionary for fine-grained control over integrations.
110
+ debug: Controls console logging of tracing activity. Accepts:
111
+ - False (default): Silent operation, no console output.
112
+ - True: Shortcut for "DEBUG" -- full firehose including every
113
+ span start/end, export results, and internal plumbing.
114
+ - "DEBUG": Same as True.
115
+ - "INFO": Recommended. Shows init summary, export success/failure,
116
+ instrumentor activation, and shutdown summary.
117
+ - "WARNING": Minimal. Only shows export failures and missing
118
+ exporter warnings.
119
+ - "ERROR": Only export failures and exceptions.
120
+ batch_queue_size: Max spans buffered in memory by BatchSpanProcessor.
121
+ Default: 2048. Increase for bulk import workloads to prevent
122
+ silent span drops. Wraps OTEL_BSP_MAX_QUEUE_SIZE.
123
+ batch_flush_interval: How often (in ms) the processor flushes spans.
124
+ Default: 5000. Decrease for lower-latency export.
125
+ Wraps OTEL_BSP_SCHEDULE_DELAY.
126
+ batch_max_export_size: Max spans per export call. Default: 512.
127
+ Wraps OTEL_BSP_MAX_EXPORT_BATCH_SIZE.
128
+
129
+ Example::
130
+
131
+ import gatewaysdk.tracing as tracing
132
+
133
+ # Minimal: auto-detect Gateway from env vars, auto-instrument
134
+ tracing.init()
135
+
136
+ # With environment and version for filtering in Gateway
137
+ tracing.init(
138
+ service_name="my-agent",
139
+ environment="production",
140
+ version="1.2.3",
141
+ instrument_default=True,
142
+ )
143
+
144
+ # Explicit Gateway credentials (instead of env vars)
145
+ tracing.init(
146
+ service_name="my-agent",
147
+ environment="production",
148
+ version="1.2.3",
149
+ gateway_host="https://app.gateway.dev",
150
+ gateway_public_key="pk-lf-...",
151
+ gateway_secret_key="sk-lf-...",
152
+ )
153
+
154
+ # Ensure cleanup on shutdown
155
+ import atexit
156
+ atexit.register(tracing.shutdown)
157
+ """
158
+ global _initialized, _provider
159
+
160
+ resolved_level = _resolve_debug_level(debug)
161
+ if resolved_level is not None:
162
+ _configure_debug_logging(resolved_level)
163
+
164
+ with _init_lock:
165
+ # Check existing provider
166
+ current_provider = trace.get_tracer_provider()
167
+ has_sdk_provider = isinstance(current_provider, TracerProvider)
168
+
169
+ if _initialized and not force:
170
+ logger.debug("GatewaySDK tracing already initialized. Use force=True to reinitialize.")
171
+ return
172
+
173
+ if has_sdk_provider and not force:
174
+ # Reuse existing provider
175
+ logger.info("Reusing existing TracerProvider")
176
+ _provider = current_provider
177
+ else:
178
+ # Create new provider
179
+ resource_attrs = {
180
+ SERVICE_NAME: service_name or "gatewaysdk-tracing",
181
+ }
182
+ if trace_name:
183
+ resource_attrs["trace.name"] = trace_name
184
+ if environment:
185
+ resource_attrs[GATEWAY_ENVIRONMENT] = environment
186
+ if version:
187
+ resource_attrs[GATEWAY_VERSION] = version
188
+
189
+ resource = Resource.create(resource_attrs)
190
+ _provider = TracerProvider(resource=resource)
191
+
192
+ # Set as global provider
193
+ trace.set_tracer_provider(_provider)
194
+ logger.info("Created new TracerProvider with service_name=%s", service_name or "gatewaysdk-tracing")
195
+
196
+ # Add TracingContextSpanProcessor for automatic context injection
197
+ # This must be added BEFORE exporter processors so context is set first
198
+ _add_context_processor_idempotent(_provider)
199
+
200
+ if resolved_level is not None:
201
+ _add_logging_processor_idempotent(_provider)
202
+
203
+ configured_exporters = exporters or []
204
+
205
+ # Auto-configure Gateway exporter if no custom exporters provided
206
+ if not configured_exporters:
207
+ # Check if Gateway credentials are provided via parameters
208
+ if gateway_host and gateway_public_key and gateway_secret_key:
209
+ try:
210
+ gateway_exporter = gateway(
211
+ host=gateway_host,
212
+ public_key=gateway_public_key,
213
+ secret_key=gateway_secret_key,
214
+ endpoint=gateway_endpoint,
215
+ )
216
+ configured_exporters.append(gateway_exporter)
217
+ logger.info("Configured Gateway exporter from init() parameters")
218
+ except ValueError as e:
219
+ logger.warning("Could not configure Gateway exporter: %s", e)
220
+ # Fall back to environment variables
221
+ elif is_gateway_configured():
222
+ try:
223
+ gateway_exporter = gateway()
224
+ configured_exporters.append(gateway_exporter)
225
+ logger.info("Auto-configured Gateway exporter from environment variables")
226
+ except ValueError as e:
227
+ logger.warning("Could not auto-configure Gateway exporter: %s", e)
228
+
229
+ if not configured_exporters:
230
+ logger.warning("No exporter configured -- spans will not be persisted")
231
+
232
+ # Store batch processor config for _add_processor_idempotent
233
+ _batch_config.clear()
234
+ if batch_queue_size is not None:
235
+ _batch_config["max_queue_size"] = batch_queue_size
236
+ if batch_flush_interval is not None:
237
+ _batch_config["schedule_delay_millis"] = batch_flush_interval
238
+ if batch_max_export_size is not None:
239
+ _batch_config["max_export_batch_size"] = batch_max_export_size
240
+
241
+ # Add processors for each exporter (idempotent)
242
+ for exporter in configured_exporters:
243
+ _add_processor_idempotent(_provider, exporter)
244
+
245
+ # Run instrumentation
246
+ if instrument_default:
247
+ instrument()
248
+
249
+ # Agent identity: the one declared identity. Everything else
250
+ # (user, session, context items) flows inherently.
251
+ from .identity import (
252
+ register_agent_with_platform,
253
+ resolve_agent_identity,
254
+ set_agent_identity,
255
+ )
256
+
257
+ identity = resolve_agent_identity(agent)
258
+ set_agent_identity(identity)
259
+ from .identity import initialize_ambient_session
260
+
261
+ initialize_ambient_session()
262
+ if identity is not None:
263
+ register_agent_with_platform(
264
+ identity,
265
+ host=gateway_host,
266
+ public_key=gateway_public_key,
267
+ secret_key=gateway_secret_key,
268
+ )
269
+ # Agent build identity — "the agent IS the manifest": everything
270
+ # registered before init (define_tool / register_prompt) plus the
271
+ # code ref becomes a content-addressed build, stamped on every
272
+ # span and auto-registered (idempotent on hash, fail-soft).
273
+ from gatewaysdk.build import activate_build
274
+
275
+ activate_build(
276
+ identity.id,
277
+ version=identity.version,
278
+ host=gateway_host,
279
+ public_key=gateway_public_key,
280
+ secret_key=gateway_secret_key,
281
+ )
282
+
283
+ _initialized = True
284
+ logger.info("GatewaySDK tracing initialized successfully")
285
+
286
+
287
+ def instrument(
288
+ names: Optional[List[str]] = None,
289
+ skip: Optional[List[str]] = None,
290
+ ) -> None:
291
+ """Manually enable specific instrumentations.
292
+
293
+ This function looks up instrumentors by name from the registry and
294
+ activates them. If no names are provided and init() was called with
295
+ instrument_default=True, this enables the "core set".
296
+
297
+ Core Set (enabled by default):
298
+ - openai
299
+ - anthropic
300
+ - langchain
301
+ - llama_index
302
+ - litellm
303
+
304
+ Additional Available:
305
+ - google_adk
306
+ - mistral
307
+ - groq
308
+ - bedrock
309
+
310
+ Args:
311
+ names: List of instrumentor names to enable. If None and called from
312
+ init() with instrument_default=True, enables the core set.
313
+ skip: List of instrumentor names to explicitly skip.
314
+
315
+ Example::
316
+
317
+ import gatewaysdk.tracing_claude as tracing
318
+
319
+ # Enable only specific instrumentors
320
+ tracing.init(instrument_default=False)
321
+ tracing.instrument(names=["openai", "anthropic"])
322
+
323
+ # Enable all except langchain
324
+ tracing.instrument(skip=["langchain"])
325
+ """
326
+ from .instrumentors.registry import get_registry
327
+
328
+ registry = get_registry()
329
+ skip_set = set(skip or [])
330
+
331
+ # Determine which instrumentors to enable
332
+ if names is None:
333
+ # Default core set -- instruments all installed AI libraries automatically
334
+ target_names = [
335
+ "openai_agents",
336
+ "claude_agent_sdk",
337
+ "openai",
338
+ "anthropic",
339
+ "langchain",
340
+ "llama_index",
341
+ "litellm",
342
+ ]
343
+ else:
344
+ target_names = names
345
+
346
+ # Filter out skipped instrumentors
347
+ target_names = [name for name in target_names if name not in skip_set]
348
+
349
+ # Activate each instrumentor
350
+ for name in target_names:
351
+ instrumentor = registry.get(name)
352
+ if instrumentor is not None:
353
+ try:
354
+ instrumentor.instrument()
355
+ logger.info("Instrumented: %s", name)
356
+ except Exception as e:
357
+ logger.debug("Could not instrument %s: %s", name, e)
358
+ else:
359
+ logger.debug("Instrumentor not available (not installed?): %s", name)
360
+ # Warn loudly when the AI library IS installed but its instrumentor
361
+ # is missing — otherwise the user gets zero telemetry, silently.
362
+ registry.warn_if_lib_present_but_uninstrumented(name)
363
+
364
+ # The openai-agents instrumentor rides on the Agents SDK's own tracing
365
+ # pipeline. OPENAI_AGENTS_DISABLE_TRACING=1 (commonly set to silence the
366
+ # OpenAI trace-upload 401s when pointing at a non-OpenAI base URL) turns
367
+ # that pipeline off entirely — and with it, ALL Gateway telemetry for the
368
+ # agent. Warn loudly; the 401 noise alone is harmless.
369
+ if "openai_agents" in target_names and os.environ.get(
370
+ "OPENAI_AGENTS_DISABLE_TRACING", ""
371
+ ).lower() in ("1", "true", "yes"):
372
+ print(
373
+ "gatewaysdk.tracing: OPENAI_AGENTS_DISABLE_TRACING is set, which "
374
+ "disables the OpenAI Agents SDK tracing pipeline the Gateway "
375
+ "instrumentor rides on — NOTHING from openai-agents will reach "
376
+ "Gateway. Unset it (the OpenAI trace-upload 401s it silences are "
377
+ "harmless) or set OPENAI_AGENTS_TRACING_EXPORT_API_KEY to a real "
378
+ "OpenAI key.",
379
+ file=sys.stderr,
380
+ )
381
+
382
+
383
+ def shutdown(timeout_millis: int = 30000) -> None:
384
+ """Force flush all pending spans and shutdown the tracer provider.
385
+
386
+ This function should be called before process exit to ensure all spans
387
+ are exported. It is safe to call multiple times.
388
+
389
+ Args:
390
+ timeout_millis: Maximum time to wait for flush completion in milliseconds.
391
+
392
+ Example::
393
+
394
+ import gatewaysdk.tracing_claude as tracing
395
+ import atexit
396
+
397
+ tracing.init()
398
+ atexit.register(tracing.shutdown)
399
+
400
+ # ... run application ...
401
+ """
402
+ global _initialized, _provider, _context_processor_added, _logging_processor_added, _export_count
403
+
404
+ with _init_lock:
405
+ if not _initialized or _provider is None:
406
+ logger.debug("Tracing not initialized, nothing to shutdown")
407
+ return
408
+
409
+ try:
410
+ # Shutdown the provider (which flushes and shuts down processors)
411
+ _provider.shutdown()
412
+ logger.info("Shutdown complete: exported %d span(s) total", _export_count)
413
+ except Exception as e:
414
+ logger.warning("Error during TracerProvider shutdown: %s", e)
415
+
416
+ _processors.clear()
417
+ _batch_config.clear()
418
+ _initialized = False
419
+ _provider = None
420
+ _context_processor_added = False
421
+ _logging_processor_added = False
422
+ _export_count = 0
423
+
424
+
425
+ def flush(timeout_millis: int = 30000) -> bool:
426
+ """Force flush all pending spans without shutting down.
427
+
428
+ This is useful for ensuring spans are exported at specific points
429
+ (e.g., after completing a batch of work) without ending the tracing session.
430
+
431
+ Args:
432
+ timeout_millis: Maximum time to wait for flush completion in milliseconds.
433
+
434
+ Returns:
435
+ True if flush completed successfully, False otherwise.
436
+
437
+ Example::
438
+
439
+ import gatewaysdk.tracing_claude as tracing
440
+
441
+ tracing.init()
442
+
443
+ # Process batch
444
+ for item in batch:
445
+ process(item)
446
+
447
+ # Ensure all spans from this batch are exported
448
+ tracing.flush()
449
+ """
450
+ with _init_lock:
451
+ if _provider is None:
452
+ logger.debug("No provider to flush")
453
+ return True
454
+
455
+ try:
456
+ success = _provider.force_flush(timeout_millis=timeout_millis)
457
+ if success:
458
+ logger.debug("Flush completed successfully")
459
+ else:
460
+ logger.warning("Flush timed out after %d ms", timeout_millis)
461
+ return success
462
+ except Exception as e:
463
+ logger.warning("Error during flush: %s", e)
464
+ return False
465
+
466
+
467
+ # Track if context processor has been added
468
+ _context_processor_added = False
469
+
470
+
471
+ def _add_context_processor_idempotent(provider: TracerProvider) -> None:
472
+ """Add the TracingContextSpanProcessor if not already added.
473
+
474
+ This processor injects run context (run_id, session_id) and tracing
475
+ context (call_type, tags, environment) into all spans automatically.
476
+ """
477
+ global _context_processor_added
478
+
479
+ if _context_processor_added:
480
+ logger.debug("TracingContextSpanProcessor already added")
481
+ return
482
+
483
+ processor = TracingContextSpanProcessor()
484
+ provider.add_span_processor(processor)
485
+ _context_processor_added = True
486
+ logger.debug("Added TracingContextSpanProcessor for automatic context injection")
487
+
488
+
489
+ def _add_processor_idempotent(provider: TracerProvider, exporter: SpanExporter) -> None:
490
+ """Add a BatchSpanProcessor for the exporter, avoiding duplicates.
491
+
492
+ Checks if a processor for the same exporter type/endpoint already exists
493
+ to prevent duplicate exports.
494
+ """
495
+ # Check for existing processor with same exporter type
496
+ exporter_id = _get_exporter_id(exporter)
497
+ for existing in _processors:
498
+ if _get_exporter_id(existing.span_exporter) == exporter_id:
499
+ logger.debug("Processor already exists for exporter: %s", exporter_id)
500
+ return
501
+
502
+ # Create and add new processor.
503
+ # Wrap Gateway exporters with AnnotationFilterSpanProcessor to suppress
504
+ # gatewaysdk.annotation reward spans from OTLP (rewards are sent as
505
+ # Langfuse Scores via the API instead).
506
+ from .exporters.gateway import GatewayOTLPExporter
507
+ from .processors import AnnotationFilterSpanProcessor
508
+
509
+ batch_processor = BatchSpanProcessor(exporter, **_batch_config)
510
+ if isinstance(exporter, GatewayOTLPExporter):
511
+ filtered = AnnotationFilterSpanProcessor(batch_processor)
512
+ provider.add_span_processor(filtered)
513
+ logger.debug("Added filtered BatchSpanProcessor for: %s", exporter_id)
514
+ else:
515
+ provider.add_span_processor(batch_processor)
516
+ logger.debug("Added BatchSpanProcessor for: %s", exporter_id)
517
+ _processors.append(batch_processor)
518
+
519
+
520
+ def _get_exporter_id(exporter: SpanExporter) -> str:
521
+ """Generate a unique identifier for an exporter instance.
522
+
523
+ Uses class name + endpoint (if available) to identify exporters.
524
+ """
525
+ class_name = exporter.__class__.__name__
526
+
527
+ # Try to get endpoint for OTLP exporters
528
+ endpoint = getattr(exporter, "_endpoint", None)
529
+ if endpoint:
530
+ return f"{class_name}:{endpoint}"
531
+
532
+ return class_name
533
+
534
+
535
+ def _resolve_debug_level(debug: Union[bool, str]) -> Optional[str]:
536
+ """Resolve the debug parameter to a Python logging level name, or None if disabled."""
537
+ if debug is False or debug is None:
538
+ return None
539
+ if debug is True:
540
+ return "DEBUG"
541
+ level_name = str(debug).upper()
542
+ if level_name not in ("DEBUG", "INFO", "WARNING", "ERROR"):
543
+ raise ValueError(f"Invalid debug level: {debug!r}. " "Use True, False, 'DEBUG', 'INFO', 'WARNING', or 'ERROR'.")
544
+ return level_name
545
+
546
+
547
+ def _record_exported(count: int) -> None:
548
+ """Increment the global export counter (called by GatewayOTLPExporter)."""
549
+ global _export_count
550
+ _export_count += count
551
+
552
+
553
+ _logging_processor_added = False
554
+
555
+
556
+ def _add_logging_processor_idempotent(provider: TracerProvider) -> None:
557
+ """Add the LoggingSpanProcessor if not already added."""
558
+ global _logging_processor_added
559
+
560
+ if _logging_processor_added:
561
+ return
562
+
563
+ provider.add_span_processor(LoggingSpanProcessor())
564
+ _logging_processor_added = True
565
+ logger.debug("Added LoggingSpanProcessor for debug visibility")
566
+
567
+
568
+ def _configure_debug_logging(level: str = "DEBUG") -> None:
569
+ """Configure Python logging so gatewaysdk.tracing messages reach the console.
570
+
571
+ Sets up a StreamHandler on the ``gatewaysdk.tracing`` logger hierarchy
572
+ (and the OTLP exporter logger) at the requested level.
573
+ Writes to stdout (not stderr) so output interleaves naturally with
574
+ application print() statements.
575
+
576
+ Args:
577
+ level: Python logging level name (DEBUG, INFO, WARNING, ERROR).
578
+ """
579
+ import sys
580
+
581
+ numeric_level = getattr(logging, level, logging.DEBUG)
582
+
583
+ tracing_logger = logging.getLogger("gatewaysdk.tracing")
584
+ if tracing_logger.handlers:
585
+ return
586
+
587
+ handler = logging.StreamHandler(stream=sys.stdout)
588
+ handler.setLevel(numeric_level)
589
+ fmt = logging.Formatter("[%(name)s] %(message)s")
590
+ handler.setFormatter(fmt)
591
+
592
+ tracing_logger.addHandler(handler)
593
+ tracing_logger.setLevel(numeric_level)
594
+ tracing_logger.propagate = False
595
+
596
+ # Also capture OTLP exporter warnings (connection failures, retries)
597
+ otel_logger = logging.getLogger("opentelemetry.exporter.otlp")
598
+ otel_logger.addHandler(handler)
599
+ otel_logger.setLevel(logging.WARNING)
600
+ otel_logger.propagate = False
601
+
602
+ # Suppress noisy OTel warnings about provider overriding (force=True triggers these)
603
+ for name in ("opentelemetry.trace", "opentelemetry.sdk.trace"):
604
+ lg = logging.getLogger(name)
605
+ lg.setLevel(logging.ERROR)
606
+
607
+
608
+ def get_tracer(name: str = "gatewaysdk.tracing") -> trace.Tracer:
609
+ """Get a tracer instance for creating spans.
610
+
611
+ This is primarily for internal use. Users should prefer the
612
+ trace() and span() context managers.
613
+
614
+ Args:
615
+ name: The tracer name (instrumentation scope).
616
+
617
+ Returns:
618
+ OpenTelemetry Tracer instance.
619
+ """
620
+ return trace.get_tracer(name)
@@ -0,0 +1,15 @@
1
+ # Copyright (c) Gateway. All rights reserved.
2
+
3
+ """Instrumentors for GatewayDK tracing.
4
+
5
+ This module provides a registry-based system for managing OpenTelemetry
6
+ instrumentors from various sources (OpenInference, AgentOps, etc.).
7
+ """
8
+
9
+ from .registry import BaseInstrumentor, InstrumentorRegistry, get_registry
10
+
11
+ __all__ = [
12
+ "get_registry",
13
+ "InstrumentorRegistry",
14
+ "BaseInstrumentor",
15
+ ]