proxilion 0.0.2__py3-none-any.whl → 0.0.3__py3-none-any.whl

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 (34) hide show
  1. proxilion/audit/__init__.py +15 -15
  2. proxilion/audit/compliance/base.py +4 -4
  3. proxilion/audit/compliance/eu_ai_act.py +14 -4
  4. proxilion/audit/compliance/iso27001.py +2 -2
  5. proxilion/audit/compliance/soc2.py +16 -3
  6. proxilion/audit/events.py +9 -5
  7. proxilion/audit/explainability.py +30 -19
  8. proxilion/audit/hash_chain.py +14 -0
  9. proxilion/caching/tool_cache.py +14 -8
  10. proxilion/context/context_window.py +27 -2
  11. proxilion/contrib/anthropic.py +2 -2
  12. proxilion/contrib/mcp.py +2 -1
  13. proxilion/contrib/openai.py +2 -2
  14. proxilion/core.py +26 -21
  15. proxilion/exceptions.py +84 -0
  16. proxilion/guards/output_guard.py +1 -1
  17. proxilion/observability/__init__.py +3 -1
  18. proxilion/observability/metrics.py +14 -6
  19. proxilion/observability/session_cost_tracker.py +6 -7
  20. proxilion/policies/builtin.py +2 -1
  21. proxilion/policies/registry.py +12 -6
  22. proxilion/security/__init__.py +51 -37
  23. proxilion/security/agent_trust.py +23 -8
  24. proxilion/security/behavioral_drift.py +14 -6
  25. proxilion/security/idor_protection.py +12 -4
  26. proxilion/security/intent_capsule.py +3 -2
  27. proxilion/security/intent_validator.py +89 -2
  28. proxilion/security/memory_integrity.py +14 -13
  29. proxilion/security/rate_limiter.py +112 -22
  30. proxilion/timeouts/manager.py +2 -0
  31. {proxilion-0.0.2.dist-info → proxilion-0.0.3.dist-info}/METADATA +6 -6
  32. {proxilion-0.0.2.dist-info → proxilion-0.0.3.dist-info}/RECORD +34 -34
  33. {proxilion-0.0.2.dist-info → proxilion-0.0.3.dist-info}/WHEEL +0 -0
  34. {proxilion-0.0.2.dist-info → proxilion-0.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -41,7 +41,6 @@ from __future__ import annotations
41
41
 
42
42
  import hashlib
43
43
  import hmac
44
- import json
45
44
  import logging
46
45
  import re
47
46
  import threading
@@ -49,7 +48,7 @@ import time
49
48
  from dataclasses import dataclass, field
50
49
  from datetime import datetime, timezone
51
50
  from enum import Enum
52
- from typing import Any, Protocol, runtime_checkable
51
+ from typing import Any
53
52
 
54
53
  logger = logging.getLogger(__name__)
55
54
 
@@ -462,12 +461,13 @@ class MemoryIntegrityGuard:
462
461
  if strict_sequence:
463
462
  if msg.sequence != prev_sequence + 1:
464
463
  if msg.sequence <= prev_sequence:
464
+ expected_seq = prev_sequence + 1
465
465
  violations.append(IntegrityViolation(
466
466
  violation_type=IntegrityViolationType.SEQUENCE_REORDER,
467
- message=f"Message {i} has sequence {msg.sequence}, expected {prev_sequence + 1}",
467
+ message=f"Message {i} sequence {msg.sequence}, expected {expected_seq}",
468
468
  severity=0.9,
469
469
  index=i,
470
- expected=str(prev_sequence + 1),
470
+ expected=str(expected_seq),
471
471
  actual=str(msg.sequence),
472
472
  ))
473
473
  else:
@@ -489,9 +489,10 @@ class MemoryIntegrityGuard:
489
489
  ))
490
490
  elif msg.timestamp - prev_timestamp > self._max_timestamp_drift:
491
491
  # Large gap might indicate injection
492
+ gap = msg.timestamp - prev_timestamp
492
493
  violations.append(IntegrityViolation(
493
494
  violation_type=IntegrityViolationType.TIMESTAMP_ANOMALY,
494
- message=f"Large timestamp gap at message {i}: {msg.timestamp - prev_timestamp:.1f}s",
495
+ message=f"Large timestamp gap at message {i}: {gap:.1f}s",
495
496
  severity=0.5,
496
497
  index=i,
497
498
  ))
@@ -710,15 +711,15 @@ class ContextWindowGuard:
710
711
  Raises:
711
712
  ContextIntegrityError: If verification fails.
712
713
  """
713
- result = self.verify()
714
- if not result.valid:
715
- from proxilion.exceptions import ContextIntegrityError
716
- raise ContextIntegrityError(
717
- f"Context integrity violated: {result.violations[0].message}",
718
- violations=result.violations,
719
- )
720
-
721
714
  with self._lock:
715
+ result = self._guard.verify_context(self._messages)
716
+ if not result.valid:
717
+ from proxilion.exceptions import ContextIntegrityError
718
+ raise ContextIntegrityError(
719
+ f"Context integrity violated: {result.violations[0].message}",
720
+ violations=result.violations,
721
+ )
722
+
722
723
  return [
723
724
  {"role": msg.role, "content": msg.content}
724
725
  for msg in self._messages
@@ -73,6 +73,8 @@ class TokenBucketRateLimiter:
73
73
 
74
74
  self._buckets: dict[str, RateLimitState] = {}
75
75
  self._lock = threading.RLock()
76
+ self._last_cleanup = time.monotonic()
77
+ self._cleanup_interval = 300.0 # 5 minutes
76
78
 
77
79
  def _get_or_create_bucket(self, key: str) -> RateLimitState:
78
80
  """Get or create a bucket for a key."""
@@ -109,6 +111,9 @@ class TokenBucketRateLimiter:
109
111
  ... pass
110
112
  """
111
113
  with self._lock:
114
+ # Periodically cleanup stale buckets to prevent memory growth
115
+ self._maybe_cleanup()
116
+
112
117
  bucket = self._get_or_create_bucket(key)
113
118
  self._refill_bucket(bucket)
114
119
 
@@ -173,6 +178,46 @@ class TokenBucketRateLimiter:
173
178
  with self._lock:
174
179
  self._buckets.clear()
175
180
 
181
+ def cleanup(self, max_age_seconds: float = 3600.0) -> int:
182
+ """
183
+ Remove stale buckets to prevent unbounded memory growth.
184
+
185
+ Buckets that have been at full capacity (inactive) for longer
186
+ than max_age_seconds are removed.
187
+
188
+ Args:
189
+ max_age_seconds: Maximum age for inactive buckets (default 1 hour).
190
+
191
+ Returns:
192
+ Number of buckets removed.
193
+ """
194
+ with self._lock:
195
+ now = time.monotonic()
196
+ to_remove = []
197
+
198
+ for key, bucket in self._buckets.items():
199
+ # If bucket is at or near full capacity, check how long since last use
200
+ self._refill_bucket(bucket)
201
+ if bucket.tokens >= self.capacity * 0.99: # 99% full = inactive
202
+ age = now - bucket.last_update
203
+ if age > max_age_seconds:
204
+ to_remove.append(key)
205
+
206
+ for key in to_remove:
207
+ del self._buckets[key]
208
+
209
+ if to_remove:
210
+ logger.debug(f"Cleaned up {len(to_remove)} stale rate limit buckets")
211
+
212
+ return len(to_remove)
213
+
214
+ def _maybe_cleanup(self) -> None:
215
+ """Periodically cleanup stale buckets."""
216
+ now = time.monotonic()
217
+ if now - self._last_cleanup > self._cleanup_interval:
218
+ self._last_cleanup = now
219
+ self.cleanup()
220
+
176
221
 
177
222
  class SlidingWindowRateLimiter:
178
223
  """
@@ -209,6 +254,8 @@ class SlidingWindowRateLimiter:
209
254
 
210
255
  self._requests: dict[str, list[float]] = defaultdict(list)
211
256
  self._lock = threading.RLock()
257
+ self._last_cleanup = time.monotonic()
258
+ self._cleanup_interval = 300.0 # 5 minutes
212
259
 
213
260
  def _cleanup_old_requests(self, key: str) -> None:
214
261
  """Remove requests outside the window."""
@@ -229,6 +276,9 @@ class SlidingWindowRateLimiter:
229
276
  True if allowed, False if rate limited.
230
277
  """
231
278
  with self._lock:
279
+ # Periodically cleanup empty keys to prevent memory growth
280
+ self._maybe_cleanup()
281
+
232
282
  self._cleanup_old_requests(key)
233
283
 
234
284
  current_count = len(self._requests[key])
@@ -266,6 +316,47 @@ class SlidingWindowRateLimiter:
266
316
  with self._lock:
267
317
  self._requests.pop(key, None)
268
318
 
319
+ def reset_all(self) -> None:
320
+ """Reset all request history."""
321
+ with self._lock:
322
+ self._requests.clear()
323
+
324
+ def cleanup(self) -> int:
325
+ """
326
+ Remove empty/stale keys to prevent unbounded memory growth.
327
+
328
+ Returns:
329
+ Number of keys removed.
330
+ """
331
+ with self._lock:
332
+ # First cleanup old requests from all keys
333
+ cutoff = time.monotonic() - self.window_seconds
334
+ to_remove = []
335
+
336
+ for key in list(self._requests.keys()):
337
+ # Clean old requests
338
+ self._requests[key] = [
339
+ t for t in self._requests[key] if t > cutoff
340
+ ]
341
+ # Mark empty keys for removal
342
+ if not self._requests[key]:
343
+ to_remove.append(key)
344
+
345
+ for key in to_remove:
346
+ del self._requests[key]
347
+
348
+ if to_remove:
349
+ logger.debug(f"Cleaned up {len(to_remove)} empty sliding window keys")
350
+
351
+ return len(to_remove)
352
+
353
+ def _maybe_cleanup(self) -> None:
354
+ """Periodically cleanup empty keys."""
355
+ now = time.monotonic()
356
+ if now - self._last_cleanup > self._cleanup_interval:
357
+ self._last_cleanup = now
358
+ self.cleanup()
359
+
269
360
 
270
361
  @dataclass
271
362
  class RateLimitConfig:
@@ -309,6 +400,7 @@ class MultiDimensionalRateLimiter:
309
400
  """
310
401
  self.limits = limits
311
402
  self._limiters: dict[str, TokenBucketRateLimiter | SlidingWindowRateLimiter] = {}
403
+ self._lock = threading.RLock() # Lock for atomic check-and-consume
312
404
 
313
405
  for dimension, config in limits.items():
314
406
  if use_sliding_window and config.window_seconds:
@@ -330,6 +422,10 @@ class MultiDimensionalRateLimiter:
330
422
  """
331
423
  Check if request is allowed across all dimensions.
332
424
 
425
+ This method is atomic - the check and consume operations are performed
426
+ under a single lock to prevent TOCTOU (time-of-check to time-of-use)
427
+ race conditions.
428
+
333
429
  Args:
334
430
  keys: Dictionary mapping dimension names to keys.
335
431
  costs: Optional per-dimension costs (default 1 for all).
@@ -339,38 +435,32 @@ class MultiDimensionalRateLimiter:
339
435
  """
340
436
  costs = costs or {}
341
437
 
342
- # Check all dimensions first (don't consume until we know all pass)
343
- for dimension, key in keys.items():
344
- if dimension not in self._limiters:
345
- continue
438
+ # Atomic check-and-consume to prevent TOCTOU race condition
439
+ with self._lock:
440
+ # Check all dimensions first (don't consume until we know all pass)
441
+ for dimension, key in keys.items():
442
+ if dimension not in self._limiters:
443
+ continue
346
444
 
347
- limiter = self._limiters[dimension]
348
- cost = costs.get(dimension, 1)
445
+ limiter = self._limiters[dimension]
446
+ cost = costs.get(dimension, 1)
349
447
 
350
- # For token bucket, we need to check without consuming
351
- if isinstance(limiter, TokenBucketRateLimiter):
352
- if limiter.get_remaining(key) < cost:
353
- logger.debug(
354
- f"Rate limit failed: dimension={dimension}, key={key}"
355
- )
356
- return False
357
- else:
358
448
  if limiter.get_remaining(key) < cost:
359
449
  logger.debug(
360
450
  f"Rate limit failed: dimension={dimension}, key={key}"
361
451
  )
362
452
  return False
363
453
 
364
- # All checks passed, now consume tokens
365
- for dimension, key in keys.items():
366
- if dimension not in self._limiters:
367
- continue
454
+ # All checks passed, now consume tokens
455
+ for dimension, key in keys.items():
456
+ if dimension not in self._limiters:
457
+ continue
368
458
 
369
- limiter = self._limiters[dimension]
370
- cost = costs.get(dimension, 1)
371
- limiter.allow_request(key, cost)
459
+ limiter = self._limiters[dimension]
460
+ cost = costs.get(dimension, 1)
461
+ limiter.allow_request(key, cost)
372
462
 
373
- return True
463
+ return True
374
464
 
375
465
  def get_most_restrictive(
376
466
  self,
@@ -177,6 +177,8 @@ class DeadlineContext:
177
177
  operation: Optional operation name for error messages.
178
178
  raise_on_expire: Whether to raise TimeoutError when expired.
179
179
  """
