mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-06-22 22:11:03 +02:00
Session id: int -> UUID (#2814)
* session id: int -> UUID * nit * validated * validated downgrade + upgrade + all functionality * nit * minor nit * fix test case
This commit is contained in:
parent
f3fb7c572e
commit
db0779dd02
@ -0,0 +1,153 @@
|
|||||||
|
"""
|
||||||
|
Revision ID: 6756efa39ada
|
||||||
|
Revises: 5d12a446f5c0
|
||||||
|
Create Date: 2024-10-15 17:47:44.108537
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
revision = "6756efa39ada"
|
||||||
|
down_revision = "5d12a446f5c0"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
"""
|
||||||
|
Migrate chat_session and chat_message tables to use UUID primary keys.
|
||||||
|
|
||||||
|
This script:
|
||||||
|
1. Adds UUID columns to chat_session and chat_message
|
||||||
|
2. Populates new columns with UUIDs
|
||||||
|
3. Updates foreign key relationships
|
||||||
|
4. Removes old integer ID columns
|
||||||
|
|
||||||
|
Note: Downgrade will assign new integer IDs, not restore original ones.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
op.execute("CREATE EXTENSION IF NOT EXISTS pgcrypto;")
|
||||||
|
|
||||||
|
op.add_column(
|
||||||
|
"chat_session",
|
||||||
|
sa.Column(
|
||||||
|
"new_id",
|
||||||
|
sa.UUID(as_uuid=True),
|
||||||
|
server_default=sa.text("gen_random_uuid()"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
op.execute("UPDATE chat_session SET new_id = gen_random_uuid();")
|
||||||
|
|
||||||
|
op.add_column(
|
||||||
|
"chat_message",
|
||||||
|
sa.Column("new_chat_session_id", sa.UUID(as_uuid=True), nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
op.execute(
|
||||||
|
"""
|
||||||
|
UPDATE chat_message
|
||||||
|
SET new_chat_session_id = cs.new_id
|
||||||
|
FROM chat_session cs
|
||||||
|
WHERE chat_message.chat_session_id = cs.id;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
op.drop_constraint(
|
||||||
|
"chat_message_chat_session_id_fkey", "chat_message", type_="foreignkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.drop_column("chat_message", "chat_session_id")
|
||||||
|
op.alter_column(
|
||||||
|
"chat_message", "new_chat_session_id", new_column_name="chat_session_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.drop_constraint("chat_session_pkey", "chat_session", type_="primary")
|
||||||
|
op.drop_column("chat_session", "id")
|
||||||
|
op.alter_column("chat_session", "new_id", new_column_name="id")
|
||||||
|
|
||||||
|
op.create_primary_key("chat_session_pkey", "chat_session", ["id"])
|
||||||
|
|
||||||
|
op.create_foreign_key(
|
||||||
|
"chat_message_chat_session_id_fkey",
|
||||||
|
"chat_message",
|
||||||
|
"chat_session",
|
||||||
|
["chat_session_id"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
op.drop_constraint(
|
||||||
|
"chat_message_chat_session_id_fkey", "chat_message", type_="foreignkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.add_column(
|
||||||
|
"chat_session",
|
||||||
|
sa.Column("old_id", sa.Integer, autoincrement=True, nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
op.execute("CREATE SEQUENCE chat_session_old_id_seq OWNED BY chat_session.old_id;")
|
||||||
|
op.execute(
|
||||||
|
"ALTER TABLE chat_session ALTER COLUMN old_id SET DEFAULT nextval('chat_session_old_id_seq');"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.execute(
|
||||||
|
"UPDATE chat_session SET old_id = nextval('chat_session_old_id_seq') WHERE old_id IS NULL;"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.alter_column("chat_session", "old_id", nullable=False)
|
||||||
|
|
||||||
|
op.drop_constraint("chat_session_pkey", "chat_session", type_="primary")
|
||||||
|
op.create_primary_key("chat_session_pkey", "chat_session", ["old_id"])
|
||||||
|
|
||||||
|
op.add_column(
|
||||||
|
"chat_message",
|
||||||
|
sa.Column("old_chat_session_id", sa.Integer, nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
op.execute(
|
||||||
|
"""
|
||||||
|
UPDATE chat_message
|
||||||
|
SET old_chat_session_id = cs.old_id
|
||||||
|
FROM chat_session cs
|
||||||
|
WHERE chat_message.chat_session_id = cs.id;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
op.drop_column("chat_message", "chat_session_id")
|
||||||
|
op.alter_column(
|
||||||
|
"chat_message", "old_chat_session_id", new_column_name="chat_session_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_foreign_key(
|
||||||
|
"chat_message_chat_session_id_fkey",
|
||||||
|
"chat_message",
|
||||||
|
"chat_session",
|
||||||
|
["chat_session_id"],
|
||||||
|
["old_id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
|
||||||
|
op.drop_column("chat_session", "id")
|
||||||
|
op.alter_column("chat_session", "old_id", new_column_name="id")
|
||||||
|
|
||||||
|
op.alter_column(
|
||||||
|
"chat_session",
|
||||||
|
"id",
|
||||||
|
type_=sa.Integer(),
|
||||||
|
existing_type=sa.Integer(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Rename the sequence
|
||||||
|
op.execute("ALTER SEQUENCE chat_session_old_id_seq RENAME TO chat_session_id_seq;")
|
||||||
|
|
||||||
|
# Update the default value to use the renamed sequence
|
||||||
|
op.alter_column(
|
||||||
|
"chat_session",
|
||||||
|
"id",
|
||||||
|
server_default=sa.text("nextval('chat_session_id_seq'::regclass)"),
|
||||||
|
)
|
@ -1,5 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi.datastructures import Headers
|
from fastapi.datastructures import Headers
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@ -34,7 +35,7 @@ def llm_doc_from_inference_section(inference_section: InferenceSection) -> LlmDo
|
|||||||
|
|
||||||
|
|
||||||
def create_chat_chain(
|
def create_chat_chain(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
prefetch_tool_calls: bool = True,
|
prefetch_tool_calls: bool = True,
|
||||||
# Optional id at which we finish processing
|
# Optional id at which we finish processing
|
||||||
|
@ -43,7 +43,7 @@ logger = setup_logger()
|
|||||||
|
|
||||||
|
|
||||||
def get_chat_session_by_id(
|
def get_chat_session_by_id(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
user_id: UUID | None,
|
user_id: UUID | None,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
include_deleted: bool = False,
|
include_deleted: bool = False,
|
||||||
@ -87,9 +87,9 @@ def get_chat_sessions_by_slack_thread_id(
|
|||||||
|
|
||||||
|
|
||||||
def get_valid_messages_from_query_sessions(
|
def get_valid_messages_from_query_sessions(
|
||||||
chat_session_ids: list[int],
|
chat_session_ids: list[UUID],
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
) -> dict[int, str]:
|
) -> dict[UUID, str]:
|
||||||
user_message_subquery = (
|
user_message_subquery = (
|
||||||
select(
|
select(
|
||||||
ChatMessage.chat_session_id, func.min(ChatMessage.id).label("user_msg_id")
|
ChatMessage.chat_session_id, func.min(ChatMessage.id).label("user_msg_id")
|
||||||
@ -196,7 +196,7 @@ def delete_orphaned_search_docs(db_session: Session) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def delete_messages_and_files_from_chat_session(
|
def delete_messages_and_files_from_chat_session(
|
||||||
chat_session_id: int, db_session: Session
|
chat_session_id: UUID, db_session: Session
|
||||||
) -> None:
|
) -> None:
|
||||||
# Select messages older than cutoff_time with files
|
# Select messages older than cutoff_time with files
|
||||||
messages_with_files = db_session.execute(
|
messages_with_files = db_session.execute(
|
||||||
@ -253,7 +253,7 @@ def create_chat_session(
|
|||||||
def update_chat_session(
|
def update_chat_session(
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
user_id: UUID | None,
|
user_id: UUID | None,
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
description: str | None = None,
|
description: str | None = None,
|
||||||
sharing_status: ChatSessionSharedStatus | None = None,
|
sharing_status: ChatSessionSharedStatus | None = None,
|
||||||
) -> ChatSession:
|
) -> ChatSession:
|
||||||
@ -276,7 +276,7 @@ def update_chat_session(
|
|||||||
|
|
||||||
def delete_chat_session(
|
def delete_chat_session(
|
||||||
user_id: UUID | None,
|
user_id: UUID | None,
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
hard_delete: bool = HARD_DELETE_CHATS,
|
hard_delete: bool = HARD_DELETE_CHATS,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -337,7 +337,7 @@ def get_chat_message(
|
|||||||
|
|
||||||
|
|
||||||
def get_chat_messages_by_sessions(
|
def get_chat_messages_by_sessions(
|
||||||
chat_session_ids: list[int],
|
chat_session_ids: list[UUID],
|
||||||
user_id: UUID | None,
|
user_id: UUID | None,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
skip_permission_check: bool = False,
|
skip_permission_check: bool = False,
|
||||||
@ -370,7 +370,7 @@ def get_search_docs_for_chat_message(
|
|||||||
|
|
||||||
|
|
||||||
def get_chat_messages_by_session(
|
def get_chat_messages_by_session(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
user_id: UUID | None,
|
user_id: UUID | None,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
skip_permission_check: bool = False,
|
skip_permission_check: bool = False,
|
||||||
@ -397,7 +397,7 @@ def get_chat_messages_by_session(
|
|||||||
|
|
||||||
|
|
||||||
def get_or_create_root_message(
|
def get_or_create_root_message(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
) -> ChatMessage:
|
) -> ChatMessage:
|
||||||
try:
|
try:
|
||||||
@ -433,7 +433,7 @@ def get_or_create_root_message(
|
|||||||
|
|
||||||
def reserve_message_id(
|
def reserve_message_id(
|
||||||
db_session: Session,
|
db_session: Session,
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
parent_message: int,
|
parent_message: int,
|
||||||
message_type: MessageType,
|
message_type: MessageType,
|
||||||
) -> int:
|
) -> int:
|
||||||
@ -460,7 +460,7 @@ def reserve_message_id(
|
|||||||
|
|
||||||
|
|
||||||
def create_new_chat_message(
|
def create_new_chat_message(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
parent_message: ChatMessage,
|
parent_message: ChatMessage,
|
||||||
message: str,
|
message: str,
|
||||||
prompt_id: int | None,
|
prompt_id: int | None,
|
||||||
|
@ -5,9 +5,12 @@ from typing import Any
|
|||||||
from typing import Literal
|
from typing import Literal
|
||||||
from typing import NotRequired
|
from typing import NotRequired
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from uuid import uuid4
|
||||||
from typing_extensions import TypedDict # noreorder
|
from typing_extensions import TypedDict # noreorder
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID as PGUUID
|
||||||
|
|
||||||
from fastapi_users_db_sqlalchemy import SQLAlchemyBaseOAuthAccountTableUUID
|
from fastapi_users_db_sqlalchemy import SQLAlchemyBaseOAuthAccountTableUUID
|
||||||
from fastapi_users_db_sqlalchemy import SQLAlchemyBaseUserTableUUID
|
from fastapi_users_db_sqlalchemy import SQLAlchemyBaseUserTableUUID
|
||||||
from fastapi_users_db_sqlalchemy.access_token import SQLAlchemyBaseAccessTokenTableUUID
|
from fastapi_users_db_sqlalchemy.access_token import SQLAlchemyBaseAccessTokenTableUUID
|
||||||
@ -920,7 +923,9 @@ class ToolCall(Base):
|
|||||||
class ChatSession(Base):
|
class ChatSession(Base):
|
||||||
__tablename__ = "chat_session"
|
__tablename__ = "chat_session"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[UUID] = mapped_column(
|
||||||
|
PGUUID(as_uuid=True), primary_key=True, default=uuid4
|
||||||
|
)
|
||||||
user_id: Mapped[UUID | None] = mapped_column(
|
user_id: Mapped[UUID | None] = mapped_column(
|
||||||
ForeignKey("user.id", ondelete="CASCADE"), nullable=True
|
ForeignKey("user.id", ondelete="CASCADE"), nullable=True
|
||||||
)
|
)
|
||||||
@ -990,7 +995,9 @@ class ChatMessage(Base):
|
|||||||
__tablename__ = "chat_message"
|
__tablename__ = "chat_message"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
chat_session_id: Mapped[int] = mapped_column(ForeignKey("chat_session.id"))
|
chat_session_id: Mapped[UUID] = mapped_column(
|
||||||
|
PGUUID(as_uuid=True), ForeignKey("chat_session.id")
|
||||||
|
)
|
||||||
|
|
||||||
alternate_assistant_id = mapped_column(
|
alternate_assistant_id = mapped_column(
|
||||||
Integer, ForeignKey("persona.id"), nullable=True
|
Integer, ForeignKey("persona.id"), nullable=True
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from danswer.server.query_and_chat.models import ChatSessionDetails
|
from danswer.server.query_and_chat.models import ChatSessionDetails
|
||||||
@ -23,7 +25,7 @@ class FolderUpdateRequest(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class FolderChatSessionRequest(BaseModel):
|
class FolderChatSessionRequest(BaseModel):
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
|
|
||||||
|
|
||||||
class DeleteFolderOptions(BaseModel):
|
class DeleteFolderOptions(BaseModel):
|
||||||
|
@ -4,6 +4,7 @@ import uuid
|
|||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
@ -131,7 +132,7 @@ def update_chat_session_model(
|
|||||||
|
|
||||||
@router.get("/get-chat-session/{session_id}")
|
@router.get("/get-chat-session/{session_id}")
|
||||||
def get_chat_session(
|
def get_chat_session(
|
||||||
session_id: int,
|
session_id: UUID,
|
||||||
is_shared: bool = False,
|
is_shared: bool = False,
|
||||||
user: User | None = Depends(current_user),
|
user: User | None = Depends(current_user),
|
||||||
db_session: Session = Depends(get_session),
|
db_session: Session = Depends(get_session),
|
||||||
@ -254,7 +255,7 @@ def rename_chat_session(
|
|||||||
|
|
||||||
@router.patch("/chat-session/{session_id}")
|
@router.patch("/chat-session/{session_id}")
|
||||||
def patch_chat_session(
|
def patch_chat_session(
|
||||||
session_id: int,
|
session_id: UUID,
|
||||||
chat_session_update_req: ChatSessionUpdateRequest,
|
chat_session_update_req: ChatSessionUpdateRequest,
|
||||||
user: User | None = Depends(current_user),
|
user: User | None = Depends(current_user),
|
||||||
db_session: Session = Depends(get_session),
|
db_session: Session = Depends(get_session),
|
||||||
@ -271,7 +272,7 @@ def patch_chat_session(
|
|||||||
|
|
||||||
@router.delete("/delete-chat-session/{session_id}")
|
@router.delete("/delete-chat-session/{session_id}")
|
||||||
def delete_chat_session_by_id(
|
def delete_chat_session_by_id(
|
||||||
session_id: int,
|
session_id: UUID,
|
||||||
user: User | None = Depends(current_user),
|
user: User | None = Depends(current_user),
|
||||||
db_session: Session = Depends(get_session),
|
db_session: Session = Depends(get_session),
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic import model_validator
|
from pydantic import model_validator
|
||||||
@ -34,7 +35,7 @@ class SimpleQueryRequest(BaseModel):
|
|||||||
|
|
||||||
class UpdateChatSessionThreadRequest(BaseModel):
|
class UpdateChatSessionThreadRequest(BaseModel):
|
||||||
# If not specified, use Danswer default persona
|
# If not specified, use Danswer default persona
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
new_alternate_model: str
|
new_alternate_model: str
|
||||||
|
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ class ChatSessionCreationRequest(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class CreateChatSessionID(BaseModel):
|
class CreateChatSessionID(BaseModel):
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
|
|
||||||
|
|
||||||
class ChatFeedbackRequest(BaseModel):
|
class ChatFeedbackRequest(BaseModel):
|
||||||
@ -75,7 +76,7 @@ Currently the different branches are generated by changing the search query
|
|||||||
class CreateChatMessageRequest(ChunkContext):
|
class CreateChatMessageRequest(ChunkContext):
|
||||||
"""Before creating messages, be sure to create a chat_session and get an id"""
|
"""Before creating messages, be sure to create a chat_session and get an id"""
|
||||||
|
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
# This is the primary-key (unique identifier) for the previous message of the tree
|
# This is the primary-key (unique identifier) for the previous message of the tree
|
||||||
parent_message_id: int | None
|
parent_message_id: int | None
|
||||||
# New message contents
|
# New message contents
|
||||||
@ -115,13 +116,18 @@ class CreateChatMessageRequest(ChunkContext):
|
|||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def model_dump(self, *args: Any, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
data = super().model_dump(*args, **kwargs)
|
||||||
|
data["chat_session_id"] = str(data["chat_session_id"])
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class ChatMessageIdentifier(BaseModel):
|
class ChatMessageIdentifier(BaseModel):
|
||||||
message_id: int
|
message_id: int
|
||||||
|
|
||||||
|
|
||||||
class ChatRenameRequest(BaseModel):
|
class ChatRenameRequest(BaseModel):
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
name: str | None = None
|
name: str | None = None
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +140,7 @@ class RenameChatSessionResponse(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class ChatSessionDetails(BaseModel):
|
class ChatSessionDetails(BaseModel):
|
||||||
id: int
|
id: UUID
|
||||||
name: str
|
name: str
|
||||||
persona_id: int | None = None
|
persona_id: int | None = None
|
||||||
time_created: str
|
time_created: str
|
||||||
@ -175,7 +181,7 @@ class ChatMessageDetail(BaseModel):
|
|||||||
overridden_model: str | None
|
overridden_model: str | None
|
||||||
alternate_assistant_id: int | None = None
|
alternate_assistant_id: int | None = None
|
||||||
# Dict mapping citation number to db_doc_id
|
# Dict mapping citation number to db_doc_id
|
||||||
chat_session_id: int | None = None
|
chat_session_id: UUID | None = None
|
||||||
citations: dict[int, int] | None = None
|
citations: dict[int, int] | None = None
|
||||||
files: list[FileDescriptor]
|
files: list[FileDescriptor]
|
||||||
tool_calls: list[ToolCallFinalResult]
|
tool_calls: list[ToolCallFinalResult]
|
||||||
@ -187,14 +193,14 @@ class ChatMessageDetail(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class SearchSessionDetailResponse(BaseModel):
|
class SearchSessionDetailResponse(BaseModel):
|
||||||
search_session_id: int
|
search_session_id: UUID
|
||||||
description: str
|
description: str
|
||||||
documents: list[SearchDoc]
|
documents: list[SearchDoc]
|
||||||
messages: list[ChatMessageDetail]
|
messages: list[ChatMessageDetail]
|
||||||
|
|
||||||
|
|
||||||
class ChatSessionDetailResponse(BaseModel):
|
class ChatSessionDetailResponse(BaseModel):
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
description: str
|
description: str
|
||||||
persona_id: int | None = None
|
persona_id: int | None = None
|
||||||
persona_name: str | None
|
persona_name: str | None
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
@ -186,7 +188,7 @@ def get_user_search_sessions(
|
|||||||
|
|
||||||
@basic_router.get("/search-session/{session_id}")
|
@basic_router.get("/search-session/{session_id}")
|
||||||
def get_search_session(
|
def get_search_session(
|
||||||
session_id: int,
|
session_id: UUID,
|
||||||
is_shared: bool = False,
|
is_shared: bool = False,
|
||||||
user: User | None = Depends(current_user),
|
user: User | None = Depends(current_user),
|
||||||
db_session: Session = Depends(get_session),
|
db_session: Session = Depends(get_session),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic import model_validator
|
from pydantic import model_validator
|
||||||
@ -40,7 +41,7 @@ class ToolCallFinalResult(ToolCallKickoff):
|
|||||||
|
|
||||||
|
|
||||||
class DynamicSchemaInfo(BaseModel):
|
class DynamicSchemaInfo(BaseModel):
|
||||||
chat_session_id: int | None
|
chat_session_id: UUID | None
|
||||||
message_id: int | None
|
message_id: int | None
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def get_empty_chat_messages_entries__paginated(
|
|||||||
|
|
||||||
message_skeletons.append(
|
message_skeletons.append(
|
||||||
ChatMessageSkeleton(
|
ChatMessageSkeleton(
|
||||||
message_id=chat_session.id,
|
message_id=message.id,
|
||||||
chat_session_id=chat_session.id,
|
chat_session_id=chat_session.id,
|
||||||
user_id=str(chat_session.user_id) if chat_session.user_id else None,
|
user_id=str(chat_session.user_id) if chat_session.user_id else None,
|
||||||
flow_type=flow_type,
|
flow_type=flow_type,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
|
|
||||||
@ -36,7 +38,7 @@ class BasicCreateChatMessageRequest(ChunkContext):
|
|||||||
Note, for simplicity this option only allows for a single linear chain of messages
|
Note, for simplicity this option only allows for a single linear chain of messages
|
||||||
"""
|
"""
|
||||||
|
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
# New message contents
|
# New message contents
|
||||||
message: str
|
message: str
|
||||||
# Defaults to using retrieval with no additional filters
|
# Defaults to using retrieval with no additional filters
|
||||||
|
@ -4,6 +4,7 @@ from datetime import datetime
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
@ -83,7 +84,7 @@ class MessageSnapshot(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class ChatSessionMinimal(BaseModel):
|
class ChatSessionMinimal(BaseModel):
|
||||||
id: int
|
id: UUID
|
||||||
user_email: str
|
user_email: str
|
||||||
name: str | None
|
name: str | None
|
||||||
first_user_message: str
|
first_user_message: str
|
||||||
@ -95,7 +96,7 @@ class ChatSessionMinimal(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class ChatSessionSnapshot(BaseModel):
|
class ChatSessionSnapshot(BaseModel):
|
||||||
id: int
|
id: UUID
|
||||||
user_email: str
|
user_email: str
|
||||||
name: str | None
|
name: str | None
|
||||||
messages: list[MessageSnapshot]
|
messages: list[MessageSnapshot]
|
||||||
@ -105,7 +106,7 @@ class ChatSessionSnapshot(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class QuestionAnswerPairSnapshot(BaseModel):
|
class QuestionAnswerPairSnapshot(BaseModel):
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
# 1-indexed message number in the chat_session
|
# 1-indexed message number in the chat_session
|
||||||
# e.g. the first message pair in the chat_session is 1, the second is 2, etc.
|
# e.g. the first message pair in the chat_session is 1, the second is 2, etc.
|
||||||
message_pair_num: int
|
message_pair_num: int
|
||||||
@ -350,7 +351,7 @@ def get_chat_session_history(
|
|||||||
|
|
||||||
@router.get("/admin/chat-session-history/{chat_session_id}")
|
@router.get("/admin/chat-session-history/{chat_session_id}")
|
||||||
def get_chat_session_admin(
|
def get_chat_session_admin(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
_: User | None = Depends(current_admin_user),
|
_: User | None = Depends(current_admin_user),
|
||||||
db_session: Session = Depends(get_session),
|
db_session: Session = Depends(get_session),
|
||||||
) -> ChatSessionSnapshot:
|
) -> ChatSessionSnapshot:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ class FlowType(str, Enum):
|
|||||||
|
|
||||||
class ChatMessageSkeleton(BaseModel):
|
class ChatMessageSkeleton(BaseModel):
|
||||||
message_id: int
|
message_id: int
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
user_id: str | None
|
user_id: str | None
|
||||||
flow_type: FlowType
|
flow_type: FlowType
|
||||||
time_sent: datetime
|
time_sent: datetime
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from requests.models import Response
|
from requests.models import Response
|
||||||
@ -44,7 +45,7 @@ class ChatSessionManager:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send_message(
|
def send_message(
|
||||||
chat_session_id: int,
|
chat_session_id: UUID,
|
||||||
message: str,
|
message: str,
|
||||||
parent_message_id: int | None = None,
|
parent_message_id: int | None = None,
|
||||||
user_performing_action: DATestUser | None = None,
|
user_performing_action: DATestUser | None = None,
|
||||||
|
@ -123,14 +123,14 @@ class DATestPersona(BaseModel):
|
|||||||
|
|
||||||
#
|
#
|
||||||
class DATestChatSession(BaseModel):
|
class DATestChatSession(BaseModel):
|
||||||
id: int
|
id: UUID
|
||||||
persona_id: int
|
persona_id: int
|
||||||
description: str
|
description: str
|
||||||
|
|
||||||
|
|
||||||
class DATestChatMessage(BaseModel):
|
class DATestChatMessage(BaseModel):
|
||||||
id: str | None = None
|
id: str | None = None
|
||||||
chat_session_id: int
|
chat_session_id: UUID
|
||||||
parent_message_id: str | None
|
parent_message_id: str | None
|
||||||
message: str
|
message: str
|
||||||
response: str
|
response: str
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
import uuid
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ class TestCustomTool(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
validate_openapi_schema(self.openapi_schema)
|
validate_openapi_schema(self.openapi_schema)
|
||||||
self.dynamic_schema_info: DynamicSchemaInfo = DynamicSchemaInfo(
|
self.dynamic_schema_info: DynamicSchemaInfo = DynamicSchemaInfo(
|
||||||
chat_session_id=10, message_id=20
|
chat_session_id=uuid.uuid4(), message_id=20
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch("danswer.tools.custom.custom_tool.requests.request")
|
@patch("danswer.tools.custom.custom_tool.requests.request")
|
||||||
|
@ -145,19 +145,17 @@ export function ChatPage({
|
|||||||
const existingChatIdRaw = searchParams.get("chatId");
|
const existingChatIdRaw = searchParams.get("chatId");
|
||||||
const currentPersonaId = searchParams.get(SEARCH_PARAM_NAMES.PERSONA_ID);
|
const currentPersonaId = searchParams.get(SEARCH_PARAM_NAMES.PERSONA_ID);
|
||||||
|
|
||||||
const existingChatSessionId = existingChatIdRaw
|
const existingChatSessionId = existingChatIdRaw ? existingChatIdRaw : null;
|
||||||
? parseInt(existingChatIdRaw)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const selectedChatSession = chatSessions.find(
|
const selectedChatSession = chatSessions.find(
|
||||||
(chatSession) => chatSession.id === existingChatSessionId
|
(chatSession) => chatSession.id === existingChatSessionId
|
||||||
);
|
);
|
||||||
|
|
||||||
const chatSessionIdRef = useRef<number | null>(existingChatSessionId);
|
const chatSessionIdRef = useRef<string | null>(existingChatSessionId);
|
||||||
|
|
||||||
// Only updates on session load (ie. rename / switching chat session)
|
// Only updates on session load (ie. rename / switching chat session)
|
||||||
// Useful for determining which session has been loaded (i.e. still on `new, empty session` or `previous session`)
|
// Useful for determining which session has been loaded (i.e. still on `new, empty session` or `previous session`)
|
||||||
const loadedIdSessionRef = useRef<number | null>(existingChatSessionId);
|
const loadedIdSessionRef = useRef<string | null>(existingChatSessionId);
|
||||||
|
|
||||||
// Assistants in order
|
// Assistants in order
|
||||||
const { finalAssistants } = useMemo(() => {
|
const { finalAssistants } = useMemo(() => {
|
||||||
@ -448,11 +446,11 @@ export function ChatPage({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [completeMessageDetail, setCompleteMessageDetail] = useState<
|
const [completeMessageDetail, setCompleteMessageDetail] = useState<
|
||||||
Map<number | null, Map<number, Message>>
|
Map<string | null, Map<number, Message>>
|
||||||
>(new Map());
|
>(new Map());
|
||||||
|
|
||||||
const updateCompleteMessageDetail = (
|
const updateCompleteMessageDetail = (
|
||||||
sessionId: number | null,
|
sessionId: string | null,
|
||||||
messageMap: Map<number, Message>
|
messageMap: Map<number, Message>
|
||||||
) => {
|
) => {
|
||||||
setCompleteMessageDetail((prevState) => {
|
setCompleteMessageDetail((prevState) => {
|
||||||
@ -463,13 +461,13 @@ export function ChatPage({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const currentMessageMap = (
|
const currentMessageMap = (
|
||||||
messageDetail: Map<number | null, Map<number, Message>>
|
messageDetail: Map<string | null, Map<number, Message>>
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
messageDetail.get(chatSessionIdRef.current) || new Map<number, Message>()
|
messageDetail.get(chatSessionIdRef.current) || new Map<number, Message>()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const currentSessionId = (): number => {
|
const currentSessionId = (): string => {
|
||||||
return chatSessionIdRef.current!;
|
return chatSessionIdRef.current!;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -484,7 +482,7 @@ export function ChatPage({
|
|||||||
// if calling this function repeatedly with short delay, stay may not update in time
|
// if calling this function repeatedly with short delay, stay may not update in time
|
||||||
// and result in weird behavipr
|
// and result in weird behavipr
|
||||||
completeMessageMapOverride?: Map<number, Message> | null;
|
completeMessageMapOverride?: Map<number, Message> | null;
|
||||||
chatSessionId?: number;
|
chatSessionId?: string;
|
||||||
replacementsMap?: Map<number, number> | null;
|
replacementsMap?: Map<number, number> | null;
|
||||||
makeLatestChildMessage?: boolean;
|
makeLatestChildMessage?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
@ -559,23 +557,23 @@ export function ChatPage({
|
|||||||
|
|
||||||
const [submittedMessage, setSubmittedMessage] = useState("");
|
const [submittedMessage, setSubmittedMessage] = useState("");
|
||||||
|
|
||||||
const [chatState, setChatState] = useState<Map<number | null, ChatState>>(
|
const [chatState, setChatState] = useState<Map<string | null, ChatState>>(
|
||||||
new Map([[chatSessionIdRef.current, "input"]])
|
new Map([[chatSessionIdRef.current, "input"]])
|
||||||
);
|
);
|
||||||
|
|
||||||
const [regenerationState, setRegenerationState] = useState<
|
const [regenerationState, setRegenerationState] = useState<
|
||||||
Map<number | null, RegenerationState | null>
|
Map<string | null, RegenerationState | null>
|
||||||
>(new Map([[null, null]]));
|
>(new Map([[null, null]]));
|
||||||
|
|
||||||
const [abortControllers, setAbortControllers] = useState<
|
const [abortControllers, setAbortControllers] = useState<
|
||||||
Map<number | null, AbortController>
|
Map<string | null, AbortController>
|
||||||
>(new Map());
|
>(new Map());
|
||||||
|
|
||||||
// Updates "null" session values to new session id for
|
// Updates "null" session values to new session id for
|
||||||
// regeneration, chat, and abort controller state, messagehistory
|
// regeneration, chat, and abort controller state, messagehistory
|
||||||
const updateStatesWithNewSessionId = (newSessionId: number) => {
|
const updateStatesWithNewSessionId = (newSessionId: string) => {
|
||||||
const updateState = (
|
const updateState = (
|
||||||
setState: Dispatch<SetStateAction<Map<number | null, any>>>,
|
setState: Dispatch<SetStateAction<Map<string | null, any>>>,
|
||||||
defaultValue?: any
|
defaultValue?: any
|
||||||
) => {
|
) => {
|
||||||
setState((prevState) => {
|
setState((prevState) => {
|
||||||
@ -610,7 +608,7 @@ export function ChatPage({
|
|||||||
chatSessionIdRef.current = newSessionId;
|
chatSessionIdRef.current = newSessionId;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateChatState = (newState: ChatState, sessionId?: number | null) => {
|
const updateChatState = (newState: ChatState, sessionId?: string | null) => {
|
||||||
setChatState((prevState) => {
|
setChatState((prevState) => {
|
||||||
const newChatState = new Map(prevState);
|
const newChatState = new Map(prevState);
|
||||||
newChatState.set(
|
newChatState.set(
|
||||||
@ -635,7 +633,7 @@ export function ChatPage({
|
|||||||
|
|
||||||
const updateRegenerationState = (
|
const updateRegenerationState = (
|
||||||
newState: RegenerationState | null,
|
newState: RegenerationState | null,
|
||||||
sessionId?: number | null
|
sessionId?: string | null
|
||||||
) => {
|
) => {
|
||||||
setRegenerationState((prevState) => {
|
setRegenerationState((prevState) => {
|
||||||
const newRegenerationState = new Map(prevState);
|
const newRegenerationState = new Map(prevState);
|
||||||
@ -647,18 +645,18 @@ export function ChatPage({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetRegenerationState = (sessionId?: number | null) => {
|
const resetRegenerationState = (sessionId?: string | null) => {
|
||||||
updateRegenerationState(null, sessionId);
|
updateRegenerationState(null, sessionId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentRegenerationState = (): RegenerationState | null => {
|
const currentRegenerationState = (): RegenerationState | null => {
|
||||||
return regenerationState.get(currentSessionId()) || null;
|
return regenerationState.get(currentSessionId()) || null;
|
||||||
};
|
};
|
||||||
const [canContinue, setCanContinue] = useState<Map<number | null, boolean>>(
|
const [canContinue, setCanContinue] = useState<Map<string | null, boolean>>(
|
||||||
new Map([[null, false]])
|
new Map([[null, false]])
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateCanContinue = (newState: boolean, sessionId?: number | null) => {
|
const updateCanContinue = (newState: boolean, sessionId?: string | null) => {
|
||||||
setCanContinue((prevState) => {
|
setCanContinue((prevState) => {
|
||||||
const newCanContinueState = new Map(prevState);
|
const newCanContinueState = new Map(prevState);
|
||||||
newCanContinueState.set(
|
newCanContinueState.set(
|
||||||
@ -1003,7 +1001,7 @@ export function ChatPage({
|
|||||||
|
|
||||||
setAlternativeGeneratingAssistant(alternativeAssistantOverride);
|
setAlternativeGeneratingAssistant(alternativeAssistantOverride);
|
||||||
clientScrollToBottom();
|
clientScrollToBottom();
|
||||||
let currChatSessionId: number;
|
let currChatSessionId: string;
|
||||||
const isNewSession = chatSessionIdRef.current === null;
|
const isNewSession = chatSessionIdRef.current === null;
|
||||||
const searchParamBasedChatSessionName =
|
const searchParamBasedChatSessionName =
|
||||||
searchParams.get(SEARCH_PARAM_NAMES.TITLE) || null;
|
searchParams.get(SEARCH_PARAM_NAMES.TITLE) || null;
|
||||||
@ -1014,7 +1012,7 @@ export function ChatPage({
|
|||||||
searchParamBasedChatSessionName
|
searchParamBasedChatSessionName
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
currChatSessionId = chatSessionIdRef.current as number;
|
currChatSessionId = chatSessionIdRef.current as string;
|
||||||
}
|
}
|
||||||
frozenSessionId = currChatSessionId;
|
frozenSessionId = currChatSessionId;
|
||||||
|
|
||||||
@ -1598,7 +1596,7 @@ export function ChatPage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [visibleRange, setVisibleRange] = useState<
|
const [visibleRange, setVisibleRange] = useState<
|
||||||
Map<number | null, VisibleRange>
|
Map<string | null, VisibleRange>
|
||||||
>(() => {
|
>(() => {
|
||||||
const initialRange: VisibleRange = {
|
const initialRange: VisibleRange = {
|
||||||
start: 0,
|
start: 0,
|
||||||
|
@ -30,7 +30,7 @@ const FolderItem = ({
|
|||||||
initiallySelected,
|
initiallySelected,
|
||||||
}: {
|
}: {
|
||||||
folder: Folder;
|
folder: Folder;
|
||||||
currentChatId?: number;
|
currentChatId?: string;
|
||||||
isInitiallyExpanded: boolean;
|
isInitiallyExpanded: boolean;
|
||||||
initiallySelected: boolean;
|
initiallySelected: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
@ -145,10 +145,7 @@ const FolderItem = ({
|
|||||||
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setIsDragOver(false);
|
setIsDragOver(false);
|
||||||
const chatSessionId = parseInt(
|
const chatSessionId = event.dataTransfer.getData(CHAT_SESSION_ID_KEY);
|
||||||
event.dataTransfer.getData(CHAT_SESSION_ID_KEY),
|
|
||||||
10
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
await addChatToFolder(folder.folder_id, chatSessionId);
|
await addChatToFolder(folder.folder_id, chatSessionId);
|
||||||
router.refresh(); // Refresh to show the updated folder contents
|
router.refresh(); // Refresh to show the updated folder contents
|
||||||
@ -302,7 +299,7 @@ export const FolderList = ({
|
|||||||
newFolderId,
|
newFolderId,
|
||||||
}: {
|
}: {
|
||||||
folders: Folder[];
|
folders: Folder[];
|
||||||
currentChatId?: number;
|
currentChatId?: string;
|
||||||
openedFolders?: { [key: number]: boolean };
|
openedFolders?: { [key: number]: boolean };
|
||||||
newFolderId: number | null;
|
newFolderId: number | null;
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -17,7 +17,7 @@ export async function createFolder(folderName: string): Promise<number> {
|
|||||||
// Function to add a chat session to a folder
|
// Function to add a chat session to a folder
|
||||||
export async function addChatToFolder(
|
export async function addChatToFolder(
|
||||||
folderId: number,
|
folderId: number,
|
||||||
chatSessionId: number
|
chatSessionId: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const response = await fetch(`/api/folder/${folderId}/add-chat-session`, {
|
const response = await fetch(`/api/folder/${folderId}/add-chat-session`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -34,7 +34,7 @@ export async function addChatToFolder(
|
|||||||
// Function to remove a chat session from a folder
|
// Function to remove a chat session from a folder
|
||||||
export async function removeChatFromFolder(
|
export async function removeChatFromFolder(
|
||||||
folderId: number,
|
folderId: number,
|
||||||
chatSessionId: number
|
chatSessionId: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const response = await fetch(`/api/folder/${folderId}/remove-chat-session`, {
|
const response = await fetch(`/api/folder/${folderId}/remove-chat-session`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -86,7 +86,7 @@ export function ChatInputBar({
|
|||||||
setFiles: (files: FileDescriptor[]) => void;
|
setFiles: (files: FileDescriptor[]) => void;
|
||||||
handleFileUpload: (files: File[]) => void;
|
handleFileUpload: (files: File[]) => void;
|
||||||
textAreaRef: React.RefObject<HTMLTextAreaElement>;
|
textAreaRef: React.RefObject<HTMLTextAreaElement>;
|
||||||
chatSessionId?: number;
|
chatSessionId?: string;
|
||||||
refreshUser: () => void;
|
refreshUser: () => void;
|
||||||
}) {
|
}) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -60,7 +60,7 @@ export interface ToolCallFinalResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatSession {
|
export interface ChatSession {
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
persona_id: number;
|
persona_id: number;
|
||||||
time_created: string;
|
time_created: string;
|
||||||
@ -70,7 +70,7 @@ export interface ChatSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchSession {
|
export interface SearchSession {
|
||||||
search_session_id: number;
|
search_session_id: string;
|
||||||
documents: SearchDanswerDocument[];
|
documents: SearchDanswerDocument[];
|
||||||
messages: BackendMessage[];
|
messages: BackendMessage[];
|
||||||
description: string;
|
description: string;
|
||||||
@ -97,7 +97,7 @@ export interface Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BackendChatSession {
|
export interface BackendChatSession {
|
||||||
chat_session_id: number;
|
chat_session_id: string;
|
||||||
description: string;
|
description: string;
|
||||||
persona_id: number;
|
persona_id: number;
|
||||||
persona_name: string;
|
persona_name: string;
|
||||||
@ -110,7 +110,7 @@ export interface BackendChatSession {
|
|||||||
export interface BackendMessage {
|
export interface BackendMessage {
|
||||||
message_id: number;
|
message_id: number;
|
||||||
comments: any;
|
comments: any;
|
||||||
chat_session_id: number;
|
chat_session_id: string;
|
||||||
parent_message: number | null;
|
parent_message: number | null;
|
||||||
latest_child_message: number | null;
|
latest_child_message: number | null;
|
||||||
message: string;
|
message: string;
|
||||||
|
@ -55,7 +55,7 @@ export function getChatRetentionInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateModelOverrideForChatSession(
|
export async function updateModelOverrideForChatSession(
|
||||||
chatSessionId: number,
|
chatSessionId: string,
|
||||||
newAlternateModel: string
|
newAlternateModel: string
|
||||||
) {
|
) {
|
||||||
const response = await fetch("/api/chat/update-chat-session-model", {
|
const response = await fetch("/api/chat/update-chat-session-model", {
|
||||||
@ -74,7 +74,7 @@ export async function updateModelOverrideForChatSession(
|
|||||||
export async function createChatSession(
|
export async function createChatSession(
|
||||||
personaId: number,
|
personaId: number,
|
||||||
description: string | null
|
description: string | null
|
||||||
): Promise<number> {
|
): Promise<string> {
|
||||||
const createChatSessionResponse = await fetch(
|
const createChatSessionResponse = await fetch(
|
||||||
"/api/chat/create-chat-session",
|
"/api/chat/create-chat-session",
|
||||||
{
|
{
|
||||||
@ -131,7 +131,7 @@ export async function* sendMessage({
|
|||||||
message: string;
|
message: string;
|
||||||
fileDescriptors: FileDescriptor[];
|
fileDescriptors: FileDescriptor[];
|
||||||
parentMessageId: number | null;
|
parentMessageId: number | null;
|
||||||
chatSessionId: number;
|
chatSessionId: string;
|
||||||
promptId: number | null | undefined;
|
promptId: number | null | undefined;
|
||||||
filters: Filters | null;
|
filters: Filters | null;
|
||||||
selectedDocumentIds: number[] | null;
|
selectedDocumentIds: number[] | null;
|
||||||
@ -203,7 +203,7 @@ export async function* sendMessage({
|
|||||||
yield* handleSSEStream<PacketType>(response);
|
yield* handleSSEStream<PacketType>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function nameChatSession(chatSessionId: number, message: string) {
|
export async function nameChatSession(chatSessionId: string, message: string) {
|
||||||
const response = await fetch("/api/chat/rename-chat-session", {
|
const response = await fetch("/api/chat/rename-chat-session", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
@ -252,7 +252,7 @@ export async function handleChatFeedback(
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
export async function renameChatSession(
|
export async function renameChatSession(
|
||||||
chatSessionId: number,
|
chatSessionId: string,
|
||||||
newName: string
|
newName: string
|
||||||
) {
|
) {
|
||||||
const response = await fetch(`/api/chat/rename-chat-session`, {
|
const response = await fetch(`/api/chat/rename-chat-session`, {
|
||||||
@ -269,7 +269,7 @@ export async function renameChatSession(
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteChatSession(chatSessionId: number) {
|
export async function deleteChatSession(chatSessionId: string) {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`/api/chat/delete-chat-session/${chatSessionId}`,
|
`/api/chat/delete-chat-session/${chatSessionId}`,
|
||||||
{
|
{
|
||||||
@ -348,6 +348,7 @@ export function getCitedDocumentsFromMessage(message: Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function groupSessionsByDateRange(chatSessions: ChatSession[]) {
|
export function groupSessionsByDateRange(chatSessions: ChatSession[]) {
|
||||||
|
console.log(chatSessions);
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
today.setHours(0, 0, 0, 0); // Set to start of today for accurate comparison
|
today.setHours(0, 0, 0, 0); // Set to start of today for accurate comparison
|
||||||
|
|
||||||
@ -584,7 +585,7 @@ const PARAMS_TO_SKIP = [
|
|||||||
|
|
||||||
export function buildChatUrl(
|
export function buildChatUrl(
|
||||||
existingSearchParams: ReadonlyURLSearchParams,
|
existingSearchParams: ReadonlyURLSearchParams,
|
||||||
chatSessionId: number | null,
|
chatSessionId: string | null,
|
||||||
personaId: number | null,
|
personaId: number | null,
|
||||||
search?: boolean
|
search?: boolean
|
||||||
) {
|
) {
|
||||||
|
@ -6,12 +6,12 @@ import { ChatSessionSharedStatus } from "../interfaces";
|
|||||||
import { FiCopy } from "react-icons/fi";
|
import { FiCopy } from "react-icons/fi";
|
||||||
import { CopyButton } from "@/components/CopyButton";
|
import { CopyButton } from "@/components/CopyButton";
|
||||||
|
|
||||||
function buildShareLink(chatSessionId: number) {
|
function buildShareLink(chatSessionId: string) {
|
||||||
const baseUrl = `${window.location.protocol}//${window.location.host}`;
|
const baseUrl = `${window.location.protocol}//${window.location.host}`;
|
||||||
return `${baseUrl}/chat/shared/${chatSessionId}`;
|
return `${baseUrl}/chat/shared/${chatSessionId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateShareLink(chatSessionId: number) {
|
async function generateShareLink(chatSessionId: string) {
|
||||||
const response = await fetch(`/api/chat/chat-session/${chatSessionId}`, {
|
const response = await fetch(`/api/chat/chat-session/${chatSessionId}`, {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
@ -26,7 +26,7 @@ async function generateShareLink(chatSessionId: number) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteShareLink(chatSessionId: number) {
|
async function deleteShareLink(chatSessionId: string) {
|
||||||
const response = await fetch(`/api/chat/chat-session/${chatSessionId}`, {
|
const response = await fetch(`/api/chat/chat-session/${chatSessionId}`, {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
@ -44,7 +44,7 @@ export function ShareChatSessionModal({
|
|||||||
onShare,
|
onShare,
|
||||||
onClose,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
chatSessionId: number;
|
chatSessionId: string;
|
||||||
existingSharedStatus: ChatSessionSharedStatus;
|
existingSharedStatus: ChatSessionSharedStatus;
|
||||||
onShare?: (shared: boolean) => void;
|
onShare?: (shared: boolean) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -14,7 +14,7 @@ interface LlmTabProps {
|
|||||||
llmOverrideManager: LlmOverrideManager;
|
llmOverrideManager: LlmOverrideManager;
|
||||||
currentLlm: string;
|
currentLlm: string;
|
||||||
openModelSettings: () => void;
|
openModelSettings: () => void;
|
||||||
chatSessionId?: number;
|
chatSessionId?: string;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
currentAssistant: Persona;
|
currentAssistant: Persona;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ export function PagesTab({
|
|||||||
}: {
|
}: {
|
||||||
page: pageType;
|
page: pageType;
|
||||||
existingChats?: ChatSession[];
|
existingChats?: ChatSession[];
|
||||||
currentChatId?: number;
|
currentChatId?: string;
|
||||||
folders?: Folder[];
|
folders?: Folder[];
|
||||||
openedFolders?: { [key: number]: boolean };
|
openedFolders?: { [key: number]: boolean };
|
||||||
closeSidebar?: () => void;
|
closeSidebar?: () => void;
|
||||||
@ -44,10 +44,7 @@ export function PagesTab({
|
|||||||
) => {
|
) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setIsDragOver(false); // Reset drag over state on drop
|
setIsDragOver(false); // Reset drag over state on drop
|
||||||
const chatSessionId = parseInt(
|
const chatSessionId = event.dataTransfer.getData(CHAT_SESSION_ID_KEY);
|
||||||
event.dataTransfer.getData(CHAT_SESSION_ID_KEY),
|
|
||||||
10
|
|
||||||
);
|
|
||||||
const folderId = event.dataTransfer.getData(FOLDER_ID_KEY);
|
const folderId = event.dataTransfer.getData(FOLDER_ID_KEY);
|
||||||
|
|
||||||
if (folderId) {
|
if (folderId) {
|
||||||
|
@ -48,7 +48,7 @@ export default async function Page({ params }: { params: { chatId: string } }) {
|
|||||||
const user = results[1] as User | null;
|
const user = results[1] as User | null;
|
||||||
const chatSession = results[2] as BackendChatSession | null;
|
const chatSession = results[2] as BackendChatSession | null;
|
||||||
const assistantsResponse = results[3] as FetchAssistantsResponse | null;
|
const assistantsResponse = results[3] as FetchAssistantsResponse | null;
|
||||||
const [availableAssistants, _] = assistantsResponse ?? [[], null];
|
const [availableAssistants, error] = assistantsResponse ?? [[], null];
|
||||||
|
|
||||||
const authDisabled = authTypeMetadata?.authType === "disabled";
|
const authDisabled = authTypeMetadata?.authType === "disabled";
|
||||||
if (!authDisabled && !user) {
|
if (!authDisabled && !user) {
|
||||||
@ -58,7 +58,6 @@ export default async function Page({ params }: { params: { chatId: string } }) {
|
|||||||
if (user && !user.is_verified && authTypeMetadata?.requiresVerification) {
|
if (user && !user.is_verified && authTypeMetadata?.requiresVerification) {
|
||||||
return redirect("/auth/waiting-on-verification");
|
return redirect("/auth/waiting-on-verification");
|
||||||
}
|
}
|
||||||
|
|
||||||
const persona: Persona =
|
const persona: Persona =
|
||||||
chatSession?.persona_id && availableAssistants?.length
|
chatSession?.persona_id && availableAssistants?.length
|
||||||
? (availableAssistants.find((p) => p.id === chatSession.persona_id) ??
|
? (availableAssistants.find((p) => p.id === chatSession.persona_id) ??
|
||||||
@ -72,7 +71,7 @@ export default async function Page({ params }: { params: { chatId: string } }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex relative bg-background text-default overflow-hidden pt-16 h-screen">
|
<div className="flex relative bg-background text-default overflow-hidden pt-16 h-screen">
|
||||||
<SharedChatDisplay chatSession={chatSession} persona={persona!} />
|
<SharedChatDisplay chatSession={chatSession} persona={persona} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -168,13 +168,10 @@ export const SearchSection = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const existingSearchIdRaw = searchParams.get("searchId");
|
const existingSearchessionId = searchParams.get("searchId");
|
||||||
const existingSearchessionId = existingSearchIdRaw
|
|
||||||
? parseInt(existingSearchIdRaw)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (existingSearchIdRaw == null) {
|
if (existingSearchessionId == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
function extractFirstMessageByType(
|
function extractFirstMessageByType(
|
||||||
@ -207,7 +204,7 @@ export const SearchSection = ({
|
|||||||
quotes: null,
|
quotes: null,
|
||||||
selectedDocIndices: null,
|
selectedDocIndices: null,
|
||||||
error: null,
|
error: null,
|
||||||
messageId: existingSearchIdRaw ? parseInt(existingSearchIdRaw) : null,
|
messageId: searchSession.messages[0].message_id,
|
||||||
suggestedFlowType: null,
|
suggestedFlowType: null,
|
||||||
additional_relevance: undefined,
|
additional_relevance: undefined,
|
||||||
};
|
};
|
||||||
@ -219,7 +216,7 @@ export const SearchSection = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
initialSessionFetch();
|
initialSessionFetch();
|
||||||
}, [existingSearchessionId, existingSearchIdRaw]);
|
}, [existingSearchessionId]);
|
||||||
|
|
||||||
// Overrides for default behavior that only last a single query
|
// Overrides for default behavior that only last a single query
|
||||||
const [defaultOverrides, setDefaultOverrides] =
|
const [defaultOverrides, setDefaultOverrides] =
|
||||||
@ -328,7 +325,7 @@ export const SearchSection = ({
|
|||||||
};
|
};
|
||||||
const updateMessageAndThreadId = (
|
const updateMessageAndThreadId = (
|
||||||
messageId: number,
|
messageId: number,
|
||||||
chat_session_id: number
|
chat_session_id: string
|
||||||
) => {
|
) => {
|
||||||
setSearchResponse((prevState) => ({
|
setSearchResponse((prevState) => ({
|
||||||
...(prevState || initialSearchResponse),
|
...(prevState || initialSearchResponse),
|
||||||
|
@ -136,8 +136,10 @@ export async function fetchChatData(searchParams: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Larger ID -> created later
|
chatSessions.sort(
|
||||||
chatSessions.sort((a, b) => (a.id > b.id ? -1 : 1));
|
(a, b) =>
|
||||||
|
new Date(b.time_created).getTime() - new Date(a.time_created).getTime()
|
||||||
|
);
|
||||||
|
|
||||||
let documentSets: DocumentSet[] = [];
|
let documentSets: DocumentSet[] = [];
|
||||||
if (documentSetsResponse?.ok) {
|
if (documentSetsResponse?.ok) {
|
||||||
|
@ -152,7 +152,7 @@ export interface SearchRequestArgs {
|
|||||||
updateError: (error: string) => void;
|
updateError: (error: string) => void;
|
||||||
updateMessageAndThreadId: (
|
updateMessageAndThreadId: (
|
||||||
messageId: number,
|
messageId: number,
|
||||||
chat_session_id: number
|
chat_session_id: string
|
||||||
) => void;
|
) => void;
|
||||||
finishedSearching: () => void;
|
finishedSearching: () => void;
|
||||||
updateComments: (comments: any) => void;
|
updateComments: (comments: any) => void;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user