Merge remote-tracking branch 'origin/int' into dev-ida

:

sage

"messeage"

t
exit
close
git commit
-m "message"
git add .
exit


This commit is contained in:
Ida Dittrich 2026-01-05 06:40:09 +01:00
parent f78547e51b
commit 2672266eca

View file

@ -54,8 +54,9 @@ async def process(self, parameters: Dict[str, Any]) -> ActionResult:
logger.error(f"Invalid documentList type: {type(documentListParam)}") logger.error(f"Invalid documentList type: {type(documentListParam)}")
documentList = DocumentReferenceList(references=[]) documentList = DocumentReferenceList(references=[])
# Optional: if omitted, formats determined from prompt. Default "txt" is validation fallback only. resultType = parameters.get("resultType", "txt")
resultType = parameters.get("resultType") simpleMode = parameters.get("simpleMode", False)
if not aiPrompt: if not aiPrompt:
logger.error(f"aiPrompt is missing or empty. Parameters: {parameters}") logger.error(f"aiPrompt is missing or empty. Parameters: {parameters}")
@ -63,18 +64,11 @@ async def process(self, parameters: Dict[str, Any]) -> ActionResult:
error="AI prompt is required" error="AI prompt is required"
) )
# Handle optional resultType: if None, formats determined from prompt by AI # Determine output extension and default MIME type without duplicating service logic
if resultType: normalized_result_type = (str(resultType).strip().lstrip('.').lower() or "txt")
normalized_result_type = (str(resultType).strip().lstrip('.').lower() or "txt") output_extension = f".{normalized_result_type}"
output_extension = f".{normalized_result_type}" output_mime_type = "application/octet-stream" # Prefer service-provided mimeType when available
output_format = output_extension.replace('.', '') or 'txt' logger.info(f"Using result type: {resultType} -> {output_extension}, simpleMode: {simpleMode}")
logger.info(f"Using result type: {resultType} -> {output_extension}")
else:
# No format specified - AI will determine formats from prompt
normalized_result_type = None
output_extension = None
output_format = None
logger.debug("resultType not provided - formats will be determined from prompt by AI")
output_mime_type = "application/octet-stream" # Prefer service-provided mimeType when available output_mime_type = "application/octet-stream" # Prefer service-provided mimeType when available
@ -96,38 +90,99 @@ async def process(self, parameters: Dict[str, Any]) -> ActionResult:
# Update progress - preparing AI call # Update progress - preparing AI call
self.services.chat.progressLogUpdate(operationId, 0.4, "Preparing AI call") self.services.chat.progressLogUpdate(operationId, 0.4, "Preparing AI call")
# Detect image generation from resultType (if provided) # Build options
imageFormats = ["png", "jpg", "jpeg", "gif", "webp"] output_format = output_extension.replace('.', '') or 'txt'
isImageGeneration = normalized_result_type in imageFormats if normalized_result_type else False
# Build options with correct operationType # Simple mode: fast path without document generation pipeline
from modules.datamodels.datamodelAi import OperationTypeEnum if simpleMode:
# resultFormat in options can be None - formats will be determined by AI if not provided # Update progress - calling AI (simple mode)
options = AiCallOptions( self.services.chat.progressLogUpdate(operationId, 0.6, "Calling AI (simple mode)")
resultFormat=output_format, # Can be None - formats determined by AI
operationType=OperationTypeEnum.IMAGE_GENERATE if isImageGeneration else OperationTypeEnum.DATA_GENERATE
)
# Get generationIntent from parameters (required for DATA_GENERATE) # Extract context from documents if provided
# Default to "document" if not provided (most common use case) context_text = ""
# For code generation, use ai.generateCode action or explicitly pass generationIntent="code" if documentList and len(documentList.references) > 0:
generationIntent = parameters.get("generationIntent", "document") try:
# Get documents from workflow
documents = self.services.chat.getChatDocumentsFromDocumentList(documentList)
context_parts = []
for doc in documents:
if hasattr(doc, 'fileId') and doc.fileId:
# Get file data
fileData = self.services.interfaceDbComponent.getFileData(doc.fileId)
if fileData:
if isinstance(fileData, bytes):
doc_text = fileData.decode('utf-8', errors='ignore')
else:
doc_text = str(fileData)
context_parts.append(doc_text)
if context_parts:
context_text = "\n\n".join(context_parts)
except Exception as e:
logger.warning(f"Error extracting context from documents in simple mode: {e}")
# Update progress - calling AI # Use direct AI call without document generation pipeline
self.services.chat.progressLogUpdate(operationId, 0.6, "Calling AI") from modules.datamodels.datamodelAi import AiCallRequest, OperationTypeEnum, ProcessingModeEnum
request = AiCallRequest(
prompt=aiPrompt,
context=context_text if context_text else None,
options=AiCallOptions(
resultFormat=output_format,
operationType=OperationTypeEnum.DATA_ANALYSE,
processingMode=ProcessingModeEnum.BASIC
)
)
# Use unified callAiContent method with BOTH documentList and contentParts aiResponse_obj = await self.services.ai.callAi(request)
# Extraction is handled by AI service - no extraction here
# outputFormat: Optional - if None, formats determined from prompt by AI # Convert AiCallResponse to AiResponse format
aiResponse = await self.services.ai.callAiContent( from modules.datamodels.datamodelWorkflow import AiResponse, AiResponseMetadata
prompt=aiPrompt, aiResponse = AiResponse(
options=options, content=aiResponse_obj.content,
documentList=documentList, # Pass documentList - AI service handles extraction metadata=AiResponseMetadata(
contentParts=contentParts, # Pass contentParts if provided (or None) additionalData={
outputFormat=output_format, # Can be None - AI determines from prompt "modelName": aiResponse_obj.modelName,
parentOperationId=operationId, "priceUsd": aiResponse_obj.priceUsd,
generationIntent=generationIntent # REQUIRED for DATA_GENERATE "processingTime": aiResponse_obj.processingTime,
) "bytesSent": aiResponse_obj.bytesSent,
"bytesReceived": aiResponse_obj.bytesReceived,
"errorCount": aiResponse_obj.errorCount
}
),
documents=[] # Simple mode doesn't generate documents
)
else:
# Full mode: use unified callAiContent method
options = AiCallOptions(
resultFormat=output_format
)
# Update progress - calling AI
self.services.chat.progressLogUpdate(operationId, 0.6, "Calling AI")
# Use unified callAiContent method
# If contentParts provided (pre-extracted), use them directly
# Otherwise, pass documentList and let callAiContent handle Phases 5A-5E internally
# Note: ContentExtracted documents (from context.extractContent) are now handled
# automatically in _extractAndPrepareContent() (Phase 5B)
if contentParts:
# Pre-extracted ContentParts - use them directly
aiResponse = await self.services.ai.callAiContent(
prompt=aiPrompt,
options=options,
contentParts=contentParts, # Pre-extracted ContentParts
outputFormat=output_format,
parentOperationId=operationId
)
else:
# Pass documentList - callAiContent handles Phases 5A-5E internally
# This includes automatic detection of ContentExtracted documents
aiResponse = await self.services.ai.callAiContent(
prompt=aiPrompt,
options=options,
documentList=documentList, # callAiContent macht Phasen 5A-5E
outputFormat=output_format,
parentOperationId=operationId
)
# Update progress - processing result # Update progress - processing result
self.services.chat.progressLogUpdate(operationId, 0.8, "Processing result") self.services.chat.progressLogUpdate(operationId, 0.8, "Processing result")