feat: unify installation model catalog

This commit is contained in:
Codex
2026-09-02 18:45:33 +02:00
parent ae053961a3
commit 7b7927bfe5
169 changed files with 3696 additions and 4572 deletions
+3 -2
View File
@@ -29,8 +29,9 @@ Keys are never logged; URLs are fine. Rotate any key that appeared in chat.
### `workspaces/<name>.yaml`
A schema-v3 workspace wires the external relational DWH to one internal Qdrant collection
and the internal Ollama embedding model. Evidence paths remain workspace-local, while Qdrant
A schema-v4 workspace wires the external relational DWH to one internal Qdrant collection.
The embedding identity and dimensions come from the Installation Model Catalog, not this
workspace descriptor. Evidence paths remain workspace-local, while Qdrant
stores the derived semantic projection for schema, Evidence, Memory, and solved-question
records. The legacy files under `workspaces/` are retained as migration fixtures; new
operator-facing descriptors live in the workspace Git registry. `${THT_*}` tokens expand
@@ -36,8 +36,7 @@ def _candidate():
def test_pi_restructurer_uses_an_ephemeral_no_tools_invocation(tmp_path, monkeypatch):
from tht.evidence import authoring
monkeypatch.setenv("PI_PROVIDER", "zai")
monkeypatch.setenv("PI_MODEL", "glm-5.2")
monkeypatch.setenv("THT_DEFAULT_SESSION_MODEL", "zai/glm-5.2")
monkeypatch.setenv("PI_THINKING", "medium")
calls = []
+8 -2
View File
@@ -34,8 +34,13 @@ def test_local_compose_uses_the_generic_external_endpoint_contract():
assert name in environment
assert environment["THT_INTERNAL_QDRANT_URL"] == "http://qdrant:6333"
assert environment["THT_INTERNAL_EMBEDDING_URL"] == "http://embedding:11434"
assert environment["THT_INTERNAL_EMBEDDING_MODEL"] == "qwen3-embedding:0.6b"
assert environment["THT_INTERNAL_EMBEDDING_DIMENSIONS"] == "1024"
# Identity and dimensions come only from the installation-generated Compose projection.
for name in (
"THT_INTERNAL_EMBEDDING_ID",
"THT_INTERNAL_EMBEDDING_MODEL",
"THT_INTERNAL_EMBEDDING_DIMENSIONS",
):
assert name not in environment
for name in ("THT_VEC_REST_URL", "THT_VEC_WRITE_REST_URL", "THT_OLLAMA_URL"):
assert name not in environment
@@ -53,6 +58,7 @@ def test_local_compose_uses_the_generic_external_endpoint_contract():
model_init = compose["services"]["embedding-model-init"]
assert "ports" not in model_init
assert "OLLAMA_MODEL" not in model_init.get("environment", {})
assert model_init["depends_on"]["embedding"]["condition"] == "service_healthy"
assert compose["services"]["core"]["depends_on"]["embedding-model-init"]["condition"] == "service_completed_successfully"
@@ -6,6 +6,7 @@ from datetime import UTC, datetime
from pathlib import Path
from types import SimpleNamespace
import pytest
from typer.testing import CliRunner
from tht.cli import app
@@ -13,6 +14,12 @@ from tht.memory import MemoryRecord, save_registry
from tht.ports.vector import VectorStoreError
@pytest.fixture(autouse=True)
def _ignore_operator_profile(monkeypatch):
"""Exercise the self-contained server runtime fixture, not the developer's harness/.env."""
monkeypatch.delenv("THT_PROFILE", raising=False)
class _FakeEmbedder:
def embed_documents(self, documents):
return [[0.1] * 4 for _ in documents]
+9 -8
View File
@@ -228,14 +228,15 @@ class PiEvidenceRestructurer:
"--no-skills",
"--extension", str(self._json_mode_extension),
]
for option, environment_name in (
("--provider", "PI_PROVIDER"),
("--model", "PI_MODEL"),
("--thinking", "PI_THINKING"),
):
value = os.environ.get(environment_name)
if value:
argv.extend((option, value))
canonical_model = os.environ.get("THT_DEFAULT_SESSION_MODEL")
if canonical_model:
provider, separator, model = canonical_model.partition("/")
if separator != "/" or not provider or not model:
raise EvidencePreparationError("pi_restructure_failed", request.source_file)
argv.extend(("--provider", provider, "--model", model))
thinking = os.environ.get("PI_THINKING")
if thinking:
argv.extend(("--thinking", thinking))
argv.extend((
"--system-prompt", system_prompt,
f"@{request_path}",