From d7f489f85ed65c8af3c929bd1b6613a6e965f561 Mon Sep 17 00:00:00 2001 From: Xan Torres Date: Wed, 15 Apr 2026 23:43:23 +0200 Subject: [PATCH] Gateway/skills: dedupe skills prefix-match + drop dead fallback on log --- src/gateway/config-reload.ts | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/gateway/config-reload.ts b/src/gateway/config-reload.ts index 2af65757b34..f6bbd48dba2 100644 --- a/src/gateway/config-reload.ts +++ b/src/gateway/config-reload.ts @@ -35,20 +35,18 @@ const MISSING_CONFIG_MAX_RETRIES = 2; */ const SKILLS_INVALIDATION_PREFIXES = ["skills"] as const; -export function shouldInvalidateSkillsSnapshotForPaths(changedPaths: string[]): boolean { - return changedPaths.some((path) => - SKILLS_INVALIDATION_PREFIXES.some( - (prefix) => path === prefix || path.startsWith(`${prefix}.`), - ), +function matchesSkillsInvalidationPrefix(path: string): boolean { + return SKILLS_INVALIDATION_PREFIXES.some( + (prefix) => path === prefix || path.startsWith(`${prefix}.`), ); } function firstSkillsChangedPath(changedPaths: string[]): string | undefined { - return changedPaths.find((path) => - SKILLS_INVALIDATION_PREFIXES.some( - (prefix) => path === prefix || path.startsWith(`${prefix}.`), - ), - ); + return changedPaths.find(matchesSkillsInvalidationPrefix); +} + +export function shouldInvalidateSkillsSnapshotForPaths(changedPaths: string[]): boolean { + return firstSkillsChangedPath(changedPaths) !== undefined; } export function diffConfigPaths(prev: unknown, next: unknown, prefix = ""): string[] { @@ -194,12 +192,10 @@ export function startGatewayConfigReloader(opts: { // the user touches skills.* config. Without this, sessions keep advertising // tools that no longer exist in the allowlist, which causes infinite // tool-not-found loops against the model. - if (shouldInvalidateSkillsSnapshotForPaths(changedPaths)) { - const changedPath = firstSkillsChangedPath(changedPaths); - bumpSkillsSnapshotVersion({ reason: "config-change", changedPath }); - opts.log.info( - `skills snapshot invalidated by config change (${changedPath ?? "skills.*"})`, - ); + const skillsChangedPath = firstSkillsChangedPath(changedPaths); + if (skillsChangedPath !== undefined) { + bumpSkillsSnapshotVersion({ reason: "config-change", changedPath: skillsChangedPath }); + opts.log.info(`skills snapshot invalidated by config change (${skillsChangedPath})`); } opts.log.info(`config change detected; evaluating reload (${changedPaths.join(", ")})`);