Skip to content

Commit fc2a50e

Browse files
GoGoComputerclaude
andcommitted
feat(setup): respect user's explicit model + OPENCLAW_FORCE_DEFAULT_MODEL env (case G)
After v0.2.22's auto-pick-smallest-tools-capable policy, qwen2.5:3b-instruct became default but couldn't follow direct user commands like "delete X" or "fill in Y" — it would politely loop back into conversation instead of calling the matching tool. Called this case G. Two-part fix: 1) Recommend gemma4:latest for 24GB+ machines (8.9GB, cold 7.2s / warm 0.27s, vision+audio+thinking+tools, instruction-following clearly stronger than any 3B). qwen2.5:3b-instruct stays as the recommendation for 8/16GB. 2) New env var OPENCLAW_FORCE_DEFAULT_MODEL pins the user's choice so the automatic optimizer doesn't silently overwrite it on subsequent setup runs. cmd/setup.sh now uses a three-tier policy: a) $OPENCLAW_FORCE_DEFAULT_MODEL set & registered → force it to [0] b) current [0] is tools-capable → leave alone (respect explicit choice) c) current [0] can't call tools → swap to smallest tools-capable Refactored repeated compat.supportsTools stamping into stamp_compat() helper. Added outcome codes OPT_OK_FORCED, OPT_OK_FORCED_ALREADY, OPT_WARN_FORCED_NO_TOOLS, OPT_SKIP_FORCED_NOT_REGISTERED, OPT_OK_RESPECT_USER_CHOICE for friendly setup output. The live user's .env now has OPENCLAW_FORCE_DEFAULT_MODEL=gemma4:latest locked. Verified setup --skip-confirm reports "이미 정확" and leaves the config untouched. Docs: - GUIDE-DISCORD-BOT case D: new RAM table with gemma4:latest as 24GB default, new section "default 모델을 영구 lock 하기" - GUIDE-DAILY-USE troubleshooting: case D row updated; new case G row for instruction-following regressions on 3B models - .env.example: documented OPENCLAW_FORCE_DEFAULT_MODEL with recommended values table - CHANGELOG v0.2.23 entry with full diagnosis + verification logs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9964eaf commit fc2a50e

7 files changed

Lines changed: 238 additions & 59 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 📖 목차 / Contents
44

