496 lines
No EOL
18 KiB
Python
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") |