Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

workflow_run_service.py 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import threading
  2. from collections.abc import Sequence
  3. from typing import Optional
  4. import contexts
  5. from core.repositories import SQLAlchemyWorkflowNodeExecutionRepository
  6. from core.workflow.repositories.workflow_node_execution_repository import OrderConfig
  7. from extensions.ext_database import db
  8. from libs.infinite_scroll_pagination import InfiniteScrollPagination
  9. from models import (
  10. Account,
  11. App,
  12. EndUser,
  13. WorkflowNodeExecution,
  14. WorkflowRun,
  15. WorkflowRunTriggeredFrom,
  16. )
  17. from models.workflow import WorkflowNodeExecutionTriggeredFrom
  18. class WorkflowRunService:
  19. def get_paginate_advanced_chat_workflow_runs(self, app_model: App, args: dict) -> InfiniteScrollPagination:
  20. """
  21. Get advanced chat app workflow run list
  22. Only return triggered_from == advanced_chat
  23. :param app_model: app model
  24. :param args: request args
  25. """
  26. class WorkflowWithMessage:
  27. message_id: str
  28. conversation_id: str
  29. def __init__(self, workflow_run: WorkflowRun):
  30. self._workflow_run = workflow_run
  31. def __getattr__(self, item):
  32. return getattr(self._workflow_run, item)
  33. pagination = self.get_paginate_workflow_runs(app_model, args)
  34. with_message_workflow_runs = []
  35. for workflow_run in pagination.data:
  36. message = workflow_run.message
  37. with_message_workflow_run = WorkflowWithMessage(workflow_run=workflow_run)
  38. if message:
  39. with_message_workflow_run.message_id = message.id
  40. with_message_workflow_run.conversation_id = message.conversation_id
  41. with_message_workflow_runs.append(with_message_workflow_run)
  42. pagination.data = with_message_workflow_runs
  43. return pagination
  44. def get_paginate_workflow_runs(self, app_model: App, args: dict) -> InfiniteScrollPagination:
  45. """
  46. Get debug workflow run list
  47. Only return triggered_from == debugging
  48. :param app_model: app model
  49. :param args: request args
  50. """
  51. limit = int(args.get("limit", 20))
  52. base_query = db.session.query(WorkflowRun).filter(
  53. WorkflowRun.tenant_id == app_model.tenant_id,
  54. WorkflowRun.app_id == app_model.id,
  55. WorkflowRun.triggered_from == WorkflowRunTriggeredFrom.DEBUGGING.value,
  56. )
  57. if args.get("last_id"):
  58. last_workflow_run = base_query.filter(
  59. WorkflowRun.id == args.get("last_id"),
  60. ).first()
  61. if not last_workflow_run:
  62. raise ValueError("Last workflow run not exists")
  63. workflow_runs = (
  64. base_query.filter(
  65. WorkflowRun.created_at < last_workflow_run.created_at, WorkflowRun.id != last_workflow_run.id
  66. )
  67. .order_by(WorkflowRun.created_at.desc())
  68. .limit(limit)
  69. .all()
  70. )
  71. else:
  72. workflow_runs = base_query.order_by(WorkflowRun.created_at.desc()).limit(limit).all()
  73. has_more = False
  74. if len(workflow_runs) == limit:
  75. current_page_first_workflow_run = workflow_runs[-1]
  76. rest_count = base_query.filter(
  77. WorkflowRun.created_at < current_page_first_workflow_run.created_at,
  78. WorkflowRun.id != current_page_first_workflow_run.id,
  79. ).count()
  80. if rest_count > 0:
  81. has_more = True
  82. return InfiniteScrollPagination(data=workflow_runs, limit=limit, has_more=has_more)
  83. def get_workflow_run(self, app_model: App, run_id: str) -> Optional[WorkflowRun]:
  84. """
  85. Get workflow run detail
  86. :param app_model: app model
  87. :param run_id: workflow run id
  88. """
  89. workflow_run = (
  90. db.session.query(WorkflowRun)
  91. .filter(
  92. WorkflowRun.tenant_id == app_model.tenant_id,
  93. WorkflowRun.app_id == app_model.id,
  94. WorkflowRun.id == run_id,
  95. )
  96. .first()
  97. )
  98. return workflow_run
  99. def get_workflow_run_node_executions(
  100. self,
  101. app_model: App,
  102. run_id: str,
  103. user: Account | EndUser,
  104. ) -> Sequence[WorkflowNodeExecution]:
  105. """
  106. Get workflow run node execution list
  107. """
  108. workflow_run = self.get_workflow_run(app_model, run_id)
  109. contexts.plugin_tool_providers.set({})
  110. contexts.plugin_tool_providers_lock.set(threading.Lock())
  111. if not workflow_run:
  112. return []
  113. repository = SQLAlchemyWorkflowNodeExecutionRepository(
  114. session_factory=db.engine,
  115. user=user,
  116. app_id=app_model.id,
  117. triggered_from=WorkflowNodeExecutionTriggeredFrom.WORKFLOW_RUN,
  118. )
  119. # Use the repository to get the database models directly
  120. order_config = OrderConfig(order_by=["index"], order_direction="desc")
  121. workflow_node_executions = repository.get_db_models_by_workflow_run(
  122. workflow_run_id=run_id, order_config=order_config
  123. )
  124. return workflow_node_executions