- 面板: 会话持久化(oc_sess.json)/余额实时/文件栏(搜索+MD+拖拽)/朗读(edge-tts)/工具过程实时显示/漫剧画布 - 面板: 经验自动检索注入+存经验按钮(experience.py) - 管线: local_motion本地运镜/IMAGE-FIRST-GUIDE/LOCAL-PIPELINE-V1 - 经验: EED-EXPER-014 面板工程+管线+飞书扒取全记录 - 资料: 飞书《清欢AIGC伪真人短剧全流程》归档
128 lines
4.0 KiB
Python
128 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""experience.py — 蛋蛋经验库自动模块
|
|
- search(text): 按关键词自动检索相关经验(解决问题前注入上下文)
|
|
- save(title, content): 自动编号保存经验 + 更新索引
|
|
- list_experiences(): 经验列表(供索引/前端展示)
|
|
"""
|
|
import os, re, glob, time
|
|
|
|
EXP_DIR = os.path.expanduser("~/cang-ying/eererdan/experience")
|
|
INDEX = os.path.join(EXP_DIR, "EED-EXPER-INDEX.hdlp")
|
|
|
|
|
|
def _next_num():
|
|
nums = []
|
|
for f in glob.glob(os.path.join(EXP_DIR, "EED-EXPER-*.hdlp")):
|
|
m = re.search(r"EED-EXPER-(\d+)", os.path.basename(f))
|
|
if m:
|
|
nums.append(int(m.group(1)))
|
|
return max(nums) + 1 if nums else 1
|
|
|
|
|
|
def _read(path, limit=2000):
|
|
try:
|
|
with open(path, encoding="utf-8") as f:
|
|
return f.read(limit)
|
|
except Exception:
|
|
return ""
|
|
|
|
|
|
def list_experiences():
|
|
"""经验列表(按编号倒序)。"""
|
|
out = []
|
|
for f in sorted(glob.glob(os.path.join(EXP_DIR, "EED-EXPER-*.hdlp")), reverse=True):
|
|
head = _read(f, 600)
|
|
title = ""
|
|
m = re.search(r"^# (.*)$", head, re.M)
|
|
if m:
|
|
title = m.group(1).strip()
|
|
summary = ""
|
|
for line in head.split("\n"):
|
|
line = line.strip()
|
|
if line and not line.startswith("#") and not line.startswith(">"):
|
|
summary = line[:120]
|
|
break
|
|
out.append({
|
|
"num": os.path.basename(f).replace("EED-EXPER-", "").replace(".hdlp", ""),
|
|
"title": title,
|
|
"summary": summary,
|
|
"file": os.path.basename(f),
|
|
})
|
|
return out
|
|
|
|
|
|
def search(text, limit_chars=1200, min_hits=2):
|
|
"""按关键词检索相关经验,返回注入文本(限长)。命中少于 min_hits 个关键词返回空。"""
|
|
text = (text or "").lower()
|
|
kws = re.findall(r"[\u4e00-\u9fa5]{2,}|[A-Za-z]{3,}", text)
|
|
if not kws:
|
|
return ""
|
|
scored = []
|
|
for f in glob.glob(os.path.join(EXP_DIR, "EED-EXPER-*.hdlp")):
|
|
if os.path.basename(f) == "EED-EXPER-INDEX.hdlp":
|
|
continue
|
|
content = _read(f, 3000).lower()
|
|
hits = sum(1 for k in kws if k in content)
|
|
if hits >= min_hits:
|
|
title = ""
|
|
m = re.search(r"^# (.*)$", content, re.M)
|
|
if m:
|
|
title = m.group(1)
|
|
scored.append((hits, title, os.path.basename(f)))
|
|
scored.sort(reverse=True)
|
|
if not scored:
|
|
return ""
|
|
out = ["【📚 相关经验自动调用(已验证,可直接复用)】"]
|
|
total = 0
|
|
for hits, title, fn in scored[:3]:
|
|
seg = f"▪ {title}"
|
|
total += len(seg) + 2
|
|
if total > limit_chars:
|
|
break
|
|
out.append(seg)
|
|
return "\n".join(out)
|
|
|
|
|
|
def save(title, content):
|
|
"""自动编号保存经验,返回文件名。"""
|
|
title = (title or "未命名经验").strip()[:60]
|
|
num = _next_num()
|
|
fn = os.path.join(EXP_DIR, "EED-EXPER-%03d.hdlp" % num)
|
|
body = (
|
|
"# EED-EXPER-%03d · %s\n\n"
|
|
"> 保存: %s\n\n"
|
|
"---\n\n%s\n" % (num, title, time.strftime("%Y-%m-%d %H:%M"), content)
|
|
)
|
|
with open(fn, "w", encoding="utf-8") as f:
|
|
f.write(body)
|
|
_update_index()
|
|
return os.path.basename(fn)
|
|
|
|
|
|
def _update_index():
|
|
items = list_experiences()
|
|
lines = [
|
|
"# EED-EXPER-INDEX.hdlp · 经验库索引(自动维护)",
|
|
"",
|
|
"> 倒序 · 最新的在上面 · 蛋蛋醒来扫一眼就知道手里有什么牌",
|
|
"",
|
|
]
|
|
for it in items:
|
|
lines.append("- %s | %s" % (it["file"], it["title"]))
|
|
try:
|
|
with open(INDEX, "w", encoding="utf-8") as f:
|
|
f.write("\n".join(lines) + "\n")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
if len(sys.argv) > 1 and sys.argv[1] == "list":
|
|
for it in list_experiences():
|
|
print(it["num"], it["title"])
|
|
elif len(sys.argv) > 2 and sys.argv[1] == "search":
|
|
print(search(sys.argv[2]))
|
|
else:
|
|
print("用法: experience.py list | search <关键词>")
|