app_generate_service.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. from collections.abc import Generator
  2. from typing import Any, Union
  3. from openai._exceptions import RateLimitError
  4. from configs import dify_config
  5. from core.app.apps.advanced_chat.app_generator import AdvancedChatAppGenerator
  6. from core.app.apps.agent_chat.app_generator import AgentChatAppGenerator
  7. from core.app.apps.chat.app_generator import ChatAppGenerator
  8. from core.app.apps.completion.app_generator import CompletionAppGenerator
  9. from core.app.apps.workflow.app_generator import WorkflowAppGenerator
  10. from core.app.entities.app_invoke_entities import InvokeFrom
  11. from core.app.features.rate_limiting import RateLimit
  12. from models.model import Account, App, AppMode, EndUser
  13. from services.errors.llm import InvokeRateLimitError
  14. from services.workflow_service import WorkflowService
  15. class AppGenerateService:
  16. @classmethod
  17. def generate(
  18. cls,
  19. app_model: App,
  20. user: Union[Account, EndUser],
  21. args: Any,
  22. invoke_from: InvokeFrom,
  23. streaming: bool = True,
  24. ):
  25. """
  26. App Content Generate
  27. :param app_model: app model
  28. :param user: user
  29. :param args: args
  30. :param invoke_from: invoke from
  31. :param streaming: streaming
  32. :return:
  33. """
  34. max_active_request = AppGenerateService._get_max_active_requests(app_model)
  35. rate_limit = RateLimit(app_model.id, max_active_request)
  36. request_id = RateLimit.gen_request_key()
  37. try:
  38. request_id = rate_limit.enter(request_id)
  39. if app_model.mode == AppMode.COMPLETION.value:
  40. return rate_limit.generate(
  41. CompletionAppGenerator().generate(
  42. app_model=app_model, user=user, args=args, invoke_from=invoke_from, stream=streaming
  43. ),
  44. request_id,
  45. )
  46. elif app_model.mode == AppMode.AGENT_CHAT.value or app_model.is_agent:
  47. return rate_limit.generate(
  48. AgentChatAppGenerator().generate(
  49. app_model=app_model, user=user, args=args, invoke_from=invoke_from, stream=streaming
  50. ),
  51. request_id,
  52. )
  53. elif app_model.mode == AppMode.CHAT.value:
  54. return rate_limit.generate(
  55. ChatAppGenerator().generate(
  56. app_model=app_model, user=user, args=args, invoke_from=invoke_from, stream=streaming
  57. ),
  58. request_id,
  59. )
  60. elif app_model.mode == AppMode.ADVANCED_CHAT.value:
  61. workflow = cls._get_workflow(app_model, invoke_from)
  62. return rate_limit.generate(
  63. AdvancedChatAppGenerator().generate(
  64. app_model=app_model,
  65. workflow=workflow,
  66. user=user,
  67. args=args,
  68. invoke_from=invoke_from,
  69. stream=streaming,
  70. ),
  71. request_id,
  72. )
  73. elif app_model.mode == AppMode.WORKFLOW.value:
  74. workflow = cls._get_workflow(app_model, invoke_from)
  75. return rate_limit.generate(
  76. WorkflowAppGenerator().generate(
  77. app_model=app_model,
  78. workflow=workflow,
  79. user=user,
  80. args=args,
  81. invoke_from=invoke_from,
  82. stream=streaming,
  83. ),
  84. request_id,
  85. )
  86. else:
  87. raise ValueError(f"Invalid app mode {app_model.mode}")
  88. except RateLimitError as e:
  89. raise InvokeRateLimitError(str(e))
  90. finally:
  91. if not streaming:
  92. rate_limit.exit(request_id)
  93. @staticmethod
  94. def _get_max_active_requests(app_model: App) -> int:
  95. max_active_requests = app_model.max_active_requests
  96. if app_model.max_active_requests is None:
  97. max_active_requests = int(dify_config.APP_MAX_ACTIVE_REQUESTS)
  98. return max_active_requests
  99. @classmethod
  100. def generate_single_iteration(
  101. cls, app_model: App, user: Union[Account, EndUser], node_id: str, args: Any, streaming: bool = True
  102. ):
  103. if app_model.mode == AppMode.ADVANCED_CHAT.value:
  104. workflow = cls._get_workflow(app_model, InvokeFrom.DEBUGGER)
  105. return AdvancedChatAppGenerator().single_iteration_generate(
  106. app_model=app_model, workflow=workflow, node_id=node_id, user=user, args=args, stream=streaming
  107. )
  108. elif app_model.mode == AppMode.WORKFLOW.value:
  109. workflow = cls._get_workflow(app_model, InvokeFrom.DEBUGGER)
  110. return WorkflowAppGenerator().single_iteration_generate(
  111. app_model=app_model, workflow=workflow, node_id=node_id, user=user, args=args, stream=streaming
  112. )
  113. else:
  114. raise ValueError(f"Invalid app mode {app_model.mode}")
  115. @classmethod
  116. def generate_more_like_this(
  117. cls,
  118. app_model: App,
  119. user: Union[Account, EndUser],
  120. message_id: str,
  121. invoke_from: InvokeFrom,
  122. streaming: bool = True,
  123. ) -> Union[dict, Generator]:
  124. """
  125. Generate more like this
  126. :param app_model: app model
  127. :param user: user
  128. :param message_id: message id
  129. :param invoke_from: invoke from
  130. :param streaming: streaming
  131. :return:
  132. """
  133. return CompletionAppGenerator().generate_more_like_this(
  134. app_model=app_model, message_id=message_id, user=user, invoke_from=invoke_from, stream=streaming
  135. )
  136. @classmethod
  137. def _get_workflow(cls, app_model: App, invoke_from: InvokeFrom) -> Any:
  138. """
  139. Get workflow
  140. :param app_model: app model
  141. :param invoke_from: invoke from
  142. :return:
  143. """
  144. workflow_service = WorkflowService()
  145. if invoke_from == InvokeFrom.DEBUGGER:
  146. # fetch draft workflow by app_model
  147. workflow = workflow_service.get_draft_workflow(app_model=app_model)
  148. if not workflow:
  149. raise ValueError("Workflow not initialized")
  150. else:
  151. # fetch published workflow by app_model
  152. workflow = workflow_service.get_published_workflow(app_model=app_model)
  153. if not workflow:
  154. raise ValueError("Workflow not published")
  155. return workflow