diff --git a/ai-hub/app/api/routes/sessions.py b/ai-hub/app/api/routes/sessions.py index e54e16e..4708132 100644 --- a/ai-hub/app/api/routes/sessions.py +++ b/ai-hub/app/api/routes/sessions.py @@ -24,7 +24,9 @@ db=db, user_id=request.user_id, provider_name=request.provider_name, - feature_name=request.feature_name + feature_name=request.feature_name, + stt_provider_name=request.stt_provider_name, + tts_provider_name=request.tts_provider_name ) return new_session except Exception as e: @@ -139,6 +141,10 @@ session.title = session_update.title if session_update.provider_name is not None: session.provider_name = session_update.provider_name + if session_update.stt_provider_name is not None: + session.stt_provider_name = session_update.stt_provider_name + if session_update.tts_provider_name is not None: + session.tts_provider_name = session_update.tts_provider_name db.commit() db.refresh(session) diff --git a/ai-hub/app/api/schemas.py b/ai-hub/app/api/schemas.py index 58b1412..ba307c1 100644 --- a/ai-hub/app/api/schemas.py +++ b/ai-hub/app/api/schemas.py @@ -130,11 +130,15 @@ """Defines the shape for starting a new conversation session.""" user_id: str provider_name: str = "deepseek" + stt_provider_name: Optional[str] = None + tts_provider_name: Optional[str] = None feature_name: Optional[str] = "default" class SessionUpdate(BaseModel): title: Optional[str] = None provider_name: Optional[str] = None + stt_provider_name: Optional[str] = None + tts_provider_name: Optional[str] = None class Session(BaseModel): """Defines the shape of a session object returned by the API.""" @@ -142,6 +146,8 @@ user_id: str title: str provider_name: str + stt_provider_name: Optional[str] = None + tts_provider_name: Optional[str] = None feature_name: str created_at: datetime model_config = ConfigDict(from_attributes=True) diff --git a/ai-hub/app/core/services/session.py b/ai-hub/app/core/services/session.py index 5f93d90..cff6a72 100644 --- a/ai-hub/app/core/services/session.py +++ b/ai-hub/app/core/services/session.py @@ -8,7 +8,15 @@ def __init__(self): pass - def create_session(self, db: Session, user_id: str, provider_name: str, feature_name: str = "default") -> models.Session: + def create_session( + self, + db: Session, + user_id: str, + provider_name: str, + feature_name: str = "default", + stt_provider_name: str = None, + tts_provider_name: str = None + ) -> models.Session: """ Creates a new chat session in the database. @@ -25,7 +33,14 @@ SQLAlchemyError: If a database error occurs during session creation. """ try: - new_session = models.Session(user_id=user_id, provider_name=provider_name, feature_name=feature_name, title=f"New Chat Session") + new_session = models.Session( + user_id=user_id, + provider_name=provider_name, + stt_provider_name=stt_provider_name, + tts_provider_name=tts_provider_name, + feature_name=feature_name, + title=f"New Chat Session" + ) db.add(new_session) db.commit() db.refresh(new_session) diff --git a/ai-hub/app/db/migrate.py b/ai-hub/app/db/migrate.py index 625b5c3..557c8ac 100644 --- a/ai-hub/app/db/migrate.py +++ b/ai-hub/app/db/migrate.py @@ -39,6 +39,24 @@ else: logger.info(f"Column '{col_name}' already exists in 'messages'.") + # Session table migrations + session_columns = [c["name"] for c in inspector.get_columns("sessions")] + session_required_columns = [ + ("stt_provider_name", "TEXT"), + ("tts_provider_name", "TEXT") + ] + for col_name, col_type in session_required_columns: + if col_name not in session_columns: + logger.info(f"Adding column '{col_name}' to 'sessions' table...") + try: + conn.execute(text(f"ALTER TABLE sessions ADD COLUMN {col_name} {col_type}")) + conn.commit() + logger.info(f"Successfully added '{col_name}'.") + except Exception as e: + logger.error(f"Failed to add column '{col_name}': {e}") + else: + logger.info(f"Column '{col_name}' already exists in 'sessions'.") + logger.info("Database migrations complete.") if __name__ == "__main__": diff --git a/ai-hub/app/db/models.py b/ai-hub/app/db/models.py index f94df2b..08cc446 100644 --- a/ai-hub/app/db/models.py +++ b/ai-hub/app/db/models.py @@ -85,6 +85,9 @@ title = Column(String, index=True, nullable=True) # The name of the LLM model used for this session (e.g., "Gemini", "DeepSeek"). provider_name = Column(String, nullable=True) + # Track STT and TTS providers used in this session context + stt_provider_name = Column(String, nullable=True) + tts_provider_name = Column(String, nullable=True) # The feature namespace this session belongs to (e.g., "coding_assistant"). feature_name = Column(String, default="default", nullable=False) # Timestamp for when the session was created. diff --git a/ui/client-app/src/components/SessionSidebar.js b/ui/client-app/src/components/SessionSidebar.js index 93f419a..964b02d 100644 --- a/ui/client-app/src/components/SessionSidebar.js +++ b/ui/client-app/src/components/SessionSidebar.js @@ -106,12 +106,15 @@ ? s.title : `Session #${s.id}`; - const configInfo = s.provider_name ? `AI Model: ${s.provider_name}` : 'Default AI Configuration'; + const llmInfo = s.provider_name ? `LLM: ${s.provider_name}` : 'LLM: Default'; + const sttInfo = s.stt_provider_name ? `STT: ${s.stt_provider_name}` : 'STT: Default'; + const ttsInfo = s.tts_provider_name ? `TTS: ${s.tts_provider_name}` : 'TTS: Default'; + const usageInfo = td ? `Context: ${td.token_count.toLocaleString()} / ${td.token_limit.toLocaleString()} tokens (${td.percentage}%)` : 'Hover to load token usage stats'; - const tooltip = `${displayTitle}\n---\n${configInfo}\n${usageInfo}`; + const tooltip = `${displayTitle}\n---\n${llmInfo}\n${sttInfo}\n${ttsInfo}\n---\n${usageInfo}`; return (