@@ -14,6 +14,9 @@ from fields.conversation_fields import (
|
||||
conversation_infinite_scroll_pagination_fields,
|
||||
simple_conversation_fields,
|
||||
)
|
||||
from fields.conversation_variable_fields import (
|
||||
conversation_variable_infinite_scroll_pagination_fields,
|
||||
)
|
||||
from libs.helper import uuid_value
|
||||
from models.model import App, AppMode, EndUser
|
||||
from services.conversation_service import ConversationService
|
||||
@@ -93,6 +96,31 @@ class ConversationRenameApi(Resource):
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
|
||||
class ConversationVariablesApi(Resource):
|
||||
@validate_app_token(fetch_user_arg=FetchUserArg(fetch_from=WhereisUserArg.QUERY))
|
||||
@marshal_with(conversation_variable_infinite_scroll_pagination_fields)
|
||||
def get(self, app_model: App, end_user: EndUser, c_id):
|
||||
# conversational variable only for chat app
|
||||
app_mode = AppMode.value_of(app_model.mode)
|
||||
if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:
|
||||
raise NotChatAppError()
|
||||
|
||||
conversation_id = str(c_id)
|
||||
|
||||
parser = reqparse.RequestParser()
|
||||
parser.add_argument("last_id", type=uuid_value, location="args")
|
||||
parser.add_argument("limit", type=int_range(1, 100), required=False, default=20, location="args")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
return ConversationService.get_conversational_variable(
|
||||
app_model, conversation_id, end_user, args["limit"], args["last_id"]
|
||||
)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
|
||||
api.add_resource(ConversationRenameApi, "/conversations/<uuid:c_id>/name", endpoint="conversation_name")
|
||||
api.add_resource(ConversationApi, "/conversations")
|
||||
api.add_resource(ConversationDetailApi, "/conversations/<uuid:c_id>", endpoint="conversation_detail")
|
||||
api.add_resource(ConversationVariablesApi, "/conversations/<uuid:c_id>/variables", endpoint="conversation_variables")
|
||||
|
||||
@@ -19,3 +19,9 @@ paginated_conversation_variable_fields = {
|
||||
"has_more": fields.Boolean,
|
||||
"data": fields.List(fields.Nested(conversation_variable_fields), attribute="data"),
|
||||
}
|
||||
|
||||
conversation_variable_infinite_scroll_pagination_fields = {
|
||||
"limit": fields.Integer,
|
||||
"has_more": fields.Boolean,
|
||||
"data": fields.List(fields.Nested(conversation_variable_fields)),
|
||||
}
|
||||
|
||||
@@ -9,9 +9,14 @@ from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from core.llm_generator.llm_generator import LLMGenerator
|
||||
from extensions.ext_database import db
|
||||
from libs.infinite_scroll_pagination import InfiniteScrollPagination
|
||||
from models import ConversationVariable
|
||||
from models.account import Account
|
||||
from models.model import App, Conversation, EndUser, Message
|
||||
from services.errors.conversation import ConversationNotExistsError, LastConversationNotExistsError
|
||||
from services.errors.conversation import (
|
||||
ConversationNotExistsError,
|
||||
ConversationVariableNotExistsError,
|
||||
LastConversationNotExistsError,
|
||||
)
|
||||
from services.errors.message import MessageNotExistsError
|
||||
|
||||
|
||||
@@ -166,3 +171,50 @@ class ConversationService:
|
||||
conversation.is_deleted = True
|
||||
conversation.updated_at = datetime.now(UTC).replace(tzinfo=None)
|
||||
db.session.commit()
|
||||
|
||||
@classmethod
|
||||
def get_conversational_variable(
|
||||
cls,
|
||||
app_model: App,
|
||||
conversation_id: str,
|
||||
user: Optional[Union[Account, EndUser]],
|
||||
limit: int,
|
||||
last_id: Optional[str],
|
||||
) -> InfiniteScrollPagination:
|
||||
conversation = cls.get_conversation(app_model, conversation_id, user)
|
||||
|
||||
stmt = (
|
||||
select(ConversationVariable)
|
||||
.where(ConversationVariable.app_id == app_model.id)
|
||||
.where(ConversationVariable.conversation_id == conversation.id)
|
||||
.order_by(ConversationVariable.created_at)
|
||||
)
|
||||
|
||||
with Session(db.engine) as session:
|
||||
if last_id:
|
||||
last_variable = session.scalar(stmt.where(ConversationVariable.id == last_id))
|
||||
if not last_variable:
|
||||
raise ConversationVariableNotExistsError()
|
||||
|
||||
# Filter for variables created after the last_id
|
||||
stmt = stmt.where(ConversationVariable.created_at > last_variable.created_at)
|
||||
|
||||
# Apply limit to query
|
||||
query_stmt = stmt.limit(limit) # Get one extra to check if there are more
|
||||
rows = session.scalars(query_stmt).all()
|
||||
|
||||
has_more = False
|
||||
if len(rows) > limit:
|
||||
has_more = True
|
||||
rows = rows[:limit] # Remove the extra item
|
||||
|
||||
variables = [
|
||||
{
|
||||
"created_at": row.created_at,
|
||||
"updated_at": row.updated_at,
|
||||
**row.to_variable().model_dump(),
|
||||
}
|
||||
for row in rows
|
||||
]
|
||||
|
||||
return InfiniteScrollPagination(variables, limit, has_more)
|
||||
|
||||
@@ -11,3 +11,7 @@ class ConversationNotExistsError(BaseServiceError):
|
||||
|
||||
class ConversationCompletedError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ConversationVariableNotExistsError(BaseServiceError):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user