From 893287a5a34cd5227b104eda89c3171ccead4562 Mon Sep 17 00:00:00 2001 From: altair823 Date: Sat, 2 May 2026 16:34:24 +0000 Subject: [PATCH] =?UTF-8?q?fix(config=20+=20tilde):=20LLM=20default=20?= =?UTF-8?q?=E2=86=92=20gemma4:e4b=20+=20workspace.root=20~=20expansion=20?= =?UTF-8?q?=EC=9D=BC=EA=B4=80=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 도그푸딩 시 사용자 결정 (2026-05-02): 텍스트 LLM 기본을 gemma4 계열로 통일. OCR/caption 어댑터 (P6-2/P6-3) 가 이미 gemma4:e4b 사용 중 — 사용자가 한 family 만 pull 하면 ingest + ask 모두 작동. 같이 발견된 ~ expansion 불일치: - kebab-source-fs::connector 는 expand_tilde 사용 (walk 정상) - kebab-app::ingest_one_image_asset / ingest_one_pdf_asset 은 직접 PathBuf::from → ~ 미확장 → ExtractContext 에 ~/KnowledgeBase 그대로 전달 - kebab-tui::search::handle_key_search 의 editor jump 도 동일 → 의미 없는 경로 spawn Fix: - Config::defaults().models.llm.model = \"gemma4:e4b\". OCR/caption family 통일 코멘트 추가. - kebab-app 의 image / pdf 분기 두 곳 모두 expand_tilde 호출. - kebab-tui::search jump 가 kebab_config::expand_path(.., \"\") 사용 (expand_path 는 ~ / ${XDG_DATA_HOME} / {data_dir} 모두 처리하는 정식 helper). Caveat: kebab-app::expand_tilde 와 kebab-config::expand_path 가 별도 정의. 통합은 P+ task. Docs (sync rule): - README 사전 요구 절: gemma4:e4b 기본 + 더 큰 variant override 안내. - docs/ARCHITECTURE 핵심 결정 표: LLM default qwen2.5:7b-instruct → gemma4:e4b. - docs/SMOKE: ollama pull 예시 + KEBAB_MODELS_LLM_MODEL env 예시 qwen2.5:32b → gemma4:26b. - HOTFIXES: 새 entry (\"Config defaults: LLM = gemma4:e4b + workspace.root tilde expansion\"). - Memory: project_llm_default.md 신설, MEMORY.md 인덱스 추가. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 2 +- crates/kebab-app/src/lib.rs | 8 ++++++-- crates/kebab-config/src/lib.rs | 8 ++++++-- crates/kebab-tui/src/search.rs | 6 +++++- docs/ARCHITECTURE.md | 2 +- docs/SMOKE.md | 4 ++-- tasks/HOTFIXES.md | 24 ++++++++++++++++++++++++ 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0e21075..3712a12 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## 사전 요구 - **Rust toolchain** ≥ 1.85 (workspace 가 edition 2024 + resolver 3 사용). [rustup](https://rustup.rs) 권장. -- **Ollama** — `kebab ask` 와 이미지 OCR/caption 가 사용. `https://ollama.com/download` 에서 설치 후 `ollama serve` 실행. 모델은 `ollama pull qwen2.5:7b-instruct` (텍스트) / `ollama pull gemma4:e4b` (vision) 등. config 의 `[models.llm].endpoint` 에 host:port 명시. +- **Ollama** — `kebab ask` 와 이미지 OCR/caption 가 사용. `https://ollama.com/download` 에서 설치 후 `ollama serve` 실행. 기본 LLM 은 gemma4 계열 (`ollama pull gemma4:e4b`) — OCR / caption 도 같은 family 라 모델 하나만 pull 하면 됨. 더 큰 variant 원하면 `gemma4:26b` 등으로 config override. config 의 `[models.llm].endpoint` 에 host:port 명시. - **빌드 디스크** — 첫 빌드 시 `target/` 가 6–10 GB (Lance + DataFusion + fastembed). 여유 확인. - **fastembed 모델** — 첫 `kebab ingest` 시 `multilingual-e5-small` (~470 MB) 자동 다운로드. diff --git a/crates/kebab-app/src/lib.rs b/crates/kebab-app/src/lib.rs index 3f0f413..78c8a81 100644 --- a/crates/kebab-app/src/lib.rs +++ b/crates/kebab-app/src/lib.rs @@ -744,7 +744,10 @@ fn ingest_one_image_asset( // nothing the image extractor reads today; we pass a default // instance per the trait shape. let extract_config = kebab_core::ExtractConfig::default(); - let workspace_root = std::path::PathBuf::from(&app.config.workspace.root); + // `~` / `${XDG_…}` expansion via the same helper the markdown + // path uses, so a `~/KnowledgeBase` workspace.root resolves + // identically across all media (HOTFIXES 2026-05-02 P9-4 follow-up). + let workspace_root = expand_tilde(&app.config.workspace.root); let ctx = ExtractContext { asset, workspace_root: &workspace_root, @@ -1047,7 +1050,8 @@ fn ingest_one_pdf_asset( .with_context(|| format!("read PDF asset bytes from {}", path.display()))?; let extract_config = kebab_core::ExtractConfig::default(); - let workspace_root = std::path::PathBuf::from(&app.config.workspace.root); + // `~` / `${XDG_…}` expansion (HOTFIXES 2026-05-02 P9-4 follow-up). + let workspace_root = expand_tilde(&app.config.workspace.root); let ctx = ExtractContext { asset, workspace_root: &workspace_root, diff --git a/crates/kebab-config/src/lib.rs b/crates/kebab-config/src/lib.rs index 898fd67..e70b953 100644 --- a/crates/kebab-config/src/lib.rs +++ b/crates/kebab-config/src/lib.rs @@ -239,7 +239,11 @@ impl Config { }, llm: LlmCfg { provider: "ollama".to_string(), - model: "qwen2.5:14b-instruct".to_string(), + // gemma4 계열 통일 — OCR (P6-2) + caption (P6-3) + // 어댑터가 같은 family 사용. 사용자가 더 큰 + // variant (gemma4:26b 등) 원하면 자기 config.toml + // 에서 override. + model: "gemma4:e4b".to_string(), context_tokens: 32768, endpoint: "http://127.0.0.1:11434".to_string(), temperature: 0.0, @@ -733,7 +737,7 @@ batch_size = 64 [models.llm] provider = "ollama" -model = "qwen2.5:14b-instruct" +model = "gemma4:e4b" context_tokens = 32768 endpoint = "http://127.0.0.1:11434" temperature = 0.0 diff --git a/crates/kebab-tui/src/search.rs b/crates/kebab-tui/src/search.rs index dde8510..dfd7f93 100644 --- a/crates/kebab-tui/src/search.rs +++ b/crates/kebab-tui/src/search.rs @@ -224,7 +224,11 @@ pub fn handle_key_search(state: &mut App, key: KeyEvent) -> KeyOutcome { }; if has_hits { let editor = std::env::var("EDITOR").unwrap_or_else(|_| "vi".into()); - let workspace_root = std::path::PathBuf::from(&state.config.workspace.root); + // `~/...` / `${XDG_…}` expansion via `kebab-config::expand_path` + // — same helper used by the markdown / image / PDF ingest + // paths (HOTFIXES 2026-05-02 P9-4 follow-up). + let workspace_root = + kebab_config::expand_path(&state.config.workspace.root, ""); if let Err(e) = jump_to_citation(&citation.unwrap(), &editor, &workspace_root) { state.error_overlay = Some(ErrorOverlay::from_anyhow(&e)); } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index ad5dd35..4829e11 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -17,7 +17,7 @@ Cargo workspace, 함수 호출 기반 모듈러 모놀리스. UI binary (`kebab- | vector | LanceDB (embedded, model 별 분리 table) | | Markdown parser | `pulldown-cmark` | | embedding | `fastembed-rs` (`multilingual-e5-small`, 384d) | -| LLM | Ollama HTTP (default `qwen2.5:7b-instruct` ─ 사용자 환경에 맞춰 `gemma4:26b` 등으로 교체 가능) | +| LLM | Ollama HTTP (default `gemma4:e4b` ─ OCR / caption 와 family 통일. 사용자가 더 큰 variant `gemma4:26b` 등으로 override 가능) | | 음성 ASR | `whisper.cpp` (via `whisper-rs`) — P8 보류, 시스템 dep brainstorm 후 | | OCR | Ollama vision LM (default `gemma4:e4b`) — `OcrEngine` trait 으로 Tesseract / Apple Vision 등 future swap (HOTFIXES P6-2) | | Image caption | Ollama vision LM, runtime gate `image.caption.enabled` (default OFF) | diff --git a/docs/SMOKE.md b/docs/SMOKE.md index c813f3b..53c7c71 100644 --- a/docs/SMOKE.md +++ b/docs/SMOKE.md @@ -20,7 +20,7 @@ cargo build --release -p kebab-cli # debug 도 무방. 디버그가 더 빠르 ```bash # Mac 등 별도 호스트에서 OLLAMA_HOST=0.0.0.0:11434 ollama serve -ollama pull gemma4:26b # 또는 qwen2.5:32b 등 — 자세한 비교는 README +ollama pull gemma4:e4b # 기본 default. 더 큰 variant 원하면 gemma4:26b ``` 본 머신에서 reachability 검증: @@ -110,7 +110,7 @@ explain_default = false max_context_tokens = 6000 ``` -`KEBAB_*` 환경변수로 override 가능 (`KEBAB_MODELS_LLM_MODEL=qwen2.5:32b kebab …` 등). 자세한 키 목록은 `crates/kebab-config/src/lib.rs` 의 `apply_env` 매치 암. +`KEBAB_*` 환경변수로 override 가능 (`KEBAB_MODELS_LLM_MODEL=gemma4:26b kebab …` 등). 자세한 키 목록은 `crates/kebab-config/src/lib.rs` 의 `apply_env` 매치 암. ## 명령 시퀀스 diff --git a/tasks/HOTFIXES.md b/tasks/HOTFIXES.md index d30508f..f50b3d1 100644 --- a/tasks/HOTFIXES.md +++ b/tasks/HOTFIXES.md @@ -14,6 +14,30 @@ historical contract that was implemented; this file accumulates the deltas so phase 5+ readers can find the live behavior without diffing git history. +## 2026-05-02 — Config defaults: LLM = gemma4:e4b + workspace.root tilde expansion + +**Discovered**: 사용자가 도그푸딩 환경에 `kebab init` 으로 생성된 `~/.config/kebab/config.toml` 검토하던 중. + +**Symptom 1 (default 변경)**: `Config::defaults().models.llm.model` 가 `qwen2.5:14b-instruct`. OCR (P6-2) / caption (P6-3) 어댑터는 이미 `gemma4:e4b` 기본 사용 — 사용자가 OCR / caption / ask 모두 쓰려면 두 family 모델 (`qwen2.5` + `gemma4`) 을 모두 pull 해야 했음. 사용자 결정 (2026-05-02): **텍스트 LLM 기본도 gemma4 계열로 통일**. + +**Symptom 2 (load-bearing)**: `workspace.root = "~/KnowledgeBase"` 같은 `~` 시작 경로가 코드 path 별로 다르게 처리: +- ✅ `kebab-source-fs::connector` 가 `expand_tilde` 사용 → walk 정상. +- ❌ `kebab-app::ingest_one_image_asset` 이 `PathBuf::from(&workspace.root)` 직접 → `~` 미확장 → ExtractContext 에 `~/KnowledgeBase` 그대로. +- ❌ `kebab-app::ingest_one_pdf_asset` 동일. +- ❌ `kebab-tui::search::handle_key_search` editor jump 도 동일 → `vim +12 ~/KnowledgeBase/foo.md` 의미 없는 경로 spawn. + +**Fix**: +- `Config::defaults().models.llm.model` → `"gemma4:e4b"`. 코멘트가 OCR / caption family 통일 명시. +- kebab-app 의 image / pdf 분기 두 곳 모두 `expand_tilde(&app.config.workspace.root)` 호출 (markdown path 가 이미 쓰는 self-contained helper). +- kebab-tui::search jump 호출 site 가 `kebab_config::expand_path(&state.config.workspace.root, "")` 사용 — `expand_path` 가 `~` / `${XDG_DATA_HOME}` / `{data_dir}` 모두 처리하는 정식 helper. +- README / docs/SMOKE.md / docs/ARCHITECTURE.md 의 LLM 모델 예시 모두 `qwen2.5` → `gemma4` 갱신 (sync rule). + +**Caveat (남은 inconsistency)**: kebab-app 자체 helper `expand_tilde` 와 kebab-config `expand_path` 가 별도 정의. 후자가 superset (env var + `{data_dir}` templating 추가). 통합은 P+ task — 본 PR scope 밖. + +**Amends**: +- `Config::defaults` 의 `qwen2.5:14b-instruct` → `gemma4:e4b`. +- README 사전 요구 절 / docs/ARCHITECTURE 핵심 결정 표 / docs/SMOKE 의 ollama pull 예시 갱신. + ## 2026-05-02 — P9-4 TUI Inspect: render_inspect generic + Search `i` entry + collapse simplification **Discovered**: P9-4 implementation start. -- 2.49.1