From 0bdba54ba24a14e7dc2cfab64084452756bccce7 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Mon, 22 Dec 2025 16:59:04 +0200 Subject: feat: Add user settings to disable auto tagging/summarization (#2275) * feat: Add per-user settings to disable auto-tagging and auto-summarization This commit adds user-level controls for AI features when they are enabled on the server. Users can now toggle auto-tagging and auto-summarization on/off from the AI Settings page. Changes: - Added autoTaggingEnabled and autoSummarizationEnabled fields to user table - Updated user settings schemas and API endpoints to handle new fields - Modified inference workers to check user preferences before processing - Added toggle switches to AI Settings page (only visible when server has features enabled) - Generated database migration for new fields - Exposed enableAutoTagging and enableAutoSummarization in client config The settings default to null (use server default). When explicitly set to false, the user's bookmarks will skip the respective AI processing. * revert migration * i18n --------- Co-authored-by: Claude --- apps/workers/workers/inference/summarize.ts | 17 ++++++++++++++++- apps/workers/workers/inference/tagging.ts | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'apps/workers') diff --git a/apps/workers/workers/inference/summarize.ts b/apps/workers/workers/inference/summarize.ts index 23636961..460c3328 100644 --- a/apps/workers/workers/inference/summarize.ts +++ b/apps/workers/workers/inference/summarize.ts @@ -1,7 +1,7 @@ import { and, eq } from "drizzle-orm"; import { db } from "@karakeep/db"; -import { bookmarks, customPrompts } from "@karakeep/db/schema"; +import { bookmarks, customPrompts, users } from "@karakeep/db/schema"; import { triggerSearchReindex, ZOpenAIRequest } from "@karakeep/shared-server"; import serverConfig from "@karakeep/shared/config"; import { InferenceClient } from "@karakeep/shared/inference"; @@ -56,6 +56,21 @@ export async function runSummarization( const bookmarkData = await fetchBookmarkDetailsForSummary(bookmarkId); + // Check user-level preference + const userSettings = await db.query.users.findFirst({ + where: eq(users.id, bookmarkData.userId), + columns: { + autoSummarizationEnabled: true, + }, + }); + + if (userSettings?.autoSummarizationEnabled === false) { + logger.debug( + `[inference][${jobId}] Skipping summarization job for bookmark with id "${bookmarkId}" because user has disabled auto-summarization.`, + ); + return; + } + let textToSummarize = ""; if (bookmarkData.type === BookmarkTypes.LINK && bookmarkData.link) { const link = bookmarkData.link; diff --git a/apps/workers/workers/inference/tagging.ts b/apps/workers/workers/inference/tagging.ts index 1c0077b9..6d20b953 100644 --- a/apps/workers/workers/inference/tagging.ts +++ b/apps/workers/workers/inference/tagging.ts @@ -13,6 +13,7 @@ import { bookmarkTags, customPrompts, tagsOnBookmarks, + users, } from "@karakeep/db/schema"; import { triggerRuleEngineOnEvent, @@ -437,6 +438,21 @@ export async function runTagging( ); } + // Check user-level preference + const userSettings = await db.query.users.findFirst({ + where: eq(users.id, bookmark.userId), + columns: { + autoTaggingEnabled: true, + }, + }); + + if (userSettings?.autoTaggingEnabled === false) { + logger.debug( + `[inference][${jobId}] Skipping tagging job for bookmark with id "${bookmarkId}" because user has disabled auto-tagging.`, + ); + return; + } + logger.info( `[inference][${jobId}] Starting an inference job for bookmark with id "${bookmark.id}"`, ); -- cgit v1.2.3-70-g09d2