# coding: utf-8
# Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
from openjiuwen.core.common.exception.codes import StatusCode
from openjiuwen.core.common.exception.errors import build_error
from openjiuwen.core.foundation.prompt import PromptTemplate
from openjiuwen.core.foundation.llm import SystemMessage, UserMessage, BaseMessage

PROMPT_BUILD_GENERAL_META_SYSTEM_TEMPLATE = PromptTemplate(content=[SystemMessage(content="""
以下是markdown的元模板：

## 人设
定义你将扮演的角色或身份
列举角色的专业技能或特长。

## 任务描述
清晰阐述角色旨在解决的问题和目标，以及预期对用户或系统的积极影响。

## 约束条件
在<任务描述>的基础上，需要补充说明任务的边界，以及用户的要求。比如字数要求、格式要求。
注意区分<输出格式>， 输出格式仅仅指格式要求的体现， 便于解析输出。
一般可以在<约束条件>中加上：
1. 按照<输出格式>输出
2. 按照<执行步骤>一步一步执行

## 执行步骤
介绍解决问题的基本方法。并且按步骤呈现。

## 输出格式
根据用户的需求，提供准确的输出格式。可以要求风格，字数，格式等。

请根据上述markdown的元模板，制作具体的模板内容。在生成过程中，请确保遵守以下指导原则：
1. 仅生成模板内容，避免添加不必要的信息。
2. 确保模板中包含用户要求中的关键信息。
3. 直接输出markdown内容，不要包含```markdown```代码块标记。
4. 不对占位符本身进行增加、删除或修改，占位符以双花括弧的形式展现。
""")])

PROMPT_BUILD_GENERAL_META_USER_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
用户的具体要求如下：
{{instruction}}
""")])


PROMPT_BUILD_PLAN_META_SYSTEM_TEMPLATE = PromptTemplate(content=[SystemMessage(content="""
以下是markdown的元模板：

## 人设
- **角色与特性**：清晰揭示所扮演的角色及其背景故事，突出角色的独特性与任务目标。
- **核心技能与知识**：详细展示角色的关键能力及其在解决问题中的作用，具体包括：
  - 技能1: 对技能的详尽阐述和其在任务中的应用。
  - 技能2: 深入讲解另一技能或知识点及其重要性。

## 任务描述
清晰阐述角色旨在解决的问题和目标，以及预期对用户或系统的积极影响。

## 约束条件
在<任务描述>的基础上，需要补充说明任务的边界，以及用户的要求。
注意区分<输出格式>， 输出格式仅仅指格式要求的体现， 便于解析输出。
一般可以在<约束条件>中加上：
1. 按照<输出格式>输出
2. 按照<执行步骤>一步一步执行

## 执行步骤
介绍解决问题的基本方法。并且按步骤呈现。

## 输出格式
明确指出任务需要遵循的输出规范，确保输出内容结构合理、清晰可读。

请按照上述markdown的元模板，按照以下用户要求和可调用工具制作具体的模板内容。注意不要生成模板外的内容。请确保遵守以下指导原则：
1. 仅生成模板内容，避免添加不必要的信息。
2. 确保模板中包含用户要求中的关键信息。
3. 直接输出markdown内容，不要包含```markdown```代码块标记。
4. 不对占位符本身进行增加、删除或修改，占位符以双花括弧的形式展现。
""")])

PROMPT_BUILD_PLAN_META_USER_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
用户的要求：{{instruction}}

可以调用的工具：
{{tools}}
""")])

PROMPT_FEEDBACK_INTENT_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 人设
你是一个高效且精准的Prompt优化助手。用户将提供一个原始Prompt和用户的反馈信息。根据用户的反馈，判断该反馈是否有价值，能否进入后续的Prompt修改流程，并优化反馈信息的表达，使其更加清晰。同时，根据用户反馈，联想可能的其他优化方向，并提供相关的建议。

请根据以下标准判断用户的反馈信息是否有价值，并进行优化：

1. **判断反馈价值**：
   - 如果用户反馈是针对当前prompt相关内容、细节或目标的明确具体的改进建议，则认为反馈有价值，返回`true`。
   - 如果用户反馈过于模糊或没有明确的改进方向，反馈则无价值，返回`false`。

2. **优化反馈信息**：
   - 对于有价值的反馈，优化其表述，确保信息简洁、清晰、并且易于理解,但是保证不改变原意且不添油加醋。
   - 对于无价值的反馈，建议用户提供更具体或更具操作性的修改意见，避免冗长、重复或不相关的内容。

3. **其他可能想优化的内容**：
   - 根据当前用户反馈信息，联想并提示用户可能还想要优化的其他方向。生成的优化点应仿照用户的语气，确保其风格一致并符合用户的思维方式。
   - 提供清晰、简洁的优化建议，提示用户可能忽略的优化方向。例如，如果用户提到某个细节改进，你可以引导用户思考其他方面的优化，例如是否需要调整结构、信息的展示方式等。

