@@ -104,6 +104,7 @@ class Chatgpt(SimpleService): start_time = time.time() info = input_message.info.copy() model_name = info.pop('version', 'gpt-4o') + user_system_prompt = info.pop('system_prompt', '') input_content = [{'type': 'text', 'text': input_message.content or ''}] file = input_message.file image = None @@ -164,13 +165,13 @@ class Chatgpt(SimpleService): runnable=self.llm, get_session_history=lambda _: chat_history, ) - llm_input = HumanMessage(content=input_content) + llm_input = [SystemMessage(content=user_system_prompt), HumanMessage(content=input_content)] if file and not image: - input_tokens = self.count_text_tokens([*chat_history.messages, llm_input, *chunks]) + input_tokens = self.count_text_tokens([*chat_history.messages, *llm_input, *chunks]) elif image: - input_tokens = self.count_text_tokens([llm_input]) + input_tokens = self.count_text_tokens(llm_input) else: - input_tokens = self.count_text_tokens([*chat_history.messages, llm_input]) + input_tokens = self.count_text_tokens([*chat_history.messages, *llm_input]) output_tokens = 0 self.assert_enough_balance(input_tokens, image_size, model=self.llm.model_name) if model_name in ('o3-mini', 'gpt-4.5-preview'): @@ -180,6 +181,7 @@ class Chatgpt(SimpleService): for msg in chat_history.messages ] messages.insert(0, {'role': 'system', 'content': system.content}) + messages.insert(0, {'role': 'system', 'content': user_system_prompt}) if image: messages[-1]['content'] = [ {'type': 'text', 'text': input_message.content}, @@ -204,6 +206,7 @@ class Chatgpt(SimpleService): ] if model_name not in ('o1-preview', 'o1-mini'): messages.insert(0, {'role': 'system', 'content': system.content}) + messages.insert(0, {'role': 'system', 'content': user_system_prompt}) search_context_size = search_context_sizes.get(info.get('web_search', 'Средний контекст')) info['web_search'] = search_context_size json_data = { @@ -219,7 +222,7 @@ class Chatgpt(SimpleService): } input_tokens, output_tokens, response = self.call_openai_api(proxy=proxy, endpoint='responses',json_data=json_data) elif image: - response = self.llm.invoke([llm_input]) + response = self.llm.invoke(llm_input) chat_history.add_ai_message(response) elif file: human_messages = [] @@ -253,8 +256,10 @@ class Chatgpt(SimpleService): ) else: # Somehow this chain doesn't support Vision, even though ChatOpenAI (above) does. + if model_name in ('o1-preview', 'o1-mini'): + llm_input.pop(0) response = conversation.invoke( - {'input': llm_input.content[0]['text']}, + {'input': llm_input}, config={'configurable': {'session_id': 'default'}}, ) chat_history.add_ai_message(response) @@ -61,9 +61,13 @@ class Claude(SimpleService): def make(self, input_message: Message, save: bool = True) -> list[Message]: start_time = time.time() version = f'anthropic/{input_message.info.pop("version", "claude-3.7-sonnet:thinking")}' + system_prompt = input_message.info.pop('system_prompt', '') callback_data = {'provider': {'order': ['Anthropic']}, **input_message.info} - messages = self.get_chat_history() - messages.append({'role': 'user', 'content': input_message.content}) + messages = [ + {'role': 'system', 'content': system_prompt}, + *self.get_chat_history(), + {'role': 'user', 'content': input_message.content} + ] image = input_message.file if image: kind = filetype.guess(image.read(20)) @@ -47,11 +47,15 @@ class Deepseek(SimpleService): def make(self, input_message: Message, save: bool = True) -> list[Message]: info = input_message.info.copy() version = info.pop('version') + system_prompt = input_message.info.pop('system_prompt', '') callback_data = { **input_message.info, } - messages = self.get_chat_history() - messages.append({'role': 'user', 'content': input_message.content}) + messages = [ + {'role': 'system', 'content': system_prompt}, + *self.get_chat_history(), + {'role': 'user', 'content': input_message.content} + ] start_time = time.time() result = openrouter_run(version, messages, callback_data, 'Deepseek') process_time = timedelta(seconds=(time.time() - start_time))