KeiSeiKit-1.0/install/lib-onboarding-registry.sh
Parfii-bot d729a2e903 refactor(install): production-ready финальный круг
1. lib-onboarding.sh раскидан на 3 куба (Constructor Pattern <200 LOC):
   - lib-onboarding-registry.sh (79 LOC) — парсеры providers/models.toml
     + onboarding_fallback_providers (14 провайдеров)
     + onboarding_auth_env_for_provider helper (был inline в collect_auth)
   - lib-onboarding-ui.sh (189 LOC) — pick_language/transport/provider/model
     + collect_auth (whiptail/bash select)
   - lib-onboarding-state.sh (57 LOC) — write_secrets + write_config
     + user-model-override.toml для kei-model-router
   - lib-onboarding.sh (95 LOC) — тонкий оркестратор: should_run + run

   Сам lib-onboarding.sh source'ит 3 подкуба автоматически. Глобалы
   (ONBOARDING_*, REGISTRY_*, ONBOARDED_FLAG, etc.) объявлены в
   оркестраторе, подкубы их используют через имена.

2. lib-menu.sh локализован:
   - whiptail title + radiolist prompt через ${STR_MENU_TITLE} +
     ${STR_MENU_SUBSTRATE} + ${STR_MENU_PROFILE_PROMPT}.
   - Plain heading тоже использует словарь.
   - 12 коротких имён профилей (minimal/core/dev/...) — оставлены EN
     как стабильные id (не переводятся).

3. _blocks/build-index.sh — детерминированная регенерация INDEX.md.
   Группировка по 14 категорийным префиксам + "Прочие" для остальных.
   Безопасно перезапускать. INDEX.md обновлён через этот скрипт
   (минимальный diff — добавлена ссылка на build-index.sh в шапке).

Проверено: bash -n чисто, unit тесты onboarding_list_providers/
transports/models OK, non-TTY smoke ./install.sh --profile=minimal
--no-execute проходит.
2026-05-17 23:57:23 +08:00

79 lines
4.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# shellcheck shell=bash
# lib-onboarding-registry.sh — парсеры реестров providers.toml + models.toml.
#
# Constructor Pattern: 1 файл = парсинг реестров. UI и state — в соседних кубах.
#
# Источник: $KIT_DIR/_blocks/registries/{providers,models}.toml (submodule
# kei-registries). Если файла нет — fallback на захардкоженный набор
# покрывающий все 7 транспортов.
#
# Глобалы (общие с lib-onboarding-*):
# REGISTRY_PROVIDERS — путь к providers.toml
# REGISTRY_MODELS — путь к models.toml
REGISTRY_PROVIDERS="${REGISTRY_PROVIDERS:-$KIT_DIR/_blocks/registries/providers.toml}"
REGISTRY_MODELS="${REGISTRY_MODELS:-$KIT_DIR/_blocks/registries/models.toml}"
# Парсер providers.toml. Простой awk-граббер по [[provider]] секциям.
# Печатает: <id>\t<transport>\t<display_name>\t<auth_env>
onboarding_list_providers() {
[ -f "$REGISTRY_PROVIDERS" ] || { onboarding_fallback_providers; return; }
awk '
/^\[\[provider\]\]/ { id=""; tr=""; dn=""; ae=""; next }
/^id[[:space:]]*=/ { gsub(/^id[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); id=$0 }
/^transport[[:space:]]*=/ { gsub(/^transport[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); tr=$0 }
/^display_name[[:space:]]*=/ { gsub(/^display_name[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); dn=$0 }
/^auth_env[[:space:]]*=/ { gsub(/^auth_env[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); ae=$0;
if (id && tr) print id "\t" tr "\t" dn "\t" ae }
' "$REGISTRY_PROVIDERS"
}
# Fallback если submodule не подтянут.
# Покрывает 7 транспортов минимальными представителями. Синхронизировать
# вручную если в реестре появится новый транспорт-тип.
onboarding_fallback_providers() {
printf "anthropic\tdirect-api\tAnthropic (Direct API)\tANTHROPIC_API_KEY\n"
printf "anthropic-bedrock\taws-bedrock\tAnthropic (AWS Bedrock)\tAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION\n"
printf "openai\tdirect-api\tOpenAI (Direct API)\tOPENAI_API_KEY\n"
printf "openai-azure\tazure-openai\tOpenAI (Azure)\tAZURE_OPENAI_API_KEY,AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_DEPLOYMENT\n"
printf "xai\tdirect-api\txAI\tXAI_API_KEY\n"
printf "deepseek\tdirect-api\tDeepSeek\tDEEPSEEK_API_KEY\n"
printf "google\tdirect-api\tGoogle Gemini (Direct API)\tGEMINI_API_KEY\n"
printf "google-vertex\tgoogle-vertex\tGoogle Gemini (Vertex AI)\tGOOGLE_APPLICATION_CREDENTIALS,GCP_PROJECT_ID,GCP_REGION\n"
printf "ollama-local\tlocal\tOllama (local)\t_\n"
printf "mlx-local\tlocal\tMLX (Apple silicon local)\t_\n"
printf "lmstudio-local\tlocal\tLM Studio (local)\t_\n"
printf "litellm-proxy\tproxy\tLiteLLM proxy (keisei.app)\tKEI_LITELLM_KEY\n"
printf "openrouter\tproxy\tOpenRouter\tOPENROUTER_API_KEY\n"
printf "codex\tsubscription\tOpenAI Codex (ChatGPT OAuth)\t_\n"
}
# Уникальные транспорты — для первого экрана выбора.
onboarding_list_transports() {
onboarding_list_providers | awk -F'\t' '{print $2}' | sort -u
}
# Провайдеры внутри транспорта.
onboarding_providers_in_transport() {
local tr="$1"
onboarding_list_providers | awk -F'\t' -v t="$tr" '$2==t {print $1 "\t" $3 "\t" $4}'
}
# Модели по provider_ref.
onboarding_models_for_provider() {
local pr="$1"
[ -f "$REGISTRY_MODELS" ] || { printf "claude-sonnet-4-6\tClaude Sonnet 4.6\n"; return; }
awk -v pr="$pr" '
/^\[\[model\]\]/ { id=""; pref=""; dn=""; next }
/^id[[:space:]]*=/ { gsub(/^id[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); id=$0 }
/^provider_ref[[:space:]]*=/ { gsub(/^provider_ref[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); pref=$0 }
/^display_name[[:space:]]*=/ { gsub(/^display_name[[:space:]]*=[[:space:]]*"/, ""); gsub(/".*$/, ""); dn=$0;
if (pref==pr) print id "\t" dn }
' "$REGISTRY_MODELS"
}
# auth_env для одного провайдера (для onboarding_collect_auth).
onboarding_auth_env_for_provider() {
local p="$1"
onboarding_list_providers | awk -F'\t' -v p="$p" '$1==p {print $4}'
}