feat(harness): tht ollama ensure CLI command (hard-fail preflight)

This commit is contained in:
2026-06-29 19:25:23 +02:00
parent 9c39ea129e
commit 7e19f81173
3 changed files with 78 additions and 0 deletions
+2
View File
@@ -45,6 +45,7 @@ from tht.cli.evidence_cmd import evidence_app # noqa: E402
from tht.cli.formula_cmd import formula_app # noqa: E402
from tht.cli.lsh_cmd import lsh_app # noqa: E402
from tht.cli.memory_cmd import memory_app # noqa: E402
from tht.cli.ollama_cmd import ollama_app # noqa: E402
from tht.cli.phase_cmd import phase_app # noqa: E402
from tht.cli.schema_cmd import schema_app # noqa: E402
from tht.cli.search_cmd import search_app # noqa: E402
@@ -67,3 +68,4 @@ app.add_typer(sql_app, name="sql")
app.add_typer(cte_app, name="cte")
app.add_typer(datamart_app, name="datamart")
app.add_typer(lsh_app, name="lsh")
app.add_typer(ollama_app, name="ollama")
+35
View File
@@ -5,8 +5,17 @@ error (the caller refuses the session). "Load" = warm the already-installed mode
"""
from __future__ import annotations
import json
import subprocess
import time
from pathlib import Path
import typer
from tht.cli.config_cmd import CONFIG_OPT
from tht.cli.schema_cmd import _load_config_or_exit
ollama_app = typer.Typer(help="Ollama (embeddings) -- preflight.")
# --- low-level ops (real implementations; injected as fakes in tests) ----------
@@ -118,3 +127,29 @@ def ensure_ollama(
"error": f"warm del modello '{emb.model}' fallito: {e}"}
return {"ok": True, "server": server_state, "model": "warmed", "model_name": emb.model}
# --- CLI command ----------
@ollama_app.command("ensure")
def ensure_cmd(
timeout: int = typer.Option(60, "--timeout", help="Secondi di attesa per l'avvio di Ollama."),
no_start: bool = typer.Option(False, "--no-start", help="Non avviare Ollama (solo verifica)."),
json_out: bool = typer.Option(False, "--json", help="Emetti JSON puro su stdout."),
config: Path = CONFIG_OPT,
) -> None:
"""Assicura Ollama attivo + modello di embedding caricato; errore se non possibile."""
cfg = _load_config_or_exit(config)
result = ensure_ollama(cfg, timeout=timeout, no_start=no_start)
if json_out:
typer.echo(json.dumps(result, ensure_ascii=False))
elif result["ok"]:
typer.secho(
f"OK: Ollama {result['server']}, modello {result['model_name']} {result['model']}.",
fg=typer.colors.GREEN,
)
else:
typer.secho(f"ERRORE [{result['stage']}]: {result['error']}", fg=typer.colors.RED, err=True)
if not result["ok"]:
raise typer.Exit(code=1)