synth-ai 0.22.2.dev689__tar.gz → 0.22.2.dev690__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 (365) hide show
  1. {synth_ai-0.22.2.dev689/synth_ai.egg-info → synth_ai-0.22.2.dev690}/PKG-INFO +1 -1
  2. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/pyproject.toml +1 -1
  3. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/async_transport.py +3 -2
  4. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/transport.py +4 -3
  5. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/__init__.py +2 -0
  6. synth_ai-0.22.2.dev690/synth_ai/sdk/research/__init__.py +69 -0
  7. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced_swarms.py +19 -6
  8. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/client.py +56 -1
  9. synth_ai-0.22.2.dev690/synth_ai/sdk/research/execution_reads.py +260 -0
  10. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/facade.py +13 -0
  11. synth_ai-0.22.2.dev690/synth_ai/sdk/research/hierarchy.py +552 -0
  12. synth_ai-0.22.2.dev690/synth_ai/sdk/research/hierarchy_models.py +474 -0
  13. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/operations.py +78 -0
  14. synth_ai-0.22.2.dev690/synth_ai/sdk/research/owner_reads.py +341 -0
  15. synth_ai-0.22.2.dev690/synth_ai/sdk/research/planning_reads.py +331 -0
  16. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/projects.py +4 -1
  17. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/swarms.py +5 -1
  18. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690/synth_ai.egg-info}/PKG-INFO +1 -1
  19. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/SOURCES.txt +5 -0
  20. synth_ai-0.22.2.dev689/synth_ai/sdk/research/__init__.py +0 -26
  21. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/LICENSE +0 -0
  22. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/MANIFEST.in +0 -0
  23. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/README.md +0 -0
  24. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/index-v1.json +0 -0
  25. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/messaging-v1.json +0 -0
  26. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/research-v1.json +0 -0
  27. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/setup.cfg +0 -0
  28. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/setup.py +0 -0
  29. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/README.md +0 -0
  30. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/__init__.py +0 -0
  31. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/__main__.py +0 -0
  32. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/AGENTS.md +0 -0
  33. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/README.md +0 -0
  34. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/__init__.py +0 -0
  35. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/__main__.py +0 -0
  36. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/index.py +0 -0
  37. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/main.py +0 -0
  38. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research.py +0 -0
  39. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_environments.py +0 -0
  40. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_image_releases.py +0 -0
  41. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_projects.py +0 -0
  42. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/utils/__init__.py +0 -0
  43. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/utils/research_launch.py +0 -0
  44. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/client.py +0 -0
  45. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/README.md +0 -0
  46. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/__init__.py +0 -0
  47. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/auth/__init__.py +0 -0
  48. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/auth/credentials.py +0 -0
  49. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/__init__.py +0 -0
  50. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/json_value.py +0 -0
  51. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/pagination.py +0 -0
  52. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/errors.py +0 -0
  53. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/__init__.py +0 -0
  54. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/request.py +0 -0
  55. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/retry.py +0 -0
  56. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/streaming.py +0 -0
  57. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/local_files.py +0 -0
  58. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/research/__init__.py +0 -0
  59. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/__init__.py +0 -0
  60. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/env.py +0 -0
  61. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/log_filter.py +0 -0
  62. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/paths.py +0 -0
  63. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/urls.py +0 -0
  64. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/README.md +0 -0
  65. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/__init__.py +0 -0
  66. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/__main__.py +0 -0
  67. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/objective_tools.py +0 -0
  68. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/registry.py +0 -0
  69. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/request_models.py +0 -0
  70. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/server.py +0 -0
  71. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/approvals.py +0 -0
  72. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/artifacts.py +0 -0
  73. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/datasets.py +0 -0
  74. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/environments.py +0 -0
  75. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/exports.py +0 -0
  76. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/factories.py +0 -0
  77. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/factory_results.py +0 -0
  78. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/files.py +0 -0
  79. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/image_releases.py +0 -0
  80. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/index.py +0 -0
  81. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/index_qa.py +0 -0
  82. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/integrations.py +0 -0
  83. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/intern_program.py +0 -0
  84. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/launch_schemas.py +0 -0
  85. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/local_files.py +0 -0
  86. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/logs.py +0 -0
  87. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/models.py +0 -0
  88. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/outputs.py +0 -0
  89. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/policy_schemas.py +0 -0
  90. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/progress.py +0 -0
  91. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/project_data.py +0 -0
  92. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/projects.py +0 -0
  93. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/prs.py +0 -0
  94. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/readiness.py +0 -0
  95. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/repos.py +0 -0
  96. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/research_intern.py +0 -0
  97. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/resource_reads.py +0 -0
  98. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/resources.py +0 -0
  99. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/runs.py +0 -0
  100. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/scientific_records.py +0 -0
  101. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/trained_models.py +0 -0
  102. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/usage.py +0 -0
  103. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/visuals.py +0 -0
  104. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/workspace_inputs.py +0 -0
  105. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/pools.py +0 -0
  106. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/py.typed +0 -0
  107. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/README.md +0 -0
  108. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/__init__.py +0 -0
  109. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/AGENT_SETUP_PROMPT.md +0 -0
  110. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/README.md +0 -0
  111. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/__init__.py +0 -0
  112. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/agent_policy.py +0 -0
  113. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/artifacts.py +0 -0
  114. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/catalog.py +0 -0
  115. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/catalogue.py +0 -0
  116. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/classification.py +0 -0
  117. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/client.py +0 -0
  118. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/contracts.py +0 -0
  119. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/contributions.py +0 -0
  120. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/errors.py +0 -0
  121. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/forge_notices.py +0 -0
  122. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/intake.py +0 -0
  123. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/lifecycle.py +0 -0
  124. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/local_files.py +0 -0
  125. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/manifest.py +0 -0
  126. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/oauth.py +0 -0
  127. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/package.py +0 -0
  128. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public.py +0 -0
  129. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public_corpus.py +0 -0
  130. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public_search.py +0 -0
  131. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa.py +0 -0
  132. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_checks.py +0 -0
  133. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_preflight.py +0 -0
  134. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_reviews.py +0 -0
  135. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/__init__.py +0 -0
  136. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/build.py +0 -0
  137. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/capture.py +0 -0
  138. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/contracts.py +0 -0
  139. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/files.py +0 -0
  140. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/release.py +0 -0
  141. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research_intake.py +0 -0
  142. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/retry.py +0 -0
  143. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/rights.py +0 -0
  144. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scientific_provenance.py +0 -0
  145. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scope_errors.py +0 -0
  146. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scopes.py +0 -0
  147. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/search.py +0 -0
  148. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/submission.py +0 -0
  149. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/timeouts.py +0 -0
  150. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/transfer.py +0 -0
  151. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/upload_session.py +0 -0
  152. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/usage_accounting.py +0 -0
  153. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/value.py +0 -0
  154. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/wallet_search.py +0 -0
  155. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/README.md +0 -0
  156. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/__init__.py +0 -0
  157. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/client.py +0 -0
  158. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/contracts.py +0 -0
  159. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/__init__.py +0 -0
  160. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/client.py +0 -0
  161. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/contracts.py +0 -0
  162. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/pagination.py +0 -0
  163. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/__init__.py +0 -0
  164. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/crypto.py +0 -0
  165. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/env.py +0 -0
  166. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/urls.py +0 -0
  167. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/account.py +0 -0
  168. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced.py +0 -0
  169. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced_factories.py +0 -0
  170. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/artifacts.py +0 -0
  171. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/auth.py +0 -0
  172. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/__init__.py +0 -0
  173. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/api.py +0 -0
  174. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/contracts.py +0 -0
  175. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/operations.py +0 -0
  176. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/packaging.py +0 -0
  177. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/__init__.py +0 -0
  178. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_activity_wire.py +0 -0
  179. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_environment_wire.py +0 -0
  180. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_transcript_wire.py +0 -0
  181. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_wire.py +0 -0
  182. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/activity.py +0 -0
  183. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/activity_items.py +0 -0
  184. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/actor_images.py +0 -0
  185. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/billing.py +0 -0
  186. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/canonical_usage.py +0 -0
  187. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/checkpoints.py +0 -0
  188. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/cloud_deployment_claims.py +0 -0
  189. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/cloud_deployments.py +0 -0
  190. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/common.py +0 -0
  191. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/dataset_revisions.py +0 -0
  192. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/deliveries.py +0 -0
  193. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/dev_environment_evidence.py +0 -0
  194. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/economics.py +0 -0
  195. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/environment_manifest.py +0 -0
  196. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/environments.py +0 -0
  197. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/evidence.py +0 -0
  198. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/experiment_evidence.py +0 -0
  199. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factories.py +0 -0
  200. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_evidence.py +0 -0
  201. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_lenses.py +0 -0
  202. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_operations.py +0 -0
  203. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_role_receipts.py +0 -0
  204. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/failure.py +0 -0
  205. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/__init__.py +0 -0
  206. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/contracts.py +0 -0
  207. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/evaluation.py +0 -0
  208. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/exports.py +0 -0
  209. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/operations.py +0 -0
  210. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/records.py +0 -0
  211. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/resources.py +0 -0
  212. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/schema.py +0 -0
  213. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge_citations.py +0 -0
  214. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge_uploads.py +0 -0
  215. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/image_releases.py +0 -0
  216. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_authority.py +0 -0
  217. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_blockers.py +0 -0
  218. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_grants.py +0 -0
  219. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_program.py +0 -0
  220. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_resources.py +0 -0
  221. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_usage.py +0 -0
  222. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/limit_evidence.py +0 -0
  223. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/local_execution_profile.py +0 -0
  224. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/native_attachment.py +0 -0
  225. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/native_result_outcome.py +0 -0
  226. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/operator_evidence.py +0 -0
  227. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project.py +0 -0
  228. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_data.py +0 -0
  229. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_runtime.py +0 -0
  230. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_workspace.py +0 -0
  231. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_workspace_evidence.py +0 -0
  232. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/projects.py +0 -0
  233. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/promotions.py +0 -0
  234. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/research_intern.py +0 -0
  235. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/resource_reads.py +0 -0
  236. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/resource_settlement.py +0 -0
  237. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_authority.py +0 -0
  238. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_control.py +0 -0
  239. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_diagnostics.py +0 -0
  240. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_events.py +0 -0
  241. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_execution.py +0 -0
  242. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_launch.py +0 -0
  243. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_observability.py +0 -0
  244. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_state.py +0 -0
  245. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_timeline.py +0 -0
  246. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_image.py +0 -0
  247. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_intent.py +0 -0
  248. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_stream.py +0 -0
  249. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_stream_snapshot.py +0 -0
  250. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/scientific_citations.py +0 -0
  251. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/scientific_integrity.py +0 -0
  252. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_actor_models.py +0 -0
  253. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_actor_policy_data.py +0 -0
  254. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_harnesses.py +0 -0
  255. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_kinds.py +0 -0
  256. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_models.py +0 -0
  257. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_branching.py +0 -0
  258. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_credential_providers.py +0 -0
  259. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_environment_kinds.py +0 -0
  260. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_evidence_obligations.py +0 -0
  261. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_funding_sources.py +0 -0
  262. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_horizons.py +0 -0
  263. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_host_kinds.py +0 -0
  264. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_inference_providers.py +0 -0
  265. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_network_topology.py +0 -0
  266. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_providers.py +0 -0
  267. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_resource_kinds.py +0 -0
  268. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_roles.py +0 -0
  269. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_run_policy.py +0 -0
  270. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runbooks.py +0 -0
  271. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runnable_project.py +0 -0
  272. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runtime_kinds.py +0 -0
  273. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_tool_providers.py +0 -0
  274. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_work_modes.py +0 -0
  275. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/status.py +0 -0
  276. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_controls.py +0 -0
  277. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_history.py +0 -0
  278. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_rollouts.py +0 -0
  279. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_tasks.py +0 -0
  280. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarms.py +0 -0
  281. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/tag.py +0 -0
  282. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/traces.py +0 -0
  283. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/transcript.py +0 -0
  284. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/types.py +0 -0
  285. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/usage.py +0 -0
  286. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/visuals.py +0 -0
  287. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/wire_models.py +0 -0
  288. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/wire_models_README.md +0 -0
  289. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/work_products.py +0 -0
  290. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/workspaces.py +0 -0
  291. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/economics.py +0 -0
  292. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/efforts.py +0 -0
  293. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/environments.py +0 -0
  294. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/errors.py +0 -0
  295. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/events.py +0 -0
  296. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/experiments.py +0 -0
  297. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/factories.py +0 -0
  298. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/factory_storage.py +0 -0
  299. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/image_releases.py +0 -0
  300. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_authority.py +0 -0
  301. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_blockers.py +0 -0
  302. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_program.py +0 -0
  303. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/knowledge.py +0 -0
  304. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/models.py +0 -0
  305. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_data.py +0 -0
  306. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_deliveries.py +0 -0
  307. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_workspaces.py +0 -0
  308. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/public.py +0 -0
  309. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/readouts.py +0 -0
  310. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/research_intern.py +0 -0
  311. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/resource_reads.py +0 -0
  312. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/scientific_records.py +0 -0
  313. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/secrets.py +0 -0
  314. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/README.md +0 -0
  315. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/__init__.py +0 -0
  316. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_base.py +0 -0
  317. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_client_helpers.py +0 -0
  318. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_run_authority_mixin.py +0 -0
  319. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/approvals.py +0 -0
  320. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/billing.py +0 -0
  321. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/client.py +0 -0
  322. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/cloud_deployments.py +0 -0
  323. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/config.py +0 -0
  324. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/cost.py +0 -0
  325. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/datasets.py +0 -0
  326. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/dev_environments.py +0 -0
  327. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/directory_inputs.py +0 -0
  328. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/environments.py +0 -0
  329. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/exports.py +0 -0
  330. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/factories.py +0 -0
  331. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/factory_evidence.py +0 -0
  332. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/files.py +0 -0
  333. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/github.py +0 -0
  334. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/image_releases.py +0 -0
  335. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/images.py +0 -0
  336. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/logs.py +0 -0
  337. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/models.py +0 -0
  338. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/outputs.py +0 -0
  339. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/progress.py +0 -0
  340. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/project.py +0 -0
  341. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/projects.py +0 -0
  342. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/prs.py +0 -0
  343. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/readiness.py +0 -0
  344. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/repositories.py +0 -0
  345. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/runs.py +0 -0
  346. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/secrets.py +0 -0
  347. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/setup.py +0 -0
  348. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/tag.py +0 -0
  349. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/trained_models.py +0 -0
  350. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/transport.py +0 -0
  351. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/usage.py +0 -0
  352. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/work_products.py +0 -0
  353. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/workspace_inputs.py +0 -0
  354. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/surface_parity.py +0 -0
  355. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/traces.py +0 -0
  356. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/__init__.py +0 -0
  357. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/http.py +0 -0
  358. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/pagination.py +0 -0
  359. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/version.py +0 -0
  360. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/visuals.py +0 -0
  361. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/wiki.py +0 -0
  362. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/dependency_links.txt +0 -0
  363. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/entry_points.txt +0 -0
  364. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/requires.txt +0 -0
  365. {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/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.22.2.dev689
3
+ Version: 0.22.2.dev690
4
4
  Summary: Python SDK, CLI and MCP servers for Synth Index search and Swarms
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.22.2.dev689"
3
+ version = "0.22.2.dev690"
4
4
  description = "Python SDK, CLI and MCP servers for Synth Index search and Swarms"
5
5
  keywords = ["synth", "index", "search", "citations", "research", "swarms", "mcp", "sdk"]
6
6
  authors = [{name = "Synth AI", email = "josh@usesynth.ai"}]
@@ -38,12 +38,13 @@ class AsyncHttpTransport:
38
38
  """One native async transport for JSON, bytes, and SSE operations."""
39
39
 
40
40
  base_url: str
41
- headers: Mapping[str, str]
41
+ headers: Mapping[str, str] = field(repr=False)
42
42
  timeout_seconds: float = 30.0
43
43
  retry_policy: RetryPolicy = field(default_factory=RetryPolicy)
44
44
  error_handler: ErrorHandler = raise_http_error
45
45
  exception_handler: ExceptionHandler = raise_transport_exception
46
46
  decode_error_handler: DecodeErrorHandler = raise_json_decode_error
47
+ follow_redirects: bool = True
47
48
  client: httpx.AsyncClient = field(init=False, repr=False)
48
49
 
49
50
  def __post_init__(self) -> None:
@@ -52,7 +53,7 @@ class AsyncHttpTransport:
52
53
  headers=dict(self.headers),
53
54
  timeout=self.timeout_seconds,
54
55
  limits=httpx.Limits(max_keepalive_connections=0),
55
- follow_redirects=True,
56
+ follow_redirects=self.follow_redirects,
56
57
  )
