mirror of
https://github.com/imartinez/privateGPT.git
synced 2025-06-29 00:37:06 +00:00
Updated the title for chat history
This commit is contained in:
parent
a59782e24e
commit
44d94e145e
2
.env
2
.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
|
||||
|
@ -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
|
@ -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 ###
|
@ -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 ###
|
@ -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
|
@ -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 ###
|
@ -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
|
||||
|
@ -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",
|
||||
)
|
@ -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")
|
||||
|
@ -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]
|
||||
|
@ -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"<ChatHistory {self.id!r}>"
|
@ -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
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user