apical 0.2.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.
apical-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: apical
3
+ Version: 0.2.0
4
+ Summary: Apical Labs — Zero-Retention Continual Memory & Embedding Router
5
+ Author-email: Apical Labs Ltd <research@apical-labs.com>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://apical-labs.com
8
+ Project-URL: Documentation, https://docs.apical-labs.com
9
+ Project-URL: Repository, https://github.com/apical-labs/apical-sdk
10
+ Project-URL: Changelog, https://github.com/apical-labs/apical-sdk/releases
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Classifier: Topic :: Security :: Cryptography
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: numpy>=1.24.0
23
+ Requires-Dist: httpx>=0.25.0
24
+ Requires-Dist: cryptography>=41.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
27
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
28
+
29
+ # `apical` — Python Client SDK for Apical Labs
30
+
31
+ [![PyPI version](https://img.shields.io/pypi/v/apical.svg)](https://pypi.org/project/apical/)
32
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
33
+
34
+ Official Python client for the **Apical Labs** Zero-Retention Continual Memory & Embedding Router platform.
35
+
36
+ - **Zero Data Retention:** Every update operates in constant $O(1)$ memory (`persisted_bytes_delta == 0`). No replay buffers, no logs, and no historical samples.
37
+ - **Client-Side Privacy Blindness:** Transform features via a customer-held orthogonal secret ($Q \in O(d)$) before they leave your servers.
38
+ - **Cryptographic Receipts:** Every API request returns a tamper-evident `Ed25519` cryptographic receipt provable offline.
39
+ - **Instant Machine Unlearning:** Purge any class coordinate back to quiescent hold in under $1\text{ ms}$ (GDPR / UK GDPR Article 17).
40
+
41
+ ---
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install apical
47
+ ```
48
+
49
+ Dependencies: `numpy>=1.24.0`, `httpx>=0.25.0`, `cryptography>=41.0.0`.
50
+ *Requires ZERO PyTorch and ZERO local training frameworks.*
51
+
52
+ ---
53
+
54
+ ## Quickstart
55
+
56
+ ### 1. Continual Classifier with Instant Machine Unlearning
57
+
58
+ ```python
59
+ from apical import ApicalClient
60
+
61
+ # Initialize client (optionally pass privacy_secret for client-side orthogonal encryption)
62
+ client = ApicalClient(
63
+ api_key="apk_test_...",
64
+ privacy_secret="my-super-secret-salt-key",
65
+ )
66
+
67
+ # Bind to model
68
+ classifier = client.classifier("customer-intent-v1")
69
+
70
+ # Create model on Apical Cloud (128-D input embedding, 10 classes)
71
+ classifier.create(in_features=128, num_classes=10)
72
+
73
+ # Online update (learn a new sample with zero data retention)
74
+ embedding = [0.05] * 128
75
+ learn_result = classifier.learn(embedding, target_class=2)
76
+ print(f"Updated: status={learn_result.status}, delta_bytes={learn_result.persisted_bytes_delta}")
77
+
78
+ # Predict class
79
+ pred = classifier.predict(embedding)
80
+ print(f"Predicted class {pred.prediction} with confidence {pred.confidence:.4f}")
81
+
82
+ # Instant GDPR Article 17 Machine Unlearning (< 1 ms)
83
+ unlearn_result = classifier.unlearn(class_id=2)
84
+ print(f"Erased class 2: status={unlearn_result.status}, delta_bytes={unlearn_result.persisted_bytes_delta}")
85
+ ```
86
+
87
+ ---
88
+
89
+ ### 2. Real-Time Dynamic Memory Router
90
+
91
+ ```python
92
+ from apical import ApicalClient
93
+
94
+ client = ApicalClient(api_key="apk_test_...")
95
+ router = client.memory_router("agent-tool-router")
96
+
97
+ # Create router: 512-D embeddings, 32 rule destinations
98
+ router.create(embedding_dim=512, num_rules=32)
99
+
100
+ # Route incoming query embedding to top 3 matching tools/rules
101
+ query_embedding = [0.12] * 512
102
+ route_result = router.route(query_embedding, top_k=3)
103
+ for r in route_result.routes:
104
+ print(f"Rule ID: {r.rule_id}, Affinity: {r.affinity}")
105
+
106
+ # Reinforce a target rule based on positive execution outcome
107
+ router.reinforce(query_embedding, target_rule=5)
108
+ ```
109
+
110
+ ---
111
+
112
+ ### 3. Offline Ed25519 Zero-Retention Receipt Verification
113
+
114
+ Every response returns an `Ed25519` cryptographic receipt certifying:
115
+ 1. `persisted_bytes_delta == 0` (mathematical proof that no raw sample was appended)
116
+ 2. `input_buffer_zeroed == True` (transient RAM scrubber timestamp)
117
+ 3. Cryptographic signature over canonical JSON
118
+
119
+ ```python
120
+ from apical import verify_zero_retention_receipt
121
+
122
+ # Verify receipt offline without making any network requests
123
+ is_valid = verify_zero_retention_receipt(pred.receipt)
124
+ assert is_valid is True
125
+ print("Zero-retention receipt cryptographically verified!")
126
+ ```
127
+
128
+ ---
129
+
130
+ ## License
131
+
132
+ Apache-2.0. Copyright &copy; 2026 Apical Labs Ltd. All rights reserved.
apical-0.2.0/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # `apical` — Python Client SDK for Apical Labs
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/apical.svg)](https://pypi.org/project/apical/)
4
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
5
+
6
+ Official Python client for the **Apical Labs** Zero-Retention Continual Memory & Embedding Router platform.
7
+
8
+ - **Zero Data Retention:** Every update operates in constant $O(1)$ memory (`persisted_bytes_delta == 0`). No replay buffers, no logs, and no historical samples.
9
+ - **Client-Side Privacy Blindness:** Transform features via a customer-held orthogonal secret ($Q \in O(d)$) before they leave your servers.
10
+ - **Cryptographic Receipts:** Every API request returns a tamper-evident `Ed25519` cryptographic receipt provable offline.
11
+ - **Instant Machine Unlearning:** Purge any class coordinate back to quiescent hold in under $1\text{ ms}$ (GDPR / UK GDPR Article 17).
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install apical
19
+ ```
20
+
21
+ Dependencies: `numpy>=1.24.0`, `httpx>=0.25.0`, `cryptography>=41.0.0`.
22
+ *Requires ZERO PyTorch and ZERO local training frameworks.*
23
+
24
+ ---
25
+
26
+ ## Quickstart
27
+
28
+ ### 1. Continual Classifier with Instant Machine Unlearning
29
+
30
+ ```python
31
+ from apical import ApicalClient
32
+
33
+ # Initialize client (optionally pass privacy_secret for client-side orthogonal encryption)
34
+ client = ApicalClient(
35
+ api_key="apk_test_...",
36
+ privacy_secret="my-super-secret-salt-key",
37
+ )
38
+
39
+ # Bind to model
40
+ classifier = client.classifier("customer-intent-v1")
41
+
42
+ # Create model on Apical Cloud (128-D input embedding, 10 classes)
43
+ classifier.create(in_features=128, num_classes=10)
44
+
45
+ # Online update (learn a new sample with zero data retention)
46
+ embedding = [0.05] * 128
47
+ learn_result = classifier.learn(embedding, target_class=2)
48
+ print(f"Updated: status={learn_result.status}, delta_bytes={learn_result.persisted_bytes_delta}")
49
+
50
+ # Predict class
51
+ pred = classifier.predict(embedding)
52
+ print(f"Predicted class {pred.prediction} with confidence {pred.confidence:.4f}")
53
+
54
+ # Instant GDPR Article 17 Machine Unlearning (< 1 ms)
55
+ unlearn_result = classifier.unlearn(class_id=2)
56
+ print(f"Erased class 2: status={unlearn_result.status}, delta_bytes={unlearn_result.persisted_bytes_delta}")
57
+ ```
58
+
59
+ ---
60
+
61
+ ### 2. Real-Time Dynamic Memory Router
62
+
63
+ ```python
64
+ from apical import ApicalClient
65
+
66
+ client = ApicalClient(api_key="apk_test_...")
67
+ router = client.memory_router("agent-tool-router")
68
+
69
+ # Create router: 512-D embeddings, 32 rule destinations
70
+ router.create(embedding_dim=512, num_rules=32)
71
+
72
+ # Route incoming query embedding to top 3 matching tools/rules
73
+ query_embedding = [0.12] * 512
74
+ route_result = router.route(query_embedding, top_k=3)
75
+ for r in route_result.routes:
76
+ print(f"Rule ID: {r.rule_id}, Affinity: {r.affinity}")
77
+
78
+ # Reinforce a target rule based on positive execution outcome
79
+ router.reinforce(query_embedding, target_rule=5)
80
+ ```
81
+
82
+ ---
83
+
84
+ ### 3. Offline Ed25519 Zero-Retention Receipt Verification
85
+
86
+ Every response returns an `Ed25519` cryptographic receipt certifying:
87
+ 1. `persisted_bytes_delta == 0` (mathematical proof that no raw sample was appended)
88
+ 2. `input_buffer_zeroed == True` (transient RAM scrubber timestamp)
89
+ 3. Cryptographic signature over canonical JSON
90
+
91
+ ```python
92
+ from apical import verify_zero_retention_receipt
93
+
94
+ # Verify receipt offline without making any network requests
95
+ is_valid = verify_zero_retention_receipt(pred.receipt)
96
+ assert is_valid is True
97
+ print("Zero-retention receipt cryptographically verified!")
98
+ ```
99
+
100
+ ---
101
+
102
+ ## License
103
+
104
+ Apache-2.0. Copyright &copy; 2026 Apical Labs Ltd. All rights reserved.
@@ -0,0 +1,88 @@
1
+ """Apical Labs — Zero-Retention Continual Memory & Embedding Router.
2
+
3
+ Client SDK providing:
4
+ - ApicalClient: Main client connection pool
5
+ - Classifier: Continual classification with instant GDPR Art. 17 unlearning
6
+ - MemoryRouter: Real-time dynamic embedding routing and reinforcement
7
+ - OrthogonalPrivacyProjector: Client-side mathematical input de-identification
8
+ - verify_zero_retention_receipt: Offline Ed25519 receipt verification
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from apical.classifier import (
14
+ Classifier,
15
+ LearnResult,
16
+ PredictionResult,
17
+ UnlearnResult,
18
+ )
19
+ from apical.client import ApicalClient, ArborNamespace, BridgeResult
20
+
21
+ # Backward-compatible convenience alias
22
+ Client = ApicalClient
23
+ from apical.exceptions import (
24
+ APIError,
25
+ ApicalError,
26
+ AuthenticationError,
27
+ FixedByteInvariantError,
28
+ ModelNotFoundError,
29
+ ProductNotEntitledError,
30
+ RateLimitError,
31
+ SparseProbeError,
32
+ SweepDetectedError,
33
+ VerificationError,
34
+ )
35
+ from apical.orthogonal import OrthogonalPrivacyProjector
36
+ from apical.plexus import (
37
+ PlexusClassifier,
38
+ PlexusLearnResult,
39
+ PlexusNetwork,
40
+ PlexusPredictionResult,
41
+ PlexusRouteResult,
42
+ PlexusRouter,
43
+ PlexusUnlearnResult,
44
+ )
45
+ from apical.router import (
46
+ MemoryRouter,
47
+ ReinforceResult,
48
+ RouteItem,
49
+ RouteResult,
50
+ )
51
+ from apical.verifier import verify_zero_retention_receipt
52
+
53
+
54
+ __version__ = "0.2.0"
55
+
56
+ __all__ = [
57
+ "APIError",
58
+ "ApicalClient",
59
+ "ApicalError",
60
+ "ArborNamespace",
61
+ "AuthenticationError",
62
+ "BridgeResult",
63
+ "Classifier",
64
+ "Client",
65
+ "FixedByteInvariantError",
66
+ "LearnResult",
67
+ "MemoryRouter",
68
+ "ModelNotFoundError",
69
+ "OrthogonalPrivacyProjector",
70
+ "PlexusClassifier",
71
+ "PlexusLearnResult",
72
+ "PlexusNetwork",
73
+ "PlexusPredictionResult",
74
+ "PlexusRouteResult",
75
+ "PlexusRouter",
76
+ "PlexusUnlearnResult",
77
+ "PredictionResult",
78
+ "ProductNotEntitledError",
79
+ "RateLimitError",
80
+ "ReinforceResult",
81
+ "RouteItem",
82
+ "RouteResult",
83
+ "SparseProbeError",
84
+ "SweepDetectedError",
85
+ "UnlearnResult",
86
+ "VerificationError",
87
+ "verify_zero_retention_receipt",
88
+ ]
@@ -0,0 +1,205 @@
1
+ """Classifier Surface for the Apical Labs Platform."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Dict, NamedTuple, Optional, Sequence, Union
6
+ import numpy as np
7
+
8
+ from apical.orthogonal import OrthogonalPrivacyProjector
9
+ from apical.verifier import verify_zero_retention_receipt
10
+
11
+
12
+ class PredictionResult(NamedTuple):
13
+ """Result of a classifier inference pass."""
14
+ prediction: int
15
+ confidence: float
16
+ receipt: Dict[str, Any]
17
+ crystallization_pct: Optional[float] = None
18
+ mean_plasticity: Optional[float] = None
19
+
20
+ @property
21
+ def signature(self) -> str:
22
+ """Return the Ed25519 signature from the cryptographic attestation receipt."""
23
+ return str(self.receipt.get("ed25519_signature", ""))
24
+
25
+
26
+ class LearnResult(NamedTuple):
27
+ """Result of a single continual update."""
28
+ status: str
29
+ target_class: int
30
+ winner_class: int
31
+ confidence: float
32
+ update_count: int
33
+ persisted_bytes_delta: int
34
+ receipt: Dict[str, Any]
35
+
36
+ @property
37
+ def signature(self) -> str:
38
+ """Return the Ed25519 signature from the cryptographic attestation receipt."""
39
+ return str(self.receipt.get("ed25519_signature", ""))
40
+
41
+
42
+ class UnlearnResult(NamedTuple):
43
+ """Result of an instant GDPR Article 17 class erasure."""
44
+ status: str
45
+ erased_class_id: int
46
+ persisted_bytes_delta: int
47
+ receipt: Dict[str, Any]
48
+
49
+ @property
50
+ def signature(self) -> str:
51
+ """Return the Ed25519 signature from the cryptographic attestation receipt."""
52
+ return str(self.receipt.get("ed25519_signature", ""))
53
+
54
+
55
+ class Classifier:
56
+ """Client interface for continuous classification models."""
57
+
58
+ def __init__(
59
+ self,
60
+ client: Any,
61
+ model_id: str,
62
+ in_features: Optional[int] = None,
63
+ num_classes: Optional[int] = None,
64
+ privacy_secret: Optional[str] = None,
65
+ ) -> None:
66
+ self.client = client
67
+ self.model_id = model_id
68
+ self.in_features = in_features
69
+ self.num_classes = num_classes
70
+ self.privacy_secret = privacy_secret
71
+
72
+ self._projector: Optional[OrthogonalPrivacyProjector] = None
73
+ if self.privacy_secret and self.in_features:
74
+ self._projector = OrthogonalPrivacyProjector(self.privacy_secret, self.in_features)
75
+
76
+ def _prepare_vector(self, vector: Union[Sequence[float], np.ndarray]) -> list[float]:
77
+ """Optionally apply orthogonal privacy projection, returning a JSON-serializable list."""
78
+ arr = np.asarray(vector, dtype=np.float32).ravel()
79
+
80
+ if self._projector is not None:
81
+ arr = self._projector.project(arr)
82
+ elif self.privacy_secret and not self._projector:
83
+ # Lazy initialize projector once vector dimension is known
84
+ self.in_features = arr.size
85
+ self._projector = OrthogonalPrivacyProjector(self.privacy_secret, self.in_features)
86
+ arr = self._projector.project(arr)
87
+
88
+ return arr.tolist()
89
+
90
+ def create(self, in_features: int, num_classes: int) -> Dict[str, Any]:
91
+ """Create and initialize a new fixed-byte model container on Apical Cloud."""
92
+ self.in_features = in_features
93
+ self.num_classes = num_classes
94
+
95
+ if self.privacy_secret and not self._projector:
96
+ self._projector = OrthogonalPrivacyProjector(self.privacy_secret, self.in_features)
97
+
98
+ payload = {
99
+ "model_id": self.model_id,
100
+ "in_features": in_features,
101
+ "out_features": num_classes,
102
+ }
103
+ resp = self.client.request("POST", f"/api/v1/models", payload)
104
+ data = resp.get("data", resp)
105
+
106
+ if "receipt" in data:
107
+ verify_zero_retention_receipt(data["receipt"])
108
+
109
+ return data
110
+
111
+ def predict(
112
+ self,
113
+ vector: Union[Sequence[float], np.ndarray],
114
+ tier: int = 0,
115
+ verify_receipt: bool = True,
116
+ ) -> PredictionResult:
117
+ """Execute directional classification, returning class prediction and signed receipt."""
118
+ prep_vec = self._prepare_vector(vector)
119
+ payload = {
120
+ "model_id": self.model_id,
121
+ "vector": prep_vec,
122
+ "tier": tier,
123
+ }
124
+ resp = self.client.request("POST", f"/api/v1/predict", payload)
125
+ data = resp.get("data", resp)
126
+
127
+ receipt = data.get("receipt", {})
128
+ if verify_receipt and receipt:
129
+ verify_zero_retention_receipt(receipt)
130
+
131
+ return PredictionResult(
132
+ prediction=int(data["prediction"]),
133
+ confidence=float(data["confidence"]),
134
+ receipt=receipt,
135
+ crystallization_pct=data.get("crystallization_pct"),
136
+ mean_plasticity=data.get("mean_plasticity"),
137
+ )
138
+
139
+ def learn(
140
+ self,
141
+ vector: Union[Sequence[float], np.ndarray],
142
+ target_class: int,
143
+ tier: int = 0,
144
+ verify_receipt: bool = True,
145
+ ) -> LearnResult:
146
+ """Stream a single continual update, updating model state under zero retention."""
147
+ prep_vec = self._prepare_vector(vector)
148
+ payload = {
149
+ "model_id": self.model_id,
150
+ "vector": prep_vec,
151
+ "target_class": target_class,
152
+ "tier": tier,
153
+ }
154
+ resp = self.client.request("POST", f"/api/v1/learn", payload)
155
+ data = resp.get("data", resp)
156
+
157
+ receipt = data.get("receipt", {})
158
+ if verify_receipt and receipt:
159
+ verify_zero_retention_receipt(receipt)
160
+
161
+ return LearnResult(
162
+ status=str(data.get("status", "updated")),
163
+ target_class=int(data["target_class"]),
164
+ winner_class=int(data["winner_class"]),
165
+ confidence=float(data["confidence"]),
166
+ update_count=int(data.get("update_count", 0)),
167
+ persisted_bytes_delta=int(data.get("persisted_bytes_delta", 0)),
168
+ receipt=receipt,
169
+ )
170
+
171
+ def unlearn(
172
+ self,
173
+ class_id: int,
174
+ verify_receipt: bool = True,
175
+ ) -> UnlearnResult:
176
+ """Execute instant GDPR Article 17 Machine Unlearning for a specific class coordinate."""
177
+ payload = {
178
+ "model_id": self.model_id,
179
+ "class_id": class_id,
180
+ }
181
+ resp = self.client.request("POST", f"/api/v1/unlearn", payload)
182
+ data = resp.get("data", resp)
183
+
184
+ receipt = data.get("receipt", {})
185
+ if verify_receipt and receipt:
186
+ verify_zero_retention_receipt(receipt)
187
+
188
+ return UnlearnResult(
189
+ status=str(data.get("status", "erased")),
190
+ erased_class_id=int(data.get("erased_class_id", class_id)),
191
+ persisted_bytes_delta=int(data.get("persisted_bytes_delta", 0)),
192
+ receipt=receipt,
193
+ )
194
+
195
+ def erase_class(
196
+ self,
197
+ target_class: Optional[int] = None,
198
+ class_id: Optional[int] = None,
199
+ verify_receipt: bool = True,
200
+ ) -> UnlearnResult:
201
+ """Execute instant GDPR Article 17 Machine Unlearning for a specific class coordinate (alias for unlearn)."""
202
+ target = target_class if target_class is not None else class_id
203
+ if target is None:
204
+ raise ValueError("Either target_class or class_id must be provided")
205
+ return self.unlearn(class_id=target, verify_receipt=verify_receipt)