180
+ if timeout <= 0:
181
+ raise ValueError(f"Timeout must be positive, got {timeout}")
180
182
  self.timeout = timeout
181
183
  self.operation = operation
182
184
  self.raise_on_expire = raise_on_expire
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxilion
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Application-layer security SDK for LLM tool call authorization
5
5
  Project-URL: Homepage, https://proxilion.com
6
6
  Project-URL: Documentation, https://proxilion.com
@@ -290,11 +290,11 @@ if limiter.allow_request("user_123"):
290
290
  limiter = SlidingWindowRateLimiter(max_requests=100, window_seconds=60)
291
291
 
292
292
  # Multi-dimensional (user + IP + tool)
293
- limiter = MultiDimensionalRateLimiter(configs=[
294
- RateLimitConfig(dimension="user", capacity=100, refill_rate=10),
295
- RateLimitConfig(dimension="ip", capacity=1000, refill_rate=100),
296
- RateLimitConfig(dimension="tool", capacity=50, refill_rate=5),
297
- ])
293
+ limiter = MultiDimensionalRateLimiter(limits={
294
+ "user": RateLimitConfig(capacity=100, refill_rate=10),
295
+ "ip": RateLimitConfig(capacity=1000, refill_rate=100),
296
+ "tool": RateLimitConfig(capacity=50, refill_rate=5),
297
+ })
298
298
  ```
299
299
 
300
300
  **Deterministic**: Counter-based algorithms with configurable thresholds.
@@ -1,20 +1,20 @@
1
1
  proxilion/__init__.py,sha256=BDp82vX1aooKPTD0r45rNh6z5J1rvjSJHu57oYLvooA,3339
2
- proxilion/core.py,sha256=QiZLkLl4pnDPGEkPx456Ys-qulR4Zd-S-xGFIcYb5Lc,100184
2
+ proxilion/core.py,sha256=pB_LYecpqKNk4bhNYgT2A7R0Yb9ae_CFlHhL5ZLhYbU,100612
3
3
  proxilion/decorators.py,sha256=6Oy-RbNXUgYDKQc9oaRHO1GcmHeIFg9_EhNiaWa7NS8,32242
4
- proxilion/exceptions.py,sha256=dl4oUgRPoynbzeV-QOLFs_MGNglTVMkaMkwhybU7iiY,27257
4
+ proxilion/exceptions.py,sha256=t1ZVM840Fqu86lMuSLQjzFHymqL4Ui7ieI4INe61-GM,29885
5
5
  proxilion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  proxilion/types.py,sha256=6D1Q-v4cre2WYU6GAqFpqMuu6eK_1ufzjwYy2dtvNhE,11990
7
- proxilion/audit/__init__.py,sha256=HWbi_SMkPYcjSwDllLVu1LYJRRJbSUjofwnlVkdE7_g,3181
7
+ proxilion/audit/__init__.py,sha256=sWLCCudk32eBnhe0pNBOcGcMrkoFW_oOadY9s2SUR2I,3181
8
8
  proxilion/audit/base_exporters.py,sha256=AwjcO4ZltruVVIryUAReyqSOGuXw1IOcPy0p7gcHrm4,15874
9
- proxilion/audit/events.py,sha256=fKfnd4YClemgxiRs-GUhhJ7R6kDH50illZByLORdJyM,16677
10
- proxilion/audit/explainability.py,sha256=tCBGgjjQe8nlv3DBs3bi8T4opRCUbCiPrMq3OJ88OaU,41820
11
- proxilion/audit/hash_chain.py,sha256=b5bu5O0qCLdYeOi3Zd24nOqfwmoHuw6_pJEyWc-mVh4,20738
9
+ proxilion/audit/events.py,sha256=4qyvwsHBszyv8XQua8DKrhPDJ2Np58ow3xGmchbgwlI,16749
10
+ proxilion/audit/explainability.py,sha256=aGjka_Xap_oLtw3wXAmhEEFxpnMkMAGnTycaktHdKpA,42007
11
+ proxilion/audit/hash_chain.py,sha256=0kWU7TEP498U5etIbX7COH4owz4yfLXJ1k9QEA2Bh60,21389
12
12
  proxilion/audit/logger.py,sha256=ew4XFP0fOUii673AUVlK1gBMUgaGn5-OZErilagnamk,17171
13
13
  proxilion/audit/compliance/__init__.py,sha256=lA_IuyZt2JCRFtJqq6sdUT5hkAZmdMX1Rj_Lu65JzZo,3962
14
- proxilion/audit/compliance/base.py,sha256=Tm9WaVTlqL6_WsK7enyoXyh_bHk-bvg_5xl95Pt1wJM,14665
15
- proxilion/audit/compliance/eu_ai_act.py,sha256=W8Eut-hdVJ8MxDCtonHSSO4i4DQ_5S4NZKHgExUr0Ag,22458
16
- proxilion/audit/compliance/iso27001.py,sha256=_bpL7UgQhTpw-yC02LOpag1qbsLfzsofK3TjxS8gPAs,19824
17
- proxilion/audit/compliance/soc2.py,sha256=DVK6z8rIcWy_7BZstI-oDl_2d9eadNhBki9mOFYdx7E,18216
14
+ proxilion/audit/compliance/base.py,sha256=vF_yz9RaDB_k770_Sn7CGPKl7wqXSOhCaDqiZdoveVI,14654
15
+ proxilion/audit/compliance/eu_ai_act.py,sha256=EujjIZbJw-ngNzqXv69voLCM1RTnAuf2lEXljbxSJc0,23047
16
+ proxilion/audit/compliance/iso27001.py,sha256=AV3-yAbGiWlmUanaUg9HjuFZaTathAGYI9BAy_mIPjs,19858
17
+ proxilion/audit/compliance/soc2.py,sha256=M_lAHrvF0R1lozt1r5mZogC6r10BkDkJDEDGJentQM0,18881
18
18
  proxilion/audit/exporters/__init__.py,sha256=InGXMfiKtHTqsOP9nxnJx43bcdC3oER74nF5bQ9qkkw,1523
19
19
  proxilion/audit/exporters/aws_s3.py,sha256=ThIDI9P2VwnCDFFISFtYU-97MOJVO35aleejL0XgdGw,20381
20
20
  proxilion/audit/exporters/azure_storage.py,sha256=R_j4dGFIyPL-NmoBFXSO-3IrN01ZE60rO7SBu-l6Fpc,19396
@@ -22,17 +22,17 @@ proxilion/audit/exporters/cloud_base.py,sha256=WDtars1wwexRd3l8mtt11IsX5dfXJE_Av
22
22
  proxilion/audit/exporters/gcp_storage.py,sha256=hODFAVPgJdGLcg7_IBrqaAM62nksB5ojOkeNL-_8AQA,19195
23
23
  proxilion/audit/exporters/multi_exporter.py,sha256=nBLyqmrqNHmm00yRtOhmmz1oc9UcY6HGhOFbB1-ha9I,16134
24
24
  proxilion/caching/__init__.py,sha256=0h6Czbxt_IQjh35m9ZhbpbckS7F4Xfxub4DEMrcuEhU,1203
25
- proxilion/caching/tool_cache.py,sha256=Xb5B5iDUfwSeMiKB6MitB4BmXC-em04nkPyFYCSWqWU,17984
25
+ proxilion/caching/tool_cache.py,sha256=QYQH8ZLVDxiKK6pnhqRZet6JE7C-QM3uxKgn4kJttrg,18385
26
26
  proxilion/context/__init__.py,sha256=B8-Uo93P2HuXJojeblkxMM7s-5bIZOScWkhLq3iSIxk,1947
27
- proxilion/context/context_window.py,sha256=DFxaaTw-tMoUV2N8YEdSO-10zF165Gz07wx31dfpd4Y,16631
27
+ proxilion/context/context_window.py,sha256=ewSubup8e2afxOrm3sGpx4yBREoCWdukTicuO6Q3pp0,17727
28
28
  proxilion/context/message_history.py,sha256=FAWAT9J4Emx9SqsPDXTv9I5KFhGqhnfB-Z3OaplvKKA,15786
29
29
  proxilion/context/session.py,sha256=KiWURjFEY5DLi_dAW-iZzyE_kRCSMv_5aI2unQ_-d8Y,23044
30
30
  proxilion/contrib/__init__.py,sha256=heLZfZ_Oxp_qlFmzTB-P1KdW8Dc7QWQZ6WS0-sy7JIc,1464
31
- proxilion/contrib/anthropic.py,sha256=ZhboQje0kqxieGCCKqNOFI9shWkW53gE7rw1G6Ohce0,18685
31
+ proxilion/contrib/anthropic.py,sha256=17xq5X1CZsS849Ho56POLECgF_Dcio06gnQhBqZDxIc,18685
32
32
  proxilion/contrib/google.py,sha256=xFnRM0kZLX29PEyiaumvo7jNxK7mwAGpVBP5omrujSE,32729
33
33
  proxilion/contrib/langchain.py,sha256=8c__3FR-eTPtY40eKWn-ykNBS5CNIl6Vqlds0HV2OrU,20710
34
- proxilion/contrib/mcp.py,sha256=pfjwu_0ZTRRl324BtVSfQmdEgcuefdrbUV0SLeTofxg,27825
35
- proxilion/contrib/openai.py,sha256=RGk9upYhB1uYrgJtenvwCwCxQcNSuO_tZO9lftBjXos,21359
34
+ proxilion/contrib/mcp.py,sha256=aRBvlHaZW8U-p_eKROtpV-pEzhhyVFSSdd44yXbseW4,27894
35
+ proxilion/contrib/openai.py,sha256=LBfvLHcY8P8qk2w2POllcpxvyJxqd-tzCakmFu5igZo,21359
36
36
  proxilion/engines/__init__.py,sha256=_dasC_CYnL5K-JPIxj_fufu5tvERwD5y9Ptt7PBcTUg,8257
37
37
  proxilion/engines/base.py,sha256=ko1r_zFhKKwzTHb076Pr9FKfkIOLP-cgyjUYFHeMVg8,8246
38
38
  proxilion/engines/casbin_engine.py,sha256=GZ4DiAJveKbDfmssqDoHqmGTe-A_B76LYHCP-Y4iEYA,12534
@@ -40,16 +40,16 @@ proxilion/engines/opa_engine.py,sha256=GoPcor-3CcjljSH2Xlvz9tOggs6b4V1SnDdO0MUJ2
40
40
  proxilion/engines/simple.py,sha256=dv_vZN5bLNdAeLJTQdpxG77oX9-5cde0GzEQd20NDrs,14167
41
41
  proxilion/guards/__init__.py,sha256=QgIjrzNRGtRtjO82JhbYiW2BX8yZMr1y0RElcmAb18A,1407
42
42
  proxilion/guards/input_guard.py,sha256=wR1LrczGZH4cXFy-WHCbBCG91BFlLOLAs0nNQmiSM7k,17911
43
- proxilion/guards/output_guard.py,sha256=D8ZItSroDcxSW-Y7xjsAuxU8bFCsSBS-CxIRzPMGSYw,20566
44
- proxilion/observability/__init__.py,sha256=SS2JWidto_GfeQis7YwXcIaO3ORF1QAmBBifA8oS4Jw,5165
43
+ proxilion/guards/output_guard.py,sha256=u25ERiym9m5M-l3uuY5sGYjgEyem_RnQw_3P8lu3fD4,20576
44
+ proxilion/observability/__init__.py,sha256=sG8fMhbG3IFcaDynOmng-uHC5yjyFASouyORWxUHBYY,5213
45
45
  proxilion/observability/cost_tracker.py,sha256=xTpFUsOpOrX9cktMxYLceLIOLTJ9KavonBu9ki2YxMY,28511
46
46
  proxilion/observability/hooks.py,sha256=Sy95ZgfifXCBZYewlpmZoBirDGvQHlubbZ2I9jSZPEs,21851
47
- proxilion/observability/metrics.py,sha256=gJ5-pU8z08PYfNVMlugJiyBIOtbH6Et-Ct_7n3cSn_c,25236
48
- proxilion/observability/session_cost_tracker.py,sha256=BVwOnegjGoVQ8GytWq_Dk2sINiuSdgyxenKFbcGVq6E,36047
47
+ proxilion/observability/metrics.py,sha256=slN9dnV3ArBbdCLqWzfrYYYmzyhk5Tot5f6uMWZOLhM,25443
48
+ proxilion/observability/session_cost_tracker.py,sha256=-ljaBZ_8YVEKNyDKk9_HDFOPg7Pg15FCylawgHMKmZY,36085
49
49
  proxilion/policies/__init__.py,sha256=m0Mi57lCPHSBEdwbSx4ZnY-HV4TtzscC09x5-uJ1YGc,1669
50
50
  proxilion/policies/base.py,sha256=bVIWMMR_46MCvVLjlTp4P99NKqVYWPVUNtmrHvY2tFc,9971
51
- proxilion/policies/builtin.py,sha256=eqkKAWecuV9V59D7YHiOW0tfnc5Nld9aJbVbxQjtRdE,15482
52
- proxilion/policies/registry.py,sha256=SfPdrkqMdiDx5c6WIHZwO3lcQjLgmnECxeSyCA9KqmM,12032
51
+ proxilion/policies/builtin.py,sha256=NcFzw-pTnbZUBr3Jqao7AyIjcdeZZsvVRd7vA1dKWQA,15548
52
+ proxilion/policies/registry.py,sha256=h3KZ0MSiLTWZTSpnSGWNtgtEFQW_MuhYjBkL6V2mCtg,12274
53
53
  proxilion/providers/__init__.py,sha256=ZaJOedfgtS19Kl30CtWp0w56hiECXVv9utr1-eH0uVI,5685
54
54
  proxilion/providers/adapter.py,sha256=YMuJEV9BlDmdGzJ716QKCZdsVButu1dFZATbjSODDSI,13358
55
55
  proxilion/providers/anthropic_adapter.py,sha256=8z_JSqEUZe-F0Kg_REvff-pbUzOzW9ngWxmlp09d7bw,10211
@@ -62,17 +62,17 @@ proxilion/resilience/retry.py,sha256=ks7OGwErtmMy7BqHJrJ-2hBDyCHulBgxe3gldzh78rs
62
62
  proxilion/scheduling/__init__.py,sha256=ajTi0PrZB14WmYjr7iJ8OujZx11A5yqoecpzUA2nj1I,1548
63
63
  proxilion/scheduling/priority_queue.py,sha256=0XxEdWcuIfcMwnpl8Mk5U-jJ_JNkcSWZ39PP8FmPhBQ,13146
64
64
  proxilion/scheduling/scheduler.py,sha256=WyJxb9nHukKq7bfp3TNenS0r0hQhLO5hWrj4gtrY9Bw,14239
65
- proxilion/security/__init__.py,sha256=GPpnkYeCp_QEH7kPOOby-ufkuWL6no0tSUIXO2fkrYo,6522
66
- proxilion/security/agent_trust.py,sha256=PeIk8BEhlRRX3fYZomnk5z4aVFBPZPFU5wjET_sbdTk,32263
67
- proxilion/security/behavioral_drift.py,sha256=euC_rjhFIQhPPPeotVJMPQsonvBG7CywZYVXzr4SUno,26001
65
+ proxilion/security/__init__.py,sha256=geZmb8jiyF1F9NQiU37p-2p4063QEDwNDxa5kY_hAio,6864
66
+ proxilion/security/agent_trust.py,sha256=z229ewKFIuf8F2pVj4FSwKVBoQmW6xwyj6VLKxT4Ts4,32866
67
+ proxilion/security/behavioral_drift.py,sha256=eq979vIFW9IFuBL-Uajn1sLzhVfAl7LQ4Pcwz73Wa5o,26178
68
68
  proxilion/security/cascade_protection.py,sha256=sYhPNFZB2_NfdEPoopvyTECY1KZJVd6O7zjbnEOupOc,29343
69
69
  proxilion/security/circuit_breaker.py,sha256=3BN3XihMt5erpIiI_byRuaLqKzQQAvoEcEh-GdS3ci0,14604
70
70
  proxilion/security/cost_limiter.py,sha256=_qih591q9kfZ21CTwDP0dUIJaPX94lvPZmi9Zw_0PUY,21733
71
- proxilion/security/idor_protection.py,sha256=2cl2ud73Z_UU--bwcx9WpZvO_emZs70H2-2MXsxN7gA,14671
72
- proxilion/security/intent_capsule.py,sha256=xcFQIbZZxKuhrhiW5WR5kD-Bv-DunFkcGo49ZGo6UH8,27900
73
- proxilion/security/intent_validator.py,sha256=AZO8zb5TyHibrJiTUSYPv9p7UevqS0l65OcslTbchwk,17298
74
- proxilion/security/memory_integrity.py,sha256=BDvG08of0WmbVKZWasBn9x-bON88Q5hmk7dDEXpmK5o,25634
75
- proxilion/security/rate_limiter.py,sha256=Aj74Xf-aXCo2hihpfYIOYwafn8Wx0UNS6zriBLbdQZw,15716
71
+ proxilion/security/idor_protection.py,sha256=z_C02SH4UrybU5eEuBmZrKLE5f8GJM1M2WSFyBSFHlg,15269
72
+ proxilion/security/intent_capsule.py,sha256=4YsqXM16M9IagTr5PtTRoPyuFTkNFQdiQwYfeXbXrNA,27940
73
+ proxilion/security/intent_validator.py,sha256=0VoJZyQCV2iJRraqzkfao3lXxGVKKHTw2QEVOJfM4GQ,20389
74
+ proxilion/security/memory_integrity.py,sha256=o7zqM2nxURQ55_eT2_SC4gKL41jY0XtuwZ0RFKBqoEU,25723
75
+ proxilion/security/rate_limiter.py,sha256=vijK4kldjsf5JsJS0K4Dq6KmOIBpTfXyqdDQNVCgipc,18841
76
76
  proxilion/security/scope_enforcer.py,sha256=_B2Q4tOPxKMi20uGHlx2pw8ul_WhO9uPl8ZE3LmbOzM,22210
77
77
  proxilion/security/sequence_validator.py,sha256=bQztsvPEdWy4JhHb1TQ5Ih9PurtwbFJUW0cBS_57aao,20964
78
78
  proxilion/security/trust_boundaries.py,sha256=TiTekRbP-hBlpqiq5uk5hYJiJl-EyolpSDZOB8FvqJM,26635
@@ -81,14 +81,14 @@ proxilion/streaming/detector.py,sha256=2xXWhRByT_Y3HYZ0Bgn6NwC8NG855qu_w3vji_di_
81
81
  proxilion/streaming/transformer.py,sha256=Ld74W_LJQKJi9UvjccIhiWAe_k3yTtQc8tT_u303Bd8,19500
82
82
  proxilion/timeouts/__init__.py,sha256=i3fUpv1b0M7OodoeNqnR_Ahsg-TBSnW7q9Qd8WlffFI,1540
83
83
  proxilion/timeouts/decorators.py,sha256=BdNgO9Bn8r2DZiEcTb-mAt4vDL-FL5MVD7XsH11XPHk,14675
84
- proxilion/timeouts/manager.py,sha256=d_EiBA4zFxrN99VG1O7h0LnBSTz2RZUXChN94zXEzvs,16397
84
+ proxilion/timeouts/manager.py,sha256=8gPUj0oP5fZpAD_NRGgd80kEpoWn_potFopbt00LuDc,16495
85
85
  proxilion/tools/__init__.py,sha256=APidtQOGT2atMYoG3HOhghplmNss-9cXbjn9Eb1k5OQ,1821
86
86
  proxilion/tools/decorators.py,sha256=l5993mqwGhfSMV6tCf-rO6MjEp5oKMxSKwWtHrh7els,15305
87
87
  proxilion/tools/registry.py,sha256=dMwXsUBJW0QPQaTmfr_Fp1zmJ_8Iyrh6vQpB5xmIW90,21169
88
88
  proxilion/validation/__init__.py,sha256=4BxLcD_2KXC0u01F3khyHb-w-HWvToCRniENcVn1Kwc,2690
89
89
  proxilion/validation/pydantic_schema.py,sha256=6sIN1vDibRG1_vHT08JPXRMw4IQRCeLJLi6yoFf8RI8,10979
90
90
  proxilion/validation/schema.py,sha256=FKusctu0V7b39dqwLamjOAgCpZ6vlD3hcDiYqLy0pfA,21262
91
- proxilion-0.0.2.dist-info/METADATA,sha256=2LozwHqSExYcgmsaxU6YMomW4e_VZtTxLMdgJDgvtJ8,25257
92
- proxilion-0.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
93
- proxilion-0.0.2.dist-info/licenses/LICENSE,sha256=rOqlmNwJr6G1jB5CEn-snGBeHT6sktVQHtBYOqoEj1o,1066
94
- proxilion-0.0.2.dist-info/RECORD,,
91
+ proxilion-0.0.3.dist-info/METADATA,sha256=oE8acHJpgrLHrVJPb-s47-KdVwF7gKkTmh_DhUKQG_A,25226
92
+ proxilion-0.0.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
93
+ proxilion-0.0.3.dist-info/licenses/LICENSE,sha256=rOqlmNwJr6G1jB5CEn-snGBeHT6sktVQHtBYOqoEj1o,1066
94
+ proxilion-0.0.3.dist-info/RECORD,,