mainsequence 3.19.2__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.2 → mainsequence-3.19.5}/PKG-INFO +4 -2
- {mainsequence-3.19.2 → mainsequence-3.19.5}/README.md +3 -1
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/AGENTS.md +2 -2
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +366 -45
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/api.py +64 -9
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/cli.py +91 -117
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/local_ops.py +6 -12
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace.py +1 -1
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_helpers.py +1 -1
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_tdag.py +50 -18
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/PKG-INFO +4 -2
- {mainsequence-3.19.2 → mainsequence-3.19.5}/pyproject.toml +1 -1
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_cli.py +135 -16
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_project_batch_jobs_from_file.py +43 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/LICENSE +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/data_publishing/simple_tables/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/maintenance/local_journal/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/assets_and_translation/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/instruments_and_pricing/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/markets_platform/virtualfundbuilder/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/__main__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/bootstrap.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/config.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/cli/ui.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/base.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/client.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_simple_tables.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_user.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/models_vam.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/client/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/compute_validation.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/asset_select.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/date_settings.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/components/logged_user.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/instruments/streamlit_form_factory.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/defaults.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/data_interface/data_interface.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/base_instrument.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/bond.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/callability.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/json_codec.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/position.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/instruments/ql_fields.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/curve_codec.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/nodes.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/interest_rates/etl/registry.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/indices_builders.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/settings.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/instruments/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/logconf.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/__main__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/base_persist_managers.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/config.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/configuration_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/filters.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/namespacing.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/run_operations.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/data_nodes/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/filters.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/future_registry.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/pydantic_metadata.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/filters.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/persist_managers.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/schema.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/simple_tables/table_nodes.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/tdag/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/enums.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/portfolio_nodes.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence/virtualfundbuilder/utils.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/setup.cfg +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_auth_precedence.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_client.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_command_center_models.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_dependency_extras.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_filter_normalization.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_instruments.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_logconf.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_logged_user_components.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_run_configuration.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_simple_tables_configuration_hashing.py +0 -0
- {mainsequence-3.19.2 → mainsequence-3.19.5}/tests/test_simple_tables_persistence.py +0 -0
- {mainsequence-3.19.2 → 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
|
|
@@ -89,7 +89,7 @@ Requires-Dist: playwright; extra == "workspace-snapshots"
|
|
|
89
89
|
Dynamic: license-file
|
|
90
90
|
|
|
91
91
|
<p align="center">
|
|
92
|
-
<img src="https://main-sequence.
|
|
92
|
+
<img src="https://www.main-sequence.io/images/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
|
|
93
93
|
</p>
|
|
94
94
|
|
|
95
95
|
# Main Sequence Python SDK
|
|
@@ -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
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://main-sequence.
|
|
2
|
+
<img src="https://www.main-sequence.io/images/logos/MS_logo_long_black.png" alt="Main Sequence Logo" width="500"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# Main Sequence Python SDK
|
|
@@ -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
|
|
|
@@ -104,6 +111,92 @@ Think in terms of these objects:
|
|
|
104
111
|
- saved widget or saved group:
|
|
105
112
|
import-layer snapshot/template, not a live linked widget instance inside the workspace
|
|
106
113
|
|
|
114
|
+
## Workspace JSON Model
|
|
115
|
+
|
|
116
|
+
Workspace JSON is the durable workspace definition. It is not a raw frontend state dump and it is
|
|
117
|
+
not a loaded runtime snapshot.
|
|
118
|
+
|
|
119
|
+
Portable export artifacts may use a wrapper:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"schema": "mainsequence.workspace",
|
|
124
|
+
"version": 1,
|
|
125
|
+
"exportedAt": "2026-05-07T00:00:00.000Z",
|
|
126
|
+
"workspace": {
|
|
127
|
+
"id": "workspace-example",
|
|
128
|
+
"title": "Example Workspace",
|
|
129
|
+
"description": "User-scoped workspace managed in Command Center.",
|
|
130
|
+
"type": "workspace",
|
|
131
|
+
"labels": [],
|
|
132
|
+
"category": "Custom",
|
|
133
|
+
"source": "user",
|
|
134
|
+
"layoutKind": "custom",
|
|
135
|
+
"grid": { "columns": 48, "rowHeight": 15, "gap": 8 },
|
|
136
|
+
"controls": {
|
|
137
|
+
"enabled": true,
|
|
138
|
+
"timeRange": {
|
|
139
|
+
"enabled": true,
|
|
140
|
+
"defaultRange": "24h",
|
|
141
|
+
"options": ["15m", "1h", "6h", "24h", "7d", "30d", "90d"]
|
|
142
|
+
},
|
|
143
|
+
"refresh": {
|
|
144
|
+
"enabled": true,
|
|
145
|
+
"defaultIntervalMs": 300000,
|
|
146
|
+
"intervals": [null, 30000, 60000, 300000, 600000, 3600000]
|
|
147
|
+
},
|
|
148
|
+
"actions": { "enabled": true, "share": false, "view": true }
|
|
149
|
+
},
|
|
150
|
+
"widgets": []
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Use the wrapper for portable artifacts. For direct workspace update commands, pass the writable
|
|
156
|
+
workspace payload shape expected by that command, not an arbitrary wrapper, unless the command
|
|
157
|
+
explicitly documents wrapper support.
|
|
158
|
+
|
|
159
|
+
Durable workspace JSON owns:
|
|
160
|
+
|
|
161
|
+
- workspace metadata, labels, category, source, layout kind, grid, and shared controls
|
|
162
|
+
- mounted widget instances and ordering
|
|
163
|
+
- widget `props`, `layout`, `position`, `bindings`, `managedBy`, `presentation`, and `row.children`
|
|
164
|
+
- connection/query configuration on source widgets when the source widget contract requires it
|
|
165
|
+
|
|
166
|
+
Durable workspace JSON does not own:
|
|
167
|
+
|
|
168
|
+
- current user-selected control values when the platform separates user state
|
|
169
|
+
- runtime/view state when the platform separates user state
|
|
170
|
+
- credentials, provider URLs, native socket details, or backend route fragments
|
|
171
|
+
- compiled or public runtime metadata generated by the platform
|
|
172
|
+
|
|
173
|
+
## Widget Instance Shape
|
|
174
|
+
|
|
175
|
+
Each mounted widget instance should resolve to this shape:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"id": "unique-instance-id",
|
|
180
|
+
"widgetId": "registered-widget-type-id",
|
|
181
|
+
"title": "Optional title",
|
|
182
|
+
"props": {},
|
|
183
|
+
"bindings": {},
|
|
184
|
+
"layout": { "cols": 12, "rows": 8 },
|
|
185
|
+
"position": { "x": 0, "y": 0 }
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Important fields:
|
|
190
|
+
|
|
191
|
+
- `id`: unique mounted instance id inside the workspace
|
|
192
|
+
- `widgetId`: registered widget type id, not a saved-widget id and not a mounted instance id
|
|
193
|
+
- `props`: durable widget configuration
|
|
194
|
+
- `runtimeState`: optional current runtime/view state, not durable source configuration
|
|
195
|
+
- `bindings`: target-owned graph edges from this widget's input ports to upstream output ports
|
|
196
|
+
- `managedBy`: marks hidden managed source widgets
|
|
197
|
+
- `presentation`: placement, rail visibility, chrome, and exposed field behavior
|
|
198
|
+
- `row.children`: nested widgets inside a row/container widget
|
|
199
|
+
|
|
107
200
|
## Inputs This Skill Needs
|
|
108
201
|
|
|
109
202
|
Before writing or mutating a workspace, collect or infer:
|
|
@@ -286,27 +379,133 @@ If the payload shape is not defined by those sources and cannot be verified, sto
|
|
|
286
379
|
|
|
287
380
|
### 3.1 Resolve connection-backed data before mounting consumers
|
|
288
381
|
|
|
289
|
-
|
|
382
|
+
Connections are backend-owned data resources. Workspace consumers should not store connection
|
|
383
|
+
details directly unless their registered widget contract explicitly supports embedded managed source
|
|
384
|
+
props.
|
|
290
385
|
|
|
291
|
-
|
|
292
|
-
2. verify the selected connection instance exists and is usable
|
|
293
|
-
3. verify the connection type and `queryModelId`
|
|
294
|
-
4. verify the typed query payload
|
|
295
|
-
5. verify the published output contract
|
|
296
|
-
6. add a Tabular Transform widget if analytical reshaping is required
|
|
297
|
-
7. bind consumers to the source or transform `dataset` output
|
|
386
|
+
Prefer explicit source widgets:
|
|
298
387
|
|
|
299
|
-
|
|
300
|
-
connection
|
|
388
|
+
- `connection-query` for request/response datasets
|
|
389
|
+
- `connection-stream-query` for streaming or incremental paths
|
|
390
|
+
- `tabular-transform` when analytical reshaping is needed before presentation
|
|
301
391
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
through an Adapter from API connection first, then use an explicit transform when analytical
|
|
305
|
-
reshaping is still required.
|
|
392
|
+
One source widget can feed several consumers. Reuse one source when the same query drives several
|
|
393
|
+
tables, charts, statistics, curves, or agent contexts.
|
|
306
394
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
395
|
+
Before mounting table, chart, statistic, curve, or similar data consumers:
|
|
396
|
+
|
|
397
|
+
1. identify the source widget
|
|
398
|
+
2. verify the selected connection instance exists and is usable
|
|
399
|
+
3. verify `connectionRef.id` is real and backend-owned
|
|
400
|
+
4. verify `connectionRef.typeId` matches the connection type
|
|
401
|
+
5. verify `queryModelId` matches `query.kind`
|
|
402
|
+
6. verify the typed query payload matches the selected connection type and query model
|
|
403
|
+
7. verify the published output contract
|
|
404
|
+
8. add a Tabular Transform widget if analytical reshaping is required
|
|
405
|
+
9. bind consumers to the source or transform output through target-owned `bindings`
|
|
406
|
+
|
|
407
|
+
Do not store credentials, provider URLs, native route fragments, backend route fragments, provider
|
|
408
|
+
ids, or mutable connection display labels as authoritative widget props.
|
|
409
|
+
|
|
410
|
+
Request/response source props:
|
|
411
|
+
|
|
412
|
+
```json
|
|
413
|
+
{
|
|
414
|
+
"connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
|
|
415
|
+
"queryModelId": "simple-table-sql",
|
|
416
|
+
"query": {
|
|
417
|
+
"kind": "simple-table-sql",
|
|
418
|
+
"sql": "select * from {{simple_table}} limit 500"
|
|
419
|
+
},
|
|
420
|
+
"timeRangeMode": "dashboard",
|
|
421
|
+
"variables": {},
|
|
422
|
+
"maxRows": 500
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Incremental request/response props:
|
|
427
|
+
|
|
428
|
+
```json
|
|
429
|
+
{
|
|
430
|
+
"incrementalRefreshMode": "incremental",
|
|
431
|
+
"incrementalTimeField": "timestamp",
|
|
432
|
+
"incrementalMergeKeyFields": ["symbol", "timestamp"],
|
|
433
|
+
"incrementalOverlapMs": 60000,
|
|
434
|
+
"incrementalRetentionMs": 86400000,
|
|
435
|
+
"incrementalDedupePolicy": "latest"
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Stream source props:
|
|
440
|
+
|
|
441
|
+
```json
|
|
442
|
+
{
|
|
443
|
+
"connectionRef": { "id": 123, "typeId": "binance.market-data" },
|
|
444
|
+
"queryModelId": "ticker-stream",
|
|
445
|
+
"query": {
|
|
446
|
+
"kind": "ticker-stream",
|
|
447
|
+
"symbols": ["BTCUSDT", "ETHUSDT"]
|
|
448
|
+
},
|
|
449
|
+
"timeRangeMode": "none",
|
|
450
|
+
"mergeKeyFields": ["symbol"],
|
|
451
|
+
"retentionMaxRows": 1000
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Connection source rules:
|
|
456
|
+
|
|
457
|
+
- use stream widgets only when the query model advertises stream support
|
|
458
|
+
- configure retention and merge keys explicitly when the consumer expects bounded live state
|
|
459
|
+
- incremental refresh requires a time-range-aware query model and stable time and identity columns
|
|
460
|
+
- `incrementalTimeField` must exist in the returned frame
|
|
461
|
+
- `incrementalMergeKeyFields` must identify stable rows
|
|
462
|
+
- generic tabular consumers must receive `core.tabular_frame@v1`
|
|
463
|
+
- if the upstream connection returns raw arrays, paginated JSON, nested provider payloads, or other
|
|
464
|
+
ad hoc records, normalize through an Adapter from API connection first, then use an explicit
|
|
465
|
+
transform when analytical reshaping is still required
|
|
466
|
+
- when a project API or AppComponent legitimately returns a full canonical frame, ground the
|
|
467
|
+
contract against `mainsequence.client.command_center.data_models.TabularFrameResponse`
|
|
468
|
+
- source-specific runtime details belong in `source.context`, not top-level widget payload fields
|
|
469
|
+
|
|
470
|
+
### 3.2 Historical and incremental lanes
|
|
471
|
+
|
|
472
|
+
Modern tabular consumers use explicit role inputs:
|
|
473
|
+
|
|
474
|
+
- `seedData`: retained baseline or historical dataset
|
|
475
|
+
- `liveUpdates`: incremental publication lane
|
|
476
|
+
|
|
477
|
+
Source outputs:
|
|
478
|
+
|
|
479
|
+
- `connection-query.dataset`: retained `core.tabular_frame@v1` frame for historical consumers
|
|
480
|
+
- `connection-query.updates`: incremental output when incremental refresh is active
|
|
481
|
+
- `connection-stream-query.dataset`: retained compatibility frame
|
|
482
|
+
- `connection-stream-query.updates`: seed/update publication stream
|
|
483
|
+
|
|
484
|
+
Canonical binding shape:
|
|
485
|
+
|
|
486
|
+
```json
|
|
487
|
+
"bindings": {
|
|
488
|
+
"seedData": {
|
|
489
|
+
"sourceWidgetId": "historical-source",
|
|
490
|
+
"sourceOutputId": "dataset"
|
|
491
|
+
},
|
|
492
|
+
"liveUpdates": {
|
|
493
|
+
"sourceWidgetId": "stream-source",
|
|
494
|
+
"sourceOutputId": "updates"
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
Rules:
|
|
500
|
+
|
|
501
|
+
- historical/request-response data uses `dataset -> seedData`
|
|
502
|
+
- live or incremental data uses `updates -> liveUpdates`
|
|
503
|
+
- `sourceData` is legacy or compatibility input; use it only when the widget contract requires it
|
|
504
|
+
- do not send stream `dataset` to `liveUpdates`
|
|
505
|
+
- do not send request/response `dataset` to `liveUpdates`
|
|
506
|
+
- generic tabular consumers must receive `core.tabular_frame@v1`
|
|
507
|
+
- raw arrays, paginated JSON, or nested provider payloads must be normalized before reaching generic
|
|
508
|
+
consumers
|
|
310
509
|
|
|
311
510
|
### 4. Shared workspace state and current-user state are different
|
|
312
511
|
|
|
@@ -389,26 +588,51 @@ Prefer:
|
|
|
389
588
|
Bindings are canonical instance-level graph edges. They live on the target widget instance in
|
|
390
589
|
`bindings`, not in `props`, and not in widget-type metadata.
|
|
391
590
|
|
|
392
|
-
One binding is always
|
|
591
|
+
One binding is always:
|
|
393
592
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
593
|
+
```text
|
|
594
|
+
source widget output port -> target widget input port
|
|
595
|
+
```
|
|
397
596
|
|
|
398
597
|
Persisted shape:
|
|
399
598
|
|
|
400
599
|
- `bindings[inputId] = WidgetPortBinding`
|
|
401
600
|
- `bindings[inputId] = WidgetPortBinding[]` when the target input declares `cardinality: "many"`
|
|
402
601
|
|
|
403
|
-
|
|
602
|
+
Minimal `WidgetPortBinding`:
|
|
404
603
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
-
|
|
604
|
+
```json
|
|
605
|
+
{
|
|
606
|
+
"sourceWidgetId": "prices-source",
|
|
607
|
+
"sourceOutputId": "dataset"
|
|
608
|
+
}
|
|
609
|
+
```
|
|
408
610
|
|
|
409
|
-
|
|
611
|
+
Binding with transform steps:
|
|
612
|
+
|
|
613
|
+
```json
|
|
614
|
+
{
|
|
615
|
+
"sourceWidgetId": "source-widget",
|
|
616
|
+
"sourceOutputId": "agent-context",
|
|
617
|
+
"transformSteps": [
|
|
618
|
+
{ "id": "extract-path", "path": ["summary"], "contractId": "core.value.string@v1" }
|
|
619
|
+
]
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Treat ordered `transformSteps` as canonical. Legacy `transformId`, `transformPath`, and
|
|
410
624
|
`transformContractId` may still appear only as backward-compatible mirrors for older persisted
|
|
411
|
-
workspaces.
|
|
625
|
+
workspaces. Do not author those legacy fields in new workspace JSON.
|
|
626
|
+
|
|
627
|
+
Supported lightweight transform steps:
|
|
628
|
+
|
|
629
|
+
- `select-array-item`
|
|
630
|
+
- `extract-path`
|
|
631
|
+
|
|
632
|
+
Binding transforms are only for selecting one array item or extracting a nested field before
|
|
633
|
+
compatibility is evaluated. Do not use binding transforms for analytical reshaping. Use a
|
|
634
|
+
`tabular-transform` widget for projection, aggregate, pivot, unpivot, filtering, joining, or other
|
|
635
|
+
visible data operations.
|
|
412
636
|
|
|
413
637
|
Do not describe bindings loosely as “widget A uses widget B”. In this platform, bindings are always
|
|
414
638
|
port-to-port:
|
|
@@ -424,17 +648,16 @@ Resolve bindings from the target widget outward:
|
|
|
424
648
|
2. For each target input, record:
|
|
425
649
|
- `inputId`
|
|
426
650
|
- accepted contracts
|
|
651
|
+
- `acceptedOutputIds`
|
|
427
652
|
- `required`
|
|
428
653
|
- `cardinality`
|
|
429
654
|
- `effects`
|
|
430
655
|
3. Choose a source widget instance that actually publishes the required output id.
|
|
431
|
-
4.
|
|
656
|
+
4. Validate the source output id against `acceptedOutputIds` when the target input declares it.
|
|
657
|
+
5. If the source output is structured JSON or an array, resolve binding transforms before contract
|
|
432
658
|
validation.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
- `extract-path`
|
|
436
|
-
5. Validate the transformed contract against the target input `accepts`.
|
|
437
|
-
6. Treat the binding as usable only when the resolved status is `valid`.
|
|
659
|
+
6. Validate the transformed contract against the target input `accepts`.
|
|
660
|
+
7. Treat the binding as usable only when the resolved status is `valid`.
|
|
438
661
|
|
|
439
662
|
A binding can exist in workspace JSON and still be unusable at runtime. The runtime may resolve a
|
|
440
663
|
binding as:
|
|
@@ -461,6 +684,10 @@ Runtime and persistence rules:
|
|
|
461
684
|
- binding changes clear that target widget's `runtimeState`
|
|
462
685
|
- the widget settings `Bindings` tab and the workspace graph editor edit the same canonical binding model
|
|
463
686
|
- for `cardinality: "many"` inputs, preserve order and store an array of bindings for that input id
|
|
687
|
+
- for `cardinality: "one"` inputs, store a single binding object, not an array
|
|
688
|
+
- do not bind a widget to itself
|
|
689
|
+
- graph/editor interactions may be dragged in either visual direction, but persisted JSON is always
|
|
690
|
+
normalized back to target-owned bindings
|
|
464
691
|
|
|
465
692
|
Dynamic-IO rule:
|
|
466
693
|
|
|
@@ -471,6 +698,10 @@ Dynamic-IO rule:
|
|
|
471
698
|
Concrete examples:
|
|
472
699
|
|
|
473
700
|
- a Connection Query widget publishes `dataset`; a Tabular Transform widget can consume and republish `dataset`
|
|
701
|
+
- modern tabular consumers use explicit role inputs:
|
|
702
|
+
- historical/request-response data binds `dataset -> seedData`
|
|
703
|
+
- live or incremental data binds `updates -> liveUpdates`
|
|
704
|
+
- legacy `sourceData` should appear only when the widget contract still requires it
|
|
474
705
|
- `main-sequence-ai-agent-terminal` accepts one input with `cardinality: "many"`, so several
|
|
475
706
|
upstream widget contexts can feed one terminal
|
|
476
707
|
- widgets that implement `buildAgentSnapshot(...)` may also publish a synthetic `agent-context`
|
|
@@ -483,16 +714,85 @@ Review rule:
|
|
|
483
714
|
- target input id
|
|
484
715
|
- source widget instance id
|
|
485
716
|
- source output id
|
|
717
|
+
- accepted output id constraint, if any
|
|
486
718
|
- transform steps, if any
|
|
487
719
|
- final resolved contract
|
|
488
720
|
- final resolved status
|
|
489
721
|
|
|
722
|
+
## Managed Connection Sources
|
|
723
|
+
|
|
724
|
+
Some consumers support embedded connection authoring. Treat this as UI convenience, not a shortcut
|
|
725
|
+
around the source-widget model.
|
|
726
|
+
|
|
727
|
+
The persisted model still has:
|
|
728
|
+
|
|
729
|
+
- a visible owner widget, for example `graph`
|
|
730
|
+
- a hidden source widget, either `connection-query` or `connection-stream-query`
|
|
731
|
+
- `managedBy: { "ownerInstanceId": "<owner-id>", "role": "embedded-connection-source" }` on the hidden source widget
|
|
732
|
+
- a normal binding from the owner input to the hidden source output
|
|
733
|
+
|
|
734
|
+
Owner widget:
|
|
735
|
+
|
|
736
|
+
```json
|
|
737
|
+
{
|
|
738
|
+
"id": "graph-1",
|
|
739
|
+
"widgetId": "graph",
|
|
740
|
+
"props": {
|
|
741
|
+
"graphSourceMode": "connection",
|
|
742
|
+
"embeddedConnectionQuery": {
|
|
743
|
+
"connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
|
|
744
|
+
"queryModelId": "simple-table-sql",
|
|
745
|
+
"query": { "kind": "simple-table-sql", "sql": "select * from {{simple_table}}" }
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
"bindings": {
|
|
749
|
+
"seedData": {
|
|
750
|
+
"sourceWidgetId": "graph-1-source",
|
|
751
|
+
"sourceOutputId": "dataset"
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
Hidden source widget:
|
|
758
|
+
|
|
759
|
+
```json
|
|
760
|
+
{
|
|
761
|
+
"id": "graph-1-source",
|
|
762
|
+
"widgetId": "connection-query",
|
|
763
|
+
"title": "Graph Source",
|
|
764
|
+
"props": {
|
|
765
|
+
"connectionRef": { "id": 123, "typeId": "mainsequence.simple-table" },
|
|
766
|
+
"queryModelId": "simple-table-sql",
|
|
767
|
+
"query": { "kind": "simple-table-sql", "sql": "select * from {{simple_table}}" }
|
|
768
|
+
},
|
|
769
|
+
"managedBy": {
|
|
770
|
+
"ownerInstanceId": "graph-1",
|
|
771
|
+
"role": "embedded-connection-source"
|
|
772
|
+
},
|
|
773
|
+
"presentation": {
|
|
774
|
+
"placementMode": "sidebar",
|
|
775
|
+
"railVisibility": "hidden"
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
Managed stream sources bind hidden source `updates` to owner `liveUpdates`.
|
|
781
|
+
|
|
782
|
+
Rules:
|
|
783
|
+
|
|
784
|
+
- keep owner props, hidden source props, `managedBy`, and bindings aligned
|
|
785
|
+
- do not leave orphan hidden source widgets
|
|
786
|
+
- do not point `managedBy.ownerInstanceId` at a missing owner
|
|
787
|
+
- prefer explicit visible source widgets when they make the workspace easier to inspect or reuse
|
|
788
|
+
|
|
490
789
|
|
|
491
790
|
## Review Rules
|
|
492
791
|
|
|
493
792
|
When reviewing a workspace task, look for:
|
|
494
793
|
|
|
495
794
|
- guessed widget payloads
|
|
795
|
+
- guessed input ids or output ids
|
|
496
796
|
- widget work that skipped CLI registry verification
|
|
497
797
|
- widget work that skipped SDK client model review when one exists
|
|
498
798
|
- unknown or unverified `widgetId` values
|
|
@@ -500,12 +800,21 @@ When reviewing a workspace task, look for:
|
|
|
500
800
|
- workspace mutation attempted without first exporting the current workspace JSON
|
|
501
801
|
- widget payloads changed without saving versioned JSON drafts under `workspaces/widgets/`
|
|
502
802
|
- workspace-wide rewrites for one-widget changes
|
|
503
|
-
-
|
|
803
|
+
- current-user runtime state mixed into durable workspace JSON accidentally
|
|
504
804
|
- runtime ownership violations such as consumer widgets inventing canonical fetch paths
|
|
505
805
|
- unresolved external resource ids
|
|
506
|
-
- connection-backed consumers missing a source or transform
|
|
806
|
+
- connection-backed consumers missing a source widget or required transform widget
|
|
507
807
|
- generic tabular consumers bound to raw JSON instead of `core.tabular_frame@v1`
|
|
508
808
|
- full canonical tabular payloads that drift from `TabularFrameResponse`
|
|
809
|
+
- bindings authored in `props` instead of `widget.bindings`
|
|
810
|
+
- bindings placed on the source widget instead of the target widget
|
|
811
|
+
- bindings that ignore `acceptedOutputIds`
|
|
812
|
+
- `dataset -> liveUpdates`
|
|
813
|
+
- stream `dataset` used for live data instead of stream `updates`
|
|
814
|
+
- stream or incremental outputs wired to the wrong role input
|
|
815
|
+
- binding transforms used for analytical reshaping instead of a transform widget
|
|
816
|
+
- hidden managed source widgets missing their owner widget
|
|
817
|
+
- stale `managedBy.ownerInstanceId` values
|
|
509
818
|
- widget trees using structures not supported by the Main Sequence repository source models
|
|
510
819
|
|
|
511
820
|
## Validation Checklist
|
|
@@ -523,13 +832,25 @@ Do not claim success until you have checked:
|
|
|
523
832
|
- versioned workspace/widget JSON files were preserved pending user acceptance
|
|
524
833
|
- widget detail was reviewed for `widgetVersion`, configuration, runtime, IO, capabilities, agent hints, and examples
|
|
525
834
|
- the relevant SDK client model was reviewed when one exists
|
|
526
|
-
-
|
|
835
|
+
- every source widget has a valid connection ref, query model id, typed query payload, and output contract
|
|
836
|
+
- every `query.kind` matches `queryModelId`
|
|
527
837
|
- generic tabular consumers receive `core.tabular_frame@v1`
|
|
838
|
+
- every binding references an existing source widget and output id
|
|
839
|
+
- every binding targets an existing input id
|
|
840
|
+
- every binding matches the target input contract
|
|
841
|
+
- every binding respects `acceptedOutputIds` when declared
|
|
842
|
+
- `cardinality: "many"` bindings preserve order as arrays
|
|
843
|
+
- `cardinality: "one"` bindings are single binding objects
|
|
844
|
+
- historical/request-response data uses `dataset -> seedData` when the widget exposes role inputs
|
|
845
|
+
- live or incremental data uses `updates -> liveUpdates` when the widget exposes role inputs
|
|
528
846
|
- full canonical tabular frames match `TabularFrameResponse`
|
|
529
847
|
- widget ids and widget instance ids are correct
|
|
530
848
|
- any mounted widget that depends on a project API points to a FastAPI project resource that already exists
|
|
531
849
|
- any mounted widget that depends on a project API points to a FastAPI `ResourceRelease` that already exists
|
|
532
850
|
- local payload shape was reconciled against the verified widget id, widget-detail contract, and SDK model
|
|
851
|
+
- managed sources have valid `managedBy.ownerInstanceId` values
|
|
852
|
+
- owner widgets and hidden managed source widgets agree on connection/query props
|
|
853
|
+
- no credentials, native URLs, or backend route fragments are embedded in workspace JSON
|
|
533
854
|
- the chosen mutation mode is correct:
|
|
534
855
|
- full workspace update
|
|
535
856
|
- widget-scoped mutation
|