You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

workflow_run_service.py 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import threading
  2. from collections.abc import Sequence
  3. from sqlalchemy.orm import sessionmaker
  4. import contexts
  5. from extensions.ext_database import db
  6. from libs.infinite_scroll_pagination import InfiniteScrollPagination
  7. from models import (
  8. Account,
  9. App,
  10. EndUser,
  11. WorkflowNodeExecutionModel,
  12. WorkflowRun,
  13. WorkflowRunTriggeredFrom,
  14. )
  15. from repositories.factory import DifyAPIRepositoryFactory
  16. class WorkflowRunService:
  17. def __init__(self):
  18. """Initialize WorkflowRunService with repository dependencies."""
  19. session_maker = sessionmaker(bind=db.engine, expire_on_commit=False)
  20. self._node_execution_service_repo = DifyAPIRepositoryFactory.create_api_workflow_node_execution_repository(
  21. session_maker
  22. )
  23. self._workflow_run_repo = DifyAPIRepositoryFactory.create_api_workflow_run_repository(session_maker)
  24. def get_paginate_advanced_chat_workflow_runs(self, app_model: App, args: dict) -> InfiniteScrollPagination:
  25. """
  26. Get advanced chat app workflow run list
  27. Only return triggered_from == advanced_chat
  28. :param app_model: app model
  29. :param args: request args
  30. """
  31. class WorkflowWithMessage:
  32. message_id: str
  33. conversation_id: str
  34. def __init__(self, workflow_run: WorkflowRun):
  35. self._workflow_run = workflow_run
  36. def __getattr__(self, item):
  37. return getattr(self._workflow_run, item)
  38. pagination = self.get_paginate_workflow_runs(app_model, args)
  39. with_message_workflow_runs = []
  40. for workflow_run in pagination.data:
  41. message = workflow_run.message
  42. with_message_workflow_run = WorkflowWithMessage(workflow_run=workflow_run)
  43. if message:
  44. with_message_workflow_run.message_id = message.id
  45. with_message_workflow_run.conversation_id = message.conversation_id
  46. with_message_workflow_runs.append(with_message_workflow_run)
  47. pagination.data = with_message_workflow_runs
  48. return pagination
  49. def get_paginate_workflow_runs(self, app_model: App, args: dict) -> InfiniteScrollPagination:
  50. """
  51. Get debug workflow run list
  52. Only return triggered_from == debugging
  53. :param app_model: app model
  54. :param args: request args
  55. """
  56. limit = int(args.get("limit", 20))
  57. last_id = args.get("last_id")
  58. return self._workflow_run_repo.get_paginated_workflow_runs(
  59. tenant_id=app_model.tenant_id,
  60. app_id=app_model.id,
  61. triggered_from=WorkflowRunTriggeredFrom.DEBUGGING.value,
  62. limit=limit,
  63. last_id=last_id,
  64. )
  65. def get_workflow_run(self, app_model: App, run_id: str) -> WorkflowRun | None:
  66. """
  67. Get workflow run detail
  68. :param app_model: app model
  69. :param run_id: workflow run id
  70. """
  71. return self._workflow_run_repo.get_workflow_run_by_id(
  72. tenant_id=app_model.tenant_id,
  73. app_id=app_model.id,
  74. run_id=run_id,
  75. )
  76. def get_workflow_run_node_executions(
  77. self,
  78. app_model: App,
  79. run_id: str,
  80. user: Account | EndUser,
  81. ) -> Sequence[WorkflowNodeExecutionModel]:
  82. """
  83. Get workflow run node execution list
  84. """
  85. workflow_run = self.get_workflow_run(app_model, run_id)
  86. contexts.plugin_tool_providers.set({})
  87. contexts.plugin_tool_providers_lock.set(threading.Lock())
  88. if not workflow_run:
  89. return []
  90. # Get tenant_id from user
  91. tenant_id = user.tenant_id if isinstance(user, EndUser) else user.current_tenant_id
  92. if tenant_id is None:
  93. raise ValueError("User tenant_id cannot be None")
  94. return self._node_execution_service_repo.get_executions_by_workflow_run(
  95. tenant_id=tenant_id,
  96. app_id=app_model.id,
  97. workflow_run_id=run_id,
  98. )