xproof 0.2.4__tar.gz → 0.2.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.
Files changed (26) hide show
  1. {xproof-0.2.4 → xproof-0.2.6}/PKG-INFO +1 -1
  2. {xproof-0.2.4 → xproof-0.2.6}/pyproject.toml +1 -1
  3. {xproof-0.2.4 → xproof-0.2.6}/xproof/__init__.py +11 -1
  4. {xproof-0.2.4 → xproof-0.2.6}/xproof/client.py +55 -6
  5. {xproof-0.2.4 → xproof-0.2.6}/xproof/models.py +113 -1
  6. {xproof-0.2.4 → xproof-0.2.6}/xproof.egg-info/PKG-INFO +1 -1
  7. {xproof-0.2.4 → xproof-0.2.6}/LICENSE +0 -0
  8. {xproof-0.2.4 → xproof-0.2.6}/README.md +0 -0
  9. {xproof-0.2.4 → xproof-0.2.6}/setup.cfg +0 -0
  10. {xproof-0.2.4 → xproof-0.2.6}/tests/test_client.py +0 -0
  11. {xproof-0.2.4 → xproof-0.2.6}/tests/test_integration.py +0 -0
  12. {xproof-0.2.4 → xproof-0.2.6}/xproof/exceptions.py +0 -0
  13. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/__init__.py +0 -0
  14. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/autogen.py +0 -0
  15. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/crewai.py +0 -0
  16. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/deerflow.py +0 -0
  17. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/fetchai.py +0 -0
  18. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/langchain.py +0 -0
  19. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/llamaindex.py +0 -0
  20. {xproof-0.2.4 → xproof-0.2.6}/xproof/integrations/openai_agents.py +0 -0
  21. {xproof-0.2.4 → xproof-0.2.6}/xproof/py.typed +0 -0
  22. {xproof-0.2.4 → xproof-0.2.6}/xproof/utils.py +0 -0
  23. {xproof-0.2.4 → xproof-0.2.6}/xproof.egg-info/SOURCES.txt +0 -0
  24. {xproof-0.2.4 → xproof-0.2.6}/xproof.egg-info/dependency_links.txt +0 -0
  25. {xproof-0.2.4 → xproof-0.2.6}/xproof.egg-info/requires.txt +0 -0
  26. {xproof-0.2.4 → xproof-0.2.6}/xproof.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xproof
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Python SDK for xProof — blockchain-anchored proof-of-existence for AI agents on MultiversX
5
5
  Author-email: xProof <contact@xproof.app>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "xproof"
7
- version = "0.2.4"
7
+ version = "0.2.6"
8
8
  description = "Python SDK for xProof — blockchain-anchored proof-of-existence for AI agents on MultiversX"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -14,14 +14,19 @@ from .models import (
14
14
  BatchResult,
15
15
  BatchResultSummary,
16
16
  Certification,
17
+ ConfidenceTrail,
18
+ ConfidenceTrailStage,
19
+ PolicyCheckResult,
20
+ PolicyViolation,
17
21
  PricingInfo,
18
22
  PricingTier,
19
23
  RegistrationResult,
24
+ ReversibilityClass,
20
25
  TrialInfo,
21
26
  )
22
27
  from .utils import hash_bytes, hash_file
23
28
 
24
- __version__ = "0.2.3"
29
+ __version__ = "0.2.6"
25
30
 
