liquid-loop 0.6.0__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/PKG-INFO +1 -1
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/__init__.py +3 -2
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/storage.py +2 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/workspace.py +60 -1
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/PKG-INFO +1 -1
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/pyproject.toml +1 -1
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/LICENSE +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/README.md +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/__main__.py +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/cli.py +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop/entropy.py +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/SOURCES.txt +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/dependency_links.txt +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/entry_points.txt +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/requires.txt +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/liquid_loop.egg-info/top_level.txt +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/setup.cfg +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/tests/test_entropy.py +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/tests/test_self_evolve.py +0 -0
- {liquid_loop-0.6.0 → liquid_loop-0.6.1}/tests/test_workspace.py +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
"""Liquid Loop — Workspace Cognitive Runtime v0.6.
|
|
2
|
-
__version__ = "0.6.
|
|
1
|
+
"""Liquid Loop — Workspace Cognitive Runtime v0.6.1 (CPE-fused, proactive, rhythmic sampling)"""
|
|
2
|
+
__version__ = "0.6.1"
|
|
3
3
|
|
|
4
4
|
from .workspace import (
|
|
5
5
|
WorkspaceState, Anchor, Evidence, Memory, Conflict,
|
|
6
6
|
AuditChain, CPERegularizer, SelfRefineEngine,
|
|
7
|
+
rhythmic_retrieve,
|
|
7
8
|
)
|
|
8
9
|
from .storage import load, save
|
|
9
10
|
from .entropy import calculate, calculate_detail, calculate as calculate_entropy
|
|
@@ -57,6 +57,8 @@ def save(state: WorkspaceState, workspace_root: Path):
|
|
|
57
57
|
state.audit_prev_hash = state.audit_chain_hash
|
|
58
58
|
state.audit_chain_hash = audit_hash
|
|
59
59
|
data = asdict(state)
|
|
60
|
+
# overlap_cache 仅为运行时熵计算缓存,键为 tuple,不可 JSON 序列化,且不具持久价值
|
|
61
|
+
data.pop("overlap_cache", None)
|
|
60
62
|
with open(path, "w", encoding="utf-8") as f:
|
|
61
63
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
62
64
|
|
|
@@ -658,7 +658,8 @@ def _keyword_overlap(a: str, b: str, cache: dict | None = None) -> float:
|
|
|
658
658
|
return 0.0
|
|
659
659
|
if cache is not None:
|
|
660
660
|
import hashlib
|
|
661
|
-
|
|
661
|
+
h1, h2 = hashlib.md5(a.encode()).hexdigest()[:8], hashlib.md5(b.encode()).hexdigest()[:8]
|
|
662
|
+
key = f"{min(h1,h2)}:{max(h1,h2)}" # str key,JSON 兼容
|
|
662
663
|
if key in cache:
|
|
663
664
|
return cache[key]
|
|
664
665
|
import re
|
|
@@ -896,3 +897,61 @@ def meta_thinker_advice(anchor: Anchor, state: WorkspaceState, new_evidence: str
|
|
|
896
897
|
return {"action": "ADD", "reason": f"弱相关(overlap={best_score:.2f}),添加但标记为low value"}
|
|
897
898
|
else:
|
|
898
899
|
return {"action": "SKIP", "reason": "与当前锚点无关联"}
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
# ==============================================================================
|
|
903
|
+
# 节律采样检索(Rhythmic Sampling Retrieve)
|
|
904
|
+
# 启发来源:Biba et al. 2026, Nature Human Behaviour — 7Hz theta 脉冲记忆编码
|
|
905
|
+
# 思路:记忆检索不是"取 top-N",而是分窗口脉冲采样,每组取最优,跨组去重
|
|
906
|
+
# ==============================================================================
|
|
907
|
+
|
|
908
|
+
def rhythmic_retrieve(
|
|
909
|
+
state: WorkspaceState,
|
|
910
|
+
query: str,
|
|
911
|
+
window_size: int = 7,
|
|
912
|
+
top_per_window: int = 1,
|
|
913
|
+
total_slots: int = 5,
|
|
914
|
+
) -> list[str]:
|
|
915
|
+
"""节律采样检索:分窗口脉冲采样,每组取最优,跨组去重。
|
|
916
|
+
|
|
917
|
+
- window_size: 每个"脉冲窗口"的候选数量(默认 7,呼应 7Hz theta 节律)
|
|
918
|
+
- top_per_window: 每个窗口保留的条数
|
|
919
|
+
- total_slots: 最终返回的总条数
|
|
920
|
+
|
|
921
|
+
比直接 top-N 的优势:避免同质记忆堆叠,增加多样性
|
|
922
|
+
"""
|
|
923
|
+
if not query:
|
|
924
|
+
return []
|
|
925
|
+
|
|
926
|
+
# 候选集:证据 + 锚点描述
|
|
927
|
+
candidates: list[str] = []
|
|
928
|
+
for e in state.evidences:
|
|
929
|
+
if e.content:
|
|
930
|
+
candidates.append(e.content)
|
|
931
|
+
for a in state.anchors:
|
|
932
|
+
if a.description:
|
|
933
|
+
candidates.append(a.description)
|
|
934
|
+
if a.name:
|
|
935
|
+
candidates.append(a.name)
|
|
936
|
+
|
|
937
|
+
if not candidates:
|
|
938
|
+
return []
|
|
939
|
+
|
|
940
|
+
# 计算 overlap 并排序
|
|
941
|
+
scored = [(_keyword_overlap(query, c, state.overlap_cache), c) for c in candidates]
|
|
942
|
+
scored.sort(key=lambda x: x[0], reverse=True)
|
|
943
|
+
|
|
944
|
+
# 节律窗口采样:每 window_size 个为一组脉冲,每组取 top_per_window
|
|
945
|
+
result = []
|
|
946
|
+
seen = set()
|
|
947
|
+
for i in range(0, len(scored), window_size):
|
|
948
|
+
window = scored[i : i + window_size]
|
|
949
|
+
# 每组内按 overlap 降序取 top_per_window
|
|
950
|
+
for _, content in window[:top_per_window]:
|
|
951
|
+
if content not in seen and len(result) < total_slots:
|
|
952
|
+
seen.add(content)
|
|
953
|
+
result.append(content)
|
|
954
|
+
if len(result) >= total_slots:
|
|
955
|
+
break
|
|
956
|
+
|
|
957
|
+
return result[:total_slots]
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "liquid-loop"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.1"
|
|
8
8
|
description = "Self-Organizing Cognitive Memory for AI Agents — Liquid Loop theory implementation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|