5+
- [v0.2.23 — 2026-05-15](#v0223--2026-05-15)
56
- [v0.2.22 — 2026-05-15](#v0222--2026-05-15)
67
- [v0.2.21 — 2026-05-15](#v0221--2026-05-15)
78
- [v0.2.20 — 2026-05-14](#v0220--2026-05-14)
@@ -31,6 +32,97 @@
3132

3233
---
3334

35+
## v0.2.23 — 2026-05-15
36+
37+
### Discord case G + respect user's explicit model choice
38+
39+
After v0.2.22 auto-picked `qwen2.5:3b-instruct` (the lightest tool-capable model), the Discord bot responded fast but **stopped following direct user commands**:
40+
41+
```
42+
user: @openclaw bootstrap 끝났으니 BOOTSTRAP.md 지워줘
43+
bot: Understood, the BOOTSTRAP.md file has been read and the workspace is now ready to proceed.
44+
Let's start by creating or updating our IDENTITY.md. We can then move on with any other bootstrap steps.
45+
Would you like me to create a new IDENTITY.md file or update an existing one?
46+
… (file is NOT deleted; bot loops back into onboarding chat)
47+
```
48+
49+
This is **case G** — a separate failure mode from cases A–F. The bot is fast, tool-call format is correct, the watchdog doesn't fire — the model just **can't decide to call a tool in response to an unambiguous user instruction**. 3B-class models are weak at the multi-step reasoning chain "user said delete → I have a delete tool → I should call it" and instead fall back to conversational politeness.
50+
51+
#### Two-part fix
52+
53+
**1) Recommend `gemma4:latest` over `qwen2.5:3b-instruct` on 24GB+ RAM machines**
54+
55+
`gemma4:latest` benchmarks on this MacBook Pro:
56+
57+
```
58+
$ time curl -s http://127.0.0.1:11434/api/chat \
59+
-d '{"model":"gemma4:latest","messages":[{"role":"user","content":"hi"}],"stream":false}'
60+
{"model":"gemma4:latest","message":{"role":"assistant","content":"Hello! How can I help you today? 😊"}…
61+
real 0m7.18s ← cold load
62+
63+
$ time curl -s … (second call)
64+
real 0m0.27s ← warm
65+
```
66+
67+
7.2s cold / 0.27s warm — well under the 120s idle watchdog. Plus vision + audio + thinking + tools capabilities native. Instruction-following is in a different league from 3B models on direct commands.
68+
69+
`qwen2.5:3b-instruct` is still recommended on 8GB–16GB machines where the 8.9GB cost of `gemma4:latest` is too much, with the explicit caveat that direct commands ("delete X", "fill in Y") may need rephrasing as a request.
70+
71+
**2) New env var `OPENCLAW_FORCE_DEFAULT_MODEL` — pin the user's choice**
72+
73+
`./openclaw setup` v0.2.22 auto-resorted by size. If a user explicitly moved `gemma4:latest` to `models[0]`, the next `setup` run would silently overwrite it back to `qwen2.5:3b-instruct`. Fixed by giving `optimize_default_ollama_model()` a three-tier policy:
74+
75+
| Priority | Condition | Action |
76+
|---|---|---|
77+
| 1 | `$OPENCLAW_FORCE_DEFAULT_MODEL` is set and that model is registered | Force it to `models[0]`. Skip auto-sort entirely. |
78+
| 2 | Current `models[0]` is tools-capable | Leave it alone. Respect user's explicit choice. |
79+
| 3 | Current `models[0]` is NOT tools-capable (e.g., embedding-only, tinyllama) | Swap to the smallest tools-capable model. |
80+
81+
For the live user's setup, added to `openclaw-mgr/.env`:
82+
83+
```bash
84+
# === Locked default model (added 2026-05-15) ===
85+
OPENCLAW_FORCE_DEFAULT_MODEL="gemma4:latest"
86+
```
87+
88+
#### Files changed
89+
90+
- `openclaw-mgr/cmd/setup.sh`:
91+
- `optimize_default_ollama_model()` now takes a forced-model arg from `$OPENCLAW_FORCE_DEFAULT_MODEL`
92+
- Replaced "always sort by size" with the three-tier policy above
93+
- Refactored repeated `compat.supportsTools` stamping into `stamp_compat()` helper
94+
- Added new outcome codes: `OPT_OK_FORCED`, `OPT_OK_FORCED_ALREADY`, `OPT_WARN_FORCED_NO_TOOLS`, `OPT_SKIP_FORCED_NOT_REGISTERED`, `OPT_OK_RESPECT_USER_CHOICE`
95+
- `openclaw-mgr/.env.example`: documented `OPENCLAW_FORCE_DEFAULT_MODEL` with a recommended-values table
96+
- `docs/GUIDE-DISCORD-BOT.md`: case D RAM table updated (`gemma4:latest` is new 24GB+ default), new "default 모델을 영구 lock 하기" subsection
97+
- `docs/GUIDE-DAILY-USE.md`: case D row updated; new row for case G (instruction-following regression on 3B models)
98+
- `openclaw-mgr/openclaw` / `openclaw-mgr/openclaw.ps1`: VERSION → 0.2.23
99+
100+
#### Side note — BOOTSTRAP.md deletion is now a manual step
101+
102+
The model wouldn't delete `~/.openclaw/workspace/BOOTSTRAP.md` even when asked, so it was deleted directly on the host. Because the workspace dir is bind-mounted from `~/.openclaw/workspace/` into `/home/node/.openclaw/workspace/`, `rm` on the host is immediately visible to OpenClaw without restart. This pattern (host-side cleanup of onboarding artifacts) deserves its own subsection in a future docs update.
103+
104+
#### Verified
105+
106+
```
107+
$ ./openclaw setup status
108+
…
109+
✓ default 모델: gemma4:latest ($OPENCLAW_FORCE_DEFAULT_MODEL 로 lock — 이미 정확)
110+
111+
$ docker logs openclaw-openclaw-gateway-1 | grep 'agent model'
112+
[gateway] agent model: ollama/gemma4:latest
113+
114+
$ docker logs openclaw-openclaw-gateway-1 | grep 'logged in to discord'
115+
[discord] logged in to discord as 1477667959601369139 (openclaw)
116+
```
117+
118+
#### Carried TODO
119+
120+
- Upstream PR for `OPENCLAW_HOST_PATH_PREFIX` (v0.2.20 — would let sandbox.mode go back to `non-main`)
121+
- `./openclaw chat --warm-default` flag (v0.2.22)
122+
- (new) `./openclaw cleanup-bootstrap` command that safely deletes `BOOTSTRAP.md` from the workspace and prints a confirmation — automate the host-side cleanup pattern this version introduced
123+
124+
---
125+
34126
## v0.2.22 — 2026-05-15
35127

36128
### Discord case D regression: `llama3.1:8b-instruct-q4_K_M` is still too heavy → auto-pick the lightest tool-capable model

‎docs/GUIDE-DAILY-USE.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,9 @@ rm ~/.openclaw-mgr/state
400400
| Discord 봇 응답: **`Something went wrong while processing your request. Please try again, or use /new to start a fresh session.`** (게이트웨이 로그에서 `Failed to inspect sandbox image: dial unix /var/run/docker.sock: no such file or directory`) | `./openclaw stop && start` 또는 `network` 토글 후 **gateway 컨테이너에 `/var/run/docker.sock` 마운트가 빠진 상태**. 봇이 도구 실행할 때 sandbox 컨테이너 못 띄움. v0.2.17+ 에서 `start.sh` / `step_lockdown` 이 자동으로 `docker-compose.sandbox.yml` 오버레이를 포함하도록 패치됨 — `git pull && ./openclaw stop && ./openclaw start` 한 번이면 해결. 확인: `docker inspect openclaw-openclaw-gateway-1 --format '{{range .Mounts}}{{.Source}} {{end}}' \| grep docker.sock` |
401401
| Discord 봇 응답: 위와 같은 메시지인데 로그는 **`Failed to inspect sandbox image: permission denied while trying to connect to the docker API`** | docker.sock 마운트는 있는데 **컨테이너 안 node 사용자가 그 sock 에 접근 권한이 없음**. macOS Docker Desktop 에선 마운트된 sock 가 `root:root` 로 보이는데 (호스트 GID `daemon`(1) 과 다름), `group_add` 가 `1` 만 추가하던 게 회귀. v0.2.19+ `step_sandbox` 가 `0`(root) 도 함께 추가. 즉시 fix: sandbox compose 의 `group_add` 에 `"0"` 추가 후 재시작. 검증: `docker exec openclaw-openclaw-gateway-1 docker info --format '{{.ServerVersion}}'` 가 버전을 반환. |
402402
| Discord 봇 응답: 같은 generic 에러, 로그는 **`mounts denied: The path /home/node/.openclaw/sandboxes/... is not shared from the host and is not known to Docker`** | OpenClaw 본체가 sandbox sub-container 띄울 때 mount source 로 **컨테이너 내부 경로**를 그대로 daemon 에 넘김 → daemon 이 호스트의 그 경로를 찾으려다 실패. OpenClaw upstream 한계 (호스트 경로 변환 env 없음). **즉시 fix (v0.2.20)**: `agents.defaults.sandbox.mode = "off"` 로 sandbox sub-container 자체를 비활성화 — 자세한 트레이드오프와 patch 명령은 [GUIDE-DISCORD-BOT: 케이스 C](GUIDE-DISCORD-BOT.md#봇이-응답으로-something-went-wrong-while-processing-your-request-please-try-again-or-use-new-to-start-a-fresh-session). |
403-
| Discord 봇 응답: 같은 generic 에러, 로그는 **`agent/embedded Profile ollama:default timed out`** / **`llm-idle-timeout: ollama/<model> produced no reply before the idle watchdog`** | **모델이 너무 무거워 첫 응답 전에 OpenClaw idle watchdog (2분) 트리거**. `gemma4:26b` (17GB) 는 55+초, `llama3.1:8b-instruct-q4_K_M` (4.6GB) 도 system prompt + workspace 7개 .md 컨텍스트면 종종 timeout. **v0.2.22 권장: `qwen2.5:3b-instruct` (1.8GB)** — 워밍업 후 1.6초. v0.2.22+ 에선 `./openclaw setup --skip-confirm` 한 번이면 자동으로 **가장 작은 tools-capable 모델**이 default 로 들어감. 자세히 → [GUIDE-DISCORD-BOT: 케이스 D](GUIDE-DISCORD-BOT.md#케이스-d--모델이-너무-무거워-첫-응답-전에-watchdog-트리거-v021--v022-권장-모델-변경) |
403+
| Discord 봇 응답: 같은 generic 에러, 로그는 **`agent/embedded Profile ollama:default timed out`** / **`llm-idle-timeout: ollama/<model> produced no reply before the idle watchdog`** | **모델이 너무 무거워 첫 응답 전에 OpenClaw idle watchdog (2분) 트리거**. `gemma4:26b` (17GB) 는 55+초, `llama3.1:8b-instruct-q4_K_M` (4.6GB) 도 system prompt + workspace 7개 .md 컨텍스트면 종종 timeout. **v0.2.23 권장 (24GB RAM): `gemma4:latest` (8.9GB)** — cold 7.2초 / warm 0.27초, vision+audio+thinking+tools. 16GB 이하면 `qwen2.5:7b-instruct` (4.7GB), 8GB 면 `qwen2.5:3b-instruct` (1.8GB). 영구 lock: `.env` 에 `OPENCLAW_FORCE_DEFAULT_MODEL="gemma4:latest"`. 자세히 → [GUIDE-DISCORD-BOT: 케이스 D](GUIDE-DISCORD-BOT.md#케이스-d--모델이-너무-무거워-첫-응답-전에-watchdog-트리거-v021--v022-권장-모델-변경) |
404404
| Discord 봇 응답이 평문 JSON 으로 나옴 (`{"name": "read", "parameters": {...}}` 같은 거) | **케이스 D 의 부산물** — 별개 버그 아님. 모델이 도구 호출 객체를 만들다가 watchdog 가 끊어서 incomplete JSON 이 그대로 사용자한테 전달. Fix 는 케이스 D 와 동일 (가벼운 모델로 default 변경). 한때 case F 로 의심됐지만 모델 빠르면 자동 해결. |
405+
| Discord 봇이 빠르게 응답하긴 하는데 **직접 명령 ("지워줘", "채워줘", "기억해줘") 을 안 따라감** — 대신 "Would you like me to…" 식으로 대화로 빠짐 | **모델 instruction-following 한계** (case G — v0.2.23 신규). 흔히 3B 이하 모델 (`qwen2.5:3b-instruct`, `llama3.2:3b` 등) 이 다단계 reasoning + 도구 호출 결정 약함. Fix: 더 큰 모델로 — 24GB RAM 이면 `gemma4:latest` 추천 (vision+audio+thinking+tools, 8.9GB). 영구화는 `.env` 에 `OPENCLAW_FORCE_DEFAULT_MODEL="gemma4:latest"` + `./openclaw setup --skip-confirm` 한 번. |
405406
| Discord 봇 응답: 같은 generic 에러, 로그는 **`channel exited: Cannot find module '.../plugin-runtime-deps/openclaw-unknown-<hash>/...text-runtime.js'`** 또는 **`ENOENT: ... account-core.js`** | OpenClaw 가 컨테이너 안에서 자기 버전 못 읽고 **`openclaw-unknown-<hash>` 디렉토리를 새로 만들면서 plugin-sdk 를 부분적으로만 채움** (text-runtime.js / account-core.js 누락). 보통 host-paths 실험이나 env 변경 후 발생. **Fix**: `trash ~/.openclaw/plugin-runtime-deps` (또는 `rm -rf`) 후 `./openclaw stop && start` — OpenClaw 가 다음 부팅 시 26개 dep 새로 정상 설치. 로그에 `discord installed bundled runtime deps in <N>ms: @buape/carbon, @discordjs/voice, ...` 보이면 OK. |
406407
| TUI 에서 답이 안 옴 / 느림 (메시지는 가긴 감) | 모델이 너무 크다 — `./openclaw chat` 의 picker 로 가벼운 모델 선택 |
407408
| install 이 [skip] 만 띄움 | [state 파일 vs 실제 산출물 어긋남 FAQ](../README.md) |

‎docs/GUIDE-DISCORD-BOT.md‎

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -963,20 +963,37 @@ cd ~/DEV/openclawAgent/openclaw-workspace/openclaw-mgr
963963
./openclaw setup --skip-confirm # 자동으로 가장 작은 tools-capable 모델을 [0] 로
964964
```
965965

966-
RAM 가이드 (v0.2.22 갱신):
967-
| RAM | 권장 default | 무거운 모델은 |
968-
|---|---|---|
969-
| 8GB | `qwen2.5:3b-instruct` (1.8GB) | — (단일 모델 권장) |
970-
| 16GB | `qwen2.5:3b-instruct` (1.8GB) | `llama3.1:8b-instruct-q4_K_M` 명시 호출만 |
971-
| 24GB | `qwen2.5:3b-instruct` (1.8GB) default ; 무거운 작업은 `qwen2.5-coder:7b` 명시 | `gemma4:26b`/`gemma4:latest` 워밍업 필수, DM 으로만 |
972-
| 32GB+ | `qwen2.5-coder:14b` (8.4GB) 또는 `llama3.1:8b` | `gemma4:26b` 도 OK |
973-
974-
> **왜 `qwen2.5:3b` 가 default 권장?**
975-
> - 1.8GB → 모든 macOS RAM 등급에서 RAM 압박 없음
976-
> - `tools` capability 네이티브 (Ollama `/api/show` 로 확인됨)
977-
> - 첫 로드 ~3초, 워밍업 후 1.6초 — OpenClaw idle watchdog (120초) 와 큰 격차
978-
> - 한국어·영어 둘 다 잘함, 일상 Discord 명령엔 충분
979-
> - 무거운 작업만 `@openclaw use gemma4:26b 사주풀이…` 식으로 명시 호출하면 됨
966+
RAM 가이드 (v0.2.23 갱신 — `gemma4:latest` 추천 상향, instruction-following 가중치):
967+
| RAM | 권장 default | 가벼운 대안 (응답 속도 우선) | 무거운 작업 |
968+
|---|---|---|---|
969+
| 8GB | `qwen2.5:3b-instruct` (1.8GB) | — | — (단일 모델 권장) |
970+
| 16GB | `qwen2.5:7b-instruct` (4.7GB) | `qwen2.5:3b-instruct` (1.8GB) | — |
971+
| **24GB** | **`gemma4:latest` (8.9GB)** — 추천 | `qwen2.5:3b-instruct` (1.8GB) | `gemma4:26b`(17GB) 워밍업 후 명시 호출 |
972+
| 32GB+ | `gemma4:latest` 또는 `qwen2.5-coder:14b` (8.4GB) | `gemma4:latest` | `gemma4:26b`, `llama3.3:70b` 등 |
973+
974+
> **왜 24GB 추천이 v0.2.22 의 `qwen2.5:3b` → v0.2.23 의 `gemma4:latest` 로 올라갔나?**
975+
> - `qwen2.5:3b` 는 빠르긴 한데 **instruction-following 한계 명확** — 사용자가 "BOOTSTRAP.md 지워줘" 같은 직접 명령을 내려도 도구 호출 결정 못 하고 대화로 빠짐.
976+
> - `gemma4:latest` (8.9GB) 는 cold 7.2초 / warm 0.27초 → watchdog 한참 아래. + vision+audio+thinking+tools 다 지원해서 능력 격차가 큼.
977+
> - 24GB 노트북에선 `gemma4:latest` 가 RAM 압박 없고 instruction-following 도 좋아 일상 명령에 잘 반응.
978+
> - `qwen2.5:3b` 는 "응답 속도 절대 우선" 또는 16GB 이하 노트북에서.
979+
980+
#### default 모델을 영구 lock 하기 (v0.2.23+)
981+
982+
`./openclaw setup` 다시 실행해도 자동 최적화가 사용자 선택을 갈아치우지 못하게 하려면 `.env` 에:
983+
984+
```bash
985+
# openclaw-mgr/.env 또는 ~/.openclaw-mgr/.env
986+
OPENCLAW_FORCE_DEFAULT_MODEL="gemma4:latest"
987+
```
988+
989+
이게 set 돼 있으면:
990+
- `./openclaw setup` 의 `optimize_default_ollama_model()` 함수가 이 모델을 무조건 [0] 으로 보장
991+
- size 기준 자동 정렬 스킵
992+
- 다음 setup 실행 시 `default 모델: gemma4:latest ($OPENCLAW_FORCE_DEFAULT_MODEL 로 lock — 이미 정확)` 로그 출력
993+
994+
비워 두면 (`OPENCLAW_FORCE_DEFAULT_MODEL=""`):
995+
- 현재 [0] 이 tools-capable 이면 그대로 둠 (사용자 명시 선택 존중)
996+
- [0] 이 tools 못 쓰는 모델이면 가장 작은 tools-capable 로 swap (회귀 방지)
980997

981998
**케이스 E — `plugin-runtime-deps/openclaw-unknown-<hash>/` 가 부분 설치된 채로 남음 (v0.2.21)**: OpenClaw 가 컨테이너 안에서 자기 버전을 못 읽거나 (`process.env.OPENCLAW_VERSION` 비어 있음), upstream 의 plugin-sdk autoinstall 가 중간에 끊겼거나, host-paths 실험 후 디렉토리가 어긋난 상태. 결과적으로 `~/.openclaw/plugin-runtime-deps/openclaw-unknown-<hash>/` 디렉토리가 만들어졌는데 그 안에 `text-runtime.js` · `account-core.js` 같은 핵심 모듈이 빠져 있음. Discord 채널은 부팅까진 되는데, 첫 메시지가 와서 도구를 실행하려는 순간 모듈 못 찾고 채널이 죽음.
982999

‎openclaw-mgr/.env.example‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ OLLAMA_MODE="host"
4949
# ⚠ 13B 이상은 24GB 에서 메모리 부족 위험 (macOS 공유 메모리 구조상 8-9B 권장)
5050
OLLAMA_MODELS="qwen2.5-coder:7b"
5151

52+
# ── default 모델 강제 lock (v0.2.23+) ───────────────────────────────────────
53+
# `./openclaw setup` 의 자동 최적화 함수가 size 만 보고 더 작은 모델로 바꾸지 못하게,
54+
# 사용자가 명시적으로 고른 모델을 영구 lock 합니다. 비워 두면 자동 정책:
55+
# 1) 현재 models[0] 가 tools-capable 이면 그대로 둠
56+
# 2) 아니면 가장 작은 tools-capable 모델로 swap
57+
# 추천 값:
58+
# gemma4:latest 8.9GB · vision+audio+tools+thinking, instruction-following 가장 좋음
59+
# qwen2.5:7b-instruct 4.7GB · tools, 한국어/영어 모두 강함
60+
# qwen2.5:3b-instruct 1.8GB · tools, 가장 가볍지만 instruction-following 약함
61+
# llama3.1:8b-instruct-q4_K_M 4.6GB · tools, q4 양자화로 응답 느림
62+
OPENCLAW_FORCE_DEFAULT_MODEL=""
63+
5264
# ── 컨테이너 리소스 한도 (보안/안정성) ────────────────────────────────────────
5365
# M5 Pro 24GB 기준: 에이전트 컨테이너에 8GB / 8 CPU 코어 제한
5466
OPENCLAW_MEM_LIMIT="8g"

0 commit comments

Comments
 (0)