Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
96 lines
3.3 KiB
Python
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,
|
|
}
|