fixed ui harmonization
This commit is contained in:
parent
5c006da27d
commit
fa91016e16
2 changed files with 62 additions and 17 deletions
|
|
@ -197,6 +197,7 @@ Respond with ONLY a JSON object in this exact format:
|
||||||
iteration = 0
|
iteration = 0
|
||||||
allSections = [] # Accumulate all sections across iterations
|
allSections = [] # Accumulate all sections across iterations
|
||||||
lastRawResponse = None # Store last raw JSON response for continuation
|
lastRawResponse = None # Store last raw JSON response for continuation
|
||||||
|
documentMetadata = None # Store document metadata (title, filename) from first iteration
|
||||||
|
|
||||||
while iteration < maxIterations:
|
while iteration < maxIterations:
|
||||||
iteration += 1
|
iteration += 1
|
||||||
|
|
@ -276,7 +277,11 @@ Respond with ONLY a JSON object in this exact format:
|
||||||
pass # Flag detected, will stop in _shouldContinueGeneration
|
pass # Flag detected, will stop in _shouldContinueGeneration
|
||||||
|
|
||||||
# Extract sections from response (handles both valid and broken JSON)
|
# 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
|
# Update progress after parsing
|
||||||
if operationId:
|
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})")
|
logger.warning(f"AI call stopped after maximum iterations ({maxIterations})")
|
||||||
|
|
||||||
# Build final result from accumulated sections
|
# Build final result from accumulated sections
|
||||||
final_result = self._buildFinalResultFromSections(allSections)
|
final_result = self._buildFinalResultFromSections(allSections, documentMetadata)
|
||||||
|
|
||||||
# Write final result to debug file
|
# Write final result to debug file
|
||||||
self.services.utils.writeDebugFile(final_result, f"{debugPrefix}_final_result")
|
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,
|
result: str,
|
||||||
iteration: int,
|
iteration: int,
|
||||||
debugPrefix: str
|
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.
|
Extract sections from AI response, handling both valid and broken JSON.
|
||||||
Uses repair mechanism for broken JSON.
|
Uses repair mechanism for broken JSON.
|
||||||
Checks for "complete_response": true flag to determine completion.
|
Checks for "complete_response": true flag to determine completion.
|
||||||
Returns (sections, wasJsonComplete)
|
Returns (sections, wasJsonComplete, parsedResult)
|
||||||
"""
|
"""
|
||||||
# First, try to parse as valid JSON
|
# First, try to parse as valid JSON
|
||||||
try:
|
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 AI marked as complete, always return as complete
|
||||||
if isComplete:
|
if isComplete:
|
||||||
return sections, True
|
return sections, True, parsed_result
|
||||||
|
|
||||||
# If in continuation mode (iteration > 1), continuation responses are expected to be fragments
|
# 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
|
# A fragment with 0 extractable sections means JSON is incomplete - need another iteration
|
||||||
if len(sections) == 0 and iteration > 1:
|
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
|
# First iteration with 0 sections means empty response - stop
|
||||||
if len(sections) == 0:
|
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:
|
except json.JSONDecodeError as e:
|
||||||
# Broken JSON - try repair mechanism (normal in iterative generation)
|
# 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:
|
if repaired_json:
|
||||||
# Extract sections from repaired JSON
|
# Extract sections from repaired JSON
|
||||||
sections = extractSectionsFromDocument(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:
|
else:
|
||||||
# Repair failed - log error
|
# Repair failed - log error
|
||||||
logger.error(f"Iteration {iteration}: All repair strategies failed")
|
logger.error(f"Iteration {iteration}: All repair strategies failed")
|
||||||
return [], False
|
return [], False, None
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Iteration {iteration}: Unexpected error during parsing: {str(e)}")
|
logger.error(f"Iteration {iteration}: Unexpected error during parsing: {str(e)}")
|
||||||
return [], False
|
return [], False, None
|
||||||
|
|
||||||
def _shouldContinueGeneration(
|
def _shouldContinueGeneration(
|
||||||
self,
|
self,
|
||||||
|
|
@ -414,22 +419,58 @@ Respond with ONLY a JSON object in this exact format:
|
||||||
# JSON was incomplete/broken - continue
|
# JSON was incomplete/broken - continue
|
||||||
return True
|
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(
|
def _buildFinalResultFromSections(
|
||||||
self,
|
self,
|
||||||
allSections: List[Dict[str, Any]]
|
allSections: List[Dict[str, Any]],
|
||||||
|
documentMetadata: Optional[Dict[str, Any]] = None
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Build final JSON result from accumulated sections.
|
Build final JSON result from accumulated sections.
|
||||||
|
Uses AI-provided metadata (title, filename) if available.
|
||||||
"""
|
"""
|
||||||
if not allSections:
|
if not allSections:
|
||||||
return ""
|
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
|
# Build documents structure
|
||||||
# Assuming single document for now
|
# Assuming single document for now
|
||||||
documents = [{
|
documents = [{
|
||||||
"id": "doc_1",
|
"id": "doc_1",
|
||||||
"title": "Generated Document", # This should come from prompt
|
"title": title,
|
||||||
"filename": "document.json",
|
"filename": filename,
|
||||||
"sections": allSections
|
"sections": allSections
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ async def buildGenerationPrompt(
|
||||||
|
|
||||||
continuationText = "\n".join(continuationGuidance) if continuationGuidance else "Continue from where it stopped."
|
continuationText = "\n".join(continuationGuidance) if continuationGuidance else "Continue from where it stopped."
|
||||||
|
|
||||||
|
# PROMPT FOR CONTINUATION
|
||||||
|
|
||||||
generationPrompt = f"""User request: "{userPrompt}"
|
generationPrompt = f"""User request: "{userPrompt}"
|
||||||
|
|
||||||
The user already received part of the response. Continue generating the remaining content.
|
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.
|
- Arrays must contain ONLY JSON values; do not include comments or ellipses.
|
||||||
- Use ONLY the element structures shown in the template.
|
- Use ONLY the element structures shown in the template.
|
||||||
- Continue from where it stopped — add NEW items only; do not repeat existing items.
|
- 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...").
|
- 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.
|
- 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.
|
- 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:
|
Continue generating:
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
# FIRST CALL - initial generation
|
|
||||||
|
# PROMPT FOR FIRST CALL
|
||||||
|
|
||||||
generationPrompt = f"""User request: "{userPrompt}"
|
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.
|
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.
|
- Start with {{"metadata": ...}} — return COMPLETE, STRICT JSON.
|
||||||
- Return ONLY valid JSON (strict). No comments. No trailing commas. Use double quotes.
|
- Return ONLY valid JSON (strict). No comments. No trailing commas. Use double quotes.
|
||||||
- Do NOT reuse example section IDs; create your own.
|
- 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.
|
- 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.
|
- When the request is fully satisfied, add "complete_response": true at root level.
|
||||||
- Output JSON only; no markdown fences or extra text.
|
- Output JSON only; no markdown fences or extra text.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue