synth-ai 0.18.2.dev615__tar.gz → 0.18.2.dev617__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 (260) hide show
  1. {synth_ai-0.18.2.dev615/synth_ai.egg-info → synth_ai-0.18.2.dev617}/PKG-INFO +2 -4
  2. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/README.md +1 -3
  3. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/pyproject.toml +1 -1
  4. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/research_intern.py +5 -0
  5. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/optimizers/client.py +18 -0
  6. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/__init__.py +12 -0
  7. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/research_intern.py +67 -0
  8. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_launch.py +15 -1
  9. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/traces.py +48 -1
  10. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/errors.py +65 -0
  11. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/operations.py +335 -4
  12. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/public.py +34 -0
  13. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/research_intern.py +184 -0
  14. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/_client_helpers.py +55 -0
  15. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/client.py +32 -55
  16. synth_ai-0.18.2.dev617/synth_ai/sdk/research/surface_parity.py +189 -0
  17. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/traces.py +47 -0
  18. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/transport/http.py +15 -0
  19. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617/synth_ai.egg-info}/PKG-INFO +2 -4
  20. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai.egg-info/SOURCES.txt +1 -0
  21. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/LICENSE +0 -0
  22. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/MANIFEST.in +0 -0
  23. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/setup.cfg +0 -0
  24. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/README.md +0 -0
  25. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/__init__.py +0 -0
  26. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/__main__.py +0 -0
  27. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/AGENTS.md +0 -0
  28. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/README.md +0 -0
  29. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/__init__.py +0 -0
  30. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/__main__.py +0 -0
  31. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/main.py +0 -0
  32. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/research.py +0 -0
  33. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/research_environments.py +0 -0
  34. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/research_image_releases.py +0 -0
  35. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/cli/research_projects.py +0 -0
  36. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/client.py +0 -0
  37. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/README.md +0 -0
  38. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/__init__.py +0 -0
  39. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/auth/__init__.py +0 -0
  40. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/auth/credentials.py +0 -0
  41. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/contracts/__init__.py +0 -0
  42. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/contracts/json_value.py +0 -0
  43. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/contracts/pagination.py +0 -0
  44. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/errors.py +0 -0
  45. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/__init__.py +0 -0
  46. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/async_transport.py +0 -0
  47. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/request.py +0 -0
  48. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/retry.py +0 -0
  49. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/streaming.py +0 -0
  50. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/http/transport.py +0 -0
  51. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/research/__init__.py +0 -0
  52. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/utils/__init__.py +0 -0
  53. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/utils/env.py +0 -0
  54. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/utils/log_filter.py +0 -0
  55. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/utils/paths.py +0 -0
  56. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/core/utils/urls.py +0 -0
  57. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/README.md +0 -0
  58. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/__init__.py +0 -0
  59. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/__main__.py +0 -0
  60. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/objective_tools.py +0 -0
  61. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/registry.py +0 -0
  62. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/request_models.py +0 -0
  63. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/server.py +0 -0
  64. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/__init__.py +0 -0
  65. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/approvals.py +0 -0
  66. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/artifacts.py +0 -0
  67. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/datasets.py +0 -0
  68. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/environments.py +0 -0
  69. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/exports.py +0 -0
  70. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/factories.py +0 -0
  71. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/factory_results.py +0 -0
  72. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/files.py +0 -0
  73. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/image_releases.py +0 -0
  74. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/integrations.py +0 -0
  75. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/intern_program.py +0 -0
  76. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/logs.py +0 -0
  77. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/models.py +0 -0
  78. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/outputs.py +0 -0
  79. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/policy_schemas.py +0 -0
  80. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/progress.py +0 -0
  81. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/project_data.py +0 -0
  82. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/projects.py +0 -0
  83. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/prs.py +0 -0
  84. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/readiness.py +0 -0
  85. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/repos.py +0 -0
  86. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/resources.py +0 -0
  87. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/runs.py +0 -0
  88. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/trained_models.py +0 -0
  89. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/usage.py +0 -0
  90. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/visuals.py +0 -0
  91. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/mcp/research/tools/workspace_inputs.py +0 -0
  92. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/py.typed +0 -0
  93. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/README.md +0 -0
  94. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/__init__.py +0 -0
  95. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/optimizers/__init__.py +0 -0
  96. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/optimizers/contracts.py +0 -0
  97. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/pagination.py +0 -0
  98. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/__init__.py +0 -0
  99. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/_internal/__init__.py +0 -0
  100. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/_internal/crypto.py +0 -0
  101. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/_internal/env.py +0 -0
  102. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/_internal/urls.py +0 -0
  103. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/account.py +0 -0
  104. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/advanced.py +0 -0
  105. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/advanced_factories.py +0 -0
  106. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/advanced_swarms.py +0 -0
  107. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/artifacts.py +0 -0
  108. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/auth.py +0 -0
  109. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/client.py +0 -0
  110. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/_activity_wire.py +0 -0
  111. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/_environment_wire.py +0 -0
  112. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/_transcript_wire.py +0 -0
  113. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/_wire.py +0 -0
  114. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/activity.py +0 -0
  115. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/activity_items.py +0 -0
  116. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/actor_images.py +0 -0
  117. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/billing.py +0 -0
  118. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/canonical_usage.py +0 -0
  119. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/checkpoints.py +0 -0
  120. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/cloud_deployment_claims.py +0 -0
  121. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/cloud_deployments.py +0 -0
  122. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/common.py +0 -0
  123. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/dataset_revisions.py +0 -0
  124. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/deliveries.py +0 -0
  125. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/dev_environment_evidence.py +0 -0
  126. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/economics.py +0 -0
  127. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/environment_manifest.py +0 -0
  128. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/environments.py +0 -0
  129. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/evidence.py +0 -0
  130. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/factories.py +0 -0
  131. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/factory_evidence.py +0 -0
  132. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/factory_lenses.py +0 -0
  133. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/factory_operations.py +0 -0
  134. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/factory_role_receipts.py +0 -0
  135. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/failure.py +0 -0
  136. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/image_releases.py +0 -0
  137. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/intern_grants.py +0 -0
  138. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/intern_program.py +0 -0
  139. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/limit_evidence.py +0 -0
  140. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/local_execution_profile.py +0 -0
  141. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/operator_evidence.py +0 -0
  142. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/project.py +0 -0
  143. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/project_data.py +0 -0
  144. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/project_runtime.py +0 -0
  145. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/project_workspace.py +0 -0
  146. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/project_workspace_evidence.py +0 -0
  147. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/projects.py +0 -0
  148. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/promotions.py +0 -0
  149. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_authority.py +0 -0
  150. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_control.py +0 -0
  151. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_diagnostics.py +0 -0
  152. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_events.py +0 -0
  153. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_execution.py +0 -0
  154. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_observability.py +0 -0
  155. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_state.py +0 -0
  156. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/run_timeline.py +0 -0
  157. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/runtime_image.py +0 -0
  158. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/runtime_intent.py +0 -0
  159. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/runtime_stream.py +0 -0
  160. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/runtime_stream_snapshot.py +0 -0
  161. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/scientific_integrity.py +0 -0
  162. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_actor_models.py +0 -0
  163. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_actor_policy_data.py +0 -0
  164. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_agent_harnesses.py +0 -0
  165. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_agent_kinds.py +0 -0
  166. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_agent_models.py +0 -0
  167. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_branching.py +0 -0
  168. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_credential_providers.py +0 -0
  169. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_environment_kinds.py +0 -0
  170. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_evidence_obligations.py +0 -0
  171. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_funding_sources.py +0 -0
  172. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_horizons.py +0 -0
  173. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_host_kinds.py +0 -0
  174. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_inference_providers.py +0 -0
  175. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_network_topology.py +0 -0
  176. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_providers.py +0 -0
  177. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_resource_kinds.py +0 -0
  178. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_roles.py +0 -0
  179. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_run_policy.py +0 -0
  180. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_runbooks.py +0 -0
  181. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_runnable_project.py +0 -0
  182. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_runtime_kinds.py +0 -0
  183. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_tool_providers.py +0 -0
  184. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/smr_work_modes.py +0 -0
  185. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/status.py +0 -0
  186. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/swarms.py +0 -0
  187. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/tag.py +0 -0
  188. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/transcript.py +0 -0
  189. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/types.py +0 -0
  190. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/usage.py +0 -0
  191. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/visuals.py +0 -0
  192. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/wire_models.py +0 -0
  193. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/wire_models_README.md +0 -0
  194. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/work_products.py +0 -0
  195. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/contracts/workspaces.py +0 -0
  196. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/economics.py +0 -0
  197. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/efforts.py +0 -0
  198. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/environments.py +0 -0
  199. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/events.py +0 -0
  200. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/experiments.py +0 -0
  201. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/facade.py +0 -0
  202. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/factories.py +0 -0
  203. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/factory_storage.py +0 -0
  204. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/image_releases.py +0 -0
  205. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/intern_program.py +0 -0
  206. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/knowledge.py +0 -0
  207. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/models.py +0 -0
  208. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/project_data.py +0 -0
  209. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/project_deliveries.py +0 -0
  210. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/project_workspaces.py +0 -0
  211. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/projects.py +0 -0
  212. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/readouts.py +0 -0
  213. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/secrets.py +0 -0
  214. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/README.md +0 -0
  215. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/__init__.py +0 -0
  216. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/_base.py +0 -0
  217. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/_run_authority_mixin.py +0 -0
  218. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/approvals.py +0 -0
  219. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/billing.py +0 -0
  220. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/cloud_deployments.py +0 -0
  221. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/config.py +0 -0
  222. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/cost.py +0 -0
  223. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/datasets.py +0 -0
  224. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/dev_environments.py +0 -0
  225. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/environments.py +0 -0
  226. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/exports.py +0 -0
  227. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/factories.py +0 -0
  228. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/factory_evidence.py +0 -0
  229. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/files.py +0 -0
  230. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/github.py +0 -0
  231. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/image_releases.py +0 -0
  232. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/images.py +0 -0
  233. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/logs.py +0 -0
  234. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/models.py +0 -0
  235. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/outputs.py +0 -0
  236. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/progress.py +0 -0
  237. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/project.py +0 -0
  238. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/projects.py +0 -0
  239. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/prs.py +0 -0
  240. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/readiness.py +0 -0
  241. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/repositories.py +0 -0
  242. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/runs.py +0 -0
  243. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/secrets.py +0 -0
  244. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/setup.py +0 -0
  245. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/tag.py +0 -0
  246. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/trained_models.py +0 -0
  247. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/transport.py +0 -0
  248. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/usage.py +0 -0
  249. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/work_products.py +0 -0
  250. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/session/workspace_inputs.py +0 -0
  251. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/swarms.py +0 -0
  252. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/transport/__init__.py +0 -0
  253. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/transport/pagination.py +0 -0
  254. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/version.py +0 -0
  255. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/visuals.py +0 -0
  256. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai/sdk/research/wiki.py +0 -0
  257. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai.egg-info/dependency_links.txt +0 -0
  258. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai.egg-info/entry_points.txt +0 -0
  259. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/synth_ai.egg-info/requires.txt +0 -0
  260. {synth_ai-0.18.2.dev615 → synth_ai-0.18.2.dev617}/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.dev615
3
+ Version: 0.18.2.dev617
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
@@ -145,9 +145,7 @@ from synth_ai import SynthClient
145
145
  from synth_ai.sdk.research.public import EffortSpec, FactorySpec, ProjectId
146
146
 
147
147
  with SynthClient() as client:
148
- factory = client.research.factories.create(
149
- FactorySpec(name="Prompt optimizer")
150
- )
148
+ factory = client.research.factories.create(FactorySpec(name="Prompt optimizer"))
151
149
  effort = client.research.factories.efforts.create(
152
150
  EffortSpec(
153
151
  factory_id=factory.factory_id,
@@ -118,9 +118,7 @@ from synth_ai import SynthClient
118
118
  from synth_ai.sdk.research.public import EffortSpec, FactorySpec, ProjectId
119
119
 
120
120
  with SynthClient() as client:
121
- factory = client.research.factories.create(
122
- FactorySpec(name="Prompt optimizer")
123
- )
121
+ factory = client.research.factories.create(FactorySpec(name="Prompt optimizer"))
124
122
  effort = client.research.factories.efforts.create(
125
123
  EffortSpec(
126
124
  factory_id=factory.factory_id,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "synth-ai"
3
- version = "0.18.2.dev615"
3
+ version = "0.18.2.dev617"
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"
@@ -1153,6 +1153,11 @@ def build_research_intern_tools(
1153
1153
  "type": "integer",
1154
1154
  "minimum": 0,
1155
1155
  "maximum": 60,
1156
+ "description": (
1157
+ "Bounded wait for the explicit Factory-ready "
1158
+ "condition before binding; omit to refuse "
1159
+ "immediately with a typed readiness report."
1160
+ ),
1156
1161
  },
1157
1162
  },
1158
1163
  required=["objective", "idempotency_key"],
@@ -53,6 +53,7 @@ class CheckpointsAPI:
53
53
  limit: int = 50,
54
54
  offset: int = 0,
55
55
  ) -> SavedLoraCheckpointPage:
56
+ """Search saved checkpoints with filters and a page size clamped to 1–100."""
56
57
  payload = self._transport.request_json(
57
58
  "GET",
58
59
  "/api/v1/optimizers/checkpoints",
@@ -76,6 +77,7 @@ class CheckpointsAPI:
76
77
  return SavedLoraCheckpointPage.model_validate(_object(payload))
77
78
 
78
79
  def get(self, checkpoint_id: str) -> SavedLoraCheckpoint:
80
+ """Retrieve one saved checkpoint by its URL-escaped identifier."""
79
81
  payload = self._transport.request_json(
80
82
  "GET",
81
83
  f"/api/v1/optimizers/checkpoints/{quote(checkpoint_id, safe='')}",
@@ -92,6 +94,7 @@ class CheckpointsAPI:
92
94
  limit: int = 100,
93
95
  offset: int = 0,
94
96
  ) -> SavedLoraRunPage:
97
+ """List saved checkpoints for one run with bounded pagination."""
95
98
  payload = self._transport.request_json(
96
99
  "GET",
97
100
  f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/saved-checkpoints",
@@ -115,6 +118,7 @@ class ModelsAPI:
115
118
  def list(
116
119
  self, *, algorithm: str | None = None, provider: str | None = None
117
120
  ) -> HostedTrainingModelCatalog:
121
+ """Discover hosted training models filtered by algorithm and provider."""
118
122
  payload = self._transport.request_json(
119
123
  "GET",
120
124
  "/api/v1/optimizers/models/training",
@@ -131,6 +135,7 @@ class RunsAPI:
131
135
  self._transport = transport
132
136
 
133
137
  def outputs(self, run_id: str) -> OptimizerRunOutputs:
138
+ """Retrieve the backend-owned output inventory for one optimizer run."""
134
139
  payload = self._transport.request_json(
135
140
  "GET",
136
141
  f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/outputs",
@@ -140,6 +145,8 @@ class RunsAPI:
140
145
 
141
146
 
142
147
  class AsyncCheckpointsAPI:
148
+ """Asynchronous saved-checkpoint discovery and lineage reads."""
149
+
143
150
  def __init__(self, transport: AsyncHttpTransport) -> None:
144
151
  self._transport = transport
145
152
 
@@ -160,6 +167,7 @@ class AsyncCheckpointsAPI:
160
167
  limit: int = 50,
161
168
  offset: int = 0,
162
169
  ) -> SavedLoraCheckpointPage:
170
+ """Search saved checkpoints with filters and a page size clamped to 1–100."""
163
171
  payload = await self._transport.request_json(
164
172
  "GET",
165
173
  "/api/v1/optimizers/checkpoints",
@@ -183,6 +191,7 @@ class AsyncCheckpointsAPI:
183
191
  return SavedLoraCheckpointPage.model_validate(_object(payload))
184
192
 
185
193
  async def get(self, checkpoint_id: str) -> SavedLoraCheckpoint:
194
+ """Retrieve one saved checkpoint by its URL-escaped identifier."""
186
195
  payload = await self._transport.request_json(
187
196
  "GET",
188
197
  f"/api/v1/optimizers/checkpoints/{quote(checkpoint_id, safe='')}",
@@ -199,6 +208,7 @@ class AsyncCheckpointsAPI:
199
208
  limit: int = 100,
200
209
  offset: int = 0,
201
210
  ) -> SavedLoraRunPage:
211
+ """List saved checkpoints for one run with bounded pagination."""
202
212
  payload = await self._transport.request_json(
203
213
  "GET",
204
214
  f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/saved-checkpoints",
@@ -214,10 +224,13 @@ class AsyncCheckpointsAPI:
214
224
 
215
225
 
216
226
  class AsyncModelsAPI:
227
+ """Asynchronous hosted training model discovery."""
228
+
217
229
  def __init__(self, transport: AsyncHttpTransport) -> None:
218
230
  self._transport = transport
219
231
 
220
232
  async def list(self, **filters: Any) -> HostedTrainingModelCatalog:
233
+ """Read the training model catalog using backend-supported query filters."""
221
234
  payload = await self._transport.request_json(
222
235
  "GET",
223
236
  "/api/v1/optimizers/models/training",
@@ -228,10 +241,13 @@ class AsyncModelsAPI:
228
241
 
229
242
 
230
243
  class AsyncRunsAPI:
244
+ """Asynchronous reads of persisted hosted optimizer outputs."""
245
+
231
246
  def __init__(self, transport: AsyncHttpTransport) -> None:
232
247
  self._transport = transport
233
248
 
234
249
  async def outputs(self, run_id: str) -> OptimizerRunOutputs:
250
+ """Retrieve the backend-owned output inventory for one optimizer run."""
235
251
  payload = await self._transport.request_json(
236
252
  "GET",
237
253
  f"/api/v1/optimizers/runs/{quote(run_id, safe='')}/outputs",
@@ -261,6 +277,7 @@ class OptimizersClient:
261
277
  self.runs = RunsAPI(self._transport)
262
278
 
263
279
  def close(self) -> None:
280
+ """Close the hosted optimizer HTTP transport."""
264
281
  self._transport.close()
265
282
 
266
283
 
@@ -285,6 +302,7 @@ class AsyncOptimizersClient:
285
302
  self.runs = AsyncRunsAPI(self._transport)
286
303
 
287
304
  async def close(self) -> None:
305
+ """Close the asynchronous hosted optimizer HTTP transport."""
288
306
  await self._transport.close()
289
307
 
290
308
 
@@ -322,6 +322,9 @@ from synth_ai.sdk.research.contracts.research_intern import (
322
322
  DataBindingResponse,
323
323
  DatasetRevisionCreateRequest,
324
324
  DatasetRevisionResponse,
325
+ InternAcceptanceFixtureReceipt,
326
+ InternAcceptanceFixtureRequest,
327
+ InternAcceptanceFixtureResource,
325
328
  InternAgentConfig,
326
329
  InternAsyncBlocker,
327
330
  InternAsyncCheckpoint,
@@ -517,8 +520,11 @@ from synth_ai.sdk.research.contracts.traces import (
517
520
  TraceStoreAccessReceipt,
518
521
  TraceStoreDescriptor,
519
522
  TraceStoreLifecycleReceipt,
523
+ TraceStorePreflightRequest,
524
+ TraceStorePreflightResponse,
520
525
  TraceStoreProvisioningStatus,
521
526
  TraceStoreProvisionResult,
527
+ TraceStoreRunEnvelopeIdentity,
522
528
  )
523
529
  from synth_ai.sdk.research.contracts.transcript import (
524
530
  SwarmTranscriptEvent,
@@ -794,6 +800,9 @@ __all__ = [
794
800
  "ImageUploadId",
795
801
  "InferenceProvider",
796
802
  "InternAgentConfig",
803
+ "InternAcceptanceFixtureReceipt",
804
+ "InternAcceptanceFixtureRequest",
805
+ "InternAcceptanceFixtureResource",
797
806
  "InternAsyncBlocker",
798
807
  "InternAsyncCheckpoint",
799
808
  "InternAsyncCommandKind",
@@ -1103,6 +1112,9 @@ __all__ = [
1103
1112
  "TranscriptReplayMode",
1104
1113
  "TranscriptView",
1105
1114
  "TranscriptVisibilityDecision",
1115
+ "TraceStorePreflightRequest",
1116
+ "TraceStorePreflightResponse",
1117
+ "TraceStoreRunEnvelopeIdentity",
1106
1118
  "UsageFreshness",
1107
1119
  "UsageMoney",
1108
1120
  "UsageSource",
@@ -536,6 +536,17 @@ class InternSyncCommandReceipt(_StrictContract):
536
536
  state_generation: int = Field(ge=0)
537
537
  decision_code: str
538
538
  created_at: datetime
539
+ # Durable actuation receipt (schema smr.intern-command-actuation.v1),
540
+ # present once the command reached a final decision. Kept opaque
541
+ # (WS3 per-field decision: supported_opaque) because the backend mints it,
542
+ # types it as an open JSON object in its own contract, and stamps a
543
+ # result_digest over its canonical content; re-modeling it here would put
544
+ # a second schema authority under that digest. Absent on older backends.
545
+ actuation: dict[str, Any] | None = None
546
+ # True when this response replays an already-admitted command (idempotent
547
+ # retry); the stored receipt/actuation is immutable. Older backends omit
548
+ # the field, which means first application.
549
+ duplicate: bool = False
539
550
 
540
551
 
541
552
  class InternSyncEvent(_StrictContract):
@@ -926,6 +937,14 @@ class InternAsyncCommandReceipt(_StrictContract):
926
937
  state_generation: int = Field(ge=0)
927
938
  decision_code: str
928
939
  created_at: datetime
940
+ # Same durable actuation receipt as InternSyncCommandReceipt.actuation:
941
+ # backend-minted smr.intern-command-actuation.v1, kept opaque
942
+ # (supported_opaque) because the backend is the schema and digest
943
+ # authority for it. Absent on older backends.
944
+ actuation: dict[str, Any] | None = None
945
+ # True when this response replays an already-admitted command (idempotent
946
+ # retry). Older backends omit the field, which means first application.
947
+ duplicate: bool = False
929
948
 
930
949
 
931
950
  class InternAsyncEvent(_StrictContract):
@@ -954,6 +973,51 @@ class InternAsyncEventPage(_StrictContract):
954
973
  next_sequence: int = Field(ge=0)
955
974
 
956
975
 
976
+ class InternAcceptanceFixtureRequest(_StrictContract):
977
+ """Bootstrap one disposable Factory/Project/Effort/Run acceptance fixture.
978
+
979
+ No tribal ids: the backend provisions the whole chain from the named task
980
+ template and binds the organization Intern to it. Idempotent within one
981
+ test attempt via ``idempotency_key``.
982
+ """
983
+
984
+ idempotency_key: str = Field(min_length=1, max_length=180)
985
+ task_template: str = Field(default="acceptance_default", min_length=1, max_length=128)
986
+ # A fixture Run is an inert, pre-terminalized row that satisfies binding
987
+ # validation without dispatching compute. Disable for chain-only fixtures.
988
+ include_run: bool = True
989
+ metadata: dict[str, Any] = Field(default_factory=dict)
990
+
991
+
992
+ class InternAcceptanceFixtureResource(_StrictContract):
993
+ resource_kind: str
994
+ resource_id: str | None = None
995
+ status: str
996
+ error_code: str | None = None
997
+
998
+
999
+ class InternAcceptanceFixtureReceipt(_StrictContract):
1000
+ """Durable, validator-readable evidence for one acceptance fixture."""
1001
+
1002
+ schema_version: Literal["smr.intern-acceptance-fixture.v1"]
1003
+ fixture_id: str
1004
+ org_id: str
1005
+ research_intern_id: str
1006
+ task_template: str
1007
+ status: Literal["ready", "torn_down"]
1008
+ binding: InternRuntimeBinding
1009
+ resources: tuple[InternAcceptanceFixtureResource, ...] = ()
1010
+ # Backend factory_binding_readiness report; opaque because the backend is
1011
+ # the readiness authority and its report shape is advisory evidence.
1012
+ factory_readiness: dict[str, Any] = Field(default_factory=dict)
1013
+ replayed: bool = False
1014
+ created_at: datetime
1015
+ torn_down_at: datetime | None = None
1016
+ # Evidence stays readable until this instant; teardown never destroys it
1017
+ # before the validation window ends.
1018
+ retention_expires_at: datetime | None = None
1019
+
1020
+
957
1021
  class ResearchInternFactoryMembershipResponse(_StrictContract):
958
1022
  research_intern_id: str
959
1023
  org_id: str
@@ -1558,6 +1622,9 @@ __all__ = [
1558
1622
  "DatasetRevisionCreateRequest",
1559
1623
  "DatasetRevisionLifecycleRequest",
1560
1624
  "DatasetRevisionResponse",
1625
+ "InternAcceptanceFixtureReceipt",
1626
+ "InternAcceptanceFixtureRequest",
1627
+ "InternAcceptanceFixtureResource",
1561
1628
  "InternAsyncBlocker",
1562
1629
  "InternAsyncCheckpoint",
1563
1630
  "InternAsyncCommandKind",
@@ -6,7 +6,7 @@ from collections.abc import AsyncIterable, AsyncIterator, Iterable, Iterator, Ma
6
6
  from dataclasses import dataclass, field
7
7
  from datetime import datetime
8
8
  from enum import StrEnum
9
- from typing import Self, TypeAlias
9
+ from typing import Literal, Self, TypeAlias
10
10
 
11
11
  from synth_ai.sdk.research.contracts.actor_images import (
12
12
  ActorImageBinding,
@@ -238,6 +238,14 @@ class RunLaunchRequest(CommandRequest):
238
238
  dev_environment_id: str | None = None
239
239
  run_policy: SmrRunPolicy | WireMapping | None = None
240
240
  kickoff_contract: KickoffContract | WireMapping | None = None
241
+ # Sealed-run provenance: one resolved deployment receipt per participating
242
+ # repository, and the posture that governs them. The backend provenance
243
+ # authority validates and digest-stamps the pins ('live' refuses
244
+ # placeholder pins and unprovisioned trace stores with typed 422s), so the
245
+ # SDK passes them through opaquely and only checks shape and the mode
246
+ # vocabulary client-side.
247
+ deployment_pins: Sequence[WireMapping] | None = None
248
+ provenance_mode: Literal["live", "dry_run"] | str | None = None
241
249
  resource_bindings: RunResourceBindings | WireMapping | None = None
242
250
  evidence_obligations: EvidenceObligations | WireMapping | None = None
243
251
  ai_cache: WireMapping | None = None
@@ -271,6 +279,8 @@ class RunLaunchRequest(CommandRequest):
271
279
  )
272
280
  _validate_launch_text(self.idempotency_key, field_name="idempotency_key")
273
281
  _validate_positive_int(self.timebox_seconds, field_name="timebox_seconds")
282
+ if self.provenance_mode is not None and self.provenance_mode not in ("live", "dry_run"):
283
+ raise ValueError("provenance_mode must be 'live' or 'dry_run'")
274
284
  _validate_launch_sequences(self)
275
285
  _validate_launch_mappings(self)
276
286
  _validate_launch_combinations(self)
@@ -316,6 +326,8 @@ class RunLaunchRequest(CommandRequest):
316
326
  workflow=self.workflow,
317
327
  run_policy=self.run_policy,
318
328
  kickoff_contract=self.kickoff_contract,
329
+ deployment_pins=tuple(self.deployment_pins) if self.deployment_pins else None,
330
+ provenance_mode=self.provenance_mode,
319
331
  resource_bindings=self.resource_bindings,
320
332
  evidence_obligations=self._evidence_obligations_payload(),
321
333
  dev_environment_id=self.dev_environment_id,
@@ -1240,6 +1252,8 @@ def _validate_launch_sequences(request: RunLaunchRequest) -> None:
1240
1252
  raise ValueError(f"actor_model_overrides[{index}] must be an actor model assignment")
1241
1253
  for index, spec in enumerate(request.required_work_products or ()):
1242
1254
  _require_mapping(spec, label=f"required_work_products[{index}]")
1255
+ for index, pin in enumerate(request.deployment_pins or ()):
1256
+ _require_mapping(pin, label=f"deployment_pins[{index}]")
1243
1257
 
1244
1258
 
1245
1259
  def _validate_launch_mappings(request: RunLaunchRequest) -> None:
@@ -8,7 +8,7 @@ from __future__ import annotations
8
8
 
9
9
  from datetime import datetime
10
10
  from enum import StrEnum
11
- from typing import Any
11
+ from typing import Any, Literal
12
12
 
13
13
  from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
14
14
 
@@ -351,6 +351,50 @@ class TraceStoreProvisionResult(_TraceContract):
351
351
  receipt: TraceStoreLifecycleReceipt
352
352
 
353
353
 
354
+ # The preflight trio keeps the backend contract names verbatim (unlike the
355
+ # older abridged names above) because the response and identity block are
356
+ # schema-versioned envelopes that sealed runners embed and re-verify by name.
357
+
358
+
359
+ class TraceStorePreflightRequest(_TraceContract):
360
+ """Pre-launch trace-store readiness gate for a sealed run."""
361
+
362
+ catalog_provider: TraceCatalogProvider = TraceCatalogProvider.NONE
363
+ provision_if_missing: bool = True
364
+
365
+
366
+ class TraceStoreRunEnvelopeIdentity(_TraceContract):
367
+ """Trace-store identity carried inside a sealed-run envelope.
368
+
369
+ Sealed runners embed exactly this block (as ``trace_store``) in the run
370
+ envelope so trace-inventory collection after grading can never 404 on an
371
+ unprovisioned or ambiguous store.
372
+ """
373
+
374
+ schema_version: Literal["synth.trace-store-run-envelope-identity.v1"]
375
+ trace_store_id: str
376
+ org_id: str
377
+ factory_id: str
378
+ blob_bucket: str
379
+ blob_prefix: str
380
+ catalog_provider: TraceCatalogProvider
381
+ catalog_database_name: str | None = None
382
+ provisioning_status: TraceStoreProvisioningStatus
383
+ provisioning_version: int
384
+
385
+
386
+ class TraceStorePreflightResponse(_TraceContract):
387
+ """Typed provision-and-health result gating sealed-run launch."""
388
+
389
+ schema_version: Literal["synth.trace-store-preflight.v1"]
390
+ healthy: bool
391
+ provisioned: Literal["existing", "created"]
392
+ descriptor: TraceStoreDescriptor
393
+ run_envelope_identity: TraceStoreRunEnvelopeIdentity
394
+ health_conditions: list[str] = Field(default_factory=list)
395
+ checked_at: datetime
396
+
397
+
354
398
  __all__ = [
355
399
  "TraceBundleDownload",
356
400
  "TraceBundleDownloadObject",
@@ -372,8 +416,11 @@ __all__ = [
372
416
  "TraceStoreAccessReceipt",
373
417
  "TraceStoreDescriptor",
374
418
  "TraceStoreLifecycleReceipt",
419
+ "TraceStorePreflightRequest",
420
+ "TraceStorePreflightResponse",
375
421
  "TraceStoreProvisionResult",
376
422
  "TraceStoreProvisioningStatus",
423
+ "TraceStoreRunEnvelopeIdentity",
377
424
  "validate_optional_sha256_digest",
378
425
  "validate_sha256_digest",
379
426
  "validate_sha256_digest_list",
@@ -317,6 +317,70 @@ class ResearchStructuredDenialError(ResearchApiError):
317
317
  self.detail = dict(detail) if detail else {}
318
318
 
319
319
 
320
+ class ResearchNotFoundError(ResearchStructuredDenialError):
321
+ """Raised when the backend reports a typed ``*_not_found`` condition (HTTP 404).
322
+
323
+ The backend scopes every Research Intern lookup to the organization bound
324
+ to the caller's API key, so a 404 only proves the resource is absent *for
325
+ that organization* -- it never proves global absence. Release evidence must
326
+ be able to distinguish a genuine miss from a wrong-organization lookup, so
327
+ this error preserves the backend's typed condition instead of collapsing it
328
+ into an opaque denial:
329
+
330
+ - ``backend_error_code``: the exact backend condition, for example
331
+ ``intern_async_runtime_not_found``, ``intern_sync_session_not_found``,
332
+ or a retention condition such as
333
+ ``intern_async_runtime_retention_expired`` /
334
+ ``intern_acceptance_fixture_retention_expired`` (the resource existed;
335
+ its read-only retention window ended). (Named to avoid shadowing the
336
+ read-only ``SynthError.error_code`` transport-failure property.)
337
+ - ``resource``: the resource segment of the condition (``async_runtime``,
338
+ ``sync_session``, ``acceptance_fixture``, ...), or ``None`` when the
339
+ code has neither the ``intern_*_not_found`` nor the
340
+ ``intern_*_retention_expired`` shape.
341
+ - ``scope_identifier``: the lookup key the backend echoed back (the
342
+ organization id for org-singleton lookups such as the Async Intern, the
343
+ resource id otherwise), when the backend provided one.
344
+
345
+ Evidence that records ``backend_error_code`` + ``scope_identifier`` next to
346
+ the caller's organization binding can attribute the miss: a not-found under
347
+ the expected organization is a true absence for that organization, while a
348
+ mismatch between the expected resource's organization and the caller's
349
+ binding identifies a wrong-organization lookup.
350
+ """
351
+
352
+ def __init__(
353
+ self,
354
+ message: str,
355
+ *,
356
+ status_code: int | None = None,
357
+ response_text: str | None = None,
358
+ detail: dict[str, Any] | None = None,
359
+ ) -> None:
360
+ super().__init__(
361
+ message,
362
+ status_code=status_code,
363
+ response_text=response_text,
364
+ detail=detail,
365
+ )
366
+ code = self.detail.get("error_code")
367
+ self.backend_error_code: str = code.strip() if isinstance(code, str) else ""
368
+ resource: str | None = None
369
+ if self.backend_error_code.startswith("intern_"):
370
+ for suffix in ("_not_found", "_retention_expired"):
371
+ if self.backend_error_code.endswith(suffix):
372
+ resource = self.backend_error_code.removeprefix("intern_").removesuffix(suffix)
373
+ break
374
+ self.resource: str | None = resource
375
+ scope: str | None = None
376
+ for key in ("runtime_id", "resource_id", "fixture_id", "async_runtime_id", "org_id"):
377
+ value = self.detail.get(key)
378
+ if isinstance(value, str) and value.strip():
379
+ scope = value.strip()
380
+ break
381
+ self.scope_identifier: str | None = scope
382
+
383
+
320
384
  class ResearchLimitExtensionError(ResearchApiError):
321
385
  """Base class for durable run-limit extension refusals."""
322
386
 
@@ -569,6 +633,7 @@ __all__ = [
569
633
  "ResearchLimitExtensionIdempotencyConflictError",
570
634
  "ResearchLimitRevisionConflictError",
571
635
  "ResearchManagedInferenceUnavailableError",
636
+ "ResearchNotFoundError",
572
637
  "ResearchOperationError",
573
638
  "ResearchProjectMonthlyBudgetExhaustedError",
574
639
  "ResearchStructuredDenialError",