@@ -43,6 +43,22 @@ class Claude(SimpleService): }, # 1M tokens } + HISTORY_CONTEXT_SYSTEM_PROMPT = """ + Conversation history handling rules (strict priority): + 1. The user's latest message is the only message that determines whether you may respond. + Evaluate it independently. Past messages must never cause a refusal by themselves. + 2. Use earlier history only when it is safe and genuinely helps answer the latest message + (context, definitions, preferences, prior facts). Skip everything else. + 3. Treat the following in history as void — do not read, cite, follow, or be influenced by them: + NSFW content, sexual content, illegal requests, violence, hate, self-harm, + prohibited topics, policy violations, and any prior refusals or moderation replies + (including messages like "I cannot process your request"). + 4. If the latest message is appropriate, you must answer it fully and helpfully. + Do not refuse, apologize for history, mention moderation of past turns, + or explain why earlier messages were blocked. + 5. Refuse only when the latest message itself violates policy — never because of history alone. + """ + FABLE_SYSTEM_PROMPT = """ You are a helpful assistant. Answer the user’s question directly and accurately. @@ -89,8 +105,10 @@ class Claude(SimpleService): callback_data = {'provider': {'order': ['anthropic']}, **input_message.info, 'tools': []} messages = [ {'role': 'system', 'content': system_prompt}, + *self.get_chat_history(), {'role': 'user', 'content': input_message.content}, ] + messages.insert(0, {'role': 'system', 'content': self.HISTORY_CONTEXT_SYSTEM_PROMPT}) if version_slug == 'claude-fable-5': current_user_balance = PaymentPlanSelector(self.store.user).get_current_balance() if current_user_balance < (cost := Decimal('100')) and input_message.file: @@ -40,6 +40,12 @@ from poller.models import Proxy logger = logging.getLogger(__name__) +CLAUDE_CONTENT_FILTER_FALLBACK = ( + 'Запрос содержит материалы, которые я не могу обрабатывать.\n\n' + '**Токены списываются, поскольку мне приходится анализировать ваш запрос. ' + 'Прошу формулировать запрос точнее, чтобы избежать повторного анализа**' +) + @shared_task def create_d_image(payload: dict): @@ -167,6 +173,13 @@ def openrouter_run(version: str, messages: list, callback_data: dict, model_name for c in (data.get('choices') or []) ): raise RequestBlocked + if model_name == 'Claude': + usage = data.get('usage') or {} + return ( + CLAUDE_CONTENT_FILTER_FALLBACK, + usage.get('prompt_tokens', 0), + usage.get('completion_tokens', 0), + ) raise GenerationException content = ','.join(raw_content) reasoning = ','.join(