Spaces:
Paused
Paused
| import type { ContextPruningToolMatch } from "./settings.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; | |
| } | |
| export function makeToolPrunablePredicate( | |
| match: ContextPruningToolMatch, | |
| ): (toolName: string) => boolean { | |
| const deny = compilePatterns(match.deny); | |
| const allow = compilePatterns(match.allow); | |
| return (toolName: string) => { | |
| const normalized = toolName.trim().toLowerCase(); | |
| if (matchesAny(normalized, deny)) { | |
| return false; | |
| } | |
| if (allow.length === 0) { | |
| return true; | |
| } | |
| return matchesAny(normalized, allow); | |
| }; | |
| } | |