mainsequence 3.19.3__tar.gz → 3.19.5__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.
- {mainsequence-3.19.3 → mainsequence-3.19.5}/PKG-INFO +3 -1
- {mainsequence-3.19.3 → mainsequence-3.19.5}/README.md +2 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/AGENTS.md +2 -2
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +16 -9
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/api.py +51 -2
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/cli.py +36 -68
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/local_ops.py +6 -12
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace.py +1 -1
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/models_helpers.py +1 -1
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/PKG-INFO +3 -1
- {mainsequence-3.19.3 → mainsequence-3.19.5}/pyproject.toml +1 -1
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_cli.py +64 -6
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_project_batch_jobs_from_file.py +43 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/LICENSE +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/simple_tables/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/local_journal/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/assets_and_translation/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/instruments_and_pricing/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/virtualfundbuilder/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/__main__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/bootstrap.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/config.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/cli/ui.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/base.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/client.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/models_simple_tables.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/models_tdag.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/models_user.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/models_vam.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/client/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/compute_validation.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/asset_select.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/date_settings.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/logged_user.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/streamlit_form_factory.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/defaults.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/data_interface.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/base_instrument.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/bond.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/callability.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/json_codec.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/position.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/instruments/ql_fields.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/curve_codec.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/nodes.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/registry.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices_builders.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/settings.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/instruments/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/logconf.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/__main__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/base_persist_managers.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/config.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/configuration_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/filters.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/namespacing.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/run_operations.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/filters.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/future_registry.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/pydantic_metadata.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/filters.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/persist_managers.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/schema.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/table_nodes.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/tdag/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/enums.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/portfolio_nodes.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/utils.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/setup.cfg +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_auth_precedence.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_client.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_command_center_models.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_dependency_extras.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_filter_normalization.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_instruments.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_logconf.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_logged_user_components.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_run_configuration.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_simple_tables_configuration_hashing.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_simple_tables_persistence.py +0 -0
- {mainsequence-3.19.3 → mainsequence-3.19.5}/tests/test_workspace_snapshot.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mainsequence
|
|
3
|
-
Version: 3.19.
|
|
3
|
+
Version: 3.19.5
|
|
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
|
|
@@ -154,6 +154,7 @@ Recommended entry points:
|
|
|
154
154
|
- [Working With Simple Tables](docs/tutorial/working_with_simple_tables.md)
|
|
155
155
|
- [Create Your First API](docs/tutorial/create_your_first_api.md)
|
|
156
156
|
- [Role-Based Access Control](docs/tutorial/role_based_access_control.md)
|
|
157
|
+
- [Turn Your Project Into an Agent](docs/tutorial/project_to_agent.md)
|
|
157
158
|
- Knowledge:
|
|
158
159
|
- [Data Nodes](docs/knowledge/data_nodes.md)
|
|
159
160
|
- [Command Center](docs/knowledge/command_center/index.md)
|
|
@@ -209,6 +210,7 @@ From there, the normal learning path is:
|
|
|
209
210
|
4. understand sharing and RBAC
|
|
210
211
|
5. schedule jobs
|
|
211
212
|
6. build dashboards or downstream consumers
|
|
213
|
+
7. package the project as an agent-facing surface when the repository is ready
|
|
212
214
|
|
|
213
215
|
## Installation for development
|
|
214
216
|
|
|
@@ -64,6 +64,7 @@ Recommended entry points:
|
|
|
64
64
|
- [Working With Simple Tables](docs/tutorial/working_with_simple_tables.md)
|
|
65
65
|
- [Create Your First API](docs/tutorial/create_your_first_api.md)
|
|
66
66
|
- [Role-Based Access Control](docs/tutorial/role_based_access_control.md)
|
|
67
|
+
- [Turn Your Project Into an Agent](docs/tutorial/project_to_agent.md)
|
|
67
68
|
- Knowledge:
|
|
68
69
|
- [Data Nodes](docs/knowledge/data_nodes.md)
|
|
69
70
|
- [Command Center](docs/knowledge/command_center/index.md)
|
|
@@ -119,6 +120,7 @@ From there, the normal learning path is:
|
|
|
119
120
|
4. understand sharing and RBAC
|
|
120
121
|
5. schedule jobs
|
|
121
122
|
6. build dashboards or downstream consumers
|
|
123
|
+
7. package the project as an agent-facing surface when the repository is ready
|
|
122
124
|
|
|
123
125
|
## Installation for development
|
|
124
126
|
|
|
@@ -18,9 +18,9 @@ uses them to update only the Main Sequence section below.
|
|
|
18
18
|
## Main Sequence Instructions
|
|
19
19
|
|
|
20
20
|
Before any non-trivial Main Sequence work, verify that this Main Sequence section matches the
|
|
21
|
-
latest installed `
|
|
21
|
+
latest installed `AGENTS.md` template and that
|
|
22
22
|
`.agents/skills/mainsequence/project_builder/SKILL.md` matches the latest installed
|
|
23
|
-
|
|
23
|
+
`.agents/skills/project_builder/SKILL.md`; if either local file does not match, update it
|
|
24
24
|
before proceeding.
|
|
25
25
|
|
|
26
26
|
Canonical Main Sequence documentation root:
|
|
@@ -69,25 +69,32 @@ This skill must not claim ownership of:
|
|
|
69
69
|
|
|
70
70
|
0. If widget selection, layout narrative, or visualization strategy is not already decided, use:
|
|
71
71
|
- `.agents/skills/mainsequence/command_center/workspace_design/SKILL.md`
|
|
72
|
-
1.
|
|
72
|
+
1. If the workspace may use connection-backed source widgets, inspect the available connections through the CLI first:
|
|
73
|
+
- `mainsequence cc connection list --json`
|
|
74
|
+
- identify the target connection instance `uid`
|
|
75
|
+
- `mainsequence cc connection detail <CONNECTION_UID> --json`
|
|
76
|
+
- `mainsequence cc connection_type list --json`
|
|
77
|
+
- identify the target connection `type_id`
|
|
78
|
+
- `mainsequence cc connection_type detail <TYPE_ID> --json`
|
|
79
|
+
2. Verify the widget catalog through the CLI:
|
|
73
80
|
- `mainsequence cc registered_widget_type list --json`
|
|
74
81
|
- identify the target `widget_id`
|
|
75
82
|
- `mainsequence cc registered_widget_type detail <WIDGET_ID> --json`
|
|
76
|
-
|
|
83
|
+
3. The SDK client models in `mainsequence/client/command_center/`:
|
|
77
84
|
- `workspace.py`
|
|
78
85
|
- `connections.py` when source widgets depend on backend-owned connections
|
|
79
86
|
- `data_models.py`
|
|
80
87
|
- `app_component.py` when the workspace contains AppComponent widgets or editable form payloads
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
4. `docs/knowledge/command_center/workspaces.md`
|
|
89
|
+
5. the local Main Sequence docs/models/examples in this repository that define the widget payloads being mounted
|
|
90
|
+
6. the current CLI docs if the task uses CLI workflow
|
|
84
91
|
|
|
85
92
|
If the workspace contains AppComponent widgets, also read:
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
7. `docs/knowledge/command_center/forms.md`
|
|
95
|
+
8. `docs/knowledge/command_center/widget_data_contracts.md`
|
|
96
|
+
9. `.agents/skills/mainsequence/platform_operations/orchestration_and_releases/SKILL.md` when mounted widgets depend on project APIs that must be usable from Command Center
|
|
97
|
+
10. `.agents/skills/mainsequence/command_center/api_mock_prototyping/SKILL.md` when the workspace should validate an AppComponent/API contract in `mock-json` mode before deployment
|
|
91
98
|
|
|
92
99
|
## Command Center Mental Model
|
|
93
100
|
|
|
@@ -18,6 +18,7 @@ import importlib
|
|
|
18
18
|
import json
|
|
19
19
|
import os
|
|
20
20
|
import re
|
|
21
|
+
import shlex
|
|
21
22
|
from typing import Any
|
|
22
23
|
from urllib.parse import urlencode
|
|
23
24
|
|
|
@@ -4679,6 +4680,30 @@ def schedule_batch_project_jobs(
|
|
|
4679
4680
|
os.environ[k] = v
|
|
4680
4681
|
|
|
4681
4682
|
|
|
4683
|
+
def get_project_job(
|
|
4684
|
+
job_id: int | str,
|
|
4685
|
+
*,
|
|
4686
|
+
timeout: int | None = None,
|
|
4687
|
+
) -> dict[str, Any]:
|
|
4688
|
+
"""
|
|
4689
|
+
Retrieve one project job via SDK client model.
|
|
4690
|
+
"""
|
|
4691
|
+
try:
|
|
4692
|
+
job = _run_sdk_model_operation(
|
|
4693
|
+
module_name="mainsequence.client.models_helpers",
|
|
4694
|
+
class_name="Job",
|
|
4695
|
+
operation=lambda ClientJob: ClientJob.get(pk=int(job_id), timeout=timeout),
|
|
4696
|
+
)
|
|
4697
|
+
return _sdk_object_to_dict(job)
|
|
4698
|
+
except Exception as e:
|
|
4699
|
+
err_name = type(e).__name__
|
|
4700
|
+
if err_name == "NotFoundError":
|
|
4701
|
+
raise ApiError(f"Job not found: {job_id}") from e
|
|
4702
|
+
if isinstance(e, (ApiError, NotLoggedIn)):
|
|
4703
|
+
raise
|
|
4704
|
+
raise ApiError(f"Project job fetch failed: {e}") from e
|
|
4705
|
+
|
|
4706
|
+
|
|
4682
4707
|
def run_project_job(
|
|
4683
4708
|
job_id: int | str,
|
|
4684
4709
|
*,
|
|
@@ -4738,11 +4763,35 @@ def run_project_job(
|
|
|
4738
4763
|
|
|
4739
4764
|
job = ClientJob.get(pk=int(job_id), timeout=timeout)
|
|
4740
4765
|
payload = job.run_job(timeout=timeout, command_args=command_args)
|
|
4766
|
+
effective_tokens: list[str] = []
|
|
4767
|
+
execution_path = str(getattr(job, "execution_path", "") or "").strip()
|
|
4768
|
+
app_name = str(getattr(job, "app_name", "") or "").strip()
|
|
4769
|
+
if execution_path:
|
|
4770
|
+
effective_tokens.append(execution_path)
|
|
4771
|
+
elif app_name:
|
|
4772
|
+
effective_tokens.append(f"app:{app_name}")
|
|
4773
|
+
if command_args:
|
|
4774
|
+
effective_tokens.extend(str(arg) for arg in command_args)
|
|
4775
|
+
effective_run = shlex.join(effective_tokens) if effective_tokens else None
|
|
4741
4776
|
if isinstance(payload, dict):
|
|
4777
|
+
if effective_run:
|
|
4778
|
+
payload.setdefault("effective_run", effective_run)
|
|
4779
|
+
if command_args is not None:
|
|
4780
|
+
payload.setdefault("command_args", list(command_args))
|
|
4742
4781
|
return payload
|
|
4743
4782
|
if hasattr(payload, "model_dump"):
|
|
4744
|
-
|
|
4745
|
-
|
|
4783
|
+
payload = payload.model_dump()
|
|
4784
|
+
if effective_run:
|
|
4785
|
+
payload.setdefault("effective_run", effective_run)
|
|
4786
|
+
if command_args is not None:
|
|
4787
|
+
payload.setdefault("command_args", list(command_args))
|
|
4788
|
+
return payload
|
|
4789
|
+
out = {"job_id": int(job_id)}
|
|
4790
|
+
if effective_run:
|
|
4791
|
+
out["effective_run"] = effective_run
|
|
4792
|
+
if command_args is not None:
|
|
4793
|
+
out["command_args"] = list(command_args)
|
|
4794
|
+
return out
|
|
4746
4795
|
|
|
4747
4796
|
except Exception as e:
|
|
4748
4797
|
err_name = type(e).__name__
|
|
@@ -31,6 +31,7 @@ import os
|
|
|
31
31
|
import pathlib
|
|
32
32
|
import platform
|
|
33
33
|
import re
|
|
34
|
+
import shlex
|
|
34
35
|
import shutil
|
|
35
36
|
import subprocess
|
|
36
37
|
import sys
|
|
@@ -114,6 +115,7 @@ from .api import (
|
|
|
114
115
|
get_project,
|
|
115
116
|
get_project_data_node_updates,
|
|
116
117
|
get_project_image,
|
|
118
|
+
get_project_job,
|
|
117
119
|
get_project_job_run_logs,
|
|
118
120
|
get_projects,
|
|
119
121
|
get_registered_widget_type,
|
|
@@ -8834,42 +8836,6 @@ def project_project_resource_create_dashboard_cmd(
|
|
|
8834
8836
|
)
|
|
8835
8837
|
|
|
8836
8838
|
|
|
8837
|
-
@project_project_resource_group.command("create_agent")
|
|
8838
|
-
def project_project_resource_create_agent_cmd(
|
|
8839
|
-
project_id: int | None = typer.Argument(None, help="Project ID. Defaults to local .env when omitted."),
|
|
8840
|
-
resource_id: int | None = typer.Option(None, "--resource-id", help="Project resource ID."),
|
|
8841
|
-
path: str | None = typer.Option(None, "--path", help="Project repository path (default: current project)"),
|
|
8842
|
-
related_image_id: int | None = typer.Option(None, "--related-image-id", help="Project image ID."),
|
|
8843
|
-
readme_resource_id: int | None = typer.Option(None, "--readme-resource-id", help="Optional README resource ID."),
|
|
8844
|
-
cpu_request: str | None = typer.Option(None, "--cpu-request", help="CPU request (accepts 0.5 or 500m; default: 0.25)."),
|
|
8845
|
-
memory_request: str | None = typer.Option(None, "--memory-request", help="Memory request (accepts 1 or 1Gi; default: 0.5)."),
|
|
8846
|
-
gpu_request: str | None = typer.Option(None, "--gpu-request", help="GPU request count."),
|
|
8847
|
-
gpu_type: str | None = typer.Option(None, "--gpu-type", help="GPU accelerator type."),
|
|
8848
|
-
spot: bool | None = typer.Option(None, "--spot/--no-spot", help="Whether to prefer spot capacity."),
|
|
8849
|
-
timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
|
|
8850
|
-
):
|
|
8851
|
-
"""
|
|
8852
|
-
Create an agent release from a project resource.
|
|
8853
|
-
|
|
8854
|
-
The command first lets the user select a project image and then filters resources so
|
|
8855
|
-
only resources with `repo_commit_sha == related_image.project_repo_hash` are eligible.
|
|
8856
|
-
"""
|
|
8857
|
-
_project_resource_release_create_impl(
|
|
8858
|
-
release_kind="agent",
|
|
8859
|
-
project_id=project_id,
|
|
8860
|
-
resource_id=resource_id,
|
|
8861
|
-
path=path,
|
|
8862
|
-
related_image_id=related_image_id,
|
|
8863
|
-
readme_resource_id=readme_resource_id,
|
|
8864
|
-
cpu_request=cpu_request,
|
|
8865
|
-
memory_request=memory_request,
|
|
8866
|
-
gpu_request=gpu_request,
|
|
8867
|
-
gpu_type=gpu_type,
|
|
8868
|
-
spot=spot,
|
|
8869
|
-
timeout=timeout,
|
|
8870
|
-
)
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
8839
|
@project_project_resource_group.command("create_fastapi")
|
|
8874
8840
|
def project_project_resource_create_fastapi_cmd(
|
|
8875
8841
|
project_id: int | None = typer.Argument(None, help="Project ID. Defaults to local .env when omitted."),
|
|
@@ -8977,30 +8943,6 @@ def project_project_resource_delete_dashboard_cmd(
|
|
|
8977
8943
|
)
|
|
8978
8944
|
|
|
8979
8945
|
|
|
8980
|
-
@project_project_resource_group.command("delete_agent")
|
|
8981
|
-
def project_project_resource_delete_agent_cmd(
|
|
8982
|
-
release_id: int = typer.Argument(..., help="Agent resource release ID."),
|
|
8983
|
-
yes: bool = typer.Option(False, "--yes", help="Delete without confirmation."),
|
|
8984
|
-
timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
|
|
8985
|
-
):
|
|
8986
|
-
"""
|
|
8987
|
-
Delete an agent resource release.
|
|
8988
|
-
|
|
8989
|
-
Examples
|
|
8990
|
-
--------
|
|
8991
|
-
```bash
|
|
8992
|
-
mainsequence project project_resource delete_agent 601
|
|
8993
|
-
mainsequence project project_resource delete_agent 601 --yes
|
|
8994
|
-
```
|
|
8995
|
-
"""
|
|
8996
|
-
_project_resource_release_delete_impl(
|
|
8997
|
-
release_id=release_id,
|
|
8998
|
-
expected_release_kind="agent",
|
|
8999
|
-
yes=yes,
|
|
9000
|
-
timeout=timeout,
|
|
9001
|
-
)
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
8946
|
@project_project_resource_group.command("delete_fastapi")
|
|
9005
8947
|
def project_project_resource_delete_fastapi_cmd(
|
|
9006
8948
|
release_id: int = typer.Argument(..., help="FastAPI resource release ID."),
|
|
@@ -9574,10 +9516,14 @@ def project_jobs_list_cmd(
|
|
|
9574
9516
|
@project_jobs_group.command("run")
|
|
9575
9517
|
def project_jobs_run_cmd(
|
|
9576
9518
|
job_id: int = pydantic_argument(JOB_MODEL_REF, "id", ..., help="Job ID to run."),
|
|
9519
|
+
passthrough_args: list[str] | None = typer.Argument(
|
|
9520
|
+
None,
|
|
9521
|
+
help="Additional per-run args after `--`, for example `mainsequence project jobs run 91 -- --name demo`.",
|
|
9522
|
+
),
|
|
9577
9523
|
command_args: list[str] | None = typer.Option(
|
|
9578
9524
|
None,
|
|
9579
|
-
"--
|
|
9580
|
-
help="
|
|
9525
|
+
"--arg",
|
|
9526
|
+
help="Append one per-run arg to the saved job entrypoint. Repeatable. Does not replace the saved execution_path or app_name.",
|
|
9581
9527
|
),
|
|
9582
9528
|
timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
|
|
9583
9529
|
):
|
|
@@ -9585,21 +9531,43 @@ def project_jobs_run_cmd(
|
|
|
9585
9531
|
Run a project job immediately.
|
|
9586
9532
|
|
|
9587
9533
|
Uses SDK client `Job.run_job()` as the single source of truth.
|
|
9534
|
+
Per-run args are appended to the saved job entrypoint; they do not replace it.
|
|
9588
9535
|
|
|
9589
9536
|
Examples
|
|
9590
9537
|
--------
|
|
9591
9538
|
```bash
|
|
9592
9539
|
mainsequence project jobs run 91
|
|
9593
|
-
mainsequence project jobs run 91 --
|
|
9540
|
+
mainsequence project jobs run 91 --arg demo-from-cli
|
|
9541
|
+
mainsequence project jobs run 91 -- --name demo-from-cli
|
|
9594
9542
|
mainsequence project jobs run 91 --timeout 60
|
|
9595
9543
|
```
|
|
9596
9544
|
"""
|
|
9597
9545
|
_require_login()
|
|
9598
9546
|
|
|
9547
|
+
merged_command_args = list(command_args or [])
|
|
9548
|
+
if passthrough_args:
|
|
9549
|
+
merged_command_args.extend(str(arg) for arg in passthrough_args)
|
|
9550
|
+
|
|
9551
|
+
try:
|
|
9552
|
+
job_payload = get_project_job(job_id, timeout=timeout)
|
|
9553
|
+
except ApiError as e:
|
|
9554
|
+
error(f"Project job fetch failed: {e}")
|
|
9555
|
+
raise typer.Exit(1) from e
|
|
9556
|
+
|
|
9557
|
+
entrypoint = str(job_payload.get("execution_path") or "").strip()
|
|
9558
|
+
if not entrypoint:
|
|
9559
|
+
app_name = str(job_payload.get("app_name") or "").strip()
|
|
9560
|
+
if app_name:
|
|
9561
|
+
entrypoint = f"app:{app_name}"
|
|
9562
|
+
|
|
9563
|
+
if entrypoint:
|
|
9564
|
+
effective_tokens = [entrypoint, *merged_command_args]
|
|
9565
|
+
info(f"Effective run: {shlex.join(effective_tokens)}")
|
|
9566
|
+
|
|
9599
9567
|
try:
|
|
9600
9568
|
payload = run_project_job(
|
|
9601
9569
|
job_id=job_id,
|
|
9602
|
-
command_args=
|
|
9570
|
+
command_args=merged_command_args or None,
|
|
9603
9571
|
timeout=timeout,
|
|
9604
9572
|
)
|
|
9605
9573
|
except ApiError as e:
|
|
@@ -10625,7 +10593,7 @@ def project_refresh_token(
|
|
|
10625
10593
|
def project_freeze_env(
|
|
10626
10594
|
project_id: int | None = typer.Argument(None, help="Project ID"),
|
|
10627
10595
|
path: str | None = typer.Option(None, "--path", help="Project directory"),
|
|
10628
|
-
ensure_uv: bool = typer.Option(True, "--ensure-uv/--no-ensure-uv", help="
|
|
10596
|
+
ensure_uv: bool = typer.Option(True, "--ensure-uv/--no-ensure-uv", help="Allow resolving uv from PATH when it is not present inside .venv."),
|
|
10629
10597
|
):
|
|
10630
10598
|
"""
|
|
10631
10599
|
Export pinned dependencies into `requirements.txt` using `uv`.
|
|
@@ -10637,7 +10605,7 @@ def project_freeze_env(
|
|
|
10637
10605
|
path:
|
|
10638
10606
|
Explicit local path.
|
|
10639
10607
|
ensure_uv:
|
|
10640
|
-
|
|
10608
|
+
Allow resolving `uv` from PATH when it is not present inside `.venv`.
|
|
10641
10609
|
|
|
10642
10610
|
Examples
|
|
10643
10611
|
--------
|
|
@@ -10736,7 +10704,7 @@ def project_sync(
|
|
|
10736
10704
|
raise typer.Exit(1)
|
|
10737
10705
|
|
|
10738
10706
|
steps = [
|
|
10739
|
-
"
|
|
10707
|
+
"resolve uv executable",
|
|
10740
10708
|
f"uv version --bump {bump}",
|
|
10741
10709
|
"uv lock",
|
|
10742
10710
|
"uv sync",
|
|
@@ -11045,7 +11013,7 @@ def project_update_sdk(
|
|
|
11045
11013
|
ensure_venv(project_dir)
|
|
11046
11014
|
|
|
11047
11015
|
steps = [
|
|
11048
|
-
"
|
|
11016
|
+
"resolve uv executable",
|
|
11049
11017
|
"uv lock --upgrade-package mainsequence",
|
|
11050
11018
|
"uv sync",
|
|
11051
11019
|
]
|
|
@@ -13,6 +13,7 @@ Local operations shared by several commands:
|
|
|
13
13
|
|
|
14
14
|
import os
|
|
15
15
|
import pathlib
|
|
16
|
+
import shutil
|
|
16
17
|
import subprocess
|
|
17
18
|
import sys
|
|
18
19
|
from dataclasses import dataclass
|
|
@@ -62,7 +63,7 @@ def ensure_venv(project_dir: pathlib.Path) -> VenvPaths:
|
|
|
62
63
|
|
|
63
64
|
def ensure_uv_installed(project_dir: pathlib.Path, upgrade: bool = True) -> pathlib.Path:
|
|
64
65
|
"""
|
|
65
|
-
|
|
66
|
+
Resolve a usable uv executable for the project workflow.
|
|
66
67
|
|
|
67
68
|
Returns:
|
|
68
69
|
Path to uv executable
|
|
@@ -71,18 +72,11 @@ def ensure_uv_installed(project_dir: pathlib.Path, upgrade: bool = True) -> path
|
|
|
71
72
|
if vp.uv and vp.uv.exists():
|
|
72
73
|
return vp.uv
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
if
|
|
76
|
-
|
|
77
|
-
args.append("uv")
|
|
78
|
-
r = subprocess.run(args, cwd=str(project_dir))
|
|
79
|
-
if r.returncode != 0:
|
|
80
|
-
raise RuntimeError("Failed to install uv into the virtual environment.")
|
|
75
|
+
uv_bin = shutil.which("uv")
|
|
76
|
+
if uv_bin:
|
|
77
|
+
return pathlib.Path(uv_bin)
|
|
81
78
|
|
|
82
|
-
|
|
83
|
-
if not vp.uv or not vp.uv.exists():
|
|
84
|
-
raise RuntimeError("uv installed but executable not found in .venv.")
|
|
85
|
-
return vp.uv
|
|
79
|
+
raise RuntimeError("uv executable not found. Install uv and ensure it is available in PATH.")
|
|
86
80
|
|
|
87
81
|
|
|
88
82
|
def run_cmd(cmd: list[str], cwd: pathlib.Path, env: dict[str, str] | None = None) -> subprocess.CompletedProcess:
|
|
@@ -101,7 +101,7 @@ class Workspace(LabelableObjectMixin, ShareableObjectMixin, CommandCenterBaseObj
|
|
|
101
101
|
description="Free-form workspace description.",
|
|
102
102
|
)
|
|
103
103
|
type: WorkspaceType = Field(default=WorkspaceType.WORKSPACE)
|
|
104
|
-
public_url:str=Field(description="Public URL for workspace endpoint if exists.", default=
|
|
104
|
+
public_url:str| None =Field(description="Public URL for workspace endpoint if exists.", default=None)
|
|
105
105
|
created_at:datetime=Field()
|
|
106
106
|
labels: list[str] = Field(
|
|
107
107
|
default_factory=list,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mainsequence
|
|
3
|
-
Version: 3.19.
|
|
3
|
+
Version: 3.19.5
|
|
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
|
|
@@ -154,6 +154,7 @@ Recommended entry points:
|
|
|
154
154
|
- [Working With Simple Tables](docs/tutorial/working_with_simple_tables.md)
|
|
155
155
|
- [Create Your First API](docs/tutorial/create_your_first_api.md)
|
|
156
156
|
- [Role-Based Access Control](docs/tutorial/role_based_access_control.md)
|
|
157
|
+
- [Turn Your Project Into an Agent](docs/tutorial/project_to_agent.md)
|
|
157
158
|
- Knowledge:
|
|
158
159
|
- [Data Nodes](docs/knowledge/data_nodes.md)
|
|
159
160
|
- [Command Center](docs/knowledge/command_center/index.md)
|
|
@@ -209,6 +210,7 @@ From there, the normal learning path is:
|
|
|
209
210
|
4. understand sharing and RBAC
|
|
210
211
|
5. schedule jobs
|
|
211
212
|
6. build dashboards or downstream consumers
|
|
213
|
+
7. package the project as an agent-facing surface when the repository is ready
|
|
212
214
|
|
|
213
215
|
## Installation for development
|
|
214
216
|
|
|
@@ -5699,13 +5699,15 @@ def test_run_project_job_uses_client_model(cli_mod, monkeypatch):
|
|
|
5699
5699
|
def get(cls, pk, timeout=None):
|
|
5700
5700
|
captured["job_id_arg"] = pk
|
|
5701
5701
|
return types.SimpleNamespace(
|
|
5702
|
+
execution_path="scripts/test.py",
|
|
5703
|
+
app_name=None,
|
|
5702
5704
|
run_job=lambda timeout=None, command_args=None: (
|
|
5703
5705
|
captured.update(command_args=command_args)
|
|
5704
5706
|
or {
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5707
|
+
"id": 501,
|
|
5708
|
+
"job": pk,
|
|
5709
|
+
"status": "QUEUED",
|
|
5710
|
+
"unique_identifier": "jobrun_abc123",
|
|
5709
5711
|
}
|
|
5710
5712
|
)
|
|
5711
5713
|
)
|
|
@@ -5728,6 +5730,8 @@ def test_run_project_job_uses_client_model(cli_mod, monkeypatch):
|
|
|
5728
5730
|
"job": 91,
|
|
5729
5731
|
"status": "QUEUED",
|
|
5730
5732
|
"unique_identifier": "jobrun_abc123",
|
|
5733
|
+
"effective_run": "scripts/test.py python -m jobs.daily",
|
|
5734
|
+
"command_args": ["python", "-m", "jobs.daily"],
|
|
5731
5735
|
}
|
|
5732
5736
|
|
|
5733
5737
|
|
|
@@ -7951,6 +7955,16 @@ def test_markets_asset_translation_table_detail(cli_mod, runner, monkeypatch):
|
|
|
7951
7955
|
def test_project_jobs_run(cli_mod, runner, monkeypatch):
|
|
7952
7956
|
monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
|
|
7953
7957
|
captured = {}
|
|
7958
|
+
monkeypatch.setattr(
|
|
7959
|
+
cli_mod,
|
|
7960
|
+
"get_project_job",
|
|
7961
|
+
lambda job_id, timeout=None: {
|
|
7962
|
+
"id": job_id,
|
|
7963
|
+
"name": "daily-run",
|
|
7964
|
+
"execution_path": "scripts/test.py",
|
|
7965
|
+
"app_name": None,
|
|
7966
|
+
},
|
|
7967
|
+
)
|
|
7954
7968
|
monkeypatch.setattr(
|
|
7955
7969
|
cli_mod,
|
|
7956
7970
|
"run_project_job",
|
|
@@ -7963,24 +7977,68 @@ def test_project_jobs_run(cli_mod, runner, monkeypatch):
|
|
|
7963
7977
|
"job": job_id,
|
|
7964
7978
|
"status": "QUEUED",
|
|
7965
7979
|
"unique_identifier": "jobrun_abc123",
|
|
7980
|
+
"effective_run": "scripts/test.py --name demo-from-cli",
|
|
7966
7981
|
},
|
|
7967
7982
|
)
|
|
7968
7983
|
|
|
7969
7984
|
result = runner.invoke(
|
|
7970
7985
|
cli_mod.app,
|
|
7971
|
-
["project", "jobs", "run", "91", "--
|
|
7986
|
+
["project", "jobs", "run", "91", "--", "--name", "demo-from-cli"],
|
|
7972
7987
|
)
|
|
7973
7988
|
assert result.exit_code == 0
|
|
7974
7989
|
assert captured == {
|
|
7975
7990
|
"job_id": 91,
|
|
7976
|
-
"command_args": ["
|
|
7991
|
+
"command_args": ["--name", "demo-from-cli"],
|
|
7977
7992
|
"timeout": None,
|
|
7978
7993
|
}
|
|
7994
|
+
assert "Effective run: scripts/test.py --name demo-from-cli" in result.output
|
|
7979
7995
|
assert "Project job run requested: job_id=91" in result.output
|
|
7980
7996
|
assert "jobrun_abc123" in result.output
|
|
7981
7997
|
assert "QUEUED" in result.output
|
|
7982
7998
|
|
|
7983
7999
|
|
|
8000
|
+
def test_project_jobs_run_with_arg_option(cli_mod, runner, monkeypatch):
|
|
8001
|
+
monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
|
|
8002
|
+
captured = {}
|
|
8003
|
+
monkeypatch.setattr(
|
|
8004
|
+
cli_mod,
|
|
8005
|
+
"get_project_job",
|
|
8006
|
+
lambda job_id, timeout=None: {
|
|
8007
|
+
"id": job_id,
|
|
8008
|
+
"name": "daily-run",
|
|
8009
|
+
"execution_path": "scripts/test.py",
|
|
8010
|
+
"app_name": None,
|
|
8011
|
+
},
|
|
8012
|
+
)
|
|
8013
|
+
monkeypatch.setattr(
|
|
8014
|
+
cli_mod,
|
|
8015
|
+
"run_project_job",
|
|
8016
|
+
lambda job_id, command_args=None, timeout=None: captured.update(
|
|
8017
|
+
job_id=job_id,
|
|
8018
|
+
command_args=command_args,
|
|
8019
|
+
timeout=timeout,
|
|
8020
|
+
) or {
|
|
8021
|
+
"id": 501,
|
|
8022
|
+
"job": job_id,
|
|
8023
|
+
"status": "QUEUED",
|
|
8024
|
+
"unique_identifier": "jobrun_abc123",
|
|
8025
|
+
"effective_run": "scripts/test.py demo-from-cli",
|
|
8026
|
+
},
|
|
8027
|
+
)
|
|
8028
|
+
|
|
8029
|
+
result = runner.invoke(
|
|
8030
|
+
cli_mod.app,
|
|
8031
|
+
["project", "jobs", "run", "91", "--arg", "demo-from-cli"],
|
|
8032
|
+
)
|
|
8033
|
+
assert result.exit_code == 0
|
|
8034
|
+
assert captured == {
|
|
8035
|
+
"job_id": 91,
|
|
8036
|
+
"command_args": ["demo-from-cli"],
|
|
8037
|
+
"timeout": None,
|
|
8038
|
+
}
|
|
8039
|
+
assert "Effective run: scripts/test.py demo-from-cli" in result.output
|
|
8040
|
+
|
|
8041
|
+
|
|
7984
8042
|
def test_project_job_runs_list(cli_mod, runner, monkeypatch):
|
|
7985
8043
|
monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
|
|
7986
8044
|
monkeypatch.setattr(
|
|
@@ -177,3 +177,46 @@ def test_job_bulk_get_or_create_rejects_invalid_job_definition(tmp_path):
|
|
|
177
177
|
|
|
178
178
|
with pytest.raises(ValueError, match=r"jobs\[0\] is invalid"):
|
|
179
179
|
Job.bulk_get_or_create(yaml_file=jobs_file, project_id=123)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_job_run_job_posts_command_args_as_json(monkeypatch):
|
|
183
|
+
models_helpers = _load_models_helpers_module()
|
|
184
|
+
Job = models_helpers.Job
|
|
185
|
+
|
|
186
|
+
captured = {}
|
|
187
|
+
|
|
188
|
+
class FakeResponse:
|
|
189
|
+
status_code = 202
|
|
190
|
+
|
|
191
|
+
def json(self):
|
|
192
|
+
return {"id": 501, "status": "QUEUED"}
|
|
193
|
+
|
|
194
|
+
monkeypatch.setattr(Job, "build_session", classmethod(lambda cls: object()))
|
|
195
|
+
monkeypatch.setattr(
|
|
196
|
+
Job,
|
|
197
|
+
"get_object_url",
|
|
198
|
+
classmethod(lambda cls: "https://backend.test/orm/api/pods/job"),
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
|
|
202
|
+
captured["r_type"] = r_type
|
|
203
|
+
captured["url"] = url
|
|
204
|
+
captured["payload"] = payload
|
|
205
|
+
captured["timeout"] = time_out
|
|
206
|
+
return FakeResponse()
|
|
207
|
+
|
|
208
|
+
monkeypatch.setattr(models_helpers, "make_request", _fake_make_request)
|
|
209
|
+
|
|
210
|
+
job = Job(
|
|
211
|
+
id=91,
|
|
212
|
+
name="Simulated Prices",
|
|
213
|
+
project=123,
|
|
214
|
+
execution_path="scripts/simulated_prices_launcher.py",
|
|
215
|
+
)
|
|
216
|
+
out = job.run_job(timeout=30, command_args=["--name", "demo-from-cli"])
|
|
217
|
+
|
|
218
|
+
assert captured["r_type"] == "POST"
|
|
219
|
+
assert captured["url"] == "https://backend.test/orm/api/pods/job/91/run_job/"
|
|
220
|
+
assert captured["timeout"] == 30
|
|
221
|
+
assert captured["payload"] == {"json": {"command_args": ["--name", "demo-from-cli"]}}
|
|
222
|
+
assert out == {"id": 501, "status": "QUEUED"}
|
|
File without changes
|
{mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/a2a_communication/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/dashboards/streamlit/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-3.19.3 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/local_journal/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|