Returns ``None`` when the user picks ``[s] Skip``.
(
console: Console,
strings: dict,
catalog: dict,
llm_api_key: str,
)
| 188 | |
| 189 | |
| 190 | def _embedding_step( |
| 191 | console: Console, |
| 192 | strings: dict, |
| 193 | catalog: dict, |
| 194 | llm_api_key: str, |
| 195 | ) -> wiz.EmbeddingChoice | None: |
| 196 | """Returns ``None`` when the user picks ``[s] Skip``.""" |
| 197 | |
| 198 | from deeptutor.services.config.embedding_endpoint import ( |
| 199 | EMBEDDING_PROVIDER_LABELS, |
| 200 | normalize_embedding_endpoint_for_display, |
| 201 | ) |
| 202 | from deeptutor.services.config.provider_runtime import EMBEDDING_PROVIDERS |
| 203 | |
| 204 | current_profile = (catalog.get("services", {}).get("embedding", {}).get("profiles") or [{}])[ |
| 205 | 0 |
| 206 | ] or {} |
| 207 | current_binding = str(current_profile.get("binding") or "openai") |
| 208 | |
| 209 | provider_pick = wiz.select_embedding_provider(console, strings, current=current_binding) |
| 210 | if provider_pick == wiz.SKIP_SENTINEL: |
| 211 | wiz.info(console, strings["init.skipped"]) |
| 212 | return None |
| 213 | if provider_pick is None: |
| 214 | provider = typer.prompt(strings["init.binding"], default=current_binding or "openai") |
| 215 | else: |
| 216 | provider = provider_pick |
| 217 | |
| 218 | spec = EMBEDDING_PROVIDERS.get(provider) |
| 219 | display_provider = ( |
| 220 | spec.label if spec else EMBEDDING_PROVIDER_LABELS.get(provider, provider.title()) |
| 221 | ) |
| 222 | default_endpoint = spec.default_api_base if spec else str(current_profile.get("base_url") or "") |
| 223 | |
| 224 | edit_endpoint = typer.confirm(strings["init.edit_base_url"], default=not bool(default_endpoint)) |
| 225 | endpoint = ( |
| 226 | typer.prompt(strings["init.embedding_endpoint"], default=default_endpoint) |
| 227 | if edit_endpoint |
| 228 | else default_endpoint |
| 229 | ) |
| 230 | endpoint = normalize_embedding_endpoint_for_display(provider, endpoint) |
| 231 | if not edit_endpoint: |
| 232 | wiz.info(console, f"Endpoint · {endpoint or '(empty)'}") |
| 233 | |
| 234 | # Reuse the LLM key by default — most users share creds across services. |
| 235 | masked = wiz._mask_secret(llm_api_key) |
| 236 | if llm_api_key and typer.confirm( |
| 237 | strings["init.api_key_reuse_llm"].format(masked=masked), default=True |
| 238 | ): |
| 239 | api_key = llm_api_key |
| 240 | else: |
| 241 | api_key = typer.prompt( |
| 242 | strings["init.embedding_api_key"], default="", hide_input=True, show_default=False |
| 243 | ) |
| 244 | |
| 245 | # Try live ``/models`` first; fall back to the curated list (spec default |
| 246 | # first, then EMBEDDING_FALLBACK_MODELS) when the fetch returns nothing. |
| 247 | models = wiz.fetch_embedding_models( |