|
6 | 6 | @date:2024/6/4 14:30 |
7 | 7 | @desc: |
8 | 8 | """ |
| 9 | +import base64 |
9 | 10 | import json |
10 | 11 | import re |
11 | 12 | import time |
12 | 13 | from functools import reduce |
| 14 | +from imghdr import what |
13 | 15 | from typing import List, Dict |
14 | 16 |
|
15 | 17 | from django.db.models import QuerySet |
|
25 | 27 | from common.utils.rsa_util import rsa_long_decrypt |
26 | 28 | from common.utils.shared_resource_auth import filter_authorized_ids |
27 | 29 | from common.utils.tool_code import ToolExecutor |
| 30 | +from knowledge.models import File |
28 | 31 | from models_provider.models import Model |
29 | 32 | from models_provider.tools import get_model_credential, get_model_instance_by_model_workspace_id |
30 | 33 | from tools.models import Tool, ToolType |
@@ -196,11 +199,11 @@ def execute(self, model_id, system, prompt, dialogue_number, history_chat_record |
196 | 199 | self.runtime_node_id) |
197 | 200 | self.context['history_message'] = [{'content': message.content, 'role': message.type} for message in |
198 | 201 | (history_message if history_message is not None else [])] |
199 | | - question = self.generate_prompt_question(prompt) |
| 202 | + question = self.generate_prompt_question(prompt, chat_model) |
200 | 203 | self.context['question'] = question.content |
201 | 204 | system = self.workflow_manage.generate_prompt(system) |
202 | 205 | self.context['system'] = system |
203 | | - message_list = self.generate_message_list(prompt, history_message) |
| 206 | + message_list = self.generate_message_list(question, history_message) |
204 | 207 | self.context['message_list'] = message_list |
205 | 208 |
|
206 | 209 | # 过滤tool_id |
@@ -386,11 +389,73 @@ def get_history_message(history_chat_record, dialogue_number, dialogue_type, run |
386 | 389 | message.content = re.sub(r'<form_rander>.*?<\/form_rander>', '', message.content, flags=re.DOTALL) |
387 | 390 | return history_message |
388 | 391 |
|
389 | | - def generate_prompt_question(self, prompt): |
390 | | - return HumanMessage(self.workflow_manage.generate_prompt(prompt)) |
| 392 | + def generate_prompt_question(self, prompt, model): |
| 393 | + image = self.get_image() |
| 394 | + video = self.get_video() |
| 395 | + videos = [] |
| 396 | + images = [] |
| 397 | + if image: |
| 398 | + images = self._process_images(image) |
| 399 | + if video: |
| 400 | + videos = self._process_videos(video, model) |
| 401 | + return HumanMessage( |
| 402 | + content=[*videos, *images, {'type': 'text', 'text': self.workflow_manage.generate_prompt(prompt)}]) |
| 403 | + |
| 404 | + def get_image(self): |
| 405 | + if 'image_list' in self.node_params_serializer.data: |
| 406 | + image = self.workflow_manage.get_reference_field(self.node_params_serializer.data.get('image_list')[0], |
| 407 | + self.node_params_serializer.data.get('image_list')[1:]) |
| 408 | + return image |
| 409 | + return None |
| 410 | + |
| 411 | + def get_video(self): |
| 412 | + if 'video_list' in self.node_params_serializer.data: |
| 413 | + video = self.workflow_manage.get_reference_field(self.node_params_serializer.data.get('video_list')[0], |
| 414 | + self.node_params_serializer.data.get('video_list')[1:]) |
| 415 | + return video |
| 416 | + return None |
391 | 417 |
|
392 | | - def generate_message_list(self, prompt: str, history_message): |
393 | | - return [*history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] |
| 418 | + def _process_videos(self, image, video_model): |
| 419 | + videos = [] |
| 420 | + if isinstance(image, str) and image.startswith('http'): |
| 421 | + videos.append({'type': 'video_url', 'video_url': {'url': image}}) |
| 422 | + elif image is not None and len(image) > 0: |
| 423 | + for img in image: |
| 424 | + if 'file_id' in img: |
| 425 | + file_id = img['file_id'] |
| 426 | + file = QuerySet(File).filter(id=file_id).first() |
| 427 | + url = video_model.upload_file_and_get_url(file.get_bytes(), file.file_name) |
| 428 | + videos.append( |
| 429 | + {'type': 'video_url', 'video_url': {'url': url}}) |
| 430 | + elif 'url' in img and img['url'].startswith('http'): |
| 431 | + videos.append( |
| 432 | + {'type': 'video_url', 'video_url': {'url': img['url']}}) |
| 433 | + return videos |
| 434 | + |
| 435 | + def _process_images(self, image): |
| 436 | + """ |
| 437 | + 处理图像数据,转换为模型可识别的格式 |
| 438 | + """ |
| 439 | + images = [] |
| 440 | + if isinstance(image, str) and image.startswith('http'): |
| 441 | + images.append({'type': 'image_url', 'image_url': {'url': image}}) |
| 442 | + elif image is not None and len(image) > 0: |
| 443 | + for img in image: |
| 444 | + if 'file_id' in img: |
| 445 | + file_id = img['file_id'] |
| 446 | + file = QuerySet(File).filter(id=file_id).first() |
| 447 | + image_bytes = file.get_bytes() |
| 448 | + base64_image = base64.b64encode(image_bytes).decode("utf-8") |
| 449 | + image_format = what(None, image_bytes) |
| 450 | + images.append( |
| 451 | + {'type': 'image_url', 'image_url': {'url': f'data:image/{image_format};base64,{base64_image}'}}) |
| 452 | + elif 'url' in img and img['url'].startswith('http'): |
| 453 | + images.append( |
| 454 | + {'type': 'image_url', 'image_url': {'url': img["url"]}}) |
| 455 | + return images |
| 456 | + |
| 457 | + def generate_message_list(self, question, history_message): |
| 458 | + return [*history_message, question] |
394 | 459 |
|
395 | 460 | @staticmethod |
396 | 461 | def reset_message_list(message_list: List[BaseMessage], answer_text): |
|
0 commit comments