feat(mimo): add ai-mimo launcher for Xiaomi MiMo V2.6 Pro
ai-mimo runs Claude Code through Xiaomi's Anthropic-compatible API (Token Plan or pay-as-you-go). The key's endpoint is found by probing token-plan-sgp, token-plan-ams and api.xiaomimimo.com (a key only works in its own region) and is saved to mimo_base_url; MIMO_BASE_URL overrides. Unreachable endpoints are skipped, token-plan-cn is left out of the probe since it times out from our network, and a 402 on the pay-as-you-go endpoint explains that a tp- Token Plan key is needed. Always the smartest model: mimo-v2.6-pro in every slot and for subagents, --model opus and --effort max on each start, 128000 output tokens (Claude Code's ceiling), real 1M context window. Measured on 13.10: MiMo ignores output_config.effort (even "bogus" is accepted, no length trend from low to max) and treats thinking adaptive like enabled, so reasoning is always on; EFFORT_MAPPING.md records this. /logout-mimo is registered as a command and handled by the logout hook (removes mimo_key and mimo_base_url). setup.sh status, statusline brand color, README, QUICK_START and AGENTS.md list the new launcher. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ KIMI_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-kimi"/,/^KIMIEOF/' "$SCRIPT")
|
||||
GLM_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-glm"/,/^GLMEOF/' "$SCRIPT")
|
||||
ELTEX_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-eltex"/,/^ELTEXEOF/' "$SCRIPT")
|
||||
ELTEX_QWEN_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-eltex-qwen"/,/^ELTEXQWENEOF/' "$SCRIPT")
|
||||
MIMO_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-mimo"/,/^MIMOEOF/' "$SCRIPT")
|
||||
LOGOUT_HOOK="$(cd "$(dirname "$0")/.." && pwd)/home-configs/claude/hooks/logout-account-hook.sh"
|
||||
GEMINI_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-gemini"/,/^GEMINIEOF/' "$SCRIPT")
|
||||
OPENCODE_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-opencode"/,/^OPENCODEEOF/' "$SCRIPT")
|
||||
@@ -230,6 +231,117 @@ test_logout_eltex() {
|
||||
rm -rf "$tmp_home"
|
||||
}
|
||||
|
||||
# ── ai-mimo: Claude Code через Xiaomi MiMo V2.6 ───────────────────────────
|
||||
test_mimo_launcher() {
|
||||
if echo "$MIMO_SECTION" | grep -q 'claude --dangerously-skip-permissions' \
|
||||
&& echo "$MIMO_SECTION" | grep -q 'key_file="$HOME/.config/ai-setup/mimo_key"' \
|
||||
&& echo "$MIMO_SECTION" | grep -q 'CLAUDE_CONFIG_DIR="$HOME/.config/ai-setup/cfg/mimo"' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^ANTHROPIC_BASE_URL="$mimo_base_url"' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^ANTHROPIC_DEFAULT_OPUS_MODEL=mimo-v2.6-pro' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^ANTHROPIC_DEFAULT_SONNET_MODEL=mimo-v2.6-pro' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^ANTHROPIC_DEFAULT_HAIKU_MODEL=mimo-v2.6-pro' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^CLAUDE_CODE_SUBAGENT_MODEL=mimo-v2.6-pro' \
|
||||
&& echo "$MIMO_SECTION" | grep -q -- 'claude --dangerously-skip-permissions --model opus ' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^CLAUDE_CODE_MAX_OUTPUT_TOKENS=128000' \
|
||||
&& echo "$MIMO_SECTION" | grep -q '^CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000' \
|
||||
&& ! echo "$MIMO_SECTION" | grep -q '^CLAUDE_CODE_DISABLE_1M_CONTEXT=' \
|
||||
&& echo "$MIMO_SECTION" | grep -q 'cat > "$CLAUDE_CONFIG_DIR/commands/logout-mimo.md"'; then
|
||||
ok "ai-mimo: own key/config, Pro in every slot and subagents, --model opus, 128000 output, 1M window, /logout-mimo"
|
||||
else
|
||||
fail "ai-mimo: must use mimo_key, cfg/mimo, mimo-v2.6-pro everywhere, --model opus, 128000 output, 1M window and logout-mimo.md"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── ai-mimo: эндпоинт региона Token Plan находится перебором и запоминается ──
|
||||
test_mimo_region_probe() {
|
||||
local tmp ok_run=1
|
||||
tmp=$(mktemp -d)
|
||||
mkdir -p "$tmp/bin" "$tmp/mock" "$tmp/home"
|
||||
echo "$HELPERS_SECTION" | HELPERS_FILE="$tmp/bin/ai-api-helpers.sh" bash
|
||||
echo "$MIMO_SECTION" | BIN_DIR="$tmp/bin" bash
|
||||
# Ключ подходит только к региону ams, sgp недоступен по сети (как curl: -w печатает
|
||||
# 000 и exit 28), остальные эндпоинты отвечают 401. MOCK_DOWN=1 - сети нет совсем.
|
||||
cat > "$tmp/mock/curl" <<CURLEOF
|
||||
#!/usr/bin/env bash
|
||||
for a in "\$@"; do
|
||||
case "\$a" in
|
||||
https://*) echo "\$a" >> "$tmp/curl.log" ;;
|
||||
esac
|
||||
case "\$a" in
|
||||
https://*) [ -n "\${MOCK_DOWN:-}" ] && { printf '\n000'; exit 28; } ;;
|
||||
esac
|
||||
case "\$a" in
|
||||
https://api.xiaomimimo.com/*) [ -n "\${MOCK_SK:-}" ] && { printf '{"error":{"message":"Insufficient account balance"}}\n402'; exit 0; } ;;
|
||||
https://token-plan-*) [ -n "\${MOCK_SK:-}" ] && { printf '{"error":{"message":"invalid api key"}}\n401'; exit 0; } ;;
|
||||
esac
|
||||
case "\$a" in
|
||||
https://token-plan-sgp.xiaomimimo.com/*) printf '\n000'; exit 28 ;;
|
||||
https://token-plan-ams.xiaomimimo.com/*) printf '{"content":[]}\n200'; exit 0 ;;
|
||||
https://*) printf '{"error":{"message":"invalid api key"}}\n401'; exit 0 ;;
|
||||
esac
|
||||
done
|
||||
CURLEOF
|
||||
printf '#!/usr/bin/env bash\necho "$ANTHROPIC_BASE_URL" > "%s/claude.url"\n' "$tmp" > "$tmp/mock/claude"
|
||||
chmod +x "$tmp/mock/curl" "$tmp/mock/claude"
|
||||
_run_mimo() {
|
||||
(cd "$tmp" && printf 'tp-test\n' | HOME="$tmp/home" PATH="$tmp/mock:$PATH" \
|
||||
MIMO_BASE_URL= AI_RESET_KEY= AI_EFFORT= bash "$tmp/bin/ai-mimo" >/dev/null 2>&1)
|
||||
}
|
||||
local ams=https://token-plan-ams.xiaomimimo.com/anthropic
|
||||
_run_mimo || ok_run=0
|
||||
[ "$(cat "$tmp/claude.url" 2>/dev/null)" = "$ams" ] || ok_run=0
|
||||
[ "$(cat "$tmp/home/.config/ai-setup/mimo_base_url" 2>/dev/null)" = "$ams" ] || ok_run=0
|
||||
[ "$(cat "$tmp/home/.config/ai-setup/mimo_key" 2>/dev/null)" = "tp-test" ] || ok_run=0
|
||||
# Повторный запуск: сохранённый эндпоинт, без перебора регионов.
|
||||
rm -f "$tmp/curl.log" "$tmp/claude.url"
|
||||
_run_mimo || ok_run=0
|
||||
[ "$(cat "$tmp/curl.log" 2>/dev/null)" = "$ams/v1/messages" ] || ok_run=0
|
||||
[ "$(cat "$tmp/claude.url" 2>/dev/null)" = "$ams" ] || ok_run=0
|
||||
# Без сети: ключ не сохраняется и Claude Code не запускается с пустым эндпоинтом.
|
||||
rm -rf "$tmp/home" "$tmp/claude.url"
|
||||
MOCK_DOWN=1 _run_mimo && ok_run=0
|
||||
[ ! -e "$tmp/claude.url" ] && [ ! -e "$tmp/home/.config/ai-setup/mimo_key" ] || ok_run=0
|
||||
# Ключ pay-as-you-go без баланса: Token Plan отвечает 401, api.xiaomimimo.com - 402,
|
||||
# нужна подсказка про ключ tp-...
|
||||
rm -rf "$tmp/home"
|
||||
local out
|
||||
out=$(cd "$tmp" && printf 'sk-test\n' | HOME="$tmp/home" PATH="$tmp/mock:$PATH" MOCK_SK=1 \
|
||||
MIMO_BASE_URL= AI_RESET_KEY= AI_EFFORT= bash "$tmp/bin/ai-mimo" 2>&1) && ok_run=0
|
||||
echo "$out" | grep -q 'Dedicated API Key' || ok_run=0
|
||||
[ ! -e "$tmp/claude.url" ] && [ ! -e "$tmp/home/.config/ai-setup/mimo_key" ] || ok_run=0
|
||||
if [ "$ok_run" -eq 1 ]; then
|
||||
ok "ai-mimo: finds the Token Plan region by probing (skips unreachable), saves and reuses it"
|
||||
else
|
||||
fail "ai-mimo: region probe must skip unreachable regions, pick the one that accepts the key and reuse it"
|
||||
fi
|
||||
rm -rf "$tmp"
|
||||
}
|
||||
|
||||
# ── ai-mimo: effort max по умолчанию через CLI (MiMo effort игнорирует) ────
|
||||
test_mimo_effort() {
|
||||
if echo "$MIMO_SECTION" | grep -q -- '--effort "${AI_EFFORT:-max}"' \
|
||||
&& ! echo "$MIMO_SECTION" | grep -q '^_apply_effort'; then
|
||||
ok "ai-mimo: starts with --effort max by default, AI_EFFORT via CLI"
|
||||
else
|
||||
fail "ai-mimo: must start with --effort \"\${AI_EFFORT:-max}\", no _apply_effort"
|
||||
fi
|
||||
}
|
||||
|
||||
test_logout_mimo() {
|
||||
local tmp_home rc=0
|
||||
tmp_home=$(mktemp -d)
|
||||
mkdir -p "$tmp_home/.config/ai-setup"
|
||||
echo "tp-test" > "$tmp_home/.config/ai-setup/mimo_key"
|
||||
echo "https://token-plan-ams.xiaomimimo.com/anthropic" > "$tmp_home/.config/ai-setup/mimo_base_url"
|
||||
echo '{"prompt":"/logout-mimo"}' | HOME="$tmp_home" AI_LAUNCHER=claude bash "$LOGOUT_HOOK" 2>/dev/null || rc=$?
|
||||
if [ "$rc" -eq 2 ] && [ ! -f "$tmp_home/.config/ai-setup/mimo_key" ] && [ ! -f "$tmp_home/.config/ai-setup/mimo_base_url" ]; then
|
||||
ok "logout hook: /logout-mimo removes mimo_key and mimo_base_url"
|
||||
else
|
||||
fail "logout hook: /logout-mimo must remove mimo_key and mimo_base_url (rc=$rc)"
|
||||
fi
|
||||
rm -rf "$tmp_home"
|
||||
}
|
||||
|
||||
# ── ai-glm: default effort is max (still overridable via AI_EFFORT) ───────
|
||||
test_glm_default_effort() {
|
||||
if echo "$GLM_SECTION" | grep -q -- '--effort "${AI_EFFORT:-max}"' \
|
||||
@@ -449,6 +561,10 @@ test_eltex_qwen_effort
|
||||
test_logout_eltex
|
||||
test_eltex_qwen_launcher
|
||||
test_logout_eltex_qwen
|
||||
test_mimo_launcher
|
||||
test_mimo_region_probe
|
||||
test_mimo_effort
|
||||
test_logout_mimo
|
||||
test_gemini_native_launcher
|
||||
test_cursor_native_launcher
|
||||
test_global_rules_source_installed
|
||||
|
||||
Reference in New Issue
Block a user