您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. from collections.abc import Sequence
  2. from flask_login import current_user
  3. from flask_restful import Resource, reqparse
  4. from controllers.console import api
  5. from controllers.console.app.error import (
  6. CompletionRequestError,
  7. ProviderModelCurrentlyNotSupportError,
  8. ProviderNotInitializeError,
  9. ProviderQuotaExceededError,
  10. )
  11. from controllers.console.wraps import account_initialization_required, setup_required
  12. from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
  13. from core.llm_generator.llm_generator import LLMGenerator
  14. from core.model_runtime.errors.invoke import InvokeError
  15. from libs.login import login_required
  16. class RuleGenerateApi(Resource):
  17. @setup_required
  18. @login_required
  19. @account_initialization_required
  20. def post(self):
  21. parser = reqparse.RequestParser()
  22. parser.add_argument("instruction", type=str, required=True, nullable=False, location="json")
  23. parser.add_argument("model_config", type=dict, required=True, nullable=False, location="json")
  24. parser.add_argument("no_variable", type=bool, required=True, default=False, location="json")
  25. args = parser.parse_args()
  26. account = current_user
  27. try:
  28. rules = LLMGenerator.generate_rule_config(
  29. tenant_id=account.current_tenant_id,
  30. instruction=args["instruction"],
  31. model_config=args["model_config"],
  32. no_variable=args["no_variable"],
  33. )
  34. except ProviderTokenNotInitError as ex:
  35. raise ProviderNotInitializeError(ex.description)
  36. except QuotaExceededError:
  37. raise ProviderQuotaExceededError()
  38. except ModelCurrentlyNotSupportError:
  39. raise ProviderModelCurrentlyNotSupportError()
  40. except InvokeError as e:
  41. raise CompletionRequestError(e.description)
  42. return rules
  43. class RuleCodeGenerateApi(Resource):
  44. @setup_required
  45. @login_required
  46. @account_initialization_required
  47. def post(self):
  48. parser = reqparse.RequestParser()
  49. parser.add_argument("instruction", type=str, required=True, nullable=False, location="json")
  50. parser.add_argument("model_config", type=dict, required=True, nullable=False, location="json")
  51. parser.add_argument("no_variable", type=bool, required=True, default=False, location="json")
  52. parser.add_argument("code_language", type=str, required=False, default="javascript", location="json")
  53. args = parser.parse_args()
  54. account = current_user
  55. try:
  56. code_result = LLMGenerator.generate_code(
  57. tenant_id=account.current_tenant_id,
  58. instruction=args["instruction"],
  59. model_config=args["model_config"],
  60. code_language=args["code_language"],
  61. )
  62. except ProviderTokenNotInitError as ex:
  63. raise ProviderNotInitializeError(ex.description)
  64. except QuotaExceededError:
  65. raise ProviderQuotaExceededError()
  66. except ModelCurrentlyNotSupportError:
  67. raise ProviderModelCurrentlyNotSupportError()
  68. except InvokeError as e:
  69. raise CompletionRequestError(e.description)
  70. return code_result
  71. class RuleStructuredOutputGenerateApi(Resource):
  72. @setup_required
  73. @login_required
  74. @account_initialization_required
  75. def post(self):
  76. parser = reqparse.RequestParser()
  77. parser.add_argument("instruction", type=str, required=True, nullable=False, location="json")
  78. parser.add_argument("model_config", type=dict, required=True, nullable=False, location="json")
  79. args = parser.parse_args()
  80. account = current_user
  81. try:
  82. structured_output = LLMGenerator.generate_structured_output(
  83. tenant_id=account.current_tenant_id,
  84. instruction=args["instruction"],
  85. model_config=args["model_config"],
  86. )
  87. except ProviderTokenNotInitError as ex:
  88. raise ProviderNotInitializeError(ex.description)
  89. except QuotaExceededError:
  90. raise ProviderQuotaExceededError()
  91. except ModelCurrentlyNotSupportError:
  92. raise ProviderModelCurrentlyNotSupportError()
  93. except InvokeError as e:
  94. raise CompletionRequestError(e.description)
  95. return structured_output
  96. class InstructionGenerateApi(Resource):
  97. @setup_required
  98. @login_required
  99. @account_initialization_required
  100. def post(self):
  101. parser = reqparse.RequestParser()
  102. parser.add_argument("flow_id", type=str, required=True, default="", location="json")
  103. parser.add_argument("node_id", type=str, required=False, default="", location="json")
  104. parser.add_argument("current", type=str, required=False, default="", location="json")
  105. parser.add_argument("language", type=str, required=False, default="javascript", location="json")
  106. parser.add_argument("instruction", type=str, required=True, nullable=False, location="json")
  107. parser.add_argument("model_config", type=dict, required=True, nullable=False, location="json")
  108. parser.add_argument("ideal_output", type=str, required=False, default="", location="json")
  109. args = parser.parse_args()
  110. try:
  111. if args["current"] == "" and args["node_id"] != "": # Generate from nothing for a workflow node
  112. from models import App, db
  113. from services.workflow_service import WorkflowService
  114. app = db.session.query(App).filter(App.id == args["flow_id"]).first()
  115. if not app:
  116. return {"error": f"app {args['flow_id']} not found"}, 400
  117. workflow = WorkflowService().get_draft_workflow(app_model=app)
  118. if not workflow:
  119. return {"error": f"workflow {args['flow_id']} not found"}, 400
  120. nodes: Sequence = workflow.graph_dict["nodes"]
  121. node = [node for node in nodes if node["id"] == args["node_id"]]
  122. if len(node) == 0:
  123. return {"error": f"node {args['node_id']} not found"}, 400
  124. node_type = node[0]["data"]["type"]
  125. match node_type:
  126. case "llm":
  127. return LLMGenerator.generate_rule_config(
  128. current_user.current_tenant_id,
  129. instruction=args["instruction"],
  130. model_config=args["model_config"],
  131. no_variable=True,
  132. )
  133. case "agent":
  134. return LLMGenerator.generate_rule_config(
  135. current_user.current_tenant_id,
  136. instruction=args["instruction"],
  137. model_config=args["model_config"],
  138. no_variable=True,
  139. )
  140. case "code":
  141. return LLMGenerator.generate_code(
  142. tenant_id=current_user.current_tenant_id,
  143. instruction=args["instruction"],
  144. model_config=args["model_config"],
  145. code_language=args["language"],
  146. )
  147. case _:
  148. return {"error": f"invalid node type: {node_type}"}
  149. if args["node_id"] == "" and args["current"] != "": # For legacy app without a workflow
  150. return LLMGenerator.instruction_modify_legacy(
  151. tenant_id=current_user.current_tenant_id,
  152. flow_id=args["flow_id"],
  153. current=args["current"],
  154. instruction=args["instruction"],
  155. model_config=args["model_config"],
  156. ideal_output=args["ideal_output"],
  157. )
  158. if args["node_id"] != "" and args["current"] != "": # For workflow node
  159. return LLMGenerator.instruction_modify_workflow(
  160. tenant_id=current_user.current_tenant_id,
  161. flow_id=args["flow_id"],
  162. node_id=args["node_id"],
  163. current=args["current"],
  164. instruction=args["instruction"],
  165. model_config=args["model_config"],
  166. ideal_output=args["ideal_output"],
  167. )
  168. return {"error": "incompatible parameters"}, 400
  169. except ProviderTokenNotInitError as ex:
  170. raise ProviderNotInitializeError(ex.description)
  171. except QuotaExceededError:
  172. raise ProviderQuotaExceededError()
  173. except ModelCurrentlyNotSupportError:
  174. raise ProviderModelCurrentlyNotSupportError()
  175. except InvokeError as e:
  176. raise CompletionRequestError(e.description)
  177. class InstructionGenerationTemplateApi(Resource):
  178. @setup_required
  179. @login_required
  180. @account_initialization_required
  181. def post(self) -> dict:
  182. parser = reqparse.RequestParser()
  183. parser.add_argument("type", type=str, required=True, default=False, location="json")
  184. args = parser.parse_args()
  185. match args["type"]:
  186. case "prompt":
  187. from core.llm_generator.prompts import INSTRUCTION_GENERATE_TEMPLATE_PROMPT
  188. return {"data": INSTRUCTION_GENERATE_TEMPLATE_PROMPT}
  189. case "code":
  190. from core.llm_generator.prompts import INSTRUCTION_GENERATE_TEMPLATE_CODE
  191. return {"data": INSTRUCTION_GENERATE_TEMPLATE_CODE}
  192. case _:
  193. raise ValueError(f"Invalid type: {args['type']}")
  194. api.add_resource(RuleGenerateApi, "/rule-generate")
  195. api.add_resource(RuleCodeGenerateApi, "/rule-code-generate")
  196. api.add_resource(RuleStructuredOutputGenerateApi, "/rule-structured-output-generate")
  197. api.add_resource(InstructionGenerateApi, "/instruction-generate")
  198. api.add_resource(InstructionGenerationTemplateApi, "/instruction-generate/template")