From: Stefan Gasser Date: Sat, 10 Jan 2026 14:00:48 +0000 (+0100) Subject: Fix lint errors from multimodal PR (#11) X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=3958cefec7c3e968db345fc88bc2c79aad1041aa;p=sgasser-llm-shield.git Fix lint errors from multimodal PR (#11) - Remove unused imports in multimodal.test.ts - Remove unused secretsConfig variable - Fix import ordering in masking.ts and content.test.ts - Remove trailing whitespace in proxy.ts and masking.ts --- diff --git a/src/routes/proxy.ts b/src/routes/proxy.ts index c2c9094..c1f6e3e 100644 --- a/src/routes/proxy.ts +++ b/src/routes/proxy.ts @@ -228,12 +228,12 @@ function redactMessagesWithSecrets( // Track offset position within the concatenated text for this message // (matches how extractTextContent joins parts with \n) let partOffset = 0; - + // Redact only text parts of array content with proper offset tracking const redactedContent = msg.content.map((part: ContentPart) => { if (part.type === "text" && typeof part.text === "string") { const partLength = part.text.length; - + // Find redactions that apply to this specific part const partRedactions = messageRedactions .filter((r) => r.start < partOffset + partLength && r.end > partOffset) @@ -242,7 +242,7 @@ function redactMessagesWithSecrets( start: Math.max(0, r.start - partOffset), end: Math.min(partLength, r.end - partOffset), })); - + if (partRedactions.length > 0) { const { redacted, context: updatedContext } = redactSecrets( part.text, @@ -254,7 +254,7 @@ function redactMessagesWithSecrets( partOffset += partLength + 1; // +1 for \n separator return { ...part, text: redacted }; } - + partOffset += partLength + 1; // +1 for \n separator return part; } diff --git a/src/secrets/multimodal.test.ts b/src/secrets/multimodal.test.ts index 9810619..5dafa9c 100644 --- a/src/secrets/multimodal.test.ts +++ b/src/secrets/multimodal.test.ts @@ -1,14 +1,12 @@ import { describe, expect, test } from "bun:test"; -import type { MaskingConfig, SecretsDetectionConfig } from "../config"; +import type { SecretsDetectionConfig } from "../config"; import type { ChatMessage } from "../services/llm-client"; import { maskMessages } from "../services/masking"; import type { PIIEntity } from "../services/pii-detector"; -import { detectSecrets } from "./detect"; -import { redactSecrets } from "./redact"; import type { ContentPart } from "../utils/content"; describe("Multimodal content handling", () => { - const secretsConfig: SecretsDetectionConfig = { + const _secretsConfig: SecretsDetectionConfig = { enabled: true, action: "redact", entities: ["API_KEY_OPENAI"], @@ -72,9 +70,7 @@ describe("Multimodal content handling", () => { const messages: ChatMessage[] = [ { role: "user", - content: [ - { type: "text", text: "Contact Alice at alice@secret.com" }, - ], + content: [{ type: "text", text: "Contact Alice at alice@secret.com" }], }, ]; @@ -89,7 +85,7 @@ describe("Multimodal content handling", () => { expect(Array.isArray(masked[0].content)).toBe(true); const maskedContent = masked[0].content as ContentPart[]; - + // Verify the text is actually masked (not the original) expect(maskedContent[0].text).not.toContain("Alice"); expect(maskedContent[0].text).not.toContain("alice@secret.com"); @@ -125,10 +121,10 @@ describe("Multimodal content handling", () => { // At minimum, verify that the entity is masked somewhere const fullMasked = maskedContent - .filter(p => p.type === "text") - .map(p => p.text) + .filter((p) => p.type === "text") + .map((p) => p.text) .join("\n"); - + expect(fullMasked).toContain(" { const entities = entitiesByMessage[i] || []; - + // Handle array content (multimodal messages) if (Array.isArray(msg.content)) { if (entities.length === 0) { return msg; } - + // Track offset position within the concatenated text for this message // (matches how extractTextContent joins parts with \n) let partOffset = 0; - + // Mask only text parts with proper offset tracking const maskedContent = msg.content.map((part) => { if (part.type === "text" && typeof part.text === "string") { const partLength = part.text.length; - + // Find entities that apply to this specific part const partEntities = entities .filter((e) => e.start < partOffset + partLength && e.end > partOffset) @@ -142,22 +142,22 @@ export function maskMessages( start: Math.max(0, e.start - partOffset), end: Math.min(partLength, e.end - partOffset), })); - + if (partEntities.length > 0) { const { masked: maskedText } = mask(part.text, partEntities, context); partOffset += partLength + 1; // +1 for \n separator return { ...part, text: maskedText }; } - + partOffset += partLength + 1; // +1 for \n separator return part; } return part; }); - + return { ...msg, content: maskedContent }; } - + // Handle string content (text-only messages) const text = extractTextContent(msg.content); const { masked: maskedContent } = mask(text, entities, context); diff --git a/src/utils/content.test.ts b/src/utils/content.test.ts index b211210..0040d07 100644 --- a/src/utils/content.test.ts +++ b/src/utils/content.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test"; -import { extractTextContent, hasTextContent, type ContentPart } from "./content"; +import { type ContentPart, extractTextContent, hasTextContent } from "./content"; describe("extractTextContent", () => { test("returns empty string for null", () => {