mainsequence 4.4.30__tar.gz → 4.4.32__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 (160) hide show
  1. {mainsequence-4.4.30 → mainsequence-4.4.32}/PKG-INFO +1 -1
  2. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +77 -0
  3. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/api.py +2 -0
  4. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/cli.py +54 -23
  5. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/base.py +1 -0
  6. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/models_helpers.py +177 -6
  7. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/PKG-INFO +1 -1
  8. {mainsequence-4.4.30 → mainsequence-4.4.32}/pyproject.toml +1 -1
  9. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_cli.py +13 -10
  10. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_filter_normalization.py +239 -9
  11. {mainsequence-4.4.30 → mainsequence-4.4.32}/LICENSE +0 -0
  12. {mainsequence-4.4.30 → mainsequence-4.4.32}/README.md +0 -0
  13. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/AGENTS.md +0 -0
  14. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  15. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  16. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  17. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  18. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  19. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/widgets/app_components/SKILL.md +0 -0
  20. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/widgets/tables/SKILL.md +0 -0
  21. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/widgets/tabular_transform/SKILL.md +0 -0
  22. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  23. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  24. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  25. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  26. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  27. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  28. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  29. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  30. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  31. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  32. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  33. {mainsequence-4.4.30 → mainsequence-4.4.32}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  34. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/__init__.py +0 -0
  35. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/__main__.py +0 -0
  36. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/bootstrap.py +0 -0
  37. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/__init__.py +0 -0
  38. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/browser_auth.py +0 -0
  39. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/config.py +0 -0
  40. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/docker_utils.py +0 -0
  41. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/doctor.py +0 -0
  42. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/local_ops.py +0 -0
  43. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/migrations.py +0 -0
  44. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/model_filters.py +0 -0
  45. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/project_status.py +0 -0
  46. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/pydantic_cli.py +0 -0
  47. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/sdk_utils.py +0 -0
  48. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/ssh_utils.py +0 -0
  49. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/cli/ui.py +0 -0
  50. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/__init__.py +0 -0
  51. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/agent_runtime_models.py +0 -0
  52. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/client.py +0 -0
  53. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/__init__.py +0 -0
  54. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/app_component.py +0 -0
  55. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/connections.py +0 -0
  56. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/__init__.py +0 -0
  57. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/adapter_from_api.py +0 -0
  58. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/response_mapping.py +0 -0
  59. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/table_visuals.py +0 -0
  60. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/tabular.py +0 -0
  61. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/contracts/ui.py +0 -0
  62. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/data_models.py +0 -0
  63. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/providers/__init__.py +0 -0
  64. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/providers/adapter_from_api.py +0 -0
  65. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/__init__.py +0 -0
  66. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/bindings.py +0 -0
  67. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/connection_query.py +0 -0
  68. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/registry.py +0 -0
  69. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/table.py +0 -0
  70. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/widgets/tabular_transform.py +0 -0
  71. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/workspace.py +0 -0
  72. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  73. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/workspaces/__init__.py +0 -0
  74. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/workspaces/documents.py +0 -0
  75. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/command_center/workspaces/mounted_widgets.py +0 -0
  76. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/compute_validation.py +0 -0
  77. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  78. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  79. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  80. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  81. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/dtype_codec.py +0 -0
  82. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/exceptions.py +0 -0
  83. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/fastapi/__init__.py +0 -0
  84. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/fastapi/auth.py +0 -0
  85. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/metatables/__init__.py +0 -0
  86. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/metatables/core.py +0 -0
  87. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/models_foundry.py +0 -0
  88. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/models_user.py +0 -0
  89. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/client/utils.py +0 -0
  90. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/defaults.py +0 -0
  91. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/instrumentation/__init__.py +0 -0
  92. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/instrumentation/utils.py +0 -0
  93. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/logconf.py +0 -0
  94. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/__init__.py +0 -0
  95. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/__main__.py +0 -0
  96. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  97. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  98. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  99. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  100. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
  101. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  102. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  103. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  104. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  105. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  106. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/future_registry.py +0 -0
  107. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/hashing.py +0 -0
  108. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  109. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  110. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/env.py +0 -0
  111. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/provider.py +0 -0
  112. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/registry.py +0 -0
  113. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  114. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  115. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  116. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  117. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  118. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/schema_names.py +0 -0
  119. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  120. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/runtime_flags.py +0 -0
  121. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence/scaffold_skills.py +0 -0
  122. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/SOURCES.txt +0 -0
  123. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/dependency_links.txt +0 -0
  124. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/entry_points.txt +0 -0
  125. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/requires.txt +0 -0
  126. {mainsequence-4.4.30 → mainsequence-4.4.32}/mainsequence.egg-info/top_level.txt +0 -0
  127. {mainsequence-4.4.30 → mainsequence-4.4.32}/setup.cfg +0 -0
  128. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_auth_precedence.py +0 -0
  129. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_build_operations_hashing.py +0 -0
  130. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_cli_browser_auth.py +0 -0
  131. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_cli_migrations.py +0 -0
  132. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_client.py +0 -0
  133. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_command_center_app_component_models.py +0 -0
  134. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_command_center_data_models.py +0 -0
  135. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_command_center_models.py +0 -0
  136. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_command_center_table_contracts.py +0 -0
  137. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_command_center_tabular_transform.py +0 -0
  138. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  139. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_data_node_storage_dimension_queries.py +0 -0
  140. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_data_node_update_flow.py +0 -0
  141. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_dependency_extras.py +0 -0
  142. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_duckdb_interface_dimensions.py +0 -0
  143. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_instrumentation.py +0 -0
  144. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_logconf.py +0 -0
  145. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_meta_table_migrations.py +0 -0
  146. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_meta_tables_client_models.py +0 -0
  147. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  148. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_models_user_request_bound_auth.py +0 -0
  149. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_pod_project_resolution.py +0 -0
  150. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_project_batch_jobs_from_file.py +0 -0
  151. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_run_configuration.py +0 -0
  152. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_scaffold_skills.py +0 -0
  153. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_schema_names.py +0 -0
  154. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_secret_client_model.py +0 -0
  155. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_source_table_configuration.py +0 -0
  156. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_sqlite_interface_dimensions.py +0 -0
  157. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_update_runner_uid_runtime.py +0 -0
  158. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_update_statistics.py +0 -0
  159. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_update_uid_guards.py +0 -0
  160. {mainsequence-4.4.30 → mainsequence-4.4.32}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.30
3
+ Version: 4.4.32
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -31,6 +31,8 @@ This skill is for:
31
31
  - freeze jobs to a project image
32
32
  - inspect job runs and logs
33
33
  - reason about project resources and resource releases
34
+ - decide whether a `ResourceRelease` should opt into `automatic_deployment`
35
+ - inspect automatic deployment run state for release rotations
34
36
  - create or review Streamlit dashboard deployment through project resources and `streamlit_dashboard` releases
35
37
  - review Artifact-based workflows in operational pipelines
36
38
 
@@ -96,6 +98,7 @@ Before changing orchestration or release behavior, collect or infer:
96
98
  - direct CLI/client job creation
97
99
  - repository-managed batch scheduling
98
100
  - Streamlit dashboard release creation
101
+ - whether a `ResourceRelease` should be manually pinned or opted into repository-sync automatic deployment
99
102
  - whether Artifact inputs or outputs are part of the run
100
103
  - whether the job should be reproducible against a pinned image
101
104
  - for Streamlit dashboard deployment, the `README.md` resource next to `app.py`
@@ -113,6 +116,7 @@ For every non-trivial orchestration task, decide:
113
116
  5. Does the workflow depend on Artifacts?
114
117
  6. Is the task actually a release/resource problem instead of only a job problem?
115
118
  7. For Streamlit dashboard deployment, do the selected app resource, README resource, and project image all refer to the intended pushed commit?
119
+ 8. For a `ResourceRelease`, should repository sync be allowed to rotate the release automatically through `automatic_deployment`?
116
120
 
117
121
  ## Build Rules
118
122
 
@@ -218,6 +222,71 @@ That workflow exists to validate the contract in `apiTargetMode: "mock-json"` be
218
222
 
219
223
  Only publish the real FastAPI API after the AppComponent contract is stable.
220
224
 
