Skip to content

Commit a4465a5

Browse files
chr156r33ntunethewebmax-ostapenko
authored
Create llms-txt-validation.js (#166)
* Create llms-txt-validation.js Fetches /llms.txt and returns a simple validity flag (1 or 0). It checks that the response: - Succeeds (HTTP 2xx) - Has a Content-Type of text/plain - Contains balanced Markdown code fences (…) - Has matching counts of [ vs. ] and ( vs. ) If any check fails, it returns 0; otherwise it returns 1. * Update llms-txt-validation.js * Update llms-txt-validation.js * Return JSON * JSON stringify * Update llms-txt-validation.js * Rename llms-txt-validation.js to dist/llms-txt-validation.js * Update llms-txt-validation.js * Update llms-txt-validation.js * Rename llms-txt-validation.js to llms_txt_validation.js * Update llms_txt_validation.js * Change to Boolean * Validation Changes Making LLMs.txt scoring less strict, so present - yet malformed llms.txt files - will always be marked as "valid", rather than invalid to make it easier to count total adoption whilst understanding which files have errors or not. --------- Co-authored-by: Barry Pollard <barrypollard@google.com> Co-authored-by: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com>
1 parent d43f46b commit a4465a5

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

dist/llms_txt_validation.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//[llms-txt-valid]
2+
3+
const fetchWithTimeout = (url) => {
4+
var controller = new AbortController();
5+
setTimeout(() => {controller.abort()}, 5000);
6+
return fetch(url, {signal: controller.signal});
7+
}
8+
9+
return fetchWithTimeout('/llms.txt')
10+
.then(response => {
11+
if (!response.ok) return JSON.stringify({valid: false, message: response.status, error: "Non OK status code"});
12+
const ct = response.headers.get('Content-Type')||'';
13+
if (!ct.toLowerCase().includes('text/plain')) return JSON.stringify({valid: false, message: ct, error: "Invalid content type"});
14+
return response.text().then(text => {
15+
const m = s => (text.match(new RegExp(`\\${s}`,'g'))||[]).length;
16+
if (m('[')!==m(']')||m('(')!==m(')')) return JSON.stringify({valid: true, error: "Invalid markdown: Unmatched braces"});
17+
if ((text.match(/```/g)||[]).length %2) return JSON.stringify({valid: true, error: "Invalid markdown: Uneven code fences"});
18+
return JSON.stringify({valid: true});
19+
});
20+
})
21+
.catch(error => {
22+
return JSON.stringify({valid: false, message: error.message, error: error});
23+
});

0 commit comments

Comments
 (0)