fix: index decisions/ as entities so decision records reach the bot prompt
Root cause: decision records have type: decision, but the entity indexer only accepted type: entity and only scanned entities/. The claim indexer scanned decisions/ but filtered out non-claim types. Result: decision records fell through both indexes entirely — invisible to the bot. Fix: add decisions/ to entity indexer scan paths, accept type: decision alongside type: entity, include summary/proposer in search aliases. Remove decisions/ from claim indexer (was silently dropping them anyway). Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
This commit is contained in:
parent
c7c71ec9d1
commit
425e7a1bac
1 changed files with 84 additions and 63 deletions
|
|
@ -106,15 +106,23 @@ class KBIndex:
|
||||||
time.time() - start, len(self._entities), len(self._claims), len(self._positions))
|
time.time() - start, len(self._entities), len(self._claims), len(self._positions))
|
||||||
|
|
||||||
def _index_entities(self):
|
def _index_entities(self):
|
||||||
"""Scan entities/ for all entity files."""
|
"""Scan entities/ and decisions/ for entity and decision files."""
|
||||||
entities_dir = self.repo_dir / "entities"
|
entity_dirs = [
|
||||||
|
self.repo_dir / "entities",
|
||||||
|
self.repo_dir / "decisions",
|
||||||
|
]
|
||||||
|
for entities_dir in entity_dirs:
|
||||||
if not entities_dir.exists():
|
if not entities_dir.exists():
|
||||||
return
|
continue
|
||||||
for md_file in entities_dir.rglob("*.md"):
|
for md_file in entities_dir.rglob("*.md"):
|
||||||
|
self._index_single_entity(md_file)
|
||||||
|
|
||||||
|
def _index_single_entity(self, md_file: Path):
|
||||||
|
"""Index a single entity or decision file."""
|
||||||
try:
|
try:
|
||||||
fm, body = _parse_frontmatter(md_file)
|
fm, body = _parse_frontmatter(md_file)
|
||||||
if not fm or fm.get("type") != "entity":
|
if not fm or fm.get("type") not in ("entity", "decision"):
|
||||||
continue
|
return
|
||||||
|
|
||||||
name = fm.get("name", md_file.stem)
|
name = fm.get("name", md_file.stem)
|
||||||
handles = fm.get("handles", []) or []
|
handles = fm.get("handles", []) or []
|
||||||
|
|
@ -122,6 +130,10 @@ class KBIndex:
|
||||||
entity_type = fm.get("entity_type", "unknown")
|
entity_type = fm.get("entity_type", "unknown")
|
||||||
domain = fm.get("domain", "unknown")
|
domain = fm.get("domain", "unknown")
|
||||||
|
|
||||||
|
# For decision records, also index summary and proposer as searchable text
|
||||||
|
summary = fm.get("summary", "")
|
||||||
|
proposer = fm.get("proposer", "")
|
||||||
|
|
||||||
# Build aliases from multiple sources
|
# Build aliases from multiple sources
|
||||||
aliases = set()
|
aliases = set()
|
||||||
aliases.add(name.lower())
|
aliases.add(name.lower())
|
||||||
|
|
@ -130,6 +142,9 @@ class KBIndex:
|
||||||
aliases.add(h.lower().lstrip("@"))
|
aliases.add(h.lower().lstrip("@"))
|
||||||
for t in tags:
|
for t in tags:
|
||||||
aliases.add(t.lower())
|
aliases.add(t.lower())
|
||||||
|
# Add proposer name as alias for decision records
|
||||||
|
if proposer:
|
||||||
|
aliases.add(proposer.lower())
|
||||||
|
|
||||||
# Mine body for ticker mentions ($XXXX and standalone ALL-CAPS tokens)
|
# Mine body for ticker mentions ($XXXX and standalone ALL-CAPS tokens)
|
||||||
dollar_tickers = re.findall(r"\$([A-Z]{2,10})", body[:2000])
|
dollar_tickers = re.findall(r"\$([A-Z]{2,10})", body[:2000])
|
||||||
|
|
@ -155,7 +170,14 @@ class KBIndex:
|
||||||
# Extract wiki-linked claim references from body
|
# Extract wiki-linked claim references from body
|
||||||
related_claims = re.findall(r"\[\[([^\]]+)\]\]", body)
|
related_claims = re.findall(r"\[\[([^\]]+)\]\]", body)
|
||||||
|
|
||||||
# Body excerpt for context
|
# Body excerpt — for decisions, lead with summary for better prompt context
|
||||||
|
if summary:
|
||||||
|
overview = f"{summary} "
|
||||||
|
body_lines = [l for l in body.split("\n") if l.strip() and not l.startswith("#")]
|
||||||
|
remaining = 500 - len(overview)
|
||||||
|
if remaining > 0:
|
||||||
|
overview += " ".join(body_lines[:10])[:remaining]
|
||||||
|
else:
|
||||||
body_lines = [l for l in body.split("\n") if l.strip() and not l.startswith("#")]
|
body_lines = [l for l in body.split("\n") if l.strip() and not l.startswith("#")]
|
||||||
overview = " ".join(body_lines[:10])[:500]
|
overview = " ".join(body_lines[:10])[:500]
|
||||||
|
|
||||||
|
|
@ -185,7 +207,6 @@ class KBIndex:
|
||||||
self.repo_dir / "domains",
|
self.repo_dir / "domains",
|
||||||
self.repo_dir / "core",
|
self.repo_dir / "core",
|
||||||
self.repo_dir / "foundations",
|
self.repo_dir / "foundations",
|
||||||
self.repo_dir / "decisions",
|
|
||||||
]
|
]
|
||||||
for claim_dir in claim_dirs:
|
for claim_dir in claim_dirs:
|
||||||
if not claim_dir.exists():
|
if not claim_dir.exists():
|
||||||
|
|
@ -447,7 +468,7 @@ def _domain_from_path(path: Path, repo_dir: Path) -> str:
|
||||||
"""Infer domain from file path."""
|
"""Infer domain from file path."""
|
||||||
rel = path.relative_to(repo_dir)
|
rel = path.relative_to(repo_dir)
|
||||||
parts = rel.parts
|
parts = rel.parts
|
||||||
if len(parts) >= 2 and parts[0] in ("domains", "entities"):
|
if len(parts) >= 2 and parts[0] in ("domains", "entities", "decisions"):
|
||||||
return parts[1]
|
return parts[1]
|
||||||
if len(parts) >= 1 and parts[0] == "core":
|
if len(parts) >= 1 and parts[0] == "core":
|
||||||
return "core"
|
return "core"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue