refactor(agents): share glob matcher

This commit is contained in:
Peter Steinberger
2026-02-14 13:34:10 +00:00
parent fdc3a6a809
commit 60a7625f2a
4 changed files with 92 additions and 155 deletions

View File

@@ -1,69 +1,26 @@
import type { ContextPruningToolMatch } from "./settings.js";
import { compileGlobPatterns, matchesAnyGlobPattern } from "../../glob-pattern.js";
function normalizePatterns(patterns?: string[]): string[] {
if (!Array.isArray(patterns)) {
return [];
}
return patterns
.map((p) =>
String(p ?? "")
.trim()
.toLowerCase(),
)
.filter(Boolean);
}
type CompiledPattern =
| { kind: "all" }
| { kind: "exact"; value: string }
| { kind: "regex"; value: RegExp };
function compilePattern(pattern: string): CompiledPattern {
if (pattern === "*") {
return { kind: "all" };
}
if (!pattern.includes("*")) {
return { kind: "exact", value: pattern };
}
const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const re = new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`);
return { kind: "regex", value: re };
}
function compilePatterns(patterns?: string[]): CompiledPattern[] {
return normalizePatterns(patterns).map(compilePattern);
}
function matchesAny(toolName: string, patterns: CompiledPattern[]): boolean {
for (const p of patterns) {
if (p.kind === "all") {
return true;
}
if (p.kind === "exact" && toolName === p.value) {
return true;
}
if (p.kind === "regex" && p.value.test(toolName)) {
return true;
}
}
return false;
function normalizeGlob(value: string) {
return String(value ?? "")
.trim()
.toLowerCase();
}
export function makeToolPrunablePredicate(
match: ContextPruningToolMatch,
): (toolName: string) => boolean {
const deny = compilePatterns(match.deny);
const allow = compilePatterns(match.allow);
const deny = compileGlobPatterns({ raw: match.deny, normalize: normalizeGlob });
const allow = compileGlobPatterns({ raw: match.allow, normalize: normalizeGlob });
return (toolName: string) => {
const normalized = toolName.trim().toLowerCase();
if (matchesAny(normalized, deny)) {
const normalized = normalizeGlob(toolName);
if (matchesAnyGlobPattern(normalized, deny)) {
return false;
}
if (allow.length === 0) {
return true;
}
return matchesAny(normalized, allow);
return matchesAnyGlobPattern(normalized, allow);
};
}