V10.422 persist 111 Ollama proxy launch agent
This commit is contained in:
@@ -325,7 +325,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.421"
|
||||
SYSTEM_VERSION = "V10.422"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **最後更新**: 2026-05-24 (台北時間)
|
||||
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地;LLM 路由紅線升級為 Ollama-first 三主機級聯,Gemini 備援預設關閉
|
||||
> **適用版本**: V10.420
|
||||
> **適用版本**: V10.422
|
||||
|
||||
---
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
- Gemini 不可被任何狀態面板或 router 推薦為主提供者:`AIProviderService._get_recommended_provider()` 不得回傳 `gemini`,只能顯示為 fallback 狀態;`llm_model_router` 的 `ea_engine` 若收到 `gemini-*` default 必須改回 `hermes3:latest`,需要深推理時才升本地 `deepseek-r1:14b`。
|
||||
- ElephantAlpha prompt / agent registry 不得再把 OpenClaw 描述為 Gemini 主模型;OpenClaw 是 `qwen2.5-coder:7b` / `qwen3:14b` Ollama-first 策略師,Gemini 僅能在 guard 顯式解鎖後作 emergency fallback。
|
||||
- 111 `192.168.0.111` 只是最後一道 Mac fallback,不承接 7B+、vision、long-context 模型長駐;`OllamaService.generate()` 落到 111 時會將 `qwen3`、`deepseek-r1`、`hermes3`、`qwen2.5*`、`gemma3`、`llava`、`minicpm-v` 與 7B+ 模型依 `OLLAMA_111_MODEL_DOWNGRADE_PATTERNS` 降級到 `OLLAMA_111_MODEL_FALLBACK=llama3.2:latest`,並以 `OLLAMA_111_KEEP_ALIVE=5m`、`OLLAMA_111_MAX_TIMEOUT=20`、`OLLAMA_111_NUM_CTX=4096`、`OLLAMA_111_NUM_PREDICT=512` 封頂。OpenClaw 報告型路徑的業務 keep-alive 預設 `5m`;Code Review 以 `CODE_REVIEW_ALLOW_111_FALLBACK=false`、Hermes 以 `HERMES_ALLOW_111_FALLBACK=false` 預設跳過 111,避免 16GB RAM 主機與 GCP-B 被長駐 runner、長輸出與 24h keep-alive 壓到高 load。
|
||||
- 111 的 LAN 入口必須經 `scripts/ops/ollama111_allow_proxy.py` allowlist proxy:真實 Ollama 綁 `127.0.0.1:11434`,proxy 綁 `192.168.0.111:11434`,預設只允許 111 本機與 188 生產宿主;110 / 121 / 其他 LAN client 不能直接打 111,避免跨專案 CI 或 VM 繞過 momo-pro router 載入 7B+ runner。
|
||||
- 111 的 LAN 入口必須經 `scripts/ops/ollama111_allow_proxy.py` allowlist proxy:真實 Ollama 綁 `127.0.0.1:11434`,proxy 綁 `192.168.0.111:11434`,預設只允許 111 本機與 188 生產宿主;110 / 121 / 其他 LAN client 不能直接打 111,避免跨專案 CI 或 VM 繞過 momo-pro router 載入 7B+ runner。111 上以 `scripts/ops/install_ollama111_allow_proxy.sh` 安裝 user LaunchAgent,讓 proxy 與 `OLLAMA_HOST=127.0.0.1:11434` 在登入/重啟後自動恢復。
|
||||
- ElephantAlpha 的 `price_drop_alert` / `market_opportunity` Telegram HITL 告警必須把同款證據獨立呈現,至少包含 `match_type`、`price_basis`、`alert_tier` 與 `match_score`;沒有高信心同款與總價可比證據時,不得把 PChome/MOMO 價差寫成可直接跟價建議。
|
||||
|
||||
## 一、四 AI Agent 路由架構
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
## 📅 詳細更新日誌 (考古存檔)
|
||||
|
||||
### 2026-05-24:PChome 近門檻身份回收第二輪
|
||||
- **V10.422 111 proxy LaunchAgent 持久化**: 新增 `scripts/ops/install_ollama111_allow_proxy.sh`,在 111 以 user LaunchAgent 安裝 `com.momo.ollama111-allow-proxy`,啟動時設定 `OLLAMA_HOST=127.0.0.1:11434`、重啟 Ollama、載入 allowlist proxy,避免重開機或重新登入後 111 又回到 LAN 全開狀態。
|
||||
- **V10.421 Kanebo Milano / hoi 蠟燭品類防錯配**: marketplace matcher 追加 `kanebo_milano_type_conflict` 與 `hoi_candle_line_conflict`,將 Kanebo Milano Collection 蜜粉餅 vs 絕色香水、hoi 日京山風香氛蠟燭 vs hoi!LAB 實驗室香氛蠟燭經典篇列為 hard veto;同品牌、同系列字樣或同容量仍不可跨品類/跨產品線直接比價。
|
||||
- **V10.420 111 Ollama LAN allowlist proxy**: 追查 111 高負載時確認來源不是 momo-pro,而是 110 上 `awoooi-cd` 臨時測試與 121 VMware VM 直接打 `192.168.0.111:11434`,繞過 `ai_calls` 與 momo-pro router 載入 7B runner。新增 `scripts/ops/ollama111_allow_proxy.py`,將真實 Ollama 收斂到 `127.0.0.1:11434`,由 user-space proxy 綁 `192.168.0.111:11434` 並預設只允許 111 本機與 188 生產宿主;110 / 121 會被 reset,111 fallback 保留給 momo production。
|
||||
- **V10.419 Dr.Hsieh LabSmart 精華品線防錯配**: marketplace matcher 追加 `dr_hsieh_labsmart_line_conflict`,只針對 Dr.Hsieh/達特醫的 `LabSmart Hi-Tech` / `LabSmart Classic` 精華被拿去對 `神經醯胺多重修復保濕精華液` 的近門檻錯配做 hard veto;同品牌同容量但不同產品線不再因規格相同停在 `true_low_confidence` 或被誤推進比價。
|
||||
|
||||
108
scripts/ops/install_ollama111_allow_proxy.sh
Executable file
108
scripts/ops/install_ollama111_allow_proxy.sh
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Install a user LaunchAgent that keeps the 111 Ollama LAN entrypoint behind
|
||||
# scripts/ops/ollama111_allow_proxy.py. This avoids sudo/pfctl and keeps the
|
||||
# real Ollama process bound to localhost while exposing an allowlisted LAN port.
|
||||
|
||||
PROJECT_DIR="${PROJECT_DIR:-$(cd "$(dirname "$0")/../.." && pwd)}"
|
||||
LABEL="${OLLAMA111_PROXY_LABEL:-com.momo.ollama111-allow-proxy}"
|
||||
PLIST_DIR="${HOME}/Library/LaunchAgents"
|
||||
PLIST_PATH="${PLIST_DIR}/${LABEL}.plist"
|
||||
LOG_DIR="${HOME}/Library/Logs"
|
||||
PID_FILE="${HOME}/.ollama/ollama111-allow-proxy.pid"
|
||||
PYTHON_BIN="${PYTHON_BIN:-/usr/bin/python3}"
|
||||
OLLAMA_APP="${OLLAMA_APP:-/Applications/Ollama.app}"
|
||||
OLLAMA_HOST_VALUE="${OLLAMA_HOST_VALUE:-127.0.0.1:11434}"
|
||||
ALLOWED_CIDRS="${OLLAMA111_PROXY_ALLOWED_CIDRS:-127.0.0.1/32,192.168.0.80/32,192.168.0.111/32,192.168.0.188/32}"
|
||||
GUI_DOMAIN="gui/$(id -u)"
|
||||
|
||||
if [[ ! -f "${PROJECT_DIR}/scripts/ops/ollama111_allow_proxy.py" ]]; then
|
||||
echo "missing proxy script under PROJECT_DIR=${PROJECT_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${PLIST_DIR}" "${LOG_DIR}" "${HOME}/.ollama"
|
||||
|
||||
launchctl setenv OLLAMA_HOST "${OLLAMA_HOST_VALUE}"
|
||||
|
||||
# Stop the ad-hoc nohup proxy from the initial incident response, if present.
|
||||
if [[ -f "${PID_FILE}" ]]; then
|
||||
old_pid="$(cat "${PID_FILE}" 2>/dev/null || true)"
|
||||
if [[ -n "${old_pid}" ]]; then
|
||||
kill "${old_pid}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -f "${PID_FILE}"
|
||||
fi
|
||||
while IFS= read -r old_proxy_pid; do
|
||||
[[ -n "${old_proxy_pid}" ]] && kill "${old_proxy_pid}" >/dev/null 2>&1 || true
|
||||
done < <(pgrep -f '[o]llama111_allow_proxy.py' || true)
|
||||
|
||||
# Restart Ollama so it observes the launchd user environment. The pgrep pattern
|
||||
# intentionally avoids matching this installer command.
|
||||
osascript -e 'quit app "Ollama"' >/dev/null 2>&1 || true
|
||||
while IFS= read -r old_ollama_pid; do
|
||||
[[ -n "${old_ollama_pid}" ]] && kill "${old_ollama_pid}" >/dev/null 2>&1 || true
|
||||
done < <(pgrep -f '[o]llama serve' || true)
|
||||
sleep 2
|
||||
open "${OLLAMA_APP}"
|
||||
|
||||
for _ in $(seq 1 20); do
|
||||
if curl -fsS --max-time 2 "http://${OLLAMA_HOST_VALUE}/api/version" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
cat > "${PLIST_PATH}" <<PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>${LABEL}</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>${PYTHON_BIN}</string>
|
||||
<string>${PROJECT_DIR}/scripts/ops/ollama111_allow_proxy.py</string>
|
||||
</array>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>${PROJECT_DIR}</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>OLLAMA111_PROXY_ALLOWED_CIDRS</key>
|
||||
<string>${ALLOWED_CIDRS}</string>
|
||||
<key>OLLAMA111_PROXY_LISTEN_HOST</key>
|
||||
<string>192.168.0.111</string>
|
||||
<key>OLLAMA111_PROXY_LISTEN_PORT</key>
|
||||
<string>11434</string>
|
||||
<key>OLLAMA111_PROXY_TARGET_HOST</key>
|
||||
<string>127.0.0.1</string>
|
||||
<key>OLLAMA111_PROXY_TARGET_PORT</key>
|
||||
<string>11434</string>
|
||||
<key>PYTHONUNBUFFERED</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>${LOG_DIR}/ollama111-allow-proxy.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>${LOG_DIR}/ollama111-allow-proxy.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
launchctl bootout "${GUI_DOMAIN}" "${PLIST_PATH}" >/dev/null 2>&1 || true
|
||||
launchctl bootstrap "${GUI_DOMAIN}" "${PLIST_PATH}"
|
||||
launchctl kickstart -k "${GUI_DOMAIN}/${LABEL}"
|
||||
|
||||
sleep 2
|
||||
echo "installed ${LABEL}"
|
||||
echo "plist=${PLIST_PATH}"
|
||||
echo "allowed=${ALLOWED_CIDRS}"
|
||||
launchctl print "${GUI_DOMAIN}/${LABEL}" | head -40 || true
|
||||
tail -20 "${LOG_DIR}/ollama111-allow-proxy.log" || true
|
||||
0
scripts/ops/ollama111_allow_proxy.py
Normal file → Executable file
0
scripts/ops/ollama111_allow_proxy.py
Normal file → Executable file
Reference in New Issue
Block a user