mainsequence 9.0.10.dev47__tar.gz → 9.0.11__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 (104) hide show
  1. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/PKG-INFO +1 -1
  2. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +8 -5
  3. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/agent_runtime_models.py +8 -0
  4. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/models_helpers.py +20 -0
  5. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/models_user.py +85 -17
  6. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/PKG-INFO +1 -1
  7. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/pyproject.toml +1 -1
  8. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/LICENSE +0 -0
  9. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/README.md +0 -0
  10. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/AGENTS.md +0 -0
  11. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  12. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/mainsequence-inference/SKILL.md +0 -0
  13. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  14. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
  15. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/maintenance/metatables_transition/SKILL.md +0 -0
  16. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  17. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  18. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
  19. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/__init__.py +0 -0
  20. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/__main__.py +0 -0
  21. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/_request_identity.py +0 -0
  22. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/bootstrap.py +0 -0
  23. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/__init__.py +0 -0
  24. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/api.py +0 -0
  25. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/browser_auth.py +0 -0
  26. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/cli.py +0 -0
  27. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/code_repository_status.py +0 -0
  28. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/config.py +0 -0
  29. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/docker_utils.py +0 -0
  30. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/doctor.py +0 -0
  31. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/local_ops.py +0 -0
  32. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/model_filters.py +0 -0
  33. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/pydantic_cli.py +0 -0
  34. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/sdk_utils.py +0 -0
  35. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/ssh_utils.py +0 -0
  36. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/cli/ui.py +0 -0
  37. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/__init__.py +0 -0
  38. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/_transport.py +0 -0
  39. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/base.py +0 -0
  40. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/client.py +0 -0
  41. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/compute_validation.py +0 -0
  42. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/exceptions.py +0 -0
  43. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/github_issues.py +0 -0
  44. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/inference.py +0 -0
  45. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/models_foundry.py +0 -0
  46. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/observability.py +0 -0
  47. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/utils.py +0 -0
  48. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/client/value_sets.py +0 -0
  49. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/code_repository_context.py +0 -0
  50. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/code_repository_skills.py +0 -0
  51. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/defaults.py +0 -0
  52. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/instrumentation/__init__.py +0 -0
  53. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/instrumentation/utils.py +0 -0
  54. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/logconf.py +0 -0
  55. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/repository_identity_security.py +0 -0
  56. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/runtime_credential_exchange.py +0 -0
  57. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/runtime_flags.py +0 -0
  58. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/scaffold_skills.py +0 -0
  59. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/server/__init__.py +0 -0
  60. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/server/caller_assertions.py +0 -0
  61. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence/server/fastapi.py +0 -0
  62. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/SOURCES.txt +0 -0
  63. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/dependency_links.txt +0 -0
  64. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/entry_points.txt +0 -0
  65. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/requires.txt +0 -0
  66. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/mainsequence.egg-info/top_level.txt +0 -0
  67. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/setup.cfg +0 -0
  68. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_auth_bootstrap.py +0 -0
  69. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_auth_precedence.py +0 -0
  70. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_caller_assertions.py +0 -0
  71. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_canonical_api_route_contract.py +0 -0
  72. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_cli_auth_contract.py +0 -0
  73. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_cli_browser_auth.py +0 -0
  74. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_cli_secure_storage.py +0 -0
  75. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_client.py +0 -0
  76. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_code_repository_branch_contract.py +0 -0
  77. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_code_repository_documentation_contract.py +0 -0
  78. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_code_repository_runtime_context.py +0 -0
  79. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_code_repository_skills.py +0 -0
  80. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_credential_repr.py +0 -0
  81. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_dependency_extras.py +0 -0
  82. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_dev_release_version.py +0 -0
  83. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_environment_resource_context.py +0 -0
  84. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_environment_response_contracts.py +0 -0
  85. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_fastapi_request_identity.py +0 -0
  86. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_github_issues_client.py +0 -0
  87. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_http_retry_budget.py +0 -0
  88. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_independent_context.py +0 -0
  89. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_inference_client.py +0 -0
  90. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_instrumentation.py +0 -0
  91. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_job_client.py +0 -0
  92. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_local_ops.py +0 -0
  93. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_logconf.py +0 -0
  94. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_models_user_request_bound_auth.py +0 -0
  95. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_notification_uid_contract.py +0 -0
  96. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_observability_client.py +0 -0
  97. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_runtime_credential_exchange.py +0 -0
  98. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_scaffold_skills.py +0 -0
  99. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_secret_client_model.py +0 -0
  100. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_source_ownership.py +0 -0
  101. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_ssh_utils.py +0 -0
  102. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_tolerant_response_reading.py +0 -0
  103. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_tolerant_value_sets.py +0 -0
  104. {mainsequence-9.0.10.dev47 → mainsequence-9.0.11}/tests/test_user_application_facts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 9.0.10.dev47
3
+ Version: 9.0.11
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -138,11 +138,14 @@ remain projections of the same identity, not a separate resolver. Outside an
138
138
  authenticated request, including public routes, `User.get_logged_user()` raises
139
139
  `RequestIdentityError`.
140
140
 
141
- On a protected route, this identity is the human making the current HTTP
142
- request. It is not the release creator, deployment owner, runtime workload
143
- principal, or the process account returned by `User.get_authenticated_user_details()`.
144
- Caller authentication is not resource authorization; apply the endpoint's
145
- application policy using the verified user UID.
141
+ On a protected route, this identity is the caller of the current HTTP request:
142
+ a person, or the workload identity a deployed Job, FastAPI release or Agent runs
143
+ as. It is not the release creator, deployment owner, the application's own
144
+ runtime workload principal, or the process account returned by
145
+ `User.get_authenticated_user_details()`. To tell a workload caller from a
146
+ person, read `User.get_by_uid(uid)`: a workload identity has `identity_type`
147
+ `"workload"`. Caller authentication is not resource authorization; apply the
148
+ endpoint's application policy using the verified user UID.
146
149
 
147
150
  WebSockets retain the platform's gateway ticket/header contract rather than
148
151
  the HTTP Bearer/assertion flow; the getter is available while the authenticated
@@ -579,6 +579,14 @@ class Agent(
579
579
  "or null when the Agent has no deployed runtime release."
580
580
  ),
581
581
  )