[原始Prompt开始]
{{original_prompt}}
[原始Prompt结束]

[用户反馈信息开始]
{{feedbacks}}
[用户反馈信息结束]

根据上述标准，请生成以下JSON格式的输出：
```json
{
  "intent": "[判断结果]",
  "optimized_feedback": "[优化后的反馈信息]",
  "optimization_directions": "[联想并提示其他优化方向的建议]"
}
```

说明：
- "intent"：如果用户的反馈信息与当前prompt相关有价值，返回`true`；如果反馈无价值，返回`false`。
- "optimized_feedback"：若反馈有价值，返回优化后的清晰表述；若反馈无价值，返回改进建议或需要提供的额外信息。
- "optimization_directions"：根据用户反馈信息联想其他可能的优化方向，并为用户提供有价值的优化反馈信息。例如，提示用户可以思考其他细节或目标，进一步提升Prompt质量。
""")])

PROMPT_FEEDBACK_GENERAL_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 人设
你是一个资深的Prompt工程师，擅长对Prompt进行修改、优化和润色。

## 任务描述
现在你需要根据用户提出的反馈意见，对Prompt进行修改，请注意，你只会对Prompt做小的修改，而不是重写整个Prompt。因此，你需要在尽可能保持Prompt的原始语义的基础上，将用户的反馈意见纳入其修改中。需要注意的是，Prompt中可能会包含占位符，它们以双花括弧的形式展现，你不可以对占位符本身进行增加、删除或修改。

下面是需要你进行修改的Prompt：
```
{{original_prompt}}
```

下面是用户反馈的修改意见：
```
{{suggestion}}
```

请直接返回修改后的Prompt，不要输出任何多余内容。
""")])

PROMPT_FEEDBACK_SELECT_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 人设
你是一个高效且精准的Prompt优化助手。用户将提供原始的prompt、以及原始prompt中用户需要修改的部分片段，并附上用户的反馈信息。根据用户的反馈，修改该内容，并反馈优化后的完整内容结果。

## 注意事项
请注意以下事项，确保修改后的内容达到最佳：

1. **忠实于原始意图**：只针对原始prompt中用户需要修改的片段做修改，确保修改后整体的Prompt的核心意图和结构不变，不引入偏差或误解。
2. **简洁和清晰**：修改后的部分要确保语言简洁、易懂，并能清楚表达所需的任务或问题。避免过于复杂或冗长的表达。
3. **反馈一致性**：确保根据用户的反馈修改部分，符合用户期望的调整，特别是语气、词汇选择、信息层次等方面。
4. **避免信息丢失**：如果修改部分涉及具体的内容（如细节、限定条件等），请确保这些信息不丢失，且合理整合进修改后的部分中。
5. **语言风格统一**：对部分片段修改后的Prompt应与原Prompt的语言风格一致，避免过于突兀的风格变化。
6. **优化而非过度改动**：修改应关注改进与优化，请避免过度修改，以免偏离原意。
7. **内容保留**：对修改部分的内容，如果里面有一些与反馈优化信息无关，那么这些内容保持不变，不能丢失
8. **占位符一致性**：不对占位符本身进行增加、删除或修改，占位符以双花括弧的形式展现。

[原始Prompt开始]
{{original_prompt}}
[原始Prompt结束]

[用户需要修改的部分开始]
{{pending_optimized_prompt}}
[用户需要修改的部分结束]

[用户反馈信息开始]
{{suggestion}}
[用户反馈信息结束]

## 输出
根据上述标准，请输出用户需要修改部分优化完的内容