225
+ ### 6.3 Automatic ResourceRelease deployment
226
+
227
+ `automatic_deployment` is the automated deployment opt-in flag on a `ResourceRelease`. It means repository synchronization can rotate an existing release to the latest synced project commit for the same resource path.
228
+
229
+ When `automatic_deployment=True`, repository-sync events may create a `ResourceReleaseAutomaticDeploymentRun` with source `repository_event`. That run:
230
+
231
+ - reads the project's current synced commit
232
+ - resolves the current project resource at the release's existing resource path
233
+ - resolves the current adjacent `README.md` when the release kind requires one, such as Streamlit dashboards
234
+ - creates or resolves the project image for that commit
235
+ - redeploys the existing release to the current resource, README, and project image
236
+ - records status, current step, revision context, image/resource context, result, and errors on the deployment run
237
+
238
+ This is not a local development shortcut. It does not deploy unpushed local files. The repository must be pushed, the project repository must be synced, and project resource discovery must find the resource at the same path for the current commit.
239
+
240
+ Enable `automatic_deployment` only when:
241
+
242
+ - the release should track the project's synced repository version
243
+ - the resource path is stable across commits
244
+ - the current synced branch/version is an acceptable deployment source for that release
245
+ - dashboard README requirements are satisfied for the current commit
246
+ - the team accepts CI/CD-style rotation for this release
247
+
248
+ Keep `automatic_deployment` disabled when:
249
+
250
+ - the release must stay pinned to a manually selected image or resource version
251
+ - each release rotation needs human approval
252
+ - the resource path or entrypoint is still moving
253
+ - API or widget contracts are not stable enough for automatic rotation
254
+ - the current branch/project sync target is not the intended deployment source
255
+
256
+ Create opted-in releases with the CLI flags that exist:
257
+
258
+ - `mainsequence project project_resource create_dashboard --automatic-deployment`
259
+ - `mainsequence project project_resource create_fastapi --automatic-deployment`
260
+ - use `--no-automatic-deployment` when the decision is explicitly to keep the release pinned/manual
261
+
262
+ The SDK surface also accepts:
263
+
264
+ - `ProjectResource.create_dashboard(..., automatic_deployment=True)`
265
+ - `ProjectResource.create_fastapi(..., automatic_deployment=True)`
266
+ - `ResourceRelease.create(..., automatic_deployment=True)`
267
+ - `ResourceRelease.deploy_current_version()` for an SDK-triggered manual deployment run
268
+
269
+ Do not claim there is a CLI command for `deploy_current_version` unless the local CLI actually exposes one. In this SDK, the manual detail action is available through the client model.
270
+
271
+ Automatic deployment runs can have these statuses:
272
+
273
+ - `pending`
274
+ - `running`
275
+ - `waiting_project_image`
276
+ - `waiting_runtime_ready`
277
+ - `no_action`
278
+ - `deployed`
279
+ - `skipped`
280
+ - `blocked`
281
+ - `failed`
282
+
283
+ Important blocked/skipped cases include:
284
+
285
+ - `automatic_deployment_disabled`: repository-event rotation skipped because the release is not opted in
286
+ - `project_current_version_missing`: the project has no current synced version
287
+ - `resource_missing_for_current_commit`: no resource exists at the release path for the latest synced commit
288
+ - `readme_missing_for_current_commit`: a dashboard-style release needs an adjacent README for the current commit
289
+
221
290
  ## Review Rules
222
291
 
223
292
  When reviewing an orchestration task, look for:
@@ -230,6 +299,9 @@ When reviewing an orchestration task, look for:
230
299
  - unsafe use of `--strict`
231
300
  - workflows depending on laptop-specific file paths instead of Artifacts
232
301
  - image or release work being used as a substitute for predeployment AppComponent/API contract validation
302
+ - `automatic_deployment` enabled without an explicit decision about repository-sync CI/CD rotation
303
+ - assumptions that automatic deployment will deploy local unpushed changes
304
+ - automatic release rotation where the resource path or dashboard README is not stable
233
305
  - Streamlit dashboard deployment work drifting into app design or UI implementation ownership
234
306
  - tasks that are really resource/release problems rather than simple job problems
235
307
 
@@ -248,6 +320,9 @@ Do not claim success until you have checked:
248
320
  - runs and logs were inspected when execution success matters
249
321
  - resources and releases were verified when deployment success matters
250
322
  - Streamlit dashboard releases use the intended app resource, README resource, image, and `streamlit_dashboard` release kind
323
+ - `automatic_deployment` is intentionally enabled or disabled on each release
324
+ - automatic deployment runs were inspected when repository-sync rotation matters
325
+ - automatic deployment results match the intended commit, resource, README, image, and terminal status
251
326
  - Command Center-facing API publishing is not being used just to test AppComponent UX that should have been validated first in `mock-json` mode
252
327
 
253
328
  If the workflow uses `scheduled_jobs.yaml`, also check:
@@ -270,6 +345,8 @@ If the workflow uses Artifacts, also check:
270
345
  - strict batch sync could delete jobs and the desired state is not explicit
271
346
  - the workflow depends on local file paths that should be platform Artifacts
272
347
  - the real need is AppComponent/API contract validation before deployment rather than release execution itself
348
+ - automatic deployment is requested but the deployment source branch/current synced project version is unclear
349
+ - automatic deployment is requested but the resource path or required README is not stable
273
350
  - the task is actually about RBAC policy rather than orchestration
274
351
  - the task is actually about producer semantics rather than platform execution
275
352
 
@@ -2635,6 +2635,7 @@ def create_project_resource_release(
2635
2635
  gpu_request: str | int | None = None,
2636
2636
  gpu_type: str | None = None,
2637
2637
  spot: bool | None = None,
2638
+ automatic_deployment: bool | None = None,
2638
2639
  timeout: int | None = None,
2639
2640
  ) -> dict[str, Any]:
