mirror of
https://github.com/langgenius/dify.git
synced 2026-05-02 16:38:04 +08:00
feat(api): Add image multimodal support for LLMNode (#17372)
Enhance `LLMNode` with multimodal capability, introducing support for image outputs. This implementation extracts base64-encoded images from LLM responses, saves them to the storage service, and records the file metadata in the `ToolFile` table. In conversations, these images are rendered as markdown-based inline images. Additionally, the images are included in the LLMNode's output as file variables, enabling subsequent nodes in the workflow to utilize them. To integrate file outputs into workflows, adjustments to the frontend code are necessary. For multimodal output functionality, updates to related model configurations are required. Currently, this capability has been applied exclusively to Google's Gemini models. Close #15814. Signed-off-by: -LAN- <laipz8200@outlook.com> Co-authored-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
@ -10,4 +10,16 @@ POSTGRES_INDEXES_NAMING_CONVENTION = {
|
||||
}
|
||||
|
||||
metadata = MetaData(naming_convention=POSTGRES_INDEXES_NAMING_CONVENTION)
|
||||
|
||||
# ****** IMPORTANT NOTICE ******
|
||||
#
|
||||
# NOTE(QuantumGhost): Avoid directly importing and using `db` in modules outside of the
|
||||
# `controllers` package.
|
||||
#
|
||||
# Instead, import `db` within the `controllers` package and pass it as an argument to
|
||||
# functions or class constructors.
|
||||
#
|
||||
# Directly importing `db` in other modules can make the code more difficult to read, test, and maintain.
|
||||
#
|
||||
# Whenever possible, avoid this pattern in new code.
|
||||
db = SQLAlchemy(metadata=metadata)
|
||||
|
||||
@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any, Literal, Optional, cast
|
||||
|
||||
from core.plugin.entities.plugin import GenericProviderID
|
||||
from core.tools.entities.tool_entities import ToolProviderType
|
||||
from core.tools.signature import sign_tool_file
|
||||
from services.plugin.plugin_service import PluginService
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -23,7 +24,6 @@ from configs import dify_config
|
||||
from constants import DEFAULT_FILE_NUMBER_LIMITS
|
||||
from core.file import FILE_MODEL_IDENTITY, File, FileTransferMethod, FileType
|
||||
from core.file import helpers as file_helpers
|
||||
from core.file.tool_file_parser import ToolFileParser
|
||||
from libs.helper import generate_string
|
||||
from models.base import Base
|
||||
from models.enums import CreatedByRole
|
||||
@ -986,9 +986,7 @@ class Message(db.Model): # type: ignore[name-defined]
|
||||
if not tool_file_id:
|
||||
continue
|
||||
|
||||
sign_url = ToolFileParser.get_tool_file_manager().sign_file(
|
||||
tool_file_id=tool_file_id, extension=extension
|
||||
)
|
||||
sign_url = sign_tool_file(tool_file_id=tool_file_id, extension=extension)
|
||||
elif "file-preview" in url:
|
||||
# get upload file id
|
||||
upload_file_id_pattern = r"\/files\/([\w-]+)\/file-preview?\?timestamp="
|
||||
|
||||
@ -263,8 +263,8 @@ class ToolConversationVariables(Base):
|
||||
|
||||
|
||||
class ToolFile(Base):
|
||||
"""
|
||||
store the file created by agent
|
||||
"""This table stores file metadata generated in workflows,
|
||||
not only files created by agent.
|
||||
"""
|
||||
|
||||
__tablename__ = "tool_files"
|
||||
|
||||
Reference in New Issue
Block a user