ready for handover test
This commit is contained in:
parent
8d8b800859
commit
55fed49a28
3 changed files with 163 additions and 3 deletions
|
|
@ -728,6 +728,10 @@ NOTE: Respond with ONLY the JSON object. Do not include any explanatory text."""
|
|||
action.setSuccess()
|
||||
action.result = result.data.get("result", "")
|
||||
action.execResultLabel = result.data.get("resultLabel", "")
|
||||
|
||||
# Create and store message in workflow for successful action
|
||||
await self._createActionMessage(action, result, workflow)
|
||||
|
||||
else:
|
||||
action.setError(result.error or "Action execution failed")
|
||||
|
||||
|
|
@ -749,6 +753,143 @@ NOTE: Respond with ONLY the JSON object. Do not include any explanatory text."""
|
|||
"action": action
|
||||
}
|
||||
|
||||
async def _createActionMessage(self, action: TaskAction, result: Any, workflow: ChatWorkflow) -> None:
|
||||
"""Create and store a message for the action result in the workflow"""
|
||||
try:
|
||||
# Get result data
|
||||
result_data = result.data if hasattr(result, 'data') else {}
|
||||
result_label = result_data.get("resultLabel", "")
|
||||
documents_data = result_data.get("documents", [])
|
||||
|
||||
# Create message data
|
||||
message_data = {
|
||||
"workflowId": workflow.id,
|
||||
"role": "assistant",
|
||||
"message": f"Executed {action.execMethod}.{action.execAction} successfully",
|
||||
"status": "step",
|
||||
"sequenceNr": len(workflow.messages) + 1,
|
||||
"publishedAt": datetime.now(UTC).isoformat(),
|
||||
"actionId": action.id,
|
||||
"actionMethod": action.execMethod,
|
||||
"actionName": action.execAction,
|
||||
"documentsLabel": result_label, # Use resultLabel as documentsLabel
|
||||
"documents": []
|
||||
}
|
||||
|
||||
# Process documents if any
|
||||
if documents_data:
|
||||
processed_documents = []
|
||||
for doc_data in documents_data:
|
||||
try:
|
||||
# Extract document information
|
||||
document_name = doc_data.get("documentName", f"{action.execMethod}_{action.execAction}_{datetime.now(UTC).strftime('%Y%m%d_%H%M%S')}")
|
||||
document_data = doc_data.get("documentData", {})
|
||||
|
||||
# Determine file extension and MIME type
|
||||
file_extension = self._getFileExtension(document_name)
|
||||
mime_type = self._getMimeType(file_extension)
|
||||
|
||||
# Convert document data to string content
|
||||
content = self._convertDocumentDataToString(document_data, file_extension)
|
||||
|
||||
# Create file in database
|
||||
file_id = self.service.createFile(
|
||||
fileName=document_name,
|
||||
mimeType=mime_type,
|
||||
content=content,
|
||||
base64encoded=False
|
||||
)
|
||||
|
||||
# Create ChatDocument object
|
||||
document = self.service.createDocument(
|
||||
fileName=document_name,
|
||||
mimeType=mime_type,
|
||||
content=content,
|
||||
base64encoded=False
|
||||
)
|
||||
|
||||
if document:
|
||||
processed_documents.append(document)
|
||||
logger.info(f"Created document: {document_name} with file ID: {file_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing document {doc_data.get('documentName', 'unknown')}: {str(e)}")
|
||||
continue
|
||||
|
||||
# Update message with processed documents
|
||||
message_data["documents"] = processed_documents
|
||||
|
||||
# Create message using interface
|
||||
message = self.chatInterface.createWorkflowMessage(message_data)
|
||||
if message:
|
||||
workflow.messages.append(message)
|
||||
logger.info(f"Created action message for {action.execMethod}.{action.execAction} with {len(message_data.get('documents', []))} documents")
|
||||
else:
|
||||
logger.error(f"Failed to create workflow message for action {action.execMethod}.{action.execAction}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating action message: {str(e)}")
|
||||
|
||||
def _getFileExtension(self, filename: str) -> str:
|
||||
"""Extract file extension from filename"""
|
||||
if '.' in filename:
|
||||
return filename.split('.')[-1].lower()
|
||||
return "txt" # Default to text
|
||||
|
||||
def _getMimeType(self, extension: str) -> str:
|
||||
"""Get MIME type based on file extension"""
|
||||
mime_types = {
|
||||
'txt': 'text/plain',
|
||||
'json': 'application/json',
|
||||
'xml': 'application/xml',
|
||||
'csv': 'text/csv',
|
||||
'html': 'text/html',
|
||||
'md': 'text/markdown',
|
||||
'py': 'text/x-python',
|
||||
'js': 'application/javascript',
|
||||
'css': 'text/css',
|
||||
'pdf': 'application/pdf',
|
||||
'doc': 'application/msword',
|
||||
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'xls': 'application/vnd.ms-excel',
|
||||
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'ppt': 'application/vnd.ms-powerpoint',
|
||||
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
||||
}
|
||||
return mime_types.get(extension, 'application/octet-stream')
|
||||
|
||||
def _convertDocumentDataToString(self, document_data: Dict[str, Any], file_extension: str) -> str:
|
||||
"""Convert document data to string content based on file type"""
|
||||
try:
|
||||
if file_extension == 'json':
|
||||
return json.dumps(document_data, indent=2, ensure_ascii=False)
|
||||
elif file_extension in ['txt', 'md', 'html', 'css', 'js', 'py']:
|
||||
# For text files, try to extract text content
|
||||
if isinstance(document_data, dict):
|
||||
# Look for common text content fields
|
||||
text_fields = ['content', 'text', 'data', 'result', 'summary']
|
||||
for field in text_fields:
|
||||
if field in document_data:
|
||||
content = document_data[field]
|
||||
if isinstance(content, str):
|
||||
return content
|
||||
elif isinstance(content, (dict, list)):
|
||||
return json.dumps(content, indent=2, ensure_ascii=False)
|
||||
|
||||
# If no text field found, convert entire dict to JSON
|
||||
return json.dumps(document_data, indent=2, ensure_ascii=False)
|
||||
elif isinstance(document_data, str):
|
||||
return document_data
|
||||
else:
|
||||
return str(document_data)
|
||||
else:
|
||||
# For other file types, convert to JSON
|
||||
return json.dumps(document_data, indent=2, ensure_ascii=False)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting document data to string: {str(e)}")
|
||||
return str(document_data)
|
||||
|
||||
async def _performTaskReview(self, review_context: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Perform AI-based task review"""
|
||||
try:
|
||||
|
|
@ -778,11 +919,23 @@ NOTE: Respond with ONLY the JSON object. Do not include any explanatory text."""
|
|||
}
|
||||
|
||||
def _getPreviousResultsFromActions(self, task_actions: List[TaskAction]) -> List[str]:
|
||||
"""Get list of previous results from completed actions"""
|
||||
"""Get list of previous results from completed actions and workflow messages"""
|
||||
results = []
|
||||
|
||||
# Get results from action objects
|
||||
for action in task_actions:
|
||||
if action.execResultLabel and action.isSuccessful():
|
||||
results.append(action.execResultLabel)
|
||||
|
||||
# Get results from workflow messages (for actions that have been executed)
|
||||
if hasattr(self, 'workflow') and self.workflow and self.workflow.messages:
|
||||
for message in self.workflow.messages:
|
||||
if (message.role == 'assistant' and
|
||||
message.status == 'step' and
|
||||
message.documentsLabel and
|
||||
message.documentsLabel not in results):
|
||||
results.append(message.documentsLabel)
|
||||
|
||||
return results
|
||||
|
||||
def _calculateTaskQualityMetrics(self, task_step: Dict[str, Any], action_results: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ class ServiceContainer:
|
|||
if message.documentsLabel.startswith("mdoc:"):
|
||||
return message.documentsLabel
|
||||
|
||||
# Otherwise construct the reference
|
||||
# Otherwise construct the reference using the action ID and documents label
|
||||
return f"mdoc:{message.actionId}:{message.documentsLabel}"
|
||||
|
||||
def getChatDocumentsFromDocumentReference(self, documentReference: str) -> List[ChatDocument]:
|
||||
|
|
@ -256,6 +256,14 @@ class ServiceContainer:
|
|||
message.documentsLabel == documentReference and # Compare full reference
|
||||
message.documents):
|
||||
return message.documents
|
||||
|
||||
# If not found by actionId, try to find by documentsLabel only
|
||||
# This handles cases where the reference format might be different
|
||||
for message in self.workflow.messages:
|
||||
if (message.documentsLabel and
|
||||
message.documentsLabel == documentReference and
|
||||
message.documents):
|
||||
return message.documents
|
||||
|
||||
return []
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ LOGIC
|
|||
|
||||
TODO methods:
|
||||
- reultLabel not to generate in the function, but to be set according to the action definition
|
||||
- align documentList objects: chat document to have prefix "cdoc", message document list to have prefix "mdoc" (globally: instead of document and documentList)
|
||||
- after action execution to store the documents in db and in a message object
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue