synth-ai 0.18.2.dev614__tar.gz → 0.18.2.dev615__tar.gz

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 (259) hide show
  1. {synth_ai-0.18.2.dev614/synth_ai.egg-info → synth_ai-0.18.2.dev615}/PKG-INFO +1 -1
  2. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/pyproject.toml +1 -1
  3. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/__init__.py +22 -0
  4. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/client.py +38 -3
  5. synth_ai-0.18.2.dev615/synth_ai/sdk/optimizers/__init__.py +30 -0
  6. synth_ai-0.18.2.dev615/synth_ai/sdk/optimizers/client.py +291 -0
  7. synth_ai-0.18.2.dev615/synth_ai/sdk/optimizers/contracts.py +142 -0
  8. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615/synth_ai.egg-info}/PKG-INFO +1 -1
  9. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai.egg-info/SOURCES.txt +3 -0
  10. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/LICENSE +0 -0
  11. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/MANIFEST.in +0 -0
  12. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/README.md +0 -0
  13. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/setup.cfg +0 -0
  14. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/README.md +0 -0
  15. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/__main__.py +0 -0
  16. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/AGENTS.md +0 -0
  17. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/README.md +0 -0
  18. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/__init__.py +0 -0
  19. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/__main__.py +0 -0
  20. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/main.py +0 -0
  21. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/research.py +0 -0
  22. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/research_environments.py +0 -0
  23. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/research_image_releases.py +0 -0
  24. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/cli/research_projects.py +0 -0
  25. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/README.md +0 -0
  26. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/__init__.py +0 -0
  27. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/auth/__init__.py +0 -0
  28. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/auth/credentials.py +0 -0
  29. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/contracts/__init__.py +0 -0
  30. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/contracts/json_value.py +0 -0
  31. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/contracts/pagination.py +0 -0
  32. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/errors.py +0 -0
  33. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/__init__.py +0 -0
  34. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/async_transport.py +0 -0
  35. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/request.py +0 -0
  36. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/retry.py +0 -0
  37. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/streaming.py +0 -0
  38. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/http/transport.py +0 -0
  39. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/research/__init__.py +0 -0
  40. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/utils/__init__.py +0 -0
  41. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/utils/env.py +0 -0
  42. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/utils/log_filter.py +0 -0
  43. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/utils/paths.py +0 -0
  44. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/core/utils/urls.py +0 -0
  45. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/README.md +0 -0
  46. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/__init__.py +0 -0
  47. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/__main__.py +0 -0
  48. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/objective_tools.py +0 -0
  49. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/registry.py +0 -0
  50. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/request_models.py +0 -0
  51. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/server.py +0 -0
  52. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/__init__.py +0 -0
  53. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/approvals.py +0 -0
  54. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/artifacts.py +0 -0
  55. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/datasets.py +0 -0
  56. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/environments.py +0 -0
  57. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/exports.py +0 -0
  58. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/factories.py +0 -0
  59. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/factory_results.py +0 -0
  60. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/files.py +0 -0
  61. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/image_releases.py +0 -0
  62. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/integrations.py +0 -0
  63. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/intern_program.py +0 -0
  64. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/logs.py +0 -0
  65. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/models.py +0 -0
  66. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/outputs.py +0 -0
  67. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/policy_schemas.py +0 -0
  68. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/progress.py +0 -0
  69. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/project_data.py +0 -0
  70. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/projects.py +0 -0
  71. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/prs.py +0 -0
  72. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/readiness.py +0 -0
  73. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/repos.py +0 -0
  74. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/research_intern.py +0 -0
  75. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/resources.py +0 -0
  76. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/runs.py +0 -0
  77. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/trained_models.py +0 -0
  78. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/usage.py +0 -0
  79. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/visuals.py +0 -0
  80. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/mcp/research/tools/workspace_inputs.py +0 -0
  81. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/py.typed +0 -0
  82. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/README.md +0 -0
  83. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/__init__.py +0 -0
  84. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/pagination.py +0 -0
  85. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/__init__.py +0 -0
  86. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/_internal/__init__.py +0 -0
  87. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/_internal/crypto.py +0 -0
  88. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/_internal/env.py +0 -0
  89. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/_internal/urls.py +0 -0
  90. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/account.py +0 -0
  91. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/advanced.py +0 -0
  92. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/advanced_factories.py +0 -0
  93. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/advanced_swarms.py +0 -0
  94. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/artifacts.py +0 -0
  95. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/auth.py +0 -0
  96. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/client.py +0 -0
  97. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/__init__.py +0 -0
  98. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/_activity_wire.py +0 -0
  99. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/_environment_wire.py +0 -0
  100. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/_transcript_wire.py +0 -0
  101. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/_wire.py +0 -0
  102. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/activity.py +0 -0
  103. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/activity_items.py +0 -0
  104. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/actor_images.py +0 -0
  105. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/billing.py +0 -0
  106. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/canonical_usage.py +0 -0
  107. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/checkpoints.py +0 -0
  108. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/cloud_deployment_claims.py +0 -0
  109. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/cloud_deployments.py +0 -0
  110. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/common.py +0 -0
  111. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/dataset_revisions.py +0 -0
  112. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/deliveries.py +0 -0
  113. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/dev_environment_evidence.py +0 -0
  114. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/economics.py +0 -0
  115. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/environment_manifest.py +0 -0
  116. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/environments.py +0 -0
  117. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/evidence.py +0 -0
  118. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/factories.py +0 -0
  119. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/factory_evidence.py +0 -0
  120. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/factory_lenses.py +0 -0
  121. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/factory_operations.py +0 -0
  122. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/factory_role_receipts.py +0 -0
  123. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/failure.py +0 -0
  124. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/image_releases.py +0 -0
  125. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/intern_grants.py +0 -0
  126. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/intern_program.py +0 -0
  127. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/limit_evidence.py +0 -0
  128. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/local_execution_profile.py +0 -0
  129. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/operator_evidence.py +0 -0
  130. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/project.py +0 -0
  131. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/project_data.py +0 -0
  132. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/project_runtime.py +0 -0
  133. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/project_workspace.py +0 -0
  134. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/project_workspace_evidence.py +0 -0
  135. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/projects.py +0 -0
  136. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/promotions.py +0 -0
  137. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/research_intern.py +0 -0
  138. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_authority.py +0 -0
  139. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_control.py +0 -0
  140. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_diagnostics.py +0 -0
  141. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_events.py +0 -0
  142. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_execution.py +0 -0
  143. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_launch.py +0 -0
  144. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_observability.py +0 -0
  145. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_state.py +0 -0
  146. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/run_timeline.py +0 -0
  147. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/runtime_image.py +0 -0
  148. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/runtime_intent.py +0 -0
  149. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/runtime_stream.py +0 -0
  150. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/runtime_stream_snapshot.py +0 -0
  151. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/scientific_integrity.py +0 -0
  152. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_actor_models.py +0 -0
  153. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_actor_policy_data.py +0 -0
  154. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_agent_harnesses.py +0 -0
  155. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_agent_kinds.py +0 -0
  156. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_agent_models.py +0 -0
  157. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_branching.py +0 -0
  158. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_credential_providers.py +0 -0
  159. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_environment_kinds.py +0 -0
  160. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_evidence_obligations.py +0 -0
  161. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_funding_sources.py +0 -0
  162. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_horizons.py +0 -0
  163. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_host_kinds.py +0 -0
  164. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_inference_providers.py +0 -0
  165. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_network_topology.py +0 -0
  166. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_providers.py +0 -0
  167. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_resource_kinds.py +0 -0
  168. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_roles.py +0 -0
  169. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_run_policy.py +0 -0
  170. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_runbooks.py +0 -0
  171. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_runnable_project.py +0 -0
  172. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_runtime_kinds.py +0 -0
  173. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_tool_providers.py +0 -0
  174. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/smr_work_modes.py +0 -0
  175. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/status.py +0 -0
  176. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/swarms.py +0 -0
  177. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/tag.py +0 -0
  178. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/traces.py +0 -0
  179. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/transcript.py +0 -0
  180. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/types.py +0 -0
  181. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/usage.py +0 -0
  182. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/visuals.py +0 -0
  183. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/wire_models.py +0 -0
  184. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/wire_models_README.md +0 -0
  185. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/work_products.py +0 -0
  186. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/contracts/workspaces.py +0 -0
  187. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/economics.py +0 -0
  188. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/efforts.py +0 -0
  189. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/environments.py +0 -0
  190. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/errors.py +0 -0
  191. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/events.py +0 -0
  192. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/experiments.py +0 -0
  193. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/facade.py +0 -0
  194. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/factories.py +0 -0
  195. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/factory_storage.py +0 -0
  196. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/image_releases.py +0 -0
  197. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/intern_program.py +0 -0
  198. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/knowledge.py +0 -0
  199. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/models.py +0 -0
  200. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/operations.py +0 -0
  201. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/project_data.py +0 -0
  202. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/project_deliveries.py +0 -0
  203. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/project_workspaces.py +0 -0
  204. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/projects.py +0 -0
  205. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/public.py +0 -0
  206. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/readouts.py +0 -0
  207. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/research_intern.py +0 -0
  208. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/secrets.py +0 -0
  209. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/README.md +0 -0
  210. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/__init__.py +0 -0
  211. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/_base.py +0 -0
  212. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/_client_helpers.py +0 -0
  213. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/_run_authority_mixin.py +0 -0
  214. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/approvals.py +0 -0
  215. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/billing.py +0 -0
  216. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/client.py +0 -0
  217. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/cloud_deployments.py +0 -0
  218. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/config.py +0 -0
  219. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/cost.py +0 -0
  220. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/datasets.py +0 -0
  221. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/dev_environments.py +0 -0
  222. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/environments.py +0 -0
  223. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/exports.py +0 -0
  224. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/factories.py +0 -0
  225. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/factory_evidence.py +0 -0
  226. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/files.py +0 -0
  227. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/github.py +0 -0
  228. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/image_releases.py +0 -0
  229. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/images.py +0 -0
  230. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/logs.py +0 -0
  231. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/models.py +0 -0
  232. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/outputs.py +0 -0
  233. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/progress.py +0 -0
  234. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/project.py +0 -0
  235. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/projects.py +0 -0
  236. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/prs.py +0 -0
  237. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/readiness.py +0 -0
  238. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/repositories.py +0 -0
  239. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/runs.py +0 -0
  240. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/secrets.py +0 -0
  241. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/setup.py +0 -0
  242. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/tag.py +0 -0
  243. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/trained_models.py +0 -0
  244. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/transport.py +0 -0
  245. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/usage.py +0 -0
  246. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/work_products.py +0 -0
  247. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/session/workspace_inputs.py +0 -0
  248. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/swarms.py +0 -0
  249. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/traces.py +0 -0
  250. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/transport/__init__.py +0 -0
  251. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/transport/http.py +0 -0
  252. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/transport/pagination.py +0 -0
  253. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/version.py +0 -0
  254. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/visuals.py +0 -0
  255. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai/sdk/research/wiki.py +0 -0
  256. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai.egg-info/dependency_links.txt +0 -0
  257. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai.egg-info/entry_points.txt +0 -0
  258. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai.egg-info/requires.txt +0 -0
  259. {synth_ai-0.18.2.dev614 → synth_ai-0.18.2.dev615}/synth_ai.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.18.2.dev614
