mainsequence 4.4.11__tar.gz → 4.4.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. {mainsequence-4.4.11/mainsequence.egg-info → mainsequence-4.4.12}/PKG-INFO +1 -1
  2. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/api.py +54 -0
  3. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/cli.py +122 -0
  4. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/agent_runtime_models.py +71 -0
  5. {mainsequence-4.4.11 → mainsequence-4.4.12/mainsequence.egg-info}/PKG-INFO +1 -1
  6. {mainsequence-4.4.11 → mainsequence-4.4.12}/pyproject.toml +1 -1
  7. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_cli.py +154 -0
  8. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_filter_normalization.py +33 -0
  9. {mainsequence-4.4.11 → mainsequence-4.4.12}/LICENSE +0 -0
  10. {mainsequence-4.4.11 → mainsequence-4.4.12}/README.md +0 -0
  11. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/AGENTS.md +0 -0
  12. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  13. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  14. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  15. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  16. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  17. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/widgets/app_components/SKILL.md +0 -0
  18. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/widgets/tables/SKILL.md +0 -0
  19. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/widgets/tabular_transform/SKILL.md +0 -0
  20. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  21. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  22. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  23. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  24. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  25. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  26. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  27. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  28. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  29. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  30. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  31. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  32. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  33. {mainsequence-4.4.11 → mainsequence-4.4.12}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  34. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/__init__.py +0 -0
  35. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/__main__.py +0 -0
  36. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/bootstrap.py +0 -0
  37. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/__init__.py +0 -0
  38. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/browser_auth.py +0 -0
  39. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/config.py +0 -0
  40. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/docker_utils.py +0 -0
  41. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/doctor.py +0 -0
  42. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/local_ops.py +0 -0
  43. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/migrations.py +0 -0
  44. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/model_filters.py +0 -0
  45. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/project_status.py +0 -0
  46. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/pydantic_cli.py +0 -0
  47. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/sdk_utils.py +0 -0
  48. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/ssh_utils.py +0 -0
  49. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/cli/ui.py +0 -0
  50. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/__init__.py +0 -0
  51. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/base.py +0 -0
  52. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/client.py +0 -0
  53. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/__init__.py +0 -0
  54. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/app_component.py +0 -0
  55. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/connections.py +0 -0
  56. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/__init__.py +0 -0
  57. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/adapter_from_api.py +0 -0
  58. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/response_mapping.py +0 -0
  59. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/table_visuals.py +0 -0
  60. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/tabular.py +0 -0
  61. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/contracts/ui.py +0 -0
  62. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/data_models.py +0 -0
  63. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/providers/__init__.py +0 -0
  64. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/providers/adapter_from_api.py +0 -0
  65. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/__init__.py +0 -0
  66. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/bindings.py +0 -0
  67. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/connection_query.py +0 -0
  68. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/registry.py +0 -0
  69. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/table.py +0 -0
  70. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/widgets/tabular_transform.py +0 -0
  71. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/workspace.py +0 -0
  72. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  73. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/workspaces/__init__.py +0 -0
  74. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/workspaces/documents.py +0 -0
  75. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/command_center/workspaces/mounted_widgets.py +0 -0
  76. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/compute_validation.py +0 -0
  77. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  78. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  79. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  80. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  81. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/dtype_codec.py +0 -0
  82. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/exceptions.py +0 -0
  83. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/fastapi/__init__.py +0 -0
  84. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/fastapi/auth.py +0 -0
  85. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/metatables/__init__.py +0 -0
  86. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/metatables/core.py +0 -0
  87. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/models_foundry.py +0 -0
  88. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/models_helpers.py +0 -0
  89. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/models_user.py +0 -0
  90. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/client/utils.py +0 -0
  91. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/defaults.py +0 -0
  92. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/instrumentation/__init__.py +0 -0
  93. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/instrumentation/utils.py +0 -0
  94. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/logconf.py +0 -0
  95. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/__init__.py +0 -0
  96. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/__main__.py +0 -0
  97. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  98. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  99. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  100. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  101. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
  102. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  103. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  104. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  105. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  106. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  107. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/future_registry.py +0 -0
  108. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/hashing.py +0 -0
  109. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  110. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  111. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/env.py +0 -0
  112. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/provider.py +0 -0
  113. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/registry.py +0 -0
  114. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  115. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  116. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  117. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  118. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  119. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/schema_names.py +0 -0
  120. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  121. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/runtime_flags.py +0 -0
  122. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence/scaffold_skills.py +0 -0
  123. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence.egg-info/SOURCES.txt +0 -0
  124. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence.egg-info/dependency_links.txt +0 -0
  125. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence.egg-info/entry_points.txt +0 -0
  126. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence.egg-info/requires.txt +0 -0
  127. {mainsequence-4.4.11 → mainsequence-4.4.12}/mainsequence.egg-info/top_level.txt +0 -0
  128. {mainsequence-4.4.11 → mainsequence-4.4.12}/setup.cfg +0 -0
  129. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_auth_precedence.py +0 -0
  130. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_build_operations_hashing.py +0 -0
  131. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_cli_browser_auth.py +0 -0
  132. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_cli_migrations.py +0 -0
  133. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_client.py +0 -0
  134. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_command_center_app_component_models.py +0 -0
  135. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_command_center_data_models.py +0 -0
  136. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_command_center_models.py +0 -0
  137. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_command_center_table_contracts.py +0 -0
  138. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_command_center_tabular_transform.py +0 -0
  139. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  140. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_data_node_storage_dimension_queries.py +0 -0
  141. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_data_node_update_flow.py +0 -0
  142. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_dependency_extras.py +0 -0
  143. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_duckdb_interface_dimensions.py +0 -0
  144. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_instrumentation.py +0 -0
  145. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_logconf.py +0 -0
  146. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_meta_table_migrations.py +0 -0
  147. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_meta_tables_client_models.py +0 -0
  148. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  149. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_models_user_request_bound_auth.py +0 -0
  150. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_pod_project_resolution.py +0 -0
  151. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_project_batch_jobs_from_file.py +0 -0
  152. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_run_configuration.py +0 -0
  153. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_scaffold_skills.py +0 -0
  154. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_schema_names.py +0 -0
  155. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_secret_client_model.py +0 -0
  156. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_source_table_configuration.py +0 -0
  157. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_sqlite_interface_dimensions.py +0 -0
  158. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_update_runner_uid_runtime.py +0 -0
  159. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_update_statistics.py +0 -0
  160. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_update_uid_guards.py +0 -0
  161. {mainsequence-4.4.11 → mainsequence-4.4.12}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.11
