From 5df0ea2de2d4b79af3a918c0dc484f6701ed1982 Mon Sep 17 00:00:00 2001 From: "ochan.kwon" Date: Mon, 30 Mar 2026 15:11:34 +0900 Subject: [PATCH] feat(knowledge): resolve remote images in file upload path The file upload pipeline (ProcessDocument) only called ResolveAndStore(), which handles inline bytes and base64 data URIs but explicitly skips http/https URLs. This meant markdown files with external image URLs (e.g. GitHub issue screenshots) were never downloaded, stored, or processed by VLM multimodal. Add ResolveRemoteImages() call after ResolveAndStore() in the file upload path, matching the existing manual processing path behavior. --- internal/application/service/knowledge.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/application/service/knowledge.go b/internal/application/service/knowledge.go index 595836d6..6b5d9ab4 100644 --- a/internal/application/service/knowledge.go +++ b/internal/application/service/knowledge.go @@ -7576,7 +7576,20 @@ func (s *knowledgeService) ProcessDocument(ctx context.Context, t *asynq.Task) e convertResult.MarkdownContent = updatedMarkdown } storedImages = images - logger.Infof(ctx, "Resolved %d images for knowledge %s", len(storedImages), knowledge.ID) + + // Resolve remote http(s) images (e.g. markdown external URLs) → download + upload to storage. + // ResolveAndStore handles inline bytes and base64; ResolveRemoteImages handles http/https URLs. + updatedContent, remoteImages, remoteErr := s.imageResolver.ResolveRemoteImages(ctx, convertResult.MarkdownContent, fileSvc, tenantID) + if remoteErr != nil { + logger.Warnf(ctx, "Remote image resolution partially failed: %v", remoteErr) + } + if len(remoteImages) > 0 { + logger.Infof(ctx, "Resolved %d remote images for knowledge %s", len(remoteImages), knowledge.ID) + convertResult.MarkdownContent = updatedContent + storedImages = append(storedImages, remoteImages...) + } + + logger.Infof(ctx, "Resolved %d total images for knowledge %s", len(storedImages), knowledge.ID) } // Step 3: Split into chunks using Go chunker