Files

155 lines
5.3 KiB
Python
Raw Permalink Normal View History

2026-08-07 09:52:43 +08:00
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any
from gfa_core.mas.memory.base import SearchResult
from gfa_core.mas.memory.case import AnalysisCase, CaseMemory
from gfa_core.mas.memory.knowledge import KnowledgeEntry, KnowledgeMemory
from gfa_core.mas.memory.session import SessionData, SessionMemory
@dataclass
class MemoryStats:
session_count: int = 0
case_count: int = 0
knowledge_count: int = 0
last_updated: datetime = field(default_factory=datetime.now)
class MemoryManager:
def __init__(
self,
session_memory: SessionMemory | None = None,
case_memory: CaseMemory | None = None,
knowledge_memory: KnowledgeMemory | None = None,
):
self.session = session_memory or SessionMemory()
self.case = case_memory or CaseMemory()
self.knowledge = knowledge_memory or KnowledgeMemory()
async def create_session(self, session_id: str, initial_state: dict[str, Any] | None = None) -> SessionData:
session = SessionData(
session_id=session_id,
state=initial_state or {},
)
await self.session.store(session_id, session)
return session
async def get_session(self, session_id: str) -> SessionData | None:
return await self.session.retrieve(session_id)
async def add_message_to_session(self, session_id: str, role: str, content: str) -> None:
await self.session.add_message(session_id, {"role": role, "content": content})
async def update_session_state(self, session_id: str, state: dict[str, Any]) -> None:
await self.session.update_state(session_id, state)
async def create_case(
self,
case_id: str,
user_id: str | None = None,
gene_family: str | None = None,
species: str | None = None,
workflow: list[dict] | None = None,
) -> AnalysisCase:
case = AnalysisCase(
case_id=case_id,
user_id=user_id,
gene_family=gene_family,
species=species,
workflow=workflow or [],
)
await self.case.store(case_id, case)
return case
async def get_case(self, case_id: str) -> AnalysisCase | None:
return await self.case.retrieve(case_id)
async def update_case_results(self, case_id: str, results: dict[str, Any]) -> None:
case = await self.case.retrieve(case_id)
if case:
case.results.update(results)
await self.case.store(case_id, case)
async def complete_case(self, case_id: str) -> None:
await self.case.update_status(case_id, "completed")
async def add_case_feedback(self, case_id: str, feedback: dict[str, Any]) -> None:
await self.case.add_feedback(case_id, feedback)
async def add_knowledge(
self,
entry_id: str,
content: str,
embedding: list[float] | None = None,
source: str | None = None,
category: str | None = None,
tags: list[str] | None = None,
) -> None:
await self.knowledge.add_entry(
entry_id=entry_id,
content=content,
embedding=embedding,
source=source,
category=category,
tags=tags,
)
async def search_knowledge(
self,
query_embedding: list[float],
top_k: int = 10,
) -> list[SearchResult]:
return await self.knowledge.search(query_embedding, top_k)
async def search_knowledge_by_tags(self, tags: list[str], top_k: int = 10) -> list[SearchResult]:
return await self.knowledge.search_by_tags(tags, top_k)
async def extract_case_to_knowledge(self, case_id: str) -> KnowledgeEntry | None:
case = await self.case.retrieve(case_id)
if not case or case.status != "completed":
return None
entry_id = f"case_{case_id}"
content = self._extract_knowledge_content(case)
entry = KnowledgeEntry(
entry_id=entry_id,
content=content,
source=f"case:{case_id}",
category="workflow_template",
tags=[case.gene_family, case.species] if case.gene_family and case.species else [],
metadata={
"gene_family": case.gene_family,
"species": case.species,
"workflow_steps": len(case.workflow),
},
)
await self.knowledge.store(entry_id, entry)
return entry
def _extract_knowledge_content(self, case: AnalysisCase) -> str:
parts = []
if case.gene_family:
parts.append(f"Gene Family: {case.gene_family}")
if case.species:
parts.append(f"Species: {case.species}")
if case.workflow:
parts.append("Workflow:")
for i, step in enumerate(case.workflow, 1):
parts.append(f" {i}. {step.get('tool', 'unknown')}: {step.get('description', '')}")
return "\n".join(parts)
async def get_stats(self) -> MemoryStats:
return MemoryStats(
session_count=len(self.session._sessions),
case_count=len(await self.case.list_by_status("completed")),
knowledge_count=len(self.knowledge._entries),
)
async def clear_all(self) -> None:
await self.session.clear()
await self.case.clear()
await self.knowledge.clear()