diff --git a/api/controllers/service_api/app/message.py b/api/controllers/service_api/app/message.py
index 9a9b3f65ca..08f382b0a7 100644
--- a/api/controllers/service_api/app/message.py
+++ b/api/controllers/service_api/app/message.py
@@ -63,7 +63,9 @@ class MessageListApi(Resource):
'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True),
'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)),
'created_at': TimestampField,
- 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields))
+ 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)),
+ 'status': fields.String,
+ 'error': fields.String,
}
message_infinite_scroll_pagination_fields = {
diff --git a/api/controllers/web/message.py b/api/controllers/web/message.py
index cd75455f3d..865d2270ad 100644
--- a/api/controllers/web/message.py
+++ b/api/controllers/web/message.py
@@ -66,7 +66,9 @@ class MessageListApi(WebApiResource):
'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True),
'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)),
'created_at': TimestampField,
- 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields))
+ 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)),
+ 'status': fields.String,
+ 'error': fields.String,
}
message_infinite_scroll_pagination_fields = {
diff --git a/api/core/app/apps/advanced_chat/generate_task_pipeline.py b/api/core/app/apps/advanced_chat/generate_task_pipeline.py
index edef4e249b..3539f906cc 100644
--- a/api/core/app/apps/advanced_chat/generate_task_pipeline.py
+++ b/api/core/app/apps/advanced_chat/generate_task_pipeline.py
@@ -217,7 +217,7 @@ class AdvancedChatAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCyc
if workflow_run:
if workflow_run.status == WorkflowRunStatus.FAILED.value:
err_event = QueueErrorEvent(error=ValueError(f'Run failed: {workflow_run.error}'))
- yield self._error_to_stream_response(self._handle_error(err_event))
+ yield self._error_to_stream_response(self._handle_error(err_event, self._message))
break
yield self._workflow_finish_to_stream_response(
diff --git a/api/core/app/task_pipeline/based_generate_task_pipeline.py b/api/core/app/task_pipeline/based_generate_task_pipeline.py
index b8d7d731b8..a3c1fb5824 100644
--- a/api/core/app/task_pipeline/based_generate_task_pipeline.py
+++ b/api/core/app/task_pipeline/based_generate_task_pipeline.py
@@ -14,7 +14,7 @@ from core.app.entities.task_entities import (
PingStreamResponse,
TaskState,
)
-from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
+from core.errors.error import QuotaExceededError
from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError
from core.moderation.output_moderation import ModerationRule, OutputModeration
from extensions.ext_database import db
@@ -83,24 +83,12 @@ class BasedGenerateTaskPipeline:
:param e: exception
:return:
"""
- error_responses = {
- ValueError: None,
- ProviderTokenNotInitError: None,
- QuotaExceededError: "Your quota for Dify Hosted Model Provider has been exhausted. "
- "Please go to Settings -> Model Provider to complete your own provider credentials.",
- ModelCurrentlyNotSupportError: None,
- InvokeError: None
- }
+ if isinstance(e, QuotaExceededError):
+ return ("Your quota for Dify Hosted Model Provider has been exhausted. "
+ "Please go to Settings -> Model Provider to complete your own provider credentials.")
- # Determine the response based on the type of exception
- data = None
- for k, v in error_responses.items():
- if isinstance(e, k):
- data = v
-
- if data:
- message = getattr(e, 'description', str(e)) if data is None else data
- else:
+ message = getattr(e, 'description', str(e))
+ if not message:
message = 'Internal Server Error, please contact support.'
return message
diff --git a/api/core/workflow/nodes/llm/llm_node.py b/api/core/workflow/nodes/llm/llm_node.py
index df7b33d4c3..cf2f9b7176 100644
--- a/api/core/workflow/nodes/llm/llm_node.py
+++ b/api/core/workflow/nodes/llm/llm_node.py
@@ -545,7 +545,7 @@ class LLMNode(BaseNode):
"prompt": {
"text": "Here is the chat histories between human and assistant, inside "
" XML tags.\n\n\n{{"
- "#histories#}}\n\n\n\nHuman: {{#query#}}\n\nAssistant:"
+ "#histories#}}\n\n\n\nHuman: {{#sys.query#}}\n\nAssistant:"
},
"stop": ["Human:"]
}
diff --git a/api/fields/app_fields.py b/api/fields/app_fields.py
index 275e24b230..4ef00345f2 100644
--- a/api/fields/app_fields.py
+++ b/api/fields/app_fields.py
@@ -6,7 +6,7 @@ app_detail_kernel_fields = {
'id': fields.String,
'name': fields.String,
'description': fields.String,
- 'mode': fields.String,
+ 'mode': fields.String(attribute='mode_compatible_with_agent'),
'icon': fields.String,
'icon_background': fields.String,
}
@@ -43,7 +43,7 @@ app_detail_fields = {
'id': fields.String,
'name': fields.String,
'description': fields.String,
- 'mode': fields.String,
+ 'mode': fields.String(attribute='mode_compatible_with_agent'),
'icon': fields.String,
'icon_background': fields.String,
'enable_site': fields.Boolean,
@@ -65,7 +65,7 @@ app_partial_fields = {
'id': fields.String,
'name': fields.String,
'description': fields.String(attribute='desc_or_prompt'),
- 'mode': fields.String,
+ 'mode': fields.String(attribute='mode_compatible_with_agent'),
'icon': fields.String,
'icon_background': fields.String,
'model_config': fields.Nested(model_config_partial_fields, attribute='app_model_config', allow_null=True),
@@ -113,7 +113,7 @@ app_detail_fields_with_site = {
'id': fields.String,
'name': fields.String,
'description': fields.String,
- 'mode': fields.String,
+ 'mode': fields.String(attribute='mode_compatible_with_agent'),
'icon': fields.String,
'icon_background': fields.String,
'enable_site': fields.Boolean,
diff --git a/api/fields/conversation_fields.py b/api/fields/conversation_fields.py
index 4a8df14c9f..c331384b37 100644
--- a/api/fields/conversation_fields.py
+++ b/api/fields/conversation_fields.py
@@ -72,6 +72,8 @@ message_detail_fields = {
'created_at': TimestampField,
'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)),
'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'),
+ 'status': fields.String,
+ 'error': fields.String,
}
feedback_stat_fields = {
diff --git a/api/fields/message_fields.py b/api/fields/message_fields.py
index 4153db373a..3116843589 100644
--- a/api/fields/message_fields.py
+++ b/api/fields/message_fields.py
@@ -73,7 +73,9 @@ message_fields = {
'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)),
'created_at': TimestampField,
'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)),
- 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files')
+ 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'),
+ 'status': fields.String,
+ 'error': fields.String,
}
message_infinite_scroll_pagination_fields = {
diff --git a/api/models/model.py b/api/models/model.py
index 037b0aff43..c767cfebc2 100644
--- a/api/models/model.py
+++ b/api/models/model.py
@@ -126,9 +126,18 @@ class App(db.Model):
return False
if self.app_model_config.agent_mode_dict.get('enabled', False) \
and self.app_model_config.agent_mode_dict.get('strategy', '') in ['function_call', 'react']:
+ self.mode = AppMode.AGENT_CHAT.value
+ db.session.commit()
return True
return False
+ @property
+ def mode_compatible_with_agent(self) -> str:
+ if self.mode == AppMode.CHAT.value and self.is_agent:
+ return AppMode.AGENT_CHAT.value
+
+ return self.mode
+
@property
def deleted_tools(self) -> list:
# get agent mode tools
diff --git a/api/services/workflow/workflow_converter.py b/api/services/workflow/workflow_converter.py
index 86c30bd33f..d8779ce313 100644
--- a/api/services/workflow/workflow_converter.py
+++ b/api/services/workflow/workflow_converter.py
@@ -296,7 +296,7 @@ class WorkflowConverter:
request_body_json = request_body_json.replace('\{\{', '{{').replace('\}\}', '}}')
http_request_node = {
- "id": f"http-request-{index}",
+ "id": f"http_request_{index}",
"position": None,
"data": {
"title": f"HTTP REQUEST {api_based_extension.name}",
@@ -323,7 +323,7 @@ class WorkflowConverter:
# append code node for response body parsing
code_node = {
- "id": f"code-{index}",
+ "id": f"code_{index}",
"position": None,
"data": {
"title": f"Parse {api_based_extension.name} Response",
@@ -335,12 +335,11 @@ class WorkflowConverter:
"code_language": "python3",
"code": "import json\n\ndef main(response_json: str) -> str:\n response_body = json.loads("
"response_json)\n return {\n \"result\": response_body[\"result\"]\n }",
- "outputs": [
- {
- "variable": "result",
- "variable_type": "string"
+ "outputs": {
+ "result": {
+ "type": "string"
}
- ]
+ }
}
}
@@ -370,7 +369,7 @@ class WorkflowConverter:
return None
return {
- "id": "knowledge-retrieval",
+ "id": "knowledge_retrieval",
"position": None,
"data": {
"title": "KNOWLEDGE RETRIEVAL",
@@ -497,6 +496,8 @@ class WorkflowConverter:
else:
text = ""
+ text = text.replace('{{#query#}}', '{{#sys.query#}}')
+
prompts = {
"text": text,
}
@@ -534,7 +535,7 @@ class WorkflowConverter:
"memory": memory,
"context": {
"enabled": knowledge_retrieval_node is not None,
- "variable_selector": ["knowledge-retrieval", "result"]
+ "variable_selector": ["knowledge_retrieval", "result"]
if knowledge_retrieval_node is not None else None
},
"vision": {