Merge remote-tracking branch 'origin/main' into feat/queue-based-graph-engine

This commit is contained in:
-LAN-
2025-09-06 16:05:13 +08:00
295 changed files with 769 additions and 793 deletions

View File

@ -225,7 +225,7 @@ class Tenant(Base):
)
@property
def custom_config_dict(self) -> dict:
def custom_config_dict(self):
return json.loads(self.custom_config) if self.custom_config else {}
@custom_config_dict.setter

View File

@ -339,15 +339,15 @@ class AppModelConfig(Base):
return app
@property
def model_dict(self) -> dict:
def model_dict(self):
return json.loads(self.model) if self.model else {}
@property
def suggested_questions_list(self) -> list:
def suggested_questions_list(self):
return json.loads(self.suggested_questions) if self.suggested_questions else []
@property
def suggested_questions_after_answer_dict(self) -> dict:
def suggested_questions_after_answer_dict(self):
return (
json.loads(self.suggested_questions_after_answer)
if self.suggested_questions_after_answer
@ -355,19 +355,19 @@ class AppModelConfig(Base):
)
@property
def speech_to_text_dict(self) -> dict:
def speech_to_text_dict(self):
return json.loads(self.speech_to_text) if self.speech_to_text else {"enabled": False}
@property
def text_to_speech_dict(self) -> dict:
def text_to_speech_dict(self):
return json.loads(self.text_to_speech) if self.text_to_speech else {"enabled": False}
@property
def retriever_resource_dict(self) -> dict:
def retriever_resource_dict(self):
return json.loads(self.retriever_resource) if self.retriever_resource else {"enabled": True}
@property
def annotation_reply_dict(self) -> dict:
def annotation_reply_dict(self):
annotation_setting = (
db.session.query(AppAnnotationSetting).where(AppAnnotationSetting.app_id == self.app_id).first()
)
@ -390,11 +390,11 @@ class AppModelConfig(Base):
return {"enabled": False}
@property
def more_like_this_dict(self) -> dict:
def more_like_this_dict(self):
return json.loads(self.more_like_this) if self.more_like_this else {"enabled": False}
@property
def sensitive_word_avoidance_dict(self) -> dict:
def sensitive_word_avoidance_dict(self):
return (
json.loads(self.sensitive_word_avoidance)
if self.sensitive_word_avoidance
@ -410,7 +410,7 @@ class AppModelConfig(Base):
return json.loads(self.user_input_form) if self.user_input_form else []
@property
def agent_mode_dict(self) -> dict:
def agent_mode_dict(self):
return (
json.loads(self.agent_mode)
if self.agent_mode
@ -418,15 +418,15 @@ class AppModelConfig(Base):
)
@property
def chat_prompt_config_dict(self) -> dict:
def chat_prompt_config_dict(self):
return json.loads(self.chat_prompt_config) if self.chat_prompt_config else {}
@property
def completion_prompt_config_dict(self) -> dict:
def completion_prompt_config_dict(self):
return json.loads(self.completion_prompt_config) if self.completion_prompt_config else {}
@property
def dataset_configs_dict(self) -> dict:
def dataset_configs_dict(self):
if self.dataset_configs:
dataset_configs: dict = json.loads(self.dataset_configs)
if "retrieval_model" not in dataset_configs:
@ -438,7 +438,7 @@ class AppModelConfig(Base):
}
@property
def file_upload_dict(self) -> dict:
def file_upload_dict(self):
return (
json.loads(self.file_upload)
if self.file_upload
@ -452,7 +452,7 @@ class AppModelConfig(Base):
}
)
def to_dict(self) -> dict:
def to_dict(self):
return {
"opening_statement": self.opening_statement,
"suggested_questions": self.suggested_questions_list,
@ -1088,7 +1088,7 @@ class Message(Base):
return self.override_model_configs is not None
@property
def message_metadata_dict(self) -> dict:
def message_metadata_dict(self):
return json.loads(self.message_metadata) if self.message_metadata else {}
@property
@ -1177,7 +1177,7 @@ class Message(Base):
return None
def to_dict(self) -> dict:
def to_dict(self):
return {
"id": self.id,
"app_id": self.app_id,
@ -1690,7 +1690,7 @@ class MessageAgentThought(Base):
created_at = mapped_column(sa.DateTime, nullable=False, server_default=db.func.current_timestamp())
@property
def files(self) -> list:
def files(self):
if self.message_files:
return cast(list[Any], json.loads(self.message_files))
else:
@ -1701,7 +1701,7 @@ class MessageAgentThought(Base):
return self.tool.split(";") if self.tool else []
@property
def tool_labels(self) -> dict:
def tool_labels(self):
try:
if self.tool_labels_str:
return cast(dict, json.loads(self.tool_labels_str))
@ -1711,7 +1711,7 @@ class MessageAgentThought(Base):
return {}
@property
def tool_meta(self) -> dict:
def tool_meta(self):
try:
if self.tool_meta_str:
return cast(dict, json.loads(self.tool_meta_str))
@ -1721,7 +1721,7 @@ class MessageAgentThought(Base):
return {}
@property
def tool_inputs_dict(self) -> dict:
def tool_inputs_dict(self):
tools = self.tools
try:
if self.tool_input:

View File

@ -26,15 +26,15 @@ if TYPE_CHECKING:
# system level tool oauth client params (client_id, client_secret, etc.)
class ToolOAuthSystemClient(Base):
class ToolOAuthSystemClient(TypeBase):
__tablename__ = "tool_oauth_system_clients"
__table_args__ = (
sa.PrimaryKeyConstraint("id", name="tool_oauth_system_client_pkey"),
sa.UniqueConstraint("plugin_id", "provider", name="tool_oauth_system_client_plugin_id_provider_idx"),
)
id: Mapped[str] = mapped_column(StringUUID, server_default=sa.text("uuid_generate_v4()"))
plugin_id = mapped_column(String(512), nullable=False)
id: Mapped[str] = mapped_column(StringUUID, server_default=sa.text("uuid_generate_v4()"), init=False)
plugin_id: Mapped[str] = mapped_column(String(512), nullable=False)
provider: Mapped[str] = mapped_column(String(255), nullable=False)
# oauth params of the tool provider
encrypted_oauth_params: Mapped[str] = mapped_column(sa.Text, nullable=False)
@ -58,7 +58,7 @@ class ToolOAuthTenantClient(Base):
encrypted_oauth_params: Mapped[str] = mapped_column(sa.Text, nullable=False)
@property
def oauth_params(self) -> dict:
def oauth_params(self):
return cast(dict, json.loads(self.encrypted_oauth_params or "{}"))
@ -100,7 +100,7 @@ class BuiltinToolProvider(Base):
expires_at: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("-1"))
@property
def credentials(self) -> dict:
def credentials(self):
return cast(dict, json.loads(self.encrypted_credentials))
@ -154,7 +154,7 @@ class ApiToolProvider(Base):
return [ApiToolBundle(**tool) for tool in json.loads(self.tools_str)]
@property
def credentials(self) -> dict:
def credentials(self):
return dict(json.loads(self.credentials_str))
@property
@ -299,7 +299,7 @@ class MCPToolProvider(Base):
return db.session.query(Tenant).where(Tenant.id == self.tenant_id).first()
@property
def credentials(self) -> dict:
def credentials(self):
try:
return cast(dict, json.loads(self.encrypted_credentials)) or {}
except Exception:
@ -341,7 +341,7 @@ class MCPToolProvider(Base):
return mask_url(self.decrypted_server_url)
@property
def decrypted_credentials(self) -> dict:
def decrypted_credentials(self):
from core.helper.provider_cache import NoOpProviderCredentialCache
from core.tools.mcp_tool.provider import MCPToolProviderController
from core.tools.utils.encryption import create_provider_encrypter
@ -422,11 +422,11 @@ class ToolConversationVariables(Base):
updated_at = mapped_column(sa.DateTime, nullable=False, server_default=func.current_timestamp())
@property
def variables(self) -> Any:
def variables(self):
return json.loads(self.variables_str)
class ToolFile(Base):
class ToolFile(TypeBase):
"""This table stores file metadata generated in workflows,
not only files created by agent.
"""
@ -437,19 +437,19 @@ class ToolFile(Base):
sa.Index("tool_file_conversation_id_idx", "conversation_id"),
)
id: Mapped[str] = mapped_column(StringUUID, server_default=sa.text("uuid_generate_v4()"))
id: Mapped[str] = mapped_column(StringUUID, server_default=sa.text("uuid_generate_v4()"), init=False)
# conversation user id
user_id: Mapped[str] = mapped_column(StringUUID)
# tenant id
tenant_id: Mapped[str] = mapped_column(StringUUID)
# conversation id
conversation_id: Mapped[str] = mapped_column(StringUUID, nullable=True)
conversation_id: Mapped[Optional[str]] = mapped_column(StringUUID, nullable=True)
# file key
file_key: Mapped[str] = mapped_column(String(255), nullable=False)
# mime type
mimetype: Mapped[str] = mapped_column(String(255), nullable=False)
# original url
original_url: Mapped[str] = mapped_column(String(2048), nullable=True)
original_url: Mapped[Optional[str]] = mapped_column(String(2048), nullable=True, default=None)
# name
name: Mapped[str] = mapped_column(default="")
# size