57
58
 
58
59
  async def close(self) -> None:
@@ -124,7 +124,7 @@ def _declares_runtime_unavailable(decoded: JsonValue | None) -> bool:
124
124
  return False
125
125
  nested = decoded.get("detail")
126
126
  return any(
127
- source.get(key) in RUNTIME_UNAVAILABLE_CODES
127
+ isinstance(source.get(key), str) and source.get(key) in RUNTIME_UNAVAILABLE_CODES
128
128
  for source in (nested, decoded)
129
129
  if isinstance(source, dict)
130
130
  for key in ("error_code", "code", "error")
@@ -425,12 +425,13 @@ class HttpTransport:
425
425
  """One strict sync transport for JSON, bytes, and SSE operations."""
426
426
 
427
427
  base_url: str
428
- headers: Mapping[str, str]
428
+ headers: Mapping[str, str] = field(repr=False)
429
429
  timeout_seconds: float = 30.0
430
430
  retry_policy: RetryPolicy = field(default_factory=RetryPolicy)
431
431
  error_handler: ErrorHandler = raise_http_error
432
432
  exception_handler: ExceptionHandler = raise_transport_exception
433
433
  decode_error_handler: DecodeErrorHandler = raise_json_decode_error
434
+ follow_redirects: bool = True
434
435
  db_backpressure_policy: DbBackpressureRetryPolicy = field(
435
436
  default_factory=DbBackpressureRetryPolicy
436
437
  )
@@ -445,7 +446,7 @@ class HttpTransport:
445
446
  headers=dict(self.headers),
446
447
  timeout=self.timeout_seconds,
447
448
  limits=httpx.Limits(max_keepalive_connections=0),
448
- follow_redirects=True,
449
+ follow_redirects=self.follow_redirects,
449
450
  )
