[docs]asyncdefupdate_agent_status(*,agent_id:str,status:str,activity:str,current_user_id:Optional[int]=None,current_topic_id:Optional[int]=None,papers_processed:int=0,papers_found:int=0,)->None:"""Update agent status. :param agent_id: Agent ID :param status: Agent status :param activity: Agent activity :param current_user_id: Current user ID :param current_topic_id: Current topic ID :param papers_processed: Papers processed count :param papers_found: Papers found count """try:asyncwithSessionLocal()assession:result=awaitsession.execute(select(AgentStatus).where(AgentStatus.agent_id==agent_id).order_by(AgentStatus.id.desc()))agent_status=result.scalars().first()ifagent_statusisNone:agent_status=AgentStatus(agent_id=agent_id,status=status,activity=activity,current_user_id=current_user_id,current_topic_id=current_topic_id,papers_processed=papers_processed,papers_found=papers_found,session_start=datetime.now(),)session.add(agent_status)else:agent_status.status=statusagent_status.activity=activityagent_status.current_user_id=current_user_idagent_status.current_topic_id=current_topic_idagent_status.papers_processed=papers_processedagent_status.papers_found=papers_foundagent_status.last_activity=datetime.now()agent_status.updated_at=datetime.now()awaitsession.commit()exceptException:# Avoid propagating exceptions from background status updatesimporttracebacktraceback.print_exc()
[docs]asyncdefget_agent_status(agent_id:str)->Optional[AgentStatus]:"""Get agent status. :param agent_id: Agent ID :returns: AgentStatus instance or None """asyncwithSessionLocal()assession:result=awaitsession.execute(select(AgentStatus).where(AgentStatus.agent_id==agent_id).order_by(AgentStatus.id.desc()))returnresult.scalars().first()
[docs]asyncdefcount_analyses_for_user(user_id:int)->int:"""Count analyses for user. :param user_id: User ID :returns: Analysis count """asyncwithSessionLocal()assession:result=awaitsession.execute(select(func.count(PaperAnalysis.id)).join(ResearchTopic,PaperAnalysis.topic_id==ResearchTopic.id).where(ResearchTopic.user_id==user_id))returnint(result.scalar_one()or0)
[docs]asyncdefcount_relevant_analyses_for_user(user_id:int,min_overall:float)->int:"""Count relevant analyses for user. :param user_id: User ID :param min_overall: Minimum relevance score :returns: Relevant analysis count """asyncwithSessionLocal()assession:result=awaitsession.execute(select(func.count(PaperAnalysis.id)).join(ResearchTopic,PaperAnalysis.topic_id==ResearchTopic.id).where(and_(ResearchTopic.user_id==user_id,PaperAnalysis.relevance>=min_overall,)))returnint(result.scalar_one()or0)
[docs]asyncdeflist_recent_analyses_for_user(user_id:int,limit:int=5)->List[Tuple[PaperAnalysis,ArxivPaper]]:"""List recent analyses for user. :param user_id: User ID :param limit: Result limit :returns: List of (PaperAnalysis, ArxivPaper) tuples """asyncwithSessionLocal()assession:result=awaitsession.execute(select(PaperAnalysis,ArxivPaper).join(ArxivPaper,PaperAnalysis.paper_id==ArxivPaper.id).join(ResearchTopic,PaperAnalysis.topic_id==ResearchTopic.id).where(ResearchTopic.user_id==user_id).order_by(PaperAnalysis.created_at.desc()).limit(limit))rows=result.all()return[(row[0],row[1])forrowinrows]
[docs]asyncdefswap_user_active_topics(user_id:int)->Optional[ResearchTopic]:"""Swap user active topics. :param user_id: User ID :returns: ResearchTopic instance or None """asyncwithSessionLocal()assession:result=awaitsession.execute(select(ResearchTopic).where(and_(ResearchTopic.user_id==user_id,ResearchTopic.is_active)))topic=result.scalar_one_or_none()iftopicisNone:returnNoneold_target=topic.target_topictopic.target_topic=topic.search_areatopic.search_area=old_targettopic.updated_at=datetime.now()awaitsession.commit()awaitsession.refresh(topic)returntopic