diff --git a/src/main/ai/AiWorker.ts b/src/main/ai/AiWorker.ts index 9cb314f..73c4790 100644 --- a/src/main/ai/AiWorker.ts +++ b/src/main/ai/AiWorker.ts @@ -144,7 +144,17 @@ export class AiWorker { // 5MB cap 초과 시 throw → AiWorker 의 'other' 분기 → markAiFailed 도달. const visionModel = this.settings ? await this.settings.getVisionModel() : null; let images: Array<{ base64: string; mime: string }> | undefined; - if (visionModel && note.media.length > 0 && this.mediaStore) { + const visionActive = !!(visionModel && note.media.length > 0 && this.mediaStore); + // v0.3.14 — vision 활성 여부 진단 로그. 사용자가 vision_model 미설정으로 text-only + // path 가 도는지 / 이미지가 모델에 전달되는지 확인 가능 (logs/main.log). + this.logger.info('ai.vision.decide', { + noteId: job.noteId, + visionActive, + visionModelConfigured: !!visionModel, + mediaCount: note.media.length, + mediaStorePresent: !!this.mediaStore + }); + if (visionActive) { const oversize = note.media.find((m) => m.bytes > 5 * 1024 * 1024); if (oversize) { throw new Error(`image ${oversize.relPath} exceeds 5MB cap (${oversize.bytes} bytes)`); diff --git a/src/renderer/inbox/components/NoteCard.tsx b/src/renderer/inbox/components/NoteCard.tsx index 474dd59..80bf483 100644 --- a/src/renderer/inbox/components/NoteCard.tsx +++ b/src/renderer/inbox/components/NoteCard.tsx @@ -279,6 +279,18 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore

{fallbackTitle}

)} + {/* v0.3.14 — graceful fallback 가시화. title 이 placeholder 면 vision 처리 실패 + (모델 미선택 / 응답 unparseable / null 반환). 사용자가 설정 점검 + 수동 편집 유도. */} + {!isTrash && local.aiStatus === 'done' && local.aiTitle === '(첨부 메모)' && local.media.length > 0 && ( +
+ 💡 AI 가 이미지 내용을 정리하지 못했습니다. 설정 → AI 제공자 → Vision 섹션에서 + vision-capable 모델 (예: gemma4:26b, gemma3:27b) 선택 여부 확인하세요. + 제목/요약을 직접 클릭해 수정 가능합니다. +
+ )} {local.aiStatus === 'done' && ( <> {isTrash ? (