feat: добавить ai-glm - лаунчер Claude Code через Zhipu AI GLM 5.2
Новый лаунчер ai-glm запускает Claude Code через официальный Anthropic-совместимый API Zhipu AI (api.z.ai). Модели: glm-5.2 (opus/sonnet), glm-5.2[1m] (haiku). Обновлены документация, статус, тесты и EFFORT_MAPPING. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,4 +2,4 @@
|
||||
|
||||
Данные правила применяются ко всем агентам, работающим конкретно в этом репозитории.
|
||||
|
||||
1. **Полная перегенерация standalone-скриптов при запуске сетап-скрипта (Full regeneration of standalone scripts on setup run):** При каждом запуске `ai-setup.sh` все генерируемые скрипты в выбранном `BIN_DIR` (`~/bin`, если он уже есть в `PATH`, иначе `~/.local/bin`: `ai-gpt`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`, `ai-gemini`, `ai-api-helpers.sh`, `ai-claude`, `claude-gpt-effort-proxy.py`) должны быть **полностью перезаписаны** актуальными версиями. Запрещено выполнять слияние (merge) старого и нового содержимого или дополнение (append). Скрипт обязан привести все генерируемые файлы к эталонному виду, однозначно определяемому текущей конфигурацией.
|
||||
1. **Полная перегенерация standalone-скриптов при запуске сетап-скрипта (Full regeneration of standalone scripts on setup run):** При каждом запуске `ai-setup.sh` все генерируемые скрипты в выбранном `BIN_DIR` (`~/bin`, если он уже есть в `PATH`, иначе `~/.local/bin`: `ai-gpt`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`, `ai-gemini`, `ai-api-helpers.sh`, `ai-claude`, `claude-gpt-effort-proxy.py`) должны быть **полностью перезаписаны** актуальными версиями. Запрещено выполнять слияние (merge) старого и нового содержимого или дополнение (append). Скрипт обязан привести все генерируемые файлы к эталонному виду, однозначно определяемому текущей конфигурацией.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Как это работает
|
||||
|
||||
`/effort` и `AI_EFFORT` относятся к лаунчерам, которые запускают Claude Code:
|
||||
`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`.
|
||||
`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`.
|
||||
|
||||
Нативные лаунчеры `ai-gpt` (OpenAI Codex) и `ai-gemini` (Antigravity `agy`) не используют
|
||||
эту схему. У них свои настройки reasoning внутри соответствующего CLI.
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
## Таблица маппинга
|
||||
|
||||
| Claude Code `/effort` | Anthropic (`ai-claude`) | DeepSeek V4 (`ai-deepseek`) | Kimi K2.7/K2.6 (`ai-kimi`) | OpenRouter/GPT-5.5 (`ai-openrouter`) |
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
| `low` | нативно `low` | провайдер поднимает до `high` | thinking on | без локального маппинга |
|
||||
| `medium` | нативно `medium` | провайдер поднимает до `high` | thinking on | без локального маппинга |
|
||||
| `high` | нативно `high` | нативно `high` | thinking on | без локального маппинга |
|
||||
| `xhigh` | нативно `xhigh` | провайдер поднимает до `max` | thinking on | без локального маппинга |
|
||||
| `max` | нативно `max` | нативно `max` | thinking on | без локального маппинга |
|
||||
| Claude Code `/effort` | Anthropic (`ai-claude`) | DeepSeek V4 (`ai-deepseek`) | Kimi K2.7/K2.6 (`ai-kimi`) | GLM 5.2 (`ai-glm`) | OpenRouter/GPT-5.5 (`ai-openrouter`) |
|
||||
|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| `low` | нативно `low` | провайдер поднимает до `high` | thinking on | на стороне сервера | без локального маппинга |
|
||||
| `medium` | нативно `medium` | провайдер поднимает до `high` | thinking on | на стороне сервера | без локального маппинга |
|
||||
| `high` | нативно `high` | нативно `high` | thinking on | на стороне сервера | без локального маппинга |
|
||||
| `xhigh` | нативно `xhigh` | провайдер поднимает до `max` | thinking on | на стороне сервера | без локального маппинга |
|
||||
| `max` | нативно `max` | нативно `max` | thinking on | на стороне сервера | без локального маппинга |
|
||||
|
||||
Для OpenRouter текущий лаунчер не делает локального преобразования effort и отправляет
|
||||
значение дальше через Claude Code/OpenRouter. Конкретная интерпретация зависит от выбранной
|
||||
@@ -59,6 +59,16 @@ on / off
|
||||
- Градаций глубины reasoning нет.
|
||||
- Дефолт `ai-kimi`: `high`.
|
||||
|
||||
### GLM 5.2 (Zhipu AI)
|
||||
|
||||
```text
|
||||
high / max
|
||||
```
|
||||
|
||||
- Маппинг выполняется на стороне Zhipu AI API.
|
||||
- Текущий `ai-glm` не делает локального преобразования effort.
|
||||
- Дефолт `ai-glm`: `high`.
|
||||
|
||||
### OpenRouter / GPT-5.5
|
||||
|
||||
Текущий `ai-openrouter` работает через Claude Code с `ANTHROPIC_BASE_URL=https://openrouter.ai/api`
|
||||
@@ -76,12 +86,13 @@ on / off
|
||||
| Anthropic | Не нужен | - |
|
||||
| DeepSeek V4 | DeepSeek API | На стороне сервера |
|
||||
| Kimi K2.7/K2.6 | Moonshot API | На стороне сервера |
|
||||
| GLM 5.2 | Zhipu AI API | На стороне сервера |
|
||||
| OpenRouter/GPT-5.5 | Локального маппинга нет | `ai-openrouter` отправляет значение как есть |
|
||||
| Legacy GPT proxy | helper-маппинг `xhigh` -> `high` | `~/bin/claude-gpt-effort-proxy.py` или `~/.local/bin/claude-gpt-effort-proxy.py` |
|
||||
|
||||
## Persistence effort между сессиями
|
||||
|
||||
Каждый Claude Code лаунчер (`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`)
|
||||
Каждый Claude Code лаунчер (`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`)
|
||||
запоминает свой уровень effort отдельно в `settings.json` лаунчера.
|
||||
|
||||
`/effort` внутри сессии работает для всех уровней. `CLAUDE_CODE_EFFORT_LEVEL` не используется.
|
||||
@@ -99,5 +110,5 @@ ai-deepseek # без флага - использовать ур
|
||||
## Рекомендации
|
||||
|
||||
- Для повседневной работы: `high` или `xhigh`.
|
||||
- `max` effort имеет реальный эффект у Anthropic и DeepSeek; у Kimi это все тот же thinking on.
|
||||
- `low`/`medium` у DeepSeek и Kimi фактически не снижают reasoning.
|
||||
- `max` effort имеет реальный эффект у Anthropic и DeepSeek; у Kimi и GLM это всё тот же thinking on / маппинг на стороне сервера.
|
||||
- `low`/`medium` у DeepSeek, Kimi и GLM фактически не снижают reasoning.
|
||||
|
||||
@@ -7,7 +7,7 @@ bash setup.sh
|
||||
```
|
||||
|
||||
Спросит про VLESS-прокси (по умолчанию `Y`; если не нужен, ответь `n`), затем установит лаунчеры
|
||||
`ai-claude`, `ai-gpt`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`, `ai-gemini`
|
||||
`ai-claude`, `ai-gpt`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`, `ai-gemini`
|
||||
в `~/bin`, если он уже есть в `PATH`, иначе в `~/.local/bin/`, и запишет API-ключи.
|
||||
|
||||
После установки, если команды не видны:
|
||||
|
||||
10
README.md
10
README.md
@@ -29,7 +29,7 @@ home-configs/
|
||||
tests/
|
||||
├── test_fixes.sh # юнит-тесты структуры ai-setup.sh
|
||||
└── test_network.sh # тесты маршрутизации
|
||||
test_isolated.sh # проверка автоустановки ai-gpt и ai-kimi
|
||||
test_isolated.sh # проверка автоустановки ai-gpt, ai-kimi и ai-glm
|
||||
test_sigint.sh # ручной тест поведения SIGINT
|
||||
```
|
||||
|
||||
@@ -157,6 +157,7 @@ bash tests/test_network.sh # полные тесты
|
||||
- `ai-gpt` - нативный OpenAI Codex CLI
|
||||
- `ai-deepseek` - Claude Code через DeepSeek API
|
||||
- `ai-kimi` - Claude Code через официальный Kimi Code API (`api.kimi.com/coding`)
|
||||
- `ai-glm` - Claude Code через Zhipu AI GLM 5.2 API (`api.z.ai/api/anthropic`)
|
||||
- `ai-openrouter` - Claude Code через OpenRouter (GPT-5.5, Grok, Qwen, MiniMax, Llama и др.)
|
||||
- `ai-gemini` - нативный Antigravity CLI `agy`
|
||||
- `ai-api-helpers.sh` - вспомогательные функции для лаунчеров
|
||||
@@ -226,6 +227,7 @@ android init
|
||||
|
||||
- `~/.config/ai-setup/deepseek_key` - DeepSeek API key (права 600)
|
||||
- `~/.config/ai-setup/kimi_key` - Kimi API key (права 600)
|
||||
- `~/.config/ai-setup/glm_key` - Zhipu AI (GLM) API key (права 600)
|
||||
- `~/.config/ai-setup/openrouter_key` - OpenRouter API key (права 600)
|
||||
- `~/.config/ai-setup/global_rules.md` - глобальные правила агентов
|
||||
- `~/.config/ai-setup/network_<profile>.conf` - сохранённые сетевые профили (`GATEWAY`, `DEV`, `LOCAL_DNS`, `AMNEZIA_SERVER`, `KILL_SWITCH_EXCEPTIONS`)
|
||||
@@ -233,7 +235,7 @@ android init
|
||||
## Права запуска агентов
|
||||
|
||||
- `ai-gpt` использует `--dangerously-bypass-approvals-and-sandbox`
|
||||
- `ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`, `ai-gemini` используют `--dangerously-skip-permissions`
|
||||
- `ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`, `ai-gemini` используют `--dangerously-skip-permissions`
|
||||
|
||||
Удобно для локального coding workflow, но это не sandbox для недоверенного кода.
|
||||
|
||||
@@ -248,7 +250,7 @@ Surgical Changes, Goal-Driven Execution) плюс пользовательски
|
||||
## Effort Mapping
|
||||
|
||||
`EFFORT_MAPPING.md` - таблица effort-уровней (`low`/`medium`/`high`/`xhigh`/`max`)
|
||||
для Claude Code лаунчеров (`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-openrouter`).
|
||||
для Claude Code лаунчеров (`ai-claude`, `ai-deepseek`, `ai-kimi`, `ai-glm`, `ai-openrouter`).
|
||||
Нативные `ai-gpt` и `ai-gemini` живут отдельно.
|
||||
|
||||
`claude-gpt-effort-proxy.py` маппит `xhigh` -> `high` для совместимости со старым
|
||||
@@ -266,7 +268,7 @@ GPT/claude-code-proxy backend; текущие лаунчеры его напря
|
||||
|
||||
```bash
|
||||
bash tests/test_fixes.sh # структура ai-setup.sh и синтаксис bash
|
||||
bash test_isolated.sh # автоустановка ai-gpt и ai-kimi через mock curl
|
||||
bash test_isolated.sh # автоустановка ai-gpt, ai-kimi и ai-glm через mock curl
|
||||
bash tests/test_network.sh # маршрутизация (нужен активный ru-bypass)
|
||||
# test_sigint.sh # ручной диагностический тест SIGINT
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================
|
||||
# AI Setup - Claude / GPT-5.5 / Grok / Qwen / DeepSeek / Kimi / MiniMax / Llama / Gemini
|
||||
# AI Setup - Claude / GPT-5.5 / Grok / Qwen / DeepSeek / Kimi / GLM / MiniMax / Llama / Gemini
|
||||
# Запуск: bash ai-setup.sh
|
||||
# ============================================================
|
||||
|
||||
@@ -1687,6 +1687,95 @@ done
|
||||
KIMIEOF
|
||||
chmod +x "$BIN_DIR/ai-kimi"
|
||||
|
||||
# === ai-glm ===
|
||||
cat > "$BIN_DIR/ai-glm" << 'GLMEOF'
|
||||
#!/usr/bin/env bash
|
||||
# ai-glm - запуск Claude Code через Zhipu AI GLM 5.2 (Anthropic-compatible API)
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/ai-api-helpers.sh" 2>/dev/null || true
|
||||
|
||||
key_file="$HOME/.config/ai-setup/glm_key"
|
||||
api_key=""
|
||||
reauth=0
|
||||
|
||||
[ -f "$key_file" ] && api_key=$(cat "$key_file")
|
||||
|
||||
# Endpoint: international Z.AI по умолчанию, можно переопределить через GLM_BASE_URL.
|
||||
glm_base_url="${GLM_BASE_URL:-https://api.z.ai/api/anthropic}"
|
||||
|
||||
if [ -n "$api_key" ]; then
|
||||
echo -n "Проверка сохранённого GLM ключа... "
|
||||
_claude_test_api "$glm_base_url/v1/messages" "x-api-key: $api_key" "glm-5.2"
|
||||
_handle_api_response "GLM" "$_CLAUDE_TEST_CODE" "$_CLAUDE_TEST_BODY" "Пополните баланс: https://z.ai/manage-apikey/apikey-list"
|
||||
ret=$_API_RET
|
||||
if [ $ret -eq 401 ]; then
|
||||
rm -f "$key_file"
|
||||
api_key=""
|
||||
reauth=1
|
||||
elif [ $ret -eq 429 ]; then
|
||||
echo -n "Продолжить всё равно? (запросы могут не проходить) [y/N] "
|
||||
read -r _ans; case "${_ans:-N}" in [Yy]*) ;; *) exit 1 ;; esac
|
||||
elif [ $ret -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$api_key" ] && [ "$reauth" -eq 1 ]; then
|
||||
echo -n "Хотите ввести новый GLM ключ? [Y/n] "
|
||||
read -r _ans; case "${_ans:-Y}" in [Yy]*) ;; *) exit 1 ;; esac
|
||||
fi
|
||||
|
||||
if [ -z "$api_key" ]; then
|
||||
echo "Получить ключ: https://z.ai/manage-apikey/apikey-list"
|
||||
read -r -p "Введите ваш Zhipu AI (GLM) API ключ: " api_key
|
||||
[ -z "$api_key" ] && { echo "Выход."; exit 1; }
|
||||
|
||||
echo -n "Проверяю ключ... "
|
||||
_claude_test_api "$glm_base_url/v1/messages" "x-api-key: $api_key" "glm-5.2"
|
||||
_handle_api_response "GLM" "$_CLAUDE_TEST_CODE" "$_CLAUDE_TEST_BODY" "Пополните баланс: https://z.ai/manage-apikey/apikey-list"
|
||||
ret=$_API_RET
|
||||
if [ $ret -eq 0 ] || [ $ret -eq 429 ]; then
|
||||
mkdir -p "$(dirname "$key_file")"
|
||||
echo "$api_key" > "$key_file"
|
||||
chmod 600 "$key_file"
|
||||
echo "Ключ сохранён."
|
||||
if [ $ret -eq 429 ]; then
|
||||
echo -n "Продолжить всё равно? (запросы могут не проходить) [y/N] "
|
||||
read -r _ans; case "${_ans:-N}" in [Yy]*) ;; *) exit 1 ;; esac
|
||||
fi
|
||||
else
|
||||
echo "Ключ НЕ сохранён."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_PROMPT_FILE=$(mktemp /tmp/ai-sys-prompt.XXXXXX)
|
||||
trap 'rm -f "$_PROMPT_FILE"' EXIT INT TERM
|
||||
_build_ai_sys_prompt > "$_PROMPT_FILE"
|
||||
export AI_LAUNCHER=glm
|
||||
export CLAUDE_CONFIG_DIR="$HOME/.config/ai-setup/cfg/glm"
|
||||
# Пикер: Opus/Sonnet = GLM 5.2, Haiku = GLM 5.2[1m]. availableModels НЕ задаём
|
||||
# (он схлопывает пикер). Claude Code навязывает 3 слота; незаданный показал бы
|
||||
# чужой Claude, поэтому opus+sonnet = glm-5.2, haiku = glm-5.2[1m].
|
||||
_setup_isolated_config glm opus high ''
|
||||
_apply_effort glm high
|
||||
ANTHROPIC_BASE_URL="$glm_base_url" \
|
||||
ANTHROPIC_AUTH_TOKEN="$api_key" \
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5.2 \
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL_NAME="GLM 5.2" \
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION="GLM 5.2 — флагман Zhipu AI" \
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL=glm-5.2 \
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL_NAME="GLM 5.2" \
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION="GLM 5.2 — флагман Zhipu AI" \
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL='glm-5.2[1m]' \
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME="GLM 5.2 [1M]" \
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION="GLM 5.2 [1M] — расширенный контекст" \
|
||||
CLAUDE_CODE_SUBAGENT_MODEL=glm-5.2 \
|
||||
CLAUDE_CODE_DISABLE_1M_CONTEXT=1 \
|
||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
|
||||
claude --dangerously-skip-permissions --system-prompt-file "$_PROMPT_FILE" "$@"
|
||||
GLMEOF
|
||||
chmod +x "$BIN_DIR/ai-glm"
|
||||
|
||||
# === ai-openrouter ===
|
||||
cat > "$BIN_DIR/ai-openrouter" << 'OPENROUTEREOF'
|
||||
#!/usr/bin/env bash
|
||||
@@ -1838,6 +1927,7 @@ if [ "$USE_VLESS" -eq 1 ]; then
|
||||
sed -i 's/^exec "\$codex_bin"/exec proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" "\$codex_bin"/' "$BIN_DIR/ai-gpt"
|
||||
sed -i 's/^claude --dangerously-skip-permissions/proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" claude --dangerously-skip-permissions/' "$BIN_DIR/ai-deepseek"
|
||||
sed -i 's/^claude --dangerously-skip-permissions/proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" claude --dangerously-skip-permissions/' "$BIN_DIR/ai-kimi"
|
||||
sed -i 's/^claude --dangerously-skip-permissions/proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" claude --dangerously-skip-permissions/' "$BIN_DIR/ai-glm"
|
||||
sed -i 's/^claude --dangerously-skip-permissions/proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" claude --dangerously-skip-permissions/' "$BIN_DIR/ai-openrouter"
|
||||
sed -i 's/^\([[:space:]]*\)exec "\$agy_bin"/\1exec proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" "\$agy_bin"/' "$BIN_DIR/ai-gemini"
|
||||
sed -i 's/^claude --dangerously-skip-permissions/proxychains4 -f "\$HOME\/\.proxychains-xray\.conf" claude --dangerously-skip-permissions/' "$BIN_DIR/ai-claude"
|
||||
@@ -1850,6 +1940,7 @@ fi
|
||||
source "$BIN_DIR/ai-api-helpers.sh"
|
||||
_setup_isolated_config deepseek opus high ''
|
||||
_setup_isolated_config kimi opus high ''
|
||||
_setup_isolated_config glm opus high ''
|
||||
_setup_isolated_config openrouter "openai/gpt-5.5" high ''
|
||||
|
||||
info "Удаляю старые версии скриптов (claude_*)..."
|
||||
@@ -1859,7 +1950,7 @@ rm -f "$BIN_DIR/claude_gpt" "$BIN_DIR/claude_deepseek" "$BIN_DIR/claude_kimi" "$
|
||||
if [ "$BIN_DIR" != "$HOME/.local/bin" ]; then
|
||||
warn "BIN_DIR=$BIN_DIR — удаляю старые скрипты из ~/.local/bin/ ..."
|
||||
rm -f "$HOME/.local/bin/ai-gpt" "$HOME/.local/bin/ai-deepseek" "$HOME/.local/bin/ai-kimi" \
|
||||
"$HOME/.local/bin/ai-openrouter" "$HOME/.local/bin/ai-gemini" "$HOME/.local/bin/ai-claude" \
|
||||
"$HOME/.local/bin/ai-glm" "$HOME/.local/bin/ai-openrouter" "$HOME/.local/bin/ai-gemini" "$HOME/.local/bin/ai-claude" \
|
||||
"$HOME/.local/bin/ai-api-helpers.sh" "$HOME/.local/bin/claude-gpt-effort-proxy.py"
|
||||
fi
|
||||
|
||||
@@ -1877,6 +1968,7 @@ echo " На базе Claude Code:"
|
||||
echo -e " ${CYAN}ai-claude${NC} - Оригинальный Claude Code (Anthropic)"
|
||||
echo -e " ${CYAN}ai-deepseek${NC} - DeepSeek (через Claude Code, API ключ сохраняется)"
|
||||
echo -e " ${CYAN}ai-kimi${NC} - Kimi K2.7 Code (через Claude Code, API ключ сохраняется)"
|
||||
echo -e " ${CYAN}ai-glm${NC} - GLM 5.2 (через Claude Code, Zhipu AI API)"
|
||||
echo -e " ${CYAN}ai-openrouter${NC} - OpenRouter (через Claude Code: GPT-5.5, Grok, Qwen, MiniMax, Llama и др.)"
|
||||
echo ""
|
||||
echo " Нативные CLI:"
|
||||
|
||||
8
setup.sh
8
setup.sh
@@ -33,7 +33,7 @@ else
|
||||
echo -e "${YEL}Шаги для новой машины (выполнить по порядку):${CLR}"
|
||||
echo ""
|
||||
echo -e " ${BLD}1) AI-инструменты${CLR}"
|
||||
echo -e " ${GRY}Устанавливает ai-claude, ai-gpt, ai-deepseek, ai-gemini и др.${CLR}"
|
||||
echo -e " ${GRY}Устанавливает ai-claude, ai-gpt, ai-deepseek, ai-kimi, ai-glm, ai-gemini и др.${CLR}"
|
||||
echo -e " ${GRY}Запрашивает API-ключи. Запускать один раз.${CLR}"
|
||||
echo ""
|
||||
echo -e " ${BLD}2) Сеть: ru-bypass + kill switch${CLR}"
|
||||
@@ -173,7 +173,7 @@ case "$choice" in
|
||||
|
||||
echo ""
|
||||
echo -e "${BLD}AI инструменты:${CLR}"
|
||||
for cmd in ai-claude ai-gpt ai-deepseek ai-kimi ai-openrouter ai-gemini android; do
|
||||
for cmd in ai-claude ai-gpt ai-deepseek ai-kimi ai-glm ai-openrouter ai-gemini android; do
|
||||
if command -v "$cmd" &>/dev/null; then
|
||||
echo -e " ${GRN}✓${CLR} $cmd"
|
||||
else
|
||||
@@ -184,7 +184,7 @@ case "$choice" in
|
||||
echo ""
|
||||
echo -e "${BLD}API ключи:${CLR}"
|
||||
cfg="$HOME/.config/ai-setup"
|
||||
for f in deepseek_key kimi_key openrouter_key; do
|
||||
for f in deepseek_key kimi_key glm_key openrouter_key; do
|
||||
name="${f/_key/}"
|
||||
if [ -s "$cfg/$f" ]; then
|
||||
echo -e " ${GRN}✓${CLR} $name"
|
||||
@@ -195,7 +195,7 @@ case "$choice" in
|
||||
|
||||
echo ""
|
||||
echo -e "${BLD}API доступность:${CLR}"
|
||||
for entry in "Anthropic:api.anthropic.com" "DeepSeek:api.deepseek.com" "OpenAI:api.openai.com" "Kimi:api.kimi.com" "OpenRouter:openrouter.ai"; do
|
||||
for entry in "Anthropic:api.anthropic.com" "DeepSeek:api.deepseek.com" "OpenAI:api.openai.com" "Kimi:api.kimi.com" "GLM:api.z.ai" "OpenRouter:openrouter.ai"; do
|
||||
_name="${entry%%:*}"
|
||||
_host="${entry##*:}"
|
||||
_ms=$(curl -s -o /dev/null -w "%{time_connect}" --max-time 5 "https://$_host" 2>/dev/null)
|
||||
|
||||
@@ -21,6 +21,11 @@ awk '/^cat > "\$BIN_DIR\/ai-kimi"/,/^KIMIEOF/' scripts/ai-setup.sh | \
|
||||
sed "s|\\\$BIN_DIR|$BIN_DIR|g" | bash
|
||||
chmod +x "$BIN_DIR/ai-kimi"
|
||||
|
||||
# Извлекаем ai-glm
|
||||
awk '/^cat > "\$BIN_DIR\/ai-glm"/,/^GLMEOF/' scripts/ai-setup.sh | \
|
||||
sed "s|\\\$BIN_DIR|$BIN_DIR|g" | bash
|
||||
chmod +x "$BIN_DIR/ai-glm"
|
||||
|
||||
echo "=== Test 1: ai-gpt calls codex install URL when missing ==="
|
||||
MOCK_LOG="$TMPDIR/mock_curl.log"
|
||||
|
||||
@@ -62,5 +67,17 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Test 3: ai-glm is a Claude Code launcher with Zhipu AI backend ==="
|
||||
|
||||
if grep -q 'ANTHROPIC_BASE_URL' "$BIN_DIR/ai-glm" \
|
||||
&& grep -q 'api.z.ai/api/anthropic' "$BIN_DIR/ai-glm" \
|
||||
&& grep -q 'claude --dangerously-skip-permissions' "$BIN_DIR/ai-glm"; then
|
||||
echo "[PASS] ai-glm запускает claude с официальным Zhipu AI API"
|
||||
else
|
||||
echo "[FAIL] ai-glm должен запускать claude с api.z.ai/api/anthropic"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== All tests passed ==="
|
||||
|
||||
@@ -14,6 +14,7 @@ fail() { echo "[FAIL] $1"; FAIL=$((FAIL+1)); }
|
||||
# Extract sections
|
||||
GPT_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-gpt"/,/^GPTEOF/' "$SCRIPT")
|
||||
KIMI_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-kimi"/,/^KIMIEOF/' "$SCRIPT")
|
||||
GLM_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-glm"/,/^GLMEOF/' "$SCRIPT")
|
||||
GEMINI_SECTION=$(awk '/^cat > "\$BIN_DIR\/ai-gemini"/,/^GEMINIEOF/' "$SCRIPT")
|
||||
HELPERS_SECTION=$(awk '/^cat > "\$HELPERS_FILE"/,/^HELPEREOF/' "$SCRIPT")
|
||||
|
||||
@@ -66,6 +67,28 @@ test_kimi_no_artemox() {
|
||||
fi
|
||||
}
|
||||
|
||||
# ── ai-glm: launches claude with GLM backend ──────────────────────────────
|
||||
test_glm_claude_launcher() {
|
||||
if echo "$GLM_SECTION" | grep -q 'claude --dangerously-skip-permissions' \
|
||||
&& echo "$GLM_SECTION" | grep -q 'ANTHROPIC_BASE_URL'; then
|
||||
ok "ai-glm: launches claude with ANTHROPIC_BASE_URL set"
|
||||
else
|
||||
fail "ai-glm: must launch claude with ANTHROPIC_BASE_URL"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── ai-glm: uses official Zhipu AI API ────────────────────────────────────
|
||||
test_glm_official_api() {
|
||||
if echo "$GLM_SECTION" | grep -q 'api.z.ai/api/anthropic' \
|
||||
&& echo "$GLM_SECTION" | grep -q 'ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5.2' \
|
||||
&& echo "$GLM_SECTION" | grep -q "ANTHROPIC_DEFAULT_HAIKU_MODEL='glm-5.2\[1m\]'" \
|
||||
&& echo "$GLM_SECTION" | grep -q 'x-api-key'; then
|
||||
ok "ai-glm: uses official Zhipu AI API (glm-5.2 opus/sonnet, glm-5.2[1m] haiku)"
|
||||
else
|
||||
fail "ai-glm: must use official Zhipu AI API with glm-5.2 and x-api-key"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── ai-gemini: native launcher generation ─────────────────────────────────
|
||||
test_gemini_native_launcher() {
|
||||
if echo "$GEMINI_SECTION" | grep -q 'antigravity CLI (agy)' \
|
||||
@@ -176,6 +199,8 @@ test_gpt_no_proxy
|
||||
test_kimi_claude_launcher
|
||||
test_kimi_official_api
|
||||
test_kimi_no_artemox
|
||||
test_glm_claude_launcher
|
||||
test_glm_official_api
|
||||
test_gemini_native_launcher
|
||||
test_global_rules_include_quality_guidelines
|
||||
test_native_rule_files_generated
|
||||
|
||||
Reference in New Issue
Block a user