From a6e4823188b5649aa932c36cb3da8ed66128a1a9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 19 Feb 2026 13:00:26 -0600 Subject: [PATCH] feat: prompt for paid copilot model selection --- openclaw-setup-copilot/README.md | 9 ++- .../docs/operations/AI_SETUP_HANDOFF.md | 1 + .../docs/operations/WORK_SETUP_CHECKLIST.md | 9 ++- .../configure_copilot_guardrails_defaults.sh | 78 +++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/openclaw-setup-copilot/README.md b/openclaw-setup-copilot/README.md index 50c0a14..0ed06a0 100644 --- a/openclaw-setup-copilot/README.md +++ b/openclaw-setup-copilot/README.md @@ -100,7 +100,8 @@ bash ./scripts/finalize_copilot_setup.sh What finalize does: - Opens `copilot auth login` if needed - Refreshes model catalog -- Auto-picks paid/free profiles from available Copilot models +- Prompts you to choose the paid profile model from non-free candidates +- Auto-picks the free profile model/fallbacks from low-cost candidates - Installs all guardrails - Enables recommended hooks - Restarts gateway @@ -115,6 +116,12 @@ openclaw status --deep If login is missing/expired, finalize will prompt for login and retry setup. +For unattended/non-interactive automation: + +```bash +PROMPT_FOR_PAID_MODEL=false bash ./scripts/finalize_copilot_setup.sh +``` + ### How To Choose Copilot Models (and Why It Matters) Choosing the right primary and fallback models is important because it controls: diff --git a/openclaw-setup-copilot/docs/operations/AI_SETUP_HANDOFF.md b/openclaw-setup-copilot/docs/operations/AI_SETUP_HANDOFF.md index cec864a..b3914db 100644 --- a/openclaw-setup-copilot/docs/operations/AI_SETUP_HANDOFF.md +++ b/openclaw-setup-copilot/docs/operations/AI_SETUP_HANDOFF.md @@ -22,6 +22,7 @@ Run in this order: 1) bash ./setup/setup_openclaw_copilot.sh 2) bash ./scripts/finalize_copilot_setup.sh - if prompted, pause and wait for user to complete browser login + - if prompted for paid model, show model list to user and ask user to choose 3) openclaw status --deep After setup, verify and report: diff --git a/openclaw-setup-copilot/docs/operations/WORK_SETUP_CHECKLIST.md b/openclaw-setup-copilot/docs/operations/WORK_SETUP_CHECKLIST.md index bd8705c..ce32a31 100644 --- a/openclaw-setup-copilot/docs/operations/WORK_SETUP_CHECKLIST.md +++ b/openclaw-setup-copilot/docs/operations/WORK_SETUP_CHECKLIST.md @@ -46,6 +46,7 @@ bash ./scripts/finalize_copilot_setup.sh Expected: - Authenticated with enterprise-linked account - Copilot models discovered +- If prompted, paid profile model selected from non-free candidates - Guardrails installed + running - Hooks enabled (`boot-md`, `command-logger`, `session-memory`) - Gateway restarted @@ -141,12 +142,18 @@ openclaw models status If step 3 already succeeded, this is already done. -This one command auto-detects your available Copilot models, picks low-cost defaults, applies policy, and installs launchd guards: +This one command auto-detects your available Copilot models, asks for paid model selection (interactive), picks low-cost free defaults, applies policy, and installs launchd guards: ```bash bash ./scripts/install_copilot_guardrails.sh ``` +For unattended/non-interactive automation: + +```bash +PROMPT_FOR_PAID_MODEL=false bash ./scripts/install_copilot_guardrails.sh +``` + 3. Verify: ```bash diff --git a/openclaw-setup-copilot/scripts/configure_copilot_guardrails_defaults.sh b/openclaw-setup-copilot/scripts/configure_copilot_guardrails_defaults.sh index 31968a8..e528768 100755 --- a/openclaw-setup-copilot/scripts/configure_copilot_guardrails_defaults.sh +++ b/openclaw-setup-copilot/scripts/configure_copilot_guardrails_defaults.sh @@ -59,6 +59,52 @@ is_cheap_model() { [[ "$m" =~ (haiku|mini|flash|fast|nano|small|lite|economy) ]] } +prompt_for_paid_model() { + local default_model="$1" + shift + local -a candidates=("$@") + + if [[ ${#candidates[@]} -eq 0 ]]; then + echo "$default_model" + return 0 + fi + + echo "" >&2 + echo "[configure-guardrails] Choose paid profile primary model (non-free candidates):" >&2 + for i in "${!candidates[@]}"; do + local n=$((i + 1)) + local marker="" + if [[ "${candidates[$i]}" == "$default_model" ]]; then + marker=" (default)" + fi + printf " %d) %s%s\n" "$n" "${candidates[$i]}" "$marker" >&2 + done + printf "Select number [default=%s]: " "$default_model" >&2 + + local choice="" + if ! IFS= read -r choice; then + echo "" >&2 + echo "$default_model" + return 0 + fi + + if [[ -z "$choice" ]]; then + echo "$default_model" + return 0 + fi + + if [[ "$choice" =~ ^[0-9]+$ ]]; then + local idx=$((choice - 1)) + if (( idx >= 0 && idx < ${#candidates[@]} )); then + echo "${candidates[$idx]}" + return 0 + fi + fi + + echo "[configure-guardrails] Invalid selection '$choice'; using default: $default_model" >&2 + echo "$default_model" +} + copilot_models=() while IFS= read -r model; do [[ -z "$model" ]] && continue @@ -83,6 +129,33 @@ MSG exit 1 fi +prompt_mode="${PROMPT_FOR_PAID_MODEL:-auto}" +interactive_picker="false" +case "$prompt_mode" in + auto) + if [[ -t 0 && -t 1 ]]; then + interactive_picker="true" + fi + ;; + true|yes|1) + interactive_picker="true" + ;; + false|no|0) + interactive_picker="false" + ;; + *) + echo "[configure-guardrails] Invalid PROMPT_FOR_PAID_MODEL='$prompt_mode' (expected auto/true/false). Using auto." >&2 + if [[ -t 0 && -t 1 ]]; then + interactive_picker="true" + fi + ;; +esac + +if [[ "$interactive_picker" == "true" && ( ! -t 0 || ! -t 1 ) ]]; then + echo "[configure-guardrails] PROMPT_FOR_PAID_MODEL enabled but no interactive TTY; falling back to auto selection." >&2 + interactive_picker="false" +fi + primary_model="" for m in "${copilot_models[@]}"; do if is_cheap_model "$m"; then @@ -150,6 +223,11 @@ if [[ -z "$paid_model" ]]; then paid_model="$primary_model" fi +if [[ "$interactive_picker" == "true" && ${#high_models[@]} -gt 0 ]]; then + paid_model="$(prompt_for_paid_model "$paid_model" "${high_models[@]}")" + echo "[configure-guardrails] selected paid model: $paid_model" +fi + # free profile = lowest-cost primary + lowest-cost fallbacks declare -a free_fallbacks=("${cheap_candidates[@]}")