diff --git a/.env b/.env index f218b889..fdfe9c80 100644 --- a/.env +++ b/.env @@ -4,7 +4,7 @@ ENVIRONMENT=dev DB_HOST=localhost DB_USER=postgres DB_PORT=5432 -DB_PASSWORD=admin +DB_PASSWORD=quick DB_NAME=QuickGpt SUPER_ADMIN_EMAIL=superadmin@email.com diff --git a/alembic/versions/0d24376ef104_update.py b/alembic/versions/0d24376ef104_update.py deleted file mode 100644 index bdde4435..00000000 --- a/alembic/versions/0d24376ef104_update.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Update - -Revision ID: 0d24376ef104 -Revises: -Create Date: 2024-04-09 15:42:56.729951 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '0d24376ef104' -down_revision: Union[str, None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - # ### end Alembic commands ### - pass - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - # ### end Alembic commands ### - pass diff --git a/alembic/versions/5f1c1d3934a1_changes_content_to_json.py b/alembic/versions/5f1c1d3934a1_changes_content_to_json.py deleted file mode 100644 index e626aa07..00000000 --- a/alembic/versions/5f1c1d3934a1_changes_content_to_json.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Changes content to json - -Revision ID: 5f1c1d3934a1 -Revises: eb18396f592a -Create Date: 2024-04-07 12:29:18.009919 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '5f1c1d3934a1' -down_revision: Union[str, None] = 'eb18396f592a' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.alter_column('chat_items', 'content', - existing_type=sa.TEXT(), - type_=sa.JSON(), - existing_nullable=True, - ) - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - op.alter_column('chat_items', 'content', - existing_type=sa.JSON(), - type_=sa.TEXT(), - existing_nullable=True) - # ### end Alembic commands ### diff --git a/alembic/versions/9957402017dc_create_chat_history_and_items.py b/alembic/versions/9957402017dc_create_chat_history_and_items.py deleted file mode 100644 index cfe73bf9..00000000 --- a/alembic/versions/9957402017dc_create_chat_history_and_items.py +++ /dev/null @@ -1,52 +0,0 @@ -"""create chat history and items - -Revision ID: 9957402017dc -Revises: -Create Date: 2024-04-04 11:31:53.261330 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '9957402017dc' -down_revision: Union[str, None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('chat_history', - sa.Column('conversation_id', sa.UUID(), nullable=False), - sa.Column('title', sa.String(length=255), nullable=True), - sa.Column('created_at', sa.DateTime(), nullable=True), - sa.Column('updated_at', sa.DateTime(), nullable=True), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), - sa.PrimaryKeyConstraint('conversation_id') - ) - op.create_table('chat_items', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('sender', sa.String(length=225), nullable=False), - sa.Column('content', sa.Text(), nullable=True), - sa.Column('created_at', sa.DateTime(), nullable=True), - sa.Column('updated_at', sa.DateTime(), nullable=True), - sa.Column('like', sa.Boolean(), nullable=True), - sa.Column('conversation_id', sa.UUID(), nullable=False), - sa.ForeignKeyConstraint(['conversation_id'], ['chat_history.conversation_id'], ), - sa.PrimaryKeyConstraint('id') - ) - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - op.drop_table('chat_items') - op.drop_table('chat_history') - # ### end Alembic commands ### diff --git a/alembic/versions/57167fd38273_changes.py b/alembic/versions/bdfec4101648_added_chat_items.py similarity index 94% rename from alembic/versions/57167fd38273_changes.py rename to alembic/versions/bdfec4101648_added_chat_items.py index 2c873c50..fec2fbc6 100644 --- a/alembic/versions/57167fd38273_changes.py +++ b/alembic/versions/bdfec4101648_added_chat_items.py @@ -1,8 +1,8 @@ -"""Changes +"""Added chat items -Revision ID: 57167fd38273 +Revision ID: bdfec4101648 Revises: -Create Date: 2024-04-07 12:33:40.975147 +Create Date: 2024-04-09 15:55:47.769162 """ from typing import Sequence, Union @@ -12,7 +12,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision: str = '57167fd38273' +revision: str = 'bdfec4101648' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None diff --git a/alembic/versions/eb18396f592a_create_title_event.py b/alembic/versions/eb18396f592a_create_title_event.py deleted file mode 100644 index 9e0a5b3b..00000000 --- a/alembic/versions/eb18396f592a_create_title_event.py +++ /dev/null @@ -1,32 +0,0 @@ -"""create title event - -Revision ID: eb18396f592a -Revises: 9957402017dc -Create Date: 2024-04-04 11:47:55.600187 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'eb18396f592a' -down_revision: Union[str, None] = '9957402017dc' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('chat_history', sa.Column('_title_generated', sa.Boolean(), nullable=True)) - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - op.drop_column('chat_history', '_title_generated') - # ### end Alembic commands ### diff --git a/private_gpt/server/completions/completions_router.py b/private_gpt/server/completions/completions_router.py index 1aba0eb4..448d5116 100644 --- a/private_gpt/server/completions/completions_router.py +++ b/private_gpt/server/completions/completions_router.py @@ -1,6 +1,6 @@ from private_gpt.users import crud, models, schemas import itertools -from llama_index.llms import ChatMessage, ChatResponse, MessageRole +from llama_index.core.llms import ChatMessage, ChatResponse, MessageRole from fastapi import APIRouter, Depends, Request, Security, HTTPException, status from private_gpt.server.ingest.ingest_service import IngestService from pydantic import BaseModel diff --git a/private_gpt/users/api/v1/routers/chat_histories.py b/private_gpt/users/api/v1/routers/chat_histories.py deleted file mode 100644 index b0e13a2a..00000000 --- a/private_gpt/users/api/v1/routers/chat_histories.py +++ /dev/null @@ -1,154 +0,0 @@ -import logging -import traceback - -from sqlalchemy.orm import Session -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -from fastapi import APIRouter, Depends, HTTPException, status, Security - -from private_gpt.users.api import deps -from private_gpt.users.constants.role import Role -from private_gpt.users import crud, models, schemas - -logger = logging.getLogger(__name__) -router = APIRouter(prefix="/c", tags=["Chat Histories"]) - - -@router.get("", response_model=list[schemas.ChatBase]) -def list_chat_histories( - db: Session = Depends(deps.get_db), - skip: int = 0, - limit: int = 100, - current_user: models.User = Security( - deps.get_current_user, - ), -) -> list[schemas.ChatBase]: - """ - Retrieve a list of chat histories with pagination support. - """ - try: - chat_histories = crud.chat.get_multi( - db, skip=skip, limit=limit, user_id=current_user.id) - return chat_histories - except Exception as e: - print(traceback.format_exc()) - logger.error(f"Error listing chat histories: {str(e)}") - raise HTTPException( - status_code=500, - detail="Internal Server Error", - ) - - -@router.post("/create", response_model=schemas.ChatBase) -def create_chat_history( - chat_history_in: schemas.ChatCreate, - db: Session = Depends(deps.get_db), - current_user: models.User = Security( - deps.get_current_user, - ), -) -> schemas.ChatBase: - """ - Create a new chat history - """ - try: - chat_history = crud.chat.create( - db=db, obj_in=chat_history_in, user_id=current_user.id) - return chat_history - except Exception as e: - print(traceback.format_exc()) - logger.error(f"Error creating chat history: {str(e)}") - raise HTTPException( - status_code=500, - detail="Internal Server Error", - ) - - -@router.get("/{chat_history_id}", response_model=schemas.ChatMessages) -def read_chat_history( - chat_history_id: int, - db: Session = Depends(deps.get_db), - current_user: models.User = Security( - deps.get_current_user, - ), -) -> schemas.ChatMessages: - """ - Read a chat history by ID - """ - try: - chat_history = crud.chat.get_by_id(db, id=chat_history_id) - if chat_history is None or chat_history.user_id != current_user.id: - raise HTTPException( - status_code=404, detail="Chat history not found") - return chat_history - except Exception as e: - print(traceback.format_exc()) - logger.error(f"Error reading chat history: {str(e)}") - raise HTTPException( - status_code=500, - detail="Internal Server Error", - ) - - -@router.post("/conversation", response_model=schemas.ChatHistory) -def conversation( - chat_history_in: schemas.ChatUpdate, - db: Session = Depends(deps.get_db), - current_user: models.User = Security( - deps.get_current_user, - ), -) -> schemas.ChatHistory: - """ - Update a chat history by ID - """ - try: - chat_history = crud.chat.get_by_id( - db, id=chat_history_in.conversation_id) - if chat_history is None or chat_history.user_id != current_user.id: - raise HTTPException( - status_code=404, detail="Chat history not found") - - updated_chat_history = crud.chat.update_messages( - db=db, db_obj=chat_history, obj_in=chat_history_in) - - return updated_chat_history - except Exception as e: - print(traceback.format_exc()) - logger.error(f"Error updating chat history: {str(e)}") - raise HTTPException( - status_code=500, - detail="Internal Server Error", - ) - - -@router.post("/delete") -def delete_chat_history( - chat_history_in: schemas.ChatDelete, - db: Session = Depends(deps.get_db), - current_user: models.User = Security( - deps.get_current_user, - ), -): - """ - Delete a chat history by ID - """ - try: - chat_history_id = chat_history_in.id - chat_history = crud.chat.get(db, id=chat_history_id) - if chat_history is None or chat_history.user_id != current_user.id: - raise HTTPException( - status_code=404, detail="Chat history not found") - - crud.chat.remove(db=db, id=chat_history_id) - return JSONResponse( - status_code=status.HTTP_200_OK, - content={ - "message": "Chat history deleted successfully", - }, - ) - except Exception as e: - print(traceback.format_exc()) - logger.error(f"Error deleting chat history: {str(e)}") - raise HTTPException( - status_code=500, - detail="Internal Server Error", - ) diff --git a/private_gpt/users/api/v1/routers/chat_history.py b/private_gpt/users/api/v1/routers/chat_history.py index 0fdf20a4..b0a0a0d2 100644 --- a/private_gpt/users/api/v1/routers/chat_history.py +++ b/private_gpt/users/api/v1/routers/chat_history.py @@ -102,7 +102,7 @@ def delete_chat_history( """ try: chat_history_id = chat_history_in.conversation_id - chat_history = crud.chat.get(db, id=chat_history_id) + chat_history = crud.chat.get_by_id(db, id=chat_history_id) if chat_history is None or chat_history.user_id != current_user.id: raise HTTPException( status_code=404, detail="Chat history not found") diff --git a/private_gpt/users/models/chat.py b/private_gpt/users/models/chat.py index d67d52c6..79be7dfe 100644 --- a/private_gpt/users/models/chat.py +++ b/private_gpt/users/models/chat.py @@ -30,7 +30,7 @@ class ChatHistory(Base): def generate_title(self): user_chat_items = [ - item for item in self.chat_items if item.role == "user"] + item for item in self.chat_items if item.sender == "user"] if user_chat_items: first_user_chat_item = user_chat_items[0] self.title = first_user_chat_item.content[:30] diff --git a/private_gpt/users/models/chat_history.py b/private_gpt/users/models/chat_history.py deleted file mode 100644 index 1b468f79..00000000 --- a/private_gpt/users/models/chat_history.py +++ /dev/null @@ -1,39 +0,0 @@ -from datetime import datetime - -from sqlalchemy.orm import relationship -from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, JSON - -from private_gpt.users.db.base_class import Base - - -class ChatHistory(Base): - """Models a chat history table""" - - __tablename__ = "chat_history" - - id = Column(Integer, nullable=False, primary_key=True) - title = Column(String(255), nullable=False) - messages = Column(JSON, nullable=False) - created_at = Column(DateTime, default=datetime.now) - user_id = Column(Integer, ForeignKey("users.id")) - user = relationship("User", back_populates="chat_histories") - - def __init__(self, messages, user_id, *args, **kwargs): - super().__init__(*args, **kwargs) - self.messages = messages - self.user_id = user_id - self.title = self.generate_title() - - def generate_title(self): - if self.messages: - first_user_message = next(+ - (msg["message"] - for msg in self.messages if msg["sender"] == "user"), None - ) - if first_user_message: - return first_user_message[:30] - return "Untitled Chat" - - def __repr__(self): - """Returns string representation of model instance""" - return f"" diff --git a/private_gpt/users/schemas/chat_history.py b/private_gpt/users/schemas/chat_history.py deleted file mode 100644 index 236518a1..00000000 --- a/private_gpt/users/schemas/chat_history.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Optional, Dict, Any -from pydantic import BaseModel -from datetime import datetime - - -class ChatBase(BaseModel): - title: Optional[str] - -class ChatCreate(ChatBase): - user_id: int - messages: Optional[Dict[str, Any]] - -class ChatUpdate(ChatBase): - conversation_id: int - messages: Dict - - -class ChatDelete(BaseModel): - conversation_id: int - -class ChatMessages(BaseModel): - messages: Dict[str, Any] - -class Chat(ChatBase): - conversation_id: int - created_at: datetime - user_id: int - - class Config: - orm_mode = True diff --git a/settings.yaml b/settings.yaml index 8910af65..449e017c 100644 --- a/settings.yaml +++ b/settings.yaml @@ -45,8 +45,8 @@ llm: llamacpp: prompt_style: "chatml" - llm_hf_repo_id: TheBloke/OpenHermes-2.5-Mistral-7B-GGUF - llm_hf_model_file: openhermes-2.5-mistral-7b.Q5_K_M.gguf + llm_hf_repo_id: NousResearch/Hermes-2-Pro-Mistral-7B + llm_hf_model_file: NousResearch/Hermes-2-Pro-Mistral-7B-GGUF tfs_z: 1.0 # Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting top_k: 40 # Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative. (Default: 40) top_p: 0.9 # Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)