3
+ Version: 0.18.2.dev615
4
4
  Summary: Python SDK and CLI for Synth Managed Research and Research Factory
5
5
  Author-email: Synth AI <josh@usesynth.ai>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "synth-ai"
3
- version = "0.18.2.dev614"
3
+ version = "0.18.2.dev615"
4
4
  description = "Python SDK and CLI for Synth Managed Research and Research Factory"
5
5
  authors = [{name = "Synth AI", email = "josh@usesynth.ai"}]
6
6
  license = "MIT"
@@ -39,6 +39,7 @@ except _PackageNotFoundError:
39
39
  __all__ = [
40
40
  "AsyncResearchInternReactiveSession",
41
41
  "AsyncSynthClient",
42
+ "AsyncOptimizersClient",
42
43
  "DataBindingCreateRequest",
43
44
  "DatasetRevisionCreateRequest",
44
45
  "DatasetRevisionFinalizeRequest",
@@ -99,9 +100,30 @@ __all__ = [
99
100
  "ResearchVisualPromotionRequest",
100
101
  "ResearchVisualVersions",
101
102
  "SynthClient",
103
+ "OptimizersClient",
104
+ "OptimizerRunOutputs",
105
+ "SavedLoraCheckpoint",
106
+ "SavedLoraCheckpointPage",
107
+ "SavedLoraLineage",
108
+ "SavedLoraRunPage",
109
+ "HostedTrainingModelCatalog",
102
110
  ]
103
111
 
104
112
  _EXPORTS: dict[str, tuple[str, str]] = {
113
+ "AsyncOptimizersClient": ("synth_ai.sdk.optimizers", "AsyncOptimizersClient"),
114
+ "HostedTrainingModelCatalog": (
115
+ "synth_ai.sdk.optimizers",
116
+ "HostedTrainingModelCatalog",
117
+ ),
118
+ "OptimizersClient": ("synth_ai.sdk.optimizers", "OptimizersClient"),
119
+ "OptimizerRunOutputs": ("synth_ai.sdk.optimizers", "OptimizerRunOutputs"),
120
+ "SavedLoraCheckpoint": ("synth_ai.sdk.optimizers", "SavedLoraCheckpoint"),
121
+ "SavedLoraCheckpointPage": (
122
+ "synth_ai.sdk.optimizers",
123
+ "SavedLoraCheckpointPage",
124
+ ),
125
+ "SavedLoraLineage": ("synth_ai.sdk.optimizers", "SavedLoraLineage"),
126
+ "SavedLoraRunPage": ("synth_ai.sdk.optimizers", "SavedLoraRunPage"),
105
127
  "AsyncResearchInternReactiveSession": (
106
128
  "synth_ai.sdk.research.research_intern",
107
129
  "AsyncResearchInternReactiveSession",
@@ -9,6 +9,7 @@ from synth_ai.core.auth.credentials import resolve_api_credential
9
9
  from synth_ai.core.utils.urls import BACKEND_URL_BASE, normalize_backend_base
10
10
 
11
11
  if TYPE_CHECKING:
12
+ from synth_ai.sdk.optimizers import AsyncOptimizersClient, OptimizersClient
12
13
  from synth_ai.sdk.research import AsyncResearchClient
13
14
  from synth_ai.sdk.research.facade import ResearchClient
14
15
 
@@ -22,10 +23,10 @@ def _resolve_base_url(base_url: str | None) -> str:
22
23
 
23
24
 
24
25
  class SynthClient:
25
- """Sync client for Managed Research.
26
+ """Sync client for Managed Research and hosted optimizers.
26
27
 
27
28
  Use ``research`` for hosted projects, swarms, and Factory lifecycles. That
28
- is the whole client: there is no container, tunnel, or pool namespace.
29
+ Use ``optimizers`` for hosted training model discovery and saved LoRAs.
29
30
  """
30
31
 
31
32
  def __init__(
@@ -41,6 +42,7 @@ class SynthClient:
41
42
  self.timeout_seconds = timeout_seconds
42
43
  self.allow_legacy_intern_sessions = allow_legacy_intern_sessions
43
44
  self._research_client: ResearchClient | None = None
45
+ self._optimizers_client: OptimizersClient | None = None
44
46
 
45
47
  @property
46
48
  def research(self) -> ResearchClient:
@@ -61,6 +63,22 @@ class SynthClient:
61
63
  if self._research_client is not None:
62
64
  self._research_client.close()
63
65
  self._research_client = None
66
+ if self._optimizers_client is not None:
67
+ self._optimizers_client.close()
68
+ self._optimizers_client = None
69
+
70
+ @property
71
+ def optimizers(self) -> OptimizersClient:
72
+ """Hosted training models and searchable saved-LoRA lineage."""
73
+ if self._optimizers_client is None:
74
+ from synth_ai.sdk.optimizers import OptimizersClient
75
+
76
+ self._optimizers_client = OptimizersClient(
77
+ api_key=self.api_key,
78
+ base_url=self.base_url,
79
+ timeout_seconds=self.timeout_seconds,
80
+ )
81
+ return self._optimizers_client
64
82
 
65
83
  def __enter__(self) -> SynthClient:
66
84
  return self
@@ -70,7 +88,7 @@ class SynthClient:
70
88
 
71
89
 
72
90
  class AsyncSynthClient:
73
- """Async client for Managed Research."""
91
+ """Async client for Managed Research and hosted optimizers."""
74
92
 
75
93
  def __init__(
76
94
  self,
@@ -85,6 +103,7 @@ class AsyncSynthClient:
85
103
  self.timeout_seconds = timeout_seconds
86
104
  self.allow_legacy_intern_sessions = allow_legacy_intern_sessions
87
105
  self._async_research_client: AsyncResearchClient | None = None
106
+ self._async_optimizers_client: AsyncOptimizersClient | None = None
88
107
 
89
108
  @property
90
109
  def research(self) -> AsyncResearchClient:
@@ -115,6 +134,22 @@ class AsyncSynthClient:
115
134
  if self._async_research_client is not None:
116
135
  await self._async_research_client.close()
117
136
  self._async_research_client = None
137
+ if self._async_optimizers_client is not None:
138
+ await self._async_optimizers_client.close()
139
+ self._async_optimizers_client = None
140
+
141
+ @property
142
+ def optimizers(self) -> AsyncOptimizersClient:
143
+ """Native asynchronous hosted optimizer namespace."""
144
+ if self._async_optimizers_client is None:
145
+ from synth_ai.sdk.optimizers import AsyncOptimizersClient
146
+
147
+ self._async_optimizers_client = AsyncOptimizersClient(
148
+ api_key=self.api_key,
149
+ base_url=self.base_url,
150
+ timeout_seconds=self.timeout_seconds,
151
+ )
152
+ return self._async_optimizers_client
118
153
 
119
154
  async def __aenter__(self) -> AsyncSynthClient:
120
155
  return self
@@ -0,0 +1,30 @@
1
+ """Public hosted optimizer SDK namespace."""
2
+
3
+ from synth_ai.sdk.optimizers.client import AsyncOptimizersClient, OptimizersClient
4
+ from synth_ai.sdk.optimizers.contracts import (
5
+ HostedTrainingModel,
6
+ HostedTrainingModelCatalog,
7
+ OptimizerRunArtifact,
8
+ OptimizerRunIdentity,
9
+ OptimizerRunOutputs,
10
+ SavedLoraCheckpoint,
11
+ SavedLoraCheckpointPage,
12
+ SavedLoraLineage,
13
+ SavedLoraRunPage,
14
+ SavedLoraStorage,
15
+ )
16
+
17
+ __all__ = [
18
+ "AsyncOptimizersClient",
19
+ "HostedTrainingModel",
20
+ "HostedTrainingModelCatalog",
21
+ "OptimizerRunIdentity",
22
+ "OptimizerRunArtifact",
23
+ "OptimizerRunOutputs",
24
+ "OptimizersClient",
25
+ "SavedLoraCheckpoint",
26
+ "SavedLoraCheckpointPage",
27
+ "SavedLoraLineage",
28
+ "SavedLoraRunPage",
29
+ "SavedLoraStorage",
30
+ ]
@@ -0,0 +1,291 @@
1
+ """Public sync and async clients for hosted optimizers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+ from typing import Any
7
+ from urllib.parse import quote
8
+
9
+ from synth_ai.core.auth.credentials import resolve_api_credential
10
+ from synth_ai.core.contracts.json_value import JsonObject, JsonValue
11
+ from synth_ai.core.http.async_transport import AsyncHttpTransport
12
+ from synth_ai.core.http.transport import HttpTransport
13
+ from synth_ai.core.utils.urls import BACKEND_URL_BASE, normalize_backend_base
14
+ from synth_ai.sdk.optimizers.contracts import (
15
+ HostedTrainingModelCatalog,
16
+ OptimizerRunOutputs,
17
+ SavedLoraCheckpoint,
18
+ SavedLoraCheckpointPage,
19
+ SavedLoraRunPage,
20
+ )
21
+
22
+
23
+ def _object(payload: JsonValue) -> JsonObject:
24
+ if not isinstance(payload, dict):
25
+ raise ValueError("optimizer API response must be an object")
26
+ return payload
27
+
28
+
29
+ def _params(**values: Any) -> dict[str, JsonValue]:
30
+ return {key: value for key, value in values.items() if value is not None and value != ""}
31
+
32
+
33
+ class CheckpointsAPI:
34
+ """List automatically persisted checkpoints and traverse their lineage."""
35
+
36
+ def __init__(self, transport: HttpTransport) -> None:
37
+ self._transport = transport
38
+
39
+ def list(
40
+ self,
41
+ *,
42
+ query: str | None = None,
43
+ scope: str = "all",
44
+ optimizer_algorithm: str | None = None,
45
+ run_id: str | None = None,
46
+ attempt_id: str | None = None,
47
+ source_checkpoint_id: str | None = None,
48
+ provider: str | None = None,
49
+ checkpoint_kind: str | None = None,
50
+ base_model: str | None = None,
51
+ status: str | None = "ready",
52
+ tags: Sequence[str] | None = None,
53
+ limit: int = 50,
54
+ offset: int = 0,
55
+ ) -> SavedLoraCheckpointPage:
56
+ payload = self._transport.request_json(
57
+ "GET",
58
+ "/api/v1/optimizers/checkpoints",
59
+ params=_params(
60
+ q=query,
61
+ scope=scope,
62
+ optimizer_algorithm=optimizer_algorithm,
63
+ run_id=run_id,
64
+ attempt_id=attempt_id,
65
+ source_checkpoint_id=source_checkpoint_id,
66
+ provider=provider,
67
+ checkpoint_kind=checkpoint_kind,
68
+ base_model=base_model,
69
+ status=status,
70
+ tags=tags,
71
+ limit=max(1, min(100, limit)),
72
+ offset=max(0, offset),
73
+ ),
74
+ operation_id="optimizers.checkpoints.list",
75
+ )
76
+ return SavedLoraCheckpointPage.model_validate(_object(payload))
77
+
78
+ def get(self, checkpoint_id: str) -> SavedLoraCheckpoint:
79
+ payload = self._transport.request_json(
80
+ "GET",
81
+ f"/api/v1/optimizers/checkpoints/{quote(checkpoint_id, safe='')}",
82
+ operation_id="optimizers.checkpoints.get",
83
+ )
84
+ return SavedLoraCheckpoint.model_validate(_object(payload))
85
+
86
+ def list_for_run(
87
+ self,
88
+ run_id: str,
89
+ *,
90
+ checkpoint_kind: str | None = None,
91
+ status: str | None = "ready",
92
+ limit: int = 100,
93
+ offset: int = 0,
94
+ ) -> SavedLoraRunPage:
95
+ payload = self._transport.request_json(
96
+ "GET",
97
+ f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/saved-checkpoints",
98
+ params=_params(
99
+ checkpoint_kind=checkpoint_kind,
100
+ status=status,
101
+ limit=max(1, min(100, limit)),
102
+ offset=max(0, offset),
103
+ ),
104
+ operation_id="optimizers.checkpoints.list_for_run",
105
+ )
106
+ return SavedLoraRunPage.model_validate(_object(payload))
107
+
108
+
109
+ class ModelsAPI:
110
+ """Discover models and algorithm support available for hosted training."""
111
+
112
+ def __init__(self, transport: HttpTransport) -> None:
113
+ self._transport = transport
114
+
115
+ def list(
116
+ self, *, algorithm: str | None = None, provider: str | None = None
117
+ ) -> HostedTrainingModelCatalog:
118
+ payload = self._transport.request_json(
119
+ "GET",
120
+ "/api/v1/optimizers/models/training",
121
+ params=_params(algorithm=algorithm, provider=provider),
122
+ operation_id="optimizers.models.list",
123
+ )
124
+ return HostedTrainingModelCatalog.model_validate(_object(payload))
125
+
126
+
127
+ class RunsAPI:
128
+ """Inspect automatically persisted outputs for hosted optimizer runs."""
129
+
130
+ def __init__(self, transport: HttpTransport) -> None:
131
+ self._transport = transport
132
+
133
+ def outputs(self, run_id: str) -> OptimizerRunOutputs:
134
+ payload = self._transport.request_json(
135
+ "GET",
136
+ f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/outputs",
137
+ operation_id="optimizers.runs.outputs",
138
+ )
139
+ return OptimizerRunOutputs.model_validate(_object(payload))
140
+
141
+
142
+ class AsyncCheckpointsAPI:
143
+ def __init__(self, transport: AsyncHttpTransport) -> None:
144
+ self._transport = transport
145
+
146
+ async def list(
147
+ self,
148
+ *,
149
+ query: str | None = None,
150
+ scope: str = "all",
151
+ optimizer_algorithm: str | None = None,
152
+ run_id: str | None = None,
153
+ attempt_id: str | None = None,
154
+ source_checkpoint_id: str | None = None,
155
+ provider: str | None = None,
156
+ checkpoint_kind: str | None = None,
157
+ base_model: str | None = None,
158
+ status: str | None = "ready",
159
+ tags: Sequence[str] | None = None,
160
+ limit: int = 50,
161
+ offset: int = 0,
162
+ ) -> SavedLoraCheckpointPage:
163
+ payload = await self._transport.request_json(
164
+ "GET",
165
+ "/api/v1/optimizers/checkpoints",
166
+ params=_params(
167
+ q=query,
168
+ scope=scope,
169
+ optimizer_algorithm=optimizer_algorithm,
170
+ run_id=run_id,
171
+ attempt_id=attempt_id,
172
+ source_checkpoint_id=source_checkpoint_id,
173
+ provider=provider,
174
+ checkpoint_kind=checkpoint_kind,
175
+ base_model=base_model,
176
+ status=status,
177
+ tags=tags,
178
+ limit=max(1, min(100, limit)),
179
+ offset=max(0, offset),
180
+ ),
181
+ operation_id="optimizers.checkpoints.list",
182
+ )
183
+ return SavedLoraCheckpointPage.model_validate(_object(payload))
184
+
185
+ async def get(self, checkpoint_id: str) -> SavedLoraCheckpoint:
186
+ payload = await self._transport.request_json(
187
+ "GET",
188
+ f"/api/v1/optimizers/checkpoints/{quote(checkpoint_id, safe='')}",
189
+ operation_id="optimizers.checkpoints.get",
190
+ )
191
+ return SavedLoraCheckpoint.model_validate(_object(payload))
192
+
193
+ async def list_for_run(
194
+ self,
195
+ run_id: str,
196
+ *,
197
+ checkpoint_kind: str | None = None,
198
+ status: str | None = "ready",
199
+ limit: int = 100,
200
+ offset: int = 0,
201
+ ) -> SavedLoraRunPage:
202
+ payload = await self._transport.request_json(
203
+ "GET",
204
+ f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/saved-checkpoints",
205
+ params=_params(
206
+ checkpoint_kind=checkpoint_kind,
207
+ status=status,
208
+ limit=max(1, min(100, limit)),
209
+ offset=max(0, offset),
210
+ ),
211
+ operation_id="optimizers.checkpoints.list_for_run",
212
+ )
213
+ return SavedLoraRunPage.model_validate(_object(payload))
214
+
215
+
216
+ class AsyncModelsAPI:
217
+ def __init__(self, transport: AsyncHttpTransport) -> None:
218
+ self._transport = transport
219
+
220
+ async def list(self, **filters: Any) -> HostedTrainingModelCatalog:
221
+ payload = await self._transport.request_json(
222
+ "GET",
223
+ "/api/v1/optimizers/models/training",
224
+ params=_params(**filters),
225
+ operation_id="optimizers.models.list",
226
+ )
227
+ return HostedTrainingModelCatalog.model_validate(_object(payload))
228
+
229
+
230
+ class AsyncRunsAPI:
231
+ def __init__(self, transport: AsyncHttpTransport) -> None:
232
+ self._transport = transport
233
+
234
+ async def outputs(self, run_id: str) -> OptimizerRunOutputs:
235
+ payload = await self._transport.request_json(
236
+ "GET",
237
+ f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/outputs",
238
+ operation_id="optimizers.runs.outputs",
239
+ )
240
+ return OptimizerRunOutputs.model_validate(_object(payload))
241
+
242
+
243
+ class OptimizersClient:
244
+ """Hosted optimizer namespace mounted at ``SynthClient.optimizers``."""
245
+
246
+ def __init__(
247
+ self,
248
+ *,
249
+ api_key: str | None = None,
250
+ base_url: str | None = None,
251
+ timeout_seconds: float = 30.0,
252
+ ) -> None:
253
+ credential = resolve_api_credential(api_key)
254
+ self._transport = HttpTransport(
255
+ base_url=normalize_backend_base(base_url or BACKEND_URL_BASE),
256
+ headers=credential.authorization_headers(),
257
+ timeout_seconds=timeout_seconds,
258
+ )
259
+ self.checkpoints = CheckpointsAPI(self._transport)
260
+ self.models = ModelsAPI(self._transport)
261
+ self.runs = RunsAPI(self._transport)
262
+
263
+ def close(self) -> None:
264
+ self._transport.close()
265
+
266
+
267
+ class AsyncOptimizersClient:
268
+ """Native asynchronous hosted optimizer namespace."""
269
+
270
+ def __init__(
271
+ self,
272
+ *,
273
+ api_key: str | None = None,
274
+ base_url: str | None = None,
275
+ timeout_seconds: float = 30.0,
276
+ ) -> None:
277
+ credential = resolve_api_credential(api_key)
278
+ self._transport = AsyncHttpTransport(
279
+ base_url=normalize_backend_base(base_url or BACKEND_URL_BASE),
280
+ headers=credential.authorization_headers(),
281
+ timeout_seconds=timeout_seconds,
282
+ )
283
+ self.checkpoints = AsyncCheckpointsAPI(self._transport)
284
+ self.models = AsyncModelsAPI(self._transport)
285
+ self.runs = AsyncRunsAPI(self._transport)
286
+
287
+ async def close(self) -> None:
288
+ await self._transport.close()
289
+
290
+
291
+ __all__ = ["AsyncOptimizersClient", "OptimizersClient"]
@@ -0,0 +1,142 @@
1
+ """Typed public contracts for hosted optimizer model discovery and lineage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+
10
+ class OptimizerContract(BaseModel):
11
+ """Forward-compatible base for optimizer API payloads."""
12
+
13
+ model_config = ConfigDict(extra="allow")
14
+
15
+
16
+ class SavedLoraStorage(OptimizerContract):
17
+ backend: str
18
+ bucket: str
19
+ key: str
20
+ version: str | None = None
21
+ etag: str | None = None
22
+ sha256: str | None = None
23
+ size_bytes: int | None = None
24
+ content_type: str
25
+
26
+
27
+ class SavedLoraLineage(OptimizerContract):
28
+ optimizer_algorithm: str | None = None
29
+ run_id: str | None = None
30
+ attempt_id: str | None = None
31
+ source_checkpoint_id: str | None = None
32
+ provider_checkpoint_reference: str | None = None
33
+
34
+
35
+ class SavedLoraCheckpoint(OptimizerContract):
36
+ schema_version: str = "saved_lora_checkpoint.v1"
37
+ checkpoint_id: str
38
+ org_id: str
39
+ owner_user_id: str | None = None
40
+ visibility: str
41
+ name: str
42
+ description: str = ""
43
+ provider: str
44
+ checkpoint_kind: str
45
+ provider_checkpoint_reference: str | None = None
46
+ optimizer_algorithm: str | None = None
47
+ run_id: str | None = None
48
+ attempt_id: str | None = None
49
+ source_checkpoint_id: str | None = None
50
+ base_model: str
51
+ lora_rank: int | None = None
52
+ step: int | None = None
53
+ status: str
54
+ storage: SavedLoraStorage
55
+ lineage: SavedLoraLineage = Field(default_factory=SavedLoraLineage)
56
+ tags: list[str] = Field(default_factory=list)
57
+ metadata: dict[str, Any] = Field(default_factory=dict)
58
+ created_at: str | None = None
59
+ updated_at: str | None = None
60
+ archived_at: str | None = None
61
+
62
+
63
+ class SavedLoraCheckpointPage(OptimizerContract):
64
+ items: list[SavedLoraCheckpoint]
65
+ total: int
66
+ limit: int
67
+ offset: int
68
+
69
+
70
+ class OptimizerRunIdentity(OptimizerContract):
71
+ run_id: str
72
+ attempt_id: str | None = None
73
+ optimizer_algorithm: str
74
+ status: str
75
+
76
+
77
+ class OptimizerRunArtifact(OptimizerContract):
78
+ artifact_id: str
79
+ run_id: str
80
+ artifact_name: str
81
+ content_type: str | None = None
82
+ size_bytes: int
83
+ sha256: str | None = None
84
+ storage_backend: str
85
+ uri: str
86
+ download_path: str
87
+ metadata: dict[str, Any] = Field(default_factory=dict)
88
+ created_at: str | None = None
89
+ updated_at: str | None = None
90
+
91
+
92
+ class OptimizerRunOutputs(OptimizerContract):
93
+ """All automatically persisted outputs for one optimizer run."""
94
+
95
+ schema_version: str = "optimizer.run_outputs.v1"
96
+ run: OptimizerRunIdentity
97
+ result: dict[str, Any] | None = None
98
+ artifacts: list[OptimizerRunArtifact]
99
+ model_checkpoints: list[SavedLoraCheckpoint]
100
+ counts: dict[str, int]
101
+
102
+
103
+ class SavedLoraRunPage(OptimizerContract):
104
+ schema_version: str = "saved_lora_checkpoint.run_page.v1"
105
+ run: OptimizerRunIdentity
106
+ items: list[SavedLoraCheckpoint]
107
+ counts: dict[str, int]
108
+ total: int
109
+ limit: int
110
+ offset: int
111
+
112
+
113
+ class HostedTrainingModel(OptimizerContract):
114
+ model_id: str
115
+ label: str
116
+ provider: str
117
+ provider_revision: str
118
+ architecture: str
119
+ max_context_length: int
120
+ rank: dict[str, int]
121
+ algorithms: dict[str, dict[str, Any]]
122
+
123
+
124
+ class HostedTrainingModelCatalog(OptimizerContract):
125
+ catalog_revision: str
126
+ live_preflight_required: bool
127
+ models: list[HostedTrainingModel]
128
+ total: int
129
+
130
+
131
+ __all__ = [
132
+ "HostedTrainingModel",
133
+ "HostedTrainingModelCatalog",
134
+ "OptimizerRunIdentity",
135
+ "OptimizerRunArtifact",
136
+ "OptimizerRunOutputs",
137
+ "SavedLoraCheckpoint",
138
+ "SavedLoraCheckpointPage",
139
+ "SavedLoraLineage",
140
+ "SavedLoraRunPage",
141
+ "SavedLoraStorage",
142
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.18.2.dev614
3
+ Version: 0.18.2.dev615
4
4
  Summary: Python SDK and CLI for Synth Managed Research and Research Factory
5
5
  Author-email: Synth AI <josh@usesynth.ai>
6
6
  License-Expression: MIT
@@ -81,6 +81,9 @@ synth_ai/mcp/research/tools/workspace_inputs.py
81
81
  synth_ai/sdk/README.md
82
82
  synth_ai/sdk/__init__.py
83
83
  synth_ai/sdk/pagination.py
84
+ synth_ai/sdk/optimizers/__init__.py
85
+ synth_ai/sdk/optimizers/client.py
86
+ synth_ai/sdk/optimizers/contracts.py
84
87
  synth_ai/sdk/research/__init__.py
85
88
  synth_ai/sdk/research/account.py
86
89
  synth_ai/sdk/research/advanced.py