fix(api): prevent HITL pause from aborting workflow resume (#39485)

Co-authored-by: 李政达 <1242427577@qq.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
This commit is contained in:
李政达 2026-07-30 11:21:28 +08:00 committed by GitHub
parent 1593b7cc60
commit 7fd2f4f4e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 1 deletions

View File

@ -9,6 +9,7 @@ from core.app.entities.queue_entities import (
QueueStopEvent,
QueueWorkflowFailedEvent,
QueueWorkflowPartialSuccessEvent,
QueueWorkflowPausedEvent,
QueueWorkflowSucceededEvent,
WorkflowQueueMessage,
)
@ -32,6 +33,11 @@ class WorkflowAppQueueManager(AppQueueManager):
self._q.put(message)
# A pause ends only the current listener segment; the workflow stays PAUSED and
# resumes with the same task ID. Without this marker, listen() cleanup calls
# _abort_execution(), whose stop flag and abort command can stop the resumed run.
# This is a compatibility workaround: cancellation policy belongs to the execution
# owner, not the response-stream listener.
if isinstance(
event,
QueueStopEvent
@ -39,6 +45,7 @@ class WorkflowAppQueueManager(AppQueueManager):
| QueueMessageEndEvent
| QueueWorkflowSucceededEvent
| QueueWorkflowFailedEvent
| QueueWorkflowPausedEvent
| QueueWorkflowPartialSuccessEvent,
):
self.stop_listen(execution_terminal=True)

View File

@ -5,7 +5,12 @@ from unittest.mock import patch
from core.app.apps.base_app_queue_manager import PublishFrom
from core.app.apps.workflow.app_queue_manager import WorkflowAppQueueManager
from core.app.entities.app_invoke_entities import InvokeFrom
from core.app.entities.queue_entities import QueueMessageEndEvent, QueuePingEvent, QueueStopEvent
from core.app.entities.queue_entities import (
QueueMessageEndEvent,
QueuePingEvent,
QueueStopEvent,
QueueWorkflowPausedEvent,
)
class TestWorkflowAppQueueManager:
@ -99,3 +104,23 @@ class TestWorkflowAppQueueManager:
_ = list(manager.listen())
graph_engine_manager.return_value.send_stop_command.assert_not_called()
def test_workflow_pause_does_not_abort_execution(self):
with (
patch("core.app.apps.base_app_queue_manager.redis_client") as redis_client,
patch("core.app.apps.base_app_queue_manager.GraphEngineManager") as graph_engine_manager,
):
redis_client.get.return_value = None
manager = WorkflowAppQueueManager(
task_id="task",
user_id="user",
invoke_from=InvokeFrom.DEBUGGER,
app_mode="workflow",
)
manager.publish(QueueWorkflowPausedEvent(), PublishFrom.APPLICATION_MANAGER)
listener = manager.listen()
assert isinstance(next(listener).event, QueueWorkflowPausedEvent)
listener.close()
graph_engine_manager.return_value.send_stop_command.assert_not_called()