From 91aff56e1c192b5770733943fbf69c18b7dd7ebe Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 2 Sep 2025 11:47:39 +0200
Subject: [PATCH] messageing aligned
---
modules/chat/handling/handlingTasks.py | 315 +++++--------------------
modules/chat/handling/promptFactory.py | 10 +-
modules/chat/serviceCenter.py | 102 +++++++-
modules/methods/methodDocument.py | 24 +-
modules/routes/routeWorkflows.py | 9 -
modules/workflow/managerWorkflow.py | 10 +-
notes/changelog.txt | 3 +-
7 files changed, 177 insertions(+), 296 deletions(-)
diff --git a/modules/chat/handling/handlingTasks.py b/modules/chat/handling/handlingTasks.py
index 290fdf0a..6138932b 100644
--- a/modules/chat/handling/handlingTasks.py
+++ b/modules/chat/handling/handlingTasks.py
@@ -192,7 +192,8 @@ class HandlingTasks:
task_plan = TaskPlan(
overview=task_plan_dict.get('overview', ''),
- tasks=tasks
+ tasks=tasks,
+ userMessage=task_plan_dict.get('userMessage', '')
)
# Set workflow totals for progress tracking
@@ -217,24 +218,19 @@ class HandlingTasks:
"""Create a chat message containing the task plan with user-friendly messages"""
try:
# Build task plan summary
- task_summary = f"š **Task Plan Generated**\n\n"
- task_summary += f"**Overview:** {task_plan.overview}\n\n"
- task_summary += f"**Total Tasks:** {len(task_plan.tasks)}\n\n"
-
- # Add each task with its user message
- for i, task in enumerate(task_plan.tasks):
- task_summary += f"**Task {i+1}:** {task.objective}\n"
- if task.userMessage:
- task_summary += f" š¬ {task.userMessage}\n"
- if task.success_criteria:
- criteria_str = ', '.join(task.success_criteria)
- task_summary += f" ā
Success Criteria: {criteria_str}\n"
- task_summary += "\n"
-
+ task_summary = f"š **Task Plan**\n\n"
+
# Get overall user message from task plan if available
overall_message = task_plan.userMessage
if overall_message:
- task_summary += f"**Plan Summary:** {overall_message}\n\n"
+ task_summary += f"{overall_message}\n\n"
+
+ # Add each task with its user message
+ for i, task in enumerate(task_plan.tasks):
+ if task.userMessage:
+ task_summary += f"š¬ {task.userMessage}\n"
+ task_summary += "\n"
+
# Create workflow message
message_data = {
@@ -269,76 +265,6 @@ class HandlingTasks:
except Exception as e:
logger.error(f"Error creating task plan message: {str(e)}")
- async def createDocumentContextMessage(self, documents: List, workflow):
- """Create a chat message with document context and workflow labeling"""
- try:
- # Get current workflow context and stats
- workflow_context = self.service.getWorkflowContext()
- workflow_stats = self.service.getWorkflowStats()
-
- # Create a simple document context message without AI dependency
- message_text = f"š **Document Context**\n\n"
- message_text += f"**Total Documents:** {len(documents)}\n\n"
-
- # Add workflow context information
- current_round = workflow_context.get('currentRound', 0)
- current_task = workflow_context.get('currentTask', 0)
- total_tasks = workflow_stats.get('totalTasks', 0)
- current_action = workflow_context.get('currentAction', 0)
- total_actions = workflow_stats.get('totalActions', 0)
-
- message_text += f"**Workflow Context:**\n"
- message_text += f"- Round: {current_round}\n"
- if total_tasks > 0:
- message_text += f"- Task: {current_task}/{total_tasks}\n"
- else:
- message_text += f"- Task: {current_task}\n"
- if total_actions > 0:
- message_text += f"- Action: {current_action}/{total_actions}\n"
- else:
- message_text += f"- Action: {current_action}\n"
- message_text += f"- Status: {workflow_stats.get('workflowStatus', 'unknown')}\n\n"
-
- # Add document list
- if documents:
- message_text += "**Available Documents:**\n"
- for i, doc in enumerate(documents[:5]): # Show first 5 documents
- message_text += f"- {doc.fileName if hasattr(doc, 'fileName') else f'Document {i+1}'}\n"
- if len(documents) > 5:
- message_text += f"- ... and {len(documents) - 5} more documents\n"
- message_text += "\n"
-
- message_text += "Document context information is available for processing."
-
- # Create workflow message
- message_data = {
- "workflowId": workflow.id,
- "role": "assistant",
- "message": message_text,
- "status": "step",
- "sequenceNr": len(workflow.messages) + 1,
- "publishedAt": get_utc_timestamp(),
- "documentsLabel": "document_context",
- "documents": [], # Empty documents for context message
- # Add workflow context fields
- "roundNumber": workflow_context.get('currentRound', 0),
- "taskNumber": workflow_context.get('currentTask', 0),
- "actionNumber": workflow_context.get('currentAction', 0),
- # Add progress status
- "taskProgress": "pending",
- "actionProgress": "pending"
- }
-
- message = self.chatInterface.createWorkflowMessage(message_data)
- if message:
- workflow.messages.append(message)
- logger.info(f"Document context message created with {len(documents)} documents")
- else:
- logger.error("Failed to create document context message")
-
- except Exception as e:
- logger.error(f"Error creating document context message: {str(e)}")
-
async def generateTaskActions(self, task_step, workflow, previous_results=None, enhanced_context=None) -> List[TaskAction]:
"""Generate actions for a given task step."""
try:
@@ -546,25 +472,13 @@ class HandlingTasks:
# Create database log entry for task start in format expected by frontend
if task_index is not None:
- if total_tasks is not None:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"Executing task {task_index}/{total_tasks}",
- "type": "info"
- })
- else:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"Executing task {task_index}/?",
- "type": "info"
- })
-
+
# Create a task start message for the user
task_progress = f"{task_index}/{total_tasks}" if total_tasks is not None else str(task_index)
task_start_message = {
"workflowId": workflow.id,
"role": "assistant",
- "message": f"š Starting Task {task_progress}\n\nObjective: {task_step.objective}",
+ "message": f"š **Task {task_progress}**",
"status": "step",
"sequenceNr": len(workflow.messages) + 1,
"publishedAt": get_utc_timestamp(),
@@ -617,11 +531,6 @@ class HandlingTasks:
logger.error("No actions defined for task step, aborting task execution")
break
- # Create document context message if documents are available
- available_docs = self.service.getAvailableDocuments(workflow)
- if available_docs:
- await self.createDocumentContextMessage(available_docs, workflow)
-
action_results = []
for action_idx, action in enumerate(actions):
# Check workflow status before each action execution
@@ -639,18 +548,11 @@ class HandlingTasks:
# Log action start in format expected by frontend
logger.info(f"Task {task_index} - Starting action {action_number}/{total_actions}")
- # Create database log entry for action start
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"Task {task_index} - Starting action {action_number}/{total_actions}",
- "type": "info"
- })
-
# Create an action start message for the user
action_start_message = {
"workflowId": workflow.id,
"role": "assistant",
- "message": f"ā” Task {task_index} - Action {action_number}/{total_actions}\n\nMethod: {action.execMethod}.{action.execAction}",
+ "message": f"ā” **Action {action_number}/{total_actions}** (Method {action.execMethod}.{action.execAction})",
"status": "step",
"sequenceNr": len(workflow.messages) + 1,
"publishedAt": get_utc_timestamp(),
@@ -694,34 +596,19 @@ class HandlingTasks:
if success:
logger.info(f"=== TASK {task_index or '?'} COMPLETED SUCCESSFULLY: {task_step.objective} ===")
- # Create database log entry for task completion
- if total_tasks is not None:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"šÆ Task {task_index}/{total_tasks} completed",
- "type": "success"
- })
- else:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"šÆ Task {task_index}/? completed",
- "type": "success"
- })
-
# Create a task completion message for the user
task_progress = f"{task_index}/{total_tasks}" if total_tasks is not None else str(task_index)
# Enhanced completion message with criteria details
- completion_message = f"šÆ Task {task_progress} Completed Successfully!\n\nObjective: {task_step.objective}\n\nFeedback: {feedback or 'Task completed successfully'}"
+ completion_message = f"šÆ **Task {task_progress}**\n\nā
{feedback or 'Task completed successfully'}"
# Add criteria status if available
if hasattr(review_result, 'met_criteria') and review_result.met_criteria:
- completion_message += f"\n\nā
**Success Criteria Met:**\n"
for criterion in review_result.met_criteria:
- completion_message += f"⢠{criterion}\n"
+ completion_message += f"\n⢠{criterion}\n"
if hasattr(review_result, 'quality_score'):
- completion_message += f"\nš **Quality Score:** {review_result.quality_score}/10"
+ completion_message += f"\nš Score {review_result.quality_score}/10"
task_completion_message = {
"workflowId": workflow.id,
@@ -740,10 +627,6 @@ class HandlingTasks:
"taskProgress": "success"
}
- # Add user-friendly message if available
- if task_step.userMessage:
- task_completion_message["message"] += f"\n\nš¬ {task_step.userMessage}"
-
message = self.chatInterface.createWorkflowMessage(task_completion_message)
if message:
workflow.messages.append(message)
@@ -824,7 +707,7 @@ class HandlingTasks:
retry_message = {
"workflowId": workflow.id,
"role": "assistant",
- "message": f"š Task {task_index} requires retry: {review_result.improvements}",
+ "message": f"š **Task {task_index}** needs retry: {review_result.improvements}",
"status": "step",
"sequenceNr": len(workflow.messages) + 1,
"publishedAt": get_utc_timestamp(),
@@ -843,19 +726,19 @@ class HandlingTasks:
continue
else:
logger.error(f"=== TASK {task_index or '?'} FAILED: {task_step.objective} after {attempt+1} attempts ===")
-
+ task_progress = f"{task_index}/{total_tasks}" if total_tasks is not None else str(task_index)
+
# Create user-facing error message for task failure
- error_message = f"ā Task {task_index or '?'} - '{task_step.objective}' failed after {attempt+1} attempts\n\n"
- error_message += f"Objective: {task_step.objective}\n\n"
+ error_message = f"**Task {task_progress}**\n\nā '{task_step.objective}' {attempt+1}x failed\n\n"
# Add specific error details if available
if review_result and hasattr(review_result, 'reason') and review_result.reason:
- error_message += f"Reason: {review_result.reason}\n\n"
+ error_message += f"{review_result.reason}\n\n"
# Add criteria progress information if available
if retry_context and hasattr(retry_context, 'criteria_progress'):
progress = retry_context.criteria_progress
- error_message += f"š **Progress Summary:**\n"
+ error_message += f"š **Details**\n"
if progress.get('met_criteria'):
error_message += f"ā
Met criteria: {', '.join(progress['met_criteria'])}\n"
if progress.get('unmet_criteria'):
@@ -908,19 +791,18 @@ class HandlingTasks:
logger.error(f"=== TASK {task_index or '?'} FAILED AFTER ALL RETRIES: {task_step.objective} ===")
# Create user-facing error message for task failure
- error_message = f"ā Task {task_index or '?'} - '{task_step.objective}' failed after all retries\n\n"
- error_message += f"Objective: {task_step.objective}\n\n"
+ error_message = f"**Task {task_index or '?'}**\n\nā '{task_step.objective}' failed after all retries\n\n"
+ error_message += f"{task_step.objective}\n\n"
# Add specific error details if available
if retry_context and hasattr(retry_context, 'previous_review_result') and retry_context.previous_review_result:
reason = retry_context.previous_review_result.get('reason', '')
if reason and reason != "Task failed after all retries.":
- error_message += f"Reason: {reason}\n\n"
+ error_message += f"{reason}\n\n"
# Add retry information
error_message += f"Retries attempted: {retry_context.retry_count if retry_context else 'Unknown'}\n"
- error_message += f"Status: Task failed permanently\n\n"
- error_message += "Please check the connection and try again, or contact support if the issue persists."
+ error_message += f"Status: Task failed permanently"
# Create workflow message for user
message_data = {
@@ -1170,7 +1052,8 @@ class HandlingTasks:
processingTime=createdAction.get("processingTime"),
timestamp=float(createdAction.get("timestamp", get_utc_timestamp())),
result=createdAction.get("result"),
- resultDocuments=createdAction.get("resultDocuments", [])
+ resultDocuments=createdAction.get("resultDocuments", []),
+ userMessage=createdAction.get("userMessage")
)
except Exception as e:
@@ -1241,20 +1124,6 @@ class HandlingTasks:
# Log action results
logger.info(f"Action completed successfully")
- # Create database log entry for action completion
- if total_actions is not None:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"ā
Task {task_num} - Action {action_num}/{total_actions} completed",
- "type": "success"
- })
- else:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"ā
Task {task_num} - Action {action_num}/? completed",
- "type": "success"
- })
-
if created_documents:
logger.info(f"Output documents ({len(created_documents)}):")
for i, doc in enumerate(created_documents):
@@ -1276,19 +1145,12 @@ class HandlingTasks:
await self.createActionMessage(action, result, workflow, result_label, [], task_step, task_index)
# Create database log entry for action failure
- if total_actions is not None:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"ā Task {task_num} - Action {action_num}/{total_actions} failed: {result.error}",
- "type": "error"
- })
- else:
- self.chatInterface.createWorkflowLog({
- "workflowId": workflow.id,
- "message": f"ā Task {task_num} - Action {action_num}/? failed: {result.error}",
- "type": "error"
- })
-
+ self.chatInterface.createWorkflowLog({
+ "workflowId": workflow.id,
+ "message": f"ā **Task {task_num}**\n\nā **Action {action_num}/{total_actions}** failed: {result.error}",
+ "type": "error"
+ })
+
# Log action summary
logger.info(f"=== TASK {task_num} ACTION {action_num} COMPLETED ===")
@@ -1336,89 +1198,25 @@ class HandlingTasks:
# Create a more meaningful message that includes task context
task_objective = task_step.objective if task_step else 'Unknown task'
-
+
+ # Add comprehensive workflow context
+ current_round = workflow_context.get('currentRound', 0)
+ current_task = workflow_context.get('currentTask', 0)
+ total_tasks = workflow_stats.get('totalTasks', 0)
+ current_action = workflow_context.get('currentAction', 0)
+ total_actions = workflow_stats.get('totalActions', 0)
+
# Build a user-friendly message based on success/failure
if result.success:
- if created_documents and len(created_documents) > 0:
- doc_names = [doc.fileName for doc in created_documents[:3]]
- if len(created_documents) > 3:
- doc_names.append(f"... and {len(created_documents) - 3} more")
-
- # Enhanced message with workflow context
- message_text = f"ā
**Task {task_index or '?'} - Action {action.execMethod}.{action.execAction} Completed**\n\n"
- message_text += f"**Objective:** {task_objective}\n\n"
- message_text += f"**Generated {len(created_documents)} document(s):** {', '.join(doc_names)}\n\n"
- message_text += f"**Result Label:** {result_label}\n"
-
- # Add comprehensive workflow context
- current_round = workflow_context.get('currentRound', 0)
- current_task = workflow_context.get('currentTask', 0)
- total_tasks = workflow_stats.get('totalTasks', 0)
- current_action = workflow_context.get('currentAction', 0)
- total_actions = workflow_stats.get('totalActions', 0)
-
- message_text += f"**Workflow Context:**\n"
- message_text += f"- Round: {current_round}\n"
- if total_tasks > 0:
- message_text += f"- Task: {current_task}/{total_tasks}\n"
- else:
- message_text += f"- Task: {current_task}\n"
- if total_actions > 0:
- message_text += f"- Action: {current_action}/{total_actions}\n"
- else:
- message_text += f"- Action: {current_action}\n"
- message_text += f"- Status: {workflow_stats.get('workflowStatus', 'unknown')}"
- else:
- message_text = f"ā
**Task {task_index or '?'} - Action {action.execMethod}.{action.execAction} Completed**\n\n"
- message_text += f"**Objective:** {task_objective}\n\n"
- message_text += "**Action executed successfully**\n\n"
- message_text += f"**Result Label:** {result_label}\n"
-
- # Add comprehensive workflow context
- current_round = workflow_context.get('currentRound', 0)
- current_task = workflow_context.get('currentTask', 0)
- total_tasks = workflow_stats.get('totalTasks', 0)
- current_action = workflow_context.get('currentAction', 0)
- total_actions = workflow_stats.get('totalActions', 0)
-
- message_text += f"**Workflow Context:**\n"
- message_text += f"- Round: {current_round}\n"
- if total_tasks > 0:
- message_text += f"- Task: {current_task}/{total_tasks}\n"
- else:
- message_text += f"- Task: {current_task}\n"
- if total_actions > 0:
- message_text += f"- Action: {current_action}/{total_actions}\n"
- else:
- message_text += f"- Action: {current_action}\n"
- message_text += f"- Status: {workflow_stats.get('workflowStats', 'unknown')}"
+ message_text = f"**Action {current_action}/{total_actions} ({action.execMethod}.{action.execAction})**\n\n"
+ message_text += f"ā
{task_objective}\n\n"
else:
# ā ļø FAILURE MESSAGE - Show error details to user
error_details = result.error if result.error else "Unknown error occurred"
- message_text = f"ā **Task {task_index or '?'} - Action {action.execMethod}.{action.execAction} Failed**\n\n"
- message_text += f"**Objective:** {task_objective}\n\n"
- message_text += f"**Error:** {error_details}\n\n"
- message_text += f"**Result Label:** {result_label}\n"
-
- # Add comprehensive workflow context
- current_round = workflow_context.get('currentRound', 0)
- current_task = workflow_context.get('currentTask', 0)
- total_tasks = workflow_stats.get('totalTasks', 0)
- current_action = workflow_context.get('currentAction', 0)
- total_actions = workflow_stats.get('totalActions', 0)
-
- message_text += f"**Workflow Context:**\n"
- message_text += f"- Round: {current_round}\n"
- if total_tasks > 0:
- message_text += f"- Task: {current_task}/{total_tasks}\n"
- else:
- message_text += f"- Task: {current_task}\n"
- if total_actions > 0:
- message_text += f"- Action: {current_action}/{total_actions}\n"
- message_text += f"- Action: {current_action}\n"
- message_text += f"- Status: {workflow_stats.get('workflowStatus', 'unknown')}\n\n"
- message_text += "Please check the connection and try again."
-
+ message_text = f"**Action {current_action}/{total_actions} ({action.execMethod}.{action.execAction})**\n\n"
+ message_text += f"ā {task_objective}\n\n"
+ message_text += f"{error_details}\n\n"
+
message_data = {
"workflowId": workflow.id,
"role": "assistant",
@@ -1432,19 +1230,12 @@ class HandlingTasks:
"documentsLabel": result_label,
"documents": created_documents,
# Add workflow context fields - extract from result_label to match document reference
- "roundNumber": workflow_context.get('currentRound', 0),
- "taskNumber": task_index,
- "actionNumber": self._extractActionNumberFromLabel(result_label) if result_label else workflow_context.get('currentAction', 0),
+ "roundNumber": current_round,
+ "taskNumber": current_task,
+ "actionNumber": current_action,
"actionProgress": "success" if result.success else "fail"
}
- # Add user-friendly message if available
- if action.userMessage:
- if result.success:
- message_data["message"] += f"\n\nš¬ {action.userMessage}"
- else:
- message_data["message"] += f"\n\nš¬ Action was intended to: {action.userMessage}"
-
# Add debugging for error messages
if not result.success:
logger.info(f"Creating ERROR message: {message_text}")
diff --git a/modules/chat/handling/promptFactory.py b/modules/chat/handling/promptFactory.py
index 884606e4..4587cce4 100644
--- a/modules/chat/handling/promptFactory.py
+++ b/modules/chat/handling/promptFactory.py
@@ -34,8 +34,8 @@ INSTRUCTIONS:
3. Focus on business outcomes, not technical operations
4. Each task should produce meaningful, usable outputs
5. Ensure proper handover between tasks using result labels
-6. Generate user-friendly messages for each task in the user's language ({user_language})
-7. Detect the language of the user request and include it in languageUserDetected
+6. Detect the language of the user request and include it in languageUserDetected
+7. Generate user-friendly messages for each task in the user's request language
8. Return a JSON object with the exact structure shown below
TASK GROUPING PRINCIPLES:
@@ -63,15 +63,15 @@ TASK PLANNING PRINCIPLES:
- Keep tasks at a meaningful level of abstraction
- Each task should produce results that can be used by subsequent tasks
- Ensure clear dependencies and handovers between tasks
-- Provide clear, actionable user messages in the user's language ({user_language})
+- Provide clear, actionable user messages in the user's request language
- Group related activities to minimize task fragmentation
- Only create multiple tasks when dealing with truly different, independent objectives
REQUIRED JSON STRUCTURE:
{{
"overview": "Brief description of the overall plan",
- "userMessage": "User-friendly message explaining the task plan in {user_language}",
"languageUserDetected": "en", // Language code detected from user request (en, de, fr, it, es, etc.)
+ "userMessage": "User-friendly message explaining the task plan in user's request language",
"tasks": [
{{
"id": "task_1",
@@ -79,7 +79,7 @@ REQUIRED JSON STRUCTURE:
"dependencies": ["task_0"], // IDs of tasks that must complete first
"success_criteria": ["criteria1", "criteria2"],
"estimated_complexity": "low|medium|high",
- "userMessage": "User-friendly message explaining what this task will accomplish in {user_language}"
+ "userMessage": "User-friendly message explaining what this task will accomplish in user's request language"
}}
]
}}
diff --git a/modules/chat/serviceCenter.py b/modules/chat/serviceCenter.py
index 9a37030c..13545001 100644
--- a/modules/chat/serviceCenter.py
+++ b/modules/chat/serviceCenter.py
@@ -350,16 +350,19 @@ class ServiceCenter:
doc_exchange = None
if message.documents:
if message.actionId and message.documentsLabel:
- # Use new document label format
+ # Validate that we use the same label as in the message
+ validated_label = self._validateDocumentLabelConsistency(message)
+
+ # Use the message's actual documentsLabel
doc_refs = []
for doc in message.documents:
doc_ref = self.getDocumentReferenceFromChatDocument(doc, message)
doc_refs.append(doc_ref)
- doc_exchange = DocumentExchange(
- documentsLabel=message.documentsLabel,
+ doc_exchange = DocumentExchange(
+ documentsLabel=validated_label,
documents=doc_refs
- )
+ )
else:
# Generate new labels for documents without explicit labels
doc_refs = []
@@ -444,8 +447,21 @@ class ServiceCenter:
if document_list["chat"]:
context += "CURRENT ROUND DOCUMENTS:\n"
for exchange in document_list["chat"]:
- # Generate docList reference for the exchange (using message ID)
- doc_list_ref = f"docList:{exchange.documentsLabel}"
+ # Generate docList reference for the exchange (using message ID and label)
+ # Find the message that corresponds to this exchange
+ message_id = None
+ for message in self.workflow.messages:
+ if hasattr(message, 'documentsLabel') and message.documentsLabel == exchange.documentsLabel:
+ message_id = message.id
+ break
+
+ if message_id:
+ doc_list_ref = f"docList:{message_id}:{exchange.documentsLabel}"
+ else:
+ # Fallback to label-only format if message ID not found
+ doc_list_ref = f"docList:{exchange.documentsLabel}"
+
+ logger.debug(f"Using document label for action planning: {exchange.documentsLabel} (message_id: {message_id})")
context += f"- {doc_list_ref} contains:\n"
# Generate docItem references for each document in the list
for doc_ref in exchange.documents:
@@ -460,8 +476,21 @@ class ServiceCenter:
if document_list["history"]:
context += "WORKFLOW HISTORY DOCUMENTS:\n"
for exchange in document_list["history"]:
- # Generate docList reference for the exchange (using message ID)
- doc_list_ref = f"docList:{exchange.documentsLabel}"
+ # Generate docList reference for the exchange (using message ID and label)
+ # Find the message that corresponds to this exchange
+ message_id = None
+ for message in self.workflow.messages:
+ if hasattr(message, 'documentsLabel') and message.documentsLabel == exchange.documentsLabel:
+ message_id = message.id
+ break
+
+ if message_id:
+ doc_list_ref = f"docList:{message_id}:{exchange.documentsLabel}"
+ else:
+ # Fallback to label-only format if message ID not found
+ doc_list_ref = f"docList:{exchange.documentsLabel}"
+
+ logger.debug(f"Using history document label for action planning: {exchange.documentsLabel} (message_id: {message_id})")
context += f"- {doc_list_ref} contains:\n"
# Generate docItem references for each document in the list
for doc_ref in exchange.documents:
@@ -481,6 +510,16 @@ class ServiceCenter:
logger.error(f"Error generating enhanced document context: {str(e)}")
return "NO DOCUMENTS AVAILABLE - Error generating document context."
+ def _validateDocumentLabelConsistency(self, message) -> str:
+ """Validate that the document label used for references matches the message's actual label"""
+ if not hasattr(message, 'documentsLabel') or not message.documentsLabel:
+ logger.debug(f"Message {message.id} has no documentsLabel, returning None")
+ return None
+
+ # Simply return the message's actual documentsLabel - no correction, just validation
+ logger.debug(f"Using message's documentsLabel for references: '{message.documentsLabel}'")
+ return message.documentsLabel
+
def _extractDocumentInfoFromReference(self, doc_ref: str) -> Dict[str, str]:
"""Extract document information from reference string"""
try:
@@ -569,19 +608,56 @@ class ServiceCenter:
if message.documents:
for doc in message.documents:
if doc.id == doc_id:
+ doc_name = getattr(doc, 'fileName', 'unknown')
+ logger.debug(f"Found docItem reference {doc_ref}: {doc_name}")
all_documents.append(doc)
break
elif doc_ref.startswith("docList:"):
- # docList::