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.
- {synth_ai-0.22.2.dev689/synth_ai.egg-info → synth_ai-0.22.2.dev690}/PKG-INFO +1 -1
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/pyproject.toml +1 -1
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/async_transport.py +3 -2
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/transport.py +4 -3
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/__init__.py +2 -0
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/__init__.py +69 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced_swarms.py +19 -6
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/client.py +56 -1
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/execution_reads.py +260 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/facade.py +13 -0
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/hierarchy.py +552 -0
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/hierarchy_models.py +474 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/operations.py +78 -0
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/owner_reads.py +341 -0
- synth_ai-0.22.2.dev690/synth_ai/sdk/research/planning_reads.py +331 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/projects.py +4 -1
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/swarms.py +5 -1
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690/synth_ai.egg-info}/PKG-INFO +1 -1
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/SOURCES.txt +5 -0
- synth_ai-0.22.2.dev689/synth_ai/sdk/research/__init__.py +0 -26
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/LICENSE +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/MANIFEST.in +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/index-v1.json +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/messaging-v1.json +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/openapi/research-v1.json +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/setup.cfg +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/setup.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/__main__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/AGENTS.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/__main__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/index.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/main.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_image_releases.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/research_projects.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/utils/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/cli/utils/research_launch.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/client.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/auth/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/auth/credentials.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/json_value.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/contracts/pagination.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/errors.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/request.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/retry.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/http/streaming.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/local_files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/research/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/env.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/log_filter.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/paths.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/core/utils/urls.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/__main__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/objective_tools.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/registry.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/request_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/server.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/approvals.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/artifacts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/datasets.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/exports.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/factories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/factory_results.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/image_releases.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/index.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/index_qa.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/integrations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/intern_program.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/launch_schemas.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/local_files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/logs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/outputs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/policy_schemas.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/progress.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/project_data.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/projects.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/prs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/readiness.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/repos.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/research_intern.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/resource_reads.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/resources.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/runs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/scientific_records.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/trained_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/usage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/visuals.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/mcp/research/tools/workspace_inputs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/pools.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/py.typed +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/AGENT_SETUP_PROMPT.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/agent_policy.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/artifacts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/catalog.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/catalogue.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/classification.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/client.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/contributions.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/errors.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/forge_notices.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/intake.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/lifecycle.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/local_files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/manifest.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/oauth.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/package.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public_corpus.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/public_search.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_checks.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_preflight.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/qa_reviews.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/build.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/capture.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research/release.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/research_intake.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/retry.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/rights.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scientific_provenance.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scope_errors.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/scopes.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/search.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/submission.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/timeouts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/transfer.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/upload_session.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/usage_accounting.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/value.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/index/wallet_search.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/client.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/messaging/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/client.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/optimizers/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/pagination.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/crypto.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/env.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/_internal/urls.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/account.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/advanced_factories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/artifacts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/auth.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/api.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/operations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/container_pools/packaging.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_activity_wire.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_environment_wire.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_transcript_wire.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/_wire.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/activity.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/activity_items.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/actor_images.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/billing.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/canonical_usage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/checkpoints.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/cloud_deployment_claims.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/cloud_deployments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/common.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/dataset_revisions.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/deliveries.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/dev_environment_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/economics.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/environment_manifest.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/experiment_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_lenses.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_operations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/factory_role_receipts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/failure.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/contracts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/evaluation.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/exports.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/operations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/records.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/resources.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge/schema.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge_citations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/forge_uploads.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/image_releases.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_authority.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_blockers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_grants.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_program.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_resources.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/intern_usage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/limit_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/local_execution_profile.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/native_attachment.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/native_result_outcome.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/operator_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_data.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_runtime.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_workspace.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/project_workspace_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/projects.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/promotions.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/research_intern.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/resource_reads.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/resource_settlement.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_authority.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_control.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_diagnostics.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_events.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_execution.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_launch.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_observability.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_state.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/run_timeline.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_image.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_intent.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_stream.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/runtime_stream_snapshot.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/scientific_citations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/scientific_integrity.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_actor_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_actor_policy_data.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_harnesses.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_kinds.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_agent_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_branching.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_credential_providers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_environment_kinds.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_evidence_obligations.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_funding_sources.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_horizons.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_host_kinds.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_inference_providers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_network_topology.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_providers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_resource_kinds.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_roles.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_run_policy.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runbooks.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runnable_project.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_runtime_kinds.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_tool_providers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/smr_work_modes.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/status.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_controls.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_history.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_rollouts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarm_tasks.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/swarms.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/tag.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/traces.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/transcript.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/types.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/usage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/visuals.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/wire_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/wire_models_README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/work_products.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/contracts/workspaces.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/economics.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/efforts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/errors.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/events.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/experiments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/factories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/factory_storage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/image_releases.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_authority.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_blockers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/intern_program.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/knowledge.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_data.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_deliveries.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/project_workspaces.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/public.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/readouts.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/research_intern.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/resource_reads.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/scientific_records.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/secrets.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/README.md +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_base.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_client_helpers.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/_run_authority_mixin.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/approvals.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/billing.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/client.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/cloud_deployments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/config.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/cost.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/datasets.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/dev_environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/directory_inputs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/environments.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/exports.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/factories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/factory_evidence.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/files.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/github.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/image_releases.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/images.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/logs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/outputs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/progress.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/project.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/projects.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/prs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/readiness.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/repositories.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/runs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/secrets.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/setup.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/tag.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/trained_models.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/transport.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/usage.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/work_products.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/session/workspace_inputs.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/surface_parity.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/traces.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/__init__.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/http.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/transport/pagination.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/version.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/visuals.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai/sdk/research/wiki.py +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/dependency_links.txt +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/entry_points.txt +0 -0
- {synth_ai-0.22.2.dev689 → synth_ai-0.22.2.dev690}/synth_ai.egg-info/requires.txt +0 -0
- {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
|
[project]
|
|
2
2
|
name = "synth-ai"
|
|
3
|
-
version = "0.22.2.
|
|
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=
|
|
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=
|
|
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."""
|