@@ -7,7 +7,6 @@ from typing import Any, Iterator from pathlib import Path import filetype -from django.db.models.fields.files import FieldFile from PIL import Image from ml_model.services.FileService import FileProcessingService from ml_model.exceptions import FileExtensionNotSupported, CorruptedFileError @@ -27,21 +26,12 @@ from tools.public_api.models import APIStore class Grok(SimpleService): - """ - Grok Service - contains abstract method make, which makes a generation - """ TOKENS_COST = { - 'grok-4': { - 'input': Decimal('900'), - 'output': Decimal('4500'), - 'input_imgs': Decimal('1500'), - }, # 1M tokens and 1K imgs - 'grok-code-fast-1': { - 'input': Decimal('60'), - 'output': Decimal('450'), - }, # 1M tokens + 'grok-4.3': { + 'input': {'default': Decimal('875'), 'high': Decimal('1750')}, + 'output': {'default': Decimal('1750'), 'high': Decimal('3500')}, + }, } TOOLS_TOKEN_COSTS = {'text-embedding-3-small': {'output': Decimal('0.00001')}} @@ -49,14 +39,17 @@ class Grok(SimpleService): SUPPORTED_EXTENSIONS = ['PDF', 'DOC', 'DOCX', 'XLSX', 'JPG', 'JPEG', 'PNG', 'WEBP'] def calculate_price( - self, version: str, input_tokens: int, output_tokens: int, image: FieldFile, embedding_tokens: int + self, version: str, input_tokens: int, output_tokens: int, embedding_tokens: int ) -> Decimal: price_map = self.TOKENS_COST[version.split('/')[1]] price = ( - input_tokens * price_map['input'] / 1_000_000 + output_tokens * price_map['output'] / 1_000_000 + input_tokens + * price_map['input']['default' if input_tokens <= 200_000 else 'high'] + / 1_000_000 + + output_tokens + * price_map['output']['default' if output_tokens <= 200_000 else 'high'] + / 1_000_000 ) - if image: - price += price_map['input_imgs'] / 1_000 if embedding_tokens: price += embedding_tokens * self.TOOLS_TOKEN_COSTS['text-embedding-3-small']['output'] return price.quantize(Decimal('0.1'), rounding='ROUND_UP') @@ -75,12 +68,11 @@ class Grok(SimpleService): def make(self, input_message: Message, save: bool = True) -> list[Message]: start_time = time.time() - version = f'x-ai/{input_message.info.pop("version", "grok-4")}' + version = f'x-ai/{input_message.info.pop("version", "grok-4.3")}' callback_data = {**input_message.info} messages = self.get_chat_history() messages.append({'role': 'user', 'content': input_message.content}) embedding_tokens = 0 - image = None if input_message.file: file_service = FileProcessingService file_bytes = input_message.file.read() @@ -97,7 +89,9 @@ class Grok(SimpleService): approx_tokens = sum([len(message['content']) for message in messages]) / 3 predict_price = ( Decimal(approx_tokens) - * self.TOKENS_COST[version.split('/')[1]]['input'] + * self.TOKENS_COST[version.split('/')[1]]['input'][ + 'default' if approx_tokens <= 200_000 else 'high' + ] / Decimal('1000000') + len(chunks) * 2100 * self.TOOLS_TOKEN_COSTS['text-embedding-3-small']['output'] ).quantize(Decimal('0.1'), rounding='ROUND_UP') @@ -126,8 +120,6 @@ class Grok(SimpleService): ) elif file_extension in ('jpg', 'jpeg', 'png', 'webp'): - image = input_message.file - mime = kind.mime if kind else 'application/octet-stream' input_message.file.seek(0) normalized_image = Image.open(input_message.file) @@ -151,7 +143,6 @@ class Grok(SimpleService): input_tokens=result[1], output_tokens=result[2], embedding_tokens=embedding_tokens, - image=image, ) msgs = self.save_results(result[0], process_time) return msgs @@ -176,7 +176,7 @@ def openrouter_run(version: str, messages: list, callback_data: dict, model_name ) reasoning = re.sub(r'Вывод:|Основная мысль:|Рассуждение:|\*\*', '', reasoning) answer = reasoning - if any(m in data['model'] for m in ('google/gemini', 'x-ai/grok-4.1-fast')) or re.match( + if any(m in data['model'] for m in ('google/gemini', 'x-ai/grok-4.3')) or re.match( r'^qwen/qwen3\.5-.*$', data['model'] ): answer = content