fleet-memory/hindsight-docs/scripts/generate-llms-full.js
Nicolò Boschi 4191597098 add llms.txt
2025-12-10 13:51:21 +01:00

150 lines
3.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Generates llms-full.txt by concatenating all documentation markdown files.
* This file is used by LLMs to understand the full documentation.
*
* Usage: node scripts/generate-llms-full.js
*
* Output: static/llms-full.txt (served at /llms-full.txt)
*/
const fs = require('fs');
const path = require('path');
const DOCS_DIR = path.join(__dirname, '..', 'docs');
const OUTPUT_FILE = path.join(__dirname, '..', 'static', 'llms-full.txt');
// Order matters - more important docs first
const 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.md',
'cookbook/per-user-memory.md',
'cookbook/support-agent-with-shared-knowledge.md',
];
function getAllMarkdownFiles(dir, baseDir = dir) {
const files = [];
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...getAllMarkdownFiles(fullPath, baseDir));
} else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) {
const relativePath = path.relative(baseDir, fullPath);
files.push(relativePath);
}
}
return files;
}
function stripFrontmatter(content) {
// Remove YAML frontmatter (between --- markers)
const frontmatterRegex = /^---\n[\s\S]*?\n---\n/;
return content.replace(frontmatterRegex, '');
}
function cleanMarkdown(content) {
let cleaned = stripFrontmatter(content);
// Remove import statements
cleaned = cleaned.replace(/^import\s+.*$/gm, '');
// Remove empty lines at start
cleaned = cleaned.replace(/^\n+/, '');
return cleaned;
}
function generateLlmsFullTxt() {
console.log('Generating llms-full.txt...');
// Get all markdown files
const allFiles = getAllMarkdownFiles(DOCS_DIR);
// Create ordered list: prioritized files first, then remaining files
const orderedFiles = [];
const remainingFiles = new Set(allFiles);
// Add prioritized files in order
for (const file of DOC_ORDER) {
if (remainingFiles.has(file)) {
orderedFiles.push(file);
remainingFiles.delete(file);
}
}
// Add remaining files (sorted alphabetically)
const sortedRemaining = Array.from(remainingFiles).sort();
orderedFiles.push(...sortedRemaining);
// Build the output
const sections = [];
// Header
sections.push(`# Hindsight Documentation
> Agent Memory that Works Like Human Memory
This file contains the complete Hindsight documentation for LLM consumption.
Generated: ${new Date().toISOString()}
---
`);
// Process each file
for (const file of orderedFiles) {
const filePath = path.join(DOCS_DIR, file);
if (!fs.existsSync(filePath)) {
console.warn(` Warning: ${file} not found, skipping`);
continue;
}
const content = fs.readFileSync(filePath, 'utf-8');
const cleanedContent = cleanMarkdown(content);
if (cleanedContent.trim()) {
// Add file path as context
sections.push(`\n## File: ${file}\n`);
sections.push(cleanedContent);
sections.push('\n---\n');
console.log(` Added: ${file}`);
}
}
// Write output
const output = sections.join('\n');
fs.writeFileSync(OUTPUT_FILE, output);
const stats = fs.statSync(OUTPUT_FILE);
const sizeKb = (stats.size / 1024).toFixed(1);
console.log(`\nGenerated: ${OUTPUT_FILE}`);
console.log(`Size: ${sizeKb} KB`);
console.log(`Files included: ${orderedFiles.length}`);
}
generateLlmsFullTxt();