fable-engine 1.3.1__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 (104) hide show
  1. fable_compressor.py +356 -0
  2. fable_engine/__init__.py +1 -0
  3. fable_engine/actions/__init__.py +291 -0
  4. fable_engine/actions/cas.py +182 -0
  5. fable_engine/actions/deliberation.py +523 -0
  6. fable_engine/actions/fleet.py +807 -0
  7. fable_engine/actions/lifecycle.py +298 -0
  8. fable_engine/actions/scrapers.py +116 -0
  9. fable_engine/actions/system3.py +815 -0
  10. fable_engine/browser.py +824 -0
  11. fable_engine/cas.py +974 -0
  12. fable_engine/fable_session.json +510 -0
  13. fable_engine/guards.py +283 -0
  14. fable_engine/schema.py +714 -0
  15. fable_engine/scrapers/__init__.py +32 -0
  16. fable_engine/scrapers/arxiv.py +115 -0
  17. fable_engine/scrapers/base.py +386 -0
  18. fable_engine/scrapers/github.py +129 -0
  19. fable_engine/scrapers/reddit.py +154 -0
  20. fable_engine/scrapers/web.py +120 -0
  21. fable_engine/scrapers/x.py +125 -0
  22. fable_engine/scrapers/youtube.py +132 -0
  23. fable_engine/server.py +414 -0
  24. fable_engine/session.py +1819 -0
  25. fable_engine/test_server.py +1362 -0
  26. fable_engine/updater.py +541 -0
  27. fable_engine-1.3.1.dist-info/LICENSE +22 -0
  28. fable_engine-1.3.1.dist-info/METADATA +173 -0
  29. fable_engine-1.3.1.dist-info/RECORD +104 -0
  30. fable_engine-1.3.1.dist-info/WHEEL +5 -0
  31. fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
  32. fable_engine-1.3.1.dist-info/top_level.txt +6 -0
  33. fable_mode/__init__.py +3 -0
  34. fable_mode/__main__.py +4 -0
  35. fable_mode/adapters.py +1014 -0
  36. fable_mode/installer.py +553 -0
  37. fable_mode/launcher.py +437 -0
  38. fable_mode/manifest.py +142 -0
  39. fable_mode/resources.json +114 -0
  40. fable_mode/safety.py +103 -0
  41. fable_mode_entry.py +10 -0
  42. fable_v2/__init__.py +146 -0
  43. fable_v2/adapters.py +151 -0
  44. fable_v2/coder_fleet/__init__.py +100 -0
  45. fable_v2/coder_fleet/ast_tools.py +158 -0
  46. fable_v2/coder_fleet/compute.py +199 -0
  47. fable_v2/coder_fleet/design_engine.py +1316 -0
  48. fable_v2/coder_fleet/diagnostics.py +293 -0
  49. fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
  50. fable_v2/coder_fleet/mock_auditor.py +306 -0
  51. fable_v2/coder_fleet/mutation.py +216 -0
  52. fable_v2/coder_fleet/property_oracle.py +260 -0
  53. fable_v2/coder_fleet/receipt_attestor.py +122 -0
  54. fable_v2/coder_fleet/red_team_swarm.py +908 -0
  55. fable_v2/coder_fleet/test_harness.py +198 -0
  56. fable_v2/coder_fleet/vector_engine.py +1287 -0
  57. fable_v2/coder_fleet/visual.py +357 -0
  58. fable_v2/coder_fleet/workspace.py +153 -0
  59. fable_v2/cortical/__init__.py +20 -0
  60. fable_v2/cortical/plasticity_engine.py +992 -0
  61. fable_v2/execution_broker.py +811 -0
  62. fable_v2/proof_engine.py +1141 -0
  63. fable_v2/protocol.py +485 -0
  64. fable_v2/runtime.py +1010 -0
  65. fable_v2/system3/__init__.py +204 -0
  66. fable_v2/system3/causal.py +558 -0
  67. fable_v2/system3/dialectical.py +577 -0
  68. fable_v2/system3/evolution.py +503 -0
  69. fable_v2/system3/executive.py +338 -0
  70. fable_v2/system3/free_energy.py +479 -0
  71. fable_v2/system3/hyperbolic.py +555 -0
  72. fable_v2/system3/induction.py +336 -0
  73. fable_v2/system3/kripke.py +548 -0
  74. fable_v2/system3/oracle.py +745 -0
  75. fable_v2/verifiers.py +72 -0
  76. tests/__init__.py +1 -0
  77. tests/test_anti_loop_circuit_breaker.py +64 -0
  78. tests/test_auto_updater.py +407 -0
  79. tests/test_coder_fleet.py +535 -0
  80. tests/test_delegation_compiler.py +54 -0
  81. tests/test_descriptor_boundaries.py +126 -0
  82. tests/test_design_engine.py +603 -0
  83. tests/test_epistemic_evidence_validator.py +66 -0
  84. tests/test_execution_broker.py +233 -0
  85. tests/test_fable_v2.py +406 -0
  86. tests/test_fleet_transitions.py +116 -0
  87. tests/test_fsm_redteam_evolution.py +406 -0
  88. tests/test_goal_rubric_and_pipeline.py +367 -0
  89. tests/test_hebbian_plasticity.py +585 -0
  90. tests/test_packaging_runtime.py +194 -0
  91. tests/test_proof_engine.py +259 -0
  92. tests/test_red_team_swarm.py +645 -0
  93. tests/test_redteam_remediation.py +169 -0
  94. tests/test_registration_transaction.py +375 -0
  95. tests/test_requested_regressions.py +467 -0
  96. tests/test_scrapers.py +370 -0
  97. tests/test_server_actions.py +93 -0
  98. tests/test_server_frontier_actions.py +269 -0
  99. tests/test_server_protocol.py +88 -0
  100. tests/test_stealth_browser.py +970 -0
  101. tests/test_system3.py +381 -0
  102. tests/test_system3_deep_integration.py +385 -0
  103. tests/test_system3_frontier.py +436 -0
  104. tests/test_vector_engine.py +608 -0