View File

@ -282,14 +282,14 @@ class Workflow(Base):
return self._features
@features.setter
def features(self, value: str) -> None:
def features(self, value: str):
self._features = value
@property
def features_dict(self) -> dict[str, Any]:
return json.loads(self.features) if self.features else {}
def user_input_form(self, to_old_structure: bool = False) -> list:
def user_input_form(self, to_old_structure: bool = False):
# get start node from graph
if not self.graph:
return []
@ -439,7 +439,7 @@ class Workflow(Base):
return results
@conversation_variables.setter
def conversation_variables(self, value: Sequence[Variable]) -> None:
def conversation_variables(self, value: Sequence[Variable]):
self._conversation_variables = json.dumps(
{var.name: var.model_dump() for var in value},
ensure_ascii=False,
@ -892,7 +892,7 @@ class ConversationVariable(Base):
DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp()
)
def __init__(self, *, id: str, app_id: str, conversation_id: str, data: str) -> None:
def __init__(self, *, id: str, app_id: str, conversation_id: str, data: str):
self.id = id
self.app_id = app_id
self.conversation_id = conversation_id
@ -1073,7 +1073,7 @@ class WorkflowDraftVariable(Base):
return self.build_segment_with_type(self.value_type, value)
@staticmethod
def rebuild_file_types(value: Any) -> Any:
def rebuild_file_types(value: Any):
# NOTE(QuantumGhost): Temporary workaround for structured data handling.
# By this point, `output` has been converted to dict by
# `WorkflowEntry.handle_special_values`, so we need to