app.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. from collections.abc import Generator, Mapping
  2. from typing import Optional, Union
  3. from core.app.apps.advanced_chat.app_generator import AdvancedChatAppGenerator
  4. from core.app.apps.agent_chat.app_generator import AgentChatAppGenerator
  5. from core.app.apps.chat.app_generator import ChatAppGenerator
  6. from core.app.apps.completion.app_generator import CompletionAppGenerator
  7. from core.app.apps.workflow.app_generator import WorkflowAppGenerator
  8. from core.app.entities.app_invoke_entities import InvokeFrom
  9. from core.plugin.backwards_invocation.base import BaseBackwardsInvocation
  10. from extensions.ext_database import db
  11. from models.account import Account
  12. from models.model import App, AppMode, EndUser
  13. class PluginAppBackwardsInvocation(BaseBackwardsInvocation):
  14. @classmethod
  15. def invoke_app(
  16. cls, app_id: str,
  17. user_id: str,
  18. tenant_id: str,
  19. conversation_id: Optional[str],
  20. query: Optional[str],
  21. stream: bool,
  22. inputs: Mapping,
  23. files: list[dict],
  24. ) -> Generator[dict | str, None, None] | dict:
  25. """
  26. invoke app
  27. """
  28. app = cls._get_app(app_id, tenant_id)
  29. user = cls._get_user(user_id)
  30. conversation_id = conversation_id or ""
  31. if app.mode in [AppMode.ADVANCED_CHAT.value, AppMode.AGENT_CHAT.value, AppMode.CHAT.value]:
  32. if not query:
  33. raise ValueError("missing query")
  34. return cls.invoke_chat_app(app, user, conversation_id, query, stream, inputs, files)
  35. elif app.mode in [AppMode.WORKFLOW.value]:
  36. return cls.invoke_workflow_app(app, user, stream, inputs, files)
  37. elif app.mode in [AppMode.COMPLETION]:
  38. return cls.invoke_completion_app(app, user, stream, inputs, files)
  39. raise ValueError("unexpected app type")
  40. @classmethod
  41. def invoke_chat_app(
  42. cls,
  43. app: App,
  44. user: Account | EndUser,
  45. conversation_id: str,
  46. query: str,
  47. stream: bool,
  48. inputs: Mapping,
  49. files: list[dict],
  50. ) -> Generator[dict | str, None, None] | dict:
  51. """
  52. invoke chat app
  53. """
  54. if app.mode == AppMode.ADVANCED_CHAT.value:
  55. workflow = app.workflow
  56. if not workflow:
  57. raise ValueError("unexpected app type")
  58. return AdvancedChatAppGenerator().generate(
  59. app_model=app,
  60. workflow=workflow,
  61. user=user,
  62. args={
  63. "inputs": inputs,
  64. "query": query,
  65. "files": files,
  66. "conversation_id": conversation_id,
  67. },
  68. invoke_from=InvokeFrom.SERVICE_API,
  69. stream=stream
  70. )
  71. elif app.mode == AppMode.AGENT_CHAT.value:
  72. return AgentChatAppGenerator().generate(
  73. app_model=app,
  74. user=user,
  75. args={
  76. "inputs": inputs,
  77. "query": query,
  78. "files": files,
  79. "conversation_id": conversation_id,
  80. },
  81. invoke_from=InvokeFrom.SERVICE_API,
  82. stream=stream
  83. )
  84. elif app.mode == AppMode.CHAT.value:
  85. return ChatAppGenerator().generate(
  86. app_model=app,
  87. user=user,
  88. args={
  89. "inputs": inputs,
  90. "query": query,
  91. "files": files,
  92. "conversation_id": conversation_id,
  93. },
  94. invoke_from=InvokeFrom.SERVICE_API,
  95. stream=stream
  96. )
  97. else:
  98. raise ValueError("unexpected app type")
  99. @classmethod
  100. def invoke_workflow_app(
  101. cls,
  102. app: App,
  103. user: EndUser | Account,
  104. stream: bool,
  105. inputs: Mapping,
  106. files: list[dict],
  107. ):
  108. """
  109. invoke workflow app
  110. """
  111. workflow = app.workflow
  112. if not workflow:
  113. raise ValueError("")
  114. return WorkflowAppGenerator().generate(
  115. app_model=app,
  116. workflow=workflow,
  117. user=user,
  118. args={
  119. 'inputs': inputs,
  120. 'files': files
  121. },
  122. invoke_from=InvokeFrom.SERVICE_API,
  123. stream=stream,
  124. call_depth=1,
  125. )
  126. @classmethod
  127. def invoke_completion_app(
  128. cls,
  129. app: App,
  130. user: EndUser | Account,
  131. stream: bool,
  132. inputs: Mapping,
  133. files: list[dict],
  134. ):
  135. """
  136. invoke completion app
  137. """
  138. return CompletionAppGenerator().generate(
  139. app_model=app,
  140. user=user,
  141. args={
  142. 'inputs': inputs,
  143. 'files': files
  144. },
  145. invoke_from=InvokeFrom.SERVICE_API,
  146. stream=stream,
  147. )
  148. @classmethod
  149. def _get_user(cls, user_id: str) -> Union[EndUser, Account]:
  150. """
  151. get the user by user id
  152. """
  153. user = db.session.query(EndUser).filter(EndUser.id == user_id).first()
  154. if not user:
  155. user = db.session.query(Account).filter(Account.id == user_id).first()
  156. if not user:
  157. raise ValueError('user not found')
  158. return user
  159. @classmethod
  160. def _get_app(cls, app_id: str, tenant_id: str) -> App:
  161. """
  162. get app
  163. """
  164. app = db.session.query(App). \
  165. filter(App.id == app_id). \
  166. filter(App.tenant_id == tenant_id). \
  167. first()
  168. if not app:
  169. raise ValueError("app not found")
  170. return app