app_generate_service.py 6.5 KB

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