Files
JARVIS/backend/app/agents/learning/session_search.py

96 lines
3.3 KiB
Python

from __future__ import annotations
from app.agents.schemas.learning import SessionRetrospective
from app.agents.skills.matcher import score_text_match
from app.agents.learning.store import SessionRetrospectiveStore
from app.config import settings
class SessionRetrospectiveSearch:
def __init__(self, db):
self.db = db
async def shortlist(
self,
*,
user_id: str,
query_text: str,
conversation_id: str | None = None,
task_type: str | None = None,
skill_name: str | None = None,
limit: int = 3,
) -> list[SessionRetrospective]:
records = await SessionRetrospectiveStore(self.db).list_recent(user_id=user_id, limit=25)
scored: list[tuple[float, SessionRetrospective]] = []
for record in records:
if task_type and record.task_type != task_type:
continue
if skill_name and skill_name not in (record.skill_names or []):
continue
score, _matched_terms = score_text_match(
query_text,
record.query_text,
record.summary_text,
" ".join(record.skill_names or []),
)
if conversation_id and record.conversation_id == conversation_id:
score = min(1.0, score + 0.1)
if score <= 0:
continue
payload = dict(record.payload or {})
payload["retrospective_id"] = record.id
retrospective = SessionRetrospective.model_validate(payload)
scored.append((score, retrospective))
scored.sort(key=lambda item: item[0], reverse=True)
return [item for _score, item in scored[:limit]]
async def search_recent_retrospectives(
db,
*,
user_id: str,
query: str,
conversation_id: str | None = None,
task_type: str | None = None,
skill_name: str | None = None,
limit: int = 3,
) -> list[SessionRetrospective]:
if not settings.ENABLE_SESSION_RETROSPECTIVE_SEARCH:
return []
return await SessionRetrospectiveSearch(db).shortlist(
user_id=user_id,
query_text=query,
conversation_id=conversation_id,
task_type=task_type,
skill_name=skill_name,
limit=limit,
)
def summarize_retrospective(retrospective: SessionRetrospective) -> dict[str, object]:
verification_status = retrospective.verification_status or retrospective.outcome
success_score = 1.0 if verification_status == "passed" else 0.6 if verification_status == "skipped" else 0.2
reusable_patterns = []
if retrospective.used_skill_names:
reusable_patterns.append("skill_shortlist_hit")
if retrospective.execution_mode:
reusable_patterns.append(f"mode:{retrospective.execution_mode}")
avoid_patterns = []
if retrospective.outcome == "failed":
avoid_patterns.append("failed_outcome")
return {
"retrospective_id": retrospective.retrospective_id,
"task_type": retrospective.task_type,
"request_summary": retrospective.query_text[:120],
"summary": retrospective.summary,
"execution_mode": retrospective.execution_mode,
"success_score": round(success_score, 2),
"reusable_patterns": reusable_patterns,
"avoid_patterns": avoid_patterns,
}