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,617 @@
1
+ # Copyright (c) Gateway. All rights reserved.
2
+
3
+ """Public API for JSON push-to-trace.
4
+
5
+ Provides three functions:
6
+ - push() -- convert JSON to OTel spans and export
7
+ - validate() -- dry-run preview without exporting
8
+ - inspect() -- analyze JSON structure and suggest mappings
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import logging
15
+ from typing import Any, Dict, List, Optional, Union
16
+
17
+ from .mapping import (
18
+ CHILD_CONVENTIONS,
19
+ CHILDREN_KEYS,
20
+ TRACE_CONVENTIONS,
21
+ apply_conventions,
22
+ describe_type,
23
+ merge_fields,
24
+ normalize_mapping,
25
+ resolve_path,
26
+ suggest_mapping_for_key,
27
+ truncate_sample,
28
+ validate_mapping,
29
+ )
30
+ from .push_models import (
31
+ ChildMapping,
32
+ FieldInfo,
33
+ InspectResult,
34
+ PushError,
35
+ PushResult,
36
+ SpanPreview,
37
+ TraceMapping,
38
+ TracePreview,
39
+ ValidationIssue,
40
+ )
41
+ from .span_builder import build_trace_preview, build_trace_spans
42
+
43
+ logger = logging.getLogger(__name__)
44
+
45
+
46
+ # =============================================================================
47
+ # push()
48
+ # =============================================================================
49
+
50
+
51
+ def push(
52
+ data: Union[dict, list, str],
53
+ *,
54
+ mapping: Union[TraceMapping, dict, None] = None,
55
+ depth: Optional[int] = 1,
56
+ name: Optional[str] = None,
57
+ session_id: Optional[str] = None,
58
+ user_id: Optional[str] = None,
59
+ run_id: Optional[str] = None,
60
+ tags: Optional[List[str]] = None,
61
+ metadata: Optional[dict] = None,
62
+ environment: Optional[str] = None,
63
+ attributes: Optional[Dict[str, Any]] = None,
64
+ strict: bool = True,
65
+ timestamp_unit: str = "auto",
66
+ ) -> Union[PushResult, List[PushResult]]:
67
+ """Push structured JSON data as a trace.
68
+
69
+ Converts JSON into OTel spans and routes through the existing export
70
+ pipeline. No new server endpoints needed.
71
+
72
+ Args:
73
+ data: JSON data as a dict, list of dicts (batch), or JSON string.
74
+ If str, parsed as JSON first (raises PushError on invalid JSON).
75
+ mapping: Field mapping config. Accepts TraceMapping (Pydantic) or dict.
76
+ If None, convention defaults auto-detect fields.
77
+ Pass {} (empty dict) to disable conventions.
78
+ depth: Controls convention auto-detection recursion depth.
79
+ 0=flat (root only), 1=one level, None=unlimited.
80
+ Ignored when an explicit mapping with nested children is provided.
81
+ name: Override trace name.
82
+ session_id: Override session ID.
83
+ user_id: Override user ID.
84
+ run_id: Override run ID.
85
+ tags: Tags to merge with mapped tags.
86
+ metadata: Metadata to deep-merge with mapped metadata.
87
+ environment: Override environment.
88
+ attributes: Extra OTel span attributes (escape hatch).
89
+ strict: If True, raise on validation errors. If False, warn and continue.
90
+ timestamp_unit: Unit for numeric timestamp values in the data.
91
+ "s" (seconds), "ms" (milliseconds), "us" (microseconds),
92
+ "ns" (nanoseconds), or "auto" (default, infer from magnitude).
93
+
94
+ Returns:
95
+ PushResult for a single dict, List[PushResult] for a batch.
96
+
97
+ Raises:
98
+ PushError: On invalid JSON or validation errors (when strict=True).
99
+ """
100
+ parsed = _parse_input(data)
101
+
102
+ # Handle batch: resolve mapping once, push each item
103
+ if isinstance(parsed, list):
104
+ return _push_batch(
105
+ parsed,
106
+ mapping=mapping,
107
+ depth=depth,
108
+ name=name,
109
+ session_id=session_id,
110
+ user_id=user_id,
111
+ run_id=run_id,
112
+ tags=tags,
113
+ metadata=metadata,
114
+ environment=environment,
115
+ attributes=attributes,
116
+ strict=strict,
117
+ timestamp_unit=timestamp_unit,
118
+ )
119
+
120
+ # Resolve mapping
121
+ resolved_mapping, unrecognized_keys = _resolve_mapping(parsed, mapping, depth)
122
+
123
+ # Fail fast on unrecognized mapping keys
124
+ if unrecognized_keys:
125
+ for key in unrecognized_keys:
126
+ issue = ValidationIssue(
127
+ field="mapping",
128
+ path=key,
129
+ issue="unrecognized_key",
130
+ message=f"Mapping key '{key}' not recognized. Keys must start with 'trace.' or 'children.'.",
131
+ )
132
+ if strict:
133
+ raise PushError(
134
+ f"Unrecognized mapping key: '{key}'. " f"Keys must start with 'trace.' or 'children.'.",
135
+ issues=[issue],
136
+ )
137
+
138
+ # Validate
139
+ errors, warnings = validate_mapping(parsed, resolved_mapping)
140
+
141
+ # Surface unrecognized keys as warnings in lenient mode
142
+ for key in unrecognized_keys:
143
+ warnings.append(
144
+ ValidationIssue(
145
+ field="mapping",
146
+ path=key,
147
+ issue="unrecognized_key",
148
+ message=f"Mapping key '{key}' not recognized. Keys must start with 'trace.' or 'children.'.",
149
+ )
150
+ )
151
+
152
+ if errors and strict:
153
+ messages = "; ".join(e.message for e in errors)
154
+ raise PushError(f"Validation failed: {messages}", issues=errors)
155
+ if errors and not strict:
156
+ warnings.extend(errors) # Demote errors to warnings in lenient mode
157
+
158
+ # Extract mapped values
159
+ mapped_values = _extract_mapped_values(parsed, resolved_mapping)
160
+
161
+ # Build explicit overrides
162
+ explicit = _build_explicit(
163
+ name=name,
164
+ session_id=session_id,
165
+ user_id=user_id,
166
+ run_id=run_id,
167
+ tags=tags,
168
+ metadata=metadata,
169
+ environment=environment,
170
+ )
171
+
172
+ # Merge fields
173
+ fields = merge_fields(
174
+ mapped=mapped_values,
175
+ explicit=explicit,
176
+ context={}, # Ambient context injected by TracingContextSpanProcessor
177
+ defaults={},
178
+ )
179
+
180
+ # Build OTel spans
181
+ trace_id, observation_count, runtime_warnings = build_trace_spans(
182
+ data=parsed,
183
+ fields=fields,
184
+ child_mapping=resolved_mapping.children,
185
+ extra_attributes=attributes,
186
+ timestamp_unit=timestamp_unit,
187
+ )
188
+
189
+ # Strict mode: raise on any runtime issues (non-dict children, bad timestamps)
190
+ if runtime_warnings and strict:
191
+ messages = "; ".join(w.message for w in runtime_warnings)
192
+ raise PushError(f"Runtime validation failed: {messages}", issues=runtime_warnings)
193
+
194
+ warnings.extend(runtime_warnings)
195
+
196
+ logger.info(
197
+ "Pushed trace %s with %d observations",
198
+ trace_id,
199
+ observation_count,
200
+ )
201
+
202
+ return PushResult(
203
+ trace_id=trace_id,
204
+ observation_count=observation_count,
205
+ warnings=warnings,
206
+ )
207
+
208
+
209
+ def _push_batch(
210
+ items: list,
211
+ *,
212
+ mapping: Union[TraceMapping, dict, None],
213
+ depth: Optional[int],
214
+ name: Optional[str],
215
+ session_id: Optional[str],
216
+ user_id: Optional[str],
217
+ run_id: Optional[str],
218
+ tags: Optional[List[str]],
219
+ metadata: Optional[dict],
220
+ environment: Optional[str],
221
+ attributes: Optional[Dict[str, Any]],
222
+ strict: bool,
223
+ timestamp_unit: str = "auto",
224
+ ) -> List[PushResult]:
225
+ """Flat batch path: resolve mapping once, build spans for each item."""
226
+ # Check for non-dict items
227
+ skipped = [(i, type(item).__name__) for i, item in enumerate(items) if not isinstance(item, dict)]
228
+ if skipped and strict:
229
+ indices = [i for i, _ in skipped]
230
+ raise PushError(
231
+ f"Batch contains {len(skipped)} non-dict item(s) at indices {indices}. " "All batch items must be dicts."
232
+ )
233
+
234
+ dict_items = [item for item in items if isinstance(item, dict)]
235
+ if not dict_items:
236
+ raise PushError("Batch data contained no valid dict items.")
237
+
238
+ # Resolve mapping once using first item as reference
239
+ resolved_mapping, unrecognized_keys = _resolve_mapping(dict_items[0], mapping, depth)
240
+
241
+ if unrecognized_keys:
242
+ for key in unrecognized_keys:
243
+ issue = ValidationIssue(
244
+ field="mapping",
245
+ path=key,
246
+ issue="unrecognized_key",
247
+ message=f"Mapping key '{key}' not recognized. Keys must start with 'trace.' or 'children.'.",
248
+ )
249
+ if strict:
250
+ raise PushError(
251
+ f"Unrecognized mapping key: '{key}'. " f"Keys must start with 'trace.' or 'children.'.",
252
+ issues=[issue],
253
+ )
254
+
255
+ # Validate mapping once against first item
256
+ errors, mapping_warnings = validate_mapping(dict_items[0], resolved_mapping)
257
+
258
+ for key in unrecognized_keys:
259
+ mapping_warnings.append(
260
+ ValidationIssue(
261
+ field="mapping",
262
+ path=key,
263
+ issue="unrecognized_key",
264
+ message=f"Mapping key '{key}' not recognized. Keys must start with 'trace.' or 'children.'.",
265
+ )
266
+ )
267
+
268
+ if errors and strict:
269
+ messages = "; ".join(e.message for e in errors)
270
+ raise PushError(f"Validation failed: {messages}", issues=errors)
271
+
272
+ explicit = _build_explicit(
273
+ name=name,
274
+ session_id=session_id,
275
+ user_id=user_id,
276
+ run_id=run_id,
277
+ tags=tags,
278
+ metadata=metadata,
279
+ environment=environment,
280
+ )
281
+
282
+ # Build spans for each item (no recursion)
283
+ results: List[PushResult] = []
284
+ for item in dict_items:
285
+ mapped_values = _extract_mapped_values(item, resolved_mapping)
286
+ fields = merge_fields(
287
+ mapped=mapped_values,
288
+ explicit=explicit,
289
+ context={},
290
+ defaults={},
291
+ )
292
+
293
+ trace_id, obs_count, runtime_warnings = build_trace_spans(
294
+ data=item,
295
+ fields=fields,
296
+ child_mapping=resolved_mapping.children,
297
+ extra_attributes=attributes,
298
+ timestamp_unit=timestamp_unit,
299
+ )
300
+
301
+ if runtime_warnings and strict:
302
+ messages = "; ".join(w.message for w in runtime_warnings)
303
+ raise PushError(f"Runtime validation failed: {messages}", issues=runtime_warnings)
304
+
305
+ item_warnings = list(mapping_warnings) + runtime_warnings
306
+ if errors and not strict:
307
+ item_warnings.extend(errors)
308
+
309
+ results.append(
310
+ PushResult(
311
+ trace_id=trace_id,
312
+ observation_count=obs_count,
313
+ warnings=item_warnings,
314
+ )
315
+ )
316
+
317
+ # Surface skipped items as warnings on the last result (lenient mode)
318
+ if skipped and results:
319
+ indices = [i for i, _ in skipped]
320
+ results[-1].warnings.append(
321
+ ValidationIssue(
322
+ field="batch",
323
+ path="",
324
+ issue="non_dict_items",
325
+ message=f"Skipped {len(skipped)} non-dict item(s) at indices {indices}.",
326
+ )
327
+ )
328
+
329
+ logger.info("Pushed batch of %d traces", len(results))
330
+ return results
331
+
332
+
333
+ # =============================================================================
334
+ # validate()
335
+ # =============================================================================
336
+
337
+
338
+ def validate(
339
+ data: Union[dict, str],
340
+ *,
341
+ mapping: Union[TraceMapping, dict, None] = None,
342
+ depth: Optional[int] = 1,
343
+ name: Optional[str] = None,
344
+ session_id: Optional[str] = None,
345
+ user_id: Optional[str] = None,
346
+ run_id: Optional[str] = None,
347
+ tags: Optional[List[str]] = None,
348
+ metadata: Optional[dict] = None,
349
+ environment: Optional[str] = None,
350
+ ) -> TracePreview:
351
+ """Validate data + mapping without exporting.
352
+
353
+ Returns a preview of the trace tree that would be created,
354
+ along with any warnings and errors.
355
+ """
356
+ parsed = _parse_input(data)
357
+ if isinstance(parsed, list):
358
+ raise PushError("validate() does not accept batch data. Pass a single dict.")
359
+
360
+ resolved_mapping, unrecognized_keys = _resolve_mapping(parsed, mapping, depth)
361
+ errors, warnings = validate_mapping(parsed, resolved_mapping)
362
+
363
+ for key in unrecognized_keys:
364
+ errors.append(
365
+ ValidationIssue(
366
+ field="mapping",
367
+ path=key,
368
+ issue="unrecognized_key",
369
+ message=f"Mapping key '{key}' not recognized. Keys must start with 'trace.' or 'children.'.",
370
+ )
371
+ )
372
+
373
+ mapped_values = _extract_mapped_values(parsed, resolved_mapping)
374
+
375
+ explicit = _build_explicit(
376
+ name=name,
377
+ session_id=session_id,
378
+ user_id=user_id,
379
+ run_id=run_id,
380
+ tags=tags,
381
+ metadata=metadata,
382
+ environment=environment,
383
+ )
384
+
385
+ fields = merge_fields(
386
+ mapped=mapped_values,
387
+ explicit=explicit,
388
+ context={},
389
+ defaults={},
390
+ )
391
+
392
+ children_preview = build_trace_preview(
393
+ parsed,
394
+ fields,
395
+ resolved_mapping.children,
396
+ )
397
+
398
+ return TracePreview(
399
+ name=fields.get("name"),
400
+ input=fields.get("input"),
401
+ output=fields.get("output"),
402
+ metadata=fields.get("metadata"),
403
+ tags=fields.get("tags", []),
404
+ session_id=fields.get("session_id"),
405
+ user_id=fields.get("user_id"),
406
+ run_id=fields.get("run_id"),
407
+ environment=fields.get("environment"),
408
+ children=children_preview,
409
+ warnings=warnings,
410
+ errors=errors,
411
+ )
412
+
413
+
414
+ # =============================================================================
415
+ # inspect()
416
+ # =============================================================================
417
+
418
+
419
+ def inspect(
420
+ data: Union[dict, str],
421
+ *,
422
+ depth: Optional[int] = None,
423
+ ) -> InspectResult:
424
+ """Inspect a JSON structure and show what conventions match.
425
+
426
+ Does not require tracing.init() -- purely local analysis.
427
+
428
+ Args:
429
+ data: JSON data as a dict or JSON string.
430
+ depth: How deep to recurse into children for inspection.
431
+ None = unlimited.
432
+
433
+ Returns:
434
+ InspectResult with structure, convention matches, unmatched keys,
435
+ and a suggested mapping.
436
+ """
437
+ parsed = _parse_input(data)
438
+ if isinstance(parsed, list):
439
+ raise PushError("inspect() does not accept batch data. Pass a single dict.")
440
+
441
+ structure: List[FieldInfo] = []
442
+ convention_matches: Dict[str, str] = {}
443
+ unmatched: List[FieldInfo] = []
444
+ suggestions: Dict[str, str] = {}
445
+
446
+ # Scan trace-level fields
447
+ for target, candidates in TRACE_CONVENTIONS.items():
448
+ from .mapping import _find_convention_match
449
+
450
+ match = _find_convention_match(parsed, candidates)
451
+ if match is not None:
452
+ convention_matches[f"trace.{target}"] = match
453
+
454
+ # Detect children
455
+ from .mapping import _find_convention_match
456
+
457
+ children_key = _find_convention_match(parsed, CHILDREN_KEYS)
458
+ if children_key is not None:
459
+ convention_matches["children"] = children_key
460
+
461
+ # Build structure and find unmatched keys
462
+ matched_root_keys = set(convention_matches.values())
463
+
464
+ for key, value in parsed.items():
465
+ info = FieldInfo(
466
+ path=key,
467
+ type=describe_type(value),
468
+ sample=truncate_sample(value),
469
+ matched_as=None,
470
+ )
471
+
472
+ # Check if this key was matched
473
+ for target, matched_key in convention_matches.items():
474
+ if matched_key == key:
475
+ info.matched_as = target
476
+ break
477
+
478
+ structure.append(info)
479
+
480
+ if key not in matched_root_keys:
481
+ suggestion = suggest_mapping_for_key(key, "root")
482
+ if suggestion:
483
+ suggestions[suggestion] = key
484
+ unmatched.append(info)
485
+
486
+ # Scan children if present
487
+ if children_key is not None:
488
+ found, children_data = resolve_path(parsed, children_key)
489
+ if found and isinstance(children_data, list) and children_data:
490
+ sample_child = children_data[0]
491
+ if isinstance(sample_child, dict):
492
+ _inspect_children(
493
+ sample_child,
494
+ children_key,
495
+ convention_matches,
496
+ structure,
497
+ unmatched,
498
+ suggestions,
499
+ )
500
+
501
+ return InspectResult(
502
+ structure=structure,
503
+ convention_matches=convention_matches,
504
+ unmatched_keys=unmatched,
505
+ suggested_mapping=suggestions,
506
+ )
507
+
508
+
509
+ # =============================================================================
510
+ # Internal Helpers
511
+ # =============================================================================
512
+
513
+
514
+ def _parse_input(data: Union[dict, list, str]) -> Union[dict, list]:
515
+ """Parse input data, accepting dict, list, or JSON string."""
516
+ if isinstance(data, (dict, list)):
517
+ return data
518
+ if isinstance(data, str):
519
+ try:
520
+ parsed = json.loads(data)
521
+ except json.JSONDecodeError as e:
522
+ raise PushError(f"Invalid JSON string: {e}. Pass a dict instead, or fix the JSON.") from e
523
+ if not isinstance(parsed, (dict, list)):
524
+ raise PushError(f"JSON parsed to {type(parsed).__name__}, expected dict or list.")
525
+ return parsed
526
+ raise PushError(f"Unsupported data type: {type(data).__name__}. Expected dict, list, or str.")
527
+
528
+
529
+ def _resolve_mapping(
530
+ data: dict,
531
+ mapping: Union[TraceMapping, dict, None],
532
+ depth: Optional[int],
533
+ ) -> tuple[TraceMapping, List[str]]:
534
+ """Resolve the mapping parameter to a TraceMapping.
535
+
536
+ Returns (mapping, unrecognized_keys).
537
+ """
538
+ if mapping is None:
539
+ return apply_conventions(data, depth=depth), []
540
+ if isinstance(mapping, dict):
541
+ if not mapping:
542
+ return TraceMapping(), [] # Empty = no conventions
543
+ return normalize_mapping(mapping)
544
+ return mapping, []
545
+
546
+
547
+ def _extract_mapped_values(data: dict, mapping: TraceMapping) -> Dict[str, Any]:
548
+ """Extract values from data using the resolved mapping."""
549
+ values: Dict[str, Any] = {}
550
+
551
+ fields = [
552
+ "name",
553
+ "input",
554
+ "output",
555
+ "metadata",
556
+ "tags",
557
+ "session_id",
558
+ "user_id",
559
+ "run_id",
560
+ "timestamp",
561
+ "environment",
562
+ ]
563
+ for field in fields:
564
+ dot_path = getattr(mapping, field, None)
565
+ if dot_path is not None:
566
+ found, value = resolve_path(data, dot_path)
567
+ if found:
568
+ values[field] = value
569
+
570
+ return values
571
+
572
+
573
+ def _build_explicit(**kwargs: Any) -> Dict[str, Any]:
574
+ """Build the explicit overrides dict, filtering out None values."""
575
+ return {k: v for k, v in kwargs.items() if v is not None}
576
+
577
+
578
+ def _inspect_children(
579
+ sample_child: dict,
580
+ children_key: str,
581
+ convention_matches: Dict[str, str],
582
+ structure: List[FieldInfo],
583
+ unmatched: List[FieldInfo],
584
+ suggestions: Dict[str, str],
585
+ ) -> None:
586
+ """Inspect child fields and update conventions/suggestions."""
587
+ from .mapping import _find_convention_match
588
+
589
+ matched_child_keys: set = set()
590
+
591
+ for target, candidates in CHILD_CONVENTIONS.items():
592
+ match = _find_convention_match(sample_child, candidates)
593
+ if match is not None:
594
+ convention_matches[f"children.{target}"] = match
595
+ matched_child_keys.add(match)
596
+
597
+ for key, value in sample_child.items():
598
+ path = f"{children_key}[*].{key}"
599
+ info = FieldInfo(
600
+ path=path,
601
+ type=describe_type(value),
602
+ sample=truncate_sample(value),
603
+ matched_as=None,
604
+ )
605
+
606
+ if key in matched_child_keys:
607
+ for target, matched_key in convention_matches.items():
608
+ if target.startswith("children.") and matched_key == key:
609
+ info.matched_as = target
610
+ break
611
+ structure.append(info)
612
+ else:
613
+ suggestion = suggest_mapping_for_key(key, "child")
614
+ if suggestion:
615
+ suggestions[suggestion] = key
616
+ structure.append(info)
617
+ unmatched.append(info)