@@ -215,6 +215,7 @@ DATABASES = { 'HOST': env.str('POSTGRES_HOST'), 'PORT': env.str('POSTGRES_PORT'), 'CONN_HEALTH_CHECKS': True, + 'DISABLE_SERVER_SIDE_CURSOR': False } } @@ -161,7 +161,7 @@ class Chatgpt(SimpleService): self.llm.tiktoken_model_name = 'gpt-4' if model_name not in self.TOKENS_COST.keys(): raise Exception(_('No matching version found')) - chat_history = self.get_chat_history() + chat_history = self.get_chat_history(model_name=model_name) if model_name in ('o1-preview', 'o1-mini'): chat_history.messages.pop(0) conversation = RunnableWithMessageHistory( @@ -296,33 +296,41 @@ class Chatgpt(SimpleService): return msgs raise GenerationException - def get_chat_history( - self, - message_limit: int = 10, - token_limit: int = 580, # ~ 1 AIR Token with GPT 3.5 - ) -> InMemoryChatMessageHistory: + def get_chat_history(self, model_name: str) -> InMemoryChatMessageHistory: if isinstance(self.store, Chat): - air_messages = list( - reversed( - Message.objects.filter( - chats_chats_messages=self.store, - is_deleted=False, - is_sent=True, - ).order_by('-created_at')[:message_limit] - ) - ) + air_messages = Message.objects.filter( + chats_chats_messages=self.store, + is_deleted=False, + is_sent=True, + ).order_by('-created_at') elif isinstance(self.store, APIStore): air_messages = [] elif isinstance(self.store, Copywrite): - air_messages = list( - reversed( - Message.objects.filter( - copywrite_copywrites_messages=self.store, - is_deleted=False, - is_sent=True, - ).order_by('-created_at')[:message_limit] - ) - ) + air_messages = Message.objects.filter( + copywrite_copywrites_messages=self.store, + is_deleted=False, + is_sent=True, + ).order_by('-created_at') + + token_limits = { + 'o3-mini': 100_000, + 'o1-preview': 100_000, + 'gpt-4o-mini': 64_000, + 'gpt-4o': 64_000, + 'gpt-4.5-preview': 64_000, + } + tokens = 0 + history: List[BaseMessage] = [] + for message in air_messages.iterator(5): + air_message = [ + AIMessage(content=message.content or '') + if message.from_model else + HumanMessage(content=message.content or '') + ] + if self.count_text_tokens(air_message) + tokens > token_limits[model_name]: + break + tokens += self.count_text_tokens(air_message) + history.append(air_message[0]) memory = InMemoryChatMessageHistory() memory.add_message(SystemMessage( content=( @@ -331,20 +339,7 @@ class Chatgpt(SimpleService): 'Любая информация должна быть преобразована в простой строковый текст (str).' ) )) - for msg in air_messages: - content = msg.content or '' - if msg.from_model: - memory.add_message(AIMessage(content=content)) - else: - memory.add_message(HumanMessage(content=content)) - - messages = memory.messages - tokens = self.llm.get_num_tokens_from_messages(messages) - - while tokens > token_limit: - messages.pop(1) - tokens = self.llm.get_num_tokens_from_messages(messages) - + memory.add_messages(list(reversed(history))) return memory def assert_enough_balance( @@ -581,7 +576,7 @@ class Chatgpt(SimpleService): 'top_p': input_message.info.pop('top_p', 0.5), }, ) - chat_history = self.get_chat_history() + chat_history = self.get_chat_history(model_name=input_message.info.pop('version', 'gpt-3.5-turbo')) conversation = ConversationChain( llm=self.llm, memory=chat_history,