fixed ui harmonization

This commit is contained in:
ValueOn AG 2025-11-02 15:36:02 +01:00
parent 5c006da27d
commit fa91016e16
2 changed files with 62 additions and 17 deletions

View file

@ -197,6 +197,7 @@ Respond with ONLY a JSON object in this exact format:
iteration = 0
allSections = [] # Accumulate all sections across iterations
lastRawResponse = None # Store last raw JSON response for continuation
documentMetadata = None # Store document metadata (title, filename) from first iteration
while iteration < maxIterations:
iteration += 1
@ -276,7 +277,11 @@ Respond with ONLY a JSON object in this exact format:
pass # Flag detected, will stop in _shouldContinueGeneration
# Extract sections from response (handles both valid and broken JSON)
extractedSections, wasJsonComplete = self._extractSectionsFromResponse(result, iteration, debugPrefix)
extractedSections, wasJsonComplete, parsedResult = self._extractSectionsFromResponse(result, iteration, debugPrefix)
# Extract document metadata from first iteration if available
if iteration == 1 and parsedResult and not documentMetadata:
documentMetadata = self._extractDocumentMetadata(parsedResult)
# Update progress after parsing
if operationId:
@ -313,7 +318,7 @@ Respond with ONLY a JSON object in this exact format:
logger.warning(f"AI call stopped after maximum iterations ({maxIterations})")
# Build final result from accumulated sections
final_result = self._buildFinalResultFromSections(allSections)
final_result = self._buildFinalResultFromSections(allSections, documentMetadata)
# Write final result to debug file
self.services.utils.writeDebugFile(final_result, f"{debugPrefix}_final_result")
@ -325,12 +330,12 @@ Respond with ONLY a JSON object in this exact format:
result: str,
iteration: int,
debugPrefix: str
) -> Tuple[List[Dict[str, Any]], bool]:
) -> Tuple[List[Dict[str, Any]], bool, Optional[Dict[str, Any]]]:
"""
Extract sections from AI response, handling both valid and broken JSON.
Uses repair mechanism for broken JSON.
Checks for "complete_response": true flag to determine completion.
Returns (sections, wasJsonComplete)
Returns (sections, wasJsonComplete, parsedResult)
"""
# First, try to parse as valid JSON
try:
@ -345,18 +350,18 @@ Respond with ONLY a JSON object in this exact format:
# If AI marked as complete, always return as complete
if isComplete:
return sections, True
return sections, True, parsed_result
# If in continuation mode (iteration > 1), continuation responses are expected to be fragments
# A fragment with 0 extractable sections means JSON is incomplete - need another iteration
if len(sections) == 0 and iteration > 1:
return sections, False # Mark as incomplete so loop continues
return sections, False, parsed_result # Mark as incomplete so loop continues
# First iteration with 0 sections means empty response - stop
if len(sections) == 0:
return sections, True # Complete but empty
return sections, True, parsed_result # Complete but empty
return sections, True # JSON was complete with sections
return sections, True, parsed_result # JSON was complete with sections
except json.JSONDecodeError as e:
# Broken JSON - try repair mechanism (normal in iterative generation)
@ -368,15 +373,15 @@ Respond with ONLY a JSON object in this exact format:
if repaired_json:
# Extract sections from repaired JSON
sections = extractSectionsFromDocument(repaired_json)
return sections, False # JSON was broken but repaired
return sections, False, repaired_json # JSON was broken but repaired
else:
# Repair failed - log error
logger.error(f"Iteration {iteration}: All repair strategies failed")
return [], False
return [], False, None
except Exception as e:
logger.error(f"Iteration {iteration}: Unexpected error during parsing: {str(e)}")
return [], False
return [], False, None
def _shouldContinueGeneration(
self,
@ -414,22 +419,58 @@ Respond with ONLY a JSON object in this exact format:
# JSON was incomplete/broken - continue
return True
def _extractDocumentMetadata(
self,
parsedResult: Dict[str, Any]
) -> Optional[Dict[str, Any]]:
"""
Extract document metadata (title, filename) from parsed AI response.
Returns dict with 'title' and 'filename' keys if found, None otherwise.
"""
if not isinstance(parsedResult, dict):
return None
# Try to get from documents array (preferred structure)
if "documents" in parsedResult and isinstance(parsedResult["documents"], list) and len(parsedResult["documents"]) > 0:
firstDoc = parsedResult["documents"][0]
if isinstance(firstDoc, dict):
title = firstDoc.get("title")
filename = firstDoc.get("filename")
if title or filename:
return {
"title": title,
"filename": filename
}
return None
def _buildFinalResultFromSections(
self,
allSections: List[Dict[str, Any]]
allSections: List[Dict[str, Any]],
documentMetadata: Optional[Dict[str, Any]] = None
) -> str:
"""
Build final JSON result from accumulated sections.
Uses AI-provided metadata (title, filename) if available.
"""
if not allSections:
return ""
# Extract metadata from AI response if available
title = "Generated Document"
filename = "document.json"
if documentMetadata:
if documentMetadata.get("title"):
title = documentMetadata["title"]
if documentMetadata.get("filename"):
filename = documentMetadata["filename"]
# Build documents structure
# Assuming single document for now
documents = [{
"id": "doc_1",
"title": "Generated Document", # This should come from prompt
"filename": "document.json",
"title": title,
"filename": filename,
"sections": allSections
}]

View file

@ -74,6 +74,8 @@ async def buildGenerationPrompt(
continuationText = "\n".join(continuationGuidance) if continuationGuidance else "Continue from where it stopped."
# PROMPT FOR CONTINUATION
generationPrompt = f"""User request: "{userPrompt}"
The user already received part of the response. Continue generating the remaining content.
@ -93,7 +95,7 @@ Instructions:
- Arrays must contain ONLY JSON values; do not include comments or ellipses.
- Use ONLY the element structures shown in the template.
- Continue from where it stopped add NEW items only; do not repeat existing items.
- Generate remaining content to complete the user request.
- Generate remaining content to complete the user request. Do NOT just give an instruction or comments. Deliver the complete response.
- Fill with actual content (no placeholders or instructional text such as "Add more...").
- IMPORTANT: Ensure "filename" in each document has meaningful name with appropriate extension matching the content.
- When the request is fully satisfied, add "complete_response": true at root level.
@ -104,7 +106,9 @@ IMPORTANT: Before responding, analyse the remaining data to fully satisfy user r
Continue generating:
"""
else:
# FIRST CALL - initial generation
# PROMPT FOR FIRST CALL
generationPrompt = f"""User request: "{userPrompt}"
Generate a VALID JSON response for the user request. The template below shows ONLY the structure pattern - it is NOT existing content.
@ -116,7 +120,7 @@ Instructions:
- Start with {{"metadata": ...}} return COMPLETE, STRICT JSON.
- Return ONLY valid JSON (strict). No comments. No trailing commas. Use double quotes.
- Do NOT reuse example section IDs; create your own.
- Generate complete content based on the user request.
- Generate complete content based on the user request. Do NOT just give an instruction or comments. Deliver the complete response.
- IMPORTANT: Set a meaningful "filename" in each document with appropriate file extension (e.g., "prime_numbers.txt", "report.docx", "data.json"). The filename should reflect the content and task objective.
- When the request is fully satisfied, add "complete_response": true at root level.
- Output JSON only; no markdown fences or extra text.