feat: add test containers based tests for workflow converter (#25115)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,553 @@
|
|||||||
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from faker import Faker
|
||||||
|
|
||||||
|
from core.app.app_config.entities import (
|
||||||
|
DatasetEntity,
|
||||||
|
DatasetRetrieveConfigEntity,
|
||||||
|
ExternalDataVariableEntity,
|
||||||
|
ModelConfigEntity,
|
||||||
|
PromptTemplateEntity,
|
||||||
|
VariableEntity,
|
||||||
|
VariableEntityType,
|
||||||
|
)
|
||||||
|
from core.model_runtime.entities.llm_entities import LLMMode
|
||||||
|
from models.account import Account, Tenant
|
||||||
|
from models.api_based_extension import APIBasedExtension
|
||||||
|
from models.model import App, AppMode, AppModelConfig
|
||||||
|
from models.workflow import Workflow
|
||||||
|
from services.workflow.workflow_converter import WorkflowConverter
|
||||||
|
|
||||||
|
|
||||||
|
class TestWorkflowConverter:
|
||||||
|
"""Integration tests for WorkflowConverter using testcontainers."""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_external_service_dependencies(self):
|
||||||
|
"""Mock setup for external service dependencies."""
|
||||||
|
with (
|
||||||
|
patch("services.workflow.workflow_converter.encrypter") as mock_encrypter,
|
||||||
|
patch("services.workflow.workflow_converter.SimplePromptTransform") as mock_prompt_transform,
|
||||||
|
patch("services.workflow.workflow_converter.AgentChatAppConfigManager") as mock_agent_chat_config_manager,
|
||||||
|
patch("services.workflow.workflow_converter.ChatAppConfigManager") as mock_chat_config_manager,
|
||||||
|
patch("services.workflow.workflow_converter.CompletionAppConfigManager") as mock_completion_config_manager,
|
||||||
|
):
|
||||||
|
# Setup default mock returns
|
||||||
|
mock_encrypter.decrypt_token.return_value = "decrypted_api_key"
|
||||||
|
mock_prompt_transform.return_value.get_prompt_template.return_value = {
|
||||||
|
"prompt_template": type("obj", (object,), {"template": "You are a helpful assistant {{text_input}}"})(),
|
||||||
|
"prompt_rules": {"human_prefix": "Human", "assistant_prefix": "Assistant"},
|
||||||
|
}
|
||||||
|
mock_agent_chat_config_manager.get_app_config.return_value = self._create_mock_app_config()
|
||||||
|
mock_chat_config_manager.get_app_config.return_value = self._create_mock_app_config()
|
||||||
|
mock_completion_config_manager.get_app_config.return_value = self._create_mock_app_config()
|
||||||
|
|
||||||
|
yield {
|
||||||
|
"encrypter": mock_encrypter,
|
||||||
|
"prompt_transform": mock_prompt_transform,
|
||||||
|
"agent_chat_config_manager": mock_agent_chat_config_manager,
|
||||||
|
"chat_config_manager": mock_chat_config_manager,
|
||||||
|
"completion_config_manager": mock_completion_config_manager,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _create_mock_app_config(self):
|
||||||
|
"""Helper method to create a mock app config."""
|
||||||
|
mock_config = type("obj", (object,), {})()
|
||||||
|
mock_config.variables = [
|
||||||
|
VariableEntity(
|
||||||
|
variable="text_input",
|
||||||
|
label="Text Input",
|
||||||
|
type=VariableEntityType.TEXT_INPUT,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
mock_config.model = ModelConfigEntity(
|
||||||
|
provider="openai",
|
||||||
|
model="gpt-4",
|
||||||
|
mode=LLMMode.CHAT.value,
|
||||||
|
parameters={},
|
||||||
|
stop=[],
|
||||||
|
)
|
||||||
|
mock_config.prompt_template = PromptTemplateEntity(
|
||||||
|
prompt_type=PromptTemplateEntity.PromptType.SIMPLE,
|
||||||
|
simple_prompt_template="You are a helpful assistant {{text_input}}",
|
||||||
|
)
|
||||||
|
mock_config.dataset = None
|
||||||
|
mock_config.external_data_variables = []
|
||||||
|
mock_config.additional_features = type("obj", (object,), {"file_upload": None})()
|
||||||
|
mock_config.app_model_config_dict = {}
|
||||||
|
return mock_config
|
||||||
|
|
||||||
|
def _create_test_account_and_tenant(self, db_session_with_containers, mock_external_service_dependencies):
|
||||||
|
"""
|
||||||
|
Helper method to create a test account and tenant for testing.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_session_with_containers: Database session from testcontainers infrastructure
|
||||||
|
mock_external_service_dependencies: Mock dependencies
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (account, tenant) - Created account and tenant instances
|
||||||
|
"""
|
||||||
|
fake = Faker()
|
||||||
|
|
||||||
|
# Create account
|
||||||
|
account = Account(
|
||||||
|
email=fake.email(),
|
||||||
|
name=fake.name(),
|
||||||
|
interface_language="en-US",
|
||||||
|
status="active",
|
||||||
|
)
|
||||||
|
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.add(account)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Create tenant for the account
|
||||||
|
tenant = Tenant(
|
||||||
|
name=fake.company(),
|
||||||
|
status="normal",
|
||||||
|
)
|
||||||
|
db.session.add(tenant)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Create tenant-account join
|
||||||
|
from models.account import TenantAccountJoin, TenantAccountRole
|
||||||
|
|
||||||
|
join = TenantAccountJoin(
|
||||||
|
tenant_id=tenant.id,
|
||||||
|
account_id=account.id,
|
||||||
|
role=TenantAccountRole.OWNER.value,
|
||||||
|
current=True,
|
||||||
|
)
|
||||||
|
db.session.add(join)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Set current tenant for account
|
||||||
|
account.current_tenant = tenant
|
||||||
|
|
||||||
|
return account, tenant
|
||||||
|
|
||||||
|
def _create_test_app(self, db_session_with_containers, mock_external_service_dependencies, tenant, account):
|
||||||
|
"""
|
||||||
|
Helper method to create a test app for testing.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_session_with_containers: Database session from testcontainers infrastructure
|
||||||
|
mock_external_service_dependencies: Mock dependencies
|
||||||
|
tenant: Tenant instance
|
||||||
|
account: Account instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
App: Created app instance
|
||||||
|
"""
|
||||||
|
fake = Faker()
|
||||||
|
|
||||||
|
# Create app
|
||||||
|
app = App(
|
||||||
|
tenant_id=tenant.id,
|
||||||
|
name=fake.company(),
|
||||||
|
mode=AppMode.CHAT.value,
|
||||||
|
icon_type="emoji",
|
||||||
|
icon="🤖",
|
||||||
|
icon_background="#FF6B6B",
|
||||||
|
enable_site=True,
|
||||||
|
enable_api=True,
|
||||||
|
api_rpm=100,
|
||||||
|
api_rph=10,
|
||||||
|
is_demo=False,
|
||||||
|
is_public=False,
|
||||||
|
created_by=account.id,
|
||||||
|
updated_by=account.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.add(app)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Create app model config
|
||||||
|
app_model_config = AppModelConfig(
|
||||||
|
app_id=app.id,
|
||||||
|
provider="openai",
|
||||||
|
model="gpt-4",
|
||||||
|
configs={},
|
||||||
|
created_by=account.id,
|
||||||
|
updated_by=account.id,
|
||||||
|
)
|
||||||
|
db.session.add(app_model_config)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Link app model config to app
|
||||||
|
app.app_model_config_id = app_model_config.id
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
def test_convert_to_workflow_success(self, db_session_with_containers, mock_external_service_dependencies):
|
||||||
|
"""
|
||||||
|
Test successful conversion of app to workflow.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper app to workflow conversion
|
||||||
|
- Correct database state after conversion
|
||||||
|
- Proper relationship establishment
|
||||||
|
- Workflow creation with correct configuration
|
||||||
|
"""
|
||||||
|
# Arrange: Create test data
|
||||||
|
fake = Faker()
|
||||||
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
db_session_with_containers, mock_external_service_dependencies
|
||||||
|
)
|
||||||
|
app = self._create_test_app(db_session_with_containers, mock_external_service_dependencies, tenant, account)
|
||||||
|
|
||||||
|
# Act: Execute the conversion
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
new_app = workflow_converter.convert_to_workflow(
|
||||||
|
app_model=app,
|
||||||
|
account=account,
|
||||||
|
name="Test Workflow App",
|
||||||
|
icon_type="emoji",
|
||||||
|
icon="🚀",
|
||||||
|
icon_background="#4CAF50",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assert: Verify the expected outcomes
|
||||||
|
assert new_app is not None
|
||||||
|
assert new_app.name == "Test Workflow App"
|
||||||
|
assert new_app.mode == AppMode.ADVANCED_CHAT.value
|
||||||
|
assert new_app.icon_type == "emoji"
|
||||||
|
assert new_app.icon == "🚀"
|
||||||
|
assert new_app.icon_background == "#4CAF50"
|
||||||
|
assert new_app.tenant_id == app.tenant_id
|
||||||
|
assert new_app.created_by == account.id
|
||||||
|
|
||||||
|
# Verify database state
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.refresh(new_app)
|
||||||
|
assert new_app.id is not None
|
||||||
|
|
||||||
|
# Verify workflow was created
|
||||||
|
workflow = db.session.query(Workflow).where(Workflow.app_id == new_app.id).first()
|
||||||
|
assert workflow is not None
|
||||||
|
assert workflow.tenant_id == app.tenant_id
|
||||||
|
assert workflow.type == "chat"
|
||||||
|
|
||||||
|
def test_convert_to_workflow_without_app_model_config_error(
|
||||||
|
self, db_session_with_containers, mock_external_service_dependencies
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Test error handling when app model config is missing.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper error handling for missing app model config
|
||||||
|
- Correct exception type and message
|
||||||
|
- Database state remains unchanged
|
||||||
|
"""
|
||||||
|
# Arrange: Create test data without app model config
|
||||||
|
fake = Faker()
|
||||||
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
db_session_with_containers, mock_external_service_dependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
app = App(
|
||||||
|
tenant_id=tenant.id,
|
||||||
|
name=fake.company(),
|
||||||
|
mode=AppMode.CHAT.value,
|
||||||
|
icon_type="emoji",
|
||||||
|
icon="🤖",
|
||||||
|
icon_background="#FF6B6B",
|
||||||
|
enable_site=True,
|
||||||
|
enable_api=True,
|
||||||
|
api_rpm=100,
|
||||||
|
api_rph=10,
|
||||||
|
is_demo=False,
|
||||||
|
is_public=False,
|
||||||
|
created_by=account.id,
|
||||||
|
updated_by=account.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.add(app)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Act & Assert: Verify proper error handling
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
|
||||||
|
# Check initial state
|
||||||
|
initial_workflow_count = db.session.query(Workflow).count()
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="App model config is required"):
|
||||||
|
workflow_converter.convert_to_workflow(
|
||||||
|
app_model=app,
|
||||||
|
account=account,
|
||||||
|
name="Test Workflow App",
|
||||||
|
icon_type="emoji",
|
||||||
|
icon="🚀",
|
||||||
|
icon_background="#4CAF50",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify database state remains unchanged
|
||||||
|
# The workflow creation happens in convert_app_model_config_to_workflow
|
||||||
|
# which is called before the app_model_config check, so we need to clean up
|
||||||
|
db.session.rollback()
|
||||||
|
final_workflow_count = db.session.query(Workflow).count()
|
||||||
|
assert final_workflow_count == initial_workflow_count
|
||||||
|
|
||||||
|
def test_convert_app_model_config_to_workflow_success(
|
||||||
|
self, db_session_with_containers, mock_external_service_dependencies
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Test successful conversion of app model config to workflow.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper app model config to workflow conversion
|
||||||
|
- Correct workflow graph structure
|
||||||
|
- Proper node creation and configuration
|
||||||
|
- Database state management
|
||||||
|
"""
|
||||||
|
# Arrange: Create test data
|
||||||
|
fake = Faker()
|
||||||
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
db_session_with_containers, mock_external_service_dependencies
|
||||||
|
)
|
||||||
|
app = self._create_test_app(db_session_with_containers, mock_external_service_dependencies, tenant, account)
|
||||||
|
|
||||||
|
# Act: Execute the conversion
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
workflow = workflow_converter.convert_app_model_config_to_workflow(
|
||||||
|
app_model=app,
|
||||||
|
app_model_config=app.app_model_config,
|
||||||
|
account_id=account.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assert: Verify the expected outcomes
|
||||||
|
assert workflow is not None
|
||||||
|
assert workflow.tenant_id == app.tenant_id
|
||||||
|
assert workflow.app_id == app.id
|
||||||
|
assert workflow.type == "chat"
|
||||||
|
assert workflow.version == Workflow.VERSION_DRAFT
|
||||||
|
assert workflow.created_by == account.id
|
||||||
|
|
||||||
|
# Verify workflow graph structure
|
||||||
|
graph = json.loads(workflow.graph)
|
||||||
|
assert "nodes" in graph
|
||||||
|
assert "edges" in graph
|
||||||
|
assert len(graph["nodes"]) > 0
|
||||||
|
assert len(graph["edges"]) > 0
|
||||||
|
|
||||||
|
# Verify start node exists
|
||||||
|
start_node = next((node for node in graph["nodes"] if node["data"]["type"] == "start"), None)
|
||||||
|
assert start_node is not None
|
||||||
|
assert start_node["id"] == "start"
|
||||||
|
|
||||||
|
# Verify LLM node exists
|
||||||
|
llm_node = next((node for node in graph["nodes"] if node["data"]["type"] == "llm"), None)
|
||||||
|
assert llm_node is not None
|
||||||
|
assert llm_node["id"] == "llm"
|
||||||
|
|
||||||
|
# Verify answer node exists for chat mode
|
||||||
|
answer_node = next((node for node in graph["nodes"] if node["data"]["type"] == "answer"), None)
|
||||||
|
assert answer_node is not None
|
||||||
|
assert answer_node["id"] == "answer"
|
||||||
|
|
||||||
|
# Verify database state
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.refresh(workflow)
|
||||||
|
assert workflow.id is not None
|
||||||
|
|
||||||
|
# Verify features were set
|
||||||
|
features = json.loads(workflow._features) if workflow._features else {}
|
||||||
|
assert isinstance(features, dict)
|
||||||
|
|
||||||
|
def test_convert_to_start_node_success(self, db_session_with_containers, mock_external_service_dependencies):
|
||||||
|
"""
|
||||||
|
Test successful conversion to start node.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper start node creation with variables
|
||||||
|
- Correct node structure and data
|
||||||
|
- Variable encoding and formatting
|
||||||
|
"""
|
||||||
|
# Arrange: Create test variables
|
||||||
|
variables = [
|
||||||
|
VariableEntity(
|
||||||
|
variable="text_input",
|
||||||
|
label="Text Input",
|
||||||
|
type=VariableEntityType.TEXT_INPUT,
|
||||||
|
),
|
||||||
|
VariableEntity(
|
||||||
|
variable="number_input",
|
||||||
|
label="Number Input",
|
||||||
|
type=VariableEntityType.NUMBER,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Act: Execute the conversion
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
start_node = workflow_converter._convert_to_start_node(variables=variables)
|
||||||
|
|
||||||
|
# Assert: Verify the expected outcomes
|
||||||
|
assert start_node is not None
|
||||||
|
assert start_node["id"] == "start"
|
||||||
|
assert start_node["data"]["title"] == "START"
|
||||||
|
assert start_node["data"]["type"] == "start"
|
||||||
|
assert len(start_node["data"]["variables"]) == 2
|
||||||
|
|
||||||
|
# Verify variable encoding
|
||||||
|
first_variable = start_node["data"]["variables"][0]
|
||||||
|
assert first_variable["variable"] == "text_input"
|
||||||
|
assert first_variable["label"] == "Text Input"
|
||||||
|
assert first_variable["type"] == "text-input"
|
||||||
|
|
||||||
|
second_variable = start_node["data"]["variables"][1]
|
||||||
|
assert second_variable["variable"] == "number_input"
|
||||||
|
assert second_variable["label"] == "Number Input"
|
||||||
|
assert second_variable["type"] == "number"
|
||||||
|
|
||||||
|
def test_convert_to_http_request_node_success(self, db_session_with_containers, mock_external_service_dependencies):
|
||||||
|
"""
|
||||||
|
Test successful conversion to HTTP request node.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper HTTP request node creation
|
||||||
|
- Correct API configuration and authorization
|
||||||
|
- Code node creation for response parsing
|
||||||
|
- External data variable mapping
|
||||||
|
"""
|
||||||
|
# Arrange: Create test data
|
||||||
|
fake = Faker()
|
||||||
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
db_session_with_containers, mock_external_service_dependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
app = self._create_test_app(db_session_with_containers, mock_external_service_dependencies, tenant, account)
|
||||||
|
|
||||||
|
# Create API based extension
|
||||||
|
api_based_extension = APIBasedExtension(
|
||||||
|
tenant_id=tenant.id,
|
||||||
|
name="Test API Extension",
|
||||||
|
api_key="encrypted_api_key",
|
||||||
|
api_endpoint="https://api.example.com/test",
|
||||||
|
)
|
||||||
|
|
||||||
|
from extensions.ext_database import db
|
||||||
|
|
||||||
|
db.session.add(api_based_extension)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Mock encrypter
|
||||||
|
mock_external_service_dependencies["encrypter"].decrypt_token.return_value = "decrypted_api_key"
|
||||||
|
|
||||||
|
variables = [
|
||||||
|
VariableEntity(
|
||||||
|
variable="user_input",
|
||||||
|
label="User Input",
|
||||||
|
type=VariableEntityType.TEXT_INPUT,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
external_data_variables = [
|
||||||
|
ExternalDataVariableEntity(
|
||||||
|
variable="external_data", type="api", config={"api_based_extension_id": api_based_extension.id}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Act: Execute the conversion
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
nodes, external_data_variable_node_mapping = workflow_converter._convert_to_http_request_node(
|
||||||
|
app_model=app,
|
||||||
|
variables=variables,
|
||||||
|
external_data_variables=external_data_variables,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assert: Verify the expected outcomes
|
||||||
|
assert len(nodes) == 2 # HTTP request node + code node
|
||||||
|
assert len(external_data_variable_node_mapping) == 1
|
||||||
|
|
||||||
|
# Verify HTTP request node
|
||||||
|
http_request_node = nodes[0]
|
||||||
|
assert http_request_node["data"]["type"] == "http-request"
|
||||||
|
assert http_request_node["data"]["method"] == "post"
|
||||||
|
assert http_request_node["data"]["url"] == api_based_extension.api_endpoint
|
||||||
|
assert http_request_node["data"]["authorization"]["type"] == "api-key"
|
||||||
|
assert http_request_node["data"]["authorization"]["config"]["type"] == "bearer"
|
||||||
|
assert http_request_node["data"]["authorization"]["config"]["api_key"] == "decrypted_api_key"
|
||||||
|
|
||||||
|
# Verify code node
|
||||||
|
code_node = nodes[1]
|
||||||
|
assert code_node["data"]["type"] == "code"
|
||||||
|
assert code_node["data"]["code_language"] == "python3"
|
||||||
|
assert "response_json" in code_node["data"]["variables"][0]["variable"]
|
||||||
|
|
||||||
|
# Verify mapping
|
||||||
|
assert external_data_variable_node_mapping["external_data"] == code_node["id"]
|
||||||
|
|
||||||
|
def test_convert_to_knowledge_retrieval_node_success(
|
||||||
|
self, db_session_with_containers, mock_external_service_dependencies
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Test successful conversion to knowledge retrieval node.
|
||||||
|
|
||||||
|
This test verifies:
|
||||||
|
- Proper knowledge retrieval node creation
|
||||||
|
- Correct dataset configuration
|
||||||
|
- Model configuration integration
|
||||||
|
- Query variable selector setup
|
||||||
|
"""
|
||||||
|
# Arrange: Create test data
|
||||||
|
fake = Faker()
|
||||||
|
account, tenant = self._create_test_account_and_tenant(
|
||||||
|
db_session_with_containers, mock_external_service_dependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create dataset config
|
||||||
|
dataset_config = DatasetEntity(
|
||||||
|
dataset_ids=["dataset_1", "dataset_2"],
|
||||||
|
retrieve_config=DatasetRetrieveConfigEntity(
|
||||||
|
retrieve_strategy=DatasetRetrieveConfigEntity.RetrieveStrategy.MULTIPLE,
|
||||||
|
top_k=10,
|
||||||
|
score_threshold=0.8,
|
||||||
|
reranking_model={"provider": "cohere", "model": "rerank-v2"},
|
||||||
|
reranking_enabled=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
model_config = ModelConfigEntity(
|
||||||
|
provider="openai",
|
||||||
|
model="gpt-4",
|
||||||
|
mode=LLMMode.CHAT.value,
|
||||||
|
parameters={"temperature": 0.7},
|
||||||
|
stop=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Act: Execute the conversion for advanced chat mode
|
||||||
|
workflow_converter = WorkflowConverter()
|
||||||
|
node = workflow_converter._convert_to_knowledge_retrieval_node(
|
||||||
|
new_app_mode=AppMode.ADVANCED_CHAT,
|
||||||
|
dataset_config=dataset_config,
|
||||||
|
model_config=model_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assert: Verify the expected outcomes
|
||||||
|
assert node is not None
|
||||||
|
assert node["data"]["type"] == "knowledge-retrieval"
|
||||||
|
assert node["data"]["title"] == "KNOWLEDGE RETRIEVAL"
|
||||||
|
assert node["data"]["dataset_ids"] == ["dataset_1", "dataset_2"]
|
||||||
|
assert node["data"]["retrieval_mode"] == "multiple"
|
||||||
|
assert node["data"]["query_variable_selector"] == ["sys", "query"]
|
||||||
|
|
||||||
|
# Verify multiple retrieval config
|
||||||
|
multiple_config = node["data"]["multiple_retrieval_config"]
|
||||||
|
assert multiple_config["top_k"] == 10
|
||||||
|
assert multiple_config["score_threshold"] == 0.8
|
||||||
|
assert multiple_config["reranking_model"]["provider"] == "cohere"
|
||||||
|
assert multiple_config["reranking_model"]["model"] == "rerank-v2"
|
||||||
|
|
||||||
|
# Verify single retrieval config is None for multiple strategy
|
||||||
|
assert node["data"]["single_retrieval_config"] is None
|
Reference in New Issue
Block a user