feat: pin sessions to workspace revisions

This commit is contained in:
2026-08-04 04:52:06 +02:00
parent 2573d87a0e
commit 90894176b6
13 changed files with 313 additions and 80 deletions
+10 -1
View File
@@ -7,7 +7,7 @@ from typer.testing import CliRunner
from tht.config import DatabaseConfig
from tht.decisions import DecisionRecord
from tht.session.models import SessionSnapshot
from tht.session.store import build_documents, build_snapshot_documents, create_session
from tht.session.store import build_documents, build_snapshot_documents, create_session, new_session_manifest
from tht.cli.session_cmd import session_app
@@ -18,6 +18,15 @@ def _db():
)
def test_manifest_persists_workspace_revision():
manifest = new_session_manifest(
"q", _db(), workspace_id="psd-clinical", workspace_revision="a" * 40
)
assert manifest.workspace_id == "psd-clinical"
assert manifest.workspace_revision == "a" * 40
def test_build_documents_always_has_original_question(tmp_path):
m = create_session("quante ablazioni nel 2024", _db(), tmp_path)
docs = build_documents(m, tmp_path / m.id)
+3
View File
@@ -175,6 +175,8 @@ def new_cmd(
provider: str = typer.Option(None, "--provider", help="Provider LLM (es. zai, anthropic)."),
model: str = typer.Option(None, "--model", help="Modello LLM (es. glm-5.2)."),
thinking: str = typer.Option(None, "--thinking", help="Livello di thinking (es. medium)."),
workspace_id: str = typer.Option(None, "--workspace-id", help="Workspace canonico risolto dal backend."),
workspace_revision: str = typer.Option(None, "--workspace-revision", help="Commit immutabile del workspace."),
name: str = typer.Option(None, "--name", help="Nome descrittivo della sessione."),
json_out: bool = typer.Option(False, "--json", help="Emetti JSON puro {\"id\": ...} su stdout."),
config: Path = CONFIG_OPT,
@@ -185,6 +187,7 @@ def new_cmd(
cfg = _load_config_or_exit(config)
manifest = new_session_manifest(question, cfg.database,
provider=provider, model=model, thinking=thinking,
workspace_id=workspace_id, workspace_revision=workspace_revision,
name=name or _extract_name(question))
repository = session_repository(cfg)
repository.create(manifest)
+2
View File
@@ -117,6 +117,8 @@ class SessionManifest(_YamlModel):
provider: str | None = None
model: str | None = None
thinking: str | None = None
workspace_id: str | None = None
workspace_revision: str | None = None
name: str | None = None
archived: bool = False
group: str | None = None
+8 -4
View File
@@ -102,7 +102,8 @@ def create_session(
question: str, db: DatabaseConfig, sessions_root: Path,
*, author: str | None = None, summary: str | None = None,
provider: str | None = None, model: str | None = None,
thinking: str | None = None, name: str | None = None,
thinking: str | None = None, workspace_id: str | None = None,
workspace_revision: str | None = None, name: str | None = None,
) -> SessionManifest:
now = datetime.now(UTC)
# stamp con ora/min/sec: identifica univocamente sessioni dello stesso giorno
@@ -123,7 +124,8 @@ def create_session(
database=db.database, schema=db.db_schema,
author=who, summary=summary or _summarize(question),
updated_at=now, updated_by=who, schema_version=schema_version,
provider=provider, model=model, thinking=thinking, name=name,
provider=provider, model=model, thinking=thinking, workspace_id=workspace_id,
workspace_revision=workspace_revision, name=name,
)
session_dir = sessions_root / session_id
manifest.to_yaml(session_dir / MANIFEST)
@@ -132,7 +134,8 @@ def create_session(
def new_session_manifest(
question: str, db: DatabaseConfig, *, provider=None, model=None, thinking=None, name=None
question: str, db: DatabaseConfig, *, provider=None, model=None, thinking=None,
workspace_id=None, workspace_revision=None, name=None,
) -> SessionManifest:
"""Create an unsaved UUIDv4 manifest for a repository-owned session."""
now = datetime.now(UTC)
@@ -140,7 +143,8 @@ def new_session_manifest(
id=str(uuid.uuid4()), created_at=now, question=question,
database=db.database, schema=db.db_schema, author=current_author(),
summary=_summarize(question), updated_at=now, updated_by=current_author(),
provider=provider, model=model, thinking=thinking, name=name,
provider=provider, model=model, thinking=thinking, workspace_id=workspace_id,
workspace_revision=workspace_revision, name=name,
)