3
+ Version: 4.4.12
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
@@ -1239,6 +1239,60 @@ def get_agent_latest_session(
1239
1239
  raise ApiError(f"Agent latest session fetch failed: {e}") from e
1240
1240
 
1241
1241
 
1242
+ def list_agent_sessions(
1243
+ *,
1244
+ timeout: int | None = None,
1245
+ filters: dict[str, Any] | None = None,
1246
+ agent_uid: str | None = None,
1247
+ agent_unique_id: str | None = None,
1248
+ ) -> list[dict[str, Any]]:
1249
+ """
1250
+ List agent sessions via SDK client model, optionally scoped to one agent.
1251
+ """
1252
+ if agent_uid and agent_unique_id:
1253
+ raise ApiError("Pass either agent_uid or agent_unique_id, not both.")
1254
+
1255
+ session_filters = dict(filters or {})
1256
+ if agent_uid:
1257
+ session_filters["agent_uid"] = str(agent_uid)
1258
+ elif agent_unique_id:
1259
+ try:
1260
+ agent = _run_sdk_model_operation(
1261
+ module_name="mainsequence.client.agent_runtime_models",
1262
+ class_name="Agent",
1263
+ operation=lambda ClientAgent: ClientAgent.get_by_agent_unique_id(
1264
+ str(agent_unique_id), timeout=timeout
1265
+ ),
1266
+ )
1267
+ except Exception as e:
1268
+ err_name = type(e).__name__
1269
+ if err_name in {"DoesNotExist", "NotFoundError"}:
1270
+ raise ApiError(f"Agent not found for agent_unique_id={agent_unique_id!r}") from e
1271
+ if isinstance(e, (ApiError, NotLoggedIn)):
1272
+ raise
1273
+ raise ApiError(f"Agent lookup failed for agent_unique_id={agent_unique_id!r}: {e}") from e
1274
+
1275
+ resolved_agent = _sdk_object_to_dict(agent)
1276
+ resolved_agent_uid = str(resolved_agent.get("uid") or "").strip()
1277
+ if not resolved_agent_uid:
1278
+ raise ApiError(f"Agent lookup returned no uid for agent_unique_id={agent_unique_id!r}")
1279
+ session_filters["agent_uid"] = resolved_agent_uid
1280
+
1281
+ try:
1282
+ payload = _run_sdk_model_operation(
1283
+ module_name="mainsequence.client.agent_runtime_models",
1284
+ class_name="AgentSession",
1285
+ operation=lambda ClientAgentSession: ClientAgentSession.filter(
1286
+ timeout=timeout, **session_filters
1287
+ ),
1288
+ )
1289
+ return [_sdk_object_to_dict(item) for item in list(payload or [])]
1290
+ except Exception as e:
1291
+ if isinstance(e, (ApiError, NotLoggedIn)):
1292
+ raise
1293
+ raise ApiError(f"Agent sessions fetch failed: {e}") from e
1294
+
1295
+
1242
1296
  def get_agent_session(
1243
1297
  agent_session_uid: str,
1244
1298
  *,
@@ -130,6 +130,7 @@ from .api import (
130
130
  get_secret,
131
131
  get_workspace,
132
132
  list_agent_runs,
133
+ list_agent_sessions,
133
134
  list_agent_users_can_edit,
134
135
  list_agent_users_can_view,
135
136
  list_agents,
@@ -3948,6 +3949,82 @@ def _agent_get_latest_session_impl(
3948
3949
  print_kv("Agent Session Details", _format_agent_session_details(agent_session_payload))
3949
3950
 
3950
3951
 
3952
+ def _agent_session_list_impl(
3953
+ *,
3954
+ agent_uid: str | None,
3955
+ agent_unique_id: str | None,
3956
+ timeout: int | None,
3957
+ filter_entries: list[str] | None,
3958
+ show_filters: bool,
3959
+ ) -> None:
3960
+ filters = _resolve_cli_list_filters(
3961
+ model_ref=AGENT_SESSION_MODEL_REF,
3962
+ filter_entries=filter_entries,
3963
+ show_filters=show_filters,
3964
+ command_label="Agent Sessions",
3965
+ )
3966
+ if agent_uid and agent_unique_id:
3967
+ error("Pass either `--agent-uid` or `--agent-unique-id`, not both.")
3968
+ raise typer.Exit(1)
3969
+ if (agent_uid or agent_unique_id) and any(
3970
+ key in filters for key in ("agent_uid", "agent_uid__in")
3971
+ ):
3972
+ error(
3973
+ "Do not pass `--filter agent_uid=...` with `--agent-uid` or "
3974
+ "`--agent-unique-id`. Use only one agent scope."
3975
+ )
3976
+ raise typer.Exit(1)
3977
+
3978
+ _require_login()
3979
+
3980
+ try:
3981
+ agent_sessions = list_agent_sessions(
3982
+ timeout=timeout,
3983
+ filters=filters,
3984
+ agent_uid=agent_uid,
3985
+ agent_unique_id=agent_unique_id,
3986
+ )
3987
+ except ApiError as e:
3988
+ error(f"Agent sessions fetch failed: {e}")
3989
+ raise typer.Exit(1) from e
3990
+
3991
+ if _emit_json(agent_sessions):
3992
+ return
3993
+
3994
+ rows: list[list[str]] = []
3995
+ for agent_session_payload in agent_sessions:
3996
+ rows.append(
3997
+ [
3998
+ str(agent_session_payload.get("uid") or "-"),
3999
+ str(agent_session_payload.get("agent_uid") or "-"),
4000
+ str(
4001
+ agent_session_payload.get("agent_name")
4002
+ or agent_session_payload.get("agent_type")
4003
+ or "-"
4004
+ ),
4005
+ str(agent_session_payload.get("status") or "-"),
4006
+ str(
4007
+ agent_session_payload.get("runtime_state")
4008
+ or agent_session_payload.get("engine_name")
4009
+ or "-"
4010
+ ),
4011
+ str(agent_session_payload.get("started_at") or "-"),
4012
+ str(agent_session_payload.get("ended_at") or "-"),
4013
+ str(agent_session_payload.get("name") or "-"),
4014
+ ]
4015
+ )
4016
+
4017
+ if rows:
4018
+ print_table(
4019
+ "Agent Sessions",
4020
+ ["UID", "Agent UID", "Agent", "Status", "Runtime", "Started At", "Ended At", "Name"],
4021
+ rows,
4022
+ )
4023
+ else:
4024
+ info("No agent sessions.")
4025
+ info(f"Total agent sessions: {len(agent_sessions)}")
4026
+
4027
+
3951
4028
  def _agent_session_detail_impl(
3952
4029
  *,
3953
4030
  agent_session_uid: str,
@@ -6674,6 +6751,51 @@ def agent_get_latest_session_cmd(
6674
6751
  _agent_get_latest_session_impl(agent_uid=agent_uid, timeout=timeout)
6675
6752
 
6676
6753
 
6754
+ @agent_session_group.command("list")
6755
+ def agent_session_list_cmd(
6756
+ agent_uid: str | None = pydantic_option(
6757
+ AGENT_SESSION_MODEL_REF,
6758
+ "agent_uid",
6759
+ None,
6760
+ "--agent-uid",
6761
+ help="Agent UID to scope the session list.",
6762
+ ),
6763
+ agent_unique_id: str | None = pydantic_option(
6764
+ AGENT_MODEL_REF,
6765
+ "agent_unique_id",
6766
+ None,
6767
+ "--agent-unique-id",
6768
+ help="Agent unique id to resolve before listing sessions.",
6769
+ ),
6770
+ filter_entries: list[str] | None = typer.Option(None, "--filter", help=LIST_FILTER_OPTION_HELP),
6771
+ show_filters: bool = typer.Option(
6772
+ False, "--show-filters", help="Show the filters supported by this list command and exit."
6773
+ ),
6774
+ timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
6775
+ ):
6776
+ """
6777
+ List agent sessions, optionally scoped to one agent.
6778
+
6779
+ Uses SDK client `AgentSession.filter()` as the single source of truth.
6780
+
6781
+ Examples
6782
+ --------
6783
+ ```bash
6784
+ mainsequence agent session list
6785
+ mainsequence agent session list --agent-uid e0e75693-4110-464c-93e0-82c7fd9c9a23
6786
+ mainsequence agent session list --agent-unique-id research-copilot
6787
+ mainsequence agent session list --agent-uid e0e75693-4110-464c-93e0-82c7fd9c9a23 --filter status=running
6788
+ ```
6789
+ """
6790
+ _agent_session_list_impl(
6791
+ agent_uid=agent_uid,
6792
+ agent_unique_id=agent_unique_id,
6793
+ timeout=timeout,
6794
+ filter_entries=filter_entries,
6795
+ show_filters=show_filters,
6796
+ )
6797
+
6798
+
6677
6799
  @agent_session_group.command("detail")
6678
6800
  def agent_session_detail_cmd(
6679
6801
  agent_session_uid: str = pydantic_argument(
@@ -48,6 +48,54 @@ class AgentSemanticSearchResult(BasePydanticModel):
48
48
  )
49
49
 
50
50
 
51
+ class AgentRuntimeImageDriftCheck(BasePydanticModel):
52
+ key: str = Field(..., description="Machine-readable identifier for the drift check.")
53
+ label: str = Field(..., description="Human-readable label for the drift check.")
54
+ status: str = Field(..., description="Backend status for this drift check.")
55
+ has_drift: bool = Field(..., description="Whether this check detected runtime drift.")
56
+ matches: bool = Field(..., description="Whether the actual runtime state matches the expected state.")
57
+ reason: str = Field("", description="Machine-readable explanation for the status.")
58
+ message: str = Field("", description="Human-readable explanation for this drift check.")
59
+ autoheal_supported: bool = Field(
60
+ False,
61
+ description="Whether the backend can automatically repair this specific drift condition.",
62
+ )
63
+ autoheal_mode: str | None = Field(
64
+ None,
65
+ description="Backend repair mode for this check when automatic repair is supported.",
66
+ )
67
+ autoheal_message: str | None = Field(
68
+ None,
69
+ description="Human-readable automatic repair guidance for this check.",
70
+ )
71
+ expected_image_uri: str = Field("", description="Expected runtime image URI, when the check is image-based.")
72
+ actual_image_uri: str = Field("", description="Actual runtime image URI, when the check is image-based.")
73
+ expected_commit_hash: str = Field("", description="Expected project commit hash, when the check is commit-based.")
74
+ actual_commit_hash: str = Field("", description="Actual runtime commit hash, when the check is commit-based.")
75
+
76
+
77
+ class AgentRuntimeImageDrift(BasePydanticModel):
78
+ agent_kind: str = Field(..., description="Runtime family that produced the drift payload.")
79
+ available: bool = Field(..., description="Whether drift information could be resolved.")
80
+ has_drift: bool = Field(..., description="Whether any included drift check is currently drifting.")
81
+ autoheal_available: bool = Field(
82
+ False,
83
+ description="Whether all currently drifting checks can be repaired automatically by the backend.",
84
+ )
85
+ autoheal_message: str | None = Field(
86
+ None,
87
+ description="Human-readable summary of automatic repair availability.",
88
+ )
89
+ checks: list[AgentRuntimeImageDriftCheck] = Field(
90
+ default_factory=list,
91
+ description="Individual runtime drift checks returned by the backend.",
92
+ )
93
+ detail: str | None = Field(
94
+ None,
95
+ description="Additional backend detail when drift information is unavailable or degraded.",
96
+ )
97
+
98
+
51
99
  class AgentSessionRuntimeAccess(BasePydanticModel):
52
100
  coding_agent_service_id: str = Field(
53
101
  ...,
@@ -69,6 +117,24 @@ class AgentSessionRuntimeAccess(BasePydanticModel):
69
117
  ...,
70
118
  description="Bearer token that authorizes calls to the coding-agent gateway.",
71
119
  )
120
+ is_ready: bool = Field(
121
+ False,
122
+ description="Whether the resolved coding-agent runtime is currently routable.",
123
+ )
124
+ knative_service_runtime_uid: str | None = Field(
125
+ None,
126
+ description="Public UID of the linked Knative service runtime, when the backend has one.",
127
+ )
128
+ image_drift: AgentRuntimeImageDrift | None = Field(
129
+ None,
130
+ description="Runtime image drift payload for the resolved coding-agent runtime.",
131
+ )
132
+
133
+ @property
134
+ def image_drift_dict(self) -> dict[str, Any] | None:
135
+ if self.image_drift is None:
136
+ return None
137
+ return self.image_drift.model_dump()
72
138
 
73
139
 
74
140
  class Agent(ShareableObjectMixin, BaseObjectOrm, BasePydanticModel):
@@ -445,6 +511,7 @@ class AgentSession(BaseObjectOrm, BasePydanticModel):
445
511
  ENDPOINT: ClassVar[str] = "agents/v1/sessions"
446
512
  FILTERSET_FIELDS: ClassVar[dict[str, list[str]] | None] = {
447
513
  "uid": ["exact", "in"],
514
+ "agent_uid": ["exact", "in"],
448
515
  "status": ["exact"],
449
516
  "search": ["exact"],
450
517
  "q": ["exact"],
@@ -452,6 +519,8 @@ class AgentSession(BaseObjectOrm, BasePydanticModel):
452
519
  FILTER_VALUE_NORMALIZERS: ClassVar[dict[str, str]] = {
453
520
  "uid": "uid",
454
521
  "uid__in": "uid",
522
+ "agent_uid": "uid",
523
+ "agent_uid__in": "uid",
455
524
  "status": "str",
456
525
  "search": "str",
457
526
  "q": "str",
@@ -597,6 +666,8 @@ class AgentSession(BaseObjectOrm, BasePydanticModel):
597
666
 
598
667
  __all__ = [
599
668
  "Agent",
669
+ "AgentRuntimeImageDrift",
670
+ "AgentRuntimeImageDriftCheck",
600
671
  "AgentSemanticSearchResult",
601
672
  "AgentSessionRuntimeAccess",
602
673
  "UserOrchestratorAgentService",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.11
3
+ Version: 4.4.12
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "4.4.11"
7
+ version = "4.4.12"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1848,6 +1848,107 @@ def test_get_agent_latest_session_uses_client_model(cli_mod, monkeypatch):
1848
1848
  assert out["uid"] == session_uid
1849
1849
 
1850
1850
 
1851
+ def test_list_agent_sessions_uses_client_model(cli_mod, monkeypatch):
1852
+ api_mod = importlib.import_module("mainsequence.cli.api")
1853
+ captured = {}
1854
+ agent_uid = "e0e75693-4110-464c-93e0-82c7fd9c9a23"
1855
+ session_uid = "3f1cc452-43ec-49cb-b2ba-87dbac164d29"
1856
+
1857
+ class FakeAgentSession:
1858
+ @staticmethod
1859
+ def model_dump(mode="json"):
1860
+ return {
1861
+ "uid": session_uid,
1862
+ "agent_uid": agent_uid,
1863
+ "status": "completed",
1864
+ "llm_provider": "openai",
1865
+ "llm_model": "gpt-5.4",
1866
+ "engine_name": "codex",
1867
+ }
1868
+
1869
+ def _run_sdk_model_operation(*, module_name, class_name, operation, project_id_env=None):
1870
+ captured["module_name"] = module_name
1871
+ captured["class_name"] = class_name
1872
+
1873
+ class _ClientAgentSession:
1874
+ @classmethod
1875
+ def filter(cls, timeout=None, **filters):
1876
+ captured["timeout"] = timeout
1877
+ captured["filters"] = filters
1878
+ return [FakeAgentSession()]
1879
+
1880
+ return operation(_ClientAgentSession)
1881
+
1882
+ monkeypatch.setattr(api_mod, "_run_sdk_model_operation", _run_sdk_model_operation)
1883
+
1884
+ out = api_mod.list_agent_sessions(
1885
+ timeout=18,
1886
+ filters={"status": "completed"},
1887
+ agent_uid=agent_uid,
1888
+ )
1889
+ assert captured == {
1890
+ "module_name": "mainsequence.client.agent_runtime_models",
1891
+ "class_name": "AgentSession",
1892
+ "timeout": 18,
1893
+ "filters": {"status": "completed", "agent_uid": agent_uid},
1894
+ }
1895
+ assert out == [FakeAgentSession().model_dump()]
1896
+
1897
+
1898
+ def test_list_agent_sessions_resolves_agent_unique_id(cli_mod, monkeypatch):
1899
+ api_mod = importlib.import_module("mainsequence.cli.api")
1900
+ captured = {"calls": []}
1901
+ agent_uid = "e0e75693-4110-464c-93e0-82c7fd9c9a23"
1902
+ session_uid = "3f1cc452-43ec-49cb-b2ba-87dbac164d29"
1903
+
1904
+ class FakeAgent:
1905
+ @staticmethod
1906
+ def model_dump(mode="json"):
1907
+ return {"uid": agent_uid, "agent_unique_id": "research-copilot"}
1908
+
1909
+ class FakeAgentSession:
1910
+ @staticmethod
1911
+ def model_dump(mode="json"):
1912
+ return {"uid": session_uid, "agent_uid": agent_uid, "status": "running"}
1913
+
1914
+ def _run_sdk_model_operation(*, module_name, class_name, operation, project_id_env=None):
1915
+ captured["calls"].append((module_name, class_name))
1916
+ if class_name == "Agent":
1917
+
1918
+ class _ClientAgent:
1919
+ @classmethod
1920
+ def get_by_agent_unique_id(cls, agent_unique_id, timeout=None):
1921
+ captured["agent_unique_id"] = agent_unique_id
1922
+ captured["agent_timeout"] = timeout
1923
+ return FakeAgent()
1924
+
1925
+ return operation(_ClientAgent)
1926
+
1927
+ class _ClientAgentSession:
1928
+ @classmethod
1929
+ def filter(cls, timeout=None, **filters):
1930
+ captured["session_timeout"] = timeout
1931
+ captured["filters"] = filters
1932
+ return [FakeAgentSession()]
1933
+
1934
+ return operation(_ClientAgentSession)
1935
+
1936
+ monkeypatch.setattr(api_mod, "_run_sdk_model_operation", _run_sdk_model_operation)
1937
+
1938
+ out = api_mod.list_agent_sessions(agent_unique_id="research-copilot", timeout=19)
1939
+ assert captured == {
1940
+ "calls": [
1941
+ ("mainsequence.client.agent_runtime_models", "Agent"),
1942
+ ("mainsequence.client.agent_runtime_models", "AgentSession"),
1943
+ ],
1944
+ "agent_unique_id": "research-copilot",
1945
+ "agent_timeout": 19,
1946
+ "session_timeout": 19,
1947
+ "filters": {"agent_uid": agent_uid},
1948
+ }
1949
+ assert out == [FakeAgentSession().model_dump()]
1950
+
1951
+
1851
1952
  def test_get_agent_session_uses_client_model(cli_mod, monkeypatch):
1852
1953
  api_mod = importlib.import_module("mainsequence.cli.api")
1853
1954
  captured = {}
@@ -7385,6 +7486,59 @@ def test_agent_get_latest_session(cli_mod, runner, monkeypatch):
7385
7486
  assert "prompt_tokens" in result.output
7386
7487
 
7387
7488
 
7489
+ def test_agent_session_list_scoped_by_agent_uid(cli_mod, runner, monkeypatch):
7490
+ captured = {}
7491
+ monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
7492
+ agent_uid = "e0e75693-4110-464c-93e0-82c7fd9c9a23"
7493
+ session_uid = "3f1cc452-43ec-49cb-b2ba-87dbac164d29"
7494
+
7495
+ def _list_agent_sessions(*, timeout=None, filters=None, agent_uid=None, agent_unique_id=None):
7496
+ captured["timeout"] = timeout
7497
+ captured["filters"] = filters
7498
+ captured["agent_uid"] = agent_uid
7499
+ captured["agent_unique_id"] = agent_unique_id
7500
+ return [
7501
+ {
7502
+ "uid": session_uid,
7503
+ "agent_uid": agent_uid,
7504
+ "agent_name": "Research Copilot",
7505
+ "status": "running",
7506
+ "runtime_state": "connected",
7507
+ "started_at": "2026-04-11T09:15:00Z",
7508
+ "name": "Rates check",
7509
+ }
7510
+ ]
7511
+
7512
+ monkeypatch.setattr(cli_mod, "list_agent_sessions", _list_agent_sessions)
7513
+
7514
+ result = runner.invoke(
7515
+ cli_mod.app,
7516
+ [
7517
+ "agent",
7518
+ "session",
7519
+ "list",
7520
+ "--agent-uid",
7521
+ agent_uid,
7522
+ "--filter",
7523
+ "status=running",
7524
+ "--timeout",
7525
+ "12",
7526
+ ],
7527
+ )
7528
+ assert result.exit_code == 0
7529
+ assert captured == {
7530
+ "timeout": 12,
7531
+ "filters": {"status": "running"},
7532
+ "agent_uid": agent_uid,
7533
+ "agent_unique_id": None,
7534
+ }
7535
+ assert "Agent Sessions" in result.output
7536
+ assert "3f1cc45" in result.output
7537
+ assert "Copilot" in result.output
7538
+ assert "connect" in result.output
7539
+ assert "Total agent sessions: 1" in result.output
7540
+
7541
+
7388
7542
  def test_agent_session_detail(cli_mod, runner, monkeypatch):
7389
7543
  monkeypatch.setattr(cli_mod, "_require_login", lambda: {"username": "u"})
7390
7544
  monkeypatch.setattr(
@@ -1473,6 +1473,34 @@ def test_agent_session_runtime_access_uses_session_uid_route(monkeypatch):
1473
1473
  "mode": "token",
1474
1474
  "rpc_url": "https://runtime.main-sequence.app/rpc",
1475
1475
  "token": "tok-secret",
1476
+ "is_ready": True,
1477
+ "knative_service_runtime_uid": "70c6efb9-8e80-4051-ad3a-f432b2c37f5a",
1478
+ "image_drift": {
1479
+ "agent_kind": "astro_orchestrator",
1480
+ "available": True,
1481
+ "has_drift": False,
1482
+ "autoheal_available": False,
1483
+ "autoheal_message": "No automatic drift repair is needed.",
1484
+ "checks": [
1485
+ {
1486
+ "key": "orchestrator_image",
1487
+ "label": "Orchestrator image",
1488
+ "status": "match",
1489
+ "has_drift": False,
1490
+ "matches": True,
1491
+ "reason": "match",
1492
+ "message": "The runtime image matches the catalog image.",
1493
+ "autoheal_supported": True,
1494
+ "autoheal_mode": "request_driven_runtime_sync",
1495
+ "autoheal_message": "No runtime repair is needed.",
1496
+ "expected_image_uri": "registry.example/astro@sha256:expected",
1497
+ "actual_image_uri": "registry.example/astro@sha256:expected",
1498
+ "expected_commit_hash": "",
1499
+ "actual_commit_hash": "",
1500
+ }
1501
+ ],
1502
+ "detail": None,
1503
+ },
1476
1504
  }
1477
1505
 
1478
1506
  def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
@@ -1487,6 +1515,11 @@ def test_agent_session_runtime_access_uses_session_uid_route(monkeypatch):
1487
1515
  access = agent_models_mod.AgentSession.resolve_runtime_access(session_uid, timeout=11)
1488
1516
 
1489
1517
  assert access.coding_agent_service_id == "svc-12"
1518
+ assert access.is_ready is True
1519
+ assert access.knative_service_runtime_uid == "70c6efb9-8e80-4051-ad3a-f432b2c37f5a"
1520
+ assert access.image_drift is not None
1521
+ assert access.image_drift.agent_kind == "astro_orchestrator"
1522
+ assert access.image_drift.checks[0].key == "orchestrator_image"
1490
1523
  assert captured == {
1491
1524
  "r_type": "POST",
1492
1525
  "url": f"{agent_models_mod.AgentSession.get_object_url()}/{session_uid}/resolve_runtime_access/",
File without changes
File without changes
File without changes