2640
2641
  """
@@ -2699,6 +2700,7 @@ def create_project_resource_release(
2699
2700
  "gpu_request": gpu_request,
2700
2701
  "gpu_type": gpu_type,
2701
2702
  "spot": spot,
2703
+ "automatic_deployment": automatic_deployment,
2702
2704
  "timeout": timeout,
2703
2705
  }
2704
2706
 
@@ -3376,27 +3376,35 @@ def _format_shareable_permission_change(payload: dict[str, object]) -> list[tupl
3376
3376
  ("Explicit Can Edit", str(payload.get("explicit_can_edit"))),
3377
3377
  (
3378
3378
  "Explicit View User IDs",
3379
- ", ".join(str(item) for item in explicit_view_ids)
3380
- if isinstance(explicit_view_ids, list)
3381
- else "-",
3379
+ (
3380
+ ", ".join(str(item) for item in explicit_view_ids)
3381
+ if isinstance(explicit_view_ids, list)
3382
+ else "-"
3383
+ ),
3382
3384
  ),
3383
3385
  (
3384
3386
  "Explicit Edit User IDs",
3385
- ", ".join(str(item) for item in explicit_edit_ids)
3386
- if isinstance(explicit_edit_ids, list)
3387
- else "-",
3387
+ (
3388
+ ", ".join(str(item) for item in explicit_edit_ids)
3389
+ if isinstance(explicit_edit_ids, list)
3390
+ else "-"
3391
+ ),
3388
3392
  ),
3389
3393
  (
3390
3394
  "Explicit View Team IDs",
3391
- ", ".join(str(item) for item in explicit_view_team_ids)
3392
- if isinstance(explicit_view_team_ids, list)
3393
- else "-",
3395
+ (
3396
+ ", ".join(str(item) for item in explicit_view_team_ids)
3397
+ if isinstance(explicit_view_team_ids, list)
3398
+ else "-"
3399
+ ),
3394
3400
  ),
3395
3401
  (
3396
3402
  "Explicit Edit Team IDs",
3397
- ", ".join(str(item) for item in explicit_edit_team_ids)
3398
- if isinstance(explicit_edit_team_ids, list)
3399
- else "-",
3403
+ (
3404
+ ", ".join(str(item) for item in explicit_edit_team_ids)
3405
+ if isinstance(explicit_edit_team_ids, list)
3406
+ else "-"
3407
+ ),
3400
3408
  ),
3401
3409
  ]
3402
3410
 
@@ -3610,9 +3618,11 @@ def _agent_list_impl(
3610
3618
  str(agent_payload.get("uid") or "-"),
3611
3619
  str(agent_payload.get("name") or "-"),
3612
3620
  str(agent_payload.get("status") or "-"),
3613
- ", ".join(str(item) for item in labels)
3614
- if isinstance(labels, list) and labels
3615
- else "-",
3621
+ (
3622
+ ", ".join(str(item) for item in labels)
3623
+ if isinstance(labels, list) and labels
3624
+ else "-"
3625
+ ),
3616
3626
  str(agent_payload.get("llm_provider") or "-"),
3617
3627
  str(agent_payload.get("llm_model") or "-"),
3618
3628
  str(agent_payload.get("engine_name") or "-"),
@@ -3929,9 +3939,9 @@ def _agent_session_a2a_send_impl(
3929
3939
  attachments = [
3930
3940
  {
3931
3941
  "path": str(path),
3932
- "media_type": attachment_media_types[index]
3933
- if attachment_media_types
3934
- else "application/pdf",
3942
+ "media_type": (
3943
+ attachment_media_types[index] if attachment_media_types else "application/pdf"
3944
+ ),
3935
3945
  }
3936
3946
  for index, path in enumerate(attachment_paths)
3937
3947
  ]
@@ -4040,8 +4050,7 @@ def _agent_session_list_impl(
4040
4050
  )
4041
4051
  if agent_uid and any(key in filters for key in ("agent_uid", "agent_uid__in")):
4042
4052
  error(
4043
- "Do not pass `--filter agent_uid=...` with `--agent-uid`. "
4044
- "Use only one agent scope."
4053
+ "Do not pass `--filter agent_uid=...` with `--agent-uid`. " "Use only one agent scope."
4045
4054
  )
4046
4055
  raise typer.Exit(1)
4047
4056
 
@@ -8391,9 +8400,9 @@ def data_node_storage_search_cmd(
8391
8400
  {
8392
8401
  "query": q,
8393
8402
  "mode": normalized_mode,
8394
- "description": description_payload
8395
- if normalized_mode in {"both", "description"}
8396
- else None,
8403
+ "description": (
8404
+ description_payload if normalized_mode in {"both", "description"} else None
8405
+ ),
8397
8406
  "column": column_payload if normalized_mode in {"both", "column"} else None,
8398
8407
  "total_matches": total_matches,
8399
8408
  }
@@ -9916,6 +9925,7 @@ def _project_resource_release_create_impl(
9916
9925
  gpu_request: str | None,
9917
9926
  gpu_type: str | None,
9918
9927
  spot: bool | None,
9928
+ automatic_deployment: bool | None,
9919
9929
  timeout: int | None,
9920
9930
  ) -> None:
9921
9931
  _require_login()
@@ -10039,6 +10049,7 @@ def _project_resource_release_create_impl(
10039
10049
  gpu_request=gpu_request,
10040
10050
  gpu_type=gpu_type,
10041
10051
  spot=spot,
10052
+ automatic_deployment=automatic_deployment,
10042
10053
  timeout=timeout,
10043
10054
  )
10044
10055
  except ApiError as e:
@@ -10064,6 +10075,14 @@ def _project_resource_release_create_impl(
10064
10075
  ("GPU Request", str(created.get("gpu_request") or gpu_request or "-")),
10065
10076
  ("GPU Type", str(created.get("gpu_type") or gpu_type or "-")),
10066
10077
  ("Spot", str(created.get("spot") if created.get("spot") is not None else spot).lower()),
10078
+ (
10079
+ "Automatic Deployment",
10080
+ str(
10081
+ created.get("automatic_deployment")
10082
+ if created.get("automatic_deployment") is not None
10083
+ else bool(automatic_deployment)
10084
+ ).lower(),
10085
+ ),
10067
10086
  ],
10068
10087
  )
10069
10088
 
@@ -10094,6 +10113,11 @@ def project_project_resource_create_dashboard_cmd(
10094
10113
  spot: bool | None = typer.Option(
10095
10114
  None, "--spot/--no-spot", help="Whether to prefer spot capacity."
10096
10115
  ),
10116
+ automatic_deployment: bool | None = typer.Option(
10117
+ None,
10118
+ "--automatic-deployment/--no-automatic-deployment",
10119
+ help="Opt the release into repository-sync CI/CD rotation.",
10120
+ ),
10097
10121
  timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
10098
10122
  ):
10099
10123
  """
@@ -10114,6 +10138,7 @@ def project_project_resource_create_dashboard_cmd(
10114
10138
  gpu_request=gpu_request,
10115
10139
  gpu_type=gpu_type,
10116
10140
  spot=spot,
10141
+ automatic_deployment=automatic_deployment,
10117
10142
  timeout=timeout,
10118
10143
  )
10119
10144
 
