@farming-labs/docs 0.2.71 → 0.2.73
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-bof3qzKZ.mjs → agent-ClRpctMG.mjs} +3 -2
- package/dist/{agent-evals-Cr9TAkmB.mjs → agent-evals-BFHGypqh.mjs} +116 -20
- package/dist/{agent-export-7Ws4KqDE.mjs → agent-export-B9bah0AV.mjs} +9 -8
- package/dist/{agent-FIyl4-Oa.mjs → agent-o9OTadrf.mjs} +607 -769
- package/dist/agent-skills-bundle.d.mts +1 -1
- package/dist/{agent-skills-server-DTwblsLu.d.mts → agent-skills-server-DCbAx5WU.d.mts} +2 -2
- package/dist/{agent-skills-server-B4u3qy-1.mjs → agent-skills-server-noFn1l_p.mjs} +1 -1
- package/dist/agent-skills-vite.d.mts +3 -3
- package/dist/agent-skills-vite.mjs +2 -2
- package/dist/{agents-Be2ntaFr.mjs → agents-CR-Uasbc.mjs} +7 -6
- package/dist/cli/index.mjs +14 -14
- package/dist/client/react.d.mts +1 -1
- package/dist/{cloud-ask-ai-BfnX18rI.d.mts → cloud-ask-ai-yR9vZmSG.d.mts} +1 -1
- package/dist/docs-cloud-server.d.mts +2 -2
- package/dist/{doctor-DoPAofVP.mjs → doctor-BeyN3Ljh.mjs} +12 -11
- package/dist/{golden-evaluations-CPGGnXOV.mjs → golden-evaluations-CloP0pAe.mjs} +23 -2
- package/dist/index.d.mts +93 -6
- package/dist/index.mjs +9 -8
- package/dist/markdown-rendering.d.mts +75 -0
- package/dist/markdown-rendering.mjs +618 -0
- package/dist/markdown-sections-7OoA7ylx.mjs +1492 -0
- package/dist/{mcp-BLynUzE7.mjs → mcp-BLLXvEXB.mjs} +7 -6
- package/dist/mcp.d.mts +7 -2
- package/dist/mcp.mjs +130 -25
- package/dist/{metadata-bw8k-9x-.mjs → metadata-N252j5_a.mjs} +1 -1
- package/dist/{reading-time-DtNegNiq.mjs → prompt-references-Cz35rlOa.mjs} +158 -4
- package/dist/{review-NFnYbMRI.mjs → review-DaJLdPLh.mjs} +7 -6
- package/dist/{robots-DOqBwQw8.mjs → robots-BcuxnZqZ.mjs} +2 -2
- package/dist/{robots-B3e-aWPy.mjs → robots-DI-9MZz1.mjs} +4 -3
- package/dist/{search-CozHzW7v.d.mts → search-D1n8Sf25.d.mts} +45 -9
- package/dist/{search-DOGUUZvs.mjs → search-DeOJiMAy.mjs} +7 -6
- package/dist/{search-x5O0-9X3.mjs → search-RfPcG1if.mjs} +742 -42
- package/dist/server.d.mts +13 -5
- package/dist/server.mjs +8 -7
- package/dist/{sitemap-BpMKdDUd.mjs → sitemap-BGGbX_KE.mjs} +7 -6
- package/dist/{sitemap-server-D_hayOp6.mjs → sitemap-server-VefDnzEB.mjs} +1 -1
- package/dist/{standards-discovery-C0CIC4QI.d.mts → standards-discovery-83lp1lew.d.mts} +5 -4
- package/dist/{standards-discovery-CYfiQE13.mjs → standards-discovery-BwL5ffGx.mjs} +4 -3
- package/dist/{types-BQC05SQm.d.mts → types-_HCPD4wc.d.mts} +49 -1
- package/package.json +9 -1
- package/dist/agent-scope-C_U--OZ7.mjs +0 -283
- /package/dist/{i18n-CCaFUnAN.mjs → i18n-hHVWcflJ.mjs} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as isDocsAgentDiscoveryRequest, K as isDocsAgentsRequest, Q as isDocsSkillRequest, _t as resolveDocsMarkdownRequest, dt as resolveDocsAgentsFormat, jt as resolveDocsAudienceMdxContent, lt as resolveDocsAgentFeedbackConfig, pt as resolveDocsLlmsTxtRequest, ut as resolveDocsAgentFeedbackRequest, xt as resolveDocsSkillFormat } from "./agent-o9OTadrf.mjs";
|
|
2
|
+
import { S as upsertPageAgentContractMarkdown, a as findDocsGeneratedAgentContractRanges, d as PAGE_AGENT_CONTRACT_END_MARKER, l as stripDocsGeneratedAgentContractMarkers, m as PAGE_AGENT_CONTRACT_START_MARKER, o as findDocsMarkdownSection, s as parseDocsMarkdownSections, y as renderPageAgentContractMarkdown } from "./markdown-sections-7OoA7ylx.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/telemetry.ts
|
|
4
5
|
const DOCS_PACKAGE_NAME = "@farming-labs/docs";
|
|
@@ -457,6 +458,326 @@ function serializeGeneratedAgentDocument(content, provenance) {
|
|
|
457
458
|
].join("\n")}\n`;
|
|
458
459
|
}
|
|
459
460
|
|
|
461
|
+
//#endregion
|
|
462
|
+
//#region src/agent-scope.ts
|
|
463
|
+
/** Normalize framework aliases used by page metadata, agent contracts, MCP, and evaluations. */
|
|
464
|
+
function normalizeAgentFramework(value) {
|
|
465
|
+
const normalized = value.toLowerCase().replace(/[^a-z0-9]/gu, "");
|
|
466
|
+
if ([
|
|
467
|
+
"next",
|
|
468
|
+
"nextjs",
|
|
469
|
+
"nextjsapp",
|
|
470
|
+
"reactnext"
|
|
471
|
+
].includes(normalized)) return "nextjs";
|
|
472
|
+
if ([
|
|
473
|
+
"tanstack",
|
|
474
|
+
"tanstackstart",
|
|
475
|
+
"start"
|
|
476
|
+
].includes(normalized)) return "tanstackstart";
|
|
477
|
+
if (["svelte", "sveltekit"].includes(normalized)) return "sveltekit";
|
|
478
|
+
if (["nuxt", "nuxtjs"].includes(normalized)) return "nuxt";
|
|
479
|
+
return normalized;
|
|
480
|
+
}
|
|
481
|
+
function normalizeAgentLocale(value) {
|
|
482
|
+
return value.trim().toLowerCase().replace(/_/gu, "-");
|
|
483
|
+
}
|
|
484
|
+
function normalizeAgentVersion(value) {
|
|
485
|
+
return value.trim().toLowerCase().replace(/^v(?=\d)/u, "");
|
|
486
|
+
}
|
|
487
|
+
function normalizeAgentScopeValues(value) {
|
|
488
|
+
const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
489
|
+
return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));
|
|
490
|
+
}
|
|
491
|
+
function compareVersions(left, right) {
|
|
492
|
+
for (let index = 0; index < 3; index += 1) if (left[index] !== right[index]) return left[index] > right[index] ? 1 : -1;
|
|
493
|
+
return 0;
|
|
494
|
+
}
|
|
495
|
+
function parseExactVersion(value) {
|
|
496
|
+
const match = normalizeAgentVersion(value).match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$/iu);
|
|
497
|
+
if (!match) return void 0;
|
|
498
|
+
return [
|
|
499
|
+
Number(match[1]),
|
|
500
|
+
Number(match[2] ?? 0),
|
|
501
|
+
Number(match[3] ?? 0)
|
|
502
|
+
];
|
|
503
|
+
}
|
|
504
|
+
function parseVersionOperand(value) {
|
|
505
|
+
const normalized = normalizeAgentVersion(value);
|
|
506
|
+
if (normalized === "*" || normalized === "x") return {
|
|
507
|
+
version: [
|
|
508
|
+
0,
|
|
509
|
+
0,
|
|
510
|
+
0
|
|
511
|
+
],
|
|
512
|
+
components: 0,
|
|
513
|
+
wildcard: true
|
|
514
|
+
};
|
|
515
|
+
const match = normalized.match(/^(\d+)(?:\.(\d+|x|\*))?(?:\.(\d+|x|\*))?$/iu);
|
|
516
|
+
if (!match) return void 0;
|
|
517
|
+
const raw = [
|
|
518
|
+
match[1],
|
|
519
|
+
match[2],
|
|
520
|
+
match[3]
|
|
521
|
+
];
|
|
522
|
+
const wildcardIndex = raw.findIndex((part, index) => index > 0 && (part?.toLowerCase() === "x" || part === "*"));
|
|
523
|
+
if (wildcardIndex >= 0 && raw.slice(wildcardIndex + 1).some((part) => part && part.toLowerCase() !== "x" && part !== "*")) return;
|
|
524
|
+
const components = wildcardIndex >= 0 ? wildcardIndex : raw.filter(Boolean).length;
|
|
525
|
+
return {
|
|
526
|
+
version: [
|
|
527
|
+
Number(raw[0]),
|
|
528
|
+
Number(raw[1] ?? 0) || 0,
|
|
529
|
+
Number(raw[2] ?? 0) || 0
|
|
530
|
+
],
|
|
531
|
+
components,
|
|
532
|
+
wildcard: wildcardIndex >= 0
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function nextVersionBoundary(operand) {
|
|
536
|
+
const [major, minor] = operand.version;
|
|
537
|
+
if (operand.components <= 0) return void 0;
|
|
538
|
+
if (operand.components === 1) return [
|
|
539
|
+
major + 1,
|
|
540
|
+
0,
|
|
541
|
+
0
|
|
542
|
+
];
|
|
543
|
+
return [
|
|
544
|
+
major,
|
|
545
|
+
minor + 1,
|
|
546
|
+
0
|
|
547
|
+
];
|
|
548
|
+
}
|
|
549
|
+
function operandRange(operand) {
|
|
550
|
+
if (operand.components === 0) return {
|
|
551
|
+
minimumInclusive: true,
|
|
552
|
+
maximumInclusive: false
|
|
553
|
+
};
|
|
554
|
+
if (operand.components < 3 || operand.wildcard) return {
|
|
555
|
+
minimum: operand.version,
|
|
556
|
+
minimumInclusive: true,
|
|
557
|
+
maximum: nextVersionBoundary(operand),
|
|
558
|
+
maximumInclusive: false
|
|
559
|
+
};
|
|
560
|
+
return {
|
|
561
|
+
minimum: operand.version,
|
|
562
|
+
minimumInclusive: true,
|
|
563
|
+
maximum: operand.version,
|
|
564
|
+
maximumInclusive: true
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function caretRange(operand) {
|
|
568
|
+
const [major, minor, patch] = operand.version;
|
|
569
|
+
let maximum;
|
|
570
|
+
if (major > 0) maximum = [
|
|
571
|
+
major + 1,
|
|
572
|
+
0,
|
|
573
|
+
0
|
|
574
|
+
];
|
|
575
|
+
else if (operand.components <= 1) maximum = [
|
|
576
|
+
1,
|
|
577
|
+
0,
|
|
578
|
+
0
|
|
579
|
+
];
|
|
580
|
+
else if (minor > 0 || operand.components === 2) maximum = [
|
|
581
|
+
0,
|
|
582
|
+
minor + 1,
|
|
583
|
+
0
|
|
584
|
+
];
|
|
585
|
+
else maximum = [
|
|
586
|
+
0,
|
|
587
|
+
0,
|
|
588
|
+
patch + 1
|
|
589
|
+
];
|
|
590
|
+
return {
|
|
591
|
+
minimum: operand.version,
|
|
592
|
+
minimumInclusive: true,
|
|
593
|
+
maximum,
|
|
594
|
+
maximumInclusive: false
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function tildeRange(operand) {
|
|
598
|
+
const [major, minor] = operand.version;
|
|
599
|
+
const maximum = operand.components <= 1 ? [
|
|
600
|
+
major + 1,
|
|
601
|
+
0,
|
|
602
|
+
0
|
|
603
|
+
] : [
|
|
604
|
+
major,
|
|
605
|
+
minor + 1,
|
|
606
|
+
0
|
|
607
|
+
];
|
|
608
|
+
return {
|
|
609
|
+
minimum: operand.version,
|
|
610
|
+
minimumInclusive: true,
|
|
611
|
+
maximum,
|
|
612
|
+
maximumInclusive: false
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function intersectRanges(left, right) {
|
|
616
|
+
let minimum = left.minimum;
|
|
617
|
+
let minimumInclusive = left.minimumInclusive;
|
|
618
|
+
if (!minimum || right.minimum && compareVersions(right.minimum, minimum) > 0) {
|
|
619
|
+
minimum = right.minimum;
|
|
620
|
+
minimumInclusive = right.minimumInclusive;
|
|
621
|
+
} else if (right.minimum && compareVersions(right.minimum, minimum) === 0) minimumInclusive = minimumInclusive && right.minimumInclusive;
|
|
622
|
+
let maximum = left.maximum;
|
|
623
|
+
let maximumInclusive = left.maximumInclusive;
|
|
624
|
+
if (!maximum || right.maximum && compareVersions(right.maximum, maximum) < 0) {
|
|
625
|
+
maximum = right.maximum;
|
|
626
|
+
maximumInclusive = right.maximumInclusive;
|
|
627
|
+
} else if (right.maximum && compareVersions(right.maximum, maximum) === 0) maximumInclusive = maximumInclusive && right.maximumInclusive;
|
|
628
|
+
if (minimum && maximum) {
|
|
629
|
+
const compared = compareVersions(minimum, maximum);
|
|
630
|
+
if (compared > 0 || compared === 0 && !(minimumInclusive && maximumInclusive)) return void 0;
|
|
631
|
+
}
|
|
632
|
+
return {
|
|
633
|
+
minimum,
|
|
634
|
+
minimumInclusive,
|
|
635
|
+
maximum,
|
|
636
|
+
maximumInclusive
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function comparatorRange(operator, operand) {
|
|
640
|
+
if (!operator || operator === "=") return operandRange(operand);
|
|
641
|
+
if (operator === ">=") return {
|
|
642
|
+
minimum: operand.version,
|
|
643
|
+
minimumInclusive: true,
|
|
644
|
+
maximumInclusive: false
|
|
645
|
+
};
|
|
646
|
+
if (operator === ">") {
|
|
647
|
+
const partialBoundary = operand.components < 3 ? nextVersionBoundary(operand) : void 0;
|
|
648
|
+
return {
|
|
649
|
+
minimum: partialBoundary ?? operand.version,
|
|
650
|
+
minimumInclusive: Boolean(partialBoundary),
|
|
651
|
+
maximumInclusive: false
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
if (operator === "<") return {
|
|
655
|
+
minimumInclusive: true,
|
|
656
|
+
maximum: operand.version,
|
|
657
|
+
maximumInclusive: false
|
|
658
|
+
};
|
|
659
|
+
const partialBoundary = operand.components < 3 ? nextVersionBoundary(operand) : void 0;
|
|
660
|
+
return {
|
|
661
|
+
minimumInclusive: true,
|
|
662
|
+
maximum: partialBoundary ?? operand.version,
|
|
663
|
+
maximumInclusive: !partialBoundary
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
function parseVersionRangeBranch(value) {
|
|
667
|
+
const branch = normalizeAgentVersion(value).trim();
|
|
668
|
+
if (!branch) return void 0;
|
|
669
|
+
const hyphen = branch.match(/^(.+?)\s+-\s+(.+)$/u);
|
|
670
|
+
if (hyphen) {
|
|
671
|
+
const minimumOperand = parseVersionOperand(hyphen[1]);
|
|
672
|
+
const maximumOperand = parseVersionOperand(hyphen[2]);
|
|
673
|
+
if (!minimumOperand || !maximumOperand) return void 0;
|
|
674
|
+
const maximumBoundary = maximumOperand.components < 3 ? nextVersionBoundary(maximumOperand) : maximumOperand.version;
|
|
675
|
+
return intersectRanges({
|
|
676
|
+
minimum: minimumOperand.version,
|
|
677
|
+
minimumInclusive: true,
|
|
678
|
+
maximumInclusive: false
|
|
679
|
+
}, {
|
|
680
|
+
minimumInclusive: true,
|
|
681
|
+
maximum: maximumBoundary,
|
|
682
|
+
maximumInclusive: maximumOperand.components === 3
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
const special = branch.match(/^(\^|~)\s*(.+)$/u);
|
|
686
|
+
if (special) {
|
|
687
|
+
const operand = parseVersionOperand(special[2]);
|
|
688
|
+
if (!operand || operand.components === 0) return void 0;
|
|
689
|
+
return special[1] === "^" ? caretRange(operand) : tildeRange(operand);
|
|
690
|
+
}
|
|
691
|
+
const comparators = Array.from(branch.matchAll(/(>=|<=|>|<|=)\s*([^\s]+)/gu));
|
|
692
|
+
if (comparators.length > 0) {
|
|
693
|
+
if (comparators.map((match) => match[0]).join(" ").replace(/\s+/gu, " ") !== branch.replace(/\s+/gu, " ")) return void 0;
|
|
694
|
+
let range = {
|
|
695
|
+
minimumInclusive: true,
|
|
696
|
+
maximumInclusive: false
|
|
697
|
+
};
|
|
698
|
+
for (const comparator of comparators) {
|
|
699
|
+
const operand = parseVersionOperand(comparator[2]);
|
|
700
|
+
if (!operand) return void 0;
|
|
701
|
+
const next = intersectRanges(range, comparatorRange(comparator[1], operand));
|
|
702
|
+
if (!next) return void 0;
|
|
703
|
+
range = next;
|
|
704
|
+
}
|
|
705
|
+
return range;
|
|
706
|
+
}
|
|
707
|
+
const operand = parseVersionOperand(branch);
|
|
708
|
+
return operand ? operandRange(operand) : void 0;
|
|
709
|
+
}
|
|
710
|
+
function parseVersionRanges(value) {
|
|
711
|
+
return normalizeAgentVersion(value).split("||").map((branch) => parseVersionRangeBranch(branch)).filter((range) => Boolean(range));
|
|
712
|
+
}
|
|
713
|
+
function parseVersionConstraintBranches(value) {
|
|
714
|
+
const ranges = parseVersionRanges(value);
|
|
715
|
+
if (ranges.length > 0) return ranges.map((range) => ({
|
|
716
|
+
kind: "range",
|
|
717
|
+
range
|
|
718
|
+
}));
|
|
719
|
+
const normalized = normalizeAgentVersion(value);
|
|
720
|
+
return normalized ? [{
|
|
721
|
+
kind: "opaque",
|
|
722
|
+
value: normalized
|
|
723
|
+
}] : [];
|
|
724
|
+
}
|
|
725
|
+
function intersectVersionConstraintBranches(left, right) {
|
|
726
|
+
if (left.kind === "opaque" || right.kind === "opaque") return left.kind === "opaque" && right.kind === "opaque" && left.value === right.value ? left : void 0;
|
|
727
|
+
const range = intersectRanges(left.range, right.range);
|
|
728
|
+
return range ? {
|
|
729
|
+
kind: "range",
|
|
730
|
+
range
|
|
731
|
+
} : void 0;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Return true when choosing one alternative from every group can select one shared version.
|
|
735
|
+
*
|
|
736
|
+
* Each inner group is an OR list while the groups themselves are intersected. Computing the
|
|
737
|
+
* accumulated range prevents pairwise matches from accepting three mutually incompatible scopes.
|
|
738
|
+
*/
|
|
739
|
+
function agentVersionConstraintGroupsOverlap(groups) {
|
|
740
|
+
if (groups.length === 0) return false;
|
|
741
|
+
let intersections = groups[0].flatMap(parseVersionConstraintBranches);
|
|
742
|
+
if (intersections.length === 0) return false;
|
|
743
|
+
for (const group of groups.slice(1)) {
|
|
744
|
+
const branches = group.flatMap(parseVersionConstraintBranches);
|
|
745
|
+
if (branches.length === 0) return false;
|
|
746
|
+
intersections = intersections.flatMap((intersection) => branches.map((branch) => intersectVersionConstraintBranches(intersection, branch)).filter((value) => Boolean(value)));
|
|
747
|
+
if (intersections.length === 0) return false;
|
|
748
|
+
}
|
|
749
|
+
return true;
|
|
750
|
+
}
|
|
751
|
+
function rangeContains(range, version) {
|
|
752
|
+
if (range.minimum) {
|
|
753
|
+
const compared = compareVersions(version, range.minimum);
|
|
754
|
+
if (compared < 0 || compared === 0 && !range.minimumInclusive) return false;
|
|
755
|
+
}
|
|
756
|
+
if (range.maximum) {
|
|
757
|
+
const compared = compareVersions(version, range.maximum);
|
|
758
|
+
if (compared > 0 || compared === 0 && !range.maximumInclusive) return false;
|
|
759
|
+
}
|
|
760
|
+
return true;
|
|
761
|
+
}
|
|
762
|
+
function rangesOverlap(left, right) {
|
|
763
|
+
return Boolean(intersectRanges(left, right));
|
|
764
|
+
}
|
|
765
|
+
/** Match an exact requested version against an exact or range-like documented constraint. */
|
|
766
|
+
function agentVersionConstraintMatches(requested, constraint) {
|
|
767
|
+
if (normalizeAgentVersion(requested) === normalizeAgentVersion(constraint)) return Boolean(normalizeAgentVersion(requested));
|
|
768
|
+
const wanted = parseExactVersion(requested);
|
|
769
|
+
if (!wanted) return false;
|
|
770
|
+
return parseVersionRanges(constraint).some((range) => rangeContains(range, wanted));
|
|
771
|
+
}
|
|
772
|
+
/** Return true when two exact or range-like documented version constraints can select one version. */
|
|
773
|
+
function agentVersionConstraintsOverlap(left, right) {
|
|
774
|
+
const normalizedLeft = normalizeAgentVersion(left);
|
|
775
|
+
if (normalizedLeft === normalizeAgentVersion(right)) return Boolean(normalizedLeft);
|
|
776
|
+
const leftRanges = parseVersionRanges(left);
|
|
777
|
+
const rightRanges = parseVersionRanges(right);
|
|
778
|
+
return leftRanges.some((leftRange) => rightRanges.some((rightRange) => rangesOverlap(leftRange, rightRange)));
|
|
779
|
+
}
|
|
780
|
+
|
|
460
781
|
//#endregion
|
|
461
782
|
//#region src/search.ts
|
|
462
783
|
const DEFAULT_SEARCH_LIMIT = 10;
|
|
@@ -467,6 +788,26 @@ const syncedIndexes = /* @__PURE__ */ new Set();
|
|
|
467
788
|
const ALGOLIA_MAX_RECORD_BYTES = 9500;
|
|
468
789
|
const DEFAULT_ASK_AI_CONTEXT_CHARS = 24e3;
|
|
469
790
|
const DEFAULT_ASK_AI_RESULT_CHARS = 6e3;
|
|
791
|
+
const MAX_SEARCH_FILTER_VALUES = 16;
|
|
792
|
+
const MAX_SEARCH_FILTER_VALUE_CHARS = 128;
|
|
793
|
+
const MAX_SEARCH_FILTER_RAW_CHARS = 4096;
|
|
794
|
+
const MAX_SEARCH_FILTER_SEGMENTS = 64;
|
|
795
|
+
const MAX_PROVIDER_SCOPE_FILTER_IDS = 1e3;
|
|
796
|
+
const MAX_PROVIDER_SCOPE_FILTER_CHARS = 16e3;
|
|
797
|
+
const MAX_SEARCH_WARNINGS = 16;
|
|
798
|
+
const MAX_SEARCH_WARNING_VALUES = 16;
|
|
799
|
+
const MAX_SEARCH_WARNING_PAGE_URLS = 8;
|
|
800
|
+
const SEARCH_FILTER_FIELDS = [
|
|
801
|
+
"framework",
|
|
802
|
+
"version",
|
|
803
|
+
"package",
|
|
804
|
+
"tags"
|
|
805
|
+
];
|
|
806
|
+
const SEARCH_AMBIGUITY_FIELDS = [
|
|
807
|
+
"framework",
|
|
808
|
+
"version",
|
|
809
|
+
"package"
|
|
810
|
+
];
|
|
470
811
|
const SEARCH_STOP_WORDS = new Set([
|
|
471
812
|
"a",
|
|
472
813
|
"an",
|
|
@@ -498,6 +839,143 @@ const SEARCH_STOP_WORDS = new Set([
|
|
|
498
839
|
"which",
|
|
499
840
|
"with"
|
|
500
841
|
]);
|
|
842
|
+
function normalizeDocsSearchFilterValue(field, value) {
|
|
843
|
+
const bounded = value.trim().slice(0, MAX_SEARCH_FILTER_VALUE_CHARS).trim();
|
|
844
|
+
if (!bounded) return "";
|
|
845
|
+
if (field === "framework") return normalizeAgentFramework(bounded);
|
|
846
|
+
if (field === "version") return normalizeAgentVersion(bounded);
|
|
847
|
+
return bounded.toLowerCase();
|
|
848
|
+
}
|
|
849
|
+
function normalizeDocsSearchFilterValues(field, input) {
|
|
850
|
+
const values = typeof input === "string" ? [input] : input ?? [];
|
|
851
|
+
const normalized = [];
|
|
852
|
+
const seen = /* @__PURE__ */ new Set();
|
|
853
|
+
let remainingChars = MAX_SEARCH_FILTER_RAW_CHARS;
|
|
854
|
+
let remainingSegments = MAX_SEARCH_FILTER_SEGMENTS;
|
|
855
|
+
for (const item of values) {
|
|
856
|
+
if (remainingChars <= 0 || remainingSegments <= 0) break;
|
|
857
|
+
const boundedItem = item.slice(0, remainingChars);
|
|
858
|
+
remainingChars -= boundedItem.length;
|
|
859
|
+
for (const part of boundedItem.split(",")) {
|
|
860
|
+
if (remainingSegments <= 0) break;
|
|
861
|
+
remainingSegments -= 1;
|
|
862
|
+
const value = normalizeDocsSearchFilterValue(field, part);
|
|
863
|
+
if (!value || seen.has(value)) continue;
|
|
864
|
+
seen.add(value);
|
|
865
|
+
normalized.push(value);
|
|
866
|
+
if (normalized.length >= MAX_SEARCH_FILTER_VALUES) return normalized;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return normalized;
|
|
870
|
+
}
|
|
871
|
+
/** Normalize scalar or array-valued scope filters for programmatic, HTTP, and MCP callers. */
|
|
872
|
+
function normalizeDocsSearchFilters(input = {}) {
|
|
873
|
+
const filters = {};
|
|
874
|
+
for (const field of SEARCH_FILTER_FIELDS) {
|
|
875
|
+
const values = normalizeDocsSearchFilterValues(field, input[field]);
|
|
876
|
+
if (values.length > 0) filters[field] = values;
|
|
877
|
+
}
|
|
878
|
+
return filters;
|
|
879
|
+
}
|
|
880
|
+
/** Parse the public search scope parameters from a URL query string. */
|
|
881
|
+
function resolveDocsSearchFilters(searchParams) {
|
|
882
|
+
return normalizeDocsSearchFilters({
|
|
883
|
+
framework: searchParams.getAll("framework"),
|
|
884
|
+
version: searchParams.getAll("version"),
|
|
885
|
+
package: searchParams.getAll("package"),
|
|
886
|
+
tags: searchParams.getAll("tags")
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
/** Resolve search filters and the backwards-compatible structured response opt-in. */
|
|
890
|
+
function resolveDocsSearchRequest(searchParams) {
|
|
891
|
+
return {
|
|
892
|
+
filters: resolveDocsSearchFilters(searchParams),
|
|
893
|
+
structured: searchParams.get("response") === "structured"
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
function hasDocsSearchFilters(filters) {
|
|
897
|
+
return SEARCH_FILTER_FIELDS.some((field) => (filters[field]?.length ?? 0) > 0);
|
|
898
|
+
}
|
|
899
|
+
function resolveProviderScopeDocumentIds(query, context) {
|
|
900
|
+
if (!hasDocsSearchFilters(query.filters ?? {})) return void 0;
|
|
901
|
+
const ids = Array.from(new Set(context.documents.map((document) => document.id)));
|
|
902
|
+
return ids.length <= MAX_PROVIDER_SCOPE_FILTER_IDS ? ids : [];
|
|
903
|
+
}
|
|
904
|
+
function docsSearchFiltersMatch(expected, actual) {
|
|
905
|
+
return SEARCH_FILTER_FIELDS.every((field) => {
|
|
906
|
+
const expectedValues = expected[field] ?? [];
|
|
907
|
+
const actualValues = actual[field] ?? [];
|
|
908
|
+
return expectedValues.length === actualValues.length && expectedValues.every((value) => actualValues.includes(value));
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
function parseVerifiedMcpSearchFilters(value) {
|
|
912
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
913
|
+
const record = value;
|
|
914
|
+
const filterFields = SEARCH_FILTER_FIELDS;
|
|
915
|
+
if (Object.keys(record).some((field) => !filterFields.includes(field))) return;
|
|
916
|
+
const input = {};
|
|
917
|
+
for (const field of SEARCH_FILTER_FIELDS) {
|
|
918
|
+
const values = record[field];
|
|
919
|
+
if (values === void 0) continue;
|
|
920
|
+
if (!Array.isArray(values) || values.length > MAX_SEARCH_FILTER_VALUES || values.some((item) => typeof item !== "string" || item.length > MAX_SEARCH_FILTER_VALUE_CHARS)) return;
|
|
921
|
+
input[field] = values;
|
|
922
|
+
}
|
|
923
|
+
const normalized = normalizeDocsSearchFilters(input);
|
|
924
|
+
for (const field of SEARCH_FILTER_FIELDS) {
|
|
925
|
+
const values = record[field];
|
|
926
|
+
if (values === void 0) continue;
|
|
927
|
+
if (!Array.isArray(values) || values.length !== (normalized[field]?.length ?? 0) || values.some((value, index) => value !== normalized[field]?.[index])) return;
|
|
928
|
+
}
|
|
929
|
+
return normalized;
|
|
930
|
+
}
|
|
931
|
+
function normalizeDocsSearchMetadataValues(field, value) {
|
|
932
|
+
const values = normalizeAgentScopeValues(value);
|
|
933
|
+
return Array.from(new Set(values.map((item) => normalizeDocsSearchFilterValue(field, item)).filter((item) => Boolean(item))));
|
|
934
|
+
}
|
|
935
|
+
function valuesOverlap(left, right, matches) {
|
|
936
|
+
return left.some((leftValue) => right.some((rightValue) => matches(leftValue, rightValue)));
|
|
937
|
+
}
|
|
938
|
+
function resolveDocsSearchPageScope(page) {
|
|
939
|
+
const topFramework = normalizeDocsSearchMetadataValues("framework", page.framework);
|
|
940
|
+
const contractFramework = normalizeDocsSearchMetadataValues("framework", page.agent?.appliesTo?.framework);
|
|
941
|
+
const topVersion = normalizeDocsSearchMetadataValues("version", page.version);
|
|
942
|
+
const contractVersion = normalizeDocsSearchMetadataValues("version", page.agent?.appliesTo?.version);
|
|
943
|
+
const packageValues = normalizeDocsSearchMetadataValues("package", page.agent?.appliesTo?.package);
|
|
944
|
+
const tags = normalizeDocsSearchMetadataValues("tags", page.tags);
|
|
945
|
+
const conflicts = [];
|
|
946
|
+
if (topFramework.length > 0 && contractFramework.length > 0 && !valuesOverlap(topFramework, contractFramework, (left, right) => left === right)) conflicts.push("framework");
|
|
947
|
+
if (topVersion.length > 0 && contractVersion.length > 0 && !valuesOverlap(topVersion, contractVersion, agentVersionConstraintsOverlap)) conflicts.push("version");
|
|
948
|
+
return {
|
|
949
|
+
framework: topFramework.length > 0 && contractFramework.length > 0 ? topFramework.filter((value) => contractFramework.includes(value)) : Array.from(new Set([...topFramework, ...contractFramework])),
|
|
950
|
+
version: Array.from(new Set([...topVersion, ...contractVersion])),
|
|
951
|
+
package: packageValues,
|
|
952
|
+
tags,
|
|
953
|
+
declarations: {
|
|
954
|
+
framework: [topFramework, contractFramework].filter((values) => values.length > 0),
|
|
955
|
+
version: [topVersion, contractVersion].filter((values) => values.length > 0),
|
|
956
|
+
package: packageValues.length > 0 ? [packageValues] : [],
|
|
957
|
+
tags: tags.length > 0 ? [tags] : []
|
|
958
|
+
},
|
|
959
|
+
conflicts
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function docsSearchScopeValueMatches(field, requested, candidate) {
|
|
963
|
+
return field === "version" ? agentVersionConstraintsOverlap(requested, candidate) : requested === candidate;
|
|
964
|
+
}
|
|
965
|
+
function docsSearchPageMatchesFilters(scope, filters) {
|
|
966
|
+
if (scope.conflicts.length > 0) return false;
|
|
967
|
+
return SEARCH_FILTER_FIELDS.every((field) => {
|
|
968
|
+
const requested = filters[field];
|
|
969
|
+
if (!requested || requested.length === 0) return true;
|
|
970
|
+
return docsSearchScopeFieldMatches(scope, field, requested);
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
function docsSearchScopeFieldMatches(scope, field, requested) {
|
|
974
|
+
const declarations = scope.declarations[field];
|
|
975
|
+
if (declarations.length === 0) return false;
|
|
976
|
+
if (field === "version") return agentVersionConstraintGroupsOverlap([requested, ...declarations]);
|
|
977
|
+
return requested.some((value) => declarations.every((candidates) => candidates.some((candidate) => docsSearchScopeValueMatches(field, value, candidate))));
|
|
978
|
+
}
|
|
501
979
|
function stripMarkdownText(content) {
|
|
502
980
|
return removeMdxModuleLinesOutsideFences(content).replace(/```[^\n]*\n([\s\S]*?)```/g, "$1").replace(/```([\s\S]*?)```/g, "$1").replace(/~~~[^\n]*\n([\s\S]*?)~~~/g, "$1").replace(/~~~([\s\S]*?)~~~/g, "$1").replace(/<[^>]+\/>/g, "").replace(/<\/?[A-Z][^>]*>/g, "").replace(/<\/?[a-z][^>]*>/g, "").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^\|?[\s:-]+(\|[\s:-]+)+\|?\s*$/gm, "").replace(/\|/g, " ").replace(/^[-*+]\s+/gm, "").replace(/(\*{1,3}|_{1,3})(.*?)\1/g, "$2").replace(/`{3,}[^\n]*$/gm, "").replace(/`([^`]+)`/g, "$1").replace(/`+/g, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}\s*$/gm, "").replace(/\n{3,}/g, "\n\n").replace(/\s{2,}/g, " ").trim();
|
|
503
981
|
}
|
|
@@ -567,8 +1045,14 @@ function resolveAskAIContextUrl(value, baseUrl) {
|
|
|
567
1045
|
return value;
|
|
568
1046
|
}
|
|
569
1047
|
}
|
|
1048
|
+
function cleanGeneratedAgentContractMarkers(content) {
|
|
1049
|
+
return stripDocsGeneratedAgentContractMarkers(content);
|
|
1050
|
+
}
|
|
1051
|
+
function getAskAIPageSectionContent(page) {
|
|
1052
|
+
return getPageAudienceSectionContent(page, "agent");
|
|
1053
|
+
}
|
|
570
1054
|
function getAskAIPageContent(page) {
|
|
571
|
-
return
|
|
1055
|
+
return cleanGeneratedAgentContractMarkers(getAskAIPageSectionContent(page));
|
|
572
1056
|
}
|
|
573
1057
|
function getPageAgentContractSearchText(page) {
|
|
574
1058
|
return stripMarkdownText(renderPageAgentContractMarkdown(page.agent).replace(PAGE_AGENT_CONTRACT_START_MARKER, "").replace(PAGE_AGENT_CONTRACT_END_MARKER, ""));
|
|
@@ -668,7 +1152,7 @@ function formatAskAIContextResult(options) {
|
|
|
668
1152
|
const title = inferResultTitle(result, page);
|
|
669
1153
|
const section = result.section;
|
|
670
1154
|
const sectionSelector = getSearchResultAnchor(result.url) ?? section;
|
|
671
|
-
const contextContent = clampText(cleanAskAIContextMarkdown(page ? sectionSelector ? findDocsMarkdownSection(
|
|
1155
|
+
const contextContent = clampText(cleanAskAIContextMarkdown(page ? sectionSelector ? cleanGeneratedAgentContractMarkers(findDocsMarkdownSection(getAskAIPageSectionContent(page), sectionSelector)?.content ?? "") : getAskAIPageContent(page) : [result.content, result.description].filter(Boolean).join("\n\n")), maxChars);
|
|
672
1156
|
return {
|
|
673
1157
|
...result,
|
|
674
1158
|
url: resolveAskAIContextUrl(result.url, baseUrl),
|
|
@@ -677,20 +1161,17 @@ function formatAskAIContextResult(options) {
|
|
|
677
1161
|
};
|
|
678
1162
|
}
|
|
679
1163
|
function getSearchResultKey(result) {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
} catch {
|
|
684
|
-
hash = result.url.split("#")[1]?.split(/[?&]/)[0] ?? "";
|
|
685
|
-
}
|
|
686
|
-
return `${normalizeUrlPathname(result.url)}#${normalizeWhitespace(hash || result.section || "").toLowerCase()}`;
|
|
1164
|
+
const anchor = getSearchResultAnchor(result.url);
|
|
1165
|
+
const sectionFallback = normalizeWhitespace(result.section ?? "").toLowerCase();
|
|
1166
|
+
return `${normalizeUrlPathname(result.url)}#${anchor ?? sectionFallback}`;
|
|
687
1167
|
}
|
|
688
1168
|
function getSearchResultAnchor(value) {
|
|
689
1169
|
let hash = "";
|
|
690
1170
|
try {
|
|
691
1171
|
hash = new URL(value, "https://docs.local").hash.replace(/^#/, "");
|
|
692
1172
|
} catch {
|
|
693
|
-
|
|
1173
|
+
const hashIndex = value.indexOf("#");
|
|
1174
|
+
hash = hashIndex >= 0 ? value.slice(hashIndex + 1) : "";
|
|
694
1175
|
}
|
|
695
1176
|
if (!hash) return void 0;
|
|
696
1177
|
try {
|
|
@@ -714,7 +1195,9 @@ function getAskAIResultPageKey(value, baseUrl, strictExternalOrigins = false) {
|
|
|
714
1195
|
}
|
|
715
1196
|
}
|
|
716
1197
|
function getAskAIResultKey(result, baseUrl, strictExternalOrigins = false) {
|
|
717
|
-
|
|
1198
|
+
const anchor = getSearchResultAnchor(result.url);
|
|
1199
|
+
const sectionFallback = normalizeWhitespace(result.section ?? "").toLowerCase();
|
|
1200
|
+
return `${getAskAIResultPageKey(result.url, baseUrl, strictExternalOrigins)}#${anchor ?? sectionFallback}`;
|
|
718
1201
|
}
|
|
719
1202
|
function mergeSearchResults(groups, getResultKey = getSearchResultKey) {
|
|
720
1203
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -790,6 +1273,10 @@ function shouldPreserveUnmatchedExternalResult(options) {
|
|
|
790
1273
|
function getPageAudienceRawContent(page, audience) {
|
|
791
1274
|
return resolveDocsAudienceMdxContent(audience === "agent" ? page.agentRawContent ?? page.agentFallbackRawContent ?? page.agentContent ?? page.agentFallbackContent ?? page.rawContent ?? page.content : page.rawContent ?? page.content, audience);
|
|
792
1275
|
}
|
|
1276
|
+
function getPageAudienceSectionContent(page, audience) {
|
|
1277
|
+
const content = getPageAudienceRawContent(page, audience);
|
|
1278
|
+
return audience === "agent" ? upsertPageAgentContractMarkdown(content, page.agent) : content;
|
|
1279
|
+
}
|
|
793
1280
|
function getPageAudienceSearchText(page, audience) {
|
|
794
1281
|
return stripMarkdownText(getPageAudienceRawContent(page, audience));
|
|
795
1282
|
}
|
|
@@ -830,6 +1317,7 @@ function hasOppositeAudienceEvidence(options) {
|
|
|
830
1317
|
return oppositeOnlyMatches > selectedOnlyMatches;
|
|
831
1318
|
}
|
|
832
1319
|
function pageToSearchDocument(page, audience = "human") {
|
|
1320
|
+
const scope = resolveDocsSearchPageScope(page);
|
|
833
1321
|
return {
|
|
834
1322
|
id: makeDocumentId(page.url, "page"),
|
|
835
1323
|
url: page.url,
|
|
@@ -838,9 +1326,10 @@ function pageToSearchDocument(page, audience = "human") {
|
|
|
838
1326
|
description: page.description,
|
|
839
1327
|
type: "page",
|
|
840
1328
|
locale: page.locale,
|
|
841
|
-
framework:
|
|
842
|
-
version:
|
|
843
|
-
|
|
1329
|
+
framework: scope.framework[0],
|
|
1330
|
+
version: scope.version[0],
|
|
1331
|
+
package: scope.package.length > 0 ? scope.package : void 0,
|
|
1332
|
+
tags: scope.tags.length > 0 ? scope.tags : void 0
|
|
844
1333
|
};
|
|
845
1334
|
}
|
|
846
1335
|
function buildExactPageSearchResults(query, pages, audience = "human") {
|
|
@@ -903,21 +1392,29 @@ function makeDocumentId(url, suffix) {
|
|
|
903
1392
|
return `${url}#${suffix}`;
|
|
904
1393
|
}
|
|
905
1394
|
function splitPageIntoSections(page, audience = "human") {
|
|
906
|
-
|
|
1395
|
+
const raw = getPageAudienceSectionContent(page, audience);
|
|
1396
|
+
const generatedContract = audience === "agent" ? findDocsGeneratedAgentContractRanges(raw)[0] : void 0;
|
|
1397
|
+
const scope = resolveDocsSearchPageScope(page);
|
|
1398
|
+
let documentIndex = 0;
|
|
1399
|
+
return parseDocsMarkdownSections(raw).flatMap((section) => {
|
|
1400
|
+
if (generatedContract && section.startLine > generatedContract.startLine && section.startLine < generatedContract.endLine) return [];
|
|
907
1401
|
const content = normalizeWhitespace(stripMarkdownText(section.content));
|
|
908
1402
|
if (!content) return [];
|
|
1403
|
+
const index = documentIndex;
|
|
1404
|
+
documentIndex += 1;
|
|
909
1405
|
return [{
|
|
910
1406
|
id: makeDocumentId(page.url, `section-${index}`),
|
|
911
|
-
url: `${page.url}#${section.anchor}`,
|
|
1407
|
+
url: `${page.url.split("#", 1)[0]}#${encodeURIComponent(section.anchor)}`,
|
|
912
1408
|
title: page.title,
|
|
913
1409
|
section: section.title,
|
|
914
1410
|
content,
|
|
915
1411
|
description: page.description,
|
|
916
1412
|
type: "heading",
|
|
917
1413
|
locale: page.locale,
|
|
918
|
-
framework:
|
|
919
|
-
version:
|
|
920
|
-
|
|
1414
|
+
framework: scope.framework[0],
|
|
1415
|
+
version: scope.version[0],
|
|
1416
|
+
package: scope.package.length > 0 ? scope.package : void 0,
|
|
1417
|
+
tags: scope.tags.length > 0 ? scope.tags : void 0
|
|
921
1418
|
}];
|
|
922
1419
|
});
|
|
923
1420
|
}
|
|
@@ -1055,7 +1552,12 @@ function buildAlgoliaRecord(document) {
|
|
|
1055
1552
|
section: document.section,
|
|
1056
1553
|
content: document.content,
|
|
1057
1554
|
description: document.description,
|
|
1058
|
-
type: document.type
|
|
1555
|
+
type: document.type,
|
|
1556
|
+
locale: document.locale,
|
|
1557
|
+
framework: document.framework,
|
|
1558
|
+
version: document.version,
|
|
1559
|
+
package: document.package,
|
|
1560
|
+
tags: document.tags
|
|
1059
1561
|
};
|
|
1060
1562
|
const encoder = new TextEncoder();
|
|
1061
1563
|
const sizeOf = (value) => encoder.encode(JSON.stringify(value)).length;
|
|
@@ -1160,6 +1662,14 @@ function mapMcpSearchResult(value) {
|
|
|
1160
1662
|
section
|
|
1161
1663
|
};
|
|
1162
1664
|
}
|
|
1665
|
+
function readMcpSearchToolPayload(payload) {
|
|
1666
|
+
if (!payload || typeof payload !== "object" || !("result" in payload) || !payload.result || typeof payload.result !== "object") return null;
|
|
1667
|
+
const result = payload.result;
|
|
1668
|
+
if (result.structuredContent && typeof result.structuredContent === "object" && !Array.isArray(result.structuredContent)) return result.structuredContent;
|
|
1669
|
+
const content = Array.isArray(result.content) ? result.content : [];
|
|
1670
|
+
const resultText = content.length > 0 && content[0] && typeof content[0] === "object" && "text" in content[0] && typeof content[0].text === "string" ? content[0].text : null;
|
|
1671
|
+
return resultText ? JSON.parse(resultText) : null;
|
|
1672
|
+
}
|
|
1163
1673
|
async function createOllamaEmbedding(text, config, signal) {
|
|
1164
1674
|
const response = await fetch(`${(config.baseUrl ?? "http://127.0.0.1:11434").replace(/\/$/, "")}/api/embed`, {
|
|
1165
1675
|
method: "POST",
|
|
@@ -1179,6 +1689,9 @@ async function createOllamaEmbedding(text, config, signal) {
|
|
|
1179
1689
|
function getTypesenseSearchBase(config) {
|
|
1180
1690
|
return config.baseUrl.replace(/\/$/, "");
|
|
1181
1691
|
}
|
|
1692
|
+
function quoteTypesenseFilterValue(value) {
|
|
1693
|
+
return `\`${value.replace(/\\/gu, "\\\\").replace(/`/gu, "\\`")}\``;
|
|
1694
|
+
}
|
|
1182
1695
|
async function ensureTypesenseCollection(config, dimensions, signal) {
|
|
1183
1696
|
const baseUrl = getTypesenseSearchBase(config);
|
|
1184
1697
|
const headers = {
|
|
@@ -1237,6 +1750,11 @@ async function ensureTypesenseCollection(config, dimensions, signal) {
|
|
|
1237
1750
|
type: "string",
|
|
1238
1751
|
optional: true
|
|
1239
1752
|
},
|
|
1753
|
+
{
|
|
1754
|
+
name: "package",
|
|
1755
|
+
type: "string[]",
|
|
1756
|
+
optional: true
|
|
1757
|
+
},
|
|
1240
1758
|
{
|
|
1241
1759
|
name: "tags",
|
|
1242
1760
|
type: "string[]",
|
|
@@ -1276,6 +1794,7 @@ function createTypesenseSearchAdapter(config) {
|
|
|
1276
1794
|
locale: document.locale,
|
|
1277
1795
|
framework: document.framework,
|
|
1278
1796
|
version: document.version,
|
|
1797
|
+
package: document.package,
|
|
1279
1798
|
tags: document.tags
|
|
1280
1799
|
};
|
|
1281
1800
|
if (config.mode === "hybrid" && config.embeddings) next.embedding = await createOllamaEmbedding(`${document.title}\n${document.section ?? ""}\n${document.content}`.trim(), config.embeddings, context.signal);
|
|
@@ -1294,6 +1813,8 @@ function createTypesenseSearchAdapter(config) {
|
|
|
1294
1813
|
}), "Failed to sync documents to Typesense");
|
|
1295
1814
|
},
|
|
1296
1815
|
async search(query, context) {
|
|
1816
|
+
const scopedDocumentIds = resolveProviderScopeDocumentIds(query, context);
|
|
1817
|
+
if (scopedDocumentIds?.length === 0) return [];
|
|
1297
1818
|
const params = new URLSearchParams({
|
|
1298
1819
|
q: query.query,
|
|
1299
1820
|
query_by: (config.queryBy ?? [
|
|
@@ -1311,12 +1832,27 @@ function createTypesenseSearchAdapter(config) {
|
|
|
1311
1832
|
const vector = await createOllamaEmbedding(query.query, config.embeddings, context.signal);
|
|
1312
1833
|
params.set("vector_query", `embedding:([${vector.join(",")}],k:${Math.max((query.limit ?? 10) * 4, 20)})`);
|
|
1313
1834
|
}
|
|
1314
|
-
const
|
|
1835
|
+
const filterBy = scopedDocumentIds ? `id:=[${scopedDocumentIds.map(quoteTypesenseFilterValue).join(",")}]` : void 0;
|
|
1836
|
+
if (filterBy && filterBy.length > MAX_PROVIDER_SCOPE_FILTER_CHARS) return [];
|
|
1837
|
+
const response = filterBy ? await fetch(`${getTypesenseSearchBase(config)}/multi_search`, {
|
|
1838
|
+
method: "POST",
|
|
1839
|
+
headers: {
|
|
1840
|
+
"Content-Type": "application/json",
|
|
1841
|
+
"X-TYPESENSE-API-KEY": config.apiKey
|
|
1842
|
+
},
|
|
1843
|
+
body: JSON.stringify({ searches: [{
|
|
1844
|
+
collection: config.collection,
|
|
1845
|
+
...Object.fromEntries(params),
|
|
1846
|
+
filter_by: filterBy
|
|
1847
|
+
}] }),
|
|
1848
|
+
signal: context.signal
|
|
1849
|
+
}) : await fetch(`${getTypesenseSearchBase(config)}/collections/${encodeURIComponent(config.collection)}/documents/search?${params.toString()}`, {
|
|
1315
1850
|
headers: { "X-TYPESENSE-API-KEY": config.apiKey },
|
|
1316
1851
|
signal: context.signal
|
|
1317
1852
|
});
|
|
1318
1853
|
ensureOk(response, "Typesense search failed");
|
|
1319
|
-
|
|
1854
|
+
const rawPayload = await readResponseJson(response);
|
|
1855
|
+
return ((filterBy ? rawPayload.results?.[0] ?? {} : rawPayload).hits ?? []).map((hit) => {
|
|
1320
1856
|
const document = hit.document ?? {};
|
|
1321
1857
|
const section = typeof document.section === "string" ? document.section : void 0;
|
|
1322
1858
|
const content = typeof document.title === "string" ? section ? `${document.title} — ${section}` : document.title : typeof document.content === "string" ? document.content : "Untitled result";
|
|
@@ -1427,7 +1963,11 @@ function createMcpSearchAdapter(config) {
|
|
|
1427
1963
|
query: query.query,
|
|
1428
1964
|
limit: query.limit ?? config.maxResults ?? DEFAULT_SEARCH_LIMIT,
|
|
1429
1965
|
locale: query.locale,
|
|
1430
|
-
...forwardAudience ? { audience } : {}
|
|
1966
|
+
...forwardAudience ? { audience } : {},
|
|
1967
|
+
...query.filters?.framework ? { framework: query.filters.framework } : {},
|
|
1968
|
+
...query.filters?.version ? { version: query.filters.version } : {},
|
|
1969
|
+
...query.filters?.package ? { package: query.filters.package } : {},
|
|
1970
|
+
...query.filters?.tags ? { tags: query.filters.tags } : {}
|
|
1431
1971
|
}
|
|
1432
1972
|
}
|
|
1433
1973
|
}),
|
|
@@ -1436,9 +1976,13 @@ function createMcpSearchAdapter(config) {
|
|
|
1436
1976
|
const payload = await readMcpResponsePayload(searchResponse);
|
|
1437
1977
|
ensureOk(searchResponse, "MCP search request failed");
|
|
1438
1978
|
ensureJsonRpcOk(payload, "MCP search request failed");
|
|
1439
|
-
const
|
|
1440
|
-
if (!
|
|
1441
|
-
|
|
1979
|
+
const parsed = readMcpSearchToolPayload(payload);
|
|
1980
|
+
if (!parsed) return [];
|
|
1981
|
+
if (hasDocsSearchFilters(query.filters ?? {})) {
|
|
1982
|
+
if (Array.isArray(parsed) || parsed.format !== "docs-search.v1") return [];
|
|
1983
|
+
const echoedFilters = parseVerifiedMcpSearchFilters(parsed.filters);
|
|
1984
|
+
if (!echoedFilters || !docsSearchFiltersMatch(query.filters ?? {}, echoedFilters)) return [];
|
|
1985
|
+
}
|
|
1442
1986
|
return (Array.isArray(parsed) ? parsed : Array.isArray(parsed.results) ? parsed.results : Array.isArray(parsed.pages) ? parsed.pages : []).map(mapMcpSearchResult).filter((result) => Boolean(result));
|
|
1443
1987
|
} finally {
|
|
1444
1988
|
if (sessionId) {
|
|
@@ -1465,6 +2009,9 @@ function createMcpSearchAdapter(config) {
|
|
|
1465
2009
|
function getAlgoliaBase(config) {
|
|
1466
2010
|
return `https://${config.appId}-dsn.algolia.net`;
|
|
1467
2011
|
}
|
|
2012
|
+
function quoteAlgoliaFilterValue(value) {
|
|
2013
|
+
return `"${value.replace(/\\/gu, "\\\\").replace(/"/gu, "\\\"")}"`;
|
|
2014
|
+
}
|
|
1468
2015
|
function createAlgoliaSearchAdapter(config) {
|
|
1469
2016
|
return {
|
|
1470
2017
|
name: "algolia",
|
|
@@ -1485,6 +2032,10 @@ function createAlgoliaSearchAdapter(config) {
|
|
|
1485
2032
|
}), "Failed to sync documents to Algolia");
|
|
1486
2033
|
},
|
|
1487
2034
|
async search(query, context) {
|
|
2035
|
+
const scopedDocumentIds = resolveProviderScopeDocumentIds(query, context);
|
|
2036
|
+
if (scopedDocumentIds?.length === 0) return [];
|
|
2037
|
+
const filters = scopedDocumentIds?.map((id) => `objectID:${quoteAlgoliaFilterValue(id)}`).join(" OR ");
|
|
2038
|
+
if (filters && filters.length > MAX_PROVIDER_SCOPE_FILTER_CHARS) return [];
|
|
1488
2039
|
const response = await fetch(`${getAlgoliaBase(config)}/1/indexes/${encodeURIComponent(config.indexName)}/query`, {
|
|
1489
2040
|
method: "POST",
|
|
1490
2041
|
headers: {
|
|
@@ -1495,7 +2046,8 @@ function createAlgoliaSearchAdapter(config) {
|
|
|
1495
2046
|
body: JSON.stringify({
|
|
1496
2047
|
query: query.query,
|
|
1497
2048
|
hitsPerPage: query.limit ?? config.maxResults ?? DEFAULT_SEARCH_LIMIT,
|
|
1498
|
-
attributesToSnippet: ["content:20"]
|
|
2049
|
+
attributesToSnippet: ["content:20"],
|
|
2050
|
+
...filters ? { filters } : {}
|
|
1499
2051
|
}),
|
|
1500
2052
|
signal: context.signal
|
|
1501
2053
|
});
|
|
@@ -1552,10 +2104,22 @@ async function performDocsSearch(options) {
|
|
|
1552
2104
|
const search = normalizeDocsSearchConfig(options.search);
|
|
1553
2105
|
if (!search.enabled) return [];
|
|
1554
2106
|
const audience = resolveDocsSearchAudience(options.audience);
|
|
1555
|
-
const
|
|
2107
|
+
const filters = normalizeDocsSearchFilters(options.filters);
|
|
2108
|
+
const hasFilters = hasDocsSearchFilters(filters);
|
|
2109
|
+
const scopedPages = hasFilters ? options.pages.filter((page) => docsSearchPageMatchesFilters(resolveDocsSearchPageScope(page), filters)) : options.pages;
|
|
2110
|
+
let resolvedDocuments;
|
|
2111
|
+
const getDocuments = () => {
|
|
2112
|
+
if (!resolvedDocuments) resolvedDocuments = buildDocsSearchDocuments(scopedPages, search.chunking, audience);
|
|
2113
|
+
return resolvedDocuments;
|
|
2114
|
+
};
|
|
1556
2115
|
const context = {
|
|
1557
|
-
pages:
|
|
1558
|
-
documents
|
|
2116
|
+
pages: scopedPages,
|
|
2117
|
+
get documents() {
|
|
2118
|
+
return getDocuments();
|
|
2119
|
+
},
|
|
2120
|
+
set documents(documents) {
|
|
2121
|
+
resolvedDocuments = documents;
|
|
2122
|
+
},
|
|
1559
2123
|
audience,
|
|
1560
2124
|
locale: options.locale,
|
|
1561
2125
|
pathname: options.pathname,
|
|
@@ -1567,27 +2131,41 @@ async function performDocsSearch(options) {
|
|
|
1567
2131
|
limit: options.limit ?? search.maxResults,
|
|
1568
2132
|
locale: options.locale,
|
|
1569
2133
|
pathname: options.pathname,
|
|
1570
|
-
audience
|
|
2134
|
+
audience,
|
|
2135
|
+
...hasFilters ? { filters } : {}
|
|
1571
2136
|
};
|
|
1572
2137
|
try {
|
|
1573
2138
|
const adapter = await resolveSearchAdapter(search, context);
|
|
1574
|
-
await maybeSyncSearchIndex(adapter, search, audience === "agent" ? {
|
|
1575
|
-
|
|
2139
|
+
if (shouldSyncOnSearch(search) && typeof adapter.index === "function") await maybeSyncSearchIndex(adapter, search, audience === "agent" || hasFilters ? {
|
|
2140
|
+
pages: options.pages,
|
|
1576
2141
|
documents: buildDocsSearchDocuments(options.pages, search.chunking, "human"),
|
|
1577
|
-
audience: "human"
|
|
2142
|
+
audience: "human",
|
|
2143
|
+
locale: options.locale,
|
|
2144
|
+
pathname: options.pathname,
|
|
2145
|
+
siteTitle: options.siteTitle,
|
|
2146
|
+
signal: options.signal
|
|
1578
2147
|
} : context);
|
|
1579
|
-
const
|
|
2148
|
+
const adapterSearch = adapter.search(query, context);
|
|
2149
|
+
let documents;
|
|
2150
|
+
try {
|
|
2151
|
+
documents = getDocuments();
|
|
2152
|
+
} catch (error) {
|
|
2153
|
+
adapterSearch.catch(() => void 0);
|
|
2154
|
+
throw error;
|
|
2155
|
+
}
|
|
2156
|
+
const results = await adapterSearch;
|
|
1580
2157
|
if (search.provider === "simple") return results;
|
|
1581
2158
|
const localAudienceProjectionResults = buildAudienceProjectionSearchResults(documents, options.query);
|
|
1582
|
-
const localPagePaths = new Set(
|
|
1583
|
-
const
|
|
2159
|
+
const localPagePaths = new Set(scopedPages.map((page) => normalizeUrlPathname(page.url)));
|
|
2160
|
+
const allLocalPagePaths = hasFilters && search.provider === "mcp" ? new Set(options.pages.map((page) => normalizeUrlPathname(page.url))) : localPagePaths;
|
|
2161
|
+
const preserveUnmatched = !hasFilters && audience === "human" || search.provider === "mcp" ? (result) => shouldPreserveUnmatchedExternalResult({
|
|
1584
2162
|
result,
|
|
1585
|
-
localPagePaths,
|
|
2163
|
+
localPagePaths: allLocalPagePaths,
|
|
1586
2164
|
baseUrl: options.baseUrl
|
|
1587
2165
|
}) : void 0;
|
|
1588
2166
|
const safeAdapterResults = sanitizeExternalAudienceSearchResults(results.filter((result) => !hasOppositeAudienceEvidence({
|
|
1589
2167
|
result,
|
|
1590
|
-
pages:
|
|
2168
|
+
pages: scopedPages,
|
|
1591
2169
|
query: options.query,
|
|
1592
2170
|
audience,
|
|
1593
2171
|
baseUrl: options.baseUrl,
|
|
@@ -1596,7 +2174,7 @@ async function performDocsSearch(options) {
|
|
|
1596
2174
|
if (options.supplementExternalResults === false) return safeAdapterResults.slice(0, query.limit ?? search.maxResults ?? DEFAULT_SEARCH_LIMIT);
|
|
1597
2175
|
const simpleAudienceResults = audience === "agent" || results.length === 0 || safeAdapterResults.length < results.length ? await createSimpleSearchAdapter().search(query, context) : [];
|
|
1598
2176
|
const combinedResults = mergeSearchResults([
|
|
1599
|
-
buildExactPageSearchResults(options.query,
|
|
2177
|
+
buildExactPageSearchResults(options.query, scopedPages, audience),
|
|
1600
2178
|
safeAdapterResults,
|
|
1601
2179
|
simpleAudienceResults
|
|
1602
2180
|
], audience === "agent" ? (result) => getAskAIResultKey(result, options.baseUrl, options.strictExternalOrigins) : void 0);
|
|
@@ -1606,6 +2184,127 @@ async function performDocsSearch(options) {
|
|
|
1606
2184
|
return createSimpleSearchAdapter().search(query, context);
|
|
1607
2185
|
}
|
|
1608
2186
|
}
|
|
2187
|
+
function compareSearchMetadataValues(left, right) {
|
|
2188
|
+
if (left === right) return 0;
|
|
2189
|
+
return left < right ? -1 : 1;
|
|
2190
|
+
}
|
|
2191
|
+
function boundedSearchWarningValues(values) {
|
|
2192
|
+
const bounded = Array.from(new Set(values)).sort(compareSearchMetadataValues).slice(0, MAX_SEARCH_WARNING_VALUES);
|
|
2193
|
+
return bounded.length > 0 ? bounded : void 0;
|
|
2194
|
+
}
|
|
2195
|
+
function boundedSearchWarningPageUrls(pages) {
|
|
2196
|
+
const bounded = Array.from(new Set(pages.map((page) => page.url))).sort(compareSearchMetadataValues).slice(0, MAX_SEARCH_WARNING_PAGE_URLS);
|
|
2197
|
+
return bounded.length > 0 ? bounded : void 0;
|
|
2198
|
+
}
|
|
2199
|
+
function findSearchResultPages(pages, results, baseUrl) {
|
|
2200
|
+
const pagesByPath = new Map(pages.map((page) => [normalizeUrlPathname(page.url), page]));
|
|
2201
|
+
const found = /* @__PURE__ */ new Map();
|
|
2202
|
+
for (const result of results) {
|
|
2203
|
+
if (!isLocalProviderResult(result, baseUrl, true)) continue;
|
|
2204
|
+
const page = pagesByPath.get(normalizeUrlPathname(result.url));
|
|
2205
|
+
if (page) found.set(page.url, page);
|
|
2206
|
+
}
|
|
2207
|
+
return [...found.values()].sort((left, right) => compareSearchMetadataValues(left.url, right.url));
|
|
2208
|
+
}
|
|
2209
|
+
function searchScopeIsAmbiguous(field, values) {
|
|
2210
|
+
if (values.length < 2) return false;
|
|
2211
|
+
if (field !== "version") return true;
|
|
2212
|
+
return values.some((left, index) => values.slice(index + 1).some((right) => !agentVersionConstraintsOverlap(left, right)));
|
|
2213
|
+
}
|
|
2214
|
+
function buildDocsSearchWarnings(options) {
|
|
2215
|
+
const pageScopes = options.pages.map((page) => ({
|
|
2216
|
+
page,
|
|
2217
|
+
scope: resolveDocsSearchPageScope(page)
|
|
2218
|
+
}));
|
|
2219
|
+
const relevantPageScopes = pageScopes.filter(({ page }) => scoreDocument(options.query, pageToSearchDocument(page, options.audience)) > 0);
|
|
2220
|
+
const warnings = [];
|
|
2221
|
+
for (const field of SEARCH_FILTER_FIELDS) {
|
|
2222
|
+
const conflicting = relevantPageScopes.filter(({ scope }) => scope.conflicts.includes(field));
|
|
2223
|
+
if (conflicting.length > 0) warnings.push({
|
|
2224
|
+
code: "conflicting_scope_metadata",
|
|
2225
|
+
field,
|
|
2226
|
+
message: `${conflicting.length} page${conflicting.length === 1 ? "" : "s"} declare conflicting ${field} metadata and cannot be selected safely by scoped search.`,
|
|
2227
|
+
pageUrls: boundedSearchWarningPageUrls(conflicting.map(({ page }) => page)),
|
|
2228
|
+
count: conflicting.length
|
|
2229
|
+
});
|
|
2230
|
+
const requested = options.filters[field];
|
|
2231
|
+
if (!requested || requested.length === 0) continue;
|
|
2232
|
+
const missing = relevantPageScopes.filter(({ scope }) => scope.declarations[field].length === 0);
|
|
2233
|
+
if (missing.length > 0) warnings.push({
|
|
2234
|
+
code: "missing_scope_metadata",
|
|
2235
|
+
field,
|
|
2236
|
+
message: `${missing.length} page${missing.length === 1 ? "" : "s"} lack ${field} metadata and were excluded by the strict scope filter.`,
|
|
2237
|
+
pageUrls: boundedSearchWarningPageUrls(missing.map(({ page }) => page)),
|
|
2238
|
+
count: missing.length
|
|
2239
|
+
});
|
|
2240
|
+
const unknown = requested.filter((value) => !pageScopes.some(({ scope }) => !scope.conflicts.includes(field) && docsSearchScopeFieldMatches(scope, field, [value])));
|
|
2241
|
+
if (unknown.length > 0) warnings.push({
|
|
2242
|
+
code: "unknown_filter_value",
|
|
2243
|
+
field,
|
|
2244
|
+
message: `No page metadata matches ${field} filter value${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}.`,
|
|
2245
|
+
values: boundedSearchWarningValues(unknown),
|
|
2246
|
+
count: unknown.length
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
const resultPages = findSearchResultPages(options.pages, options.results, options.baseUrl);
|
|
2250
|
+
for (const field of SEARCH_AMBIGUITY_FIELDS) {
|
|
2251
|
+
if ((options.filters[field]?.length ?? 0) > 0) continue;
|
|
2252
|
+
const values = resultPages.flatMap((page) => {
|
|
2253
|
+
const scope = resolveDocsSearchPageScope(page);
|
|
2254
|
+
return scope.conflicts.includes(field) ? [] : scope[field];
|
|
2255
|
+
});
|
|
2256
|
+
const unique = Array.from(new Set(values)).sort(compareSearchMetadataValues);
|
|
2257
|
+
if (!searchScopeIsAmbiguous(field, unique)) continue;
|
|
2258
|
+
const contributingPages = resultPages.filter((page) => {
|
|
2259
|
+
const scope = resolveDocsSearchPageScope(page);
|
|
2260
|
+
return !scope.conflicts.includes(field) && scope[field].length > 0;
|
|
2261
|
+
});
|
|
2262
|
+
warnings.push({
|
|
2263
|
+
code: "ambiguous_scope",
|
|
2264
|
+
field,
|
|
2265
|
+
message: `Search results span multiple ${field} scopes; add a ${field} filter before acting on scope-specific guidance.`,
|
|
2266
|
+
values: boundedSearchWarningValues(unique),
|
|
2267
|
+
pageUrls: boundedSearchWarningPageUrls(contributingPages),
|
|
2268
|
+
count: unique.length
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
const codeOrder = {
|
|
2272
|
+
ambiguous_scope: 0,
|
|
2273
|
+
unknown_filter_value: 1,
|
|
2274
|
+
missing_scope_metadata: 2,
|
|
2275
|
+
conflicting_scope_metadata: 3
|
|
2276
|
+
};
|
|
2277
|
+
return warnings.sort((left, right) => {
|
|
2278
|
+
const codeDelta = codeOrder[left.code] - codeOrder[right.code];
|
|
2279
|
+
if (codeDelta !== 0) return codeDelta;
|
|
2280
|
+
return SEARCH_FILTER_FIELDS.indexOf(left.field) - SEARCH_FILTER_FIELDS.indexOf(right.field);
|
|
2281
|
+
}).slice(0, MAX_SEARCH_WARNINGS);
|
|
2282
|
+
}
|
|
2283
|
+
async function performDocsSearchWithMetadata(options) {
|
|
2284
|
+
const audience = resolveDocsSearchAudience(options.audience);
|
|
2285
|
+
const filters = normalizeDocsSearchFilters(options.filters);
|
|
2286
|
+
const results = await performDocsSearch({
|
|
2287
|
+
...options,
|
|
2288
|
+
audience,
|
|
2289
|
+
filters
|
|
2290
|
+
});
|
|
2291
|
+
return {
|
|
2292
|
+
format: "docs-search.v1",
|
|
2293
|
+
query: options.query,
|
|
2294
|
+
audience,
|
|
2295
|
+
filters,
|
|
2296
|
+
resultCount: results.length,
|
|
2297
|
+
results,
|
|
2298
|
+
warnings: buildDocsSearchWarnings({
|
|
2299
|
+
pages: options.pages,
|
|
2300
|
+
results,
|
|
2301
|
+
filters,
|
|
2302
|
+
query: options.query,
|
|
2303
|
+
audience,
|
|
2304
|
+
baseUrl: options.baseUrl
|
|
2305
|
+
})
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
1609
2308
|
async function buildDocsAskAIContext(options) {
|
|
1610
2309
|
const limit = options.limit ?? 5;
|
|
1611
2310
|
const searchLimit = Math.max(limit * 2, limit);
|
|
@@ -1621,6 +2320,7 @@ async function buildDocsAskAIContext(options) {
|
|
|
1621
2320
|
siteTitle: options.siteTitle,
|
|
1622
2321
|
baseUrl: options.baseUrl,
|
|
1623
2322
|
limit: searchLimit,
|
|
2323
|
+
filters: options.filters,
|
|
1624
2324
|
failureMode: options.searchFailureMode,
|
|
1625
2325
|
strictExternalOrigins: options.strictExternalOrigins,
|
|
1626
2326
|
signal: options.signal
|
|
@@ -1683,4 +2383,4 @@ function createCustomSearchAdapter(adapter) {
|
|
|
1683
2383
|
}
|
|
1684
2384
|
|
|
1685
2385
|
//#endregion
|
|
1686
|
-
export {
|
|
2386
|
+
export { stripGeneratedAgentProvenance as A, inferDocsTelemetryAgentSurface as B, normalizeAgentVersion as C, normalizeGeneratedAgentContent as D, hashGeneratedAgentContent as E, emitDocsTelemetryAgentSurfaceEvent as F, normalizeDocsTelemetryOrigin as H, emitDocsTelemetryEvent as I, emitDocsTelemetryMcpToolEvent as L, resolvePageSidebarFolderIndexBehavior as M, resolveSidebarFolderIndexBehavior as N, parseGeneratedAgentDocument as O, resolveSidebarFolderIndexBehaviorForPath as P, emitDocsTelemetryProjectEvent as R, normalizeAgentScopeValues as S, GENERATED_AGENT_PROVENANCE_VERSION as T, resolveDocsTelemetryConfig as U, isLocalDocsTelemetryOrigin as V, resolveSearchRequestConfig as _, createMcpSearchAdapter as a, normalizeAgentFramework as b, formatDocsAskAIPackageHints as c, performDocsSearch as d, performDocsSearchWithMetadata as f, resolveDocsSearchRequest as g, resolveDocsSearchFilters as h, createCustomSearchAdapter as i, applySidebarFolderIndexBehavior as j, serializeGeneratedAgentDocument as k, inferDocsAskAIPackageHints as l, resolveDocsSearchAudience as m, buildDocsSearchDocuments as n, createSimpleSearchAdapter as o, resolveAskAISearchRequestConfig as p, createAlgoliaSearchAdapter as r, createTypesenseSearchAdapter as s, buildDocsAskAIContext as t, normalizeDocsSearchFilters as u, agentVersionConstraintMatches as v, GENERATED_AGENT_PROVENANCE_MARKER as w, normalizeAgentLocale as x, agentVersionConstraintsOverlap as y, getDocsTelemetryFeatures as z };
|