From e2fc7f596d0da2327026e81ef53f81fde204fe73 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 29 Apr 2025 21:45:34 -0700 Subject: [PATCH] Add llmindex to systemstatus --- .../admin/settings/settings.component.spec.ts | 3 ++ .../system-status-dialog.component.html | 37 +++++++++++++++++++ .../system-status-dialog.component.spec.ts | 3 ++ .../system-status-dialog.component.ts | 7 ++++ .../document-detail.component.ts | 1 + src-ui/src/app/data/system-status.ts | 4 ++ src/documents/tasks.py | 18 ++++++--- src/documents/views.py | 33 +++++++++++++++++ 8 files changed, 100 insertions(+), 6 deletions(-) diff --git a/src-ui/src/app/components/admin/settings/settings.component.spec.ts b/src-ui/src/app/components/admin/settings/settings.component.spec.ts index c6eeaf896..ce092364e 100644 --- a/src-ui/src/app/components/admin/settings/settings.component.spec.ts +++ b/src-ui/src/app/components/admin/settings/settings.component.spec.ts @@ -314,6 +314,9 @@ describe('SettingsComponent', () => { sanity_check_status: SystemStatusItemStatus.ERROR, sanity_check_last_run: new Date().toISOString(), sanity_check_error: 'Error running sanity check.', + llmindex_status: SystemStatusItemStatus.DISABLED, + llmindex_last_modified: new Date().toISOString(), + llmindex_error: null, }, } jest.spyOn(systemStatusService, 'get').mockReturnValue(of(status)) diff --git a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.html b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.html index e3b09ee7e..d5df7959d 100644 --- a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.html +++ b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.html @@ -254,6 +254,43 @@
Error:
{{status.tasks.sanity_check_error}} } + @if (aiEnabled) { +
AI Index
+
+ + @if (currentUserIsSuperUser) { + @if (isRunning(PaperlessTaskName.LLMIndexUpdate)) { +
+ } @else { + + } + } +
+ + @if (status.tasks.llmindex_status === 'OK') { +
Last Run:
{{status.tasks.llmindex_last_modified | customDate:'medium'}} + } @else { +
Error:
{{status.tasks.llmindex_error}} + } +
+ } diff --git a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.spec.ts b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.spec.ts index f9d8b4d68..6ac1fd34a 100644 --- a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.spec.ts +++ b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.spec.ts @@ -67,6 +67,9 @@ const status: SystemStatus = { sanity_check_status: SystemStatusItemStatus.OK, sanity_check_last_run: new Date().toISOString(), sanity_check_error: null, + llmindex_status: SystemStatusItemStatus.OK, + llmindex_last_modified: new Date().toISOString(), + llmindex_error: null, }, } diff --git a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.ts b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.ts index bc027ebbf..19171941c 100644 --- a/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.ts +++ b/src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.ts @@ -12,9 +12,11 @@ import { SystemStatus, SystemStatusItemStatus, } from 'src/app/data/system-status' +import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe' import { FileSizePipe } from 'src/app/pipes/file-size.pipe' import { PermissionsService } from 'src/app/services/permissions.service' +import { SettingsService } from 'src/app/services/settings.service' import { SystemStatusService } from 'src/app/services/system-status.service' import { TasksService } from 'src/app/services/tasks.service' import { ToastService } from 'src/app/services/toast.service' @@ -41,6 +43,7 @@ export class SystemStatusDialogComponent implements OnInit { private tasksService = inject(TasksService) private toastService = inject(ToastService) private permissionsService = inject(PermissionsService) + private settingsService = inject(SettingsService) public SystemStatusItemStatus = SystemStatusItemStatus public PaperlessTaskName = PaperlessTaskName @@ -56,6 +59,10 @@ export class SystemStatusDialogComponent implements OnInit { return this.permissionsService.isSuperUser() } + get aiEnabled(): boolean { + return this.settingsService.get(SETTINGS_KEYS.AI_ENABLED) + } + public ngOnInit() { this.versionMismatch = environment.production && diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 337cba668..8d2f32ac9 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -182,6 +182,7 @@ export class DocumentDetailComponent { private documentsService = inject(DocumentService) private route = inject(ActivatedRoute) + private tagService = inject(TagService) private correspondentService = inject(CorrespondentService) private documentTypeService = inject(DocumentTypeService) private router = inject(Router) diff --git a/src-ui/src/app/data/system-status.ts b/src-ui/src/app/data/system-status.ts index 698382154..dc18677a5 100644 --- a/src-ui/src/app/data/system-status.ts +++ b/src-ui/src/app/data/system-status.ts @@ -7,6 +7,7 @@ export enum SystemStatusItemStatus { OK = 'OK', ERROR = 'ERROR', WARNING = 'WARNING', + DISABLED = 'DISABLED', } export interface SystemStatus { @@ -43,5 +44,8 @@ export interface SystemStatus { sanity_check_status: SystemStatusItemStatus sanity_check_last_run: string // ISO date string sanity_check_error: string + llmindex_status: SystemStatusItemStatus + llmindex_last_modified: string // ISO date string + llmindex_error: string } } diff --git a/src/documents/tasks.py b/src/documents/tasks.py index d0d2bd95b..8841d8518 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -558,12 +558,18 @@ def llmindex_index( ) from paperless_ai.indexing import update_llm_index - result = update_llm_index( - progress_bar_disable=progress_bar_disable, - rebuild=rebuild, - ) - task.status = states.SUCCESS - task.result = result + try: + result = update_llm_index( + progress_bar_disable=progress_bar_disable, + rebuild=rebuild, + ) + task.status = states.SUCCESS + task.result = result + except Exception as e: + logger.error("LLM index error: " + str(e)) + task.status = states.FAILURE + task.result = str(e) + task.date_done = timezone.now() task.save(update_fields=["status", "result", "date_done"]) diff --git a/src/documents/views.py b/src/documents/views.py index 61b4af214..2e8ca85c5 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -185,6 +185,7 @@ from paperless.serialisers import UserSerializer from paperless.views import StandardPagination from paperless_ai.ai_classifier import get_ai_document_classification from paperless_ai.chat import stream_chat_with_documents +from paperless_ai.indexing import update_llm_index from paperless_ai.matching import extract_unmatched_names from paperless_ai.matching import match_correspondents_by_name from paperless_ai.matching import match_document_types_by_name @@ -2465,6 +2466,10 @@ class TasksViewSet(ReadOnlyModelViewSet): sanity_check, {"scheduled": False, "raise_on_error": False}, ), + PaperlessTask.TaskName.LLMINDEX_UPDATE: ( + update_llm_index, + {"scheduled": False, "rebuild": False}, + ), } def get_queryset(self): @@ -2970,6 +2975,31 @@ class SystemStatusView(PassUserMixin): last_sanity_check.date_done if last_sanity_check else None ) + ai_config = AIConfig() + if not ai_config.llm_index_enabled: + llmindex_status = "DISABLED" + llmindex_error = None + llmindex_last_modified = None + else: + last_llmindex_update = ( + PaperlessTask.objects.filter( + task_name=PaperlessTask.TaskName.LLMINDEX_UPDATE, + ) + .order_by("-date_done") + .first() + ) + llmindex_status = "OK" + llmindex_error = None + if last_llmindex_update is None: + llmindex_status = "WARNING" + llmindex_error = "No LLM index update tasks found" + elif last_llmindex_update and last_llmindex_update.status == states.FAILURE: + llmindex_status = "ERROR" + llmindex_error = last_llmindex_update.result + llmindex_last_modified = ( + last_llmindex_update.date_done if last_llmindex_update else None + ) + return Response( { "pngx_version": current_version, @@ -3007,6 +3037,9 @@ class SystemStatusView(PassUserMixin): "sanity_check_status": sanity_check_status, "sanity_check_last_run": sanity_check_last_run, "sanity_check_error": sanity_check_error, + "llmindex_status": llmindex_status, + "llmindex_last_modified": llmindex_last_modified, + "llmindex_error": llmindex_error, }, }, )