@farm.js/core 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-runtime.d.mts +2 -2
- package/dist/agent-runtime.d.ts +2 -2
- package/dist/api/route-manager.d.mts +2 -2
- package/dist/api/route-manager.d.ts +2 -2
- package/dist/api.d.mts +3 -3
- package/dist/api.d.ts +3 -3
- package/dist/{app-ZuWrAMc_.d.mts → app-29vG5tmY.d.mts} +3 -3
- package/dist/{app-BF-ctoxh.d.ts → app-Cx71s_PT.d.ts} +3 -3
- package/dist/app-markdown.cjs +6 -4
- package/dist/app-markdown.d.mts +3 -3
- package/dist/app-markdown.d.ts +3 -3
- package/dist/app-markdown.mjs +5 -3
- package/dist/{chunk-E3RDL2DA.cjs → chunk-2CT6XUNO.cjs} +61 -31
- package/dist/{chunk-R7LCG3BT.cjs → chunk-3TQG7CGC.cjs} +84 -77
- package/dist/{chunk-AXYTGLF3.cjs → chunk-3WSWXPYM.cjs} +4 -4
- package/dist/{chunk-2BIJGZR3.mjs → chunk-74RZNRY6.mjs} +1 -1
- package/dist/{chunk-TTVHACQV.cjs → chunk-ALIFMS4A.cjs} +1 -1
- package/dist/{chunk-T2OPSH6S.mjs → chunk-ARXCHQLX.mjs} +9 -2
- package/dist/{chunk-2KI3CL3N.mjs → chunk-DU2CASV6.mjs} +1 -1
- package/dist/chunk-J63ZH5OQ.cjs +62 -0
- package/dist/{chunk-XM4ZDVD7.mjs → chunk-JM5GQL4H.mjs} +1 -1
- package/dist/{chunk-6VEHUKZ2.mjs → chunk-MM5D6VLP.mjs} +4 -20
- package/dist/chunk-MVL2RAJW.mjs +62 -0
- package/dist/{chunk-YA6LLTIJ.cjs → chunk-ND224OE2.cjs} +4 -20
- package/dist/{chunk-XME4TCLB.mjs → chunk-OFKG57MZ.mjs} +2 -2
- package/dist/{chunk-U4MP7XTD.mjs → chunk-OOIL3BWR.mjs} +168 -16
- package/dist/{chunk-WOI2HOGA.mjs → chunk-PPIW3MH6.mjs} +1 -1
- package/dist/{chunk-2ITKVAIF.cjs → chunk-QIH2HD6H.cjs} +191 -39
- package/dist/{chunk-65P6OGYN.cjs → chunk-QJ4D3UKJ.cjs} +10 -3
- package/dist/{chunk-RYDW7GPR.cjs → chunk-QLXEYIAW.cjs} +13 -13
- package/dist/{chunk-WJYCI56T.mjs → chunk-QPPQHB6X.mjs} +43 -30
- package/dist/{chunk-RR6UGYUT.mjs → chunk-RAI7NULA.mjs} +39 -9
- package/dist/{chunk-6K4SPQWL.cjs → chunk-RCYINC4A.cjs} +3 -3
- package/dist/{chunk-QYMRIVG6.cjs → chunk-SZ4LYNUX.cjs} +110 -97
- package/dist/{chunk-N2Z4ZFDE.mjs → chunk-UXQXGB5A.mjs} +19 -12
- package/dist/{chunk-CFNOGDUS.cjs → chunk-W2HZKYES.cjs} +2 -2
- package/dist/{chunk-O5DVPF3R.cjs → chunk-WFPRVVF2.cjs} +10 -10
- package/dist/{chunk-5YYJ6Q2L.mjs → chunk-YMUH2BLR.mjs} +2 -2
- package/dist/{client-plugins-DPG0NeZN.d.mts → client-plugins-B8RPJnot.d.mts} +90 -3
- package/dist/{client-plugins-Fgni-_25.d.ts → client-plugins-bPBf4haK.d.ts} +90 -3
- package/dist/client-plugins.d.mts +2 -2
- package/dist/client-plugins.d.ts +2 -2
- package/dist/client.d.mts +6 -6
- package/dist/client.d.ts +6 -6
- package/dist/config.d.mts +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/{devtools-I7TBFOKD.mjs → devtools-5D4ZDRPR.mjs} +5 -3
- package/dist/{devtools-6OA7FEF6.cjs → devtools-QZJEUOJW.cjs} +6 -4
- package/dist/docs.cjs +8 -6
- package/dist/docs.mjs +7 -5
- package/dist/index.cjs +17 -13
- package/dist/index.d.mts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.mjs +16 -12
- package/dist/integrations.d.mts +2 -2
- package/dist/integrations.d.ts +2 -2
- package/dist/internal/app-markdown-runtime.cjs +5 -3
- package/dist/internal/app-markdown-runtime.d.mts +2 -2
- package/dist/internal/app-markdown-runtime.d.ts +2 -2
- package/dist/internal/app-markdown-runtime.mjs +4 -2
- package/dist/internal/build-runtime.cjs +14 -13
- package/dist/internal/build-runtime.d.mts +4 -4
- package/dist/internal/build-runtime.d.ts +4 -4
- package/dist/internal/build-runtime.mjs +13 -12
- package/dist/internal/cli-runtime.cjs +6 -5
- package/dist/internal/cli-runtime.mjs +5 -4
- package/dist/internal/client-error-overlay.cjs +4 -4
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/compression-runtime.d.mts +2 -2
- package/dist/internal/compression-runtime.d.ts +2 -2
- package/dist/internal/config-runtime.cjs +6 -4
- package/dist/internal/config-runtime.d.mts +3 -3
- package/dist/internal/config-runtime.d.ts +3 -3
- package/dist/internal/config-runtime.mjs +5 -3
- package/dist/internal/infra-analytics-runtime.cjs +4 -3
- package/dist/internal/infra-analytics-runtime.mjs +2 -1
- package/dist/internal/product-telemetry-runtime.cjs +2 -2
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-runtime.cjs +5 -4
- package/dist/internal/production-runtime.d.mts +11 -9
- package/dist/internal/production-runtime.d.ts +11 -9
- package/dist/internal/production-runtime.mjs +4 -3
- package/dist/markdown.cjs +4 -2
- package/dist/markdown.mjs +3 -1
- package/dist/{metadata-D0EF7esB.d.mts → metadata-C3na4CBj.d.mts} +1 -1
- package/dist/{metadata-CDnRHKVq.d.ts → metadata-CzBP4Mfp.d.ts} +1 -1
- package/dist/middleware.d.mts +4 -4
- package/dist/middleware.d.ts +4 -4
- package/dist/navigation.d.mts +5 -5
- package/dist/navigation.d.ts +5 -5
- package/dist/observability-BupkiN0m.d.mts +447 -0
- package/dist/observability-BupkiN0m.d.ts +447 -0
- package/dist/observability.d.mts +2 -417
- package/dist/observability.d.ts +2 -417
- package/dist/plugin.cjs +9 -8
- package/dist/plugin.d.mts +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.mjs +8 -7
- package/dist/{production-runtime-DpCt0opU.d.ts → production-runtime-CYg4wM4E.d.ts} +1 -1
- package/dist/{production-runtime-x3W4wVqx.d.mts → production-runtime-DP94hPGe.d.mts} +1 -1
- package/dist/{render-plan-D5oFRVBV.d.ts → render-plan-Bl6Fzg5z.d.ts} +1 -1
- package/dist/{render-plan-tazUJalK.d.mts → render-plan-CKAJg0jC.d.mts} +1 -1
- package/dist/renderer-client.d.mts +4 -4
- package/dist/renderer-client.d.ts +4 -4
- package/dist/{request-CzZX0Aew.d.ts → request-CR-Bp1Px.d.ts} +1 -1
- package/dist/{request-CXmQy5ks.d.mts → request-CrBCcPZZ.d.mts} +1 -1
- package/dist/request.d.mts +3 -3
- package/dist/request.d.ts +3 -3
- package/dist/{route-rendering-B-qpe32B.d.mts → route-rendering-C1NAHo-C.d.mts} +1 -1
- package/dist/{route-rendering-Dw3C362T.d.ts → route-rendering-CZH5FegB.d.ts} +1 -1
- package/dist/{router-CafM2jlw.d.mts → router-B57eDJ3u.d.mts} +1 -1
- package/dist/{router-CLl3xHwl.d.ts → router-Cg_kD3Bd.d.ts} +1 -1
- package/dist/routes.d.mts +2 -2
- package/dist/routes.d.ts +2 -2
- package/dist/server-plugins.d.mts +3 -3
- package/dist/server-plugins.d.ts +3 -3
- package/dist/server.cjs +159 -102
- package/dist/server.d.mts +8 -8
- package/dist/server.d.ts +8 -8
- package/dist/server.mjs +140 -83
- package/dist/{spa-router-DePr2aZ6.d.ts → spa-router-BstQUO6Q.d.ts} +2 -2
- package/dist/{spa-router-6sJfsMlQ.d.mts → spa-router-DTdbuinx.d.mts} +2 -2
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/{utils-BPHr-1mP.d.mts → utils-CS3ZLnEJ.d.mts} +1 -1
- package/dist/{utils-BBKC3cf3.d.ts → utils-D3rdsIvM.d.ts} +1 -1
- package/dist/version.cjs +2 -2
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +9 -8
- package/dist/vite.d.mts +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.mjs +8 -7
- package/package.json +1 -1
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-XAXTTBUT.mjs";
|
|
4
4
|
import {
|
|
5
5
|
serializeFarmLlmsTxt
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RAI7NULA.mjs";
|
|
7
|
+
import {
|
|
8
|
+
emitFarmAgentRead
|
|
9
|
+
} from "./chunk-MVL2RAJW.mjs";
|
|
7
10
|
import {
|
|
8
11
|
resolveFarmThemeConfig
|
|
9
12
|
} from "./chunk-AELACLOB.mjs";
|
|
@@ -201,6 +204,9 @@ function createFarmMetadataRouteResponse(kind, value, routeModule = {}, options
|
|
|
201
204
|
if (method !== "GET" && method !== "HEAD") {
|
|
202
205
|
return new Response(null, { status: 405, headers: { Allow: "GET, HEAD" } });
|
|
203
206
|
}
|
|
207
|
+
if ((kind === "llms" || kind === "llms-full") && options.request) {
|
|
208
|
+
emitFarmAgentRead(options.request, kind, isResponse(value) ? value.status : 200);
|
|
209
|
+
}
|
|
204
210
|
if (isResponse(value)) {
|
|
205
211
|
return method === "HEAD" ? omitFarmResponseBody(value) : value;
|
|
206
212
|
}
|
|
@@ -486,7 +492,7 @@ function createFarmApiCatalog(input) {
|
|
|
486
492
|
};
|
|
487
493
|
}
|
|
488
494
|
__name(createFarmApiCatalog, "createFarmApiCatalog");
|
|
489
|
-
function createFarmApiCatalogResponse(method, input) {
|
|
495
|
+
function createFarmApiCatalogResponse(method, input, request) {
|
|
490
496
|
const upperMethod = method.toUpperCase();
|
|
491
497
|
if (upperMethod !== "GET" && upperMethod !== "HEAD") {
|
|
492
498
|
return new Response("Method Not Allowed", {
|
|
@@ -494,6 +500,7 @@ function createFarmApiCatalogResponse(method, input) {
|
|
|
494
500
|
headers: { Allow: "GET, HEAD", "Content-Type": "text/plain; charset=utf-8" }
|
|
495
501
|
});
|
|
496
502
|
}
|
|
503
|
+
if (request) emitFarmAgentRead(request, "api-catalog", 200);
|
|
497
504
|
const catalog = createFarmApiCatalog(input);
|
|
498
505
|
return new Response(upperMethod === "HEAD" ? null : JSON.stringify(catalog), {
|
|
499
506
|
status: 200,
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
var _chunkE3UK5IIBcjs = require('./chunk-E3UK5IIB.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkS3JO3N4Hcjs = require('./chunk-S3JO3N4H.cjs');
|
|
7
|
+
|
|
8
|
+
// src/agent-identity.ts
|
|
9
|
+
var AGENT_TOKENS = [
|
|
10
|
+
["ChatGPT-User", "openai", "agent"],
|
|
11
|
+
["OAI-SearchBot", "openai", "crawler"],
|
|
12
|
+
["GPTBot", "openai", "crawler"],
|
|
13
|
+
["Claude-User", "anthropic", "agent"],
|
|
14
|
+
["Claude-SearchBot", "anthropic", "crawler"],
|
|
15
|
+
["ClaudeBot", "anthropic", "crawler"],
|
|
16
|
+
["Perplexity-User", "perplexity", "agent"],
|
|
17
|
+
["PerplexityBot", "perplexity", "crawler"],
|
|
18
|
+
["CCBot", "other", "crawler"],
|
|
19
|
+
["Bytespider", "other", "crawler"],
|
|
20
|
+
["Meta-ExternalAgent", "other", "crawler"]
|
|
21
|
+
];
|
|
22
|
+
var AGENT_PATTERNS = AGENT_TOKENS.map(([token, family, category]) => ({
|
|
23
|
+
pattern: new RegExp(`(?:^|[\\s;(])${token}(?=[/\\s;)]|$)`, "i"),
|
|
24
|
+
family,
|
|
25
|
+
category
|
|
26
|
+
}));
|
|
27
|
+
var UNKNOWN = { family: "unknown", category: "unknown", identity: "unknown" };
|
|
28
|
+
function classifyFarmAgent(userAgent) {
|
|
29
|
+
const value = (_nullishCoalesce(userAgent, () => ( ""))).slice(0, 2048);
|
|
30
|
+
const matches = AGENT_PATTERNS.filter(({ pattern }) => pattern.test(value));
|
|
31
|
+
if (matches.length === 1) {
|
|
32
|
+
const { family, category } = matches[0];
|
|
33
|
+
return { family, category, identity: "self-reported" };
|
|
34
|
+
}
|
|
35
|
+
return { ...UNKNOWN };
|
|
36
|
+
}
|
|
37
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, classifyFarmAgent, "classifyFarmAgent");
|
|
38
|
+
var FARM_INTERNAL_READ_HEADER = "x-farm-internal-read";
|
|
39
|
+
function emitFarmAgentRead(request, surface, status, view) {
|
|
40
|
+
if (request.headers.has(FARM_INTERNAL_READ_HEADER)) return;
|
|
41
|
+
let route;
|
|
42
|
+
try {
|
|
43
|
+
route = new URL(request.url).pathname;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
_chunkE3UK5IIBcjs.emitFarmEvent.call(void 0, {
|
|
48
|
+
type: "agent.read",
|
|
49
|
+
surface,
|
|
50
|
+
route,
|
|
51
|
+
...view ? { view } : {},
|
|
52
|
+
status,
|
|
53
|
+
agent: classifyFarmAgent(request.headers.get("user-agent"))
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, emitFarmAgentRead, "emitFarmAgentRead");
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
exports.classifyFarmAgent = classifyFarmAgent; exports.FARM_INTERNAL_READ_HEADER = FARM_INTERNAL_READ_HEADER; exports.emitFarmAgentRead = emitFarmAgentRead;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifyFarmAgent
|
|
3
|
+
} from "./chunk-MVL2RAJW.mjs";
|
|
1
4
|
import {
|
|
2
5
|
onFarmEvent
|
|
3
6
|
} from "./chunk-FUZEBRP3.mjs";
|
|
@@ -74,27 +77,8 @@ function resolveFarmInfraAnalytics(env = processEnv()) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
__name(resolveFarmInfraAnalytics, "resolveFarmInfraAnalytics");
|
|
77
|
-
var AGENT_TOKENS = [
|
|
78
|
-
["ChatGPT-User", "openai", "agent"],
|
|
79
|
-
["OAI-SearchBot", "openai", "crawler"],
|
|
80
|
-
["GPTBot", "openai", "crawler"],
|
|
81
|
-
["Claude-User", "anthropic", "agent"],
|
|
82
|
-
["Claude-SearchBot", "anthropic", "crawler"],
|
|
83
|
-
["ClaudeBot", "anthropic", "crawler"]
|
|
84
|
-
];
|
|
85
|
-
var AGENT_PATTERNS = AGENT_TOKENS.map(([token, family, category]) => ({
|
|
86
|
-
pattern: new RegExp(`(?:^|[\\s;(])${token}(?=[/\\s;)]|$)`, "i"),
|
|
87
|
-
family,
|
|
88
|
-
category
|
|
89
|
-
}));
|
|
90
80
|
function classifyFarmInfraAgent(userAgent) {
|
|
91
|
-
|
|
92
|
-
const matches = AGENT_PATTERNS.filter(({ pattern }) => pattern.test(value));
|
|
93
|
-
if (matches.length === 1) {
|
|
94
|
-
const { family, category } = matches[0];
|
|
95
|
-
return { family, category, identity: "self-reported" };
|
|
96
|
-
}
|
|
97
|
-
return { family: "unknown", category: "unknown", identity: "unknown" };
|
|
81
|
+
return classifyFarmAgent(userAgent);
|
|
98
82
|
}
|
|
99
83
|
__name(classifyFarmInfraAgent, "classifyFarmInfraAgent");
|
|
100
84
|
function routeTemplate(pattern) {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
emitFarmEvent
|
|
3
|
+
} from "./chunk-FUZEBRP3.mjs";
|
|
4
|
+
import {
|
|
5
|
+
__name
|
|
6
|
+
} from "./chunk-LPEX4YW6.mjs";
|
|
7
|
+
|
|
8
|
+
// src/agent-identity.ts
|
|
9
|
+
var AGENT_TOKENS = [
|
|
10
|
+
["ChatGPT-User", "openai", "agent"],
|
|
11
|
+
["OAI-SearchBot", "openai", "crawler"],
|
|
12
|
+
["GPTBot", "openai", "crawler"],
|
|
13
|
+
["Claude-User", "anthropic", "agent"],
|
|
14
|
+
["Claude-SearchBot", "anthropic", "crawler"],
|
|
15
|
+
["ClaudeBot", "anthropic", "crawler"],
|
|
16
|
+
["Perplexity-User", "perplexity", "agent"],
|
|
17
|
+
["PerplexityBot", "perplexity", "crawler"],
|
|
18
|
+
["CCBot", "other", "crawler"],
|
|
19
|
+
["Bytespider", "other", "crawler"],
|
|
20
|
+
["Meta-ExternalAgent", "other", "crawler"]
|
|
21
|
+
];
|
|
22
|
+
var AGENT_PATTERNS = AGENT_TOKENS.map(([token, family, category]) => ({
|
|
23
|
+
pattern: new RegExp(`(?:^|[\\s;(])${token}(?=[/\\s;)]|$)`, "i"),
|
|
24
|
+
family,
|
|
25
|
+
category
|
|
26
|
+
}));
|
|
27
|
+
var UNKNOWN = { family: "unknown", category: "unknown", identity: "unknown" };
|
|
28
|
+
function classifyFarmAgent(userAgent) {
|
|
29
|
+
const value = (userAgent ?? "").slice(0, 2048);
|
|
30
|
+
const matches = AGENT_PATTERNS.filter(({ pattern }) => pattern.test(value));
|
|
31
|
+
if (matches.length === 1) {
|
|
32
|
+
const { family, category } = matches[0];
|
|
33
|
+
return { family, category, identity: "self-reported" };
|
|
34
|
+
}
|
|
35
|
+
return { ...UNKNOWN };
|
|
36
|
+
}
|
|
37
|
+
__name(classifyFarmAgent, "classifyFarmAgent");
|
|
38
|
+
var FARM_INTERNAL_READ_HEADER = "x-farm-internal-read";
|
|
39
|
+
function emitFarmAgentRead(request, surface, status, view) {
|
|
40
|
+
if (request.headers.has(FARM_INTERNAL_READ_HEADER)) return;
|
|
41
|
+
let route;
|
|
42
|
+
try {
|
|
43
|
+
route = new URL(request.url).pathname;
|
|
44
|
+
} catch {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
emitFarmEvent({
|
|
48
|
+
type: "agent.read",
|
|
49
|
+
surface,
|
|
50
|
+
route,
|
|
51
|
+
...view ? { view } : {},
|
|
52
|
+
status,
|
|
53
|
+
agent: classifyFarmAgent(request.headers.get("user-agent"))
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
__name(emitFarmAgentRead, "emitFarmAgentRead");
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
classifyFarmAgent,
|
|
60
|
+
FARM_INTERNAL_READ_HEADER,
|
|
61
|
+
emitFarmAgentRead
|
|
62
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
+
var _chunkJ63ZH5OQcjs = require('./chunk-J63ZH5OQ.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
var _chunkE3UK5IIBcjs = require('./chunk-E3UK5IIB.cjs');
|
|
4
7
|
|
|
5
8
|
|
|
@@ -74,27 +77,8 @@ function resolveFarmInfraAnalytics(env = processEnv()) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
_chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmInfraAnalytics, "resolveFarmInfraAnalytics");
|
|
77
|
-
var AGENT_TOKENS = [
|
|
78
|
-
["ChatGPT-User", "openai", "agent"],
|
|
79
|
-
["OAI-SearchBot", "openai", "crawler"],
|
|
80
|
-
["GPTBot", "openai", "crawler"],
|
|
81
|
-
["Claude-User", "anthropic", "agent"],
|
|
82
|
-
["Claude-SearchBot", "anthropic", "crawler"],
|
|
83
|
-
["ClaudeBot", "anthropic", "crawler"]
|
|
84
|
-
];
|
|
85
|
-
var AGENT_PATTERNS = AGENT_TOKENS.map(([token, family, category]) => ({
|
|
86
|
-
pattern: new RegExp(`(?:^|[\\s;(])${token}(?=[/\\s;)]|$)`, "i"),
|
|
87
|
-
family,
|
|
88
|
-
category
|
|
89
|
-
}));
|
|
90
80
|
function classifyFarmInfraAgent(userAgent) {
|
|
91
|
-
|
|
92
|
-
const matches = AGENT_PATTERNS.filter(({ pattern }) => pattern.test(value));
|
|
93
|
-
if (matches.length === 1) {
|
|
94
|
-
const { family, category } = matches[0];
|
|
95
|
-
return { family, category, identity: "self-reported" };
|
|
96
|
-
}
|
|
97
|
-
return { family: "unknown", category: "unknown", identity: "unknown" };
|
|
81
|
+
return _chunkJ63ZH5OQcjs.classifyFarmAgent.call(void 0, userAgent);
|
|
98
82
|
}
|
|
99
83
|
_chunkS3JO3N4Hcjs.__name.call(void 0, classifyFarmInfraAgent, "classifyFarmInfraAgent");
|
|
100
84
|
function routeTemplate(pattern) {
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
loadFarmDocsPage,
|
|
4
4
|
resolveFarmDocsContentDir,
|
|
5
5
|
toFarmDocsMarkdownPage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DU2CASV6.mjs";
|
|
7
7
|
import {
|
|
8
8
|
docsEngine,
|
|
9
9
|
loadFarmDocsEngine
|
|
10
10
|
} from "./chunk-2VQKKQ6D.mjs";
|
|
11
11
|
import {
|
|
12
12
|
resolveDocsConfig
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-YMUH2BLR.mjs";
|
|
14
14
|
import {
|
|
15
15
|
getFarmDocsAdapterConfigModule
|
|
16
16
|
} from "./chunk-VVBO3QH7.mjs";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
emitFarmAgentRead
|
|
3
|
+
} from "./chunk-MVL2RAJW.mjs";
|
|
1
4
|
import {
|
|
2
5
|
__name
|
|
3
6
|
} from "./chunk-LPEX4YW6.mjs";
|
|
@@ -39,10 +42,12 @@ function parseFarmMarkdownHeadings(markdown) {
|
|
|
39
42
|
end: lines.length
|
|
40
43
|
});
|
|
41
44
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
const open = [];
|
|
46
|
+
for (const heading of headings) {
|
|
47
|
+
while (open.length > 0 && open[open.length - 1].level >= heading.level) {
|
|
48
|
+
open.pop().end = heading.start;
|
|
49
|
+
}
|
|
50
|
+
open.push(heading);
|
|
46
51
|
}
|
|
47
52
|
return headings;
|
|
48
53
|
}
|
|
@@ -55,23 +60,49 @@ function estimateFarmMarkdownTokens(text) {
|
|
|
55
60
|
return Math.ceil(text.length / 4);
|
|
56
61
|
}
|
|
57
62
|
__name(estimateFarmMarkdownTokens, "estimateFarmMarkdownTokens");
|
|
63
|
+
var FARM_MARKDOWN_MIN_TOKEN_BUDGET = 100;
|
|
64
|
+
var FARM_MARKDOWN_VIEW_PARAMS = [
|
|
65
|
+
"outline",
|
|
66
|
+
"section",
|
|
67
|
+
"actions",
|
|
68
|
+
"max_tokens",
|
|
69
|
+
"cursor"
|
|
70
|
+
];
|
|
58
71
|
function selectFarmMarkdownView(markdown, searchParams, markdownPath) {
|
|
59
72
|
const wantsOutline = searchParams.has("outline");
|
|
60
73
|
const sectionId = searchParams.get("section");
|
|
61
|
-
|
|
74
|
+
const budget = searchParams.get("max_tokens");
|
|
75
|
+
if (!wantsOutline && sectionId === null && budget === null)
|
|
76
|
+
return { status: 200, body: markdown };
|
|
77
|
+
const viewUrl = /* @__PURE__ */ __name((view) => {
|
|
78
|
+
const query = new URLSearchParams(searchParams);
|
|
79
|
+
for (const name of FARM_MARKDOWN_VIEW_PARAMS) query.delete(name);
|
|
80
|
+
for (const [name, value] of Object.entries(view)) {
|
|
81
|
+
if (value !== null && value !== void 0) query.set(name, value);
|
|
82
|
+
}
|
|
83
|
+
const search = query.toString();
|
|
84
|
+
return search ? `${markdownPath}?${search}` : markdownPath;
|
|
85
|
+
}, "viewUrl");
|
|
86
|
+
const withinBudget = /* @__PURE__ */ __name((document) => budget === null ? { status: 200, body: document } : selectFarmMarkdownPart(
|
|
87
|
+
document,
|
|
88
|
+
budget,
|
|
89
|
+
searchParams.get("cursor"),
|
|
90
|
+
(cursor) => viewUrl({ section: sectionId, max_tokens: budget, cursor })
|
|
91
|
+
), "withinBudget");
|
|
92
|
+
if (!wantsOutline && sectionId === null) return withinBudget(markdown);
|
|
62
93
|
const lines = markdown.split("\n");
|
|
63
94
|
const headings = parseFarmMarkdownHeadings(markdown);
|
|
64
95
|
const sectionText = /* @__PURE__ */ __name((heading) => lines.slice(heading.start, heading.end).join("\n").trim(), "sectionText");
|
|
65
96
|
if (sectionId !== null) {
|
|
66
97
|
const heading = headings.find((candidate) => candidate.id === sectionId);
|
|
67
|
-
if (heading) return
|
|
68
|
-
`
|
|
98
|
+
if (heading) return withinBudget(`${sectionText(heading)}
|
|
99
|
+
`);
|
|
69
100
|
const available = headings.map((candidate) => `- \`${candidate.id}\``).join("\n");
|
|
70
101
|
return {
|
|
71
102
|
status: 404,
|
|
72
103
|
body: `# Section not found
|
|
73
104
|
|
|
74
|
-
|
|
105
|
+
${markdownCodeSpan(sectionId)} is not a section of ${markdownPath}.
|
|
75
106
|
|
|
76
107
|
` + (available ? `Available sections:
|
|
77
108
|
|
|
@@ -79,23 +110,31 @@ ${available}
|
|
|
79
110
|
` : "This page has no sections.\n")
|
|
80
111
|
};
|
|
81
112
|
}
|
|
82
|
-
const minLevel =
|
|
113
|
+
const minLevel = headings.reduce((min, heading) => Math.min(min, heading.level), 6);
|
|
83
114
|
const entries = headings.map((heading) => {
|
|
84
115
|
const indent = " ".repeat(heading.level - minLevel);
|
|
85
116
|
const tokens = estimateFarmMarkdownTokens(sectionText(heading));
|
|
86
|
-
return `${indent}- [${heading.text}](${
|
|
117
|
+
return `${indent}- [${heading.text}](${viewUrl({ section: heading.id })}) ~${tokens} tokens`;
|
|
87
118
|
});
|
|
88
119
|
return {
|
|
89
120
|
status: 200,
|
|
90
121
|
body: `# Outline of ${markdownPath}
|
|
91
122
|
|
|
92
|
-
About ${estimateFarmMarkdownTokens(markdown)} tokens in total. Request one section with \`?section=<id>\`.
|
|
123
|
+
About ${estimateFarmMarkdownTokens(markdown)} tokens in total. Request one section with \`?section=<id>\`, or read in parts with \`?max_tokens=<n>\`.
|
|
93
124
|
|
|
94
125
|
` + (entries.length > 0 ? `${entries.join("\n")}
|
|
95
126
|
` : "This page has no headings.\n")
|
|
96
127
|
};
|
|
97
128
|
}
|
|
98
129
|
__name(selectFarmMarkdownView, "selectFarmMarkdownView");
|
|
130
|
+
function markdownCodeSpan(value) {
|
|
131
|
+
const text = value.replace(/[\p{Cc}\u2028\u2029]+/gu, " ");
|
|
132
|
+
const longestRun = (text.match(/`+/g) ?? []).reduce((max, run) => Math.max(max, run.length), 0);
|
|
133
|
+
const fence = "`".repeat(longestRun + 1);
|
|
134
|
+
const pad = text.startsWith("`") || text.endsWith("`") ? " " : "";
|
|
135
|
+
return `${fence}${pad}${text}${pad}${fence}`;
|
|
136
|
+
}
|
|
137
|
+
__name(markdownCodeSpan, "markdownCodeSpan");
|
|
99
138
|
function selectFarmPageActionsView(markdownPath, actions, headers) {
|
|
100
139
|
headers.set("Content-Type", "application/json; charset=utf-8");
|
|
101
140
|
const page = markdownPath === "/index.md" ? "/" : markdownPath.replace(/\.md$/, "");
|
|
@@ -106,7 +145,117 @@ function selectFarmPageActionsView(markdownPath, actions, headers) {
|
|
|
106
145
|
};
|
|
107
146
|
}
|
|
108
147
|
__name(selectFarmPageActionsView, "selectFarmPageActionsView");
|
|
148
|
+
function selectFarmMarkdownPart(document, rawBudget, rawCursor, partUrl) {
|
|
149
|
+
const budget = /^\d{1,9}$/.test(rawBudget) ? Number(rawBudget) : Number.NaN;
|
|
150
|
+
if (!(budget >= FARM_MARKDOWN_MIN_TOKEN_BUDGET)) {
|
|
151
|
+
return {
|
|
152
|
+
status: 400,
|
|
153
|
+
body: `# Invalid max_tokens
|
|
154
|
+
|
|
155
|
+
\`max_tokens\` must be a whole number of at least ${FARM_MARKDOWN_MIN_TOKEN_BUDGET}.
|
|
156
|
+
`
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const lines = document.replace(/\n$/, "").split("\n");
|
|
160
|
+
const version = hashFarmMarkdown(document).slice(0, 8);
|
|
161
|
+
let start = 0;
|
|
162
|
+
if (rawCursor !== null) {
|
|
163
|
+
const match = /^(\d{1,9})\.([0-9a-z]+)$/.exec(rawCursor);
|
|
164
|
+
if (!match || Number(match[1]) <= 0 || Number(match[1]) >= lines.length) {
|
|
165
|
+
return {
|
|
166
|
+
status: 400,
|
|
167
|
+
body: `# Invalid cursor
|
|
168
|
+
|
|
169
|
+
Start again at ${partUrl()}.
|
|
170
|
+
`
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (match[2] !== version) {
|
|
174
|
+
return {
|
|
175
|
+
status: 409,
|
|
176
|
+
body: `# Page changed
|
|
177
|
+
|
|
178
|
+
The page changed after this cursor was issued. Start again at ${partUrl()}.
|
|
179
|
+
`
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
start = Number(match[1]);
|
|
183
|
+
}
|
|
184
|
+
const fences = readOpenFences(lines);
|
|
185
|
+
const reopen = fences[start];
|
|
186
|
+
const room = budget * 4 - 200;
|
|
187
|
+
let size = reopen ? reopen.opener.length + 1 : 0;
|
|
188
|
+
let end = start;
|
|
189
|
+
let lastBreak = -1;
|
|
190
|
+
while (end < lines.length) {
|
|
191
|
+
const length = lines[end].length + 1;
|
|
192
|
+
if (end > start && size + length > room) break;
|
|
193
|
+
size += length;
|
|
194
|
+
end++;
|
|
195
|
+
if (end < lines.length && isPartBreak(lines, fences, end)) lastBreak = end;
|
|
196
|
+
}
|
|
197
|
+
const head = reopen ? `${reopen.opener}
|
|
198
|
+
` : "";
|
|
199
|
+
if (end >= lines.length) {
|
|
200
|
+
return { status: 200, body: `${head}${lines.slice(start).join("\n")}
|
|
201
|
+
` };
|
|
202
|
+
}
|
|
203
|
+
if (lastBreak > start) end = lastBreak;
|
|
204
|
+
const open = fences[end];
|
|
205
|
+
const part = `${head}${lines.slice(start, end).join("\n").replace(/\n+$/, "")}${open ? `
|
|
206
|
+
${open.closer}` : ""}`;
|
|
207
|
+
const next = partUrl(`${end}.${version}`);
|
|
208
|
+
const remaining = estimateFarmMarkdownTokens(lines.slice(end).join("\n"));
|
|
209
|
+
return {
|
|
210
|
+
status: 200,
|
|
211
|
+
body: `${part}
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
Continue: ${next} (about ${remaining} more tokens)
|
|
216
|
+
`,
|
|
217
|
+
headers: { Link: `<${next}>; rel="next"` }
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
__name(selectFarmMarkdownPart, "selectFarmMarkdownPart");
|
|
221
|
+
function readOpenFences(lines) {
|
|
222
|
+
const open = [];
|
|
223
|
+
let fence;
|
|
224
|
+
let frontMatter = lines[0]?.trim() === "---";
|
|
225
|
+
for (let index = 0; index < lines.length; index++) {
|
|
226
|
+
open.push(frontMatter && index > 0 ? { opener: "", closer: "" } : fence);
|
|
227
|
+
const line = lines[index];
|
|
228
|
+
if (frontMatter) {
|
|
229
|
+
if (index > 0 && line.trim() === "---") frontMatter = false;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const match = FENCE.exec(line);
|
|
233
|
+
if (!match) continue;
|
|
234
|
+
const marker = match[1];
|
|
235
|
+
if (!fence) fence = { opener: line.trim(), closer: marker, marker };
|
|
236
|
+
else if (marker[0] === fence.marker[0] && marker.length >= fence.marker.length)
|
|
237
|
+
fence = void 0;
|
|
238
|
+
}
|
|
239
|
+
return open;
|
|
240
|
+
}
|
|
241
|
+
__name(readOpenFences, "readOpenFences");
|
|
242
|
+
function isPartBreak(lines, fences, index) {
|
|
243
|
+
if (fences[index]) return false;
|
|
244
|
+
return lines[index - 1].trim() === "" || ATX_HEADING.test(lines[index]);
|
|
245
|
+
}
|
|
246
|
+
__name(isPartBreak, "isPartBreak");
|
|
247
|
+
function readMarkdownViewName(searchParams) {
|
|
248
|
+
if (searchParams.has("actions")) return "actions";
|
|
249
|
+
if (searchParams.has("outline")) return "outline";
|
|
250
|
+
if (searchParams.has("max_tokens")) return "parts";
|
|
251
|
+
return searchParams.has("section") ? "section" : void 0;
|
|
252
|
+
}
|
|
253
|
+
__name(readMarkdownViewName, "readMarkdownViewName");
|
|
109
254
|
function createFarmMarkdownETag(body) {
|
|
255
|
+
return `W/"${hashFarmMarkdown(body)}-${body.length.toString(36)}"`;
|
|
256
|
+
}
|
|
257
|
+
__name(createFarmMarkdownETag, "createFarmMarkdownETag");
|
|
258
|
+
function hashFarmMarkdown(body) {
|
|
110
259
|
let h1 = 3735928559;
|
|
111
260
|
let h2 = 1103547991;
|
|
112
261
|
for (let index = 0; index < body.length; index++) {
|
|
@@ -116,10 +265,9 @@ function createFarmMarkdownETag(body) {
|
|
|
116
265
|
}
|
|
117
266
|
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
118
267
|
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
119
|
-
|
|
120
|
-
return `W/"${hash}-${body.length.toString(36)}"`;
|
|
268
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
|
|
121
269
|
}
|
|
122
|
-
__name(
|
|
270
|
+
__name(hashFarmMarkdown, "hashFarmMarkdown");
|
|
123
271
|
function ifNoneMatchIncludes(header, etag) {
|
|
124
272
|
if (!header) return false;
|
|
125
273
|
const opaque = etag.replace(/^W\//, "");
|
|
@@ -130,6 +278,9 @@ function createFarmMarkdownViewResponse(options) {
|
|
|
130
278
|
const url = options.requestUrl ?? new URL(options.request.url);
|
|
131
279
|
const view = url.searchParams.has("actions") ? selectFarmPageActionsView(options.markdownPath, options.actions ?? [], options.headers) : selectFarmMarkdownView(options.markdown, url.searchParams, options.markdownPath);
|
|
132
280
|
const status = view.status === 200 ? options.status : view.status;
|
|
281
|
+
emitFarmAgentRead(options.request, "markdown", status, readMarkdownViewName(url.searchParams));
|
|
282
|
+
for (const [name, value] of Object.entries(view.headers ?? {}))
|
|
283
|
+
options.headers.append(name, value);
|
|
133
284
|
const etag = createFarmMarkdownETag(view.body);
|
|
134
285
|
options.headers.set("ETag", etag);
|
|
135
286
|
if (status === 200 && ifNoneMatchIncludes(options.request.headers.get("if-none-match"), etag)) {
|
|
@@ -220,7 +371,7 @@ async function createMarkdownMirrorResponse(options) {
|
|
|
220
371
|
}
|
|
221
372
|
const pageUrl = new URL(options.request.url);
|
|
222
373
|
pageUrl.pathname = target.pathname;
|
|
223
|
-
for (const name of
|
|
374
|
+
for (const name of FARM_MARKDOWN_VIEW_PARAMS) pageUrl.searchParams.delete(name);
|
|
224
375
|
const headers = new Headers(options.request.headers);
|
|
225
376
|
headers.set("accept", "text/html");
|
|
226
377
|
const pageResponse = await options.renderPage(
|
|
@@ -229,7 +380,8 @@ async function createMarkdownMirrorResponse(options) {
|
|
|
229
380
|
headers
|
|
230
381
|
})
|
|
231
382
|
);
|
|
232
|
-
|
|
383
|
+
const redirects = pageResponse.status >= 300 && pageResponse.status < 400 && pageResponse.headers.has("location");
|
|
384
|
+
if (redirects || !isHtmlResponse(pageResponse)) {
|
|
233
385
|
return createMarkdownAccessResponse(
|
|
234
386
|
pageResponse,
|
|
235
387
|
target.pathname,
|