from datetime import datetime import gradio as gr from langchain.prompts import ChatPromptTemplate from langchain_community.llms import Ollama from func_facebook import get_page_id, get_unanswered_comments, reply_comment, \ process_negative_comments, process_negative_comments_in_post, get_comments, has_page_replied def log_message(message): timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') print(f"[{timestamp}] {message}") llm = Ollama(model="llama3.1") log_message("Модель Ollama 'llama3.1' инициализирована.") template = """ You are an assistant answering users' questions using only the links provided in the context. Your tasks: 1. **Brevity**: Respond concisely, using only relevant information from the context. 2. **Politeness**: Start your response with a greeting if appropriate, but prioritize maintaining a respectful and professional tone. 3. **Clarity**: Avoid unnecessary explanations and use simple language. 4. **Language of the response**: Detect the language of the user's comment and reply in the same language. 5. **Safety**: Do not use phrases like "according to the context" and remove any warnings. 6. **Accuracy**: Only use the links provided in the context and **always include them at the end of your response**. 7. **Stay on Topic**: If the user's input is a greeting or not directly related to the context, politely guide them back to the relevant topic without engaging in small talk. 8. **Links**: Always provide the relevant links from the context at the end of the response and **do not add any other links**. {context} Question: {input} """ def generate_response(user_query, context): log_message(f"Генерация ответа на запрос: {user_query}") prompt = ChatPromptTemplate.from_template(template) log_message(f"Контекст из базы данных: {context[:100]}...") full_prompt = prompt.format(context=context, input=user_query) response = llm.invoke(full_prompt) log_message(f"Сгенерированный ответ: {response}") return response def generate_responses(user_queries, context): log_message(f"Генерация ответов на {len(user_queries)} запросов") prompt = ChatPromptTemplate.from_template(template) # Формируем список полных промптов для каждого запроса full_prompts = [prompt.format(context=context, input=query) for query in user_queries] # Используем llm.batch для получения ответов на все промпты responses = llm.batch(full_prompts) log_message("Ответы сгенерированы.") return responses def process_single_post(post_id, token, action, user_context): log_message(f"Начинаем обработку поста {post_id}") page_id = get_page_id(token) full_post_id = page_id + "_" + post_id # Шаг 1: Скрытие негативных комментариев processed_comments = process_negative_comments_in_post(full_post_id, token, action) # Шаг 2: Получение неотвеченных комментариев comments = get_comments(full_post_id, token) unanswered_comments = [] for comment in comments: comment_id = comment['id'] if not comment.get('is_hidden', False) and not has_page_replied(comment_id, get_page_id(token), token): unanswered_comments.append(comment) log_message(f"Найдено {len(unanswered_comments)} неотвеченных комментариев.") # Шаг 3: Ответ на неотвеченные комментарии replies = [] for comment in unanswered_comments: message = comment['message'] response_message = generate_response(message, context=user_context) if reply_comment(comment_id=comment['id'], message=response_message, token=token): replies.append({ 'comment_id': comment['id'], 'comment_message': comment['message'], 'reply_message': response_message }) return [{ "status": "completed", "post_id": full_post_id, "hidden_or_deleted_comments": processed_comments, "replies": replies }] def process_comments(ACCESS_TOKEN, action, user_context): log_message(f"Selected action: {action}") hidden_comments_data = process_negative_comments(ACCESS_TOKEN, action) log_message(f"Количество постов с скрытыми комментариями: {len(hidden_comments_data)}") log_message("Получение неотвеченных комментариев.") posts_with_unanswered_comments = get_unanswered_comments(ACCESS_TOKEN) page_id = get_page_id(ACCESS_TOKEN) if not page_id: log_message("Не удалось получить ID страницы.") return {"status": "failed", "reason": "Не удалось получить ID страницы."} log_message(f"ID страницы: {page_id}") processed_comment_ids = set() # Отслеживание обработанных комментариев all_comments = [] all_comment_ids = [] comment_id_to_post_id = {} comment_id_to_message = {} for post_data in posts_with_unanswered_comments: post_id = post_data['post_id'] # post_message = post_data['post_message'] unanswered_comments = post_data['unanswered_comments'] for comment in unanswered_comments: comment_id = comment['id'] if comment_id in processed_comment_ids: log_message(f"Комментарий {comment_id} уже обработан. Пропуск.") continue processed_comment_ids.add(comment_id) message = comment['message'] log_message(f"Добавление комментария для обработки: {message}") # Сохраняем данные комментария all_comments.append(message) all_comment_ids.append(comment_id) comment_id_to_post_id[comment_id] = post_id comment_id_to_message[comment_id] = message # Генерируем ответы на все комментарии батчем responses = generate_responses(all_comments, context=user_context) # Собираем результаты в список для отображения result_data = [] for comment_id, response_message in zip(all_comment_ids, responses): log_message(f"Ответ на комментарий {comment_id}: {response_message}") success = reply_comment(comment_id=comment_id, message=response_message, token=ACCESS_TOKEN) if success: log_message(f"Успешно отправлен ответ на комментарий {comment_id}") else: log_message(f"Ошибка при отправке ответа на комментарий {comment_id}") # Добавляем информацию в результат result_data.append({ 'Post ID': comment_id_to_post_id[comment_id], 'Comment ID': comment_id, 'Comment': comment_id_to_message[comment_id], 'Response': response_message }) return result_data with gr.Blocks() as demo: gr.Markdown("# Facebook Comment Filter") token_input = gr.Textbox(label="Access Token") context_input = gr.Textbox(label="Контекст") radio = gr.Radio(["Hide", "Delete"], info="Choose hide or delete comments", show_label=False) with gr.Tab("Главная страница"): output_main = gr.JSON() process_btn = gr.Button("Процессировать комментарии") process_btn.click(process_comments, inputs=[token_input, radio, context_input], # Обновлено: добавлен context_input outputs=output_main) with gr.Tab("Обработать пост"): post_id = gr.Textbox(label="Post ID") output = gr.JSON() process_post_btn = gr.Button("Обработать пост") process_post_btn.click(process_single_post, inputs=[post_id, token_input, radio, context_input], outputs=output) if __name__ == "__main__": demo.launch( debug=True, server_port=7860, server_name="0.0.0.0" )