fixed workflow run with chatlog

This commit is contained in:
ValueOn AG 2025-12-29 23:54:27 +01:00
parent b205a2c5ad
commit a958defd42
4 changed files with 87 additions and 36 deletions

View file

@ -437,19 +437,26 @@ class StructureFiller:
if isinstance(jsonContent, dict) and jsonContent.get("type") == "image":
elements.append(jsonContent)
logger.debug("AI returned proper JSON image structure")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
elif isinstance(jsonContent, list) and len(jsonContent) > 0:
# Check if first element is an image
if isinstance(jsonContent[0], dict) and jsonContent[0].get("type") == "image":
elements.extend(jsonContent)
logger.debug("AI returned proper JSON image structure in list")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
else:
base64Data = "" # Continue with normal processing
except (json.JSONDecodeError, ValueError, AttributeError):
# Not JSON, treat as base64 string or data URI
pass
base64Data = "" # Will be processed below
# Already base64 string or data URI
if aiResponse.content.startswith("data:image/"):
# Process base64 if not already handled above
if base64Data is None:
# Already processed as JSON, skip base64 processing
pass
elif aiResponse.content.startswith("data:image/"):
# Extract base64 from data URI
base64Data = aiResponse.content.split(",", 1)[1]
else:
@ -463,8 +470,11 @@ class StructureFiller:
else:
base64Data = ""
# Always create proper JSON structure for images
if base64Data:
# Always create proper JSON structure for images (if not already processed)
if base64Data is None:
# Image already processed as JSON, skip
pass
elif base64Data:
elements.append({
"type": "image",
"content": {
@ -634,17 +644,25 @@ class StructureFiller:
if isinstance(jsonContent, dict) and jsonContent.get("type") == "image":
elements.append(jsonContent)
logger.debug("AI returned proper JSON image structure")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
elif isinstance(jsonContent, list) and len(jsonContent) > 0:
if isinstance(jsonContent[0], dict) and jsonContent[0].get("type") == "image":
elements.extend(jsonContent)
logger.debug("AI returned proper JSON image structure in list")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
else:
base64Data = "" # Continue with normal processing
except (json.JSONDecodeError, ValueError, AttributeError):
pass
base64Data = "" # Will be processed below
# Already base64 string or data URI
if aiResponse.content.startswith("data:image/"):
# Process base64 if not already handled above
if base64Data is None:
# Already processed as JSON, skip base64 processing
pass
elif aiResponse.content.startswith("data:image/"):
# Extract base64 from data URI
base64Data = aiResponse.content.split(",", 1)[1]
else:
content_stripped = aiResponse.content.strip()
@ -655,8 +673,11 @@ class StructureFiller:
else:
base64Data = ""
# Always create proper JSON structure for images
if base64Data:
# Always create proper JSON structure for images (if not already processed)
if base64Data is None:
# Image already processed as JSON, skip
pass
elif base64Data:
elements.append({
"type": "image",
"content": {
@ -853,17 +874,25 @@ class StructureFiller:
if isinstance(jsonContent, dict) and jsonContent.get("type") == "image":
elements.append(jsonContent)
logger.debug("AI returned proper JSON image structure")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
elif isinstance(jsonContent, list) and len(jsonContent) > 0:
if isinstance(jsonContent[0], dict) and jsonContent[0].get("type") == "image":
elements.extend(jsonContent)
logger.debug("AI returned proper JSON image structure in list")
continue
# Skip remaining image processing, but continue with progress updates
base64Data = None # Signal that image was already processed
else:
base64Data = "" # Continue with normal processing
except (json.JSONDecodeError, ValueError, AttributeError):
pass
base64Data = "" # Will be processed below
# Already base64 string or data URI
if aiResponse.content.startswith("data:image/"):
# Process base64 if not already handled above
if base64Data is None:
# Already processed as JSON, skip base64 processing
pass
elif aiResponse.content.startswith("data:image/"):
# Extract base64 from data URI
base64Data = aiResponse.content.split(",", 1)[1]
else:
content_stripped = aiResponse.content.strip()
@ -874,8 +903,11 @@ class StructureFiller:
else:
base64Data = ""
# Always create proper JSON structure for images
if base64Data:
# Always create proper JSON structure for images (if not already processed)
if base64Data is None:
# Image already processed as JSON, skip
pass
elif base64Data:
elements.append({
"type": "image",
"content": {

View file

@ -139,6 +139,10 @@ class ProgressLogger:
logger.warning(f"Cannot log progress: no workflow available")
return None
# Validate parentOperationId exists in activeOperations (for debugging)
if parentOperationId and parentOperationId not in self.activeOperations:
logger.debug(f"WARNING: Parent operation '{parentOperationId}' not found in activeOperations when creating log for '{operationId}'. Available operations: {list(self.activeOperations.keys())}. Child operation may appear at root level.")
# parentId in ChatLog should be the operationId of the parent operation, not the log entry ID
logData = {
"workflowId": workflow.id,

View file

@ -38,6 +38,11 @@ async def process(self, parameters: Dict[str, Any]) -> ActionResult:
# Start progress tracking
parentOperationId = parameters.get('parentOperationId')
if not parentOperationId:
logger.warning(f"ai.process: No parentOperationId provided in parameters. Operation '{operationId}' will appear at root level. Available parameters: {list(parameters.keys())}")
else:
logger.debug(f"ai.process: Using parentOperationId '{parentOperationId}' for operation '{operationId}'")
self.services.chat.progressLogStart(
operationId,
"Generate",

View file

@ -188,9 +188,19 @@ class MethodBase:
return wrapper
def _validateParameters(self, parameters: Dict[str, Any], paramDefs: Dict[str, WorkflowActionParameter]) -> Dict[str, Any]:
"""Validate parameters against definitions"""
"""Validate parameters against definitions
IMPORTANT: System parameters (like parentOperationId, expectedDocumentFormats) are preserved
even if they're not in the parameter definitions, as they're used internally by the framework.
"""
validated = {}
# System parameters that should always be preserved, even if not in paramDefs
systemParams = ['parentOperationId', 'expectedDocumentFormats']
for sysParam in systemParams:
if sysParam in parameters:
validated[sysParam] = parameters[sysParam]
for paramName, paramDef in paramDefs.items():
value = parameters.get(paramName)