aboutsummaryrefslogtreecommitdiffstats
path: root/apps/workers
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-09-07 10:43:48 +0000
committerMohamed Bassem <me@mbassem.com>2025-09-07 10:43:48 +0000
commit5f870549ce689c4c35df6a322c931fe78c51d5ac (patch)
treec5c8c7ea39abeb695dc40abeaaaa9c205f26cc80 /apps/workers
parent517e0c105b159266e5ac7503d1124e44363b8828 (diff)
downloadkarakeep-5f870549ce689c4c35df6a322c931fe78c51d5ac.tar.zst
fix: don't mark inferenace job as failed when there's no content. fixes #1666
Diffstat (limited to 'apps/workers')
-rw-r--r--apps/workers/workers/inference/summarize.ts8
-rw-r--r--apps/workers/workers/inference/tagging.ts31
2 files changed, 32 insertions, 7 deletions
diff --git a/apps/workers/workers/inference/summarize.ts b/apps/workers/workers/inference/summarize.ts
index 8564ef15..02a7f4e0 100644
--- a/apps/workers/workers/inference/summarize.ts
+++ b/apps/workers/workers/inference/summarize.ts
@@ -65,6 +65,14 @@ export async function runSummarization(
(await Bookmark.getBookmarkPlainTextContent(link, bookmarkData.userId)) ??
"";
+ if (!link.description && !content) {
+ // No content to infer from; skip summarization
+ logger.info(
+ `[inference] No content found for link "${bookmarkId}". Skipping summary.`,
+ );
+ return;
+ }
+
textToSummarize = `
Title: ${link.title ?? ""}
Description: ${link.description ?? ""}
diff --git a/apps/workers/workers/inference/tagging.ts b/apps/workers/workers/inference/tagging.ts
index 6c862f76..5697e73a 100644
--- a/apps/workers/workers/inference/tagging.ts
+++ b/apps/workers/workers/inference/tagging.ts
@@ -3,7 +3,10 @@ import { DequeuedJob, EnqueueOptions } from "liteque";
import { buildImpersonatingTRPCClient } from "trpc";
import { z } from "zod";
-import type { InferenceClient } from "@karakeep/shared/inference";
+import type {
+ InferenceClient,
+ InferenceResponse,
+} from "@karakeep/shared/inference";
import type { ZOpenAIRequest } from "@karakeep/shared/queues";
import { db } from "@karakeep/db";
import {
@@ -75,7 +78,7 @@ function tagNormalizer(col: Column) {
}
async function buildPrompt(
bookmark: NonNullable<Awaited<ReturnType<typeof fetchBookmark>>>,
-) {
+): Promise<string | null> {
const prompts = await fetchCustomPrompts(bookmark.userId, "text");
if (bookmark.link) {
let content =
@@ -85,9 +88,11 @@ async function buildPrompt(
)) ?? "";
if (!bookmark.link.description && !content) {
- throw new Error(
- `No content found for link "${bookmark.id}". Skipping ...`,
+ // No content to infer from; signal skip to avoid marking job as failed
+ logger.info(
+ `[inference] No content found for link "${bookmark.id}". Skipping tagging.`,
);
+ return null;
}
return buildTextPrompt(
serverConfig.inference.inferredTagLang,
@@ -221,7 +226,11 @@ async function inferTagsFromText(
inferenceClient: InferenceClient,
abortSignal: AbortSignal,
) {
- return await inferenceClient.inferFromText(await buildPrompt(bookmark), {
+ const prompt = await buildPrompt(bookmark);
+ if (!prompt) {
+ return null;
+ }
+ return await inferenceClient.inferFromText(prompt, {
schema: openAIResponseSchema,
abortSignal,
});
@@ -233,7 +242,7 @@ async function inferTags(
inferenceClient: InferenceClient,
abortSignal: AbortSignal,
) {
- let response;
+ let response: InferenceResponse | null;
if (bookmark.link || bookmark.text) {
response = await inferTagsFromText(bookmark, inferenceClient, abortSignal);
} else if (bookmark.asset) {
@@ -262,7 +271,8 @@ async function inferTags(
}
if (!response) {
- throw new Error(`[inference][${jobId}] Inference response is empty`);
+ // Skipped due to missing content or prompt; propagate skip
+ return null;
}
try {
@@ -432,6 +442,13 @@ export async function runTagging(
job.abortSignal,
);
+ if (tags === null) {
+ logger.info(
+ `[inference][${jobId}] Skipping tagging for bookmark "${bookmark.id}" due to missing content.`,
+ );
+ return;
+ }
+
await connectTags(bookmarkId, tags, bookmark.userId);
// Propagate priority to child jobs