Dama12 commited on
Commit
d2193b7
·
1 Parent(s): 2f9efc0

feat: complete memory system with Research Profile (Level 3)

Browse files
app/api/routes/analysis.py CHANGED
@@ -75,6 +75,7 @@ async def start_project_analysis(
75
  user_repo.deduct_credits(current_user, 50)
76
 
77
  request.user_id = str(current_user.id)
 
78
  target_project_id = project_id
79
 
80
  # If project_id is the "nil" UUID from frontend, use/create a real project for history
@@ -281,6 +282,7 @@ async def get_specific_analysis(
281
  k2_request = K2AnalysisRequest(
282
  documents=docs,
283
  user_id=str(current_user.id),
 
284
  reasoning_depth=depth,
285
  ethics_rigor=rigor,
286
  info_density=density
 
75
  user_repo.deduct_credits(current_user, 50)
76
 
77
  request.user_id = str(current_user.id)
78
+ request.user_profile = current_user.research_profile
79
  target_project_id = project_id
80
 
81
  # If project_id is the "nil" UUID from frontend, use/create a real project for history
 
282
  k2_request = K2AnalysisRequest(
283
  documents=docs,
284
  user_id=str(current_user.id),
285
+ user_profile=current_user.research_profile,
286
  reasoning_depth=depth,
287
  ethics_rigor=rigor,
288
  info_density=density
app/api/routes/users.py CHANGED
@@ -196,8 +196,26 @@ async def register_and_login(user: UserCreate, db: Session = Depends(get_db)):
196
  )
197
 
198
 
 
 
 
 
 
199
  @router.get("/me", response_model=UserResponse)
200
  async def get_current_user_info(current_user = Depends(get_current_user), db: Session = Depends(get_db)):
201
  """Récupère les infos de l'utilisateur courant et déclenche le refill journalier si nécessaire"""
202
  user_repo = UserRepository(db)
203
  return user_repo.check_and_refill_credits(current_user)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  )
197
 
198
 
199
+ from pydantic import BaseModel
200
+
201
+ class ProfileUpdate(BaseModel):
202
+ research_profile: str
203
+
204
  @router.get("/me", response_model=UserResponse)
205
  async def get_current_user_info(current_user = Depends(get_current_user), db: Session = Depends(get_db)):
206
  """Récupère les infos de l'utilisateur courant et déclenche le refill journalier si nécessaire"""
207
  user_repo = UserRepository(db)
208
  return user_repo.check_and_refill_credits(current_user)
209
+
210
+ @router.put("/me/profile", response_model=UserResponse)
211
+ async def update_research_profile(
212
+ profile_data: ProfileUpdate,
213
+ current_user = Depends(get_current_user),
214
+ db: Session = Depends(get_db)
215
+ ):
216
+ """Met à jour le profil de recherche de l'utilisateur"""
217
+ if current_user.id.hex.startswith("0000"):
218
+ raise HTTPException(status_code=400, detail="Cannot update profile in demo mode")
219
+
220
+ user_repo = UserRepository(db)
221
+ return user_repo.update_profile(current_user, profile_data.research_profile)
app/db/models/user.py CHANGED
@@ -21,6 +21,7 @@ class User(Base):
21
  role = Column(Text)
22
  credits = Column(Integer, default=2000)
23
  last_refill_date = Column(Date, default=datetime.utcnow().date())
 
24
  created_at = Column(DateTime, default=datetime.utcnow)
25
 
26
  # Relationships
 
21
  role = Column(Text)
22
  credits = Column(Integer, default=2000)
23
  last_refill_date = Column(Date, default=datetime.utcnow().date())
24
+ research_profile = Column(Text, nullable=True)
25
  created_at = Column(DateTime, default=datetime.utcnow)
26
 
27
  # Relationships
app/db/repositories/user_repo.py CHANGED
@@ -73,3 +73,11 @@ class UserRepository(BaseRepository[User, UserCreate, UserCreate]):
73
  self.db.refresh(user)
74
  return True
75
  return False
 
 
 
 
 
 
 
 
 
73
  self.db.refresh(user)
74
  return True
75
  return False
76
+
77
+ def update_profile(self, user: User, profile: str) -> User:
78
+ """Met à jour le profil de recherche de l'utilisateur"""
79
+ user.research_profile = profile
80
+ self.db.add(user)
81
+ self.db.commit()
82
+ self.db.refresh(user)
83
+ return user
app/main.py CHANGED
@@ -58,6 +58,13 @@ async def lifespan(app: FastAPI):
58
  with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as ddl_conn:
59
  ddl_conn.execute(text("UPDATE users SET credits = 2000 WHERE credits IS NULL"))
60
  logger.info("Backfilled NULL credits to 2000 for existing users.")
 
 
 
 
 
 
 
61
  except Exception as e:
62
  logger.warning(f"Auto-migration warning (non-fatal): {str(e)}")
63
 
 
58
  with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as ddl_conn:
59
  ddl_conn.execute(text("UPDATE users SET credits = 2000 WHERE credits IS NULL"))
60
  logger.info("Backfilled NULL credits to 2000 for existing users.")
61
+
62
+ # Check if 'research_profile' column exists
63
+ res_profile = conn.execute(text("SELECT column_name FROM information_schema.columns WHERE table_name='users' AND column_name='research_profile'")).fetchone()
64
+ if not res_profile:
65
+ with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as ddl_conn:
66
+ ddl_conn.execute(text("ALTER TABLE users ADD COLUMN research_profile TEXT"))
67
+ logger.info("Added 'research_profile' column to users table.")
68
  except Exception as e:
69
  logger.warning(f"Auto-migration warning (non-fatal): {str(e)}")
70
 
app/models/schemas.py CHANGED
@@ -119,6 +119,7 @@ class AnalysisRequest(BaseModel):
119
  """Requête d'analyse scientifique"""
120
  documents: List[ScientificDocument]
121
  user_id: Optional[str] = None
 
122
  user_notes: Optional[str] = None
123
 
124
  # Scientific Settings from UI
 
119
  """Requête d'analyse scientifique"""
120
  documents: List[ScientificDocument]
121
  user_id: Optional[str] = None
122
+ user_profile: Optional[str] = None
123
  user_notes: Optional[str] = None
124
 
125
  # Scientific Settings from UI
app/services/k2_think_engine.py CHANGED
@@ -118,6 +118,9 @@ Your core capability and primary directive is MULTI-DOCUMENT REASONING and KNOWL
118
  Do NOT just summarize individual papers. You MUST cross-reference, compare, and contrast the provided documents to uncover deeper strategic insights.
119
  {past_context_instruction}
120
 
 
 
 
121
  REASONING GUIDELINES:
122
  - DEPTH: {depth_instruction}
123
  - ETHICS: {ethics_instruction}
 
118
  Do NOT just summarize individual papers. You MUST cross-reference, compare, and contrast the provided documents to uncover deeper strategic insights.
119
  {past_context_instruction}
120
 
121
+ GLOBAL RESEARCHER PROFILE & OBJECTIVES (Apply these filters to your strategy):
122
+ {request.user_profile if request.user_profile else "General scientific investigation without specific profile constraints."}
123
+
124
  REASONING GUIDELINES:
125
  - DEPTH: {depth_instruction}
126
  - ETHICS: {ethics_instruction}