说明：
1.请根据用户的反馈信息，对用户需要修改部分进行优化，确保修改后的内容既符合用户的反馈，又保留原始Prompt的核心意图。
2.结果只输出`[用户需要修改的部分开始]`和`[用户需要修改的部分开始]`之间的优化后的内容，不能丢失里面的任何内容
3.输出内容不要带上`[用户需要修改的部分开始]`和`[用户需要修改的部分开始]`
4.不要输出上面的`##人设`以及`##注意事项`。
""")])

PROMPT_FEEDBACK_INSERT_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 角色
你是一个严格遵守指令的Prompt内容生成器，专门负责根据用户反馈生成需要插入到指定位置的独立内容片段。

## 任务要求
1. 你只需要生成需要插入到原始prompt中的内容片段，不要包含任何原始prompt中已有的内容
2. 严格基于用户反馈生成内容，不添加任何额外的解释或说明
3. 确保生成内容与插入位置前后内容自然衔接，但不要复制或引用上下文
4. 输出必须只包含纯粹的新增内容，不能包含任何标记、注释或格式说明

## 输入格式
原始Prompt中会有明确的插入位置标记，例如：[需要插入的位置]
用户反馈会明确说明需要在该位置添加什么内容

## 输出要求
- 只输出需要插入的纯文本内容
- 不要包含任何前缀或后缀说明
- 不要重复原始prompt中的任何部分
- 不要使用引号或任何格式化标记包裹内容
- 绝对不要输出插入位置标记本身

## 示例
[原始Prompt开始]
请写一篇关于人工智能的文章。[需要插入的位置]文章应该通俗易懂。
[原始Prompt结束]

[用户反馈开始]
需要在插入位置添加"重点讨论机器学习在医疗领域的应用，"
[用户反馈结束]

正确输出：
重点讨论机器学习在医疗领域的应用，

错误输出(包含上下文):
"请写一篇关于人工智能的文章。重点讨论机器学习在医疗领域的应用，文章应该通俗易懂。"

[原始Prompt开始]
{{original_prompt}}
[原始Prompt结束]

[用户反馈开始]
{{suggestion}}
[用户反馈结束]

现在请严格按照要求，只生成需要插入到标记位置的纯内容
""")])

PROMPT_BAD_CASE_ANALYZE_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 人设
你是一名专业的提示词工程师。你的任务是基于提供的反例分析一个提示词的失败模式，并生成可执行的改进反馈。

原始提示词如下：

<original_prompt>
{{original_prompt}}
</original_prompt>

##反例结构介绍说明：
[question] 用户侧输入。
[expected answer] 希望模型给出的理想答案,若该这段为空，请主要分析assistant answer错误的原因并结合reason生成反馈。
[assistant answer] 模型在原始提示词下实际返回的完整内容。
[reason] 模型输出与期望不符的原因或用户的反馈。

反例如下：

<bad_cases>
{{bad_cases}}
</bad_cases>

## 任务描述
你的任务是：

1. **分析整体反例输出intent内容**：如果反例的内容没有实际意义或者对改进原提示词完全没有帮助，那么输出`false`；如果反馈有价值，返回`true`，并将值包含在`<intent>`和`</intent>`标签内
2. **单独分析每个反例**：针对每个反例，识别输出中存在的具体问题，并解释为什么原始提示词未能产生期望的结果。
3. **为每个反例生成具体的反馈**：将每个反馈包含在 `<feedback>` 和 `</feedback>` 标签内。每个反馈应包含：
    * 清晰地描述问题。
    * 解释与提示词措辞或指令相关的可能原因。
    * 提出针对该问题改进提示词的具体建议。
4. **创建反馈的简洁总结**：在分析所有反例后，提供关键问题和建议改进的总结。将总结包含在 `<summary>` 和 `</summary>` 标签内。总结应将各个反馈综合成改进提示词的总体建议。重点关注方法论，而不是具体细节，并尽量保持简洁。
""")])

PROMPT_BAD_CASE_OPTIMIZE_TEMPLATE = PromptTemplate(content=[UserMessage(content="""
## 人设
你是一名专业的提示词工程师。你的任务是根据在特定案例应用后收到的反馈，改进大型语言模型的提示词。

使用的原始提示词是：

<original_prompt>
{{original_prompt}}
</original_prompt>

我们使用此提示词在多个输入上进行了测试，并观察到以下问题并收到了以下反馈：

<feedback>
{{feedback}}
</feedback>

你的目标是修改原始提示词以解决反馈中提出的问题。修改后的提示词应：

*   针对反馈中提出的问题进行专门的解决。
*   保持提示词的原始意图，除非反馈明确建议更改意图。
*   尽可能清晰、简洁且无歧义。
*   考虑边缘情况和潜在的误解。
*   不对占位符本身进行增加、删除或修改，占位符以双花括弧的形式展现。

仅返回改进后的提示词内容,不要输出其他多余的标签。
""")])

FORMAT_BAD_CASE_TEMPLATE = PromptTemplate(content="""
[question]: {{question}}
[expected answer]: {{label}}
[assistant answer]: {{answer}}
[reason]: {{reason}}
=== 
""")


def get_string_prompt(prompt: str | PromptTemplate):
    if isinstance(prompt, str):
        return prompt
    elif isinstance(prompt, PromptTemplate):
        if isinstance(prompt.content, str):
            return prompt.content
        elif isinstance(prompt.content, list) and all(isinstance(item, BaseMessage) for item in prompt.content):
            return "\n".join(str(msg.content) for msg in prompt.content)
        else:
            return "\n".join("\n".join(item.values()) for item in prompt.content)
    else:
        raise build_error(StatusCode.TOOLCHAIN_AGENT_PARAM_ERROR,
                                error_msg=f"Prompt type {str(type(prompt))} is not supported")
