gateway/test_workflow.py
2025-07-08 01:14:27 +02:00

496 lines
No EOL
18 KiB
Python

#!/usr/bin/env python3
"""
Test routine for WorkflowManager.workflowProcess() with new unified workflow architecture
"""
import asyncio
import sys
import os
import json
from datetime import datetime, UTC, timedelta
import uuid
from typing import List
print("Starting test_workflow.py...")
# Configure logging FIRST, before any other imports
import logging
# Clear any existing handlers to avoid duplicate logs
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.FileHandler('test_workflow.log', mode='w', encoding='utf-8') # 'w' mode clears the file
],
force=True # Force reconfiguration even if already configured
)
# Filter out httpcore messages
logging.getLogger('httpcore').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
# Set up test configuration
os.environ['POWERON_CONFIG_FILE'] = 'test_config.ini'
print("Set POWERON_CONFIG_FILE environment variable")
try:
# Simple imports from modules (same as app.py)
from modules.interfaces.interfaceAppObjects import User, UserConnection
from modules.interfaces.interfaceChatObjects import ChatObjects
from modules.interfaces.interfaceChatModel import UserInputRequest, ChatWorkflow
from modules.workflow.managerWorkflow import WorkflowManager
print("All imports successful")
except Exception as e:
print(f"Import error: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
def log_workflow_debug(message: str, data: dict = None):
"""Log workflow debug data with JSON dumps"""
timestamp = datetime.now(UTC).isoformat()
if data:
logger.debug(f"[{timestamp}] {message}\n{json.dumps(data, indent=2, ensure_ascii=False)}")
else:
logger.debug(f"[{timestamp}] {message}")
def create_test_user() -> User:
"""Create a test user for the workflow"""
return User(
id="test-user-001",
mandateId="test-mandate-001",
username="testuser",
email="test@example.com",
fullName="Test User",
enabled=True,
language="en",
privilege="user",
authenticationAuthority="local"
)
def create_test_workflow() -> ChatWorkflow:
"""Create a test workflow"""
return ChatWorkflow(
id="test-workflow-001",
mandateId="test-mandate-001",
status="running",
name="Candidate Evaluation and Selection Workflow",
currentRound=1,
lastActivity=datetime.now(UTC).isoformat(),
startedAt=datetime.now(UTC).isoformat(),
logs=[],
messages=[],
stats=None,
tasks=[]
)
def create_test_user_input() -> UserInputRequest:
"""Create test user input with a candidate evaluation task"""
return UserInputRequest(
prompt="""I have following list of job profiles from candidates (3 job profiles as text files) and want to know, who is best suited for the position of product designer (file with criteria). Create an evaluation matrix and rate all candidates according to the matrix, then produce PowerPoint presentation for the management to decide and store it on the SharePoint for the account p.motsch valueon.
The task involves:
1. Analyze the job profiles of the 3 candidates
2. Review the product designer position criteria
3. Create a comprehensive evaluation matrix with relevant criteria
4. Rate each candidate against the evaluation matrix
5. Generate a professional PowerPoint presentation for management decision
6. Store the final presentation in SharePoint for p.motsch valueon account
Please ensure the evaluation includes:
- Technical skills assessment
- Experience level evaluation
- Cultural fit analysis
- Portfolio quality review
- Communication skills assessment
- Overall suitability score
The output should be suitable for executive review and include both detailed analysis and clear recommendations.""",
listFileId=["candidate_1_profile.txt", "candidate_2_profile.txt", "candidate_3_profile.txt", "product_designer_criteria.txt"],
userLanguage="en"
)
def create_test_files(chat_interface) -> List[str]:
"""Create test files in the database for candidate evaluation"""
test_files = []
# Import the component interface
from modules.interfaces.interfaceComponentObjects import getInterface as getComponentObjects
# Get component interface with the same user context
component_interface = getComponentObjects(chat_interface.currentUser)
# Candidate 1 Profile
candidate_1_content = """CANDIDATE 1: Sarah Johnson
Position: Senior Product Designer
Experience: 8 years
TECHNICAL SKILLS:
- Figma, Sketch, Adobe Creative Suite (Expert)
- Prototyping tools: Framer, Principle (Advanced)
- Design systems and component libraries (Expert)
- User research and usability testing (Advanced)
- HTML/CSS/JavaScript basics (Intermediate)
EXPERIENCE:
- Senior Product Designer at TechCorp (3 years)
- Product Designer at StartupXYZ (3 years)
- UI/UX Designer at DesignAgency (2 years)
PORTFOLIO HIGHLIGHTS:
- Redesigned e-commerce platform increasing conversion by 25%
- Created comprehensive design system for 50+ product team
- Led user research for mobile banking app with 1M+ users
COMMUNICATION SKILLS:
- Excellent presentation skills
- Experience presenting to C-level executives
- Strong stakeholder management
- Mentored 5 junior designers
CULTURAL FIT:
- Collaborative team player
- Proactive problem solver
- Adapts quickly to new environments
- Values user-centered design approach"""
# Candidate 2 Profile
candidate_2_content = """CANDIDATE 2: Michael Chen
Position: Product Designer
Experience: 5 years
TECHNICAL SKILLS:
- Figma, Sketch, Adobe Creative Suite (Advanced)
- Prototyping tools: InVision, Marvel (Intermediate)
- Design systems (Intermediate)
- User research (Intermediate)
- No coding experience
EXPERIENCE:
- Product Designer at MidSizeTech (3 years)
- Junior Designer at CreativeStudio (2 years)
PORTFOLIO HIGHLIGHTS:
- Designed mobile app for local restaurant chain
- Created brand identity for startup
- Improved user flow for SaaS dashboard
COMMUNICATION SKILLS:
- Good presentation skills
- Works well in small teams
- Some experience with stakeholders
- Learning to mentor others
CULTURAL FIT:
- Quiet but dedicated worker
- Detail-oriented
- Prefers structured environments
- Focuses on visual design quality"""
# Candidate 3 Profile
candidate_3_content = """CANDIDATE 3: Emma Rodriguez
Position: UX/UI Designer
Experience: 6 years
TECHNICAL SKILLS:
- Figma, Sketch, Adobe Creative Suite (Advanced)
- Prototyping tools: Framer, Axure (Advanced)
- Design systems (Advanced)
- User research and analytics (Expert)
- Basic React/JavaScript (Intermediate)
EXPERIENCE:
- UX/UI Designer at EnterpriseCorp (4 years)
- UX Designer at ConsultingFirm (2 years)
PORTFOLIO HIGHLIGHTS:
- Led UX research for enterprise software used by 10K+ users
- Implemented data-driven design improvements increasing user satisfaction by 30%
- Created accessibility-compliant design system
- Conducted international user research studies
COMMUNICATION SKILLS:
- Outstanding presentation and storytelling skills
- Experience with international stakeholders
- Strong analytical communication
- Excellent at translating user insights to business value
CULTURAL FIT:
- Natural leader and team motivator
- Strategic thinker
- Adapts well to change
- Passionate about user advocacy"""
# Product Designer Criteria
criteria_content = """PRODUCT DESIGNER POSITION CRITERIA
Company: ValueOn
Department: Product Development
Level: Senior
REQUIRED SKILLS:
- Expert proficiency in Figma and modern design tools
- Strong understanding of user-centered design principles
- Experience with design systems and component libraries
- Ability to conduct user research and usability testing
- Basic understanding of front-end development (HTML/CSS/JavaScript)
REQUIRED EXPERIENCE:
- Minimum 5 years in product design
- Experience working with cross-functional teams
- Portfolio demonstrating complex product design solutions
- Experience with SaaS or enterprise software preferred
COMMUNICATION REQUIREMENTS:
- Excellent presentation skills
- Ability to communicate design decisions to stakeholders
- Experience presenting to management/executives
- Strong collaboration and feedback skills
CULTURAL FIT:
- Team-oriented and collaborative
- Proactive and self-motivated
- Adaptable to fast-paced environment
- Passionate about user experience
RESPONSIBILITIES:
- Lead design for core product features
- Collaborate with product managers and engineers
- Conduct user research and usability testing
- Create and maintain design system
- Present design solutions to stakeholders
- Mentor junior designers
EVALUATION WEIGHTS:
- Technical Skills: 30%
- Experience: 25%
- Communication: 20%
- Cultural Fit: 15%
- Portfolio Quality: 10%"""
# Create files in database
file_contents = [
("candidate_1_profile.txt", candidate_1_content),
("candidate_2_profile.txt", candidate_2_content),
("candidate_3_profile.txt", candidate_3_content),
("product_designer_criteria.txt", criteria_content)
]
for filename, content in file_contents:
try:
# Create file in database using the component interface
file_item = component_interface.saveUploadedFile(
fileContent=content.encode('utf-8'),
fileName=filename
)
test_files.append(file_item.id)
log_workflow_debug(f"Created test file: {filename}", {
"file_id": file_item.id,
"filename": filename,
"content_length": len(content)
})
except Exception as e:
log_workflow_debug(f"Error creating test file {filename}: {str(e)}")
# Create a dummy file ID if creation fails
test_files.append(f"file_{filename.replace('.', '_')}")
return test_files
async def test_workflow_process():
print("Inside test_workflow_process()")
"""Test the workflowProcess function with new unified workflow architecture"""
try:
logger.info("=== STARTING UNIFIED WORKFLOW PROCESS TEST ===")
# Create test data
test_user = create_test_user()
test_workflow = create_test_workflow()
test_user_input = create_test_user_input()
log_workflow_debug("Test data created", {
"user_id": test_user.id,
"workflow_id": test_workflow.id,
"user_input_prompt": test_user_input.prompt,
"file_ids": test_user_input.listFileId
})
# Create test user in database through AppObjects interface
from modules.interfaces.interfaceAppObjects import getRootInterface
from modules.interfaces.interfaceAppModel import AuthAuthority, ConnectionStatus, Token, UserPrivilege
root_interface = getRootInterface()
created_user = root_interface.createUser(
username=test_user.username,
password="testpassword123", # Required for local authentication
email=test_user.email,
fullName=test_user.fullName,
language=test_user.language,
enabled=test_user.enabled,
privilege=UserPrivilege.USER,
authenticationAuthority=AuthAuthority.LOCAL
)
log_workflow_debug("Created test user in database", {
"user_id": created_user.id,
"username": created_user.username,
"email": created_user.email
})
# Create test connection through AppObjects interface
from modules.interfaces.interfaceAppObjects import getInterface as getAppObjects
app_interface = getAppObjects(created_user)
test_connection = app_interface.addUserConnection(
userId=created_user.id,
authority=AuthAuthority.MSFT,
externalId="msft-user-123",
externalUsername="testuser@example.com",
externalEmail="testuser@example.com",
status=ConnectionStatus.ACTIVE
)
log_workflow_debug("Created test connection", {
"connection_id": test_connection.id,
"authority": test_connection.authority,
"external_username": test_connection.externalUsername
})
# Create test token for the connection
test_token = Token(
userId=created_user.id,
authority=AuthAuthority.MSFT,
tokenAccess="test-access-token-123",
tokenRefresh="test-refresh-token-456",
tokenType="bearer",
expiresAt=datetime.now(UTC).timestamp() + 3600, # 1 hour from now
createdAt=datetime.now(UTC)
)
app_interface.saveToken(test_token)
log_workflow_debug("Created test token", {
"token_id": test_token.id,
"authority": test_token.authority,
"expires_at": test_token.expiresAt
})
# Create test workflow in database through ChatObjects interface
from modules.interfaces.interfaceChatObjects import getInterface as getChatObjects
chat_interface = getChatObjects(created_user)
workflow_data = {
"name": test_workflow.name,
"status": test_workflow.status,
"mandateId": created_user.mandateId,
"currentRound": test_workflow.currentRound,
"startedAt": test_workflow.startedAt,
"lastActivity": test_workflow.lastActivity
}
created_workflow = chat_interface.createWorkflow(workflow_data)
log_workflow_debug("Created test workflow in database", {
"workflow_id": created_workflow.id,
"name": created_workflow.name,
"status": created_workflow.status
})
# Update the test_workflow object with the created workflow's ID
test_workflow.id = created_workflow.id
# Create test files in database
logger.info("Creating test files for candidate evaluation...")
test_file_ids = create_test_files(chat_interface)
log_workflow_debug("Test files created", {
"file_count": len(test_file_ids),
"file_ids": test_file_ids
})
# Update user input with real file IDs
test_user_input.listFileId = test_file_ids
log_workflow_debug("Updated user input with file IDs", {
"file_ids": test_user_input.listFileId
})
# Initialize WorkflowManager
workflow_manager = WorkflowManager(chat_interface, created_user)
logger.info("WorkflowManager initialized")
# Test the workflowProcess function
logger.info("Calling workflowProcess with unified workflow architecture...")
try:
# Execute the unified workflow process
await workflow_manager.workflowProcess(test_user_input, test_workflow)
# Log workflow results
log_workflow_debug("Workflow process completed successfully", {
"workflow_id": test_workflow.id,
"workflow_status": test_workflow.status,
"message_count": len(test_workflow.messages),
"final_messages": [
{
"role": msg.role,
"message": msg.message[:200] + "..." if len(msg.message) > 200 else msg.message,
"status": msg.status,
"sequence_nr": msg.sequenceNr
} for msg in test_workflow.messages[-3:] # Last 3 messages
]
})
# Log detailed workflow messages
for i, message in enumerate(test_workflow.messages):
log_workflow_debug(f"WORKFLOW MESSAGE {i+1}:", {
"role": message.role,
"message": message.message,
"status": message.status,
"sequence_nr": message.sequenceNr,
"published_at": message.publishedAt,
"document_count": len(message.documents) if hasattr(message, 'documents') else 0
})
return test_workflow
except Exception as e:
import traceback
error_details = {
"error_type": type(e).__name__,
"error_message": str(e),
"error_args": e.args if hasattr(e, 'args') else None,
"traceback": traceback.format_exc()
}
log_workflow_debug("WORKFLOW PROCESS EXCEPTION:", error_details)
raise
logger.info("=== UNIFIED WORKFLOW PROCESS TEST COMPLETED ===")
return test_workflow
except Exception as e:
logger.error(f"❌ Test failed with error: {str(e)}")
log_workflow_debug("Full error details", {
"error_type": type(e).__name__,
"error_message": str(e)
})
raise
async def main():
print("Inside main()")
logger.info("=" * 50)
logger.info("CANDIDATE EVALUATION UNIFIED WORKFLOW TEST")
logger.info("=" * 50)
try:
workflow = await test_workflow_process()
logger.info("=" * 50)
logger.info("TEST COMPLETED SUCCESSFULLY")
logger.info("=" * 50)
return workflow
except Exception as e:
logger.error("=" * 50)
logger.error("TEST FAILED")
logger.error("=" * 50)
raise
if __name__ == "__main__":
print("About to run main()")
asyncio.run(main())
print("main() finished")