[PR #31121] fix: call get_text_content() instead of casting to str #33100

Closed
opened 2026-02-21 20:52:39 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/31121

State: closed
Merged: Yes


Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

/rule-generate with Gemini 2.5 pro will fail with code 500:

[on_llm_before_invoke]
Model: gemini-2.5-pro
Parameters:
Stream: False
Prompt messages:
        role: user
        content:
Here is a task description for which I would like you to create a high-quality prompt template for:
<task_description>
The output of this prompt is not as expected: {{#last_run#}}.
You should edit the prompt according to the IDEAL OUTPUT.
</task_description>
Based on task description, please create a well-structured prompt template that another AI could use to consistently complete the task. The prompt template should include:
- Descriptive variable names surrounded by {{ }} (two curly brackets) to indicate where the actual values will be substituted in. Choose variable names that clearly indicate the type of value expected. Variable names have to be composed of number, english alphabets and underline and nothing else.
- Clear instructions for the AI that will be using this prompt, demarcated with <instruction> tags. The instructions should provide step-by-step directions on how to complete the task using the input variables. Also Specifies in the instructions that the output should not contain any xml tag.
- Relevant examples if needed to clarify the task further, demarcated with <example> tags. Do not use curly brackets any other than in <instruction> section.
- Any other relevant sections demarcated with appropriate XML tags like <input>, <output>, etc.
- Use the same language as task description.
- Output in ``` xml ``` and start with <instruction>
Please generate the full prompt template and output only the prompt template.
2026-01-16 07:27:29.824 INFO [Thread-2236 (process_request_thread)] [_internal.py:97] 26eb4877753b5aeba8ad9ee030ec7caf - 172.20.0.23 - - [16/Jan/2026 07:27:29] "POST /console/api/apps/fbb73341-f28a-43d9-901c-d0251fbe6ed5/workflows/draft HTTP/1.1" 200 -
2026-01-16 07:27:36.319 INFO [Thread-2235 (process_request_thread)] [_client.py:1038] 7e1cd831bcbf5f8dacecb43e0cceb60e - HTTP Request: POST http://plugin_daemon:5002/plugin/5686915f-1145-4226-9490-d7e08f1df00e/dispatch/llm/invoke "HTTP/1.1 200 OK"
[on_llm_after_invoke]
Content: [TextPromptMessageContent(type=<PromptMessageContentType.TEXT: 'text'>, data='```xml\n<instruction>\nYou are an expert prompt engineer. Your task is to analyze an original prompt, its unsatisfactory output, and an ideal output, and then rewrite the original prompt to make it better. The goal is to create a new prompt that will consistently generate outputs similar in quality and structure to the ideal one.\n\nFollow these steps to complete the task:\n1.  **Analyze the Input:** Carefully review the `{{original_prompt}}`, the `{{unexpected_output}}`, and the `{{ideal_output}}`.\n2.  **Identify the Gap:** Determine why the `{{original_prompt}}` failed. Was it too vague, ambiguous, or lacking in specific constraints (e.g., format, tone, length)? Compare the `{{unexpected_output}}` with the `{{ideal_output}}` to pinpoint the exact differences.\n3.  **Formulate a Strategy:** Based on your analysis, decide what changes are needed. This might include adding context, defining the desired format, specifying a persona for the AI, providing examples, or setting clear constraints.\n4.  **Rewrite the Prompt:** Edit the `{{original_prompt}}` to create a new, high-quality prompt. This revised prompt should be clear, detailed, and structured to guide an AI toward producing outputs that match the style and quality of the `{{ideal_output}}`.\n5.  **Final Output:** Your output must be ONLY the text of the new, revised prompt. Do not include any extra explanations, introductory phrases like "Here is the revised prompt:", or any xml tags.\n</instruction>\n\n<example>\n<input>\n<original_prompt>\nWrite a title for a blog post about productivity.\n</original_prompt>\n<unexpected_output>\nProductivity Tips\n</unexpected_output>\n<ideal_output>\n10x Your Output: 5 Unconventional Productivity Hacks You Haven\'t Tried\n</ideal_output>\n</input>\n<output>\nGenerate 5 catchy and compelling blog post titles about productivity. The titles should be action-oriented and create a sense of curiosity. They should target an audience looking for unique, non-obvious tips. Include numbers where appropriate to suggest a list format.\n</output>\n</example>\n\n<input>\n<original_prompt>\n{{original_prompt}}\n</original_prompt>\n<unexpected_output>\n{{unexpected_output}}\n</unexpected_output>\n<ideal_output>\n{{ideal_output}}\n</ideal_output>\n</input>\n```')]
Model: gemini-2.5-pro
Usage: prompt_tokens=303 prompt_unit_price=Decimal('1.25') prompt_price_unit=Decimal('0.000001') prompt_price=Decimal('0.0003788') completion_tokens=2310 completion_unit_price=Decimal('10') completion_price_unit=Decimal('0.000001') completion_price=Decimal('0.0231') total_tokens=2613 total_price=Decimal('0.0234788') currency='USD' latency=19.303683698002715 time_to_first_token=None time_to_generate=None
System Fingerprint:
2026-01-16 07:27:36.322 ERROR [Thread-2235 (process_request_thread)] [llm_generator.py:281] 7e1cd831bcbf5f8dacecb43e0cceb60e - Failed to generate rule config, model: gemini-2.5-pro
Traceback (most recent call last):
  File "/app/api/core/llm_generator/llm_generator.py", line 243, in generate_rule_config
    raise NotImplementedError("prompt content is not a string")
NotImplementedError: prompt content is not a string
2026-01-16 07:27:36.337 ERROR [Thread-2235 (process_request_thread)] [app.py:875] 7e1cd831bcbf5f8dacecb43e0cceb60e - Exception on /console/api/rule-generate [POST]
Traceback (most recent call last):
  File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/api.py", line 408, in wrapper
    return self.make_response(data, code, headers=headers)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/api.py", line 432, in make_response
    resp = self.representations[mediatype](data, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/representations.py", line 22, in output_json
    dumped = dumps(data, **settings) + "\n"
             ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: TextPromptMessageContent(type=<PromptMessageContentType.TEXT: 'text'>, data='```xml\n<instruction>\nYou are an expert prompt engineer. Your task is to analyze an original prompt, its unsatisfactory output, and an ideal output, and then rewrite the original prompt to make it better. The goal is to create a new prompt that will consistently generate outputs similar in quality and structure to the ideal one.\n\nFollow these steps to complete the task:\n1.  **Analyze the Input:** Carefully review the `{{original_prompt}}`, the `{{unexpected_output}}`, and the `{{ideal_output}}`.\n2.  **Identify the Gap:** Determine why the `{{original_prompt}}` failed. Was it too vague, ambiguous, or lacking in specific constraints (e.g., format, tone, length)? Compare the `{{unexpected_output}}` with the `{{ideal_output}}` to pinpoint the exact differences.\n3.  **Formulate a Strategy:** Based on your analysis, decide what changes are needed. This might include adding context, defining the desired format, specifying a persona for the AI, providing examples, or setting clear constraints.\n4.  **Rewrite the Prompt:** Edit the `{{original_prompt}}` to create a new, high-quality prompt. This revised prompt should be clear, detailed, and structured to guide an AI toward producing outputs that match the style and quality of the `{{ideal_output}}`.\n5.  **Final Output:** Your output must be ONLY the text of the new, revised prompt. Do not include any extra explanations, introductory phrases like "Here is the revised prompt:", or any xml tags.\n</instruction>\n\n<example>\n<input>\n<original_prompt>\nWrite a title for a blog post about productivity.\n</original_prompt>\n<unexpected_output>\nProductivity Tips\n</unexpected_output>\n<ideal_output>\n10x Your Output: 5 Unconventional Productivity Hacks You Haven\'t Tried\n</ideal_output>\n</input>\n<output>\nGenerate 5 catchy and compelling blog post titles about productivity. The titles should be action-oriented and create a sense of curiosity. They should target an audience looking for unique, non-obvious tips. Include numbers where appropriate to suggest a list format.\n</output>\n</example>\n\n<input>\n<original_prompt>\n{{original_prompt}}\n</original_prompt>\n<unexpected_output>\n{{unexpected_output}}\n</unexpected_output>\n<ideal_output>\n{{ideal_output}}\n</ideal_output>\n</input>\n```') is not JSON serializable

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint and make type-check (backend) and cd web && npx lint-staged (frontend) to appease the lint gods
**Original Pull Request:** https://github.com/langgenius/dify/pull/31121 **State:** closed **Merged:** Yes --- > [!IMPORTANT] > > 1. Make sure you have read our [contribution guidelines](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) > 1. Ensure there is an associated issue and you have been assigned to it > 1. Use the correct syntax to link this PR: `Fixes #<issue number>`. ## Summary `/rule-generate` with Gemini 2.5 pro will fail with code 500: ```terminaloutput [on_llm_before_invoke] Model: gemini-2.5-pro Parameters: Stream: False Prompt messages: role: user content: Here is a task description for which I would like you to create a high-quality prompt template for: <task_description> The output of this prompt is not as expected: {{#last_run#}}. You should edit the prompt according to the IDEAL OUTPUT. </task_description> Based on task description, please create a well-structured prompt template that another AI could use to consistently complete the task. The prompt template should include: - Descriptive variable names surrounded by {{ }} (two curly brackets) to indicate where the actual values will be substituted in. Choose variable names that clearly indicate the type of value expected. Variable names have to be composed of number, english alphabets and underline and nothing else. - Clear instructions for the AI that will be using this prompt, demarcated with <instruction> tags. The instructions should provide step-by-step directions on how to complete the task using the input variables. Also Specifies in the instructions that the output should not contain any xml tag. - Relevant examples if needed to clarify the task further, demarcated with <example> tags. Do not use curly brackets any other than in <instruction> section. - Any other relevant sections demarcated with appropriate XML tags like <input>, <output>, etc. - Use the same language as task description. - Output in ``` xml ``` and start with <instruction> Please generate the full prompt template and output only the prompt template. 2026-01-16 07:27:29.824 INFO [Thread-2236 (process_request_thread)] [_internal.py:97] 26eb4877753b5aeba8ad9ee030ec7caf - 172.20.0.23 - - [16/Jan/2026 07:27:29] "POST /console/api/apps/fbb73341-f28a-43d9-901c-d0251fbe6ed5/workflows/draft HTTP/1.1" 200 - 2026-01-16 07:27:36.319 INFO [Thread-2235 (process_request_thread)] [_client.py:1038] 7e1cd831bcbf5f8dacecb43e0cceb60e - HTTP Request: POST http://plugin_daemon:5002/plugin/5686915f-1145-4226-9490-d7e08f1df00e/dispatch/llm/invoke "HTTP/1.1 200 OK" [on_llm_after_invoke] Content: [TextPromptMessageContent(type=<PromptMessageContentType.TEXT: 'text'>, data='```xml\n<instruction>\nYou are an expert prompt engineer. Your task is to analyze an original prompt, its unsatisfactory output, and an ideal output, and then rewrite the original prompt to make it better. The goal is to create a new prompt that will consistently generate outputs similar in quality and structure to the ideal one.\n\nFollow these steps to complete the task:\n1. **Analyze the Input:** Carefully review the `{{original_prompt}}`, the `{{unexpected_output}}`, and the `{{ideal_output}}`.\n2. **Identify the Gap:** Determine why the `{{original_prompt}}` failed. Was it too vague, ambiguous, or lacking in specific constraints (e.g., format, tone, length)? Compare the `{{unexpected_output}}` with the `{{ideal_output}}` to pinpoint the exact differences.\n3. **Formulate a Strategy:** Based on your analysis, decide what changes are needed. This might include adding context, defining the desired format, specifying a persona for the AI, providing examples, or setting clear constraints.\n4. **Rewrite the Prompt:** Edit the `{{original_prompt}}` to create a new, high-quality prompt. This revised prompt should be clear, detailed, and structured to guide an AI toward producing outputs that match the style and quality of the `{{ideal_output}}`.\n5. **Final Output:** Your output must be ONLY the text of the new, revised prompt. Do not include any extra explanations, introductory phrases like "Here is the revised prompt:", or any xml tags.\n</instruction>\n\n<example>\n<input>\n<original_prompt>\nWrite a title for a blog post about productivity.\n</original_prompt>\n<unexpected_output>\nProductivity Tips\n</unexpected_output>\n<ideal_output>\n10x Your Output: 5 Unconventional Productivity Hacks You Haven\'t Tried\n</ideal_output>\n</input>\n<output>\nGenerate 5 catchy and compelling blog post titles about productivity. The titles should be action-oriented and create a sense of curiosity. They should target an audience looking for unique, non-obvious tips. Include numbers where appropriate to suggest a list format.\n</output>\n</example>\n\n<input>\n<original_prompt>\n{{original_prompt}}\n</original_prompt>\n<unexpected_output>\n{{unexpected_output}}\n</unexpected_output>\n<ideal_output>\n{{ideal_output}}\n</ideal_output>\n</input>\n```')] Model: gemini-2.5-pro Usage: prompt_tokens=303 prompt_unit_price=Decimal('1.25') prompt_price_unit=Decimal('0.000001') prompt_price=Decimal('0.0003788') completion_tokens=2310 completion_unit_price=Decimal('10') completion_price_unit=Decimal('0.000001') completion_price=Decimal('0.0231') total_tokens=2613 total_price=Decimal('0.0234788') currency='USD' latency=19.303683698002715 time_to_first_token=None time_to_generate=None System Fingerprint: 2026-01-16 07:27:36.322 ERROR [Thread-2235 (process_request_thread)] [llm_generator.py:281] 7e1cd831bcbf5f8dacecb43e0cceb60e - Failed to generate rule config, model: gemini-2.5-pro Traceback (most recent call last): File "/app/api/core/llm_generator/llm_generator.py", line 243, in generate_rule_config raise NotImplementedError("prompt content is not a string") NotImplementedError: prompt content is not a string 2026-01-16 07:27:36.337 ERROR [Thread-2235 (process_request_thread)] [app.py:875] 7e1cd831bcbf5f8dacecb43e0cceb60e - Exception on /console/api/rule-generate [POST] Traceback (most recent call last): File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/app/api/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/api.py", line 408, in wrapper return self.make_response(data, code, headers=headers) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/api.py", line 432, in make_response resp = self.representations[mediatype](data, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/api/.venv/lib/python3.12/site-packages/flask_restx/representations.py", line 22, in output_json dumped = dumps(data, **settings) + "\n" ^^^^^^^^^^^^^^^^^^^^^^^ TypeError: TextPromptMessageContent(type=<PromptMessageContentType.TEXT: 'text'>, data='```xml\n<instruction>\nYou are an expert prompt engineer. Your task is to analyze an original prompt, its unsatisfactory output, and an ideal output, and then rewrite the original prompt to make it better. The goal is to create a new prompt that will consistently generate outputs similar in quality and structure to the ideal one.\n\nFollow these steps to complete the task:\n1. **Analyze the Input:** Carefully review the `{{original_prompt}}`, the `{{unexpected_output}}`, and the `{{ideal_output}}`.\n2. **Identify the Gap:** Determine why the `{{original_prompt}}` failed. Was it too vague, ambiguous, or lacking in specific constraints (e.g., format, tone, length)? Compare the `{{unexpected_output}}` with the `{{ideal_output}}` to pinpoint the exact differences.\n3. **Formulate a Strategy:** Based on your analysis, decide what changes are needed. This might include adding context, defining the desired format, specifying a persona for the AI, providing examples, or setting clear constraints.\n4. **Rewrite the Prompt:** Edit the `{{original_prompt}}` to create a new, high-quality prompt. This revised prompt should be clear, detailed, and structured to guide an AI toward producing outputs that match the style and quality of the `{{ideal_output}}`.\n5. **Final Output:** Your output must be ONLY the text of the new, revised prompt. Do not include any extra explanations, introductory phrases like "Here is the revised prompt:", or any xml tags.\n</instruction>\n\n<example>\n<input>\n<original_prompt>\nWrite a title for a blog post about productivity.\n</original_prompt>\n<unexpected_output>\nProductivity Tips\n</unexpected_output>\n<ideal_output>\n10x Your Output: 5 Unconventional Productivity Hacks You Haven\'t Tried\n</ideal_output>\n</input>\n<output>\nGenerate 5 catchy and compelling blog post titles about productivity. The titles should be action-oriented and create a sense of curiosity. They should target an audience looking for unique, non-obvious tips. Include numbers where appropriate to suggest a list format.\n</output>\n</example>\n\n<input>\n<original_prompt>\n{{original_prompt}}\n</original_prompt>\n<unexpected_output>\n{{unexpected_output}}\n</unexpected_output>\n<ideal_output>\n{{ideal_output}}\n</ideal_output>\n</input>\n```') is not JSON serializable ``` ## Checklist - [ ] This change requires a documentation update, included: [Dify Document](https://github.com/langgenius/dify-docs) - [x] I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!) - [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. - [x] I've updated the documentation accordingly. - [x] I ran `make lint` and `make type-check` (backend) and `cd web && npx lint-staged` (frontend) to appease the lint gods
yindo added the pull-request label 2026-02-21 20:52:39 -05:00
yindo closed this issue 2026-02-21 20:52:39 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#33100