fix style of LF to CRLF

pull/18977/head
lizb 1 year ago
parent 664ef7044f
commit f09469df50

@ -1,393 +1,393 @@
import json import json
import logging import logging
import re import re
from typing import Optional, cast from typing import Optional, cast
import json_repair import json_repair
from core.llm_generator.output_parser.rule_config_generator import RuleConfigGeneratorOutputParser from core.llm_generator.output_parser.rule_config_generator import RuleConfigGeneratorOutputParser
from core.llm_generator.output_parser.suggested_questions_after_answer import SuggestedQuestionsAfterAnswerOutputParser from core.llm_generator.output_parser.suggested_questions_after_answer import SuggestedQuestionsAfterAnswerOutputParser
from core.llm_generator.prompts import ( from core.llm_generator.prompts import (
CONVERSATION_TITLE_PROMPT, CONVERSATION_TITLE_PROMPT,
GENERATOR_QA_PROMPT, GENERATOR_QA_PROMPT,
JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE, JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE,
PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE, PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE,
SYSTEM_STRUCTURED_OUTPUT_GENERATE, SYSTEM_STRUCTURED_OUTPUT_GENERATE,
WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE, WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE,
) )
from core.model_manager import ModelManager from core.model_manager import ModelManager
from core.model_runtime.entities.llm_entities import LLMResult from core.model_runtime.entities.llm_entities import LLMResult
from core.model_runtime.entities.message_entities import SystemPromptMessage, UserPromptMessage from core.model_runtime.entities.message_entities import SystemPromptMessage, UserPromptMessage
from core.model_runtime.entities.model_entities import ModelType from core.model_runtime.entities.model_entities import ModelType
from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError
from core.ops.entities.trace_entity import TraceTaskName from core.ops.entities.trace_entity import TraceTaskName
from core.ops.ops_trace_manager import TraceQueueManager, TraceTask from core.ops.ops_trace_manager import TraceQueueManager, TraceTask
from core.ops.utils import measure_time from core.ops.utils import measure_time
from core.prompt.utils.prompt_template_parser import PromptTemplateParser from core.prompt.utils.prompt_template_parser import PromptTemplateParser
from core.workflow.nodes.llm.exc import LLMNodeError from core.workflow.nodes.llm.exc import LLMNodeError
class LLMGenerator: class LLMGenerator:
@classmethod @classmethod
def generate_conversation_name( def generate_conversation_name(
cls, tenant_id: str, query, conversation_id: Optional[str] = None, app_id: Optional[str] = None cls, tenant_id: str, query, conversation_id: Optional[str] = None, app_id: Optional[str] = None
): ):
prompt = CONVERSATION_TITLE_PROMPT prompt = CONVERSATION_TITLE_PROMPT
if len(query) > 2000: if len(query) > 2000:
query = query[:300] + "...[TRUNCATED]..." + query[-300:] query = query[:300] + "...[TRUNCATED]..." + query[-300:]
query = query.replace("\n", " ") query = query.replace("\n", " ")
prompt += query + "\n" prompt += query + "\n"
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_default_model_instance( model_instance = model_manager.get_default_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
) )
prompts = [UserPromptMessage(content=prompt)] prompts = [UserPromptMessage(content=prompt)]
with measure_time() as timer: with measure_time() as timer:
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompts), model_parameters={"max_tokens": 100, "temperature": 1}, stream=False prompt_messages=list(prompts), model_parameters={"max_tokens": 100, "temperature": 1}, stream=False
), ),
) )
answer = cast(str, response.message.content) answer = cast(str, response.message.content)
cleaned_answer = re.sub(r"^.*(\{.*\}).*$", r"\1", answer, flags=re.DOTALL) cleaned_answer = re.sub(r"^.*(\{.*\}).*$", r"\1", answer, flags=re.DOTALL)
if cleaned_answer is None: if cleaned_answer is None:
return "" return ""
result_dict = json.loads(cleaned_answer) result_dict = json.loads(cleaned_answer)
answer = result_dict["Your Output"] answer = result_dict["Your Output"]
name = answer.strip() name = answer.strip()
if len(name) > 75: if len(name) > 75:
name = name[:75] + "..." name = name[:75] + "..."
# get tracing instance # get tracing instance
trace_manager = TraceQueueManager(app_id=app_id) trace_manager = TraceQueueManager(app_id=app_id)
trace_manager.add_trace_task( trace_manager.add_trace_task(
TraceTask( TraceTask(
TraceTaskName.GENERATE_NAME_TRACE, TraceTaskName.GENERATE_NAME_TRACE,
conversation_id=conversation_id, conversation_id=conversation_id,
generate_conversation_name=name, generate_conversation_name=name,
inputs=prompt, inputs=prompt,
timer=timer, timer=timer,
tenant_id=tenant_id, tenant_id=tenant_id,
) )
) )
return name return name
@classmethod @classmethod
def generate_suggested_questions_after_answer(cls, tenant_id: str, histories: str): def generate_suggested_questions_after_answer(cls, tenant_id: str, histories: str):
output_parser = SuggestedQuestionsAfterAnswerOutputParser() output_parser = SuggestedQuestionsAfterAnswerOutputParser()
format_instructions = output_parser.get_format_instructions() format_instructions = output_parser.get_format_instructions()
prompt_template = PromptTemplateParser(template="{{histories}}\n{{format_instructions}}\nquestions:\n") prompt_template = PromptTemplateParser(template="{{histories}}\n{{format_instructions}}\nquestions:\n")
prompt = prompt_template.format({"histories": histories, "format_instructions": format_instructions}) prompt = prompt_template.format({"histories": histories, "format_instructions": format_instructions})
try: try:
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_default_model_instance( model_instance = model_manager.get_default_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
) )
except InvokeAuthorizationError: except InvokeAuthorizationError:
return [] return []
prompt_messages = [UserPromptMessage(content=prompt)] prompt_messages = [UserPromptMessage(content=prompt)]
try: try:
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompt_messages), prompt_messages=list(prompt_messages),
model_parameters={"max_tokens": 256, "temperature": 0}, model_parameters={"max_tokens": 256, "temperature": 0},
stream=False, stream=False,
), ),
) )
questions = output_parser.parse(cast(str, response.message.content)) questions = output_parser.parse(cast(str, response.message.content))
except InvokeError: except InvokeError:
questions = [] questions = []
except Exception: except Exception:
logging.exception("Failed to generate suggested questions after answer") logging.exception("Failed to generate suggested questions after answer")
questions = [] questions = []
return questions return questions
@classmethod @classmethod
def generate_rule_config( def generate_rule_config(
cls, tenant_id: str, instruction: str, model_config: dict, no_variable: bool, rule_config_max_tokens: int = 512 cls, tenant_id: str, instruction: str, model_config: dict, no_variable: bool, rule_config_max_tokens: int = 512
) -> dict: ) -> dict:
output_parser = RuleConfigGeneratorOutputParser() output_parser = RuleConfigGeneratorOutputParser()
error = "" error = ""
error_step = "" error_step = ""
rule_config = {"prompt": "", "variables": [], "opening_statement": "", "error": ""} rule_config = {"prompt": "", "variables": [], "opening_statement": "", "error": ""}
model_parameters = {"max_tokens": rule_config_max_tokens, "temperature": 0.01} model_parameters = {"max_tokens": rule_config_max_tokens, "temperature": 0.01}
if no_variable: if no_variable:
prompt_template = PromptTemplateParser(WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE) prompt_template = PromptTemplateParser(WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE)
prompt_generate = prompt_template.format( prompt_generate = prompt_template.format(
inputs={ inputs={
"TASK_DESCRIPTION": instruction, "TASK_DESCRIPTION": instruction,
}, },
remove_template_variables=False, remove_template_variables=False,
) )
prompt_messages = [UserPromptMessage(content=prompt_generate)] prompt_messages = [UserPromptMessage(content=prompt_generate)]
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_default_model_instance( model_instance = model_manager.get_default_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
) )
try: try:
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
), ),
) )
rule_config["prompt"] = cast(str, response.message.content) rule_config["prompt"] = cast(str, response.message.content)
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
error_step = "generate rule config" error_step = "generate rule config"
except Exception as e: except Exception as e:
logging.exception(f"Failed to generate rule config, model: {model_config.get('name')}") logging.exception(f"Failed to generate rule config, model: {model_config.get('name')}")
rule_config["error"] = str(e) rule_config["error"] = str(e)
rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else "" rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else ""
return rule_config return rule_config
# get rule config prompt, parameter and statement # get rule config prompt, parameter and statement
prompt_generate, parameter_generate, statement_generate = output_parser.get_format_instructions() prompt_generate, parameter_generate, statement_generate = output_parser.get_format_instructions()
prompt_template = PromptTemplateParser(prompt_generate) prompt_template = PromptTemplateParser(prompt_generate)
parameter_template = PromptTemplateParser(parameter_generate) parameter_template = PromptTemplateParser(parameter_generate)
statement_template = PromptTemplateParser(statement_generate) statement_template = PromptTemplateParser(statement_generate)
# format the prompt_generate_prompt # format the prompt_generate_prompt
prompt_generate_prompt = prompt_template.format( prompt_generate_prompt = prompt_template.format(
inputs={ inputs={
"TASK_DESCRIPTION": instruction, "TASK_DESCRIPTION": instruction,
}, },
remove_template_variables=False, remove_template_variables=False,
) )
prompt_messages = [UserPromptMessage(content=prompt_generate_prompt)] prompt_messages = [UserPromptMessage(content=prompt_generate_prompt)]
# get model instance # get model instance
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_model_instance( model_instance = model_manager.get_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
provider=model_config.get("provider", ""), provider=model_config.get("provider", ""),
model=model_config.get("name", ""), model=model_config.get("name", ""),
) )
try: try:
try: try:
# the first step to generate the task prompt # the first step to generate the task prompt
prompt_content = cast( prompt_content = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
), ),
) )
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
error_step = "generate prefix prompt" error_step = "generate prefix prompt"
rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else "" rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else ""
return rule_config return rule_config
rule_config["prompt"] = cast(str, prompt_content.message.content) rule_config["prompt"] = cast(str, prompt_content.message.content)
if not isinstance(prompt_content.message.content, str): if not isinstance(prompt_content.message.content, str):
raise NotImplementedError("prompt content is not a string") raise NotImplementedError("prompt content is not a string")
parameter_generate_prompt = parameter_template.format( parameter_generate_prompt = parameter_template.format(
inputs={ inputs={
"INPUT_TEXT": prompt_content.message.content, "INPUT_TEXT": prompt_content.message.content,
}, },
remove_template_variables=False, remove_template_variables=False,
) )
parameter_messages = [UserPromptMessage(content=parameter_generate_prompt)] parameter_messages = [UserPromptMessage(content=parameter_generate_prompt)]
# the second step to generate the task_parameter and task_statement # the second step to generate the task_parameter and task_statement
statement_generate_prompt = statement_template.format( statement_generate_prompt = statement_template.format(
inputs={ inputs={
"TASK_DESCRIPTION": instruction, "TASK_DESCRIPTION": instruction,
"INPUT_TEXT": prompt_content.message.content, "INPUT_TEXT": prompt_content.message.content,
}, },
remove_template_variables=False, remove_template_variables=False,
) )
statement_messages = [UserPromptMessage(content=statement_generate_prompt)] statement_messages = [UserPromptMessage(content=statement_generate_prompt)]
try: try:
parameter_content = cast( parameter_content = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(parameter_messages), model_parameters=model_parameters, stream=False prompt_messages=list(parameter_messages), model_parameters=model_parameters, stream=False
), ),
) )
rule_config["variables"] = re.findall(r'"\s*([^"]+)\s*"', cast(str, parameter_content.message.content)) rule_config["variables"] = re.findall(r'"\s*([^"]+)\s*"', cast(str, parameter_content.message.content))
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
error_step = "generate variables" error_step = "generate variables"
try: try:
statement_content = cast( statement_content = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(statement_messages), model_parameters=model_parameters, stream=False prompt_messages=list(statement_messages), model_parameters=model_parameters, stream=False
), ),
) )
rule_config["opening_statement"] = cast(str, statement_content.message.content) rule_config["opening_statement"] = cast(str, statement_content.message.content)
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
error_step = "generate conversation opener" error_step = "generate conversation opener"
except Exception as e: except Exception as e:
logging.exception(f"Failed to generate rule config, model: {model_config.get('name')}") logging.exception(f"Failed to generate rule config, model: {model_config.get('name')}")
rule_config["error"] = str(e) rule_config["error"] = str(e)
rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else "" rule_config["error"] = f"Failed to {error_step}. Error: {error}" if error else ""
return rule_config return rule_config
@classmethod @classmethod
def generate_code( def generate_code(
cls, cls,
tenant_id: str, tenant_id: str,
instruction: str, instruction: str,
model_config: dict, model_config: dict,
code_language: str = "javascript", code_language: str = "javascript",
max_tokens: int = 1000, max_tokens: int = 1000,
) -> dict: ) -> dict:
if code_language == "python": if code_language == "python":
prompt_template = PromptTemplateParser(PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE) prompt_template = PromptTemplateParser(PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE)
else: else:
prompt_template = PromptTemplateParser(JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE) prompt_template = PromptTemplateParser(JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE)
prompt = prompt_template.format( prompt = prompt_template.format(
inputs={ inputs={
"INSTRUCTION": instruction, "INSTRUCTION": instruction,
"CODE_LANGUAGE": code_language, "CODE_LANGUAGE": code_language,
}, },
remove_template_variables=False, remove_template_variables=False,
) )
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_model_instance( model_instance = model_manager.get_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
provider=model_config.get("provider", ""), provider=model_config.get("provider", ""),
model=model_config.get("name", ""), model=model_config.get("name", ""),
) )
prompt_messages = [UserPromptMessage(content=prompt)] prompt_messages = [UserPromptMessage(content=prompt)]
model_parameters = {"max_tokens": max_tokens, "temperature": 0.01} model_parameters = {"max_tokens": max_tokens, "temperature": 0.01}
try: try:
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
), ),
) )
generated_code = cast(str, response.message.content) generated_code = cast(str, response.message.content)
return {"code": generated_code, "language": code_language, "error": ""} return {"code": generated_code, "language": code_language, "error": ""}
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
return {"code": "", "language": code_language, "error": f"Failed to generate code. Error: {error}"} return {"code": "", "language": code_language, "error": f"Failed to generate code. Error: {error}"}
except Exception as e: except Exception as e:
logging.exception( logging.exception(
f"Failed to invoke LLM model, model: {model_config.get('name')}, language: {code_language}" f"Failed to invoke LLM model, model: {model_config.get('name')}, language: {code_language}"
) )
return {"code": "", "language": code_language, "error": f"An unexpected error occurred: {str(e)}"} return {"code": "", "language": code_language, "error": f"An unexpected error occurred: {str(e)}"}
@classmethod @classmethod
def generate_qa_document(cls, tenant_id: str, query, document_language: str): def generate_qa_document(cls, tenant_id: str, query, document_language: str):
prompt = GENERATOR_QA_PROMPT.format(language=document_language) prompt = GENERATOR_QA_PROMPT.format(language=document_language)
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_default_model_instance( model_instance = model_manager.get_default_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
) )
prompt_messages = [SystemPromptMessage(content=prompt), UserPromptMessage(content=query)] prompt_messages = [SystemPromptMessage(content=prompt), UserPromptMessage(content=query)]
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=prompt_messages, prompt_messages=prompt_messages,
model_parameters={"temperature": 0.01, "max_tokens": 2000}, model_parameters={"temperature": 0.01, "max_tokens": 2000},
stream=False, stream=False,
), ),
) )
answer = cast(str, response.message.content) answer = cast(str, response.message.content)
return answer.strip() return answer.strip()
@classmethod @classmethod
def generate_structured_output(cls, tenant_id: str, instruction: str, model_config: dict): def generate_structured_output(cls, tenant_id: str, instruction: str, model_config: dict):
model_manager = ModelManager() model_manager = ModelManager()
model_instance = model_manager.get_model_instance( model_instance = model_manager.get_model_instance(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=ModelType.LLM, model_type=ModelType.LLM,
provider=model_config.get("provider", ""), provider=model_config.get("provider", ""),
model=model_config.get("name", ""), model=model_config.get("name", ""),
) )
prompt_messages = [ prompt_messages = [
SystemPromptMessage(content=SYSTEM_STRUCTURED_OUTPUT_GENERATE), SystemPromptMessage(content=SYSTEM_STRUCTURED_OUTPUT_GENERATE),
UserPromptMessage(content=instruction), UserPromptMessage(content=instruction),
] ]
model_parameters = model_config.get("model_parameters", {}) model_parameters = model_config.get("model_parameters", {})
try: try:
response = cast( response = cast(
LLMResult, LLMResult,
model_instance.invoke_llm( model_instance.invoke_llm(
prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False prompt_messages=list(prompt_messages), model_parameters=model_parameters, stream=False
), ),
) )
raw_content = response.message.content raw_content = response.message.content
if not isinstance(raw_content, str): if not isinstance(raw_content, str):
raise LLMNodeError(f"LLM response content must be a string, got: {type(raw_content)}") raise LLMNodeError(f"LLM response content must be a string, got: {type(raw_content)}")
try: try:
parsed_content = json.loads(raw_content) parsed_content = json.loads(raw_content)
except json.JSONDecodeError: except json.JSONDecodeError:
parsed_content = json_repair.loads(raw_content) parsed_content = json_repair.loads(raw_content)
if not isinstance(parsed_content, dict | list): if not isinstance(parsed_content, dict | list):
raise LLMNodeError(f"Failed to parse structured output from llm: {raw_content}") raise LLMNodeError(f"Failed to parse structured output from llm: {raw_content}")
generated_json_schema = json.dumps(parsed_content, indent=2, ensure_ascii=False) generated_json_schema = json.dumps(parsed_content, indent=2, ensure_ascii=False)
return {"output": generated_json_schema, "error": ""} return {"output": generated_json_schema, "error": ""}
except InvokeError as e: except InvokeError as e:
error = str(e) error = str(e)
return {"output": "", "error": f"Failed to generate JSON Schema. Error: {error}"} return {"output": "", "error": f"Failed to generate JSON Schema. Error: {error}"}
except Exception as e: except Exception as e:
logging.exception(f"Failed to invoke LLM model, model: {model_config.get('name')}") logging.exception(f"Failed to invoke LLM model, model: {model_config.get('name')}")
return {"output": "", "error": f"An unexpected error occurred: {str(e)}"} return {"output": "", "error": f"An unexpected error occurred: {str(e)}"}

Loading…
Cancel
Save