fable_engine/guards.py ADDED
@@ -0,0 +1,283 @@
1
+ """
2
+ Frontier Uplift Guards and Micro-Engines.
3
+ Implements:
4
+ - AntiLoopCircuitBreaker: O(1) cyclical loop and oscillation detection
5
+ - EpistemicEvidenceValidator: AST/URL/command proof grounded evidence verification
6
+ - ModelVelocityProfiler: Real-time throughput profiling and model tier classification
7
+ - DelegationContractCompiler: Statically verified subagent contract compilation with System 3 scaffolds
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import json
14
+ import re
15
+ import threading
16
+ import time
17
+ from pathlib import Path
18
+ from typing import Any, Dict, List, Optional, Tuple, Union
19
+
20
+ # DeterministicProofValidator imported lazily in EpistemicEvidenceValidator
21
+
22
+
23
+ class AntiLoopCircuitBreaker:
24
+ """Detects repeated identical failed actions and cyclical oscillations in O(1)."""
25
+
26
+ def __init__(self, max_consecutive_repeats: int = 2, window_size: int = 6):
27
+ self.max_consecutive_repeats = max_consecutive_repeats
28
+ self.window_size = window_size
29
+ self.signatures: List[str] = []
30
+
31
+ def _compute_action_signature(self, tool_name: str, args: Dict[str, Any]) -> str:
32
+ canonical = json.dumps({"tool": tool_name, "args": args}, sort_keys=True)
33
+ return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
34
+
35
+ def record_and_evaluate(self, tool_name: str, args: Dict[str, Any], is_error: bool) -> Tuple[bool, str]:
36
+ sig = self._compute_action_signature(tool_name, args)
37
+ self.signatures.append(sig)
38
+ if len(self.signatures) > self.window_size:
39
+ self.signatures.pop(0)
40
+
41
+ # Check consecutive identical tool invocations in failing state
42
+ consecutive_count = 0
43
+ for s in reversed(self.signatures):
44
+ if s == sig:
45
+ consecutive_count += 1
46
+ else:
47
+ break
48
+
49
+ if consecutive_count >= self.max_consecutive_repeats and is_error:
50
+ return True, (
51
+ f"[CIRCUIT_BREAKER_TRIGGERED]: You have invoked '{tool_name}' with the same arguments "
52
+ f"{consecutive_count} times in a failing state. STOP repeating this action. "
53
+ "Execute the OODA Loop: inspect line numbers with view_file or re-verify preconditions."
54
+ )
55
+
56
+ # Check cyclical loop (A -> B -> A -> B) where A != B
57
+ if len(self.signatures) >= 4:
58
+ if (
59
+ self.signatures[-1] != self.signatures[-2]
60
+ and self.signatures[-1] == self.signatures[-3]
61
+ and self.signatures[-2] == self.signatures[-4]
62
+ ):
63
+ return True, (
64
+ "[CIRCUIT_BREAKER_TRIGGERED]: Cyclical 2-step oscillation detected (Action A <-> Action B). "
65
+ "Break the loop immediately and reconsider system invariants."
66
+ )
67
+
68
+ return False, "OK"
69
+
70
+
71
+ class EpistemicEvidenceValidator:
72
+ """Validates that [PROVEN] evidence strings map to real filesystem files, line ranges, URLs, or CLI stdout."""
73
+
74
+ CITATION_PATTERN = re.compile(r"^(.*?)(?::(?:L)?(\d+)(?:-(?:L)?(\d+))?)?$")
75
+
76
+ def __init__(self, workspace_root: Optional[Path] = None):
77
+ self.workspace_root = Path(workspace_root) if workspace_root else Path.cwd()
78
+ from fable_v2.proof_engine import DeterministicProofValidator
79
+ self._validator = DeterministicProofValidator(workspace_root=self.workspace_root)
80
+
81
+ def parse_evidence_citation(self, evidence_str: str) -> Optional[Dict[str, Any]]:
82
+ return self._validator._parse_file_citation(evidence_str)
83
+
84
+ def validate_proven_claim(self, claim: str, evidence: str) -> Tuple[bool, str]:
85
+ valid, msg, _ = self._validator.validate_proven_claim(claim, evidence)
86
+ return valid, msg
87
+
88
+
89
+ class ModelVelocityProfiler:
90
+ """
91
+ Tracks timestamps and character/token volume across incoming tool requests.
92
+ Computes rolling velocity (chars/sec, est. tokens/sec, tool call frequency).
93
+ Classifies model tier:
94
+ - flash (Fast / High Throughput): tokens_per_sec > 80 or rapid successive tool calls. Multiplier = 2.5x
95
+ - pro / heavy (Deep sequential): tokens_per_sec 20-80. Multiplier = 1.0x
96
+ - local / weak: tokens_per_sec < 20. Automatically injects micro-scaffold hints.
97
+ """
98
+
99
+ def __init__(self, window_size: int = 20, clock: Optional[Any] = None):
100
+ self.window_size = window_size
101
+ self._clock = clock or time.time
102
+ self.request_history: List[Dict[str, Any]] = []
103
+ self._lock = threading.Lock()
104
+ self.total_requests: int = 0
105
+ self.total_chars: int = 0
106
+ self.total_estimated_tokens: int = 0
107
+
108
+ def record_request(self, action: str, raw_payload: Union[str, Dict[str, Any], int], timestamp: Optional[float] = None) -> None:
109
+ """Record an incoming tool request's character/token volume and timestamp."""
110
+ ts = timestamp if timestamp is not None else self._clock()
111
+ if isinstance(raw_payload, int):
112
+ char_count = max(0, raw_payload)
113
+ elif isinstance(raw_payload, str):
114
+ char_count = len(raw_payload)
115
+ elif isinstance(raw_payload, dict):
116
+ try:
117
+ char_count = len(json.dumps(raw_payload))
118
+ except Exception:
119
+ char_count = 100
120
+ else:
121
+ char_count = 100
122
+
123
+ est_tokens = max(1, char_count // 4)
124
+ with self._lock:
125
+ self.total_requests += 1
126
+ self.total_chars += char_count
127
+ self.total_estimated_tokens += est_tokens
128
+ self.request_history.append({
129
+ "timestamp": ts,
130
+ "action": action,
131
+ "chars": char_count,
132
+ "tokens": est_tokens,
133
+ })
134
+ if len(self.request_history) > self.window_size * 2:
135
+ self.request_history = self.request_history[-self.window_size:]
136
+
137
+ def get_velocity_profile(self) -> Dict[str, Any]:
138
+ """Compute rolling velocity metrics and classify model tier."""
139
+ with self._lock:
140
+ history = list(self.request_history)
141
+ total_reqs = self.total_requests
142
+ tot_chars = self.total_chars
143
+ tot_tokens = self.total_estimated_tokens
144
+
145
+ if not history:
146
+ return {
147
+ "chars_per_sec": 0.0,
148
+ "tokens_per_sec": 0.0,
149
+ "tool_call_frequency_cpm": 0.0,
150
+ "avg_interval_seconds": 0.0,
151
+ "model_tier": "pro",
152
+ "tier_multiplier": 1.0,
153
+ "tier_description": "pro / heavy (Deep sequential reasoning tier)",
154
+ "total_requests": total_reqs,
155
+ "total_chars": tot_chars,
156
+ "total_estimated_tokens": tot_tokens,
157
+ "requires_micro_scaffolds": False,
158
+ }
159
+
160
+ if len(history) == 1:
161
+ time_span = 1.0
162
+ window_chars = history[0]["chars"]
163
+ window_tokens = history[0]["tokens"]
164
+ call_count = 1
165
+ avg_interval = 5.0
166
+ else:
167
+ recent = history[-self.window_size:]
168
+ time_span = max(0.5, recent[-1]["timestamp"] - recent[0]["timestamp"])
169
+ window_chars = sum(r["chars"] for r in recent)
170
+ window_tokens = sum(r["tokens"] for r in recent)
171
+ call_count = len(recent)
172
+ intervals = [recent[i]["timestamp"] - recent[i-1]["timestamp"] for i in range(1, len(recent))]
173
+ avg_interval = sum(intervals) / max(1, len(intervals))
174
+
175
+ chars_per_sec = round(window_chars / time_span, 2)
176
+ tokens_per_sec = round(window_tokens / time_span, 2)
177
+ cpm = round((call_count / time_span) * 60.0, 2)
178
+
179
+ if tokens_per_sec > 80.0 or (avg_interval < 2.0 and call_count >= 3) or cpm > 20.0:
180
+ tier = "flash"
181
+ multiplier = 2.5
182
+ desc = "flash (Fast / High Throughput: requires deeper parallel exploration, 5+ mockup concepts, rich coordinate modeling)"
183
+ micro_scaffolds = False
184
+ elif tokens_per_sec >= 20.0:
185
+ tier = "pro"
186
+ multiplier = 1.0
187
+ desc = "pro / heavy (Deep sequential reasoning tier)"
188
+ micro_scaffolds = False
189
+ else:
190
+ tier = "local"
191
+ multiplier = 0.5
192
+ desc = "local / weak (Resource-constrained tier: automatically injects micro-scaffold hints)"
193
+ micro_scaffolds = True
194
+
195
+ return {
196
+ "chars_per_sec": chars_per_sec,
197
+ "tokens_per_sec": tokens_per_sec,
198
+ "tool_call_frequency_cpm": cpm,
199
+ "avg_interval_seconds": round(avg_interval, 2),
200
+ "model_tier": tier,
201
+ "tier_multiplier": multiplier,
202
+ "tier_description": desc,
203
+ "total_requests": total_reqs,
204
+ "total_chars": tot_chars,
205
+ "total_estimated_tokens": tot_tokens,
206
+ "requires_micro_scaffolds": micro_scaffolds,
207
+ }
208
+
209
+
210
+ GLOBAL_VELOCITY_PROFILER = ModelVelocityProfiler()
211
+
212
+
213
+ class DelegationContractCompiler:
214
+ """Verifies that subagent delegation prompts/contracts are complete, unambiguous, and statically sound."""
215
+
216
+ REQUIRED_SECTIONS = [
217
+ "TargetFile",
218
+ "InterfaceContract",
219
+ "StrictConstraints",
220
+ "VerificationCommand"
221
+ ]
222
+
223
+ def __init__(self):
224
+ self.file_regex = re.compile(r"(TargetFile|FileBoundary):\s*[`\"]?([A-Za-z0-9_./\\:-]+)[`\"]?", re.IGNORECASE)
225
+ self.cmd_regex = re.compile(r"(VerificationCommand|TestCommand):\s*[`\"]?([^`\"\n]+)[`\"]?", re.IGNORECASE)
226
+
227
+ @staticmethod
228
+ def inject_system3_micro_scaffolds(prompt: str, parsed: Dict[str, str]) -> str:
229
+ """Inject System 3 Micro-Scaffolds into the delegation contract for weak-model frontier uplift."""
230
+ target_file = parsed.get("TargetFile", "src/target.py")
231
+ verif_cmd = parsed.get("VerificationCommand", "python -m unittest")
232
+
233
+ scaffold = f"""
234
+ ### 🛡️ SYSTEM 3 MICRO-SCAFFOLD (WEAK-MODEL FRONTIER UPLIFT)
235
+
236
+ #### 1. Kripke Safety Invariant Contract ($AG(\\text{{safe}})$):
237
+ - $AG(\\text{{NoHallucination}} \\land \\text{{TypeSoundness}})$: Never invent non-existent APIs or variables.
238
+ - $AX(\\text{{TargetFileBoundary}})$: Modify ONLY `{target_file}`. Zero modifications outside `{target_file}`.
239
+ - $AF(\\text{{VerificationPass}})$: Every execution must satisfy `{verif_cmd}` with exit code 0.
240
+
241
+ #### 2. Causal Failure Mode Boundaries ($do(\\cdot)$ Sensitivities):
242
+ - Invariant under intervention: $P(\\text{{SystemError}} \\mid do(\\text{{Edit}}({target_file}))) = 0$.
243
+ - Pre-condition validation: Inspect and verify exact file line bounds before applying replacements.
244
+ - Post-condition validation: Run `{verif_cmd}` immediately after edit to confirm 0 regressions.
245
+
246
+ #### 3. TRIZ Transcendent Resolution Guidelines:
247
+ - Avoid lazy compromises (do NOT comment out tests or catch-and-ignore exceptions).
248
+ - Apply TRIZ Principle 1 (Segmentation): Decompose complex logic into pure helper functions.
249
+ - Apply TRIZ Principle 10 (Preliminary Action): Validate all preconditions before mutating state.
250
+
251
+ #### 4. Structured Output Regex Acceptance Constraint:
252
+ - Your response MUST strictly adhere to atomic execution formatting:
253
+ Pattern: `^```(?:python|json|diff)[\\s\\S]*?```$`
254
+ """
255
+ return prompt.strip() + "\n\n" + scaffold.strip()
256
+
257
+ def compile_and_validate(self, prompt: str) -> Tuple[bool, List[str], Dict[str, str]]:
258
+ errors = []
259
+ parsed = {}
260
+
261
+ file_match = self.file_regex.search(prompt)
262
+ if not file_match:
263
+ errors.append("Missing explicit 'TargetFile' declaration. Subagents must have bounded file write targets.")
264
+ else:
265
+ parsed["TargetFile"] = file_match.group(2)
266
+
267
+ cmd_match = self.cmd_regex.search(prompt)
268
+ if not cmd_match:
269
+ errors.append("Missing explicit 'VerificationCommand'. Subagents must know what test to execute for DoD verification.")
270
+ else:
271
+ parsed["VerificationCommand"] = cmd_match.group(2).strip()
272
+
273
+ if not any(k.lower() in prompt.lower() for k in ["interfacecontract", "functionsignature", "typedefinition", "api contract", "interface"]):
274
+ errors.append("Missing 'InterfaceContract' or 'FunctionSignature'. Subagents require explicit types/signatures.")
275
+
276
+ if not any(k.lower() in prompt.lower() for k in ["strictconstraints", "invariants", "non-negotiable", "constraints"]):
277
+ errors.append("Missing 'StrictConstraints' or 'Invariants'. Subagents must be constrained against regressions.")
278
+
279
+ is_valid = len(errors) == 0
280
+ if is_valid:
281
+ parsed["system3_micro_scaffold"] = self.inject_system3_micro_scaffolds(prompt, parsed)
282
+ parsed["compiled_prompt"] = parsed["system3_micro_scaffold"]
283
+ return is_valid, errors, parsed