fleet-memory/hindsight-dev/hindsight_dev/generate_llms_full.py
Nicolò Boschi 47be07f97f
bump pg0 0.11.x and improve documentation (#33)
* bump pg0 0.11.x and improve documentation

* bump pg0 0.11.x and improve documentation

* bump pg0 0.11.x and improve documentation

* ci: test notebooks on ci

* ci: test notebooks on ci

* rm llms-full from repo

* formatting

* formatting
2025-12-16 13:33:01 +01:00

156 lines
4.3 KiB
Python

#!/usr/bin/env python3
"""
Generates llms-full.txt by concatenating all documentation markdown files.
This file is used by LLMs to understand the full documentation.
Usage: generate-llms-full (after installing hindsight-dev)
Output: hindsight-docs/static/llms-full.txt (served at /llms-full.txt)
"""
import re
from datetime import datetime, timezone
from pathlib import Path
# Order matters - more important docs first
DOC_ORDER = [
"developer/index.md",
"developer/api/quickstart.md",
"developer/api/main-methods.md",
"developer/retain.md",
"developer/retrieval.md",
"developer/reflect.md",
"developer/api/retain.md",
"developer/api/recall.md",
"developer/api/reflect.md",
"developer/api/memory-banks.md",
"developer/api/entities.md",
"developer/api/documents.md",
"developer/api/operations.md",
"developer/installation.md",
"developer/configuration.md",
"developer/models.md",
"developer/rag-vs-hindsight.md",
"sdks/python.md",
"sdks/nodejs.md",
"sdks/cli.md",
"sdks/mcp.md",
"cookbook/index.mdx",
"cookbook/recipes/quickstart.md",
"cookbook/recipes/per-user-memory.md",
"cookbook/recipes/support-agent-shared-knowledge.md",
"cookbook/applications/openai-fitness-coach.md",
]
def get_docs_dir() -> Path:
"""Find the hindsight-docs directory relative to this script."""
script_dir = Path(__file__).parent
return script_dir.parent.parent / "hindsight-docs" / "docs"
def get_output_file() -> Path:
"""Get output file path."""
script_dir = Path(__file__).parent
return script_dir.parent.parent / "hindsight-docs" / "static" / "llms-full.txt"
def get_all_markdown_files(docs_dir: Path) -> list[str]:
"""Recursively find all markdown files."""
files = []
for path in docs_dir.rglob("*"):
if path.suffix in (".md", ".mdx"):
files.append(str(path.relative_to(docs_dir)))
return files
def strip_frontmatter(content: str) -> str:
"""Remove YAML frontmatter (between --- markers)."""
return re.sub(r"^---\n[\s\S]*?\n---\n", "", content)
def clean_markdown(content: str) -> str:
"""Clean markdown content for LLM consumption."""
cleaned = strip_frontmatter(content)
# Remove import statements
cleaned = re.sub(r"^import\s+.*$", "", cleaned, flags=re.MULTILINE)
# Remove JSX components (like <RecipeCarousel ... />)
cleaned = re.sub(r"<[A-Z][a-zA-Z]*\s+[^>]*/>", "", cleaned)
cleaned = re.sub(r"<[A-Z][a-zA-Z]*[^>]*>[\s\S]*?</[A-Z][a-zA-Z]*>", "", cleaned)
# Remove empty lines at start
cleaned = re.sub(r"^\n+", "", cleaned)
return cleaned
def main():
"""Generate llms-full.txt."""
print("Generating llms-full.txt...")
docs_dir = get_docs_dir()
output_file = get_output_file()
# Get all markdown files
all_files = get_all_markdown_files(docs_dir)
# Create ordered list: prioritized files first, then remaining files
ordered_files = []
remaining_files = set(all_files)
# Add prioritized files in order
for file in DOC_ORDER:
if file in remaining_files:
ordered_files.append(file)
remaining_files.discard(file)
# Add remaining files (sorted alphabetically)
ordered_files.extend(sorted(remaining_files))
# Build the output
sections = []
# Header
timestamp = datetime.now(timezone.utc).isoformat()
sections.append(f"""# Hindsight Documentation
> Agent Memory that Works Like Human Memory
This file contains the complete Hindsight documentation for LLM consumption.
Generated: {timestamp}
---
""")
# Process each file
for file in ordered_files:
file_path = docs_dir / file
if not file_path.exists():
print(f" Warning: {file} not found, skipping")
continue
content = file_path.read_text()
cleaned_content = clean_markdown(content)
if cleaned_content.strip():
sections.append(f"\n## File: {file}\n")
sections.append(cleaned_content)
sections.append("\n---\n")
print(f" Added: {file}")
# Write output
output = "\n".join(sections)
output_file.write_text(output)
size_kb = output_file.stat().st_size / 1024
print(f"\nGenerated: {output_file}")
print(f"Size: {size_kb:.1f} KB")
print(f"Files included: {len(ordered_files)}")
if __name__ == "__main__":
main()