Add ekos-gazete-search FullSweep + telegram + browser-use skills
Skills:
- ekos-gazete-search: EKOS gazete arşivi (1928-1942) tarama skill'i.
+ 04_export.py (CSV+DOCX), run_capped.sh (systemd cap wrapper),
02_search_pdfs.py interleaved-dispatch patch (crash-safe), kirim_core.yaml.
- telegram: TG inbox/search/send/read scripts.
- browser-use: paperclip browser automation skill.
build.py:
- Add ekos-gazete-search → scribe, scholar, oracle, frodo, chronos,
centurion, wraith mapping.
- Add telegram, browser-use mappings (browser-use uses "*" wildcard).
- Add wildcard "*" support in DEFAULT_SKILL_PERSONA_MAP.
- Add paperclip_skills + community_skills buckets to skill injection.
- Wrap yaml.safe_load in try/except for malformed frontmatter.
- Index paperclip_skills with inferred persona mapping.
README.md:
- Add telegram skill to Sentinel/Frodo/Oracle/Echo skill lists.
This commit is contained in:
92
build.py
92
build.py
@@ -258,7 +258,12 @@ def build_persona(
|
||||
# Inject mapped skills for this persona
|
||||
if skills_index:
|
||||
mapped_skills = []
|
||||
for bucket in ("skills", "feynman_skills"):
|
||||
for bucket in (
|
||||
"skills",
|
||||
"paperclip_skills",
|
||||
"community_skills",
|
||||
"feynman_skills",
|
||||
):
|
||||
for skill_name, skill_info in skills_index.get(bucket, {}).items():
|
||||
if not isinstance(skill_info, dict):
|
||||
continue
|
||||
@@ -306,6 +311,8 @@ def build_persona(
|
||||
|
||||
|
||||
DEFAULT_SKILL_PERSONA_MAP = {
|
||||
# Browser automation for every persona
|
||||
"browser-use": ["*"],
|
||||
# Cybersecurity skills → personas
|
||||
"pentest": ["neo"],
|
||||
"nmap-recon": ["neo", "vortex"],
|
||||
@@ -336,6 +343,7 @@ DEFAULT_SKILL_PERSONA_MAP = {
|
||||
"news-crawler": ["frodo", "herald"],
|
||||
"dellight-intelligence-ops": ["frodo", "echo"],
|
||||
"dellight-strategic-intelligence": ["frodo"],
|
||||
"telegram": ["frodo", "oracle", "sentinel", "echo"],
|
||||
"agent-intelligence-network-scan": ["oracle"],
|
||||
"social-trust-manipulation-detector": ["ghost"],
|
||||
# Infrastructure skills → personas
|
||||
@@ -349,6 +357,8 @@ DEFAULT_SKILL_PERSONA_MAP = {
|
||||
# Web scraping → personas
|
||||
"deep-scraper": ["oracle"],
|
||||
"crawl-for-ai": ["oracle", "herald"],
|
||||
# Historical / archival research → personas
|
||||
"ekos-gazete-search": ["scribe", "scholar", "oracle", "frodo", "chronos", "centurion", "wraith"],
|
||||
}
|
||||
|
||||
|
||||
@@ -391,7 +401,10 @@ def parse_skill_frontmatter(skill_md: Path) -> dict:
|
||||
fm_match = re.match(r"^---\n(.*?)\n---\n", content, re.DOTALL)
|
||||
if not fm_match:
|
||||
return {}
|
||||
parsed = yaml.safe_load(fm_match.group(1))
|
||||
try:
|
||||
parsed = yaml.safe_load(fm_match.group(1))
|
||||
except yaml.YAMLError:
|
||||
return {}
|
||||
return parsed if isinstance(parsed, dict) else {}
|
||||
|
||||
|
||||
@@ -514,13 +527,18 @@ def infer_personas_from_skill_metadata(skill_name: str, metadata: dict) -> list:
|
||||
def load_skill_persona_map(config: dict) -> dict:
|
||||
"""Load skill→persona mapping from config.yaml or use defaults."""
|
||||
custom = config.get("skill_persona_map", {})
|
||||
merged = {
|
||||
k: [p for p in v if p in VALID_PERSONAS]
|
||||
for k, v in DEFAULT_SKILL_PERSONA_MAP.items()
|
||||
}
|
||||
merged = {}
|
||||
for skill, personas in DEFAULT_SKILL_PERSONA_MAP.items():
|
||||
if "*" in personas:
|
||||
merged[skill] = sorted(VALID_PERSONAS)
|
||||
else:
|
||||
merged[skill] = [p for p in personas if p in VALID_PERSONAS]
|
||||
for skill, personas in custom.items():
|
||||
if isinstance(personas, list):
|
||||
merged[skill] = [p for p in personas if p in VALID_PERSONAS]
|
||||
if "*" in personas:
|
||||
merged[skill] = sorted(VALID_PERSONAS)
|
||||
else:
|
||||
merged[skill] = [p for p in personas if p in VALID_PERSONAS]
|
||||
return merged
|
||||
|
||||
|
||||
@@ -718,7 +736,35 @@ def build_skills_index(shared_dir: Path, config: dict = None) -> dict:
|
||||
continue
|
||||
skill_md = skill_dir / "SKILL.md"
|
||||
if skill_md.exists():
|
||||
index["paperclip_skills"][skill_dir.name] = True
|
||||
skill_meta = parse_skill_frontmatter(skill_md)
|
||||
inferred_personas = infer_personas_from_skill_metadata(
|
||||
skill_dir.name, skill_meta
|
||||
)
|
||||
configured_personas = skill_map.get(skill_dir.name, [])
|
||||
merged_personas = sorted(
|
||||
set(configured_personas).union(inferred_personas)
|
||||
)
|
||||
content = skill_md.read_text(encoding="utf-8")
|
||||
first_line = ""
|
||||
for line in content.split("\n"):
|
||||
line = line.strip()
|
||||
if line and not line.startswith(
|
||||
("---", "#", "name:", "description:")
|
||||
):
|
||||
first_line = line[:120]
|
||||
break
|
||||
index["paperclip_skills"][skill_dir.name] = {
|
||||
"personas": merged_personas,
|
||||
"summary": first_line,
|
||||
"domain": str(skill_meta.get("domain", "")),
|
||||
"subdomain": str(skill_meta.get("subdomain", "")),
|
||||
"tags": skill_meta.get("tags", []),
|
||||
"mapped_by": {
|
||||
"explicit": configured_personas,
|
||||
"inferred": inferred_personas,
|
||||
},
|
||||
"has_references": (skill_dir / "references").is_dir(),
|
||||
}
|
||||
|
||||
# Index community-skills
|
||||
cskills_dir = shared_dir / "community-skills"
|
||||
@@ -728,7 +774,35 @@ def build_skills_index(shared_dir: Path, config: dict = None) -> dict:
|
||||
continue
|
||||
skill_md = skill_dir / "SKILL.md"
|
||||
if skill_md.exists():
|
||||
index["community_skills"][skill_dir.name] = True
|
||||
skill_meta = parse_skill_frontmatter(skill_md)
|
||||
inferred_personas = infer_personas_from_skill_metadata(
|
||||
skill_dir.name, skill_meta
|
||||
)
|
||||
configured_personas = skill_map.get(skill_dir.name, [])
|
||||
merged_personas = sorted(
|
||||
set(configured_personas).union(inferred_personas)
|
||||
)
|
||||
content = skill_md.read_text(encoding="utf-8")
|
||||
first_line = ""
|
||||
for line in content.split("\n"):
|
||||
line = line.strip()
|
||||
if line and not line.startswith(
|
||||
("---", "#", "name:", "description:")
|
||||
):
|
||||
first_line = line[:120]
|
||||
break
|
||||
index["community_skills"][skill_dir.name] = {
|
||||
"personas": merged_personas,
|
||||
"summary": first_line,
|
||||
"domain": str(skill_meta.get("domain", "")),
|
||||
"subdomain": str(skill_meta.get("subdomain", "")),
|
||||
"tags": skill_meta.get("tags", []),
|
||||
"mapped_by": {
|
||||
"explicit": configured_personas,
|
||||
"inferred": inferred_personas,
|
||||
},
|
||||
"has_references": (skill_dir / "references").is_dir(),
|
||||
}
|
||||
|
||||
# Index feynman-skills (research workflows adapted from Feynman).
|
||||
# Use the same persona-aware indexing as shared skills so mapped skills
|
||||
|
||||
Reference in New Issue
Block a user