feat: брендовые цвета имён моделей, персистентность model между сессиями
- _brand_color: цвет имени модели по AI_LAUNCHER deepseek=синий(69), claude=оранжевый(173), kimi=голубой(81), openrouter=фиолетовый(135), остальные=кремовый(223) - _restore_model / _restore_model_str: сохранение и восстановление model_id в кэше лаунчера (~/.cache/ai-setup/model_<launcher>) - effort-save-hook также сохраняет model_id при завершении сессии - ai-claude/ai-openrouter используют восстановленную модель при старте Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,17 +4,21 @@
|
||||
launcher="${AI_LAUNCHER:-}"
|
||||
[ -z "$launcher" ] && exit 0
|
||||
cat /dev/stdin > /dev/null 2>&1 # drain stdin (Claude Code передаёт JSON)
|
||||
effort=$(python3 -c "
|
||||
import json, os
|
||||
p = os.path.expanduser('~/.claude/settings.json')
|
||||
if os.path.exists(p):
|
||||
try:
|
||||
d = json.load(open(p))
|
||||
print(d.get('effortLevel', ''))
|
||||
except Exception:
|
||||
pass
|
||||
" 2>/dev/null)
|
||||
[ -z "$effort" ] && exit 0
|
||||
mkdir -p "$HOME/.cache/ai-setup"
|
||||
echo "$effort" > "$HOME/.cache/ai-setup/effort_${launcher}"
|
||||
python3 - "$HOME/.claude/settings.json" "$HOME/.cache/ai-setup" "$launcher" <<'PYEOF'
|
||||
import json, os, sys
|
||||
settings_path, cache_dir, launcher = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
if not os.path.exists(settings_path):
|
||||
sys.exit(0)
|
||||
try:
|
||||
d = json.load(open(settings_path))
|
||||
except Exception:
|
||||
sys.exit(0)
|
||||
effort = d.get('effortLevel', '')
|
||||
if effort:
|
||||
open(os.path.join(cache_dir, f'effort_{launcher}'), 'w').write(effort)
|
||||
model = d.get('model', '')
|
||||
if model:
|
||||
open(os.path.join(cache_dir, f'model_{launcher}'), 'w').write(model)
|
||||
PYEOF
|
||||
exit 0
|
||||
|
||||
@@ -10,28 +10,40 @@ week_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
|
||||
ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
|
||||
|
||||
|
||||
# Цвет effort: мягкая гармоничная палитра
|
||||
# Цвет effort: насыщенные, глубже чем пастельные (jewel tones)
|
||||
_effort_color() {
|
||||
case "$1" in
|
||||
low) printf '\033[38;5;220m[low]\033[00m' ;; # золотой
|
||||
medium) printf '\033[38;5;43m[medium]\033[00m' ;; # бирюзовый
|
||||
high) printf '\033[38;5;39m[high]\033[00m' ;; # небесно-голубой
|
||||
xhigh) printf '\033[38;5;171m[xhigh]\033[00m' ;; # лавандовый
|
||||
max) printf '\033[38;5;210m[\033[38;5;220mm\033[38;5;114ma\033[38;5;43mx\033[38;5;171m]\033[00m' ;; # радуга
|
||||
*) printf '\033[38;5;250m[%s]\033[00m' "$1" ;;
|
||||
medium) printf '\033[38;5;50m[medium]\033[00m' ;; # насыщенный teal
|
||||
high) printf '\033[38;5;38m[high]\033[00m' ;; # глубокий голубой
|
||||
xhigh) printf '\033[38;5;206m[xhigh]\033[00m' ;; # насыщенный фиолетовый
|
||||
max) printf '\033[38;5;210m[\033[38;5;220mm\033[38;5;114ma\033[38;5;50mx\033[38;5;206m]\033[00m' ;; # радуга
|
||||
*) printf '\033[38;5;252m[%s]\033[00m' "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Брендовый цвет имени модели по лаунчеру
|
||||
_brand_color() {
|
||||
case "${1:-}" in
|
||||
deepseek) printf '\033[38;5;69m' ;; # DeepSeek фирменный синий
|
||||
claude) printf '\033[38;5;173m' ;; # Anthropic оранжевый
|
||||
kimi) printf '\033[38;5;81m' ;; # Kimi голубой
|
||||
openrouter) printf '\033[38;5;135m' ;; # OpenRouter фиолетовый
|
||||
*) printf '\033[38;5;223m' ;; # кремовый (fallback)
|
||||
esac
|
||||
}
|
||||
|
||||
branch=$(git -C "$cwd" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null)
|
||||
|
||||
short_cwd="${cwd/#$HOME/\~}"
|
||||
printf "\033[38;5;250m%s\033[00m" "$short_cwd"
|
||||
printf "\033[38;5;252m%s\033[00m" "$short_cwd"
|
||||
|
||||
[ -n "$branch" ] && printf " \033[38;5;250m[%s]\033[00m" "$branch"
|
||||
[ -n "$branch" ] && printf " \033[38;5;252m[%s]\033[00m" "$branch"
|
||||
if [ -n "$model" ]; then
|
||||
brand_color=$(_brand_color "${AI_LAUNCHER:-}")
|
||||
effort=$(echo "$input" | jq -r ".effort.level // empty")
|
||||
# Сохраняем effort для persistence между сессиями одного лаунчера
|
||||
if [ -n "$effort" ] && [ -n "${AI_LAUNCHER:-}" ]; then
|
||||
if [ -n "${AI_LAUNCHER:-}" ] && [ -n "$effort" ]; then
|
||||
effort_file="$HOME/.cache/ai-setup/effort_${AI_LAUNCHER}"
|
||||
prev_effort=$(cat "$effort_file" 2>/dev/null)
|
||||
if [ "$effort" != "$prev_effort" ]; then
|
||||
@@ -79,13 +91,13 @@ if [ -n "$model" ]; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
[ -n "$account" ] && printf " \033[38;5;223m[%s]\033[00m" "$account"
|
||||
[ -n "$account" ] && printf " %s[%s]\033[00m" "$brand_color" "$account"
|
||||
fi
|
||||
if [ -n "$effort" ]; then
|
||||
printf " \033[38;5;223m%s " "$model"
|
||||
printf " %s%s " "$brand_color" "$model"
|
||||
_effort_color "$effort"
|
||||
else
|
||||
printf " \033[38;5;223m%s\033[00m" "$model"
|
||||
printf " %s%s\033[00m" "$brand_color" "$model"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -114,7 +126,7 @@ pct_color() {
|
||||
if [ "$pct" -lt 40 ]; then
|
||||
printf '\033[38;5;114m' # мягкий зелёный
|
||||
elif [ "$pct" -lt 60 ]; then
|
||||
printf '\033[38;5;221m' # золотистый
|
||||
printf '\033[38;5;220m' # золотой (как effort low)
|
||||
else
|
||||
printf '\033[38;5;210m' # мягкий красный
|
||||
fi
|
||||
@@ -127,7 +139,7 @@ if [[ "$model_id" == *deepseek* ]]; then
|
||||
cache_file="$HOME/.cache/ai-setup/deepseek_balance"
|
||||
if [ -f "$cache_file" ]; then
|
||||
balance=$(head -1 "$cache_file")
|
||||
[ -n "$balance" ] && printf " \033[38;5;147m%s\033[00m" "$balance"
|
||||
[ -n "$balance" ] && printf " \033[38;5;183m%s\033[00m" "$balance"
|
||||
fi
|
||||
|
||||
# Фоновое обновление баланса (не чаще раза в 30 секунд)
|
||||
|
||||
@@ -1106,6 +1106,44 @@ with open(settings_path, 'w') as f:
|
||||
PYEOF
|
||||
}
|
||||
|
||||
_restore_model() {
|
||||
local default_model="${1:-}"
|
||||
local launcher="${AI_LAUNCHER:-}"
|
||||
[ -z "$launcher" ] && return
|
||||
local model_file="$HOME/.cache/ai-setup/model_${launcher}"
|
||||
local model
|
||||
model=$(cat "$model_file" 2>/dev/null)
|
||||
[ -z "$model" ] && model="$default_model"
|
||||
[ -z "$model" ] && return
|
||||
python3 - "$HOME/.claude/settings.json" "$model" <<'PYEOF'
|
||||
import sys, json, os
|
||||
settings_path, model = sys.argv[1], sys.argv[2]
|
||||
data = {}
|
||||
if os.path.exists(settings_path):
|
||||
try:
|
||||
with open(settings_path) as f:
|
||||
data = json.load(f)
|
||||
except Exception:
|
||||
pass
|
||||
data['model'] = model
|
||||
with open(settings_path, 'w') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
f.write('\n')
|
||||
PYEOF
|
||||
}
|
||||
|
||||
# _restore_model_str: возвращает сохранённую модель строкой (для ANTHROPIC_MODEL env var)
|
||||
_restore_model_str() {
|
||||
local default_model="${1:-}"
|
||||
local launcher="${AI_LAUNCHER:-}"
|
||||
[ -z "$launcher" ] && echo "$default_model" && return
|
||||
local model_file="$HOME/.cache/ai-setup/model_${launcher}"
|
||||
local model
|
||||
model=$(cat "$model_file" 2>/dev/null)
|
||||
[ -z "$model" ] && model="$default_model"
|
||||
echo "$model"
|
||||
}
|
||||
|
||||
_build_ai_sys_prompt() {
|
||||
local global_rules="$HOME/.config/ai-setup/global_rules.md"
|
||||
local global_rendered=""
|
||||
@@ -1377,9 +1415,10 @@ trap 'rm -f "$_PROMPT_FILE"' EXIT INT TERM
|
||||
_build_ai_sys_prompt > "$_PROMPT_FILE"
|
||||
export AI_LAUNCHER=openrouter
|
||||
_restore_effort high
|
||||
_MODEL=$(_restore_model_str "openai/gpt-5.5")
|
||||
ANTHROPIC_BASE_URL=https://openrouter.ai/api \
|
||||
ANTHROPIC_AUTH_TOKEN="$api_key" \
|
||||
ANTHROPIC_MODEL=openai/gpt-5.5 \
|
||||
ANTHROPIC_MODEL=$_MODEL \
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL=anthropic/claude-4.8-opus \
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL=anthropic/claude-4.6-sonnet \
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL=openai/gpt-5.5 \
|
||||
@@ -1431,7 +1470,8 @@ trap 'rm -f "$_PROMPT_FILE"' EXIT INT TERM
|
||||
_build_ai_sys_prompt > "$_PROMPT_FILE"
|
||||
export AI_LAUNCHER=claude
|
||||
_restore_effort xhigh
|
||||
claude --dangerously-skip-permissions --model sonnet --system-prompt-file "$_PROMPT_FILE" "$@"
|
||||
_restore_model "sonnet"
|
||||
claude --dangerously-skip-permissions --system-prompt-file "$_PROMPT_FILE" "$@"
|
||||
CLAUDEEOF
|
||||
chmod +x "$BIN_DIR/ai-claude"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user