Merge remote-tracking branch 'origin/main' into feat/queen-responsibility
This commit is contained in:
+242
-98
@@ -407,7 +407,7 @@ if [ "$USE_ASSOC_ARRAYS" = true ]; then
|
||||
)
|
||||
|
||||
declare -A DEFAULT_MODELS=(
|
||||
["anthropic"]="claude-haiku-4-5"
|
||||
["anthropic"]="claude-haiku-4-5-20251001"
|
||||
["openai"]="gpt-5-mini"
|
||||
["gemini"]="gemini-3-flash-preview"
|
||||
["groq"]="moonshotai/kimi-k2-instruct-0905"
|
||||
@@ -420,12 +420,12 @@ if [ "$USE_ASSOC_ARRAYS" = true ]; then
|
||||
# Model choices per provider: composite-key associative arrays
|
||||
# Keys: "provider:index" -> value
|
||||
declare -A MODEL_CHOICES_ID=(
|
||||
["anthropic:0"]="claude-opus-4-6"
|
||||
["anthropic:1"]="claude-sonnet-4-5-20250929"
|
||||
["anthropic:2"]="claude-sonnet-4-20250514"
|
||||
["anthropic:3"]="claude-haiku-4-5-20251001"
|
||||
["openai:0"]="gpt-5.2"
|
||||
["openai:1"]="gpt-5-mini"
|
||||
["anthropic:0"]="claude-haiku-4-5-20251001"
|
||||
["anthropic:1"]="claude-sonnet-4-20250514"
|
||||
["anthropic:2"]="claude-sonnet-4-5-20250929"
|
||||
["anthropic:3"]="claude-opus-4-6"
|
||||
["openai:0"]="gpt-5-mini"
|
||||
["openai:1"]="gpt-5.2"
|
||||
["gemini:0"]="gemini-3-flash-preview"
|
||||
["gemini:1"]="gemini-3.1-pro-preview"
|
||||
["groq:0"]="moonshotai/kimi-k2-instruct-0905"
|
||||
@@ -435,12 +435,12 @@ if [ "$USE_ASSOC_ARRAYS" = true ]; then
|
||||
)
|
||||
|
||||
declare -A MODEL_CHOICES_LABEL=(
|
||||
["anthropic:0"]="Opus 4.6 - Most capable (recommended)"
|
||||
["anthropic:1"]="Sonnet 4.5 - Best balance"
|
||||
["anthropic:2"]="Sonnet 4 - Fast + capable"
|
||||
["anthropic:3"]="Haiku 4.5 - Fast + cheap"
|
||||
["openai:0"]="GPT-5.2 - Most capable (recommended)"
|
||||
["openai:1"]="GPT-5 Mini - Fast + cheap"
|
||||
["anthropic:0"]="Haiku 4.5 - Fast + cheap (recommended)"
|
||||
["anthropic:1"]="Sonnet 4 - Fast + capable"
|
||||
["anthropic:2"]="Sonnet 4.5 - Best balance"
|
||||
["anthropic:3"]="Opus 4.6 - Most capable"
|
||||
["openai:0"]="GPT-5 Mini - Fast + cheap (recommended)"
|
||||
["openai:1"]="GPT-5.2 - Most capable"
|
||||
["gemini:0"]="Gemini 3 Flash - Fast (recommended)"
|
||||
["gemini:1"]="Gemini 3.1 Pro - Best quality"
|
||||
["groq:0"]="Kimi K2 - Best quality (recommended)"
|
||||
@@ -450,10 +450,10 @@ if [ "$USE_ASSOC_ARRAYS" = true ]; then
|
||||
)
|
||||
|
||||
declare -A MODEL_CHOICES_MAXTOKENS=(
|
||||
["anthropic:0"]=32768
|
||||
["anthropic:1"]=16384
|
||||
["anthropic:2"]=8192
|
||||
["anthropic:3"]=8192
|
||||
["anthropic:0"]=8192
|
||||
["anthropic:1"]=8192
|
||||
["anthropic:2"]=16384
|
||||
["anthropic:3"]=32768
|
||||
["openai:0"]=16384
|
||||
["openai:1"]=16384
|
||||
["gemini:0"]=8192
|
||||
@@ -508,7 +508,7 @@ else
|
||||
|
||||
# Default models by provider id (parallel arrays)
|
||||
MODEL_PROVIDER_IDS=(anthropic openai gemini groq cerebras mistral together_ai deepseek)
|
||||
MODEL_DEFAULTS=("claude-opus-4-6" "gpt-5.2" "gemini-3-flash-preview" "moonshotai/kimi-k2-instruct-0905" "zai-glm-4.7" "mistral-large-latest" "meta-llama/Llama-3.3-70B-Instruct-Turbo" "deepseek-chat")
|
||||
MODEL_DEFAULTS=("claude-haiku-4-5-20251001" "gpt-5-mini" "gemini-3-flash-preview" "moonshotai/kimi-k2-instruct-0905" "zai-glm-4.7" "mistral-large-latest" "meta-llama/Llama-3.3-70B-Instruct-Turbo" "deepseek-chat")
|
||||
|
||||
# Helper: get provider display name for an env var
|
||||
get_provider_name() {
|
||||
@@ -552,9 +552,9 @@ else
|
||||
# Model choices per provider - flat parallel arrays with provider offsets
|
||||
# Provider order: anthropic(4), openai(2), gemini(2), groq(2), cerebras(2)
|
||||
MC_PROVIDERS=(anthropic anthropic anthropic anthropic openai openai gemini gemini groq groq cerebras cerebras)
|
||||
MC_IDS=("claude-opus-4-6" "claude-sonnet-4-5-20250929" "claude-sonnet-4-20250514" "claude-haiku-4-5-20251001" "gpt-5.2" "gpt-5-mini" "gemini-3-flash-preview" "gemini-3.1-pro-preview" "moonshotai/kimi-k2-instruct-0905" "openai/gpt-oss-120b" "zai-glm-4.7" "qwen3-235b-a22b-instruct-2507")
|
||||
MC_LABELS=("Opus 4.6 - Most capable (recommended)" "Sonnet 4.5 - Best balance" "Sonnet 4 - Fast + capable" "Haiku 4.5 - Fast + cheap" "GPT-5.2 - Most capable (recommended)" "GPT-5 Mini - Fast + cheap" "Gemini 3 Flash - Fast (recommended)" "Gemini 3.1 Pro - Best quality" "Kimi K2 - Best quality (recommended)" "GPT-OSS 120B - Fast reasoning" "ZAI-GLM 4.7 - Best quality (recommended)" "Qwen3 235B - Frontier reasoning")
|
||||
MC_MAXTOKENS=(32768 16384 8192 8192 16384 16384 8192 8192 8192 8192 8192 8192)
|
||||
MC_IDS=("claude-haiku-4-5-20251001" "claude-sonnet-4-20250514" "claude-sonnet-4-5-20250929" "claude-opus-4-6" "gpt-5-mini" "gpt-5.2" "gemini-3-flash-preview" "gemini-3.1-pro-preview" "moonshotai/kimi-k2-instruct-0905" "openai/gpt-oss-120b" "zai-glm-4.7" "qwen3-235b-a22b-instruct-2507")
|
||||
MC_LABELS=("Haiku 4.5 - Fast + cheap (recommended)" "Sonnet 4 - Fast + capable" "Sonnet 4.5 - Best balance" "Opus 4.6 - Most capable" "GPT-5 Mini - Fast + cheap (recommended)" "GPT-5.2 - Most capable" "Gemini 3 Flash - Fast (recommended)" "Gemini 3.1 Pro - Best quality" "Kimi K2 - Best quality (recommended)" "GPT-OSS 120B - Fast reasoning" "ZAI-GLM 4.7 - Best quality (recommended)" "Qwen3 235B - Frontier reasoning")
|
||||
MC_MAXTOKENS=(8192 8192 16384 32768 16384 16384 8192 8192 8192 8192 8192 8192)
|
||||
|
||||
# Helper: get number of model choices for a provider
|
||||
get_model_choice_count() {
|
||||
@@ -687,6 +687,19 @@ prompt_model_selection() {
|
||||
echo -e "${BOLD}Select a model:${NC}"
|
||||
echo ""
|
||||
|
||||
# Find default index from previous model (if same provider)
|
||||
local default_idx=""
|
||||
if [ -n "$PREV_MODEL" ] && [ "$provider_id" = "$PREV_PROVIDER" ]; then
|
||||
local j=0
|
||||
while [ $j -lt "$count" ]; do
|
||||
if [ "$(get_model_choice_id "$provider_id" "$j")" = "$PREV_MODEL" ]; then
|
||||
default_idx=$((j + 1))
|
||||
break
|
||||
fi
|
||||
j=$((j + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
local i=0
|
||||
while [ $i -lt "$count" ]; do
|
||||
local label
|
||||
@@ -701,7 +714,12 @@ prompt_model_selection() {
|
||||
|
||||
local choice
|
||||
while true; do
|
||||
read -r -p "Enter choice (1-$count): " choice || true
|
||||
if [ -n "$default_idx" ]; then
|
||||
read -r -p "Enter choice (1-$count) [$default_idx]: " choice || true
|
||||
choice="${choice:-$default_idx}"
|
||||
else
|
||||
read -r -p "Enter choice (1-$count): " choice || true
|
||||
fi
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
|
||||
local idx=$((choice - 1))
|
||||
SELECTED_MODEL="$(get_model_choice_id "$provider_id" "$idx")"
|
||||
@@ -781,7 +799,9 @@ SUBSCRIPTION_MODE="" # "claude_code" | "codex" | "zai_code" | ""
|
||||
|
||||
# ── Credential detection (silent — just set flags) ───────────
|
||||
CLAUDE_CRED_DETECTED=false
|
||||
if [ -f "$HOME/.claude/.credentials.json" ]; then
|
||||
if command -v security &>/dev/null && security find-generic-password -s "Claude Code-credentials" &>/dev/null 2>&1; then
|
||||
CLAUDE_CRED_DETECTED=true
|
||||
elif [ -f "$HOME/.claude/.credentials.json" ]; then
|
||||
CLAUDE_CRED_DETECTED=true
|
||||
fi
|
||||
|
||||
@@ -814,6 +834,65 @@ else
|
||||
done
|
||||
fi
|
||||
|
||||
# ── Read previous configuration (if any) ──────────────────────
|
||||
PREV_PROVIDER=""
|
||||
PREV_MODEL=""
|
||||
PREV_ENV_VAR=""
|
||||
PREV_SUB_MODE=""
|
||||
if [ -f "$HIVE_CONFIG_FILE" ]; then
|
||||
eval "$($PYTHON_CMD -c "
|
||||
import json, sys
|
||||
try:
|
||||
with open('$HIVE_CONFIG_FILE') as f:
|
||||
c = json.load(f)
|
||||
llm = c.get('llm', {})
|
||||
print(f'PREV_PROVIDER={llm.get(\"provider\", \"\")}')
|
||||
print(f'PREV_MODEL={llm.get(\"model\", \"\")}')
|
||||
print(f'PREV_ENV_VAR={llm.get(\"api_key_env_var\", \"\")}')
|
||||
sub = ''
|
||||
if llm.get('use_claude_code_subscription'): sub = 'claude_code'
|
||||
elif llm.get('use_codex_subscription'): sub = 'codex'
|
||||
elif 'api.z.ai' in llm.get('api_base', ''): sub = 'zai_code'
|
||||
print(f'PREV_SUB_MODE={sub}')
|
||||
except Exception:
|
||||
pass
|
||||
" 2>/dev/null)" || true
|
||||
fi
|
||||
|
||||
# Compute default menu number from previous config (only if credential is still valid)
|
||||
DEFAULT_CHOICE=""
|
||||
if [ -n "$PREV_SUB_MODE" ] || [ -n "$PREV_PROVIDER" ]; then
|
||||
PREV_CRED_VALID=false
|
||||
case "$PREV_SUB_MODE" in
|
||||
claude_code) [ "$CLAUDE_CRED_DETECTED" = true ] && PREV_CRED_VALID=true ;;
|
||||
zai_code) [ "$ZAI_CRED_DETECTED" = true ] && PREV_CRED_VALID=true ;;
|
||||
codex) [ "$CODEX_CRED_DETECTED" = true ] && PREV_CRED_VALID=true ;;
|
||||
*)
|
||||
# API key provider — check if the env var is set
|
||||
if [ -n "$PREV_ENV_VAR" ] && [ -n "${!PREV_ENV_VAR}" ]; then
|
||||
PREV_CRED_VALID=true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$PREV_CRED_VALID" = true ]; then
|
||||
case "$PREV_SUB_MODE" in
|
||||
claude_code) DEFAULT_CHOICE=1 ;;
|
||||
zai_code) DEFAULT_CHOICE=2 ;;
|
||||
codex) DEFAULT_CHOICE=3 ;;
|
||||
esac
|
||||
if [ -z "$DEFAULT_CHOICE" ]; then
|
||||
case "$PREV_PROVIDER" in
|
||||
anthropic) DEFAULT_CHOICE=4 ;;
|
||||
openai) DEFAULT_CHOICE=5 ;;
|
||||
gemini) DEFAULT_CHOICE=6 ;;
|
||||
groq) DEFAULT_CHOICE=7 ;;
|
||||
cerebras) DEFAULT_CHOICE=8 ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Show unified provider selection menu ─────────────────────
|
||||
echo -e "${BOLD}Select your default LLM provider:${NC}"
|
||||
echo ""
|
||||
@@ -858,8 +937,18 @@ done
|
||||
echo -e " ${CYAN}9)${NC} Skip for now"
|
||||
echo ""
|
||||
|
||||
if [ -n "$DEFAULT_CHOICE" ]; then
|
||||
echo -e " ${DIM}Previously configured: ${PREV_PROVIDER}/${PREV_MODEL}. Press Enter to keep.${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
while true; do
|
||||
read -r -p "Enter choice (1-9): " choice || true
|
||||
if [ -n "$DEFAULT_CHOICE" ]; then
|
||||
read -r -p "Enter choice (1-9) [$DEFAULT_CHOICE]: " choice || true
|
||||
choice="${choice:-$DEFAULT_CHOICE}"
|
||||
else
|
||||
read -r -p "Enter choice (1-9): " choice || true
|
||||
fi
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le 9 ]; then
|
||||
break
|
||||
fi
|
||||
@@ -968,48 +1057,132 @@ case $choice in
|
||||
;;
|
||||
esac
|
||||
|
||||
# For API-key providers: prompt for key if not already set
|
||||
if [ -z "$SUBSCRIPTION_MODE" ] && [ -n "$SELECTED_ENV_VAR" ] && [ -z "${!SELECTED_ENV_VAR}" ]; then
|
||||
echo ""
|
||||
echo -e "Get your API key from: ${CYAN}$SIGNUP_URL${NC}"
|
||||
echo ""
|
||||
read -r -p "Paste your $PROVIDER_NAME API key (or press Enter to skip): " API_KEY
|
||||
# For API-key providers: prompt for key (allow replacement if already set)
|
||||
if [ -z "$SUBSCRIPTION_MODE" ] && [ -n "$SELECTED_ENV_VAR" ]; then
|
||||
while true; do
|
||||
CURRENT_KEY="${!SELECTED_ENV_VAR}"
|
||||
if [ -n "$CURRENT_KEY" ]; then
|
||||
# Key exists — offer to keep or replace
|
||||
MASKED_KEY="${CURRENT_KEY:0:4}...${CURRENT_KEY: -4}"
|
||||
echo ""
|
||||
echo -e " ${GREEN}⬢${NC} Current key: ${DIM}$MASKED_KEY${NC}"
|
||||
read -r -p " Press Enter to keep, or paste a new key to replace: " API_KEY
|
||||
else
|
||||
# No key — prompt for one
|
||||
echo ""
|
||||
echo -e "Get your API key from: ${CYAN}$SIGNUP_URL${NC}"
|
||||
echo ""
|
||||
read -r -p "Paste your $PROVIDER_NAME API key (or press Enter to skip): " API_KEY
|
||||
fi
|
||||
|
||||
if [ -n "$API_KEY" ]; then
|
||||
echo "" >> "$SHELL_RC_FILE"
|
||||
echo "# Hive Agent Framework - $PROVIDER_NAME API key" >> "$SHELL_RC_FILE"
|
||||
echo "export $SELECTED_ENV_VAR=\"$API_KEY\"" >> "$SHELL_RC_FILE"
|
||||
export "$SELECTED_ENV_VAR=$API_KEY"
|
||||
echo ""
|
||||
echo -e "${GREEN}⬢${NC} API key saved to $SHELL_RC_FILE"
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}Skipped.${NC} Add your API key to $SHELL_RC_FILE when ready."
|
||||
SELECTED_ENV_VAR=""
|
||||
SELECTED_PROVIDER_ID=""
|
||||
fi
|
||||
if [ -n "$API_KEY" ]; then
|
||||
# Remove old export line(s) for this env var from shell rc, then append new
|
||||
sed -i.bak "/^export ${SELECTED_ENV_VAR}=/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
echo "" >> "$SHELL_RC_FILE"
|
||||
echo "# Hive Agent Framework - $PROVIDER_NAME API key" >> "$SHELL_RC_FILE"
|
||||
echo "export $SELECTED_ENV_VAR=\"$API_KEY\"" >> "$SHELL_RC_FILE"
|
||||
export "$SELECTED_ENV_VAR=$API_KEY"
|
||||
echo ""
|
||||
echo -e "${GREEN}⬢${NC} API key saved to $SHELL_RC_FILE"
|
||||
# Health check the new key
|
||||
echo -n " Verifying API key... "
|
||||
HC_RESULT=$(uv run python "$SCRIPT_DIR/scripts/check_llm_key.py" "$SELECTED_PROVIDER_ID" "$API_KEY" 2>/dev/null) || true
|
||||
HC_VALID=$(echo "$HC_RESULT" | $PYTHON_CMD -c "import json,sys; print(json.loads(sys.stdin.read()).get('valid',''))" 2>/dev/null) || true
|
||||
HC_MSG=$(echo "$HC_RESULT" | $PYTHON_CMD -c "import json,sys; print(json.loads(sys.stdin.read()).get('message',''))" 2>/dev/null) || true
|
||||
if [ "$HC_VALID" = "True" ]; then
|
||||
echo -e "${GREEN}ok${NC}"
|
||||
break
|
||||
elif [ "$HC_VALID" = "False" ]; then
|
||||
echo -e "${RED}failed${NC}"
|
||||
echo -e " ${YELLOW}⚠ $HC_MSG${NC}"
|
||||
# Undo the save so the user can retry cleanly
|
||||
sed -i.bak "/^export ${SELECTED_ENV_VAR}=/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
# Remove the comment line we just added
|
||||
sed -i.bak "/^# Hive Agent Framework - $PROVIDER_NAME API key$/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
unset "$SELECTED_ENV_VAR"
|
||||
echo ""
|
||||
read -r -p " Press Enter to try again: " _
|
||||
# Loop back to key prompt
|
||||
else
|
||||
echo -e "${YELLOW}--${NC}"
|
||||
echo -e " ${DIM}Could not verify key (network issue). The key has been saved.${NC}"
|
||||
break
|
||||
fi
|
||||
elif [ -z "$CURRENT_KEY" ]; then
|
||||
# No existing key and user skipped — abort provider
|
||||
echo ""
|
||||
echo -e "${YELLOW}Skipped.${NC} Add your API key to $SHELL_RC_FILE when ready."
|
||||
SELECTED_ENV_VAR=""
|
||||
SELECTED_PROVIDER_ID=""
|
||||
break
|
||||
else
|
||||
# User pressed Enter with existing key — keep it, proceed normally
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# For ZAI subscription: always prompt for API key
|
||||
# For ZAI subscription: prompt for API key (allow replacement if already set)
|
||||
if [ "$SUBSCRIPTION_MODE" = "zai_code" ]; then
|
||||
echo ""
|
||||
read -r -p "Paste your ZAI API key (or press Enter to skip): " API_KEY
|
||||
while true; do
|
||||
if [ "$ZAI_CRED_DETECTED" = true ] && [ -n "$ZAI_API_KEY" ]; then
|
||||
# Key exists — offer to keep or replace
|
||||
MASKED_KEY="${ZAI_API_KEY:0:4}...${ZAI_API_KEY: -4}"
|
||||
echo ""
|
||||
echo -e " ${GREEN}⬢${NC} Current ZAI key: ${DIM}$MASKED_KEY${NC}"
|
||||
read -r -p " Press Enter to keep, or paste a new key to replace: " API_KEY
|
||||
else
|
||||
# No key — prompt for one
|
||||
echo ""
|
||||
read -r -p "Paste your ZAI API key (or press Enter to skip): " API_KEY
|
||||
fi
|
||||
|
||||
if [ -n "$API_KEY" ]; then
|
||||
echo "" >> "$SHELL_RC_FILE"
|
||||
echo "# Hive Agent Framework - ZAI Code subscription API key" >> "$SHELL_RC_FILE"
|
||||
echo "export ZAI_API_KEY=\"$API_KEY\"" >> "$SHELL_RC_FILE"
|
||||
export ZAI_API_KEY="$API_KEY"
|
||||
echo ""
|
||||
echo -e "${GREEN}⬢${NC} ZAI API key saved to $SHELL_RC_FILE"
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}Skipped.${NC} Add your ZAI API key to $SHELL_RC_FILE when ready:"
|
||||
echo -e " ${CYAN}echo 'export ZAI_API_KEY=\"your-key\"' >> $SHELL_RC_FILE${NC}"
|
||||
SELECTED_ENV_VAR=""
|
||||
SELECTED_PROVIDER_ID=""
|
||||
SUBSCRIPTION_MODE=""
|
||||
fi
|
||||
if [ -n "$API_KEY" ]; then
|
||||
sed -i.bak "/^export ZAI_API_KEY=/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
echo "" >> "$SHELL_RC_FILE"
|
||||
echo "# Hive Agent Framework - ZAI Code subscription API key" >> "$SHELL_RC_FILE"
|
||||
echo "export ZAI_API_KEY=\"$API_KEY\"" >> "$SHELL_RC_FILE"
|
||||
export ZAI_API_KEY="$API_KEY"
|
||||
echo ""
|
||||
echo -e "${GREEN}⬢${NC} ZAI API key saved to $SHELL_RC_FILE"
|
||||
# Health check the new key
|
||||
echo -n " Verifying ZAI API key... "
|
||||
HC_RESULT=$(uv run python "$SCRIPT_DIR/scripts/check_llm_key.py" "zai" "$API_KEY" "https://api.z.ai/api/coding/paas/v4" 2>/dev/null) || true
|
||||
HC_VALID=$(echo "$HC_RESULT" | $PYTHON_CMD -c "import json,sys; print(json.loads(sys.stdin.read()).get('valid',''))" 2>/dev/null) || true
|
||||
HC_MSG=$(echo "$HC_RESULT" | $PYTHON_CMD -c "import json,sys; print(json.loads(sys.stdin.read()).get('message',''))" 2>/dev/null) || true
|
||||
if [ "$HC_VALID" = "True" ]; then
|
||||
echo -e "${GREEN}ok${NC}"
|
||||
break
|
||||
elif [ "$HC_VALID" = "False" ]; then
|
||||
echo -e "${RED}failed${NC}"
|
||||
echo -e " ${YELLOW}⚠ $HC_MSG${NC}"
|
||||
# Undo the save so the user can retry cleanly
|
||||
sed -i.bak "/^export ZAI_API_KEY=/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
sed -i.bak "/^# Hive Agent Framework - ZAI Code subscription API key$/d" "$SHELL_RC_FILE" && rm -f "${SHELL_RC_FILE}.bak"
|
||||
unset ZAI_API_KEY
|
||||
ZAI_CRED_DETECTED=false
|
||||
echo ""
|
||||
read -r -p " Press Enter to try again: " _
|
||||
# Loop back to key prompt
|
||||
else
|
||||
echo -e "${YELLOW}--${NC}"
|
||||
echo -e " ${DIM}Could not verify key (network issue). The key has been saved.${NC}"
|
||||
break
|
||||
fi
|
||||
elif [ "$ZAI_CRED_DETECTED" = false ] || [ -z "$ZAI_API_KEY" ]; then
|
||||
# No existing key and user skipped — abort provider
|
||||
echo ""
|
||||
echo -e "${YELLOW}Skipped.${NC} Add your ZAI API key to $SHELL_RC_FILE when ready:"
|
||||
echo -e " ${CYAN}echo 'export ZAI_API_KEY=\"your-key\"' >> $SHELL_RC_FILE${NC}"
|
||||
SELECTED_ENV_VAR=""
|
||||
SELECTED_PROVIDER_ID=""
|
||||
SUBSCRIPTION_MODE=""
|
||||
break
|
||||
else
|
||||
# User pressed Enter with existing key — keep it, proceed normally
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Prompt for model if not already selected (manual provider path)
|
||||
@@ -1037,52 +1210,22 @@ fi
|
||||
echo ""
|
||||
|
||||
# ============================================================
|
||||
# Step 4b: Browser Automation (GCU)
|
||||
# Step 4b: Browser Automation (GCU) — always enabled
|
||||
# ============================================================
|
||||
|
||||
echo -e "${BOLD}Enable browser automation?${NC}"
|
||||
echo -e "${DIM}This lets your agents control a real browser — navigate websites, fill forms,${NC}"
|
||||
echo -e "${DIM}scrape dynamic pages, and interact with web UIs.${NC}"
|
||||
echo ""
|
||||
echo -e " ${CYAN}${BOLD}1)${NC} ${BOLD}Yes${NC}"
|
||||
echo -e " ${CYAN}2)${NC} No"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
read -r -p "Enter choice (1-2, default 1): " gcu_choice || true
|
||||
gcu_choice="${gcu_choice:-1}"
|
||||
if [ "$gcu_choice" = "1" ] || [ "$gcu_choice" = "2" ]; then
|
||||
break
|
||||
fi
|
||||
echo -e "${RED}Invalid choice. Please enter 1 or 2${NC}"
|
||||
done
|
||||
|
||||
if [ "$gcu_choice" = "1" ]; then
|
||||
GCU_ENABLED=true
|
||||
echo -e "${GREEN}⬢${NC} Browser automation enabled"
|
||||
else
|
||||
GCU_ENABLED=false
|
||||
echo -e "${DIM}⬡ Browser automation skipped${NC}"
|
||||
fi
|
||||
echo -e "${GREEN}⬢${NC} Browser automation enabled"
|
||||
|
||||
# Patch gcu_enabled into configuration.json
|
||||
if [ "$GCU_ENABLED" = "true" ]; then
|
||||
GCU_PY_VAL="True"
|
||||
else
|
||||
GCU_PY_VAL="False"
|
||||
fi
|
||||
|
||||
if [ -f "$HIVE_CONFIG_FILE" ]; then
|
||||
uv run python -c "
|
||||
import json
|
||||
with open('$HIVE_CONFIG_FILE') as f:
|
||||
config = json.load(f)
|
||||
config['gcu_enabled'] = $GCU_PY_VAL
|
||||
config['gcu_enabled'] = True
|
||||
with open('$HIVE_CONFIG_FILE', 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
"
|
||||
elif [ "$GCU_ENABLED" = "true" ]; then
|
||||
# No config file yet (user skipped LLM provider) — create minimal one
|
||||
else
|
||||
mkdir -p "$HIVE_CONFIG_DIR"
|
||||
uv run python -c "
|
||||
import json
|
||||
@@ -1318,9 +1461,10 @@ if [ "$FRONTEND_BUILT" = true ]; then
|
||||
echo -e " ${DIM}Starting server on http://localhost:8787${NC}"
|
||||
echo -e " ${DIM}Press Ctrl+C to stop${NC}"
|
||||
echo ""
|
||||
# exec replaces the quickstart process with hive serve
|
||||
# --open tells it to auto-open the browser once the server is ready
|
||||
exec "$SCRIPT_DIR/hive" serve --open
|
||||
echo -e " ${DIM}Tip: You can restart the dashboard anytime with:${NC} ${CYAN}hive open${NC}"
|
||||
echo ""
|
||||
# exec replaces the quickstart process with hive open
|
||||
exec "$SCRIPT_DIR/hive" open
|
||||
else
|
||||
# No frontend — show manual instructions
|
||||
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
|
||||
Reference in New Issue
Block a user