From 3e454a262f907f550ab91754245f2d8a818d2c78 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 18:09:54 +0800 Subject: [PATCH 1/8] =?UTF-8?q?build:=20=E5=B0=86=20tesseract.js=20?= =?UTF-8?q?=E4=BB=8E=20devDependencies=20=E7=A7=BB=E8=87=B3=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 确保生产环境能正确使用 tesseract.js 功能 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 73339601ad..49f7340559 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "officeparser": "^4.2.0", "os-proxy-config": "^1.1.2", "selection-hook": "^1.0.11", + "tesseract.js": "^6.0.1", "turndown": "7.2.0" }, "devDependencies": { @@ -258,7 +259,6 @@ "string-width": "^7.2.0", "styled-components": "^6.1.11", "tar": "^7.4.3", - "tesseract.js": "^6.0.1", "tiny-pinyin": "^1.3.2", "tokenx": "^1.1.0", "tsx": "^4.20.3", From 9d8eea7f2ea5f6a773ffd161b7d688d766c4994b Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 18:16:03 +0800 Subject: [PATCH 2/8] =?UTF-8?q?refactor(ocr):=20=E5=B0=86Tesseract?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=96=87=E4=BB=B6=E7=A7=BB=E5=8A=A8=E5=88=B0?= =?UTF-8?q?tesseract=E5=AD=90=E7=9B=AE=E5=BD=95=E5=B9=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/services/ocr/OcrService.ts | 2 +- src/main/services/ocr/{ => tesseract}/TesseractService.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) rename src/main/services/ocr/{ => tesseract}/TesseractService.ts (95%) diff --git a/src/main/services/ocr/OcrService.ts b/src/main/services/ocr/OcrService.ts index 11f3a41ec0..8e6845de9c 100644 --- a/src/main/services/ocr/OcrService.ts +++ b/src/main/services/ocr/OcrService.ts @@ -13,7 +13,7 @@ import { import { statSync } from 'fs' import { readFile } from 'fs/promises' -import { getTesseractWorker } from './TesseractService' +import { getTesseractWorker } from './tesseract/TesseractService' const logger = loggerService.withContext('main:OcrService') diff --git a/src/main/services/ocr/TesseractService.ts b/src/main/services/ocr/tesseract/TesseractService.ts similarity index 95% rename from src/main/services/ocr/TesseractService.ts rename to src/main/services/ocr/tesseract/TesseractService.ts index 6cd98b9bf5..59942ddac1 100644 --- a/src/main/services/ocr/TesseractService.ts +++ b/src/main/services/ocr/tesseract/TesseractService.ts @@ -110,7 +110,10 @@ let worker: Tesseract.Worker | null = null export const getTesseractWorker = async (): Promise => { if (!worker) { // for now, only support limited languages - worker = await createWorker(['chi_sim', 'chi_tra', 'eng']) + worker = await createWorker(['chi_sim', 'chi_tra', 'eng'], undefined, { + dataPath: '', + gzip: false + }) } return worker } From 94b71dde607e8d4b8300a86066baeb1fd1bafcf9 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 18:32:31 +0800 Subject: [PATCH 3/8] =?UTF-8?q?refactor(TesseractService):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0worker=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加loggerService用于记录worker日志,并更新createWorker配置以使用自定义logger --- src/main/services/ocr/tesseract/TesseractService.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/services/ocr/tesseract/TesseractService.ts b/src/main/services/ocr/tesseract/TesseractService.ts index 59942ddac1..7700324606 100644 --- a/src/main/services/ocr/tesseract/TesseractService.ts +++ b/src/main/services/ocr/tesseract/TesseractService.ts @@ -1,5 +1,8 @@ +import { loggerService } from '@logger' import Tesseract, { createWorker } from 'tesseract.js' +const logger = loggerService.withContext('TesseractService') + let worker: Tesseract.Worker | null = null // const languageCodeMap: Record = { @@ -111,8 +114,8 @@ export const getTesseractWorker = async (): Promise => { if (!worker) { // for now, only support limited languages worker = await createWorker(['chi_sim', 'chi_tra', 'eng'], undefined, { - dataPath: '', - gzip: false + // langPath: getCacheDir(), + logger: (m) => logger.debug('From worker', m) }) } return worker From a37e81fc4f0c5ef597fdf873c22b7f58e838e101 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 18:51:57 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat(i18n):=20=E6=B7=BB=E5=8A=A0OCR?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=9A=84=E5=A4=9A=E8=AF=AD=E8=A8=80=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/i18n/locales/en-us.json | 19 +++++++++++++++++++ src/renderer/src/i18n/locales/ja-jp.json | 19 +++++++++++++++++++ src/renderer/src/i18n/locales/ru-ru.json | 19 +++++++++++++++++++ src/renderer/src/i18n/locales/zh-tw.json | 19 +++++++++++++++++++ src/renderer/src/i18n/translate/el-gr.json | 20 ++++++++++++++++++++ src/renderer/src/i18n/translate/es-es.json | 20 ++++++++++++++++++++ src/renderer/src/i18n/translate/fr-fr.json | 20 ++++++++++++++++++++ src/renderer/src/i18n/translate/pt-pt.json | 20 ++++++++++++++++++++ 8 files changed, 156 insertions(+) diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index a7a52d1ac3..71a168fa04 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -1558,6 +1558,15 @@ }, "tip": "If the response is successful, then only messages exceeding 30 seconds will trigger a reminder" }, + "ocr": { + "error": { + "unknown": "An error occurred during the OCR process" + }, + "file": { + "not_supported": "Unsupported file type {{type}}" + }, + "processing": "OCR processing..." + }, "ollama": { "keep_alive_time": { "description": "The time in minutes to keep the connection alive, default is 5 minutes.", @@ -3478,6 +3487,16 @@ }, "title": "Settings", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "The provider does not exist" + }, + "title": "Image" + }, + "image_provider": "OCR service provider", + "title": "OCR service" + }, "preprocess": { "provider": "Document Processing Provider", "provider_placeholder": "Choose a document processing provider", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 953213fdbf..a2157c4a21 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1558,6 +1558,15 @@ }, "tip": "応答が成功した場合、30秒を超えるメッセージのみに通知を行います" }, + "ocr": { + "error": { + "unknown": "OCR処理中にエラーが発生しました" + }, + "file": { + "not_supported": "サポートされていないファイルタイプ {{type}}" + }, + "processing": "OCR処理中..." + }, "ollama": { "keep_alive_time": { "description": "モデルがメモリに保持される時間(デフォルト:5分)", @@ -3478,6 +3487,16 @@ }, "title": "設定", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "該提供者は存在しません" + }, + "title": "画像" + }, + "image_provider": "OCRサービスプロバイダー", + "title": "OCRサービス" + }, "preprocess": { "provider": "プレプロセスプロバイダー", "provider_placeholder": "前処理プロバイダーを選択してください", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index a251854c34..b6e6c26590 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -1558,6 +1558,15 @@ }, "tip": "Если ответ успешен, уведомление выдается только по сообщениям, превышающим 30 секунд" }, + "ocr": { + "error": { + "unknown": "Произошла ошибка в процессе распознавания текста" + }, + "file": { + "not_supported": "Неподдерживаемый тип файла {{type}}" + }, + "processing": "Обработка OCR..." + }, "ollama": { "keep_alive_time": { "description": "Время в минутах, в течение которого модель остается активной, по умолчанию 5 минут.", @@ -3478,6 +3487,16 @@ }, "title": "Настройки", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "Поставщик не существует" + }, + "title": "Изображение" + }, + "image_provider": "Поставщик услуг OCR", + "title": "OCR-сервис" + }, "preprocess": { "provider": "Поставщик обработки документов", "provider_placeholder": "Выберите поставщика услуг обработки документов", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 2e2babab9c..9f8f75b301 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1558,6 +1558,15 @@ }, "tip": "如果回應成功,則只針對超過30秒的訊息發出提醒" }, + "ocr": { + "error": { + "unknown": "OCR過程發生錯誤" + }, + "file": { + "not_supported": "不支持的文件類型 {{type}}" + }, + "processing": "OCR 處理中..." + }, "ollama": { "keep_alive_time": { "description": "對話後模型在記憶體中保持的時間(預設為 5 分鐘)", @@ -3478,6 +3487,16 @@ }, "title": "設定", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "該提供商不存在" + }, + "title": "圖片" + }, + "image_provider": "OCR 服務提供商", + "title": "OCR 服務" + }, "preprocess": { "provider": "文件處理供應商", "provider_placeholder": "選擇一個文件處理供應商", diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 9cbbda52c1..015558658b 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -1558,6 +1558,15 @@ }, "tip": "Εάν η απάντηση είναι επιτυχής, η ειδοποίηση εμφανίζεται μόνο για μηνύματα που υπερβαίνουν τα 30 δευτερόλεπτα" }, + "ocr": { + "error": { + "unknown": "Η διαδικασία OCR εμφάνισε σφάλμα" + }, + "file": { + "not_supported": "Μη υποστηριζόμενος τύπος αρχείου {{type}}" + }, + "processing": "Η επεξεργασία OCR βρίσκεται σε εξέλιξη..." + }, "ollama": { "keep_alive_time": { "description": "Χρόνος που ο μοντέλος διατηρείται στη μνήμη μετά τη συζήτηση (προεπιλογή: 5 λεπτά)", @@ -2679,6 +2688,7 @@ "title": "Αυτόματη ενημέρωση" }, "avatar": { + "builtin": "Ενσωματωμένο αναγνωριστικό προφίλ", "reset": "Επαναφορά εικονιδίου" }, "backup": { @@ -3477,6 +3487,16 @@ }, "title": "Ρυθμίσεις", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "Ο πάροχος δεν υπάρχει" + }, + "title": "Εικόνα" + }, + "image_provider": "Πάροχοι υπηρεσιών OCR", + "title": "Υπηρεσία OCR" + }, "preprocess": { "provider": "πάροχος υπηρεσιών προεπεξεργασίας εγγράφων", "provider_placeholder": "Επιλέξτε έναν πάροχο υπηρεσιών προεπεξεργασίας εγγράφων", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 25e186c567..f6ba2ce7a9 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -1558,6 +1558,15 @@ }, "tip": "Si la respuesta es exitosa, solo se enviará un recordatorio para mensajes que excedan los 30 segundos" }, + "ocr": { + "error": { + "unknown": "El proceso OCR ha fallado" + }, + "file": { + "not_supported": "Tipo de archivo no compatible {{type}}" + }, + "processing": "Procesando OCR..." + }, "ollama": { "keep_alive_time": { "description": "Tiempo que el modelo permanece en memoria después de la conversación (por defecto: 5 minutos)", @@ -2679,6 +2688,7 @@ "title": "Actualización automática" }, "avatar": { + "builtin": "Avatares integrados", "reset": "Restablecer avatar" }, "backup": { @@ -3477,6 +3487,16 @@ }, "title": "Configuración", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "El proveedor no existe" + }, + "title": "Imagen" + }, + "image_provider": "Proveedor de servicios OCR", + "title": "Servicio OCR" + }, "preprocess": { "provider": "Proveedor de servicios de preprocesamiento de documentos", "provider_placeholder": "Seleccionar un proveedor de servicios de preprocesamiento de documentos", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index 266985c94b..454e03f305 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -1558,6 +1558,15 @@ }, "tip": "Si la réponse est réussie, un rappel est envoyé uniquement pour les messages dépassant 30 secondes" }, + "ocr": { + "error": { + "unknown": "Une erreur s'est produite lors du processus OCR" + }, + "file": { + "not_supported": "Type de fichier non pris en charge {{type}}" + }, + "processing": "Traitement OCR en cours..." + }, "ollama": { "keep_alive_time": { "description": "Le temps pendant lequel le modèle reste en mémoire après la conversation (par défaut : 5 minutes)", @@ -2679,6 +2688,7 @@ "title": "Mise à jour automatique" }, "avatar": { + "builtin": "Avatar intégré", "reset": "Réinitialiser l'avatar" }, "backup": { @@ -3477,6 +3487,16 @@ }, "title": "Paramètres", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "Ce fournisseur n'existe pas" + }, + "title": "Image" + }, + "image_provider": "Fournisseur de service OCR", + "title": "Service OCR" + }, "preprocess": { "provider": "fournisseur de services de prétraitement de documents", "provider_placeholder": "Choisissez un prestataire de traitement de documents", diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index def1ee8900..b655984b86 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -1558,6 +1558,15 @@ }, "tip": "Se a resposta for bem-sucedida, lembrete apenas para mensagens que excedam 30 segundos" }, + "ocr": { + "error": { + "unknown": "O processo OCR apresentou um erro" + }, + "file": { + "not_supported": "Tipo de arquivo não suportado {{type}}" + }, + "processing": "Processamento OCR em andamento..." + }, "ollama": { "keep_alive_time": { "description": "Tempo que o modelo permanece na memória após a conversa (padrão: 5 minutos)", @@ -2679,6 +2688,7 @@ "title": "Atualização automática" }, "avatar": { + "builtin": "Avatares integrados", "reset": "Redefinir avatar" }, "backup": { @@ -3477,6 +3487,16 @@ }, "title": "Configurações", "tool": { + "ocr": { + "image": { + "error": { + "provider_not_found": "O provedor não existe" + }, + "title": "Imagem" + }, + "image_provider": "Provedor de serviços OCR", + "title": "Serviço OCR" + }, "preprocess": { "provider": "prestador de serviços de pré-processamento de documentos", "provider_placeholder": "Escolha um fornecedor de pré-processamento de documentos", From 239c9c7205d4895024f629d4c5b7fe7225d8cb48 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 20:23:23 +0800 Subject: [PATCH 5/8] =?UTF-8?q?refactor(preload):=20=E7=A7=BB=E5=8A=A8OCR?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89=E5=88=B0=E5=85=B1=E4=BA=AB?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将OCR相关的类型定义(OcrProvider, OcrResult, SupportedOcrFile)从渲染进程类型文件移动到共享类型文件@types,以提高代码复用性和维护性 --- src/preload/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/preload/index.ts b/src/preload/index.ts index b7d18edd70..af4803fd50 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -17,15 +17,17 @@ import { MemoryConfig, MemoryListOptions, MemorySearchOptions, + OcrProvider, + OcrResult, Provider, S3Config, Shortcut, + SupportedOcrFile, ThemeMode, WebDavConfig } from '@types' import { contextBridge, ipcRenderer, OpenDialogOptions, shell, webUtils } from 'electron' import { Notification } from 'src/renderer/src/types/notification' -import { OcrProvider, OcrResult, SupportedOcrFile } from 'src/renderer/src/types/ocr' import { CreateDirectoryOptions } from 'webdav' import type { ActionItem } from '../renderer/src/types/selectionTypes' From cf0e6a8f735399cf6784698f1ec1765fb04336b2 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 20:28:33 +0800 Subject: [PATCH 6/8] =?UTF-8?q?refactor(ocr):=20=E4=BF=AE=E6=94=B9tesserac?= =?UTF-8?q?tOcr=E8=BF=94=E5=9B=9E=E5=AE=8C=E6=95=B4=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E8=80=8C=E9=9D=9E=E4=BB=85=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 返回完整识别结果以便后续处理使用更多OCR信息,同时简化imageOcr中的条件判断逻辑 --- src/main/services/ocr/OcrService.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/services/ocr/OcrService.ts b/src/main/services/ocr/OcrService.ts index 8e6845de9c..d4fe7eef46 100644 --- a/src/main/services/ocr/OcrService.ts +++ b/src/main/services/ocr/OcrService.ts @@ -23,7 +23,7 @@ const logger = loggerService.withContext('main:OcrService') * @returns ocr result * @throws {Error} */ -const tesseractOcr = async (file: ImageFileMetadata | string): Promise => { +const tesseractOcr = async (file: ImageFileMetadata | string): Promise => { try { const worker = await getTesseractWorker() let ret: Tesseract.RecognizeResult @@ -37,7 +37,7 @@ const tesseractOcr = async (file: ImageFileMetadata | string): Promise = const buffer = await readFile(file.path) ret = await worker.recognize(buffer) } - return ret.data.text + return ret } catch (e) { logger.error('Failed to ocr with tesseract.', e as Error) throw e @@ -53,13 +53,11 @@ const tesseractOcr = async (file: ImageFileMetadata | string): Promise = */ const imageOcr = async (file: ImageFileMetadata, provider: ImageOcrProvider): Promise => { if (isBuiltinOcrProvider(provider)) { - let text: string - switch (provider.id) { - case 'tesseract': - text = await tesseractOcr(file) - return { text } - default: - throw new Error(`Unsupported built-in ocr provider: ${provider.id}`) + if (provider.id === 'tesseract') { + const result = await tesseractOcr(file) + return { text: result.data.text } + } else { + throw new Error(`Unsupported built-in ocr provider: ${provider.id}`) } } throw new Error(`Provider ${provider.id} is not supported.`) From 364a0f8bb7ff7aac3811f64037b93cd6fa8eb2d0 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 20:29:46 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix(ocr):=20=E4=BF=AE=E5=A4=8D=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=E4=B8=8EOCR=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E8=80=85=E8=83=BD=E5=8A=9B=E4=B8=8D=E5=8C=B9=E9=85=8D=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8A=9B=E5=87=BA=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将错误抛出语句移至else分支 --- src/main/services/ocr/OcrService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/services/ocr/OcrService.ts b/src/main/services/ocr/OcrService.ts index d4fe7eef46..5a52ad7833 100644 --- a/src/main/services/ocr/OcrService.ts +++ b/src/main/services/ocr/OcrService.ts @@ -73,8 +73,9 @@ const imageOcr = async (file: ImageFileMetadata, provider: ImageOcrProvider): Pr export const ocr = async (file: SupportedOcrFile, provider: OcrProvider): Promise => { if (isImageFile(file) && isImageOcrProvider(provider)) { return imageOcr(file, provider) + } else { + throw new Error(`File type and provider capability is not matched, otherwise one of them is not supported.`) } - throw new Error(`File type and provider capability is not matched, otherwise one of them is not supported.`) } /** From 9ac7d7f95eefc4db26dd93600adc9de1832b7d4b Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 22 Aug 2025 20:32:07 +0800 Subject: [PATCH 8/8] =?UTF-8?q?refactor(ocr):=20=E7=AE=80=E5=8C=96=20DEFAU?= =?UTF-8?q?LT=5FOCR=5FPROVIDER=20=E7=9A=84=E7=B1=BB=E5=9E=8B=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/config/ocr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/config/ocr.ts b/src/renderer/src/config/ocr.ts index 7af72a9802..1187b49dc0 100644 --- a/src/renderer/src/config/ocr.ts +++ b/src/renderer/src/config/ocr.ts @@ -10,6 +10,6 @@ const tesseract: BuiltinOcrProvider & ImageOcrProvider = { export const BUILTIN_OCR_PROVIDERS: BuiltinOcrProvider[] = [tesseract] as const -export const DEFAULT_OCR_PROVIDER: Record = { +export const DEFAULT_OCR_PROVIDER = { image: tesseract -} as const +} as const satisfies Record