macp-sdk-python 0.8.0__tar.gz → 0.9.0__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 (40) hide show
  1. {macp_sdk_python-0.8.0/src/macp_sdk_python.egg-info → macp_sdk_python-0.9.0}/PKG-INFO +1 -1
  2. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/pyproject.toml +1 -1
  3. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/__init__.py +2 -0
  4. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/client.py +12 -3
  5. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/policy.py +17 -2
  6. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/validation.py +36 -0
  7. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0/src/macp_sdk_python.egg-info}/PKG-INFO +1 -1
  8. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/LICENSE +0 -0
  9. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/README.md +0 -0
  10. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/setup.cfg +0 -0
  11. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/_logging.py +0 -0
  12. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/__init__.py +0 -0
  13. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/cancel_callback.py +0 -0
  14. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/dispatcher.py +0 -0
  15. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/participant.py +0 -0
  16. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/runner.py +0 -0
  17. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/strategies.py +0 -0
  18. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/transports.py +0 -0
  19. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/types.py +0 -0
  20. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/auth.py +0 -0
  21. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/base_projection.py +0 -0
  22. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/base_session.py +0 -0
  23. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/commitment_hash.py +0 -0
  24. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/constants.py +0 -0
  25. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/decision.py +0 -0
  26. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/envelope.py +0 -0
  27. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/errors.py +0 -0
  28. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/handoff.py +0 -0
  29. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/projections.py +0 -0
  30. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/proposal.py +0 -0
  31. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/proto_registry.py +0 -0
  32. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/py.typed +0 -0
  33. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/quorum.py +0 -0
  34. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/retry.py +0 -0
  35. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/task.py +0 -0
  36. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/watchers.py +0 -0
  37. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/SOURCES.txt +0 -0
  38. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/dependency_links.txt +0 -0
  39. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/requires.txt +0 -0
  40. {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: macp-sdk-python
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: Python SDK for the MACP Rust runtime
5
5
  Author-email: Multi-Agent Coordination Protocol <macp@multiagentcoordinationprotocol.org>
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "macp-sdk-python"
7
- version = "0.8.0"
7
+ version = "0.9.0"
8
8
  description = "Python SDK for the MACP Rust runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -95,6 +95,7 @@ from .validation import (
95
95
  validate_confidence,
96
96
  validate_participant_count,
97
97
  validate_participants,
98
+ validate_progress_scope,
98
99
  validate_recommendation,
99
100
  validate_required_field,
100
101
  validate_session_id,
@@ -218,6 +219,7 @@ __all__ = [
218
219
  "validate_confidence",
219
220
  "validate_participant_count",
220
221
  "validate_participants",
222
+ "validate_progress_scope",
221
223
  "validate_recommendation",
222
224
  "validate_required_field",
223
225
  "validate_session_id",
@@ -24,6 +24,7 @@ from .errors import (
24
24
  MacpSessionError,
25
25
  MacpTransportError,
26
26
  )
27
+ from .validation import validate_progress_scope
27
28
 
28
29
  # Public typing alias for inline stream-error callbacks. Parity with
29
30
  # typescript-sdk's ``InlineErrorCallback``. Receives the protobuf
@@ -962,10 +963,18 @@ class MacpClient:
962
963
  ) -> envelope_pb2.Ack:
963
964
  """Send a progress update.
964
965
 
965
- When ``session_id`` and ``mode`` are empty, the progress is treated
966
- as an *ambient* progress message routed through the signal broadcast
967
- path.
966
+ Per RFC-MACP-0001 §6, ``Progress`` is legal in exactly two shapes:
967
+
968
+ * *ambient* -- ``session_id`` and ``mode`` both empty, routed through
969
+ the signal broadcast path; or
970
+ * *session-scoped* -- both non-empty.
971
+
972
+ Supplying exactly one of the two raises ``MacpSessionError`` naming
973
+ the mismatched field. The runtime rejects that mixed envelope with
974
+ ``INVALID_ENVELOPE``, so this only surfaces the failure earlier and
975
+ more clearly.
968
976
  """
977
+ validate_progress_scope(session_id, mode)
969
978
  auth_cfg = self._require_auth(auth)
970
979
  payload = build_progress_payload(
971
980
  progress_token=progress_token,
@@ -155,7 +155,8 @@ class QuorumThreshold:
155
155
  ``quorum-rules.schema.json``: an approval count for ``n_of_m`` /
156
156
  ``weighted``, and an integer percentage 0-100 for ``percentage``. A
157
157
  fractional value (e.g. ``0.75``) is rejected by the runtime's schema
158
- validation, so this is typed ``int`` and range-checked at build time.
158
+ validation, so this is typed ``int`` and ``build_quorum_policy`` rejects
159
+ a non-integer or out-of-range value at build time.
159
160
  """
160
161
 
161
162
  type: str = "n_of_m"
@@ -185,7 +186,21 @@ def build_quorum_policy(
185
186
 
186
187
  # Match the canonical schema's constraints before the runtime does, so a
187
188
  # bad descriptor fails immediately client-side instead of round-tripping
188
- # to an INVALID_POLICY_DEFINITION from RegisterPolicy.
189
+ # to an INVALID_POLICY_DEFINITION from RegisterPolicy. Order matters:
190
+ # type first (a float or bool reaching the range checks below would
191
+ # compare fine numerically but produce a confusing message), then >= 0,
192
+ # then the percentage-specific <= 100 cap.
193
+ #
194
+ # bool is checked explicitly because isinstance(True, int) is True in
195
+ # Python -- QuorumThreshold(value=True) must not silently mean 1.
196
+ if isinstance(t.value, bool) or not isinstance(t.value, int):
197
+ raise MacpSessionError(
198
+ "quorum threshold value must be an integer (e.g. 75 for 75%), got "
199
+ f"{t.value!r}. The canonical quorum-rules schema declares "
200
+ "'value' as an integer for every threshold type; a fractional "
201
+ "value like 0.75 would produce a schema-invalid descriptor that "
202
+ "the runtime rejects at RegisterPolicy with worse diagnostics."
203
+ )
189
204
  if t.value < 0:
190
205
  raise MacpSessionError(f"quorum threshold value must be >= 0, got {t.value}")
191
206
  if t.type == "percentage" and t.value > 100:
@@ -122,6 +122,42 @@ def validate_signal_type(signal_type: str, data: bytes | None = None) -> None:
122
122
  raise MacpSessionError("signal_type must be non-empty when data is present")
123
123
 
124
124
 
125
+ def validate_progress_scope(session_id: str, mode: str) -> None:
126
+ """Validate the ``Progress`` scope pairing (RFC-MACP-0001 §6).
127
+
128
+ ``Progress`` is legal in exactly two shapes -- *ambient* (``session_id``
129
+ and ``mode`` both empty) or *session-scoped* (both non-empty). An envelope
130
+ with exactly one of the two empty is a mixed shape that the runtime
131
+ rejects with ``INVALID_ENVELOPE``; raising here names the mismatched field
132
+ instead.
133
+
134
+ Unlike Signals, ``Progress`` is *not* required to be ambient -- this is a
135
+ tri-state rule, so neither field may be inferred from the other.
136
+
137
+ The emptiness test deliberately mirrors the runtime's
138
+ ``validate_envelope_shape`` **exactly**, including its asymmetry:
139
+ ``session_id`` is compared raw while ``mode`` is stripped first. Mirroring
140
+ rather than normalising is the only choice under which the SDK neither
141
+ accepts a shape the runtime rejects nor rejects one it accepts.
142
+ Concretely, a whitespace-only ``mode`` alongside an empty ``session_id``
143
+ is ambient to the runtime, so it stays ambient here.
144
+ """
145
+ session_id_empty = session_id == ""
146
+ mode_empty = mode.strip() == ""
147
+ if session_id_empty == mode_empty:
148
+ return
149
+ detail = (
150
+ f"mode is {mode!r} but session_id is empty"
151
+ if session_id_empty
152
+ else f"session_id is {session_id!r} but mode is empty"
153
+ )
154
+ raise MacpSessionError(
155
+ "Progress must be either ambient (session_id and mode both empty) or "
156
+ f"session-scoped (both non-empty), but {detail} (RFC-MACP-0001 §6). "
157
+ "Pass both fields for a session-scoped Progress, or neither for an ambient one."
158
+ )
159
+
160
+
125
161
  def validate_ttl_ms(ttl_ms: int) -> None:
126
162
  """Validate that *ttl_ms* is in [1, 86_400_000]."""
127
163
  if ttl_ms < 1 or ttl_ms > _MAX_TTL_MS:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: macp-sdk-python
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: Python SDK for the MACP Rust runtime
5
5
  Author-email: Multi-Agent Coordination Protocol <macp@multiagentcoordinationprotocol.org>
6
6
  License: Apache-2.0
File without changes