@@ -10144,6 +10169,11 @@ def project_project_resource_create_fastapi_cmd(
10144
10169
  spot: bool | None = typer.Option(
10145
10170
  None, "--spot/--no-spot", help="Whether to prefer spot capacity."
10146
10171
  ),
10172
+ automatic_deployment: bool | None = typer.Option(
10173
+ None,
10174
+ "--automatic-deployment/--no-automatic-deployment",
10175
+ help="Opt the release into repository-sync CI/CD rotation.",
10176
+ ),
10147
10177
  timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
10148
10178
  ):
10149
10179
  """
@@ -10164,6 +10194,7 @@ def project_project_resource_create_fastapi_cmd(
10164
10194
  gpu_request=gpu_request,
10165
10195
  gpu_type=gpu_type,
10166
10196
  spot=spot,
10197
+ automatic_deployment=automatic_deployment,
10167
10198
  timeout=timeout,
10168
10199
  )
10169
10200
 
@@ -101,6 +101,7 @@ class BaseObjectOrm:
101
101
  "GithubOrganization": "pods/github-organization",
102
102
  "ProjectResource": "pods/project-resource",
103
103
  "ResourceRelease": "pods/resource-release",
104
+ "ResourceReleaseAutomaticDeploymentRun": "pods/resource-release-automatic-deployment-runs",
104
105
  "Bucket": "pods/bucket",
105
106
  }
106
107
  ROOT_URL = API_ENDPOINT
@@ -7,7 +7,7 @@ from collections.abc import Collection
7
7
  from decimal import Decimal
8
8
  from enum import Enum
9
9
  from pathlib import PurePosixPath
10
- from typing import Any, ClassVar, Literal, Union
10
+ from typing import Any, ClassVar, Literal
11
11
  from uuid import UUID
12
12
 
13
13
  import yaml
@@ -78,7 +78,7 @@ class IntervalSchedule(BaseModel):
78
78
  )
79
79
 
80
80
 
81
- Schedule = Union[CrontabSchedule, IntervalSchedule]
81
+ Schedule = CrontabSchedule | IntervalSchedule
82
82
 
83
83
 
84
84
  class PeriodicTask(BasePydanticModel):
@@ -989,11 +989,14 @@ class ProjectResource(BaseObjectOrm, BasePydanticModel):
989
989
  description="Display name of the resource discovered in the project's repository.",
990
990
  examples=["analytics_dashboard.py"],
991
991
  )
992
- resource_type: Literal["dashboard", "fastapi", "markdown"] | None = Field(
992
+ resource_type: Literal["dashboard", "fastapi", "markdown", "agent"] | None = Field(
993
993
  None,
994
994
  title="Resource Type",
995
- description="Type of the project resource. Allowed values are `dashboard`, `fastapi`, and `markdown`.",
996
- examples=["dashboard", "fastapi", "markdown"],
995
+ description=(
996
+ "Type of the project resource. Allowed values are `dashboard`, `fastapi`, "
997
+ "`markdown`, and `agent`."
998
+ ),
999
+ examples=["dashboard", "fastapi", "markdown", "agent"],
997
1000
  )
998
1001
  code: str | None = Field(
999
1002
  None,
@@ -1047,9 +1050,19 @@ class ProjectResource(BaseObjectOrm, BasePydanticModel):
1047
1050
  **kwargs,
1048
1051
  ) -> ResourceRelease:
1049
1052
  resource_uid = self._public_detail_reference()
1053
+ if "related_image_id" in kwargs and "related_image_uid" not in kwargs:
1054
+ kwargs["related_image_uid"] = kwargs.pop("related_image_id")
1055
+
1056
+ readme_resource_id = kwargs.pop("readme_resource_id", None)
1057
+ if readme_resource_id is not None:
1058
+ raise ValueError(
1059
+ "readme_resource_id is not supported by ResourceRelease.create(); "
1060
+ "README resources are resolved by the backend."
1061
+ )
1062
+
1050
1063
  kwargs["resource_uid"] = resource_uid
1051
1064
  kwargs["release_kind"] = release_kind.value
1052
- return ResourceRelease.create(timeout=timeout, files=files, *args, **kwargs)
1065
+ return ResourceRelease.create(*args, timeout=timeout, files=files, **kwargs)
1053
1066
 
1054
1067
  def create_dashboard(self, timeout=None, files=None, *args, **kwargs) -> ResourceRelease:
1055
1068
  return self._create_release(
@@ -1069,13 +1082,36 @@ class ProjectResource(BaseObjectOrm, BasePydanticModel):
1069
1082
  **kwargs,
1070
1083
  )
1071
1084
 
1085
+ def create_agent(self, timeout=None, files=None, *args, **kwargs) -> ResourceRelease:
1086
+ return self._create_release(
1087
+ ResourceReleaseKind.AGENT,
1088
+ timeout,
1089
+ files,
1090
+ *args,
1091
+ **kwargs,
1092
+ )
1093
+
1072
1094
 
1073
1095
  class ResourceReleaseKind(str, Enum):
1074
1096
  STREAMLIT_DASHBOARD = "streamlit_dashboard"
1097
+ AGENT = "agent"
1075
1098
  FAST_API = "fastapi"
1076
1099
 
1077
1100
 
1078
1101
  class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
1102
+ FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
1103
+ "uid": ["exact", "in"],
1104
+ "resource__uid": ["exact", "in"],
1105
+ "related_job__uid": ["exact", "in"],
1106
+ "release_kind": ["exact", "in"],
1107
+ }
1108
+ FILTER_VALUE_NORMALIZERS: ClassVar[dict[str, str]] = {
1109
+ "uid": "uid",
1110
+ "resource__uid": "uid",
1111
+ "related_job__uid": "uid",
1112
+ "release_kind": "str",
1113
+ }
1114
+
1079
1115
  uid: str | None = Field(
1080
1116
  None,
1081
1117
  title="Resource Release UID",
@@ -1141,6 +1177,15 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
1141
1177
  description="Whether the release should prefer spot or preemptible capacity.",
1142
1178
  examples=[False, True],
1143
1179
  )
1180
+ automatic_deployment: bool = Field(
1181
+ default=False,
1182
+ title="Automatic Deployment",
1183
+ description=(
1184
+ "Whether repository synchronization should rotate this release to the "
1185
+ "current project commit."
1186
+ ),
1187
+ examples=[False, True],
1188
+ )
1144
1189
 
1145
1190
  @classmethod
1146
1191
  def create(
@@ -1154,6 +1199,7 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
1154
1199
  gpu_request: str | int | None = None,
1155
1200
  gpu_type: str | None = None,
1156
1201
  spot: bool | None = None,
1202
+ automatic_deployment: bool | None = None,
1157
1203
  timeout: int | None = None,
1158
1204
  files=None,
1159
1205
  ) -> ResourceRelease:
@@ -1198,6 +1244,8 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
1198
1244
  payload["gpu_type"] = normalized_compute["gpu_type"]
1199
1245
  if spot is not None:
1200
1246
  payload["spot"] = bool(spot)
1247
+ if automatic_deployment is not None:
1248
+ payload["automatic_deployment"] = bool(automatic_deployment)
1201
1249
 
1202
1250
  request_payload = {"json": cls.serialize_for_json(payload)}
1203
1251
  if files:
@@ -1216,3 +1264,126 @@ class ResourceRelease(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
1216
1264
  raise_for_response(r, payload=request_payload)
1217
1265
 
1218
1266
  return cls(**r.json())
1267
+
1268
+ def deploy_current_version(
1269
+ self,
1270
+ *,
1271
+ timeout: int | float | tuple[float, float] | None = None,
1272
+ ) -> ResourceReleaseAutomaticDeploymentRun:
1273
+ data = self._request_detail_action(
1274
+ r_type="POST",
1275
+ action_name="deploy-current-version",
1276
+ payload={},
1277
+ timeout=timeout,
1278
+ expected_statuses=(200, 202),
1279
+ )
1280
+ return ResourceReleaseAutomaticDeploymentRun(**data)
1281
+
1282
+
1283
+ class ResourceReleaseAutomaticDeploymentRun(BaseObjectOrm, BasePydanticModel):
1284
+ FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
1285
+ "resource_release__uid": ["exact", "in"],
1286
+ "status": ["exact", "in"],
1287
+ "release_kind": ["exact", "in"],
1288
+ "automatic_deployment_source": ["exact", "in"],
1289
+ }
1290
+ FILTER_VALUE_NORMALIZERS: ClassVar[dict[str, str]] = {
1291
+ "resource_release__uid": "uid",
1292
+ "status": "str",
1293
+ "release_kind": "str",
1294
+ "automatic_deployment_source": "str",
1295
+ }
1296
+
1297
+ STATUS_PENDING: ClassVar[str] = "pending"
1298
+ STATUS_RUNNING: ClassVar[str] = "running"
1299
+ STATUS_WAITING_PROJECT_IMAGE: ClassVar[str] = "waiting_project_image"
1300
+ STATUS_WAITING_RUNTIME_READY: ClassVar[str] = "waiting_runtime_ready"
1301
+ STATUS_NO_ACTION: ClassVar[str] = "no_action"
1302
+ STATUS_DEPLOYED: ClassVar[str] = "deployed"
1303
+ STATUS_SKIPPED: ClassVar[str] = "skipped"
1304
+ STATUS_BLOCKED: ClassVar[str] = "blocked"
1305
+ STATUS_FAILED: ClassVar[str] = "failed"
1306
+
1307
+ SOURCE_MANUAL: ClassVar[str] = "manual"
1308
+ SOURCE_REPOSITORY_EVENT: ClassVar[str] = "repository_event"
1309
+
1310
+ uid: str | None = Field(
1311
+ None,
1312
+ title="Resource Release Automatic Deployment Run UID",
1313
+ description="Public UID of the automatic deployment run.",
1314
+ )
1315
+ resource_release_uid: str | None = Field(
1316
+ None,
1317
+ title="Resource Release UID",
1318
+ description="Public UID snapshot of the resource release targeted by this run.",
1319
+ )
1320
+ resource_release_name: str = Field(
1321
+ default="",
1322
+ title="Resource Release Name",
1323
+ description="Display-name snapshot of the targeted resource release.",
1324
+ )
1325
+ release_kind: ResourceReleaseKind | str | None = Field(
1326
+ None,
1327
+ title="Release Kind",
1328
+ description="Resource release kind targeted by this run.",
1329
+ )
1330
+ status: str | None = Field(
1331
+ None,
1332
+ title="Status",
1333
+ description="Deployment run status.",
1334
+ )
1335
+ current_step: str = Field(
1336
+ default="",
1337
+ title="Current Step",
1338
+ description="Current orchestration step key.",
1339
+ )
1340
+ automatic_deployment_source: str | None = Field(
1341
+ None,
1342
+ title="Automatic Deployment Source",
1343
+ description="Run trigger source, for example manual or repository_event.",
1344
+ )
1345
+ revision_context: dict[str, Any] = Field(
1346
+ default_factory=dict,
1347
+ title="Revision Context",
1348
+ description="Stable project/revision/resource context for the run.",
1349
+ )
1350
+ trigger_context: dict[str, Any] = Field(
1351
+ default_factory=dict,
1352
+ title="Trigger Context",
1353
+ description="Repository event or manual trigger correlation metadata.",
1354
+ )
1355
+ image_artifact_context: dict[str, Any] = Field(
1356
+ default_factory=dict,
1357
+ title="Image Artifact Context",
1358
+ description="Project image and resource snapshots captured by the run.",
1359
+ )
1360
+ cleanup_context: dict[str, Any] = Field(
1361
+ default_factory=dict,
1362
+ title="Cleanup Context",
1363
+ description="Cleanup outcomes captured by the run.",
1364
+ )
1365
+ started_at: datetime.datetime | None = Field(
1366
+ None,
1367
+ title="Started At",
1368
+ description="Timestamp when execution started.",
1369
+ )
1370
+ finished_at: datetime.datetime | None = Field(
1371
+ None,
1372
+ title="Finished At",
1373
+ description="Timestamp when execution finished.",
1374
+ )
1375
+ result: dict[str, Any] = Field(
1376
+ default_factory=dict,
1377
+ title="Result",
1378
+ description="Terminal or intermediate deployment result payload.",
1379
+ )
1380
+ error_code: str = Field(
1381
+ default="",
1382
+ title="Error Code",
1383
+ description="Machine-readable error code when the run failed or was blocked.",
1384
+ )
1385
+ error_detail: str = Field(
1386
+ default="",
1387
+ title="Error Detail",
1388
+ description="Human-readable error detail when the run failed or was blocked.",
1389
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.30
3
+ Version: 4.4.32
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "4.4.30"
7
+ version = "4.4.32"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"