582
+ workload_user_uid: str | None = Field(
583
+ None,
584
+ description=(
585
+ "Read-only UID of the workload identity, the User this Agent runs as; the "
586
+ "same value its runtime release reports. Pass it to `User.get_by_uid` and "
587
+ "to sharing calls. None when the Agent has no runtime release."
588
+ ),
589
+ )
582
590
  code_repository_branch_uid: str | None = Field(
583
591
  None,
584
592
  description=(
@@ -174,6 +174,16 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
174
174
  examples=["58218213-5e4e-43de-a5bd-6757f4e1c8f6"],
175
175
  )
176
176
 
177
+ workload_user_uid: str | None = Field(
178
+ default=None,
179
+ description=(
180
+ "Read-only UID of the workload identity, the User this Job runs as. "
181
+ "Pass it to `User.get_by_uid` and to sharing calls. None when the Job "
182
+ "has no workload identity, for example a release's backing Job."
183
+ ),
184
+ examples=["88888888-8888-4888-8888-888888888888"],
185
+ )
186
+
177
187
  code_repository_commit_hash: str | None = Field(
178
188
  default=None,
179
189
  description=(
@@ -985,6 +995,16 @@ class ResourceRelease(
985
995
  description="Public UID of the job associated with this resource release.",
986
996
  examples=["7d0ab07c-d1c0-4b7f-9c69-3c1a41c0a4da"],
987
997
  )
998
+ workload_user_uid: str | None = Field(
999
+ None,
1000
+ title="Workload User UID",
1001
+ description=(
1002
+ "Read-only UID of the workload identity, the User this release runs as. "
1003
+ "Pass it to `User.get_by_uid` and to sharing calls. None when the release "
1004
+ "has no workload identity, for example a static-site release."
1005
+ ),
1006
+ examples=["88888888-8888-4888-8888-888888888888"],
1007
+ )
988
1008
  observability: ObservabilityLinks | None = Field(
989
1009
  default=None,
990
1010
  description="Backend-owned runtime observability and related-history capabilities.",
@@ -23,14 +23,21 @@ from .value_sets import OpenValueSet
23
23
 
24
24
 
25
25
  class RequestUserIdentity(BaseModel):
26
- """Minimal identity of the human making the current runtime request."""
26
+ """Minimal identity of the caller of the current runtime request.
27
+
28
+ The caller is a person or a workload identity; ``User.get_by_uid(uid)``
29
+ reads its User.
30
+ """
27
31
 
28
32
  model_config = ConfigDict(extra="forbid", frozen=True)
29
33
 
30
34
  uid: str = Field(
31
35
  ...,
32
36
  title="User UID",
33
- description="Canonical public UUID of the human making the current request.",
37
+ description=(
38
+ "Canonical public UUID of the User making the current request, a person or a "
39
+ "workload identity."
40
+ ),
34
41
  )
35
42
  username: str | None = Field(
36
43
  None,
@@ -954,6 +961,21 @@ class ShareableAccessState(BasePydanticModel):
954
961
 
955
962
 
956
963
  class User(UserApiBaseObjectOrm, BasePydanticModel):
964
+ """A platform User: a person, or the workload identity a deployed Job,
965
+ FastAPI release or Agent runs as.
966
+
967
+ A workload identity is read with ``User.get_by_uid(uid)`` or listed with
968
+ ``User.filter(identity_type="workload")``. Its row carries ``uid``,
969
+ ``identity_type`` (``"workload"``), ``is_active`` and the UID of its
970
+ workload in ``job_uid``, ``resource_release_uid`` or ``agent_uid``, without
971
+ a username, email, join date or name. Fields the row does not carry are
972
+ ``None``, or empty for lists.
973
+
974
+ The reverse direction is ``workload_user_uid`` on ``Job``,
975
+ ``ResourceRelease`` and ``Agent``: the UID of the User that workload runs
976
+ as, to pass to ``User.get_by_uid`` and to sharing calls.
977
+ """
978
+
957
979
  # Platform facts, not application authorization policy. None means the
958
980
  # connected platform has not supplied the versioned additive contract.
959
981
  is_organization_admin: StrictBool | None = None
@@ -963,6 +985,7 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
963
985
  FILTERSET_FIELDS: ClassVar[dict[str, list[str]] | None] = {
964
986
  "uid": ["exact", "in"],
965
987
  "email": ["exact", "contains", "in"],
988
+ "identity_type": ["exact"],
966
989
  }
967
990
  FILTER_VALUE_NORMALIZERS: ClassVar[dict[str, str]] = {
968
991
  "uid": "uid",
@@ -970,6 +993,7 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
970
993
  "email": "str",
971
994
  "email__contains": "str",
972
995
  "email__in": "str",
996
+ "identity_type": "str",
973
997
  }
974
998
 
975
999
  id: int | None = Field(
@@ -985,6 +1009,35 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
985
1009
  description="Stable public unique identifier of the user.",
986
1010
  examples=["8f5d6b54-2f5e-4a8b-bb10-0b17f3f4c123"],
987
1011
  )
1012
+ identity_type: (
1013
+ OpenValueSet[Literal["human", "service_account", "deleted_user", "workload"]] | None
1014
+ ) = Field(
1015
+ None,
1016
+ title="Identity Type",
1017
+ description=(
1018
+ "Kind of identity: `workload` for the identity a deployed Job, FastAPI release "
1019
+ "or Agent runs as. None when the response does not carry it."
1020
+ ),
1021
+ examples=["workload"],
1022
+ )
1023
+ job_uid: str | None = Field(
1024
+ None,
1025
+ title="Job UID",
1026
+ description="UID of the Job a workload identity belongs to; None otherwise.",
1027
+ examples=["88888888-8888-4888-8888-888888888888"],
1028
+ )
1029
+ resource_release_uid: str | None = Field(
1030
+ None,
1031
+ title="Resource Release UID",
1032
+ description="UID of the release a workload identity belongs to; None otherwise.",
1033
+ examples=[None],
1034
+ )
1035
+ agent_uid: str | None = Field(
1036
+ None,
1037
+ title="Agent UID",
1038
+ description="UID of the Agent a workload identity belongs to; None otherwise.",
1039
+ examples=[None],
1040
+ )
988
1041
  profile_picture: str | None = Field(
989
1042
  None,
990
1043
  title="Profile Picture URL",
@@ -1022,10 +1075,13 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
1022
1075
  examples=["enterprise"],
1023
1076
  )
1024
1077
 
1025
- date_joined: datetime.datetime = Field(
1026
- ...,
1078
+ date_joined: datetime.datetime | None = Field(
1079
+ None,
1027
1080
  title="Date Joined",
1028
- description="Timestamp when the user account was created.",
1081
+ description=(
1082
+ "Timestamp when the user account was created. None when the response does not "
1083
+ "carry it, as for a workload identity."
1084
+ ),
1029
1085
  examples=["2025-01-10T08:15:00Z"],
1030
1086
  )
1031
1087
  is_active: bool = Field(
@@ -1034,16 +1090,22 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
1034
1090
  description="Whether the user account is active.",
1035
1091
  examples=[True],
1036
1092
  )
1037
- username: str = Field(
1038
- ...,
1093
+ username: str | None = Field(
1094
+ None,
1039
1095
  title="Username",
1040
- description="Unique username used by the platform.",
1096
+ description=(
1097
+ "Unique username used by the platform. None when the response does not carry it, "
1098
+ "as for a workload identity."
1099
+ ),
1041
1100
  examples=["jose@main-sequence.io"],
1042
1101
  )
1043
- email: str = Field(
1044
- ...,
1102
+ email: str | None = Field(
1103
+ None,
1045
1104
  title="Email",
1046
- description="Primary email address of the user.",
1105
+ description=(
1106
+ "Primary email address of the user. None when the response does not carry it, "
1107
+ "as for a workload identity."
1108
+ ),
1047
1109
  examples=["jose@main-sequence.io"],
1048
1110
  )
1049
1111
  first_name: str | None = Field(
@@ -1064,16 +1126,22 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
1064
1126
  description="Timestamp of the last successful login.",
1065
1127
  examples=["2026-03-15T11:20:00Z"],
1066
1128
  )
1067
- api_request_limit: int = Field(
1068
- ...,
1129
+ api_request_limit: int | None = Field(
1130
+ None,
1069
1131
  title="API Request Limit",
1070
- description="Maximum number of API requests available to the user in the current limit window.",
1132
+ description=(
1133
+ "Maximum number of API requests available to the user in the current limit "
1134
+ "window. None when the response does not carry it, as for a workload identity."
1135
+ ),
1071
1136
  examples=[10000],
1072
1137
  )
1073
- mfa_enabled: bool = Field(
1074
- ...,
1138
+ mfa_enabled: bool | None = Field(
1139
+ None,
1075
1140
  title="MFA Enabled",
1076
- description="Whether multi-factor authentication is enabled for the user.",
1141
+ description=(
1142
+ "Whether multi-factor authentication is enabled for the user. None when the "
1143
+ "response does not carry it, as for a workload identity."
1144
+ ),
1077
1145
  examples=[True],
1078
1146
  )
1079
1147
  organization: Organization | None = Field(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 9.0.10.dev47
3
+ Version: 9.0.11
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "9.0.10.dev47"
7
+ version = "9.0.11"
8
8
  description = "Main Sequence SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"