@silmaril-security/sdk 0.5.1 → 0.6.0
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/CHANGELOG.md +16 -0
- package/README.md +27 -19
- package/dist/adapters/langchain.cjs +6 -3
- package/dist/adapters/langchain.cjs.map +1 -1
- package/dist/adapters/langchain.d.cts +1 -1
- package/dist/adapters/langchain.d.ts +1 -1
- package/dist/adapters/langchain.js +6 -3
- package/dist/adapters/langchain.js.map +1 -1
- package/dist/adapters/vercel.cjs +10 -4
- package/dist/adapters/vercel.cjs.map +1 -1
- package/dist/adapters/vercel.d.cts +1 -1
- package/dist/adapters/vercel.d.ts +1 -1
- package/dist/adapters/vercel.js +10 -4
- package/dist/adapters/vercel.js.map +1 -1
- package/dist/{firewall-D2doJsD5.d.cts → firewall-C0ibVbst.d.cts} +14 -1
- package/dist/{firewall-D2doJsD5.d.ts → firewall-C0ibVbst.d.ts} +14 -1
- package/dist/index.cjs +47 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +47 -12
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/exceptions.ts","../src/hooks.ts","../src/utils/extract.ts","../src/adapters/langchain.ts","../src/index.ts","../src/firewall.ts","../src/adapters/vercel.ts","../src/outcomes.ts","../src/sanitization.ts"],"sourcesContent":["// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { HookLabel } from \"./hooks.js\";\nimport type { BlockResult } from \"./types.js\";\n\nconst MAX_PROMPT_DISPLAY_LEN = 100;\n\nexport interface MalformedInputDetails {\n field?: string;\n inputIndex?: number;\n charOffset?: number;\n malformedToken?: string;\n codePoint?: string;\n reason?: string;\n}\n\nexport class FirewallBlockedException extends Error {\n readonly score: number;\n readonly threshold: number;\n readonly promptText: string;\n readonly runId: string | undefined;\n readonly hook: HookLabel | undefined;\n readonly toolName: string | undefined;\n readonly toolCallId: string | undefined;\n readonly result: BlockResult | undefined;\n\n constructor(params: {\n score: number;\n threshold: number;\n promptText: string;\n runId?: string;\n hook?: HookLabel;\n toolName?: string;\n toolCallId?: string;\n result?: BlockResult;\n }) {\n super(FirewallBlockedException.formatMessage(params));\n this.name = \"FirewallBlockedException\";\n this.score = params.score;\n this.threshold = params.threshold;\n this.promptText = params.promptText;\n this.runId = params.runId;\n this.hook = params.hook;\n this.toolName = params.toolName;\n this.toolCallId = params.toolCallId;\n this.result = params.result;\n Object.setPrototypeOf(this, FirewallBlockedException.prototype);\n }\n\n private static formatMessage(params: {\n score: number;\n threshold: number;\n promptText: string;\n }): string {\n const truncated =\n params.promptText.length > MAX_PROMPT_DISPLAY_LEN\n ? `${params.promptText.slice(0, MAX_PROMPT_DISPLAY_LEN)}...`\n : params.promptText;\n return (\n `Request blocked by Silmaril Firewall ` +\n `(score=${params.score.toFixed(4)}, threshold=${params.threshold.toFixed(4)}): ` +\n `'${truncated}'`\n );\n }\n}\n\n/** @deprecated Use FirewallBlockedException instead. */\nexport const PromptBlockedException = FirewallBlockedException;\n/** @deprecated Use FirewallBlockedException instead. */\nexport type PromptBlockedException = FirewallBlockedException;\n\nexport class SilmarilApiError extends Error {\n readonly status: number;\n readonly statusText: string;\n readonly body: string;\n readonly details: MalformedInputDetails | undefined;\n readonly error: string | undefined;\n readonly apiMessage: string | undefined;\n\n constructor(params: {\n status: number;\n statusText: string;\n body: string;\n details?: MalformedInputDetails;\n error?: string;\n apiMessage?: string;\n }) {\n const statusText = params.statusText ? ` ${params.statusText}` : \"\";\n super(`Silmaril API error ${params.status}${statusText}`);\n this.name = \"SilmarilApiError\";\n this.status = params.status;\n this.statusText = params.statusText;\n this.body = params.body;\n const parsed = parseErrorBody(params.body);\n this.details = params.details ?? parsed.details;\n this.error = params.error ?? parsed.error;\n this.apiMessage = params.apiMessage ?? parsed.apiMessage;\n Object.setPrototypeOf(this, SilmarilApiError.prototype);\n }\n}\n\nfunction parseErrorBody(body: string): {\n details: MalformedInputDetails | undefined;\n error: string | undefined;\n apiMessage: string | undefined;\n} {\n try {\n const parsed = JSON.parse(body) as unknown;\n if (!parsed || typeof parsed !== \"object\") {\n return { details: undefined, error: undefined, apiMessage: undefined };\n }\n const data = parsed as Record<string, unknown>;\n return {\n details:\n data.details && typeof data.details === \"object\"\n ? (data.details as MalformedInputDetails)\n : undefined,\n error: typeof data.error === \"string\" ? data.error : undefined,\n apiMessage: typeof data.message === \"string\" ? data.message : undefined,\n };\n } catch {\n return { details: undefined, error: undefined, apiMessage: undefined };\n }\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport const HookLabel = {\n USER_INPUT: \"user_input\",\n SYSTEM_PROMPT: \"system_prompt\",\n TOOL_CALL: \"tool_call\",\n TOOL_RESPONSE: \"tool_response\",\n LLM_OUTPUT: \"llm_output\",\n UNKNOWN: \"unknown\",\n} as const;\n\nexport type HookLabel = (typeof HookLabel)[keyof typeof HookLabel];\n\nexport const FirewallHook = {\n LLM_START: \"on_llm_start\",\n CHAT_MODEL_START: \"on_chat_model_start\",\n TOOL_START: \"on_tool_start\",\n RETRIEVER_START: \"on_retriever_start\",\n LLM_END: \"on_llm_end\",\n TOOL_END: \"on_tool_end\",\n RETRIEVER_END: \"on_retriever_end\",\n} as const;\n\nexport type FirewallHook = (typeof FirewallHook)[keyof typeof FirewallHook];\n\nexport const DEFAULT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_START,\n FirewallHook.CHAT_MODEL_START,\n]);\n\nexport const INPUT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_START,\n FirewallHook.CHAT_MODEL_START,\n FirewallHook.TOOL_START,\n FirewallHook.RETRIEVER_START,\n]);\n\nexport const OUTPUT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_END,\n FirewallHook.TOOL_END,\n FirewallHook.RETRIEVER_END,\n]);\n\nexport const ALL_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n ...INPUT_HOOKS,\n ...OUTPUT_HOOKS,\n]);\n\nexport const FIREWALL_HOOK_TO_LABEL: Readonly<Record<FirewallHook, HookLabel>> = {\n [FirewallHook.CHAT_MODEL_START]: HookLabel.USER_INPUT,\n [FirewallHook.LLM_START]: HookLabel.USER_INPUT,\n [FirewallHook.TOOL_START]: HookLabel.TOOL_CALL,\n [FirewallHook.TOOL_END]: HookLabel.TOOL_RESPONSE,\n [FirewallHook.RETRIEVER_START]: HookLabel.TOOL_CALL,\n [FirewallHook.RETRIEVER_END]: HookLabel.TOOL_RESPONSE,\n [FirewallHook.LLM_END]: HookLabel.LLM_OUTPUT,\n};\n\nconst FIREWALL_HOOK_VALUES: ReadonlySet<string> = new Set(Object.values(FirewallHook));\n\nexport function resolveHooks(\n hooks: Iterable<FirewallHook | string> | undefined,\n): ReadonlySet<FirewallHook> {\n if (hooks === undefined) {\n return DEFAULT_HOOKS;\n }\n const resolved = new Set<FirewallHook>();\n for (const h of hooks) {\n if (!FIREWALL_HOOK_VALUES.has(h)) {\n throw new Error(`Invalid FirewallHook value: ${String(h)}`);\n }\n resolved.add(h as FirewallHook);\n }\n return resolved;\n}\n\nexport function prependHook(text: string, hook: HookLabel | string | undefined | null): string {\n if (hook === undefined || hook === null) {\n return text;\n }\n if (hook === HookLabel.UNKNOWN) {\n return text;\n }\n return `[HOOK:${hook}] ${text}`;\n}\n\nexport function prependToolName(text: string, toolName: string | undefined | null): string {\n if (toolName === undefined || toolName === null) {\n return text;\n }\n return `[TOOL:${toolName}] ${text}`;\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nconst SKIP_ROLES: ReadonlySet<string> = new Set([\"ai\", \"assistant\"]);\nconst SYSTEM_ROLES: ReadonlySet<string> = new Set([\"system\"]);\nconst TOOL_ROLES: ReadonlySet<string> = new Set([\"tool\", \"function\"]);\n\ntype MessageContent = string | ReadonlyArray<string | { type?: string; text?: string }>;\n\ninterface DucktypedMessage {\n role?: string;\n type?: string;\n content?: MessageContent;\n}\n\ninterface DucktypedGeneration {\n text?: string;\n}\n\ninterface DucktypedLLMResult {\n generations?: ReadonlyArray<ReadonlyArray<DucktypedGeneration>>;\n}\n\ninterface DucktypedDocument {\n pageContent?: string;\n}\n\nfunction extractContentText(content: MessageContent | undefined): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && typeof block === \"object\" && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n }\n return \"\";\n}\n\nfunction getRole(message: DucktypedMessage): string {\n if (message.role !== undefined) {\n return message.role.toLowerCase();\n }\n if (typeof message.type === \"string\") {\n return message.type.toLowerCase();\n }\n return \"\";\n}\n\nexport function extractTextFromMessages(\n messages: ReadonlyArray<DucktypedMessage>,\n options: { includeSystem?: boolean; includeTool?: boolean } = {},\n): string {\n const includeSystem = options.includeSystem ?? true;\n const includeTool = options.includeTool ?? true;\n const parts: string[] = [];\n for (const message of messages) {\n const role = getRole(message);\n if (SKIP_ROLES.has(role)) {\n continue;\n }\n if (!includeSystem && SYSTEM_ROLES.has(role)) {\n continue;\n }\n if (!includeTool && TOOL_ROLES.has(role)) {\n continue;\n }\n const text = extractContentText(message.content);\n const stripped = text.trim();\n if (stripped) {\n parts.push(stripped);\n }\n }\n return parts.join(\"\\n\");\n}\n\nexport function extractTextFromPrompts(prompts: readonly string[]): string {\n return prompts\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .join(\"\\n\");\n}\n\nexport function extractTextFromToolInput(inputStr: string): string {\n return inputStr.trim();\n}\n\nexport function extractTextFromLLMResult(response: DucktypedLLMResult): string {\n const parts: string[] = [];\n for (const genList of response.generations ?? []) {\n for (const gen of genList) {\n const text = (gen.text ?? \"\").trim();\n if (text) {\n parts.push(text);\n }\n }\n }\n return parts.join(\"\\n\");\n}\n\nexport function extractTextFromDocuments(documents: ReadonlyArray<DucktypedDocument>): string {\n const parts: string[] = [];\n for (const doc of documents) {\n const text = (doc.pageContent ?? \"\").trim();\n if (text) {\n parts.push(text);\n }\n }\n return parts.join(\"\\n\");\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\n\nimport type { Firewall } from \"../firewall.js\";\nimport { FirewallBlockedException } from \"../exceptions.js\";\nimport {\n FIREWALL_HOOK_TO_LABEL,\n FirewallHook,\n HookLabel,\n resolveHooks,\n} from \"../hooks.js\";\nimport type { BlockResult, ClassifyEvent, LangChainAdapterOptions } from \"../types.js\";\nimport {\n extractTextFromDocuments,\n extractTextFromLLMResult,\n extractTextFromPrompts,\n extractTextFromToolInput,\n} from \"../utils/extract.js\";\n\nconst USER_ROLES: ReadonlySet<string> = new Set([\"human\", \"user\"]);\n\ninterface LangChainDucktypedMessage {\n role?: string;\n type?: string;\n content?: string | ReadonlyArray<string | { type?: string; text?: string }>;\n}\n\nfunction getMessageRole(message: LangChainDucktypedMessage): string {\n if (typeof message.role === \"string\") {\n return message.role.toLowerCase();\n }\n if (typeof message.type === \"string\") {\n return message.type.toLowerCase();\n }\n return \"\";\n}\n\nfunction extractMessageText(content: LangChainDucktypedMessage[\"content\"]): string {\n if (content === undefined) {\n return \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n}\n\nfunction findLastUserMessage(\n messages: ReadonlyArray<LangChainDucktypedMessage>,\n): LangChainDucktypedMessage | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]!;\n if (USER_ROLES.has(getMessageRole(msg))) {\n return msg;\n }\n }\n return undefined;\n}\n\nexport async function createLangChainHandler(\n firewall: Firewall,\n options: LangChainAdapterOptions = {},\n): Promise<BaseCallbackHandler> {\n const { BaseCallbackHandler } = await import(\"@langchain/core/callbacks/base\");\n\n const enabledHooks = resolveHooks(options.hooks);\n // includeSystem / includeTool are retained in LangChainAdapterOptions for\n // backwards compat but are inert under the per-message hook-routing algorithm:\n // handleChatModelStart only scans the last user-role message; system and tool\n // messages are either trusted or already classified by their own hooks.\n const failOpen = options.failOpen ?? true;\n const logger =\n options.logger ??\n ((message: string, error: unknown): void => {\n // eslint-disable-next-line no-console\n console.warn(`silmaril.firewall: ${message}`, error);\n });\n const shadowMode = options.shadowMode ?? firewall.shadowMode;\n const onClassify = options.onClassify;\n\n const fireOnClassify = (event: ClassifyEvent): void => {\n if (!onClassify) {\n return;\n }\n try {\n onClassify(event);\n } catch (err) {\n logger(\"onClassify callback threw\", err);\n }\n };\n\n const classify = async (\n text: string,\n hookLabel: HookLabel,\n runId: string,\n toolName?: string,\n ): Promise<void> => {\n let result: BlockResult;\n try {\n result = await firewall.classify(text, {\n hook: hookLabel,\n ...(toolName !== undefined ? { toolName } : {}),\n });\n } catch (err) {\n if (!failOpen) {\n throw err;\n }\n logger(\"classification failed, allowing prompt through\", err);\n return;\n }\n const threshold = result.threshold;\n const blocked = result.prediction === \"MALICIOUS\";\n const commonEventFields = {\n hook: hookLabel,\n ...(toolName !== undefined ? { toolName } : {}),\n runId,\n text,\n result,\n };\n fireOnClassify({\n ...commonEventFields,\n blocked,\n shadowMode,\n });\n if (!blocked || shadowMode) {\n return;\n }\n\n throw new FirewallBlockedException({\n score: result.score,\n threshold,\n promptText: text,\n runId,\n hook: hookLabel,\n ...(toolName !== undefined ? { toolName } : {}),\n result,\n });\n };\n\n class SilmarilFirewallHandler extends BaseCallbackHandler {\n override name = \"silmaril_firewall_handler\";\n override raiseError = true;\n override awaitHandlers = true;\n\n override async handleChatModelStart(\n _llm: unknown,\n messages: unknown,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.CHAT_MODEL_START)) {\n return;\n }\n const batches = messages as ReadonlyArray<ReadonlyArray<LangChainDucktypedMessage>>;\n const flat: LangChainDucktypedMessage[] = [];\n for (const batch of batches) {\n for (const m of batch) {\n flat.push(m);\n }\n }\n const lastUser = findLastUserMessage(flat);\n if (!lastUser) {\n return;\n }\n const text = extractMessageText(lastUser.content).trim();\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.CHAT_MODEL_START], runId);\n }\n\n override async handleLLMStart(\n _llm: unknown,\n prompts: string[],\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.LLM_START)) {\n return;\n }\n const text = extractTextFromPrompts(prompts);\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_START], runId);\n }\n\n override async handleToolStart(\n tool: { name?: string } | undefined,\n inputStr: string,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.TOOL_START)) {\n return;\n }\n const text = extractTextFromToolInput(inputStr);\n if (!text) {\n return;\n }\n const toolName = tool?.name;\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, toolName);\n }\n\n override async handleRetrieverStart(\n _retriever: unknown,\n query: string,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.RETRIEVER_START)) {\n return;\n }\n const text = query.trim();\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);\n }\n\n override async handleLLMEnd(output: unknown, runId: string): Promise<void> {\n if (!enabledHooks.has(FirewallHook.LLM_END)) {\n return;\n }\n const text = extractTextFromLLMResult(output as { generations?: ReadonlyArray<ReadonlyArray<{ text?: string }>> });\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);\n }\n\n override async handleToolEnd(\n output: unknown,\n runId: string,\n _parentRunId?: string,\n _tags?: string[],\n _kwargs?: { name?: string },\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.TOOL_END)) {\n return;\n }\n const text = String(output).trim();\n if (!text) {\n return;\n }\n const toolName = _kwargs?.name;\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, toolName);\n }\n\n override async handleRetrieverEnd(\n documents: ReadonlyArray<{ pageContent?: string }>,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.RETRIEVER_END)) {\n return;\n }\n const text = extractTextFromDocuments(documents);\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_END], runId);\n }\n }\n\n return new SilmarilFirewallHandler();\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport {\n Firewall,\n DEFAULT_TIMEOUT_MS,\n} from \"./firewall.js\";\n\nexport { FirewallBlockedException, PromptBlockedException, SilmarilApiError } from \"./exceptions.js\";\nexport type { MalformedInputDetails } from \"./exceptions.js\";\n\nexport type { FirewallMiddleware } from \"./adapters/vercel.js\";\n\nexport {\n HookLabel,\n FirewallHook,\n DEFAULT_HOOKS,\n INPUT_HOOKS,\n OUTPUT_HOOKS,\n ALL_HOOKS,\n FIREWALL_HOOK_TO_LABEL,\n resolveHooks,\n prependHook,\n prependToolName,\n} from \"./hooks.js\";\n\nexport {\n Outcome,\n PRIMARY_OUTCOMES,\n HARMFUL_OUTCOMES,\n OUTCOME_DESCRIPTIONS,\n isPrimaryOutcome,\n isHarmfulOutcome,\n normalizePrimaryOutcome,\n normalizeHarmfulOutcome,\n normalizeHarmfulOutcomeMap,\n} from \"./outcomes.js\";\n\nexport type {\n KnownPrimaryOutcome,\n KnownHarmfulOutcome,\n PrimaryOutcome,\n HarmfulOutcome,\n UnknownOutcome,\n} from \"./outcomes.js\";\n\nexport type {\n BlockResult,\n ClassifyEvent,\n Prediction,\n ClassificationMetadata,\n FirewallOptions,\n ClassifyOptions,\n ClassifyBatchOptions,\n LangChainAdapterOptions,\n LangChainFirewallHandler,\n MiddlewareOptions,\n} from \"./types.js\";\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport { randomUUID } from \"node:crypto\";\n\nimport { createMiddleware, type FirewallMiddleware } from \"./adapters/vercel.js\";\nimport { SilmarilApiError } from \"./exceptions.js\";\nimport { normalizeHarmfulOutcomeMap, normalizePrimaryOutcome } from \"./outcomes.js\";\nimport { sanitizeText } from \"./sanitization.js\";\nimport type {\n BlockResult,\n ClassifyBatchOptions,\n ClassifyOptions,\n ClassificationMetadata,\n FirewallOptions,\n LangChainAdapterOptions,\n LangChainFirewallHandler,\n MiddlewareOptions,\n Prediction,\n} from \"./types.js\";\n\nexport const SDK_VERSION = \"0.5.1\";\nexport const DEFAULT_TIMEOUT_MS = 10_000;\nconst DEFAULT_MAX_RETRIES = 5;\nconst MAX_BACKOFF_SECONDS = 30;\nconst MAX_ERROR_BODY_BYTES = 1 << 16;\n\ninterface SingleClassifyPayload {\n text: string;\n hook?: string;\n tool_name?: string;\n metadata?: ClassificationMetadata;\n}\n\ninterface BatchClassifyPayload {\n texts: readonly string[];\n hooks?: readonly string[];\n tool_names?: readonly (string | null)[];\n metadata?: readonly (ClassificationMetadata | null)[];\n}\n\ninterface SingleClassifyResponse {\n prediction: Prediction;\n score: number;\n threshold: number;\n primary_outcome?: unknown;\n outcome_scores?: unknown;\n detector_scores?: unknown;\n detector_counts?: unknown;\n}\n\ninterface BatchClassifyResponse {\n predictions: readonly SingleClassifyResponse[];\n}\n\nfunction blockResultFromResponse(data: SingleClassifyResponse): BlockResult {\n if (data.prediction !== \"BENIGN\" && data.prediction !== \"MALICIOUS\") {\n throw new Error(\"Firewall: response prediction must be BENIGN or MALICIOUS\");\n }\n const result: {\n prediction: Prediction;\n score: number;\n threshold: number;\n primaryOutcome?: NonNullable<BlockResult[\"primaryOutcome\"]>;\n outcomeScores?: NonNullable<BlockResult[\"outcomeScores\"]>;\n detectorScores?: NonNullable<BlockResult[\"detectorScores\"]>;\n detectorCounts?: NonNullable<BlockResult[\"detectorCounts\"]>;\n } = {\n prediction: data.prediction,\n score: Number(data.score),\n threshold: Number(data.threshold),\n };\n if (data.primary_outcome !== undefined) {\n result.primaryOutcome = normalizePrimaryOutcome(data.primary_outcome);\n }\n if (data.outcome_scores !== undefined) {\n const outcomeScores = normalizeHarmfulOutcomeMap(data.outcome_scores, \"outcome_scores\");\n if (outcomeScores !== undefined) {\n result.outcomeScores = outcomeScores;\n }\n }\n if (data.detector_scores !== undefined) {\n const detectorScores = normalizeHarmfulOutcomeMap(data.detector_scores, \"detector_scores\");\n if (detectorScores !== undefined) {\n result.detectorScores = detectorScores;\n }\n }\n if (data.detector_counts !== undefined) {\n const detectorCounts = normalizeHarmfulOutcomeMap(data.detector_counts, \"detector_counts\");\n if (detectorCounts !== undefined) {\n result.detectorCounts = detectorCounts;\n }\n }\n return Object.freeze(result);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction withSdkMetadata(\n metadata: ClassificationMetadata | undefined,\n info: {\n requestId: string;\n inputIndex?: number;\n },\n): ClassificationMetadata {\n const payload: Record<string, unknown> = { ...(metadata ?? {}) };\n const existing = payload.silmaril;\n if (existing !== undefined && !isRecord(existing)) {\n throw new Error(\"Firewall: metadata.silmaril must be an object when provided\");\n }\n payload.silmaril = {\n ...(isRecord(existing) ? existing : {}),\n sdk_language: \"typescript\",\n sdk_version: SDK_VERSION,\n request_id: info.requestId,\n ...(info.inputIndex === undefined ? {} : { input_index: info.inputIndex }),\n };\n return payload;\n}\n\nasync function readCappedErrorBody(response: Response): Promise<string> {\n if (!response.body) {\n return response.text().then((body) => body.slice(0, MAX_ERROR_BODY_BYTES)).catch(() => \"\");\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let remaining = MAX_ERROR_BODY_BYTES;\n try {\n while (remaining > 0) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (!value) {\n continue;\n }\n const chunk = value.byteLength > remaining ? value.slice(0, remaining) : value;\n chunks.push(chunk);\n remaining -= chunk.byteLength;\n if (chunk.byteLength < value.byteLength) {\n break;\n }\n }\n } catch {\n return \"\";\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n\n const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);\n const body = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(body);\n}\n\nexport class Firewall {\n readonly apiKey: string;\n readonly apiUrl: string;\n readonly timeoutMs: number;\n readonly shadowMode: boolean;\n\n private readonly headers: Readonly<Record<string, string>>;\n\n constructor(options: FirewallOptions) {\n if (!options.apiKey) {\n throw new Error(\"Firewall: apiKey is required\");\n }\n if (!options.apiUrl) {\n throw new Error(\"Firewall: apiUrl is required\");\n }\n this.apiKey = options.apiKey;\n this.apiUrl = options.apiUrl;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (typeof this.timeoutMs !== \"number\" || !Number.isFinite(this.timeoutMs) || this.timeoutMs < 0) {\n throw new Error(`Firewall: timeoutMs must be a finite non-negative number, got ${this.timeoutMs}`);\n }\n this.shadowMode = options.shadowMode ?? false;\n this.headers = Object.freeze({\n \"x-api-key\": this.apiKey,\n \"content-type\": \"application/json\",\n });\n }\n\n async classify(text: string, options: ClassifyOptions = {}): Promise<BlockResult> {\n const requestId = options.requestId ?? randomUUID();\n return this.classifySingle(sanitizeText(text), options, { requestId });\n }\n\n async classifyBatch(\n texts: readonly string[],\n options: ClassifyBatchOptions = {},\n ): Promise<BlockResult[]> {\n if (texts.length === 0) {\n throw new Error(\"Firewall: texts must not be empty\");\n }\n if (options.hooks !== undefined && options.hooks.length !== texts.length) {\n throw new Error(\n `Firewall: hooks length ${options.hooks.length} does not match texts length ${texts.length}`,\n );\n }\n if (options.toolNames !== undefined && options.toolNames.length !== texts.length) {\n throw new Error(\n `Firewall: toolNames length ${options.toolNames.length} does not match texts length ${texts.length}`,\n );\n }\n if (options.metadata !== undefined && options.metadata.length !== texts.length) {\n throw new Error(\n `Firewall: metadata length ${options.metadata.length} does not match texts length ${texts.length}`,\n );\n }\n\n const requestId = options.requestId ?? randomUUID();\n const payload: BatchClassifyPayload = {\n texts: texts.map((text) => sanitizeText(text)),\n };\n if (options.hooks && options.hooks.length > 0) {\n payload.hooks = options.hooks.map((h) => String(h));\n }\n if (options.toolNames && options.toolNames.length > 0) {\n payload.tool_names = options.toolNames.map((t) => (t === undefined ? null : t));\n }\n payload.metadata = texts.map((_, index) =>\n withSdkMetadata(options.metadata?.[index], {\n requestId,\n inputIndex: index,\n }),\n );\n const data = await this.postWithRetry<BatchClassifyResponse>(payload);\n return data.predictions.map((p) => blockResultFromResponse(p));\n }\n\n asLangChainHandler<THandler = LangChainFirewallHandler>(\n options: LangChainAdapterOptions = {},\n ): Promise<THandler> {\n return import(\"./adapters/langchain.js\").then((m) =>\n m.createLangChainHandler(this, options) as Promise<THandler>,\n );\n }\n\n asMiddleware(options: MiddlewareOptions = {}): FirewallMiddleware {\n return createMiddleware(this, options);\n }\n\n private async postWithRetry<T>(\n payload: SingleClassifyPayload | BatchClassifyPayload,\n maxRetries: number = DEFAULT_MAX_RETRIES,\n ): Promise<T> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(payload),\n redirect: \"error\",\n signal: AbortSignal.timeout(this.timeoutMs),\n });\n if (response.status !== 429 || attempt === maxRetries) {\n if (!response.ok) {\n const body = await readCappedErrorBody(response);\n throw new SilmarilApiError({\n status: response.status,\n statusText: response.statusText,\n body,\n });\n }\n return (await response.json()) as T;\n }\n const waitSeconds = Math.min(2 ** attempt, MAX_BACKOFF_SECONDS);\n await new Promise<void>((resolve) => setTimeout(resolve, waitSeconds * 1000));\n }\n throw new Error(\"Firewall: exhausted retries (unreachable)\");\n }\n\n private async classifySingle(\n text: string,\n options: ClassifyOptions,\n metadataInfo: {\n requestId: string;\n },\n ): Promise<BlockResult> {\n const payload: SingleClassifyPayload = { text };\n if (options.hook !== undefined) {\n payload.hook = options.hook;\n }\n if (options.toolName !== undefined) {\n payload.tool_name = options.toolName;\n }\n payload.metadata = withSdkMetadata(options.metadata, metadataInfo);\n const data = await this.postWithRetry<SingleClassifyResponse>(payload);\n return blockResultFromResponse(data);\n }\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { Firewall } from \"../firewall.js\";\nimport { FirewallBlockedException } from \"../exceptions.js\";\nimport { HookLabel } from \"../hooks.js\";\nimport type { BlockResult, MiddlewareOptions } from \"../types.js\";\n\ninterface VercelContentPart {\n type?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n output?: unknown;\n result?: unknown;\n}\n\ninterface VercelPromptMessage {\n role: string;\n content: string | ReadonlyArray<VercelContentPart | string>;\n}\n\ninterface VercelToolCall {\n toolCallType?: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n input?: unknown;\n}\n\ninterface VercelGenerateResult {\n text?: string;\n toolCalls?: ReadonlyArray<VercelToolCall>;\n}\n\ninterface WrapGenerateArgs<TResult extends VercelGenerateResult & Record<string, unknown>> {\n params: { prompt?: ReadonlyArray<VercelPromptMessage> } & Record<string, unknown>;\n doGenerate: () => PromiseLike<TResult>;\n}\n\ninterface WrapStreamArgs<\n TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>,\n> {\n params: { prompt?: ReadonlyArray<VercelPromptMessage> } & Record<string, unknown>;\n doStream: () => PromiseLike<TResult>;\n}\n\ninterface StreamPart {\n type?: string;\n textDelta?: string;\n delta?: string;\n}\n\ninterface VercelStepContext {\n toolName: string | undefined;\n toolCallId: string | undefined;\n}\n\nfunction stringifyToolValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction extractContentText(content: VercelPromptMessage[\"content\"]): string {\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n}\n\nfunction iterateToolResultParts(\n message: VercelPromptMessage,\n): Array<{ text: string; toolName: string | undefined; toolCallId: string | undefined }> {\n if (typeof message.content === \"string\") {\n return [];\n }\n const out: Array<{ text: string; toolName: string | undefined; toolCallId: string | undefined }> = [];\n for (const part of message.content) {\n if (typeof part === \"string\") {\n continue;\n }\n if (part.type === \"tool-result\") {\n const text = stringifyToolResult(part.result !== undefined ? part.result : part.output);\n if (text.trim()) {\n out.push({ text, toolName: part.toolName, toolCallId: part.toolCallId });\n }\n }\n }\n return out;\n}\n\nfunction stringifyToolResult(value: unknown): string {\n if (!isRecord(value)) {\n return stringifyToolValue(value);\n }\n if ((value.type === \"text\" || value.type === \"error-text\") && typeof value.value === \"string\") {\n return value.value;\n }\n if ((value.type === \"json\" || value.type === \"error-json\") && value.value !== undefined) {\n return stringifyToolValue(value.value);\n }\n if (value.type === \"content\" && Array.isArray(value.value)) {\n return value.value\n .map((part) => (isRecord(part) && part.type === \"text\" && typeof part.text === \"string\" ? part.text : \"\"))\n .filter((text) => text.length > 0)\n .join(\" \");\n }\n return stringifyToolValue(value);\n}\n\nfunction findLastUserMessage(\n messages: ReadonlyArray<VercelPromptMessage>,\n): VercelPromptMessage | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]!;\n if (msg.role.toLowerCase() === \"user\") {\n return msg;\n }\n }\n return undefined;\n}\n\nexport interface FirewallMiddleware {\n readonly specificationVersion: \"v3\";\n readonly middlewareVersion: \"v2\";\n wrapGenerate: <TResult extends VercelGenerateResult & Record<string, unknown>>(\n args: WrapGenerateArgs<TResult>,\n ) => Promise<TResult>;\n wrapStream: <TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>>(\n args: WrapStreamArgs<TResult>,\n ) => Promise<TResult>;\n}\n\nexport function createMiddleware(\n firewall: Firewall,\n options: MiddlewareOptions = {},\n): FirewallMiddleware {\n const scanInput = options.scanInput ?? true;\n const scanOutput = options.scanOutput ?? false;\n const shadowMode = options.shadowMode ?? firewall.shadowMode;\n\n const classifyOrBlock = async (\n text: string,\n hook: HookLabel,\n context: VercelStepContext = { toolName: undefined, toolCallId: undefined },\n ): Promise<void> => {\n if (!text.trim()) {\n return;\n }\n const { toolName, toolCallId } = context;\n const result: BlockResult = await firewall.classify(\n text,\n toolName !== undefined ? { hook, toolName } : { hook },\n );\n const threshold = result.threshold;\n const blocked = result.prediction === \"MALICIOUS\";\n const commonEventFields = {\n hook,\n ...(toolName !== undefined ? { toolName } : {}),\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n text,\n result,\n };\n options.onClassify?.({\n ...commonEventFields,\n blocked,\n shadowMode,\n });\n if (!blocked || shadowMode) {\n return;\n }\n\n const err = new FirewallBlockedException({\n score: result.score,\n threshold,\n promptText: text,\n hook,\n ...(toolName !== undefined ? { toolName } : {}),\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n result,\n });\n options.onBlocked?.(err);\n throw err;\n };\n\n const scanPrompt = async (prompt: ReadonlyArray<VercelPromptMessage>): Promise<void> => {\n if (prompt.length === 0) {\n return;\n }\n const last = prompt[prompt.length - 1]!;\n const role = last.role.toLowerCase();\n\n // If the newest message is a tool result (typical mid-flow in a\n // tool-calling loop), classify each tool-result part individually with\n // tool_response + toolName. No manual wiring from the caller — the\n // toolName is read directly from the Vercel content part.\n if (role === \"tool\") {\n for (const { text, toolName, toolCallId } of iterateToolResultParts(last)) {\n await classifyOrBlock(text, HookLabel.TOOL_RESPONSE, { toolName, toolCallId });\n }\n return;\n }\n\n // Otherwise, fall back to scanning the most recent user message.\n // Covers: [user], [system, user], [user, assistant(text), user], etc.\n const lastUser = findLastUserMessage(prompt);\n if (!lastUser) {\n return;\n }\n const text = extractContentText(lastUser.content).trim();\n if (!text) {\n return;\n }\n await classifyOrBlock(text, HookLabel.USER_INPUT);\n };\n\n const scanGenerateResult = async (result: VercelGenerateResult): Promise<void> => {\n if (scanOutput && typeof result.text === \"string\" && result.text.length > 0) {\n await classifyOrBlock(result.text, HookLabel.LLM_OUTPUT);\n }\n if (options.scanToolCalls && Array.isArray(result.toolCalls)) {\n for (const call of result.toolCalls) {\n if (!call || typeof call !== \"object\") {\n continue;\n }\n const toolInput = call.args !== undefined ? call.args : call.input;\n const args =\n typeof toolInput === \"string\" ? toolInput : stringifyToolValue(toolInput);\n const toolName = typeof call.toolName === \"string\" ? call.toolName : undefined;\n const toolCallId = typeof call.toolCallId === \"string\" ? call.toolCallId : undefined;\n if (args.trim()) {\n await classifyOrBlock(args, HookLabel.TOOL_CALL, { toolName, toolCallId });\n }\n }\n }\n };\n\n return {\n specificationVersion: \"v3\",\n middlewareVersion: \"v2\",\n\n async wrapGenerate<TResult extends VercelGenerateResult & Record<string, unknown>>({\n params,\n doGenerate,\n }: WrapGenerateArgs<TResult>): Promise<TResult> {\n if (scanInput) {\n await scanPrompt(params.prompt ?? []);\n }\n const result = await doGenerate();\n await scanGenerateResult(result);\n return result;\n },\n\n async wrapStream<TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>>({\n params,\n doStream,\n }: WrapStreamArgs<TResult>): Promise<TResult> {\n if (scanInput) {\n await scanPrompt(params.prompt ?? []);\n }\n const { stream, ...rest } = await doStream();\n if (!scanOutput) {\n return { stream, ...rest } as unknown as TResult;\n }\n\n let buffered = \"\";\n const transformed = stream.pipeThrough(\n new TransformStream<unknown, unknown>({\n transform(chunk, controller): void {\n const part = chunk as StreamPart;\n if (part && part.type === \"text-delta\") {\n const delta = part.textDelta ?? part.delta ?? \"\";\n buffered += delta;\n }\n controller.enqueue(chunk);\n },\n async flush(controller): Promise<void> {\n if (!buffered.trim()) {\n return;\n }\n try {\n await classifyOrBlock(buffered, HookLabel.LLM_OUTPUT);\n } catch (err) {\n if (err instanceof FirewallBlockedException) {\n controller.enqueue({ type: \"error\", error: err });\n return;\n }\n throw err;\n }\n },\n }),\n );\n return { stream: transformed, ...rest } as unknown as TResult;\n },\n };\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport const Outcome = {\n Benign: \"benign\",\n InformationDisclosure: \"information_disclosure\",\n SecretExposure: \"secret_exposure\",\n ControlAbuse: \"control_abuse\",\n SystemCompromise: \"system_compromise\",\n ServiceDisruption: \"service_disruption\",\n CodeGeneration: \"code_generation\",\n StoryScriptGeneration: \"story_script_generation\",\n GameGeneration: \"game_generation\",\n WebsiteGeneration: \"website_generation\",\n ClickUpTermsViolation: \"clickup_terms_violation\",\n TraditionalAiAbuse: \"traditional_ai_abuse\",\n} as const;\n\ndeclare const unknownOutcomeBrand: unique symbol;\n\nexport type KnownPrimaryOutcome = (typeof Outcome)[keyof typeof Outcome];\nexport type KnownHarmfulOutcome = Exclude<KnownPrimaryOutcome, typeof Outcome.Benign>;\nexport type UnknownOutcome = string & { readonly [unknownOutcomeBrand]: \"UnknownOutcome\" };\nexport type PrimaryOutcome = KnownPrimaryOutcome | UnknownOutcome;\nexport type HarmfulOutcome = KnownHarmfulOutcome | UnknownOutcome;\n\nexport const PRIMARY_OUTCOMES = [\n Outcome.Benign,\n Outcome.InformationDisclosure,\n Outcome.SecretExposure,\n Outcome.ControlAbuse,\n Outcome.SystemCompromise,\n Outcome.ServiceDisruption,\n Outcome.CodeGeneration,\n Outcome.StoryScriptGeneration,\n Outcome.GameGeneration,\n Outcome.WebsiteGeneration,\n Outcome.ClickUpTermsViolation,\n Outcome.TraditionalAiAbuse,\n] as const satisfies readonly PrimaryOutcome[];\n\nexport const HARMFUL_OUTCOMES = [\n Outcome.InformationDisclosure,\n Outcome.SecretExposure,\n Outcome.ControlAbuse,\n Outcome.SystemCompromise,\n Outcome.ServiceDisruption,\n Outcome.CodeGeneration,\n Outcome.StoryScriptGeneration,\n Outcome.GameGeneration,\n Outcome.WebsiteGeneration,\n Outcome.ClickUpTermsViolation,\n Outcome.TraditionalAiAbuse,\n] as const satisfies readonly KnownHarmfulOutcome[];\n\nexport const OUTCOME_DESCRIPTIONS = {\n [Outcome.Benign]: \"No harmful firewall outcome detected.\",\n [Outcome.InformationDisclosure]:\n \"Exposes private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.\",\n [Outcome.SecretExposure]:\n \"Exposes credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.\",\n [Outcome.ControlAbuse]:\n \"Misuses authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.\",\n [Outcome.SystemCompromise]:\n \"Enables privilege escalation, account takeover, hostile integration or plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.\",\n [Outcome.ServiceDisruption]:\n \"Causes downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence.\",\n [Outcome.CodeGeneration]:\n \"Requests generation or material modification of executable code, scripts, workflows, or configuration.\",\n [Outcome.StoryScriptGeneration]:\n \"Requests generation of narrative prose, dialogue, scripts, or story artifacts.\",\n [Outcome.GameGeneration]:\n \"Requests generation of a game, quest, level, mechanic, or playable experience.\",\n [Outcome.WebsiteGeneration]:\n \"Requests generation of a website, landing page, storefront, or web experience.\",\n [Outcome.ClickUpTermsViolation]:\n \"Requests content or actions that violate the configured ClickUp tenant policy.\",\n [Outcome.TraditionalAiAbuse]:\n \"Requests unsafe AI assistance outside the concrete security outcome classes.\",\n} as const satisfies Readonly<Record<KnownPrimaryOutcome, string>>;\n\nconst PRIMARY_OUTCOME_SET = new Set<string>(PRIMARY_OUTCOMES);\nconst HARMFUL_OUTCOME_SET = new Set<string>(HARMFUL_OUTCOMES);\n\nexport function isPrimaryOutcome(value: unknown): value is KnownPrimaryOutcome {\n return typeof value === \"string\" && PRIMARY_OUTCOME_SET.has(value);\n}\n\nexport function isHarmfulOutcome(value: unknown): value is KnownHarmfulOutcome {\n return typeof value === \"string\" && HARMFUL_OUTCOME_SET.has(value);\n}\n\nexport function normalizePrimaryOutcome(\n value: unknown,\n fieldName = \"primary_outcome\",\n): PrimaryOutcome {\n if (typeof value !== \"string\") {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);\n }\n return isPrimaryOutcome(value) ? value : (value as UnknownOutcome);\n}\n\nexport function normalizeHarmfulOutcome(\n value: unknown,\n fieldName = \"outcome\",\n): HarmfulOutcome {\n if (typeof value !== \"string\" || value === Outcome.Benign) {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);\n }\n return isHarmfulOutcome(value) ? value : (value as UnknownOutcome);\n}\n\nexport function normalizeHarmfulOutcomeMap(\n values: unknown,\n fieldName: string,\n): Readonly<Partial<Record<HarmfulOutcome, number>>> | undefined {\n if (values === undefined || values === null) {\n return undefined;\n }\n if (typeof values !== \"object\" || Array.isArray(values)) {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(values)}`);\n }\n const out: Partial<Record<HarmfulOutcome, number>> = {};\n for (const [key, value] of Object.entries(values)) {\n const normalizedKey = normalizeHarmfulOutcome(key, `${fieldName} key`);\n if (typeof value !== \"number\") {\n throw new Error(`Firewall: invalid ${fieldName} value for ${JSON.stringify(key)}`);\n }\n out[normalizedKey] = value;\n }\n return Object.freeze(out);\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nfunction isHighSurrogate(code: number): boolean {\n return code >= 0xd800 && code <= 0xdbff;\n}\n\nfunction isLowSurrogate(code: number): boolean {\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\nexport function sanitizeText(text: string): string {\n let out = \"\";\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i);\n if (isHighSurrogate(code)) {\n if (i + 1 < text.length && isLowSurrogate(text.charCodeAt(i + 1))) {\n out += text[i]!;\n out += text[i + 1]!;\n i++;\n }\n continue;\n }\n if (!isLowSurrogate(code)) {\n out += text[i]!;\n }\n }\n return out;\n}\n"],"mappings":"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","names":["findLastUserMessage","text","isRecord","body"]}
|
|
1
|
+
{"version":3,"sources":["../src/exceptions.ts","../src/hooks.ts","../src/utils/extract.ts","../src/adapters/langchain.ts","../src/index.ts","../src/firewall.ts","../src/adapters/vercel.ts","../src/outcomes.ts","../src/sanitization.ts"],"sourcesContent":["// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { HookLabel } from \"./hooks.js\";\nimport type { BlockResult } from \"./types.js\";\n\nconst MAX_PROMPT_DISPLAY_LEN = 100;\n\nexport interface MalformedInputDetails {\n field?: string;\n inputIndex?: number;\n charOffset?: number;\n malformedToken?: string;\n codePoint?: string;\n reason?: string;\n}\n\nexport class FirewallBlockedException extends Error {\n readonly score: number;\n readonly threshold: number;\n readonly promptText: string;\n readonly runId: string | undefined;\n readonly hook: HookLabel | undefined;\n readonly toolName: string | undefined;\n readonly toolCallId: string | undefined;\n readonly result: BlockResult | undefined;\n\n constructor(params: {\n score: number;\n threshold: number;\n promptText: string;\n runId?: string;\n hook?: HookLabel;\n toolName?: string;\n toolCallId?: string;\n result?: BlockResult;\n }) {\n super(FirewallBlockedException.formatMessage(params));\n this.name = \"FirewallBlockedException\";\n this.score = params.score;\n this.threshold = params.threshold;\n this.promptText = params.promptText;\n this.runId = params.runId;\n this.hook = params.hook;\n this.toolName = params.toolName;\n this.toolCallId = params.toolCallId;\n this.result = params.result;\n Object.setPrototypeOf(this, FirewallBlockedException.prototype);\n }\n\n private static formatMessage(params: {\n score: number;\n threshold: number;\n promptText: string;\n }): string {\n const truncated =\n params.promptText.length > MAX_PROMPT_DISPLAY_LEN\n ? `${params.promptText.slice(0, MAX_PROMPT_DISPLAY_LEN)}...`\n : params.promptText;\n return (\n `Request blocked by Silmaril Firewall ` +\n `(score=${params.score.toFixed(4)}, threshold=${params.threshold.toFixed(4)}): ` +\n `'${truncated}'`\n );\n }\n}\n\n/** @deprecated Use FirewallBlockedException instead. */\nexport const PromptBlockedException = FirewallBlockedException;\n/** @deprecated Use FirewallBlockedException instead. */\nexport type PromptBlockedException = FirewallBlockedException;\n\nexport class SilmarilApiError extends Error {\n readonly status: number;\n readonly statusText: string;\n readonly body: string;\n readonly details: MalformedInputDetails | undefined;\n readonly error: string | undefined;\n readonly apiMessage: string | undefined;\n\n constructor(params: {\n status: number;\n statusText: string;\n body: string;\n details?: MalformedInputDetails;\n error?: string;\n apiMessage?: string;\n }) {\n const statusText = params.statusText ? ` ${params.statusText}` : \"\";\n super(`Silmaril API error ${params.status}${statusText}`);\n this.name = \"SilmarilApiError\";\n this.status = params.status;\n this.statusText = params.statusText;\n this.body = params.body;\n const parsed = parseErrorBody(params.body);\n this.details = params.details ?? parsed.details;\n this.error = params.error ?? parsed.error;\n this.apiMessage = params.apiMessage ?? parsed.apiMessage;\n Object.setPrototypeOf(this, SilmarilApiError.prototype);\n }\n}\n\nfunction parseErrorBody(body: string): {\n details: MalformedInputDetails | undefined;\n error: string | undefined;\n apiMessage: string | undefined;\n} {\n try {\n const parsed = JSON.parse(body) as unknown;\n if (!parsed || typeof parsed !== \"object\") {\n return { details: undefined, error: undefined, apiMessage: undefined };\n }\n const data = parsed as Record<string, unknown>;\n return {\n details:\n data.details && typeof data.details === \"object\"\n ? (data.details as MalformedInputDetails)\n : undefined,\n error: typeof data.error === \"string\" ? data.error : undefined,\n apiMessage: typeof data.message === \"string\" ? data.message : undefined,\n };\n } catch {\n return { details: undefined, error: undefined, apiMessage: undefined };\n }\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport const HookLabel = {\n USER_INPUT: \"user_input\",\n SYSTEM_PROMPT: \"system_prompt\",\n TOOL_CALL: \"tool_call\",\n TOOL_RESPONSE: \"tool_response\",\n LLM_OUTPUT: \"llm_output\",\n UNKNOWN: \"unknown\",\n} as const;\n\nexport type HookLabel = (typeof HookLabel)[keyof typeof HookLabel];\n\nexport const FirewallHook = {\n LLM_START: \"on_llm_start\",\n CHAT_MODEL_START: \"on_chat_model_start\",\n TOOL_START: \"on_tool_start\",\n RETRIEVER_START: \"on_retriever_start\",\n LLM_END: \"on_llm_end\",\n TOOL_END: \"on_tool_end\",\n RETRIEVER_END: \"on_retriever_end\",\n} as const;\n\nexport type FirewallHook = (typeof FirewallHook)[keyof typeof FirewallHook];\n\nexport const DEFAULT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_START,\n FirewallHook.CHAT_MODEL_START,\n]);\n\nexport const INPUT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_START,\n FirewallHook.CHAT_MODEL_START,\n FirewallHook.TOOL_START,\n FirewallHook.RETRIEVER_START,\n]);\n\nexport const OUTPUT_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n FirewallHook.LLM_END,\n FirewallHook.TOOL_END,\n FirewallHook.RETRIEVER_END,\n]);\n\nexport const ALL_HOOKS: ReadonlySet<FirewallHook> = new Set<FirewallHook>([\n ...INPUT_HOOKS,\n ...OUTPUT_HOOKS,\n]);\n\nexport const FIREWALL_HOOK_TO_LABEL: Readonly<Record<FirewallHook, HookLabel>> = {\n [FirewallHook.CHAT_MODEL_START]: HookLabel.USER_INPUT,\n [FirewallHook.LLM_START]: HookLabel.USER_INPUT,\n [FirewallHook.TOOL_START]: HookLabel.TOOL_CALL,\n [FirewallHook.TOOL_END]: HookLabel.TOOL_RESPONSE,\n [FirewallHook.RETRIEVER_START]: HookLabel.TOOL_CALL,\n [FirewallHook.RETRIEVER_END]: HookLabel.TOOL_RESPONSE,\n [FirewallHook.LLM_END]: HookLabel.LLM_OUTPUT,\n};\n\nconst FIREWALL_HOOK_VALUES: ReadonlySet<string> = new Set(Object.values(FirewallHook));\n\nexport function resolveHooks(\n hooks: Iterable<FirewallHook | string> | undefined,\n): ReadonlySet<FirewallHook> {\n if (hooks === undefined) {\n return DEFAULT_HOOKS;\n }\n const resolved = new Set<FirewallHook>();\n for (const h of hooks) {\n if (!FIREWALL_HOOK_VALUES.has(h)) {\n throw new Error(`Invalid FirewallHook value: ${String(h)}`);\n }\n resolved.add(h as FirewallHook);\n }\n return resolved;\n}\n\nexport function prependHook(text: string, hook: HookLabel | string | undefined | null): string {\n if (hook === undefined || hook === null) {\n return text;\n }\n if (hook === HookLabel.UNKNOWN) {\n return text;\n }\n return `[HOOK:${hook}] ${text}`;\n}\n\nexport function prependToolName(text: string, toolName: string | undefined | null): string {\n if (toolName === undefined || toolName === null) {\n return text;\n }\n return `[TOOL:${toolName}] ${text}`;\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nconst SKIP_ROLES: ReadonlySet<string> = new Set([\"ai\", \"assistant\"]);\nconst SYSTEM_ROLES: ReadonlySet<string> = new Set([\"system\"]);\nconst TOOL_ROLES: ReadonlySet<string> = new Set([\"tool\", \"function\"]);\n\ntype MessageContent = string | ReadonlyArray<string | { type?: string; text?: string }>;\n\ninterface DucktypedMessage {\n role?: string;\n type?: string;\n content?: MessageContent;\n}\n\ninterface DucktypedGeneration {\n text?: string;\n}\n\ninterface DucktypedLLMResult {\n generations?: ReadonlyArray<ReadonlyArray<DucktypedGeneration>>;\n}\n\ninterface DucktypedDocument {\n pageContent?: string;\n}\n\nfunction extractContentText(content: MessageContent | undefined): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && typeof block === \"object\" && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n }\n return \"\";\n}\n\nfunction getRole(message: DucktypedMessage): string {\n if (message.role !== undefined) {\n return message.role.toLowerCase();\n }\n if (typeof message.type === \"string\") {\n return message.type.toLowerCase();\n }\n return \"\";\n}\n\nexport function extractTextFromMessages(\n messages: ReadonlyArray<DucktypedMessage>,\n options: { includeSystem?: boolean; includeTool?: boolean } = {},\n): string {\n const includeSystem = options.includeSystem ?? true;\n const includeTool = options.includeTool ?? true;\n const parts: string[] = [];\n for (const message of messages) {\n const role = getRole(message);\n if (SKIP_ROLES.has(role)) {\n continue;\n }\n if (!includeSystem && SYSTEM_ROLES.has(role)) {\n continue;\n }\n if (!includeTool && TOOL_ROLES.has(role)) {\n continue;\n }\n const text = extractContentText(message.content);\n const stripped = text.trim();\n if (stripped) {\n parts.push(stripped);\n }\n }\n return parts.join(\"\\n\");\n}\n\nexport function extractTextFromPrompts(prompts: readonly string[]): string {\n return prompts\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .join(\"\\n\");\n}\n\nexport function extractTextFromToolInput(inputStr: string): string {\n return inputStr.trim();\n}\n\nexport function extractTextFromLLMResult(response: DucktypedLLMResult): string {\n const parts: string[] = [];\n for (const genList of response.generations ?? []) {\n for (const gen of genList) {\n const text = (gen.text ?? \"\").trim();\n if (text) {\n parts.push(text);\n }\n }\n }\n return parts.join(\"\\n\");\n}\n\nexport function extractTextFromDocuments(documents: ReadonlyArray<DucktypedDocument>): string {\n const parts: string[] = [];\n for (const doc of documents) {\n const text = (doc.pageContent ?? \"\").trim();\n if (text) {\n parts.push(text);\n }\n }\n return parts.join(\"\\n\");\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\n\nimport type { Firewall } from \"../firewall.js\";\nimport { FirewallBlockedException } from \"../exceptions.js\";\nimport {\n FIREWALL_HOOK_TO_LABEL,\n FirewallHook,\n HookLabel,\n resolveHooks,\n} from \"../hooks.js\";\nimport type { BlockResult, ClassifyEvent, LangChainAdapterOptions } from \"../types.js\";\nimport {\n extractTextFromDocuments,\n extractTextFromLLMResult,\n extractTextFromPrompts,\n extractTextFromToolInput,\n} from \"../utils/extract.js\";\n\nconst USER_ROLES: ReadonlySet<string> = new Set([\"human\", \"user\"]);\n\ninterface LangChainDucktypedMessage {\n role?: string;\n type?: string;\n content?: string | ReadonlyArray<string | { type?: string; text?: string }>;\n}\n\nfunction getMessageRole(message: LangChainDucktypedMessage): string {\n if (typeof message.role === \"string\") {\n return message.role.toLowerCase();\n }\n if (typeof message.type === \"string\") {\n return message.type.toLowerCase();\n }\n return \"\";\n}\n\nfunction extractMessageText(content: LangChainDucktypedMessage[\"content\"]): string {\n if (content === undefined) {\n return \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n}\n\nfunction findLastUserMessage(\n messages: ReadonlyArray<LangChainDucktypedMessage>,\n): LangChainDucktypedMessage | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]!;\n if (USER_ROLES.has(getMessageRole(msg))) {\n return msg;\n }\n }\n return undefined;\n}\n\nexport async function createLangChainHandler(\n firewall: Firewall,\n options: LangChainAdapterOptions = {},\n): Promise<BaseCallbackHandler> {\n const { BaseCallbackHandler } = await import(\"@langchain/core/callbacks/base\");\n\n const enabledHooks = resolveHooks(options.hooks);\n // includeSystem / includeTool are retained in LangChainAdapterOptions for\n // backwards compat but are inert under the per-message hook-routing algorithm:\n // handleChatModelStart only scans the last user-role message; system and tool\n // messages are either trusted or already classified by their own hooks.\n const failOpen = options.failOpen ?? true;\n const logger =\n options.logger ??\n ((message: string, error: unknown): void => {\n // eslint-disable-next-line no-console\n console.warn(`silmaril.firewall: ${message}`, error);\n });\n const requestedMode = options.mode ?? (\n options.shadowMode === undefined\n ? firewall.mode\n : options.shadowMode ? \"shadow\" : \"block\"\n );\n const onClassify = options.onClassify;\n\n const fireOnClassify = (event: ClassifyEvent): void => {\n if (!onClassify) {\n return;\n }\n try {\n onClassify(event);\n } catch (err) {\n logger(\"onClassify callback threw\", err);\n }\n };\n\n const classify = async (\n text: string,\n hookLabel: HookLabel,\n runId: string,\n toolName?: string,\n ): Promise<void> => {\n let result: BlockResult;\n try {\n result = await firewall.classify(text, {\n hook: hookLabel,\n ...(requestedMode !== undefined ? { mode: requestedMode } : {}),\n ...(toolName !== undefined ? { toolName } : {}),\n });\n } catch (err) {\n if (!failOpen) {\n throw err;\n }\n logger(\"classification failed, allowing prompt through\", err);\n return;\n }\n const threshold = result.threshold;\n const blocked = result.prediction === \"MALICIOUS\";\n const effectiveMode = requestedMode ?? result.mode ?? \"block\";\n const commonEventFields = {\n hook: hookLabel,\n ...(toolName !== undefined ? { toolName } : {}),\n runId,\n text,\n result,\n };\n fireOnClassify({\n ...commonEventFields,\n blocked,\n mode: effectiveMode,\n shadowMode: effectiveMode === \"shadow\",\n });\n if (!blocked || effectiveMode !== \"block\") {\n return;\n }\n\n throw new FirewallBlockedException({\n score: result.score,\n threshold,\n promptText: text,\n runId,\n hook: hookLabel,\n ...(toolName !== undefined ? { toolName } : {}),\n result,\n });\n };\n\n class SilmarilFirewallHandler extends BaseCallbackHandler {\n override name = \"silmaril_firewall_handler\";\n override raiseError = true;\n override awaitHandlers = true;\n\n override async handleChatModelStart(\n _llm: unknown,\n messages: unknown,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.CHAT_MODEL_START)) {\n return;\n }\n const batches = messages as ReadonlyArray<ReadonlyArray<LangChainDucktypedMessage>>;\n const flat: LangChainDucktypedMessage[] = [];\n for (const batch of batches) {\n for (const m of batch) {\n flat.push(m);\n }\n }\n const lastUser = findLastUserMessage(flat);\n if (!lastUser) {\n return;\n }\n const text = extractMessageText(lastUser.content).trim();\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.CHAT_MODEL_START], runId);\n }\n\n override async handleLLMStart(\n _llm: unknown,\n prompts: string[],\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.LLM_START)) {\n return;\n }\n const text = extractTextFromPrompts(prompts);\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_START], runId);\n }\n\n override async handleToolStart(\n tool: { name?: string } | undefined,\n inputStr: string,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.TOOL_START)) {\n return;\n }\n const text = extractTextFromToolInput(inputStr);\n if (!text) {\n return;\n }\n const toolName = tool?.name;\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, toolName);\n }\n\n override async handleRetrieverStart(\n _retriever: unknown,\n query: string,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.RETRIEVER_START)) {\n return;\n }\n const text = query.trim();\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);\n }\n\n override async handleLLMEnd(output: unknown, runId: string): Promise<void> {\n if (!enabledHooks.has(FirewallHook.LLM_END)) {\n return;\n }\n const text = extractTextFromLLMResult(output as { generations?: ReadonlyArray<ReadonlyArray<{ text?: string }>> });\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);\n }\n\n override async handleToolEnd(\n output: unknown,\n runId: string,\n _parentRunId?: string,\n _tags?: string[],\n _kwargs?: { name?: string },\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.TOOL_END)) {\n return;\n }\n const text = String(output).trim();\n if (!text) {\n return;\n }\n const toolName = _kwargs?.name;\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, toolName);\n }\n\n override async handleRetrieverEnd(\n documents: ReadonlyArray<{ pageContent?: string }>,\n runId: string,\n ): Promise<void> {\n if (!enabledHooks.has(FirewallHook.RETRIEVER_END)) {\n return;\n }\n const text = extractTextFromDocuments(documents);\n if (!text) {\n return;\n }\n await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_END], runId);\n }\n }\n\n return new SilmarilFirewallHandler();\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport {\n Firewall,\n DEFAULT_TIMEOUT_MS,\n} from \"./firewall.js\";\n\nexport { FirewallBlockedException, PromptBlockedException, SilmarilApiError } from \"./exceptions.js\";\nexport type { MalformedInputDetails } from \"./exceptions.js\";\n\nexport type { FirewallMiddleware } from \"./adapters/vercel.js\";\n\nexport {\n HookLabel,\n FirewallHook,\n DEFAULT_HOOKS,\n INPUT_HOOKS,\n OUTPUT_HOOKS,\n ALL_HOOKS,\n FIREWALL_HOOK_TO_LABEL,\n resolveHooks,\n prependHook,\n prependToolName,\n} from \"./hooks.js\";\n\nexport {\n Outcome,\n PRIMARY_OUTCOMES,\n HARMFUL_OUTCOMES,\n OUTCOME_DESCRIPTIONS,\n isPrimaryOutcome,\n isHarmfulOutcome,\n normalizePrimaryOutcome,\n normalizeHarmfulOutcome,\n normalizeHarmfulOutcomeMap,\n} from \"./outcomes.js\";\n\nexport type {\n KnownPrimaryOutcome,\n KnownHarmfulOutcome,\n PrimaryOutcome,\n HarmfulOutcome,\n UnknownOutcome,\n} from \"./outcomes.js\";\n\nexport type {\n BlockResult,\n ClassifyEvent,\n Prediction,\n FirewallMode,\n ClassificationMetadata,\n FirewallOptions,\n ClassifyOptions,\n ClassifyBatchOptions,\n LangChainAdapterOptions,\n LangChainFirewallHandler,\n MiddlewareOptions,\n} from \"./types.js\";\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport { randomUUID } from \"node:crypto\";\n\nimport { createMiddleware, type FirewallMiddleware } from \"./adapters/vercel.js\";\nimport { SilmarilApiError } from \"./exceptions.js\";\nimport { normalizeHarmfulOutcomeMap, normalizePrimaryOutcome } from \"./outcomes.js\";\nimport { sanitizeText } from \"./sanitization.js\";\nimport type {\n BlockResult,\n ClassifyBatchOptions,\n ClassifyOptions,\n ClassificationMetadata,\n FirewallOptions,\n FirewallMode,\n LangChainAdapterOptions,\n LangChainFirewallHandler,\n MiddlewareOptions,\n Prediction,\n} from \"./types.js\";\n\nexport const SDK_VERSION = \"0.6.0\";\nexport const DEFAULT_TIMEOUT_MS = 10_000;\nconst DEFAULT_MAX_RETRIES = 5;\nconst MAX_BACKOFF_SECONDS = 30;\nconst MAX_ERROR_BODY_BYTES = 1 << 16;\n\ninterface SingleClassifyPayload {\n text: string;\n mode?: FirewallMode;\n hook?: string;\n tool_name?: string;\n metadata?: ClassificationMetadata;\n}\n\ninterface BatchClassifyPayload {\n texts: readonly string[];\n mode?: FirewallMode;\n hooks?: readonly string[];\n tool_names?: readonly (string | null)[];\n metadata?: readonly (ClassificationMetadata | null)[];\n}\n\ninterface SingleClassifyResponse {\n prediction: Prediction;\n score: number;\n threshold: number;\n mode?: unknown;\n primary_outcome?: unknown;\n outcome_scores?: unknown;\n detector_scores?: unknown;\n detector_counts?: unknown;\n}\n\ninterface BatchClassifyResponse {\n predictions: readonly SingleClassifyResponse[];\n}\n\nfunction resolveMode(value: unknown, requestedMode?: FirewallMode): FirewallMode | undefined {\n let responseMode: FirewallMode | undefined;\n if (value === \"shadow\" || value === \"warn\" || value === \"block\") {\n responseMode = value;\n } else if (value !== undefined) {\n throw new Error(\"Firewall: response mode must be shadow, warn, or block\");\n }\n\n // A supplied mode is the per-request override contract. Prefer it during\n // rolling upgrades so a missing or stale response field cannot strengthen\n // enforcement beyond what the caller requested.\n return requestedMode ?? responseMode;\n}\n\nfunction legacyMode(shadowMode: boolean | undefined): FirewallMode | undefined {\n return shadowMode === undefined ? undefined : shadowMode ? \"shadow\" : \"block\";\n}\n\nfunction blockResultFromResponse(\n data: SingleClassifyResponse,\n requestedMode?: FirewallMode,\n): BlockResult {\n if (data.prediction !== \"BENIGN\" && data.prediction !== \"MALICIOUS\") {\n throw new Error(\"Firewall: response prediction must be BENIGN or MALICIOUS\");\n }\n const result: {\n prediction: Prediction;\n score: number;\n threshold: number;\n mode?: FirewallMode;\n primaryOutcome?: NonNullable<BlockResult[\"primaryOutcome\"]>;\n outcomeScores?: NonNullable<BlockResult[\"outcomeScores\"]>;\n detectorScores?: NonNullable<BlockResult[\"detectorScores\"]>;\n detectorCounts?: NonNullable<BlockResult[\"detectorCounts\"]>;\n } = {\n prediction: data.prediction,\n score: Number(data.score),\n threshold: Number(data.threshold),\n };\n const mode = resolveMode(data.mode, requestedMode);\n if (mode !== undefined) {\n result.mode = mode;\n }\n if (data.primary_outcome !== undefined) {\n result.primaryOutcome = normalizePrimaryOutcome(data.primary_outcome);\n }\n if (data.outcome_scores !== undefined) {\n const outcomeScores = normalizeHarmfulOutcomeMap(data.outcome_scores, \"outcome_scores\");\n if (outcomeScores !== undefined) {\n result.outcomeScores = outcomeScores;\n }\n }\n if (data.detector_scores !== undefined) {\n const detectorScores = normalizeHarmfulOutcomeMap(data.detector_scores, \"detector_scores\");\n if (detectorScores !== undefined) {\n result.detectorScores = detectorScores;\n }\n }\n if (data.detector_counts !== undefined) {\n const detectorCounts = normalizeHarmfulOutcomeMap(data.detector_counts, \"detector_counts\");\n if (detectorCounts !== undefined) {\n result.detectorCounts = detectorCounts;\n }\n }\n return Object.freeze(result);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction withSdkMetadata(\n metadata: ClassificationMetadata | undefined,\n info: {\n requestId: string;\n inputIndex?: number;\n },\n): ClassificationMetadata {\n const payload: Record<string, unknown> = { ...(metadata ?? {}) };\n const existing = payload.silmaril;\n if (existing !== undefined && !isRecord(existing)) {\n throw new Error(\"Firewall: metadata.silmaril must be an object when provided\");\n }\n payload.silmaril = {\n ...(isRecord(existing) ? existing : {}),\n sdk_language: \"typescript\",\n sdk_version: SDK_VERSION,\n request_id: info.requestId,\n ...(info.inputIndex === undefined ? {} : { input_index: info.inputIndex }),\n };\n return payload;\n}\n\nasync function readCappedErrorBody(response: Response): Promise<string> {\n if (!response.body) {\n return response.text().then((body) => body.slice(0, MAX_ERROR_BODY_BYTES)).catch(() => \"\");\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let remaining = MAX_ERROR_BODY_BYTES;\n try {\n while (remaining > 0) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (!value) {\n continue;\n }\n const chunk = value.byteLength > remaining ? value.slice(0, remaining) : value;\n chunks.push(chunk);\n remaining -= chunk.byteLength;\n if (chunk.byteLength < value.byteLength) {\n break;\n }\n }\n } catch {\n return \"\";\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n\n const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);\n const body = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(body);\n}\n\nexport class Firewall {\n readonly apiKey: string;\n readonly apiUrl: string;\n readonly timeoutMs: number;\n readonly shadowMode: boolean;\n readonly mode: FirewallMode | undefined;\n\n private readonly headers: Readonly<Record<string, string>>;\n\n constructor(options: FirewallOptions) {\n if (!options.apiKey) {\n throw new Error(\"Firewall: apiKey is required\");\n }\n if (!options.apiUrl) {\n throw new Error(\"Firewall: apiUrl is required\");\n }\n this.apiKey = options.apiKey;\n this.apiUrl = options.apiUrl;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (typeof this.timeoutMs !== \"number\" || !Number.isFinite(this.timeoutMs) || this.timeoutMs < 0) {\n throw new Error(`Firewall: timeoutMs must be a finite non-negative number, got ${this.timeoutMs}`);\n }\n this.mode = options.mode ?? legacyMode(options.shadowMode);\n this.shadowMode = this.mode === \"shadow\";\n this.headers = Object.freeze({\n \"x-api-key\": this.apiKey,\n \"content-type\": \"application/json\",\n });\n }\n\n async classify(text: string, options: ClassifyOptions = {}): Promise<BlockResult> {\n const requestId = options.requestId ?? randomUUID();\n return this.classifySingle(sanitizeText(text), options, { requestId });\n }\n\n async classifyBatch(\n texts: readonly string[],\n options: ClassifyBatchOptions = {},\n ): Promise<BlockResult[]> {\n if (texts.length === 0) {\n throw new Error(\"Firewall: texts must not be empty\");\n }\n if (options.hooks !== undefined && options.hooks.length !== texts.length) {\n throw new Error(\n `Firewall: hooks length ${options.hooks.length} does not match texts length ${texts.length}`,\n );\n }\n if (options.toolNames !== undefined && options.toolNames.length !== texts.length) {\n throw new Error(\n `Firewall: toolNames length ${options.toolNames.length} does not match texts length ${texts.length}`,\n );\n }\n if (options.metadata !== undefined && options.metadata.length !== texts.length) {\n throw new Error(\n `Firewall: metadata length ${options.metadata.length} does not match texts length ${texts.length}`,\n );\n }\n\n const requestId = options.requestId ?? randomUUID();\n const payload: BatchClassifyPayload = {\n texts: texts.map((text) => sanitizeText(text)),\n };\n const requestedMode = options.mode ?? this.mode;\n if (requestedMode !== undefined) {\n payload.mode = requestedMode;\n }\n if (options.hooks && options.hooks.length > 0) {\n payload.hooks = options.hooks.map((h) => String(h));\n }\n if (options.toolNames && options.toolNames.length > 0) {\n payload.tool_names = options.toolNames.map((t) => (t === undefined ? null : t));\n }\n payload.metadata = texts.map((_, index) =>\n withSdkMetadata(options.metadata?.[index], {\n requestId,\n inputIndex: index,\n }),\n );\n const data = await this.postWithRetry<BatchClassifyResponse>(payload);\n return data.predictions.map((p) => blockResultFromResponse(p, requestedMode));\n }\n\n asLangChainHandler<THandler = LangChainFirewallHandler>(\n options: LangChainAdapterOptions = {},\n ): Promise<THandler> {\n return import(\"./adapters/langchain.js\").then((m) =>\n m.createLangChainHandler(this, options) as Promise<THandler>,\n );\n }\n\n asMiddleware(options: MiddlewareOptions = {}): FirewallMiddleware {\n return createMiddleware(this, options);\n }\n\n private async postWithRetry<T>(\n payload: SingleClassifyPayload | BatchClassifyPayload,\n maxRetries: number = DEFAULT_MAX_RETRIES,\n ): Promise<T> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const response = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(payload),\n redirect: \"error\",\n signal: AbortSignal.timeout(this.timeoutMs),\n });\n if (response.status !== 429 || attempt === maxRetries) {\n if (!response.ok) {\n const body = await readCappedErrorBody(response);\n throw new SilmarilApiError({\n status: response.status,\n statusText: response.statusText,\n body,\n });\n }\n return (await response.json()) as T;\n }\n const waitSeconds = Math.min(2 ** attempt, MAX_BACKOFF_SECONDS);\n await new Promise<void>((resolve) => setTimeout(resolve, waitSeconds * 1000));\n }\n throw new Error(\"Firewall: exhausted retries (unreachable)\");\n }\n\n private async classifySingle(\n text: string,\n options: ClassifyOptions,\n metadataInfo: {\n requestId: string;\n },\n ): Promise<BlockResult> {\n const payload: SingleClassifyPayload = { text };\n const requestedMode = options.mode ?? this.mode;\n if (requestedMode !== undefined) {\n payload.mode = requestedMode;\n }\n if (options.hook !== undefined) {\n payload.hook = options.hook;\n }\n if (options.toolName !== undefined) {\n payload.tool_name = options.toolName;\n }\n payload.metadata = withSdkMetadata(options.metadata, metadataInfo);\n const data = await this.postWithRetry<SingleClassifyResponse>(payload);\n return blockResultFromResponse(data, requestedMode);\n }\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nimport type { Firewall } from \"../firewall.js\";\nimport { FirewallBlockedException } from \"../exceptions.js\";\nimport { HookLabel } from \"../hooks.js\";\nimport type { BlockResult, MiddlewareOptions } from \"../types.js\";\n\ninterface VercelContentPart {\n type?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n output?: unknown;\n result?: unknown;\n}\n\ninterface VercelPromptMessage {\n role: string;\n content: string | ReadonlyArray<VercelContentPart | string>;\n}\n\ninterface VercelToolCall {\n toolCallType?: string;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n input?: unknown;\n}\n\ninterface VercelGenerateResult {\n text?: string;\n toolCalls?: ReadonlyArray<VercelToolCall>;\n}\n\ninterface WrapGenerateArgs<TResult extends VercelGenerateResult & Record<string, unknown>> {\n params: { prompt?: ReadonlyArray<VercelPromptMessage> } & Record<string, unknown>;\n doGenerate: () => PromiseLike<TResult>;\n}\n\ninterface WrapStreamArgs<\n TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>,\n> {\n params: { prompt?: ReadonlyArray<VercelPromptMessage> } & Record<string, unknown>;\n doStream: () => PromiseLike<TResult>;\n}\n\ninterface StreamPart {\n type?: string;\n textDelta?: string;\n delta?: string;\n}\n\ninterface VercelStepContext {\n toolName: string | undefined;\n toolCallId: string | undefined;\n}\n\nfunction stringifyToolValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction extractContentText(content: VercelPromptMessage[\"content\"]): string {\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push(block);\n } else if (block && block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n return parts.join(\" \");\n}\n\nfunction iterateToolResultParts(\n message: VercelPromptMessage,\n): Array<{ text: string; toolName: string | undefined; toolCallId: string | undefined }> {\n if (typeof message.content === \"string\") {\n return [];\n }\n const out: Array<{ text: string; toolName: string | undefined; toolCallId: string | undefined }> = [];\n for (const part of message.content) {\n if (typeof part === \"string\") {\n continue;\n }\n if (part.type === \"tool-result\") {\n const text = stringifyToolResult(part.result !== undefined ? part.result : part.output);\n if (text.trim()) {\n out.push({ text, toolName: part.toolName, toolCallId: part.toolCallId });\n }\n }\n }\n return out;\n}\n\nfunction stringifyToolResult(value: unknown): string {\n if (!isRecord(value)) {\n return stringifyToolValue(value);\n }\n if ((value.type === \"text\" || value.type === \"error-text\") && typeof value.value === \"string\") {\n return value.value;\n }\n if ((value.type === \"json\" || value.type === \"error-json\") && value.value !== undefined) {\n return stringifyToolValue(value.value);\n }\n if (value.type === \"content\" && Array.isArray(value.value)) {\n return value.value\n .map((part) => (isRecord(part) && part.type === \"text\" && typeof part.text === \"string\" ? part.text : \"\"))\n .filter((text) => text.length > 0)\n .join(\" \");\n }\n return stringifyToolValue(value);\n}\n\nfunction findLastUserMessage(\n messages: ReadonlyArray<VercelPromptMessage>,\n): VercelPromptMessage | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]!;\n if (msg.role.toLowerCase() === \"user\") {\n return msg;\n }\n }\n return undefined;\n}\n\nexport interface FirewallMiddleware {\n readonly specificationVersion: \"v3\";\n readonly middlewareVersion: \"v2\";\n wrapGenerate: <TResult extends VercelGenerateResult & Record<string, unknown>>(\n args: WrapGenerateArgs<TResult>,\n ) => Promise<TResult>;\n wrapStream: <TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>>(\n args: WrapStreamArgs<TResult>,\n ) => Promise<TResult>;\n}\n\nexport function createMiddleware(\n firewall: Firewall,\n options: MiddlewareOptions = {},\n): FirewallMiddleware {\n const scanInput = options.scanInput ?? true;\n const scanOutput = options.scanOutput ?? false;\n const requestedMode = options.mode ?? (\n options.shadowMode === undefined\n ? firewall.mode\n : options.shadowMode ? \"shadow\" : \"block\"\n );\n\n const classifyOrBlock = async (\n text: string,\n hook: HookLabel,\n context: VercelStepContext = { toolName: undefined, toolCallId: undefined },\n ): Promise<void> => {\n if (!text.trim()) {\n return;\n }\n const { toolName, toolCallId } = context;\n const result: BlockResult = await firewall.classify(\n text,\n {\n hook,\n ...(toolName !== undefined ? { toolName } : {}),\n ...(requestedMode !== undefined ? { mode: requestedMode } : {}),\n },\n );\n const threshold = result.threshold;\n const blocked = result.prediction === \"MALICIOUS\";\n const effectiveMode = requestedMode ?? result.mode ?? \"block\";\n const commonEventFields = {\n hook,\n ...(toolName !== undefined ? { toolName } : {}),\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n text,\n result,\n };\n options.onClassify?.({\n ...commonEventFields,\n blocked,\n mode: effectiveMode,\n shadowMode: effectiveMode === \"shadow\",\n });\n if (!blocked || effectiveMode !== \"block\") {\n return;\n }\n\n const err = new FirewallBlockedException({\n score: result.score,\n threshold,\n promptText: text,\n hook,\n ...(toolName !== undefined ? { toolName } : {}),\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n result,\n });\n options.onBlocked?.(err);\n throw err;\n };\n\n const scanPrompt = async (prompt: ReadonlyArray<VercelPromptMessage>): Promise<void> => {\n if (prompt.length === 0) {\n return;\n }\n const last = prompt[prompt.length - 1]!;\n const role = last.role.toLowerCase();\n\n // If the newest message is a tool result (typical mid-flow in a\n // tool-calling loop), classify each tool-result part individually with\n // tool_response + toolName. No manual wiring from the caller — the\n // toolName is read directly from the Vercel content part.\n if (role === \"tool\") {\n for (const { text, toolName, toolCallId } of iterateToolResultParts(last)) {\n await classifyOrBlock(text, HookLabel.TOOL_RESPONSE, { toolName, toolCallId });\n }\n return;\n }\n\n // Otherwise, fall back to scanning the most recent user message.\n // Covers: [user], [system, user], [user, assistant(text), user], etc.\n const lastUser = findLastUserMessage(prompt);\n if (!lastUser) {\n return;\n }\n const text = extractContentText(lastUser.content).trim();\n if (!text) {\n return;\n }\n await classifyOrBlock(text, HookLabel.USER_INPUT);\n };\n\n const scanGenerateResult = async (result: VercelGenerateResult): Promise<void> => {\n if (scanOutput && typeof result.text === \"string\" && result.text.length > 0) {\n await classifyOrBlock(result.text, HookLabel.LLM_OUTPUT);\n }\n if (options.scanToolCalls && Array.isArray(result.toolCalls)) {\n for (const call of result.toolCalls) {\n if (!call || typeof call !== \"object\") {\n continue;\n }\n const toolInput = call.args !== undefined ? call.args : call.input;\n const args =\n typeof toolInput === \"string\" ? toolInput : stringifyToolValue(toolInput);\n const toolName = typeof call.toolName === \"string\" ? call.toolName : undefined;\n const toolCallId = typeof call.toolCallId === \"string\" ? call.toolCallId : undefined;\n if (args.trim()) {\n await classifyOrBlock(args, HookLabel.TOOL_CALL, { toolName, toolCallId });\n }\n }\n }\n };\n\n return {\n specificationVersion: \"v3\",\n middlewareVersion: \"v2\",\n\n async wrapGenerate<TResult extends VercelGenerateResult & Record<string, unknown>>({\n params,\n doGenerate,\n }: WrapGenerateArgs<TResult>): Promise<TResult> {\n if (scanInput) {\n await scanPrompt(params.prompt ?? []);\n }\n const result = await doGenerate();\n await scanGenerateResult(result);\n return result;\n },\n\n async wrapStream<TResult extends { stream: ReadableStream<unknown> } & Record<string, unknown>>({\n params,\n doStream,\n }: WrapStreamArgs<TResult>): Promise<TResult> {\n if (scanInput) {\n await scanPrompt(params.prompt ?? []);\n }\n const { stream, ...rest } = await doStream();\n if (!scanOutput) {\n return { stream, ...rest } as unknown as TResult;\n }\n\n let buffered = \"\";\n const transformed = stream.pipeThrough(\n new TransformStream<unknown, unknown>({\n transform(chunk, controller): void {\n const part = chunk as StreamPart;\n if (part && part.type === \"text-delta\") {\n const delta = part.textDelta ?? part.delta ?? \"\";\n buffered += delta;\n }\n controller.enqueue(chunk);\n },\n async flush(controller): Promise<void> {\n if (!buffered.trim()) {\n return;\n }\n try {\n await classifyOrBlock(buffered, HookLabel.LLM_OUTPUT);\n } catch (err) {\n if (err instanceof FirewallBlockedException) {\n controller.enqueue({ type: \"error\", error: err });\n return;\n }\n throw err;\n }\n },\n }),\n );\n return { stream: transformed, ...rest } as unknown as TResult;\n },\n };\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nexport const Outcome = {\n Benign: \"benign\",\n InformationDisclosure: \"information_disclosure\",\n SecretExposure: \"secret_exposure\",\n ControlAbuse: \"control_abuse\",\n SystemCompromise: \"system_compromise\",\n ServiceDisruption: \"service_disruption\",\n CodeGeneration: \"code_generation\",\n StoryScriptGeneration: \"story_script_generation\",\n GameGeneration: \"game_generation\",\n WebsiteGeneration: \"website_generation\",\n ClickUpTermsViolation: \"clickup_terms_violation\",\n TraditionalAiAbuse: \"traditional_ai_abuse\",\n} as const;\n\ndeclare const unknownOutcomeBrand: unique symbol;\n\nexport type KnownPrimaryOutcome = (typeof Outcome)[keyof typeof Outcome];\nexport type KnownHarmfulOutcome = Exclude<KnownPrimaryOutcome, typeof Outcome.Benign>;\nexport type UnknownOutcome = string & { readonly [unknownOutcomeBrand]: \"UnknownOutcome\" };\nexport type PrimaryOutcome = KnownPrimaryOutcome | UnknownOutcome;\nexport type HarmfulOutcome = KnownHarmfulOutcome | UnknownOutcome;\n\nexport const PRIMARY_OUTCOMES = [\n Outcome.Benign,\n Outcome.InformationDisclosure,\n Outcome.SecretExposure,\n Outcome.ControlAbuse,\n Outcome.SystemCompromise,\n Outcome.ServiceDisruption,\n Outcome.CodeGeneration,\n Outcome.StoryScriptGeneration,\n Outcome.GameGeneration,\n Outcome.WebsiteGeneration,\n Outcome.ClickUpTermsViolation,\n Outcome.TraditionalAiAbuse,\n] as const satisfies readonly PrimaryOutcome[];\n\nexport const HARMFUL_OUTCOMES = [\n Outcome.InformationDisclosure,\n Outcome.SecretExposure,\n Outcome.ControlAbuse,\n Outcome.SystemCompromise,\n Outcome.ServiceDisruption,\n Outcome.CodeGeneration,\n Outcome.StoryScriptGeneration,\n Outcome.GameGeneration,\n Outcome.WebsiteGeneration,\n Outcome.ClickUpTermsViolation,\n Outcome.TraditionalAiAbuse,\n] as const satisfies readonly KnownHarmfulOutcome[];\n\nexport const OUTCOME_DESCRIPTIONS = {\n [Outcome.Benign]: \"No harmful firewall outcome detected.\",\n [Outcome.InformationDisclosure]:\n \"Exposes private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.\",\n [Outcome.SecretExposure]:\n \"Exposes credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.\",\n [Outcome.ControlAbuse]:\n \"Misuses authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.\",\n [Outcome.SystemCompromise]:\n \"Enables privilege escalation, account takeover, hostile integration or plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.\",\n [Outcome.ServiceDisruption]:\n \"Causes downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence.\",\n [Outcome.CodeGeneration]:\n \"Requests generation or material modification of executable code, scripts, workflows, or configuration.\",\n [Outcome.StoryScriptGeneration]:\n \"Requests generation of narrative prose, dialogue, scripts, or story artifacts.\",\n [Outcome.GameGeneration]:\n \"Requests generation of a game, quest, level, mechanic, or playable experience.\",\n [Outcome.WebsiteGeneration]:\n \"Requests generation of a website, landing page, storefront, or web experience.\",\n [Outcome.ClickUpTermsViolation]:\n \"Requests content or actions that violate the configured ClickUp tenant policy.\",\n [Outcome.TraditionalAiAbuse]:\n \"Requests unsafe AI assistance outside the concrete security outcome classes.\",\n} as const satisfies Readonly<Record<KnownPrimaryOutcome, string>>;\n\nconst PRIMARY_OUTCOME_SET = new Set<string>(PRIMARY_OUTCOMES);\nconst HARMFUL_OUTCOME_SET = new Set<string>(HARMFUL_OUTCOMES);\n\nexport function isPrimaryOutcome(value: unknown): value is KnownPrimaryOutcome {\n return typeof value === \"string\" && PRIMARY_OUTCOME_SET.has(value);\n}\n\nexport function isHarmfulOutcome(value: unknown): value is KnownHarmfulOutcome {\n return typeof value === \"string\" && HARMFUL_OUTCOME_SET.has(value);\n}\n\nexport function normalizePrimaryOutcome(\n value: unknown,\n fieldName = \"primary_outcome\",\n): PrimaryOutcome {\n if (typeof value !== \"string\") {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);\n }\n return isPrimaryOutcome(value) ? value : (value as UnknownOutcome);\n}\n\nexport function normalizeHarmfulOutcome(\n value: unknown,\n fieldName = \"outcome\",\n): HarmfulOutcome {\n if (typeof value !== \"string\" || value === Outcome.Benign) {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);\n }\n return isHarmfulOutcome(value) ? value : (value as UnknownOutcome);\n}\n\nexport function normalizeHarmfulOutcomeMap(\n values: unknown,\n fieldName: string,\n): Readonly<Partial<Record<HarmfulOutcome, number>>> | undefined {\n if (values === undefined || values === null) {\n return undefined;\n }\n if (typeof values !== \"object\" || Array.isArray(values)) {\n throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(values)}`);\n }\n const out: Partial<Record<HarmfulOutcome, number>> = {};\n for (const [key, value] of Object.entries(values)) {\n const normalizedKey = normalizeHarmfulOutcome(key, `${fieldName} key`);\n if (typeof value !== \"number\") {\n throw new Error(`Firewall: invalid ${fieldName} value for ${JSON.stringify(key)}`);\n }\n out[normalizedKey] = value;\n }\n return Object.freeze(out);\n}\n","// Copyright (c) 2024-2025 Silmaril Security Inc. All rights reserved.\n// PROPRIETARY AND CONFIDENTIAL\n\nfunction isHighSurrogate(code: number): boolean {\n return code >= 0xd800 && code <= 0xdbff;\n}\n\nfunction isLowSurrogate(code: number): boolean {\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\nexport function sanitizeText(text: string): string {\n let out = \"\";\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i);\n if (isHighSurrogate(code)) {\n if (i + 1 < text.length && isLowSurrogate(text.charCodeAt(i + 1))) {\n out += text[i]!;\n out += text[i + 1]!;\n i++;\n }\n continue;\n }\n if (!isLowSurrogate(code)) {\n out += text[i]!;\n }\n }\n return out;\n}\n"],"mappings":"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","names":["findLastUserMessage","text","isRecord","body"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HookLabel, B as BlockResult } from './firewall-
|
|
2
|
-
export { A as ALL_HOOKS, C as ClassificationMetadata, a as ClassifyBatchOptions, b as ClassifyEvent, c as ClassifyOptions, D as DEFAULT_HOOKS, d as DEFAULT_TIMEOUT_MS, F as FIREWALL_HOOK_TO_LABEL, e as Firewall, f as FirewallHook, g as FirewallMiddleware, h as
|
|
1
|
+
import { H as HookLabel, B as BlockResult } from './firewall-C0ibVbst.cjs';
|
|
2
|
+
export { A as ALL_HOOKS, C as ClassificationMetadata, a as ClassifyBatchOptions, b as ClassifyEvent, c as ClassifyOptions, D as DEFAULT_HOOKS, d as DEFAULT_TIMEOUT_MS, F as FIREWALL_HOOK_TO_LABEL, e as Firewall, f as FirewallHook, g as FirewallMiddleware, h as FirewallMode, i as FirewallOptions, j as HARMFUL_OUTCOMES, k as HarmfulOutcome, I as INPUT_HOOKS, K as KnownHarmfulOutcome, l as KnownPrimaryOutcome, L as LangChainAdapterOptions, m as LangChainFirewallHandler, M as MiddlewareOptions, O as OUTCOME_DESCRIPTIONS, n as OUTPUT_HOOKS, o as Outcome, P as PRIMARY_OUTCOMES, p as Prediction, q as PrimaryOutcome, U as UnknownOutcome, r as isHarmfulOutcome, s as isPrimaryOutcome, t as normalizeHarmfulOutcome, u as normalizeHarmfulOutcomeMap, v as normalizePrimaryOutcome, w as prependHook, x as prependToolName, y as resolveHooks } from './firewall-C0ibVbst.cjs';
|
|
3
3
|
|
|
4
4
|
interface MalformedInputDetails {
|
|
5
5
|
field?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HookLabel, B as BlockResult } from './firewall-
|
|
2
|
-
export { A as ALL_HOOKS, C as ClassificationMetadata, a as ClassifyBatchOptions, b as ClassifyEvent, c as ClassifyOptions, D as DEFAULT_HOOKS, d as DEFAULT_TIMEOUT_MS, F as FIREWALL_HOOK_TO_LABEL, e as Firewall, f as FirewallHook, g as FirewallMiddleware, h as
|
|
1
|
+
import { H as HookLabel, B as BlockResult } from './firewall-C0ibVbst.js';
|
|
2
|
+
export { A as ALL_HOOKS, C as ClassificationMetadata, a as ClassifyBatchOptions, b as ClassifyEvent, c as ClassifyOptions, D as DEFAULT_HOOKS, d as DEFAULT_TIMEOUT_MS, F as FIREWALL_HOOK_TO_LABEL, e as Firewall, f as FirewallHook, g as FirewallMiddleware, h as FirewallMode, i as FirewallOptions, j as HARMFUL_OUTCOMES, k as HarmfulOutcome, I as INPUT_HOOKS, K as KnownHarmfulOutcome, l as KnownPrimaryOutcome, L as LangChainAdapterOptions, m as LangChainFirewallHandler, M as MiddlewareOptions, O as OUTCOME_DESCRIPTIONS, n as OUTPUT_HOOKS, o as Outcome, P as PRIMARY_OUTCOMES, p as Prediction, q as PrimaryOutcome, U as UnknownOutcome, r as isHarmfulOutcome, s as isPrimaryOutcome, t as normalizeHarmfulOutcome, u as normalizeHarmfulOutcomeMap, v as normalizePrimaryOutcome, w as prependHook, x as prependToolName, y as resolveHooks } from './firewall-C0ibVbst.js';
|
|
3
3
|
|
|
4
4
|
interface MalformedInputDetails {
|
|
5
5
|
field?: string;
|
package/dist/index.js
CHANGED
|
@@ -251,7 +251,7 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
251
251
|
const logger = options.logger ?? ((message, error) => {
|
|
252
252
|
console.warn(`silmaril.firewall: ${message}`, error);
|
|
253
253
|
});
|
|
254
|
-
const
|
|
254
|
+
const requestedMode = options.mode ?? (options.shadowMode === void 0 ? firewall.mode : options.shadowMode ? "shadow" : "block");
|
|
255
255
|
const onClassify = options.onClassify;
|
|
256
256
|
const fireOnClassify = (event) => {
|
|
257
257
|
if (!onClassify) {
|
|
@@ -268,6 +268,7 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
268
268
|
try {
|
|
269
269
|
result = await firewall.classify(text, {
|
|
270
270
|
hook: hookLabel,
|
|
271
|
+
...requestedMode !== void 0 ? { mode: requestedMode } : {},
|
|
271
272
|
...toolName !== void 0 ? { toolName } : {}
|
|
272
273
|
});
|
|
273
274
|
} catch (err) {
|
|
@@ -279,6 +280,7 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
279
280
|
}
|
|
280
281
|
const threshold = result.threshold;
|
|
281
282
|
const blocked = result.prediction === "MALICIOUS";
|
|
283
|
+
const effectiveMode = requestedMode ?? result.mode ?? "block";
|
|
282
284
|
const commonEventFields = {
|
|
283
285
|
hook: hookLabel,
|
|
284
286
|
...toolName !== void 0 ? { toolName } : {},
|
|
@@ -289,9 +291,10 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
289
291
|
fireOnClassify({
|
|
290
292
|
...commonEventFields,
|
|
291
293
|
blocked,
|
|
292
|
-
|
|
294
|
+
mode: effectiveMode,
|
|
295
|
+
shadowMode: effectiveMode === "shadow"
|
|
293
296
|
});
|
|
294
|
-
if (!blocked ||
|
|
297
|
+
if (!blocked || effectiveMode !== "block") {
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
300
|
throw new FirewallBlockedException({
|
|
@@ -486,7 +489,7 @@ function findLastUserMessage(messages) {
|
|
|
486
489
|
function createMiddleware(firewall, options = {}) {
|
|
487
490
|
const scanInput = options.scanInput ?? true;
|
|
488
491
|
const scanOutput = options.scanOutput ?? false;
|
|
489
|
-
const
|
|
492
|
+
const requestedMode = options.mode ?? (options.shadowMode === void 0 ? firewall.mode : options.shadowMode ? "shadow" : "block");
|
|
490
493
|
const classifyOrBlock = async (text, hook, context = { toolName: void 0, toolCallId: void 0 }) => {
|
|
491
494
|
if (!text.trim()) {
|
|
492
495
|
return;
|
|
@@ -494,10 +497,15 @@ function createMiddleware(firewall, options = {}) {
|
|
|
494
497
|
const { toolName, toolCallId } = context;
|
|
495
498
|
const result = await firewall.classify(
|
|
496
499
|
text,
|
|
497
|
-
|
|
500
|
+
{
|
|
501
|
+
hook,
|
|
502
|
+
...toolName !== void 0 ? { toolName } : {},
|
|
503
|
+
...requestedMode !== void 0 ? { mode: requestedMode } : {}
|
|
504
|
+
}
|
|
498
505
|
);
|
|
499
506
|
const threshold = result.threshold;
|
|
500
507
|
const blocked = result.prediction === "MALICIOUS";
|
|
508
|
+
const effectiveMode = requestedMode ?? result.mode ?? "block";
|
|
501
509
|
const commonEventFields = {
|
|
502
510
|
hook,
|
|
503
511
|
...toolName !== void 0 ? { toolName } : {},
|
|
@@ -508,9 +516,10 @@ function createMiddleware(firewall, options = {}) {
|
|
|
508
516
|
options.onClassify?.({
|
|
509
517
|
...commonEventFields,
|
|
510
518
|
blocked,
|
|
511
|
-
|
|
519
|
+
mode: effectiveMode,
|
|
520
|
+
shadowMode: effectiveMode === "shadow"
|
|
512
521
|
});
|
|
513
|
-
if (!blocked ||
|
|
522
|
+
if (!blocked || effectiveMode !== "block") {
|
|
514
523
|
return;
|
|
515
524
|
}
|
|
516
525
|
const err = new FirewallBlockedException({
|
|
@@ -747,12 +756,24 @@ function sanitizeText(text) {
|
|
|
747
756
|
}
|
|
748
757
|
|
|
749
758
|
// src/firewall.ts
|
|
750
|
-
var SDK_VERSION = "0.
|
|
759
|
+
var SDK_VERSION = "0.6.0";
|
|
751
760
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
752
761
|
var DEFAULT_MAX_RETRIES = 5;
|
|
753
762
|
var MAX_BACKOFF_SECONDS = 30;
|
|
754
763
|
var MAX_ERROR_BODY_BYTES = 1 << 16;
|
|
755
|
-
function
|
|
764
|
+
function resolveMode(value, requestedMode) {
|
|
765
|
+
let responseMode;
|
|
766
|
+
if (value === "shadow" || value === "warn" || value === "block") {
|
|
767
|
+
responseMode = value;
|
|
768
|
+
} else if (value !== void 0) {
|
|
769
|
+
throw new Error("Firewall: response mode must be shadow, warn, or block");
|
|
770
|
+
}
|
|
771
|
+
return requestedMode ?? responseMode;
|
|
772
|
+
}
|
|
773
|
+
function legacyMode(shadowMode) {
|
|
774
|
+
return shadowMode === void 0 ? void 0 : shadowMode ? "shadow" : "block";
|
|
775
|
+
}
|
|
776
|
+
function blockResultFromResponse(data, requestedMode) {
|
|
756
777
|
if (data.prediction !== "BENIGN" && data.prediction !== "MALICIOUS") {
|
|
757
778
|
throw new Error("Firewall: response prediction must be BENIGN or MALICIOUS");
|
|
758
779
|
}
|
|
@@ -761,6 +782,10 @@ function blockResultFromResponse(data) {
|
|
|
761
782
|
score: Number(data.score),
|
|
762
783
|
threshold: Number(data.threshold)
|
|
763
784
|
};
|
|
785
|
+
const mode = resolveMode(data.mode, requestedMode);
|
|
786
|
+
if (mode !== void 0) {
|
|
787
|
+
result.mode = mode;
|
|
788
|
+
}
|
|
764
789
|
if (data.primary_outcome !== void 0) {
|
|
765
790
|
result.primaryOutcome = normalizePrimaryOutcome(data.primary_outcome);
|
|
766
791
|
}
|
|
@@ -844,6 +869,7 @@ var Firewall = class {
|
|
|
844
869
|
apiUrl;
|
|
845
870
|
timeoutMs;
|
|
846
871
|
shadowMode;
|
|
872
|
+
mode;
|
|
847
873
|
headers;
|
|
848
874
|
constructor(options) {
|
|
849
875
|
if (!options.apiKey) {
|
|
@@ -858,7 +884,8 @@ var Firewall = class {
|
|
|
858
884
|
if (typeof this.timeoutMs !== "number" || !Number.isFinite(this.timeoutMs) || this.timeoutMs < 0) {
|
|
859
885
|
throw new Error(`Firewall: timeoutMs must be a finite non-negative number, got ${this.timeoutMs}`);
|
|
860
886
|
}
|
|
861
|
-
this.
|
|
887
|
+
this.mode = options.mode ?? legacyMode(options.shadowMode);
|
|
888
|
+
this.shadowMode = this.mode === "shadow";
|
|
862
889
|
this.headers = Object.freeze({
|
|
863
890
|
"x-api-key": this.apiKey,
|
|
864
891
|
"content-type": "application/json"
|
|
@@ -891,6 +918,10 @@ var Firewall = class {
|
|
|
891
918
|
const payload = {
|
|
892
919
|
texts: texts.map((text) => sanitizeText(text))
|
|
893
920
|
};
|
|
921
|
+
const requestedMode = options.mode ?? this.mode;
|
|
922
|
+
if (requestedMode !== void 0) {
|
|
923
|
+
payload.mode = requestedMode;
|
|
924
|
+
}
|
|
894
925
|
if (options.hooks && options.hooks.length > 0) {
|
|
895
926
|
payload.hooks = options.hooks.map((h) => String(h));
|
|
896
927
|
}
|
|
@@ -904,7 +935,7 @@ var Firewall = class {
|
|
|
904
935
|
})
|
|
905
936
|
);
|
|
906
937
|
const data = await this.postWithRetry(payload);
|
|
907
|
-
return data.predictions.map((p) => blockResultFromResponse(p));
|
|
938
|
+
return data.predictions.map((p) => blockResultFromResponse(p, requestedMode));
|
|
908
939
|
}
|
|
909
940
|
asLangChainHandler(options = {}) {
|
|
910
941
|
return Promise.resolve().then(() => (init_langchain(), langchain_exports)).then(
|
|
@@ -941,6 +972,10 @@ var Firewall = class {
|
|
|
941
972
|
}
|
|
942
973
|
async classifySingle(text, options, metadataInfo) {
|
|
943
974
|
const payload = { text };
|
|
975
|
+
const requestedMode = options.mode ?? this.mode;
|
|
976
|
+
if (requestedMode !== void 0) {
|
|
977
|
+
payload.mode = requestedMode;
|
|
978
|
+
}
|
|
944
979
|
if (options.hook !== void 0) {
|
|
945
980
|
payload.hook = options.hook;
|
|
946
981
|
}
|
|
@@ -949,7 +984,7 @@ var Firewall = class {
|
|
|
949
984
|
}
|
|
950
985
|
payload.metadata = withSdkMetadata(options.metadata, metadataInfo);
|
|
951
986
|
const data = await this.postWithRetry(payload);
|
|
952
|
-
return blockResultFromResponse(data);
|
|
987
|
+
return blockResultFromResponse(data, requestedMode);
|
|
953
988
|
}
|
|
954
989
|
};
|
|
955
990
|
|