런타임 계약과 학습자 흐름 보강

This commit is contained in:
Yun Chan 2026-06-29 08:12:14 +09:00
parent f456b8997a
commit 206018b088
56 changed files with 4306 additions and 1008 deletions

View file

@ -7,7 +7,7 @@ import uuid
import hashlib
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Any, Iterable
from typing import Any, Iterable, Protocol
from .db import acquire, get_pool
from .deps import Principal
@ -56,6 +56,78 @@ class SessionSummaryWrite:
open_threads: list[str]
class _SessionEvaluationResult(Protocol):
scope: str
stage: str
error: str | None
def to_dict(self) -> dict[str, Any]: ...
@dataclass(slots=True)
class SessionEvaluationWrite:
session_id: str
learner_id: str
status: str
source: str
scope: str
stage: str
payload: dict[str, Any]
error: str | None = None
@classmethod
def from_result(
cls,
*,
session_id: str,
learner_id: str,
result: _SessionEvaluationResult,
source: str = "engine",
) -> "SessionEvaluationWrite":
return cls(
session_id=session_id,
learner_id=learner_id,
status="error" if result.error else "ready",
source=source,
scope=result.scope,
stage=result.stage,
payload=result.to_dict(),
error=result.error,
)
@classmethod
def from_error(
cls,
*,
session_id: str,
learner_id: str,
scope: str,
stage: str,
error: BaseException | str,
source: str = "engine",
) -> "SessionEvaluationWrite":
return cls(
session_id=session_id,
learner_id=learner_id,
status="error",
source=source,
scope=scope,
stage=stage,
payload={},
error=str(error),
)
def cache_record(self) -> dict[str, Any]:
return {
"status": self.status,
"source": self.source,
"scope": self.scope,
"stage": self.stage,
"payload": self.payload,
"error": self.error,
}
_JOINED_CARD_COLUMNS = (
"card_persona_id",
"card_code",
@ -1125,30 +1197,13 @@ async def ensure_review_tables() -> None:
return
async def save_session_evaluation(
*,
session_id: str,
learner_id: str,
status: str,
source: str,
scope: str,
stage: str,
payload: dict[str, Any],
error: str | None = None,
) -> bool:
record = {
"status": status,
"source": source,
"scope": scope,
"stage": stage,
"payload": payload,
"error": error,
}
async def save_session_evaluation(write: SessionEvaluationWrite) -> bool:
record = write.cache_record()
if runtime_fallback_allowed():
_EVALUATION_CACHE[session_id] = record
_EVALUATION_CACHE[write.session_id] = record
try:
get_pool()
async with acquire(role="learner", user_id=learner_id) as conn:
async with acquire(role="learner", user_id=write.learner_id) as conn:
await conn.execute(
"""
INSERT INTO app.session_evaluation (
@ -1165,13 +1220,13 @@ async def save_session_evaluation(
error = EXCLUDED.error,
updated_at = now()
""",
session_id,
status,
source,
scope,
stage,
payload,
error,
write.session_id,
write.status,
write.source,
write.scope,
write.stage,
write.payload,
write.error,
)
return True
except Exception:
@ -2301,7 +2356,9 @@ async def end_session(sess: InProcSession, carry: memory.CarryOver) -> bool:
end_state = EXCLUDED.end_state,
rapport_delta = EXCLUDED.rapport_delta,
digest = EXCLUDED.digest,
open_threads = EXCLUDED.open_threads
open_threads = EXCLUDED.open_threads,
compressed_by = NULL,
token_count = NULL
""",
summary_write.session_id,
summary_write.case_id,