simplicio-prompt 0.1.0

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.
@@ -0,0 +1,1109 @@
1
+ """Reference Tuple-Space + Yool kernel.
2
+
3
+ The kernel keeps the repository intentionally dependency-free while showing the
4
+ production shape expected by the spec:
5
+
6
+ - Linda-style tuple-space primitives: out_tuple, in_tuple, rd_tuple.
7
+ - Capability-addressed yools with Hilbert-like tuple map positions.
8
+ - Hookwall capability checks.
9
+ - Hierarchical batch_spawn for 1,000,000+ virtual subagents without a flat list.
10
+ - compress_token/pruning for inactive materialized agents.
11
+ - Lane worker fan-out controlled by environment-driven runtime policy.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import hashlib
17
+ import json
18
+ import os
19
+ import random
20
+ import threading
21
+ import time
22
+ import weakref
23
+ from collections import OrderedDict, defaultdict
24
+ from concurrent.futures import Future, ThreadPoolExecutor, as_completed
25
+ from dataclasses import dataclass, field
26
+ from typing import Any, Callable, DefaultDict, Dict, Iterable, List, Optional, Tuple
27
+
28
+
29
+ DEFAULT_LANE_CONCURRENCY = 32
30
+ DEFAULT_MAX_LANE_CONCURRENCY = 64
31
+ DEFAULT_CPU_QUOTA_PCT = 95
32
+ DEFAULT_QUEUE_MAXSIZE = 8192
33
+ DEFAULT_COMPRESSION_THRESHOLD = 1024
34
+ DEFAULT_CACHE_MAX_ENTRIES = 16384
35
+ DEFAULT_CACHE_TTL_S = 3600
36
+ DEFAULT_API_MAX_RETRIES = 3
37
+ DEFAULT_API_BACKOFF_BASE_MS = 100
38
+ DEFAULT_API_BACKOFF_MAX_MS = 5000
39
+ DEFAULT_CIRCUIT_FAILURE_THRESHOLD = 5
40
+ DEFAULT_CIRCUIT_COOLDOWN_S = 30
41
+ DEFAULT_BATCH_SMALL_TASK_SIZE = 32
42
+ DEFAULT_CONTEXT_COMPRESSION_CHARS = 6000
43
+
44
+
45
+ def _positive_int_from_env(names: Iterable[str], default: int) -> int:
46
+ for name in names:
47
+ value = os.getenv(name)
48
+ if value is None or not value.strip():
49
+ continue
50
+ try:
51
+ parsed = int(value)
52
+ except ValueError:
53
+ return default
54
+ return parsed if parsed > 0 else default
55
+ return default
56
+
57
+
58
+ def _positive_float_from_env(names: Iterable[str], default: float) -> float:
59
+ for name in names:
60
+ value = os.getenv(name)
61
+ if value is None or not value.strip():
62
+ continue
63
+ try:
64
+ parsed = float(value)
65
+ except ValueError:
66
+ return default
67
+ return parsed if parsed > 0 else default
68
+ return default
69
+
70
+
71
+ @dataclass(frozen=True)
72
+ class RuntimePolicy:
73
+ """Host-aware runtime policy, with env aliases for adoption in agents/IDEs."""
74
+
75
+ lane_concurrency: int = DEFAULT_LANE_CONCURRENCY
76
+ max_lane_concurrency: int = DEFAULT_MAX_LANE_CONCURRENCY
77
+ cpu_quota_pct: int = DEFAULT_CPU_QUOTA_PCT
78
+ queue_maxsize: int = DEFAULT_QUEUE_MAXSIZE
79
+ compression_threshold: int = DEFAULT_COMPRESSION_THRESHOLD
80
+ cache_max_entries: int = DEFAULT_CACHE_MAX_ENTRIES
81
+ cache_ttl_s: float = DEFAULT_CACHE_TTL_S
82
+ api_max_retries: int = DEFAULT_API_MAX_RETRIES
83
+ api_backoff_base_ms: int = DEFAULT_API_BACKOFF_BASE_MS
84
+ api_backoff_max_ms: int = DEFAULT_API_BACKOFF_MAX_MS
85
+ circuit_failure_threshold: int = DEFAULT_CIRCUIT_FAILURE_THRESHOLD
86
+ circuit_cooldown_s: float = DEFAULT_CIRCUIT_COOLDOWN_S
87
+ batch_small_task_size: int = DEFAULT_BATCH_SMALL_TASK_SIZE
88
+ context_compression_chars: int = DEFAULT_CONTEXT_COMPRESSION_CHARS
89
+
90
+ @classmethod
91
+ def from_env(cls) -> "RuntimePolicy":
92
+ requested = _positive_int_from_env(
93
+ ("YOOL_TUPLE_LANE_CONCURRENCY", "YOOL_LANE_CONCURRENCY"),
94
+ DEFAULT_LANE_CONCURRENCY,
95
+ )
96
+ max_lane = _positive_int_from_env(
97
+ ("YOOL_TUPLE_MAX_LANE_CONCURRENCY", "YOOL_MAX_LANE_CONCURRENCY"),
98
+ DEFAULT_MAX_LANE_CONCURRENCY,
99
+ )
100
+ cpu_quota = _positive_int_from_env(
101
+ ("YOOL_TUPLE_CPU_QUOTA_PCT", "YOOL_CPU_QUOTA_PCT"),
102
+ DEFAULT_CPU_QUOTA_PCT,
103
+ )
104
+ queue_size = _positive_int_from_env(
105
+ ("YOOL_TUPLE_QUEUE_MAXSIZE", "YOOL_QUEUE_MAXSIZE"),
106
+ DEFAULT_QUEUE_MAXSIZE,
107
+ )
108
+ compression = _positive_int_from_env(
109
+ ("YOOL_TUPLE_COMPRESSION_THRESHOLD", "YOOL_COMPRESSION_THRESHOLD"),
110
+ DEFAULT_COMPRESSION_THRESHOLD,
111
+ )
112
+ cache_max_entries = _positive_int_from_env(
113
+ ("YOOL_TUPLE_CACHE_MAX_ENTRIES", "YOOL_CACHE_MAX_ENTRIES"),
114
+ DEFAULT_CACHE_MAX_ENTRIES,
115
+ )
116
+ cache_ttl = _positive_float_from_env(
117
+ ("YOOL_TUPLE_CACHE_TTL_S", "YOOL_CACHE_TTL_S"),
118
+ DEFAULT_CACHE_TTL_S,
119
+ )
120
+ api_max_retries = _positive_int_from_env(
121
+ ("YOOL_TUPLE_API_MAX_RETRIES", "YOOL_API_MAX_RETRIES"),
122
+ DEFAULT_API_MAX_RETRIES,
123
+ )
124
+ backoff_base = _positive_int_from_env(
125
+ ("YOOL_TUPLE_API_BACKOFF_BASE_MS", "YOOL_API_BACKOFF_BASE_MS"),
126
+ DEFAULT_API_BACKOFF_BASE_MS,
127
+ )
128
+ backoff_max = _positive_int_from_env(
129
+ ("YOOL_TUPLE_API_BACKOFF_MAX_MS", "YOOL_API_BACKOFF_MAX_MS"),
130
+ DEFAULT_API_BACKOFF_MAX_MS,
131
+ )
132
+ circuit_threshold = _positive_int_from_env(
133
+ ("YOOL_TUPLE_CIRCUIT_FAILURE_THRESHOLD", "YOOL_CIRCUIT_FAILURE_THRESHOLD"),
134
+ DEFAULT_CIRCUIT_FAILURE_THRESHOLD,
135
+ )
136
+ circuit_cooldown = _positive_float_from_env(
137
+ ("YOOL_TUPLE_CIRCUIT_COOLDOWN_S", "YOOL_CIRCUIT_COOLDOWN_S"),
138
+ DEFAULT_CIRCUIT_COOLDOWN_S,
139
+ )
140
+ batch_size = _positive_int_from_env(
141
+ ("YOOL_TUPLE_BATCH_SMALL_TASK_SIZE", "YOOL_BATCH_SMALL_TASK_SIZE"),
142
+ DEFAULT_BATCH_SMALL_TASK_SIZE,
143
+ )
144
+ context_chars = _positive_int_from_env(
145
+ ("YOOL_TUPLE_CONTEXT_COMPRESSION_CHARS", "YOOL_CONTEXT_COMPRESSION_CHARS"),
146
+ DEFAULT_CONTEXT_COMPRESSION_CHARS,
147
+ )
148
+ return cls(
149
+ lane_concurrency=requested,
150
+ max_lane_concurrency=max(1, max_lane),
151
+ cpu_quota_pct=max(1, min(100, cpu_quota)),
152
+ queue_maxsize=max(1, queue_size),
153
+ compression_threshold=max(1, compression),
154
+ cache_max_entries=max(1, cache_max_entries),
155
+ cache_ttl_s=max(0.001, cache_ttl),
156
+ api_max_retries=max(0, api_max_retries),
157
+ api_backoff_base_ms=max(1, backoff_base),
158
+ api_backoff_max_ms=max(1, backoff_max),
159
+ circuit_failure_threshold=max(1, circuit_threshold),
160
+ circuit_cooldown_s=max(0.001, circuit_cooldown),
161
+ batch_small_task_size=max(1, batch_size),
162
+ context_compression_chars=max(64, context_chars),
163
+ )
164
+
165
+ def concurrency_for(
166
+ self,
167
+ queued_roots: int,
168
+ *,
169
+ ewma_latency_ms: float | None = None,
170
+ error_rate: float = 0.0,
171
+ ) -> int:
172
+ requested = self.lane_concurrency
173
+ if requested <= 0:
174
+ requested = min(max(1, queued_roots), max(1, os.cpu_count() or 1))
175
+ ceiling = max(1, min(self.max_lane_concurrency, queued_roots or 1))
176
+ concurrency = max(1, min(requested, ceiling))
177
+ if queued_roots > requested * 4:
178
+ concurrency = min(ceiling, max(concurrency, requested * 2))
179
+ if ewma_latency_ms is not None and ewma_latency_ms > 250:
180
+ concurrency = min(ceiling, max(concurrency, concurrency * 2))
181
+ if error_rate >= 0.2:
182
+ concurrency = max(1, concurrency // 2)
183
+ return max(1, concurrency)
184
+
185
+
186
+ class HilbertIndex:
187
+ """Simplified Hilbert-style index: tuple multi-dim -> stable hashable path."""
188
+
189
+ @staticmethod
190
+ def compute(keys: Tuple[Any, ...]) -> Tuple[Any, ...]:
191
+ return keys
192
+
193
+
194
+ class YoolTuple:
195
+ """Tuple envelope: yool + map + authority + lane + source pointers + receipts."""
196
+
197
+ def __init__(
198
+ self,
199
+ yool: str,
200
+ map_index: Tuple[Any, ...],
201
+ authority: str,
202
+ lane: str,
203
+ source: str,
204
+ data: Optional[Dict[str, Any]] = None,
205
+ *,
206
+ parent_id: int | None = None,
207
+ agent_id: int | None = None,
208
+ ) -> None:
209
+ self.id = agent_id
210
+ self.yool = yool
211
+ self.map = map_index
212
+ self.authority = authority
213
+ self.lane = lane
214
+ self.source = source
215
+ self.parent_id = parent_id
216
+ self.receipts: List[str] = []
217
+ self.data = data or {}
218
+ self.last_active = time.monotonic()
219
+
220
+ def touch(self) -> None:
221
+ self.last_active = time.monotonic()
222
+
223
+ def to_dict(self) -> Dict[str, Any]:
224
+ return {
225
+ "id": self.id,
226
+ "yool": self.yool,
227
+ "map": list(self.map),
228
+ "authority": self.authority,
229
+ "lane": self.lane,
230
+ "source": self.source,
231
+ "parent_id": self.parent_id,
232
+ "receipts": list(self.receipts),
233
+ "data": dict(self.data),
234
+ }
235
+
236
+
237
+ @dataclass
238
+ class CompressToken:
239
+ """Compact inactive agent state; enough to inspect or lazily restore later."""
240
+
241
+ agent_id: int
242
+ yool: str
243
+ map_index: Tuple[Any, ...]
244
+ authority: str
245
+ lane: str
246
+ source: str
247
+ parent_id: int | None
248
+ receipts: List[str] = field(default_factory=list)
249
+ data_digest: str = ""
250
+ compressed_at: float = field(default_factory=time.monotonic)
251
+
252
+
253
+ @dataclass(frozen=True)
254
+ class BatchSpawnReceipt:
255
+ root_agent_id: int
256
+ depth: int
257
+ branching: int
258
+ virtual_agents: int
259
+ compression_threshold: int
260
+ receipt_id: str
261
+
262
+
263
+ class CircuitOpenError(RuntimeError):
264
+ """Raised when a provider is cooling down after repeated transient failures."""
265
+
266
+
267
+ Executor = Callable[[YoolTuple], Any]
268
+ BatchExecutor = Callable[[List[YoolTuple]], Any]
269
+
270
+
271
+ def _stable_digest(value: Any) -> str:
272
+ raw = json.dumps(value, sort_keys=True, separators=(",", ":"), default=repr)
273
+ return hashlib.blake2b(raw.encode("utf-8"), digest_size=16).hexdigest()
274
+
275
+
276
+ @dataclass
277
+ class CacheEntry:
278
+ value: Any
279
+ created_at: float = field(default_factory=time.monotonic)
280
+ hits: int = 0
281
+
282
+
283
+ class ReceiptCache:
284
+ """Small LRU+TTL cache keyed by tuple receipt and deterministic input hashes."""
285
+
286
+ def __init__(self, *, max_entries: int, ttl_s: float) -> None:
287
+ self.max_entries = max(1, max_entries)
288
+ self.ttl_s = max(0.001, ttl_s)
289
+ self._items: OrderedDict[str, CacheEntry] = OrderedDict()
290
+ self._lock = threading.RLock()
291
+
292
+ def get(self, keys: Iterable[str]) -> tuple[bool, Any, str | None]:
293
+ now = time.monotonic()
294
+ with self._lock:
295
+ for key in keys:
296
+ item = self._items.get(key)
297
+ if item is None:
298
+ continue
299
+ if now - item.created_at > self.ttl_s:
300
+ self._items.pop(key, None)
301
+ continue
302
+ item.hits += 1
303
+ self._items.move_to_end(key)
304
+ return True, item.value, key
305
+ return False, None, None
306
+
307
+ def set(self, keys: Iterable[str], value: Any) -> None:
308
+ now = time.monotonic()
309
+ with self._lock:
310
+ for key in keys:
311
+ self._items[key] = CacheEntry(value=value, created_at=now)
312
+ self._items.move_to_end(key)
313
+ while len(self._items) > self.max_entries:
314
+ self._items.popitem(last=False)
315
+
316
+ def snapshot(self) -> Dict[str, Any]:
317
+ with self._lock:
318
+ return {
319
+ "entries": len(self._items),
320
+ "max_entries": self.max_entries,
321
+ "ttl_s": self.ttl_s,
322
+ "hits": sum(item.hits for item in self._items.values()),
323
+ }
324
+
325
+
326
+ @dataclass(frozen=True)
327
+ class BackoffPolicy:
328
+ max_retries: int
329
+ base_ms: int
330
+ max_ms: int
331
+ jitter_ratio: float = 0.25
332
+
333
+ @classmethod
334
+ def from_runtime(cls, policy: RuntimePolicy) -> "BackoffPolicy":
335
+ return cls(
336
+ max_retries=policy.api_max_retries,
337
+ base_ms=policy.api_backoff_base_ms,
338
+ max_ms=policy.api_backoff_max_ms,
339
+ )
340
+
341
+ def delay_s(self, attempt: int) -> float:
342
+ capped_ms = min(self.max_ms, self.base_ms * (2**attempt))
343
+ jitter = 1 + random.uniform(-self.jitter_ratio, self.jitter_ratio)
344
+ return max(0.0, capped_ms * jitter / 1000)
345
+
346
+
347
+ @dataclass
348
+ class CircuitState:
349
+ failures: int = 0
350
+ opened_until: float = 0.0
351
+ successes: int = 0
352
+
353
+
354
+ class ProviderCircuitBreaker:
355
+ """Provider-level circuit breaker to avoid hammering APIs/LLMs during faults."""
356
+
357
+ def __init__(self, *, failure_threshold: int, cooldown_s: float) -> None:
358
+ self.failure_threshold = max(1, failure_threshold)
359
+ self.cooldown_s = max(0.001, cooldown_s)
360
+ self._states: DefaultDict[str, CircuitState] = defaultdict(CircuitState)
361
+ self._lock = threading.RLock()
362
+
363
+ def before_call(self, provider: str) -> None:
364
+ with self._lock:
365
+ state = self._states[provider]
366
+ if state.opened_until > time.monotonic():
367
+ remaining = state.opened_until - time.monotonic()
368
+ raise CircuitOpenError(
369
+ f"circuit open for provider {provider!r}; retry after {remaining:.2f}s"
370
+ )
371
+
372
+ def record_success(self, provider: str) -> None:
373
+ with self._lock:
374
+ state = self._states[provider]
375
+ state.failures = 0
376
+ state.opened_until = 0.0
377
+ state.successes += 1
378
+
379
+ def record_failure(self, provider: str) -> None:
380
+ with self._lock:
381
+ state = self._states[provider]
382
+ state.failures += 1
383
+ if state.failures >= self.failure_threshold:
384
+ state.opened_until = time.monotonic() + self.cooldown_s
385
+
386
+ def snapshot(self) -> Dict[str, Any]:
387
+ with self._lock:
388
+ return {
389
+ provider: {
390
+ "failures": state.failures,
391
+ "successes": state.successes,
392
+ "open": state.opened_until > time.monotonic(),
393
+ }
394
+ for provider, state in sorted(self._states.items())
395
+ }
396
+
397
+
398
+ @dataclass
399
+ class LaneMetrics:
400
+ successes: int = 0
401
+ failures: int = 0
402
+ ewma_latency_ms: float = 0.0
403
+
404
+ def record(self, elapsed_ms: float, *, ok: bool) -> None:
405
+ if self.ewma_latency_ms <= 0:
406
+ self.ewma_latency_ms = elapsed_ms
407
+ else:
408
+ self.ewma_latency_ms = (self.ewma_latency_ms * 0.8) + (elapsed_ms * 0.2)
409
+ if ok:
410
+ self.successes += 1
411
+ else:
412
+ self.failures += 1
413
+
414
+ @property
415
+ def error_rate(self) -> float:
416
+ total = self.successes + self.failures
417
+ return 0.0 if total == 0 else self.failures / total
418
+
419
+
420
+ class ContextCompressor:
421
+ """Digest-preserving compression for large LLM prompt/context payloads."""
422
+
423
+ def __init__(self, *, threshold_chars: int) -> None:
424
+ self.threshold_chars = max(64, threshold_chars)
425
+
426
+ def compress(self, data: Dict[str, Any]) -> tuple[Dict[str, Any], bool]:
427
+ changed = False
428
+ compressed: Dict[str, Any] = {}
429
+ for key, value in data.items():
430
+ new_value, item_changed = self._compress_value(value)
431
+ compressed[key] = new_value
432
+ changed = changed or item_changed
433
+ return compressed, changed
434
+
435
+ def _compress_value(self, value: Any) -> tuple[Any, bool]:
436
+ if isinstance(value, str) and len(value) > self.threshold_chars:
437
+ head = value[: self.threshold_chars // 2]
438
+ tail = value[-self.threshold_chars // 4 :]
439
+ return (
440
+ {
441
+ "compressed": True,
442
+ "encoding": "sha256+head_tail",
443
+ "digest": hashlib.sha256(value.encode("utf-8")).hexdigest(),
444
+ "original_chars": len(value),
445
+ "preview": f"{head}\n...[compressed]...\n{tail}",
446
+ },
447
+ True,
448
+ )
449
+ if isinstance(value, list):
450
+ changed = False
451
+ out = []
452
+ for item in value:
453
+ new_item, item_changed = self._compress_value(item)
454
+ out.append(new_item)
455
+ changed = changed or item_changed
456
+ return out, changed
457
+ if isinstance(value, dict):
458
+ compressor = ContextCompressor(threshold_chars=self.threshold_chars)
459
+ out, changed = compressor.compress(value)
460
+ return out, changed
461
+ return value, False
462
+
463
+
464
+ class TupleSpace:
465
+ """Thread-safe tuple space with indexed lanes and lazy hierarchical agents."""
466
+
467
+ def __init__(self, *, policy: RuntimePolicy | None = None) -> None:
468
+ self.policy = policy or RuntimePolicy.from_env()
469
+ self.space: Dict[Tuple[Any, ...], List[YoolTuple]] = defaultdict(list)
470
+ self.lane_index: DefaultDict[str, List[YoolTuple]] = defaultdict(list)
471
+ self.agents: weakref.WeakValueDictionary[int, YoolTuple] = (
472
+ weakref.WeakValueDictionary()
473
+ )
474
+ self.walls: DefaultDict[str, List[str]] = defaultdict(list)
475
+ self.compressed_agents: Dict[int, CompressToken] = {}
476
+ self.receipt_cache = ReceiptCache(
477
+ max_entries=self.policy.cache_max_entries,
478
+ ttl_s=self.policy.cache_ttl_s,
479
+ )
480
+ self.circuit_breaker = ProviderCircuitBreaker(
481
+ failure_threshold=self.policy.circuit_failure_threshold,
482
+ cooldown_s=self.policy.circuit_cooldown_s,
483
+ )
484
+ self.context_compressor = ContextCompressor(
485
+ threshold_chars=self.policy.context_compression_chars
486
+ )
487
+ self.local_yools: Dict[str, Executor] = {}
488
+ self.virtual_agent_count = 0
489
+ self._next_agent_id = 0
490
+ self._lock = threading.RLock()
491
+ self._cond = threading.Condition(self._lock)
492
+
493
+ def out_tuple(self, t: YoolTuple) -> None:
494
+ with self._cond:
495
+ self.space[t.map].append(t)
496
+ self.lane_index[t.lane].append(t)
497
+ t.receipts.append(
498
+ f"out@{self._receipt_hash(t.map, t.yool, len(t.receipts))}"
499
+ )
500
+ t.touch()
501
+ self._cond.notify_all()
502
+
503
+ def in_tuple(
504
+ self,
505
+ template: Dict[str, Any],
506
+ *,
507
+ timeout_s: float | None = None,
508
+ ) -> Optional[YoolTuple]:
509
+ deadline = time.monotonic() + timeout_s if timeout_s is not None else None
510
+ with self._cond:
511
+ while True:
512
+ match = self._find_match(template)
513
+ if match is not None:
514
+ self._remove_tuple(match)
515
+ match.touch()
516
+ return match
517
+ if timeout_s is None:
518
+ return None
519
+ remaining = deadline - time.monotonic() if deadline is not None else 0
520
+ if remaining <= 0:
521
+ return None
522
+ self._cond.wait(timeout=remaining)
523
+
524
+ def rd_tuple(self, template: Dict[str, Any]) -> Optional[YoolTuple]:
525
+ with self._lock:
526
+ match = self._find_match(template)
527
+ if match is not None:
528
+ match.touch()
529
+ return match
530
+
531
+ def register_local_yool(self, yool: str, executor: Executor) -> None:
532
+ """Register deterministic local work to avoid unnecessary LLM/API calls."""
533
+ with self._lock:
534
+ self.local_yools[yool] = executor
535
+
536
+ def execute_tuple(
537
+ self,
538
+ tup: YoolTuple,
539
+ executor: Executor,
540
+ *,
541
+ provider: str | None = None,
542
+ use_cache: bool = True,
543
+ retryable: Callable[[BaseException], bool] | None = None,
544
+ sleep_fn: Callable[[float], None] = time.sleep,
545
+ ) -> Any:
546
+ """Execute one tuple through local routing, compression, cache, and guardrails."""
547
+ local_executor = self.local_yools.get(tup.yool)
548
+ if local_executor is not None:
549
+ tup.receipts.append(f"local_route@{self._receipt_hash(tup.yool, tup.map)}")
550
+ return local_executor(tup)
551
+
552
+ if self._should_compress_context(tup):
553
+ self.compress_context(tup)
554
+
555
+ cache_keys = self.cache_keys_for_tuple(tup)
556
+ if use_cache:
557
+ hit, cached, key = self.receipt_cache.get(cache_keys)
558
+ if hit:
559
+ tup.receipts.append(f"cache_hit@{key}")
560
+ return cached
561
+
562
+ provider_name = provider or str(tup.data.get("provider") or "local")
563
+
564
+ def run() -> Any:
565
+ return executor(tup)
566
+
567
+ if provider_name == "local":
568
+ result = run()
569
+ else:
570
+ result = self.call_with_backoff(
571
+ provider_name,
572
+ run,
573
+ retryable=retryable,
574
+ sleep_fn=sleep_fn,
575
+ )
576
+ if use_cache:
577
+ self.receipt_cache.set(cache_keys, result)
578
+ tup.receipts.append(
579
+ f"cache_store@{self._receipt_hash(provider_name, cache_keys)}"
580
+ )
581
+ return result
582
+
583
+ def call_with_backoff(
584
+ self,
585
+ provider: str,
586
+ fn: Callable[[], Any],
587
+ *,
588
+ retryable: Callable[[BaseException], bool] | None = None,
589
+ sleep_fn: Callable[[float], None] = time.sleep,
590
+ ) -> Any:
591
+ """Call APIs/LLMs with jittered exponential backoff and provider breaker."""
592
+ policy = BackoffPolicy.from_runtime(self.policy)
593
+ retryable = retryable or self._default_retryable
594
+ attempt = 0
595
+ while True:
596
+ self.circuit_breaker.before_call(provider)
597
+ try:
598
+ result = fn()
599
+ except BaseException as exc:
600
+ self.circuit_breaker.record_failure(provider)
601
+ if attempt >= policy.max_retries or not retryable(exc):
602
+ raise
603
+ sleep_fn(policy.delay_s(attempt))
604
+ attempt += 1
605
+ continue
606
+ self.circuit_breaker.record_success(provider)
607
+ return result
608
+
609
+ def compress_context(
610
+ self, tup: YoolTuple, *, threshold_chars: int | None = None
611
+ ) -> bool:
612
+ compressor = (
613
+ self.context_compressor
614
+ if threshold_chars is None
615
+ else ContextCompressor(threshold_chars=threshold_chars)
616
+ )
617
+ compressed, changed = compressor.compress(tup.data)
618
+ if changed:
619
+ tup.data = compressed
620
+ tup.receipts.append(
621
+ f"compress_context@{self._receipt_hash(tup.yool, tup.map, tup.data)}"
622
+ )
623
+ tup.touch()
624
+ return changed
625
+
626
+ def cache_keys_for_tuple(self, tup: YoolTuple) -> List[str]:
627
+ input_key = _stable_digest(
628
+ {
629
+ "yool": tup.yool,
630
+ "data": tup.data,
631
+ }
632
+ )
633
+ receipt_key = _stable_digest({"receipts": tup.receipts, "input": input_key})
634
+ return [f"input:{input_key}", f"receipt:{receipt_key}"]
635
+
636
+ def scan_index(
637
+ self,
638
+ *,
639
+ lane: str | None = None,
640
+ yool: str | None = None,
641
+ limit: int = 100,
642
+ ) -> List[YoolTuple]:
643
+ with self._lock:
644
+ candidates = (
645
+ self.lane_index.get(lane, [])
646
+ if lane
647
+ else [tup for values in self.space.values() for tup in values]
648
+ )
649
+ out: List[YoolTuple] = []
650
+ for tup in candidates:
651
+ if yool is None or tup.yool == yool:
652
+ out.append(tup)
653
+ if len(out) >= limit:
654
+ break
655
+ return out
656
+
657
+ def spawn_agent(
658
+ self, parent: YoolTuple, agent_yool: str, agent_data: Dict[str, Any]
659
+ ) -> int:
660
+ with self._lock:
661
+ agent_id = self._allocate_agent_id()
662
+ map_idx = HilbertIndex.compute((*parent.map, agent_id))
663
+ new_tuple = YoolTuple(
664
+ yool=agent_yool,
665
+ map_index=map_idx,
666
+ authority=f"subagent_{agent_id}",
667
+ lane=str(agent_data.get("lane") or parent.lane),
668
+ source=f"spawned_from_{parent.authority}",
669
+ data=agent_data,
670
+ parent_id=parent.id,
671
+ agent_id=agent_id,
672
+ )
673
+ self.agents[agent_id] = new_tuple
674
+ self.out_tuple(new_tuple)
675
+ self.prune_idle(self.policy.compression_threshold)
676
+ return agent_id
677
+
678
+ def batch_spawn(
679
+ self,
680
+ parent: YoolTuple,
681
+ agent_yool: str,
682
+ *,
683
+ depth: int,
684
+ branching: int,
685
+ compression_threshold: int | None = None,
686
+ agent_data: Dict[str, Any] | None = None,
687
+ ) -> BatchSpawnReceipt:
688
+ """Create a lazy deep hierarchy without enumerating every leaf.
689
+
690
+ Example: depth=4, branching=32 represents 1,048,576 leaf subagents while
691
+ materializing one controller tuple plus a compressed virtual subtree.
692
+ """
693
+ if depth < 1:
694
+ raise ValueError("depth must be >= 1")
695
+ if branching < 1:
696
+ raise ValueError("branching must be >= 1")
697
+ threshold = compression_threshold or self.policy.compression_threshold
698
+ virtual_agents = branching**depth
699
+ controller_id = self.spawn_agent(
700
+ parent,
701
+ agent_yool,
702
+ {
703
+ **(agent_data or {}),
704
+ "lazy_batch": True,
705
+ "depth": depth,
706
+ "branching": branching,
707
+ "virtual_agents": virtual_agents,
708
+ "compression_threshold": threshold,
709
+ },
710
+ )
711
+ with self._lock:
712
+ self.virtual_agent_count += virtual_agents
713
+ receipt_id = self._receipt_hash(
714
+ (controller_id, depth, branching), agent_yool, virtual_agents
715
+ )
716
+ controller = self.agents.get(controller_id)
717
+ if controller is not None:
718
+ controller.receipts.append(f"batch_spawn@{receipt_id}")
719
+ if len(self.agents) > threshold:
720
+ self.compress_token(controller_id)
721
+ return BatchSpawnReceipt(
722
+ root_agent_id=controller_id,
723
+ depth=depth,
724
+ branching=branching,
725
+ virtual_agents=virtual_agents,
726
+ compression_threshold=threshold,
727
+ receipt_id=receipt_id,
728
+ )
729
+
730
+ def compress_token(self, agent_id: int) -> CompressToken | None:
731
+ with self._lock:
732
+ tup = self.agents.get(agent_id)
733
+ if tup is None:
734
+ return self.compressed_agents.get(agent_id)
735
+ digest = hashlib.sha256(
736
+ repr(sorted(tup.data.items())).encode("utf-8")
737
+ ).hexdigest()
738
+ token = CompressToken(
739
+ agent_id=agent_id,
740
+ yool=tup.yool,
741
+ map_index=tup.map,
742
+ authority=tup.authority,
743
+ lane=tup.lane,
744
+ source=tup.source,
745
+ parent_id=tup.parent_id,
746
+ receipts=list(tup.receipts),
747
+ data_digest=digest,
748
+ )
749
+ self._remove_tuple(tup)
750
+ self.compressed_agents[agent_id] = token
751
+ self.agents.pop(agent_id, None)
752
+ return token
753
+
754
+ def prune_idle(self, max_active: int | None = None) -> int:
755
+ max_active = max_active or self.policy.compression_threshold
756
+ with self._lock:
757
+ active = [
758
+ (agent_id, tup.last_active) for agent_id, tup in self.agents.items()
759
+ ]
760
+ if len(active) <= max_active:
761
+ return 0
762
+ active.sort(key=lambda item: item[1])
763
+ to_compress = len(active) - max_active
764
+ for agent_id, _ in active[:to_compress]:
765
+ self.compress_token(agent_id)
766
+ return to_compress
767
+
768
+ def route_packet(self, packet: Dict[str, Any], target_lane: str) -> bool:
769
+ target = self.rd_tuple({"lane": target_lane})
770
+ if target is None:
771
+ return False
772
+ target.data.update(packet)
773
+ target.receipts.append(
774
+ f"route@{self._receipt_hash(target.map, target_lane, len(packet))}"
775
+ )
776
+ target.touch()
777
+ return True
778
+
779
+ def hookwall(self, wall_id: str, capability: str, action: str = "hook") -> bool:
780
+ with self._lock:
781
+ if action == "hook":
782
+ if capability not in self.walls[wall_id]:
783
+ self.walls[wall_id].append(capability)
784
+ return True
785
+ if action == "check":
786
+ return capability in self.walls.get(wall_id, [])
787
+ if action == "unhook":
788
+ if capability in self.walls.get(wall_id, []):
789
+ self.walls[wall_id].remove(capability)
790
+ return True
791
+ return False
792
+
793
+ def snapshot(self) -> Dict[str, Any]:
794
+ with self._lock:
795
+ return {
796
+ "tuples": sum(len(items) for items in self.space.values()),
797
+ "lanes": {
798
+ lane: len(items) for lane, items in sorted(self.lane_index.items())
799
+ },
800
+ "active_agents": len(self.agents),
801
+ "compressed_agents": len(self.compressed_agents),
802
+ "virtual_agents": self.virtual_agent_count,
803
+ "total_agents": len(self.agents)
804
+ + len(self.compressed_agents)
805
+ + self.virtual_agent_count,
806
+ "policy": {
807
+ "lane_concurrency": self.policy.lane_concurrency,
808
+ "max_lane_concurrency": self.policy.max_lane_concurrency,
809
+ "cpu_quota_pct": self.policy.cpu_quota_pct,
810
+ "queue_maxsize": self.policy.queue_maxsize,
811
+ "compression_threshold": self.policy.compression_threshold,
812
+ "cache_max_entries": self.policy.cache_max_entries,
813
+ "cache_ttl_s": self.policy.cache_ttl_s,
814
+ "api_max_retries": self.policy.api_max_retries,
815
+ "api_backoff_base_ms": self.policy.api_backoff_base_ms,
816
+ "api_backoff_max_ms": self.policy.api_backoff_max_ms,
817
+ "circuit_failure_threshold": self.policy.circuit_failure_threshold,
818
+ "circuit_cooldown_s": self.policy.circuit_cooldown_s,
819
+ "batch_small_task_size": self.policy.batch_small_task_size,
820
+ "context_compression_chars": self.policy.context_compression_chars,
821
+ },
822
+ "cache": self.receipt_cache.snapshot(),
823
+ "circuit_breakers": self.circuit_breaker.snapshot(),
824
+ }
825
+
826
+ def _allocate_agent_id(self) -> int:
827
+ agent_id = self._next_agent_id
828
+ self._next_agent_id += 1
829
+ return agent_id
830
+
831
+ def _find_match(self, template: Dict[str, Any]) -> YoolTuple | None:
832
+ if "lane" in template:
833
+ candidates = list(self.lane_index.get(str(template["lane"]), []))
834
+ else:
835
+ candidates = [
836
+ tup for tuples_list in self.space.values() for tup in tuples_list
837
+ ]
838
+ for tup in candidates:
839
+ if self._matches(tup, template):
840
+ return tup
841
+ return None
842
+
843
+ def _matches(self, t: YoolTuple, template: Dict[str, Any]) -> bool:
844
+ for key, expected in template.items():
845
+ if hasattr(t, key):
846
+ value = getattr(t, key)
847
+ else:
848
+ value = t.data.get(key)
849
+ if value != expected:
850
+ return False
851
+ return True
852
+
853
+ def _remove_tuple(self, t: YoolTuple) -> None:
854
+ tuples_list = self.space.get(t.map)
855
+ if tuples_list:
856
+ self.space[t.map] = [item for item in tuples_list if item is not t]
857
+ if not self.space[t.map]:
858
+ del self.space[t.map]
859
+ lane_items = self.lane_index.get(t.lane)
860
+ if lane_items:
861
+ self.lane_index[t.lane] = [item for item in lane_items if item is not t]
862
+ if not self.lane_index[t.lane]:
863
+ del self.lane_index[t.lane]
864
+
865
+ @staticmethod
866
+ def _receipt_hash(*parts: Any) -> str:
867
+ raw = repr(parts).encode("utf-8")
868
+ return hashlib.blake2b(raw, digest_size=8).hexdigest()
869
+
870
+ @staticmethod
871
+ def _default_retryable(exc: BaseException) -> bool:
872
+ return isinstance(exc, (TimeoutError, ConnectionError))
873
+
874
+ @staticmethod
875
+ def _should_compress_context(tup: YoolTuple) -> bool:
876
+ if tup.data.get("compress_context") is False:
877
+ return False
878
+ if tup.data.get("compress_context") is True:
879
+ return True
880
+ return bool(tup.data.get("provider") or tup.data.get("llm_context"))
881
+
882
+
883
+ class LaneWorkerPool:
884
+ """Bounded per-lane worker fan-out for tuple execution."""
885
+
886
+ def __init__(
887
+ self,
888
+ space: TupleSpace,
889
+ *,
890
+ policy: RuntimePolicy | None = None,
891
+ lane_concurrency: Dict[str, int] | None = None,
892
+ ) -> None:
893
+ self.space = space
894
+ self.policy = policy or space.policy
895
+ self.lane_concurrency = dict(lane_concurrency or {})
896
+ self.lane_metrics: DefaultDict[str, LaneMetrics] = defaultdict(LaneMetrics)
897
+
898
+ def concurrency_for(self, lane: str) -> int:
899
+ queued = len(self.space.scan_index(lane=lane, limit=self.policy.queue_maxsize))
900
+ configured = self.lane_concurrency.get(lane)
901
+ metrics = self.lane_metrics[lane]
902
+ if configured is not None:
903
+ baseline = RuntimePolicy(
904
+ lane_concurrency=configured,
905
+ max_lane_concurrency=self.policy.max_lane_concurrency,
906
+ )
907
+ return baseline.concurrency_for(
908
+ queued,
909
+ ewma_latency_ms=metrics.ewma_latency_ms or None,
910
+ error_rate=metrics.error_rate,
911
+ )
912
+ return self.policy.concurrency_for(
913
+ queued,
914
+ ewma_latency_ms=metrics.ewma_latency_ms or None,
915
+ error_rate=metrics.error_rate,
916
+ )
917
+
918
+ def run_lane(
919
+ self,
920
+ lane: str,
921
+ executor: Executor,
922
+ *,
923
+ provider: str | None = None,
924
+ use_cache: bool = True,
925
+ retryable: Callable[[BaseException], bool] | None = None,
926
+ sleep_fn: Callable[[float], None] = time.sleep,
927
+ speculative_executor: Executor | None = None,
928
+ ) -> List[Any]:
929
+ tuples = self.space.scan_index(lane=lane, limit=self.policy.queue_maxsize)
930
+ if not tuples:
931
+ return []
932
+ concurrency = self.concurrency_for(lane)
933
+ semaphore = threading.Semaphore(concurrency)
934
+ results: List[Any] = []
935
+ with ThreadPoolExecutor(max_workers=concurrency) as pool:
936
+ futures: List[Future[Any]] = [
937
+ pool.submit(
938
+ self._execute_one,
939
+ lane,
940
+ executor,
941
+ semaphore,
942
+ provider,
943
+ use_cache,
944
+ retryable,
945
+ sleep_fn,
946
+ speculative_executor,
947
+ )
948
+ for _ in tuples
949
+ ]
950
+ for future in as_completed(futures):
951
+ results.append(future.result())
952
+ return results
953
+
954
+ def run_lane_batched(
955
+ self,
956
+ lane: str,
957
+ batch_executor: BatchExecutor,
958
+ *,
959
+ batch_size: int | None = None,
960
+ ) -> List[Any]:
961
+ """Drain small lane tasks in batches to reduce scheduler/API overhead."""
962
+ concurrency_hint = self.concurrency_for(lane)
963
+ tuples = self._drain_lane(lane)
964
+ if not tuples:
965
+ return []
966
+ size = max(1, batch_size or self.policy.batch_small_task_size)
967
+ batches = [
968
+ tuples[index : index + size] for index in range(0, len(tuples), size)
969
+ ]
970
+ concurrency = min(concurrency_hint, len(batches))
971
+ results: List[Any] = []
972
+ with ThreadPoolExecutor(max_workers=max(1, concurrency)) as pool:
973
+ futures = [
974
+ pool.submit(self._execute_batch, lane, batch, batch_executor)
975
+ for batch in batches
976
+ ]
977
+ for future in as_completed(futures):
978
+ item = future.result()
979
+ if isinstance(item, list):
980
+ results.extend(item)
981
+ else:
982
+ results.append(item)
983
+ return results
984
+
985
+ def _execute_one(
986
+ self,
987
+ lane: str,
988
+ executor: Executor,
989
+ semaphore: threading.Semaphore,
990
+ provider: str | None,
991
+ use_cache: bool,
992
+ retryable: Callable[[BaseException], bool] | None,
993
+ sleep_fn: Callable[[float], None],
994
+ speculative_executor: Executor | None,
995
+ ) -> Any:
996
+ with semaphore:
997
+ tup = self.space.in_tuple({"lane": lane})
998
+ if tup is None:
999
+ return None
1000
+ return self._execute_tuple(
1001
+ lane,
1002
+ tup,
1003
+ executor,
1004
+ provider=provider,
1005
+ use_cache=use_cache,
1006
+ retryable=retryable,
1007
+ sleep_fn=sleep_fn,
1008
+ speculative_executor=speculative_executor,
1009
+ )
1010
+
1011
+ def _execute_tuple(
1012
+ self,
1013
+ lane: str,
1014
+ tup: YoolTuple,
1015
+ executor: Executor,
1016
+ *,
1017
+ provider: str | None,
1018
+ use_cache: bool,
1019
+ retryable: Callable[[BaseException], bool] | None,
1020
+ sleep_fn: Callable[[float], None],
1021
+ speculative_executor: Executor | None,
1022
+ ) -> Any:
1023
+ start = time.perf_counter()
1024
+ ok = False
1025
+ try:
1026
+ if speculative_executor is not None and tup.data.get("idempotent") is True:
1027
+ result = self._speculative_execute(tup, executor, speculative_executor)
1028
+ else:
1029
+ result = self.space.execute_tuple(
1030
+ tup,
1031
+ executor,
1032
+ provider=provider,
1033
+ use_cache=use_cache,
1034
+ retryable=retryable,
1035
+ sleep_fn=sleep_fn,
1036
+ )
1037
+ ok = True
1038
+ return result
1039
+ finally:
1040
+ elapsed_ms = (time.perf_counter() - start) * 1000
1041
+ self.lane_metrics[lane].record(elapsed_ms, ok=ok)
1042
+
1043
+ def _speculative_execute(
1044
+ self, tup: YoolTuple, primary: Executor, speculative: Executor
1045
+ ) -> Any:
1046
+ errors: List[BaseException] = []
1047
+ with ThreadPoolExecutor(max_workers=2) as pool:
1048
+ futures = [
1049
+ pool.submit(primary, tup),
1050
+ pool.submit(speculative, tup),
1051
+ ]
1052
+ for future in as_completed(futures):
1053
+ try:
1054
+ result = future.result()
1055
+ except BaseException as exc:
1056
+ errors.append(exc)
1057
+ continue
1058
+ for pending in futures:
1059
+ if pending is not future:
1060
+ pending.cancel()
1061
+ tup.receipts.append(
1062
+ f"speculative_win@{self.space._receipt_hash(tup.yool, tup.map)}"
1063
+ )
1064
+ return result
1065
+ raise errors[0]
1066
+
1067
+ def _drain_lane(self, lane: str) -> List[YoolTuple]:
1068
+ tuples = self.space.scan_index(lane=lane, limit=self.policy.queue_maxsize)
1069
+ drained: List[YoolTuple] = []
1070
+ for _ in tuples:
1071
+ tup = self.space.in_tuple({"lane": lane})
1072
+ if tup is not None:
1073
+ drained.append(tup)
1074
+ return drained
1075
+
1076
+ def _execute_batch(
1077
+ self, lane: str, batch: List[YoolTuple], batch_executor: BatchExecutor
1078
+ ) -> Any:
1079
+ start = time.perf_counter()
1080
+ ok = False
1081
+ try:
1082
+ receipt = self.space._receipt_hash(
1083
+ lane, [tup.map for tup in batch], len(batch)
1084
+ )
1085
+ for tup in batch:
1086
+ tup.receipts.append(f"batch@{receipt}")
1087
+ result = batch_executor(batch)
1088
+ ok = True
1089
+ return result
1090
+ finally:
1091
+ elapsed_ms = (time.perf_counter() - start) * 1000
1092
+ self.lane_metrics[lane].record(elapsed_ms, ok=ok)
1093
+
1094
+
1095
+ def build_default_space() -> tuple[TupleSpace, YoolTuple]:
1096
+ ts = TupleSpace()
1097
+ root = YoolTuple("kernel_root", HilbertIndex.compute((0,)), "root", "main", "user")
1098
+ ts.out_tuple(root)
1099
+ return ts, root
1100
+
1101
+
1102
+ if __name__ == "__main__":
1103
+ ts, root = build_default_space()
1104
+ ts.spawn_agent(root, "hamt_builder", {"status": "ready"})
1105
+ ts.batch_spawn(
1106
+ root, "codex_worker", depth=4, branching=32, compression_threshold=128
1107
+ )
1108
+ ts.hookwall("main_wall", "capability_root", "hook")
1109
+ print(ts.snapshot())