macp-sdk-python 0.3.0__tar.gz → 0.4.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.3.0/src/macp_sdk_python.egg-info → macp_sdk_python-0.4.0}/PKG-INFO +5 -4
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/README.md +2 -1
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/pyproject.toml +11 -7
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/__init__.py +2 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/base_session.py +17 -1
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/client.py +73 -5
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/envelope.py +23 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/watchers.py +33 -10
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0/src/macp_sdk_python.egg-info}/PKG-INFO +5 -4
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk_python.egg-info/requires.txt +2 -2
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/LICENSE +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/setup.cfg +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/_logging.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/__init__.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/cancel_callback.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/dispatcher.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/participant.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/runner.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/strategies.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/transports.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/agent/types.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/auth.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/base_projection.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/constants.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/decision.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/errors.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/handoff.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/policy.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/projections.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/proposal.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/proto_registry.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/py.typed +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/quorum.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/retry.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/task.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk/validation.py +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk_python.egg-info/SOURCES.txt +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk_python.egg-info/dependency_links.txt +0 -0
- {macp_sdk_python-0.3.0 → macp_sdk_python-0.4.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.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for the MACP Rust runtime
|
|
5
5
|
Author-email: OpenAI <support@openai.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,9 +15,9 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
15
15
|
Requires-Python: >=3.11
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: grpcio>=1.
|
|
18
|
+
Requires-Dist: grpcio>=1.81.1
|
|
19
19
|
Requires-Dist: protobuf>=5.27.0
|
|
20
|
-
Requires-Dist: macp-proto<0.2.0,>=0.1.
|
|
20
|
+
Requires-Dist: macp-proto<0.2.0,>=0.1.3
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: grpcio-tools>=1.74.0; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
@@ -165,6 +165,7 @@ Business logic — voting rules, AI decision heuristics, policy enforcement —
|
|
|
165
165
|
|
|
166
166
|
- `GetSession` returns metadata only (not mode state/transcript) — hence the local projection pattern; use `StreamSession` + `send_subscribe` for the full transcript
|
|
167
167
|
- `StreamSession` is scoped to one session per stream; use `MacpStream.send_subscribe(session_id)` (RFC-MACP-0006-A1, since SDK 0.2.3 / `macp-proto 0.1.2`) to replay accepted history before live broadcast
|
|
168
|
-
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` lifecycle events
|
|
168
|
+
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` / `CANCELLED` / `SUSPENDED` / `RESUMED` lifecycle events
|
|
169
|
+
- Pause and cancel sessions with `MacpClient.suspend_session()` / `resume_session()` / `cancel_session()` (SDK 0.4.0 / `macp-proto 0.1.3`). A suspended session is non-terminal and rejects messages until resumed; an accepted `cancel_session()` now terminates as `CANCELLED` (previously surfaced as `EXPIRED`)
|
|
169
170
|
- `ListRoots` currently returns an empty list and `WatchRoots` idles — the runtime does not yet populate roots
|
|
170
171
|
- Business policy (majority, quorum, veto) belongs in your orchestrator/policy layer
|
|
@@ -131,6 +131,7 @@ Business logic — voting rules, AI decision heuristics, policy enforcement —
|
|
|
131
131
|
|
|
132
132
|
- `GetSession` returns metadata only (not mode state/transcript) — hence the local projection pattern; use `StreamSession` + `send_subscribe` for the full transcript
|
|
133
133
|
- `StreamSession` is scoped to one session per stream; use `MacpStream.send_subscribe(session_id)` (RFC-MACP-0006-A1, since SDK 0.2.3 / `macp-proto 0.1.2`) to replay accepted history before live broadcast
|
|
134
|
-
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` lifecycle events
|
|
134
|
+
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` / `CANCELLED` / `SUSPENDED` / `RESUMED` lifecycle events
|
|
135
|
+
- Pause and cancel sessions with `MacpClient.suspend_session()` / `resume_session()` / `cancel_session()` (SDK 0.4.0 / `macp-proto 0.1.3`). A suspended session is non-terminal and rejects messages until resumed; an accepted `cancel_session()` now terminates as `CANCELLED` (previously surfaced as `EXPIRED`)
|
|
135
136
|
- `ListRoots` currently returns an empty list and `WatchRoots` idles — the runtime does not yet populate roots
|
|
136
137
|
- Business policy (majority, quorum, veto) belongs in your orchestrator/policy layer
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "macp-sdk-python"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Python SDK for the MACP Rust runtime"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -23,14 +23,18 @@ classifiers = [
|
|
|
23
23
|
"Topic :: Software Development :: Libraries",
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
|
-
|
|
26
|
+
# macp-proto 0.1.3's generated gRPC stubs require grpcio>=1.81.1.
|
|
27
|
+
"grpcio>=1.81.1",
|
|
27
28
|
"protobuf>=5.27.0",
|
|
28
|
-
# Requires 0.1.
|
|
29
|
+
# Requires 0.1.3+ for the suspend/cancel/supersede surface: SuspendSession
|
|
30
|
+
# /ResumeSession RPCs, SESSION_STATE_SUSPENDED/CANCELLED, the SUSPENDED/
|
|
31
|
+
# RESUMED/CANCELLED lifecycle events, and CommitmentPayload.supersedes
|
|
32
|
+
# (CommitmentRef). 0.1.2 added the RFC-MACP-0006-A1 subscribe_session_id /
|
|
29
33
|
# after_sequence fields on StreamSessionRequest (used by MacpStream
|
|
30
|
-
# .send_subscribe and the gRPC agent transport adapter)
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
"macp-proto>=0.1.
|
|
34
|
+
# .send_subscribe and the gRPC agent transport adapter); 0.1.1 is the
|
|
35
|
+
# earlier baseline for context_id / extensions on SessionStartPayload.
|
|
36
|
+
# See docs/contributing.md "Bumping macp-proto".
|
|
37
|
+
"macp-proto>=0.1.3,<0.2.0",
|
|
34
38
|
]
|
|
35
39
|
|
|
36
40
|
[project.optional-dependencies]
|
|
@@ -19,6 +19,7 @@ from .constants import (
|
|
|
19
19
|
from .decision import DecisionSession
|
|
20
20
|
from .envelope import (
|
|
21
21
|
build_commitment_payload,
|
|
22
|
+
build_commitment_ref,
|
|
22
23
|
build_envelope,
|
|
23
24
|
build_progress_payload,
|
|
24
25
|
build_root,
|
|
@@ -181,6 +182,7 @@ __all__ = [
|
|
|
181
182
|
"TaskSession",
|
|
182
183
|
"VotingRules",
|
|
183
184
|
"build_commitment_payload",
|
|
185
|
+
"build_commitment_ref",
|
|
184
186
|
"build_decision_policy",
|
|
185
187
|
"build_envelope",
|
|
186
188
|
"build_handoff_policy",
|
|
@@ -163,9 +163,25 @@ class BaseSession(ABC):
|
|
|
163
163
|
return self.client.get_session(self.session_id, auth=auth or self.auth)
|
|
164
164
|
|
|
165
165
|
def cancel(self, *, reason: str = "", auth: AuthConfig | None = None) -> envelope_pb2.Ack:
|
|
166
|
-
"""Cancel the session."""
|
|
166
|
+
"""Cancel the session (terminates as ``CANCELLED`` since proto 0.1.3)."""
|
|
167
167
|
return self.client.cancel_session(self.session_id, reason=reason, auth=auth or self.auth)
|
|
168
168
|
|
|
169
|
+
def suspend(self, *, reason: str = "", auth: AuthConfig | None = None) -> envelope_pb2.Ack:
|
|
170
|
+
"""Suspend this session (proto 0.1.3+).
|
|
171
|
+
|
|
172
|
+
Moves it to the non-terminal ``SUSPENDED`` state; the runtime rejects
|
|
173
|
+
messages until :meth:`resume`. Delegates to
|
|
174
|
+
:meth:`MacpClient.suspend_session`.
|
|
175
|
+
"""
|
|
176
|
+
return self.client.suspend_session(self.session_id, reason=reason, auth=auth or self.auth)
|
|
177
|
+
|
|
178
|
+
def resume(self, *, reason: str = "", auth: AuthConfig | None = None) -> envelope_pb2.Ack:
|
|
179
|
+
"""Resume this suspended session (proto 0.1.3+), restoring ``OPEN``.
|
|
180
|
+
|
|
181
|
+
Delegates to :meth:`MacpClient.resume_session`.
|
|
182
|
+
"""
|
|
183
|
+
return self.client.resume_session(self.session_id, reason=reason, auth=auth or self.auth)
|
|
184
|
+
|
|
169
185
|
def open_stream(self, *, auth: AuthConfig | None = None) -> MacpStream:
|
|
170
186
|
"""Open a bidirectional stream for this session."""
|
|
171
187
|
return self.client.open_stream(auth=auth or self.auth)
|
|
@@ -213,7 +213,7 @@ class MacpClient:
|
|
|
213
213
|
root_certificates: bytes | None = None,
|
|
214
214
|
default_timeout: float | None = None,
|
|
215
215
|
client_name: str = "macp-sdk-python",
|
|
216
|
-
client_version: str = "0.
|
|
216
|
+
client_version: str = "0.4.0",
|
|
217
217
|
) -> None:
|
|
218
218
|
if secure is None:
|
|
219
219
|
secure = not allow_insecure
|
|
@@ -370,6 +370,13 @@ class MacpClient:
|
|
|
370
370
|
timeout: float | None = None,
|
|
371
371
|
raise_on_nack: bool = True,
|
|
372
372
|
) -> envelope_pb2.Ack:
|
|
373
|
+
"""Terminate a session.
|
|
374
|
+
|
|
375
|
+
Since runtime 0.4.0 / macp-proto 0.1.3 an accepted cancellation
|
|
376
|
+
moves the session to ``SESSION_STATE_CANCELLED`` (previously
|
|
377
|
+
``EXPIRED``) and surfaces an ``EVENT_TYPE_CANCELLED`` lifecycle
|
|
378
|
+
event. The returned ``Ack.session_state`` reflects ``CANCELLED``.
|
|
379
|
+
"""
|
|
373
380
|
auth_cfg = self._require_auth(auth)
|
|
374
381
|
request_kwargs: dict[str, object] = {
|
|
375
382
|
"session_id": session_id,
|
|
@@ -395,6 +402,66 @@ class MacpClient:
|
|
|
395
402
|
raise MacpAckError(self._failure_from_ack(ack))
|
|
396
403
|
return ack
|
|
397
404
|
|
|
405
|
+
def suspend_session(
|
|
406
|
+
self,
|
|
407
|
+
session_id: str,
|
|
408
|
+
*,
|
|
409
|
+
reason: str = "",
|
|
410
|
+
auth: AuthConfig | None = None,
|
|
411
|
+
timeout: float | None = None,
|
|
412
|
+
raise_on_nack: bool = True,
|
|
413
|
+
) -> envelope_pb2.Ack:
|
|
414
|
+
"""Suspend an open session (macp-proto 0.1.3 / runtime 0.4.0).
|
|
415
|
+
|
|
416
|
+
Moves the session to the non-terminal ``SESSION_STATE_SUSPENDED``
|
|
417
|
+
state and emits an ``EVENT_TYPE_SUSPENDED`` lifecycle event. While
|
|
418
|
+
suspended the runtime rejects messages sent to the session with a
|
|
419
|
+
non-OPEN error; call :meth:`resume_session` to return it to OPEN.
|
|
420
|
+
The returned ``Ack.session_state`` reflects ``SUSPENDED``.
|
|
421
|
+
"""
|
|
422
|
+
auth_cfg = self._require_auth(auth)
|
|
423
|
+
try:
|
|
424
|
+
response = self.stub.SuspendSession(
|
|
425
|
+
core_pb2.SuspendSessionRequest(session_id=session_id, reason=reason),
|
|
426
|
+
metadata=self._metadata(auth_cfg),
|
|
427
|
+
timeout=timeout or self.default_timeout,
|
|
428
|
+
)
|
|
429
|
+
except grpc.RpcError as rpc_err:
|
|
430
|
+
raise MacpTransportError(rpc_err.details() or str(rpc_err)) from rpc_err
|
|
431
|
+
ack = response.ack
|
|
432
|
+
if raise_on_nack and not ack.ok:
|
|
433
|
+
raise MacpAckError(self._failure_from_ack(ack))
|
|
434
|
+
return ack
|
|
435
|
+
|
|
436
|
+
def resume_session(
|
|
437
|
+
self,
|
|
438
|
+
session_id: str,
|
|
439
|
+
*,
|
|
440
|
+
reason: str = "",
|
|
441
|
+
auth: AuthConfig | None = None,
|
|
442
|
+
timeout: float | None = None,
|
|
443
|
+
raise_on_nack: bool = True,
|
|
444
|
+
) -> envelope_pb2.Ack:
|
|
445
|
+
"""Resume a suspended session (macp-proto 0.1.3 / runtime 0.4.0).
|
|
446
|
+
|
|
447
|
+
Returns a ``SESSION_STATE_SUSPENDED`` session to
|
|
448
|
+
``SESSION_STATE_OPEN`` and emits an ``EVENT_TYPE_RESUMED`` lifecycle
|
|
449
|
+
event. The returned ``Ack.session_state`` reflects ``OPEN``.
|
|
450
|
+
"""
|
|
451
|
+
auth_cfg = self._require_auth(auth)
|
|
452
|
+
try:
|
|
453
|
+
response = self.stub.ResumeSession(
|
|
454
|
+
core_pb2.ResumeSessionRequest(session_id=session_id, reason=reason),
|
|
455
|
+
metadata=self._metadata(auth_cfg),
|
|
456
|
+
timeout=timeout or self.default_timeout,
|
|
457
|
+
)
|
|
458
|
+
except grpc.RpcError as rpc_err:
|
|
459
|
+
raise MacpTransportError(rpc_err.details() or str(rpc_err)) from rpc_err
|
|
460
|
+
ack = response.ack
|
|
461
|
+
if raise_on_nack and not ack.ok:
|
|
462
|
+
raise MacpAckError(self._failure_from_ack(ack))
|
|
463
|
+
return ack
|
|
464
|
+
|
|
398
465
|
def get_manifest(
|
|
399
466
|
self, agent_id: str = "", *, timeout: float | None = None
|
|
400
467
|
) -> core_pb2.GetManifestResponse:
|
|
@@ -452,10 +519,11 @@ class MacpClient:
|
|
|
452
519
|
|
|
453
520
|
The runtime emits an initial ``EVENT_TYPE_CREATED`` frame for every
|
|
454
521
|
currently-open session, then live events as sessions transition
|
|
455
|
-
through ``CREATED``, ``RESOLVED``,
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
522
|
+
through ``CREATED``, ``RESOLVED``, ``EXPIRED``, ``CANCELLED``, and
|
|
523
|
+
the non-terminal ``SUSPENDED`` / ``RESUMED`` pair (the latter three
|
|
524
|
+
since macp-proto 0.1.3). Each event carries a full
|
|
525
|
+
``SessionMetadata`` (including ``context_id`` and ``extension_keys``),
|
|
526
|
+
so callers can project run state without a follow-up ``get_session``.
|
|
459
527
|
"""
|
|
460
528
|
logger.debug("watch_sessions starting")
|
|
461
529
|
auth_cfg = self._require_auth(auth)
|
|
@@ -80,6 +80,17 @@ def _has_outcome_positive_field() -> bool:
|
|
|
80
80
|
return any(f.name == "outcome_positive" for f in core_pb2.CommitmentPayload.DESCRIPTOR.fields)
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
def _has_supersedes_field() -> bool:
|
|
84
|
+
"""Check if the proto schema supports CommitmentPayload.supersedes (>=0.1.3)."""
|
|
85
|
+
return any(f.name == "supersedes" for f in core_pb2.CommitmentPayload.DESCRIPTOR.fields)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def build_commitment_ref(*, session_id: str, commitment_hash: str) -> core_pb2.CommitmentRef:
|
|
89
|
+
"""Build a ``CommitmentRef`` (macp-proto 0.1.3) pointing at a prior
|
|
90
|
+
commitment, for use as ``build_commitment_payload(supersedes=...)``."""
|
|
91
|
+
return core_pb2.CommitmentRef(session_id=session_id, commitment_hash=commitment_hash)
|
|
92
|
+
|
|
93
|
+
|
|
83
94
|
def build_commitment_payload(
|
|
84
95
|
*,
|
|
85
96
|
action: str,
|
|
@@ -90,7 +101,15 @@ def build_commitment_payload(
|
|
|
90
101
|
configuration_version: str = DEFAULT_CONFIGURATION_VERSION,
|
|
91
102
|
policy_version: str = DEFAULT_POLICY_VERSION,
|
|
92
103
|
outcome_positive: bool | None = None,
|
|
104
|
+
supersedes: core_pb2.CommitmentRef | None = None,
|
|
93
105
|
) -> core_pb2.CommitmentPayload:
|
|
106
|
+
"""Build a ``CommitmentPayload``.
|
|
107
|
+
|
|
108
|
+
``supersedes`` (macp-proto 0.1.3) optionally references a prior
|
|
109
|
+
commitment this one revises, as a ``CommitmentRef`` of
|
|
110
|
+
``(session_id, commitment_hash)``. It is absent by default and unrelated
|
|
111
|
+
to proposal-mode ``supersedes_proposal_id``.
|
|
112
|
+
"""
|
|
94
113
|
if outcome_positive is None:
|
|
95
114
|
outcome_positive = infer_outcome_positive(action)
|
|
96
115
|
kwargs: dict[str, object] = dict(
|
|
@@ -104,6 +123,10 @@ def build_commitment_payload(
|
|
|
104
123
|
)
|
|
105
124
|
if _has_outcome_positive_field():
|
|
106
125
|
kwargs["outcome_positive"] = outcome_positive
|
|
126
|
+
if supersedes is not None:
|
|
127
|
+
if not _has_supersedes_field():
|
|
128
|
+
raise MacpSessionError("CommitmentPayload.supersedes requires macp-proto >= 0.1.3")
|
|
129
|
+
kwargs["supersedes"] = supersedes
|
|
107
130
|
return core_pb2.CommitmentPayload(**kwargs)
|
|
108
131
|
|
|
109
132
|
|
|
@@ -29,10 +29,13 @@ class PolicyChange:
|
|
|
29
29
|
class SessionLifecycle:
|
|
30
30
|
"""A single session lifecycle event from ``WatchSessions``.
|
|
31
31
|
|
|
32
|
-
Runtime event types (per ``SessionLifecycleEvent.EventType
|
|
33
|
-
on SessionStart acceptance (also emitted
|
|
34
|
-
subscribe time), ``RESOLVED`` on
|
|
35
|
-
``EXPIRED`` on TTL expiry
|
|
32
|
+
Runtime event types (per ``SessionLifecycleEvent.EventType``, since
|
|
33
|
+
macp-proto 0.1.3): ``CREATED`` on SessionStart acceptance (also emitted
|
|
34
|
+
for pre-existing sessions at subscribe time), ``RESOLVED`` on
|
|
35
|
+
mode-determined terminal outcome, ``EXPIRED`` on TTL/policy expiry,
|
|
36
|
+
``CANCELLED`` on an accepted ``CancelSession`` (previously surfaced as
|
|
37
|
+
``EXPIRED``), and the non-terminal pair ``SUSPENDED`` / ``RESUMED`` from
|
|
38
|
+
``SuspendSession`` / ``ResumeSession``.
|
|
36
39
|
"""
|
|
37
40
|
|
|
38
41
|
event_type: str = "UNSPECIFIED"
|
|
@@ -49,12 +52,31 @@ class SessionLifecycle:
|
|
|
49
52
|
|
|
50
53
|
@property
|
|
51
54
|
def is_expired(self) -> bool:
|
|
55
|
+
"""``True`` only for TTL/policy expiry; explicit cancellation now
|
|
56
|
+
surfaces as ``CANCELLED`` — see ``is_cancelled``."""
|
|
52
57
|
return self.event_type == "EXPIRED"
|
|
53
58
|
|
|
59
|
+
@property
|
|
60
|
+
def is_cancelled(self) -> bool:
|
|
61
|
+
"""``True`` for an accepted ``CancelSession`` (terminal)."""
|
|
62
|
+
return self.event_type == "CANCELLED"
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def is_suspended(self) -> bool:
|
|
66
|
+
"""``True`` after ``SuspendSession`` — non-terminal; the session can
|
|
67
|
+
still ``RESUMED``."""
|
|
68
|
+
return self.event_type == "SUSPENDED"
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def is_resumed(self) -> bool:
|
|
72
|
+
"""``True`` after ``ResumeSession`` returns a suspended session to OPEN."""
|
|
73
|
+
return self.event_type == "RESUMED"
|
|
74
|
+
|
|
54
75
|
@property
|
|
55
76
|
def is_terminal(self) -> bool:
|
|
56
|
-
"""``True`` for RESOLVED or
|
|
57
|
-
|
|
77
|
+
"""``True`` for RESOLVED, EXPIRED, or CANCELLED — the session won't
|
|
78
|
+
emit more events. ``SUSPENDED`` / ``RESUMED`` are non-terminal."""
|
|
79
|
+
return self.event_type in ("RESOLVED", "EXPIRED", "CANCELLED")
|
|
58
80
|
|
|
59
81
|
|
|
60
82
|
class ModeRegistryWatcher:
|
|
@@ -151,10 +173,11 @@ class SessionLifecycleWatcher:
|
|
|
151
173
|
|
|
152
174
|
Wraps ``MacpClient.watch_sessions()`` and normalises each response into
|
|
153
175
|
a ``SessionLifecycle`` record carrying the event type as a short
|
|
154
|
-
string (``CREATED`` / ``RESOLVED`` / ``EXPIRED``
|
|
155
|
-
``
|
|
156
|
-
every already-open session at
|
|
157
|
-
thereafter — see
|
|
176
|
+
string (``CREATED`` / ``RESOLVED`` / ``EXPIRED`` / ``CANCELLED`` /
|
|
177
|
+
``SUSPENDED`` / ``RESUMED``) and the full ``SessionMetadata``. The
|
|
178
|
+
runtime emits an initial CREATED event for every already-open session at
|
|
179
|
+
subscribe time, then live events thereafter — see
|
|
180
|
+
``runtime/src/server.rs::watch_sessions``.
|
|
158
181
|
"""
|
|
159
182
|
|
|
160
183
|
def __init__(self, client: MacpClient, *, auth: AuthConfig | None = None) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: macp-sdk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for the MACP Rust runtime
|
|
5
5
|
Author-email: OpenAI <support@openai.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,9 +15,9 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
15
15
|
Requires-Python: >=3.11
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: grpcio>=1.
|
|
18
|
+
Requires-Dist: grpcio>=1.81.1
|
|
19
19
|
Requires-Dist: protobuf>=5.27.0
|
|
20
|
-
Requires-Dist: macp-proto<0.2.0,>=0.1.
|
|
20
|
+
Requires-Dist: macp-proto<0.2.0,>=0.1.3
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: grpcio-tools>=1.74.0; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
@@ -165,6 +165,7 @@ Business logic — voting rules, AI decision heuristics, policy enforcement —
|
|
|
165
165
|
|
|
166
166
|
- `GetSession` returns metadata only (not mode state/transcript) — hence the local projection pattern; use `StreamSession` + `send_subscribe` for the full transcript
|
|
167
167
|
- `StreamSession` is scoped to one session per stream; use `MacpStream.send_subscribe(session_id)` (RFC-MACP-0006-A1, since SDK 0.2.3 / `macp-proto 0.1.2`) to replay accepted history before live broadcast
|
|
168
|
-
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` lifecycle events
|
|
168
|
+
- For cross-session observability, use `MacpClient.list_sessions()` and `SessionLifecycleWatcher` (SDK 0.3.0) to enumerate active sessions and stream `CREATED` / `RESOLVED` / `EXPIRED` / `CANCELLED` / `SUSPENDED` / `RESUMED` lifecycle events
|
|
169
|
+
- Pause and cancel sessions with `MacpClient.suspend_session()` / `resume_session()` / `cancel_session()` (SDK 0.4.0 / `macp-proto 0.1.3`). A suspended session is non-terminal and rejects messages until resumed; an accepted `cancel_session()` now terminates as `CANCELLED` (previously surfaced as `EXPIRED`)
|
|
169
170
|
- `ListRoots` currently returns an empty list and `WatchRoots` idles — the runtime does not yet populate roots
|
|
170
171
|
- Business policy (majority, quorum, veto) belongs in your orchestrator/policy layer
|
|
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.3.0 → macp_sdk_python-0.4.0}/src/macp_sdk_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|