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.
- {macp_sdk_python-0.8.0/src/macp_sdk_python.egg-info → macp_sdk_python-0.9.0}/PKG-INFO +1 -1
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/pyproject.toml +1 -1
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/__init__.py +2 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/client.py +12 -3
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/policy.py +17 -2
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/validation.py +36 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0/src/macp_sdk_python.egg-info}/PKG-INFO +1 -1
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/LICENSE +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/README.md +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/setup.cfg +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/_logging.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/__init__.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/cancel_callback.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/dispatcher.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/participant.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/runner.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/strategies.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/transports.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/agent/types.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/auth.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/base_projection.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/base_session.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/commitment_hash.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/constants.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/decision.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/envelope.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/errors.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/handoff.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/projections.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/proposal.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/proto_registry.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/py.typed +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/quorum.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/retry.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/task.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk/watchers.py +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/SOURCES.txt +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/dependency_links.txt +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/requires.txt +0 -0
- {macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/top_level.txt +0 -0
|
@@ -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
|
-
|
|
966
|
-
|
|
967
|
-
|
|
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
|
|
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:
|
|
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
|
|
File without changes
|
|
File without changes
|
{macp_sdk_python-0.8.0 → macp_sdk_python-0.9.0}/src/macp_sdk_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|