OpenClaw-Setup/openclaw-setup-max/scripts/model_profile_switch.sh

159 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_PATH="${MODEL_PROFILES_CONFIG:-$ROOT_DIR/config/model-profiles.config.json}"
SESSION_KEY="${MODEL_SWITCH_SESSION_KEY:-agent:main:main}"
if ! command -v jq >/dev/null 2>&1; then
echo "[model-switch] jq is required" >&2
exit 1
fi
if ! command -v openclaw >/dev/null 2>&1; then
echo "[model-switch] openclaw CLI is required" >&2
exit 1
fi
usage() {
cat <<'USAGE'
Usage:
bash ./scripts/model_profile_switch.sh status
bash ./scripts/model_profile_switch.sh <profile> [--no-live] [--no-status]
Examples:
bash ./scripts/model_profile_switch.sh free
bash ./scripts/model_profile_switch.sh paid --no-live
USAGE
}
get_session_id() {
local session_key="$1"
local state_dir="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
local sessions_file="$state_dir/agents/main/sessions/sessions.json"
if [[ ! -f "$sessions_file" ]]; then
return 0
fi
jq -r --arg key "$session_key" '.[$key].sessionId // empty' "$sessions_file"
}
if [[ ! -f "$CONFIG_PATH" ]]; then
echo "[model-switch] missing config: $CONFIG_PATH" >&2
exit 1
fi
profile="${1:-}"
if [[ -z "$profile" ]]; then
usage
exit 1
fi
shift || true
apply_live="true"
show_status="true"
while (( "$#" )); do
case "$1" in
--no-live) apply_live="false" ;;
--no-status) show_status="false" ;;
-h|--help)
usage
exit 0
;;
*)
echo "[model-switch] unknown argument: $1" >&2
usage
exit 1
;;
esac
shift
done
if [[ "$profile" == "status" ]]; then
echo "Available profiles:"
jq -r '.profiles | to_entries[] | "- \(.key): \(.value.primary) (\(.value.description // "no description"))"' "$CONFIG_PATH"
echo ""
openclaw models status
exit 0
fi
profile_exists="$(jq -r --arg p "$profile" '.profiles[$p] != null' "$CONFIG_PATH")"
if [[ "$profile_exists" != "true" ]]; then
echo "[model-switch] unknown profile '$profile' in $CONFIG_PATH" >&2
jq -r '.profiles | keys[]' "$CONFIG_PATH" | sed 's/^/ - /'
exit 1
fi
primary="$(jq -r --arg p "$profile" '.profiles[$p].primary // empty' "$CONFIG_PATH")"
if [[ -z "$primary" ]]; then
echo "[model-switch] profile '$profile' has no primary model" >&2
exit 1
fi
fallbacks=()
while IFS= read -r fb; do
[[ -z "$fb" ]] && continue
fallbacks+=("$fb")
done < <(jq -r --arg p "$profile" '.profiles[$p].fallbacks[]? // empty' "$CONFIG_PATH")
echo "[model-switch] Applying profile: $profile"
echo "[model-switch] primary: $primary"
if [[ ${#fallbacks[@]} -gt 0 ]]; then
echo "[model-switch] fallbacks: ${fallbacks[*]}"
else
echo "[model-switch] fallbacks: (none)"
fi
openclaw models set "$primary" >/dev/null
openclaw models fallbacks clear >/dev/null
for fb in "${fallbacks[@]}"; do
[[ -z "$fb" ]] && continue
openclaw models fallbacks add "$fb" >/dev/null
done
provider_policy_len="$(jq -r --arg p "$profile" '.profiles[$p].providerPolicy // {} | length' "$CONFIG_PATH")"
if [[ "$provider_policy_len" != "0" ]]; then
while IFS=$'\t' read -r provider enabled; do
if [[ -z "$provider" || -z "$enabled" ]]; then
continue
fi
openclaw config set --json "providers.$provider.enabled" "$enabled" >/dev/null || true
done < <(jq -r --arg p "$profile" '.profiles[$p].providerPolicy // {} | to_entries[] | "\(.key)\t\(.value)"' "$CONFIG_PATH")
fi
if [[ "$apply_live" == "true" ]]; then
session_id="$(get_session_id "$SESSION_KEY")"
if [[ -n "$session_id" ]]; then
python3 - "$session_id" "$primary" <<'PY'
import subprocess
import sys
session_id = sys.argv[1]
primary = sys.argv[2]
cmd = [
"openclaw",
"agent",
"--session-id", session_id,
"--channel", "last",
"--message", f"/model {primary}",
]
try:
subprocess.run(
cmd,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=False,
timeout=20,
)
except subprocess.TimeoutExpired:
pass
PY
echo "[model-switch] live session updated: $session_id"
else
echo "[model-switch] no active session found for key $SESSION_KEY"
fi
fi
if [[ "$show_status" == "true" ]]; then
echo ""
openclaw models status
fi