@@ -7,6 +7,7 @@ from typing import Any, Generator, TypeAlias, TypedDict import httpx from backend import settings +from messages.services.message_service import MessageService from ml_model.exceptions import ( FileExtensionNotSupported, GenerationException, @@ -132,7 +133,6 @@ class BytedanceModelArkAdapter: return str(error.get('code', '')) == 'InputTextSensitiveContentDetected' - @classmethod def _extract_chat_answer( cls, @@ -145,11 +145,14 @@ class BytedanceModelArkAdapter: for choice in choices if choice.get('finish_reason') in (BytedanceFinishReason.STOP, BytedanceFinishReason.LENGTH) and choice.get('message') - and choice['message'].get('content') is not None + and ( + choice['message'].get('content') is not None + or choice['message'].get('reasoning_content') is not None + ) ] if stop_choices: - content = ','.join(str(choice['message']['content']) for choice in stop_choices) - # TODO: включить после разделения reasoning и content в хранении + content = ','.join(choice['message'].get('content') or '' for choice in stop_choices) + reasoning = '' if include_reasoning: reasoning = ','.join( str(reasoning) @@ -157,11 +160,7 @@ class BytedanceModelArkAdapter: if choice.get('message') and (reasoning := choice['message'].get('reasoning_content')) is not None ) - if reasoning and content: - return f'**Рассуждение:**\n\n{reasoning}\n\n**Основная мысль:**\n\n{content}' - if reasoning: - return reasoning - return content + return MessageService.prepare_output_message(reasoning, content) cls._raise_by_error_payload(data, choices) @@ -20,6 +20,7 @@ from replicate.exceptions import ModelError from requests import Response from backend import settings +from messages.services.message_service import MessageService from ml_model.adapters.bytedance_model_ark import BytedanceContentType, BytedanceModelArkAdapter from ml_model.adapters.openrouter import OpenrouterAdapter from ml_model.exceptions import ( @@ -167,7 +168,12 @@ def openrouter_run(version: str, messages: list, callback_data: dict, model_name for c in data.get('choices', []) if c.get('message') and c['message'].get('content') is not None ] - if not raw_content: + raw_reasoning = ','.join( + reasoning + for choice in data.get('choices', []) + if (reasoning := choice['message'].get('reasoning')) is not None + ) + if not raw_content and not raw_reasoning: if any( c.get('native_finish_reason') == 'SAFETY_CHECK_TYPE_CSAM' for c in (data.get('choices') or []) @@ -182,22 +188,8 @@ def openrouter_run(version: str, messages: list, callback_data: dict, model_name ) raise GenerationException content = ','.join(raw_content) - reasoning = ','.join( - reasoning - for choice in data.get('choices', []) - if (reasoning := choice['message'].get('reasoning')) is not None - ) - reasoning = re.sub(r'Вывод:|Основная мысль:|Рассуждение:|\*\*', '', reasoning) - answer = reasoning - if any(m in data['model'] for m in ('google/gemini', 'x-ai/grok-4.3')) or re.match( - r'^qwen/qwen3\.(?:5|6|7)-.*$', data['model'] - ): - answer = content - elif reasoning and content: - # TODO: переделать рендеринг сообщения на Jinja 2 - answer = f'**Рассуждение:**\n\n{reasoning}\n\n**Основная мысль:**\n\n{content}' - elif content: - answer = content + reasoning = re.sub(r'Вывод:|Основная мысль:|Рассуждение:|\*\*', '', raw_reasoning) + answer = MessageService.prepare_output_message(reasoning, content) if int(data.get('choices')[0].get('error', {}).get('code', 0)) == 502: error_type = re.sub(r'["\']', '', str(data['choices'][0]['error']['message'])) if error_type == 'Overloaded':