mainsequence 8.1.4__tar.gz → 8.1.6__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-8.1.4/mainsequence.egg-info → mainsequence-8.1.6}/PKG-INFO +1 -1
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/agent_runtime_models.py +29 -2
- {mainsequence-8.1.4 → mainsequence-8.1.6/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-8.1.4 → mainsequence-8.1.6}/pyproject.toml +1 -1
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_cli.py +3 -3
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_filter_normalization.py +88 -8
- {mainsequence-8.1.4 → mainsequence-8.1.6}/LICENSE +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/MANIFEST.in +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/README.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_publishing/time_index_table_updates/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/__main__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/bootstrap.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/api.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/cli.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/code_repository_status.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/config.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/cli/ui.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/base.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/client.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/metatables/core.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/models_user.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/observability.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/code_repository_context.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/code_repository_skills.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/defaults.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/logconf.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/alembic.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/env.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/provider.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/registry.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_refs.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/__init__.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/configuration.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/dependencies.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/managers.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/namespacing.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/runner.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/updaters.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/repository_identity_security.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/scaffold_skills.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/setup.cfg +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/fixtures/time_index_table_update_hash_v2_golden.json +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_auth_precedence.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_canonical_api_route_contract.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_cli_migrations.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_client.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_batch_jobs_from_file.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_branch_contract.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_documentation_contract.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_runtime_context.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_skills.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_dependency_extras.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_environment_resource_context.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_environment_response_contracts.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_instrumentation.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_local_ops.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_logconf.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_notification_uid_contract.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_observability_client.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_scaffold_skills.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_schema_names.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_secret_client_model.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_ssh_utils.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_access_dimension_audit.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_dimension_queries.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_configuration.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_configuration_client.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_flow.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_hard_cut.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_update_statistics.py +0 -0
- {mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_update_uid_guards.py +0 -0
|
@@ -30,6 +30,8 @@ DEFAULT_AGENT_RUNTIME_ACCESS_CACHE_EXPIRY_SKEW_SECONDS = 30.0
|
|
|
30
30
|
STANDARD_A2A_MESSAGE_SEND_PATH = "/api/a2a/v1/message:send"
|
|
31
31
|
STANDARD_A2A_TASKS_PATH = "/api/a2a/v1/tasks"
|
|
32
32
|
STANDARD_A2A_CONTENT_TYPE = "application/a2a+json"
|
|
33
|
+
STANDARD_A2A_REQUESTER_ROLE = "ROLE_REQUESTER"
|
|
34
|
+
STANDARD_A2A_RESPONDER_ROLE = "ROLE_RESPONDER"
|
|
33
35
|
STANDARD_A2A_RESPONSE_KIND_EXTENSION_URI = "https://mainsequence.ai/a2a/extensions/response-kind/v1"
|
|
34
36
|
STANDARD_A2A_OUTPUT_CONTRACT_METADATA_KEY = (
|
|
35
37
|
"https://mainsequence.ai/a2a/extensions/output-contract/v1"
|
|
@@ -105,6 +107,14 @@ class A2AMessageSendResult(BasePydanticModel):
|
|
|
105
107
|
def _require_exact_result(self) -> A2AMessageSendResult:
|
|
106
108
|
if (self.message is None) == (self.task is None):
|
|
107
109
|
raise ValueError("A2A message-send result must contain exactly one of message or task")
|
|
110
|
+
if (
|
|
111
|
+
self.message is not None
|
|
112
|
+
and self.message.get("role") != STANDARD_A2A_RESPONDER_ROLE
|
|
113
|
+
):
|
|
114
|
+
raise ValueError(
|
|
115
|
+
"A2A message result role must be "
|
|
116
|
+
f"{STANDARD_A2A_RESPONDER_ROLE}."
|
|
117
|
+
)
|
|
108
118
|
return self
|
|
109
119
|
|
|
110
120
|
@property
|
|
@@ -227,6 +237,13 @@ class AgentRuntimeImageDrift(BasePydanticModel):
|
|
|
227
237
|
has_drift: bool = Field(
|
|
228
238
|
False, description="Whether any included drift check is currently drifting."
|
|
229
239
|
)
|
|
240
|
+
requires_user_action: bool = Field(
|
|
241
|
+
False,
|
|
242
|
+
description=(
|
|
243
|
+
"Whether at least one current drift condition requires explicit user "
|
|
244
|
+
"action instead of backend autohealing."
|
|
245
|
+
),
|
|
246
|
+
)
|
|
230
247
|
autoheal_available: bool = Field(
|
|
231
248
|
False,
|
|
232
249
|
description="Whether all currently drifting checks can be repaired automatically by the backend.",
|
|
@@ -670,7 +687,7 @@ class Agent(
|
|
|
670
687
|
body: dict[str, Any] = {
|
|
671
688
|
"message": {
|
|
672
689
|
"messageId": str(message_id or "").strip() or f"msg-{uuid.uuid4()}",
|
|
673
|
-
"role":
|
|
690
|
+
"role": STANDARD_A2A_REQUESTER_ROLE,
|
|
674
691
|
"parts": parts,
|
|
675
692
|
},
|
|
676
693
|
"configuration": {
|
|
@@ -1519,7 +1536,7 @@ class AgentSession(OwnerLogMixin, BaseObjectOrm, BasePydanticModel):
|
|
|
1519
1536
|
body: dict[str, Any] = {
|
|
1520
1537
|
"message": {
|
|
1521
1538
|
"messageId": normalized_message_id,
|
|
1522
|
-
"role":
|
|
1539
|
+
"role": STANDARD_A2A_REQUESTER_ROLE,
|
|
1523
1540
|
"contextId": agent_session_uid,
|
|
1524
1541
|
"parts": parts,
|
|
1525
1542
|
},
|
|
@@ -1725,6 +1742,16 @@ class AgentSession(OwnerLogMixin, BaseObjectOrm, BasePydanticModel):
|
|
|
1725
1742
|
response=response,
|
|
1726
1743
|
payload=body,
|
|
1727
1744
|
)
|
|
1745
|
+
if (
|
|
1746
|
+
result.message is not None
|
|
1747
|
+
and result.message.get("contextId") != session_uid
|
|
1748
|
+
):
|
|
1749
|
+
raise ApiError(
|
|
1750
|
+
"Standard A2A message response contextId does not match the target "
|
|
1751
|
+
"AgentSession.",
|
|
1752
|
+
response=response,
|
|
1753
|
+
payload=body,
|
|
1754
|
+
)
|
|
1728
1755
|
return result
|
|
1729
1756
|
|
|
1730
1757
|
@classmethod
|
|
@@ -1055,7 +1055,7 @@ def test_send_agent_session_a2a_message_uses_client_model(cli_mod, monkeypatch):
|
|
|
1055
1055
|
return {
|
|
1056
1056
|
"message": {
|
|
1057
1057
|
"messageId": "msg-runtime-output",
|
|
1058
|
-
"role": "
|
|
1058
|
+
"role": "ROLE_RESPONDER",
|
|
1059
1059
|
"contextId": agent_session,
|
|
1060
1060
|
"parts": [{"text": "Done."}],
|
|
1061
1061
|
}
|
|
@@ -6785,7 +6785,7 @@ def test_agent_session_a2a_send_always_returns_json(cli_mod, runner, monkeypatch
|
|
|
6785
6785
|
return {
|
|
6786
6786
|
"message": {
|
|
6787
6787
|
"messageId": "msg-runtime-output",
|
|
6788
|
-
"role": "
|
|
6788
|
+
"role": "ROLE_RESPONDER",
|
|
6789
6789
|
"contextId": agent_session_uid,
|
|
6790
6790
|
"parts": [{"text": '{"ok": true}'}],
|
|
6791
6791
|
}
|
|
@@ -6860,7 +6860,7 @@ def test_agent_session_a2a_send_does_not_require_runtime_resolve(cli_mod, runner
|
|
|
6860
6860
|
return {
|
|
6861
6861
|
"message": {
|
|
6862
6862
|
"messageId": "msg-runtime-output",
|
|
6863
|
-
"role": "
|
|
6863
|
+
"role": "ROLE_RESPONDER",
|
|
6864
6864
|
"contextId": args[0],
|
|
6865
6865
|
"parts": [{"text": "Done."}],
|
|
6866
6866
|
}
|
|
@@ -3609,6 +3609,7 @@ def test_agent_session_runtime_access_uses_session_uid_route(monkeypatch):
|
|
|
3609
3609
|
"agent_kind": "astro_orchestrator",
|
|
3610
3610
|
"available": True,
|
|
3611
3611
|
"has_drift": False,
|
|
3612
|
+
"requires_user_action": False,
|
|
3612
3613
|
"autoheal_available": False,
|
|
3613
3614
|
"autoheal_message": "No automatic drift repair is needed.",
|
|
3614
3615
|
"checks": [
|
|
@@ -3667,6 +3668,7 @@ def test_agent_session_runtime_access_uses_session_uid_route(monkeypatch):
|
|
|
3667
3668
|
assert access.knative_service_runtime_uid == "70c6efb9-8e80-4051-ad3a-f432b2c37f5a"
|
|
3668
3669
|
assert access.image_drift is not None
|
|
3669
3670
|
assert access.image_drift.agent_kind == "astro_orchestrator"
|
|
3671
|
+
assert access.image_drift.requires_user_action is False
|
|
3670
3672
|
assert access.image_drift.checks[0].key == "orchestrator_image"
|
|
3671
3673
|
assert access.image_drift.catalog_state is not None
|
|
3672
3674
|
assert access.image_drift.catalog_state["refresh_required"] is False
|
|
@@ -3711,6 +3713,7 @@ def test_agent_session_runtime_access_accepts_minimal_image_drift(monkeypatch):
|
|
|
3711
3713
|
|
|
3712
3714
|
assert access.image_drift is not None
|
|
3713
3715
|
assert access.image_drift.has_drift is False
|
|
3716
|
+
assert access.image_drift.requires_user_action is False
|
|
3714
3717
|
assert access.image_drift.detail is None
|
|
3715
3718
|
assert access.model_dump()["reconciliation"] == {
|
|
3716
3719
|
"queued": False,
|
|
@@ -3718,6 +3721,20 @@ def test_agent_session_runtime_access_accepts_minimal_image_drift(monkeypatch):
|
|
|
3718
3721
|
}
|
|
3719
3722
|
|
|
3720
3723
|
|
|
3724
|
+
@pytest.mark.parametrize("requires_user_action", [False, True])
|
|
3725
|
+
def test_agent_runtime_image_drift_parses_user_action_signal(requires_user_action):
|
|
3726
|
+
image_drift = agent_models_mod.AgentRuntimeImageDrift.model_validate(
|
|
3727
|
+
{"requires_user_action": requires_user_action}
|
|
3728
|
+
)
|
|
3729
|
+
|
|
3730
|
+
assert image_drift.requires_user_action is requires_user_action
|
|
3731
|
+
|
|
3732
|
+
with pytest.raises(ValidationError, match="requires_user_action"):
|
|
3733
|
+
agent_models_mod.AgentRuntimeImageDrift.model_validate(
|
|
3734
|
+
{"requires_user_action": None}
|
|
3735
|
+
)
|
|
3736
|
+
|
|
3737
|
+
|
|
3721
3738
|
def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
3722
3739
|
captured = {"resolve_count": 0, "runtime": {}}
|
|
3723
3740
|
session_uid = "3f1cc452-43ec-49cb-b2ba-87dbac164d29"
|
|
@@ -3747,6 +3764,13 @@ def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
|
3747
3764
|
"token": "tok-secret",
|
|
3748
3765
|
"expires_at": "2999-01-01T00:00:00Z",
|
|
3749
3766
|
**_ready_runtime_contract(),
|
|
3767
|
+
"image_drift": {
|
|
3768
|
+
"agent_kind": "astro_orchestrator",
|
|
3769
|
+
"available": True,
|
|
3770
|
+
"has_drift": False,
|
|
3771
|
+
"requires_user_action": False,
|
|
3772
|
+
"checks": [],
|
|
3773
|
+
},
|
|
3750
3774
|
}
|
|
3751
3775
|
|
|
3752
3776
|
class FakeRuntimeResponse:
|
|
@@ -3759,7 +3783,7 @@ def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
|
3759
3783
|
return {
|
|
3760
3784
|
"message": {
|
|
3761
3785
|
"messageId": "msg-runtime-output",
|
|
3762
|
-
"role": "
|
|
3786
|
+
"role": "ROLE_RESPONDER",
|
|
3763
3787
|
"contextId": session_uid,
|
|
3764
3788
|
"parts": [{"text": "I can analyze workspaces."}],
|
|
3765
3789
|
}
|
|
@@ -3799,6 +3823,10 @@ def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
|
3799
3823
|
)
|
|
3800
3824
|
|
|
3801
3825
|
assert captured["resolve_count"] == 1
|
|
3826
|
+
cached_access = agent_models_mod.AgentSession.get_cached_runtime_access(session)
|
|
3827
|
+
assert cached_access is not None
|
|
3828
|
+
assert cached_access.image_drift is not None
|
|
3829
|
+
assert cached_access.image_drift.requires_user_action is False
|
|
3802
3830
|
assert captured["resolve"] == {
|
|
3803
3831
|
"r_type": "POST",
|
|
3804
3832
|
"url": f"{agent_models_mod.AgentSession.get_object_url()}/{session_uid}/resolve-runtime-access/",
|
|
@@ -3821,7 +3849,7 @@ def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
|
3821
3849
|
assert request_body == {
|
|
3822
3850
|
"message": {
|
|
3823
3851
|
"messageId": "msg-00000000-0000-4000-8000-000000000001",
|
|
3824
|
-
"role": "
|
|
3852
|
+
"role": "ROLE_REQUESTER",
|
|
3825
3853
|
"contextId": session_uid,
|
|
3826
3854
|
"parts": [{"text": "What can this agent do?"}],
|
|
3827
3855
|
},
|
|
@@ -3833,6 +3861,58 @@ def test_agent_session_send_a2a_message_posts_standard_contract(monkeypatch):
|
|
|
3833
3861
|
assert "omit_reasoning" not in captured["runtime"]["data"]
|
|
3834
3862
|
|
|
3835
3863
|
|
|
3864
|
+
@pytest.mark.parametrize("invalid_role", [None, "ROLE_REQUESTER", "requester"])
|
|
3865
|
+
def test_a2a_message_result_requires_responder_role(invalid_role):
|
|
3866
|
+
with pytest.raises(ValidationError, match="ROLE_RESPONDER"):
|
|
3867
|
+
agent_models_mod.A2AMessageSendResult.model_validate(
|
|
3868
|
+
{
|
|
3869
|
+
"message": {
|
|
3870
|
+
"messageId": "msg-output",
|
|
3871
|
+
"role": invalid_role,
|
|
3872
|
+
"contextId": "session-uid",
|
|
3873
|
+
"parts": [{"text": "Result."}],
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
)
|
|
3877
|
+
|
|
3878
|
+
|
|
3879
|
+
def test_agent_session_send_rejects_mismatched_response_context(monkeypatch):
|
|
3880
|
+
session_uid = "3f1cc452-43ec-49cb-b2ba-87dbac164d29"
|
|
3881
|
+
|
|
3882
|
+
class FakeResponse:
|
|
3883
|
+
status_code = 200
|
|
3884
|
+
|
|
3885
|
+
@staticmethod
|
|
3886
|
+
def json():
|
|
3887
|
+
return {
|
|
3888
|
+
"message": {
|
|
3889
|
+
"messageId": "msg-output",
|
|
3890
|
+
"role": "ROLE_RESPONDER",
|
|
3891
|
+
"contextId": "different-session",
|
|
3892
|
+
"parts": [{"text": "Result."}],
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
monkeypatch.setattr(
|
|
3897
|
+
agent_models_mod.AgentSession,
|
|
3898
|
+
"_resolve_runtime_access_for_message_send",
|
|
3899
|
+
classmethod(lambda cls, agent_session, timeout=None: object()),
|
|
3900
|
+
)
|
|
3901
|
+
monkeypatch.setattr(
|
|
3902
|
+
agent_models_mod.AgentSession,
|
|
3903
|
+
"_post_standard_a2a_message",
|
|
3904
|
+
classmethod(
|
|
3905
|
+
lambda cls, access, *, body, timeout=None: FakeResponse()
|
|
3906
|
+
),
|
|
3907
|
+
)
|
|
3908
|
+
|
|
3909
|
+
with pytest.raises(agent_models_mod.ApiError, match="contextId"):
|
|
3910
|
+
agent_models_mod.AgentSession.send_a2a_message(
|
|
3911
|
+
session_uid,
|
|
3912
|
+
message="Return a result.",
|
|
3913
|
+
)
|
|
3914
|
+
|
|
3915
|
+
|
|
3836
3916
|
def test_agent_session_send_waits_only_while_runtime_interaction_is_transient(
|
|
3837
3917
|
monkeypatch,
|
|
3838
3918
|
):
|
|
@@ -3887,7 +3967,7 @@ def test_agent_session_send_waits_only_while_runtime_interaction_is_transient(
|
|
|
3887
3967
|
return {
|
|
3888
3968
|
"message": {
|
|
3889
3969
|
"messageId": "msg-output",
|
|
3890
|
-
"role": "
|
|
3970
|
+
"role": "ROLE_RESPONDER",
|
|
3891
3971
|
"contextId": session_uid,
|
|
3892
3972
|
"parts": [{"text": "Ready."}],
|
|
3893
3973
|
}
|
|
@@ -4170,7 +4250,7 @@ def test_agent_session_send_a2a_message_posts_strict_dictionary_contract(monkeyp
|
|
|
4170
4250
|
return {
|
|
4171
4251
|
"message": {
|
|
4172
4252
|
"messageId": "msg-runtime-output",
|
|
4173
|
-
"role": "
|
|
4253
|
+
"role": "ROLE_RESPONDER",
|
|
4174
4254
|
"contextId": session_uid,
|
|
4175
4255
|
"parts": [{"text": '{"ok": true}'}],
|
|
4176
4256
|
}
|
|
@@ -4253,7 +4333,7 @@ def test_agent_session_send_a2a_message_refreshes_access_and_reuses_body(monkeyp
|
|
|
4253
4333
|
return {
|
|
4254
4334
|
"message": {
|
|
4255
4335
|
"messageId": "msg-runtime-output",
|
|
4256
|
-
"role": "
|
|
4336
|
+
"role": "ROLE_RESPONDER",
|
|
4257
4337
|
"contextId": session_uid,
|
|
4258
4338
|
"parts": [{"text": "Done."}],
|
|
4259
4339
|
}
|
|
@@ -4329,7 +4409,7 @@ def test_agent_respond_uses_agent_scoped_sessionless_contract(monkeypatch):
|
|
|
4329
4409
|
"message": {
|
|
4330
4410
|
"kind": "message",
|
|
4331
4411
|
"messageId": "msg-output",
|
|
4332
|
-
"role": "
|
|
4412
|
+
"role": "ROLE_RESPONDER",
|
|
4333
4413
|
"parts": [{"data": {"answer": 42}, "mediaType": "application/json"}],
|
|
4334
4414
|
}
|
|
4335
4415
|
}
|
|
@@ -4383,7 +4463,7 @@ def test_agent_respond_uses_agent_scoped_sessionless_contract(monkeypatch):
|
|
|
4383
4463
|
body = runtime["body"]
|
|
4384
4464
|
assert body["message"] == {
|
|
4385
4465
|
"messageId": "msg-input",
|
|
4386
|
-
"role": "
|
|
4466
|
+
"role": "ROLE_REQUESTER",
|
|
4387
4467
|
"parts": [{"text": "Return an answer."}],
|
|
4388
4468
|
}
|
|
4389
4469
|
assert "contextId" not in body["message"]
|
|
@@ -4460,7 +4540,7 @@ def test_agent_respond_waits_for_transient_runtime_interaction(monkeypatch):
|
|
|
4460
4540
|
return {
|
|
4461
4541
|
"message": {
|
|
4462
4542
|
"messageId": "msg-output",
|
|
4463
|
-
"role": "
|
|
4543
|
+
"role": "ROLE_RESPONDER",
|
|
4464
4544
|
"parts": [{"text": "Ready."}],
|
|
4465
4545
|
}
|
|
4466
4546
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/agent_scaffold/skills/maintenance/bug_auditor/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/local_paths.py
RENAMED
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/client/data_sources_interfaces/sqlite.py
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/templates/__init__.py
RENAMED
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/migrations/templates/env.py.mako
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/mainsequence/meta_tables/time_index_table_updates/utils.py
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
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/tests/fixtures/time_index_table_update_hash_v2_golden.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_batch_jobs_from_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_code_repository_documentation_contract.py
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_access_dimension_audit.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_configuration.py
RENAMED
|
File without changes
|
{mainsequence-8.1.4 → mainsequence-8.1.6}/tests/test_time_index_table_update_configuration_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|