fix: disable duplicate trigger nodes in workflow builder

AddNodePanel: disable trigger buttons and show tooltip when a trigger
already exists on the canvas, using bySpecName to identify trigger-
category specs from the live node list.
useWorkflowState: preflight in saveWorkflow rejects saves with multiple
trigger nodes via a sonner toast before the network request is made.
text_chat_session_service: include the original exception message in
TextChatSessionExecutionError so the HTTP 500 detail surfaces the root
cause without DB inspection.

Closes #378
This commit is contained in:
Varun Nuthalapati 2026-06-02 08:39:47 -07:00
parent acc2ef9e96
commit 5b3ea3e018
5 changed files with 53 additions and 5 deletions

View file

@ -207,7 +207,7 @@ async def execute_pending_text_chat_turn(
error_message=str(e),
)
raise TextChatSessionExecutionError(
"Failed to execute text chat assistant turn"
f"Failed to execute text chat assistant turn: {e}"
) from e
completed_session_data = normalize_text_chat_session_data(text_session.session_data)

View file

@ -1,4 +1,4 @@
from unittest.mock import AsyncMock
from unittest.mock import AsyncMock, patch
import pytest
@ -9,6 +9,7 @@ from api.services.workflow.text_chat_session_service import (
TextChatTurnNotFoundError,
_reload_text_chat_session,
build_pending_text_chat_turn,
execute_pending_text_chat_turn,
truncate_text_chat_future_turns,
validate_text_chat_turn_cursor,
)
@ -77,6 +78,31 @@ async def test_reload_text_chat_session_uses_run_id_to_resolve_organization(
get_text_session.assert_awaited_once_with(123, organization_id=77)
@pytest.mark.asyncio
async def test_execute_pending_turn_surfaces_original_exception_message(monkeypatch):
session = WorkflowRunTextSessionModel(workflow_run_id=42)
session.session_data = {"turns": [{"id": "turn-1", "status": "pending"}], "cursor_turn_id": "turn-1"}
session.checkpoint = None
monkeypatch.setattr(
text_chat_session_service,
"execute_text_chat_pending_turn",
AsyncMock(side_effect=RuntimeError("Workflow has 2 start nodes")),
)
monkeypatch.setattr(
text_chat_session_service,
"_mark_pending_turn_failed",
AsyncMock(),
)
with pytest.raises(TextChatSessionExecutionError, match="Workflow has 2 start nodes"):
await execute_pending_text_chat_turn(
workflow_id=1,
run_id=42,
text_session=session,
)
@pytest.mark.asyncio
async def test_reload_text_chat_session_raises_when_run_organization_is_missing(
monkeypatch,