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.
- fable_compressor.py +356 -0
- fable_engine/__init__.py +1 -0
- fable_engine/actions/__init__.py +291 -0
- fable_engine/actions/cas.py +182 -0
- fable_engine/actions/deliberation.py +523 -0
- fable_engine/actions/fleet.py +807 -0
- fable_engine/actions/lifecycle.py +298 -0
- fable_engine/actions/scrapers.py +116 -0
- fable_engine/actions/system3.py +815 -0
- fable_engine/browser.py +824 -0
- fable_engine/cas.py +974 -0
- fable_engine/fable_session.json +510 -0
- fable_engine/guards.py +283 -0
- fable_engine/schema.py +714 -0
- fable_engine/scrapers/__init__.py +32 -0
- fable_engine/scrapers/arxiv.py +115 -0
- fable_engine/scrapers/base.py +386 -0
- fable_engine/scrapers/github.py +129 -0
- fable_engine/scrapers/reddit.py +154 -0
- fable_engine/scrapers/web.py +120 -0
- fable_engine/scrapers/x.py +125 -0
- fable_engine/scrapers/youtube.py +132 -0
- fable_engine/server.py +414 -0
- fable_engine/session.py +1819 -0
- fable_engine/test_server.py +1362 -0
- fable_engine/updater.py +541 -0
- fable_engine-1.3.1.dist-info/LICENSE +22 -0
- fable_engine-1.3.1.dist-info/METADATA +173 -0
- fable_engine-1.3.1.dist-info/RECORD +104 -0
- fable_engine-1.3.1.dist-info/WHEEL +5 -0
- fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
- fable_engine-1.3.1.dist-info/top_level.txt +6 -0
- fable_mode/__init__.py +3 -0
- fable_mode/__main__.py +4 -0
- fable_mode/adapters.py +1014 -0
- fable_mode/installer.py +553 -0
- fable_mode/launcher.py +437 -0
- fable_mode/manifest.py +142 -0
- fable_mode/resources.json +114 -0
- fable_mode/safety.py +103 -0
- fable_mode_entry.py +10 -0
- fable_v2/__init__.py +146 -0
- fable_v2/adapters.py +151 -0
- fable_v2/coder_fleet/__init__.py +100 -0
- fable_v2/coder_fleet/ast_tools.py +158 -0
- fable_v2/coder_fleet/compute.py +199 -0
- fable_v2/coder_fleet/design_engine.py +1316 -0
- fable_v2/coder_fleet/diagnostics.py +293 -0
- fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
- fable_v2/coder_fleet/mock_auditor.py +306 -0
- fable_v2/coder_fleet/mutation.py +216 -0
- fable_v2/coder_fleet/property_oracle.py +260 -0
- fable_v2/coder_fleet/receipt_attestor.py +122 -0
- fable_v2/coder_fleet/red_team_swarm.py +908 -0
- fable_v2/coder_fleet/test_harness.py +198 -0
- fable_v2/coder_fleet/vector_engine.py +1287 -0
- fable_v2/coder_fleet/visual.py +357 -0
- fable_v2/coder_fleet/workspace.py +153 -0
- fable_v2/cortical/__init__.py +20 -0
- fable_v2/cortical/plasticity_engine.py +992 -0
- fable_v2/execution_broker.py +811 -0
- fable_v2/proof_engine.py +1141 -0
- fable_v2/protocol.py +485 -0
- fable_v2/runtime.py +1010 -0
- fable_v2/system3/__init__.py +204 -0
- fable_v2/system3/causal.py +558 -0
- fable_v2/system3/dialectical.py +577 -0
- fable_v2/system3/evolution.py +503 -0
- fable_v2/system3/executive.py +338 -0
- fable_v2/system3/free_energy.py +479 -0
- fable_v2/system3/hyperbolic.py +555 -0
- fable_v2/system3/induction.py +336 -0
- fable_v2/system3/kripke.py +548 -0
- fable_v2/system3/oracle.py +745 -0
- fable_v2/verifiers.py +72 -0
- tests/__init__.py +1 -0
- tests/test_anti_loop_circuit_breaker.py +64 -0
- tests/test_auto_updater.py +407 -0
- tests/test_coder_fleet.py +535 -0
- tests/test_delegation_compiler.py +54 -0
- tests/test_descriptor_boundaries.py +126 -0
- tests/test_design_engine.py +603 -0
- tests/test_epistemic_evidence_validator.py +66 -0
- tests/test_execution_broker.py +233 -0
- tests/test_fable_v2.py +406 -0
- tests/test_fleet_transitions.py +116 -0
- tests/test_fsm_redteam_evolution.py +406 -0
- tests/test_goal_rubric_and_pipeline.py +367 -0
- tests/test_hebbian_plasticity.py +585 -0
- tests/test_packaging_runtime.py +194 -0
- tests/test_proof_engine.py +259 -0
- tests/test_red_team_swarm.py +645 -0
- tests/test_redteam_remediation.py +169 -0
- tests/test_registration_transaction.py +375 -0
- tests/test_requested_regressions.py +467 -0
- tests/test_scrapers.py +370 -0
- tests/test_server_actions.py +93 -0
- tests/test_server_frontier_actions.py +269 -0
- tests/test_server_protocol.py +88 -0
- tests/test_stealth_browser.py +970 -0
- tests/test_system3.py +381 -0
- tests/test_system3_deep_integration.py +385 -0
- tests/test_system3_frontier.py +436 -0
- tests/test_vector_engine.py +608 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""CAS storage, payload compression, slice viewing, and accumulation action handlers."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger("fable-engine.actions.cas")
|
|
13
|
+
|
|
14
|
+
from fable_engine.cas import (
|
|
15
|
+
CAS_ENGINE,
|
|
16
|
+
AdaptiveChunkAccumulator,
|
|
17
|
+
CompositeFrame,
|
|
18
|
+
CASSliceViewer,
|
|
19
|
+
DATA_DIR,
|
|
20
|
+
MAX_CAS_OBJECT_BYTES,
|
|
21
|
+
MAX_SLICE_RESPONSE_BYTES,
|
|
22
|
+
MAX_RPC_RESPONSE_BYTES,
|
|
23
|
+
)
|
|
24
|
+
from fable_engine.session import FableSession
|
|
25
|
+
|
|
26
|
+
def _handle_compress_payload(arguments: Dict[str, Any]) -> str:
|
|
27
|
+
action = arguments.get("action", "").strip().lower()
|
|
28
|
+
session_name = arguments.get("session_name", "").strip()
|
|
29
|
+
session: Optional[FableSession] = None
|
|
30
|
+
content = arguments.get("content")
|
|
31
|
+
if content is None:
|
|
32
|
+
content = arguments.get("payload")
|
|
33
|
+
if content is None:
|
|
34
|
+
return "Error: 'content' (or 'payload') is required for action 'compress_payload'."
|
|
35
|
+
label = arguments.get("label", "payload")
|
|
36
|
+
content_text = str(content)
|
|
37
|
+
if len(content_text.encode("utf-8")) > MAX_CAS_OBJECT_BYTES:
|
|
38
|
+
return "Error: payload exceeds maximum CAS object size."
|
|
39
|
+
|
|
40
|
+
compressed_node = CAS_ENGINE.compress_payload_to_cas(content_text, label=label)
|
|
41
|
+
raw_len = len(content_text)
|
|
42
|
+
raw_tokens = CAS_ENGINE.estimate_token_count(content_text)
|
|
43
|
+
comp_repr = json.dumps(compressed_node, separators=(",", ":"))
|
|
44
|
+
comp_tokens = CAS_ENGINE.estimate_token_count(comp_repr)
|
|
45
|
+
ratio = CAS_ENGINE.calculate_token_ratio(content_text, comp_repr)
|
|
46
|
+
|
|
47
|
+
invariant_met = ratio <= 0.003 if raw_len >= 10000 else True
|
|
48
|
+
badge = "â
PASS (<= 0.003 tokens/char)" if invariant_met else f"â ī¸ Ratio: {ratio:.6f} tokens/char"
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
f"### đī¸ Fable CAS Payload Compressed\n\n"
|
|
52
|
+
f"- **CAS URI**: `{compressed_node['cas_ref']}`\n"
|
|
53
|
+
f"- **Line Count**: `{compressed_node['lines']}`\n"
|
|
54
|
+
f"- **Raw Size**: `{raw_len}` characters (~`{raw_tokens}` tokens)\n"
|
|
55
|
+
f"- **Compressed Reference Size**: `{len(comp_repr)}` characters (~`{comp_tokens}` tokens)\n"
|
|
56
|
+
f"- **Token Compression Ratio**: `{ratio:.6f}` tokens/char\n"
|
|
57
|
+
f"- **Invariant Status**: {badge}\n"
|
|
58
|
+
f"- **JSON Descriptor**:\n```json\n{json.dumps(compressed_node, indent=2)}\n```\n\n"
|
|
59
|
+
f"> [!TIP]\n"
|
|
60
|
+
f"> Use action `view_slice` with `cas_ref` to inspect specific line windows without loading full payload."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _handle_decompress_payload(arguments: Dict[str, Any]) -> str:
|
|
65
|
+
action = arguments.get("action", "").strip().lower()
|
|
66
|
+
session_name = arguments.get("session_name", "").strip()
|
|
67
|
+
session: Optional[FableSession] = None
|
|
68
|
+
cas_ref = arguments.get("cas_ref") or arguments.get("ref_or_hash")
|
|
69
|
+
if not cas_ref:
|
|
70
|
+
return "Error: 'cas_ref' is required for action 'decompress_payload'."
|
|
71
|
+
try:
|
|
72
|
+
text = CAS_ENGINE.cas_store.get_text(cas_ref, verify=True)
|
|
73
|
+
if len(text.encode("utf-8")) > MAX_RPC_RESPONSE_BYTES // 2:
|
|
74
|
+
return "Error: decompressed response exceeds maximum size; use view_slice."
|
|
75
|
+
lines = CAS_ENGINE.slice_viewer.get_line_count(cas_ref)
|
|
76
|
+
return (
|
|
77
|
+
f"### đĻ Fable CAS Payload Retrieved\n\n"
|
|
78
|
+
f"- **CAS URI**: `{cas_ref}`\n"
|
|
79
|
+
f"- **Total Length**: `{len(text)}` characters\n"
|
|
80
|
+
f"- **Total Lines**: `{lines}`\n\n"
|
|
81
|
+
f"```text\n{text}\n```"
|
|
82
|
+
)
|
|
83
|
+
except Exception as e:
|
|
84
|
+
return f"Error decompressing CAS payload: {e}"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _handle_view_slice(arguments: Dict[str, Any]) -> str:
|
|
88
|
+
action = arguments.get("action", "").strip().lower()
|
|
89
|
+
session_name = arguments.get("session_name", "").strip()
|
|
90
|
+
session: Optional[FableSession] = None
|
|
91
|
+
cas_ref = arguments.get("cas_ref") or arguments.get("ref_or_hash")
|
|
92
|
+
if not cas_ref:
|
|
93
|
+
return "Error: 'cas_ref' is required for action 'view_slice'."
|
|
94
|
+
start_line = int(arguments.get("start_line", 1))
|
|
95
|
+
end_line = int(arguments.get("end_line", 100))
|
|
96
|
+
include_line_numbers = bool(arguments.get("include_line_numbers", False))
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
slice_text = CAS_ENGINE.slice_viewer.view_slice(
|
|
100
|
+
cas_ref, start_line, end_line, include_line_numbers=include_line_numbers
|
|
101
|
+
)
|
|
102
|
+
total_lines = CAS_ENGINE.slice_viewer.get_line_count(cas_ref)
|
|
103
|
+
return (
|
|
104
|
+
f"### đ Fable CAS Slice View (`{start_line}` - `{end_line}` of `{total_lines}` lines)\n\n"
|
|
105
|
+
f"- **CAS URI**: `{cas_ref}`\n"
|
|
106
|
+
f"- **Range**: Lines {start_line}..{end_line}\n\n"
|
|
107
|
+
f"```text\n{slice_text}\n```"
|
|
108
|
+
)
|
|
109
|
+
except Exception as e:
|
|
110
|
+
return f"Error reading CAS slice: {e}"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _handle_accumulate_payload(arguments: Dict[str, Any]) -> str:
|
|
114
|
+
action = arguments.get("action", "").strip().lower()
|
|
115
|
+
session_name = arguments.get("session_name", "").strip()
|
|
116
|
+
session: Optional[FableSession] = None
|
|
117
|
+
payload = arguments.get("payload")
|
|
118
|
+
if payload is None:
|
|
119
|
+
payload = arguments.get("content")
|
|
120
|
+
if payload is None:
|
|
121
|
+
return "Error: 'payload' is required for action 'accumulate_payload'."
|
|
122
|
+
metadata = arguments.get("metadata")
|
|
123
|
+
if isinstance(metadata, str):
|
|
124
|
+
try:
|
|
125
|
+
metadata = json.loads(metadata)
|
|
126
|
+
except Exception:
|
|
127
|
+
metadata = {"raw": metadata}
|
|
128
|
+
force_flush = bool(arguments.get("force_flush", False))
|
|
129
|
+
|
|
130
|
+
flushed = CAS_ENGINE.accumulator.add(str(payload), metadata=metadata, force_flush=force_flush)
|
|
131
|
+
stats = CAS_ENGINE.accumulator.get_stats()
|
|
132
|
+
|
|
133
|
+
flushed_str = "\n".join([f"- Flushed Composite Frame: `{u}`" for u in flushed]) if flushed else "- No frame flushed yet (buffering micro-payload)."
|
|
134
|
+
return (
|
|
135
|
+
f"### đĨ Micro-Payload Ingested\n\n"
|
|
136
|
+
f"- **Buffered Items**: `{stats['currently_buffered_items']}`\n"
|
|
137
|
+
f"- **Buffered Chars**: `{stats['currently_buffered_chars']}` / `{CAS_ENGINE.accumulator.min_frame_size}` bytes threshold\n"
|
|
138
|
+
f"- **Total Ingested**: `{stats['total_payloads_ingested']}`\n"
|
|
139
|
+
f"- **Total Frames Flushed**: `{stats['total_frames_flushed']}`\n\n"
|
|
140
|
+
f"{flushed_str}"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _handle_flush_accumulator(arguments: Dict[str, Any]) -> str:
|
|
145
|
+
action = arguments.get("action", "").strip().lower()
|
|
146
|
+
session_name = arguments.get("session_name", "").strip()
|
|
147
|
+
session: Optional[FableSession] = None
|
|
148
|
+
flushed = CAS_ENGINE.accumulator.flush()
|
|
149
|
+
stats = CAS_ENGINE.accumulator.get_stats()
|
|
150
|
+
if flushed:
|
|
151
|
+
flushed_str = "\n".join([f"- Flushed Frame: `{u}`" for u in flushed])
|
|
152
|
+
return (
|
|
153
|
+
f"### đ Micro-Payload Accumulator Flushed\n\n"
|
|
154
|
+
f"- **Flushed Frames**: `{len(flushed)}`\n"
|
|
155
|
+
f"- **Total CAS Bytes Written**: `{stats['total_cas_bytes_written']}`\n\n"
|
|
156
|
+
f"{flushed_str}"
|
|
157
|
+
)
|
|
158
|
+
return (
|
|
159
|
+
f"### âšī¸ Micro-Payload Accumulator Buffer Empty\n\n"
|
|
160
|
+
f"- **Currently Buffered**: `0` items\n"
|
|
161
|
+
f"- **Total Frames Flushed**: `{stats['total_frames_flushed']}`"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _handle_get_compression_stats(arguments: Dict[str, Any]) -> str:
|
|
166
|
+
action = arguments.get("action", "").strip().lower()
|
|
167
|
+
session_name = arguments.get("session_name", "").strip()
|
|
168
|
+
session: Optional[FableSession] = None
|
|
169
|
+
stats = CAS_ENGINE.accumulator.get_stats()
|
|
170
|
+
return (
|
|
171
|
+
f"### đ Fable Token Compression Subsystem Telemetry\n\n"
|
|
172
|
+
f"- **CAS Storage Root**: `{CAS_ENGINE.cas_store.root_dir}`\n"
|
|
173
|
+
f"- **Memory Cache Capacity**: `{CAS_ENGINE.cas_store.cache.capacity}` entries (Current: `{len(CAS_ENGINE.cas_store.cache)}`)\n"
|
|
174
|
+
f"- **Micro-Payloads Ingested**: `{stats['total_payloads_ingested']}`\n"
|
|
175
|
+
f"- **Composite Frames Flushed**: `{stats['total_frames_flushed']}`\n"
|
|
176
|
+
f"- **Total Raw Characters**: `{stats['total_raw_chars']}`\n"
|
|
177
|
+
f"- **Total CAS Bytes Written**: `{stats['total_cas_bytes_written']}`\n"
|
|
178
|
+
f"- **Currently Buffered Items**: `{stats['currently_buffered_items']}` (`{stats['currently_buffered_chars']}` chars)\n"
|
|
179
|
+
f"- **Token Compression Invariant**: `<= 0.003 tokens/character`"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|