450
451
 
451
452
  def close(self) -> None:
@@ -7,6 +7,7 @@ from synth_ai.mcp.research.tools.factories import build_factory_tools
7
7
  from synth_ai.mcp.research.tools.files import build_file_tools
8
8
  from synth_ai.mcp.research.tools.image_releases import build_image_release_tools
9
9
  from synth_ai.mcp.research.tools.intern_program import build_intern_program_tools
10
+ from synth_ai.mcp.research.tools.local_files import SelectedFileReader
10
11
  from synth_ai.mcp.research.tools.models import build_model_tools
11
12
  from synth_ai.mcp.research.tools.outputs import build_output_tools
12
13
  from synth_ai.mcp.research.tools.progress import build_progress_tools
@@ -21,6 +22,7 @@ from synth_ai.mcp.research.tools.visuals import build_visual_tools
21
22
  from synth_ai.mcp.research.tools.workspace_inputs import build_workspace_input_tools
22
23
 
23
24
  __all__ = [
25
+ "SelectedFileReader",
24
26
  "build_dataset_tools",
25
27
  "build_environment_tools",
26
28
  "build_export_tools",
@@ -0,0 +1,69 @@
1
+ """Dependency-clean implementation of the public Synth Research SDK."""
2
+
3
+ from synth_ai.sdk.research.client import AsyncClient, Client
4
+ from synth_ai.sdk.research.contracts.resource_reads import (
5
+ DataPoolReadReference,
6
+ DatasetRevisionReadReference,
7
+ ProjectDataPoolDescriptor,
8
+ ProjectDataPoolInventory,
9
+ )
10
+ from synth_ai.sdk.research.facade import ResearchClient
11
+ from synth_ai.sdk.research.hierarchy import AsyncHierarchyClient, HierarchyClient
12
+ from synth_ai.sdk.research.hierarchy_models import (
13
+ EntityKey,
14
+ HierarchyCommand,
15
+ HierarchyOriginal,
16
+ HierarchyRead,
17
+ HierarchyScope,
18
+ )
19
+ from synth_ai.sdk.research.operations import RESEARCH_OPERATIONS, research_operation
20
+ from synth_ai.sdk.research.owner_reads import (
21
+ AsyncOwnerReadClient,
22
+ OwnerReadAccess,
23
+ OwnerReadAccessExpired,
24
+ OwnerReadAccessExpiredError,
25
+ OwnerReadClient,
26
+ OwnerReadScope,
27
+ )
28
+ from synth_ai.sdk.research.planning_reads import (
29
+ AsyncPlanningReads,
30
+ PlanningGraphRead,
31
+ PlanningReadPosition,
32
+ PlanningReads,
33
+ PlanningTaskPage,
34
+ PlanningTaskRead,
35
+ )
36
+
37
+ AsyncResearchClient = AsyncClient
38
+
39
+ __all__ = [
40
+ "AsyncHierarchyClient",
41
+ "HierarchyClient",
42
+ "HierarchyScope",
43
+ "HierarchyCommand",
44
+ "HierarchyRead",
45
+ "HierarchyOriginal",
46
+ "EntityKey",
47
+ "AsyncClient",
48
+ "AsyncResearchClient",
49
+ "AsyncOwnerReadClient",
50
+ "AsyncPlanningReads",
51
+ "Client",
52
+ "DataPoolReadReference",
53
+ "DatasetRevisionReadReference",
54
+ "ProjectDataPoolDescriptor",
55
+ "ProjectDataPoolInventory",
56
+ "OwnerReadAccess",
57
+ "OwnerReadAccessExpired",
58
+ "OwnerReadAccessExpiredError",
59
+ "OwnerReadClient",
60
+ "OwnerReadScope",
61
+ "PlanningGraphRead",
62
+ "PlanningReadPosition",
63
+ "PlanningReads",
64
+ "PlanningTaskPage",
65
+ "PlanningTaskRead",
66
+ "RESEARCH_OPERATIONS",
67
+ "ResearchClient",
68
+ "research_operation",
69
+ ]
@@ -46,6 +46,16 @@ class _ResearchSession(Protocol):
46
46
 
47
47
  def run(self, project_id: str, run_id: str) -> _RunHandle: ...
48
48
 
49
+ def get_run_results(self, project_id: str, run_id: str) -> dict[str, Any]: ...
50
+
51
+ def get_run_logs(
52
+ self, project_id: str, run_id: str, *, limit: int | None = None, cursor: str | None = None
53
+ ) -> dict[str, Any]: ...
54
+
55
+ def get_run_execution(self, project_id: str, run_id: str, **kwargs: Any) -> Any: ...
56
+
57
+ def get_run_orchestrator(self, project_id: str, run_id: str) -> dict[str, Any]: ...
58
+
49
59
 
50
60
  def _session_project(project: ProjectSelector | str | None) -> str | None:
51
61
  if isinstance(project, ProjectSelector):
@@ -588,13 +598,16 @@ class ResearchRunsAPI:
588
598
  from synth_ai.sdk.pagination import page_from_wire
589
599
 
590
600
  payload = self.logs(project_id, run_id, limit=limit, cursor=cursor)
601
+ if isinstance(payload, dict) and "items" not in payload and "data" not in payload:
602
+ for field_name in ("entries", "logs", "records"):
603
+ if field_name in payload:
604
+ payload = {
605
+ "items": payload[field_name],
606
+ "next_cursor": payload.get("next_cursor"),
607
+ "has_more": payload.get("has_more", False),
608
+ }
609
+ break
591
610
  raw_items, next_cursor, has_more = page_from_wire(payload)
592
- if isinstance(payload, dict) and isinstance(payload.get("entries"), list):
593
- raw_items = payload["entries"]
594
- elif isinstance(payload, dict) and isinstance(payload.get("logs"), list):
595
- raw_items = payload["logs"]
596
- elif isinstance(payload, dict) and isinstance(payload.get("records"), list):
597
- raw_items = payload["records"]
598
611
  normalized = [cast(dict[str, Any], item) for item in raw_items if isinstance(item, dict)]
599
612
  return SyncPage(items=normalized, next_cursor=next_cursor, has_more=has_more)
600
613
 
@@ -11,17 +11,26 @@ from synth_ai.core.utils.urls import BACKEND_URL_BASE, normalize_backend_base
11
11
  from synth_ai.sdk.research.container_pools.api import ContainerPoolsAPI
12
12
  from synth_ai.sdk.research.environments import AsyncEnvironmentsAPI, EnvironmentsAPI
13
13
  from synth_ai.sdk.research.factories import AsyncFactoriesAPI, FactoriesAPI
14
+ from synth_ai.sdk.research.hierarchy import AsyncHierarchyClient, HierarchyClient
15
+ from synth_ai.sdk.research.hierarchy_models import HierarchyPermission, HierarchyScope
14
16
  from synth_ai.sdk.research.image_releases import (
15
17
  AsyncImageReleasesAPI,
16
18
  ImageReleasesAPI,
17
19
  )
20
+ from synth_ai.sdk.research.owner_reads import (
21
+ AsyncOwnerReadClient,
22
+ Owner,
23
+ OwnerReadAccess,
24
+ OwnerReadClient,
25
+ OwnerReadScope,
26
+ )
18
27
  from synth_ai.sdk.research.projects import AsyncProjectsAPI, ProjectsAPI
19
28
  from synth_ai.sdk.research.research_intern import (
20
29
  AsyncResearchInternAPI,
21
30
  ResearchInternAPI,
22
31
  )
32
+ from synth_ai.sdk.research.scientific_records import AsyncScientificRecordsAPI, ScientificRecordsAPI
23
33
  from synth_ai.sdk.research.swarms import AsyncSwarmsAPI, SwarmsAPI
24
- from synth_ai.sdk.research.scientific_records import ScientificRecordsAPI, AsyncScientificRecordsAPI
25
34
  from synth_ai.sdk.research.traces import AsyncResearchTracesAPI, ResearchTracesAPI
26
35
  from synth_ai.sdk.research.visuals import AsyncVisualsAPI, VisualsAPI
27
36
 
@@ -103,6 +112,29 @@ class Client:
103
112
  """Close the underlying HTTP transport."""
104
113
  self._transport.close()
105
114
 
115
+ def hierarchy(
116
+ self, *, scope: HierarchyScope, permissions: tuple[HierarchyPermission, ...] = ("read",)
117
+ ) -> HierarchyClient:
118
+ """Direct project owner API; see testing/specifications/sdk/hierarchy_owner.md."""
119
+ return HierarchyClient(self._transport, scope=scope, permissions=permissions)
120
+
121
+ def owner_reads(self, *, owner: Owner, scope: OwnerReadScope) -> OwnerReadClient:
122
+ """Issue separate scoped read access; see testing/specifications/sdk/owner_reads.md."""
123
+ value = self._transport.request_json(
124
+ "POST",
125
+ "/auth/capabilities/owner-read",
126
+ json_body={
127
+ "owner": owner,
128
+ "scope": {
129
+ "organization_id": scope.organization_id,
130
+ "project_id": scope.project_id,
131
+ "stream_id": scope.run_id,
132
+ },
133
+ },
134
+ )
135
+ access = OwnerReadAccess.from_response(value, owner=owner, scope=scope)
136
+ return OwnerReadClient(owner=owner, base_url=access.origin, access=access)
137
+
106
138
  def __enter__(self) -> Client:
107
139
  return self
108
140
 
@@ -143,6 +175,29 @@ class AsyncClient:
143
175
  """The shared typed async HTTP transport every namespace routes through."""
144
176
  return self._transport
145
177
 
178
+ def hierarchy(
179
+ self, *, scope: HierarchyScope, permissions: tuple[HierarchyPermission, ...] = ("read",)
180
+ ) -> AsyncHierarchyClient:
181
+ """Direct async project owner API; see testing/specifications/sdk/hierarchy_owner.md."""
182
+ return AsyncHierarchyClient(self._transport, scope=scope, permissions=permissions)
183
+
184
+ async def owner_reads(self, *, owner: Owner, scope: OwnerReadScope) -> AsyncOwnerReadClient:
185
+ """Issue separate scoped read access; see testing/specifications/sdk/owner_reads.md."""
186
+ value = await self._transport.request_json(
187
+ "POST",
188
+ "/auth/capabilities/owner-read",
189
+ json_body={
190
+ "owner": owner,
191
+ "scope": {
192
+ "organization_id": scope.organization_id,
193
+ "project_id": scope.project_id,
194
+ "stream_id": scope.run_id,
195
+ },
196
+ },
197
+ )
198
+ access = OwnerReadAccess.from_response(value, owner=owner, scope=scope)
199
+ return AsyncOwnerReadClient(owner=owner, base_url=access.origin, access=access)
200
+
146
201
  @property
147
202
  def economics(self) -> AsyncEconomicsAPI:
148
203
  """Advanced async economics operations, loaded only on access."""
@@ -0,0 +1,260 @@
1
+ """Direct Orchestra execution snapshots and journal pages.
2
+
3
+ # See: testing/specifications/sdk/owner_reads.md
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import hashlib
9
+ import json
10
+ import re
11
+ from dataclasses import dataclass
12
+ from typing import TYPE_CHECKING, cast
13
+
14
+ from synth_ai.core.contracts.json_value import JsonObject, JsonValue
15
+ from synth_ai.sdk.research.contracts._wire import object_value
16
+
17
+ if TYPE_CHECKING:
18
+ from synth_ai.sdk.research.owner_reads import (
19
+ AsyncOwnerReadClient,
20
+ OwnerReadClient,
21
+ OwnerReadScope,
22
+ )
23
+
24
+ _SCHEMA = "orchestra.owner.run-execution.v1"
25
+ _PORT_SCHEMA = "orchestra.execution-public-view.v1"
26
+ _SCHEMAS = frozenset({_SCHEMA, _PORT_SCHEMA})
27
+ _VIEW = "run_execution"
28
+ _DIGEST = re.compile(r"sha256:[0-9a-f]{64}\Z")
29
+
30
+
31
+ def _integer(value: JsonValue, *, maximum: int = 2**64 - 1) -> int:
32
+ if type(value) is not int or not 0 <= value <= maximum:
33
+ raise ValueError("execution owner position outside wire bounds")
34
+ return value
35
+
36
+
37
+ def _object(value: JsonValue, fields: set[str]) -> JsonObject:
38
+ result = object_value(value, operation_id="execution owner read")
39
+ if set(result) != fields:
40
+ raise ValueError("execution owner response fields drifted")
41
+ return result
42
+
43
+
44
+ def _scope(scope: OwnerReadScope) -> JsonObject:
45
+ return {
46
+ "organization_id": scope.organization_id,
47
+ "project_id": scope.project_id,
48
+ "stream_id": scope.run_id,
49
+ }
50
+
51
+
52
+ def _schema(value: JsonValue) -> str:
53
+ if not isinstance(value, str) or value not in _SCHEMAS:
54
+ raise ValueError("execution owner view schema unsupported")
55
+ return value
56
+
57
+
58
+ @dataclass(frozen=True, slots=True)
59
+ class ExecutionReadCursor:
60
+ """A position in one Orchestra view, independent of Sublinear publication."""
61
+
62
+ scope: OwnerReadScope
63
+ sequence: int
64
+ schema: str = _SCHEMA
65
+
66
+ def __post_init__(self) -> None:
67
+ _integer(self.sequence)
68
+ _schema(self.schema)
69
+
70
+ @classmethod
71
+ def from_wire(cls, value: JsonValue, scope: OwnerReadScope) -> ExecutionReadCursor:
72
+ body = _object(value, {"scope", "sequence", "view", "schema"})
73
+ if body["scope"] != _scope(scope) or body["view"] != _VIEW:
74
+ raise ValueError("execution owner cursor scope or view mismatch")
75
+ return cls(scope, _integer(body["sequence"]), _schema(body["schema"]))
76
+
77
+ def wire(self) -> JsonObject:
78
+ return {"scope": _scope(self.scope), "sequence": self.sequence, "view": _VIEW, "schema": self.schema}
79
+
80
+ def event_id(self) -> str:
81
+ """Return the exact canonical cursor accepted by the owner HTTP API."""
82
+ return json.dumps(self.wire(), sort_keys=True, separators=(",", ":"), ensure_ascii=False)
83
+
84
+
85
+ @dataclass(frozen=True, slots=True)
86
+ class ExecutionReadRetention:
87
+ floor_sequence: int
88
+ head_sequence: int
89
+ anchor: JsonObject
90
+
91
+ @classmethod
92
+ def from_wire(cls, value: JsonValue) -> ExecutionReadRetention:
93
+ body = _object(value, {"floor_sequence", "head_sequence", "anchor"})
94
+ floor, head = _integer(body["floor_sequence"]), _integer(body["head_sequence"])
95
+ anchor = _object(body["anchor"], {"owner", "schema", "reference", "sha256"})
96
+ if floor > head or not all(isinstance(v, str) and v for v in anchor.values()):
97
+ raise ValueError("execution owner retention invalid")
98
+ digest = anchor["sha256"]
99
+ if not isinstance(digest, str) or not _DIGEST.fullmatch(digest):
100
+ raise ValueError("execution owner retention anchor digest invalid")
101
+ return cls(floor, head, anchor)
102
+
103
+ def contains(self, position: ExecutionReadCursor) -> None:
104
+ if not self.floor_sequence <= position.sequence <= self.head_sequence:
105
+ raise ValueError("execution owner cursor outside retained range")
106
+
107
+
108
+ @dataclass(frozen=True, slots=True)
109
+ class ExecutionReadValue:
110
+ """Owner public view with its original JSON spelling and verified digest."""
111
+
112
+ position: ExecutionReadCursor
113
+ raw_json: str
114
+ sha256: str
115
+ value: JsonObject
116
+
117
+ @classmethod
118
+ def from_wire(
119
+ cls, payload: JsonValue, position: ExecutionReadCursor, *, kind: str
120
+ ) -> ExecutionReadValue:
121
+ body = _object(payload, {"kind", "schema", "canonical_json", "sha256"})
122
+ raw = body["canonical_json"]
123
+ if body["kind"] != "inline" or body["schema"] != position.schema or not isinstance(raw, str):
124
+ raise ValueError("execution owner public view payload invalid")
125
+ encoded = raw.encode("utf-8")
126
+ digest = "sha256:" + hashlib.sha256(encoded).hexdigest()
127
+ if len(encoded) > 131072 or body["sha256"] != digest:
128
+ raise ValueError("execution owner public view digest mismatch")
129
+ value = object_value(cast(JsonValue, json.loads(raw)), operation_id="execution public view")
130
+ if position.schema == _PORT_SCHEMA:
131
+ fields = {"schema_version", "kind", "sequence", "generation"}
132
+ fields |= {"scope", "execution"} if kind == "snapshot" else {"input_sha256", "input_bytes"}
133
+ value = _object(value, fields)
134
+ _integer(value.get("generation"))
135
+ if kind == "position":
136
+ original_digest = value.get("input_sha256")
137
+ if (
138
+ not isinstance(original_digest, str)
139
+ or not _DIGEST.fullmatch(original_digest)
140
+ or _integer(value.get("input_bytes")) == 0
141
+ ):
142
+ raise ValueError("execution owner position original invalid")
143
+ else:
144
+ object_value(value.get("execution"), operation_id="execution public view state")
145
+ if (
146
+ value.get("schema_version") != position.schema
147
+ or value.get("kind") != kind
148
+ or (
149
+ value.get("scope") != _scope(position.scope)
150
+ and not (
151
+ position.schema == _PORT_SCHEMA
152
+ and kind == "position"
153
+ and "scope" not in value
154
+ )
155
+ )
156
+ or _integer(value.get("sequence")) != position.sequence
157
+ ):
158
+ raise ValueError("execution owner public view binding mismatch")
159
+ return cls(position, raw, digest, value)
160
+
161
+
162
+ @dataclass(frozen=True, slots=True)
163
+ class ExecutionSnapshot:
164
+ snapshot: ExecutionReadValue
165
+ retention: ExecutionReadRetention
166
+
167
+ @classmethod
168
+ def from_wire(cls, value: JsonValue, scope: OwnerReadScope) -> ExecutionSnapshot:
169
+ body = _object(value, {"scope", "cursor", "snapshot", "retention"})
170
+ if body["scope"] != _scope(scope):
171
+ raise ValueError("execution owner snapshot scope mismatch")
172
+ position = ExecutionReadCursor.from_wire(body["cursor"], scope)
173
+ retention = ExecutionReadRetention.from_wire(body["retention"])
174
+ retention.contains(position)
175
+ return cls(ExecutionReadValue.from_wire(body["snapshot"], position, kind="snapshot"), retention)
176
+
177
+
178
+ @dataclass(frozen=True, slots=True)
179
+ class ExecutionEventPage:
180
+ events: tuple[ExecutionReadValue, ...]
181
+ next: ExecutionReadCursor
182
+ retention: ExecutionReadRetention
183
+
184
+ @classmethod
185
+ def from_wire(
186
+ cls, value: JsonValue, after: ExecutionReadCursor, limit: int
187
+ ) -> ExecutionEventPage:
188
+ body = _object(value, {"scope", "items", "next", "retention"})
189
+ if body["scope"] != _scope(after.scope):
190
+ raise ValueError("execution owner page scope mismatch")
191
+ rows = body["items"]
192
+ if not isinstance(rows, list) or len(rows) > limit:
193
+ raise ValueError("execution owner page exceeds requested bound")
194
+ retention = ExecutionReadRetention.from_wire(body["retention"])
195
+ retention.contains(after)
196
+ next_cursor = ExecutionReadCursor.from_wire(body["next"], after.scope)
197
+ if next_cursor.schema != after.schema:
198
+ raise ValueError("execution owner page changed view schema")
199
+ retention.contains(next_cursor)
200
+ events: list[ExecutionReadValue] = []
201
+ previous = after.sequence
202
+ for row in rows:
203
+ item = _object(row, {"cursor", "body"})
204
+ position = ExecutionReadCursor.from_wire(item["cursor"], after.scope)
205
+ if position.schema != after.schema:
206
+ raise ValueError("execution owner event changed view schema")
207
+ retention.contains(position)
208
+ if position.sequence <= previous:
209
+ raise ValueError("execution owner page did not advance")
210
+ events.append(ExecutionReadValue.from_wire(item["body"], position, kind="position"))
211
+ previous = position.sequence
212
+ if next_cursor.sequence != previous:
213
+ raise ValueError("execution owner continuation differs from last item")
214
+ return cls(tuple(events), next_cursor, retention)
215
+
216
+
217
+ def _query(after: ExecutionReadCursor, scope: OwnerReadScope, limit: int) -> JsonObject:
218
+ if after.scope != scope:
219
+ raise ValueError("execution owner cursor differs from reader scope")
220
+ if _integer(limit, maximum=256) == 0:
221
+ raise ValueError("execution owner page limit must be positive")
222
+ return {"after": after.event_id(), "limit": limit}
223
+
224
+
225
+ class ExecutionReads:
226
+ """Owner execution views; see testing/specifications/sdk/owner_reads.md."""
227
+
228
+ def __init__(self, reader: OwnerReadClient) -> None:
229
+ if reader.access.owner != "orchestra":
230
+ raise ValueError("execution reads require Orchestra owner access")
231
+ self._reader = reader
232
+
233
+ def snapshot(self) -> ExecutionSnapshot:
234
+ return ExecutionSnapshot.from_wire(
235
+ self._reader.read_json("/snapshot", query={"view": _VIEW}), self._reader.access.scope
236
+ )
237
+
238
+ def events(self, after: ExecutionReadCursor, *, limit: int = 128) -> ExecutionEventPage:
239
+ query = _query(after, self._reader.access.scope, limit)
240
+ return ExecutionEventPage.from_wire(self._reader.read_json("/events", query=query), after, limit)
241
+
242
+
243
+ class AsyncExecutionReads:
244
+ """Native async owner views; see testing/specifications/sdk/owner_reads.md."""
245
+
246
+ def __init__(self, reader: AsyncOwnerReadClient) -> None:
247
+ if reader.access.owner != "orchestra":
248
+ raise ValueError("execution reads require Orchestra owner access")
249
+ self._reader = reader
250
+
251
+ async def snapshot(self) -> ExecutionSnapshot:
252
+ return ExecutionSnapshot.from_wire(
253
+ await self._reader.read_json("/snapshot", query={"view": _VIEW}), self._reader.access.scope
254
+ )
255
+
256
+ async def events(self, after: ExecutionReadCursor, *, limit: int = 128) -> ExecutionEventPage:
257
+ query = _query(after, self._reader.access.scope, limit)
258
+ return ExecutionEventPage.from_wire(
259
+ await self._reader.read_json("/events", query=query), after, limit
260
+ )
@@ -11,8 +11,11 @@ from synth_ai.sdk.research.container_pools.api import ContainerPoolsAPI
11
11
  from synth_ai.sdk.research.environments import EnvironmentsAPI
12
12
  from synth_ai.sdk.research.experiments import ResearchExperimentsAPI
13
13
  from synth_ai.sdk.research.factories import FactoriesAPI
14
+ from synth_ai.sdk.research.hierarchy import HierarchyClient
15
+ from synth_ai.sdk.research.hierarchy_models import HierarchyPermission, HierarchyScope
14
16
  from synth_ai.sdk.research.image_releases import ImageReleasesAPI
15
17
  from synth_ai.sdk.research.knowledge import ResearchKnowledgeAPI
18
+ from synth_ai.sdk.research.owner_reads import Owner, OwnerReadClient, OwnerReadScope
16
19
  from synth_ai.sdk.research.projects import ResearchProjectsAPI
17
20
  from synth_ai.sdk.research.research_intern import ResearchInternAPI
18
21
  from synth_ai.sdk.research.scientific_records import ScientificRecordsAPI
@@ -145,6 +148,16 @@ class Client:
145
148
  )
146
149
  return self._session
147
150
 
151
+ def hierarchy(
152
+ self, *, scope: HierarchyScope, permissions: tuple[HierarchyPermission, ...] = ("read",)
153
+ ) -> HierarchyClient:
154
+ """Direct project owner API; see testing/specifications/sdk/hierarchy_owner.md."""
155
+ return self._core.hierarchy(scope=scope, permissions=permissions)
156
+
157
+ def owner_reads(self, *, owner: Owner, scope: OwnerReadScope) -> OwnerReadClient:
158
+ """Open scoped owner reads; see testing/specifications/sdk/owner_reads.md."""
159
+ return self._core.owner_reads(owner=owner, scope=scope)
160
+
148
161
  @property
149
162
  def advanced(self) -> ResearchAdvancedAPI:
150
163
  """Explicitly unstable operator capabilities outside the hero workflow."""