26
31
  __all__ = [
27
32
  "XProofClient",
@@ -30,6 +35,11 @@ __all__ = [
30
35
  "Certification",
31
36
  "BatchResult",
32
37
  "BatchResultSummary",
38
+ "ConfidenceTrail",
39
+ "ConfidenceTrailStage",
40
+ "PolicyCheckResult",
41
+ "PolicyViolation",
42
+ "ReversibilityClass",
33
43
  "PricingInfo",
34
44
  "PricingTier",
35
45
  "RegistrationResult",
@@ -1,7 +1,7 @@
1
1
  """Main client for the xProof API."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Literal, Optional, Union
5
5
 
6
6
  import requests
7
7
 
@@ -14,10 +14,18 @@ from .exceptions import (
14
14
  ValidationError,
15
15
  XProofError,
16
16
  )
17
- from .models import BatchResult, Certification, PricingInfo, RegistrationResult
17
+ from .models import (
18
+ BatchResult,
19
+ Certification,
20
+ ConfidenceTrail,
21
+ PolicyCheckResult,
22
+ PricingInfo,
23
+ RegistrationResult,
24
+ ReversibilityClass,
25
+ )
18
26
  from .utils import hash_file
19
27
 
20
- __version__ = "0.2.4"
28
+ __version__ = "0.2.6"
21
29
 
22
30
  DEFAULT_BASE_URL = "https://xproof.app"
23
31
  DEFAULT_TIMEOUT = 30
@@ -232,6 +240,7 @@ class XProofClient:
232
240
  what: Optional[str] = None,
233
241
  when: Optional[str] = None,
234
242
  why: Optional[str] = None,
243
+ reversibility_class: Optional[ReversibilityClass] = None,
235
244
  metadata: Optional[Dict[str, Any]] = None,
236
245
  ) -> Certification:
237
246
  """Certify a file using a pre-computed SHA-256 hash.
@@ -253,6 +262,9 @@ class XProofClient:
253
262
  what: 4W — action hash or description.
254
263
  when: 4W — ISO-8601 timestamp.
255
264
  why: 4W — instruction or reason.
265
+ reversibility_class: Governance class — one of ``reversible``,
266
+ ``costly``, or ``irreversible``. Irreversible actions above
267
+ the configured confidence threshold trigger a policy violation.
256
268
  metadata: Arbitrary key-value metadata stored alongside the proof.
257
269
 
258
270
  Returns:
@@ -270,6 +282,8 @@ class XProofClient:
270
282
  proof_metadata["when"] = when
271
283
  if why is not None:
272
284
  proof_metadata["why"] = why
285
+ if reversibility_class is not None:
286
+ proof_metadata["reversibility_class"] = reversibility_class
273
287
 
274
288
  payload: Dict[str, Any] = {
275
289
  "filename": file_name,
@@ -296,6 +310,7 @@ class XProofClient:
296
310
  what: Optional[str] = None,
297
311
  when: Optional[str] = None,
298
312
  why: Optional[str] = None,
313
+ reversibility_class: Optional[ReversibilityClass] = None,
299
314
  metadata: Optional[Dict[str, Any]] = None,
300
315
  ) -> Certification:
301
316
  """Certify a file hash with confidence-level anchoring.
@@ -318,6 +333,10 @@ class XProofClient:
318
333
  what: 4W -- action hash or description.
319
334
  when: 4W -- ISO-8601 timestamp.
320
335
  why: 4W -- instruction or reason.
336
+ reversibility_class: Governance class, typed as one of
337
+ ``'reversible'``, ``'costly'``, or ``'irreversible'``.
338
+ Irreversible actions above the configured confidence threshold
339
+ trigger a policy violation.
321
340
  metadata: Extra key-value metadata stored alongside the proof.
322
341
 
323
342
  Returns:
@@ -349,6 +368,8 @@ class XProofClient:
349
368
  proof_metadata["when"] = when
350
369
  if why is not None:
351
370
  proof_metadata["why"] = why
371
+ if reversibility_class is not None:
372
+ proof_metadata["reversibility_class"] = reversibility_class
352
373
 
353
374
  payload: Dict[str, Any] = {
354
375
  "filename": file_name,
@@ -359,16 +380,18 @@ class XProofClient:
359
380
  data = self._request("POST", "/api/proof", json=payload)
360
381
  return Certification.from_dict(data)
361
382
 
362
- def get_confidence_trail(self, decision_id: str) -> Dict[str, Any]:
383
+ def get_confidence_trail(self, decision_id: str) -> ConfidenceTrail:
363
384
  """Retrieve the full confidence trail for a decision chain.
364
385
 
365
386
  Args:
366
387
  decision_id: The shared identifier linking proofs in the chain.
367
388
 
368
389
  Returns:
369
- A dictionary with ``decision_id``, ``total_anchors``,
390
+ A :class:`ConfidenceTrail` with ``decision_id``, ``total_anchors``,
370
391
  ``current_confidence``, ``current_stage``, ``is_finalized``,
392
+ ``policy_compliant``, ``policy_violations``,
371
393
  and ``stages`` (list of anchor details sorted by confidence).
394
+ Access the raw API dict via ``.raw``.
372
395
  """
373
396
  from urllib.parse import quote
374
397
  data = self._request(
@@ -376,7 +399,33 @@ class XProofClient:
376
399
  f"/api/confidence-trail/{quote(decision_id, safe='')}",
377
400
  auth_required=False,
378
401
  )
379
- return data
402
+ return ConfidenceTrail.from_dict(data)
403
+
404
+ def get_policy_check(self, decision_id: str) -> PolicyCheckResult:
405
+ """Check policy compliance for a decision chain without fetching the full trail.
406
+
407
+ A lightweight alternative to :meth:`get_confidence_trail` for agents that
408
+ only need to know whether a decision chain is compliant and which proofs
409
+ violated the reversibility policy.
410
+
411
+ Args:
412
+ decision_id: The shared identifier linking proofs in the chain.
413
+
414
+ Returns:
415
+ A :class:`PolicyCheckResult` with ``policy_compliant``,
416
+ ``policy_violations``, ``total_anchors``, and ``checked_at``.
417
+ Access the raw API dict via ``.raw``.
418
+
419
+ Raises:
420
+ NotFoundError: If no proofs exist for this decision_id.
421
+ """
422
+ from urllib.parse import quote
423
+ data = self._request(
424
+ "GET",
425
+ f"/api/proofs/policy-check?decision_id={quote(decision_id, safe='')}",
426
+ auth_required=False,
427
+ )
428
+ return PolicyCheckResult.from_dict(data)
380
429
 
381
430
  def get_context_drift(self, decision_id: str) -> Dict[str, Any]:
382
431
  """Detect execution context drift across a decision chain.
@@ -1,7 +1,114 @@
1
1
  """Data models for the xProof SDK."""
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any, Dict, List, Literal, Optional
5
+
6
+ ReversibilityClass = Literal["reversible", "costly", "irreversible"]
7
+
8
+
9
+ @dataclass
10
+ class PolicyViolation:
11
+ """A single policy violation detected by the server."""
12
+
13
+ rule: str
14
+ message: str
15
+ severity: str = "error"
16
+
17
+ @classmethod
18
+ def from_dict(cls, data: Dict[str, Any]) -> "PolicyViolation":
19
+ return cls(
20
+ rule=data.get("rule", ""),
21
+ message=data.get("message", ""),
22
+ severity=data.get("severity", "error"),
23
+ )
24
+
25
+
26
+ @dataclass
27
+ class ConfidenceTrailStage:
28
+ """One stage anchor in a confidence trail."""
29
+
30
+ proof_id: str
31
+ confidence_level: float
32
+ threshold_stage: str
33
+ reversibility_class: Optional[str] = None
34
+ anchored_at: str = ""
35
+ transaction_hash: str = ""
36
+ transaction_url: str = ""
37
+ policy_violations: List[PolicyViolation] = field(default_factory=list)
38
+
39
+ @classmethod
40
+ def from_dict(cls, data: Dict[str, Any]) -> "ConfidenceTrailStage":
41
+ metadata = data.get("metadata", {})
42
+ violations_raw = data.get("policy_violations", [])
43
+ return cls(
44
+ proof_id=data.get("proof_id", data.get("id", "")),
45
+ confidence_level=data.get("confidence_level", metadata.get("confidence_level", 0.0)),
46
+ threshold_stage=data.get("threshold_stage", metadata.get("threshold_stage", "")),
47
+ reversibility_class=data.get(
48
+ "reversibility_class", metadata.get("reversibility_class")
49
+ ),
50
+ anchored_at=data.get("anchored_at", data.get("created_at", "")),
51
+ transaction_hash=data.get("transaction_hash", ""),
52
+ transaction_url=data.get("transaction_url", ""),
53
+ policy_violations=[PolicyViolation.from_dict(v) for v in violations_raw],
54
+ )
55
+
56
+
57
+ @dataclass
58
+ class ConfidenceTrail:
59
+ """Full confidence trail for a decision chain."""
60
+
61
+ decision_id: str
62
+ total_anchors: int = 0
63
+ current_confidence: float = 0.0
64
+ current_stage: str = ""
65
+ is_finalized: bool = False
66
+ policy_compliant: bool = True
67
+ policy_violations: List[PolicyViolation] = field(default_factory=list)
68
+ stages: List[ConfidenceTrailStage] = field(default_factory=list)
69
+ raw: Dict[str, Any] = field(default_factory=dict)
70
+
71
+ @classmethod
72
+ def from_dict(cls, data: Dict[str, Any]) -> "ConfidenceTrail":
73
+ """Create a ConfidenceTrail from an API response dictionary."""
74
+ stages = [ConfidenceTrailStage.from_dict(s) for s in data.get("stages", [])]
75
+ violations_raw = data.get("policy_violations", [])
76
+ return cls(
77
+ decision_id=data.get("decision_id", ""),
78
+ total_anchors=data.get("total_anchors", len(stages)),
79
+ current_confidence=data.get("current_confidence", 0.0),
80
+ current_stage=data.get("current_stage", ""),
81
+ is_finalized=data.get("is_finalized", False),
82
+ policy_compliant=data.get("policy_compliant", True),
83
+ policy_violations=[PolicyViolation.from_dict(v) for v in violations_raw],
84
+ stages=stages,
85
+ raw=data,
86
+ )
87
+
88
+
89
+ @dataclass
90
+ class PolicyCheckResult:
91
+ """Lightweight governance compliance report for a decision chain."""
92
+
93
+ decision_id: str
94
+ total_anchors: int = 0
95
+ policy_compliant: bool = True
96
+ policy_violations: List[PolicyViolation] = field(default_factory=list)
97
+ checked_at: str = ""
98
+ raw: Dict[str, Any] = field(default_factory=dict)
99
+
100
+ @classmethod
101
+ def from_dict(cls, data: Dict[str, Any]) -> "PolicyCheckResult":
102
+ """Create a PolicyCheckResult from an API response dictionary."""
103
+ violations_raw = data.get("policy_violations", [])
104
+ return cls(
105
+ decision_id=data.get("decision_id", ""),
106
+ total_anchors=data.get("total_anchors", 0),
107
+ policy_compliant=data.get("policy_compliant", True),
108
+ policy_violations=[PolicyViolation.from_dict(v) for v in violations_raw],
109
+ checked_at=data.get("checked_at", ""),
110
+ raw=data,
111
+ )
5
112
 
6
113
 
7
114
  @dataclass
@@ -21,11 +128,13 @@ class Certification:
21
128
  is_public: bool = True
22
129
  certificate_url: str = ""
23
130
  verify_url: str = ""
131
+ reversibility_class: Optional[str] = None
24
132
 
25
133
  @classmethod
26
134
  def from_dict(cls, data: Dict[str, Any]) -> "Certification":
27
135
  """Create a Certification from an API response dictionary."""
28
136
  blockchain = data.get("blockchain", {})
137
+ metadata = data.get("metadata", {})
29
138
  return cls(
30
139
  id=data.get("id", data.get("proof_id", "")),
31
140
  file_name=data.get("fileName", data.get("filename", data.get("file_name", ""))),
@@ -46,6 +155,9 @@ class Certification:
46
155
  is_public=data.get("isPublic", data.get("is_public", True)),
47
156
  certificate_url=data.get("certificateUrl", data.get("certificate_url", "")),
48
157
  verify_url=data.get("verifyUrl", data.get("verify_url", "")),
158
+ reversibility_class=data.get(
159
+ "reversibility_class", metadata.get("reversibility_class")
160
+ ),
49
161
  )
50
162
 
51
163
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xproof
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Python SDK for xProof — blockchain-anchored proof-of-existence for AI agents on MultiversX
5
5
  Author-email: xProof <contact@xproof.app>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes