From bd71bba2da93adc0cda315ac6d42a1b230a7bc74 Mon Sep 17 00:00:00 2001 From: th-kim0823 Date: Tue, 12 May 2026 13:39:11 +0900 Subject: [PATCH] =?UTF-8?q?chore(release):=20v0.3.13=20=E2=80=94=20vision?= =?UTF-8?q?=20generate=20timeout=20120s=20=E2=86=92=20300s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gemma4:26b (25B MoE + vision encoder 550M) 등 대형 vision 모델의 cold-start 가 60-180s 소요. 기본 120s timeout 으로 첫 호출 fail 빈번. vision path 에 한해 Math.max(timeoutMs, 300_000) — text-only 영향 없음. gemma4:26b 가 Text+Image 양 modality 지원 검증 완료 (blog.google/gemma-4, ollama.com/library/gemma4:26b). Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- src/main/ai/LocalOllamaProvider.ts | 6 +++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57183f6..2d2aea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,33 @@ 본 파일은 Inkling 의 버전별 사용자 영향 변경 사항을 기록한다. 형식은 [Keep a Changelog](https://keepachangelog.com/) 를 느슨하게 따른다. +## [0.3.13] — 2026-05-12 + +대형 vision 모델 (gemma4:26b 등) 의 cold-start timeout 으로 인한 AI 처리 실패 fix. + +### 수정 + +- **Vision generate 의 timeout 확장 120s → 300s (P1).** `gemma4:26b` (25B MoE 가중치 + vision encoder 550M) 같은 대형 vision 모델은 첫 generate 시 모델 load + 이미지 encoding 으로 60-180s 소요. 기본 120s timeout 으로 첫 호출 시 abort → fail 빈번. vision path 에 한해 `Math.max(timeoutMs, 300_000)` 적용 (text-only path 영향 없음). + +확인: gemma4 family 는 [공식 release](https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/) — 26B variant 가 Text+Image 양 modality 지원 ([ollama library](https://ollama.com/library/gemma4:26b)). 본 코드의 `VisionDetect` 가 'gemma4' family 인식하므로 사용자가 settings → Vision 섹션에서 선택 가능. + +### 사용자 안내 + +이미지 AI 처리가 여전히 실패한다면: +1. 설정 → AI 제공자 → Vision 섹션에서 `gemma4:26b` (또는 vision-capable 모델) 가 선택돼있는지 확인 +2. `ollama list` 로 모델 실제 설치 여부 확인 (`ollama pull gemma4:26b` 필요) +3. NoteCard 의 failed 노트 텍스트 위에 마우스 오버 → tooltip 의 `ai_error` 확인 (구체 fail mode 진단) + +### 게이트 + +- 단위 752 PASS (timeout 상수만 변경 — 회귀 없음) +- typecheck 0 errors +- 신규 npm dependency 0 + +### 업그레이드 + +v0.3.12 인스톨러 위에 v0.3.13 인스톨러를 같은 위치에 실행하면 in-place 업그레이드. + ## [0.3.12] — 2026-05-12 이미지 AI 처리 실패 fix. vision model 의 응답이 strict JSON 이 아닌 경우 (markdown fence / prose 섞임) 가 흔해 schema parse 단계에서 throw → `ai_status='failed'` 도달. diff --git a/package-lock.json b/package-lock.json index f2666a0..b52e644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "inkling", - "version": "0.3.12", + "version": "0.3.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "inkling", - "version": "0.3.12", + "version": "0.3.13", "dependencies": { "better-sqlite3": "12.9.0", "electron-log": "5.2.0", diff --git a/package.json b/package.json index 3773ff8..ea76f9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "inkling", - "version": "0.3.12", + "version": "0.3.13", "private": true, "description": "Inkling — local-first 한 줄 보관 도구", "author": "altair823 ", diff --git a/src/main/ai/LocalOllamaProvider.ts b/src/main/ai/LocalOllamaProvider.ts index 818df67..ca510da 100644 --- a/src/main/ai/LocalOllamaProvider.ts +++ b/src/main/ai/LocalOllamaProvider.ts @@ -62,8 +62,12 @@ export class LocalOllamaProvider implements InferenceProvider { ? buildVisionPrompt(input.text, input.todayKst, input.dueDateCandidates.map((c) => c.iso ?? c.matchedToken ?? ''), input.vocab ?? []) : buildPrompt(input.text, input.todayKst, input.dueDateCandidates, input.vocab ?? []); + // v0.3.13 — vision model 은 cold-start (모델 load + 이미지 encoding) 가 매우 느려 + // 120s 기본 timeout 으로 첫 호출 fail 빈번. gemma4:26b (MoE 25B) 같은 대형 vision + // 모델은 첫 generate 가 60-180s 소요. 5분 (300s) 으로 확장. + const effectiveTimeout = useVision ? Math.max(this.timeoutMs, 300_000) : this.timeoutMs; this.abortController = new AbortController(); - const timer = setTimeout(() => this.abortController?.abort(), this.timeoutMs); + const timer = setTimeout(() => this.abortController?.abort(), effectiveTimeout); try { const body: Record = { model,